diff options
author | Warwick Allison <warwick.allison@nokia.com> | 2010-02-24 02:42:00 (GMT) |
---|---|---|
committer | Warwick Allison <warwick.allison@nokia.com> | 2010-02-24 02:42:00 (GMT) |
commit | 7c76abb0dc4204043bec9b6fa315f9753a7986ae (patch) | |
tree | cee303672cfd138790645e731f2d69472564d4b7 /src/declarative/qml/qmlengine.cpp | |
parent | 4066e60e859853cfe3240245ba05271e79839506 (diff) | |
download | Qt-7c76abb0dc4204043bec9b6fa315f9753a7986ae.zip Qt-7c76abb0dc4204043bec9b6fa315f9753a7986ae.tar.gz Qt-7c76abb0dc4204043bec9b6fa315f9753a7986ae.tar.bz2 |
Change class prefix to from QmlXXX to QDeclarativeXXX, QmlGraphicsXXX to QDeclarativeXXX.
Diffstat (limited to 'src/declarative/qml/qmlengine.cpp')
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 1901 |
1 files changed, 0 insertions, 1901 deletions
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp deleted file mode 100644 index 2d904d1..0000000 --- a/src/declarative/qml/qmlengine.cpp +++ /dev/null @@ -1,1901 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmlengine_p.h" -#include "qmlengine.h" - -#include "qmlcontext_p.h" -#include "qmlcompiler_p.h" -#include "qmlglobalscriptclass_p.h" -#include "qml.h" -#include "qmlcontext.h" -#include "qmlexpression.h" -#include "qmlcomponent.h" -#include "qmlmetaproperty_p.h" -#include "qmlbinding_p_p.h" -#include "qmlvme_p.h" -#include "qmlenginedebug_p.h" -#include "qmlstringconverters_p.h" -#include "qmlxmlhttprequest_p.h" -#include "qmlsqldatabase_p.h" -#include "qmltypenamescriptclass_p.h" -#include "qmllistscriptclass_p.h" -#include "qmlscriptstring.h" -#include "qmlglobal_p.h" -#include "qmlworkerscript_p.h" -#include "qmlcomponent_p.h" -#include "qmlscriptclass_p.h" -#include "qmlnetworkaccessmanagerfactory.h" -#include "qmlimageprovider.h" -#include "qmldirparser_p.h" -#include "qmlextensioninterface.h" -#include "qmllist_p.h" - -#include <qfxperf_p_p.h> - -#include <QtCore/qmetaobject.h> -#include <QScriptClass> -#include <QNetworkReply> -#include <QNetworkRequest> -#include <QNetworkAccessManager> -#include <QDesktopServices> -#include <QTimer> -#include <QList> -#include <QPair> -#include <QDebug> -#include <QMetaObject> -#include <QStack> -#include <QPluginLoader> -#include <QtCore/qlibraryinfo.h> -#include <QtCore/qthreadstorage.h> -#include <QtCore/qthread.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdir.h> -#include <QtCore/qmutex.h> -#include <QtGui/qcolor.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qsound.h> -#include <QGraphicsObject> -#include <QtCore/qcryptographichash.h> - -#include <private/qobject_p.h> -#include <private/qscriptdeclarativeclass_p.h> - -#include <private/qmlgraphicsitemsmodule_p.h> -#include <private/qmlgraphicsutilmodule_p.h> - -#ifdef Q_OS_WIN // for %APPDATA% -#include <qt_windows.h> -#include <qlibrary.h> - -#define CSIDL_APPDATA 0x001a // <username>\Application Data -#endif - -Q_DECLARE_METATYPE(QmlMetaProperty) - -QT_BEGIN_NAMESPACE - -DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE) - -/*! - \qmlclass QtObject QObject - \since 4.7 - \brief The QtObject element is the most basic element in QML - - The QtObject element is a non-visual element which contains only - the objectName property. It is useful for when you need an extremely - lightweight element to place your own custom properties in. - - It can also be useful for C++ integration, as it is just a plain QObject. See - the QObject documentation for further details. -*/ -/*! - \qmlproperty string QtObject::objectName - This property allows you to give a name to this specific object instance. - - See \l{scripting.html#accessing-child-qobjects}{Accessing Child QObjects} - in the scripting documentation for details how objectName can be used from - scripts. -*/ - -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } -}; - -static bool qt_QmlQtModule_registered = false; - -void QmlEnginePrivate::defineModule() -{ - QML_REGISTER_TYPE(Qt,4,6,Component,QmlComponent); - QML_REGISTER_TYPE(Qt,4,6,QtObject,QObject); - QML_REGISTER_TYPE(Qt,4,6,WorkerScript,QmlWorkerScript); - QML_REGISTER_TYPE(Qt,4,6,WorkerListModel,QmlWorkerListModel); - - QML_REGISTER_NOCREATE_TYPE(QmlBinding); -} - -QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) -: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false), - contextClass(0), sharedContext(0), sharedScope(0), objectClass(0), valueTypeClass(0), - globalClass(0), cleanup(0), erroredBindings(0), inProgressCreations(0), - scriptEngine(this), workerScriptEngine(0), componentAttacheds(0), inBeginCreate(false), - networkAccessManager(0), networkAccessManagerFactory(0), - typeManager(e), uniqueId(1) -{ - if (!qt_QmlQtModule_registered) { - qt_QmlQtModule_registered = true; - QmlGraphicsItemModule::defineModule(); - QmlGraphicsUtilModule::defineModule(); - QmlEnginePrivate::defineModule(); - } - globalClass = new QmlGlobalScriptClass(&scriptEngine); - fileImportPath.append(QLibraryInfo::location(QLibraryInfo::DataPath)+QDir::separator()+QLatin1String("qml")); - - // env import paths - QByteArray envImportPath = qgetenv("QML_IMPORT_PATH"); - if (!envImportPath.isEmpty()) { -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - QLatin1Char pathSep(';'); -#else - QLatin1Char pathSep(':'); -#endif - foreach (const QString &path, QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts)) { - QString canonicalPath = QDir(path).canonicalPath(); - if (!canonicalPath.isEmpty() && !environmentImportPath.contains(canonicalPath)) - environmentImportPath.append(canonicalPath); - } - } -} - -QUrl QmlScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) -{ - if (p) { - QmlContext *ctxt = QmlEnginePrivate::get(this)->getContext(context); - Q_ASSERT(ctxt); - return ctxt->resolvedUrl(url); - } - return baseUrl.resolved(url); -} - -QmlScriptEngine::QmlScriptEngine(QmlEnginePrivate *priv) -: p(priv), sqlQueryClass(0), namedNodeMapClass(0), nodeListClass(0) -{ - // Note that all documentation for stuff put on the global object goes in - // doc/src/declarative/globalobject.qdoc - - bool mainthread = priv != 0; - - QScriptValue qtObject = - newQMetaObject(StaticQtMetaObject::get()); - globalObject().setProperty(QLatin1String("Qt"), qtObject); - - offlineStoragePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation).replace(QLatin1Char('/'), QDir::separator()) - + QDir::separator() + QLatin1String("QML") - + QDir::separator() + QLatin1String("OfflineStorage"); - - - qt_add_qmlxmlhttprequest(this); - qt_add_qmlsqldatabase(this); - // XXX A Multimedia "Qt.Sound" class also needs to be made available, - // XXX but we don't want a dependency in that cirection. - // XXX When the above a done some better way, that way should also be - // XXX used to add Qt.Sound class. - - - //types - qtObject.setProperty(QLatin1String("rgba"), newFunction(QmlEnginePrivate::rgba, 4)); - qtObject.setProperty(QLatin1String("hsla"), newFunction(QmlEnginePrivate::hsla, 4)); - qtObject.setProperty(QLatin1String("rect"), newFunction(QmlEnginePrivate::rect, 4)); - qtObject.setProperty(QLatin1String("point"), newFunction(QmlEnginePrivate::point, 2)); - qtObject.setProperty(QLatin1String("size"), newFunction(QmlEnginePrivate::size, 2)); - qtObject.setProperty(QLatin1String("vector3d"), newFunction(QmlEnginePrivate::vector, 3)); - - if (mainthread) { - //color helpers - qtObject.setProperty(QLatin1String("lighter"), newFunction(QmlEnginePrivate::lighter, 1)); - qtObject.setProperty(QLatin1String("darker"), newFunction(QmlEnginePrivate::darker, 1)); - qtObject.setProperty(QLatin1String("tint"), newFunction(QmlEnginePrivate::tint, 2)); - } - - //misc methods - qtObject.setProperty(QLatin1String("closestAngle"), newFunction(QmlEnginePrivate::closestAngle, 2)); - qtObject.setProperty(QLatin1String("playSound"), newFunction(QmlEnginePrivate::playSound, 1)); - qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QmlEnginePrivate::desktopOpenUrl, 1)); - qtObject.setProperty(QLatin1String("md5"),newFunction(QmlEnginePrivate::md5, 1)); - qtObject.setProperty(QLatin1String("btoa"),newFunction(QmlEnginePrivate::btoa, 1)); - qtObject.setProperty(QLatin1String("atob"),newFunction(QmlEnginePrivate::atob, 1)); - qtObject.setProperty(QLatin1String("quit"), newFunction(QmlEnginePrivate::quit, 0)); - qtObject.setProperty(QLatin1String("resolvedUrl"),newFunction(QmlScriptEngine::resolvedUrl, 1)); - - //firebug/webkit compat - QScriptValue consoleObject = newObject(); - consoleObject.setProperty(QLatin1String("log"),newFunction(QmlEnginePrivate::consoleLog, 1)); - consoleObject.setProperty(QLatin1String("debug"),newFunction(QmlEnginePrivate::consoleLog, 1)); - globalObject().setProperty(QLatin1String("console"), consoleObject); - - if (mainthread) { - globalObject().setProperty(QLatin1String("createQmlObject"), - newFunction(QmlEnginePrivate::createQmlObject, 1)); - globalObject().setProperty(QLatin1String("createComponent"), - newFunction(QmlEnginePrivate::createComponent, 1)); - } - - // translation functions need to be installed - // before the global script class is constructed (QTBUG-6437) - installTranslatorFunctions(); -} - -QmlScriptEngine::~QmlScriptEngine() -{ - delete sqlQueryClass; - delete nodeListClass; - delete namedNodeMapClass; -} - -QScriptValue QmlScriptEngine::resolvedUrl(QScriptContext *ctxt, QScriptEngine *engine) -{ - QString arg = ctxt->argument(0).toString(); - QUrl r = QmlScriptEngine::get(engine)->resolvedUrl(ctxt,QUrl(arg)); - return QScriptValue(r.toString()); -} - -QNetworkAccessManager *QmlScriptEngine::networkAccessManager() -{ - return p->getNetworkAccessManager(); -} - -QmlEnginePrivate::~QmlEnginePrivate() -{ - while (cleanup) { - QmlCleanup *c = cleanup; - cleanup = c->next; - if (cleanup) cleanup->prev = &cleanup; - c->next = 0; - c->prev = 0; - c->clear(); - } - - delete rootContext; - rootContext = 0; - delete contextClass; - contextClass = 0; - delete objectClass; - objectClass = 0; - delete valueTypeClass; - valueTypeClass = 0; - delete typeNameClass; - typeNameClass = 0; - delete listClass; - listClass = 0; - delete globalClass; - globalClass = 0; - - for(int ii = 0; ii < bindValues.count(); ++ii) - clear(bindValues[ii]); - for(int ii = 0; ii < parserStatus.count(); ++ii) - clear(parserStatus[ii]); - for(QHash<int, QmlCompiledData*>::ConstIterator iter = m_compositeTypes.constBegin(); iter != m_compositeTypes.constEnd(); ++iter) - (*iter)->release(); - for(QHash<const QMetaObject *, QmlPropertyCache *>::Iterator iter = propertyCache.begin(); iter != propertyCache.end(); ++iter) - (*iter)->release(); - -} - -void QmlEnginePrivate::clear(SimpleList<QmlAbstractBinding> &bvs) -{ - bvs.clear(); -} - -void QmlEnginePrivate::clear(SimpleList<QmlParserStatus> &pss) -{ - for (int ii = 0; ii < pss.count; ++ii) { - QmlParserStatus *ps = pss.at(ii); - if(ps) - ps->d = 0; - } - pss.clear(); -} - -Q_GLOBAL_STATIC(QmlEngineDebugServer, qmlEngineDebugServer); - -void QmlEnginePrivate::init() -{ - Q_Q(QmlEngine); - qRegisterMetaType<QVariant>("QVariant"); - qRegisterMetaType<QmlScriptString>("QmlScriptString"); - qRegisterMetaType<QScriptValue>("QScriptValue"); - - contextClass = new QmlContextScriptClass(q); - objectClass = new QmlObjectScriptClass(q); - valueTypeClass = new QmlValueTypeScriptClass(q); - typeNameClass = new QmlTypeNameScriptClass(q); - listClass = new QmlListScriptClass(q); - rootContext = new QmlContext(q,true); - - if (QCoreApplication::instance()->thread() == q->thread() && - QmlEngineDebugServer::isDebuggingEnabled()) { - qmlEngineDebugServer(); - isDebugging = true; - QmlEngineDebugServer::addEngine(q); - - qmlEngineDebugServer()->waitForClients(); - } -} - -QmlWorkerScriptEngine *QmlEnginePrivate::getWorkerScriptEngine() -{ - Q_Q(QmlEngine); - if (!workerScriptEngine) - workerScriptEngine = new QmlWorkerScriptEngine(q); - return workerScriptEngine; -} - -/*! - \class QmlEngine - \since 4.7 - \brief The QmlEngine class provides an environment for instantiating QML components. - \mainclass - - Each QML component is instantiated in a QmlContext. QmlContext's are - essential for passing data to QML components. In QML, contexts are arranged - hierarchically and this hierarchy is managed by the QmlEngine. - - Prior to creating any QML components, an application must have created a - QmlEngine to gain access to a QML context. The following example shows how - to create a simple Text item. - - \code - QmlEngine engine; - QmlComponent component(&engine); - component.setData("import Qt 4.6\nText { text: \"Hello world!\" }", QUrl()); - QmlGraphicsItem *item = qobject_cast<QmlGraphicsItem *>(component.create()); - - //add item to view, etc - ... - \endcode - - In this case, the Text item will be created in the engine's - \l {QmlEngine::rootContext()}{root context}. - - \sa QmlComponent QmlContext -*/ - -/*! - Create a new QmlEngine with the given \a parent. -*/ -QmlEngine::QmlEngine(QObject *parent) -: QObject(*new QmlEnginePrivate(this), parent) -{ - Q_D(QmlEngine); - d->init(); -} - -/*! - Destroys the QmlEngine. - - Any QmlContext's created on this engine will be invalidated, but not - destroyed (unless they are parented to the QmlEngine object). -*/ -QmlEngine::~QmlEngine() -{ - Q_D(QmlEngine); - if (d->isDebugging) - QmlEngineDebugServer::remEngine(this); -} - -/*! \fn void QmlEngine::quit() - This signal is emitted when the QmlEngine quits. - */ - -/*! - Clears the engine's internal component cache. - - Normally the QmlEngine caches components loaded from qml files. This method - clears this cache and forces the component to be reloaded. - */ -void QmlEngine::clearComponentCache() -{ - Q_D(QmlEngine); - d->typeManager.clearCache(); -} - -/*! - Returns the engine's root context. - - The root context is automatically created by the QmlEngine. Data that - should be available to all QML component instances instantiated by the - engine should be put in the root context. - - Additional data that should only be available to a subset of component - instances should be added to sub-contexts parented to the root context. -*/ -QmlContext *QmlEngine::rootContext() -{ - Q_D(QmlEngine); - return d->rootContext; -} - -/*! - Sets the \a factory to use for creating QNetworkAccessManager(s). - - QNetworkAccessManager is used for all network access by QML. - By implementing a factory it is possible to create custom - QNetworkAccessManager with specialized caching, proxy and - cookie support. - - The factory must be set before exceuting the engine. -*/ -void QmlEngine::setNetworkAccessManagerFactory(QmlNetworkAccessManagerFactory *factory) -{ - Q_D(QmlEngine); - QMutexLocker locker(&d->mutex); - d->networkAccessManagerFactory = factory; -} - -/*! - Returns the current QmlNetworkAccessManagerFactory. - - \sa setNetworkAccessManagerFactory() -*/ -QmlNetworkAccessManagerFactory *QmlEngine::networkAccessManagerFactory() const -{ - Q_D(const QmlEngine); - return d->networkAccessManagerFactory; -} - -QNetworkAccessManager *QmlEnginePrivate::createNetworkAccessManager(QObject *parent) const -{ - QMutexLocker locker(&mutex); - QNetworkAccessManager *nam; - if (networkAccessManagerFactory) { - nam = networkAccessManagerFactory->create(parent); - } else { - nam = new QNetworkAccessManager(parent); - } - - return nam; -} - -QNetworkAccessManager *QmlEnginePrivate::getNetworkAccessManager() const -{ - Q_Q(const QmlEngine); - if (!networkAccessManager) - networkAccessManager = createNetworkAccessManager(const_cast<QmlEngine*>(q)); - return networkAccessManager; -} - -/*! - Returns a common QNetworkAccessManager which can be used by any QML element - instantiated by this engine. - - If a QmlNetworkAccessManagerFactory has been set and a QNetworkAccessManager - has not yet been created, the QmlNetworkAccessManagerFactory will be used - to create the QNetworkAccessManager; otherwise the returned QNetworkAccessManager - will have no proxy or cache set. - - \sa setNetworkAccessManagerFactory() -*/ -QNetworkAccessManager *QmlEngine::networkAccessManager() const -{ - Q_D(const QmlEngine); - return d->getNetworkAccessManager(); -} - -/*! - Sets the \a provider to use for images requested via the \e image: url - scheme, with host \a providerId. - - QmlImageProvider allows images to be provided to QML asynchronously. - The image request will be run in a low priority thread. This allows - potentially costly image loading to be done in the background, without - affecting the performance of the UI. - - Note that images loaded from a QmlImageProvider are cached by - QPixmapCache, similar to any image loaded by QML. - - The QmlEngine assumes ownership of the provider. - - This example creates a provider with id \e colors: - - \snippet examples/declarative/imageprovider/main.cpp 0 - - \snippet examples/declarative/imageprovider/view.qml 0 - - \sa removeImageProvider() -*/ -void QmlEngine::addImageProvider(const QString &providerId, QmlImageProvider *provider) -{ - Q_D(QmlEngine); - QMutexLocker locker(&d->mutex); - d->imageProviders.insert(providerId, provider); -} - -/*! - Returns the QmlImageProvider set for \a providerId. -*/ -QmlImageProvider *QmlEngine::imageProvider(const QString &providerId) const -{ - Q_D(const QmlEngine); - QMutexLocker locker(&d->mutex); - return d->imageProviders.value(providerId); -} - -/*! - Removes the QmlImageProvider for \a providerId. - - Returns the provider if it was found; otherwise returns 0. - - \sa addImageProvider() -*/ -void QmlEngine::removeImageProvider(const QString &providerId) -{ - Q_D(QmlEngine); - QMutexLocker locker(&d->mutex); - delete d->imageProviders.take(providerId); -} - -QImage QmlEnginePrivate::getImageFromProvider(const QUrl &url) -{ - QMutexLocker locker(&mutex); - QImage image; - QmlImageProvider *provider = imageProviders.value(url.host()); - if (provider) - image = provider->request(url.path().mid(1)); - return image; -} - -/*! - Return the base URL for this engine. The base URL is only used to resolve - components when a relative URL is passed to the QmlComponent constructor. - - If a base URL has not been explicitly set, this method returns the - application's current working directory. - - \sa setBaseUrl() -*/ -QUrl QmlEngine::baseUrl() const -{ - Q_D(const QmlEngine); - if (d->baseUrl.isEmpty()) { - return QUrl::fromLocalFile(QDir::currentPath() + QDir::separator()); - } else { - return d->baseUrl; - } -} - -/*! - Set the base URL for this engine to \a url. - - \sa baseUrl() -*/ -void QmlEngine::setBaseUrl(const QUrl &url) -{ - Q_D(QmlEngine); - d->baseUrl = url; -} - -/*! - Returns the QmlContext for the \a object, or 0 if no context has been set. - - When the QmlEngine instantiates a QObject, the context is set automatically. - */ -QmlContext *QmlEngine::contextForObject(const QObject *object) -{ - if(!object) - return 0; - - QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object)); - - QmlDeclarativeData *data = - static_cast<QmlDeclarativeData *>(priv->declarativeData); - - if (!data) - return 0; - else if (data->outerContext) - return data->outerContext; - else - return data->context; -} - -/*! - Sets the QmlContext for the \a object to \a context. - If the \a object already has a context, a warning is - output, but the context is not changed. - - When the QmlEngine instantiates a QObject, the context is set automatically. - */ -void QmlEngine::setContextForObject(QObject *object, QmlContext *context) -{ - if (!object || !context) - return; - - QmlDeclarativeData *data = QmlDeclarativeData::get(object, true); - if (data->context) { - qWarning("QmlEngine::setContextForObject(): Object already has a QmlContext"); - return; - } - - data->context = context; - data->nextContextObject = context->d_func()->contextObjects; - if (data->nextContextObject) - data->nextContextObject->prevContextObject = &data->nextContextObject; - data->prevContextObject = &context->d_func()->contextObjects; - context->d_func()->contextObjects = data; -} - -void qmlExecuteDeferred(QObject *object) -{ - QmlDeclarativeData *data = QmlDeclarativeData::get(object); - - if (data && data->deferredComponent) { - - QmlEnginePrivate *ep = QmlEnginePrivate::get(data->context->engine()); - - QmlComponentPrivate::ConstructionState state; - QmlComponentPrivate::beginDeferred(data->context, ep, object, &state); - - data->deferredComponent->release(); - data->deferredComponent = 0; - - QmlComponentPrivate::complete(ep, &state); - - if (!state.errors.isEmpty()) - qWarning() << state.errors; - - } -} - -QmlContext *qmlContext(const QObject *obj) -{ - return QmlEngine::contextForObject(obj); -} - -QmlEngine *qmlEngine(const QObject *obj) -{ - QmlContext *context = QmlEngine::contextForObject(obj); - return context?context->engine():0; -} - -QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) -{ - QmlDeclarativeData *data = QmlDeclarativeData::get(object); - if (!data) - return 0; // Attached properties are only on objects created by QML - - QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0; - if (rv || !create) - return rv; - - QmlAttachedPropertiesFunc pf = QmlMetaType::attachedPropertiesFuncById(id); - if (!pf) - return 0; - - rv = pf(const_cast<QObject *>(object)); - - if (rv) { - if (!data->attachedProperties) - data->attachedProperties = new QHash<int, QObject *>(); - data->attachedProperties->insert(id, rv); - } - - return rv; -} - -void QmlDeclarativeData::destroyed(QObject *object) -{ - if (deferredComponent) - deferredComponent->release(); - if (attachedProperties) - delete attachedProperties; - - if (nextContextObject) - nextContextObject->prevContextObject = prevContextObject; - if (prevContextObject) - *prevContextObject = nextContextObject; - - QmlAbstractBinding *binding = bindings; - while (binding) { - QmlAbstractBinding *next = binding->m_nextBinding; - binding->m_prevBinding = 0; - binding->m_nextBinding = 0; - binding->destroy(); - binding = next; - } - - if (bindingBits) - free(bindingBits); - - if (propertyCache) - propertyCache->release(); - - QmlGuard<QObject> *guard = guards; - while (guard) { - QmlGuard<QObject> *g = guard; - guard = guard->next; - g->o = 0; - g->prev = 0; - g->next = 0; - g->objectDestroyed(object); - } - - delete this; -} - -bool QmlDeclarativeData::hasBindingBit(int bit) const -{ - if (bindingBitsSize > bit) - return bindingBits[bit / 32] & (1 << (bit % 32)); - else - return false; -} - -void QmlDeclarativeData::clearBindingBit(int bit) -{ - if (bindingBitsSize > bit) - bindingBits[bit / 32] &= ~(1 << (bit % 32)); -} - -void QmlDeclarativeData::setBindingBit(QObject *obj, int bit) -{ - if (bindingBitsSize <= bit) { - int props = obj->metaObject()->propertyCount(); - Q_ASSERT(bit < props); - - int arraySize = (props + 31) / 32; - int oldArraySize = bindingBitsSize / 32; - - bindingBits = (quint32 *)realloc(bindingBits, - arraySize * sizeof(quint32)); - - memset(bindingBits + oldArraySize, - 0x00, - sizeof(quint32) * (arraySize - oldArraySize)); - - bindingBitsSize = arraySize * 32; - } - - bindingBits[bit / 32] |= (1 << (bit % 32)); -} - -/*! - Creates a QScriptValue allowing you to use \a object in QML script. - \a engine is the QmlEngine it is to be created in. - - The QScriptValue returned is a QtScript Object, not a QtScript QObject, due - to the special needs of QML requiring more functionality than a standard - QtScript QObject. -*/ -QScriptValue QmlEnginePrivate::qmlScriptObject(QObject* object, - QmlEngine* engine) -{ - QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); - return enginePriv->objectClass->newQObject(object); -} - -/*! - Returns the QmlContext for the executing QScript \a ctxt. -*/ -QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt) -{ - QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); - Q_ASSERT(scopeNode.isValid()); - Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass); - return contextClass->contextFromValue(scopeNode); -} - -QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt, - QScriptEngine *engine) -{ - QmlEnginePrivate *activeEnginePriv = - static_cast<QmlScriptEngine*>(engine)->p; - QmlEngine* activeEngine = activeEnginePriv->q_func(); - - QmlContext* context = activeEnginePriv->getContext(ctxt); - Q_ASSERT(context); - if(ctxt->argumentCount() != 1) { - return engine->nullValue(); - }else{ - QString arg = ctxt->argument(0).toString(); - if (arg.isEmpty()) - return engine->nullValue(); - QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); - QmlComponent *c = new QmlComponent(activeEngine, url, activeEngine); - c->setCreationContext(context); - return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QmlComponent*>()); - } -} - -QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine) -{ - QmlEnginePrivate *activeEnginePriv = - static_cast<QmlScriptEngine*>(engine)->p; - QmlEngine* activeEngine = activeEnginePriv->q_func(); - - if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) - return engine->nullValue(); - - QmlContext* context = activeEnginePriv->getContext(ctxt); - Q_ASSERT(context); - - QString qml = ctxt->argument(0).toString(); - if (qml.isEmpty()) - return engine->nullValue(); - - QUrl url; - if(ctxt->argumentCount() > 2) - url = QUrl(ctxt->argument(2).toString()); - else - url = QUrl(QLatin1String("inline")); - - if (url.isValid() && url.isRelative()) - url = context->resolvedUrl(url); - - QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1)); - if(!parentArg) - return engine->nullValue(); - - QmlComponent component(activeEngine); - component.setData(qml.toUtf8(), url); - - if(component.isError()) { - QList<QmlError> errors = component.errors(); - qWarning().nospace() << "QmlEngine::createQmlObject():"; - foreach (const QmlError &error, errors) - qWarning().nospace() << " " << error; - - return engine->nullValue(); - } - - if (!component.isReady()) { - qWarning().nospace() << "QmlEngine::createQmlObject(): Component is not ready"; - - return engine->nullValue(); - } - - QObject *obj = component.create(context); - - if(component.isError()) { - QList<QmlError> errors = component.errors(); - qWarning().nospace() << "QmlEngine::createQmlObject():"; - foreach (const QmlError &error, errors) - qWarning().nospace() << " " << error; - - return engine->nullValue(); - } - - Q_ASSERT(obj); - - obj->setParent(parentArg); - QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj); - QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parentArg); - if(gobj && gparent) - gobj->setParentItem(gparent); - - return qmlScriptObject(obj, activeEngine); -} - -QScriptValue QmlEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 3) - return engine->nullValue(); - qsreal x = ctxt->argument(0).toNumber(); - qsreal y = ctxt->argument(1).toNumber(); - qsreal z = ctxt->argument(2).toNumber(); - return engine->newVariant(qVariantFromValue(QVector3D(x, y, z))); -} - -QScriptValue QmlEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine) -{ - int argCount = ctxt->argumentCount(); - if(argCount < 3 || argCount > 4) - return engine->nullValue(); - qsreal r = ctxt->argument(0).toNumber(); - qsreal g = ctxt->argument(1).toNumber(); - qsreal b = ctxt->argument(2).toNumber(); - qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1; - - if (r < 0 || r > 1 || g < 0 || g > 1 || b < 0 || b > 1 || a < 0 || a > 1) - return engine->nullValue(); - - return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a))); -} - -QScriptValue QmlEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine) -{ - int argCount = ctxt->argumentCount(); - if(argCount < 3 || argCount > 4) - return engine->nullValue(); - qsreal h = ctxt->argument(0).toNumber(); - qsreal s = ctxt->argument(1).toNumber(); - qsreal l = ctxt->argument(2).toNumber(); - qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1; - - if (h < 0 || h > 1 || s < 0 || s > 1 || l < 0 || l > 1 || a < 0 || a > 1) - return engine->nullValue(); - - return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a))); -} - -QScriptValue QmlEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 4) - return engine->nullValue(); - - qsreal x = ctxt->argument(0).toNumber(); - qsreal y = ctxt->argument(1).toNumber(); - qsreal w = ctxt->argument(2).toNumber(); - qsreal h = ctxt->argument(3).toNumber(); - - if (w < 0 || h < 0) - return engine->nullValue(); - - return qScriptValueFromValue(engine, qVariantFromValue(QRectF(x, y, w, h))); -} - -QScriptValue QmlEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 2) - return engine->nullValue(); - qsreal x = ctxt->argument(0).toNumber(); - qsreal y = ctxt->argument(1).toNumber(); - return qScriptValueFromValue(engine, qVariantFromValue(QPointF(x, y))); -} - -QScriptValue QmlEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 2) - return engine->nullValue(); - qsreal w = ctxt->argument(0).toNumber(); - qsreal h = ctxt->argument(1).toNumber(); - return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); -} - -QScriptValue QmlEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 1) - return engine->nullValue(); - QVariant v = ctxt->argument(0).toVariant(); - QColor color; - if (v.userType() == QVariant::Color) - color = v.value<QColor>(); - else if (v.userType() == QVariant::String) { - bool ok; - color = QmlStringConverters::colorFromString(v.toString(), &ok); - if (!ok) - return engine->nullValue(); - } else - return engine->nullValue(); - color = color.lighter(); - return qScriptValueFromValue(engine, qVariantFromValue(color)); -} - -QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 1) - return engine->nullValue(); - QVariant v = ctxt->argument(0).toVariant(); - QColor color; - if (v.userType() == QVariant::Color) - color = v.value<QColor>(); - else if (v.userType() == QVariant::String) { - bool ok; - color = QmlStringConverters::colorFromString(v.toString(), &ok); - if (!ok) - return engine->nullValue(); - } else - return engine->nullValue(); - color = color.darker(); - return qScriptValueFromValue(engine, qVariantFromValue(color)); -} - -QScriptValue QmlEnginePrivate::playSound(QScriptContext *ctxt, QScriptEngine *engine) -{ - if (ctxt->argumentCount() != 1) - return engine->undefinedValue(); - - QUrl url(ctxt->argument(0).toString()); - - QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); - if (url.isRelative()) { - QmlContext *context = enginePriv->getContext(ctxt); - if (!context) - return engine->undefinedValue(); - - url = context->resolvedUrl(url); - } - - if (url.scheme() == QLatin1String("file")) { - - QSound::play(url.toLocalFile()); - - } - return engine->undefinedValue(); -} - -QScriptValue QmlEnginePrivate::desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e) -{ - if(ctxt->argumentCount() < 1) - return e->newVariant(QVariant(false)); - bool ret = QDesktopServices::openUrl(QUrl(ctxt->argument(0).toString())); - return e->newVariant(QVariant(ret)); -} - -QScriptValue QmlEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *) -{ - QByteArray data; - - if (ctxt->argumentCount() >= 1) - data = ctxt->argument(0).toString().toUtf8(); - - QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5); - - return QScriptValue(QLatin1String(result.toHex())); -} - -QScriptValue QmlEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *) -{ - QByteArray data; - - if (ctxt->argumentCount() >= 1) - data = ctxt->argument(0).toString().toUtf8(); - - return QScriptValue(QLatin1String(data.toBase64())); -} - -QScriptValue QmlEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *) -{ - QByteArray data; - - if (ctxt->argumentCount() >= 1) - data = ctxt->argument(0).toString().toUtf8(); - - return QScriptValue(QLatin1String(QByteArray::fromBase64(data))); -} - -QScriptValue QmlEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e) -{ - if(ctxt->argumentCount() < 1) - return e->newVariant(QVariant(false)); - - QByteArray msg; - - for (int i=0; i<ctxt->argumentCount(); ++i) { - if (!msg.isEmpty()) msg += ' '; - msg += ctxt->argument(i).toString().toLocal8Bit(); - // does not support firebug "%[a-z]" formatting, since firebug really - // does just ignore the format letter, which makes it pointless. - } - - qDebug("%s",msg.constData()); - - return e->newVariant(QVariant(true)); -} - -void QmlEnginePrivate::sendQuit () -{ - Q_Q(QmlEngine); - emit q->quit(); -} - -QScriptValue QmlEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e) -{ - QmlEnginePrivate *qe = get (e); - qe->sendQuit (); - return QScriptValue(); -} - -QScriptValue QmlEnginePrivate::closestAngle(QScriptContext *ctxt, QScriptEngine *e) -{ - if(ctxt->argumentCount() < 2) - return e->newVariant(QVariant(0.0)); - qreal a = ctxt->argument(0).toNumber(); - qreal b = ctxt->argument(1).toNumber(); - qreal ret = b; - qreal diff = b-a; - while(diff > 180.0){ - ret -= 360.0; - diff -= 360.0; - } - while(diff < -180.0){ - ret += 360.0; - diff += 360.0; - } - return e->newVariant(QVariant(ret)); -} - -QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) -{ - if(ctxt->argumentCount() != 2) - return engine->nullValue(); - //get color - QVariant v = ctxt->argument(0).toVariant(); - QColor color; - if (v.userType() == QVariant::Color) - color = v.value<QColor>(); - else if (v.userType() == QVariant::String) { - bool ok; - color = QmlStringConverters::colorFromString(v.toString(), &ok); - if (!ok) - return engine->nullValue(); - } else - return engine->nullValue(); - - //get tint color - v = ctxt->argument(1).toVariant(); - QColor tintColor; - if (v.userType() == QVariant::Color) - tintColor = v.value<QColor>(); - else if (v.userType() == QVariant::String) { - bool ok; - tintColor = QmlStringConverters::colorFromString(v.toString(), &ok); - if (!ok) - return engine->nullValue(); - } else - return engine->nullValue(); - - //tint - QColor finalColor; - int a = tintColor.alpha(); - if (a == 0xFF) - finalColor = tintColor; - else if (a == 0x00) - finalColor = color; - else { - uint src = tintColor.rgba(); - uint dest = color.rgba(); - - uint res = (((a * (src & 0xFF00FF)) + - ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; - res |= (((a * ((src >> 8) & 0xFF00FF)) + - ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; - if ((src & 0xFF000000) == 0xFF000000) - res |= 0xFF000000; - - finalColor = QColor::fromRgba(res); - } - - return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); -} - - -QScriptValue QmlEnginePrivate::scriptValueFromVariant(const QVariant &val) -{ - if (val.userType() == qMetaTypeId<QmlListReference>()) { - QmlListReferencePrivate *p = QmlListReferencePrivate::get((QmlListReference*)val.constData()); - if (p->object) { - return listClass->newList(p->property, p->propertyType); - } else { - return scriptEngine.nullValue(); - } - } - - bool objOk; - QObject *obj = QmlMetaType::toQObject(val, &objOk); - if (objOk) { - return objectClass->newQObject(obj); - } else { - return qScriptValueFromValue(&scriptEngine, val); - } -} - -QVariant QmlEnginePrivate::scriptValueToVariant(const QScriptValue &val) -{ - QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val); - if (dc == objectClass) - return QVariant::fromValue(objectClass->toQObject(val)); - else if (dc == contextClass) - return QVariant(); - - QScriptDeclarativeClass *sc = QScriptDeclarativeClass::scriptClass(val); - if (!sc) { - return val.toVariant(); - } else if (sc == valueTypeClass) { - return valueTypeClass->toVariant(val); - } else { - return QVariant(); - } -} - -QmlScriptClass::QmlScriptClass(QScriptEngine *engine) -: QScriptDeclarativeClass(engine) -{ -} - -QVariant QmlScriptClass::toVariant(QmlEngine *engine, const QScriptValue &val) -{ - QmlEnginePrivate *ep = - static_cast<QmlEnginePrivate *>(QObjectPrivate::get(engine)); - - return ep->scriptValueToVariant(val); -} - -// XXX this beyonds in QUrl::toLocalFile() -static QString toLocalFileOrQrc(const QUrl& url) -{ - QString r = url.toLocalFile(); - if (r.isEmpty() && url.scheme() == QLatin1String("qrc")) - r = QLatin1Char(':') + url.path(); - return r; -} - -///////////////////////////////////////////////////////////// -struct QmlEnginePrivate::ImportedNamespace { - QStringList uris; - QStringList urls; - QList<int> majversions; - QList<int> minversions; - QList<bool> isLibrary; - QList<QString> qmlDirContent; - - bool find(const QByteArray& type, int *vmajor, int *vminor, QmlType** type_return, QUrl* url_return) const - { - for (int i=0; i<urls.count(); ++i) { - int vmaj = majversions.at(i); - int vmin = minversions.at(i); - - QByteArray qt = uris.at(i).toUtf8(); - qt += '/'; - qt += type; - - if (qmlImportTrace()) - qDebug() << "Look in" << qt; - QmlType *t = QmlMetaType::qmlType(qt,vmaj,vmin); - if (t) { - if (vmajor) *vmajor = vmaj; - if (vminor) *vminor = vmin; - if (qmlImportTrace()) - qDebug() << "Found" << qt; - if (type_return) - *type_return = t; - return true; - } - - QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); - QString qmldircontent = qmlDirContent.at(i); - if (vmaj>=0 || !qmldircontent.isEmpty()) { - // Check version file - XXX cache these in QmlEngine! - if (qmldircontent.isEmpty()) { - QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir")))); - if (qmldir.open(QIODevice::ReadOnly)) { - qmldircontent = QString::fromUtf8(qmldir.readAll()); - } - } - - const QString typeName = QString::fromUtf8(type); - - QmlDirParser qmldirParser; - qmldirParser.setUrl(url); - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); - - foreach (const QmlDirParser::Component &c, qmldirParser.components()) { // ### TODO: cache the components - if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { - if (c.typeName == typeName) { - if (url_return) - *url_return = url.resolved(QUrl(c.fileName)); - - return true; - } - } - } - - } else { - // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(toLocalFileOrQrc(url)); - if (f.exists()) { - if (url_return) - *url_return = url; - return true; - } - } - } - return false; - } -}; - -class QmlImportsPrivate { -public: - QmlImportsPrivate() : ref(1) - { - } - - ~QmlImportsPrivate() - { - foreach (QmlEnginePrivate::ImportedNamespace* s, set.values()) - delete s; - } - - QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; - - bool add(const QUrl& base, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType, const QStringList& importPath, QmlEngine *engine) - { - QmlEnginePrivate::ImportedNamespace *s; - if (prefix.isEmpty()) { - s = &unqualifiedset; - } else { - s = set.value(prefix); - if (!s) - set.insert(prefix,(s=new QmlEnginePrivate::ImportedNamespace)); - } - QString url = uri; - if (importType == QmlScriptParser::Import::Library) { - url.replace(QLatin1Char('.'), QLatin1Char('/')); - bool found = false; - QString content; - QString dir; - - // user import paths - QStringList paths; - - // base.. - paths += QFileInfo(base.toLocalFile()).path(); - paths += importPath; - paths += QmlEnginePrivate::get(engine)->environmentImportPath; - - foreach (const QString &p, paths) { - dir = p+QLatin1Char('/')+url; - QFileInfo fi(dir+QLatin1String("/qmldir")); - const QString absoluteFilePath = fi.absoluteFilePath(); - - if (fi.isFile()) { - found = true; - - url = QUrl::fromLocalFile(fi.absolutePath()).toString(); - - QFile file(absoluteFilePath); - if (file.open(QFile::ReadOnly)) - content = QString::fromUtf8(file.readAll()); - - if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { - qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - - QmlDirParser qmldirParser; - qmldirParser.setSource(content); - qmldirParser.parse(); - - foreach (const QmlDirParser::Plugin &plugin, qmldirParser.plugins()) { - QString resolvedFilePath = QmlEnginePrivate::get(engine)->resolvePlugin(dir + QDir::separator() + plugin.path, - plugin.name); - - if (!resolvedFilePath.isEmpty()) - engine->importExtension(resolvedFilePath, uri); - } - } - - break; - } - } - - } else { - url = base.resolved(QUrl(url)).toString(); - } - - s->uris.prepend(uri); - s->urls.prepend(url); - s->majversions.prepend(vmaj); - s->minversions.prepend(vmin); - s->isLibrary.prepend(importType == QmlScriptParser::Import::Library); - s->qmlDirContent.prepend(qmldircontent); - return true; - } - - bool find(const QByteArray& type, int *vmajor, int *vminor, QmlType** type_return, QUrl* url_return) - { - QmlEnginePrivate::ImportedNamespace *s = 0; - int slash = type.indexOf('/'); - if (slash >= 0) { - s = set.value(QString::fromUtf8(type.left(slash))); - if (!s) - return false; // qualifier must be a namespace - int nslash = type.indexOf('/',slash+1); - if (nslash > 0) - return false; // only single qualification allowed - } else { - s = &unqualifiedset; - } - QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) - if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) - return true; - if (s->urls.count() == 1 && !s->isLibrary[0] && url_return) { - *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml"))); - return true; - } - - } - if (url_return) { - *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); - return true; - } else { - return false; - } - } - - QmlEnginePrivate::ImportedNamespace *findNamespace(const QString& type) - { - return set.value(type); - } - - QUrl base; - int ref; - -private: - friend struct QmlEnginePrivate::Imports; - QmlEnginePrivate::ImportedNamespace unqualifiedset; - QHash<QString,QmlEnginePrivate::ImportedNamespace* > set; -}; - -QmlEnginePrivate::Imports::Imports(const Imports ©) : - d(copy.d) -{ - ++d->ref; -} - -QmlEnginePrivate::Imports &QmlEnginePrivate::Imports::operator =(const Imports ©) -{ - ++copy.d->ref; - if (--d->ref == 0) - delete d; - d = copy.d; - return *this; -} - -QmlEnginePrivate::Imports::Imports() : - d(new QmlImportsPrivate) -{ -} - -QmlEnginePrivate::Imports::~Imports() -{ - if (--d->ref == 0) - delete d; -} - -#include "qmlmetatype.h" -#include "qmltypenamecache_p.h" - -static QmlTypeNameCache *cacheForNamespace(QmlEngine *engine, const QmlEnginePrivate::ImportedNamespace &set, QmlTypeNameCache *cache) -{ - if (!cache) - cache = new QmlTypeNameCache(engine); - - QList<QmlType *> types = QmlMetaType::qmlTypes(); - - for (int ii = 0; ii < set.uris.count(); ++ii) { - QByteArray base = set.uris.at(ii).toUtf8() + '/'; - int major = set.majversions.at(ii); - int minor = set.minversions.at(ii); - - foreach (QmlType *type, types) { - if (type->qmlTypeName().startsWith(base) && - type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) && - type->availableInVersion(major,minor)) - { - QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length())); - - cache->add(name, type); - } - } - } - - return cache; -} - -QmlTypeNameCache *QmlEnginePrivate::Imports::cache(QmlEngine *engine) const -{ - const QmlEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - - QmlTypeNameCache *cache = new QmlTypeNameCache(engine); - - for (QHash<QString,QmlEnginePrivate::ImportedNamespace* >::ConstIterator iter = d->set.begin(); - iter != d->set.end(); ++iter) { - - QmlTypeNameCache::Data *d = cache->data(iter.key()); - if (d) { - if (!d->typeNamespace) - cacheForNamespace(engine, *(*iter), d->typeNamespace); - } else { - QmlTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0); - cache->add(iter.key(), nc); - nc->release(); - } - } - - cacheForNamespace(engine, set, cache); - - return cache; -} - -/* -QStringList QmlEnginePrivate::Imports::unqualifiedSet() const -{ - QStringList rv; - - const QmlEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - - for (int ii = 0; ii < set.urls.count(); ++ii) { - if (set.isBuiltin.at(ii)) - rv << set.urls.at(ii); - } - - return rv; -} -*/ - -/*! - Sets the base URL to be used for all relative file imports added. -*/ -void QmlEnginePrivate::Imports::setBaseUrl(const QUrl& url) -{ - d->base = url; -} - -/*! - Returns the base URL to be used for all relative file imports added. -*/ -QUrl QmlEnginePrivate::Imports::baseUrl() const -{ - return d->base; -} - -/*! - Adds \a path as a directory where installed QML components are - defined in a URL-based directory structure. - - For example, if you add \c /opt/MyApp/lib/qml and then load QML - that imports \c com.mycompany.Feature, then QmlEngine will look - in \c /opt/MyApp/lib/qml/com/mycompany/Feature/ for the components - provided by that module (and in the case of versioned imports, - for the \c qmldir file definiting the type version mapping. - - By default, only the "qml" subdirectory of QLibraryInfo::location(QLibraryInfo::DataPath) - is included on the import path. -*/ -void QmlEngine::addImportPath(const QString& path) -{ - if (qmlImportTrace()) - qDebug() << "QmlEngine::addImportPath" << path; - Q_D(QmlEngine); - d->fileImportPath.prepend(path); -} - -/*! - Imports the given \a extension into this QmlEngine. Returns - true if the extension was successfully imported. - - \sa QmlExtensionInterface -*/ -bool QmlEngine::importExtension(const QString &fileName, const QString &uri) -{ - QPluginLoader loader(fileName); - - if (QmlExtensionInterface *iface = qobject_cast<QmlExtensionInterface *>(loader.instance())) { - iface->initialize(this, uri.toUtf8().constData()); - return true; - } - - return false; -} - -/*! - \property QmlEngine::offlineStoragePath - \brief the directory for storing offline user data - - Returns the directory where SQL and other offline - storage is placed. - - QmlGraphicsWebView and the SQL databases created with openDatabase() - are stored here. - - The default is QML/OfflineStorage in the platform-standard - user application data directory. - - Note that the path may not currently exist on the filesystem, so - callers wanting to \e create new files at this location should create - it first - see QDir::mkpath(). -*/ -void QmlEngine::setOfflineStoragePath(const QString& dir) -{ - Q_D(QmlEngine); - d->scriptEngine.offlineStoragePath = dir; -} - -QString QmlEngine::offlineStoragePath() const -{ - Q_D(const QmlEngine); - return d->scriptEngine.offlineStoragePath; -} - -/*! - \internal - - Returns the result of the merge of \a baseName with \a dir, \a suffixes, and \a prefix. - */ -QString QmlEnginePrivate::resolvePlugin(const QDir &dir, const QString &baseName, - const QStringList &suffixes, - const QString &prefix) -{ - foreach (const QString &suffix, suffixes) { - QString pluginFileName = prefix; - - pluginFileName += baseName; - pluginFileName += QLatin1Char('.'); - pluginFileName += suffix; - - QFileInfo fileInfo(dir, pluginFileName); - - if (fileInfo.exists()) - return fileInfo.absoluteFilePath(); - } - - return QString(); -} - -/*! - \internal - - Returns the result of the merge of \a baseName with \a dir and the platform suffix. - - \table - \header \i Platform \i Valid suffixes - \row \i Windows \i \c .dll - \row \i Unix/Linux \i \c .so - \row \i AIX \i \c .a - \row \i HP-UX \i \c .sl, \c .so (HP-UXi) - \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so - \row \i Symbian \i \c .dll - \endtable - - Version number on unix are ignored. -*/ -QString QmlEnginePrivate::resolvePlugin(const QDir &dir, const QString &baseName) -{ -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) - return resolvePlugin(dir, baseName, QStringList(QLatin1String("dll"))); -#elif defined(Q_OS_SYMBIAN) - return resolvePlugin(dir, baseName, QStringList() << QLatin1String("dll") << QLatin1String("qtplugin")); -#else - -# if defined(Q_OS_DARWIN) - - return resolvePlugin(dir, baseName, QStringList() << QLatin1String("dylib") << QLatin1String("so") << QLatin1String("bundle"), - QLatin1String("lib")); -# else // Generic Unix - QStringList validSuffixList; - -# if defined(Q_OS_HPUX) -/* - See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": - "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), - the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." - */ - validSuffixList << QLatin1String("sl"); -# if defined __ia64 - validSuffixList << QLatin1String("so"); -# endif -# elif defined(Q_OS_AIX) - validSuffixList << QLatin1String("a") << QLatin1String("so"); -# elif defined(Q_OS_UNIX) - validSuffixList << QLatin1String("so"); -# endif - - // Examples of valid library names: - // libfoo.so - - return resolvePlugin(dir, baseName, validSuffixList, QLatin1String("lib")); -# endif - -#endif -} - -/*! - \internal - - Adds information to \a imports such that subsequent calls to resolveType() - will resolve types qualified by \a prefix by considering types found at the given \a uri. - - The uri is either a directory (if importType is FileImport), or a URI resolved using paths - added via addImportPath() (if importType is LibraryImport). - - The \a prefix may be empty, in which case the import location is considered for - unqualified types. - - The base URL must already have been set with Import::setBaseUrl(). -*/ -bool QmlEnginePrivate::addToImport(Imports* imports, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const -{ - QmlEngine *engine = QmlEnginePrivate::get(const_cast<QmlEnginePrivate *>(this)); - bool ok = imports->d->add(imports->d->base,qmldircontent,uri,prefix,vmaj,vmin,importType,fileImportPath, engine); - if (qmlImportTrace()) - qDebug() << "QmlEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QmlScriptParser::Import::Library? "Library" : "File") << ": " << ok; - return ok; -} - -/*! - \internal - - Using the given \a imports, the given (namespace qualified) \a type is resolved to either - an ImportedNamespace stored at \a ns_return, - a QmlType stored at \a type_return, or - a component located at \a url_return. - - If any return pointer is 0, the corresponding search is not done. - - \sa addToImport() -*/ -bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin, ImportedNamespace** ns_return) const -{ - ImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type)); - if (ns) { - if (qmlImportTrace()) - qDebug() << "QmlEngine::resolveType" << type << "is namespace for" << ns->urls; - if (ns_return) - *ns_return = ns; - return true; - } - if (type_return || url_return) { - if (imports.d->find(type,vmaj,vmin,type_return,url_return)) { - if (qmlImportTrace()) { - if (type_return && *type_return) - qDebug() << "QmlEngine::resolveType" << type << '=' << (*type_return)->typeName(); - if (url_return) - qDebug() << "QmlEngine::resolveType" << type << '=' << *url_return; - } - return true; - } - if (qmlImportTrace()) - qDebug() << "QmlEngine::resolveType" << type << "not found"; - } - return false; -} - -/*! - \internal - - Searching \e only in the namespace \a ns (previously returned in a call to - resolveType(), \a type is found and returned to either - a QmlType stored at \a type_return, or - a component located at \a url_return. - - If either return pointer is 0, the corresponding search is not done. -*/ -void QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin ) const -{ - ns->find(type,vmaj,vmin,type_return,url_return); -} - -static void voidptr_destructor(void *v) -{ - void **ptr = (void **)v; - delete ptr; -} - -static void *voidptr_constructor(const void *v) -{ - if (!v) { - return new void*; - } else { - return new void*(*(void **)v); - } -} - -void QmlEnginePrivate::registerCompositeType(QmlCompiledData *data) -{ - QByteArray name = data->root->className(); - - QByteArray ptr = name + '*'; - QByteArray lst = "QmlListProperty<" + name + ">"; - - int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor, - voidptr_constructor); - int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor, - voidptr_constructor); - - m_qmlLists.insert(lst_type, ptr_type); - m_compositeTypes.insert(ptr_type, data); - data->addref(); -} - -bool QmlEnginePrivate::isList(int t) const -{ - return m_qmlLists.contains(t) || QmlMetaType::isList(t); -} - -int QmlEnginePrivate::listType(int t) const -{ - QHash<int, int>::ConstIterator iter = m_qmlLists.find(t); - if (iter != m_qmlLists.end()) - return *iter; - else - return QmlMetaType::listType(t); -} - -bool QmlEnginePrivate::isQObject(int t) -{ - return m_compositeTypes.contains(t) || QmlMetaType::isQObject(t); -} - -QObject *QmlEnginePrivate::toQObject(const QVariant &v, bool *ok) const -{ - int t = v.userType(); - if (m_compositeTypes.contains(t)) { - if (ok) *ok = true; - return *(QObject **)(v.constData()); - } else { - return QmlMetaType::toQObject(v, ok); - } -} - -QmlMetaType::TypeCategory QmlEnginePrivate::typeCategory(int t) const -{ - if (m_compositeTypes.contains(t)) - return QmlMetaType::Object; - else if (m_qmlLists.contains(t)) - return QmlMetaType::List; - else - return QmlMetaType::typeCategory(t); -} - -const QMetaObject *QmlEnginePrivate::rawMetaObjectForType(int t) const -{ - QHash<int, QmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t); - if (iter != m_compositeTypes.end()) { - return (*iter)->root; - } else { - QmlType *type = QmlMetaType::qmlType(t); - return type?type->baseMetaObject():0; - } -} - -const QMetaObject *QmlEnginePrivate::metaObjectForType(int t) const -{ - QHash<int, QmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t); - if (iter != m_compositeTypes.end()) { - return (*iter)->root; - } else { - QmlType *type = QmlMetaType::qmlType(t); - return type?type->metaObject():0; - } -} - -QT_END_NAMESPACE |