Doc: Enabling Qt QML linking to Qt Quick.
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlengine.cpp
index 2634145..d7b6f70 100644 (file)
@@ -1,38 +1,38 @@
 /****************************************************************************
 **
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
 ** GNU Lesser General Public License Usage
-** 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.
+** 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
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** 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.
-**
-**
-**
-**
+** 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.
 **
 **
 ** $QT_END_LICENSE$
 
 #include <private/qqmllocale_p.h>
 
+#include "qqmlbind_p.h"
+#include "qqmlconnections_p.h"
+#include "qqmltimer_p.h"
+
 #ifdef Q_OS_WIN // for %APPDATA%
 #include <qt_windows.h>
 #include <qlibrary.h>
@@ -104,23 +108,24 @@ QT_BEGIN_NAMESPACE
 void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
 {
     QQmlEnginePrivate::registerBaseTypes(uri, versionMajor, versionMinor);
-    QQmlValueTypeFactory::registerBaseTypes(uri, versionMajor, versionMinor);
+    QQmlEnginePrivate::registerQtQuick2Types(uri, versionMajor, versionMinor);
+    QQmlValueTypeFactory::registerValueTypes(uri, versionMajor, versionMinor);
 }
 
 /*!
-  \qmlclass QtObject QObject
+  \qmltype QtObject
+    \instantiates QObject
   \inqmlmodule QtQuick 2
   \ingroup qml-utility-elements
-  \since 4.7
   \brief A basic QML type
 
-  The QtObject element is a non-visual element which contains only the
+  The QtObject type is a non-visual element which contains only the
   objectName property.
 
   It can be useful to create a QtObject if you need an extremely
-  lightweight element to enclose a set of custom properties:
+  lightweight type to enclose a set of custom properties:
 
-  \snippet doc/snippets/qml/qtobject.qml 0
+  \snippet qml/qtobject.qml 0
 
   It can also be useful for C++ integration, as it is just a plain
   QObject. See the QObject documentation for further details.
@@ -164,20 +169,46 @@ void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
 */
 
 bool QQmlEnginePrivate::qml_debugging_enabled = false;
+bool QQmlEnginePrivate::s_designerMode = false;
 
