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 <QtCore/qcryptographichash.h>
96 #include <private/qobject_p.h>
98 #include <private/qdeclarativeutilmodule_p.h>
99 #include <private/qsgitemsmodule_p.h>
100 #include <private/qsgparticlesmodule_p.h>
101 #include <qsgtexture.h>
103 #ifdef Q_OS_WIN // for %APPDATA%
104 #include <qt_windows.h>
105 #include <qlibrary.h>
108 #define CSIDL_APPDATA 0x001a // <username>\Application Data
111 Q_DECLARE_METATYPE(QDeclarativeProperty)
115 void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
117 QDeclarativeEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
118 QDeclarativeValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
119 QDeclarativeUtilModule::registerBaseTypes(uri, versionMajor, versionMinor);
123 \qmlclass QtObject QObject
124 \ingroup qml-utility-elements
126 \brief The QtObject element is the most basic element in QML.
128 The QtObject element is a non-visual element which contains only the
131 It can be useful to create a QtObject if you need an extremely
132 lightweight element to enclose a set of custom properties:
134 \snippet doc/src/snippets/declarative/qtobject.qml 0
136 It can also be useful for C++ integration, as it is just a plain
137 QObject. See the QObject documentation for further details.
140 \qmlproperty string QML:QtObject::objectName
141 This property holds the QObject::objectName for this specific object instance.
143 This allows a C++ application to locate an item within a QML component
144 using the QObject::findChild() method. For example, the following C++
145 application locates the child \l Rectangle item and dynamically changes its
154 width: 200; height: 200
167 QDeclarativeView view;
168 view.setSource(QUrl::fromLocalFile("MyRect.qml"));
171 QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
173 item->setProperty("color", QColor(Qt::yellow));
177 static bool qt_QmlQtModule_registered = false;
178 bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
180 void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
182 qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
183 qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
184 qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
187 void QDeclarativeEnginePrivate::defineModule()
189 registerBaseTypes("QtQuick", 2, 0);
190 qmlRegisterType<QDeclarativeBinding>();
194 \qmlclass QML:Qt QDeclarativeEnginePrivate
195 \ingroup qml-utility-elements
196 \brief The QML global Qt object provides useful enums and functions from Qt.
198 \keyword QmlGlobalQtObject
200 \brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
202 The \c Qt object is a global object with utility functions, properties and enums.
204 It is not instantiable; to use it, call the members of the global \c Qt object directly.
211 color: Qt.rgba(1, 0, 0, 1)
212 text: Qt.md5("hello, world")
219 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
220 the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
224 The Qt object also contains helper functions for creating objects of specific
225 data types. This is primarily useful when setting the properties of an item
226 when the property has one of the following types:
229 \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()}
230 \o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
231 \o \c point - use \l{QML:Qt::point()}{Qt.point()}
232 \o \c size - use \l{QML:Qt::size()}{Qt.size()}
233 \o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
236 There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
238 \section1 Date/Time Formatters
240 The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
243 \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
244 \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
245 \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
248 The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
251 \section1 Dynamic Object Creation
252 The following functions on the global object allow you to dynamically create QML
253 items from files or strings. See \l{Dynamic Object Management in QML} for an overview
257 \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
258 \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
264 \qmlproperty object QML:Qt::application
267 The \c application object provides access to global application state
268 properties shared by many QML components.
274 \o \c application.active
276 This read-only property indicates whether the application is the top-most and focused
277 application, and the user is able to interact with the application. The property
278 is false when the application is in the background, the device keylock or screen
279 saver is active, the screen backlight is turned off, or the global system dialog
280 is being displayed on top of the application. It can be used for stopping and
281 pausing animations, timers and active processing of data in order to save device
282 battery power and free device memory and processor load when the application is not
286 \o \c application.layoutDirection
288 This read-only property can be used to query the default layout direction of the
289 application. On system start-up, the default layout direction depends on the
290 application's language. The property has a value of \c Qt.RightToLeft in locales
291 where text and graphic elements are read from right to left, and \c Qt.LeftToRight
292 where the reading direction flows from left to right. You can bind to this
293 property to customize your application layouts to support both layout directions.
298 \o Qt.LeftToRight - Text and graphics elements should be positioned
300 \o Qt.RightToLeft - Text and graphics elements should be positioned
305 The following example uses the \c application object to indicate
306 whether the application is currently active:
308 \snippet doc/src/snippets/declarative/application.qml document
314 \qmlmethod object Qt::include(string url, jsobject callback)
316 Includes another JavaScript file. This method can only be used from within JavaScript files,
317 and not regular QML files.
319 This imports all functions from \a url into the current script's namespace.
321 Qt.include() returns an object that describes the status of the operation. The object has
322 a single property, \c {status}, that is set to one of the following values:
325 \header \o Symbol \o Value \o Description
326 \row \o result.OK \o 0 \o The include completed successfully.
327 \row \o result.LOADING \o 1 \o Data is being loaded from the network.
328 \row \o result.NETWORK_ERROR \o 2 \o A network error occurred while fetching the url.
329 \row \o result.EXCEPTION \o 3 \o A JavaScript exception occurred while executing the included code.
330 An additional \c exception property will be set in this case.
333 The \c status property will be updated as the operation progresses.
335 If provided, \a callback is invoked when the operation completes. The callback is passed
336 the same object as is returned from the Qt.include() call.
338 // Qt.include() is implemented in qv8include.cpp
341 QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
342 : captureProperties(false), rootContext(0), isDebugging(false),
343 outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
344 cleanup(0), erroredBindings(0), inProgressCreations(0),
345 workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
346 networkAccessManager(0), networkAccessManagerFactory(0),
347 scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
350 if (!qt_QmlQtModule_registered) {
351 qt_QmlQtModule_registered = true;
352 QDeclarativeUtilModule::defineModule();
353 QDeclarativeEnginePrivate::defineModule();
354 QSGItemsModule::defineModule();
355 QSGParticlesModule::defineModule();
356 QDeclarativeValueTypeFactory::registerValueTypes();
360 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
362 Q_ASSERT(inProgressCreations == 0);
363 Q_ASSERT(bindValues.isEmpty());
364 Q_ASSERT(parserStatus.isEmpty());
367 QDeclarativeCleanup *c = cleanup;
369 if (cleanup) cleanup->prev = &cleanup;
378 for(QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter)
380 for(QHash<const QMetaObject *, QDeclarativePropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter)
382 for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
384 for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
385 delete (*iter)->qobjectApi;
390 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
395 void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
397 for (int ii = 0; ii < pss.count; ++ii) {
398 QDeclarativeParserStatus *ps = pss.at(ii);
405 void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
407 QObjectPrivate *p = QObjectPrivate::get(o);
408 if (p->declarativeData) {
409 QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
410 if (d->ownContext && d->context) {
411 d->context->destroy();
417 void QDeclarativeData::destroyed(QAbstractDeclarativeData *d, QObject *o)
419 static_cast<QDeclarativeData *>(d)->destroyed(o);
422 void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p)
424 static_cast<QDeclarativeData *>(d)->parentChanged(o, p);
427 void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
429 static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
432 void QDeclarativeEnginePrivate::init()
434 Q_Q(QDeclarativeEngine);
435 qRegisterMetaType<QVariant>("QVariant");
436 qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
437 qRegisterMetaType<QJSValue>("QJSValue");
438 qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
439 qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
440 qRegisterMetaType<QList<int> >("QList<int>");
441 qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
443 QDeclarativeData::init();
445 v8engine()->setEngine(q);
447 rootContext = new QDeclarativeContext(q,true);
449 if (QCoreApplication::instance()->thread() == q->thread() &&
450 QDeclarativeEngineDebugService::isDebuggingEnabled()) {
452 QDeclarativeEngineDebugService::instance()->addEngine(q);
453 QV8DebugService::instance()->addEngine(q);
457 QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
459 Q_Q(QDeclarativeEngine);
460 if (!workerScriptEngine)
461 workerScriptEngine = new QDeclarativeWorkerScriptEngine(q);
462 return workerScriptEngine;
466 \class QDeclarativeEngine
468 \brief The QDeclarativeEngine class provides an environment for instantiating QML components.
471 Each QML component is instantiated in a QDeclarativeContext.
472 QDeclarativeContext's are essential for passing data to QML
473 components. In QML, contexts are arranged hierarchically and this
474 hierarchy is managed by the QDeclarativeEngine.
476 Prior to creating any QML components, an application must have
477 created a QDeclarativeEngine to gain access to a QML context. The
478 following example shows how to create a simple Text item.
481 QDeclarativeEngine engine;
482 QDeclarativeComponent component(&engine);
483 component.setData("import QtQuick 1.0\nText { text: \"Hello world!\" }", QUrl());
484 QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
486 //add item to view, etc
490 In this case, the Text item will be created in the engine's
491 \l {QDeclarativeEngine::rootContext()}{root context}.
493 \sa QDeclarativeComponent QDeclarativeContext
497 Create a new QDeclarativeEngine with the given \a parent.
499 QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
500 : QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
502 Q_D(QDeclarativeEngine);
507 Destroys the QDeclarativeEngine.
509 Any QDeclarativeContext's created on this engine will be
510 invalidated, but not destroyed (unless they are parented to the
511 QDeclarativeEngine object).
513 QDeclarativeEngine::~QDeclarativeEngine()
515 Q_D(QDeclarativeEngine);
517 QDeclarativeEngineDebugService::instance()->remEngine(this);
519 // if we are the parent of any of the qobject module api instances,
520 // we need to remove them from our internal list, in order to prevent
521 // a segfault in engine private dtor.
522 QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
523 QObject *currQObjectApi = 0;
524 QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
525 foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
526 currInstance = d->moduleApiInstances.value(key);
527 currQObjectApi = currInstance->qobjectApi;
528 if (this->children().contains(currQObjectApi)) {
529 delete currQObjectApi;
531 d->moduleApiInstances.remove(key);
536 /*! \fn void QDeclarativeEngine::quit()
537 This signal is emitted when the QML loaded by the engine would like to quit.
540 /*! \fn void QDeclarativeEngine::warnings(const QList<QDeclarativeError> &warnings)
541 This signal is emitted when \a warnings messages are generated by QML.
545 Clears the engine's internal component cache.
547 Normally the QDeclarativeEngine caches components loaded from qml
548 files. This method clears this cache and forces the component to be
551 void QDeclarativeEngine::clearComponentCache()
553 Q_D(QDeclarativeEngine);
554 d->typeLoader.clearCache();
558 Returns the engine's root context.
560 The root context is automatically created by the QDeclarativeEngine.
561 Data that should be available to all QML component instances
562 instantiated by the engine should be put in the root context.
564 Additional data that should only be available to a subset of
565 component instances should be added to sub-contexts parented to the
568 QDeclarativeContext *QDeclarativeEngine::rootContext() const
570 Q_D(const QDeclarativeEngine);
571 return d->rootContext;
575 Sets the \a factory to use for creating QNetworkAccessManager(s).
577 QNetworkAccessManager is used for all network access by QML. By
578 implementing a factory it is possible to create custom
579 QNetworkAccessManager with specialized caching, proxy and cookie
582 The factory must be set before executing the engine.
584 void QDeclarativeEngine::setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *factory)
586 Q_D(QDeclarativeEngine);
587 QMutexLocker locker(&d->mutex);
588 d->networkAccessManagerFactory = factory;
592 Returns the current QDeclarativeNetworkAccessManagerFactory.
594 \sa setNetworkAccessManagerFactory()
596 QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManagerFactory() const
598 Q_D(const QDeclarativeEngine);
599 return d->networkAccessManagerFactory;
602 QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
604 QMutexLocker locker(&mutex);
605 QNetworkAccessManager *nam;
606 if (networkAccessManagerFactory) {
607 nam = networkAccessManagerFactory->create(parent);
609 nam = new QNetworkAccessManager(parent);
615 QNetworkAccessManager *QDeclarativeEnginePrivate::getNetworkAccessManager() const
617 Q_Q(const QDeclarativeEngine);
618 if (!networkAccessManager)
619 networkAccessManager = createNetworkAccessManager(const_cast<QDeclarativeEngine*>(q));
620 return networkAccessManager;
624 Returns a common QNetworkAccessManager which can be used by any QML
625 element instantiated by this engine.
627 If a QDeclarativeNetworkAccessManagerFactory has been set and a
628 QNetworkAccessManager has not yet been created, the
629 QDeclarativeNetworkAccessManagerFactory will be used to create the
630 QNetworkAccessManager; otherwise the returned QNetworkAccessManager
631 will have no proxy or cache set.
633 \sa setNetworkAccessManagerFactory()
635 QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
637 Q_D(const QDeclarativeEngine);
638 return d->getNetworkAccessManager();
643 Sets the \a provider to use for images requested via the \e
644 image: url scheme, with host \a providerId. The QDeclarativeEngine
645 takes ownership of \a provider.
647 Image providers enable support for pixmap and threaded image
648 requests. See the QDeclarativeImageProvider documentation for details on
649 implementing and using image providers.
651 All required image providers should be added to the engine before any
652 QML sources files are loaded.
654 \sa removeImageProvider()
656 void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
658 Q_D(QDeclarativeEngine);
659 QMutexLocker locker(&d->mutex);
660 d->imageProviders.insert(providerId.toLower(), QSharedPointer<QDeclarativeImageProvider>(provider));
664 Returns the QDeclarativeImageProvider set for \a providerId.
666 Returns the provider if it was found; otherwise returns 0.
668 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
670 Q_D(const QDeclarativeEngine);
671 QMutexLocker locker(&d->mutex);
672 return d->imageProviders.value(providerId).data();
676 Removes the QDeclarativeImageProvider for \a providerId.
678 \sa addImageProvider()
680 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
682 Q_D(QDeclarativeEngine);
683 QMutexLocker locker(&d->mutex);
684 d->imageProviders.take(providerId);
687 QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProviderType(const QUrl &url)
689 QMutexLocker locker(&mutex);
690 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
693 return provider->imageType();
694 return QDeclarativeImageProvider::Invalid;
697 QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
699 QMutexLocker locker(&mutex);
700 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
703 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
704 return provider->requestTexture(imageId, size, req_size);
709 QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
711 QMutexLocker locker(&mutex);
713 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
716 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
717 image = provider->requestImage(imageId, size, req_size);
722 QPixmap QDeclarativeEnginePrivate::getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
724 QMutexLocker locker(&mutex);
726 QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
729 QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
730 pixmap = provider->requestPixmap(imageId, size, req_size);
736 Return the base URL for this engine. The base URL is only used to
737 resolve components when a relative URL is passed to the
738 QDeclarativeComponent constructor.
740 If a base URL has not been explicitly set, this method returns the
741 application's current working directory.
745 QUrl QDeclarativeEngine::baseUrl() const
747 Q_D(const QDeclarativeEngine);
748 if (d->baseUrl.isEmpty()) {
749 return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
756 Set the base URL for this engine to \a url.
760 void QDeclarativeEngine::setBaseUrl(const QUrl &url)
762 Q_D(QDeclarativeEngine);
767 Returns true if warning messages will be output to stderr in addition
768 to being emitted by the warnings() signal, otherwise false.
770 The default value is true.
772 bool QDeclarativeEngine::outputWarningsToStandardError() const
774 Q_D(const QDeclarativeEngine);
775 return d->outputWarningsToStdErr;
779 Set whether warning messages will be output to stderr to \a enabled.
781 If \a enabled is true, any warning messages generated by QML will be
782 output to stderr and emitted by the warnings() signal. If \a enabled
783 is false, on the warnings() signal will be emitted. This allows
784 applications to handle warning output themselves.
786 The default value is true.
788 void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
790 Q_D(QDeclarativeEngine);
791 d->outputWarningsToStdErr = enabled;
795 Attempt to free unused memory.
797 void QDeclarativeEngine::collectGarbage()
803 Returns the QDeclarativeContext for the \a object, or 0 if no
804 context has been set.
806 When the QDeclarativeEngine instantiates a QObject, the context is
809 QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
814 QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
816 QDeclarativeData *data =
817 static_cast<QDeclarativeData *>(priv->declarativeData);
821 else if (data->outerContext)
822 return data->outerContext->asQDeclarativeContext();
828 Sets the QDeclarativeContext for the \a object to \a context.
829 If the \a object already has a context, a warning is
830 output, but the context is not changed.
832 When the QDeclarativeEngine instantiates a QObject, the context is
835 void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContext *context)
837 if (!object || !context)
840 QDeclarativeData *data = QDeclarativeData::get(object, true);
842 qWarning("QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
846 QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
847 contextData->addObject(object);
851 \enum QDeclarativeEngine::ObjectOwnership
853 Ownership controls whether or not QML automatically destroys the
854 QObject when the object is garbage collected by the JavaScript
855 engine. The two ownership options are:
857 \value CppOwnership The object is owned by C++ code, and will
858 never be deleted by QML. The JavaScript destroy() method cannot be
859 used on objects with CppOwnership. This option is similar to
860 QScriptEngine::QtOwnership.
862 \value JavaScriptOwnership The object is owned by JavaScript.
863 When the object is returned to QML as the return value of a method
864 call or property access, QML will delete the object if there are no
865 remaining JavaScript references to it and it has no
866 QObject::parent(). This option is similar to
867 QScriptEngine::ScriptOwnership.
869 Generally an application doesn't need to set an object's ownership
870 explicitly. QML uses a heuristic to set the default object
871 ownership. By default, an object that is created by QML has
872 JavaScriptOwnership. The exception to this are the root objects
873 created by calling QDeclarativeCompnent::create() or
874 QDeclarativeComponent::beginCreate() which have CppOwnership by
875 default. The ownership of these root-level objects is considered to
876 have been transferred to the C++ caller.
878 Objects not-created by QML have CppOwnership by default. The
879 exception to this is objects returned from a C++ method call. The
880 ownership of these objects is passed to JavaScript.
882 Calling setObjectOwnership() overrides the default ownership
883 heuristic used by QML.
887 Sets the \a ownership of \a object.
889 void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
894 QDeclarativeData *ddata = QDeclarativeData::get(object, true);
898 ddata->indestructible = (ownership == CppOwnership)?true:false;
899 ddata->explicitIndestructibleSet = true;
903 Returns the ownership of \a object.
905 QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
910 QDeclarativeData *ddata = QDeclarativeData::get(object, false);
914 return ddata->indestructible?CppOwnership:JavaScriptOwnership;
917 Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
919 QDeclarativeData *data = QDeclarativeData::get(object);
921 if (data && data->deferredComponent) {
922 if (QDeclarativeDebugService::isDebuggingEnabled()) {
923 QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
924 QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
925 QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
926 QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
927 if (data->outerContext)
928 QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
930 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
932 QDeclarativeComponentPrivate::ConstructionState state;
933 QDeclarativeComponentPrivate::beginDeferred(ep, object, &state);
935 data->deferredComponent->release();
936 data->deferredComponent = 0;
938 QDeclarativeComponentPrivate::complete(ep, &state);
939 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
943 QDeclarativeContext *qmlContext(const QObject *obj)
945 return QDeclarativeEngine::contextForObject(obj);
948 QDeclarativeEngine *qmlEngine(const QObject *obj)
950 QDeclarativeData *data = QDeclarativeData::get(obj, false);
951 if (!data || !data->context)
953 return data->context->engine;
956 QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
958 QDeclarativeData *data = QDeclarativeData::get(object);
960 return 0; // Attached properties are only on objects created by QML
962 QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
966 QDeclarativeAttachedPropertiesFunc pf = QDeclarativeMetaType::attachedPropertiesFuncById(id);
970 rv = pf(const_cast<QObject *>(object));
973 data->attachedProperties()->insert(id, rv);
978 QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
979 const QMetaObject *attachedMetaObject, bool create)
982 *idCache = QDeclarativeMetaType::attachedPropertiesFuncId(attachedMetaObject);
984 if (*idCache == -1 || !object)
987 return qmlAttachedPropertiesObjectById(*idCache, object, create);
990 QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
992 #ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
993 if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
994 qWarning("Qml debugging is enabled. Only use this in a safe environment!");
996 QDeclarativeEnginePrivate::qml_debugging_enabled = true;
1001 class QDeclarativeDataExtended {
1003 QDeclarativeDataExtended();
1004 ~QDeclarativeDataExtended();
1006 QHash<int, QObject *> attachedProperties;
1007 QDeclarativeNotifier objectNameNotifier;
1010 QDeclarativeDataExtended::QDeclarativeDataExtended()
1014 QDeclarativeDataExtended::~QDeclarativeDataExtended()
1018 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
1020 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1021 return &extendedData->objectNameNotifier;
1024 QHash<int, QObject *> *QDeclarativeData::attachedProperties() const
1026 if (!extendedData) extendedData = new QDeclarativeDataExtended;
1027 return &extendedData->attachedProperties;
1030 void QDeclarativeData::destroyed(QObject *object)
1032 if (deferredComponent)
1033 deferredComponent->release();
1035 if (nextContextObject)
1036 nextContextObject->prevContextObject = prevContextObject;
1037 if (prevContextObject)
1038 *prevContextObject = nextContextObject;
1040 QDeclarativeAbstractBinding *binding = bindings;
1042 QDeclarativeAbstractBinding *next = binding->m_nextBinding;
1043 binding->m_prevBinding = 0;
1044 binding->m_nextBinding = 0;
1053 propertyCache->release();
1055 if (ownContext && context)
1059 QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
1060 *guard = (QObject *)0;
1061 guard->objectDestroyed(object);
1065 delete extendedData;
1067 v8object.Clear(); // The WeakReference handler will clean the actual handle
1073 void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
1079 void QDeclarativeData::objectNameChanged(QObject *)
1081 if (extendedData) objectNameNotifier()->notify();
1084 bool QDeclarativeData::hasBindingBit(int bit) const
1086 if (bindingBitsSize > bit)
1087 return bindingBits[bit / 32] & (1 << (bit % 32));
1092 void QDeclarativeData::clearBindingBit(int bit)
1094 if (bindingBitsSize > bit)
1095 bindingBits[bit / 32] &= ~(1 << (bit % 32));
1098 void QDeclarativeData::setBindingBit(QObject *obj, int bit)
1100 if (bindingBitsSize <= bit) {
1101 int props = obj->metaObject()->propertyCount();
1102 Q_ASSERT(bit < props);
1104 int arraySize = (props + 31) / 32;
1105 int oldArraySize = bindingBitsSize / 32;
1107 bindingBits = (quint32 *)realloc(bindingBits,
1108 arraySize * sizeof(quint32));
1110 memset(bindingBits + oldArraySize,
1112 sizeof(quint32) * (arraySize - oldArraySize));
1114 bindingBitsSize = arraySize * 32;
1117 bindingBits[bit / 32] |= (1 << (bit % 32));
1120 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
1122 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {
1123 if (url.authority().isEmpty())
1124 return QLatin1Char(':') + url.path();
1127 return url.toLocalFile();
1131 static QString toLocalFile(const QString &url)
1133 if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
1136 QString file = url.mid(7);
1138 //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
1140 // magic for drives on windows
1141 if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
1147 QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
1149 if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
1150 if (url.length() > 4)
1151 return QLatin1Char(':') + url.mid(4);
1155 return toLocalFile(url);
1158 void QDeclarativeEnginePrivate::sendQuit()
1160 Q_Q(QDeclarativeEngine);
1162 if (q->receivers(SIGNAL(quit())) == 0) {
1163 qWarning("Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it.");
1167 static void dumpwarning(const QDeclarativeError &error)
1169 qWarning().nospace() << qPrintable(error.toString());
1172 static void dumpwarning(const QList<QDeclarativeError> &errors)
1174 for (int ii = 0; ii < errors.count(); ++ii)
1175 dumpwarning(errors.at(ii));
1178 void QDeclarativeEnginePrivate::warning(const QDeclarativeError &error)
1180 Q_Q(QDeclarativeEngine);
1181 q->warnings(QList<QDeclarativeError>() << error);
1182 if (outputWarningsToStdErr)
1186 void QDeclarativeEnginePrivate::warning(const QList<QDeclarativeError> &errors)
1188 Q_Q(QDeclarativeEngine);
1189 q->warnings(errors);
1190 if (outputWarningsToStdErr)
1191 dumpwarning(errors);
1194 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QDeclarativeError &error)
1197 QDeclarativeEnginePrivate::get(engine)->warning(error);
1202 void QDeclarativeEnginePrivate::warning(QDeclarativeEngine *engine, const QList<QDeclarativeError> &error)
1205 QDeclarativeEnginePrivate::get(engine)->warning(error);
1210 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QDeclarativeError &error)
1213 engine->warning(error);
1218 void QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate *engine, const QList<QDeclarativeError> &error)
1221 engine->warning(error);
1227 This function should be called prior to evaluation of any js expression,
1228 so that scarce resources are not freed prematurely (eg, if there is a
1229 nested javascript expression).
1231 void QDeclarativeEnginePrivate::referenceScarceResources()
1233 scarceResourcesRefCount += 1;
1237 This function should be called after evaluation of the js expression is
1238 complete, and so the scarce resources may be freed safely.
1240 void QDeclarativeEnginePrivate::dereferenceScarceResources()
1242 Q_ASSERT(scarceResourcesRefCount > 0);
1243 scarceResourcesRefCount -= 1;
1245 // if the refcount is zero, then evaluation of the "top level"
1246 // expression must have completed. We can safely release the
1247 // scarce resources.
1248 if (scarceResourcesRefCount == 0) {
1249 // iterate through the list and release them all.
1250 // note that the actual SRD is owned by the JS engine,
1251 // so we cannot delete the SRD; but we can free the
1252 // memory used by the variant in the SRD.
1253 while (ScarceResourceData *sr = scarceResources.first()) {
1254 sr->data = QVariant();
1255 scarceResources.remove(sr);
1261 Adds \a path as a directory where the engine searches for
1262 installed modules in a URL-based directory structure.
1263 The \a path may be a local filesystem directory or a URL.
1265 The newly added \a path will be first in the importPathList().
1267 \sa setImportPathList(), {QML Modules}
1269 void QDeclarativeEngine::addImportPath(const QString& path)
1271 Q_D(QDeclarativeEngine);
1272 d->importDatabase.addImportPath(path);
1276 Returns the list of directories where the engine searches for
1277 installed modules in a URL-based directory structure.
1279 For example, if \c /opt/MyApp/lib/imports is in the path, then QML that
1280 imports \c com.mycompany.Feature will cause the QDeclarativeEngine to look
1281 in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
1282 provided by that module. A \c qmldir file is required for defining the
1283 type version mapping and possibly declarative extensions plugins.
1285 By default, the list contains the directory of the application executable,
1286 paths specified in the \c QML_IMPORT_PATH environment variable,
1287 and the builtin \c ImportsPath from QLibraryInfo.
1289 \sa addImportPath() setImportPathList()
1291 QStringList QDeclarativeEngine::importPathList() const
1293 Q_D(const QDeclarativeEngine);
1294 return d->importDatabase.importPathList();
1298 Sets \a paths as the list of directories where the engine searches for
1299 installed modules in a URL-based directory structure.
1301 By default, the list contains the directory of the application executable,
1302 paths specified in the \c QML_IMPORT_PATH environment variable,
1303 and the builtin \c ImportsPath from QLibraryInfo.
1305 \sa importPathList() addImportPath()
1307 void QDeclarativeEngine::setImportPathList(const QStringList &paths)
1309 Q_D(QDeclarativeEngine);
1310 d->importDatabase.setImportPathList(paths);
1315 Adds \a path as a directory where the engine searches for
1316 native plugins for imported modules (referenced in the \c qmldir file).
1318 By default, the list contains only \c ., i.e. the engine searches
1319 in the directory of the \c qmldir file itself.
1321 The newly added \a path will be first in the pluginPathList().
1323 \sa setPluginPathList()
1325 void QDeclarativeEngine::addPluginPath(const QString& path)
1327 Q_D(QDeclarativeEngine);
1328 d->importDatabase.addPluginPath(path);
1333 Returns the list of directories where the engine searches for
1334 native plugins for imported modules (referenced in the \c qmldir file).
1336 By default, the list contains only \c ., i.e. the engine searches
1337 in the directory of the \c qmldir file itself.
1339 \sa addPluginPath() setPluginPathList()
1341 QStringList QDeclarativeEngine::pluginPathList() const
1343 Q_D(const QDeclarativeEngine);
1344 return d->importDatabase.pluginPathList();
1348 Sets the list of directories where the engine searches for
1349 native plugins for imported modules (referenced in the \c qmldir file)
1352 By default, the list contains only \c ., i.e. the engine searches
1353 in the directory of the \c qmldir file itself.
1355 \sa pluginPathList() addPluginPath()
1357 void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
1359 Q_D(QDeclarativeEngine);
1360 d->importDatabase.setPluginPathList(paths);
1364 Imports the plugin named \a filePath with the \a uri provided.
1365 Returns true if the plugin was successfully imported; otherwise returns false.
1367 On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
1369 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1371 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
1373 Q_D(QDeclarativeEngine);
1374 return d->importDatabase.importPlugin(filePath, uri, errors);
1378 Imports the plugin named \a filePath with the \a uri provided.
1379 Returns true if the plugin was successfully imported; otherwise returns false.
1381 On failure and if non-null, *\a errorString will be set to a message describing the failure.
1383 The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
1385 bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
1387 Q_D(QDeclarativeEngine);
1388 QList<QDeclarativeError> errors;
1389 bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
1390 if (!errors.isEmpty()) {
1392 for (int i = 0; i < errors.size(); ++i) {
1393 builtError = QString(QLatin1String("%1\n %2"))
1395 .arg(errors.at(i).toString());
1397 *errorString = builtError;
1403 \property QDeclarativeEngine::offlineStoragePath
1404 \brief the directory for storing offline user data
1406 Returns the directory where SQL and other offline
1409 QDeclarativeWebView and the SQL databases created with openDatabase()
1412 The default is QML/OfflineStorage in the platform-standard
1413 user application data directory.
1415 Note that the path may not currently exist on the filesystem, so
1416 callers wanting to \e create new files at this location should create
1417 it first - see QDir::mkpath().
1419 void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
1421 Q_D(QDeclarativeEngine);
1422 qt_qmlsqldatabase_setOfflineStoragePath(d->v8engine(), dir);
1425 QString QDeclarativeEngine::offlineStoragePath() const
1427 Q_D(const QDeclarativeEngine);
1428 return qt_qmlsqldatabase_getOfflineStoragePath(d->v8engine());
1431 static void voidptr_destructor(void *v)
1433 void **ptr = (void **)v;
1437 static void *voidptr_constructor(const void *v)
1442 return new void*(*(void **)v);
1446 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObject *mo)
1448 Q_Q(QDeclarativeEngine);
1450 if (!mo->superClass()) {
1451 QDeclarativePropertyCache *rv = new QDeclarativePropertyCache(q, mo);
1452 propertyCache.insert(mo, rv);
1455 QDeclarativePropertyCache *super = cache(mo->superClass());
1456 QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() -
1457 mo->superClass()->propertyCount() -
1458 mo->superClass()->methodCount());
1460 propertyCache.insert(mo, rv);
1465 QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
1466 QDeclarativeError &error)
1468 QList<QDeclarativeType *> types;
1470 int maxMinorVersion = 0;
1472 const QMetaObject *metaObject = type->metaObject();
1473 while (metaObject) {
1474 QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
1475 type->majorVersion(), minorVersion);
1477 maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
1483 metaObject = metaObject->superClass();
1486 if (QDeclarativePropertyCache *c = typePropertyCache.value(qMakePair(type, maxMinorVersion))) {
1488 typePropertyCache.insert(qMakePair(type, minorVersion), c);
1492 QDeclarativePropertyCache *raw = cache(type->metaObject());
1494 bool hasCopied = false;
1496 for (int ii = 0; ii < types.count(); ++ii) {
1497 QDeclarativeType *currentType = types.at(ii);
1501 int rev = currentType->metaObjectRevision();
1502 int moIndex = types.count() - 1 - ii;
1504 if (raw->allowedRevisionCache[moIndex] != rev) {
1509 raw->allowedRevisionCache[moIndex] = rev;
1513 // Test revision compatibility - the basic rule is:
1514 // * Anything that is excluded, cannot overload something that is not excluded *
1516 // Signals override:
1517 // * other signals and methods of the same name.
1518 // * properties named on<Signal Name>
1519 // * automatic <property name>Changed notify signals
1521 // Methods override:
1522 // * other methods of the same name
1524 // Properties override:
1525 // * other elements of the same name
1527 bool overloadError = false;
1528 QString overloadName;
1531 for (QDeclarativePropertyCache::StringCache::ConstIterator iter = raw->stringCache.begin();
1532 !overloadError && iter != raw->stringCache.end();
1535 QDeclarativePropertyCache::Data *d = *iter;
1536 if (raw->isAllowedInRevision(d))
1537 continue; // Not excluded - no problems
1539 // check that a regular "name" overload isn't happening
1540 QDeclarativePropertyCache::Data *current = d;
1541 while (!overloadError && current) {
1542 current = d->overrideData(current);
1543 if (current && raw->isAllowedInRevision(current))
1544 overloadError = true;
1549 if (overloadError) {
1550 if (hasCopied) raw->release();
1552 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."));
1556 if (!hasCopied) raw->addref();
1557 typePropertyCache.insert(qMakePair(type, minorVersion), raw);
1559 if (minorVersion != maxMinorVersion) {
1561 typePropertyCache.insert(qMakePair(type, maxMinorVersion), raw);
1567 void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
1569 QByteArray name = data->root->className();
1571 QByteArray ptr = name + '*';
1572 QByteArray lst = "QDeclarativeListProperty<" + name + '>';
1574 int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
1575 voidptr_constructor);
1576 int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
1577 voidptr_constructor);
1579 m_qmlLists.insert(lst_type, ptr_type);
1580 m_compositeTypes.insert(ptr_type, data);
1584 bool QDeclarativeEnginePrivate::isList(int t) const
1586 return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
1589 int QDeclarativeEnginePrivate::listType(int t) const
1591 QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
1592 if (iter != m_qmlLists.end())
1595 return QDeclarativeMetaType::listType(t);
1598 bool QDeclarativeEnginePrivate::isQObject(int t)
1600 return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
1603 QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
1605 int t = v.userType();
1606 if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
1608 return *(QObject **)(v.constData());
1610 return QDeclarativeMetaType::toQObject(v, ok);
1614 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
1616 if (m_compositeTypes.contains(t))
1617 return QDeclarativeMetaType::Object;
1618 else if (m_qmlLists.contains(t))
1619 return QDeclarativeMetaType::List;
1621 return QDeclarativeMetaType::typeCategory(t);
1624 const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
1626 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1627 if (iter != m_compositeTypes.end()) {
1628 return (*iter)->root;
1630 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1631 return type?type->baseMetaObject():0;
1635 const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
1637 QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
1638 if (iter != m_compositeTypes.end()) {
1639 return (*iter)->root;
1641 QDeclarativeType *type = QDeclarativeMetaType::qmlType(t);
1642 return type?type->metaObject():0;
1646 bool QDeclarative_isFileCaseCorrect(const QString &fileName)
1648 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
1649 QFileInfo info(fileName);
1651 QString absolute = info.absoluteFilePath();
1653 #if defined(Q_OS_MAC)
1654 QString canonical = info.canonicalFilePath();
1655 #elif defined(Q_OS_WIN32)
1656 wchar_t buffer[1024];
1658 DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
1659 if (rv == 0 || rv >= 1024) return true;
1660 rv = ::GetLongPathName(buffer, buffer, 1024);
1661 if (rv == 0 || rv >= 1024) return true;
1663 QString canonical((QChar *)buffer);
1666 int absoluteLength = absolute.length();
1667 int canonicalLength = canonical.length();
1669 int length = qMin(absoluteLength, canonicalLength);
1670 for (int ii = 0; ii < length; ++ii) {
1671 const QChar &a = absolute.at(absoluteLength - 1 - ii);
1672 const QChar &c = canonical.at(canonicalLength - 1 - ii);
1674 if (a.toLower() != c.toLower())
1686 \fn QDeclarativeEngine *qmlEngine(const QObject *object)
1687 \relates QDeclarativeEngine
1689 Returns the QDeclarativeEngine associated with \a object, if any. This is equivalent to
1690 QDeclarativeEngine::contextForObject(object)->engine(), but more efficient.
1694 \fn QDeclarativeContext *qmlContext(const QObject *object)
1695 \relates QDeclarativeEngine
1697 Returns the QDeclarativeContext associated with \a object, if any. This is equivalent to
1698 QDeclarativeEngine::contextForObject(object).