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 \sa removeImageProvider()
801 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
803 Q_D(QDeclarativeEngine);
804 QMutexLocker locker(&d->mutex);
805 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
809 Returns the QDeclarativeImageProvider set for \a providerId.
811 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
813 Q_D(const QDeclarativeEngine);
814 QMutexLocker locker(&d->mutex);
815 return d->imageProviders.value(providerId).data();
819 Removes the QDeclarativeImageProvider for \a providerId.
821 Returns the provider if it was found; otherwise returns 0.
823 \sa addImageProvider()
825 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
827 Q_D(QDeclarativeEngine);
828 QMutexLocker locker(&d->mutex);
829 d->imageProviders.take(providerId);
832 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
834 QMutexLocker locker(&mutex);
835 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
838 return provider->imageType();
839 return QDeclarativeImageProvider::Invalid;
842 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
844 QMutexLocker locker(&mutex);
845 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
848 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
849 return provider->requestTexture(imageId, size, req_size);
854 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
856 QMutexLocker locker(&mutex);
858 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
861 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
862 image = provider->requestImage(imageId, size, req_size);
867 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
869 QMutexLocker locker(&mutex);
871 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
874 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
875 pixmap = provider->requestPixmap(imageId, size, req_size);
881 Return the base URL for this engine. The base URL is only used to
882 resolve components when a relative URL is passed to the
883 QDeclarativeComponent constructor.
885 If a base URL has not been explicitly set, this method returns the
886 application's current working directory.
890 QUrl QDeclarativeEngine::baseUrl() const
892 Q_D(const QDeclarativeEngine);
893 if (d->baseUrl.isEmpty()) {
894 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
901 Set the base URL for this engine to \a url.
905 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
907 Q_D(QDeclarativeEngine);
912 Returns true if warning messages will be output to stderr in addition
913 to being emitted by the warnings() signal, otherwise false.
915 The default value is true.
917 bool QDeclarativeEngine::outputWarningsToStandardError() const
919 Q_D(const QDeclarativeEngine);
920 return d->outputWarningsToStdErr;
924 Set whether warning messages will be output to stderr to \a enabled.
926 If \a enabled is true, any warning messages generated by QML will be
927 output to stderr and emitted by the warnings() signal. If \a enabled
928 is false, on the warnings() signal will be emitted. This allows
929 applications to handle warning output themselves.
931 The default value is true.
933 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
935 Q_D(QDeclarativeEngine);
936 d->outputWarningsToStdErr = enabled;
940 Returns the QDeclarativeContext for the \a object, or 0 if no
941 context has been set.
943 When the QDeclarativeEngine instantiates a QObject, the context is
946 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
951 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
953 QDeclarativeData *data =
954 static_cast<QDeclarativeData *>(priv->declarativeData);
958 else if (data->outerContext)
959 return data->outerContext->asQDeclarativeContext();
965 Sets the QDeclarativeContext for the \a object to \a context.
966 If the \a object already has a context, a warning is
967 output, but the context is not changed.
969 When the QDeclarativeEngine instantiates a QObject, the context is
972 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
974 if (!object || !context)
977 QDeclarativeData *data = QDeclarativeData::get(object, true);
979 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
983 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
984 contextData->addObject(object);
988 \enum QDeclarativeEngine::ObjectOwnership
990 Ownership controls whether or not QML automatically destroys the
991 QObject when the object is garbage collected by the JavaScript
992 engine. The two ownership options are:
994 \value CppOwnership The object is owned by C++ code, and will
995 never be deleted by QML. The JavaScript destroy() method cannot be
996 used on objects with CppOwnership. This option is similar to
997 QScriptEngine::QtOwnership.
999 \value JavaScriptOwnership The object is owned by JavaScript.
1000 When the object is returned to QML as the return value of a method
1001 call or property access, QML will delete the object if there are no
1002 remaining JavaScript references to it and it has no
1003 QObject::parent(). This option is similar to
1004 QScriptEngine::ScriptOwnership.
1006 Generally an application doesn't need to set an object's ownership
1007 explicitly. QML uses a heuristic to set the default object
1008 ownership. By default, an object that is created by QML has
1009 JavaScriptOwnership. The exception to this are the root objects
1010 created by calling QDeclarativeCompnent::create() or
1011 QDeclarativeComponent::beginCreate() which have CppOwnership by
1012 default. The ownership of these root-level objects is considered to
1013 have been transferred to the C++ caller.
1015 Objects not-created by QML have CppOwnership by default. The
1016 exception to this is objects returned from a C++ method call. The
1017 ownership of these objects is passed to JavaScript.
1019 Calling setObjectOwnership() overrides the default ownership
1020 heuristic used by QML.
1024 Sets the \a ownership of \a object.
1026 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1031 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1035 ddata->indestructible = (ownership == CppOwnership)?true:false;
1036 ddata->explicitIndestructibleSet = true;
1040 Returns the ownership of \a object.
1042 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1045 return CppOwnership;
1047 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1049 return CppOwnership;
1051 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1054 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1056 QDeclarativeData *data = QDeclarativeData::get(object);
1058 if (data && data->deferredComponent) {
1059 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1060 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1061 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1062 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1063 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1064 if (data->outerContext)
1065 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1067 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1069 QDeclarativeComponentPrivate::ConstructionState state;
1070 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1072 data->deferredComponent->release();
1073 data->deferredComponent = 0;
1075 QDeclarativeComponentPrivate::complete(ep, &state);
1076 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1080 QDeclarativeContext *qmlContext(const QObject *obj)
1082 return QDeclarativeEngine::contextForObject(obj);
1085 QDeclarativeEngine *qmlEngine(const QObject *obj)
1087 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1088 return context?context->engine():0;
1091 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1093 QDeclarativeData *data = QDeclarativeData::get(object);
1095 return 0; // Attached properties are only on objects created by QML
1097 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1101 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1105 rv = pf(const_cast<QObject *>(object));
1108 data->attachedProperties()->insert(id, rv);
1113 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1114 const QMetaObject *attachedMetaObject, bool create)
1117 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1119 if (*idCache == -1 || !object)
1122 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1125 class QDeclarativeDataExtended {
1127 QDeclarativeDataExtended();
1128 ~QDeclarativeDataExtended();
1130 QHash<int, QObject *> attachedProperties;
1131 QDeclarativeNotifier objectNameNotifier;
1134 QDeclarativeDataExtended::QDeclarativeDataExtended()
1138 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1142 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1144 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1145 return &extendedData->objectNameNotifier;
1148 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1150 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1151 return &extendedData->attachedProperties;
1154 void QDeclarativeData::destroyed(QObject *object)
1156 if (deferredComponent)
1157 deferredComponent->release();
1159 if (nextContextObject)
1160 nextContextObject->prevContextObject = prevContextObject;
1161 if (prevContextObject)
1162 *prevContextObject = nextContextObject;
1164 QDeclarativeAbstractBinding *binding = bindings;
1166 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1167 binding->m_prevBinding = 0;
1168 binding->m_nextBinding = 0;
1177 propertyCache->release();
1179 if (ownContext && context)
1183 QDeclarativeGuard<QObject> *guard = guards;
1184 *guard = (QObject *)0;
1185 guard->objectDestroyed(object);
1192 delete extendedData;
1198 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1200 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1203 void QDeclarativeData::objectNameChanged(QObject *)
1205 if (extendedData) objectNameNotifier()->notify();
1208 bool QDeclarativeData::hasBindingBit(int bit) const
1210 if (bindingBitsSize > bit)
1211 return bindingBits[bit / 32] & (1 << (bit % 32));
1216 void QDeclarativeData::clearBindingBit(int bit)
1218 if (bindingBitsSize > bit)
1219 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1222 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1224 if (bindingBitsSize <= bit) {
1225 int props = obj->metaObject()->propertyCount();
1226 Q_ASSERT(bit < props);
1228 int arraySize = (props + 31) / 32;
1229 int oldArraySize = bindingBitsSize / 32;
1231 bindingBits = (quint32 *)realloc(bindingBits,
1232 arraySize * sizeof(quint32));
1234 memset(bindingBits + oldArraySize,
1236 sizeof(quint32) * (arraySize - oldArraySize));
1238 bindingBitsSize = arraySize * 32;
1241 bindingBits[bit / 32] |= (1 << (bit % 32));
1245 Creates a QScriptValue allowing you to use \a object in QML script.
1246 \a engine is the QDeclarativeEngine it is to be created in.
1248 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1249 to the special needs of QML requiring more functionality than a standard
1252 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1253 QDeclarativeEngine* engine)
1255 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1256 return enginePriv->objectClass->newQObject(object);
1260 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1262 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1264 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1265 Q_ASSERT(scopeNode.isValid());
1266 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1267 return contextClass->contextFromValue(scopeNode);
1271 Returns the QUrl associated with the script \a ctxt for the case that there is
1272 no QDeclarativeContext.
1274 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1276 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1277 Q_ASSERT(scopeNode.isValid());
1278 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1279 return contextClass->urlFromValue(scopeNode);
1282 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1284 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1285 if (url.authority().isEmpty())
1286 return QLatin1Char(':') + url.path();
1289 return url.toLocalFile();
1293 \qmlmethod object Qt::createComponent(url)
1295 Returns a \l Component object created using the QML file at the specified \a url,
1296 or \c null if an empty string was given.
1298 The returned component's \l Component::status property indicates whether the
1299 component was successfully created. If the status is \c Component.Error,
1300 see \l Component::errorString() for an error description.
1302 Call \l {Component::createObject()}{Component.createObject()} on the returned
1303 component to create an object instance of the component.
1307 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1309 See \l {Dynamic Object Management in QML} for more information on using this function.
1311 To create a QML object from an arbitrary string of QML (instead of a file),
1312 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1315 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1317 QDeclarativeEnginePrivate *activeEnginePriv =
1318 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1319 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1321 if(ctxt->argumentCount() != 1) {
1322 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1325 QString arg = ctxt->argument(0).toString();
1327 return engine->nullValue();
1328 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1329 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1330 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1331 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1332 QDeclarativeData::get(c, true)->setImplicitDestructible();
1333 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1338 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1340 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1341 or \c null if there was an error in creating the object.
1343 If \a filepath is specified, it will be used for error reporting for the created object.
1345 Example (where \c parentItem is the id of an existing QML item):
1347 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1349 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1350 \c qmlErrors, which is an array of the errors encountered.
1351 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1352 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1353 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1355 Note that this function returns immediately, and therefore may not work if
1356 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1357 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1359 See \l {Dynamic Object Management in QML} for more information on using this function.
1362 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1364 QDeclarativeEnginePrivate *activeEnginePriv =
1365 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1366 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1368 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1369 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1371 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1374 QString qml = ctxt->argument(0).toString();
1376 return engine->nullValue();
1379 if(ctxt->argumentCount() > 2)
1380 url = QUrl(ctxt->argument(2).toString());
1382 url = QUrl(QLatin1String("inline"));
1384 if (url.isValid() && url.isRelative())
1385 url = context->resolvedUrl(url);
1387 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1389 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1391 QDeclarativeComponent component(activeEngine);
1392 component.setData(qml.toUtf8(), url);
1394 if(component.isError()) {
1395 QList<QDeclarativeError> errors = component.errors();
1396 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1397 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1399 foreach (const QDeclarativeError &error, errors){
1400 errstr += QLatin1String("\n ") + error.toString();
1401 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1402 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1403 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1404 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1405 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1406 arr.setProperty(i++, qmlErrObject);
1408 QScriptValue err = ctxt->throwError(errstr);
1409 err.setProperty(QLatin1String("qmlErrors"),arr);
1413 if (!component.isReady())
1414 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1416 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1418 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1419 component.completeCreate();
1421 if(component.isError()) {
1422 QList<QDeclarativeError> errors = component.errors();
1423 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1424 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1426 foreach (const QDeclarativeError &error, errors){
1427 errstr += QLatin1String("\n ") + error.toString();
1428 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1429 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1430 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1431 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1432 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1433 arr.setProperty(i++, qmlErrObject);
1435 QScriptValue err = ctxt->throwError(errstr);
1436 err.setProperty(QLatin1String("qmlErrors"),arr);
1442 obj->setParent(parentArg);
1444 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1445 for (int ii = 0; ii < functions.count(); ++ii) {
1446 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1450 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1451 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1455 \qmlmethod bool Qt::isQtObject(object)
1456 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1458 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1460 if (ctxt->argumentCount() == 0)
1461 return QScriptValue(engine, false);
1463 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1467 \qmlmethod Qt::vector3d(real x, real y, real z)
1468 Returns a Vector3D with the specified \c x, \c y and \c z.
1470 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1472 if(ctxt->argumentCount() != 3)
1473 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1474 qsreal x = ctxt->argument(0).toNumber();
1475 qsreal y = ctxt->argument(1).toNumber();
1476 qsreal z = ctxt->argument(2).toNumber();
1477 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1481 \qmlmethod string Qt::formatDate(datetime date, variant format)
1483 Returns a string representation of \c date, optionally formatted according
1486 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1487 property, a QDate, or QDateTime value. The \a format parameter may be any of
1488 the possible format values as described for
1489 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1491 If \a format is not specified, \a date is formatted using
1492 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1494 #ifndef QT_NO_DATESTRING
1495 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1497 int argCount = ctxt->argumentCount();
1498 if(argCount == 0 || argCount > 2)
1499 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1501 QDate date = ctxt->argument(0).toDateTime().date();
1502 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1503 if (argCount == 2) {
1504 QScriptValue formatArg = ctxt->argument(1);
1505 if (formatArg.isString()) {
1506 QString format = formatArg.toString();
1507 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1508 } else if (formatArg.isNumber()) {
1509 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1511 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1514 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1518 \qmlmethod string Qt::formatTime(datetime time, variant format)
1520 Returns a string representation of \c time, optionally formatted according to
1523 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1524 value. The \a format parameter may be any of the possible format values as
1525 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1527 If \a format is not specified, \a time is formatted using
1528 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1530 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1532 int argCount = ctxt->argumentCount();
1533 if(argCount == 0 || argCount > 2)
1534 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1537 QScriptValue sv = ctxt->argument(0);
1539 time = sv.toDateTime().time();
1540 else if (sv.toVariant().type() == QVariant::Time)
1541 time = sv.toVariant().toTime();
1543 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1544 if (argCount == 2) {
1545 QScriptValue formatArg = ctxt->argument(1);
1546 if (formatArg.isString()) {
1547 QString format = formatArg.toString();
1548 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1549 } else if (formatArg.isNumber()) {
1550 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1552 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1555 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1559 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1561 Returns a string representation of \c datetime, optionally formatted according to
1564 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1565 property, a QDate, QTime, or QDateTime value.
1567 If \a format is not provided, \a dateTime is formatted using
1568 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1569 \a format should be either.
1572 \o One of the Qt::DateFormat enumeration values, such as
1573 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1574 \o A string that specifies the format of the returned string, as detailed below.
1577 If \a format specifies a format string, it should use the following expressions
1578 to specify the date:
1581 \header \i Expression \i Output
1582 \row \i d \i the day as number without a leading zero (1 to 31)
1583 \row \i dd \i the day as number with a leading zero (01 to 31)
1585 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1586 Uses QDate::shortDayName().
1588 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1589 Uses QDate::longDayName().
1590 \row \i M \i the month as number without a leading zero (1-12)
1591 \row \i MM \i the month as number with a leading zero (01-12)
1593 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1594 Uses QDate::shortMonthName().
1596 \i the long localized month name (e.g. 'January' to 'December').
1597 Uses QDate::longMonthName().
1598 \row \i yy \i the year as two digit number (00-99)
1599 \row \i yyyy \i the year as four digit number
1602 In addition the following expressions can be used to specify the time:
1605 \header \i Expression \i Output
1607 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1609 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1610 \row \i m \i the minute without a leading zero (0 to 59)
1611 \row \i mm \i the minute with a leading zero (00 to 59)
1612 \row \i s \i the second without a leading zero (0 to 59)
1613 \row \i ss \i the second with a leading zero (00 to 59)
1614 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1615 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1617 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1619 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1622 All other input characters will be ignored. Any sequence of characters that
1623 are enclosed in single quotes will be treated as text and not be used as an
1624 expression. Two consecutive single quotes ("''") are replaced by a single quote
1627 For example, if the following date/time value was specified:
1630 // 21 May 2001 14:13:09
1631 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1634 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1635 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1636 with the \a format values below to produce the following results:
1639 \header \i Format \i Result
1640 \row \i "dd.MM.yyyy" \i 21.05.2001
1641 \row \i "ddd MMMM d yy" \i Tue May 21 01
1642 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1643 \row \i "h:m:s ap" \i 2:13:9 pm
1646 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1648 int argCount = ctxt->argumentCount();
1649 if(argCount == 0 || argCount > 2)
1650 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1652 QDateTime date = ctxt->argument(0).toDateTime();
1653 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1654 if (argCount == 2) {
1655 QScriptValue formatArg = ctxt->argument(1);
1656 if (formatArg.isString()) {
1657 QString format = formatArg.toString();
1658 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1659 } else if (formatArg.isNumber()) {
1660 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1662 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1665 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1667 #endif // QT_NO_DATESTRING
1670 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1672 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1673 All components should be in the range 0-1 inclusive.
1675 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1677 int argCount = ctxt->argumentCount();
1678 if(argCount < 3 || argCount > 4)
1679 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1680 qsreal r = ctxt->argument(0).toNumber();
1681 qsreal g = ctxt->argument(1).toNumber();
1682 qsreal b = ctxt->argument(2).toNumber();
1683 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1694 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1698 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1700 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1701 All components should be in the range 0-1 inclusive.
1703 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1705 int argCount = ctxt->argumentCount();
1706 if(argCount < 3 || argCount > 4)
1707 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1708 qsreal h = ctxt->argument(0).toNumber();
1709 qsreal s = ctxt->argument(1).toNumber();
1710 qsreal l = ctxt->argument(2).toNumber();
1711 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1722 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1726 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1728 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1730 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1732 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1734 if(ctxt->argumentCount() != 4)
1735 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1737 qsreal x = ctxt->argument(0).toNumber();
1738 qsreal y = ctxt->argument(1).toNumber();
1739 qsreal w = ctxt->argument(2).toNumber();
1740 qsreal h = ctxt->argument(3).toNumber();
1742 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1746 \qmlmethod point Qt::point(int x, int y)
1747 Returns a Point with the specified \c x and \c y coordinates.
1749 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1751 if(ctxt->argumentCount() != 2)
1752 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1753 qsreal x = ctxt->argument(0).toNumber();
1754 qsreal y = ctxt->argument(1).toNumber();
1755 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1759 \qmlmethod Qt::size(int width, int height)
1760 Returns a Size with the specified \c width and \c height.
1762 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1764 if(ctxt->argumentCount() != 2)
1765 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1766 qsreal w = ctxt->argument(0).toNumber();
1767 qsreal h = ctxt->argument(1).toNumber();
1768 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1772 \qmlmethod color Qt::lighter(color baseColor, real factor)
1773 Returns a color lighter than \c baseColor by the \c factor provided.
1775 If the factor is greater than 1.0, this functions returns a lighter color.
1776 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1777 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1778 If the factor is 0 or negative, the return value is unspecified.
1780 The function converts the current RGB color to HSV, multiplies the value (V) component
1781 by factor and converts the color back to RGB.
1783 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1785 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1787 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1788 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1789 QVariant v = ctxt->argument(0).toVariant();
1791 if (v.userType() == QVariant::Color)
1792 color = v.value<QColor>();
1793 else if (v.userType() == QVariant::String) {
1795 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1797 return engine->nullValue();
1799 return engine->nullValue();
1800 qsreal factor = 1.5;
1801 if (ctxt->argumentCount() == 2)
1802 factor = ctxt->argument(1).toNumber();
1803 color = color.lighter(int(qRound(factor*100.)));
1804 return engine->toScriptValue(QVariant::fromValue(color));
1808 \qmlmethod color Qt::darker(color baseColor, real factor)
1809 Returns a color darker than \c baseColor by the \c factor provided.
1811 If the factor is greater than 1.0, this function returns a darker color.
1812 Setting factor to 3.0 returns a color that has one-third the brightness.
1813 If the factor is less than 1.0, the return color is lighter, but we recommend using
1814 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1815 value is unspecified.
1817 The function converts the current RGB color to HSV, divides the value (V) component
1818 by factor and converts the color back to RGB.
1820 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1822 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1824 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1825 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1826 QVariant v = ctxt->argument(0).toVariant();
1828 if (v.userType() == QVariant::Color)
1829 color = v.value<QColor>();
1830 else if (v.userType() == QVariant::String) {
1832 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1834 return engine->nullValue();
1836 return engine->nullValue();
1837 qsreal factor = 2.0;
1838 if (ctxt->argumentCount() == 2)
1839 factor = ctxt->argument(1).toNumber();
1840 color = color.darker(int(qRound(factor*100.)));
1841 return engine->toScriptValue(QVariant::fromValue(color));
1845 \qmlmethod bool Qt::openUrlExternally(url target)
1846 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.
1848 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1850 if(ctxt->argumentCount() < 1)
1851 return QScriptValue(e, false);
1853 #ifndef QT_NO_DESKTOPSERVICES
1854 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1856 return QScriptValue(e, ret);
1860 \qmlmethod list<string> Qt::fontFamilies()
1861 Returns a list of the font families available to the application.
1864 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1866 if(ctxt->argumentCount() != 0)
1867 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1869 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1870 QFontDatabase database;
1871 return p->scriptValueFromVariant(database.families());
1875 \qmlmethod string Qt::md5(data)
1876 Returns a hex string of the md5 hash of \c data.
1878 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1880 if (ctxt->argumentCount() != 1)
1881 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1883 QByteArray data = ctxt->argument(0).toString().toUtf8();
1884 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1886 return QScriptValue(QLatin1String(result.toHex()));
1890 \qmlmethod string Qt::btoa(data)
1891 Binary to ASCII - this function returns a base64 encoding of \c data.
1893 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1895 if (ctxt->argumentCount() != 1)
1896 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1898 QByteArray data = ctxt->argument(0).toString().toUtf8();
1900 return QScriptValue(QLatin1String(data.toBase64()));
1904 \qmlmethod string Qt::atob(data)
1905 ASCII to binary - this function returns a base64 decoding of \c data.
1908 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1910 if (ctxt->argumentCount() != 1)
1911 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1913 QByteArray data = ctxt->argument(0).toString().toUtf8();
1915 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1918 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1920 if(ctxt->argumentCount() < 1)
1921 return e->newVariant(QVariant(false));
1925 for (int i=0; i<ctxt->argumentCount(); ++i) {
1926 if (!msg.isEmpty()) msg += ' ';
1927 msg += ctxt->argument(i).toString().toLocal8Bit();
1928 // does not support firebug "%[a-z]" formatting, since firebug really
1929 // does just ignore the format letter, which makes it pointless.
1932 qDebug("%s",msg.constData());
1934 return e->newVariant(QVariant(true));
1937 void QDeclarativeEnginePrivate::sendQuit()
1939 Q_Q(QDeclarativeEngine);
1941 if (q->receivers(SIGNAL(quit())) == 0) {
1942 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1946 static void dumpwarning(const QDeclarativeError &error)
1948 qWarning().nospace() << qPrintable(error.toString());
1951 static void dumpwarning(const QList<QDeclarativeError> &errors)
1953 for (int ii = 0; ii < errors.count(); ++ii)
1954 dumpwarning(errors.at(ii));
1957 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1959 Q_Q(QDeclarativeEngine);
1960 q->warnings(QList<QDeclarativeError>() << error);
1961 if (outputWarningsToStdErr)
1965 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1967 Q_Q(QDeclarativeEngine);
1968 q->warnings(errors);
1969 if (outputWarningsToStdErr)
1970 dumpwarning(errors);
1973 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1976 QDeclarativeEnginePrivate::get(engine)->warning(error);
1981 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1984 QDeclarativeEnginePrivate::get(engine)->warning(error);
1989 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1992 engine->warning(error);
1997 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2000 engine->warning(error);
2006 \qmlmethod Qt::quit()
2007 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2008 Within the \l {QML Viewer}, this causes the launcher application to exit;
2009 to quit a C++ application when this method is called, connect the
2010 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2013 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2015 QDeclarativeEnginePrivate *qe = get (e);
2017 return QScriptValue();
2021 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2022 This function allows tinting one color with another.
2024 The tint color should usually be mostly transparent, or you will not be
2025 able to see the underlying color. The below example provides a slight red
2026 tint by having the tint color be pure red which is only 1/16th opaque.
2031 x: 0; width: 80; height: 80
2032 color: "lightsteelblue"
2035 x: 100; width: 80; height: 80
2036 color: Qt.tint("lightsteelblue", "#10FF0000")
2040 \image declarative-rect_tint.png
2042 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.
2044 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2046 if(ctxt->argumentCount() != 2)
2047 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2049 QVariant v = ctxt->argument(0).toVariant();
2051 if (v.userType() == QVariant::Color)
2052 color = v.value<QColor>();
2053 else if (v.userType() == QVariant::String) {
2055 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2057 return engine->nullValue();
2059 return engine->nullValue();
2062 v = ctxt->argument(1).toVariant();
2064 if (v.userType() == QVariant::Color)
2065 tintColor = v.value<QColor>();
2066 else if (v.userType() == QVariant::String) {
2068 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2070 return engine->nullValue();
2072 return engine->nullValue();
2076 int a = tintColor.alpha();
2078 finalColor = tintColor;
2082 qreal a = tintColor.alphaF();
2083 qreal inv_a = 1.0 - a;
2085 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2086 tintColor.greenF() * a + color.greenF() * inv_a,
2087 tintColor.blueF() * a + color.blueF() * inv_a,
2088 a + inv_a * color.alphaF());
2091 return engine->toScriptValue(QVariant::fromValue(finalColor));
2094 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2096 if (variantIsScarceResource(val)) {
2097 return scarceResourceClass->newScarceResource(val);
2098 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2099 QDeclarativeListReferencePrivate *p =
2100 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2102 return listClass->newList(p->property, p->propertyType);
2104 return scriptEngine.nullValue();
2106 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2107 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2108 QScriptValue rv = scriptEngine.newArray(list.count());
2109 for (int ii = 0; ii < list.count(); ++ii) {
2110 QObject *object = list.at(ii);
2111 rv.setProperty(ii, objectClass->newQObject(object));
2114 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2115 return valueTypeClass->newObject(val, vt);
2119 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2121 return objectClass->newQObject(obj);
2123 return scriptEngine.toScriptValue(val);
2128 If the variant is a scarce resource (consumes a large amount of memory, or
2129 only a limited number of them can be held in memory at any given time without
2130 exhausting supply for future use) we need to release the scarce resource
2131 after evaluation of the javascript binding is complete.
2133 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2135 if (val.type() == QVariant::Pixmap) {
2137 } else if (val.type() == QVariant::Image) {
2145 This function should be called prior to evaluation of any js expression,
2146 so that scarce resources are not freed prematurely (eg, if there is a
2147 nested javascript expression).
2149 void QDeclarativeEnginePrivate::referenceScarceResources()
2151 scarceResourcesRefCount += 1;
2155 This function should be called after evaluation of the js expression is
2156 complete, and so the scarce resources may be freed safely.
2158 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2160 Q_ASSERT(scarceResourcesRefCount > 0);
2161 scarceResourcesRefCount -= 1;
2163 // if the refcount is zero, then evaluation of the "top level"
2164 // expression must have completed. We can safely release the
2165 // scarce resources.
2166 if (scarceResourcesRefCount == 0) {
2167 // iterate through the list and release them all.
2168 // note that the actual SRD is owned by the JS engine,
2169 // so we cannot delete the SRD; but we can free the
2170 // memory used by the variant in the SRD.
2171 ScarceResourceData *srd = 0;
2172 while (scarceResources) {
2173 srd = scarceResources; // srd points to the "old" (current) head of the list
2174 scarceResources = srd->next; // srd->next is the "new" head of the list
2175 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2178 srd->releaseResource(); // release the old head node.
2183 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2185 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2186 if (dc == objectClass)
2187 return QVariant::fromValue(objectClass->toQObject(val));
2188 else if (dc == scarceResourceClass)
2189 return scarceResourceClass->toVariant(val);
2190 else if (dc == valueTypeClass)
2191 return valueTypeClass->toVariant(val);
2192 else if (dc == contextClass)
2195 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2196 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2197 QList<QObject *> list;
2198 int length = val.property(QLatin1String("length")).toInt32();
2199 for (int ii = 0; ii < length; ++ii) {
2200 QScriptValue arrayItem = val.property(ii);
2201 QObject *d = arrayItem.toQObject();
2204 return QVariant::fromValue(list);
2207 return val.toVariant();
2211 Adds \a path as a directory where the engine searches for
2212 installed modules in a URL-based directory structure.
2213 The \a path may be a local filesystem directory or a URL.
2215 The newly added \a path will be first in the importPathList().
2217 \sa setImportPathList(), {QML Modules}
2219 void QDeclarativeEngine::addImportPath(const QString& path)
2221 Q_D(QDeclarativeEngine);
2222 d->importDatabase.addImportPath(path);
2226 Returns the list of directories where the engine searches for
2227 installed modules in a URL-based directory structure.
2229 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2230 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2231 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2232 provided by that module. A \c qmldir file is required for defining the
2233 type version mapping and possibly declarative extensions plugins.
2235 By default, the list contains the directory of the application executable,
2236 paths specified in the \c QML_IMPORT_PATH environment variable,
2237 and the builtin \c ImportsPath from QLibraryInfo.
2239 \sa addImportPath() setImportPathList()
2241 QStringList QDeclarativeEngine::importPathList() const
2243 Q_D(const QDeclarativeEngine);
2244 return d->importDatabase.importPathList();
2248 Sets \a paths as the list of directories where the engine searches for
2249 installed modules in a URL-based directory structure.
2251 By default, the list contains the directory of the application executable,
2252 paths specified in the \c QML_IMPORT_PATH environment variable,
2253 and the builtin \c ImportsPath from QLibraryInfo.
2255 \sa importPathList() addImportPath()
2257 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2259 Q_D(QDeclarativeEngine);
2260 d->importDatabase.setImportPathList(paths);
2265 Adds \a path as a directory where the engine searches for
2266 native plugins for imported modules (referenced in the \c qmldir file).
2268 By default, the list contains only \c ., i.e. the engine searches
2269 in the directory of the \c qmldir file itself.
2271 The newly added \a path will be first in the pluginPathList().
2273 \sa setPluginPathList()
2275 void QDeclarativeEngine::addPluginPath(const QString& path)
2277 Q_D(QDeclarativeEngine);
2278 d->importDatabase.addPluginPath(path);
2283 Returns the list of directories where the engine searches for
2284 native plugins for imported modules (referenced in the \c qmldir file).
2286 By default, the list contains only \c ., i.e. the engine searches
2287 in the directory of the \c qmldir file itself.
2289 \sa addPluginPath() setPluginPathList()
2291 QStringList QDeclarativeEngine::pluginPathList() const
2293 Q_D(const QDeclarativeEngine);
2294 return d->importDatabase.pluginPathList();
2298 Sets the list of directories where the engine searches for
2299 native plugins for imported modules (referenced in the \c qmldir file)
2302 By default, the list contains only \c ., i.e. the engine searches
2303 in the directory of the \c qmldir file itself.
2305 \sa pluginPathList() addPluginPath()
2307 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2309 Q_D(QDeclarativeEngine);
2310 d->importDatabase.setPluginPathList(paths);
2315 Imports the plugin named \a filePath with the \a uri provided.
2316 Returns true if the plugin was successfully imported; otherwise returns false.
2318 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2320 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2322 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2324 Q_D(QDeclarativeEngine);
2325 return d->importDatabase.importPlugin(filePath, uri, errors);
2329 Imports the plugin named \a filePath with the \a uri provided.
2330 Returns true if the plugin was successfully imported; otherwise returns false.
2332 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2334 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2336 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2338 Q_D(QDeclarativeEngine);
2339 QList<QDeclarativeError> errors;
2340 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2341 if (!errors.isEmpty()) {
2343 for (int i = 0; i < errors.size(); ++i) {
2344 builtError = QString(QLatin1String("%1\n %2"))
2346 .arg(errors.at(i).toString());
2348 *errorString = builtError;
2354 \property QDeclarativeEngine::offlineStoragePath
2355 \brief the directory for storing offline user data
2357 Returns the directory where SQL and other offline
2360 QDeclarativeWebView and the SQL databases created with openDatabase()
2363 The default is QML/OfflineStorage in the platform-standard
2364 user application data directory.
2366 Note that the path may not currently exist on the filesystem, so
2367 callers wanting to \e create new files at this location should create
2368 it first - see QDir::mkpath().
2370 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2372 Q_D(QDeclarativeEngine);
2373 d->scriptEngine.offlineStoragePath = dir;
2376 QString QDeclarativeEngine::offlineStoragePath() const
2378 Q_D(const QDeclarativeEngine);
2379 return d->scriptEngine.offlineStoragePath;
2382 static void voidptr_destructor(void *v)
2384 void **ptr = (void **)v;
2388 static void *voidptr_constructor(const void *v)
2393 return new void*(*(void **)v);
2397 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2399 Q_Q(QDeclarativeEngine);
2401 if (!mo->superClass()) {
2402 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2403 propertyCache.insert(mo, rv);
2406 QDeclarativePropertyCache *super = cache(mo->superClass());
2407 QDeclarativePropertyCache *rv = super->copy();
2409 propertyCache.insert(mo, rv);
2414 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2415 QDeclarativeError &error)
2417 QList<QDeclarativeType *> types;
2419 int maxMinorVersion = 0;
2421 const QMetaObject *metaObject = type->metaObject();
2422 while (metaObject) {
2423 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2424 type->majorVersion(), minorVersion);
2426 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2432 metaObject = metaObject->superClass();
2435 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2437 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2441 QDeclarativePropertyCache *raw = cache(type->metaObject());
2443 bool hasCopied = false;
2445 for (int ii = 0; ii < types.count(); ++ii) {
2446 QDeclarativeType *currentType = types.at(ii);
2450 int rev = currentType->metaObjectRevision();
2451 int moIndex = types.count() - 1 - ii;
2453 if (raw->allowedRevisionCache[moIndex] != rev) {
2458 raw->allowedRevisionCache[moIndex] = rev;
2462 // Test revision compatibility - the basic rule is:
2463 // * Anything that is excluded, cannot overload something that is not excluded *
2465 // Signals override:
2466 // * other signals and methods of the same name.
2467 // * properties named on<Signal Name>
2468 // * automatic <property name>Changed notify signals
2470 // Methods override:
2471 // * other methods of the same name
2473 // Properties override:
2474 // * other elements of the same name
2476 bool overloadError = false;
2477 QString overloadName;
2480 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2481 !overloadError && iter != raw->stringCache.end();
2484 QDeclarativePropertyCache::Data *d = *iter;
2485 if (raw->isAllowedInRevision(d))
2486 continue; // Not excluded - no problems
2488 // check that a regular "name" overload isn't happening
2489 QDeclarativePropertyCache::Data *current = d;
2490 while (!overloadError && current) {
2491 current = d->overrideData(current);
2492 if (current && raw->isAllowedInRevision(current))
2493 overloadError = true;
2498 if (overloadError) {
2499 if (hasCopied) raw->release();
2501 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."));
2505 if (!hasCopied) raw->addref();
2506 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2508 if (minorVersion != maxMinorVersion) {
2510 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2516 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2518 QByteArray name = data->root->className();
2520 QByteArray ptr = name + '*';
2521 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2523 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2524 voidptr_constructor);
2525 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2526 voidptr_constructor);
2528 m_qmlLists.insert(lst_type, ptr_type);
2529 m_compositeTypes.insert(ptr_type, data);
2533 bool QDeclarativeEnginePrivate::isList(int t) const
2535 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2538 int QDeclarativeEnginePrivate::listType(int t) const
2540 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2541 if (iter != m_qmlLists.end())
2544 return QDeclarativeMetaType::listType(t);
2547 bool QDeclarativeEnginePrivate::isQObject(int t)
2549 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2552 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2554 int t = v.userType();
2555 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2557 return *(QObject **)(v.constData());
2559 return QDeclarativeMetaType::toQObject(v, ok);
2563 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2565 if (m_compositeTypes.contains(t))
2566 return QDeclarativeMetaType::Object;
2567 else if (m_qmlLists.contains(t))
2568 return QDeclarativeMetaType::List;
2570 return QDeclarativeMetaType::typeCategory(t);
2573 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2575 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2576 if (iter != m_compositeTypes.end()) {
2577 return (*iter)->root;
2579 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2580 return type?type->baseMetaObject():0;
2584 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2586 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2587 if (iter != m_compositeTypes.end()) {
2588 return (*iter)->root;
2590 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2591 return type?type->metaObject():0;
2595 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2597 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2598 QFileInfo info(fileName);
2600 QString absolute = info.absoluteFilePath();
2602 #if defined(Q_OS_MAC)
2603 QString canonical = info.canonicalFilePath();
2604 #elif defined(Q_OS_WIN32)
2605 wchar_t buffer[1024];
2607 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2608 if (rv == 0 || rv >= 1024) return true;
2609 rv = ::GetLongPathName(buffer, buffer, 1024);
2610 if (rv == 0 || rv >= 1024) return true;
2612 QString canonical((QChar *)buffer);
2615 int absoluteLength = absolute.length();
2616 int canonicalLength = canonical.length();
2618 int length = qMin(absoluteLength, canonicalLength);
2619 for (int ii = 0; ii < length; ++ii) {
2620 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2621 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2623 if (a.toLower() != c.toLower())