1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "private/qdeclarativeengine_p.h"
43 #include "qdeclarativeengine.h"
45 #include "private/qdeclarativecontext_p.h"
46 #include "private/qdeclarativecompiler_p.h"
47 #include "qdeclarative.h"
48 #include "qdeclarativecontext.h"
49 #include "qdeclarativeexpression.h"
50 #include "qdeclarativecomponent.h"
51 #include "private/qdeclarativebinding_p_p.h"
52 #include "private/qdeclarativevme_p.h"
53 #include "private/qdeclarativeenginedebugservice_p.h"
54 #include "private/qdeclarativestringconverters_p.h"
55 #include "private/qdeclarativexmlhttprequest_p.h"
56 #include "private/qdeclarativesqldatabase_p.h"
57 #include "qdeclarativescriptstring.h"
58 #include "private/qdeclarativeglobal_p.h"
59 #include "private/qdeclarativeworkerscript_p.h"
60 #include "private/qdeclarativecomponent_p.h"
61 #include "qdeclarativenetworkaccessmanagerfactory.h"
62 #include "qdeclarativeimageprovider.h"
63 #include "private/qdeclarativedirparser_p.h"
64 #include "qdeclarativeextensioninterface.h"
65 #include "private/qdeclarativelist_p.h"
66 #include "private/qdeclarativetypenamecache_p.h"
67 #include "private/qdeclarativenotifier_p.h"
68 #include "private/qdeclarativedebugtrace_p.h"
69 #include "private/qdeclarativeapplication_p.h"
70 #include "private/qv8debugservice_p.h"
72 #include <QtCore/qmetaobject.h>
73 #include <QNetworkReply>
74 #include <QNetworkRequest>
75 #include <QNetworkAccessManager>
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 static bool qt_QmlQtModule_registered = false;
179 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
181 void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
183 qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
184 qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
185 qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
188 void QDeclarativeEnginePrivate::defineModule()
190 registerBaseTypes("QtQuick", 2, 0);
191 qmlRegisterType<QDeclarativeBinding>();
195 \qmlclass QML:Qt QDeclarativeEnginePrivate
196 \ingroup qml-utility-elements
197 \brief The QML global Qt object provides useful enums and functions from Qt.
199 \keyword QmlGlobalQtObject
201 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
203 The \c Qt object is a global object with utility functions, properties and enums.
205 It is not instantiable; to use it, call the members of the global \c Qt object directly.
212 color: Qt.rgba(1, 0, 0, 1)
213 text: Qt.md5("hello, world")
220 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
221 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
225 The Qt object also contains helper functions for creating objects of specific
226 data types. This is primarily useful when setting the properties of an item
227 when the property has one of the following types:
230 \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()}
231 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
232 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
233 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
234 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
237 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
239 \section1 Date/Time Formatters
241 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
244 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
245 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
246 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
249 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
252 \section1 Dynamic Object Creation
253 The following functions on the global object allow you to dynamically create QML
254 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
258 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
259 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
265 \qmlproperty object QML:Qt::application
268 The \c application object provides access to global application state
269 properties shared by many QML components.
275 \o \c application.active
277 This read-only property indicates whether the application is the top-most and focused
278 application, and the user is able to interact with the application. The property
279 is false when the application is in the background, the device keylock or screen
280 saver is active, the screen backlight is turned off, or the global system dialog
281 is being displayed on top of the application. It can be used for stopping and
282 pausing animations, timers and active processing of data in order to save device
283 battery power and free device memory and processor load when the application is not
287 \o \c application.layoutDirection
289 This read-only property can be used to query the default layout direction of the
290 application. On system start-up, the default layout direction depends on the
291 application's language. The property has a value of \c Qt.RightToLeft in locales
292 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
293 where the reading direction flows from left to right. You can bind to this
294 property to customize your application layouts to support both layout directions.
299 \o Qt.LeftToRight - Text and graphics elements should be positioned
301 \o Qt.RightToLeft - Text and graphics elements should be positioned
306 The following example uses the \c application object to indicate
307 whether the application is currently active:
309 \snippet doc/src/snippets/declarative/application.qml document
315 \qmlmethod object Qt::include(string url, jsobject callback)
317 Includes another JavaScript file. This method can only be used from within JavaScript files,
318 and not regular QML files.
320 This imports all functions from \a url into the current script's namespace.
322 Qt.include() returns an object that describes the status of the operation. The object has
323 a single property, \c {status}, that is set to one of the following values:
326 \header \o Symbol \o Value \o Description
327 \row \o result.OK \o 0 \o The include completed successfully.
328 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
329 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
330 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
331 An additional \c exception property will be set in this case.
334 The \c status property will be updated as the operation progresses.
336 If provided, \a callback is invoked when the operation completes. The callback is passed
337 the same object as is returned from the Qt.include() call.
339 // Qt.include() is implemented in qv8include.cpp
342 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
343 : captureProperties(false), rootContext(0), isDebugging(false),
344 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
345 cleanup(0), erroredBindings(0), inProgressCreations(0),
346 workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
347 networkAccessManager(0), networkAccessManagerFactory(0),
348 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
351 if (!qt_QmlQtModule_registered) {
352 qt_QmlQtModule_registered = true;
353 QDeclarativeUtilModule::defineModule();
354 QDeclarativeEnginePrivate::defineModule();
355 QSGItemsModule::defineModule();
356 QSGParticlesModule::defineModule();
357 QDeclarativeValueTypeFactory::registerValueTypes();
361 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
363 Q_ASSERT(inProgressCreations == 0);
364 Q_ASSERT(bindValues.isEmpty());
365 Q_ASSERT(parserStatus.isEmpty());
368 QDeclarativeCleanup *c = cleanup;
370 if (cleanup) cleanup->prev = &cleanup;
379 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
381 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
383 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
385 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
386 delete (*iter)->qobjectApi;
391 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
396 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
398 for (int ii = 0; ii < pss.count; ++ii) {
399 QDeclarativeParserStatus *ps = pss.at(ii);
406 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
408 QObjectPrivate *p = QObjectPrivate::get(o);
409 if (p->declarativeData) {
410 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
411 if (d->ownContext && d->context) {
412 d->context->destroy();
418 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
420 static_cast<QDeclarativeData *>(d)->destroyed(o);
423 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
425 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
428 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
430 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
433 void QDeclarativeEnginePrivate::init()
435 Q_Q(QDeclarativeEngine);
436 qRegisterMetaType<QVariant>("QVariant");
437 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
438 qRegisterMetaType<QJSValue>("QJSValue");
439 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
440 qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
441 qRegisterMetaType<QList<int> >("QList<int>");
442 qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
444 QDeclarativeData::init();
446 v8engine()->setEngine(q);
448 rootContext = new QDeclarativeContext(q,true);
450 if (QCoreApplication::instance()->thread() == q->thread() &&
451 QDeclarativeEngineDebugService::isDebuggingEnabled()) {
453 QDeclarativeEngineDebugService::instance()->addEngine(q);
454 QV8DebugService::instance()->addEngine(q);
458 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
460 Q_Q(QDeclarativeEngine);
461 if (!workerScriptEngine)
462 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
463 return workerScriptEngine;
467 \class QDeclarativeEngine
469 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
472 Each QML component is instantiated in a QDeclarativeContext.
473 QDeclarativeContext's are essential for passing data to QML
474 components. In QML, contexts are arranged hierarchically and this
475 hierarchy is managed by the QDeclarativeEngine.
477 Prior to creating any QML components, an application must have
478 created a QDeclarativeEngine to gain access to a QML context. The
479 following example shows how to create a simple Text item.
482 QDeclarativeEngine engine;
483 QDeclarativeComponent component(&engine);
484 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
485 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
487 //add item to view, etc
491 In this case, the Text item will be created in the engine's
492 \l {QDeclarativeEngine::rootContext()}{root context}.
494 \sa QDeclarativeComponent QDeclarativeContext
498 Create a new QDeclarativeEngine with the given \a parent.
500 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
501 : QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
503 Q_D(QDeclarativeEngine);
508 Destroys the QDeclarativeEngine.
510 Any QDeclarativeContext's created on this engine will be
511 invalidated, but not destroyed (unless they are parented to the
512 QDeclarativeEngine object).
514 QDeclarativeEngine::~QDeclarativeEngine()
516 Q_D(QDeclarativeEngine);
518 QDeclarativeEngineDebugService::instance()->remEngine(this);
520 // if we are the parent of any of the qobject module api instances,
521 // we need to remove them from our internal list, in order to prevent
522 // a segfault in engine private dtor.
523 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
524 QObject *currQObjectApi = 0;
525 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
526 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
527 currInstance = d->moduleApiInstances.value(key);
528 currQObjectApi = currInstance->qobjectApi;
529 if (this->children().contains(currQObjectApi)) {
530 delete currQObjectApi;
532 d->moduleApiInstances.remove(key);
537 /*! \fn void QDeclarativeEngine::quit()
538 This signal is emitted when the QML loaded by the engine would like to quit.
541 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
542 This signal is emitted when \a warnings messages are generated by QML.
546 Clears the engine's internal component cache.
548 Normally the QDeclarativeEngine caches components loaded from qml
549 files. This method clears this cache and forces the component to be
552 void QDeclarativeEngine::clearComponentCache()
554 Q_D(QDeclarativeEngine);
555 d->typeLoader.clearCache();
559 Returns the engine's root context.
561 The root context is automatically created by the QDeclarativeEngine.
562 Data that should be available to all QML component instances
563 instantiated by the engine should be put in the root context.
565 Additional data that should only be available to a subset of
566 component instances should be added to sub-contexts parented to the
569 QDeclarativeContext *QDeclarativeEngine::rootContext() const
571 Q_D(const QDeclarativeEngine);
572 return d->rootContext;
576 Sets the \a factory to use for creating QNetworkAccessManager(s).
578 QNetworkAccessManager is used for all network access by QML. By
579 implementing a factory it is possible to create custom
580 QNetworkAccessManager with specialized caching, proxy and cookie
583 The factory must be set before executing the engine.
585 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
587 Q_D(QDeclarativeEngine);
588 QMutexLocker locker(&d->mutex);
589 d->networkAccessManagerFactory = factory;
593 Returns the current QDeclarativeNetworkAccessManagerFactory.
595 \sa setNetworkAccessManagerFactory()
597 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
599 Q_D(const QDeclarativeEngine);
600 return d->networkAccessManagerFactory;
603 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
605 QMutexLocker locker(&mutex);
606 QNetworkAccessManager *nam;
607 if (networkAccessManagerFactory) {
608 nam = networkAccessManagerFactory->create(parent);
610 nam = new QNetworkAccessManager(parent);
616 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
618 Q_Q(const QDeclarativeEngine);
619 if (!networkAccessManager)
620 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
621 return networkAccessManager;
625 Returns a common QNetworkAccessManager which can be used by any QML
626 element instantiated by this engine.
628 If a QDeclarativeNetworkAccessManagerFactory has been set and a
629 QNetworkAccessManager has not yet been created, the
630 QDeclarativeNetworkAccessManagerFactory will be used to create the
631 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
632 will have no proxy or cache set.
634 \sa setNetworkAccessManagerFactory()
636 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
638 Q_D(const QDeclarativeEngine);
639 return d->getNetworkAccessManager();
644 Sets the \a provider to use for images requested via the \e
645 image: url scheme, with host \a providerId. The QDeclarativeEngine
646 takes ownership of \a provider.
648 Image providers enable support for pixmap and threaded image
649 requests. See the QDeclarativeImageProvider documentation for details on
650 implementing and using image providers.
652 All required image providers should be added to the engine before any
653 QML sources files are loaded.
655 \sa removeImageProvider()
657 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
659 Q_D(QDeclarativeEngine);
660 QMutexLocker locker(&d->mutex);
661 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
665 Returns the QDeclarativeImageProvider set for \a providerId.
667 Returns the provider if it was found; otherwise returns 0.
669 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
671 Q_D(const QDeclarativeEngine);
672 QMutexLocker locker(&d->mutex);
673 return d->imageProviders.value(providerId).data();
677 Removes the QDeclarativeImageProvider for \a providerId.
679 \sa addImageProvider()
681 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
683 Q_D(QDeclarativeEngine);
684 QMutexLocker locker(&d->mutex);
685 d->imageProviders.take(providerId);
688 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
690 QMutexLocker locker(&mutex);
691 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
694 return provider->imageType();
695 return QDeclarativeImageProvider::Invalid;
698 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
700 QMutexLocker locker(&mutex);
701 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
704 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
705 return provider->requestTexture(imageId, size, req_size);
710 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
712 QMutexLocker locker(&mutex);
714 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
717 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
718 image = provider->requestImage(imageId, size, req_size);
723 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
725 QMutexLocker locker(&mutex);
727 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
730 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
731 pixmap = provider->requestPixmap(imageId, size, req_size);
737 Return the base URL for this engine. The base URL is only used to
738 resolve components when a relative URL is passed to the
739 QDeclarativeComponent constructor.
741 If a base URL has not been explicitly set, this method returns the
742 application's current working directory.
746 QUrl QDeclarativeEngine::baseUrl() const
748 Q_D(const QDeclarativeEngine);
749 if (d->baseUrl.isEmpty()) {
750 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
757 Set the base URL for this engine to \a url.
761 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
763 Q_D(QDeclarativeEngine);
768 Returns true if warning messages will be output to stderr in addition
769 to being emitted by the warnings() signal, otherwise false.
771 The default value is true.
773 bool QDeclarativeEngine::outputWarningsToStandardError() const
775 Q_D(const QDeclarativeEngine);
776 return d->outputWarningsToStdErr;
780 Set whether warning messages will be output to stderr to \a enabled.
782 If \a enabled is true, any warning messages generated by QML will be
783 output to stderr and emitted by the warnings() signal. If \a enabled
784 is false, on the warnings() signal will be emitted. This allows
785 applications to handle warning output themselves.
787 The default value is true.
789 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
791 Q_D(QDeclarativeEngine);
792 d->outputWarningsToStdErr = enabled;
796 Attempt to free unused memory.
798 void QDeclarativeEngine::collectGarbage()
804 Returns the QDeclarativeContext for the \a object, or 0 if no
805 context has been set.
807 When the QDeclarativeEngine instantiates a QObject, the context is
810 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
815 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
817 QDeclarativeData *data =
818 static_cast<QDeclarativeData *>(priv->declarativeData);
822 else if (data->outerContext)
823 return data->outerContext->asQDeclarativeContext();
829 Sets the QDeclarativeContext for the \a object to \a context.
830 If the \a object already has a context, a warning is
831 output, but the context is not changed.
833 When the QDeclarativeEngine instantiates a QObject, the context is
836 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
838 if (!object || !context)
841 QDeclarativeData *data = QDeclarativeData::get(object, true);
843 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
847 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
848 contextData->addObject(object);
852 \enum QDeclarativeEngine::ObjectOwnership
854 Ownership controls whether or not QML automatically destroys the
855 QObject when the object is garbage collected by the JavaScript
856 engine. The two ownership options are:
858 \value CppOwnership The object is owned by C++ code, and will
859 never be deleted by QML. The JavaScript destroy() method cannot be
860 used on objects with CppOwnership. This option is similar to
861 QScriptEngine::QtOwnership.
863 \value JavaScriptOwnership The object is owned by JavaScript.
864 When the object is returned to QML as the return value of a method
865 call or property access, QML will delete the object if there are no
866 remaining JavaScript references to it and it has no
867 QObject::parent(). This option is similar to
868 QScriptEngine::ScriptOwnership.
870 Generally an application doesn't need to set an object's ownership
871 explicitly. QML uses a heuristic to set the default object
872 ownership. By default, an object that is created by QML has
873 JavaScriptOwnership. The exception to this are the root objects
874 created by calling QDeclarativeCompnent::create() or
875 QDeclarativeComponent::beginCreate() which have CppOwnership by
876 default. The ownership of these root-level objects is considered to
877 have been transferred to the C++ caller.
879 Objects not-created by QML have CppOwnership by default. The
880 exception to this is objects returned from a C++ method call. The
881 ownership of these objects is passed to JavaScript.
883 Calling setObjectOwnership() overrides the default ownership
884 heuristic used by QML.
888 Sets the \a ownership of \a object.
890 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
895 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
899 ddata->indestructible = (ownership == CppOwnership)?true:false;
900 ddata->explicitIndestructibleSet = true;
904 Returns the ownership of \a object.
906 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
911 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
915 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
918 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
920 QDeclarativeData *data = QDeclarativeData::get(object);
922 if (data && data->deferredComponent) {
923 if (QDeclarativeDebugService::isDebuggingEnabled()) {
924 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
925 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
926 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
927 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
928 if (data->outerContext)
929 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
931 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
933 QDeclarativeComponentPrivate::ConstructionState state;
934 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
936 data->deferredComponent->release();
937 data->deferredComponent = 0;
939 QDeclarativeComponentPrivate::complete(ep, &state);
940 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
944 QDeclarativeContext *qmlContext(const QObject *obj)
946 return QDeclarativeEngine::contextForObject(obj);
949 QDeclarativeEngine *qmlEngine(const QObject *obj)
951 QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
952 return context?context->engine():0;
955 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
957 QDeclarativeData *data = QDeclarativeData::get(object);
959 return 0; // Attached properties are only on objects created by QML
961 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
965 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
969 rv = pf(const_cast<QObject *>(object));
972 data->attachedProperties()->insert(id, rv);
977 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
978 const QMetaObject *attachedMetaObject, bool create)
981 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
983 if (*idCache == -1 || !object)
986 return qmlAttachedPropertiesObjectById(*idCache, object, create);
989 QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
991 #ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
992 if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
993 qWarning("Qml debugging is enabled. Only use this in a safe environment!");
995 QDeclarativeEnginePrivate::qml_debugging_enabled = true;
1000 class QDeclarativeDataExtended {
1002 QDeclarativeDataExtended();
1003 ~QDeclarativeDataExtended();
1005 QHash<int, QObject *> attachedProperties;
1006 QDeclarativeNotifier objectNameNotifier;
1009 QDeclarativeDataExtended::QDeclarativeDataExtended()
1013 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1017 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1019 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1020 return &extendedData->objectNameNotifier;
1023 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1025 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1026 return &extendedData->attachedProperties;
1029 void QDeclarativeData::destroyed(QObject *object)
1031 if (deferredComponent)
1032 deferredComponent->release();
1034 if (nextContextObject)
1035 nextContextObject->prevContextObject = prevContextObject;
1036 if (prevContextObject)
1037 *prevContextObject = nextContextObject;
1039 QDeclarativeAbstractBinding *binding = bindings;
1041 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1042 binding->m_prevBinding = 0;
1043 binding->m_nextBinding = 0;
1052 propertyCache->release();
1054 if (ownContext && context)
1058 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1059 *guard = (QObject *)0;
1060 guard->objectDestroyed(object);
1064 delete extendedData;
1066 v8object.Clear(); // The WeakReference handler will clean the actual handle
1072 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1078 void QDeclarativeData::objectNameChanged(QObject *)
1080 if (extendedData) objectNameNotifier()->notify();
1083 bool QDeclarativeData::hasBindingBit(int bit) const
1085 if (bindingBitsSize > bit)
1086 return bindingBits[bit / 32] & (1 << (bit % 32));
1091 void QDeclarativeData::clearBindingBit(int bit)
1093 if (bindingBitsSize > bit)
1094 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1097 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1099 if (bindingBitsSize <= bit) {
1100 int props = obj->metaObject()->propertyCount();
1101 Q_ASSERT(bit < props);
1103 int arraySize = (props + 31) / 32;
1104 int oldArraySize = bindingBitsSize / 32;
1106 bindingBits = (quint32 *)realloc(bindingBits,
1107 arraySize * sizeof(quint32));
1109 memset(bindingBits + oldArraySize,
1111 sizeof(quint32) * (arraySize - oldArraySize));
1113 bindingBitsSize = arraySize * 32;
1116 bindingBits[bit / 32] |= (1 << (bit % 32));
1119 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1121 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1122 if (url.authority().isEmpty())
1123 return QLatin1Char(':') + url.path();
1126 return url.toLocalFile();
1130 static QString toLocalFile(const QString &url)
1132 if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
1135 QString file = url.mid(7);
1137 //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
1139 // magic for drives on windows
1140 if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
1146 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
1148 if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
1149 if (url.length() > 4)
1150 return QLatin1Char(':') + url.mid(4);
1154 return toLocalFile(url);
1157 void QDeclarativeEnginePrivate::sendQuit()
1159 Q_Q(QDeclarativeEngine);
1161 if (q->receivers(SIGNAL(quit())) == 0) {
1162 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1166 static void dumpwarning(const QDeclarativeError &error)
1168 qWarning().nospace() << qPrintable(error.toString());
1171 static void dumpwarning(const QList<QDeclarativeError> &errors)
1173 for (int ii = 0; ii < errors.count(); ++ii)
1174 dumpwarning(errors.at(ii));
1177 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1179 Q_Q(QDeclarativeEngine);
1180 q->warnings(QList<QDeclarativeError>() << error);
1181 if (outputWarningsToStdErr)
1185 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1187 Q_Q(QDeclarativeEngine);
1188 q->warnings(errors);
1189 if (outputWarningsToStdErr)
1190 dumpwarning(errors);
1193 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1196 QDeclarativeEnginePrivate::get(engine)->warning(error);
1201 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1204 QDeclarativeEnginePrivate::get(engine)->warning(error);
1209 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1212 engine->warning(error);
1217 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1220 engine->warning(error);
1226 This function should be called prior to evaluation of any js expression,
1227 so that scarce resources are not freed prematurely (eg, if there is a
1228 nested javascript expression).
1230 void QDeclarativeEnginePrivate::referenceScarceResources()
1232 scarceResourcesRefCount += 1;
1236 This function should be called after evaluation of the js expression is
1237 complete, and so the scarce resources may be freed safely.
1239 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1241 Q_ASSERT(scarceResourcesRefCount > 0);
1242 scarceResourcesRefCount -= 1;
1244 // if the refcount is zero, then evaluation of the "top level"
1245 // expression must have completed. We can safely release the
1246 // scarce resources.
1247 if (scarceResourcesRefCount == 0) {
1248 // iterate through the list and release them all.
1249 // note that the actual SRD is owned by the JS engine,
1250 // so we cannot delete the SRD; but we can free the
1251 // memory used by the variant in the SRD.
1252 while (ScarceResourceData *sr = scarceResources.first()) {
1253 sr->data = QVariant();
1254 scarceResources.remove(sr);
1260 Adds \a path as a directory where the engine searches for
1261 installed modules in a URL-based directory structure.
1262 The \a path may be a local filesystem directory or a URL.
1264 The newly added \a path will be first in the importPathList().
1266 \sa setImportPathList(), {QML Modules}
1268 void QDeclarativeEngine::addImportPath(const QString& path)
1270 Q_D(QDeclarativeEngine);
1271 d->importDatabase.addImportPath(path);
1275 Returns the list of directories where the engine searches for
1276 installed modules in a URL-based directory structure.
1278 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1279 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1280 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1281 provided by that module. A \c qmldir file is required for defining the
1282 type version mapping and possibly declarative extensions plugins.
1284 By default, the list contains the directory of the application executable,
1285 paths specified in the \c QML_IMPORT_PATH environment variable,
1286 and the builtin \c ImportsPath from QLibraryInfo.
1288 \sa addImportPath() setImportPathList()
1290 QStringList QDeclarativeEngine::importPathList() const
1292 Q_D(const QDeclarativeEngine);
1293 return d->importDatabase.importPathList();
1297 Sets \a paths as the list of directories where the engine searches for
1298 installed modules in a URL-based directory structure.
1300 By default, the list contains the directory of the application executable,
1301 paths specified in the \c QML_IMPORT_PATH environment variable,
1302 and the builtin \c ImportsPath from QLibraryInfo.
1304 \sa importPathList() addImportPath()
1306 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1308 Q_D(QDeclarativeEngine);
1309 d->importDatabase.setImportPathList(paths);
1314 Adds \a path as a directory where the engine searches for
1315 native plugins for imported modules (referenced in the \c qmldir file).
1317 By default, the list contains only \c ., i.e. the engine searches
1318 in the directory of the \c qmldir file itself.
1320 The newly added \a path will be first in the pluginPathList().
1322 \sa setPluginPathList()
1324 void QDeclarativeEngine::addPluginPath(const QString& path)
1326 Q_D(QDeclarativeEngine);
1327 d->importDatabase.addPluginPath(path);
1332 Returns the list of directories where the engine searches for
1333 native plugins for imported modules (referenced in the \c qmldir file).
1335 By default, the list contains only \c ., i.e. the engine searches
1336 in the directory of the \c qmldir file itself.
1338 \sa addPluginPath() setPluginPathList()
1340 QStringList QDeclarativeEngine::pluginPathList() const
1342 Q_D(const QDeclarativeEngine);
1343 return d->importDatabase.pluginPathList();
1347 Sets the list of directories where the engine searches for
1348 native plugins for imported modules (referenced in the \c qmldir file)
1351 By default, the list contains only \c ., i.e. the engine searches
1352 in the directory of the \c qmldir file itself.
1354 \sa pluginPathList() addPluginPath()
1356 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1358 Q_D(QDeclarativeEngine);
1359 d->importDatabase.setPluginPathList(paths);
1363 Imports the plugin named \a filePath with the \a uri provided.
1364 Returns true if the plugin was successfully imported; otherwise returns false.
1366 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1368 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1370 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1372 Q_D(QDeclarativeEngine);
1373 return d->importDatabase.importPlugin(filePath, uri, errors);
1377 Imports the plugin named \a filePath with the \a uri provided.
1378 Returns true if the plugin was successfully imported; otherwise returns false.
1380 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1382 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1384 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1386 Q_D(QDeclarativeEngine);
1387 QList<QDeclarativeError> errors;
1388 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1389 if (!errors.isEmpty()) {
1391 for (int i = 0; i < errors.size(); ++i) {
1392 builtError = QString(QLatin1String("%1\n %2"))
1394 .arg(errors.at(i).toString());
1396 *errorString = builtError;
1402 \property QDeclarativeEngine::offlineStoragePath
1403 \brief the directory for storing offline user data
1405 Returns the directory where SQL and other offline
1408 QDeclarativeWebView and the SQL databases created with openDatabase()
1411 The default is QML/OfflineStorage in the platform-standard
1412 user application data directory.
1414 Note that the path may not currently exist on the filesystem, so
1415 callers wanting to \e create new files at this location should create
1416 it first - see QDir::mkpath().
1418 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1420 Q_D(QDeclarativeEngine);
1421 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1424 QString QDeclarativeEngine::offlineStoragePath() const
1426 Q_D(const QDeclarativeEngine);
1427 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1430 static void voidptr_destructor(void *v)
1432 void **ptr = (void **)v;
1436 static void *voidptr_constructor(const void *v)
1441 return new void*(*(void **)v);
1445 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1447 Q_Q(QDeclarativeEngine);
1449 if (!mo->superClass()) {
1450 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1451 propertyCache.insert(mo, rv);
1454 QDeclarativePropertyCache *super = cache(mo->superClass());
1455 QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() -
1456 mo->superClass()->propertyCount() -
1457 mo->superClass()->methodCount());
1459 propertyCache.insert(mo, rv);
1464 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1465 QDeclarativeError &error)
1467 QList<QDeclarativeType *> types;
1469 int maxMinorVersion = 0;
1471 const QMetaObject *metaObject = type->metaObject();
1472 while (metaObject) {
1473 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1474 type->majorVersion(), minorVersion);
1476 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1482 metaObject = metaObject->superClass();
1485 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1487 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1491 QDeclarativePropertyCache *raw = cache(type->metaObject());
1493 bool hasCopied = false;
1495 for (int ii = 0; ii < types.count(); ++ii) {
1496 QDeclarativeType *currentType = types.at(ii);
1500 int rev = currentType->metaObjectRevision();
1501 int moIndex = types.count() - 1 - ii;
1503 if (raw->allowedRevisionCache[moIndex] != rev) {
1508 raw->allowedRevisionCache[moIndex] = rev;
1512 // Test revision compatibility - the basic rule is:
1513 // * Anything that is excluded, cannot overload something that is not excluded *
1515 // Signals override:
1516 // * other signals and methods of the same name.
1517 // * properties named on<Signal Name>
1518 // * automatic <property name>Changed notify signals
1520 // Methods override:
1521 // * other methods of the same name
1523 // Properties override:
1524 // * other elements of the same name
1526 bool overloadError = false;
1527 QString overloadName;
1530 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1531 !overloadError && iter != raw->stringCache.end();
1534 QDeclarativePropertyCache::Data *d = *iter;
1535 if (raw->isAllowedInRevision(d))
1536 continue; // Not excluded - no problems
1538 // check that a regular "name" overload isn't happening
1539 QDeclarativePropertyCache::Data *current = d;
1540 while (!overloadError && current) {
1541 current = d->overrideData(current);
1542 if (current && raw->isAllowedInRevision(current))
1543 overloadError = true;
1548 if (overloadError) {
1549 if (hasCopied) raw->release();
1551 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."));
1555 if (!hasCopied) raw->addref();
1556 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1558 if (minorVersion != maxMinorVersion) {
1560 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1566 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1568 QByteArray name = data->root->className();
1570 QByteArray ptr = name + '*';
1571 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1573 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1574 voidptr_constructor);
1575 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1576 voidptr_constructor);
1578 m_qmlLists.insert(lst_type, ptr_type);
1579 m_compositeTypes.insert(ptr_type, data);
1583 bool QDeclarativeEnginePrivate::isList(int t) const
1585 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1588 int QDeclarativeEnginePrivate::listType(int t) const
1590 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1591 if (iter != m_qmlLists.end())
1594 return QDeclarativeMetaType::listType(t);
1597 bool QDeclarativeEnginePrivate::isQObject(int t)
1599 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1602 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1604 int t = v.userType();
1605 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1607 return *(QObject **)(v.constData());
1609 return QDeclarativeMetaType::toQObject(v, ok);
1613 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1615 if (m_compositeTypes.contains(t))
1616 return QDeclarativeMetaType::Object;
1617 else if (m_qmlLists.contains(t))
1618 return QDeclarativeMetaType::List;
1620 return QDeclarativeMetaType::typeCategory(t);
1623 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1625 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1626 if (iter != m_compositeTypes.end()) {
1627 return (*iter)->root;
1629 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1630 return type?type->baseMetaObject():0;
1634 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1636 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1637 if (iter != m_compositeTypes.end()) {
1638 return (*iter)->root;
1640 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1641 return type?type->metaObject():0;
1645 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1647 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1648 QFileInfo info(fileName);
1650 QString absolute = info.absoluteFilePath();
1652 #if defined(Q_OS_MAC)
1653 QString canonical = info.canonicalFilePath();
1654 #elif defined(Q_OS_WIN32)
1655 wchar_t buffer[1024];
1657 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1658 if (rv == 0 || rv >= 1024) return true;
1659 rv = ::GetLongPathName(buffer, buffer, 1024);
1660 if (rv == 0 || rv >= 1024) return true;
1662 QString canonical((QChar *)buffer);
1665 int absoluteLength = absolute.length();
1666 int canonicalLength = canonical.length();
1668 int length = qMin(absoluteLength, canonicalLength);
1669 for (int ii = 0; ii < length; ++ii) {
1670 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1671 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1673 if (a.toLower() != c.toLower())