Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeengine.cpp
index fa606ab..335eb75 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** 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_END_LICENSE$
 **
 ****************************************************************************/
 
-#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 "private/qjsdebugservice_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>
@@ -114,6 +102,12 @@ Q_DECLARE_METATYPE(QDeclarativeProperty)
 
 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
@@ -132,7 +126,7 @@ QT_BEGIN_NAMESPACE
   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
@@ -169,32 +163,27 @@ QT_BEGIN_NAMESPACE
     \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.
 
@@ -229,11 +218,11 @@ data types. This is primarily useful when setting the properties of an item
 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.
@@ -243,12 +232,12 @@ There are also string based constructors for these types. See \l{qdeclarativebas
 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
@@ -257,14 +246,14 @@ items from files or strings. See \l{Dynamic Object Management in QML} for an ove
 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
@@ -303,6 +292,13 @@ of their use.
     \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
@@ -342,53 +338,19 @@ the same object as is returned from the Qt.include() call.
 
 
 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()
+  incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
 {
 }
 
-QNetworkAccessManager *QDeclarativeScriptEngine::networkAccessManager()
-{
-    return p->getNetworkAccessManager();
-}
-
 QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
 {
     Q_ASSERT(inProgressCreations == 0);
-    Q_ASSERT(bindValues.isEmpty());
-    Q_ASSERT(parserStatus.isEmpty());
 
     while (cleanup) {
         QDeclarativeCleanup *c = cleanup;
@@ -399,6 +361,11 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
         c->clear();
     }
 
+    doDeleteInEngineThread();
+
+    if (incubationController) incubationController->d = 0;
+    incubationController = 0;
+
     delete rootContext;
     rootContext = 0;
 
@@ -414,21 +381,6 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
     }
 }
 
-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);
@@ -456,27 +408,54 @@ void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *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);
-        QJSDebugService::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()
@@ -522,7 +501,7 @@ 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();
@@ -538,8 +517,9 @@ QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
 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
@@ -556,6 +536,12 @@ QDeclarativeEngine::~QDeclarativeEngine()
             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()
@@ -624,6 +610,16 @@ QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManage
     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);
@@ -676,9 +672,6 @@ QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const
   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)
@@ -690,6 +683,8 @@ void QDeclarativeEngine::addImageProvider(const QString &providerId, QDeclarativ
 
 /*!
   Returns the QDeclarativeImageProvider set for \a providerId.
+
+  Returns the provider if it was found; otherwise returns 0.
 */
 QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &providerId) const
 {
@@ -701,8 +696,6 @@ QDeclarativeImageProvider *QDeclarativeEngine::imageProvider(const QString &prov
 /*!
   Removes the QDeclarativeImageProvider for \a providerId.
 
-  Returns the provider if it was found; otherwise returns 0.
-
   \sa addImageProvider()
 */
 void QDeclarativeEngine::removeImageProvider(const QString &providerId)
@@ -722,7 +715,7 @@ QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProvider
     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());
@@ -824,8 +817,7 @@ void QDeclarativeEngine::setOutputWarningsToStandardError(bool enabled)
 */
 void QDeclarativeEngine::collectGarbage()
 {
-    v8::V8::LowMemoryNotification();
-    while (!v8::V8::IdleNotification()) {}
+    QV8Engine::gc();
 }
 
 /*!
@@ -943,6 +935,26 @@ QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject
         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);
@@ -951,10 +963,10 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *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);
 
@@ -976,8 +988,10 @@ QDeclarativeContext *qmlContext(const QObject *obj)
 
 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)
@@ -1014,6 +1028,17 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
     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();
@@ -1031,6 +1056,80 @@ QDeclarativeDataExtended::~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 = &notifies[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 = &notifies[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 = &notifyList->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 = &notifyList->todo;
+        notifyList->todo = endpoint;
+    }
+}
+
 QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
 {
     if (!extendedData) extendedData = new QDeclarativeDataExtended;
@@ -1072,11 +1171,22 @@ void QDeclarativeData::destroyed(QObject *object)
         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;
 
@@ -1086,10 +1196,10 @@ void QDeclarativeData::destroyed(QObject *object)
         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 *)
@@ -1143,6 +1253,34 @@ QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
     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);
@@ -1407,13 +1545,13 @@ bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &ur
 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)
@@ -1441,8 +1579,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObj
         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;
     }
@@ -1456,6 +1593,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
     int maxMinorVersion = 0;
 
     const QMetaObject *metaObject = type->metaObject();
+
     while (metaObject) {
         QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
                                                             type->majorVersion(), minorVersion);
@@ -1518,12 +1656,12 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
          !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))
@@ -1535,7 +1673,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
     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;
     }
 
@@ -1550,44 +1688,31 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
     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();
-}
-
-bool QDeclarativeEnginePrivate::isList(int t) const
-{
-    return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
-}
+    QDeclarativeMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
+    if (!a) {
+        a = new QDeclarativeMetaType::ModuleApiInstance;
+        a->scriptCallback = module.script;
+        a->qobjectCallback = module.qobject;
+        moduleApiInstances.insert(module, a);
+    }
 
-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;
@@ -1599,6 +1724,7 @@ QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
 
 QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
 {
+    Locker locker(this);
     if (m_compositeTypes.contains(t))
         return QDeclarativeMetaType::Object;
     else if (m_qmlLists.contains(t))
@@ -1607,8 +1733,25 @@ QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int 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;
@@ -1620,6 +1763,7 @@ const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
 
 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;
@@ -1629,16 +1773,34 @@ const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
     }
 }
 
+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);
@@ -1646,13 +1808,13 @@ bool QDeclarative_isFileCaseCorrect(const QString &fileName)
     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);
@@ -1668,4 +1830,20 @@ bool QDeclarative_isFileCaseCorrect(const QString &fileName)
     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