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<QJSValue>("QJSValue");
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();
452 v8engine()->setEngine(q);
454 rootContext = new QDeclarativeContext(q,true);
456 if (QCoreApplication::instance()->thread() == q->thread() &&
457 QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
459 QDeclarativeEngineDebugServer::instance()->addEngine(q);
460 QJSDebugService::instance()->addEngine(q);
464 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
466 Q_Q(QDeclarativeEngine);
467 if (!workerScriptEngine)
468 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
469 return workerScriptEngine;
473 \class QDeclarativeEngine
475 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
478 Each QML component is instantiated in a QDeclarativeContext.
479 QDeclarativeContext's are essential for passing data to QML
480 components. In QML, contexts are arranged hierarchically and this
481 hierarchy is managed by the QDeclarativeEngine.
483 Prior to creating any QML components, an application must have
484 created a QDeclarativeEngine to gain access to a QML context. The
485 following example shows how to create a simple Text item.
488 QDeclarativeEngine engine;
489 QDeclarativeComponent component(&engine);
490 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
491 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
493 //add item to view, etc
497 In this case, the Text item will be created in the engine's
498 \l {QDeclarativeEngine::rootContext()}{root context}.
500 \sa QDeclarativeComponent QDeclarativeContext
504 Create a new QDeclarativeEngine with the given \a parent.
506 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
507 : QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
509 Q_D(QDeclarativeEngine);
514 Destroys the QDeclarativeEngine.
516 Any QDeclarativeContext's created on this engine will be
517 invalidated, but not destroyed (unless they are parented to the
518 QDeclarativeEngine object).
520 QDeclarativeEngine::~QDeclarativeEngine()
522 Q_D(QDeclarativeEngine);
524 QDeclarativeEngineDebugServer::instance()->remEngine(this);
526 // if we are the parent of any of the qobject module api instances,
527 // we need to remove them from our internal list, in order to prevent
528 // a segfault in engine private dtor.
529 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
530 QObject *currQObjectApi = 0;
531 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
532 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
533 currInstance = d->moduleApiInstances.value(key);
534 currQObjectApi = currInstance->qobjectApi;
535 if (this->children().contains(currQObjectApi)) {
536 delete currQObjectApi;
538 d->moduleApiInstances.remove(key);
543 /*! \fn void QDeclarativeEngine::quit()
544 This signal is emitted when the QML loaded by the engine would like to quit.
547 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
548 This signal is emitted when \a warnings messages are generated by QML.
552 Clears the engine's internal component cache.
554 Normally the QDeclarativeEngine caches components loaded from qml
555 files. This method clears this cache and forces the component to be
558 void QDeclarativeEngine::clearComponentCache()
560 Q_D(QDeclarativeEngine);
561 d->typeLoader.clearCache();
565 Returns the engine's root context.
567 The root context is automatically created by the QDeclarativeEngine.
568 Data that should be available to all QML component instances
569 instantiated by the engine should be put in the root context.
571 Additional data that should only be available to a subset of
572 component instances should be added to sub-contexts parented to the
575 QDeclarativeContext *QDeclarativeEngine::rootContext() const
577 Q_D(const QDeclarativeEngine);
578 return d->rootContext;
582 Sets the \a factory to use for creating QNetworkAccessManager(s).
584 QNetworkAccessManager is used for all network access by QML. By
585 implementing a factory it is possible to create custom
586 QNetworkAccessManager with specialized caching, proxy and cookie
589 The factory must be set before executing the engine.
591 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
593 Q_D(QDeclarativeEngine);
594 QMutexLocker locker(&d->mutex);
595 d->networkAccessManagerFactory = factory;
599 Returns the current QDeclarativeNetworkAccessManagerFactory.
601 \sa setNetworkAccessManagerFactory()
603 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
605 Q_D(const QDeclarativeEngine);
606 return d->networkAccessManagerFactory;
609 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
611 QMutexLocker locker(&mutex);
612 QNetworkAccessManager *nam;
613 if (networkAccessManagerFactory) {
614 nam = networkAccessManagerFactory->create(parent);
616 nam = new QNetworkAccessManager(parent);
622 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
624 Q_Q(const QDeclarativeEngine);
625 if (!networkAccessManager)
626 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
627 return networkAccessManager;
631 Returns a common QNetworkAccessManager which can be used by any QML
632 element instantiated by this engine.
634 If a QDeclarativeNetworkAccessManagerFactory has been set and a
635 QNetworkAccessManager has not yet been created, the
636 QDeclarativeNetworkAccessManagerFactory will be used to create the
637 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
638 will have no proxy or cache set.
640 \sa setNetworkAccessManagerFactory()
642 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
644 Q_D(const QDeclarativeEngine);
645 return d->getNetworkAccessManager();
650 Sets the \a provider to use for images requested via the \e
651 image: url scheme, with host \a providerId. The QDeclarativeEngine
652 takes ownership of \a provider.
654 Image providers enable support for pixmap and threaded image
655 requests. See the QDeclarativeImageProvider documentation for details on
656 implementing and using image providers.
658 All required image providers should be added to the engine before any
659 QML sources files are loaded.
661 \sa removeImageProvider()
663 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
665 Q_D(QDeclarativeEngine);
666 QMutexLocker locker(&d->mutex);
667 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
671 Returns the QDeclarativeImageProvider set for \a providerId.
673 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
675 Q_D(const QDeclarativeEngine);
676 QMutexLocker locker(&d->mutex);
677 return d->imageProviders.value(providerId).data();
681 Removes the QDeclarativeImageProvider for \a providerId.
683 Returns the provider if it was found; otherwise returns 0.
685 \sa addImageProvider()
687 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
689 Q_D(QDeclarativeEngine);
690 QMutexLocker locker(&d->mutex);
691 d->imageProviders.take(providerId);
694 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
696 QMutexLocker locker(&mutex);
697 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
700 return provider->imageType();
701 return QDeclarativeImageProvider::Invalid;
704 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
706 QMutexLocker locker(&mutex);
707 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
710 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
711 return provider->requestTexture(imageId, size, req_size);
716 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
718 QMutexLocker locker(&mutex);
720 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
723 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
724 image = provider->requestImage(imageId, size, req_size);
729 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
731 QMutexLocker locker(&mutex);
733 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
736 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
737 pixmap = provider->requestPixmap(imageId, size, req_size);
743 Return the base URL for this engine. The base URL is only used to
744 resolve components when a relative URL is passed to the
745 QDeclarativeComponent constructor.
747 If a base URL has not been explicitly set, this method returns the
748 application's current working directory.
752 QUrl QDeclarativeEngine::baseUrl() const
754 Q_D(const QDeclarativeEngine);
755 if (d->baseUrl.isEmpty()) {
756 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
763 Set the base URL for this engine to \a url.
767 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
769 Q_D(QDeclarativeEngine);
774 Returns true if warning messages will be output to stderr in addition
775 to being emitted by the warnings() signal, otherwise false.
777 The default value is true.
779 bool QDeclarativeEngine::outputWarningsToStandardError() const
781 Q_D(const QDeclarativeEngine);
782 return d->outputWarningsToStdErr;
786 Set whether warning messages will be output to stderr to \a enabled.
788 If \a enabled is true, any warning messages generated by QML will be
789 output to stderr and emitted by the warnings() signal. If \a enabled
790 is false, on the warnings() signal will be emitted. This allows
791 applications to handle warning output themselves.
793 The default value is true.
795 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
797 Q_D(QDeclarativeEngine);
798 d->outputWarningsToStdErr = enabled;
802 Attempt to free unused memory.
804 void QDeclarativeEngine::collectGarbage()
810 Returns the QDeclarativeContext for the \a object, or 0 if no
811 context has been set.
813 When the QDeclarativeEngine instantiates a QObject, the context is
816 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
821 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
823 QDeclarativeData *data =
824 static_cast<QDeclarativeData *>(priv->declarativeData);
828 else if (data->outerContext)
829 return data->outerContext->asQDeclarativeContext();
835 Sets the QDeclarativeContext for the \a object to \a context.
836 If the \a object already has a context, a warning is
837 output, but the context is not changed.
839 When the QDeclarativeEngine instantiates a QObject, the context is
842 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
844 if (!object || !context)
847 QDeclarativeData *data = QDeclarativeData::get(object, true);
849 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
853 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
854 contextData->addObject(object);
858 \enum QDeclarativeEngine::ObjectOwnership
860 Ownership controls whether or not QML automatically destroys the
861 QObject when the object is garbage collected by the JavaScript
862 engine. The two ownership options are:
864 \value CppOwnership The object is owned by C++ code, and will
865 never be deleted by QML. The JavaScript destroy() method cannot be
866 used on objects with CppOwnership. This option is similar to
867 QScriptEngine::QtOwnership.
869 \value JavaScriptOwnership The object is owned by JavaScript.
870 When the object is returned to QML as the return value of a method
871 call or property access, QML will delete the object if there are no
872 remaining JavaScript references to it and it has no
873 QObject::parent(). This option is similar to
874 QScriptEngine::ScriptOwnership.
876 Generally an application doesn't need to set an object's ownership
877 explicitly. QML uses a heuristic to set the default object
878 ownership. By default, an object that is created by QML has
879 JavaScriptOwnership. The exception to this are the root objects
880 created by calling QDeclarativeCompnent::create() or
881 QDeclarativeComponent::beginCreate() which have CppOwnership by
882 default. The ownership of these root-level objects is considered to
883 have been transferred to the C++ caller.
885 Objects not-created by QML have CppOwnership by default. The
886 exception to this is objects returned from a C++ method call. The
887 ownership of these objects is passed to JavaScript.
889 Calling setObjectOwnership() overrides the default ownership
890 heuristic used by QML.
894 Sets the \a ownership of \a object.
896 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
901 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
905 ddata->indestructible = (ownership == CppOwnership)?true:false;
906 ddata->explicitIndestructibleSet = true;
910 Returns the ownership of \a object.
912 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
917 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
921 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
924 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
926 QDeclarativeData *data = QDeclarativeData::get(object);
928 if (data && data->deferredComponent) {
929 if (QDeclarativeDebugService::isDebuggingEnabled()) {
930 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
931 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
932 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
933 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
934 if (data->outerContext)
935 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
937 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
939 QDeclarativeComponentPrivate::ConstructionState state;
940 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
942 data->deferredComponent->release();
943 data->deferredComponent = 0;
945 QDeclarativeComponentPrivate::complete(ep, &state);
946 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
950 QDeclarativeContext *qmlContext(const QObject *obj)
952 return QDeclarativeEngine::contextForObject(obj);
955 QDeclarativeEngine *qmlEngine(const QObject *obj)
957 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
958 return context?context->engine():0;
961 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
963 QDeclarativeData *data = QDeclarativeData::get(object);
965 return 0; // Attached properties are only on objects created by QML
967 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
971 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
975 rv = pf(const_cast<QObject *>(object));
978 data->attachedProperties()->insert(id, rv);
983 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
984 const QMetaObject *attachedMetaObject, bool create)
987 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
989 if (*idCache == -1 || !object)
992 return qmlAttachedPropertiesObjectById(*idCache, object, create);
995 class QDeclarativeDataExtended {
997 QDeclarativeDataExtended();
998 ~QDeclarativeDataExtended();
1000 QHash<int, QObject *> attachedProperties;
1001 QDeclarativeNotifier objectNameNotifier;
1004 QDeclarativeDataExtended::QDeclarativeDataExtended()
1008 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1012 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1014 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1015 return &extendedData->objectNameNotifier;
1018 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1020 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1021 return &extendedData->attachedProperties;
1024 void QDeclarativeData::destroyed(QObject *object)
1026 if (deferredComponent)
1027 deferredComponent->release();
1029 if (nextContextObject)
1030 nextContextObject->prevContextObject = prevContextObject;
1031 if (prevContextObject)
1032 *prevContextObject = nextContextObject;
1034 QDeclarativeAbstractBinding *binding = bindings;
1036 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1037 binding->m_prevBinding = 0;
1038 binding->m_nextBinding = 0;
1047 propertyCache->release();
1049 if (ownContext && context)
1053 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1054 *guard = (QObject *)0;
1055 guard->objectDestroyed(object);
1059 delete extendedData;
1061 v8object.Clear(); // The WeakReference handler will clean the actual handle
1067 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1073 void QDeclarativeData::objectNameChanged(QObject *)
1075 if (extendedData) objectNameNotifier()->notify();
1078 bool QDeclarativeData::hasBindingBit(int bit) const
1080 if (bindingBitsSize > bit)
1081 return bindingBits[bit / 32] & (1 << (bit % 32));
1086 void QDeclarativeData::clearBindingBit(int bit)
1088 if (bindingBitsSize > bit)
1089 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1092 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1094 if (bindingBitsSize <= bit) {
1095 int props = obj->metaObject()->propertyCount();
1096 Q_ASSERT(bit < props);
1098 int arraySize = (props + 31) / 32;
1099 int oldArraySize = bindingBitsSize / 32;
1101 bindingBits = (quint32 *)realloc(bindingBits,
1102 arraySize * sizeof(quint32));
1104 memset(bindingBits + oldArraySize,
1106 sizeof(quint32) * (arraySize - oldArraySize));
1108 bindingBitsSize = arraySize * 32;
1111 bindingBits[bit / 32] |= (1 << (bit % 32));
1114 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1116 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1117 if (url.authority().isEmpty())
1118 return QLatin1Char(':') + url.path();
1121 return url.toLocalFile();
1124 void QDeclarativeEnginePrivate::sendQuit()
1126 Q_Q(QDeclarativeEngine);
1128 if (q->receivers(SIGNAL(quit())) == 0) {
1129 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1133 static void dumpwarning(const QDeclarativeError &error)
1135 qWarning().nospace() << qPrintable(error.toString());
1138 static void dumpwarning(const QList<QDeclarativeError> &errors)
1140 for (int ii = 0; ii < errors.count(); ++ii)
1141 dumpwarning(errors.at(ii));
1144 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1146 Q_Q(QDeclarativeEngine);
1147 q->warnings(QList<QDeclarativeError>() << error);
1148 if (outputWarningsToStdErr)
1152 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1154 Q_Q(QDeclarativeEngine);
1155 q->warnings(errors);
1156 if (outputWarningsToStdErr)
1157 dumpwarning(errors);
1160 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1163 QDeclarativeEnginePrivate::get(engine)->warning(error);
1168 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1171 QDeclarativeEnginePrivate::get(engine)->warning(error);
1176 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1179 engine->warning(error);
1184 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1187 engine->warning(error);
1193 This function should be called prior to evaluation of any js expression,
1194 so that scarce resources are not freed prematurely (eg, if there is a
1195 nested javascript expression).
1197 void QDeclarativeEnginePrivate::referenceScarceResources()
1199 scarceResourcesRefCount += 1;
1203 This function should be called after evaluation of the js expression is
1204 complete, and so the scarce resources may be freed safely.
1206 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1208 Q_ASSERT(scarceResourcesRefCount > 0);
1209 scarceResourcesRefCount -= 1;
1211 // if the refcount is zero, then evaluation of the "top level"
1212 // expression must have completed. We can safely release the
1213 // scarce resources.
1214 if (scarceResourcesRefCount == 0) {
1215 // iterate through the list and release them all.
1216 // note that the actual SRD is owned by the JS engine,
1217 // so we cannot delete the SRD; but we can free the
1218 // memory used by the variant in the SRD.
1219 while (ScarceResourceData *sr = scarceResources.first()) {
1220 sr->data = QVariant();
1221 scarceResources.remove(sr);
1227 Adds \a path as a directory where the engine searches for
1228 installed modules in a URL-based directory structure.
1229 The \a path may be a local filesystem directory or a URL.
1231 The newly added \a path will be first in the importPathList().
1233 \sa setImportPathList(), {QML Modules}
1235 void QDeclarativeEngine::addImportPath(const QString& path)
1237 Q_D(QDeclarativeEngine);
1238 d->importDatabase.addImportPath(path);
1242 Returns the list of directories where the engine searches for
1243 installed modules in a URL-based directory structure.
1245 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1246 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1247 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1248 provided by that module. A \c qmldir file is required for defining the
1249 type version mapping and possibly declarative extensions plugins.
1251 By default, the list contains the directory of the application executable,
1252 paths specified in the \c QML_IMPORT_PATH environment variable,
1253 and the builtin \c ImportsPath from QLibraryInfo.
1255 \sa addImportPath() setImportPathList()
1257 QStringList QDeclarativeEngine::importPathList() const
1259 Q_D(const QDeclarativeEngine);
1260 return d->importDatabase.importPathList();
1264 Sets \a paths as the list of directories where the engine searches for
1265 installed modules in a URL-based directory structure.
1267 By default, the list contains the directory of the application executable,
1268 paths specified in the \c QML_IMPORT_PATH environment variable,
1269 and the builtin \c ImportsPath from QLibraryInfo.
1271 \sa importPathList() addImportPath()
1273 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1275 Q_D(QDeclarativeEngine);
1276 d->importDatabase.setImportPathList(paths);
1281 Adds \a path as a directory where the engine searches for
1282 native plugins for imported modules (referenced in the \c qmldir file).
1284 By default, the list contains only \c ., i.e. the engine searches
1285 in the directory of the \c qmldir file itself.
1287 The newly added \a path will be first in the pluginPathList().
1289 \sa setPluginPathList()
1291 void QDeclarativeEngine::addPluginPath(const QString& path)
1293 Q_D(QDeclarativeEngine);
1294 d->importDatabase.addPluginPath(path);
1299 Returns the list of directories where the engine searches for
1300 native plugins for imported modules (referenced in the \c qmldir file).
1302 By default, the list contains only \c ., i.e. the engine searches
1303 in the directory of the \c qmldir file itself.
1305 \sa addPluginPath() setPluginPathList()
1307 QStringList QDeclarativeEngine::pluginPathList() const
1309 Q_D(const QDeclarativeEngine);
1310 return d->importDatabase.pluginPathList();
1314 Sets the list of directories where the engine searches for
1315 native plugins for imported modules (referenced in the \c qmldir file)
1318 By default, the list contains only \c ., i.e. the engine searches
1319 in the directory of the \c qmldir file itself.
1321 \sa pluginPathList() addPluginPath()
1323 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1325 Q_D(QDeclarativeEngine);
1326 d->importDatabase.setPluginPathList(paths);
1330 Imports the plugin named \a filePath with the \a uri provided.
1331 Returns true if the plugin was successfully imported; otherwise returns false.
1333 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1335 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1337 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1339 Q_D(QDeclarativeEngine);
1340 return d->importDatabase.importPlugin(filePath, uri, errors);
1344 Imports the plugin named \a filePath with the \a uri provided.
1345 Returns true if the plugin was successfully imported; otherwise returns false.
1347 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1349 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1351 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1353 Q_D(QDeclarativeEngine);
1354 QList<QDeclarativeError> errors;
1355 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1356 if (!errors.isEmpty()) {
1358 for (int i = 0; i < errors.size(); ++i) {
1359 builtError = QString(QLatin1String("%1\n %2"))
1361 .arg(errors.at(i).toString());
1363 *errorString = builtError;
1369 \property QDeclarativeEngine::offlineStoragePath
1370 \brief the directory for storing offline user data
1372 Returns the directory where SQL and other offline
1375 QDeclarativeWebView and the SQL databases created with openDatabase()
1378 The default is QML/OfflineStorage in the platform-standard
1379 user application data directory.
1381 Note that the path may not currently exist on the filesystem, so
1382 callers wanting to \e create new files at this location should create
1383 it first - see QDir::mkpath().
1385 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1387 Q_D(QDeclarativeEngine);
1388 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1391 QString QDeclarativeEngine::offlineStoragePath() const
1393 Q_D(const QDeclarativeEngine);
1394 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1397 static void voidptr_destructor(void *v)
1399 void **ptr = (void **)v;
1403 static void *voidptr_constructor(const void *v)
1408 return new void*(*(void **)v);
1412 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1414 Q_Q(QDeclarativeEngine);
1416 if (!mo->superClass()) {
1417 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1418 propertyCache.insert(mo, rv);
1421 QDeclarativePropertyCache *super = cache(mo->superClass());
1422 QDeclarativePropertyCache *rv = super->copy();
1424 propertyCache.insert(mo, rv);
1429 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1430 QDeclarativeError &error)
1432 QList<QDeclarativeType *> types;
1434 int maxMinorVersion = 0;
1436 const QMetaObject *metaObject = type->metaObject();
1437 while (metaObject) {
1438 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1439 type->majorVersion(), minorVersion);
1441 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1447 metaObject = metaObject->superClass();
1450 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1452 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1456 QDeclarativePropertyCache *raw = cache(type->metaObject());
1458 bool hasCopied = false;
1460 for (int ii = 0; ii < types.count(); ++ii) {
1461 QDeclarativeType *currentType = types.at(ii);
1465 int rev = currentType->metaObjectRevision();
1466 int moIndex = types.count() - 1 - ii;
1468 if (raw->allowedRevisionCache[moIndex] != rev) {
1473 raw->allowedRevisionCache[moIndex] = rev;
1477 // Test revision compatibility - the basic rule is:
1478 // * Anything that is excluded, cannot overload something that is not excluded *
1480 // Signals override:
1481 // * other signals and methods of the same name.
1482 // * properties named on<Signal Name>
1483 // * automatic <property name>Changed notify signals
1485 // Methods override:
1486 // * other methods of the same name
1488 // Properties override:
1489 // * other elements of the same name
1491 bool overloadError = false;
1492 QString overloadName;
1495 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1496 !overloadError && iter != raw->stringCache.end();
1499 QDeclarativePropertyCache::Data *d = *iter;
1500 if (raw->isAllowedInRevision(d))
1501 continue; // Not excluded - no problems
1503 // check that a regular "name" overload isn't happening
1504 QDeclarativePropertyCache::Data *current = d;
1505 while (!overloadError && current) {
1506 current = d->overrideData(current);
1507 if (current && raw->isAllowedInRevision(current))
1508 overloadError = true;
1513 if (overloadError) {
1514 if (hasCopied) raw->release();
1516 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."));
1520 if (!hasCopied) raw->addref();
1521 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1523 if (minorVersion != maxMinorVersion) {
1525 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1531 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1533 QByteArray name = data->root->className();
1535 QByteArray ptr = name + '*';
1536 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1538 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1539 voidptr_constructor);
1540 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1541 voidptr_constructor);
1543 m_qmlLists.insert(lst_type, ptr_type);
1544 m_compositeTypes.insert(ptr_type, data);
1548 bool QDeclarativeEnginePrivate::isList(int t) const
1550 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1553 int QDeclarativeEnginePrivate::listType(int t) const
1555 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1556 if (iter != m_qmlLists.end())
1559 return QDeclarativeMetaType::listType(t);
1562 bool QDeclarativeEnginePrivate::isQObject(int t)
1564 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1567 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1569 int t = v.userType();
1570 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1572 return *(QObject **)(v.constData());
1574 return QDeclarativeMetaType::toQObject(v, ok);
1578 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1580 if (m_compositeTypes.contains(t))
1581 return QDeclarativeMetaType::Object;
1582 else if (m_qmlLists.contains(t))
1583 return QDeclarativeMetaType::List;
1585 return QDeclarativeMetaType::typeCategory(t);
1588 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1590 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1591 if (iter != m_compositeTypes.end()) {
1592 return (*iter)->root;
1594 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1595 return type?type->baseMetaObject():0;
1599 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1601 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1602 if (iter != m_compositeTypes.end()) {
1603 return (*iter)->root;
1605 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1606 return type?type->metaObject():0;
1610 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1612 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1613 QFileInfo info(fileName);
1615 QString absolute = info.absoluteFilePath();
1617 #if defined(Q_OS_MAC)
1618 QString canonical = info.canonicalFilePath();
1619 #elif defined(Q_OS_WIN32)
1620 wchar_t buffer[1024];
1622 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1623 if (rv == 0 || rv >= 1024) return true;
1624 rv = ::GetLongPathName(buffer, buffer, 1024);
1625 if (rv == 0 || rv >= 1024) return true;
1627 QString canonical((QChar *)buffer);
1630 int absoluteLength = absolute.length();
1631 int canonicalLength = canonical.length();
1633 int length = qMin(absoluteLength, canonicalLength);
1634 for (int ii = 0; ii < length; ++ii) {
1635 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1636 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1638 if (a.toLower() != c.toLower())