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/qdeclarativeenginedebug_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/qjsdebugservice_p.h"
72 #include <QtCore/qmetaobject.h>
73 #include <QNetworkReply>
74 #include <QNetworkRequest>
75 #include <QNetworkAccessManager>
76 #include <QDesktopServices>
81 #include <QMetaObject>
84 #include <QPluginLoader>
85 #include <QtGui/qfontdatabase.h>
86 #include <QtCore/qlibraryinfo.h>
87 #include <QtCore/qthreadstorage.h>
88 #include <QtCore/qthread.h>
89 #include <QtCore/qcoreapplication.h>
90 #include <QtCore/qdir.h>
91 #include <QtCore/qmutex.h>
92 #include <QtGui/qcolor.h>
93 #include <QtGui/qvector3d.h>
94 #include <QtGui/qsound.h>
95 #include <QtCore/qcryptographichash.h>
97 #include <private/qobject_p.h>
98 #include <private/qscriptdeclarativeclass_p.h>
100 #include <private/qdeclarativeitemsmodule_p.h>
101 #include <private/qdeclarativeutilmodule_p.h>
102 #include <private/qsgitemsmodule_p.h>
103 #include <qsgtexture.h>
105 #ifdef Q_OS_WIN // for %APPDATA%
106 #include <qt_windows.h>
107 #include <qlibrary.h>
110 #define CSIDL_APPDATA 0x001a // <username>\Application Data
113 Q_DECLARE_METATYPE(QDeclarativeProperty)
118 \qmlclass QtObject QObject
119 \ingroup qml-utility-elements
121 \brief The QtObject element is the most basic element in QML.
123 The QtObject element is a non-visual element which contains only the
126 It can be useful to create a QtObject if you need an extremely
127 lightweight element to enclose a set of custom properties:
129 \snippet doc/src/snippets/declarative/qtobject.qml 0
131 It can also be useful for C++ integration, as it is just a plain
132 QObject. See the QObject documentation for further details.
135 \qmlproperty string QML:QtObject::objectName
136 This property holds the QObject::objectName for this specific object instance.
138 This allows a C++ application to locate an item within a QML component
139 using the QObject::findChild() method. For example, the following C++
140 application locates the child \l Rectangle item and dynamically changes its
149 width: 200; height: 200
162 QDeclarativeView view;
163 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
166 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
168 item->setProperty("color", QColor(Qt::yellow));
172 struct StaticQtMetaObject : public QObject
174 static const QMetaObject *get()
175 { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
178 static bool qt_QmlQtModule_registered = false;
179 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
181 void QDeclarativeEnginePrivate::defineModule()
183 qmlRegisterType<QDeclarativeComponent>("QtQuick",1,0,"Component");
184 qmlRegisterType<QObject>("QtQuick",1,0,"QtObject");
185 qmlRegisterType<QDeclarativeWorkerScript>("QtQuick",1,0,"WorkerScript");
187 #ifndef QT_NO_IMPORT_QT47_QML
188 qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
189 qmlRegisterType<QObject>("Qt",4,7,"QtObject");
190 qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
193 qmlRegisterType<QDeclarativeBinding>();
197 \qmlclass QML:Qt QDeclarativeEnginePrivate
198 \ingroup qml-utility-elements
199 \brief The QML global Qt object provides useful enums and functions from Qt.
201 \keyword QmlGlobalQtObject
203 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
205 The \c Qt object is a global object with utility functions, properties and enums.
207 It is not instantiable; to use it, call the members of the global \c Qt object directly.
214 color: Qt.rgba(1, 0, 0, 1)
215 text: Qt.md5("hello, world")
222 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
223 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
227 The Qt object also contains helper functions for creating objects of specific
228 data types. This is primarily useful when setting the properties of an item
229 when the property has one of the following types:
232 \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()}
233 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
234 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
235 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
236 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
239 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
241 \section1 Date/Time Formatters
243 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
246 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
247 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
248 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
251 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
254 \section1 Dynamic Object Creation
255 The following functions on the global object allow you to dynamically create QML
256 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
260 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
261 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
267 \qmlproperty object QML:Qt::application
270 The \c application object provides access to global application state
271 properties shared by many QML components.
277 \o \c application.active
279 This read-only property indicates whether the application is the top-most and focused
280 application, and the user is able to interact with the application. The property
281 is false when the application is in the background, the device keylock or screen
282 saver is active, the screen backlight is turned off, or the global system dialog
283 is being displayed on top of the application. It can be used for stopping and
284 pausing animations, timers and active processing of data in order to save device
285 battery power and free device memory and processor load when the application is not
289 \o \c application.layoutDirection
291 This read-only property can be used to query the default layout direction of the
292 application. On system start-up, the default layout direction depends on the
293 application's language. The property has a value of \c Qt.RightToLeft in locales
294 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
295 where the reading direction flows from left to right. You can bind to this
296 property to customize your application layouts to support both layout directions.
301 \o Qt.LeftToRight - Text and graphics elements should be positioned
303 \o Qt.RightToLeft - Text and graphics elements should be positioned
308 The following example uses the \c application object to indicate
309 whether the application is currently active:
311 \snippet doc/src/snippets/declarative/application.qml document
317 \qmlmethod object Qt::include(string url, jsobject callback)
319 Includes another JavaScript file. This method can only be used from within JavaScript files,
320 and not regular QML files.
322 This imports all functions from \a url into the current script's namespace.
324 Qt.include() returns an object that describes the status of the operation. The object has
325 a single property, \c {status}, that is set to one of the following values:
328 \header \o Symbol \o Value \o Description
329 \row \o result.OK \o 0 \o The include completed successfully.
330 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
331 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
332 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
333 An additional \c exception property will be set in this case.
336 The \c status property will be updated as the operation progresses.
338 If provided, \a callback is invoked when the operation completes. The callback is passed
339 the same object as is returned from the Qt.include() call.
341 // Qt.include() is implemented in qv8include.cpp
344 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
345 : captureProperties(false), rootContext(0), isDebugging(false),
346 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
347 cleanup(0), erroredBindings(0), inProgressCreations(0), scriptEngine(this),
348 workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
349 networkAccessManager(0), networkAccessManagerFactory(0),
350 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
353 if (!qt_QmlQtModule_registered) {
354 qt_QmlQtModule_registered = true;
355 QDeclarativeItemModule::defineModule();
356 QDeclarativeUtilModule::defineModule();
357 QDeclarativeEnginePrivate::defineModule();
358 QSGItemsModule::defineModule();
359 QDeclarativeValueTypeFactory::registerValueTypes();
363 QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
366 // Note that all documentation for stuff put on the global object goes in
367 // doc/src/declarative/globalobject.qdoc
369 QScriptValue qtObject =
370 newQMetaObject(StaticQtMetaObject::get());
371 globalObject().setProperty(QLatin1String("Qt"), qtObject);
373 // translation functions need to be installed
374 // before the global script class is constructed (QTBUG-6437)
375 installTranslatorFunctions();
378 QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
382 QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
384 return p->getNetworkAccessManager();
387 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
389 Q_ASSERT(inProgressCreations == 0);
390 Q_ASSERT(bindValues.isEmpty());
391 Q_ASSERT(parserStatus.isEmpty());
394 QDeclarativeCleanup *c = cleanup;
396 if (cleanup) cleanup->prev = &cleanup;
405 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
407 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
409 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
411 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
412 delete (*iter)->qobjectApi;
417 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
422 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
424 for (int ii = 0; ii < pss.count; ++ii) {
425 QDeclarativeParserStatus *ps = pss.at(ii);
432 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
434 QObjectPrivate *p = QObjectPrivate::get(o);
435 if (p->declarativeData) {
436 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
437 if (d->ownContext && d->context) {
438 d->context->destroy();
444 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
446 static_cast<QDeclarativeData *>(d)->destroyed(o);
449 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
451 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
454 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
456 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
459 void QDeclarativeEnginePrivate::init()
461 Q_Q(QDeclarativeEngine);
462 qRegisterMetaType<QVariant>("QVariant");
463 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
464 qRegisterMetaType<QScriptValue>("QScriptValue");
465 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
467 QDeclarativeData::init();
472 rootContext = new QDeclarativeContext(q,true);
474 if (QCoreApplication::instance()->thread() == q->thread() &&
475 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
477 QDeclarativeEngineDebugServer::instance()->addEngine(q);
478 QJSDebugService::instance()->addEngine(q);
482 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
484 Q_Q(QDeclarativeEngine);
485 if (!workerScriptEngine)
486 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
487 return workerScriptEngine;
491 \class QDeclarativeEngine
493 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
496 Each QML component is instantiated in a QDeclarativeContext.
497 QDeclarativeContext's are essential for passing data to QML
498 components. In QML, contexts are arranged hierarchically and this
499 hierarchy is managed by the QDeclarativeEngine.
501 Prior to creating any QML components, an application must have
502 created a QDeclarativeEngine to gain access to a QML context. The
503 following example shows how to create a simple Text item.
506 QDeclarativeEngine engine;
507 QDeclarativeComponent component(&engine);
508 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
509 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
511 //add item to view, etc
515 In this case, the Text item will be created in the engine's
516 \l {QDeclarativeEngine::rootContext()}{root context}.
518 \sa QDeclarativeComponent QDeclarativeContext
522 Create a new QDeclarativeEngine with the given \a parent.
524 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
525 : QObject(*new QDeclarativeEnginePrivate(this), parent)
527 Q_D(QDeclarativeEngine);
532 Destroys the QDeclarativeEngine.
534 Any QDeclarativeContext's created on this engine will be
535 invalidated, but not destroyed (unless they are parented to the
536 QDeclarativeEngine object).
538 QDeclarativeEngine::~QDeclarativeEngine()
540 Q_D(QDeclarativeEngine);
542 QDeclarativeEngineDebugServer::instance()->remEngine(this);
544 // if we are the parent of any of the qobject module api instances,
545 // we need to remove them from our internal list, in order to prevent
546 // a segfault in engine private dtor.
547 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
548 QObject *currQObjectApi = 0;
549 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
550 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
551 currInstance = d->moduleApiInstances.value(key);
552 currQObjectApi = currInstance->qobjectApi;
553 if (this->children().contains(currQObjectApi)) {
554 delete currQObjectApi;
556 d->moduleApiInstances.remove(key);
561 /*! \fn void QDeclarativeEngine::quit()
562 This signal is emitted when the QML loaded by the engine would like to quit.
565 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
566 This signal is emitted when \a warnings messages are generated by QML.
570 Clears the engine's internal component cache.
572 Normally the QDeclarativeEngine caches components loaded from qml
573 files. This method clears this cache and forces the component to be
576 void QDeclarativeEngine::clearComponentCache()
578 Q_D(QDeclarativeEngine);
579 d->typeLoader.clearCache();
583 Returns the engine's root context.
585 The root context is automatically created by the QDeclarativeEngine.
586 Data that should be available to all QML component instances
587 instantiated by the engine should be put in the root context.
589 Additional data that should only be available to a subset of
590 component instances should be added to sub-contexts parented to the
593 QDeclarativeContext *QDeclarativeEngine::rootContext() const
595 Q_D(const QDeclarativeEngine);
596 return d->rootContext;
600 Sets the \a factory to use for creating QNetworkAccessManager(s).
602 QNetworkAccessManager is used for all network access by QML. By
603 implementing a factory it is possible to create custom
604 QNetworkAccessManager with specialized caching, proxy and cookie
607 The factory must be set before executing the engine.
609 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
611 Q_D(QDeclarativeEngine);
612 QMutexLocker locker(&d->mutex);
613 d->networkAccessManagerFactory = factory;
617 Returns the current QDeclarativeNetworkAccessManagerFactory.
619 \sa setNetworkAccessManagerFactory()
621 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
623 Q_D(const QDeclarativeEngine);
624 return d->networkAccessManagerFactory;
627 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
629 QMutexLocker locker(&mutex);
630 QNetworkAccessManager *nam;
631 if (networkAccessManagerFactory) {
632 nam = networkAccessManagerFactory->create(parent);
634 nam = new QNetworkAccessManager(parent);
640 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
642 Q_Q(const QDeclarativeEngine);
643 if (!networkAccessManager)
644 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
645 return networkAccessManager;
649 Returns a common QNetworkAccessManager which can be used by any QML
650 element instantiated by this engine.
652 If a QDeclarativeNetworkAccessManagerFactory has been set and a
653 QNetworkAccessManager has not yet been created, the
654 QDeclarativeNetworkAccessManagerFactory will be used to create the
655 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
656 will have no proxy or cache set.
658 \sa setNetworkAccessManagerFactory()
660 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
662 Q_D(const QDeclarativeEngine);
663 return d->getNetworkAccessManager();
668 Sets the \a provider to use for images requested via the \e
669 image: url scheme, with host \a providerId. The QDeclarativeEngine
670 takes ownership of \a provider.
672 Image providers enable support for pixmap and threaded image
673 requests. See the QDeclarativeImageProvider documentation for details on
674 implementing and using image providers.
676 All required image providers should be added to the engine before any
677 QML sources files are loaded.
679 Note that images loaded from a QDeclarativeImageProvider are cached
680 by QPixmapCache, similar to any image loaded by QML.
682 \sa removeImageProvider()
684 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
686 Q_D(QDeclarativeEngine);
687 QMutexLocker locker(&d->mutex);
688 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
692 Returns the QDeclarativeImageProvider set for \a providerId.
694 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
696 Q_D(const QDeclarativeEngine);
697 QMutexLocker locker(&d->mutex);
698 return d->imageProviders.value(providerId).data();
702 Removes the QDeclarativeImageProvider for \a providerId.
704 Returns the provider if it was found; otherwise returns 0.
706 \sa addImageProvider()
708 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
710 Q_D(QDeclarativeEngine);
711 QMutexLocker locker(&d->mutex);
712 d->imageProviders.take(providerId);
715 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
717 QMutexLocker locker(&mutex);
718 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
721 return provider->imageType();
722 return QDeclarativeImageProvider::Invalid;
725 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
727 QMutexLocker locker(&mutex);
728 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
731 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
732 return provider->requestTexture(imageId, size, req_size);
737 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
739 QMutexLocker locker(&mutex);
741 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
744 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
745 image = provider->requestImage(imageId, size, req_size);
750 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
752 QMutexLocker locker(&mutex);
754 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
757 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
758 pixmap = provider->requestPixmap(imageId, size, req_size);
764 Return the base URL for this engine. The base URL is only used to
765 resolve components when a relative URL is passed to the
766 QDeclarativeComponent constructor.
768 If a base URL has not been explicitly set, this method returns the
769 application's current working directory.
773 QUrl QDeclarativeEngine::baseUrl() const
775 Q_D(const QDeclarativeEngine);
776 if (d->baseUrl.isEmpty()) {
777 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
784 Set the base URL for this engine to \a url.
788 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
790 Q_D(QDeclarativeEngine);
795 Returns true if warning messages will be output to stderr in addition
796 to being emitted by the warnings() signal, otherwise false.
798 The default value is true.
800 bool QDeclarativeEngine::outputWarningsToStandardError() const
802 Q_D(const QDeclarativeEngine);
803 return d->outputWarningsToStdErr;
807 Set whether warning messages will be output to stderr to \a enabled.
809 If \a enabled is true, any warning messages generated by QML will be
810 output to stderr and emitted by the warnings() signal. If \a enabled
811 is false, on the warnings() signal will be emitted. This allows
812 applications to handle warning output themselves.
814 The default value is true.
816 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
818 Q_D(QDeclarativeEngine);
819 d->outputWarningsToStdErr = enabled;
823 Attempt to free unused memory.
825 void QDeclarativeEngine::collectGarbage()
831 Returns the QDeclarativeContext for the \a object, or 0 if no
832 context has been set.
834 When the QDeclarativeEngine instantiates a QObject, the context is
837 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
842 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
844 QDeclarativeData *data =
845 static_cast<QDeclarativeData *>(priv->declarativeData);
849 else if (data->outerContext)
850 return data->outerContext->asQDeclarativeContext();
856 Sets the QDeclarativeContext for the \a object to \a context.
857 If the \a object already has a context, a warning is
858 output, but the context is not changed.
860 When the QDeclarativeEngine instantiates a QObject, the context is
863 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
865 if (!object || !context)
868 QDeclarativeData *data = QDeclarativeData::get(object, true);
870 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
874 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
875 contextData->addObject(object);
879 \enum QDeclarativeEngine::ObjectOwnership
881 Ownership controls whether or not QML automatically destroys the
882 QObject when the object is garbage collected by the JavaScript
883 engine. The two ownership options are:
885 \value CppOwnership The object is owned by C++ code, and will
886 never be deleted by QML. The JavaScript destroy() method cannot be
887 used on objects with CppOwnership. This option is similar to
888 QScriptEngine::QtOwnership.
890 \value JavaScriptOwnership The object is owned by JavaScript.
891 When the object is returned to QML as the return value of a method
892 call or property access, QML will delete the object if there are no
893 remaining JavaScript references to it and it has no
894 QObject::parent(). This option is similar to
895 QScriptEngine::ScriptOwnership.
897 Generally an application doesn't need to set an object's ownership
898 explicitly. QML uses a heuristic to set the default object
899 ownership. By default, an object that is created by QML has
900 JavaScriptOwnership. The exception to this are the root objects
901 created by calling QDeclarativeCompnent::create() or
902 QDeclarativeComponent::beginCreate() which have CppOwnership by
903 default. The ownership of these root-level objects is considered to
904 have been transferred to the C++ caller.
906 Objects not-created by QML have CppOwnership by default. The
907 exception to this is objects returned from a C++ method call. The
908 ownership of these objects is passed to JavaScript.
910 Calling setObjectOwnership() overrides the default ownership
911 heuristic used by QML.
915 Sets the \a ownership of \a object.
917 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
922 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
926 ddata->indestructible = (ownership == CppOwnership)?true:false;
927 ddata->explicitIndestructibleSet = true;
931 Returns the ownership of \a object.
933 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
938 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
942 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
945 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
947 QDeclarativeData *data = QDeclarativeData::get(object);
949 if (data && data->deferredComponent) {
950 if (QDeclarativeDebugService::isDebuggingEnabled()) {
951 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
952 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
953 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
954 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
955 if (data->outerContext)
956 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
958 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
960 QDeclarativeComponentPrivate::ConstructionState state;
961 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
963 data->deferredComponent->release();
964 data->deferredComponent = 0;
966 QDeclarativeComponentPrivate::complete(ep, &state);
967 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
971 QDeclarativeContext *qmlContext(const QObject *obj)
973 return QDeclarativeEngine::contextForObject(obj);
976 QDeclarativeEngine *qmlEngine(const QObject *obj)
978 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
979 return context?context->engine():0;
982 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
984 QDeclarativeData *data = QDeclarativeData::get(object);
986 return 0; // Attached properties are only on objects created by QML
988 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
992 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
996 rv = pf(const_cast<QObject *>(object));
999 data->attachedProperties()->insert(id, rv);
1004 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
1005 const QMetaObject *attachedMetaObject, bool create)
1008 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
1010 if (*idCache == -1 || !object)
1013 return qmlAttachedPropertiesObjectById(*idCache, object, create);
1016 class QDeclarativeDataExtended {
1018 QDeclarativeDataExtended();
1019 ~QDeclarativeDataExtended();
1021 QHash<int, QObject *> attachedProperties;
1022 QDeclarativeNotifier objectNameNotifier;
1025 QDeclarativeDataExtended::QDeclarativeDataExtended()
1029 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1033 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1035 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1036 return &extendedData->objectNameNotifier;
1039 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1041 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1042 return &extendedData->attachedProperties;
1045 void QDeclarativeData::destroyed(QObject *object)
1047 if (deferredComponent)
1048 deferredComponent->release();
1050 if (nextContextObject)
1051 nextContextObject->prevContextObject = prevContextObject;
1052 if (prevContextObject)
1053 *prevContextObject = nextContextObject;
1055 QDeclarativeAbstractBinding *binding = bindings;
1057 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1058 binding->m_prevBinding = 0;
1059 binding->m_nextBinding = 0;
1068 propertyCache->release();
1070 if (ownContext && context)
1074 QDeclarativeGuard<QObject> *guard = guards;
1075 *guard = (QObject *)0;
1076 guard->objectDestroyed(object);
1080 delete extendedData;
1082 v8object.Clear(); // The WeakReference handler will clean the actual handle
1088 void QDeclarativeData::parentChanged(QObject *, QObject *parent)
1091 // if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
1094 void QDeclarativeData::objectNameChanged(QObject *)
1096 if (extendedData) objectNameNotifier()->notify();
1099 bool QDeclarativeData::hasBindingBit(int bit) const
1101 if (bindingBitsSize > bit)
1102 return bindingBits[bit / 32] & (1 << (bit % 32));
1107 void QDeclarativeData::clearBindingBit(int bit)
1109 if (bindingBitsSize > bit)
1110 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1113 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1115 if (bindingBitsSize <= bit) {
1116 int props = obj->metaObject()->propertyCount();
1117 Q_ASSERT(bit < props);
1119 int arraySize = (props + 31) / 32;
1120 int oldArraySize = bindingBitsSize / 32;
1122 bindingBits = (quint32 *)realloc(bindingBits,
1123 arraySize * sizeof(quint32));
1125 memset(bindingBits + oldArraySize,
1127 sizeof(quint32) * (arraySize - oldArraySize));
1129 bindingBitsSize = arraySize * 32;
1132 bindingBits[bit / 32] |= (1 << (bit % 32));
1135 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1137 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1138 if (url.authority().isEmpty())
1139 return QLatin1Char(':') + url.path();
1142 return url.toLocalFile();
1145 void QDeclarativeEnginePrivate::sendQuit()
1147 Q_Q(QDeclarativeEngine);
1149 if (q->receivers(SIGNAL(quit())) == 0) {
1150 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1154 static void dumpwarning(const QDeclarativeError &error)
1156 qWarning().nospace() << qPrintable(error.toString());
1159 static void dumpwarning(const QList<QDeclarativeError> &errors)
1161 for (int ii = 0; ii < errors.count(); ++ii)
1162 dumpwarning(errors.at(ii));
1165 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1167 Q_Q(QDeclarativeEngine);
1168 q->warnings(QList<QDeclarativeError>() << error);
1169 if (outputWarningsToStdErr)
1173 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1175 Q_Q(QDeclarativeEngine);
1176 q->warnings(errors);
1177 if (outputWarningsToStdErr)
1178 dumpwarning(errors);
1181 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1184 QDeclarativeEnginePrivate::get(engine)->warning(error);
1189 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1192 QDeclarativeEnginePrivate::get(engine)->warning(error);
1197 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1200 engine->warning(error);
1205 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1208 engine->warning(error);
1214 This function should be called prior to evaluation of any js expression,
1215 so that scarce resources are not freed prematurely (eg, if there is a
1216 nested javascript expression).
1218 void QDeclarativeEnginePrivate::referenceScarceResources()
1220 scarceResourcesRefCount += 1;
1224 This function should be called after evaluation of the js expression is
1225 complete, and so the scarce resources may be freed safely.
1227 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1229 Q_ASSERT(scarceResourcesRefCount > 0);
1230 scarceResourcesRefCount -= 1;
1232 // if the refcount is zero, then evaluation of the "top level"
1233 // expression must have completed. We can safely release the
1234 // scarce resources.
1235 if (scarceResourcesRefCount == 0) {
1236 // iterate through the list and release them all.
1237 // note that the actual SRD is owned by the JS engine,
1238 // so we cannot delete the SRD; but we can free the
1239 // memory used by the variant in the SRD.
1240 while (ScarceResourceData *sr = scarceResources.first()) {
1241 sr->data = QVariant();
1242 scarceResources.remove(sr);
1248 Adds \a path as a directory where the engine searches for
1249 installed modules in a URL-based directory structure.
1250 The \a path may be a local filesystem directory or a URL.
1252 The newly added \a path will be first in the importPathList().
1254 \sa setImportPathList(), {QML Modules}
1256 void QDeclarativeEngine::addImportPath(const QString& path)
1258 Q_D(QDeclarativeEngine);
1259 d->importDatabase.addImportPath(path);
1263 Returns the list of directories where the engine searches for
1264 installed modules in a URL-based directory structure.
1266 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1267 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1268 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1269 provided by that module. A \c qmldir file is required for defining the
1270 type version mapping and possibly declarative extensions plugins.
1272 By default, the list contains the directory of the application executable,
1273 paths specified in the \c QML_IMPORT_PATH environment variable,
1274 and the builtin \c ImportsPath from QLibraryInfo.
1276 \sa addImportPath() setImportPathList()
1278 QStringList QDeclarativeEngine::importPathList() const
1280 Q_D(const QDeclarativeEngine);
1281 return d->importDatabase.importPathList();
1285 Sets \a paths as the list of directories where the engine searches for
1286 installed modules in a URL-based directory structure.
1288 By default, the list contains the directory of the application executable,
1289 paths specified in the \c QML_IMPORT_PATH environment variable,
1290 and the builtin \c ImportsPath from QLibraryInfo.
1292 \sa importPathList() addImportPath()
1294 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1296 Q_D(QDeclarativeEngine);
1297 d->importDatabase.setImportPathList(paths);
1302 Adds \a path as a directory where the engine searches for
1303 native plugins for imported modules (referenced in the \c qmldir file).
1305 By default, the list contains only \c ., i.e. the engine searches
1306 in the directory of the \c qmldir file itself.
1308 The newly added \a path will be first in the pluginPathList().
1310 \sa setPluginPathList()
1312 void QDeclarativeEngine::addPluginPath(const QString& path)
1314 Q_D(QDeclarativeEngine);
1315 d->importDatabase.addPluginPath(path);
1320 Returns the list of directories where the engine searches for
1321 native plugins for imported modules (referenced in the \c qmldir file).
1323 By default, the list contains only \c ., i.e. the engine searches
1324 in the directory of the \c qmldir file itself.
1326 \sa addPluginPath() setPluginPathList()
1328 QStringList QDeclarativeEngine::pluginPathList() const
1330 Q_D(const QDeclarativeEngine);
1331 return d->importDatabase.pluginPathList();
1335 Sets the list of directories where the engine searches for
1336 native plugins for imported modules (referenced in the \c qmldir file)
1339 By default, the list contains only \c ., i.e. the engine searches
1340 in the directory of the \c qmldir file itself.
1342 \sa pluginPathList() addPluginPath()
1344 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1346 Q_D(QDeclarativeEngine);
1347 d->importDatabase.setPluginPathList(paths);
1351 Imports the plugin named \a filePath with the \a uri provided.
1352 Returns true if the plugin was successfully imported; otherwise returns false.
1354 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1356 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1358 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1360 Q_D(QDeclarativeEngine);
1361 return d->importDatabase.importPlugin(filePath, uri, errors);
1365 Imports the plugin named \a filePath with the \a uri provided.
1366 Returns true if the plugin was successfully imported; otherwise returns false.
1368 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1370 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1372 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1374 Q_D(QDeclarativeEngine);
1375 QList<QDeclarativeError> errors;
1376 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1377 if (!errors.isEmpty()) {
1379 for (int i = 0; i < errors.size(); ++i) {
1380 builtError = QString(QLatin1String("%1\n %2"))
1382 .arg(errors.at(i).toString());
1384 *errorString = builtError;
1390 \property QDeclarativeEngine::offlineStoragePath
1391 \brief the directory for storing offline user data
1393 Returns the directory where SQL and other offline
1396 QDeclarativeWebView and the SQL databases created with openDatabase()
1399 The default is QML/OfflineStorage in the platform-standard
1400 user application data directory.
1402 Note that the path may not currently exist on the filesystem, so
1403 callers wanting to \e create new files at this location should create
1404 it first - see QDir::mkpath().
1406 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1408 Q_D(QDeclarativeEngine);
1409 qt_qmlsqldatabase_setOfflineStoragePath(&d->v8engine, dir);
1412 QString QDeclarativeEngine::offlineStoragePath() const
1414 Q_D(const QDeclarativeEngine);
1415 return qt_qmlsqldatabase_getOfflineStoragePath(&d->v8engine);
1418 static void voidptr_destructor(void *v)
1420 void **ptr = (void **)v;
1424 static void *voidptr_constructor(const void *v)
1429 return new void*(*(void **)v);
1433 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1435 Q_Q(QDeclarativeEngine);
1437 if (!mo->superClass()) {
1438 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1439 propertyCache.insert(mo, rv);
1442 QDeclarativePropertyCache *super = cache(mo->superClass());
1443 QDeclarativePropertyCache *rv = super->copy();
1445 propertyCache.insert(mo, rv);
1450 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1451 QDeclarativeError &error)
1453 QList<QDeclarativeType *> types;
1455 int maxMinorVersion = 0;
1457 const QMetaObject *metaObject = type->metaObject();
1458 while (metaObject) {
1459 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1460 type->majorVersion(), minorVersion);
1462 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1468 metaObject = metaObject->superClass();
1471 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1473 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1477 QDeclarativePropertyCache *raw = cache(type->metaObject());
1479 bool hasCopied = false;
1481 for (int ii = 0; ii < types.count(); ++ii) {
1482 QDeclarativeType *currentType = types.at(ii);
1486 int rev = currentType->metaObjectRevision();
1487 int moIndex = types.count() - 1 - ii;
1489 if (raw->allowedRevisionCache[moIndex] != rev) {
1494 raw->allowedRevisionCache[moIndex] = rev;
1498 // Test revision compatibility - the basic rule is:
1499 // * Anything that is excluded, cannot overload something that is not excluded *
1501 // Signals override:
1502 // * other signals and methods of the same name.
1503 // * properties named on<Signal Name>
1504 // * automatic <property name>Changed notify signals
1506 // Methods override:
1507 // * other methods of the same name
1509 // Properties override:
1510 // * other elements of the same name
1512 bool overloadError = false;
1513 QString overloadName;
1516 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1517 !overloadError && iter != raw->stringCache.end();
1520 QDeclarativePropertyCache::Data *d = *iter;
1521 if (raw->isAllowedInRevision(d))
1522 continue; // Not excluded - no problems
1524 // check that a regular "name" overload isn't happening
1525 QDeclarativePropertyCache::Data *current = d;
1526 while (!overloadError && current) {
1527 current = d->overrideData(current);
1528 if (current && raw->isAllowedInRevision(current))
1529 overloadError = true;
1534 if (overloadError) {
1535 if (hasCopied) raw->release();
1537 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."));
1541 if (!hasCopied) raw->addref();
1542 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1544 if (minorVersion != maxMinorVersion) {
1546 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1552 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1554 QByteArray name = data->root->className();
1556 QByteArray ptr = name + '*';
1557 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1559 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1560 voidptr_constructor);
1561 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1562 voidptr_constructor);
1564 m_qmlLists.insert(lst_type, ptr_type);
1565 m_compositeTypes.insert(ptr_type, data);
1569 bool QDeclarativeEnginePrivate::isList(int t) const
1571 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1574 int QDeclarativeEnginePrivate::listType(int t) const
1576 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1577 if (iter != m_qmlLists.end())
1580 return QDeclarativeMetaType::listType(t);
1583 bool QDeclarativeEnginePrivate::isQObject(int t)
1585 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1588 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1590 int t = v.userType();
1591 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1593 return *(QObject **)(v.constData());
1595 return QDeclarativeMetaType::toQObject(v, ok);
1599 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1601 if (m_compositeTypes.contains(t))
1602 return QDeclarativeMetaType::Object;
1603 else if (m_qmlLists.contains(t))
1604 return QDeclarativeMetaType::List;
1606 return QDeclarativeMetaType::typeCategory(t);
1609 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1611 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1612 if (iter != m_compositeTypes.end()) {
1613 return (*iter)->root;
1615 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1616 return type?type->baseMetaObject():0;
1620 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1622 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1623 if (iter != m_compositeTypes.end()) {
1624 return (*iter)->root;
1626 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1627 return type?type->metaObject():0;
1631 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1633 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1634 QFileInfo info(fileName);
1636 QString absolute = info.absoluteFilePath();
1638 #if defined(Q_OS_MAC)
1639 QString canonical = info.canonicalFilePath();
1640 #elif defined(Q_OS_WIN32)
1641 wchar_t buffer[1024];
1643 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1644 if (rv == 0 || rv >= 1024) return true;
1645 rv = ::GetLongPathName(buffer, buffer, 1024);
1646 if (rv == 0 || rv >= 1024) return true;
1648 QString canonical((QChar *)buffer);
1651 int absoluteLength = absolute.length();
1652 int canonicalLength = canonical.length();
1654 int length = qMin(absoluteLength, canonicalLength);
1655 for (int ii = 0; ii < length; ++ii) {
1656 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1657 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1659 if (a.toLower() != c.toLower())