+// these types are part of the QML language
 void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
 {
     qmlRegisterType<QQmlComponent>(uri,versionMajor,versionMinor,"Component");
     qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject");
-    qmlRegisterType<QQuickListElement>(uri, versionMajor, versionMinor,"ListElement");
-    qmlRegisterCustomType<QQuickListModel>(uri, versionMajor, versionMinor,"ListModel", new QQuickListModelParser);
-    qmlRegisterType<QQuickWorkerScript>(uri,versionMajor,versionMinor,"WorkerScript");
+    qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding");
+    qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections");
+    qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer");
+    qmlRegisterCustomType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections", new QQmlConnectionsParser);
+}
+
+
+// These QtQuick types' implementation resides in the QtQml module
+void QQmlEnginePrivate::registerQtQuick2Types(const char *uri, int versionMajor, int versionMinor)
+{
+    qmlRegisterType<QQuickListElement>(uri, versionMajor, versionMinor, "ListElement");
+    qmlRegisterCustomType<QQuickListModel>(uri, versionMajor, versionMinor, "ListModel", new QQuickListModelParser);
+    qmlRegisterType<QQuickWorkerScript>(uri, versionMajor, versionMinor, "WorkerScript");
+}
+
+void QQmlEnginePrivate::defineQtQuick2Module()
+{
+    // register the base types into the QtQuick namespace
+    registerBaseTypes("QtQuick",2,0);
+
+    // register the QtQuick2 types which are implemented in the QtQml module.
+    registerQtQuick2Types("QtQuick",2,0);
+    qmlRegisterUncreatableType<QQmlLocale>("QtQuick", 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated.  Use Qt.locale()"));
+}
+
+bool QQmlEnginePrivate::designerMode()
+{
+    return s_designerMode;
 }
 
-void QQmlEnginePrivate::defineModule()
+void QQmlEnginePrivate::activateDesignerMode()
 {
-    registerBaseTypes("QtQuick", 2, 0);
-    qmlRegisterUncreatableType<QQmlLocale>("QtQuick",2,0,"Locale",QQmlEngine::tr("Locale cannot be instantiated.  Use Qt.locale()"));
+    s_designerMode = true;
 }
 
 
@@ -185,6 +216,7 @@ void QQmlEnginePrivate::defineModule()
     \class QQmlImageProviderBase
     \brief The QQmlImageProviderBase class is used to register image providers in the QML engine.
     \mainclass
+    \inmodule QtQml
 
     Image providers must be registered with the QML engine.  The only information the QML
     engine knows about image providers is the type of image data they provide.  To use an
@@ -204,7 +236,8 @@ void QQmlEnginePrivate::defineModule()
     \value Pixmap The Image Provider provides QPixmap images.
         The QQuickImageProvider::requestPixmap() method will be called for all image requests.
     \value Texture The Image Provider provides QSGTextureProvider based images.
-        The QQuickImageProvider::requestTexture() method will be called for all image requests. \omitvalue
+        The QQuickImageProvider::requestTexture() method will be called for all image requests.
+    \omitvalue Invalid
 */
 
 /*!
@@ -229,7 +262,8 @@ QQmlImageProviderBase::~QQmlImageProviderBase()
 
 
 /*!
-\qmlclass Qt QQmlEnginePrivate
+\qmltype Qt
+    \instantiates QQmlEnginePrivate
   \ingroup qml-utility-elements
 \brief The QML global Qt object provides useful enums and functions from Qt.
 
@@ -255,23 +289,33 @@ Text {
 \section1 Enums
 
 The Qt object contains the enums available in the \l {Qt Namespace}. For example, you can access
-the \l Qt::LeftButton and \l Qt::RightButton enum values as \c Qt.LeftButton and \c Qt.RightButton.
+the \l Qt::LeftButton and \l Qt::RightButton enumeration values as \c Qt.LeftButton and \c Qt.RightButton.
 
 
 \section1 Types
+
 The Qt object also contains helper functions for creating objects of specific
 data types. This is primarily useful when setting the properties of an item
 when the property has one of the following types:
-
 \list
-\li \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()}
 \li \c rect - use \l{Qt::rect()}{Qt.rect()}
 \li \c point - use \l{Qt::point()}{Qt.point()}
 \li \c size - use \l{Qt::size()}{Qt.size()}
+\endlist
+
+If the QtQuick module has been imported, the following helper functions for
+creating objects of specific data types are also available for clients to use:
+\list
+\li \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()}
+\li \c font - use \l{Qt::font()}{Qt.font()}
+\li \c vector2d - use \l{Qt::vector2d()}{Qt.vector2d()}
 \li \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()}
+\li \c vector4d - use \l{Qt::vector4d()}{Qt.vector4d()}
+\li \c quaternion - use \l{Qt::quaternion()}{Qt.quaternion()}
+\li \c matrix4x4 - use \l{Qt::matrix4x4()}{Qt.matrix4x4()}
 \endlist
 
-There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
+There are also string based constructors for these types. See \l{qtqml-typesystem-basictypes.html}{QML Basic Types} for more information.
 
 \section1 Date/Time Formatters
 
@@ -288,7 +332,7 @@ The format specification is described at \l{Qt::formatDateTime}{Qt.formatDateTim
 
 \section1 Dynamic Object Creation
 The following functions on the global object allow you to dynamically create QML
-items from files or strings. See \l{Dynamic Object Management in QML} for an overview
+items from files or strings. See \l{Dynamic QML Object Creation from JavaScript} for an overview
 of their use.
 
 \list
@@ -360,7 +404,7 @@ The following functions are also on the Qt object.
     The following example uses the \c application object to indicate
     whether the application is currently active:
 
-    \snippet doc/snippets/qml/application.qml document
+    \snippet qml/application.qml document
 */
 
 /*!
@@ -438,10 +482,6 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
         (*iter)->release();
     for(QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
         (*iter)->release();
-    for(QHash<QQmlMetaType::ModuleApi, QQmlMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
-        delete (*iter)->qobjectApi;
-        delete *iter;
-    }
     for (QHash<int, QQmlCompiledData *>::Iterator iter = m_compositeTypes.begin(); iter != m_compositeTypes.end(); ++iter)
         iter.value()->isRegisteredWithEngine = false;
 }
@@ -459,6 +499,11 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
         // Mark this object as in the process of deletion to
         // prevent it resolving in bindings
         QQmlData::markAsDeleted(o);
+
+        // Disconnect the notifiers now - during object destruction this would be too late, since
+        // the disconnect call wouldn't be able to call disconnectNotify(), as it isn't possible to
+        // get the metaobject anymore.
+        d->disconnectNotifiers();
     }
 }
 
@@ -472,6 +517,28 @@ void QQmlData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p
     static_cast<QQmlData *>(d)->parentChanged(o, p);
 }
 
+class QQmlThreadNotifierProxyObject : public QObject
+{
+public:
+    QPointer<QObject> target;
+
+    virtual int qt_metacall(QMetaObject::Call, int methodIndex, void **a) {
+        if (!target)
+            return -1;
+
+        QMetaMethod method = target->metaObject()->method(methodIndex);
+        Q_ASSERT(method.methodType() == QMetaMethod::Signal);
+        int signalIndex = QMetaObjectPrivate::signalIndex(method);
+        QQmlData *ddata = QQmlData::get(target, false);
+        QQmlNotifierEndpoint *ep = ddata->notify(signalIndex);
+        if (ep) QQmlNotifier::emitNotify(ep, a);
+
+        delete this;
+
+        return -1;
+    }
+};
+
 void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int index, void **a)
 {
     QQmlData *ddata = QQmlData::get(object, false);
@@ -486,7 +553,10 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
     if (ddata->notifyList &&
         QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId) {
 
-        QMetaMethod m = object->metaObject()->method(index);
+        if (!QObjectPrivate::get(object)->threadData->thread)
+            return;
+
+        QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
         QList<QByteArray> parameterTypes = m.parameterTypes();
 
         int *types = (int *)malloc((parameterTypes.count() + 1) * sizeof(int));
@@ -514,9 +584,13 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
             args[ii + 1] = QMetaType::create(types[ii + 1], a[ii + 1]);
         }
 
-        QMetaCallEvent *ev = new QMetaCallEvent(index, 0, 0, object, index,
+        QMetaCallEvent *ev = new QMetaCallEvent(m.methodIndex(), 0, 0, object, index,
                                                 parameterTypes.count() + 1, types, args);
-        QCoreApplication::postEvent(object, ev);
+
+        QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
+        mpo->target = object;
+        mpo->moveToThread(QObjectPrivate::get(object)->threadData->thread);
+        QCoreApplication::postEvent(mpo, ev);
 
     } else {
         QQmlNotifierEndpoint *ep = ddata->notify(index);
@@ -529,6 +603,11 @@ int QQmlData::receivers(QAbstractDeclarativeData *d, const QObject *, int index)
     return static_cast<QQmlData *>(d)->endpointCount(index);
 }
 
+bool QQmlData::isSignalConnected(QAbstractDeclarativeData *d, const QObject *, int index)
+{
+    return static_cast<QQmlData *>(d)->signalHasEndpoint(index);
+}
+
 int QQmlData::endpointCount(int index)
 {
     int count = 0;
@@ -567,25 +646,42 @@ void QQmlData::setQueuedForDeletion(QObject *object)
     }
 }
 
+void QQmlData::flushPendingBindingImpl(int coreIndex)
+{
+    clearPendingBindingBit(coreIndex);
+
+    // Find the binding
+    QQmlAbstractBinding *b = bindings;
+    while (b && *b->m_mePtr && b->propertyIndex() != coreIndex)
+        b = b->nextBinding();
+
+    if (b) {
+        b->m_mePtr = 0;
+        b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
+                            QQmlPropertyPrivate::DontRemoveBinding);
+    }
+}
+
 void QQmlEnginePrivate::init()
 {
     Q_Q(QQmlEngine);
 
     static bool firstTime = true;
     if (firstTime) {
-        qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component");
+        qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler.
+        registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks.
 
         QQmlData::init();
         firstTime = false;
     }
 
-    qRegisterMetaType<QVariant>("QVariant");
-    qRegisterMetaType<QQmlScriptString>("QQmlScriptString");
-    qRegisterMetaType<QJSValue>("QJSValue");
-    qRegisterMetaType<QQmlComponent::Status>("QQmlComponent::Status");
-    qRegisterMetaType<QList<QObject*> >("QList<QObject*>");
-    qRegisterMetaType<QList<int> >("QList<int>");
-    qRegisterMetaType<QQmlV8Handle>("QQmlV8Handle");
+    qRegisterMetaType<QVariant>();
+    qRegisterMetaType<QQmlScriptString>();
+    qRegisterMetaType<QJSValue>();
+    qRegisterMetaType<QQmlComponent::Status>();
+    qRegisterMetaType<QList<QObject*> >();
+    qRegisterMetaType<QList<int> >();
+    qRegisterMetaType<QQmlV8Handle>();
 
     v8engine()->setEngine(q);
 
@@ -675,25 +771,17 @@ QQmlEngine::~QQmlEngine()
     }
 
     // Emit onDestruction signals for the root context before
-    // we destroy the contexts, engine, Module APIs etc. that
+    // we destroy the contexts, engine, Singleton Types etc. that
     // may be required to handle the destruction signal.
     QQmlContextData::get(rootContext())->emitDestruction();
 
-    // 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
-    // a segfault in engine private dtor.
-    QList<QQmlMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
-    QObject *currQObjectApi = 0;
-    QQmlMetaType::ModuleApiInstance *currInstance = 0;
-    foreach (const QQmlMetaType::ModuleApi &key, keys) {
-        currInstance = d->moduleApiInstances.value(key);
-        currQObjectApi = currInstance->qobjectApi;
-        if (this->children().contains(currQObjectApi)) {
-            delete currQObjectApi;
-            delete currInstance;
-            d->moduleApiInstances.remove(key);
-        }
-    }
+    // clean up all singleton type instances which we own.
+    // we do this here and not in the private dtor since otherwise a crash can
+    // occur (if we are the QObject parent of the QObject singleton instance)
+    // XXX TODO: performance -- store list of singleton types separately?
+    QList<QQmlType*> singletonTypes = QQmlMetaType::qmlSingletonTypes();
+    foreach (QQmlType *currType, singletonTypes)
+        currType->singletonInstanceInfo()->destroy(this);
 
     if (d->incubationController)
         d->incubationController->d = 0;
@@ -826,7 +914,7 @@ QNetworkAccessManager *QQmlEnginePrivate::getNetworkAccessManager() const
 
 /*!
   Returns a common QNetworkAccessManager which can be used by any QML
-  element instantiated by this engine.
+  type instantiated by this engine.
 
   If a QQmlNetworkAccessManagerFactory has been set and a
   QNetworkAccessManager has not yet been created, the
@@ -1029,8 +1117,10 @@ void QQmlEngine::setContextForObject(QObject *object, QQmlContext *context)
   have been transferred to the C++ caller.
 
   Objects not-created by QML have CppOwnership by default.  The
-  exception to this is objects returned from a C++ method call.  The
-  ownership of these objects is passed to JavaScript.
+  exception to this is objects returned from C++ method calls; in these cases,
+  the ownership of the returned objects will be set to JavaScriptOwnerShip.
+  Note this applies only to explicit invocations of Q_INVOKABLE methods or slots,
+  and not to property getter invocations.
 
   Calling setObjectOwnership() overrides the default ownership
   heuristic used by QML.
@@ -1262,21 +1352,30 @@ void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint)
     }
 }
 
-bool QQml_isSignalConnected(QObject *obj, int signal_index, int index)
-{
-    QQmlData *data = QQmlData::get(obj);
-    return QObjectPrivate::get(obj)->isSignalConnected(signal_index) || (data && data->signalHasEndpoint(index));
-}
-
 /*
-    index MUST be the index returned by QMetaMethod::index()
-    This is different than the index returned by QObjectPrivate::signalIndex()
+    index MUST in the range returned by QObjectPrivate::signalIndex()
+    This is different than the index returned by QMetaMethod::methodIndex()
 */
 bool QQmlData::signalHasEndpoint(int index)
 {
     return notifyList && (notifyList->connectionMask & (1ULL << quint64(index % 64)));
 }
 
+void QQmlData::disconnectNotifiers()
+{
+    if (notifyList) {
+        while (notifyList->todo)
+            notifyList->todo->disconnect();
+        for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
+            while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii])
+                ep->disconnect();
+        }
+        free(notifyList->notifies);
+        free(notifyList);
+        notifyList = 0;
+    }
+}
+
 QHash<int, QObject *> *QQmlData::attachedProperties() const
 {
     if (!extendedData) extendedData = new QQmlDataExtended;
@@ -1357,17 +1456,7 @@ void QQmlData::destroyed(QObject *object)
         guard->objectDestroyed(object);
     }
 
