/****************************************************************************
**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
**
** 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.
+** 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
+** 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.
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
****************************************************************************/
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
+#include "qdeclarativecomponentattached_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativecompiler_p.h"
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativecomponent.h"
-#include "private/qdeclarativebinding_p_p.h"
-#include "private/qdeclarativevme_p.h"
-#include "private/qdeclarativeenginedebug_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativexmlhttprequest_p.h"
-#include "private/qdeclarativesqldatabase_p.h"
+#include "qdeclarativebinding_p_p.h"
+#include "qdeclarativevme_p.h"
+#include <private/qdeclarativeenginedebugservice_p.h>
+#include "qdeclarativestringconverters_p.h"
+#include "qdeclarativexmlhttprequest_p.h"
+#include "qdeclarativesqldatabase_p.h"
#include "qdeclarativescriptstring.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativeworkerscript_p.h"
-#include "private/qdeclarativecomponent_p.h"
+#include "qdeclarativeglobal_p.h"
+#include "qdeclarativelistmodel_p.h"
+#include "qdeclarativeworkerscript_p.h"
+#include "qdeclarativecomponent_p.h"
#include "qdeclarativenetworkaccessmanagerfactory.h"
#include "qdeclarativeimageprovider.h"
-#include "private/qdeclarativedirparser_p.h"
+#include "qdeclarativedirparser_p.h"
#include "qdeclarativeextensioninterface.h"
-#include "private/qdeclarativelist_p.h"
-#include "private/qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativenotifier_p.h"
-#include "private/qdeclarativedebugtrace_p.h"
-#include "private/qdeclarativeapplication_p.h"
+#include "qdeclarativelist_p.h"
+#include "qdeclarativetypenamecache_p.h"
+#include "qdeclarativenotifier_p.h"
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativeapplication_p.h>
+#include <private/qv8debugservice_p.h>
+#include <private/qdebugmessageservice_p.h>
+#include "qdeclarativeincubator.h"
+#include <private/qv8profilerservice_p.h>
+
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qsettings.h>
#include <QtCore/qmetaobject.h>
-#include <QNetworkReply>
-#include <QNetworkRequest>
#include <QNetworkAccessManager>
-#include <QDesktopServices>
-#include <QTimer>
-#include <QList>
-#include <QPair>
#include <QDebug>
#include <QMetaObject>
-#include <QStack>
-#include <QMap>
-#include <QPluginLoader>
-#include <QtGui/qfontdatabase.h>
-#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 <QtCore/qcryptographichash.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
#include <private/qobject_p.h>
-#include <private/qscriptdeclarativeclass_p.h>
-#include <private/qdeclarativeitemsmodule_p.h>
-#include <private/qdeclarativeutilmodule_p.h>
-#include <private/qsgitemsmodule_p.h>
-#include <qsgtexture.h>
+#include <private/qdeclarativelocale_p.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
QT_BEGIN_NAMESPACE
+void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
+{
+ QDeclarativeEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
+ QDeclarativeValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
+}
+
/*!
\qmlclass QtObject QObject
\ingroup qml-utility-elements
\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.
+ objectName property.
It can be useful to create a QtObject if you need an extremely
lightweight element to enclose a set of custom properties:
QObject. See the QObject documentation for further details.
*/
/*!
- \qmlproperty string QML:QtObject::objectName
+ \qmlproperty string QtObject::objectName
This property holds the QObject::objectName for this specific object instance.
This allows a C++ application to locate an item within a QML component
- using the QObject::findChild() method. For example, the following C++
+ using the QObject::findChild() method. For example, the following C++
application locates the child \l Rectangle item and dynamically changes its
\c color value:
Rectangle {
anchors.fill: parent
- color: "red"
+ color: "red"
objectName: "myRect"
}
}
view.show();
QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect");
- if (item)
+ if (item)
item->setProperty("color", QColor(Qt::yellow));
\endcode
*/
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
-};
-
-static bool qt_QmlQtModule_registered = false;
bool QDeclarativeEnginePrivate::qml_debugging_enabled = false;
-void QDeclarativeEnginePrivate::defineModule()
+void QDeclarativeEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
{
- qmlRegisterType<QDeclarativeComponent>("QtQuick",1,0,"Component");
- qmlRegisterType<QObject>("QtQuick",1,0,"QtObject");
- qmlRegisterType<QDeclarativeWorkerScript>("QtQuick",1,0,"WorkerScript");
-
-#ifndef QT_NO_IMPORT_QT47_QML
- qmlRegisterType<QDeclarativeComponent>("Qt",4,7,"Component");
- qmlRegisterType<QObject>("Qt",4,7,"QtObject");
- qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,7,"WorkerScript");
-#endif
+ qmlRegisterType<QDeclarativeComponent>(uri,versionMajor,versionMinor,"Component");
+ qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
+ qmlRegisterType<QDeclarativeListElement>(uri, versionMajor, versionMinor,"ListElement");
+ qmlRegisterCustomType<QDeclarativeListModel>(uri, versionMajor, versionMinor,"ListModel", new QDeclarativeListModelParser);
+ qmlRegisterType<QDeclarativeWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
+}
+void QDeclarativeEnginePrivate::defineModule()
+{
+ registerBaseTypes("QtQuick", 2, 0);
qmlRegisterType<QDeclarativeBinding>();
+ qmlRegisterUncreatableType<QDeclarativeApplication>("QtQuick",2,0,"Application", QDeclarativeApplication::tr("Application is an abstract class"));
+ qmlRegisterUncreatableType<QDeclarativeLocale>("QtQuick",2,0,"Locale",QDeclarativeEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
}
/*!
-\qmlclass QML:Qt QDeclarativeEnginePrivate
+\qmlclass Qt QDeclarativeEnginePrivate
\ingroup qml-utility-elements
\brief The QML global Qt object provides useful enums and functions from Qt.
\keyword QmlGlobalQtObject
-\brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
+\brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files.
The \c Qt object is a global object with utility functions, properties and enums.
when the property has one of the following types:
\list
-\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()}
-\o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
-\o \c point - use \l{QML:Qt::point()}{Qt.point()}
-\o \c size - use \l{QML:Qt::size()}{Qt.size()}
-\o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
+\o \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()}
+\o \c rect - use \l{Qt::rect()}{Qt.rect()}
+\o \c point - use \l{Qt::point()}{Qt.point()}
+\o \c size - use \l{Qt::size()}{Qt.size()}
+\o \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()}
\endlist
There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
\list
- \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
- \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
- \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
+ \o \l{Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
+ \o \l{Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
+ \o \l{Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
\endlist
-The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
+The format specification is described at \l{Qt::formatDateTime}{Qt.formatDateTime}.
\section1 Dynamic Object Creation
of their use.
\list
- \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
- \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
+ \o \l{Qt::createComponent()}{object Qt.createComponent(url)}
+ \o \l{Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
\endlist
*/
/*!
- \qmlproperty object QML:Qt::application
+ \qmlproperty object Qt::application
\since QtQuick 1.1
The \c application object provides access to global application state
\o Qt.RightToLeft - Text and graphics elements should be positioned
from right to left.
\endlist
+
+ \row
+ \o \c application.inputPanel
+ \o
+ This read-only property allows access to application's QInputPanel object
+ and all its properties and slots. See the QInputPanel documentation for
+ further details.
\endtable
The following example uses the \c application object to indicate
QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
-: captureProperties(false), rootContext(0), isDebugging(false),
+: propertyCapture(0), rootContext(0), isDebugging(false),
outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
- cleanup(0), erroredBindings(0), inProgressCreations(0), scriptEngine(this),
- workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
+ cleanup(0), erroredBindings(0), inProgressCreations(0),
+ workerScriptEngine(0), activeVME(0),
networkAccessManager(0), networkAccessManagerFactory(0),
scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
- sgContext(0)
-{
- if (!qt_QmlQtModule_registered) {
- qt_QmlQtModule_registered = true;
- QDeclarativeItemModule::defineModule();
- QDeclarativeUtilModule::defineModule();
- QDeclarativeEnginePrivate::defineModule();
- QSGItemsModule::defineModule();
- QDeclarativeValueTypeFactory::registerValueTypes();
- }
-}
-
-QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *priv)
-: p(priv)
-{
- // Note that all documentation for stuff put on the global object goes in
- // doc/src/declarative/globalobject.qdoc
-
- QScriptValue qtObject =
- newQMetaObject(StaticQtMetaObject::get());
- globalObject().setProperty(QLatin1String("Qt"), qtObject);
-
- // translation functions need to be installed
- // before the global script class is constructed (QTBUG-6437)
- installTranslatorFunctions();
-}
-
-QDeclarativeScriptEngine::~QDeclarativeScriptEngine()
-{
-}
-
-QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
+ incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
{
- return p->getNetworkAccessManager();
}
QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
{
Q_ASSERT(inProgressCreations == 0);
- Q_ASSERT(bindValues.isEmpty());
- Q_ASSERT(parserStatus.isEmpty());
while (cleanup) {
QDeclarativeCleanup *c = cleanup;
c->clear();
}
+ doDeleteInEngineThread();
+
+ if (incubationController) incubationController->d = 0;
+ incubationController = 0;
+
delete rootContext;
rootContext = 0;
}
}
-void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
-{
- bvs.clear();
-}
-
-void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
-{
- for (int ii = 0; ii < pss.count; ++ii) {
- QDeclarativeParserStatus *ps = pss.at(ii);
- if(ps)
- ps->d = 0;
- }
- pss.clear();
-}
-
void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
{
QObjectPrivate *p = QObjectPrivate::get(o);
static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
}
+void QDeclarativeData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int index, void **)
+{
+ QDeclarativeData *ddata = QDeclarativeData::get(object, false);
+ if (!ddata) return; // Probably being deleted
+
+ QDeclarativeNotifierEndpoint *ep = ddata->notify(index);
+ if (ep) QDeclarativeNotifier::emitNotify(ep);
+}
+
void QDeclarativeEnginePrivate::init()
{
Q_Q(QDeclarativeEngine);
+
+ static bool firstTime = true;
+ if (firstTime) {
+ qmlRegisterType<QDeclarativeComponent>("QML", 1, 0, "Component");
+
+ firstTime = false;
+ }
+
qRegisterMetaType<QVariant>("QVariant");
qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
- qRegisterMetaType<QScriptValue>("QScriptValue");
+ qRegisterMetaType<QJSValue>("QJSValue");
qRegisterMetaType<QDeclarativeComponent::Status>("QDeclarativeComponent::Status");
+ qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
+ qRegisterMetaType<QList<int> >("QList<int>");
+ qRegisterMetaType<QDeclarativeV8Handle>("QDeclarativeV8Handle");
QDeclarativeData::init();
- // Init V8 data
- v8engine.init(q);
+ v8engine()->setEngine(q);
rootContext = new QDeclarativeContext(q,true);
if (QCoreApplication::instance()->thread() == q->thread() &&
- QDeclarativeEngineDebugServer::isDebuggingEnabled()) {
+ QDeclarativeEngineDebugService::isDebuggingEnabled()) {
isDebugging = true;
- QDeclarativeEngineDebugServer::instance()->addEngine(q);
+ QDeclarativeEngineDebugService::instance()->addEngine(q);
+ QV8DebugService::initialize(v8engine());
+ QV8ProfilerService::initialize();
+ QDeclarativeDebugTrace::initialize();
+ QDebugMessageService::instance();
}
+
+ QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
+ offlineStoragePath = dataLocation.replace(QLatin1Char('/'), QDir::separator()) +
+ QDir::separator() + QLatin1String("QML") +
+ QDir::separator() + QLatin1String("OfflineStorage");
}
QDeclarativeWorkerScriptEngine *QDeclarativeEnginePrivate::getWorkerScriptEngine()
Create a new QDeclarativeEngine with the given \a parent.
*/
QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
-: QObject(*new QDeclarativeEnginePrivate(this), parent)
+: QJSEngine(*new QDeclarativeEnginePrivate(this), parent)
{
Q_D(QDeclarativeEngine);
d->init();
QDeclarativeEngine::~QDeclarativeEngine()
{
Q_D(QDeclarativeEngine);
- if (d->isDebugging)
- QDeclarativeEngineDebugServer::instance()->remEngine(this);
+ if (d->isDebugging) {
+ QDeclarativeEngineDebugService::instance()->remEngine(this);
+ }
// if we are the parent of any of the qobject module api instances,
// we need to remove them from our internal list, in order to prevent
d->moduleApiInstances.remove(key);
}
}
+
+ // ensure we clean up QObjects with JS ownership
+ d->v8engine()->gc();
+
+ if (d->incubationController)
+ d->incubationController->d = 0;
}
/*! \fn void QDeclarativeEngine::quit()
return d->networkAccessManagerFactory;
}
+void QDeclarativeEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
+{
+ if (activeVME) {
+ activeVME->finalizeCallbacks.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
+ } else {
+ void *args[] = { 0 };
+ QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, args);
+ }
+}
+
QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
{
QMutexLocker locker(&mutex);
/*!
Sets the \a provider to use for images requested via the \e
- image: url scheme, with host \a providerId. The QDeclarativeEngine
+ image: url scheme, with host \a providerId. The QDeclarativeEngine
takes ownership of \a provider.
Image providers enable support for pixmap and threaded image
All required image providers should be added to the engine before any
QML sources files are loaded.
- Note that images loaded from a QDeclarativeImageProvider are cached
- by QPixmapCache, similar to any image loaded by QML.
-
\sa removeImageProvider()
*/
void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativeImageProvider *provider)
/*!
Returns the QDeclarativeImageProvider set for \a providerId.
+
+ Returns the provider if it was found; otherwise returns 0.
*/
QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
{
/*!
Removes the QDeclarativeImageProvider for \a providerId.
- Returns the provider if it was found; otherwise returns 0.
-
\sa addImageProvider()
*/
void QDeclarativeEngine::removeImageProvider(const QString &providerId)
return QDeclarativeImageProvider::Invalid;
}
-QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
+QDeclarativeTextureFactory *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
{
QMutexLocker locker(&mutex);
QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
*/
void QDeclarativeEngine::collectGarbage()
{
- v8::V8::LowMemoryNotification();
- while (!v8::V8::IdleNotification()) {}
+ QV8Engine::gc();
}
/*!
return ddata->indestructible?CppOwnership:JavaScriptOwnership;
}
+bool QDeclarativeEngine::event(QEvent *e)
+{
+ Q_D(QDeclarativeEngine);
+ if (e->type() == QEvent::User)
+ d->doDeleteInEngineThread();
+
+ return QJSEngine::event(e);
+}
+
+void QDeclarativeEnginePrivate::doDeleteInEngineThread()
+{
+ QFieldList<Deletable, &Deletable::next> list;
+ mutex.lock();
+ list.copyAndClear(toDeleteInEngineThread);
+ mutex.unlock();
+
+ while (Deletable *d = list.takeFirst())
+ delete d;
+}
+
Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
{
QDeclarativeData *data = QDeclarativeData::get(object);
if (QDeclarativeDebugService::isDebuggingEnabled()) {
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
- QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
+ QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(object->metaObject()->className());
QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
if (data->outerContext)
- QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
+ QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber, data->columnNumber);
}
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
QDeclarativeEngine *qmlEngine(const QObject *obj)
{
- QDeclarativeContext *context = QDeclarativeEngine::contextForObject(obj);
- return context?context->engine():0;
+ QDeclarativeData *data = QDeclarativeData::get(obj, false);
+ if (!data || !data->context)
+ return 0;
+ return data->context->engine;
}
QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
rv = pf(const_cast<QObject *>(object));
- if (rv)
+ if (rv)
data->attachedProperties()->insert(id, rv);
return rv;
return qmlAttachedPropertiesObjectById(*idCache, object, create);
}
+QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler()
+{
+#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
+ if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
+ qWarning("Qml debugging is enabled. Only use this in a safe environment!");
+ }
+ QDeclarativeEnginePrivate::qml_debugging_enabled = true;
+#endif
+}
+
+
class QDeclarativeDataExtended {
public:
QDeclarativeDataExtended();
{
}
+void QDeclarativeData::NotifyList::layout(QDeclarativeNotifierEndpoint *endpoint)
+{
+ if (endpoint->next)
+ layout(endpoint->next);
+
+ int index = endpoint->sourceSignal;
+ index = qMin(index, 0xFFFF - 1);
+
+ endpoint->next = notifies[index];
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = ¬ifies[index];
+ notifies[index] = endpoint;
+}
+
+void QDeclarativeData::NotifyList::layout()
+{
+ Q_ASSERT(maximumTodoIndex >= notifiesSize);
+
+ if (todo) {
+ QDeclarativeNotifierEndpoint **old = notifies;
+ const int reallocSize = (maximumTodoIndex + 1) * sizeof(QDeclarativeNotifierEndpoint*);
+ notifies = (QDeclarativeNotifierEndpoint**)realloc(notifies, reallocSize);
+ const int memsetSize = (maximumTodoIndex - notifiesSize + 1) *
+ sizeof(QDeclarativeNotifierEndpoint*);
+ memset(notifies + notifiesSize, 0, memsetSize);
+
+ if (notifies != old) {
+ for (int ii = 0; ii < notifiesSize; ++ii)
+ if (notifies[ii])
+ notifies[ii]->prev = ¬ifies[ii];
+ }
+
+ notifiesSize = maximumTodoIndex + 1;
+
+ layout(todo);
+ }
+
+ maximumTodoIndex = 0;
+ todo = 0;
+}
+
+void QDeclarativeData::addNotify(int index, QDeclarativeNotifierEndpoint *endpoint)
+{
+ if (!notifyList) {
+ notifyList = (NotifyList *)malloc(sizeof(NotifyList));
+ notifyList->connectionMask = 0;
+ notifyList->maximumTodoIndex = 0;
+ notifyList->notifiesSize = 0;
+ notifyList->todo = 0;
+ notifyList->notifies = 0;
+ }
+
+ Q_ASSERT(!endpoint->isConnected());
+
+ index = qMin(index, 0xFFFF - 1);
+ notifyList->connectionMask |= (1ULL << quint64(index % 64));
+
+ if (index < notifyList->notifiesSize) {
+
+ endpoint->next = notifyList->notifies[index];
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = ¬ifyList->notifies[index];
+ notifyList->notifies[index] = endpoint;
+
+ } else {
+ notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index);
+
+ endpoint->next = notifyList->todo;
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = ¬ifyList->todo;
+ notifyList->todo = endpoint;
+ }
+}
+
QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
{
if (!extendedData) extendedData = new QDeclarativeDataExtended;
context->destroy();
while (guards) {
- QDeclarativeGuard<QObject> *guard = guards;
+ QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
*guard = (QObject *)0;
guard->objectDestroyed(object);
}
+ if (notifyList) {
+ while (notifyList->todo)
+ notifyList->todo->disconnect();
+ for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
+ while (QDeclarativeNotifierEndpoint *ep = notifyList->notifies[ii])
+ ep->disconnect();
+ }
+ free(notifyList->notifies);
+ free(notifyList);
+ }
+
if (extendedData)
delete extendedData;
- v8object.Dispose();
+ v8object.Clear(); // The WeakReference handler will clean the actual handle
if (ownMemory)
delete this;
}
-void QDeclarativeData::parentChanged(QObject *, QObject *parent)
+void QDeclarativeData::parentChanged(QObject *object, QObject *parent)
{
- // XXX aakenned
-// if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; }
+ Q_UNUSED(object);
+ Q_UNUSED(parent);
}
void QDeclarativeData::objectNameChanged(QObject *)
return url.toLocalFile();
}
+
+static QString toLocalFile(const QString &url)
+{
+ if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
+ return QString();
+
+ QString file = url.mid(7);
+
+ //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
+
+ // magic for drives on windows
+ if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
+ file.remove(0, 1);
+
+ return file;
+}
+
+QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
+{
+ if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
+ if (url.length() > 4)
+ return QLatin1Char(':') + url.mid(4);
+ return QString();
+ }
+
+ return toLocalFile(url);
+}
+
void QDeclarativeEnginePrivate::sendQuit()
{
Q_Q(QDeclarativeEngine);
void QDeclarativeEngine::setOfflineStoragePath(const QString& dir)
{
Q_D(QDeclarativeEngine);
- qt_qmlsqldatabase_setOfflineStoragePath(&d->v8engine, dir);
+ d->offlineStoragePath = dir;
}
QString QDeclarativeEngine::offlineStoragePath() const
{
Q_D(const QDeclarativeEngine);
- return qt_qmlsqldatabase_getOfflineStoragePath(&d->v8engine);
+ return d->offlineStoragePath;
}
static void voidptr_destructor(void *v)
return rv;
} else {
QDeclarativePropertyCache *super = cache(mo->superClass());
- QDeclarativePropertyCache *rv = super->copy();
- rv->append(q, mo);
+ QDeclarativePropertyCache *rv = super->copyAndAppend(q, mo);
propertyCache.insert(mo, rv);
return rv;
}
}
-QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
+QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion,
QDeclarativeError &error)
{
QList<QDeclarativeType *> types;
int maxMinorVersion = 0;
const QMetaObject *metaObject = type->metaObject();
+
while (metaObject) {
- QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
type->majorVersion(), minorVersion);
if (t) {
maxMinorVersion = qMax(maxMinorVersion, t->minorVersion());
// Signals override:
// * other signals and methods of the same name.
- // * properties named on<Signal Name>
+ // * properties named on<Signal Name>
// * automatic <property name>Changed notify signals
// Methods override:
!overloadError && iter != raw->stringCache.end();
++iter) {
- QDeclarativePropertyCache::Data *d = *iter;
+ QDeclarativePropertyData *d = *iter;
if (raw->isAllowedInRevision(d))
continue; // Not excluded - no problems
// check that a regular "name" overload isn't happening
- QDeclarativePropertyCache::Data *current = d;
+ QDeclarativePropertyData *current = d;
while (!overloadError && current) {
current = d->overrideData(current);
- if (current && raw->isAllowedInRevision(current))
+ if (current && raw->isAllowedInRevision(current))
overloadError = true;
}
}
if (overloadError) {
if (hasCopied) raw->release();
-
- 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."));
+
+ error.setDescription(QLatin1String("Type ") + 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."));
return 0;
}
return raw;
}
-void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
+QDeclarativeMetaType::ModuleApiInstance *
+QDeclarativeEnginePrivate::moduleApiInstance(const QDeclarativeMetaType::ModuleApi &module)
{
- QByteArray name = data->root->className();
-
- QByteArray ptr = name + '*';
- QByteArray lst = "QDeclarativeListProperty<" + name + '>';
-
- int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
- voidptr_constructor);
- int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
- voidptr_constructor);
+ Locker locker(this);
- m_qmlLists.insert(lst_type, ptr_type);
- m_compositeTypes.insert(ptr_type, data);
- data->addref();
-}
+ QDeclarativeMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
+ if (!a) {
+ a = new QDeclarativeMetaType::ModuleApiInstance;
+ a->scriptCallback = module.script;
+ a->qobjectCallback = module.qobject;
+ moduleApiInstances.insert(module, a);
+ }
-bool QDeclarativeEnginePrivate::isList(int t) const
-{
- return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
-}
-
-int QDeclarativeEnginePrivate::listType(int t) const
-{
- QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
- if (iter != m_qmlLists.end())
- return *iter;
- else
- return QDeclarativeMetaType::listType(t);
+ return a;
}
bool QDeclarativeEnginePrivate::isQObject(int t)
{
+ Locker locker(this);
return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
}
QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
{
+ Locker locker(this);
int t = v.userType();
if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
if (ok) *ok = true;
QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
{
+ Locker locker(this);
if (m_compositeTypes.contains(t))
return QDeclarativeMetaType::Object;
else if (m_qmlLists.contains(t))
return QDeclarativeMetaType::typeCategory(t);
}
+bool QDeclarativeEnginePrivate::isList(int t) const
+{
+ Locker locker(this);
+ return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
+}
+
+int QDeclarativeEnginePrivate::listType(int t) const
+{
+ Locker locker(this);
+ QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
+ if (iter != m_qmlLists.end())
+ return *iter;
+ else
+ return QDeclarativeMetaType::listType(t);
+}
+
const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
{
+ Locker locker(this);
QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
return (*iter)->root;
const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
{
+ Locker locker(this);
QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
return (*iter)->root;
}
}
+void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
+{
+ QByteArray name = data->root->className();
+
+ QByteArray ptr = name + '*';
+ QByteArray lst = "QDeclarativeListProperty<" + name + '>';
+
+ int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
+ voidptr_constructor);
+ int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
+ voidptr_constructor);
+
+ data->addref();
+
+ Locker locker(this);
+ m_qmlLists.insert(lst_type, ptr_type);
+ m_compositeTypes.insert(ptr_type, data);
+}
+
bool QDeclarative_isFileCaseCorrect(const QString &fileName)
{
-#if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
+#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
QFileInfo info(fileName);
-
- QString absolute = info.absoluteFilePath();
+ const QString absolute = info.absoluteFilePath();
#if defined(Q_OS_MAC)
- QString canonical = info.canonicalFilePath();
-#elif defined(Q_OS_WIN32)
+ const QString canonical = info.canonicalFilePath();
+#elif defined(Q_OS_WIN)
wchar_t buffer[1024];
DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024);
rv = ::GetLongPathName(buffer, buffer, 1024);
if (rv == 0 || rv >= 1024) return true;
- QString canonical((QChar *)buffer);
+ const QString canonical = QString::fromWCharArray(buffer);
#endif
- int absoluteLength = absolute.length();
- int canonicalLength = canonical.length();
+ const int absoluteLength = absolute.length();
+ const int canonicalLength = canonical.length();
- int length = qMin(absoluteLength, canonicalLength);
+ const int length = qMin(absoluteLength, canonicalLength);
for (int ii = 0; ii < length; ++ii) {
const QChar &a = absolute.at(absoluteLength - 1 - ii);
const QChar &c = canonical.at(canonicalLength - 1 - ii);
return true;
}
+/*!
+ \fn QDeclarativeEngine *qmlEngine(const QObject *object)
+ \relates QDeclarativeEngine
+
+ Returns the QDeclarativeEngine associated with \a object, if any. This is equivalent to
+ QDeclarativeEngine::contextForObject(object)->engine(), but more efficient.
+*/
+
+/*!
+ \fn QDeclarativeContext *qmlContext(const QObject *object)
+ \relates QDeclarativeEngine
+
+ Returns the QDeclarativeContext associated with \a object, if any. This is equivalent to
+ QDeclarativeEngine::contextForObject(object).
+*/
+
QT_END_NAMESPACE