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 <QtWidgets/qsound.h>
95 #include <QtCore/qcryptographichash.h>
97 #include <private/qobject_p.h>
99 #include <private/qdeclarativeutilmodule_p.h>
100 #include <private/qsgitemsmodule_p.h>
101 #include <private/qsgparticlesmodule_p.h>
102 #include <qsgtexture.h>
104 #ifdef Q_OS_WIN // for %APPDATA%
105 #include <qt_windows.h>
106 #include <qlibrary.h>
109 #define CSIDL_APPDATA 0x001a // <username>\Application Data
112 Q_DECLARE_METATYPE(QDeclarativeProperty)
116 void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
118 QDeclarativeEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
119 QDeclarativeValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
120 QDeclarativeUtilModule::registerBaseTypes(uri, versionMajor, versionMinor);
124 \qmlclass QtObject QObject
125 \ingroup qml-utility-elements
127 \brief The QtObject element is the most basic element in QML.
129 The QtObject element is a non-visual element which contains only the
132 It can be useful to create a QtObject if you need an extremely
133 lightweight element to enclose a set of custom properties:
135 \snippet doc/src/snippets/declarative/qtobject.qml 0
137 It can also be useful for C++ integration, as it is just a plain
138 QObject. See the QObject documentation for further details.
141 \qmlproperty string QML:QtObject::objectName
142 This property holds the QObject::objectName for this specific object instance.
144 This allows a C++ application to locate an item within a QML component
145 using the QObject::findChild() method. For example, the following C++
146 application locates the child \l Rectangle item and dynamically changes its
155 width: 200; height: 200
168 QDeclarativeView view;
169 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
172 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
174 item->setProperty("color", QColor(Qt::yellow));
178 struct StaticQtMetaObject : public QObject
180 static const QMetaObject *get()
181 { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
184 static bool qt_QmlQtModule_registered = false;
185 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
187 void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
189 qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
190 qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
191 qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
194 void QDeclarativeEnginePrivate::defineModule()
196 registerBaseTypes("QtQuick", 2, 0);
197 qmlRegisterType<QDeclarativeBinding>();
201 \qmlclass QML:Qt QDeclarativeEnginePrivate
202 \ingroup qml-utility-elements
203 \brief The QML global Qt object provides useful enums and functions from Qt.
205 \keyword QmlGlobalQtObject
207 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
209 The \c Qt object is a global object with utility functions, properties and enums.
211 It is not instantiable; to use it, call the members of the global \c Qt object directly.
218 color: Qt.rgba(1, 0, 0, 1)
219 text: Qt.md5("hello, world")
226 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
227 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
231 The Qt object also contains helper functions for creating objects of specific
232 data types. This is primarily useful when setting the properties of an item
233 when the property has one of the following types:
236 \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()}
237 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
238 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
239 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
240 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
243 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
245 \section1 Date/Time Formatters
247 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
250 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
251 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
252 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
255 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
258 \section1 Dynamic Object Creation
259 The following functions on the global object allow you to dynamically create QML
260 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
264 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
265 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
271 \qmlproperty object QML:Qt::application
274 The \c application object provides access to global application state
275 properties shared by many QML components.
281 \o \c application.active
283 This read-only property indicates whether the application is the top-most and focused
284 application, and the user is able to interact with the application. The property
285 is false when the application is in the background, the device keylock or screen
286 saver is active, the screen backlight is turned off, or the global system dialog
287 is being displayed on top of the application. It can be used for stopping and
288 pausing animations, timers and active processing of data in order to save device
289 battery power and free device memory and processor load when the application is not
293 \o \c application.layoutDirection
295 This read-only property can be used to query the default layout direction of the
296 application. On system start-up, the default layout direction depends on the
297 application's language. The property has a value of \c Qt.RightToLeft in locales
298 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
299 where the reading direction flows from left to right. You can bind to this
300 property to customize your application layouts to support both layout directions.
305 \o Qt.LeftToRight - Text and graphics elements should be positioned
307 \o Qt.RightToLeft - Text and graphics elements should be positioned
312 The following example uses the \c application object to indicate
313 whether the application is currently active:
315 \snippet doc/src/snippets/declarative/application.qml document
321 \qmlmethod object Qt::include(string url, jsobject callback)
323 Includes another JavaScript file. This method can only be used from within JavaScript files,
324 and not regular QML files.
326 This imports all functions from \a url into the current script's namespace.
328 Qt.include() returns an object that describes the status of the operation. The object has
329 a single property, \c {status}, that is set to one of the following values:
332 \header \o Symbol \o Value \o Description
333 \row \o result.OK \o 0 \o The include completed successfully.
334 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
335 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
336 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
337 An additional \c exception property will be set in this case.
340 The \c status property will be updated as the operation progresses.
342 If provided, \a callback is invoked when the operation completes. The callback is passed
343 the same object as is returned from the Qt.include() call.
345 // Qt.include() is implemented in qv8include.cpp
348 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
349 : captureProperties(false), rootContext(0), isDebugging(false),
350 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
351 cleanup(0), erroredBindings(0), inProgressCreations(0),
352 workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
353 networkAccessManager(0), networkAccessManagerFactory(0),
354 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
357 if (!qt_QmlQtModule_registered) {
358 qt_QmlQtModule_registered = true;
359 QDeclarativeUtilModule::defineModule();
360 QDeclarativeEnginePrivate::defineModule();
361 QSGItemsModule::defineModule();
362 QSGParticlesModule::defineModule();
363 QDeclarativeValueTypeFactory::registerValueTypes();
367 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
369 Q_ASSERT(inProgressCreations == 0);
370 Q_ASSERT(bindValues.isEmpty());
371 Q_ASSERT(parserStatus.isEmpty());
374 QDeclarativeCleanup *c = cleanup;
376 if (cleanup) cleanup->prev = &cleanup;
385 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
387 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
389 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
391 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
392 delete (*iter)->qobjectApi;
397 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
402 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
404 for (int ii = 0; ii < pss.count; ++ii) {
405 QDeclarativeParserStatus *ps = pss.at(ii);
412 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
414 QObjectPrivate *p = QObjectPrivate::get(o);
415 if (p->declarativeData) {
416 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
417 if (d->ownContext && d->context) {
418 d->context->destroy();
424 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
426 static_cast<QDeclarativeData *>(d)->destroyed(o);
429 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
431 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
434 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
436 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
439 void QDeclarativeEnginePrivate::init()
441 Q_Q(QDeclarativeEngine);
442 qRegisterMetaType<QVariant>("QVariant");
443 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
444 qRegisterMetaType<QScriptValue>("QScriptValue");
445 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
446 qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
447 qRegisterMetaType<QList<int> >("QList<int>");
448 qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
450 QDeclarativeData::init();
455 rootContext = new QDeclarativeContext(q,true);
457 if (QCoreApplication::instance()->thread() == q->thread() &&
458 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
460 QDeclarativeEngineDebugServer::instance()->addEngine(q);
461 QJSDebugService::instance()->addEngine(q);
465 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
467 Q_Q(QDeclarativeEngine);
468 if (!workerScriptEngine)
469 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
470 return workerScriptEngine;
474 \class QDeclarativeEngine
476 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
479 Each QML component is instantiated in a QDeclarativeContext.
480 QDeclarativeContext's are essential for passing data to QML
481 components. In QML, contexts are arranged hierarchically and this
482 hierarchy is managed by the QDeclarativeEngine.
484 Prior to creating any QML components, an application must have
485 created a QDeclarativeEngine to gain access to a QML context. The
486 following example shows how to create a simple Text item.
489 QDeclarativeEngine engine;
490 QDeclarativeComponent component(&engine);
491 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
492 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
494 //add item to view, etc
498 In this case, the Text item will be created in the engine's
499 \l {QDeclarativeEngine::rootContext()}{root context}.
501 \sa QDeclarativeComponent QDeclarativeContext
505 Create a new QDeclarativeEngine with the given \a parent.
507 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
508 : QObject(*new QDeclarativeEnginePrivate(this), parent)
510 Q_D(QDeclarativeEngine);
515 Destroys the QDeclarativeEngine.
517 Any QDeclarativeContext's created on this engine will be
518 invalidated, but not destroyed (unless they are parented to the
519 QDeclarativeEngine object).
521 QDeclarativeEngine::~QDeclarativeEngine()
523 Q_D(QDeclarativeEngine);
525 QDeclarativeEngineDebugServer::instance()->remEngine(this);
527 // if we are the parent of any of the qobject module api instances,
528 // we need to remove them from our internal list, in order to prevent
529 // a segfault in engine private dtor.
530 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
531 QObject *currQObjectApi = 0;
532 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
533 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
534 currInstance = d->moduleApiInstances.value(key);
535 currQObjectApi = currInstance->qobjectApi;
536 if (this->children().contains(currQObjectApi)) {
537 delete currQObjectApi;
539 d->moduleApiInstances.remove(key);
544 /*! \fn void QDeclarativeEngine::quit()
545 This signal is emitted when the QML loaded by the engine would like to quit.
548 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
549 This signal is emitted when \a warnings messages are generated by QML.
553 Clears the engine's internal component cache.
555 Normally the QDeclarativeEngine caches components loaded from qml
556 files. This method clears this cache and forces the component to be
559 void QDeclarativeEngine::clearComponentCache()
561 Q_D(QDeclarativeEngine);
562 d->typeLoader.clearCache();
566 Returns the engine's root context.
568 The root context is automatically created by the QDeclarativeEngine.
569 Data that should be available to all QML component instances
570 instantiated by the engine should be put in the root context.
572 Additional data that should only be available to a subset of
573 component instances should be added to sub-contexts parented to the
576 QDeclarativeContext *QDeclarativeEngine::rootContext() const
578 Q_D(const QDeclarativeEngine);
579 return d->rootContext;
583 Sets the \a factory to use for creating QNetworkAccessManager(s).
585 QNetworkAccessManager is used for all network access by QML. By
586 implementing a factory it is possible to create custom
587 QNetworkAccessManager with specialized caching, proxy and cookie
590 The factory must be set before executing the engine.
592 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
594 Q_D(QDeclarativeEngine);
595 QMutexLocker locker(&d->mutex);
596 d->networkAccessManagerFactory = factory;
600 Returns the current QDeclarativeNetworkAccessManagerFactory.
602 \sa setNetworkAccessManagerFactory()
604 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
606 Q_D(const QDeclarativeEngine);
607 return d->networkAccessManagerFactory;
610 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
612 QMutexLocker locker(&mutex);
613 QNetworkAccessManager *nam;
614 if (networkAccessManagerFactory) {
615 nam = networkAccessManagerFactory->create(parent);
617 nam = new QNetworkAccessManager(parent);
623 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
625 Q_Q(const QDeclarativeEngine);
626 if (!networkAccessManager)
627 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
628 return networkAccessManager;
632 Returns a common QNetworkAccessManager which can be used by any QML
633 element instantiated by this engine.
635 If a QDeclarativeNetworkAccessManagerFactory has been set and a
636 QNetworkAccessManager has not yet been created, the
637 QDeclarativeNetworkAccessManagerFactory will be used to create the
638 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
639 will have no proxy or cache set.
641 \sa setNetworkAccessManagerFactory()
643 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
645 Q_D(const QDeclarativeEngine);
646 return d->getNetworkAccessManager();
651 Sets the \a provider to use for images requested via the \e
652 image: url scheme, with host \a providerId. The QDeclarativeEngine
653 takes ownership of \a provider.
655 Image providers enable support for pixmap and threaded image
656 requests. See the QDeclarativeImageProvider documentation for details on
657 implementing and using image providers.
659 All required image providers should be added to the engine before any
660 QML sources files are loaded.
662 \sa removeImageProvider()
664 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
666 Q_D(QDeclarativeEngine);
667 QMutexLocker locker(&d->mutex);
668 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
672 Returns the QDeclarativeImageProvider set for \a providerId.
674 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
676 Q_D(const QDeclarativeEngine);
677 QMutexLocker locker(&d->mutex);
678 return d->imageProviders.value(providerId).data();
682 Removes the QDeclarativeImageProvider for \a providerId.
684 Returns the provider if it was found; otherwise returns 0.
686 \sa addImageProvider()
688 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
690 Q_D(QDeclarativeEngine);
691 QMutexLocker locker(&d->mutex);
692 d->imageProviders.take(providerId);
695 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
697 QMutexLocker locker(&mutex);
698 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
701 return provider->imageType();
702 return QDeclarativeImageProvider::Invalid;
705 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
707 QMutexLocker locker(&mutex);
708 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
711 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
712 return provider->requestTexture(imageId, size, req_size);
717 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
719 QMutexLocker locker(&mutex);
721 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
724 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
725 image = provider->requestImage(imageId, size, req_size);
730 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
732 QMutexLocker locker(&mutex);
734 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
737 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
738 pixmap = provider->requestPixmap(imageId, size, req_size);
744 Return the base URL for this engine. The base URL is only used to
745 resolve components when a relative URL is passed to the
746 QDeclarativeComponent constructor.
748 If a base URL has not been explicitly set, this method returns the
749 application's current working directory.
753 QUrl QDeclarativeEngine::baseUrl() const
755 Q_D(const QDeclarativeEngine);
756 if (d->baseUrl.isEmpty()) {
757 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
764 Set the base URL for this engine to \a url.
768 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
770 Q_D(QDeclarativeEngine);
775 Returns true if warning messages will be output to stderr in addition
776 to being emitted by the warnings() signal, otherwise false.
778 The default value is true.
780 bool QDeclarativeEngine::outputWarningsToStandardError() const
782 Q_D(const QDeclarativeEngine);
783 return d->outputWarningsToStdErr;
787 Set whether warning messages will be output to stderr to \a enabled.
789 If \a enabled is true, any warning messages generated by QML will be
790 output to stderr and emitted by the warnings() signal. If \a enabled
791 is false, on the warnings() signal will be emitted. This allows
792 applications to handle warning output themselves.
794 The default value is true.
796 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
798 Q_D(QDeclarativeEngine);
799 d->outputWarningsToStdErr = enabled;
803 Attempt to free unused memory.
805 void QDeclarativeEngine::collectGarbage()
811 Returns the QDeclarativeContext for the \a object, or 0 if no
812 context has been set.
814 When the QDeclarativeEngine instantiates a QObject, the context is
817 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
822 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
824 QDeclarativeData *data =
825 static_cast<QDeclarativeData *>(priv->declarativeData);
829 else if (data->outerContext)
830 return data->outerContext->asQDeclarativeContext();
836 Sets the QDeclarativeContext for the \a object to \a context.
837 If the \a object already has a context, a warning is
838 output, but the context is not changed.
840 When the QDeclarativeEngine instantiates a QObject, the context is
843 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
845 if (!object || !context)
848 QDeclarativeData *data = QDeclarativeData::get(object, true);
850 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
854 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
855 contextData->addObject(object);
859 \enum QDeclarativeEngine::ObjectOwnership
861 Ownership controls whether or not QML automatically destroys the
862 QObject when the object is garbage collected by the JavaScript
863 engine. The two ownership options are:
865 \value CppOwnership The object is owned by C++ code, and will
866 never be deleted by QML. The JavaScript destroy() method cannot be
867 used on objects with CppOwnership. This option is similar to
868 QScriptEngine::QtOwnership.
870 \value JavaScriptOwnership The object is owned by JavaScript.
871 When the object is returned to QML as the return value of a method
872 call or property access, QML will delete the object if there are no
873 remaining JavaScript references to it and it has no
874 QObject::parent(). This option is similar to
875 QScriptEngine::ScriptOwnership.
877 Generally an application doesn't need to set an object's ownership
878 explicitly. QML uses a heuristic to set the default object
879 ownership. By default, an object that is created by QML has
880 JavaScriptOwnership. The exception to this are the root objects
881 created by calling QDeclarativeCompnent::create() or
882 QDeclarativeComponent::beginCreate() which have CppOwnership by
883 default. The ownership of these root-level objects is considered to
884 have been transferred to the C++ caller.
886 Objects not-created by QML have CppOwnership by default. The
887 exception to this is objects returned from a C++ method call. The
888 ownership of these objects is passed to JavaScript.
890 Calling setObjectOwnership() overrides the default ownership
891 heuristic used by QML.
895 Sets the \a ownership of \a object.
897 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
902 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
906 ddata->indestructible = (ownership == CppOwnership)?true:false;
907 ddata->explicitIndestructibleSet = true;
911 Returns the ownership of \a object.
913 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
918 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
922 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
925 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
927 QDeclarativeData *data = QDeclarativeData::get(object);
929 if (data && data->deferredComponent) {
930 if (QDeclarativeDebugService::isDebuggingEnabled()) {
931 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
932 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
933 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
934 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
935 if (data->outerContext)
936 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
938 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
940 QDeclarativeComponentPrivate::ConstructionState state;
941 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
943 data->deferredComponent->release();
944 data->deferredComponent = 0;
946 QDeclarativeComponentPrivate::complete(ep, &state);
947 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
951 QDeclarativeContext *qmlContext(const QObject *obj)
953 return QDeclarativeEngine::contextForObject(obj);
956 QDeclarativeEngine *qmlEngine(const QObject *obj)
958 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
959 return context?context->engine():0;
962 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
964 QDeclarativeData *data = QDeclarativeData::get(object);
966 return 0; // Attached properties are only on objects created by QML
968 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
972 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
976 rv = pf(const_cast<QObject *>(object));
979 data->attachedProperties()->insert(id, rv);
984 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
985 const QMetaObject *attachedMetaObject, bool create)
988 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
990 if (*idCache == -1 || !object)
993 return qmlAttachedPropertiesObjectById(*idCache, object, create);
996 class QDeclarativeDataExtended {
998 QDeclarativeDataExtended();
999 ~QDeclarativeDataExtended();
1001 QHash<int, QObject *> attachedProperties;
1002 QDeclarativeNotifier objectNameNotifier;
1005 QDeclarativeDataExtended::QDeclarativeDataExtended()
1009 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1013 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1015 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1016 return &extendedData->objectNameNotifier;
1019 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1021 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1022 return &extendedData->attachedProperties;
1025 void QDeclarativeData::destroyed(QObject *object)
1027 if (deferredComponent)
1028 deferredComponent->release();
1030 if (nextContextObject)
1031 nextContextObject->prevContextObject = prevContextObject;
1032 if (prevContextObject)
1033 *prevContextObject = nextContextObject;
1035 QDeclarativeAbstractBinding *binding = bindings;
1037 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1038 binding->m_prevBinding = 0;
1039 binding->m_nextBinding = 0;
1048 propertyCache->release();
1050 if (ownContext && context)
1054 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1055 *guard = (QObject *)0;
1056 guard->objectDestroyed(object);
1060 delete extendedData;
1062 v8object.Clear(); // The WeakReference handler will clean the actual handle
1068 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1074 void QDeclarativeData::objectNameChanged(QObject *)
1076 if (extendedData) objectNameNotifier()->notify();
1079 bool QDeclarativeData::hasBindingBit(int bit) const
1081 if (bindingBitsSize > bit)
1082 return bindingBits[bit / 32] & (1 << (bit % 32));
1087 void QDeclarativeData::clearBindingBit(int bit)
1089 if (bindingBitsSize > bit)
1090 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1093 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1095 if (bindingBitsSize <= bit) {
1096 int props = obj->metaObject()->propertyCount();
1097 Q_ASSERT(bit < props);
1099 int arraySize = (props + 31) / 32;
1100 int oldArraySize = bindingBitsSize / 32;
1102 bindingBits = (quint32 *)realloc(bindingBits,
1103 arraySize * sizeof(quint32));
1105 memset(bindingBits + oldArraySize,
1107 sizeof(quint32) * (arraySize - oldArraySize));
1109 bindingBitsSize = arraySize * 32;
1112 bindingBits[bit / 32] |= (1 << (bit % 32));
1115 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1117 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1118 if (url.authority().isEmpty())
1119 return QLatin1Char(':') + url.path();
1122 return url.toLocalFile();
1125 void QDeclarativeEnginePrivate::sendQuit()
1127 Q_Q(QDeclarativeEngine);
1129 if (q->receivers(SIGNAL(quit())) == 0) {
1130 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1134 static void dumpwarning(const QDeclarativeError &error)
1136 qWarning().nospace() << qPrintable(error.toString());
1139 static void dumpwarning(const QList<QDeclarativeError> &errors)
1141 for (int ii = 0; ii < errors.count(); ++ii)
1142 dumpwarning(errors.at(ii));
1145 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1147 Q_Q(QDeclarativeEngine);
1148 q->warnings(QList<QDeclarativeError>() << error);
1149 if (outputWarningsToStdErr)
1153 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1155 Q_Q(QDeclarativeEngine);
1156 q->warnings(errors);
1157 if (outputWarningsToStdErr)
1158 dumpwarning(errors);
1161 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1164 QDeclarativeEnginePrivate::get(engine)->warning(error);
1169 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1172 QDeclarativeEnginePrivate::get(engine)->warning(error);
1177 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1180 engine->warning(error);
1185 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1188 engine->warning(error);
1194 This function should be called prior to evaluation of any js expression,
1195 so that scarce resources are not freed prematurely (eg, if there is a
1196 nested javascript expression).
1198 void QDeclarativeEnginePrivate::referenceScarceResources()
1200 scarceResourcesRefCount += 1;
1204 This function should be called after evaluation of the js expression is
1205 complete, and so the scarce resources may be freed safely.
1207 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1209 Q_ASSERT(scarceResourcesRefCount > 0);
1210 scarceResourcesRefCount -= 1;
1212 // if the refcount is zero, then evaluation of the "top level"
1213 // expression must have completed. We can safely release the
1214 // scarce resources.
1215 if (scarceResourcesRefCount == 0) {
1216 // iterate through the list and release them all.
1217 // note that the actual SRD is owned by the JS engine,
1218 // so we cannot delete the SRD; but we can free the
1219 // memory used by the variant in the SRD.
1220 while (ScarceResourceData *sr = scarceResources.first()) {
1221 sr->data = QVariant();
1222 scarceResources.remove(sr);
1228 Adds \a path as a directory where the engine searches for
1229 installed modules in a URL-based directory structure.
1230 The \a path may be a local filesystem directory or a URL.
1232 The newly added \a path will be first in the importPathList().
1234 \sa setImportPathList(), {QML Modules}
1236 void QDeclarativeEngine::addImportPath(const QString& path)
1238 Q_D(QDeclarativeEngine);
1239 d->importDatabase.addImportPath(path);
1243 Returns the list of directories where the engine searches for
1244 installed modules in a URL-based directory structure.
1246 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1247 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1248 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1249 provided by that module. A \c qmldir file is required for defining the
1250 type version mapping and possibly declarative extensions plugins.
1252 By default, the list contains the directory of the application executable,
1253 paths specified in the \c QML_IMPORT_PATH environment variable,
1254 and the builtin \c ImportsPath from QLibraryInfo.
1256 \sa addImportPath() setImportPathList()
1258 QStringList QDeclarativeEngine::importPathList() const
1260 Q_D(const QDeclarativeEngine);
1261 return d->importDatabase.importPathList();
1265 Sets \a paths as the list of directories where the engine searches for
1266 installed modules in a URL-based directory structure.
1268 By default, the list contains the directory of the application executable,
1269 paths specified in the \c QML_IMPORT_PATH environment variable,
1270 and the builtin \c ImportsPath from QLibraryInfo.
1272 \sa importPathList() addImportPath()
1274 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1276 Q_D(QDeclarativeEngine);
1277 d->importDatabase.setImportPathList(paths);
1282 Adds \a path as a directory where the engine searches for
1283 native plugins for imported modules (referenced in the \c qmldir file).
1285 By default, the list contains only \c ., i.e. the engine searches
1286 in the directory of the \c qmldir file itself.
1288 The newly added \a path will be first in the pluginPathList().
1290 \sa setPluginPathList()
1292 void QDeclarativeEngine::addPluginPath(const QString& path)
1294 Q_D(QDeclarativeEngine);
1295 d->importDatabase.addPluginPath(path);
1300 Returns the list of directories where the engine searches for
1301 native plugins for imported modules (referenced in the \c qmldir file).
1303 By default, the list contains only \c ., i.e. the engine searches
1304 in the directory of the \c qmldir file itself.
1306 \sa addPluginPath() setPluginPathList()
1308 QStringList QDeclarativeEngine::pluginPathList() const
1310 Q_D(const QDeclarativeEngine);
1311 return d->importDatabase.pluginPathList();
1315 Sets the list of directories where the engine searches for
1316 native plugins for imported modules (referenced in the \c qmldir file)
1319 By default, the list contains only \c ., i.e. the engine searches
1320 in the directory of the \c qmldir file itself.
1322 \sa pluginPathList() addPluginPath()
1324 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1326 Q_D(QDeclarativeEngine);
1327 d->importDatabase.setPluginPathList(paths);
1331 Imports the plugin named \a filePath with the \a uri provided.
1332 Returns true if the plugin was successfully imported; otherwise returns false.
1334 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1336 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1338 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1340 Q_D(QDeclarativeEngine);
1341 return d->importDatabase.importPlugin(filePath, uri, errors);
1345 Imports the plugin named \a filePath with the \a uri provided.
1346 Returns true if the plugin was successfully imported; otherwise returns false.
1348 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1350 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1352 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1354 Q_D(QDeclarativeEngine);
1355 QList<QDeclarativeError> errors;
1356 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1357 if (!errors.isEmpty()) {
1359 for (int i = 0; i < errors.size(); ++i) {
1360 builtError = QString(QLatin1String("%1\n %2"))
1362 .arg(errors.at(i).toString());
1364 *errorString = builtError;
1370 \property QDeclarativeEngine::offlineStoragePath
1371 \brief the directory for storing offline user data
1373 Returns the directory where SQL and other offline
1376 QDeclarativeWebView and the SQL databases created with openDatabase()
1379 The default is QML/OfflineStorage in the platform-standard
1380 user application data directory.
1382 Note that the path may not currently exist on the filesystem, so
1383 callers wanting to \e create new files at this location should create
1384 it first - see QDir::mkpath().
1386 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1388 Q_D(QDeclarativeEngine);
1389 qt_qmlsqldatabase_setOfflineStoragePath(&d->v8engine, dir);
1392 QString QDeclarativeEngine::offlineStoragePath() const
1394 Q_D(const QDeclarativeEngine);
1395 return qt_qmlsqldatabase_getOfflineStoragePath(&d->v8engine);
1398 static void voidptr_destructor(void *v)
1400 void **ptr = (void **)v;
1404 static void *voidptr_constructor(const void *v)
1409 return new void*(*(void **)v);
1413 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1415 Q_Q(QDeclarativeEngine);
1417 if (!mo->superClass()) {
1418 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1419 propertyCache.insert(mo, rv);
1422 QDeclarativePropertyCache *super = cache(mo->superClass());
1423 QDeclarativePropertyCache *rv = super->copy();
1425 propertyCache.insert(mo, rv);
1430 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1431 QDeclarativeError &error)
1433 QList<QDeclarativeType *> types;
1435 int maxMinorVersion = 0;
1437 const QMetaObject *metaObject = type->metaObject();
1438 while (metaObject) {
1439 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1440 type->majorVersion(), minorVersion);
1442 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1448 metaObject = metaObject->superClass();
1451 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1453 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1457 QDeclarativePropertyCache *raw = cache(type->metaObject());
1459 bool hasCopied = false;
1461 for (int ii = 0; ii < types.count(); ++ii) {
1462 QDeclarativeType *currentType = types.at(ii);
1466 int rev = currentType->metaObjectRevision();
1467 int moIndex = types.count() - 1 - ii;
1469 if (raw->allowedRevisionCache[moIndex] != rev) {
1474 raw->allowedRevisionCache[moIndex] = rev;
1478 // Test revision compatibility - the basic rule is:
1479 // * Anything that is excluded, cannot overload something that is not excluded *
1481 // Signals override:
1482 // * other signals and methods of the same name.
1483 // * properties named on<Signal Name>
1484 // * automatic <property name>Changed notify signals
1486 // Methods override:
1487 // * other methods of the same name
1489 // Properties override:
1490 // * other elements of the same name
1492 bool overloadError = false;
1493 QString overloadName;
1496 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1497 !overloadError && iter != raw->stringCache.end();
1500 QDeclarativePropertyCache::Data *d = *iter;
1501 if (raw->isAllowedInRevision(d))
1502 continue; // Not excluded - no problems
1504 // check that a regular "name" overload isn't happening
1505 QDeclarativePropertyCache::Data *current = d;
1506 while (!overloadError && current) {
1507 current = d->overrideData(current);
1508 if (current && raw->isAllowedInRevision(current))
1509 overloadError = true;
1514 if (overloadError) {
1515 if (hasCopied) raw->release();
1517 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."));
1521 if (!hasCopied) raw->addref();
1522 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1524 if (minorVersion != maxMinorVersion) {
1526 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1532 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1534 QByteArray name = data->root->className();
1536 QByteArray ptr = name + '*';
1537 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1539 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1540 voidptr_constructor);
1541 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1542 voidptr_constructor);
1544 m_qmlLists.insert(lst_type, ptr_type);
1545 m_compositeTypes.insert(ptr_type, data);
1549 bool QDeclarativeEnginePrivate::isList(int t) const
1551 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1554 int QDeclarativeEnginePrivate::listType(int t) const
1556 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1557 if (iter != m_qmlLists.end())
1560 return QDeclarativeMetaType::listType(t);
1563 bool QDeclarativeEnginePrivate::isQObject(int t)
1565 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1568 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1570 int t = v.userType();
1571 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1573 return *(QObject **)(v.constData());
1575 return QDeclarativeMetaType::toQObject(v, ok);
1579 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1581 if (m_compositeTypes.contains(t))
1582 return QDeclarativeMetaType::Object;
1583 else if (m_qmlLists.contains(t))
1584 return QDeclarativeMetaType::List;
1586 return QDeclarativeMetaType::typeCategory(t);
1589 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1591 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1592 if (iter != m_compositeTypes.end()) {
1593 return (*iter)->root;
1595 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1596 return type?type->baseMetaObject():0;
1600 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1602 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1603 if (iter != m_compositeTypes.end()) {
1604 return (*iter)->root;
1606 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1607 return type?type->metaObject():0;
1611 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1613 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1614 QFileInfo info(fileName);
1616 QString absolute = info.absoluteFilePath();
1618 #if defined(Q_OS_MAC)
1619 QString canonical = info.canonicalFilePath();
1620 #elif defined(Q_OS_WIN32)
1621 wchar_t buffer[1024];
1623 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1624 if (rv == 0 || rv >= 1024) return true;
1625 rv = ::GetLongPathName(buffer, buffer, 1024);
1626 if (rv == 0 || rv >= 1024) return true;
1628 QString canonical((QChar *)buffer);
1631 int absoluteLength = absolute.length();
1632 int canonicalLength = canonical.length();
1634 int length = qMin(absoluteLength, canonicalLength);
1635 for (int ii = 0; ii < length; ++ii) {
1636 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1637 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1639 if (a.toLower() != c.toLower())