-    if (notifyList) {
-        while (notifyList->todo)
-            notifyList->todo->disconnect();
-        for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
-            while (QQmlNotifierEndpoint *ep = notifyList->notifies[ii])
-                ep->disconnect();
-        }
-        free(notifyList->notifies);
-        free(notifyList);
-        notifyList = 0;
-    }
+    disconnectNotifiers();
 
     if (extendedData)
         delete extendedData;
@@ -1383,46 +1472,71 @@ void QQmlData::destroyed(QObject *object)
         delete this;
 }
 
+DEFINE_BOOL_CONFIG_OPTION(parentTest, QML_PARENT_TEST);
+
 void QQmlData::parentChanged(QObject *object, QObject *parent)
 {
-    Q_UNUSED(object);
-    Q_UNUSED(parent);
-}
+    if (parentTest()) {
+        if (parentFrozen && !QObjectPrivate::get(object)->wasDeleted) {
+            QString on;
+            QString pn;
 
-bool QQmlData::hasBindingBit(int bit) const
-{
-    if (bindingBitsSize > bit)
-        return bindingBits[bit / 32] & (1 << (bit % 32));
-    else
-        return false;
-}
+            { QDebug dbg(&on); dbg << object; on = on.left(on.length() - 1); }
+            { QDebug dbg(&pn); dbg << parent; pn = pn.left(pn.length() - 1); }
 
-void QQmlData::clearBindingBit(int bit)
-{
-    if (bindingBitsSize > bit)
-        bindingBits[bit / 32] &= ~(1 << (bit % 32));
+            qFatal("Object %s has had its parent frozen by QML and cannot be changed.\n"
+                   "User code is attempting to change it to %s.\n"
+                   "This behavior is NOT supported!", qPrintable(on), qPrintable(pn));
+        }
+    }
 }
 
