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"
72 #include <QtCore/qmetaobject.h>
73 #include <QNetworkReply>
74 #include <QNetworkRequest>
75 #include <QNetworkAccessManager>
80 #include <QMetaObject>
83 #include <QPluginLoader>
84 #include <QtGui/qfontdatabase.h>
85 #include <QtCore/qlibraryinfo.h>
86 #include <QtCore/qthreadstorage.h>
87 #include <QtCore/qthread.h>
88 #include <QtCore/qcoreapplication.h>
89 #include <QtCore/qdir.h>
90 #include <QtCore/qmutex.h>
91 #include <QtGui/qcolor.h>
92 #include <QtCore/qcryptographichash.h>
94 #include <private/qobject_p.h>
96 #include <private/qdeclarativeutilmodule_p.h>
97 #include <private/qsgitemsmodule_p.h>
98 #include <private/qsgparticlesmodule_p.h>
99 #include <qsgtexture.h>
101 #ifdef Q_OS_WIN // for %APPDATA%
102 #include <qt_windows.h>
103 #include <qlibrary.h>
106 #define CSIDL_APPDATA 0x001a // <username>\Application Data
109 Q_DECLARE_METATYPE(QDeclarativeProperty)
113 void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
115 QDeclarativeEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
116 QDeclarativeValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
117 QDeclarativeUtilModule::registerBaseTypes(uri, versionMajor, versionMinor);
121 \qmlclass QtObject QObject
122 \ingroup qml-utility-elements
124 \brief The QtObject element is the most basic element in QML.
126 The QtObject element is a non-visual element which contains only the
129 It can be useful to create a QtObject if you need an extremely
130 lightweight element to enclose a set of custom properties:
132 \snippet doc/src/snippets/declarative/qtobject.qml 0
134 It can also be useful for C++ integration, as it is just a plain
135 QObject. See the QObject documentation for further details.
138 \qmlproperty string QML:QtObject::objectName
139 This property holds the QObject::objectName for this specific object instance.
141 This allows a C++ application to locate an item within a QML component
142 using the QObject::findChild() method. For example, the following C++
143 application locates the child \l Rectangle item and dynamically changes its
152 width: 200; height: 200
165 QDeclarativeView view;
166 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
169 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
171 item->setProperty("color", QColor(Qt::yellow));
175 static bool qt_QmlQtModule_registered = false;
176 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
178 void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
180 qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
181 qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
182 qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
185 void QDeclarativeEnginePrivate::defineModule()
187 registerBaseTypes("QtQuick", 2, 0);
188 qmlRegisterType<QDeclarativeBinding>();
192 \qmlclass QML:Qt QDeclarativeEnginePrivate
193 \ingroup qml-utility-elements
194 \brief The QML global Qt object provides useful enums and functions from Qt.
196 \keyword QmlGlobalQtObject
198 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
200 The \c Qt object is a global object with utility functions, properties and enums.
202 It is not instantiable; to use it, call the members of the global \c Qt object directly.
209 color: Qt.rgba(1, 0, 0, 1)
210 text: Qt.md5("hello, world")
217 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
218 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
222 The Qt object also contains helper functions for creating objects of specific
223 data types. This is primarily useful when setting the properties of an item
224 when the property has one of the following types:
227 \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()}
228 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
229 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
230 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
231 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
234 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
236 \section1 Date/Time Formatters
238 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
241 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
242 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
243 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
246 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
249 \section1 Dynamic Object Creation
250 The following functions on the global object allow you to dynamically create QML
251 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
255 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
256 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
262 \qmlproperty object QML:Qt::application
265 The \c application object provides access to global application state
266 properties shared by many QML components.
272 \o \c application.active
274 This read-only property indicates whether the application is the top-most and focused
275 application, and the user is able to interact with the application. The property
276 is false when the application is in the background, the device keylock or screen
277 saver is active, the screen backlight is turned off, or the global system dialog
278 is being displayed on top of the application. It can be used for stopping and
279 pausing animations, timers and active processing of data in order to save device
280 battery power and free device memory and processor load when the application is not
284 \o \c application.layoutDirection
286 This read-only property can be used to query the default layout direction of the
287 application. On system start-up, the default layout direction depends on the
288 application's language. The property has a value of \c Qt.RightToLeft in locales
289 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
290 where the reading direction flows from left to right. You can bind to this
291 property to customize your application layouts to support both layout directions.
296 \o Qt.LeftToRight - Text and graphics elements should be positioned
298 \o Qt.RightToLeft - Text and graphics elements should be positioned
303 The following example uses the \c application object to indicate
304 whether the application is currently active:
306 \snippet doc/src/snippets/declarative/application.qml document
312 \qmlmethod object Qt::include(string url, jsobject callback)
314 Includes another JavaScript file. This method can only be used from within JavaScript files,
315 and not regular QML files.
317 This imports all functions from \a url into the current script's namespace.
319 Qt.include() returns an object that describes the status of the operation. The object has
320 a single property, \c {status}, that is set to one of the following values:
323 \header \o Symbol \o Value \o Description
324 \row \o result.OK \o 0 \o The include completed successfully.
325 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
326 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
327 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
328 An additional \c exception property will be set in this case.
331 The \c status property will be updated as the operation progresses.
333 If provided, \a callback is invoked when the operation completes. The callback is passed
334 the same object as is returned from the Qt.include() call.
336 // Qt.include() is implemented in qv8include.cpp
339 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
340 : captureProperties(false), rootContext(0), isDebugging(false),
341 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
342 cleanup(0), erroredBindings(0), inProgressCreations(0),
343 workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
344 networkAccessManager(0), networkAccessManagerFactory(0),
345 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
348 if (!qt_QmlQtModule_registered) {
349 qt_QmlQtModule_registered = true;
350 QDeclarativeUtilModule::defineModule();
351 QDeclarativeEnginePrivate::defineModule();
352 QSGItemsModule::defineModule();
353 QSGParticlesModule::defineModule();
354 QDeclarativeValueTypeFactory::registerValueTypes();
358 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
360 Q_ASSERT(inProgressCreations == 0);
361 Q_ASSERT(bindValues.isEmpty());
362 Q_ASSERT(parserStatus.isEmpty());
365 QDeclarativeCleanup *c = cleanup;
367 if (cleanup) cleanup->prev = &cleanup;
376 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
378 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
380 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
382 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
383 delete (*iter)->qobjectApi;
388 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
393 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
395 for (int ii = 0; ii < pss.count; ++ii) {
396 QDeclarativeParserStatus *ps = pss.at(ii);
403 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
405 QObjectPrivate *p = QObjectPrivate::get(o);
406 if (p->declarativeData) {
407 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
408 if (d->ownContext && d->context) {
409 d->context->destroy();
415 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
417 static_cast<QDeclarativeData *>(d)->destroyed(o);
420 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
422 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
425 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
427 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
430 void QDeclarativeEnginePrivate::init()
432 Q_Q(QDeclarativeEngine);
433 qRegisterMetaType<QVariant>("QVariant");
434 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
435 qRegisterMetaType<QJSValue>("QJSValue");
436 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
437 qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
438 qRegisterMetaType<QList<int> >("QList<int>");
439 qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
441 QDeclarativeData::init();
443 v8engine()->setEngine(q);
445 rootContext = new QDeclarativeContext(q,true);
447 if (QCoreApplication::instance()->thread() == q->thread() &&
448 QDeclarativeEngineDebugService::isDebuggingEnabled()) {
450 QDeclarativeEngineDebugService::instance()->addEngine(q);
451 QV8DebugService::instance()->addEngine(q);
455 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
457 Q_Q(QDeclarativeEngine);
458 if (!workerScriptEngine)
459 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
460 return workerScriptEngine;
464 \class QDeclarativeEngine
466 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
469 Each QML component is instantiated in a QDeclarativeContext.
470 QDeclarativeContext's are essential for passing data to QML
471 components. In QML, contexts are arranged hierarchically and this
472 hierarchy is managed by the QDeclarativeEngine.
474 Prior to creating any QML components, an application must have
475 created a QDeclarativeEngine to gain access to a QML context. The
476 following example shows how to create a simple Text item.
479 QDeclarativeEngine engine;
480 QDeclarativeComponent component(&engine);
481 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
482 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
484 //add item to view, etc
488 In this case, the Text item will be created in the engine's
489 \l {QDeclarativeEngine::rootContext()}{root context}.
491 \sa QDeclarativeComponent QDeclarativeContext
495 Create a new QDeclarativeEngine with the given \a parent.
497 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
498 : QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
500 Q_D(QDeclarativeEngine);
505 Destroys the QDeclarativeEngine.
507 Any QDeclarativeContext's created on this engine will be
508 invalidated, but not destroyed (unless they are parented to the
509 QDeclarativeEngine object).
511 QDeclarativeEngine::~QDeclarativeEngine()
513 Q_D(QDeclarativeEngine);
515 QDeclarativeEngineDebugService::instance()->remEngine(this);
517 // if we are the parent of any of the qobject module api instances,
518 // we need to remove them from our internal list, in order to prevent
519 // a segfault in engine private dtor.
520 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
521 QObject *currQObjectApi = 0;
522 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
523 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
524 currInstance = d->moduleApiInstances.value(key);
525 currQObjectApi = currInstance->qobjectApi;
526 if (this->children().contains(currQObjectApi)) {
527 delete currQObjectApi;
529 d->moduleApiInstances.remove(key);
534 /*! \fn void QDeclarativeEngine::quit()
535 This signal is emitted when the QML loaded by the engine would like to quit.
538 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
539 This signal is emitted when \a warnings messages are generated by QML.
543 Clears the engine's internal component cache.
545 Normally the QDeclarativeEngine caches components loaded from qml
546 files. This method clears this cache and forces the component to be
549 void QDeclarativeEngine::clearComponentCache()
551 Q_D(QDeclarativeEngine);
552 d->typeLoader.clearCache();
556 Returns the engine's root context.
558 The root context is automatically created by the QDeclarativeEngine.
559 Data that should be available to all QML component instances
560 instantiated by the engine should be put in the root context.
562 Additional data that should only be available to a subset of
563 component instances should be added to sub-contexts parented to the
566 QDeclarativeContext *QDeclarativeEngine::rootContext() const
568 Q_D(const QDeclarativeEngine);
569 return d->rootContext;
573 Sets the \a factory to use for creating QNetworkAccessManager(s).
575 QNetworkAccessManager is used for all network access by QML. By
576 implementing a factory it is possible to create custom
577 QNetworkAccessManager with specialized caching, proxy and cookie
580 The factory must be set before executing the engine.
582 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
584 Q_D(QDeclarativeEngine);
585 QMutexLocker locker(&d->mutex);
586 d->networkAccessManagerFactory = factory;
590 Returns the current QDeclarativeNetworkAccessManagerFactory.
592 \sa setNetworkAccessManagerFactory()
594 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
596 Q_D(const QDeclarativeEngine);
597 return d->networkAccessManagerFactory;
600 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
602 QMutexLocker locker(&mutex);
603 QNetworkAccessManager *nam;
604 if (networkAccessManagerFactory) {
605 nam = networkAccessManagerFactory->create(parent);
607 nam = new QNetworkAccessManager(parent);
613 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
615 Q_Q(const QDeclarativeEngine);
616 if (!networkAccessManager)
617 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
618 return networkAccessManager;
622 Returns a common QNetworkAccessManager which can be used by any QML
623 element instantiated by this engine.
625 If a QDeclarativeNetworkAccessManagerFactory has been set and a
626 QNetworkAccessManager has not yet been created, the
627 QDeclarativeNetworkAccessManagerFactory will be used to create the
628 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
629 will have no proxy or cache set.
631 \sa setNetworkAccessManagerFactory()
633 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
635 Q_D(const QDeclarativeEngine);
636 return d->getNetworkAccessManager();
641 Sets the \a provider to use for images requested via the \e
642 image: url scheme, with host \a providerId. The QDeclarativeEngine
643 takes ownership of \a provider.
645 Image providers enable support for pixmap and threaded image
646 requests. See the QDeclarativeImageProvider documentation for details on
647 implementing and using image providers.
649 All required image providers should be added to the engine before any
650 QML sources files are loaded.
652 \sa removeImageProvider()
654 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
656 Q_D(QDeclarativeEngine);
657 QMutexLocker locker(&d->mutex);
658 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
662 Returns the QDeclarativeImageProvider set for \a providerId.
664 Returns the provider if it was found; otherwise returns 0.
666 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
668 Q_D(const QDeclarativeEngine);
669 QMutexLocker locker(&d->mutex);
670 return d->imageProviders.value(providerId).data();
674 Removes the QDeclarativeImageProvider for \a providerId.
676 \sa addImageProvider()
678 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
680 Q_D(QDeclarativeEngine);
681 QMutexLocker locker(&d->mutex);
682 d->imageProviders.take(providerId);
685 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
687 QMutexLocker locker(&mutex);
688 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
691 return provider->imageType();
692 return QDeclarativeImageProvider::Invalid;
695 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
697 QMutexLocker locker(&mutex);
698 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
701 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
702 return provider->requestTexture(imageId, size, req_size);
707 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
709 QMutexLocker locker(&mutex);
711 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
714 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
715 image = provider->requestImage(imageId, size, req_size);
720 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
722 QMutexLocker locker(&mutex);
724 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
727 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
728 pixmap = provider->requestPixmap(imageId, size, req_size);
734 Return the base URL for this engine. The base URL is only used to
735 resolve components when a relative URL is passed to the
736 QDeclarativeComponent constructor.
738 If a base URL has not been explicitly set, this method returns the
739 application's current working directory.
743 QUrl QDeclarativeEngine::baseUrl() const
745 Q_D(const QDeclarativeEngine);
746 if (d->baseUrl.isEmpty()) {
747 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
754 Set the base URL for this engine to \a url.
758 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
760 Q_D(QDeclarativeEngine);
765 Returns true if warning messages will be output to stderr in addition
766 to being emitted by the warnings() signal, otherwise false.
768 The default value is true.
770 bool QDeclarativeEngine::outputWarningsToStandardError() const
772 Q_D(const QDeclarativeEngine);
773 return d->outputWarningsToStdErr;
777 Set whether warning messages will be output to stderr to \a enabled.
779 If \a enabled is true, any warning messages generated by QML will be
780 output to stderr and emitted by the warnings() signal. If \a enabled
781 is false, on the warnings() signal will be emitted. This allows
782 applications to handle warning output themselves.
784 The default value is true.
786 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
788 Q_D(QDeclarativeEngine);
789 d->outputWarningsToStdErr = enabled;
793 Attempt to free unused memory.
795 void QDeclarativeEngine::collectGarbage()
801 Returns the QDeclarativeContext for the \a object, or 0 if no
802 context has been set.
804 When the QDeclarativeEngine instantiates a QObject, the context is
807 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
812 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
814 QDeclarativeData *data =
815 static_cast<QDeclarativeData *>(priv->declarativeData);
819 else if (data->outerContext)
820 return data->outerContext->asQDeclarativeContext();
826 Sets the QDeclarativeContext for the \a object to \a context.
827 If the \a object already has a context, a warning is
828 output, but the context is not changed.
830 When the QDeclarativeEngine instantiates a QObject, the context is
833 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
835 if (!object || !context)
838 QDeclarativeData *data = QDeclarativeData::get(object, true);
840 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
844 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
845 contextData->addObject(object);
849 \enum QDeclarativeEngine::ObjectOwnership
851 Ownership controls whether or not QML automatically destroys the
852 QObject when the object is garbage collected by the JavaScript
853 engine. The two ownership options are:
855 \value CppOwnership The object is owned by C++ code, and will
856 never be deleted by QML. The JavaScript destroy() method cannot be
857 used on objects with CppOwnership. This option is similar to
858 QScriptEngine::QtOwnership.
860 \value JavaScriptOwnership The object is owned by JavaScript.
861 When the object is returned to QML as the return value of a method
862 call or property access, QML will delete the object if there are no
863 remaining JavaScript references to it and it has no
864 QObject::parent(). This option is similar to
865 QScriptEngine::ScriptOwnership.
867 Generally an application doesn't need to set an object's ownership
868 explicitly. QML uses a heuristic to set the default object
869 ownership. By default, an object that is created by QML has
870 JavaScriptOwnership. The exception to this are the root objects
871 created by calling QDeclarativeCompnent::create() or
872 QDeclarativeComponent::beginCreate() which have CppOwnership by
873 default. The ownership of these root-level objects is considered to
874 have been transferred to the C++ caller.
876 Objects not-created by QML have CppOwnership by default. The
877 exception to this is objects returned from a C++ method call. The
878 ownership of these objects is passed to JavaScript.
880 Calling setObjectOwnership() overrides the default ownership
881 heuristic used by QML.
885 Sets the \a ownership of \a object.
887 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
892 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
896 ddata->indestructible = (ownership == CppOwnership)?true:false;
897 ddata->explicitIndestructibleSet = true;
901 Returns the ownership of \a object.
903 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
908 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
912 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
915 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
917 QDeclarativeData *data = QDeclarativeData::get(object);
919 if (data && data->deferredComponent) {
920 if (QDeclarativeDebugService::isDebuggingEnabled()) {
921 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
922 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
923 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
924 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
925 if (data->outerContext)
926 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
928 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
930 QDeclarativeComponentPrivate::ConstructionState state;
931 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
933 data->deferredComponent->release();
934 data->deferredComponent = 0;
936 QDeclarativeComponentPrivate::complete(ep, &state);
937 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
941 QDeclarativeContext *qmlContext(const QObject *obj)
943 return QDeclarativeEngine::contextForObject(obj);
946 QDeclarativeEngine *qmlEngine(const QObject *obj)
948 QDeclarativeData *data = QDeclarativeData::get(obj, false);
949 if (!data || !data->context)
951 return data->context->engine;
954 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
956 QDeclarativeData *data = QDeclarativeData::get(object);
958 return 0; // Attached properties are only on objects created by QML
960 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
964 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
968 rv = pf(const_cast<QObject *>(object));
971 data->attachedProperties()->insert(id, rv);
976 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
977 const QMetaObject *attachedMetaObject, bool create)
980 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
982 if (*idCache == -1 || !object)
985 return qmlAttachedPropertiesObjectById(*idCache, object, create);
988 QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
990 #ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
991 if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
992 qWarning("Qml debugging is enabled. Only use this in a safe environment!");
994 QDeclarativeEnginePrivate::qml_debugging_enabled = true;
999 class QDeclarativeDataExtended {
1001 QDeclarativeDataExtended();
1002 ~QDeclarativeDataExtended();
1004 QHash<int, QObject *> attachedProperties;
1005 QDeclarativeNotifier objectNameNotifier;
1008 QDeclarativeDataExtended::QDeclarativeDataExtended()
1012 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1016 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1018 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1019 return &extendedData->objectNameNotifier;
1022 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1024 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1025 return &extendedData->attachedProperties;
1028 void QDeclarativeData::destroyed(QObject *object)
1030 if (deferredComponent)
1031 deferredComponent->release();
1033 if (nextContextObject)
1034 nextContextObject->prevContextObject = prevContextObject;
1035 if (prevContextObject)
1036 *prevContextObject = nextContextObject;
1038 QDeclarativeAbstractBinding *binding = bindings;
1040 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1041 binding->m_prevBinding = 0;
1042 binding->m_nextBinding = 0;
1051 propertyCache->release();
1053 if (ownContext && context)
1057 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1058 *guard = (QObject *)0;
1059 guard->objectDestroyed(object);
1063 delete extendedData;
1065 v8object.Clear(); // The WeakReference handler will clean the actual handle
1071 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1077 void QDeclarativeData::objectNameChanged(QObject *)
1079 if (extendedData) objectNameNotifier()->notify();
1082 bool QDeclarativeData::hasBindingBit(int bit) const
1084 if (bindingBitsSize > bit)
1085 return bindingBits[bit / 32] & (1 << (bit % 32));
1090 void QDeclarativeData::clearBindingBit(int bit)
1092 if (bindingBitsSize > bit)
1093 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1096 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1098 if (bindingBitsSize <= bit) {
1099 int props = obj->metaObject()->propertyCount();
1100 Q_ASSERT(bit < props);
1102 int arraySize = (props + 31) / 32;
1103 int oldArraySize = bindingBitsSize / 32;
1105 bindingBits = (quint32 *)realloc(bindingBits,
1106 arraySize * sizeof(quint32));
1108 memset(bindingBits + oldArraySize,
1110 sizeof(quint32) * (arraySize - oldArraySize));
1112 bindingBitsSize = arraySize * 32;
1115 bindingBits[bit / 32] |= (1 << (bit % 32));
1118 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1120 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1121 if (url.authority().isEmpty())
1122 return QLatin1Char(':') + url.path();
1125 return url.toLocalFile();
1129 static QString toLocalFile(const QString &url)
1131 if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
1134 QString file = url.mid(7);
1136 //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
1138 // magic for drives on windows
1139 if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
1145 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
1147 if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
1148 if (url.length() > 4)
1149 return QLatin1Char(':') + url.mid(4);
1153 return toLocalFile(url);
1156 void QDeclarativeEnginePrivate::sendQuit()
1158 Q_Q(QDeclarativeEngine);
1160 if (q->receivers(SIGNAL(quit())) == 0) {
1161 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1165 static void dumpwarning(const QDeclarativeError &error)
1167 qWarning().nospace() << qPrintable(error.toString());
1170 static void dumpwarning(const QList<QDeclarativeError> &errors)
1172 for (int ii = 0; ii < errors.count(); ++ii)
1173 dumpwarning(errors.at(ii));
1176 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1178 Q_Q(QDeclarativeEngine);
1179 q->warnings(QList<QDeclarativeError>() << error);
1180 if (outputWarningsToStdErr)
1184 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1186 Q_Q(QDeclarativeEngine);
1187 q->warnings(errors);
1188 if (outputWarningsToStdErr)
1189 dumpwarning(errors);
1192 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1195 QDeclarativeEnginePrivate::get(engine)->warning(error);
1200 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1203 QDeclarativeEnginePrivate::get(engine)->warning(error);
1208 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1211 engine->warning(error);
1216 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1219 engine->warning(error);
1225 This function should be called prior to evaluation of any js expression,
1226 so that scarce resources are not freed prematurely (eg, if there is a
1227 nested javascript expression).
1229 void QDeclarativeEnginePrivate::referenceScarceResources()
1231 scarceResourcesRefCount += 1;
1235 This function should be called after evaluation of the js expression is
1236 complete, and so the scarce resources may be freed safely.
1238 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1240 Q_ASSERT(scarceResourcesRefCount > 0);
1241 scarceResourcesRefCount -= 1;
1243 // if the refcount is zero, then evaluation of the "top level"
1244 // expression must have completed. We can safely release the
1245 // scarce resources.
1246 if (scarceResourcesRefCount == 0) {
1247 // iterate through the list and release them all.
1248 // note that the actual SRD is owned by the JS engine,
1249 // so we cannot delete the SRD; but we can free the
1250 // memory used by the variant in the SRD.
1251 while (ScarceResourceData *sr = scarceResources.first()) {
1252 sr->data = QVariant();
1253 scarceResources.remove(sr);
1259 Adds \a path as a directory where the engine searches for
1260 installed modules in a URL-based directory structure.
1261 The \a path may be a local filesystem directory or a URL.
1263 The newly added \a path will be first in the importPathList().
1265 \sa setImportPathList(), {QML Modules}
1267 void QDeclarativeEngine::addImportPath(const QString& path)
1269 Q_D(QDeclarativeEngine);
1270 d->importDatabase.addImportPath(path);
1274 Returns the list of directories where the engine searches for
1275 installed modules in a URL-based directory structure.
1277 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1278 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1279 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1280 provided by that module. A \c qmldir file is required for defining the
1281 type version mapping and possibly declarative extensions plugins.
1283 By default, the list contains the directory of the application executable,
1284 paths specified in the \c QML_IMPORT_PATH environment variable,
1285 and the builtin \c ImportsPath from QLibraryInfo.
1287 \sa addImportPath() setImportPathList()
1289 QStringList QDeclarativeEngine::importPathList() const
1291 Q_D(const QDeclarativeEngine);
1292 return d->importDatabase.importPathList();
1296 Sets \a paths as the list of directories where the engine searches for
1297 installed modules in a URL-based directory structure.
1299 By default, the list contains the directory of the application executable,
1300 paths specified in the \c QML_IMPORT_PATH environment variable,
1301 and the builtin \c ImportsPath from QLibraryInfo.
1303 \sa importPathList() addImportPath()
1305 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1307 Q_D(QDeclarativeEngine);
1308 d->importDatabase.setImportPathList(paths);
1313 Adds \a path as a directory where the engine searches for
1314 native plugins for imported modules (referenced in the \c qmldir file).
1316 By default, the list contains only \c ., i.e. the engine searches
1317 in the directory of the \c qmldir file itself.
1319 The newly added \a path will be first in the pluginPathList().
1321 \sa setPluginPathList()
1323 void QDeclarativeEngine::addPluginPath(const QString& path)
1325 Q_D(QDeclarativeEngine);
1326 d->importDatabase.addPluginPath(path);
1331 Returns the list of directories where the engine searches for
1332 native plugins for imported modules (referenced in the \c qmldir file).
1334 By default, the list contains only \c ., i.e. the engine searches
1335 in the directory of the \c qmldir file itself.
1337 \sa addPluginPath() setPluginPathList()
1339 QStringList QDeclarativeEngine::pluginPathList() const
1341 Q_D(const QDeclarativeEngine);
1342 return d->importDatabase.pluginPathList();
1346 Sets the list of directories where the engine searches for
1347 native plugins for imported modules (referenced in the \c qmldir file)
1350 By default, the list contains only \c ., i.e. the engine searches
1351 in the directory of the \c qmldir file itself.
1353 \sa pluginPathList() addPluginPath()
1355 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1357 Q_D(QDeclarativeEngine);
1358 d->importDatabase.setPluginPathList(paths);
1362 Imports the plugin named \a filePath with the \a uri provided.
1363 Returns true if the plugin was successfully imported; otherwise returns false.
1365 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1367 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1369 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1371 Q_D(QDeclarativeEngine);
1372 return d->importDatabase.importPlugin(filePath, uri, errors);
1376 Imports the plugin named \a filePath with the \a uri provided.
1377 Returns true if the plugin was successfully imported; otherwise returns false.
1379 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1381 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1383 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1385 Q_D(QDeclarativeEngine);
1386 QList<QDeclarativeError> errors;
1387 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1388 if (!errors.isEmpty()) {
1390 for (int i = 0; i < errors.size(); ++i) {
1391 builtError = QString(QLatin1String("%1\n %2"))
1393 .arg(errors.at(i).toString());
1395 *errorString = builtError;
1401 \property QDeclarativeEngine::offlineStoragePath
1402 \brief the directory for storing offline user data
1404 Returns the directory where SQL and other offline
1407 QDeclarativeWebView and the SQL databases created with openDatabase()
1410 The default is QML/OfflineStorage in the platform-standard
1411 user application data directory.
1413 Note that the path may not currently exist on the filesystem, so
1414 callers wanting to \e create new files at this location should create
1415 it first - see QDir::mkpath().
1417 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1419 Q_D(QDeclarativeEngine);
1420 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1423 QString QDeclarativeEngine::offlineStoragePath() const
1425 Q_D(const QDeclarativeEngine);
1426 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1429 static void voidptr_destructor(void *v)
1431 void **ptr = (void **)v;
1435 static void *voidptr_constructor(const void *v)
1440 return new void*(*(void **)v);
1444 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1446 Q_Q(QDeclarativeEngine);
1448 if (!mo->superClass()) {
1449 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1450 propertyCache.insert(mo, rv);
1453 QDeclarativePropertyCache *super = cache(mo->superClass());
1454 QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() -
1455 mo->superClass()->propertyCount() -
1456 mo->superClass()->methodCount());
1458 propertyCache.insert(mo, rv);
1463 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1464 QDeclarativeError &error)
1466 QList<QDeclarativeType *> types;
1468 int maxMinorVersion = 0;
1470 const QMetaObject *metaObject = type->metaObject();
1471 while (metaObject) {
1472 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1473 type->majorVersion(), minorVersion);
1475 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1481 metaObject = metaObject->superClass();
1484 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1486 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1490 QDeclarativePropertyCache *raw = cache(type->metaObject());
1492 bool hasCopied = false;
1494 for (int ii = 0; ii < types.count(); ++ii) {
1495 QDeclarativeType *currentType = types.at(ii);
1499 int rev = currentType->metaObjectRevision();
1500 int moIndex = types.count() - 1 - ii;
1502 if (raw->allowedRevisionCache[moIndex] != rev) {
1507 raw->allowedRevisionCache[moIndex] = rev;
1511 // Test revision compatibility - the basic rule is:
1512 // * Anything that is excluded, cannot overload something that is not excluded *
1514 // Signals override:
1515 // * other signals and methods of the same name.
1516 // * properties named on<Signal Name>
1517 // * automatic <property name>Changed notify signals
1519 // Methods override:
1520 // * other methods of the same name
1522 // Properties override:
1523 // * other elements of the same name
1525 bool overloadError = false;
1526 QString overloadName;
1529 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1530 !overloadError && iter != raw->stringCache.end();
1533 QDeclarativePropertyCache::Data *d = *iter;
1534 if (raw->isAllowedInRevision(d))
1535 continue; // Not excluded - no problems
1537 // check that a regular "name" overload isn't happening
1538 QDeclarativePropertyCache::Data *current = d;
1539 while (!overloadError && current) {
1540 current = d->overrideData(current);
1541 if (current && raw->isAllowedInRevision(current))
1542 overloadError = true;
1547 if (overloadError) {
1548 if (hasCopied) raw->release();
1550 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."));
1554 if (!hasCopied) raw->addref();
1555 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1557 if (minorVersion != maxMinorVersion) {
1559 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1565 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1567 QByteArray name = data->root->className();
1569 QByteArray ptr = name + '*';
1570 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1572 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1573 voidptr_constructor);
1574 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1575 voidptr_constructor);
1577 m_qmlLists.insert(lst_type, ptr_type);
1578 m_compositeTypes.insert(ptr_type, data);
1582 bool QDeclarativeEnginePrivate::isList(int t) const
1584 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1587 int QDeclarativeEnginePrivate::listType(int t) const
1589 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1590 if (iter != m_qmlLists.end())
1593 return QDeclarativeMetaType::listType(t);
1596 bool QDeclarativeEnginePrivate::isQObject(int t)
1598 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1601 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1603 int t = v.userType();
1604 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1606 return *(QObject **)(v.constData());
1608 return QDeclarativeMetaType::toQObject(v, ok);
1612 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1614 if (m_compositeTypes.contains(t))
1615 return QDeclarativeMetaType::Object;
1616 else if (m_qmlLists.contains(t))
1617 return QDeclarativeMetaType::List;
1619 return QDeclarativeMetaType::typeCategory(t);
1622 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1624 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1625 if (iter != m_compositeTypes.end()) {
1626 return (*iter)->root;
1628 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1629 return type?type->baseMetaObject():0;
1633 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1635 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1636 if (iter != m_compositeTypes.end()) {
1637 return (*iter)->root;
1639 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1640 return type?type->metaObject():0;
1644 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1646 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1647 QFileInfo info(fileName);
1649 QString absolute = info.absoluteFilePath();
1651 #if defined(Q_OS_MAC)
1652 QString canonical = info.canonicalFilePath();
1653 #elif defined(Q_OS_WIN32)
1654 wchar_t buffer[1024];
1656 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1657 if (rv == 0 || rv >= 1024) return true;
1658 rv = ::GetLongPathName(buffer, buffer, 1024);
1659 if (rv == 0 || rv >= 1024) return true;
1661 QString canonical((QChar *)buffer);
1664 int absoluteLength = absolute.length();
1665 int canonicalLength = canonical.length();
1667 int length = qMin(absoluteLength, canonicalLength);
1668 for (int ii = 0; ii < length; ++ii) {
1669 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1670 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1672 if (a.toLower() != c.toLower())
1684 \fn QDeclarativeEngine *qmlEngine(const QObject *object)
1685 \relates QDeclarativeEngine
1687 Returns the QDeclarativeEngine associated with \a object, if any. This is equivalent to
1688 QDeclarativeEngine::contextForObject(object)->engine(), but more efficient.
1692 \fn QDeclarativeContext *qmlContext(const QObject *object)
1693 \relates QDeclarativeEngine
1695 Returns the QDeclarativeContext associated with \a object, if any. This is equivalent to
1696 QDeclarativeEngine::contextForObject(object).