1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativeengine_p.h"
43 #include "qdeclarativeengine.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativecompiler_p.h"
47 #include "private/qdeclarativeglobalscriptclass_p.h"
48 #include "qdeclarative.h"
49 #include "qdeclarativecontext.h"
50 #include "qdeclarativeexpression.h"
51 #include "qdeclarativecomponent.h"
52 #include "private/qdeclarativebinding_p_p.h"
53 #include "private/qdeclarativevme_p.h"
54 #include "private/qdeclarativeenginedebug_p.h"
55 #include "private/qdeclarativestringconverters_p.h"
56 #include "private/qdeclarativexmlhttprequest_p.h"
57 #include "private/qdeclarativesqldatabase_p.h"
58 #include "private/qdeclarativescarceresourcescriptclass_p.h"
59 #include "private/qdeclarativetypenamescriptclass_p.h"
60 #include "private/qdeclarativelistscriptclass_p.h"
61 #include "qdeclarativescriptstring.h"
62 #include "private/qdeclarativeglobal_p.h"
63 #include "private/qdeclarativeworkerscript_p.h"
64 #include "private/qdeclarativecomponent_p.h"
65 #include "qdeclarativenetworkaccessmanagerfactory.h"
66 #include "qdeclarativeimageprovider.h"
67 #include "private/qdeclarativedirparser_p.h"
68 #include "qdeclarativeextensioninterface.h"
69 #include "private/qdeclarativelist_p.h"
70 #include "private/qdeclarativetypenamecache_p.h"
71 #include "private/qdeclarativeinclude_p.h"
72 #include "private/qdeclarativenotifier_p.h"
73 #include "private/qdeclarativedebugtrace_p.h"
74 #include "private/qdeclarativeapplication_p.h"
76 #include <QtCore/qmetaobject.h>
77 #include <QScriptClass>
78 #include <QNetworkReply>
79 #include <QNetworkRequest>
80 #include <QNetworkAccessManager>
81 #include <QDesktopServices>
86 #include <QMetaObject>
89 #include <QPluginLoader>
90 #include <QtGui/qfontdatabase.h>
91 #include <QtCore/qlibraryinfo.h>
92 #include <QtCore/qthreadstorage.h>
93 #include <QtCore/qthread.h>
94 #include <QtCore/qcoreapplication.h>
95 #include <QtCore/qdir.h>
96 #include <QtCore/qmutex.h>
97 #include <QtGui/qcolor.h>
98 #include <QtGui/qvector3d.h>
99 #include <QtGui/qsound.h>
100 #include <QtCore/qcryptographichash.h>
102 #include <private/qobject_p.h>
103 #include <private/qscriptdeclarativeclass_p.h>
105 #include <private/qdeclarativeitemsmodule_p.h>
106 #include <private/qdeclarativeutilmodule_p.h>
107 #include <private/qsgitemsmodule_p.h>
108 #include <qsgtexture.h>
110 #ifdef Q_OS_WIN // for %APPDATA%
111 #include <qt_windows.h>
112 #include <qlibrary.h>
115 #define CSIDL_APPDATA 0x001a // <username>\Application Data
118 Q_DECLARE_METATYPE(QDeclarativeProperty)
123 \qmlclass QtObject QObject
124 \ingroup qml-utility-elements
126 \brief The QtObject element is the most basic element in QML.
128 The QtObject element is a non-visual element which contains only the
131 It can be useful to create a QtObject if you need an extremely
132 lightweight element to enclose a set of custom properties:
134 \snippet doc/src/snippets/declarative/qtobject.qml 0
136 It can also be useful for C++ integration, as it is just a plain
137 QObject. See the QObject documentation for further details.
140 \qmlproperty string QML:QtObject::objectName
141 This property holds the QObject::objectName for this specific object instance.
143 This allows a C++ application to locate an item within a QML component
144 using the QObject::findChild() method. For example, the following C++
145 application locates the child \l Rectangle item and dynamically changes its
154 width: 200; height: 200
167 QDeclarativeView view;
168 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
171 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
173 item->setProperty("color", QColor(Qt::yellow));
177 struct StaticQtMetaObject : public QObject
179 static const QMetaObject *get()
180 { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
183 static bool qt_QmlQtModule_registered = false;
184 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
186 void QDeclarativeEnginePrivate::defineModule()
188 qmlRegisterType<QDeclarativeComponent>("QtQuick",1,0,"Component");
189 qmlRegisterType<QObject>("QtQuick",1,0,"QtObject");
190 qmlRegisterType<QDeclarativeWorkerScript>("QtQuick",1,0,"WorkerScript");
192 #ifndef QT_NO_IMPORT_QT47_QML
193 qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
194 qmlRegisterType<QObject>("Qt",4,7,"QtObject");
195 qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
198 qmlRegisterType<QDeclarativeBinding>();
202 \qmlclass QML:Qt QDeclarativeEnginePrivate
203 \ingroup qml-utility-elements
204 \brief The QML global Qt object provides useful enums and functions from Qt.
206 \keyword QmlGlobalQtObject
208 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
210 The \c Qt object is a global object with utility functions, properties and enums.
212 It is not instantiable; to use it, call the members of the global \c Qt object directly.
219 color: Qt.rgba(1, 0, 0, 1)
220 text: Qt.md5("hello, world")
227 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
228 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
232 The Qt object also contains helper functions for creating objects of specific
233 data types. This is primarily useful when setting the properties of an item
234 when the property has one of the following types:
237 \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()}
238 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
239 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
240 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
241 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
244 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
246 \section1 Date/Time Formatters
248 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
251 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
252 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
253 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
256 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
259 \section1 Dynamic Object Creation
260 The following functions on the global object allow you to dynamically create QML
261 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
265 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
266 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
272 \qmlproperty object QML:Qt::application
275 The \c application object provides access to global application state
276 properties shared by many QML components.
282 \o \c application.active
284 This read-only property indicates whether the application is the top-most and focused
285 application, and the user is able to interact with the application. The property
286 is false when the application is in the background, the device keylock or screen
287 saver is active, the screen backlight is turned off, or the global system dialog
288 is being displayed on top of the application. It can be used for stopping and
289 pausing animations, timers and active processing of data in order to save device
290 battery power and free device memory and processor load when the application is not
294 \o \c application.layoutDirection
296 This read-only property can be used to query the default layout direction of the
297 application. On system start-up, the default layout direction depends on the
298 application's language. The property has a value of \c Qt.RightToLeft in locales
299 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
300 where the reading direction flows from left to right. You can bind to this
301 property to customize your application layouts to support both layout directions.
306 \o Qt.LeftToRight - Text and graphics elements should be positioned
308 \o Qt.RightToLeft - Text and graphics elements should be positioned
313 The following example uses the \c application object to indicate
314 whether the application is currently active:
316 \snippet doc/src/snippets/declarative/application.qml document
322 \qmlmethod object Qt::include(string url, jsobject callback)
324 Includes another JavaScript file. This method can only be used from within JavaScript files,
325 and not regular QML files.
327 This imports all functions from \a url into the current script's namespace.
329 Qt.include() returns an object that describes the status of the operation. The object has
330 a single property, \c {status}, that is set to one of the following values:
333 \header \o Symbol \o Value \o Description
334 \row \o result.OK \o 0 \o The include completed successfully.
335 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
336 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
337 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
338 An additional \c exception property will be set in this case.
341 The \c status property will be updated as the operation progresses.
343 If provided, \a callback is invoked when the operation completes. The callback is passed
344 the same object as is returned from the Qt.include() call.
346 // Qt.include() is implemented in qdeclarativeinclude.cpp
349 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
350 : captureProperties(false), rootContext(0), isDebugging(false),
351 outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
352 objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
353 inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
354 inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
355 scarceResources(0), scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
358 if (!qt_QmlQtModule_registered) {
359 qt_QmlQtModule_registered = true;
360 QDeclarativeItemModule::defineModule();
361 QDeclarativeUtilModule::defineModule();
362 QDeclarativeEnginePrivate::defineModule();
363 QSGItemsModule::defineModule();
364 QDeclarativeValueTypeFactory::registerValueTypes();
366 globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine);
370 \qmlmethod url Qt::resolvedUrl(url url)
371 Returns \a url resolved relative to the URL of the caller.
373 QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
376 QDeclarativeContextData *ctxt = p->getContext(context);
378 return ctxt->resolvedUrl(url);
380 return p->getUrl(context).resolved(url);
382 return baseUrl.resolved(url);
385 QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
386 : p(priv), sqlQueryClass(0), namedNodeMapClass(0), nodeListClass(0)
388 // Note that all documentation for stuff put on the global object goes in
389 // doc/src/declarative/globalobject.qdoc
391 bool mainthread = priv != 0;
393 QScriptValue qtObject =
394 newQMetaObject(StaticQtMetaObject::get());
395 globalObject().setProperty(QLatin1String("Qt"), qtObject);
397 #ifndef QT_NO_DESKTOPSERVICES
398 offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator())
399 + QDir::separator() + QLatin1String("QML")
400 + QDir::separator() + QLatin1String("OfflineStorage");
403 #ifndef QT_NO_XMLSTREAMREADER
404 qt_add_qmlxmlhttprequest(this);
406 qt_add_qmlsqldatabase(this);
407 // XXX A Multimedia "Qt.Sound" class also needs to be made available,
408 // XXX but we don't want a dependency in that cirection.
409 // XXX When the above a done some better way, that way should also be
410 // XXX used to add Qt.Sound class.
414 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::include, 2));
416 qtObject.setProperty(QLatin1String("include"), newFunction(QDeclarativeInclude::worker_include, 2));
418 qtObject.setProperty(QLatin1String("isQtObject"), newFunction(QDeclarativeEnginePrivate::isQtObject, 1));
419 qtObject.setProperty(QLatin1String("rgba"), newFunction(QDeclarativeEnginePrivate::rgba, 4));
420 qtObject.setProperty(QLatin1String("hsla"), newFunction(QDeclarativeEnginePrivate::hsla, 4));
421 qtObject.setProperty(QLatin1String("rect"), newFunction(QDeclarativeEnginePrivate::rect, 4));
422 qtObject.setProperty(QLatin1String("point"), newFunction(QDeclarativeEnginePrivate::point, 2));
423 qtObject.setProperty(QLatin1String("size"), newFunction(QDeclarativeEnginePrivate::size, 2));
424 qtObject.setProperty(QLatin1String("vector3d"), newFunction(QDeclarativeEnginePrivate::vector3d, 3));
428 qtObject.setProperty(QLatin1String("lighter"), newFunction(QDeclarativeEnginePrivate::lighter, 1));
429 qtObject.setProperty(QLatin1String("darker"), newFunction(QDeclarativeEnginePrivate::darker, 1));
430 qtObject.setProperty(QLatin1String("tint"), newFunction(QDeclarativeEnginePrivate::tint, 2));
433 #ifndef QT_NO_DATESTRING
434 //date/time formatting
435 qtObject.setProperty(QLatin1String("formatDate"),newFunction(QDeclarativeEnginePrivate::formatDate, 2));
436 qtObject.setProperty(QLatin1String("formatTime"),newFunction(QDeclarativeEnginePrivate::formatTime, 2));
437 qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2));
441 qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1));
442 qtObject.setProperty(QLatin1String("fontFamilies"),newFunction(QDeclarativeEnginePrivate::fontFamilies, 0));
443 qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1));
444 qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1));
445 qtObject.setProperty(QLatin1String("atob"),newFunction(QDeclarativeEnginePrivate::atob, 1));
446 qtObject.setProperty(QLatin1String("quit"), newFunction(QDeclarativeEnginePrivate::quit, 0));
447 qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QDeclarativeScriptEngine::resolvedUrl, 1));
450 qtObject.setProperty(QLatin1String("createQmlObject"),
451 newFunction(QDeclarativeEnginePrivate::createQmlObject, 1));
452 qtObject.setProperty(QLatin1String("createComponent"),
453 newFunction(QDeclarativeEnginePrivate::createComponent, 1));
456 //firebug/webkit compat
457 QScriptValue consoleObject = newObject();
458 consoleObject.setProperty(QLatin1String("log"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
459 consoleObject.setProperty(QLatin1String("debug"),newFunction(QDeclarativeEnginePrivate::consoleLog, 1));
460 globalObject().setProperty(QLatin1String("console"), consoleObject);
462 // translation functions need to be installed
463 // before the global script class is constructed (QTBUG-6437)
464 installTranslatorFunctions();
467 QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
469 delete sqlQueryClass;
470 delete nodeListClass;
471 delete namedNodeMapClass;
474 QScriptValue QDeclarativeScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine)
476 QString arg = ctxt->argument(0).toString();
477 QUrl r = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt,QUrl(arg));
478 return QScriptValue(r.toString());
481 QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
483 return p->getNetworkAccessManager();
486 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
488 Q_ASSERT(inProgressCreations == 0);
489 Q_ASSERT(bindValues.isEmpty());
490 Q_ASSERT(parserStatus.isEmpty());
493 QDeclarativeCleanup *c = cleanup;
495 if (cleanup) cleanup->prev = &cleanup;
507 delete scarceResourceClass;
508 scarceResourceClass = 0;
509 delete valueTypeClass;
511 delete typeNameClass;
518 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
520 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
522 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
524 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
525 delete (*iter)->qobjectApi;
530 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
535 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
537 for (int ii = 0; ii < pss.count; ++ii) {
538 QDeclarativeParserStatus *ps = pss.at(ii);
545 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
547 QObjectPrivate *p = QObjectPrivate::get(o);
548 if (p->declarativeData) {
549 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
550 if (d->ownContext && d->context) {
551 d->context->destroy();
557 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
559 static_cast<QDeclarativeData *>(d)->destroyed(o);
562 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
564 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
567 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
569 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
572 void QDeclarativeEnginePrivate::init()
574 Q_Q(QDeclarativeEngine);
575 qRegisterMetaType<QVariant>("QVariant");
576 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
577 qRegisterMetaType<QScriptValue>("QScriptValue");
578 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
580 QDeclarativeData::init();
582 contextClass = new QDeclarativeContextScriptClass(q);
583 objectClass = new QDeclarativeObjectScriptClass(q);
584 scarceResourceClass = new QDeclarativeScarceResourceScriptClass(q);
585 valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
586 typeNameClass = new QDeclarativeTypeNameScriptClass(q);
587 listClass = new QDeclarativeListScriptClass(q);
588 rootContext = new QDeclarativeContext(q,true);
590 QScriptValue applicationObject = objectClass->newQObject(new QDeclarativeApplication(q));
591 scriptEngine.globalObject().property(QLatin1String("Qt")).setProperty(QLatin1String("application"), applicationObject);
593 if (QCoreApplication::instance()->thread() == q->thread() &&
594 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
596 QDeclarativeEngineDebugServer::instance()->addEngine(q);
600 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
602 Q_Q(QDeclarativeEngine);
603 if (!workerScriptEngine)
604 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
605 return workerScriptEngine;
609 \class QDeclarativeEngine
611 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
614 Each QML component is instantiated in a QDeclarativeContext.
615 QDeclarativeContext's are essential for passing data to QML
616 components. In QML, contexts are arranged hierarchically and this
617 hierarchy is managed by the QDeclarativeEngine.
619 Prior to creating any QML components, an application must have
620 created a QDeclarativeEngine to gain access to a QML context. The
621 following example shows how to create a simple Text item.
624 QDeclarativeEngine engine;
625 QDeclarativeComponent component(&engine);
626 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
627 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
629 //add item to view, etc
633 In this case, the Text item will be created in the engine's
634 \l {QDeclarativeEngine::rootContext()}{root context}.
636 \sa QDeclarativeComponent QDeclarativeContext
640 Create a new QDeclarativeEngine with the given \a parent.
642 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
643 : QObject(*new QDeclarativeEnginePrivate(this), parent)
645 Q_D(QDeclarativeEngine);
650 Destroys the QDeclarativeEngine.
652 Any QDeclarativeContext's created on this engine will be
653 invalidated, but not destroyed (unless they are parented to the
654 QDeclarativeEngine object).
656 QDeclarativeEngine::~QDeclarativeEngine()
658 Q_D(QDeclarativeEngine);
660 QDeclarativeEngineDebugServer::instance()->remEngine(this);
662 // if we are the parent of any of the qobject module api instances,
663 // we need to remove them from our internal list, in order to prevent
664 // a segfault in engine private dtor.
665 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
666 QObject *currQObjectApi = 0;
667 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
668 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
669 currInstance = d->moduleApiInstances.value(key);
670 currQObjectApi = currInstance->qobjectApi;
671 if (this->children().contains(currQObjectApi)) {
672 delete currQObjectApi;
674 d->moduleApiInstances.remove(key);
679 /*! \fn void QDeclarativeEngine::quit()
680 This signal is emitted when the QML loaded by the engine would like to quit.
683 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
684 This signal is emitted when \a warnings messages are generated by QML.
688 Clears the engine's internal component cache.
690 Normally the QDeclarativeEngine caches components loaded from qml
691 files. This method clears this cache and forces the component to be
694 void QDeclarativeEngine::clearComponentCache()
696 Q_D(QDeclarativeEngine);
697 d->typeLoader.clearCache();
701 Returns the engine's root context.
703 The root context is automatically created by the QDeclarativeEngine.
704 Data that should be available to all QML component instances
705 instantiated by the engine should be put in the root context.
707 Additional data that should only be available to a subset of
708 component instances should be added to sub-contexts parented to the
711 QDeclarativeContext *QDeclarativeEngine::rootContext() const
713 Q_D(const QDeclarativeEngine);
714 return d->rootContext;
718 Sets the \a factory to use for creating QNetworkAccessManager(s).
720 QNetworkAccessManager is used for all network access by QML. By
721 implementing a factory it is possible to create custom
722 QNetworkAccessManager with specialized caching, proxy and cookie
725 The factory must be set before executing the engine.
727 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
729 Q_D(QDeclarativeEngine);
730 QMutexLocker locker(&d->mutex);
731 d->networkAccessManagerFactory = factory;
735 Returns the current QDeclarativeNetworkAccessManagerFactory.
737 \sa setNetworkAccessManagerFactory()
739 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
741 Q_D(const QDeclarativeEngine);
742 return d->networkAccessManagerFactory;
745 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
747 QMutexLocker locker(&mutex);
748 QNetworkAccessManager *nam;
749 if (networkAccessManagerFactory) {
750 nam = networkAccessManagerFactory->create(parent);
752 nam = new QNetworkAccessManager(parent);
758 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
760 Q_Q(const QDeclarativeEngine);
761 if (!networkAccessManager)
762 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
763 return networkAccessManager;
767 Returns a common QNetworkAccessManager which can be used by any QML
768 element instantiated by this engine.
770 If a QDeclarativeNetworkAccessManagerFactory has been set and a
771 QNetworkAccessManager has not yet been created, the
772 QDeclarativeNetworkAccessManagerFactory will be used to create the
773 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
774 will have no proxy or cache set.
776 \sa setNetworkAccessManagerFactory()
778 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
780 Q_D(const QDeclarativeEngine);
781 return d->getNetworkAccessManager();
786 Sets the \a provider to use for images requested via the \e
787 image: url scheme, with host \a providerId. The QDeclarativeEngine
788 takes ownership of \a provider.
790 Image providers enable support for pixmap and threaded image
791 requests. See the QDeclarativeImageProvider documentation for details on
792 implementing and using image providers.
794 All required image providers should be added to the engine before any
795 QML sources files are loaded.
797 Note that images loaded from a QDeclarativeImageProvider are cached
798 by QPixmapCache, similar to any image loaded by QML.
800 \sa removeImageProvider()
802 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
804 Q_D(QDeclarativeEngine);
805 QMutexLocker locker(&d->mutex);
806 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
810 Returns the QDeclarativeImageProvider set for \a providerId.
812 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
814 Q_D(const QDeclarativeEngine);
815 QMutexLocker locker(&d->mutex);
816 return d->imageProviders.value(providerId).data();
820 Removes the QDeclarativeImageProvider for \a providerId.
822 Returns the provider if it was found; otherwise returns 0.
824 \sa addImageProvider()
826 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
828 Q_D(QDeclarativeEngine);
829 QMutexLocker locker(&d->mutex);
830 d->imageProviders.take(providerId);
833 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
835 QMutexLocker locker(&mutex);
836 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
839 return provider->imageType();
840 return QDeclarativeImageProvider::Invalid;
843 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
845 QMutexLocker locker(&mutex);
846 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
849 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
850 return provider->requestTexture(imageId, size, req_size);
855 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
857 QMutexLocker locker(&mutex);
859 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
862 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
863 image = provider->requestImage(imageId, size, req_size);
868 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
870 QMutexLocker locker(&mutex);
872 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
875 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
876 pixmap = provider->requestPixmap(imageId, size, req_size);
882 Return the base URL for this engine. The base URL is only used to
883 resolve components when a relative URL is passed to the
884 QDeclarativeComponent constructor.
886 If a base URL has not been explicitly set, this method returns the
887 application's current working directory.
891 QUrl QDeclarativeEngine::baseUrl() const
893 Q_D(const QDeclarativeEngine);
894 if (d->baseUrl.isEmpty()) {
895 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
902 Set the base URL for this engine to \a url.
906 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
908 Q_D(QDeclarativeEngine);
913 Returns true if warning messages will be output to stderr in addition
914 to being emitted by the warnings() signal, otherwise false.
916 The default value is true.
918 bool QDeclarativeEngine::outputWarningsToStandardError() const
920 Q_D(const QDeclarativeEngine);
921 return d->outputWarningsToStdErr;
925 Set whether warning messages will be output to stderr to \a enabled.
927 If \a enabled is true, any warning messages generated by QML will be
928 output to stderr and emitted by the warnings() signal. If \a enabled
929 is false, on the warnings() signal will be emitted. This allows
930 applications to handle warning output themselves.
932 The default value is true.
934 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
936 Q_D(QDeclarativeEngine);
937 d->outputWarningsToStdErr = enabled;
941 Returns the QDeclarativeContext for the \a object, or 0 if no
942 context has been set.
944 When the QDeclarativeEngine instantiates a QObject, the context is
947 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
952 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
954 QDeclarativeData *data =
955 static_cast<QDeclarativeData *>(priv->declarativeData);
959 else if (data->outerContext)
960 return data->outerContext->asQDeclarativeContext();
966 Sets the QDeclarativeContext for the \a object to \a context.
967 If the \a object already has a context, a warning is
968 output, but the context is not changed.
970 When the QDeclarativeEngine instantiates a QObject, the context is
973 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
975 if (!object || !context)
978 QDeclarativeData *data = QDeclarativeData::get(object, true);
980 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
984 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
985 contextData->addObject(object);
989 \enum QDeclarativeEngine::ObjectOwnership
991 Ownership controls whether or not QML automatically destroys the
992 QObject when the object is garbage collected by the JavaScript
993 engine. The two ownership options are:
995 \value CppOwnership The object is owned by C++ code, and will
996 never be deleted by QML. The JavaScript destroy() method cannot be
997 used on objects with CppOwnership. This option is similar to
998 QScriptEngine::QtOwnership.
1000 \value JavaScriptOwnership The object is owned by JavaScript.
1001 When the object is returned to QML as the return value of a method
1002 call or property access, QML will delete the object if there are no
1003 remaining JavaScript references to it and it has no
1004 QObject::parent(). This option is similar to
1005 QScriptEngine::ScriptOwnership.
1007 Generally an application doesn't need to set an object's ownership
1008 explicitly. QML uses a heuristic to set the default object
1009 ownership. By default, an object that is created by QML has
1010 JavaScriptOwnership. The exception to this are the root objects
1011 created by calling QDeclarativeCompnent::create() or
1012 QDeclarativeComponent::beginCreate() which have CppOwnership by
1013 default. The ownership of these root-level objects is considered to
1014 have been transferred to the C++ caller.
1016 Objects not-created by QML have CppOwnership by default. The
1017 exception to this is objects returned from a C++ method call. The
1018 ownership of these objects is passed to JavaScript.
1020 Calling setObjectOwnership() overrides the default ownership
1021 heuristic used by QML.
1025 Sets the \a ownership of \a object.
1027 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
1032 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
1036 ddata->indestructible = (ownership == CppOwnership)?true:false;
1037 ddata->explicitIndestructibleSet = true;
1041 Returns the ownership of \a object.
1043 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
1046 return CppOwnership;
1048 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
1050 return CppOwnership;
1052 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
1055 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
1057 QDeclarativeData *data = QDeclarativeData::get(object);
1059 if (data && data->deferredComponent) {
1060 if (QDeclarativeDebugService::isDebuggingEnabled()) {
1061 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
1062 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
1063 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
1064 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
1065 if (data->outerContext)
1066 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
1068 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
1070 QDeclarativeComponentPrivate::ConstructionState state;
1071 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
1073 data->deferredComponent->release();
1074 data->deferredComponent = 0;
1076 QDeclarativeComponentPrivate::complete(ep, &state);
1077 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
1081 QDeclarativeContext *qmlContext(const QObject *obj)
1083 return QDeclarativeEngine::contextForObject(obj);
1086 QDeclarativeEngine *qmlEngine(const QObject *obj)
1088 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
1089 return context?context->engine():0;
1092 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
1094 QDeclarativeData *data = QDeclarativeData::get(object);
1096 return 0; // Attached properties are only on objects created by QML
1098 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
1102 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
1106 rv = pf(const_cast<QObject *>(object));
1109 data->attachedProperties()->insert(id, rv);
1114 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1115 const QMetaObject *attachedMetaObject, bool create)
1118 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1120 if (*idCache == -1 || !object)
1123 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1126 class QDeclarativeDataExtended {
1128 QDeclarativeDataExtended();
1129 ~QDeclarativeDataExtended();
1131 QHash<int, QObject *> attachedProperties;
1132 QDeclarativeNotifier objectNameNotifier;
1135 QDeclarativeDataExtended::QDeclarativeDataExtended()
1139 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1143 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1145 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1146 return &extendedData->objectNameNotifier;
1149 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1151 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1152 return &extendedData->attachedProperties;
1155 void QDeclarativeData::destroyed(QObject *object)
1157 if (deferredComponent)
1158 deferredComponent->release();
1160 if (nextContextObject)
1161 nextContextObject->prevContextObject = prevContextObject;
1162 if (prevContextObject)
1163 *prevContextObject = nextContextObject;
1165 QDeclarativeAbstractBinding *binding = bindings;
1167 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1168 binding->m_prevBinding = 0;
1169 binding->m_nextBinding = 0;
1178 propertyCache->release();
1180 if (ownContext && context)
1184 QDeclarativeGuard<QObject> *guard = guards;
1185 *guard = (QObject *)0;
1186 guard->objectDestroyed(object);
1193 delete extendedData;
1199 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1201 if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1204 void QDeclarativeData::objectNameChanged(QObject *)
1206 if (extendedData) objectNameNotifier()->notify();
1209 bool QDeclarativeData::hasBindingBit(int bit) const
1211 if (bindingBitsSize > bit)
1212 return bindingBits[bit / 32] & (1 << (bit % 32));
1217 void QDeclarativeData::clearBindingBit(int bit)
1219 if (bindingBitsSize > bit)
1220 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1223 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1225 if (bindingBitsSize <= bit) {
1226 int props = obj->metaObject()->propertyCount();
1227 Q_ASSERT(bit < props);
1229 int arraySize = (props + 31) / 32;
1230 int oldArraySize = bindingBitsSize / 32;
1232 bindingBits = (quint32 *)realloc(bindingBits,
1233 arraySize * sizeof(quint32));
1235 memset(bindingBits + oldArraySize,
1237 sizeof(quint32) * (arraySize - oldArraySize));
1239 bindingBitsSize = arraySize * 32;
1242 bindingBits[bit / 32] |= (1 << (bit % 32));
1246 Creates a QScriptValue allowing you to use \a object in QML script.
1247 \a engine is the QDeclarativeEngine it is to be created in.
1249 The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
1250 to the special needs of QML requiring more functionality than a standard
1253 QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
1254 QDeclarativeEngine* engine)
1256 QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
1257 return enginePriv->objectClass->newQObject(object);
1261 Returns the QDeclarativeContext for the executing QScript \a ctxt.
1263 QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
1265 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1266 Q_ASSERT(scopeNode.isValid());
1267 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1268 return contextClass->contextFromValue(scopeNode);
1272 Returns the QUrl associated with the script \a ctxt for the case that there is
1273 no QDeclarativeContext.
1275 QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
1277 QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1278 Q_ASSERT(scopeNode.isValid());
1279 Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1280 return contextClass->urlFromValue(scopeNode);
1283 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1285 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1286 if (url.authority().isEmpty())
1287 return QLatin1Char(':') + url.path();
1290 return url.toLocalFile();
1294 \qmlmethod object Qt::createComponent(url)
1296 Returns a \l Component object created using the QML file at the specified \a url,
1297 or \c null if an empty string was given.
1299 The returned component's \l Component::status property indicates whether the
1300 component was successfully created. If the status is \c Component.Error,
1301 see \l Component::errorString() for an error description.
1303 Call \l {Component::createObject()}{Component.createObject()} on the returned
1304 component to create an object instance of the component.
1308 \snippet doc/src/snippets/declarative/createComponent-simple.qml 0
1310 See \l {Dynamic Object Management in QML} for more information on using this function.
1312 To create a QML object from an arbitrary string of QML (instead of a file),
1313 use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
1316 QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
1318 QDeclarativeEnginePrivate *activeEnginePriv =
1319 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1320 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1322 if(ctxt->argumentCount() != 1) {
1323 return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments"));
1326 QString arg = ctxt->argument(0).toString();
1328 return engine->nullValue();
1329 QUrl url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(ctxt, QUrl(arg));
1330 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1331 QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
1332 QDeclarativeComponentPrivate::get(c)->creationContext = context;
1333 QDeclarativeData::get(c, true)->setImplicitDestructible();
1334 return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
1339 \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
1341 Returns a new object created from the given \a string of QML which will have the specified \a parent,
1342 or \c null if there was an error in creating the object.
1344 If \a filepath is specified, it will be used for error reporting for the created object.
1346 Example (where \c parentItem is the id of an existing QML item):
1348 \snippet doc/src/snippets/declarative/createQmlObject.qml 0
1350 In the case of an error, a QtScript Error object is thrown. This object has an additional property,
1351 \c qmlErrors, which is an array of the errors encountered.
1352 Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
1353 For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
1354 { "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
1356 Note that this function returns immediately, and therefore may not work if
1357 the \a qml string loads new components (that is, external QML files that have not yet been loaded).
1358 If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
1360 See \l {Dynamic Object Management in QML} for more information on using this function.
1363 QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
1365 QDeclarativeEnginePrivate *activeEnginePriv =
1366 static_cast<QDeclarativeScriptEngine*>(engine)->p;
1367 QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
1369 if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
1370 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Invalid arguments"));
1372 QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
1375 QString qml = ctxt->argument(0).toString();
1377 return engine->nullValue();
1380 if(ctxt->argumentCount() > 2)
1381 url = QUrl(ctxt->argument(2).toString());
1383 url = QUrl(QLatin1String("inline"));
1385 if (url.isValid() && url.isRelative())
1386 url = context->resolvedUrl(url);
1388 QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
1390 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Missing parent object"));
1392 QDeclarativeComponent component(activeEngine);
1393 component.setData(qml.toUtf8(), url);
1395 if(component.isError()) {
1396 QList<QDeclarativeError> errors = component.errors();
1397 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1398 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1400 foreach (const QDeclarativeError &error, errors){
1401 errstr += QLatin1String("\n ") + error.toString();
1402 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1403 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1404 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1405 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1406 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1407 arr.setProperty(i++, qmlErrObject);
1409 QScriptValue err = ctxt->throwError(errstr);
1410 err.setProperty(QLatin1String("qmlErrors"),arr);
1414 if (!component.isReady())
1415 return ctxt->throwError(QLatin1String("Qt.createQmlObject(): Component is not ready"));
1417 QObject *obj = component.beginCreate(context->asQDeclarativeContext());
1419 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1420 component.completeCreate();
1422 if(component.isError()) {
1423 QList<QDeclarativeError> errors = component.errors();
1424 QString errstr = QLatin1String("Qt.createQmlObject() failed to create object: ");
1425 QScriptValue arr = ctxt->engine()->newArray(errors.length());
1427 foreach (const QDeclarativeError &error, errors){
1428 errstr += QLatin1String("\n ") + error.toString();
1429 QScriptValue qmlErrObject = ctxt->engine()->newObject();
1430 qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
1431 qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
1432 qmlErrObject.setProperty(QLatin1String("fileName"), QScriptValue(error.url().toString()));
1433 qmlErrObject.setProperty(QLatin1String("message"), QScriptValue(error.description()));
1434 arr.setProperty(i++, qmlErrObject);
1436 QScriptValue err = ctxt->throwError(errstr);
1437 err.setProperty(QLatin1String("qmlErrors"),arr);
1443 obj->setParent(parentArg);
1445 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
1446 for (int ii = 0; ii < functions.count(); ++ii) {
1447 if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
1451 QDeclarativeData::get(obj, true)->setImplicitDestructible();
1452 return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
1456 \qmlmethod bool Qt::isQtObject(object)
1457 Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
1459 QScriptValue QDeclarativeEnginePrivate::isQtObject(QScriptContext *ctxt, QScriptEngine *engine)
1461 if (ctxt->argumentCount() == 0)
1462 return QScriptValue(engine, false);
1464 return QScriptValue(engine, 0 != ctxt->argument(0).toQObject());
1468 \qmlmethod Qt::vector3d(real x, real y, real z)
1469 Returns a Vector3D with the specified \c x, \c y and \c z.
1471 QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEngine *engine)
1473 if(ctxt->argumentCount() != 3)
1474 return ctxt->throwError(QLatin1String("Qt.vector(): Invalid arguments"));
1475 qsreal x = ctxt->argument(0).toNumber();
1476 qsreal y = ctxt->argument(1).toNumber();
1477 qsreal z = ctxt->argument(2).toNumber();
1478 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QVector3D(x, y, z)));
1482 \qmlmethod string Qt::formatDate(datetime date, variant format)
1484 Returns a string representation of \c date, optionally formatted according
1487 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1488 property, a QDate, or QDateTime value. The \a format parameter may be any of
1489 the possible format values as described for
1490 \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1492 If \a format is not specified, \a date is formatted using
1493 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1495 #ifndef QT_NO_DATESTRING
1496 QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine)
1498 int argCount = ctxt->argumentCount();
1499 if(argCount == 0 || argCount > 2)
1500 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid arguments"));
1502 QDate date = ctxt->argument(0).toDateTime().date();
1503 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1504 if (argCount == 2) {
1505 QScriptValue formatArg = ctxt->argument(1);
1506 if (formatArg.isString()) {
1507 QString format = formatArg.toString();
1508 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1509 } else if (formatArg.isNumber()) {
1510 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1512 return ctxt->throwError(QLatin1String("Qt.formatDate(): Invalid date format"));
1515 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1519 \qmlmethod string Qt::formatTime(datetime time, variant format)
1521 Returns a string representation of \c time, optionally formatted according to
1524 The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime
1525 value. The \a format parameter may be any of the possible format values as
1526 described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}.
1528 If \a format is not specified, \a time is formatted using
1529 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}.
1531 QScriptValue QDeclarativeEnginePrivate::formatTime(QScriptContext*ctxt, QScriptEngine*engine)
1533 int argCount = ctxt->argumentCount();
1534 if(argCount == 0 || argCount > 2)
1535 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid arguments"));
1538 QScriptValue sv = ctxt->argument(0);
1540 time = sv.toDateTime().time();
1541 else if (sv.toVariant().type() == QVariant::Time)
1542 time = sv.toVariant().toTime();
1544 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1545 if (argCount == 2) {
1546 QScriptValue formatArg = ctxt->argument(1);
1547 if (formatArg.isString()) {
1548 QString format = formatArg.toString();
1549 return engine->newVariant(QVariant::fromValue(time.toString(format)));
1550 } else if (formatArg.isNumber()) {
1551 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1553 return ctxt->throwError(QLatin1String("Qt.formatTime(): Invalid time format"));
1556 return engine->newVariant(QVariant::fromValue(time.toString(enumFormat)));
1560 \qmlmethod string Qt::formatDateTime(datetime dateTime, variant format)
1562 Returns a string representation of \c datetime, optionally formatted according to
1565 The \a date parameter may be a JavaScript \c Date object, a \l{date}{date}
1566 property, a QDate, QTime, or QDateTime value.
1568 If \a format is not provided, \a dateTime is formatted using
1569 \l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise,
1570 \a format should be either.
1573 \o One of the Qt::DateFormat enumeration values, such as
1574 \c Qt.DefaultLocaleShortDate or \c Qt.ISODate
1575 \o A string that specifies the format of the returned string, as detailed below.
1578 If \a format specifies a format string, it should use the following expressions
1579 to specify the date:
1582 \header \i Expression \i Output
1583 \row \i d \i the day as number without a leading zero (1 to 31)
1584 \row \i dd \i the day as number with a leading zero (01 to 31)
1586 \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
1587 Uses QDate::shortDayName().
1589 \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
1590 Uses QDate::longDayName().
1591 \row \i M \i the month as number without a leading zero (1-12)
1592 \row \i MM \i the month as number with a leading zero (01-12)
1594 \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
1595 Uses QDate::shortMonthName().
1597 \i the long localized month name (e.g. 'January' to 'December').
1598 Uses QDate::longMonthName().
1599 \row \i yy \i the year as two digit number (00-99)
1600 \row \i yyyy \i the year as four digit number
1603 In addition the following expressions can be used to specify the time:
1606 \header \i Expression \i Output
1608 \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1610 \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1611 \row \i m \i the minute without a leading zero (0 to 59)
1612 \row \i mm \i the minute with a leading zero (00 to 59)
1613 \row \i s \i the second without a leading zero (0 to 59)
1614 \row \i ss \i the second with a leading zero (00 to 59)
1615 \row \i z \i the milliseconds without leading zeroes (0 to 999)
1616 \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
1618 \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1620 \i use am/pm display. \e ap will be replaced by either "am" or "pm".
1623 All other input characters will be ignored. Any sequence of characters that
1624 are enclosed in single quotes will be treated as text and not be used as an
1625 expression. Two consecutive single quotes ("''") are replaced by a single quote
1628 For example, if the following date/time value was specified:
1631 // 21 May 2001 14:13:09
1632 var dateTime = new Date(2001, 5, 21, 14, 13, 09)
1635 This \a dateTime value could be passed to \c Qt.formatDateTime(),
1636 \l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()}
1637 with the \a format values below to produce the following results:
1640 \header \i Format \i Result
1641 \row \i "dd.MM.yyyy" \i 21.05.2001
1642 \row \i "ddd MMMM d yy" \i Tue May 21 01
1643 \row \i "hh:mm:ss.zzz" \i 14:13:09.042
1644 \row \i "h:m:s ap" \i 2:13:9 pm
1647 QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScriptEngine*engine)
1649 int argCount = ctxt->argumentCount();
1650 if(argCount == 0 || argCount > 2)
1651 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid arguments"));
1653 QDateTime date = ctxt->argument(0).toDateTime();
1654 Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
1655 if (argCount == 2) {
1656 QScriptValue formatArg = ctxt->argument(1);
1657 if (formatArg.isString()) {
1658 QString format = formatArg.toString();
1659 return engine->newVariant(QVariant::fromValue(date.toString(format)));
1660 } else if (formatArg.isNumber()) {
1661 enumFormat = Qt::DateFormat(formatArg.toUInt32());
1663 return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format"));
1666 return engine->newVariant(QVariant::fromValue(date.toString(enumFormat)));
1668 #endif // QT_NO_DATESTRING
1671 \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha)
1673 Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
1674 All components should be in the range 0-1 inclusive.
1676 QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
1678 int argCount = ctxt->argumentCount();
1679 if(argCount < 3 || argCount > 4)
1680 return ctxt->throwError(QLatin1String("Qt.rgba(): Invalid arguments"));
1681 qsreal r = ctxt->argument(0).toNumber();
1682 qsreal g = ctxt->argument(1).toNumber();
1683 qsreal b = ctxt->argument(2).toNumber();
1684 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1695 return engine->toScriptValue(QVariant::fromValue(QColor::fromRgbF(r, g, b, a)));
1699 \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha)
1701 Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
1702 All components should be in the range 0-1 inclusive.
1704 QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
1706 int argCount = ctxt->argumentCount();
1707 if(argCount < 3 || argCount > 4)
1708 return ctxt->throwError(QLatin1String("Qt.hsla(): Invalid arguments"));
1709 qsreal h = ctxt->argument(0).toNumber();
1710 qsreal s = ctxt->argument(1).toNumber();
1711 qsreal l = ctxt->argument(2).toNumber();
1712 qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
1723 return engine->toScriptValue(QVariant::fromValue(QColor::fromHslF(h, s, l, a)));
1727 \qmlmethod rect Qt::rect(int x, int y, int width, int height)
1729 Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height.
1731 The returned object has \c x, \c y, \c width and \c height attributes with the given values.
1733 QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
1735 if(ctxt->argumentCount() != 4)
1736 return ctxt->throwError(QLatin1String("Qt.rect(): Invalid arguments"));
1738 qsreal x = ctxt->argument(0).toNumber();
1739 qsreal y = ctxt->argument(1).toNumber();
1740 qsreal w = ctxt->argument(2).toNumber();
1741 qsreal h = ctxt->argument(3).toNumber();
1743 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
1747 \qmlmethod point Qt::point(int x, int y)
1748 Returns a Point with the specified \c x and \c y coordinates.
1750 QScriptValue QDeclarativeEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
1752 if(ctxt->argumentCount() != 2)
1753 return ctxt->throwError(QLatin1String("Qt.point(): Invalid arguments"));
1754 qsreal x = ctxt->argument(0).toNumber();
1755 qsreal y = ctxt->argument(1).toNumber();
1756 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QPointF(x, y)));
1760 \qmlmethod Qt::size(int width, int height)
1761 Returns a Size with the specified \c width and \c height.
1763 QScriptValue QDeclarativeEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
1765 if(ctxt->argumentCount() != 2)
1766 return ctxt->throwError(QLatin1String("Qt.size(): Invalid arguments"));
1767 qsreal w = ctxt->argument(0).toNumber();
1768 qsreal h = ctxt->argument(1).toNumber();
1769 return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QSizeF(w, h)));
1773 \qmlmethod color Qt::lighter(color baseColor, real factor)
1774 Returns a color lighter than \c baseColor by the \c factor provided.
1776 If the factor is greater than 1.0, this functions returns a lighter color.
1777 Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0,
1778 the return color is darker, but we recommend using the Qt.darker() function for this purpose.
1779 If the factor is 0 or negative, the return value is unspecified.
1781 The function converts the current RGB color to HSV, multiplies the value (V) component
1782 by factor and converts the color back to RGB.
1784 If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
1786 QScriptValue QDeclarativeEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine)
1788 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1789 return ctxt->throwError(QLatin1String("Qt.lighter(): Invalid arguments"));
1790 QVariant v = ctxt->argument(0).toVariant();
1792 if (v.userType() == QVariant::Color)
1793 color = v.value<QColor>();
1794 else if (v.userType() == QVariant::String) {
1796 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1798 return engine->nullValue();
1800 return engine->nullValue();
1801 qsreal factor = 1.5;
1802 if (ctxt->argumentCount() == 2)
1803 factor = ctxt->argument(1).toNumber();
1804 color = color.lighter(int(qRound(factor*100.)));
1805 return engine->toScriptValue(QVariant::fromValue(color));
1809 \qmlmethod color Qt::darker(color baseColor, real factor)
1810 Returns a color darker than \c baseColor by the \c factor provided.
1812 If the factor is greater than 1.0, this function returns a darker color.
1813 Setting factor to 3.0 returns a color that has one-third the brightness.
1814 If the factor is less than 1.0, the return color is lighter, but we recommend using
1815 the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return
1816 value is unspecified.
1818 The function converts the current RGB color to HSV, divides the value (V) component
1819 by factor and converts the color back to RGB.
1821 If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
1823 QScriptValue QDeclarativeEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine)
1825 if(ctxt->argumentCount() != 1 && ctxt->argumentCount() != 2)
1826 return ctxt->throwError(QLatin1String("Qt.darker(): Invalid arguments"));
1827 QVariant v = ctxt->argument(0).toVariant();
1829 if (v.userType() == QVariant::Color)
1830 color = v.value<QColor>();
1831 else if (v.userType() == QVariant::String) {
1833 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
1835 return engine->nullValue();
1837 return engine->nullValue();
1838 qsreal factor = 2.0;
1839 if (ctxt->argumentCount() == 2)
1840 factor = ctxt->argument(1).toNumber();
1841 color = color.darker(int(qRound(factor*100.)));
1842 return engine->toScriptValue(QVariant::fromValue(color));
1846 \qmlmethod bool Qt::openUrlExternally(url target)
1847 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.
1849 QScriptValue QDeclarativeEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
1851 if(ctxt->argumentCount() < 1)
1852 return QScriptValue(e, false);
1854 #ifndef QT_NO_DESKTOPSERVICES
1855 ret = QDesktopServices::openUrl(QDeclarativeScriptEngine::get(e)->resolvedUrl(ctxt, QUrl(ctxt->argument(0).toString())));
1857 return QScriptValue(e, ret);
1861 \qmlmethod list<string> Qt::fontFamilies()
1862 Returns a list of the font families available to the application.
1865 QScriptValue QDeclarativeEnginePrivate::fontFamilies(QScriptContext *ctxt, QScriptEngine *e)
1867 if(ctxt->argumentCount() != 0)
1868 return ctxt->throwError(QLatin1String("Qt.fontFamilies(): Invalid arguments"));
1870 QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(e);
1871 QFontDatabase database;
1872 return p->scriptValueFromVariant(database.families());
1876 \qmlmethod string Qt::md5(data)
1877 Returns a hex string of the md5 hash of \c data.
1879 QScriptValue QDeclarativeEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
1881 if (ctxt->argumentCount() != 1)
1882 return ctxt->throwError(QLatin1String("Qt.md5(): Invalid arguments"));
1884 QByteArray data = ctxt->argument(0).toString().toUtf8();
1885 QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
1887 return QScriptValue(QLatin1String(result.toHex()));
1891 \qmlmethod string Qt::btoa(data)
1892 Binary to ASCII - this function returns a base64 encoding of \c data.
1894 QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
1896 if (ctxt->argumentCount() != 1)
1897 return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments"));
1899 QByteArray data = ctxt->argument(0).toString().toUtf8();
1901 return QScriptValue(QLatin1String(data.toBase64()));
1905 \qmlmethod string Qt::atob(data)
1906 ASCII to binary - this function returns a base64 decoding of \c data.
1909 QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
1911 if (ctxt->argumentCount() != 1)
1912 return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments"));
1914 QByteArray data = ctxt->argument(0).toString().toUtf8();
1916 return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
1919 QScriptValue QDeclarativeEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
1921 if(ctxt->argumentCount() < 1)
1922 return e->newVariant(QVariant(false));
1926 for (int i=0; i<ctxt->argumentCount(); ++i) {
1927 if (!msg.isEmpty()) msg += ' ';
1928 msg += ctxt->argument(i).toString().toLocal8Bit();
1929 // does not support firebug "%[a-z]" formatting, since firebug really
1930 // does just ignore the format letter, which makes it pointless.
1933 qDebug("%s",msg.constData());
1935 return e->newVariant(QVariant(true));
1938 void QDeclarativeEnginePrivate::sendQuit()
1940 Q_Q(QDeclarativeEngine);
1942 if (q->receivers(SIGNAL(quit())) == 0) {
1943 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1947 static void dumpwarning(const QDeclarativeError &error)
1949 qWarning().nospace() << qPrintable(error.toString());
1952 static void dumpwarning(const QList<QDeclarativeError> &errors)
1954 for (int ii = 0; ii < errors.count(); ++ii)
1955 dumpwarning(errors.at(ii));
1958 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1960 Q_Q(QDeclarativeEngine);
1961 q->warnings(QList<QDeclarativeError>() << error);
1962 if (outputWarningsToStdErr)
1966 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1968 Q_Q(QDeclarativeEngine);
1969 q->warnings(errors);
1970 if (outputWarningsToStdErr)
1971 dumpwarning(errors);
1974 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1977 QDeclarativeEnginePrivate::get(engine)->warning(error);
1982 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1985 QDeclarativeEnginePrivate::get(engine)->warning(error);
1990 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1993 engine->warning(error);
1998 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
2001 engine->warning(error);
2007 \qmlmethod Qt::quit()
2008 This function causes the QDeclarativeEngine::quit() signal to be emitted.
2009 Within the \l {QML Viewer}, this causes the launcher application to exit;
2010 to quit a C++ application when this method is called, connect the
2011 QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot.
2014 QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e)
2016 QDeclarativeEnginePrivate *qe = get (e);
2018 return QScriptValue();
2022 \qmlmethod color Qt::tint(color baseColor, color tintColor)
2023 This function allows tinting one color with another.
2025 The tint color should usually be mostly transparent, or you will not be
2026 able to see the underlying color. The below example provides a slight red
2027 tint by having the tint color be pure red which is only 1/16th opaque.
2032 x: 0; width: 80; height: 80
2033 color: "lightsteelblue"
2036 x: 100; width: 80; height: 80
2037 color: Qt.tint("lightsteelblue", "#10FF0000")
2041 \image declarative-rect_tint.png
2043 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.
2045 QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
2047 if(ctxt->argumentCount() != 2)
2048 return ctxt->throwError(QLatin1String("Qt.tint(): Invalid arguments"));
2050 QVariant v = ctxt->argument(0).toVariant();
2052 if (v.userType() == QVariant::Color)
2053 color = v.value<QColor>();
2054 else if (v.userType() == QVariant::String) {
2056 color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2058 return engine->nullValue();
2060 return engine->nullValue();
2063 v = ctxt->argument(1).toVariant();
2065 if (v.userType() == QVariant::Color)
2066 tintColor = v.value<QColor>();
2067 else if (v.userType() == QVariant::String) {
2069 tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok);
2071 return engine->nullValue();
2073 return engine->nullValue();
2077 int a = tintColor.alpha();
2079 finalColor = tintColor;
2083 qreal a = tintColor.alphaF();
2084 qreal inv_a = 1.0 - a;
2086 finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a,
2087 tintColor.greenF() * a + color.greenF() * inv_a,
2088 tintColor.blueF() * a + color.blueF() * inv_a,
2089 a + inv_a * color.alphaF());
2092 return engine->toScriptValue(QVariant::fromValue(finalColor));
2095 QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
2097 if (variantIsScarceResource(val)) {
2098 return scarceResourceClass->newScarceResource(val);
2099 } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
2100 QDeclarativeListReferencePrivate *p =
2101 QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
2103 return listClass->newList(p->property, p->propertyType);
2105 return scriptEngine.nullValue();
2107 } else if (val.userType() == qMetaTypeId<QList<QObject *> >()) {
2108 const QList<QObject *> &list = *(QList<QObject *>*)val.constData();
2109 QScriptValue rv = scriptEngine.newArray(list.count());
2110 for (int ii = 0; ii < list.count(); ++ii) {
2111 QObject *object = list.at(ii);
2112 rv.setProperty(ii, objectClass->newQObject(object));
2115 } else if (QDeclarativeValueType *vt = valueTypes[val.userType()]) {
2116 return valueTypeClass->newObject(val, vt);
2120 QObject *obj = QDeclarativeMetaType::toQObject(val, &objOk);
2122 return objectClass->newQObject(obj);
2124 return scriptEngine.toScriptValue(val);
2129 If the variant is a scarce resource (consumes a large amount of memory, or
2130 only a limited number of them can be held in memory at any given time without
2131 exhausting supply for future use) we need to release the scarce resource
2132 after evaluation of the javascript binding is complete.
2134 bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
2136 if (val.type() == QVariant::Pixmap) {
2138 } else if (val.type() == QVariant::Image) {
2146 This function should be called prior to evaluation of any js expression,
2147 so that scarce resources are not freed prematurely (eg, if there is a
2148 nested javascript expression).
2150 void QDeclarativeEnginePrivate::referenceScarceResources()
2152 scarceResourcesRefCount += 1;
2156 This function should be called after evaluation of the js expression is
2157 complete, and so the scarce resources may be freed safely.
2159 void QDeclarativeEnginePrivate::dereferenceScarceResources()
2161 Q_ASSERT(scarceResourcesRefCount > 0);
2162 scarceResourcesRefCount -= 1;
2164 // if the refcount is zero, then evaluation of the "top level"
2165 // expression must have completed. We can safely release the
2166 // scarce resources.
2167 if (scarceResourcesRefCount == 0) {
2168 // iterate through the list and release them all.
2169 // note that the actual SRD is owned by the JS engine,
2170 // so we cannot delete the SRD; but we can free the
2171 // memory used by the variant in the SRD.
2172 ScarceResourceData *srd = 0;
2173 while (scarceResources) {
2174 srd = scarceResources; // srd points to the "old" (current) head of the list
2175 scarceResources = srd->next; // srd->next is the "new" head of the list
2176 if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
2179 srd->releaseResource(); // release the old head node.
2184 QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
2186 QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
2187 if (dc == objectClass)
2188 return QVariant::fromValue(objectClass->toQObject(val));
2189 else if (dc == scarceResourceClass)
2190 return scarceResourceClass->toVariant(val);
2191 else if (dc == valueTypeClass)
2192 return valueTypeClass->toVariant(val);
2193 else if (dc == contextClass)
2196 // Convert to a QList<QObject*> only if val is an array and we were explicitly hinted
2197 if (hint == qMetaTypeId<QList<QObject *> >() && val.isArray()) {
2198 QList<QObject *> list;
2199 int length = val.property(QLatin1String("length")).toInt32();
2200 for (int ii = 0; ii < length; ++ii) {
2201 QScriptValue arrayItem = val.property(ii);
2202 QObject *d = arrayItem.toQObject();
2205 return QVariant::fromValue(list);
2208 return val.toVariant();
2212 Adds \a path as a directory where the engine searches for
2213 installed modules in a URL-based directory structure.
2214 The \a path may be a local filesystem directory or a URL.
2216 The newly added \a path will be first in the importPathList().
2218 \sa setImportPathList(), {QML Modules}
2220 void QDeclarativeEngine::addImportPath(const QString& path)
2222 Q_D(QDeclarativeEngine);
2223 d->importDatabase.addImportPath(path);
2227 Returns the list of directories where the engine searches for
2228 installed modules in a URL-based directory structure.
2230 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
2231 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
2232 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
2233 provided by that module. A \c qmldir file is required for defining the
2234 type version mapping and possibly declarative extensions plugins.
2236 By default, the list contains the directory of the application executable,
2237 paths specified in the \c QML_IMPORT_PATH environment variable,
2238 and the builtin \c ImportsPath from QLibraryInfo.
2240 \sa addImportPath() setImportPathList()
2242 QStringList QDeclarativeEngine::importPathList() const
2244 Q_D(const QDeclarativeEngine);
2245 return d->importDatabase.importPathList();
2249 Sets \a paths as the list of directories where the engine searches for
2250 installed modules in a URL-based directory structure.
2252 By default, the list contains the directory of the application executable,
2253 paths specified in the \c QML_IMPORT_PATH environment variable,
2254 and the builtin \c ImportsPath from QLibraryInfo.
2256 \sa importPathList() addImportPath()
2258 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
2260 Q_D(QDeclarativeEngine);
2261 d->importDatabase.setImportPathList(paths);
2266 Adds \a path as a directory where the engine searches for
2267 native plugins for imported modules (referenced in the \c qmldir file).
2269 By default, the list contains only \c ., i.e. the engine searches
2270 in the directory of the \c qmldir file itself.
2272 The newly added \a path will be first in the pluginPathList().
2274 \sa setPluginPathList()
2276 void QDeclarativeEngine::addPluginPath(const QString& path)
2278 Q_D(QDeclarativeEngine);
2279 d->importDatabase.addPluginPath(path);
2284 Returns the list of directories where the engine searches for
2285 native plugins for imported modules (referenced in the \c qmldir file).
2287 By default, the list contains only \c ., i.e. the engine searches
2288 in the directory of the \c qmldir file itself.
2290 \sa addPluginPath() setPluginPathList()
2292 QStringList QDeclarativeEngine::pluginPathList() const
2294 Q_D(const QDeclarativeEngine);
2295 return d->importDatabase.pluginPathList();
2299 Sets the list of directories where the engine searches for
2300 native plugins for imported modules (referenced in the \c qmldir file)
2303 By default, the list contains only \c ., i.e. the engine searches
2304 in the directory of the \c qmldir file itself.
2306 \sa pluginPathList() addPluginPath()
2308 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
2310 Q_D(QDeclarativeEngine);
2311 d->importDatabase.setPluginPathList(paths);
2316 Imports the plugin named \a filePath with the \a uri provided.
2317 Returns true if the plugin was successfully imported; otherwise returns false.
2319 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
2321 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2323 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
2325 Q_D(QDeclarativeEngine);
2326 return d->importDatabase.importPlugin(filePath, uri, errors);
2330 Imports the plugin named \a filePath with the \a uri provided.
2331 Returns true if the plugin was successfully imported; otherwise returns false.
2333 On failure and if non-null, *\a errorString will be set to a message describing the failure.
2335 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
2337 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
2339 Q_D(QDeclarativeEngine);
2340 QList<QDeclarativeError> errors;
2341 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
2342 if (!errors.isEmpty()) {
2344 for (int i = 0; i < errors.size(); ++i) {
2345 builtError = QString(QLatin1String("%1\n %2"))
2347 .arg(errors.at(i).toString());
2349 *errorString = builtError;
2355 \property QDeclarativeEngine::offlineStoragePath
2356 \brief the directory for storing offline user data
2358 Returns the directory where SQL and other offline
2361 QDeclarativeWebView and the SQL databases created with openDatabase()
2364 The default is QML/OfflineStorage in the platform-standard
2365 user application data directory.
2367 Note that the path may not currently exist on the filesystem, so
2368 callers wanting to \e create new files at this location should create
2369 it first - see QDir::mkpath().
2371 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
2373 Q_D(QDeclarativeEngine);
2374 d->scriptEngine.offlineStoragePath = dir;
2377 QString QDeclarativeEngine::offlineStoragePath() const
2379 Q_D(const QDeclarativeEngine);
2380 return d->scriptEngine.offlineStoragePath;
2383 static void voidptr_destructor(void *v)
2385 void **ptr = (void **)v;
2389 static void *voidptr_constructor(const void *v)
2394 return new void*(*(void **)v);
2398 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
2400 Q_Q(QDeclarativeEngine);
2402 if (!mo->superClass()) {
2403 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
2404 propertyCache.insert(mo, rv);
2407 QDeclarativePropertyCache *super = cache(mo->superClass());
2408 QDeclarativePropertyCache *rv = super->copy();
2410 propertyCache.insert(mo, rv);
2415 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
2416 QDeclarativeError &error)
2418 QList<QDeclarativeType *> types;
2420 int maxMinorVersion = 0;
2422 const QMetaObject *metaObject = type->metaObject();
2423 while (metaObject) {
2424 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
2425 type->majorVersion(), minorVersion);
2427 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
2433 metaObject = metaObject->superClass();
2436 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
2438 typePropertyCache.insert(qMakePair(type, minorVersion), c);
2442 QDeclarativePropertyCache *raw = cache(type->metaObject());
2444 bool hasCopied = false;
2446 for (int ii = 0; ii < types.count(); ++ii) {
2447 QDeclarativeType *currentType = types.at(ii);
2451 int rev = currentType->metaObjectRevision();
2452 int moIndex = types.count() - 1 - ii;
2454 if (raw->allowedRevisionCache[moIndex] != rev) {
2459 raw->allowedRevisionCache[moIndex] = rev;
2463 // Test revision compatibility - the basic rule is:
2464 // * Anything that is excluded, cannot overload something that is not excluded *
2466 // Signals override:
2467 // * other signals and methods of the same name.
2468 // * properties named on<Signal Name>
2469 // * automatic <property name>Changed notify signals
2471 // Methods override:
2472 // * other methods of the same name
2474 // Properties override:
2475 // * other elements of the same name
2477 bool overloadError = false;
2478 QString overloadName;
2481 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
2482 !overloadError && iter != raw->stringCache.end();
2485 QDeclarativePropertyCache::Data *d = *iter;
2486 if (raw->isAllowedInRevision(d))
2487 continue; // Not excluded - no problems
2489 // check that a regular "name" overload isn't happening
2490 QDeclarativePropertyCache::Data *current = d;
2491 while (!overloadError && current) {
2492 current = d->overrideData(current);
2493 if (current && raw->isAllowedInRevision(current))
2494 overloadError = true;
2499 if (overloadError) {
2500 if (hasCopied) raw->release();
2502 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."));
2506 if (!hasCopied) raw->addref();
2507 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
2509 if (minorVersion != maxMinorVersion) {
2511 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
2517 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
2519 QByteArray name = data->root->className();
2521 QByteArray ptr = name + '*';
2522 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
2524 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
2525 voidptr_constructor);
2526 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
2527 voidptr_constructor);
2529 m_qmlLists.insert(lst_type, ptr_type);
2530 m_compositeTypes.insert(ptr_type, data);
2534 bool QDeclarativeEnginePrivate::isList(int t) const
2536 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
2539 int QDeclarativeEnginePrivate::listType(int t) const
2541 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
2542 if (iter != m_qmlLists.end())
2545 return QDeclarativeMetaType::listType(t);
2548 bool QDeclarativeEnginePrivate::isQObject(int t)
2550 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
2553 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
2555 int t = v.userType();
2556 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
2558 return *(QObject **)(v.constData());
2560 return QDeclarativeMetaType::toQObject(v, ok);
2564 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
2566 if (m_compositeTypes.contains(t))
2567 return QDeclarativeMetaType::Object;
2568 else if (m_qmlLists.contains(t))
2569 return QDeclarativeMetaType::List;
2571 return QDeclarativeMetaType::typeCategory(t);
2574 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
2576 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2577 if (iter != m_compositeTypes.end()) {
2578 return (*iter)->root;
2580 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2581 return type?type->baseMetaObject():0;
2585 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
2587 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
2588 if (iter != m_compositeTypes.end()) {
2589 return (*iter)->root;
2591 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
2592 return type?type->metaObject():0;
2596 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
2598 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
2599 QFileInfo info(fileName);
2601 QString absolute = info.absoluteFilePath();
2603 #if defined(Q_OS_MAC)
2604 QString canonical = info.canonicalFilePath();
2605 #elif defined(Q_OS_WIN32)
2606 wchar_t buffer[1024];
2608 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
2609 if (rv == 0 || rv >= 1024) return true;
2610 rv = ::GetLongPathName(buffer, buffer, 1024);
2611 if (rv == 0 || rv >= 1024) return true;
2613 QString canonical((QChar *)buffer);
2616 int absoluteLength = absolute.length();
2617 int canonicalLength = canonical.length();
2619 int length = qMin(absoluteLength, canonicalLength);
2620 for (int ii = 0; ii < length; ++ii) {
2621 const QChar &a = absolute.at(absoluteLength - 1 - ii);
2622 const QChar &c = canonical.at(canonicalLength - 1 - ii);
2624 if (a.toLower() != c.toLower())