-void QQmlData::setBindingBit(QObject *obj, int bit)
+static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit)
 {
-    if (bindingBitsSize <= bit) {
+    if (data->bindingBitsSize <= bit) {
         int props = QQmlMetaObject(obj).propertyCount();
-        Q_ASSERT(bit < props);
+        Q_ASSERT(bit < 2 * props);
 
-        int arraySize = (props + 31) / 32;
-        int oldArraySize = bindingBitsSize / 32;
+        int arraySize = (2 * props + 31) / 32;
+        int oldArraySize = data->bindingBitsSize / 32;
 
-        bindingBits = (quint32 *)realloc(bindingBits,
-                                         arraySize * sizeof(quint32));
+        data->bindingBits = (quint32 *)realloc(data->bindingBits,
+                                               arraySize * sizeof(quint32));
 
-        memset(bindingBits + oldArraySize,
+        memset(data->bindingBits + oldArraySize,
                0x00,
                sizeof(quint32) * (arraySize - oldArraySize));
 
-        bindingBitsSize = arraySize * 32;
+        data->bindingBitsSize = arraySize * 32;
     }
 
-    bindingBits[bit / 32] |= (1 << (bit % 32));
+    data->bindingBits[bit / 32] |= (1 << (bit % 32));
+}
+
+static void QQmlData_clearBit(QQmlData *data, int bit)
+{
+    if (data->bindingBitsSize > bit)
+        data->bindingBits[bit / 32] &= ~(1 << (bit % 32));
+}
+
+void QQmlData::clearBindingBit(int coreIndex)
+{
+    QQmlData_clearBit(this, coreIndex * 2);
+}
+
+void QQmlData::setBindingBit(QObject *obj, int coreIndex)
+{
+    QQmlData_setBit(this, obj, coreIndex * 2);
+}
+
+void QQmlData::clearPendingBindingBit(int coreIndex)
+{
+    QQmlData_clearBit(this, coreIndex * 2 + 1);
+}
+
+void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex)
+{
+    QQmlData_setBit(this, obj, coreIndex * 2 + 1);
 }
 
 void QQmlEnginePrivate::sendQuit()
@@ -1463,6 +1577,12 @@ void QQmlEnginePrivate::warning(const QList<QQmlError> &errors)
         dumpwarning(errors);
 }
 
