1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "private/qdeclarativeengine_p.h"
43 #include "qdeclarativeengine.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativecompiler_p.h"
47 #include "private/qdeclarativeglobalscriptclass_p.h"
48 #include "qdeclarative.h"
49 #include "qdeclarativecontext.h"
50 #include "qdeclarativeexpression.h"
51 #include "qdeclarativecomponent.h"
52 #include "private/qdeclarativebinding_p_p.h"
53 #include "private/qdeclarativevme_p.h"
54 #include "private/qdeclarativeenginedebug_p.h"
55 #include "private/qdeclarativestringconverters_p.h"
56 #include "private/qdeclarativexmlhttprequest_p.h"
57 #include "private/qdeclarativesqldatabase_p.h"
58 #include "private/qdeclarativescarceresourcescriptclass_p.h"
59 #include "private/qdeclarativetypenamescriptclass_p.h"
60 #include "private/qdeclarativelistscriptclass_p.h"
61 #include "qdeclarativescriptstring.h"
62 #include "private/qdeclarativeglobal_p.h"
63 #include "private/qdeclarativeworkerscript_p.h"
64 #include "private/qdeclarativecomponent_p.h"
65 #include "qdeclarativenetworkaccessmanagerfactory.h"
66 #include "qdeclarativeimageprovider.h"
67 #include "private/qdeclarativedirparser_p.h"
68 #include "qdeclarativeextensioninterface.h"
69 #include "private/qdeclarativelist_p.h"
70 #include "private/qdeclarativetypenamecache_p.h"
71 #include "private/qdeclarativeinclude_p.h"
72 #include "private/qdeclarativenotifier_p.h"
73 #include "private/qdeclarativedebugtrace_p.h"
74 #include "private/qdeclarativeapplication_p.h"
75 #include "private/qjsdebugservice_p.h"
77 #include <QtCore/qmetaobject.h>
78 #include <QScriptClass>
79 #include <QNetworkReply>
80 #include <QNetworkRequest>
81 #include <QNetworkAccessManager>
82 #include <QDesktopServices>
87 #include <QMetaObject>
90 #include <QPluginLoader>
91 #include <QtGui/qfontdatabase.h>
92 #include <QtCore/qlibraryinfo.h>
93 #include <QtCore/qthreadstorage.h>
94 #include <QtCore/qthread.h>
95 #include <QtCore/qcoreapplication.h>
96 #include <QtCore/qdir.h>
97 #include <QtCore/qmutex.h>
98 #include <QtGui/qcolor.h>
99 #include <QtGui/qvector3d.h>
100 #include <QtGui/qsound.h>
101 #include <QtCore/qcryptographichash.h>
103 #include <private/qobject_p.h>
104 #include <private/qscriptdeclarativeclass_p.h>
106 #include <private/qdeclarativeitemsmodule_p.h>
107 #include <private/qdeclarativeutilmodule_p.h>
108 #include <private/qsgitemsmodule_p.h>
109 #include <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);
662 QDeclarativeEngineDebugServer::instance()->remEngine(this);
664 // if we are the parent of any of the qobject module api instances,
665 // we need to remove them from our internal list, in order to prevent
666 // a segfault in engine private dtor.
667 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
668 QObject *currQObjectApi = 0;
669 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
670 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
671 currInstance = d->moduleApiInstances.value(key);
672 currQObjectApi = currInstance->qobjectApi;
673 if (this->children().contains(currQObjectApi)) {
674 delete currQObjectApi;
676 d->moduleApiInstances.remove(key);
681 /*! \fn void QDeclarativeEngine::quit()
682 This signal is emitted when the QML loaded by the engine would like to quit.
685 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
686 This signal is emitted when \a warnings messages are generated by QML.
690 Clears the engine's internal component cache.
692 Normally the QDeclarativeEngine caches components loaded from qml
693 files. This method clears this cache and forces the component to be
696 void QDeclarativeEngine::clearComponentCache()
698 Q_D(QDeclarativeEngine);
699 d->typeLoader.clearCache();
703 Returns the engine's root context.
705 The root context is automatically created by the QDeclarativeEngine.
706 Data that should be available to all QML component instances
707 instantiated by the engine should be put in the root context.
709 Additional data that should only be available to a subset of
710 component instances should be added to sub-contexts parented to the
713 QDeclarativeContext *QDeclarativeEngine::rootContext() const
715 Q_D(const QDeclarativeEngine);
716 return d->rootContext;
720 Sets the \a factory to use for creating QNetworkAccessManager(s).
722 QNetworkAccessManager is used for all network access by QML. By
723 implementing a factory it is possible to create custom
724 QNetworkAccessManager with specialized caching, proxy and cookie
727 The factory must be set before executing the engine.
729 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
731 Q_D(QDeclarativeEngine);
732 QMutexLocker locker(&d->mutex);
733 d->networkAccessManagerFactory = factory;
737 Returns the current QDeclarativeNetworkAccessManagerFactory.
739 \sa setNetworkAccessManagerFactory()
741 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
743 Q_D(const QDeclarativeEngine);
744 return d->networkAccessManagerFactory;
747 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
749 QMutexLocker locker(&mutex);
750 QNetworkAccessManager *nam;
751 if (networkAccessManagerFactory) {
752 nam = networkAccessManagerFactory->create(parent);
754 nam = new QNetworkAccessManager(parent);
760 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
762 Q_Q(const QDeclarativeEngine);
763 if (!networkAccessManager)
764 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
765 return networkAccessManager;
769 Returns a common QNetworkAccessManager which can be used by any QML
770 element instantiated by this engine.
772 If a QDeclarativeNetworkAccessManagerFactory has been set and a
773 QNetworkAccessManager has not yet been created, the
774 QDeclarativeNetworkAccessManagerFactory will be used to create the
775 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
776 will have no proxy or cache set.
778 \sa setNetworkAccessManagerFactory()
780 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
782 Q_D(const QDeclarativeEngine);
783 return d->getNetworkAccessManager();
788 Sets the \a provider to use for images requested via the \e
789 image: url scheme, with host \a providerId. The QDeclarativeEngine
790 takes ownership of \a provider.
792 Image providers enable support for pixmap and threaded image
793 requests. See the QDeclarativeImageProvider documentation for details on
794 implementing and using image providers.
796 All required image providers should be added to the engine before any
797 QML sources files are loaded.
799 Note that images loaded from a QDeclarativeImageProvider are cached
800 by QPixmapCache, similar to any image loaded by QML.
802 \sa removeImageProvider()
804 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
806 Q_D(QDeclarativeEngine);
807 QMutexLocker locker(&d->mutex);
808 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
812 Returns the QDeclarativeImageProvider set for \a providerId.
814 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
816 Q_D(const QDeclarativeEngine);
817 QMutexLocker locker(&d->mutex);
818 return d->imageProviders.value(providerId).data();
822 Removes the QDeclarativeImageProvider for \a providerId.
824 Returns the provider if it was found; otherwise returns 0.
826 \sa addImageProvider()
828 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
830 Q_D(QDeclarativeEngine);
831 QMutexLocker locker(&d->mutex);
832 d->imageProviders.take(providerId);
835 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
837 QMutexLocker locker(&mutex);
838 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
841 return provider->imageType();
842 return QDeclarativeImageProvider::Invalid;
845 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
847 QMutexLocker locker(&mutex);
848 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
851 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
852 return provider->requestTexture(imageId, size, req_size);
857 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
859 QMutexLocker locker(&mutex);
861 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
864 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
865 image = provider->requestImage(imageId, size, req_size);
870 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
872 QMutexLocker locker(&mutex);
874 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
877 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
878 pixmap = provider->requestPixmap(imageId, size, req_size);
884 Return the base URL for this engine. The base URL is only used to
885 resolve components when a relative URL is passed to the
886 QDeclarativeComponent constructor.
888 If a base URL has not been explicitly set, this method returns the
889 application's current working directory.
893 QUrl QDeclarativeEngine::baseUrl() const
895 Q_D(const QDeclarativeEngine);
896 if (d->baseUrl.isEmpty()) {
897 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
904 Set the base URL for this engine to \a url.
908 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
910 Q_D(QDeclarativeEngine);
915 Returns true if warning messages will be output to stderr in addition
916 to being emitted by the warnings() signal, otherwise false.
918 The default value is true.
920 bool QDeclarativeEngine::outputWarningsToStandardError() const
922 Q_D(const QDeclarativeEngine);
923 return d->outputWarningsToStdErr;
927 Set whether warning messages will be output to stderr to \a enabled.
929 If \a enabled is true, any warning messages generated by QML will be
930 output to stderr and emitted by the warnings() signal. If \a enabled
931 is false, on the warnings() signal will be emitted. This allows
932 applications to handle warning output themselves.
934 The default value is true.
936 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
938 Q_D(QDeclarativeEngine);
939 d->outputWarningsToStdErr = enabled;
943 Returns the QDeclarativeContext for the \a object, or 0 if no
944 context has been set.
946 When the QDeclarativeEngine instantiates a QObject, the context is
949 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
954 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
956 QDeclarativeData *data =
957 static_cast<QDeclarativeData *>(priv->declarativeData);
961 else if (data->outerContext)
962 return data->outerContext->asQDeclarativeContext();
968 Sets the QDeclarativeContext for the \a object to \a context.
969 If the \a object already has a context, a warning is
970 output, but the context is not changed.
972 When the QDeclarativeEngine instantiates a QObject, the context is
975 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
977 if (!object || !context)
980 QDeclarativeData *data = QDeclarativeData::get(object, true);
982 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
986 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
987 contextData->addObject(object);
991 \enum QDeclarativeEngine::ObjectOwnership
993 Ownership controls whether or not QML automatically destroys the
994 QObject when the object is garbage collected by the JavaScript
995 engine. The two ownership options are:
997 \value CppOwnership The object is owned by C++ code, and will
998 never be deleted by QML. The JavaScript destroy() method cannot be
999 used on objects with CppOwnership. This option is similar to
1000 QScriptEngine::QtOwnership.
1002 \value JavaScriptOwnership The object is owned by JavaScript.
1003 When the object is returned to QML as the return value of a method
1004 call or property access, QML will delete the object if there are no
1005 remaining JavaScript references to it and it has no
1006 QObject::parent(). This option is similar to
1007 QScriptEngine::ScriptOwnership.
1009 Generally an application doesn't need to set an object's ownership
1010 explicitly. QML uses a heuristic to set the default object
1011 ownership. By default, an object that is created by QML has
1012 JavaScriptOwnership. The exception to this are the root objects
1013 created by calling QDeclarativeCompnent::create() or
1014 QDeclarativeComponent::beginCreate() which have CppOwnership by
1015 default. The ownership of these root-level objects is considered to
1016 have been transferred to the C++ caller.
1018 Objects not-created by QML have CppOwnership by default. The
1019 exception to this is objects returned from a C++ method call. The
1020 ownership of these objects is passed to JavaScript.
1022 Calling setObjectOwnership() overrides the default ownership
1023 heuristic used by QML.
1027 Sets the \a ownership of \a object.
1029 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1034 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1038 ddata->indestructible = (ownership == CppOwnership)?true:false;
1039 ddata->explicitIndestructibleSet = true;
1043 Returns the ownership of \a object.
1045 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1048 return CppOwnership;
1050 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1052 return CppOwnership;
1054 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1057 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1059 QDeclarativeData *data = QDeclarativeData::get(object);
1061 if (data && data->deferredComponent) {
1062 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1063 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1064 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1065 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1066 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1067 if (data->outerContext)
1068 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1070 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1072 QDeclarativeComponentPrivate::ConstructionState state;
1073 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1075 data->deferredComponent->release();
1076 data->deferredComponent = 0;
1078 QDeclarativeComponentPrivate::complete(ep, &state);
1079 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1083 QDeclarativeContext *qmlContext(const QObject *obj)
1085 return QDeclarativeEngine::contextForObject(obj);
1088 QDeclarativeEngine *qmlEngine(const QObject *obj)
1090 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1091 return context?context->engine():0;
1094 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1096 QDeclarativeData *data = QDeclarativeData::get(object);
1098 return 0; // Attached properties are only on objects created by QML
1100 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1104 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1108 rv = pf(const_cast<QObject *>(object));
1111 data->attachedProperties()->insert(id, rv);
1116 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1117 const QMetaObject *attachedMetaObject, bool create)
1120 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1122 if (*idCache == -1 || !object)
1125 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1128 class QDeclarativeDataExtended {
1130 QDeclarativeDataExtended();
1131 ~QDeclarativeDataExtended();
1133 QHash<int, QObject *> attachedProperties;
1134 QDeclarativeNotifier objectNameNotifier;
1137 QDeclarativeDataExtended::QDeclarativeDataExtended()
1141 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1145 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1147 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1148 return &extendedData->objectNameNotifier;
1151 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1153 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1154 return &extendedData->attachedProperties;
1157 void QDeclarativeData::destroyed(QObject *object)
1159 if (deferredComponent)
1160 deferredComponent->release();
1162 if (nextContextObject)
1163 nextContextObject->prevContextObject = prevContextObject;
1164 if (prevContextObject)
1165 *prevContextObject = nextContextObject;
1167 QDeclarativeAbstractBinding *binding = bindings;
1169 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1170 binding->m_prevBinding = 0;
1171 binding->m_nextBinding = 0;
1180 propertyCache->release();
1182 if (ownContext && context)
1186 QDeclarativeGuard<QObject> *guard = guards;
1187 *guard = (QObject *)0;
1188 guard->objectDestroyed(object);
1195 delete extendedData;
1201 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1203 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1206 void QDeclarativeData::objectNameChanged(QObject *)
1208 if (extendedData) objectNameNotifier()->notify();
1211 bool QDeclarativeData::hasBindingBit(int bit) const
1213 if (bindingBitsSize > bit)
1214 return bindingBits[bit / 32] & (1 << (bit % 32));
1219 void QDeclarativeData::clearBindingBit(int bit)
1221 if (bindingBitsSize > bit)
1222 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1225 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1227 if (bindingBitsSize <= bit) {
1228 int props = obj->metaObject()->propertyCount();
1229 Q_ASSERT(bit < props);
1231 int arraySize = (props + 31) / 32;
1232 int oldArraySize = bindingBitsSize / 32;
1234 bindingBits = (quint32 *)realloc(bindingBits,
1235 arraySize * sizeof(quint32));
1237 memset(bindingBits + oldArraySize,
1239 sizeof(quint32) * (arraySize - oldArraySize));
1241 bindingBitsSize = arraySize * 32;
1244 bindingBits[bit / 32] |= (1 << (bit % 32));
1248 Creates a QScriptValue allowing you to use \a object in QML script.
1249 \a engine is the QDeclarativeEngine it is to be created in.
1251 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1252 to the special needs of QML requiring more functionality than a standard
1255 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1256 QDeclarativeEngine* engine)
1258 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1259 return enginePriv->objectClass->newQObject(object);
1263 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1265 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1267 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1268 Q_ASSERT(scopeNode.isValid());
1269 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1270 return contextClass->contextFromValue(scopeNode);
1274 Returns the QUrl associated with the script \a ctxt for the case that there is
1275 no QDeclarativeContext.
1277 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1279 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1280 Q_ASSERT(scopeNode.isValid());
1281 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1282 return contextClass->urlFromValue(scopeNode);
1285 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1287 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1288 if (url.authority().isEmpty())
1289 return QLatin1Char(':') + url.path();
1292 return url.toLocalFile();
1296 \qmlmethod object Qt::createComponent(url)
1298 Returns a \l Component object created using the QML file at the specified \a url,
1299 or \c null if an empty string was given.
1301 The returned component's \l Component::status property indicates whether the
1302 component was successfully created. If the status is \c Component.Error,
1303 see \l Component::errorString() for an error description.
1305 Call \l {Component::createObject()}{Component.createObject()} on the returned
1306 component to create an object instance of the component.
1310 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1312 See \l {Dynamic Object Management in QML} for more information on using this function.
1314 To create a QML object from an arbitrary string of QML (instead of a file),
1315 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1318 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1320 QDeclarativeEnginePrivate *activeEnginePriv =
1321 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1322 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1324 if(ctxt->argumentCount() != 1) {
1325 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1328 QString arg = ctxt->argument(0).toString();
1330 return engine->nullValue();
1331 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1332 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1333 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1334 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1335 QDeclarativeData::get(c, true)->setImplicitDestructible();
1336 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1341 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1343 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1344 or \c null if there was an error in creating the object.
1346 If \a filepath is specified, it will be used for error reporting for the created object.
1348 Example (where \c parentItem is the id of an existing QML item):
1350 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1352 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1353 \c qmlErrors, which is an array of the errors encountered.
1354 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1355 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1356 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1358 Note that this function returns immediately, and therefore may not work if
1359 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1360 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1362 See \l {Dynamic Object Management in QML} for more information on using this function.
1365 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1367 QDeclarativeEnginePrivate *activeEnginePriv =
1368 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1369 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1371 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1372 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1374 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1377 QString qml = ctxt->argument(0).toString();
1379 return engine->nullValue();
1382 if(ctxt->argumentCount() > 2)
1383 url = QUrl(ctxt->argument(2).toString());
1385 url = QUrl(QLatin1String("inline"));
1387 if (url.isValid() && url.isRelative())
1388 url = context->resolvedUrl(url);
1390 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1392 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1394 QDeclarativeComponent component(activeEngine);
1395 component.setData(qml.toUtf8(), url);
1397 if(component.isError()) {
1398 QList<QDeclarativeError> errors = component.errors();
1399 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1400 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1402 foreach (const QDeclarativeError &error, errors){
1403 errstr += QLatin1String("\n ") + error.toString();
1404 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1405 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1406 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1407 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1408 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1409 arr.setProperty(i++, qmlErrObject);
1411 QScriptValue err = ctxt->throwError(errstr);
1412 err.setProperty(QLatin1String("qmlErrors"),arr);
1416 if (!component.isReady())
1417 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1419 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1421 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1422 component.completeCreate();
1424 if(component.isError()) {
1425 QList<QDeclarativeError> errors = component.errors();
1426 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1427 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1429 foreach (const QDeclarativeError &error, errors){
1430 errstr += QLatin1String("\n ") + error.toString();
1431 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1432 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1433 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1434 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1435 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1436 arr.setProperty(i++, qmlErrObject);
1438 QScriptValue err = ctxt->throwError(errstr);
1439 err.setProperty(QLatin1String("qmlErrors"),arr);
1445 obj->setParent(parentArg);
1447 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1448 for (int ii = 0; ii < functions.count(); ++ii) {
1449 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1453 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1454 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1458 \qmlmethod bool Qt::isQtObject(object)
1459 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1461 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1463 if (ctxt->argumentCount() == 0)
1464 return QScriptValue(engine, false);
1466 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1470 \qmlmethod Qt::vector3d(real x, real y, real z)
1471 Returns a Vector3D with the specified \c x, \c y and \c z.
1473 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1475 if(ctxt->argumentCount() != 3)
1476 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1477 qsreal x = ctxt->argument(0).toNumber();
1478 qsreal y = ctxt->argument(1).toNumber();
1479 qsreal z = ctxt->argument(2).toNumber();
1480 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1484 \qmlmethod string Qt::formatDate(datetime date, variant format)
1486 Returns a string representation of \c date, optionally formatted according
1489 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1490 property, a QDate, or QDateTime value. The \a format parameter may be any of
1491 the possible format values as described for
1492 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1494 If \a format is not specified, \a date is formatted using
1495 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1497 #ifndef QT_NO_DATESTRING
1498 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1500 int argCount = ctxt->argumentCount();
1501 if(argCount == 0 || argCount > 2)
1502 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1504 QDate date = ctxt->argument(0).toDateTime().date();
1505 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1506 if (argCount == 2) {
1507 QScriptValue formatArg = ctxt->argument(1);
1508 if (formatArg.isString()) {
1509 QString format = formatArg.toString();
1510 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1511 } else if (formatArg.isNumber()) {
1512 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1514 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1517 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1521 \qmlmethod string Qt::formatTime(datetime time, variant format)
1523 Returns a string representation of \c time, optionally formatted according to
1526 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1527 value. The \a format parameter may be any of the possible format values as
1528 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1530 If \a format is not specified, \a time is formatted using
1531 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1533 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1535 int argCount = ctxt->argumentCount();
1536 if(argCount == 0 || argCount > 2)
1537 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1540 QScriptValue sv = ctxt->argument(0);
1542 time = sv.toDateTime().time();
1543 else if (sv.toVariant().type() == QVariant::Time)
1544 time = sv.toVariant().toTime();
1546 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1547 if (argCount == 2) {
1548 QScriptValue formatArg = ctxt->argument(1);
1549 if (formatArg.isString()) {
1550 QString format = formatArg.toString();
1551 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1552 } else if (formatArg.isNumber()) {
1553 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1555 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1558 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1562 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1564 Returns a string representation of \c datetime, optionally formatted according to
1567 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1568 property, a QDate, QTime, or QDateTime value.
1570 If \a format is not provided, \a dateTime is formatted using
1571 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1572 \a format should be either.
1575 \o One of the Qt::DateFormat enumeration values, such as
1576 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1577 \o A string that specifies the format of the returned string, as detailed below.
1580 If \a format specifies a format string, it should use the following expressions
1581 to specify the date:
1584 \header \i Expression \i Output
1585 \row \i d \i the day as number without a leading zero (1 to 31)
1586 \row \i dd \i the day as number with a leading zero (01 to 31)
1588 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1589 Uses QDate::shortDayName().
1591 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1592 Uses QDate::longDayName().
1593 \row \i M \i the month as number without a leading zero (1-12)
1594 \row \i MM \i the month as number with a leading zero (01-12)
1596 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1597 Uses QDate::shortMonthName().
1599 \i the long localized month name (e.g. 'January' to 'December').
1600 Uses QDate::longMonthName().
1601 \row \i yy \i the year as two digit number (00-99)
1602 \row \i yyyy \i the year as four digit number
1605 In addition the following expressions can be used to specify the time:
1608 \header \i Expression \i Output
1610 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1612 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1613 \row \i m \i the minute without a leading zero (0 to 59)
1614 \row \i mm \i the minute with a leading zero (00 to 59)
1615 \row \i s \i the second without a leading zero (0 to 59)
1616 \row \i ss \i the second with a leading zero (00 to 59)
1617 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1618 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1620 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1622 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1625 All other input characters will be ignored. Any sequence of characters that
1626 are enclosed in single quotes will be treated as text and not be used as an
1627 expression. Two consecutive single quotes ("''") are replaced by a single quote
1630 For example, if the following date/time value was specified:
1633 // 21 May 2001 14:13:09
1634 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1637 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1638 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1639 with the \a format values below to produce the following results:
1642 \header \i Format \i Result
1643 \row \i "dd.MM.yyyy" \i 21.05.2001
1644 \row \i "ddd MMMM d yy" \i Tue May 21 01
1645 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1646 \row \i "h:m:s ap" \i 2:13:9 pm
1649 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1651 int argCount = ctxt->argumentCount();
1652 if(argCount == 0 || argCount > 2)
1653 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1655 QDateTime date = ctxt->argument(0).toDateTime();
1656 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1657 if (argCount == 2) {
1658 QScriptValue formatArg = ctxt->argument(1);
1659 if (formatArg.isString()) {
1660 QString format = formatArg.toString();
1661 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1662 } else if (formatArg.isNumber()) {
1663 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1665 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1668 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1670 #endif // QT_NO_DATESTRING
1673 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1675 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1676 All components should be in the range 0-1 inclusive.
1678 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1680 int argCount = ctxt->argumentCount();
1681 if(argCount < 3 || argCount > 4)
1682 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1683 qsreal r = ctxt->argument(0).toNumber();
1684 qsreal g = ctxt->argument(1).toNumber();
1685 qsreal b = ctxt->argument(2).toNumber();
1686 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1697 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1701 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1703 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1704 All components should be in the range 0-1 inclusive.
1706 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1708 int argCount = ctxt->argumentCount();
1709 if(argCount < 3 || argCount > 4)
1710 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1711 qsreal h = ctxt->argument(0).toNumber();
1712 qsreal s = ctxt->argument(1).toNumber();
1713 qsreal l = ctxt->argument(2).toNumber();
1714 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1725 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1729 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1731 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1733 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1735 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1737 if(ctxt->argumentCount() != 4)
1738 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1740 qsreal x = ctxt->argument(0).toNumber();
1741 qsreal y = ctxt->argument(1).toNumber();
1742 qsreal w = ctxt->argument(2).toNumber();
1743 qsreal h = ctxt->argument(3).toNumber();
1745 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1749 \qmlmethod point Qt::point(int x, int y)
1750 Returns a Point with the specified \c x and \c y coordinates.
1752 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1754 if(ctxt->argumentCount() != 2)
1755 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1756 qsreal x = ctxt->argument(0).toNumber();
1757 qsreal y = ctxt->argument(1).toNumber();
1758 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1762 \qmlmethod Qt::size(int width, int height)
1763 Returns a Size with the specified \c width and \c height.
1765 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1767 if(ctxt->argumentCount() != 2)
1768 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1769 qsreal w = ctxt->argument(0).toNumber();
1770 qsreal h = ctxt->argument(1).toNumber();
1771 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1775 \qmlmethod color Qt::lighter(color baseColor, real factor)
1776 Returns a color lighter than \c baseColor by the \c factor provided.
1778 If the factor is greater than 1.0, this functions returns a lighter color.
1779 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1780 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1781 If the factor is 0 or negative, the return value is unspecified.
1783 The function converts the current RGB color to HSV, multiplies the value (V) component
1784 by factor and converts the color back to RGB.
1786 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1788 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1790 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1791 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1792 QVariant v = ctxt->argument(0).toVariant();
1794 if (v.userType() == QVariant::Color)
1795 color = v.value<QColor>();
1796 else if (v.userType() == QVariant::String) {
1798 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1800 return engine->nullValue();
1802 return engine->nullValue();
1803 qsreal factor = 1.5;
1804 if (ctxt->argumentCount() == 2)
1805 factor = ctxt->argument(1).toNumber();
1806 color = color.lighter(int(qRound(factor*100.)));
1807 return engine->toScriptValue(QVariant::fromValue(color));
1811 \qmlmethod color Qt::darker(color baseColor, real factor)
1812 Returns a color darker than \c baseColor by the \c factor provided.
1814 If the factor is greater than 1.0, this function returns a darker color.
1815 Setting factor to 3.0 returns a color that has one-third the brightness.
1816 If the factor is less than 1.0, the return color is lighter, but we recommend using
1817 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1818 value is unspecified.
1820 The function converts the current RGB color to HSV, divides the value (V) component
1821 by factor and converts the color back to RGB.
1823 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1825 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1827 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1828 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1829 QVariant v = ctxt->argument(0).toVariant();
1831 if (v.userType() == QVariant::Color)
1832 color = v.value<QColor>();
1833 else if (v.userType() == QVariant::String) {
1835 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1837 return engine->nullValue();
1839 return engine->nullValue();
1840 qsreal factor = 2.0;
1841 if (ctxt->argumentCount() == 2)
1842 factor = ctxt->argument(1).toNumber();
1843 color = color.darker(int(qRound(factor*100.)));
1844 return engine->toScriptValue(QVariant::fromValue(color));
1848 \qmlmethod bool Qt::openUrlExternally(url target)
1849 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.
1851 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1853 if(ctxt->argumentCount() < 1)
1854 return QScriptValue(e, false);
1856 #ifndef QT_NO_DESKTOPSERVICES
1857 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1859 return QScriptValue(e, ret);
1863 \qmlmethod list<string> Qt::fontFamilies()
1864 Returns a list of the font families available to the application.
1867 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1869 if(ctxt->argumentCount() != 0)
1870 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1872 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1873 QFontDatabase database;
1874 return p->scriptValueFromVariant(database.families());
1878 \qmlmethod string Qt::md5(data)
1879 Returns a hex string of the md5 hash of \c data.
1881 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1883 if (ctxt->argumentCount() != 1)
1884 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1886 QByteArray data = ctxt->argument(0).toString().toUtf8();
1887 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1889 return QScriptValue(QLatin1String(result.toHex()));
1893 \qmlmethod string Qt::btoa(data)
1894 Binary to ASCII - this function returns a base64 encoding of \c data.
1896 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1898 if (ctxt->argumentCount() != 1)
1899 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1901 QByteArray data = ctxt->argument(0).toString().toUtf8();
1903 return QScriptValue(QLatin1String(data.toBase64()));
1907 \qmlmethod string Qt::atob(data)
1908 ASCII to binary - this function returns a base64 decoding of \c data.
1911 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1913 if (ctxt->argumentCount() != 1)
1914 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1916 QByteArray data = ctxt->argument(0).toString().toUtf8();
1918 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1921 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1923 if(ctxt->argumentCount() < 1)
1924 return e->newVariant(QVariant(false));
1928 for (int i=0; i<ctxt->argumentCount(); ++i) {
1929 if (!msg.isEmpty()) msg += ' ';
1930 msg += ctxt->argument(i).toString().toLocal8Bit();
1931 // does not support firebug "%[a-z]" formatting, since firebug really
1932 // does just ignore the format letter, which makes it pointless.
1935 qDebug("%s",msg.constData());
1937 return e->newVariant(QVariant(true));
1940 void QDeclarativeEnginePrivate::sendQuit()
1942 Q_Q(QDeclarativeEngine);
1944 if (q->receivers(SIGNAL(quit())) == 0) {
1945 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1949 static void dumpwarning(const QDeclarativeError &error)
1951 qWarning().nospace() << qPrintable(error.toString());
1954 static void dumpwarning(const QList<QDeclarativeError> &errors)
1956 for (int ii = 0; ii < errors.count(); ++ii)
1957 dumpwarning(errors.at(ii));
1960 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1962 Q_Q(QDeclarativeEngine);
1963 q->warnings(QList<QDeclarativeError>() << error);
1964 if (outputWarningsToStdErr)
1968 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1970 Q_Q(QDeclarativeEngine);
1971 q->warnings(errors);
1972 if (outputWarningsToStdErr)
1973 dumpwarning(errors);
1976 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1979 QDeclarativeEnginePrivate::get(engine)->warning(error);
1984 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1987 QDeclarativeEnginePrivate::get(engine)->warning(error);
1992 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1995 engine->warning(error);
2000 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2003 engine->warning(error);
2009 \qmlmethod Qt::quit()
2010 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2011 Within the \l {QML Viewer}, this causes the launcher application to exit;
2012 to quit a C++ application when this method is called, connect the
2013 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2016 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2018 QDeclarativeEnginePrivate *qe = get (e);
2020 return QScriptValue();
2024 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2025 This function allows tinting one color with another.
2027 The tint color should usually be mostly transparent, or you will not be
2028 able to see the underlying color. The below example provides a slight red
2029 tint by having the tint color be pure red which is only 1/16th opaque.
2034 x: 0; width: 80; height: 80
2035 color: "lightsteelblue"
2038 x: 100; width: 80; height: 80
2039 color: Qt.tint("lightsteelblue", "#10FF0000")
2043 \image declarative-rect_tint.png
2045 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.
2047 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2049 if(ctxt->argumentCount() != 2)
2050 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2052 QVariant v = ctxt->argument(0).toVariant();
2054 if (v.userType() == QVariant::Color)
2055 color = v.value<QColor>();
2056 else if (v.userType() == QVariant::String) {
2058 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2060 return engine->nullValue();
2062 return engine->nullValue();
2065 v = ctxt->argument(1).toVariant();
2067 if (v.userType() == QVariant::Color)
2068 tintColor = v.value<QColor>();
2069 else if (v.userType() == QVariant::String) {
2071 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2073 return engine->nullValue();
2075 return engine->nullValue();
2079 int a = tintColor.alpha();
2081 finalColor = tintColor;
2085 qreal a = tintColor.alphaF();
2086 qreal inv_a = 1.0 - a;
2088 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2089 tintColor.greenF() * a + color.greenF() * inv_a,
2090 tintColor.blueF() * a + color.blueF() * inv_a,
2091 a + inv_a * color.alphaF());
2094 return engine->toScriptValue(QVariant::fromValue(finalColor));
2097 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2099 if (variantIsScarceResource(val)) {
2100 return scarceResourceClass->newScarceResource(val);
2101 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2102 QDeclarativeListReferencePrivate *p =
2103 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2105 return listClass->newList(p->property, p->propertyType);
2107 return scriptEngine.nullValue();
2109 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2110 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2111 QScriptValue rv = scriptEngine.newArray(list.count());
2112 for (int ii = 0; ii < list.count(); ++ii) {
2113 QObject *object = list.at(ii);
2114 rv.setProperty(ii, objectClass->newQObject(object));
2117 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2118 return valueTypeClass->newObject(val, vt);
2122 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2124 return objectClass->newQObject(obj);
2126 return scriptEngine.toScriptValue(val);
2131 If the variant is a scarce resource (consumes a large amount of memory, or
2132 only a limited number of them can be held in memory at any given time without
2133 exhausting supply for future use) we need to release the scarce resource
2134 after evaluation of the javascript binding is complete.
2136 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2138 if (val.type() == QVariant::Pixmap) {
2140 } else if (val.type() == QVariant::Image) {
2148 This function should be called prior to evaluation of any js expression,
2149 so that scarce resources are not freed prematurely (eg, if there is a
2150 nested javascript expression).
2152 void QDeclarativeEnginePrivate::referenceScarceResources()
2154 scarceResourcesRefCount += 1;
2158 This function should be called after evaluation of the js expression is
2159 complete, and so the scarce resources may be freed safely.
2161 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2163 Q_ASSERT(scarceResourcesRefCount > 0);
2164 scarceResourcesRefCount -= 1;
2166 // if the refcount is zero, then evaluation of the "top level"
2167 // expression must have completed. We can safely release the
2168 // scarce resources.
2169 if (scarceResourcesRefCount == 0) {
2170 // iterate through the list and release them all.
2171 // note that the actual SRD is owned by the JS engine,
2172 // so we cannot delete the SRD; but we can free the
2173 // memory used by the variant in the SRD.
2174 ScarceResourceData *srd = 0;
2175 while (scarceResources) {
2176 srd = scarceResources; // srd points to the "old" (current) head of the list
2177 scarceResources = srd->next; // srd->next is the "new" head of the list
2178 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2181 srd->releaseResource(); // release the old head node.
2186 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2188 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2189 if (dc == objectClass)
2190 return QVariant::fromValue(objectClass->toQObject(val));
2191 else if (dc == scarceResourceClass)
2192 return scarceResourceClass->toVariant(val);
2193 else if (dc == valueTypeClass)
2194 return valueTypeClass->toVariant(val);
2195 else if (dc == contextClass)
2198 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2199 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2200 QList<QObject *> list;
2201 int length = val.property(QLatin1String("length")).toInt32();
2202 for (int ii = 0; ii < length; ++ii) {
2203 QScriptValue arrayItem = val.property(ii);
2204 QObject *d = arrayItem.toQObject();
2207 return QVariant::fromValue(list);
2210 return val.toVariant();
2214 Adds \a path as a directory where the engine searches for
2215 installed modules in a URL-based directory structure.
2216 The \a path may be a local filesystem directory or a URL.
2218 The newly added \a path will be first in the importPathList().
2220 \sa setImportPathList(), {QML Modules}
2222 void QDeclarativeEngine::addImportPath(const QString& path)
2224 Q_D(QDeclarativeEngine);
2225 d->importDatabase.addImportPath(path);
2229 Returns the list of directories where the engine searches for
2230 installed modules in a URL-based directory structure.
2232 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2233 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2234 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2235 provided by that module. A \c qmldir file is required for defining the
2236 type version mapping and possibly declarative extensions plugins.
2238 By default, the list contains the directory of the application executable,
2239 paths specified in the \c QML_IMPORT_PATH environment variable,
2240 and the builtin \c ImportsPath from QLibraryInfo.
2242 \sa addImportPath() setImportPathList()
2244 QStringList QDeclarativeEngine::importPathList() const
2246 Q_D(const QDeclarativeEngine);
2247 return d->importDatabase.importPathList();
2251 Sets \a paths as the list of directories where the engine searches for
2252 installed modules in a URL-based directory structure.
2254 By default, the list contains the directory of the application executable,
2255 paths specified in the \c QML_IMPORT_PATH environment variable,
2256 and the builtin \c ImportsPath from QLibraryInfo.
2258 \sa importPathList() addImportPath()
2260 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2262 Q_D(QDeclarativeEngine);
2263 d->importDatabase.setImportPathList(paths);
2268 Adds \a path as a directory where the engine searches for
2269 native plugins for imported modules (referenced in the \c qmldir file).
2271 By default, the list contains only \c ., i.e. the engine searches
2272 in the directory of the \c qmldir file itself.
2274 The newly added \a path will be first in the pluginPathList().
2276 \sa setPluginPathList()
2278 void QDeclarativeEngine::addPluginPath(const QString& path)
2280 Q_D(QDeclarativeEngine);
2281 d->importDatabase.addPluginPath(path);
2286 Returns the list of directories where the engine searches for
2287 native plugins for imported modules (referenced in the \c qmldir file).
2289 By default, the list contains only \c ., i.e. the engine searches
2290 in the directory of the \c qmldir file itself.
2292 \sa addPluginPath() setPluginPathList()
2294 QStringList QDeclarativeEngine::pluginPathList() const
2296 Q_D(const QDeclarativeEngine);
2297 return d->importDatabase.pluginPathList();
2301 Sets the list of directories where the engine searches for
2302 native plugins for imported modules (referenced in the \c qmldir file)
2305 By default, the list contains only \c ., i.e. the engine searches
2306 in the directory of the \c qmldir file itself.
2308 \sa pluginPathList() addPluginPath()
2310 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2312 Q_D(QDeclarativeEngine);
2313 d->importDatabase.setPluginPathList(paths);
2318 Imports the plugin named \a filePath with the \a uri provided.
2319 Returns true if the plugin was successfully imported; otherwise returns false.
2321 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2323 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2325 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2327 Q_D(QDeclarativeEngine);
2328 return d->importDatabase.importPlugin(filePath, uri, errors);
2332 Imports the plugin named \a filePath with the \a uri provided.
2333 Returns true if the plugin was successfully imported; otherwise returns false.
2335 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2337 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2339 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2341 Q_D(QDeclarativeEngine);
2342 QList<QDeclarativeError> errors;
2343 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2344 if (!errors.isEmpty()) {
2346 for (int i = 0; i < errors.size(); ++i) {
2347 builtError = QString(QLatin1String("%1\n %2"))
2349 .arg(errors.at(i).toString());
2351 *errorString = builtError;
2357 \property QDeclarativeEngine::offlineStoragePath
2358 \brief the directory for storing offline user data
2360 Returns the directory where SQL and other offline
2363 QDeclarativeWebView and the SQL databases created with openDatabase()
2366 The default is QML/OfflineStorage in the platform-standard
2367 user application data directory.
2369 Note that the path may not currently exist on the filesystem, so
2370 callers wanting to \e create new files at this location should create
2371 it first - see QDir::mkpath().
2373 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2375 Q_D(QDeclarativeEngine);
2376 d->scriptEngine.offlineStoragePath = dir;
2379 QString QDeclarativeEngine::offlineStoragePath() const
2381 Q_D(const QDeclarativeEngine);
2382 return d->scriptEngine.offlineStoragePath;
2385 static void voidptr_destructor(void *v)
2387 void **ptr = (void **)v;
2391 static void *voidptr_constructor(const void *v)
2396 return new void*(*(void **)v);
2400 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2402 Q_Q(QDeclarativeEngine);
2404 if (!mo->superClass()) {
2405 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2406 propertyCache.insert(mo, rv);
2409 QDeclarativePropertyCache *super = cache(mo->superClass());
2410 QDeclarativePropertyCache *rv = super->copy();
2412 propertyCache.insert(mo, rv);
2417 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2418 QDeclarativeError &error)
2420 QList<QDeclarativeType *> types;
2422 int maxMinorVersion = 0;
2424 const QMetaObject *metaObject = type->metaObject();
2425 while (metaObject) {
2426 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2427 type->majorVersion(), minorVersion);
2429 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2435 metaObject = metaObject->superClass();
2438 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2440 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2444 QDeclarativePropertyCache *raw = cache(type->metaObject());
2446 bool hasCopied = false;
2448 for (int ii = 0; ii < types.count(); ++ii) {
2449 QDeclarativeType *currentType = types.at(ii);
2453 int rev = currentType->metaObjectRevision();
2454 int moIndex = types.count() - 1 - ii;
2456 if (raw->allowedRevisionCache[moIndex] != rev) {
2461 raw->allowedRevisionCache[moIndex] = rev;
2465 // Test revision compatibility - the basic rule is:
2466 // * Anything that is excluded, cannot overload something that is not excluded *
2468 // Signals override:
2469 // * other signals and methods of the same name.
2470 // * properties named on<Signal Name>
2471 // * automatic <property name>Changed notify signals
2473 // Methods override:
2474 // * other methods of the same name
2476 // Properties override:
2477 // * other elements of the same name
2479 bool overloadError = false;
2480 QString overloadName;
2483 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2484 !overloadError && iter != raw->stringCache.end();
2487 QDeclarativePropertyCache::Data *d = *iter;
2488 if (raw->isAllowedInRevision(d))
2489 continue; // Not excluded - no problems
2491 // check that a regular "name" overload isn't happening
2492 QDeclarativePropertyCache::Data *current = d;
2493 while (!overloadError && current) {
2494 current = d->overrideData(current);
2495 if (current && raw->isAllowedInRevision(current))
2496 overloadError = true;
2501 if (overloadError) {
2502 if (hasCopied) raw->release();
2504 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."));
2508 if (!hasCopied) raw->addref();
2509 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2511 if (minorVersion != maxMinorVersion) {
2513 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2519 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2521 QByteArray name = data->root->className();
2523 QByteArray ptr = name + '*';
2524 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2526 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2527 voidptr_constructor);
2528 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2529 voidptr_constructor);
2531 m_qmlLists.insert(lst_type, ptr_type);
2532 m_compositeTypes.insert(ptr_type, data);
2536 bool QDeclarativeEnginePrivate::isList(int t) const
2538 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2541 int QDeclarativeEnginePrivate::listType(int t) const
2543 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2544 if (iter != m_qmlLists.end())
2547 return QDeclarativeMetaType::listType(t);
2550 bool QDeclarativeEnginePrivate::isQObject(int t)
2552 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2555 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2557 int t = v.userType();
2558 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2560 return *(QObject **)(v.constData());
2562 return QDeclarativeMetaType::toQObject(v, ok);
2566 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2568 if (m_compositeTypes.contains(t))
2569 return QDeclarativeMetaType::Object;
2570 else if (m_qmlLists.contains(t))
2571 return QDeclarativeMetaType::List;
2573 return QDeclarativeMetaType::typeCategory(t);
2576 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2578 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2579 if (iter != m_compositeTypes.end()) {
2580 return (*iter)->root;
2582 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2583 return type?type->baseMetaObject():0;
2587 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2589 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2590 if (iter != m_compositeTypes.end()) {
2591 return (*iter)->root;
2593 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2594 return type?type->metaObject():0;
2598 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2600 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2601 QFileInfo info(fileName);
2603 QString absolute = info.absoluteFilePath();
2605 #if defined(Q_OS_MAC)
2606 QString canonical = info.canonicalFilePath();
2607 #elif defined(Q_OS_WIN32)
2608 wchar_t buffer[1024];
2610 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2611 if (rv == 0 || rv >= 1024) return true;
2612 rv = ::GetLongPathName(buffer, buffer, 1024);
2613 if (rv == 0 || rv >= 1024) return true;
2615 QString canonical((QChar *)buffer);
2618 int absoluteLength = absolute.length();
2619 int canonicalLength = canonical.length();
2621 int length = qMin(absoluteLength, canonicalLength);
2622 for (int ii = 0; ii < length; ++ii) {
2623 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2624 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2626 if (a.toLower() != c.toLower())