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 "qdeclarative.h"
48 #include "qdeclarativecontext.h"
49 #include "qdeclarativeexpression.h"
50 #include "qdeclarativecomponent.h"
51 #include "private/qdeclarativebinding_p_p.h"
52 #include "private/qdeclarativevme_p.h"
53 #include "private/qdeclarativeenginedebugservice_p.h"
54 #include "private/qdeclarativestringconverters_p.h"
55 #include "private/qdeclarativexmlhttprequest_p.h"
56 #include "private/qdeclarativesqldatabase_p.h"
57 #include "qdeclarativescriptstring.h"
58 #include "private/qdeclarativeglobal_p.h"
59 #include "private/qdeclarativeworkerscript_p.h"
60 #include "private/qdeclarativecomponent_p.h"
61 #include "qdeclarativenetworkaccessmanagerfactory.h"
62 #include "qdeclarativeimageprovider.h"
63 #include "private/qdeclarativedirparser_p.h"
64 #include "qdeclarativeextensioninterface.h"
65 #include "private/qdeclarativelist_p.h"
66 #include "private/qdeclarativetypenamecache_p.h"
67 #include "private/qdeclarativenotifier_p.h"
68 #include "private/qdeclarativedebugtrace_p.h"
69 #include "private/qdeclarativeapplication_p.h"
70 #include "private/qv8debugservice_p.h"
71 #include "qdeclarativeincubator.h"
72 #include "private/qv8profilerservice_p.h"
74 #include <QtCore/qmetaobject.h>
75 #include <QNetworkAccessManager>
77 #include <QMetaObject>
78 #include <QtCore/qcoreapplication.h>
79 #include <QtCore/qdir.h>
80 #include <QtCore/qmutex.h>
81 #include <QtNetwork/qnetworkconfigmanager.h>
83 #include <private/qobject_p.h>
85 #include <private/qdeclarativeutilmodule_p.h>
86 #include <private/qsgitemsmodule_p.h>
87 #include <private/qsgparticlesmodule_p.h>
89 #ifdef Q_OS_WIN // for %APPDATA%
90 #include <qt_windows.h>
94 #define CSIDL_APPDATA 0x001a // <username>\Application Data
97 Q_DECLARE_METATYPE(QDeclarativeProperty)
101 void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
103 QDeclarativeEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
104 QDeclarativeValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
105 QDeclarativeUtilModule::registerBaseTypes(uri, versionMajor, versionMinor);
109 \qmlclass QtObject QObject
110 \ingroup qml-utility-elements
112 \brief The QtObject element is the most basic element in QML.
114 The QtObject element is a non-visual element which contains only the
117 It can be useful to create a QtObject if you need an extremely
118 lightweight element to enclose a set of custom properties:
120 \snippet doc/src/snippets/declarative/qtobject.qml 0
122 It can also be useful for C++ integration, as it is just a plain
123 QObject. See the QObject documentation for further details.
126 \qmlproperty string QML:QtObject::objectName
127 This property holds the QObject::objectName for this specific object instance.
129 This allows a C++ application to locate an item within a QML component
130 using the QObject::findChild() method. For example, the following C++
131 application locates the child \l Rectangle item and dynamically changes its
140 width: 200; height: 200
153 QDeclarativeView view;
154 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
157 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
159 item->setProperty("color", QColor(Qt::yellow));
163 static bool qt_QmlQtModule_registered = false;
164 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
166 void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
168 qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
169 qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
170 qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
173 void QDeclarativeEnginePrivate::defineModule()
175 registerBaseTypes("QtQuick", 2, 0);
176 qmlRegisterType<QDeclarativeBinding>();
180 \qmlclass QML:Qt QDeclarativeEnginePrivate
181 \ingroup qml-utility-elements
182 \brief The QML global Qt object provides useful enums and functions from Qt.
184 \keyword QmlGlobalQtObject
186 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
188 The \c Qt object is a global object with utility functions, properties and enums.
190 It is not instantiable; to use it, call the members of the global \c Qt object directly.
197 color: Qt.rgba(1, 0, 0, 1)
198 text: Qt.md5("hello, world")
205 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
206 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
210 The Qt object also contains helper functions for creating objects of specific
211 data types. This is primarily useful when setting the properties of an item
212 when the property has one of the following types:
215 \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()}
216 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
217 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
218 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
219 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
222 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
224 \section1 Date/Time Formatters
226 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
229 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
230 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
231 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
234 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
237 \section1 Dynamic Object Creation
238 The following functions on the global object allow you to dynamically create QML
239 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
243 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
244 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
250 \qmlproperty object QML:Qt::application
253 The \c application object provides access to global application state
254 properties shared by many QML components.
260 \o \c application.active
262 This read-only property indicates whether the application is the top-most and focused
263 application, and the user is able to interact with the application. The property
264 is false when the application is in the background, the device keylock or screen
265 saver is active, the screen backlight is turned off, or the global system dialog
266 is being displayed on top of the application. It can be used for stopping and
267 pausing animations, timers and active processing of data in order to save device
268 battery power and free device memory and processor load when the application is not
272 \o \c application.layoutDirection
274 This read-only property can be used to query the default layout direction of the
275 application. On system start-up, the default layout direction depends on the
276 application's language. The property has a value of \c Qt.RightToLeft in locales
277 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
278 where the reading direction flows from left to right. You can bind to this
279 property to customize your application layouts to support both layout directions.
284 \o Qt.LeftToRight - Text and graphics elements should be positioned
286 \o Qt.RightToLeft - Text and graphics elements should be positioned
291 The following example uses the \c application object to indicate
292 whether the application is currently active:
294 \snippet doc/src/snippets/declarative/application.qml document
300 \qmlmethod object Qt::include(string url, jsobject callback)
302 Includes another JavaScript file. This method can only be used from within JavaScript files,
303 and not regular QML files.
305 This imports all functions from \a url into the current script's namespace.
307 Qt.include() returns an object that describes the status of the operation. The object has
308 a single property, \c {status}, that is set to one of the following values:
311 \header \o Symbol \o Value \o Description
312 \row \o result.OK \o 0 \o The include completed successfully.
313 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
314 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
315 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
316 An additional \c exception property will be set in this case.
319 The \c status property will be updated as the operation progresses.
321 If provided, \a callback is invoked when the operation completes. The callback is passed
322 the same object as is returned from the Qt.include() call.
324 // Qt.include() is implemented in qv8include.cpp
327 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
328 : captureProperties(false), rootContext(0), isDebugging(false),
329 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
330 cleanup(0), erroredBindings(0), inProgressCreations(0),
331 workerScriptEngine(0), activeVME(0),
332 networkAccessManager(0), networkAccessManagerFactory(0),
333 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
334 incubatorCount(0), incubationController(0), sgContext(0), mutex(QMutex::Recursive)
336 if (!qt_QmlQtModule_registered) {
337 qt_QmlQtModule_registered = true;
338 QDeclarativeUtilModule::defineModule();
339 QDeclarativeEnginePrivate::defineModule();
340 QSGItemsModule::defineModule();
341 QSGParticlesModule::defineModule();
342 QDeclarativeValueTypeFactory::registerValueTypes();
346 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
348 Q_ASSERT(inProgressCreations == 0);
351 QDeclarativeCleanup *c = cleanup;
353 if (cleanup) cleanup->prev = &cleanup;
359 doDeleteInEngineThread();
361 if (incubationController) incubationController->d = 0;
362 incubationController = 0;
367 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
369 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
371 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
373 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
374 delete (*iter)->qobjectApi;
379 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
381 QObjectPrivate *p = QObjectPrivate::get(o);
382 if (p->declarativeData) {
383 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
384 if (d->ownContext && d->context) {
385 d->context->destroy();
391 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
393 static_cast<QDeclarativeData *>(d)->destroyed(o);
396 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
398 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
401 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
403 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
406 void QDeclarativeEnginePrivate::init()
408 Q_Q(QDeclarativeEngine);
410 static bool firstTime = true;
412 // This is a nasty hack as QNetworkAccessManager will issue a
413 // BlockingQueuedConnection to the main thread if it is initialized for the
414 // first time on a non-main thread. This can cause a lockup if the main thread
415 // is blocking on the thread that initialize the network access manager.
416 QNetworkConfigurationManager man;
421 qRegisterMetaType<QVariant>("QVariant");
422 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
423 qRegisterMetaType<QJSValue>("QJSValue");
424 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
425 qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
426 qRegisterMetaType<QList<int> >("QList<int>");
427 qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
429 QDeclarativeData::init();
431 v8engine()->setEngine(q);
433 rootContext = new QDeclarativeContext(q,true);
435 if (QCoreApplication::instance()->thread() == q->thread() &&
436 QDeclarativeEngineDebugService::isDebuggingEnabled()) {
438 QDeclarativeEngineDebugService::instance()->addEngine(q);
439 QV8DebugService::instance()->addEngine(q);
440 QV8ProfilerService::instance()->addEngine(q);
444 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
446 Q_Q(QDeclarativeEngine);
447 if (!workerScriptEngine)
448 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
449 return workerScriptEngine;
453 \class QDeclarativeEngine
455 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
458 Each QML component is instantiated in a QDeclarativeContext.
459 QDeclarativeContext's are essential for passing data to QML
460 components. In QML, contexts are arranged hierarchically and this
461 hierarchy is managed by the QDeclarativeEngine.
463 Prior to creating any QML components, an application must have
464 created a QDeclarativeEngine to gain access to a QML context. The
465 following example shows how to create a simple Text item.
468 QDeclarativeEngine engine;
469 QDeclarativeComponent component(&engine);
470 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
471 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
473 //add item to view, etc
477 In this case, the Text item will be created in the engine's
478 \l {QDeclarativeEngine::rootContext()}{root context}.
480 \sa QDeclarativeComponent QDeclarativeContext
484 Create a new QDeclarativeEngine with the given \a parent.
486 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
487 : QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
489 Q_D(QDeclarativeEngine);
494 Destroys the QDeclarativeEngine.
496 Any QDeclarativeContext's created on this engine will be
497 invalidated, but not destroyed (unless they are parented to the
498 QDeclarativeEngine object).
500 QDeclarativeEngine::~QDeclarativeEngine()
502 Q_D(QDeclarativeEngine);
503 if (d->isDebugging) {
504 QDeclarativeEngineDebugService::instance()->remEngine(this);
505 QV8ProfilerService::instance()->removeEngine(this);
508 // if we are the parent of any of the qobject module api instances,
509 // we need to remove them from our internal list, in order to prevent
510 // a segfault in engine private dtor.
511 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
512 QObject *currQObjectApi = 0;
513 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
514 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
515 currInstance = d->moduleApiInstances.value(key);
516 currQObjectApi = currInstance->qobjectApi;
517 if (this->children().contains(currQObjectApi)) {
518 delete currQObjectApi;
520 d->moduleApiInstances.remove(key);
524 // ensure we clean up QObjects with JS ownership
528 /*! \fn void QDeclarativeEngine::quit()
529 This signal is emitted when the QML loaded by the engine would like to quit.
532 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
533 This signal is emitted when \a warnings messages are generated by QML.
537 Clears the engine's internal component cache.
539 Normally the QDeclarativeEngine caches components loaded from qml
540 files. This method clears this cache and forces the component to be
543 void QDeclarativeEngine::clearComponentCache()
545 Q_D(QDeclarativeEngine);
546 d->typeLoader.clearCache();
550 Returns the engine's root context.
552 The root context is automatically created by the QDeclarativeEngine.
553 Data that should be available to all QML component instances
554 instantiated by the engine should be put in the root context.
556 Additional data that should only be available to a subset of
557 component instances should be added to sub-contexts parented to the
560 QDeclarativeContext *QDeclarativeEngine::rootContext() const
562 Q_D(const QDeclarativeEngine);
563 return d->rootContext;
567 Sets the \a factory to use for creating QNetworkAccessManager(s).
569 QNetworkAccessManager is used for all network access by QML. By
570 implementing a factory it is possible to create custom
571 QNetworkAccessManager with specialized caching, proxy and cookie
574 The factory must be set before executing the engine.
576 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
578 Q_D(QDeclarativeEngine);
579 QMutexLocker locker(&d->mutex);
580 d->networkAccessManagerFactory = factory;
584 Returns the current QDeclarativeNetworkAccessManagerFactory.
586 \sa setNetworkAccessManagerFactory()
588 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
590 Q_D(const QDeclarativeEngine);
591 return d->networkAccessManagerFactory;
594 void QDeclarativeEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
597 activeVME->finalizeCallbacks.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
599 void *args[] = { 0 };
600 QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, args);
604 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
606 QMutexLocker locker(&mutex);
607 QNetworkAccessManager *nam;
608 if (networkAccessManagerFactory) {
609 nam = networkAccessManagerFactory->create(parent);
611 nam = new QNetworkAccessManager(parent);
617 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
619 Q_Q(const QDeclarativeEngine);
620 if (!networkAccessManager)
621 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
622 return networkAccessManager;
626 Returns a common QNetworkAccessManager which can be used by any QML
627 element instantiated by this engine.
629 If a QDeclarativeNetworkAccessManagerFactory has been set and a
630 QNetworkAccessManager has not yet been created, the
631 QDeclarativeNetworkAccessManagerFactory will be used to create the
632 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
633 will have no proxy or cache set.
635 \sa setNetworkAccessManagerFactory()
637 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
639 Q_D(const QDeclarativeEngine);
640 return d->getNetworkAccessManager();
645 Sets the \a provider to use for images requested via the \e
646 image: url scheme, with host \a providerId. The QDeclarativeEngine
647 takes ownership of \a provider.
649 Image providers enable support for pixmap and threaded image
650 requests. See the QDeclarativeImageProvider documentation for details on
651 implementing and using image providers.
653 All required image providers should be added to the engine before any
654 QML sources files are loaded.
656 \sa removeImageProvider()
658 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
660 Q_D(QDeclarativeEngine);
661 QMutexLocker locker(&d->mutex);
662 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
666 Returns the QDeclarativeImageProvider set for \a providerId.
668 Returns the provider if it was found; otherwise returns 0.
670 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
672 Q_D(const QDeclarativeEngine);
673 QMutexLocker locker(&d->mutex);
674 return d->imageProviders.value(providerId).data();
678 Removes the QDeclarativeImageProvider for \a providerId.
680 \sa addImageProvider()
682 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
684 Q_D(QDeclarativeEngine);
685 QMutexLocker locker(&d->mutex);
686 d->imageProviders.take(providerId);
689 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
691 QMutexLocker locker(&mutex);
692 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
695 return provider->imageType();
696 return QDeclarativeImageProvider::Invalid;
699 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
701 QMutexLocker locker(&mutex);
702 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
705 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
706 return provider->requestTexture(imageId, size, req_size);
711 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
713 QMutexLocker locker(&mutex);
715 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
718 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
719 image = provider->requestImage(imageId, size, req_size);
724 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
726 QMutexLocker locker(&mutex);
728 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
731 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
732 pixmap = provider->requestPixmap(imageId, size, req_size);
738 Return the base URL for this engine. The base URL is only used to
739 resolve components when a relative URL is passed to the
740 QDeclarativeComponent constructor.
742 If a base URL has not been explicitly set, this method returns the
743 application's current working directory.
747 QUrl QDeclarativeEngine::baseUrl() const
749 Q_D(const QDeclarativeEngine);
750 if (d->baseUrl.isEmpty()) {
751 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
758 Set the base URL for this engine to \a url.
762 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
764 Q_D(QDeclarativeEngine);
769 Returns true if warning messages will be output to stderr in addition
770 to being emitted by the warnings() signal, otherwise false.
772 The default value is true.
774 bool QDeclarativeEngine::outputWarningsToStandardError() const
776 Q_D(const QDeclarativeEngine);
777 return d->outputWarningsToStdErr;
781 Set whether warning messages will be output to stderr to \a enabled.
783 If \a enabled is true, any warning messages generated by QML will be
784 output to stderr and emitted by the warnings() signal. If \a enabled
785 is false, on the warnings() signal will be emitted. This allows
786 applications to handle warning output themselves.
788 The default value is true.
790 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
792 Q_D(QDeclarativeEngine);
793 d->outputWarningsToStdErr = enabled;
797 Attempt to free unused memory.
799 void QDeclarativeEngine::collectGarbage()
805 Returns the QDeclarativeContext for the \a object, or 0 if no
806 context has been set.
808 When the QDeclarativeEngine instantiates a QObject, the context is
811 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
816 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
818 QDeclarativeData *data =
819 static_cast<QDeclarativeData *>(priv->declarativeData);
823 else if (data->outerContext)
824 return data->outerContext->asQDeclarativeContext();
830 Sets the QDeclarativeContext for the \a object to \a context.
831 If the \a object already has a context, a warning is
832 output, but the context is not changed.
834 When the QDeclarativeEngine instantiates a QObject, the context is
837 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
839 if (!object || !context)
842 QDeclarativeData *data = QDeclarativeData::get(object, true);
844 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
848 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
849 contextData->addObject(object);
853 \enum QDeclarativeEngine::ObjectOwnership
855 Ownership controls whether or not QML automatically destroys the
856 QObject when the object is garbage collected by the JavaScript
857 engine. The two ownership options are:
859 \value CppOwnership The object is owned by C++ code, and will
860 never be deleted by QML. The JavaScript destroy() method cannot be
861 used on objects with CppOwnership. This option is similar to
862 QScriptEngine::QtOwnership.
864 \value JavaScriptOwnership The object is owned by JavaScript.
865 When the object is returned to QML as the return value of a method
866 call or property access, QML will delete the object if there are no
867 remaining JavaScript references to it and it has no
868 QObject::parent(). This option is similar to
869 QScriptEngine::ScriptOwnership.
871 Generally an application doesn't need to set an object's ownership
872 explicitly. QML uses a heuristic to set the default object
873 ownership. By default, an object that is created by QML has
874 JavaScriptOwnership. The exception to this are the root objects
875 created by calling QDeclarativeCompnent::create() or
876 QDeclarativeComponent::beginCreate() which have CppOwnership by
877 default. The ownership of these root-level objects is considered to
878 have been transferred to the C++ caller.
880 Objects not-created by QML have CppOwnership by default. The
881 exception to this is objects returned from a C++ method call. The
882 ownership of these objects is passed to JavaScript.
884 Calling setObjectOwnership() overrides the default ownership
885 heuristic used by QML.
889 Sets the \a ownership of \a object.
891 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
896 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
900 ddata->indestructible = (ownership == CppOwnership)?true:false;
901 ddata->explicitIndestructibleSet = true;
905 Returns the ownership of \a object.
907 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
912 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
916 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
919 bool QDeclarativeEngine::event(QEvent *e)
921 Q_D(QDeclarativeEngine);
922 if (e->type() == QEvent::User)
923 d->doDeleteInEngineThread();
925 return QJSEngine::event(e);
928 void QDeclarativeEnginePrivate::doDeleteInEngineThread()
930 QFieldList<Deletable, &Deletable::next> list;
932 list.copyAndClear(toDeleteInEngineThread);
935 while (Deletable *d = list.takeFirst())
939 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
941 QDeclarativeData *data = QDeclarativeData::get(object);
943 if (data && data->deferredComponent) {
944 if (QDeclarativeDebugService::isDebuggingEnabled()) {
945 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
946 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
947 QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(object->metaObject()->className());
948 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
949 if (data->outerContext)
950 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
952 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
954 QDeclarativeComponentPrivate::ConstructionState state;
955 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
957 data->deferredComponent->release();
958 data->deferredComponent = 0;
960 QDeclarativeComponentPrivate::complete(ep, &state);
961 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
965 QDeclarativeContext *qmlContext(const QObject *obj)
967 return QDeclarativeEngine::contextForObject(obj);
970 QDeclarativeEngine *qmlEngine(const QObject *obj)
972 QDeclarativeData *data = QDeclarativeData::get(obj, false);
973 if (!data || !data->context)
975 return data->context->engine;
978 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
980 QDeclarativeData *data = QDeclarativeData::get(object);
982 return 0; // Attached properties are only on objects created by QML
984 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
988 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
992 rv = pf(const_cast<QObject *>(object));
995 data->attachedProperties()->insert(id, rv);
1000 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1001 const QMetaObject *attachedMetaObject, bool create)
1004 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1006 if (*idCache == -1 || !object)
1009 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1012 QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
1014 #ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
1015 if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
1016 qWarning("Qml debugging is enabled. Only use this in a safe environment!");
1018 QDeclarativeEnginePrivate::qml_debugging_enabled = true;
1023 class QDeclarativeDataExtended {
1025 QDeclarativeDataExtended();
1026 ~QDeclarativeDataExtended();
1028 QHash<int, QObject *> attachedProperties;
1029 QDeclarativeNotifier objectNameNotifier;
1032 QDeclarativeDataExtended::QDeclarativeDataExtended()
1036 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1040 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1042 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1043 return &extendedData->objectNameNotifier;
1046 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1048 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1049 return &extendedData->attachedProperties;
1052 void QDeclarativeData::destroyed(QObject *object)
1054 if (deferredComponent)
1055 deferredComponent->release();
1057 if (nextContextObject)
1058 nextContextObject->prevContextObject = prevContextObject;
1059 if (prevContextObject)
1060 *prevContextObject = nextContextObject;
1062 QDeclarativeAbstractBinding *binding = bindings;
1064 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1065 binding->m_prevBinding = 0;
1066 binding->m_nextBinding = 0;
1075 propertyCache->release();
1077 if (ownContext && context)
1081 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1082 *guard = (QObject *)0;
1083 guard->objectDestroyed(object);
1087 delete extendedData;
1089 v8object.Clear(); // The WeakReference handler will clean the actual handle
1095 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1101 void QDeclarativeData::objectNameChanged(QObject *)
1103 if (extendedData) objectNameNotifier()->notify();
1106 bool QDeclarativeData::hasBindingBit(int bit) const
1108 if (bindingBitsSize > bit)
1109 return bindingBits[bit / 32] & (1 << (bit % 32));
1114 void QDeclarativeData::clearBindingBit(int bit)
1116 if (bindingBitsSize > bit)
1117 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1120 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1122 if (bindingBitsSize <= bit) {
1123 int props = obj->metaObject()->propertyCount();
1124 Q_ASSERT(bit < props);
1126 int arraySize = (props + 31) / 32;
1127 int oldArraySize = bindingBitsSize / 32;
1129 bindingBits = (quint32 *)realloc(bindingBits,
1130 arraySize * sizeof(quint32));
1132 memset(bindingBits + oldArraySize,
1134 sizeof(quint32) * (arraySize - oldArraySize));
1136 bindingBitsSize = arraySize * 32;
1139 bindingBits[bit / 32] |= (1 << (bit % 32));
1142 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1144 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1145 if (url.authority().isEmpty())
1146 return QLatin1Char(':') + url.path();
1149 return url.toLocalFile();
1153 static QString toLocalFile(const QString &url)
1155 if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
1158 QString file = url.mid(7);
1160 //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
1162 // magic for drives on windows
1163 if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
1169 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
1171 if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
1172 if (url.length() > 4)
1173 return QLatin1Char(':') + url.mid(4);
1177 return toLocalFile(url);
1180 void QDeclarativeEnginePrivate::sendQuit()
1182 Q_Q(QDeclarativeEngine);
1184 if (q->receivers(SIGNAL(quit())) == 0) {
1185 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1189 static void dumpwarning(const QDeclarativeError &error)
1191 qWarning().nospace() << qPrintable(error.toString());
1194 static void dumpwarning(const QList<QDeclarativeError> &errors)
1196 for (int ii = 0; ii < errors.count(); ++ii)
1197 dumpwarning(errors.at(ii));
1200 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1202 Q_Q(QDeclarativeEngine);
1203 q->warnings(QList<QDeclarativeError>() << error);
1204 if (outputWarningsToStdErr)
1208 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1210 Q_Q(QDeclarativeEngine);
1211 q->warnings(errors);
1212 if (outputWarningsToStdErr)
1213 dumpwarning(errors);
1216 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1219 QDeclarativeEnginePrivate::get(engine)->warning(error);
1224 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1227 QDeclarativeEnginePrivate::get(engine)->warning(error);
1232 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1235 engine->warning(error);
1240 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1243 engine->warning(error);
1249 This function should be called prior to evaluation of any js expression,
1250 so that scarce resources are not freed prematurely (eg, if there is a
1251 nested javascript expression).
1253 void QDeclarativeEnginePrivate::referenceScarceResources()
1255 scarceResourcesRefCount += 1;
1259 This function should be called after evaluation of the js expression is
1260 complete, and so the scarce resources may be freed safely.
1262 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1264 Q_ASSERT(scarceResourcesRefCount > 0);
1265 scarceResourcesRefCount -= 1;
1267 // if the refcount is zero, then evaluation of the "top level"
1268 // expression must have completed. We can safely release the
1269 // scarce resources.
1270 if (scarceResourcesRefCount == 0) {
1271 // iterate through the list and release them all.
1272 // note that the actual SRD is owned by the JS engine,
1273 // so we cannot delete the SRD; but we can free the
1274 // memory used by the variant in the SRD.
1275 while (ScarceResourceData *sr = scarceResources.first()) {
1276 sr->data = QVariant();
1277 scarceResources.remove(sr);
1283 Adds \a path as a directory where the engine searches for
1284 installed modules in a URL-based directory structure.
1285 The \a path may be a local filesystem directory or a URL.
1287 The newly added \a path will be first in the importPathList().
1289 \sa setImportPathList(), {QML Modules}
1291 void QDeclarativeEngine::addImportPath(const QString& path)
1293 Q_D(QDeclarativeEngine);
1294 d->importDatabase.addImportPath(path);
1298 Returns the list of directories where the engine searches for
1299 installed modules in a URL-based directory structure.
1301 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1302 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1303 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1304 provided by that module. A \c qmldir file is required for defining the
1305 type version mapping and possibly declarative extensions plugins.
1307 By default, the list contains the directory of the application executable,
1308 paths specified in the \c QML_IMPORT_PATH environment variable,
1309 and the builtin \c ImportsPath from QLibraryInfo.
1311 \sa addImportPath() setImportPathList()
1313 QStringList QDeclarativeEngine::importPathList() const
1315 Q_D(const QDeclarativeEngine);
1316 return d->importDatabase.importPathList();
1320 Sets \a paths as the list of directories where the engine searches for
1321 installed modules in a URL-based directory structure.
1323 By default, the list contains the directory of the application executable,
1324 paths specified in the \c QML_IMPORT_PATH environment variable,
1325 and the builtin \c ImportsPath from QLibraryInfo.
1327 \sa importPathList() addImportPath()
1329 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1331 Q_D(QDeclarativeEngine);
1332 d->importDatabase.setImportPathList(paths);
1337 Adds \a path as a directory where the engine searches for
1338 native plugins for imported modules (referenced in the \c qmldir file).
1340 By default, the list contains only \c ., i.e. the engine searches
1341 in the directory of the \c qmldir file itself.
1343 The newly added \a path will be first in the pluginPathList().
1345 \sa setPluginPathList()
1347 void QDeclarativeEngine::addPluginPath(const QString& path)
1349 Q_D(QDeclarativeEngine);
1350 d->importDatabase.addPluginPath(path);
1355 Returns the list of directories where the engine searches for
1356 native plugins for imported modules (referenced in the \c qmldir file).
1358 By default, the list contains only \c ., i.e. the engine searches
1359 in the directory of the \c qmldir file itself.
1361 \sa addPluginPath() setPluginPathList()
1363 QStringList QDeclarativeEngine::pluginPathList() const
1365 Q_D(const QDeclarativeEngine);
1366 return d->importDatabase.pluginPathList();
1370 Sets the list of directories where the engine searches for
1371 native plugins for imported modules (referenced in the \c qmldir file)
1374 By default, the list contains only \c ., i.e. the engine searches
1375 in the directory of the \c qmldir file itself.
1377 \sa pluginPathList() addPluginPath()
1379 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1381 Q_D(QDeclarativeEngine);
1382 d->importDatabase.setPluginPathList(paths);
1386 Imports the plugin named \a filePath with the \a uri provided.
1387 Returns true if the plugin was successfully imported; otherwise returns false.
1389 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1391 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1393 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1395 Q_D(QDeclarativeEngine);
1396 return d->importDatabase.importPlugin(filePath, uri, errors);
1400 Imports the plugin named \a filePath with the \a uri provided.
1401 Returns true if the plugin was successfully imported; otherwise returns false.
1403 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1405 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1407 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1409 Q_D(QDeclarativeEngine);
1410 QList<QDeclarativeError> errors;
1411 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1412 if (!errors.isEmpty()) {
1414 for (int i = 0; i < errors.size(); ++i) {
1415 builtError = QString(QLatin1String("%1\n %2"))
1417 .arg(errors.at(i).toString());
1419 *errorString = builtError;
1425 \property QDeclarativeEngine::offlineStoragePath
1426 \brief the directory for storing offline user data
1428 Returns the directory where SQL and other offline
1431 QDeclarativeWebView and the SQL databases created with openDatabase()
1434 The default is QML/OfflineStorage in the platform-standard
1435 user application data directory.
1437 Note that the path may not currently exist on the filesystem, so
1438 callers wanting to \e create new files at this location should create
1439 it first - see QDir::mkpath().
1441 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1443 Q_D(QDeclarativeEngine);
1444 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1447 QString QDeclarativeEngine::offlineStoragePath() const
1449 Q_D(const QDeclarativeEngine);
1450 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1453 static void voidptr_destructor(void *v)
1455 void **ptr = (void **)v;
1459 static void *voidptr_constructor(const void *v)
1464 return new void*(*(void **)v);
1468 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1470 Q_Q(QDeclarativeEngine);
1472 if (!mo->superClass()) {
1473 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1474 propertyCache.insert(mo, rv);
1477 QDeclarativePropertyCache *super = cache(mo->superClass());
1478 QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() -
1479 mo->superClass()->propertyCount() -
1480 mo->superClass()->methodCount());
1482 propertyCache.insert(mo, rv);
1487 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1488 QDeclarativeError &error)
1490 QList<QDeclarativeType *> types;
1492 int maxMinorVersion = 0;
1494 const QMetaObject *metaObject = type->metaObject();
1496 while (metaObject) {
1497 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1498 type->majorVersion(), minorVersion);
1500 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1506 metaObject = metaObject->superClass();
1509 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1511 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1515 QDeclarativePropertyCache *raw = cache(type->metaObject());
1517 bool hasCopied = false;
1519 for (int ii = 0; ii < types.count(); ++ii) {
1520 QDeclarativeType *currentType = types.at(ii);
1524 int rev = currentType->metaObjectRevision();
1525 int moIndex = types.count() - 1 - ii;
1527 if (raw->allowedRevisionCache[moIndex] != rev) {
1532 raw->allowedRevisionCache[moIndex] = rev;
1536 // Test revision compatibility - the basic rule is:
1537 // * Anything that is excluded, cannot overload something that is not excluded *
1539 // Signals override:
1540 // * other signals and methods of the same name.
1541 // * properties named on<Signal Name>
1542 // * automatic <property name>Changed notify signals
1544 // Methods override:
1545 // * other methods of the same name
1547 // Properties override:
1548 // * other elements of the same name
1550 bool overloadError = false;
1551 QString overloadName;
1554 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1555 !overloadError && iter != raw->stringCache.end();
1558 QDeclarativePropertyCache::Data *d = *iter;
1559 if (raw->isAllowedInRevision(d))
1560 continue; // Not excluded - no problems
1562 // check that a regular "name" overload isn't happening
1563 QDeclarativePropertyCache::Data *current = d;
1564 while (!overloadError && current) {
1565 current = d->overrideData(current);
1566 if (current && raw->isAllowedInRevision(current))
1567 overloadError = true;
1572 if (overloadError) {
1573 if (hasCopied) raw->release();
1575 error.setDescription(QLatin1String("Type ") + 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."));
1579 if (!hasCopied) raw->addref();
1580 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1582 if (minorVersion != maxMinorVersion) {
1584 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1590 QDeclarativeMetaType::ModuleApiInstance *
1591 QDeclarativeEnginePrivate::moduleApiInstance(const QDeclarativeMetaType::ModuleApi &module)
1593 Locker locker(this);
1595 QDeclarativeMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
1597 a = new QDeclarativeMetaType::ModuleApiInstance;
1598 a->scriptCallback = module.script;
1599 a->qobjectCallback = module.qobject;
1600 moduleApiInstances.insert(module, a);
1606 bool QDeclarativeEnginePrivate::isQObject(int t)
1608 Locker locker(this);
1609 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1612 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1614 Locker locker(this);
1615 int t = v.userType();
1616 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1618 return *(QObject **)(v.constData());
1620 return QDeclarativeMetaType::toQObject(v, ok);
1624 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1626 Locker locker(this);
1627 if (m_compositeTypes.contains(t))
1628 return QDeclarativeMetaType::Object;
1629 else if (m_qmlLists.contains(t))
1630 return QDeclarativeMetaType::List;
1632 return QDeclarativeMetaType::typeCategory(t);
1635 bool QDeclarativeEnginePrivate::isList(int t) const
1637 Locker locker(this);
1638 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1641 int QDeclarativeEnginePrivate::listType(int t) const
1643 Locker locker(this);
1644 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1645 if (iter != m_qmlLists.end())
1648 return QDeclarativeMetaType::listType(t);
1651 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1653 Locker locker(this);
1654 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1655 if (iter != m_compositeTypes.end()) {
1656 return (*iter)->root;
1658 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1659 return type?type->baseMetaObject():0;
1663 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1665 Locker locker(this);
1666 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1667 if (iter != m_compositeTypes.end()) {
1668 return (*iter)->root;
1670 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1671 return type?type->metaObject():0;
1675 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1677 QByteArray name = data->root->className();
1679 QByteArray ptr = name + '*';
1680 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1682 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1683 voidptr_constructor);
1684 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1685 voidptr_constructor);
1689 Locker locker(this);
1690 m_qmlLists.insert(lst_type, ptr_type);
1691 m_compositeTypes.insert(ptr_type, data);
1694 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1696 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1697 QFileInfo info(fileName);
1699 QString absolute = info.absoluteFilePath();
1701 #if defined(Q_OS_MAC)
1702 QString canonical = info.canonicalFilePath();
1703 #elif defined(Q_OS_WIN32)
1704 wchar_t buffer[1024];
1706 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1707 if (rv == 0 || rv >= 1024) return true;
1708 rv = ::GetLongPathName(buffer, buffer, 1024);
1709 if (rv == 0 || rv >= 1024) return true;
1711 QString canonical((QChar *)buffer);
1714 int absoluteLength = absolute.length();
1715 int canonicalLength = canonical.length();
1717 int length = qMin(absoluteLength, canonicalLength);
1718 for (int ii = 0; ii < length; ++ii) {
1719 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1720 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1722 if (a.toLower() != c.toLower())
1734 \fn QDeclarativeEngine *qmlEngine(const QObject *object)
1735 \relates QDeclarativeEngine
1737 Returns the QDeclarativeEngine associated with \a object, if any. This is equivalent to
1738 QDeclarativeEngine::contextForObject(object)->engine(), but more efficient.
1742 \fn QDeclarativeContext *qmlContext(const QObject *object)
1743 \relates QDeclarativeEngine
1745 Returns the QDeclarativeContext associated with \a object, if any. This is equivalent to
1746 QDeclarativeEngine::contextForObject(object).