1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "private/qdeclarativeengine_p.h"
43 #include "qdeclarativeengine.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativecompiler_p.h"
47 #include "qdeclarative.h"
48 #include "qdeclarativecontext.h"
49 #include "qdeclarativeexpression.h"
50 #include "qdeclarativecomponent.h"
51 #include "private/qdeclarativebinding_p_p.h"
52 #include "private/qdeclarativevme_p.h"
53 #include "private/qdeclarativeenginedebug_p.h"
54 #include "private/qdeclarativestringconverters_p.h"
55 #include "private/qdeclarativexmlhttprequest_p.h"
56 #include "private/qdeclarativesqldatabase_p.h"
57 #include "qdeclarativescriptstring.h"
58 #include "private/qdeclarativeglobal_p.h"
59 #include "private/qdeclarativeworkerscript_p.h"
60 #include "private/qdeclarativecomponent_p.h"
61 #include "qdeclarativenetworkaccessmanagerfactory.h"
62 #include "qdeclarativeimageprovider.h"
63 #include "private/qdeclarativedirparser_p.h"
64 #include "qdeclarativeextensioninterface.h"
65 #include "private/qdeclarativelist_p.h"
66 #include "private/qdeclarativetypenamecache_p.h"
67 #include "private/qdeclarativenotifier_p.h"
68 #include "private/qdeclarativedebugtrace_p.h"
69 #include "private/qdeclarativeapplication_p.h"
70 #include "private/qjsdebugservice_p.h"
72 #include <QtCore/qmetaobject.h>
73 #include <QNetworkReply>
74 #include <QNetworkRequest>
75 #include <QNetworkAccessManager>
76 #include <QDesktopServices>
81 #include <QMetaObject>
84 #include <QPluginLoader>
85 #include <QtGui/qfontdatabase.h>
86 #include <QtCore/qlibraryinfo.h>
87 #include <QtCore/qthreadstorage.h>
88 #include <QtCore/qthread.h>
89 #include <QtCore/qcoreapplication.h>
90 #include <QtCore/qdir.h>
91 #include <QtCore/qmutex.h>
92 #include <QtGui/qcolor.h>
93 #include <QtGui/qvector3d.h>
94 #include <QtGui/qsound.h>
95 #include <QtCore/qcryptographichash.h>
97 #include <private/qobject_p.h>
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 QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
997 #ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
998 if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
999 qWarning("Qml debugging is enabled. Only use this in a safe environment!");
1001 QDeclarativeEnginePrivate::qml_debugging_enabled = true;
1006 class QDeclarativeDataExtended {
1008 QDeclarativeDataExtended();
1009 ~QDeclarativeDataExtended();
1011 QHash<int, QObject *> attachedProperties;
1012 QDeclarativeNotifier objectNameNotifier;
1015 QDeclarativeDataExtended::QDeclarativeDataExtended()
1019 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1023 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1025 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1026 return &extendedData->objectNameNotifier;
1029 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1031 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1032 return &extendedData->attachedProperties;
1035 void QDeclarativeData::destroyed(QObject *object)
1037 if (deferredComponent)
1038 deferredComponent->release();
1040 if (nextContextObject)
1041 nextContextObject->prevContextObject = prevContextObject;
1042 if (prevContextObject)
1043 *prevContextObject = nextContextObject;
1045 QDeclarativeAbstractBinding *binding = bindings;
1047 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1048 binding->m_prevBinding = 0;
1049 binding->m_nextBinding = 0;
1058 propertyCache->release();
1060 if (ownContext && context)
1064 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1065 *guard = (QObject *)0;
1066 guard->objectDestroyed(object);
1070 delete extendedData;
1072 v8object.Clear(); // The WeakReference handler will clean the actual handle
1078 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1084 void QDeclarativeData::objectNameChanged(QObject *)
1086 if (extendedData) objectNameNotifier()->notify();
1089 bool QDeclarativeData::hasBindingBit(int bit) const
1091 if (bindingBitsSize > bit)
1092 return bindingBits[bit / 32] & (1 << (bit % 32));
1097 void QDeclarativeData::clearBindingBit(int bit)
1099 if (bindingBitsSize > bit)
1100 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1103 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1105 if (bindingBitsSize <= bit) {
1106 int props = obj->metaObject()->propertyCount();
1107 Q_ASSERT(bit < props);
1109 int arraySize = (props + 31) / 32;
1110 int oldArraySize = bindingBitsSize / 32;
1112 bindingBits = (quint32 *)realloc(bindingBits,
1113 arraySize * sizeof(quint32));
1115 memset(bindingBits + oldArraySize,
1117 sizeof(quint32) * (arraySize - oldArraySize));
1119 bindingBitsSize = arraySize * 32;
1122 bindingBits[bit / 32] |= (1 << (bit % 32));
1125 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1127 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1128 if (url.authority().isEmpty())
1129 return QLatin1Char(':') + url.path();
1132 return url.toLocalFile();
1135 void QDeclarativeEnginePrivate::sendQuit()
1137 Q_Q(QDeclarativeEngine);
1139 if (q->receivers(SIGNAL(quit())) == 0) {
1140 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1144 static void dumpwarning(const QDeclarativeError &error)
1146 qWarning().nospace() << qPrintable(error.toString());
1149 static void dumpwarning(const QList<QDeclarativeError> &errors)
1151 for (int ii = 0; ii < errors.count(); ++ii)
1152 dumpwarning(errors.at(ii));
1155 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1157 Q_Q(QDeclarativeEngine);
1158 q->warnings(QList<QDeclarativeError>() << error);
1159 if (outputWarningsToStdErr)
1163 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1165 Q_Q(QDeclarativeEngine);
1166 q->warnings(errors);
1167 if (outputWarningsToStdErr)
1168 dumpwarning(errors);
1171 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1174 QDeclarativeEnginePrivate::get(engine)->warning(error);
1179 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1182 QDeclarativeEnginePrivate::get(engine)->warning(error);
1187 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1190 engine->warning(error);
1195 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1198 engine->warning(error);
1204 This function should be called prior to evaluation of any js expression,
1205 so that scarce resources are not freed prematurely (eg, if there is a
1206 nested javascript expression).
1208 void QDeclarativeEnginePrivate::referenceScarceResources()
1210 scarceResourcesRefCount += 1;
1214 This function should be called after evaluation of the js expression is
1215 complete, and so the scarce resources may be freed safely.
1217 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1219 Q_ASSERT(scarceResourcesRefCount > 0);
1220 scarceResourcesRefCount -= 1;
1222 // if the refcount is zero, then evaluation of the "top level"
1223 // expression must have completed. We can safely release the
1224 // scarce resources.
1225 if (scarceResourcesRefCount == 0) {
1226 // iterate through the list and release them all.
1227 // note that the actual SRD is owned by the JS engine,
1228 // so we cannot delete the SRD; but we can free the
1229 // memory used by the variant in the SRD.
1230 while (ScarceResourceData *sr = scarceResources.first()) {
1231 sr->data = QVariant();
1232 scarceResources.remove(sr);
1238 Adds \a path as a directory where the engine searches for
1239 installed modules in a URL-based directory structure.
1240 The \a path may be a local filesystem directory or a URL.
1242 The newly added \a path will be first in the importPathList().
1244 \sa setImportPathList(), {QML Modules}
1246 void QDeclarativeEngine::addImportPath(const QString& path)
1248 Q_D(QDeclarativeEngine);
1249 d->importDatabase.addImportPath(path);
1253 Returns the list of directories where the engine searches for
1254 installed modules in a URL-based directory structure.
1256 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1257 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1258 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1259 provided by that module. A \c qmldir file is required for defining the
1260 type version mapping and possibly declarative extensions plugins.
1262 By default, the list contains the directory of the application executable,
1263 paths specified in the \c QML_IMPORT_PATH environment variable,
1264 and the builtin \c ImportsPath from QLibraryInfo.
1266 \sa addImportPath() setImportPathList()
1268 QStringList QDeclarativeEngine::importPathList() const
1270 Q_D(const QDeclarativeEngine);
1271 return d->importDatabase.importPathList();
1275 Sets \a paths as the list of directories where the engine searches for
1276 installed modules in a URL-based directory structure.
1278 By default, the list contains the directory of the application executable,
1279 paths specified in the \c QML_IMPORT_PATH environment variable,
1280 and the builtin \c ImportsPath from QLibraryInfo.
1282 \sa importPathList() addImportPath()
1284 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1286 Q_D(QDeclarativeEngine);
1287 d->importDatabase.setImportPathList(paths);
1292 Adds \a path as a directory where the engine searches for
1293 native plugins for imported modules (referenced in the \c qmldir file).
1295 By default, the list contains only \c ., i.e. the engine searches
1296 in the directory of the \c qmldir file itself.
1298 The newly added \a path will be first in the pluginPathList().
1300 \sa setPluginPathList()
1302 void QDeclarativeEngine::addPluginPath(const QString& path)
1304 Q_D(QDeclarativeEngine);
1305 d->importDatabase.addPluginPath(path);
1310 Returns the list of directories where the engine searches for
1311 native plugins for imported modules (referenced in the \c qmldir file).
1313 By default, the list contains only \c ., i.e. the engine searches
1314 in the directory of the \c qmldir file itself.
1316 \sa addPluginPath() setPluginPathList()
1318 QStringList QDeclarativeEngine::pluginPathList() const
1320 Q_D(const QDeclarativeEngine);
1321 return d->importDatabase.pluginPathList();
1325 Sets the list of directories where the engine searches for
1326 native plugins for imported modules (referenced in the \c qmldir file)
1329 By default, the list contains only \c ., i.e. the engine searches
1330 in the directory of the \c qmldir file itself.
1332 \sa pluginPathList() addPluginPath()
1334 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1336 Q_D(QDeclarativeEngine);
1337 d->importDatabase.setPluginPathList(paths);
1341 Imports the plugin named \a filePath with the \a uri provided.
1342 Returns true if the plugin was successfully imported; otherwise returns false.
1344 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1346 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1348 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1350 Q_D(QDeclarativeEngine);
1351 return d->importDatabase.importPlugin(filePath, uri, errors);
1355 Imports the plugin named \a filePath with the \a uri provided.
1356 Returns true if the plugin was successfully imported; otherwise returns false.
1358 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1360 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1362 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1364 Q_D(QDeclarativeEngine);
1365 QList<QDeclarativeError> errors;
1366 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1367 if (!errors.isEmpty()) {
1369 for (int i = 0; i < errors.size(); ++i) {
1370 builtError = QString(QLatin1String("%1\n %2"))
1372 .arg(errors.at(i).toString());
1374 *errorString = builtError;
1380 \property QDeclarativeEngine::offlineStoragePath
1381 \brief the directory for storing offline user data
1383 Returns the directory where SQL and other offline
1386 QDeclarativeWebView and the SQL databases created with openDatabase()
1389 The default is QML/OfflineStorage in the platform-standard
1390 user application data directory.
1392 Note that the path may not currently exist on the filesystem, so
1393 callers wanting to \e create new files at this location should create
1394 it first - see QDir::mkpath().
1396 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1398 Q_D(QDeclarativeEngine);
1399 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1402 QString QDeclarativeEngine::offlineStoragePath() const
1404 Q_D(const QDeclarativeEngine);
1405 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1408 static void voidptr_destructor(void *v)
1410 void **ptr = (void **)v;
1414 static void *voidptr_constructor(const void *v)
1419 return new void*(*(void **)v);
1423 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1425 Q_Q(QDeclarativeEngine);
1427 if (!mo->superClass()) {
1428 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1429 propertyCache.insert(mo, rv);
1432 QDeclarativePropertyCache *super = cache(mo->superClass());
1433 QDeclarativePropertyCache *rv = super->copy();
1435 propertyCache.insert(mo, rv);
1440 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1441 QDeclarativeError &error)
1443 QList<QDeclarativeType *> types;
1445 int maxMinorVersion = 0;
1447 const QMetaObject *metaObject = type->metaObject();
1448 while (metaObject) {
1449 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1450 type->majorVersion(), minorVersion);
1452 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1458 metaObject = metaObject->superClass();
1461 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1463 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1467 QDeclarativePropertyCache *raw = cache(type->metaObject());
1469 bool hasCopied = false;
1471 for (int ii = 0; ii < types.count(); ++ii) {
1472 QDeclarativeType *currentType = types.at(ii);
1476 int rev = currentType->metaObjectRevision();
1477 int moIndex = types.count() - 1 - ii;
1479 if (raw->allowedRevisionCache[moIndex] != rev) {
1484 raw->allowedRevisionCache[moIndex] = rev;
1488 // Test revision compatibility - the basic rule is:
1489 // * Anything that is excluded, cannot overload something that is not excluded *
1491 // Signals override:
1492 // * other signals and methods of the same name.
1493 // * properties named on<Signal Name>
1494 // * automatic <property name>Changed notify signals
1496 // Methods override:
1497 // * other methods of the same name
1499 // Properties override:
1500 // * other elements of the same name
1502 bool overloadError = false;
1503 QString overloadName;
1506 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1507 !overloadError && iter != raw->stringCache.end();
1510 QDeclarativePropertyCache::Data *d = *iter;
1511 if (raw->isAllowedInRevision(d))
1512 continue; // Not excluded - no problems
1514 // check that a regular "name" overload isn't happening
1515 QDeclarativePropertyCache::Data *current = d;
1516 while (!overloadError && current) {
1517 current = d->overrideData(current);
1518 if (current && raw->isAllowedInRevision(current))
1519 overloadError = true;
1524 if (overloadError) {
1525 if (hasCopied) raw->release();
1527 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."));
1531 if (!hasCopied) raw->addref();
1532 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1534 if (minorVersion != maxMinorVersion) {
1536 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1542 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1544 QByteArray name = data->root->className();
1546 QByteArray ptr = name + '*';
1547 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1549 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1550 voidptr_constructor);
1551 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1552 voidptr_constructor);
1554 m_qmlLists.insert(lst_type, ptr_type);
1555 m_compositeTypes.insert(ptr_type, data);
1559 bool QDeclarativeEnginePrivate::isList(int t) const
1561 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1564 int QDeclarativeEnginePrivate::listType(int t) const
1566 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1567 if (iter != m_qmlLists.end())
1570 return QDeclarativeMetaType::listType(t);
1573 bool QDeclarativeEnginePrivate::isQObject(int t)
1575 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1578 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1580 int t = v.userType();
1581 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1583 return *(QObject **)(v.constData());
1585 return QDeclarativeMetaType::toQObject(v, ok);
1589 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1591 if (m_compositeTypes.contains(t))
1592 return QDeclarativeMetaType::Object;
1593 else if (m_qmlLists.contains(t))
1594 return QDeclarativeMetaType::List;
1596 return QDeclarativeMetaType::typeCategory(t);
1599 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(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->baseMetaObject():0;
1610 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1612 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1613 if (iter != m_compositeTypes.end()) {
1614 return (*iter)->root;
1616 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1617 return type?type->metaObject():0;
1621 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1623 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1624 QFileInfo info(fileName);
1626 QString absolute = info.absoluteFilePath();
1628 #if defined(Q_OS_MAC)
1629 QString canonical = info.canonicalFilePath();
1630 #elif defined(Q_OS_WIN32)
1631 wchar_t buffer[1024];
1633 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1634 if (rv == 0 || rv >= 1024) return true;
1635 rv = ::GetLongPathName(buffer, buffer, 1024);
1636 if (rv == 0 || rv >= 1024) return true;
1638 QString canonical((QChar *)buffer);
1641 int absoluteLength = absolute.length();
1642 int canonicalLength = canonical.length();
1644 int length = qMin(absoluteLength, canonicalLength);
1645 for (int ii = 0; ii < length; ++ii) {
1646 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1647 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1649 if (a.toLower() != c.toLower())