+void QQmlEnginePrivate::warning(QQmlDelayedError *error)
+{
+    Q_Q(QQmlEngine);
+    warning(error->error(q));
+}
+
 void QQmlEnginePrivate::warning(QQmlEngine *engine, const QQmlError &error)
 {
     if (engine)
@@ -1479,6 +1599,14 @@ void QQmlEnginePrivate::warning(QQmlEngine *engine, const QList<QQmlError> &erro
         dumpwarning(error);
 }
 
+void QQmlEnginePrivate::warning(QQmlEngine *engine, QQmlDelayedError *error)
+{
+    if (engine)
+        QQmlEnginePrivate::get(engine)->warning(error);
+    else
+        dumpwarning(error->error(0));
+}
+
 void QQmlEnginePrivate::warning(QQmlEnginePrivate *engine, const QQmlError &error)
 {
     if (engine)
@@ -1532,7 +1660,13 @@ void QQmlEnginePrivate::dereferenceScarceResources()
 /*!
   Adds \a path as a directory where the engine searches for
   installed modules in a URL-based directory structure.
-  The \a path may be a local filesystem directory or a URL.
+
+  The \a path may be a local filesystem directory, a
+  \l {The Qt Resource System}{Qt Resource} path (\c {:/imports}), a
+  \l {The Qt Resource System}{Qt Resource} url (\c {qrc:/imports}) or a URL.
+
+  The \a path will be converted into canonical form before it
+  is added to the import path list.
 
   The newly added \a path will be first in the importPathList().
 
@@ -1555,8 +1689,8 @@ void QQmlEngine::addImportPath(const QString& path)
   type version mapping and possibly QML extensions plugins.
 
   By default, the list contains the directory of the application executable,
-  paths specified in the \c QML_IMPORT_PATH environment variable,
-  and the builtin \c ImportsPath from QLibraryInfo.
+  paths specified in the \c QML2_IMPORT_PATH environment variable,
+  and the builtin \c Qml2ImportsPath from QLibraryInfo.
 
   \sa addImportPath(), setImportPathList()
 */
@@ -1571,8 +1705,8 @@ QStringList QQmlEngine::importPathList() const
   installed modules in a URL-based directory structure.
 
   By default, the list contains the directory of the application executable,
-  paths specified in the \c QML_IMPORT_PATH environment variable,
-  and the builtin \c ImportsPath from QLibraryInfo.
+  paths specified in the \c QML2_IMPORT_PATH environment variable,
+  and the builtin \c Qml2ImportsPath from QLibraryInfo.
 
   \sa importPathList(), addImportPath()
   */
@@ -1643,32 +1777,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
 bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
 {
     Q_D(QQmlEngine);
-    return d->importDatabase.importPlugin(filePath, uri, errors);
-}
-
-/*!
-  Imports the plugin named \a filePath with the \a uri provided.
-  Returns true if the plugin was successfully imported; otherwise returns false.
-
-  On failure and if non-null, *\a errorString will be set to a message describing the failure.
-
-  The plugin has to be a Qt plugin which implements the QQmlExtensionPlugin interface.
-*/
-bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
-{
-    Q_D(QQmlEngine);
-    QList<QQmlError> errors;
-    bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
-    if (!errors.isEmpty()) {
-        QString builtError;
-        for (int i = 0; i < errors.size(); ++i) {
-            builtError = QString(QLatin1String("%1\n        %2"))
-                    .arg(builtError)
-                    .arg(errors.at(i).toString());
-        }
-        *errorString = builtError;
-    }
-    return retn;
+    return d->importDatabase.importPlugin(filePath, uri, QString(), errors);
 }
 
 /*!
@@ -1819,23 +1928,6 @@ QQmlPropertyCache *QQmlEnginePrivate::createCache(QQmlType *type, int minorVersi
     return raw;
 }
 
-QQmlMetaType::ModuleApiInstance *
-QQmlEnginePrivate::moduleApiInstance(const QQmlMetaType::ModuleApi &module)
-{
-    Locker locker(this);
-
-    QQmlMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
-    if (!a) {
-        a = new QQmlMetaType::ModuleApiInstance;
-        a->scriptCallback = module.script;
-        a->qobjectCallback = module.qobject;
-        a->instanceMetaObject = module.instanceMetaObject;
-        moduleApiInstances.insert(module, a);
-    }
-
-    return a;
-}
-
 bool QQmlEnginePrivate::isQObject(int t)
 {
     Locker locker(this);
@@ -1939,18 +2031,18 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
     QByteArray lst = "QQmlListProperty<" + name + '>';
 
     int ptr_type = QMetaType::registerNormalizedType(ptr,
-                                                     qMetaTypeDeleteHelper<QObject*>,
-                                                     qMetaTypeCreateHelper<QObject*>,
-                                                     qMetaTypeDestructHelper<QObject*>,
-                                                     qMetaTypeConstructHelper<QObject*>,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Delete,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Create,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Destruct,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Construct,
                                                      sizeof(QObject*),
                                                      static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
                                                      0);
     int lst_type = QMetaType::registerNormalizedType(lst,
-                                                     qMetaTypeDeleteHelper<QQmlListProperty<QObject> >,
-                                                     qMetaTypeCreateHelper<QQmlListProperty<QObject> >,
-                                                     qMetaTypeDestructHelper<QQmlListProperty<QObject> >,
-                                                     qMetaTypeConstructHelper<QQmlListProperty<QObject> >,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Delete,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Create,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Destruct,
+                                                     QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Construct,
                                                      sizeof(QQmlListProperty<QObject>),
                                                      static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
                                                      static_cast<QMetaObject*>(0));
@@ -1986,13 +2078,13 @@ bool QQmlEnginePrivate::isScriptLoaded(const QUrl &url) const
     return typeLoader.isScriptLoaded(url);
 }
 
-bool QQml_isFileCaseCorrect(const QString &fileName)
+bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */)
 {
 #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
     QFileInfo info(fileName);
     const QString absolute = info.absoluteFilePath();
 
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) || defined(Q_OS_WINCE)
     const QString canonical = info.canonicalFilePath();
 #elif defined(Q_OS_WIN)
     wchar_t buffer[1024];
@@ -2008,7 +2100,21 @@ bool QQml_isFileCaseCorrect(const QString &fileName)
     const int absoluteLength = absolute.length();
     const int canonicalLength = canonical.length();
 
-    const int length = qMin(absoluteLength, canonicalLength);
+    int length = qMin(absoluteLength, canonicalLength);
+    if (lengthIn >= 0) {
+        length = qMin(lengthIn, length);
+    } else {
+        // No length given: Limit to file name. Do not trigger
+        // on drive letters or folder names.
+        int lastSlash = absolute.lastIndexOf(QLatin1Char('/'));
+        if (lastSlash < 0)
+            lastSlash = absolute.lastIndexOf(QLatin1Char('\\'));
+        if (lastSlash >= 0) {
+            const int fileNameLength = absoluteLength - 1 - lastSlash;
+            length = qMin(length, fileNameLength);
+        }
+    }
+
     for (int ii = 0; ii < length; ++ii) {
         const QChar &a = absolute.at(absoluteLength - 1 - ii);
         const QChar &c = canonical.at(canonicalLength - 1 - ii);
@@ -2019,6 +2125,7 @@ bool QQml_isFileCaseCorrect(const QString &fileName)
             return false;
     }
 #else
+    Q_UNUSED(lengthIn)
     Q_UNUSED(fileName)
 #endif
     return true;