aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h4
-rw-r--r--src/qml/animations/qanimationgroupjob_p.h4
-rw-r--r--src/qml/animations/qparallelanimationgroupjob_p.h4
-rw-r--r--src/qml/animations/qpauseanimationjob_p.h4
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob_p.h4
-rw-r--r--src/qml/debugger/qdebugmessageservice_p.h4
-rw-r--r--src/qml/debugger/qqmldebug.h4
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp37
-rw-r--r--src/qml/debugger/qqmldebugserver_p.h4
-rw-r--r--src/qml/debugger/qqmldebugserverconnection_p.h6
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h4
-rw-r--r--src/qml/debugger/qqmldebugservice_p_p.h4
-rw-r--r--src/qml/debugger/qqmldebugstatesdelegate_p.h4
-rw-r--r--src/qml/debugger/qqmlinspectorinterface_p.h4
-rw-r--r--src/qml/debugger/qqmlinspectorservice_p.h4
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h4
-rw-r--r--src/qml/debugger/qv8debugservice_p.h4
-rw-r--r--src/qml/debugger/qv8profilerservice_p.h4
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/doc/src/cppintegration/contextproperties.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc6
-rw-r--r--src/qml/doc/src/cppintegration/extending-tutorial.qdoc12
-rw-r--r--src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc2
-rw-r--r--src/qml/doc/src/documents/definetypes.qdoc2
-rw-r--r--src/qml/doc/src/documents/scope.qdoc34
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc2
-rw-r--r--src/qml/doc/src/javascript/hostenvironment.qdoc2
-rw-r--r--src/qml/doc/src/modules/cppplugins.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc19
-rw-r--r--src/qml/doc/src/qmltypereference.qdoc12
-rw-r--r--src/qml/doc/src/qtqml-cpp.qdoc2
-rw-r--r--src/qml/doc/src/qtqml.qdoc8
-rw-r--r--src/qml/doc/src/typesystem/basictypes.qdoc3
-rw-r--r--src/qml/doc/src/whatsnew.qdoc7
-rw-r--r--src/qml/qml.pro1
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h10
-rw-r--r--src/qml/qml/ftw/qqmlrefcount_p.h4
-rw-r--r--src/qml/qml/parser/qqmljs.g134
-rw-r--r--src/qml/qml/parser/qqmljsast.cpp28
-rw-r--r--src/qml/qml/parser/qqmljsast_p.h115
-rw-r--r--src/qml/qml/parser/qqmljsastfwd_p.h4
-rw-r--r--src/qml/qml/parser/qqmljsastvisitor_p.h10
-rw-r--r--src/qml/qml/parser/qqmljsengine_p.cpp8
-rw-r--r--src/qml/qml/parser/qqmljsengine_p.h4
-rw-r--r--src/qml/qml/parser/qqmljsglobal_p.h4
-rw-r--r--src/qml/qml/parser/qqmljsgrammar.cpp1785
-rw-r--r--src/qml/qml/parser/qqmljsgrammar_p.h36
-rw-r--r--src/qml/qml/parser/qqmljskeywords_p.h26
-rw-r--r--src/qml/qml/parser/qqmljslexer.cpp332
-rw-r--r--src/qml/qml/parser/qqmljslexer_p.h9
-rw-r--r--src/qml/qml/parser/qqmljsparser.cpp426
-rw-r--r--src/qml/qml/parser/qqmljsparser_p.h11
-rw-r--r--src/qml/qml/qml.pri23
-rw-r--r--src/qml/qml/qqml.h25
-rw-r--r--src/qml/qml/qqmlaccessors_p.h4
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp285
-rw-r--r--src/qml/qml/qqmlapplicationengine.h80
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h88
-rw-r--r--src/qml/qml/qqmlbundle.cpp1
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp2
-rw-r--r--src/qml/qml/qqmlcompiler.cpp49
-rw-r--r--src/qml/qml/qqmlcomponent.h4
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h4
-rw-r--r--src/qml/qml/qqmlcontext.h4
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h4
-rw-r--r--src/qml/qml/qqmlengine.cpp89
-rw-r--r--src/qml/qml/qqmlengine.h5
-rw-r--r--src/qml/qml/qqmlengine_p.h4
-rw-r--r--src/qml/qml/qqmlerror.h4
-rw-r--r--src/qml/qml/qqmlexpression.h4
-rw-r--r--src/qml/qml/qqmlextensioninterface.h4
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp9
-rw-r--r--src/qml/qml/qqmlextensionplugin.h17
-rw-r--r--src/qml/qml/qqmlextensionplugin_p.h74
-rw-r--r--src/qml/qml/qqmlfile.h4
-rw-r--r--src/qml/qml/qqmlglobal.cpp86
-rw-r--r--src/qml/qml/qqmlglobal_p.h52
-rw-r--r--src/qml/qml/qqmlguard_p.h2
-rw-r--r--src/qml/qml/qqmlimport.cpp127
-rw-r--r--src/qml/qml/qqmlimport_p.h5
-rw-r--r--src/qml/qml/qqmlincubator.h4
-rw-r--r--src/qml/qml/qqmlinfo.h4
-rw-r--r--src/qml/qml/qqmllist.h4
-rw-r--r--src/qml/qml/qqmllocale.cpp7
-rw-r--r--src/qml/qml/qqmllocale_p.h4
-rw-r--r--src/qml/qml/qqmlmemoryprofiler_p.h3
-rw-r--r--src/qml/qml/qqmlmetatype.cpp666
-rw-r--r--src/qml/qml/qqmlmetatype_p.h15
-rw-r--r--src/qml/qml/qqmlnetworkaccessmanagerfactory.h4
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h4
-rw-r--r--src/qml/qml/qqmlparserstatus.h4
-rw-r--r--src/qml/qml/qqmlplatform.cpp83
-rw-r--r--src/qml/qml/qqmlplatform_p.h70
-rw-r--r--src/qml/qml/qqmlprivate.h18
-rw-r--r--src/qml/qml/qqmlproperty.h4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp2
-rw-r--r--src/qml/qml/qqmlpropertyvaluesource.h4
-rw-r--r--src/qml/qml/qqmlproxymetaobject_p.h4
-rw-r--r--src/qml/qml/qqmlscript.cpp2
-rw-r--r--src/qml/qml/qqmlscript_p.h4
-rw-r--r--src/qml/qml/qqmlscriptstring.h4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp99
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmltypenotavailable_p.h4
-rw-r--r--src/qml/qml/qqmlvme.cpp9
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp56
-rw-r--r--src/qml/qml/rewriter/textwriter_p.h3
-rw-r--r--src/qml/qml/v4/qv4bindings_p.h4
-rw-r--r--src/qml/qml/v4/qv4compiler_p.h4
-rw-r--r--src/qml/qml/v4/qv4compiler_p_p.h4
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h4
-rw-r--r--src/qml/qml/v4/qv4ir_p.h4
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp14
-rw-r--r--src/qml/qml/v4/qv4irbuilder_p.h8
-rw-r--r--src/qml/qml/v4/qv4program_p.h4
-rw-r--r--src/qml/qml/v8/qjsengine.h4
-rw-r--r--src/qml/qml/v8/qjsvalue.h4
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.h4
-rw-r--r--src/qml/qml/v8/qv8bindings_p.h4
-rw-r--r--src/qml/qml/v8/qv8domerrors_p.h4
-rw-r--r--src/qml/qml/v8/qv8engine.cpp19
-rw-r--r--src/qml/qml/v8/qv8engine_p.h14
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp6
-rw-r--r--src/qml/qml/v8/qv8sqlerrors_p.h4
-rw-r--r--src/qml/qml/v8/qv8worker.cpp12
-rw-r--r--src/qml/qtqmlglobal.h3
-rw-r--r--src/qml/types/qqmlbind.cpp (renamed from src/qml/qml/qqmlbind.cpp)10
-rw-r--r--src/qml/types/qqmlbind_p.h (renamed from src/qml/qml/qqmlbind_p.h)4
-rw-r--r--src/qml/types/qqmlconnections.cpp (renamed from src/qml/qml/qqmlconnections.cpp)6
-rw-r--r--src/qml/types/qqmlconnections_p.h (renamed from src/qml/qml/qqmlconnections_p.h)4
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp3189
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h234
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h411
-rw-r--r--src/qml/types/qqmlinstantiator.cpp459
-rw-r--r--src/qml/types/qqmlinstantiator_p.h109
-rw-r--r--src/qml/types/qqmlinstantiator_p_p.h90
-rw-r--r--src/qml/types/qqmllistmodel.cpp (renamed from src/qml/qml/qquicklistmodel.cpp)185
-rw-r--r--src/qml/types/qqmllistmodel_p.h (renamed from src/qml/qml/qquicklistmodel_p.h)44
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h (renamed from src/qml/qml/qquicklistmodel_p_p.h)36
-rw-r--r--src/qml/types/qqmllistmodelworkeragent.cpp (renamed from src/qml/qml/qquicklistmodelworkeragent.cpp)56
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h (renamed from src/qml/qml/qquicklistmodelworkeragent_p.h)26
-rw-r--r--src/qml/types/qqmlmodelsmodule.cpp60
-rw-r--r--src/qml/types/qqmlmodelsmodule_p.h57
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp269
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h170
-rw-r--r--src/qml/types/qqmltimer.cpp (renamed from src/qml/qml/qqmltimer.cpp)18
-rw-r--r--src/qml/types/qqmltimer_p.h (renamed from src/qml/qml/qqmltimer_p.h)4
-rw-r--r--src/qml/types/qquickpackage.cpp198
-rw-r--r--src/qml/types/qquickpackage_p.h92
-rw-r--r--src/qml/types/qquickworkerscript.cpp (renamed from src/qml/qml/qquickworkerscript.cpp)10
-rw-r--r--src/qml/types/qquickworkerscript_p.h (renamed from src/qml/qml/qquickworkerscript_p.h)6
-rw-r--r--src/qml/types/types.pri28
-rw-r--r--src/qml/util/qqmladaptormodel.cpp977
-rw-r--r--src/qml/util/qqmladaptormodel_p.h154
-rw-r--r--src/qml/util/qqmlchangeset.cpp621
-rw-r--r--src/qml/util/qqmlchangeset_p.h167
-rw-r--r--src/qml/util/qqmllistaccessor.cpp138
-rw-r--r--src/qml/util/qqmllistaccessor_p.h74
-rw-r--r--src/qml/util/qqmllistcompositor.cpp1484
-rw-r--r--src/qml/util/qqmllistcompositor_p.h375
-rw-r--r--src/qml/util/qqmlpropertymap.h8
-rw-r--r--src/qml/util/util.pri8
162 files changed, 12946 insertions, 2276 deletions
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index 29e263abe7..abf3cd6df6 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -47,8 +47,6 @@
#include <QtCore/private/qabstractanimation_p.h>
#include "private/qpodvector_p.h"
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QAnimationGroupJob;
@@ -235,6 +233,4 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractAnimationJob::ChangeTypes)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QABSTRACTANIMATIONJOB_P_H
diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h
index 2c27e96691..0f62194656 100644
--- a/src/qml/animations/qanimationgroupjob_p.h
+++ b/src/qml/animations/qanimationgroupjob_p.h
@@ -44,8 +44,6 @@
#include "private/qabstractanimationjob_p.h"
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QAnimationGroupJob : public QAbstractAnimationJob
@@ -86,6 +84,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif //QANIMATIONGROUPJOB_P_H
diff --git a/src/qml/animations/qparallelanimationgroupjob_p.h b/src/qml/animations/qparallelanimationgroupjob_p.h
index 5f896a8bc9..8e29402f33 100644
--- a/src/qml/animations/qparallelanimationgroupjob_p.h
+++ b/src/qml/animations/qparallelanimationgroupjob_p.h
@@ -44,8 +44,6 @@
#include "private/qanimationgroupjob_p.h"
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QParallelAnimationGroupJob : public QAnimationGroupJob
@@ -74,6 +72,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QPARALLELANIMATIONGROUPJOB_P_H
diff --git a/src/qml/animations/qpauseanimationjob_p.h b/src/qml/animations/qpauseanimationjob_p.h
index 83e0553116..f84143d9bf 100644
--- a/src/qml/animations/qpauseanimationjob_p.h
+++ b/src/qml/animations/qpauseanimationjob_p.h
@@ -44,8 +44,6 @@
#include <private/qanimationgroupjob_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QPauseAnimationJob : public QAbstractAnimationJob
@@ -68,6 +66,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QPAUSEANIMATIONJOB_P_H
diff --git a/src/qml/animations/qsequentialanimationgroupjob_p.h b/src/qml/animations/qsequentialanimationgroupjob_p.h
index fce83b094c..18dc6fcc7b 100644
--- a/src/qml/animations/qsequentialanimationgroupjob_p.h
+++ b/src/qml/animations/qsequentialanimationgroupjob_p.h
@@ -44,8 +44,6 @@
#include <private/qanimationgroupjob_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QPauseAnimationJob;
@@ -101,6 +99,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif //QSEQUENTIALANIMATIONGROUPJOB_P_H
diff --git a/src/qml/debugger/qdebugmessageservice_p.h b/src/qml/debugger/qdebugmessageservice_p.h
index 911f9fe3ed..dbd05646c9 100644
--- a/src/qml/debugger/qdebugmessageservice_p.h
+++ b/src/qml/debugger/qdebugmessageservice_p.h
@@ -57,8 +57,6 @@
#include <QtCore/qlogging.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QDebugMessageServicePrivate;
@@ -84,6 +82,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QDEBUGMESSAGESERVICE_P_H
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index 3232f6bb6f..d2b0220bc6 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -44,8 +44,6 @@
#include <QtQml/qtqmlglobal.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -63,6 +61,4 @@ static QQmlDebuggingEnabler qmlEnableDebuggingHelper(true);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUG_H
diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp
index 7c9928c43c..27e3d226cd 100644
--- a/src/qml/debugger/qqmldebugserver.cpp
+++ b/src/qml/debugger/qqmldebugserver.cpp
@@ -123,8 +123,9 @@ public:
m_pluginName = pluginName;
}
- void setPort(int port, bool block, QString &hostAddress) {
- m_port = port;
+ void setPortRange(int portFrom, int portTo, bool block, QString &hostAddress) {
+ m_portFrom = portFrom;
+ m_portTo = portTo;
m_block = block;
m_hostAddress = hostAddress;
}
@@ -133,7 +134,8 @@ public:
private:
QString m_pluginName;
- int m_port;
+ int m_portFrom;
+ int m_portTo;
bool m_block;
QString m_hostAddress;
};
@@ -225,7 +227,7 @@ void QQmlDebugServerThread::run()
= server->d_func()->loadConnectionPlugin(m_pluginName);
if (connection) {
connection->setServer(QQmlDebugServer::instance());
- connection->setPort(m_port, m_block, m_hostAddress);
+ connection->setPortRange(m_portFrom, m_portTo, m_block, m_hostAddress);
} else {
QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
qWarning() << QString(QLatin1String("QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
@@ -272,12 +274,13 @@ QQmlDebugServer *QQmlDebugServer::instance()
QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
#ifndef QT_QML_NO_DEBUGGER
// ### remove port definition when protocol is changed
- int port = 0;
+ int portFrom = 0;
+ int portTo = 0;
bool block = false;
bool ok = false;
QString hostAddress;
- // format: qmljsdebugger=port:3768[,host:<ip address>][,block] OR qmljsdebugger=ost[,block]
+ // format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block]
if (!appD->qmljsDebugArgumentsString().isEmpty()) {
if (!QQmlEnginePrivate::qml_debugging_enabled) {
qWarning() << QString(QLatin1String(
@@ -290,9 +293,21 @@ QQmlDebugServer *QQmlDebugServer::instance()
QString pluginName;
QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString()
.split(QLatin1Char(','));
- foreach (const QString &strArgument, lstjsDebugArguments) {
+ QStringList::const_iterator argsItEnd = lstjsDebugArguments.end();
+ QStringList::const_iterator argsIt = lstjsDebugArguments.begin();
+ for (; argsIt != argsItEnd; ++argsIt) {
+ const QString strArgument = *argsIt;
if (strArgument.startsWith(QLatin1String("port:"))) {
- port = strArgument.mid(5).toInt(&ok);
+ portFrom = strArgument.mid(5).toInt(&ok);
+ portTo = portFrom;
+ QStringList::const_iterator argsNext = argsIt + 1;
+ if (argsNext == argsItEnd)
+ break;
+ const QString nextArgument = *argsNext;
+ if (ok && nextArgument.contains(QRegExp(QStringLiteral("^\\s*\\d+\\s*$")))) {
+ portTo = nextArgument.toInt(&ok);
+ ++argsIt;
+ }
pluginName = QLatin1String("qmldbg_tcp");
} else if (strArgument.startsWith(QLatin1String("host:"))) {
hostAddress = strArgument.mid(5);
@@ -311,7 +326,7 @@ QQmlDebugServer *QQmlDebugServer::instance()
qQmlDebugServer->d_func()->thread = thread;
qQmlDebugServer->moveToThread(thread);
thread->setPluginName(pluginName);
- thread->setPort(port, block, hostAddress);
+ thread->setPortRange(portFrom, portTo, block, hostAddress);
QQmlDebugServerPrivate *d = qQmlDebugServer->d_func();
d->blockingMode = block;
@@ -325,8 +340,8 @@ QQmlDebugServer *QQmlDebugServer::instance()
} else {
qWarning() << QString(QLatin1String(
"QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
- "Format is -qmljsdebugger=port:<port>[,block]")).arg(
- appD->qmljsDebugArgumentsString());
+ "Format is qmljsdebugger=port:<port_from>[,port_to],host:"
+ "<ip address>][,block]")).arg(appD->qmljsDebugArgumentsString());
}
}
#else
diff --git a/src/qml/debugger/qqmldebugserver_p.h b/src/qml/debugger/qqmldebugserver_p.h
index d38b1d0147..27d54d6947 100644
--- a/src/qml/debugger/qqmldebugserver_p.h
+++ b/src/qml/debugger/qqmldebugserver_p.h
@@ -57,8 +57,6 @@
// We mean it.
//
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -104,6 +102,4 @@ public:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/qml/debugger/qqmldebugserverconnection_p.h b/src/qml/debugger/qqmldebugserverconnection_p.h
index a622855071..a7c35c2d2f 100644
--- a/src/qml/debugger/qqmldebugserverconnection_p.h
+++ b/src/qml/debugger/qqmldebugserverconnection_p.h
@@ -56,8 +56,6 @@
// We mean it.
//
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -69,7 +67,7 @@ public:
virtual ~QQmlDebugServerConnection() {}
virtual void setServer(QQmlDebugServer *server) = 0;
- virtual void setPort(int port, bool bock, const QString &hostaddress) = 0;
+ virtual void setPortRange(int portFrom, int portTo, bool bock, const QString &hostaddress) = 0;
virtual bool isConnected() const = 0;
virtual void send(const QList<QByteArray> &messages) = 0;
virtual void disconnect() = 0;
@@ -82,6 +80,4 @@ Q_DECLARE_INTERFACE(QQmlDebugServerConnection, QQmlDebugServerConnection_iid)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUGSERVERCONNECTION_H
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 3e7b2f11f3..71a116f6a5 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -58,8 +58,6 @@
// We mean it.
//
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -121,7 +119,5 @@ public:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/qml/debugger/qqmldebugservice_p_p.h b/src/qml/debugger/qqmldebugservice_p_p.h
index f81a8285eb..940990f628 100644
--- a/src/qml/debugger/qqmldebugservice_p_p.h
+++ b/src/qml/debugger/qqmldebugservice_p_p.h
@@ -56,8 +56,6 @@
#include <QtCore/qglobal.h>
#include <private/qobject_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -77,6 +75,4 @@ public:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmldebugstatesdelegate_p.h b/src/qml/debugger/qqmldebugstatesdelegate_p.h
index 8beb4303de..7197b8cc3b 100644
--- a/src/qml/debugger/qqmldebugstatesdelegate_p.h
+++ b/src/qml/debugger/qqmldebugstatesdelegate_p.h
@@ -57,8 +57,6 @@
#include <QtCore/QList>
#include <QtCore/QPointer>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -96,6 +94,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLDEBUGSTATESDELEGATE_P_H
diff --git a/src/qml/debugger/qqmlinspectorinterface_p.h b/src/qml/debugger/qqmlinspectorinterface_p.h
index 1bc25937e9..0b4020c4a7 100644
--- a/src/qml/debugger/qqmlinspectorinterface_p.h
+++ b/src/qml/debugger/qqmlinspectorinterface_p.h
@@ -56,8 +56,6 @@
#include <QtQml/qtqmlglobal.h>
#include <private/qqmlglobal_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -81,6 +79,4 @@ Q_DECLARE_INTERFACE(QQmlInspectorInterface, QQmlInspectorInterface_iid)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLINSPECTORINTERFACE_H
diff --git a/src/qml/debugger/qqmlinspectorservice_p.h b/src/qml/debugger/qqmlinspectorservice_p.h
index de97e1798d..f8b2a39240 100644
--- a/src/qml/debugger/qqmlinspectorservice_p.h
+++ b/src/qml/debugger/qqmlinspectorservice_p.h
@@ -58,8 +58,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/QList>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -96,6 +94,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLINSPECTORSERVICE_H
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index d5443aaef6..a50fb5ea08 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -64,8 +64,6 @@
#include <QtCore/qwaitcondition.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
struct Q_AUTOTEST_EXPORT QQmlProfilerData
@@ -292,7 +290,5 @@ struct QQmlCompilingProfiler {
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPROFILERSERVICE_P_H
diff --git a/src/qml/debugger/qv8debugservice_p.h b/src/qml/debugger/qv8debugservice_p.h
index c93948c402..00ecf557c3 100644
--- a/src/qml/debugger/qv8debugservice_p.h
+++ b/src/qml/debugger/qv8debugservice_p.h
@@ -56,8 +56,6 @@
#include "qqmldebugservice_p.h"
#include <private/qv8debug_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -100,6 +98,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV8DEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qv8profilerservice_p.h b/src/qml/debugger/qv8profilerservice_p.h
index 6a8c1e8c3b..10906442f5 100644
--- a/src/qml/debugger/qv8profilerservice_p.h
+++ b/src/qml/debugger/qv8profilerservice_p.h
@@ -55,8 +55,6 @@
#include <private/qqmldebugservice_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -115,6 +113,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV8PROFILERSERVICE_P_H
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index d29f1454b9..4ce44ba46e 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -20,7 +20,7 @@ qhp.QtQml.customFilters.Qt.name = QtQml $QT_VERSION
qhp.QtQml.customFilters.Qt.filterAttributes = qtqml $QT_VERSION
qhp.QtQml.subprojects = classes examples
qhp.QtQml.subprojects.classes.title = C++ Classes
-qhp.QtQml.subprojects.classes.indexTitle = Qt QML Module C++ Classes
+qhp.QtQml.subprojects.classes.indexTitle = Qt QML C++ Classes
qhp.QtQml.subprojects.classes.selectors = class fake:headerfile
qhp.QtQml.subprojects.classes.sortPages = true
qhp.QtQml.subprojects.examples.title = Examples
diff --git a/src/qml/doc/src/cppintegration/contextproperties.qdoc b/src/qml/doc/src/cppintegration/contextproperties.qdoc
index b40eec7f6e..aaac43e470 100644
--- a/src/qml/doc/src/cppintegration/contextproperties.qdoc
+++ b/src/qml/doc/src/cppintegration/contextproperties.qdoc
@@ -77,7 +77,7 @@ QML code invokes a method on the object instance:
\l{QML:Qt::formatDateTime}{Qt.formatDateTime()} and associated functions.)
If the QML item needs to receive signals from the context property, it can connect to them using the
-\l Connections element. For example, if \c ApplicationData has a signal named \c
+\l Connections type. For example, if \c ApplicationData has a signal named \c
dataChanged(), this signal can be connected to using an \c onDataChanged handler within
a \l Connections object:
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 84eb4bb2cd..be5f26a865 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -168,7 +168,7 @@ are constructed and owned by the QQmlEngine, and will be destroyed when
the engine is destroyed.
A QObject singleton type can be interacted with in a manner simlar to any
-other QObject or instantiated element, except that only one (engine constructed
+other QObject or instantiated type, except that only one (engine constructed
and owned) instance will exist, and it must be referenced by type name rather
than id. Q_PROPERTYs of QObject singleton types may be bound to, and Q_INVOKABLE
functions of QObject module APIs may be used in signal handler expressions.
@@ -230,7 +230,7 @@ version of their type definition, \c root.x now resolves to a different value
because \c root is also the \c id of the top level component. The author could
specify that the new \c root property is available from a specific minor
version. This permits new properties and features to be added to existing
-elements without breaking existing programs.
+types without breaking existing programs.
The REVISION tag is used to mark the \c root property as added in revision 1
of the type. Methods such as Q_INVOKABLE's, signals and slots can also be
@@ -263,7 +263,7 @@ qmlRegisterType<CppType,1>("MyTypes", 1, 1, "CppType")
\c root is only available when \c MyTypes version 1.1 is imported.
-For the same reason, new elements introduced in later versions should use
+For the same reason, new types introduced in later versions should use
the minor version argument of qmlRegisterType.
This feature of the language allows for behavioural changes to be made
diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
index 3cba89eb67..3253752e47 100644
--- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
+++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
@@ -67,12 +67,12 @@ and \l {qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}.
\example tutorials/extending/chapter1-basics
A common task when extending QML is to provide a new QML type that supports some
- custom functionality beyond what is provided by the built-in \l {Qt Quick QML Types}{QtQuick types}.
+ custom functionality beyond what is provided by the built-in \l {Qt Quick QML Types}{Qt Quick types}.
For example, this could be done to implement particular data models, or provide
-elements with custom painting and drawing capabilities, or access system features
+types with custom painting and drawing capabilities, or access system features
like network programming that are not accessible through built-in QML features.
-In this tutorial, we will show how to use the C++ classes in the Qt Declarative
+In this tutorial, we will show how to use the C++ classes in the Qt Quick
module to extend QML. The end result will be a simple Pie Chart display implemented by
several custom QML types connected together through QML features like bindings and
signals, and made available to the QML runtime through a plugin.
@@ -210,8 +210,8 @@ Try out the example yourself with the updated code in Qt's \c examples/quick/tut
\example tutorials/extending/chapter3-bindings
Property binding is a powerful feature of QML that allows values of different
-elements to be synchronized automatically. It uses signals to notify and update
-other elements' values when property values are changed.
+types to be synchronized automatically. It uses signals to notify and update
+other types' values when property values are changed.
Let's enable property bindings for the \c color property. That means
if we have code like this:
@@ -245,7 +245,7 @@ Then, we emit this signal in \c setPieSlice():
It's important for \c setColor() to check that the color value has actually changed
before emitting \c colorChanged(). This ensures the signal is not emitted unnecessarily and
-also prevents loops when other elements respond to the value change.
+also prevents loops when other types respond to the value change.
The use of bindings is essential to QML. You should always add NOTIFY
signals for properties if they are able to be implemented, so that your
diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
index 04b278106f..15d98ec405 100644
--- a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
+++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
@@ -143,7 +143,7 @@ or QObject::setProperty() and QObject::property():
You should always use QObject::setProperty(), QQmlProperty or
QMetaProperty::write() to change a QML property value, to ensure the QML
engine is made aware of the property change. For example, say you have a
-custom element \c PushButton with a \c buttonText property that internally
+custom type \c PushButton with a \c buttonText property that internally
reflects the value of a \c m_buttonText member variable. Modifying the member
variable directly like this is not a good idea:
diff --git a/src/qml/doc/src/documents/definetypes.qdoc b/src/qml/doc/src/documents/definetypes.qdoc
index 97a841ccb8..b9df6a4381 100644
--- a/src/qml/doc/src/documents/definetypes.qdoc
+++ b/src/qml/doc/src/documents/definetypes.qdoc
@@ -34,7 +34,7 @@ One of the core features of QML is that it enables QML object types to be easily
\section1 Defining an Object Type with a QML File
-To create an object type, a QML document should be placed into a text file named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type, beginning with an uppercase letter. This document is then automatically recognized by the engine as a definition of a QML type. Additionally, a type defined in this manner is automatically made available to other QML files within the same directory as the engine searches within the immediate directory when resolving QML type names.
+To create an object type, a QML document should be placed into a text file named as \e <TypeName>.qml where \e <TypeName> is the desired name of the type, which must be comprised of alphanumeric characters or underscores and beginning with an uppercase letter. This document is then automatically recognized by the engine as a definition of a QML type. Additionally, a type defined in this manner is automatically made available to other QML files within the same directory as the engine searches within the immediate directory when resolving QML type names.
For example, below is a document that declares a \l Rectangle with a child \l MouseArea. The document has been saved to file named \c SquareButton.qml:
diff --git a/src/qml/doc/src/documents/scope.qdoc b/src/qml/doc/src/documents/scope.qdoc
index e72b07d092..9da77a4905 100644
--- a/src/qml/doc/src/documents/scope.qdoc
+++ b/src/qml/doc/src/documents/scope.qdoc
@@ -74,11 +74,11 @@ Every JavaScript expression, function or file in QML has its own unique
variable object. Local variables declared in one will never conflict
with local variables declared in another.
-\section1 Element Names and Imported JavaScript Files
+\section1 Type Names and Imported JavaScript Files
-\l {QML Document}s include import statements that define the element names
+\l {QML Document}s include import statements that define the type names
and JavaScript files visible to the document. In addition to their use in the
-QML declaration itself, element names are used by JavaScript code when accessing
+QML declaration itself, type names are used by JavaScript code when accessing
\l {Attached Properties} and enumeration values.
The effect of an import applies to every property binding, and JavaScript
@@ -130,10 +130,10 @@ Consequently unqualified attached property reads will always resolve to an
attached property on the scope object, which is not always what the programmer
intended.
-For example, the \l PathView element attaches interpolated value properties to
+For example, the \l PathView type attaches interpolated value properties to
its delegates depending on their position in the path. As PathView only
-meaningfully attaches these properties to the root element in the delegate, any
-sub-element that accesses them must explicitly qualify the root object, as shown
+meaningfully attaches these properties to the root object in the delegate, any
+sub-object that accesses them must explicitly qualify the root object, as shown
below.
\code
@@ -149,7 +149,7 @@ PathView {
}
\endcode
-If the \l Image element omitted the \c root prefix, it would inadvertently access
+If the \l Image object omitted the \c root prefix, it would inadvertently access
the unset \c {PathView.scale} attached property on itself.
\section1 Component Scope
@@ -157,21 +157,21 @@ the unset \c {PathView.scale} attached property on itself.
Each QML component in a QML document defines a logical scope. Each document
has at least one root component, but can also have other inline sub-components.
The component scope is the union of the object ids within the component and the
-component's root element's properties.
+component's root object's properties.
\code
Item {
property string title
Text {
- id: titleElement
+ id: title
text: "<b>" + title + "</b>"
font.pixelSize: 22
anchors.top: parent.top
}
Text {
- text: titleElement.text
+ text: title.text
font.pixelSize: 18
anchors.bottom: parent.bottom
}
@@ -180,15 +180,15 @@ Item {
The example above shows a simple QML component that displays a rich text title
string at the top, and a smaller copy of the same text at the bottom. The first
-\c Text element directly accesses the component's \c title property when
-forming the text to display. That the root element's properties are directly
+\c Text type directly accesses the component's \c title property when
+forming the text to display. That the root type's properties are directly
accessible makes it trivial to distribute data throughout the component.
-The second \c Text element uses an id to access the first's text directly. IDs
+The second \c Text type uses an id to access the first's text directly. IDs
are specified explicitly by the QML programmer so they always take precedence
over other property names (except for those in the \l {JavaScript Scope}). For
example, in the unlikely event that the binding's \l {Binding Scope Object}{scope
-object} had a \c titleElement property in the previous example, the \c titleElement
+object} had a \c titletype property in the previous example, the \c titletype
id would still take precedence.
\section1 Component Instance Hierarchy
@@ -215,13 +215,13 @@ Item {
\endcode
The component instance hierarchy allows instances of the delegate component
-to access the \c defaultColor property of the \c Item element. Of course,
+to access the \c defaultColor property of the \c Item type. Of course,
had the delegate component had a property called \c defaultColor that would
have taken precedence.
The component instance scope hierarchy extends to out-of-line components, too.
In the following example, the \c TitlePage.qml component creates two
-\c TitleText instances. Even though the \c TitleText element is in a separate
+\c TitleText instances. Even though the \c TitleText type is in a separate
file, it still has access to the \c title property when it is used from within
the \c TitlePage. QML is a dynamically scoped language - depending on where it
is used, the \c title property may resolve differently.
@@ -341,7 +341,7 @@ will refer to one or the other, but not both.
\section1 JavaScript Global Object
-QML disallows element, id and property names that conflict with the properties
+QML disallows type, id and property names that conflict with the properties
on the global object to prevent any confusion. Programmers can be confident
that \c Math.min(10, 9) will always work as expected!
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index a90d794864..a8e6fc8ac0 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -142,7 +142,7 @@ QML object types can emit signals in reaction to certain events occurring.
Those signals can be handled by signal handler functions, which can be defined
by clients to implement custom program logic.
-Suppose that a button represented by a Rectangle element has a MouseArea and a
+Suppose that a button represented by a Rectangle type has a MouseArea and a
Text label. The MouseArea will emit its "pressed" signal when the user presses
the defined interactive area, which will automatically trigger the
\l{MouseArea::}{onPressed} handler, which can be defined by clients. The QML
diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc
index 7a517c77d5..a63ef617c0 100644
--- a/src/qml/doc/src/javascript/hostenvironment.qdoc
+++ b/src/qml/doc/src/javascript/hostenvironment.qdoc
@@ -144,7 +144,7 @@ The \c this keyword is supported when binding properties from JavaScript.
In all other situations, the value of
\c this is undefined in QML.
-To refer to any element, provide an \c id. For example:
+To refer to a specific object, provide an \c id. For example:
\qml
Item {
diff --git a/src/qml/doc/src/modules/cppplugins.qdoc b/src/qml/doc/src/modules/cppplugins.qdoc
index a5fbafbdfc..af2a36c903 100644
--- a/src/qml/doc/src/modules/cppplugins.qdoc
+++ b/src/qml/doc/src/modules/cppplugins.qdoc
@@ -65,7 +65,7 @@
\section1 Plugin Example
Suppose there is a new \c TimeModel C++ class that should be made available
- as a new QML element. It provides the current time through \c hour and \c minute
+ as a new QML type. It provides the current time through \c hour and \c minute
properties.
\snippet qml/plugins/plugin.cpp 0
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index da62ddab6a..4a4de0531c 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -289,7 +289,7 @@
of the given type T as a singleton type.
A QObject singleton type may be referenced via the type name with which it was registered, and this
- typename may be used as the target in a \l Connections element or otherwise used as any other element id would.
+ typename may be used as the target in a \l Connections type or otherwise used as any other type id would.
One exception to this is that a QObject singleton type property may not be aliased (because the
singleton type name does not identify an object within the same component as any other item).
@@ -380,3 +380,20 @@
\endcode
*/
+
+/*!
+ \fn int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName);
+ \relates QQmlEngine
+
+ This function registers a type in the QML system with the name \a qmlName, in the library imported from \a uri having the
+ version number composed from \a versionMajor and \a versionMinor. The type is defined by the QML file located at \a url. The
+ url must be an absolute URL, i.e. url.isRelative() == false.
+
+ Normally QML files can be loaded as types directly from other QML files, or using a qmldir file. This function allows
+ registration of files to types from a C++ module, such as when the type mapping needs to be procedurally determined at startup.
+
+ #include <QtQml> to use this function.
+
+ Returns non-zero if the registration was sucessful.
+*/
+
diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc
index 203bdd3eb9..799945fa37 100644
--- a/src/qml/doc/src/qmltypereference.qdoc
+++ b/src/qml/doc/src/qmltypereference.qdoc
@@ -25,9 +25,10 @@
**
****************************************************************************/
/*!
-\page qtqml-typereference-topic.html
-\title QML Types Provided By The QtQml Module
-\brief List of QML types provided by the QtQml module
+\qmlmodule QtQml 2
+\title Qt QML QML Types
+\ingroup qmlmodules
+\brief List of QML types provided by the Qt QML module
The \c QtQml module provides the definition and implementation of various
convenience types which can be used with the QML language, including some
@@ -59,11 +60,11 @@ and functionality provided by the \c QtQml namespace are also provided by the
import QtQuick 2.0
\endqml
-See the \l{QtQuick}{QtQuick} module documentation for more information about the
+See the \l{Qt Quick} module documentation for more information about the
\c QtQuick namespace and what it provides to QML application developers.
The documentation for the types below applies equally to the types of the same
-name provided by the \l{QtQuick}{QtQuick} module, as they are in fact identical.
+name provided by the \l{Qt Quick} module, as they are in fact identical.
\section1 Basic Types
@@ -153,7 +154,6 @@ run-time:
}
}
\endcode
-
*/
/*!
diff --git a/src/qml/doc/src/qtqml-cpp.qdoc b/src/qml/doc/src/qtqml-cpp.qdoc
index 5470b00fb8..74e59d2540 100644
--- a/src/qml/doc/src/qtqml-cpp.qdoc
+++ b/src/qml/doc/src/qtqml-cpp.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
\module QtQml
-\title Qt QML Module C++ Classes
+\title Qt QML C++ Classes
\brief The C++ API provided by the Qt QML module
To include the definitions of the module's classes, use the
diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc
index 12a791899e..05a33f351a 100644
--- a/src/qml/doc/src/qtqml.qdoc
+++ b/src/qml/doc/src/qtqml.qdoc
@@ -39,8 +39,8 @@ developers to extend the QML language with custom types and integrate QML code
with JavaScript and C++.
The Qt QML module provides both the \c QtQml QML module, which supplies
-\l{Qt QML Module - C++ Classes}{a set of core QML types} for creating QML
-applications, and the \c QtQml C++ module, which supplies \l{Qt QML Module - C++ Classes}{a set of C++
+\l{Qt QML QML Types}{a set of core QML types} for creating QML
+applications, and the \c QtQml C++ module, which supplies \l{Qt QML C++ Classes}{a set of C++
APIs} for extending QML applications with custom types and integrating C++
implementations with QML applications.
@@ -102,7 +102,7 @@ for an introduction to writing QML applications.
\li \l{qtqml-documents-scope.html}{Scope and Naming Resolution}
\endlist
- \li \l{qtqml-typereference-topic.html}{QML Types Provided by the QtQml Module}
+ \li \l{qtqml-typereference-topic.html}{QML Types Provided by the Qt QML Module}
\list
\li \l{qtqml-typereference-topic.html#importing-qtqml}{Importing \c QtQml}
\li \l{qtqml-typereference-topic.html#basic-types}{Basic Types}
@@ -170,7 +170,7 @@ for an introduction to writing QML applications.
Additional Qt QML information:
\list
-\li \l{Qt QML Module - C++ Classes} - the C++ API provided by the
+\li \l{Qt QML C++ Classes} - the C++ API provided by the
Qt QML module
\li \l{Qt QML Release Notes} - list of changes and
additions in the Qt QML module
diff --git a/src/qml/doc/src/typesystem/basictypes.qdoc b/src/qml/doc/src/typesystem/basictypes.qdoc
index f8b050e7fe..6f468d42bc 100644
--- a/src/qml/doc/src/typesystem/basictypes.qdoc
+++ b/src/qml/doc/src/typesystem/basictypes.qdoc
@@ -132,7 +132,7 @@ property is only invoked when the property is reassigned to a different object v
The \c int type refers to a whole number, e.g. 0, 10, or -20.
The possible \c int values range from around -2000000000 to around 2000000000,
- although most elements will only accept a reduced range (which they
+ although most types will only accept a reduced range (which they
mention in their documentation).
Example:
@@ -673,4 +673,3 @@ property is only invoked when the property is reassigned to a different object v
\sa {QML Basic Types}
*/
-
diff --git a/src/qml/doc/src/whatsnew.qdoc b/src/qml/doc/src/whatsnew.qdoc
index e6c02c06e9..361f6e61ee 100644
--- a/src/qml/doc/src/whatsnew.qdoc
+++ b/src/qml/doc/src/whatsnew.qdoc
@@ -30,10 +30,10 @@
\page qtqml-releasenotes.html
\inqmlmodule QtQuick 2.0
-\section1 Qt 5.0
+\section1 Qt QML in Qt 5
-The QtQml C++ module is new in Qt 5. It provides the QML engine and implements
-the QML language supporting infrastructure.
+The \l{Qt QML} module is new in Qt 5.0. It provides the QML engine and
+implements the QML language supporting infrastructure.
(Prior to Qt 5, this functionality was provided by the QtDeclarative module, which
has now been replaced by the new QtQml and QtQuick C++ modules. See the
@@ -100,4 +100,3 @@ has now been replaced by the new QtQml and QtQuick C++ modules. See the
\endlist
*/
-
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 4f55b83e14..8dbe0c65d1 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -25,3 +25,4 @@ include(util/util.pri)
include(qml/qml.pri)
include(debugger/debugger.pri)
include(animations/animations.pri)
+include(types/types.pri)
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 5fc8443ecd..cdf0717e3a 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -262,8 +262,9 @@ public:
inline uint16_t *utf16Data() const { return (uint16_t *)strData->data(); }
inline bool equals(v8::Handle<v8::String> string) const {
- return isQString()?string->Equals(utf16Data(), length):
- string->Equals(cStrData(), length);
+ v8::Local<v8::String> data = isQString() ? v8::String::New(utf16Data(), length)
+ : v8::String::New(cStrData(), length);
+ return string->Equals(data);
}
inline bool symbolEquals(const QHashedV8String &string) const {
@@ -1183,8 +1184,11 @@ QString QHashedV8String::toString() const
QString result;
result.reserve(m_hash.length);
+ v8::String::Value value(m_string);
+ Q_ASSERT(*value != NULL);
+ uint16_t* string = *value;
for (int i = 0; i < m_hash.length; ++i)
- result.append(m_string->GetCharacter(i));
+ result.append(string[i]);
return result;
}
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h
index 0bc3ea038a..24c3e7a2cc 100644
--- a/src/qml/qml/ftw/qqmlrefcount_p.h
+++ b/src/qml/qml/ftw/qqmlrefcount_p.h
@@ -56,8 +56,6 @@
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -193,6 +191,4 @@ QQmlRefPointer<T> &QQmlRefPointer<T>::take(T *other)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLREFCOUNT_P_H
diff --git a/src/qml/qml/parser/qqmljs.g b/src/qml/qml/parser/qqmljs.g
index df891da992..ff4f54374b 100644
--- a/src/qml/qml/parser/qqmljs.g
+++ b/src/qml/qml/parser/qqmljs.g
@@ -24,7 +24,7 @@
%parser QQmlJSGrammar
%decl qqmljsparser_p.h
%impl qqmljsparser.cpp
-%expect 2
+%expect 5
%expect-rr 2
%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
@@ -67,6 +67,8 @@
%token T_IMPORT "import"
%token T_AS "as"
%token T_ON "on"
+%token T_GET "get"
+%token T_SET "set"
%token T_ERROR
@@ -79,7 +81,7 @@
%token T_FEED_JS_PROGRAM
%nonassoc SHIFT_THERE
-%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY
+%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET
%nonassoc REDUCE_HERE
%start TopLevel
@@ -125,16 +127,16 @@
**
****************************************************************************/
-#include <QtCore/QtDebug>
-#include <QtCore/QCoreApplication>
-
-#include <string.h>
-
#include "qqmljsengine_p.h"
#include "qqmljslexer_p.h"
#include "qqmljsast_p.h"
#include "qqmljsmemorypool_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <string.h>
+
./
/:/****************************************************************************
@@ -210,8 +212,8 @@
#include "qqmljsast_p.h"
#include "qqmljsengine_p.h"
-#include <QtCore/QList>
-#include <QtCore/QString>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
QT_QML_BEGIN_NAMESPACE
@@ -240,7 +242,8 @@ public:
AST::FunctionDeclaration *FunctionDeclaration;
AST::Node *Node;
AST::PropertyName *PropertyName;
- AST::PropertyNameAndValueList *PropertyNameAndValueList;
+ AST::PropertyAssignment *PropertyAssignment;
+ AST::PropertyAssignmentList *PropertyAssignmentList;
AST::SourceElement *SourceElement;
AST::SourceElements *SourceElements;
AST::Statement *Statement;
@@ -388,7 +391,8 @@ protected:
/.
#include "qqmljsparser_p.h"
-#include <QVarLengthArray>
+
+#include <QtCore/qvarlengtharray.h>
//
// W A R N I N G
@@ -1043,6 +1047,8 @@ JsIdentifier: T_PROPERTY ;
JsIdentifier: T_SIGNAL ;
JsIdentifier: T_READONLY ;
JsIdentifier: T_ON ;
+JsIdentifier: T_GET ;
+JsIdentifier: T_SET ;
--------------------------------------------------------------------------------------------------------
-- Expressions
@@ -1219,13 +1225,13 @@ case $rule_number: {
-- } break;
-- ./
-PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
+PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ;
/.
case $rule_number: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyNameAndValueList->finish ());
+ sym(2).PropertyAssignmentList->finish ());
else
node = new (pool) AST::ObjectLiteral();
node->lbraceToken = loc(1);
@@ -1234,11 +1240,11 @@ case $rule_number: {
} break;
./
-PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ;
+PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ;
/.
case $rule_number: {
AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyNameAndValueList->finish ());
+ sym(2).PropertyAssignmentList->finish ());
node->lbraceToken = loc(1);
node->rbraceToken = loc(4);
sym(1).Node = node;
@@ -1330,40 +1336,62 @@ case $rule_number: {
} break;
./
-PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
+PropertyAssignment: PropertyName T_COLON AssignmentExpression ;
/.
case $rule_number: {
- AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
+ AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
./
-PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
+PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
- AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
- sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
- node->commaToken = loc(2);
- node->colonToken = loc(4);
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
+ sym(2).PropertyName, sym(6).FunctionBody);
+ node->getSetToken = loc(1);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
sym(1).Node = node;
} break;
./
-PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
+PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
+ sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody);
+ node->getSetToken = loc(1);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(5);
+ node->lbraceToken = loc(6);
+ node->rbraceToken = loc(8);
sym(1).Node = node;
} break;
./
-PropertyName: T_SIGNAL ;
-/.case $rule_number:./
+PropertyAssignmentList: PropertyAssignment ;
+/.
+case $rule_number: {
+ sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
+} break;
+./
+
+PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ;
+/.
+case $rule_number: {
+ AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
+ sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+} break;
+./
-PropertyName: T_PROPERTY ;
+PropertyName: JsIdentifier %prec SHIFT_THERE ;
/.
case $rule_number: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
@@ -2669,20 +2697,7 @@ case $rule_number: {
} break;
./
-LabelledStatement: T_SIGNAL T_COLON Statement ;
-/.case $rule_number:./
-
-LabelledStatement: T_PROPERTY T_COLON Statement ;
-/.
-case $rule_number: {
- AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
- node->identifierToken = loc(1);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-./
-
-LabelledStatement: T_IDENTIFIER T_COLON Statement ;
+LabelledStatement: JsIdentifier T_COLON Statement ;
/.
case $rule_number: {
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
@@ -2762,7 +2777,12 @@ case $rule_number: {
} break;
./
-FunctionDeclaration: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+-- tell the parser to prefer function declarations to function expressions.
+-- That is, the `Function' symbol is used to mark the start of a function
+-- declaration.
+Function: T_FUNCTION %prec REDUCE_HERE ;
+
+FunctionDeclaration: Function JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
@@ -2776,7 +2796,7 @@ case $rule_number: {
} break;
./
-FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+FunctionExpression: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
@@ -2791,6 +2811,19 @@ case $rule_number: {
} break;
./
+FunctionExpression: T_FUNCTION T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+/.
+case $rule_number: {
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody);
+ node->functionToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
+ sym(1).Node = node;
+} break;
+./
+
FormalParameterList: JsIdentifier ;
/.
case $rule_number: {
@@ -2877,23 +2910,14 @@ case $rule_number: {
} break;
./
-IdentifierOpt: ;
-/.
-case $rule_number: {
- stringRef(1) = QStringRef();
-} break;
-./
-
-IdentifierOpt: JsIdentifier ;
-
-PropertyNameAndValueListOpt: ;
+PropertyAssignmentListOpt: ;
/.
case $rule_number: {
sym(1).Node = 0;
} break;
./
-PropertyNameAndValueListOpt: PropertyNameAndValueList ;
+PropertyAssignmentListOpt: PropertyAssignmentList ;
/.
} // switch
diff --git a/src/qml/qml/parser/qqmljsast.cpp b/src/qml/qml/parser/qqmljsast.cpp
index 6b5ef15352..ea0df4a537 100644
--- a/src/qml/qml/parser/qqmljsast.cpp
+++ b/src/qml/qml/parser/qqmljsast.cpp
@@ -213,12 +213,32 @@ void Elision::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PropertyNameAndValueList::accept0(Visitor *visitor)
+void PropertyNameAndValue::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- for (PropertyNameAndValueList *it = this; it; it = it->next) {
- accept(it->name, visitor);
- accept(it->value, visitor);
+ accept(name, visitor);
+ accept(value, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void PropertyGetterSetter::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(name, visitor);
+ accept(formals, visitor);
+ accept(functionBody, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void PropertyAssignmentList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (PropertyAssignmentList *it = this; it; it = it->next) {
+ accept(it->assignment, visitor);
}
}
diff --git a/src/qml/qml/parser/qqmljsast_p.h b/src/qml/qml/parser/qqmljsast_p.h
index 65a598c783..01a872f1e8 100644
--- a/src/qml/qml/parser/qqmljsast_p.h
+++ b/src/qml/qml/parser/qqmljsast_p.h
@@ -57,7 +57,7 @@
#include "qqmljsglobal_p.h"
#include "qqmljsmemorypool_p.h"
-#include <QtCore/QString>
+#include <QtCore/qstring.h>
QT_QML_BEGIN_NAMESPACE
@@ -176,8 +176,10 @@ public:
Kind_PreDecrementExpression,
Kind_PreIncrementExpression,
Kind_Program,
+ Kind_PropertyAssignmentList,
+ Kind_PropertyGetterSetter,
Kind_PropertyName,
- Kind_PropertyNameAndValueList,
+ Kind_PropertyNameAndValue,
Kind_RegExpLiteral,
Kind_ReturnStatement,
Kind_SourceElement,
@@ -487,7 +489,7 @@ public:
ObjectLiteral():
properties (0) { kind = K; }
- ObjectLiteral(PropertyNameAndValueList *plist):
+ ObjectLiteral(PropertyAssignmentList *plist):
properties (plist) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -499,7 +501,7 @@ public:
{ return rbraceToken; }
// attributes
- PropertyNameAndValueList *properties;
+ PropertyAssignmentList *properties;
SourceLocation lbraceToken;
SourceLocation rbraceToken;
};
@@ -603,50 +605,113 @@ public:
SourceLocation propertyNameToken;
};
-class QML_PARSER_EXPORT PropertyNameAndValueList: public Node
+class QML_PARSER_EXPORT PropertyAssignment: public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(PropertyNameAndValueList)
+ PropertyAssignment() {}
+};
- PropertyNameAndValueList(PropertyName *n, ExpressionNode *v):
- name (n), value (v), next (this)
- { kind = K; }
+class QML_PARSER_EXPORT PropertyAssignmentList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(PropertyAssignmentList)
- PropertyNameAndValueList(PropertyNameAndValueList *previous, PropertyName *n, ExpressionNode *v):
- name (n), value (v)
+ PropertyAssignmentList(PropertyAssignment *assignment)
+ : assignment(assignment)
+ , next(this)
+ { kind = K; }
+
+ PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment)
+ : assignment(assignment)
{
kind = K;
next = previous->next;
previous->next = this;
}
+ inline PropertyAssignmentList *finish ()
+ {
+ PropertyAssignmentList *front = next;
+ next = 0;
+ return front;
+ }
+
virtual void accept0(Visitor *visitor);
virtual SourceLocation firstSourceLocation() const
- { return name->firstSourceLocation(); }
+ { return assignment->firstSourceLocation(); }
virtual SourceLocation lastSourceLocation() const
- {
- if (next)
- return next->lastSourceLocation();
- return value->lastSourceLocation();
- }
+ { return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); }
- inline PropertyNameAndValueList *finish ()
- {
- PropertyNameAndValueList *front = next;
- next = 0;
- return front;
- }
+// attributes
+ PropertyAssignment *assignment;
+ PropertyAssignmentList *next;
+ SourceLocation commaToken;
+};
+
+class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue)
+
+ PropertyNameAndValue(PropertyName *n, ExpressionNode *v)
+ : name(n), value(v)
+ { kind = K; }
+
+ virtual void accept0(Visitor *visitor);
+
+ virtual SourceLocation firstSourceLocation() const
+ { return name->firstSourceLocation(); }
+
+ virtual SourceLocation lastSourceLocation() const
+ { return value->lastSourceLocation(); }
// attributes
PropertyName *name;
- ExpressionNode *value;
- PropertyNameAndValueList *next;
SourceLocation colonToken;
+ ExpressionNode *value;
SourceLocation commaToken;
};
+class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter)
+
+ enum Type {
+ Getter,
+ Setter
+ };
+
+ PropertyGetterSetter(PropertyName *n, FunctionBody *b)
+ : type(Getter), name(n), formals(0), functionBody (b)
+ { kind = K; }
+
+ PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b)
+ : type(Setter), name(n), formals(f), functionBody (b)
+ { kind = K; }
+
+ virtual void accept0(Visitor *visitor);
+
+ virtual SourceLocation firstSourceLocation() const
+ { return getSetToken; }
+
+ virtual SourceLocation lastSourceLocation() const
+ { return rbraceToken; }
+
+// attributes
+ Type type;
+ SourceLocation getSetToken;
+ PropertyName *name;
+ SourceLocation lparenToken;
+ FormalParameterList *formals;
+ SourceLocation rparenToken;
+ SourceLocation lbraceToken;
+ FunctionBody *functionBody;
+ SourceLocation rbraceToken;
+};
+
class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
{
public:
diff --git a/src/qml/qml/parser/qqmljsastfwd_p.h b/src/qml/qml/parser/qqmljsastfwd_p.h
index 67868234b2..fe5572c4b2 100644
--- a/src/qml/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/qml/parser/qqmljsastfwd_p.h
@@ -98,7 +98,9 @@ class ArrayLiteral;
class ObjectLiteral;
class ElementList;
class Elision;
-class PropertyNameAndValueList;
+class PropertyAssignmentList;
+class PropertyGetterSetter;
+class PropertyNameAndValue;
class PropertyName;
class IdentifierPropertyName;
class StringLiteralPropertyName;
diff --git a/src/qml/qml/parser/qqmljsastvisitor_p.h b/src/qml/qml/parser/qqmljsastvisitor_p.h
index 32f94bd436..ef022f617c 100644
--- a/src/qml/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/qml/parser/qqmljsastvisitor_p.h
@@ -137,8 +137,14 @@ public:
virtual bool visit(Elision *) { return true; }
virtual void endVisit(Elision *) {}
- virtual bool visit(PropertyNameAndValueList *) { return true; }
- virtual void endVisit(PropertyNameAndValueList *) {}
+ virtual bool visit(PropertyAssignmentList *) { return true; }
+ virtual void endVisit(PropertyAssignmentList *) {}
+
+ virtual bool visit(PropertyNameAndValue *) { return true; }
+ virtual void endVisit(PropertyNameAndValue *) {}
+
+ virtual bool visit(PropertyGetterSetter *) { return true; }
+ virtual void endVisit(PropertyGetterSetter *) {}
virtual bool visit(NestedExpression *) { return true; }
virtual void endVisit(NestedExpression *) {}
diff --git a/src/qml/qml/parser/qqmljsengine_p.cpp b/src/qml/qml/parser/qqmljsengine_p.cpp
index 8e3903d7e0..7dc3b6f6cb 100644
--- a/src/qml/qml/parser/qqmljsengine_p.cpp
+++ b/src/qml/qml/parser/qqmljsengine_p.cpp
@@ -42,15 +42,15 @@
#include "qqmljsengine_p.h"
#include "qqmljsglobal_p.h"
-#include <qnumeric.h>
-#include <QHash>
-#include <QDebug>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qdebug.h>
QT_QML_BEGIN_NAMESPACE
namespace QQmlJS {
-static int toDigit(char c)
+static inline int toDigit(char c)
{
if ((c >= '0') && (c <= '9'))
return c - '0';
diff --git a/src/qml/qml/parser/qqmljsengine_p.h b/src/qml/qml/parser/qqmljsengine_p.h
index f1729c0526..4f58e7f8ea 100644
--- a/src/qml/qml/parser/qqmljsengine_p.h
+++ b/src/qml/qml/parser/qqmljsengine_p.h
@@ -57,8 +57,8 @@
#include "qqmljsastfwd_p.h"
#include "qqmljsmemorypool_p.h"
-#include <QString>
-#include <QSet>
+#include <QtCore/qstring.h>
+#include <QtCore/qset.h>
QT_QML_BEGIN_NAMESPACE
diff --git a/src/qml/qml/parser/qqmljsglobal_p.h b/src/qml/qml/parser/qqmljsglobal_p.h
index 3aecc863d5..c53e12ea56 100644
--- a/src/qml/qml/parser/qqmljsglobal_p.h
+++ b/src/qml/qml/parser/qqmljsglobal_p.h
@@ -61,8 +61,10 @@
# if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
// QmlDevTools is a static library
# define QML_PARSER_EXPORT
-# else
+# elif defined(QT_BUILD_QML_LIB)
# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
+# else
+# define QML_PARSER_EXPORT
# endif
#endif // QT_CREATOR
diff --git a/src/qml/qml/parser/qqmljsgrammar.cpp b/src/qml/qml/parser/qqmljsgrammar.cpp
index d1b29be70a..4a5672a796 100644
--- a/src/qml/qml/parser/qqmljsgrammar.cpp
+++ b/src/qml/qml/parser/qqmljsgrammar.cpp
@@ -54,45 +54,46 @@ const char *const QQmlJSGrammar::spell [] = {
")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
"this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
"^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", 0,
- "public", "import", "as", "on", 0, 0, 0, 0, 0, 0,
- 0, 0, 0};
+ "public", "import", "as", "on", "get", "set", 0, 0, 0, 0,
+ 0, 0, 0, 0, 0};
const short QQmlJSGrammar::lhs [] = {
- 103, 103, 103, 103, 103, 103, 104, 110, 110, 113,
- 113, 115, 114, 114, 114, 114, 114, 114, 114, 114,
- 117, 112, 111, 120, 120, 121, 121, 122, 122, 119,
- 108, 108, 108, 108, 124, 124, 124, 124, 124, 124,
- 124, 108, 132, 132, 132, 133, 133, 134, 134, 108,
- 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 118, 118, 118, 118,
- 118, 137, 137, 137, 137, 137, 137, 137, 137, 137,
- 137, 137, 137, 137, 137, 137, 137, 137, 137, 123,
- 139, 139, 139, 139, 138, 138, 141, 141, 143, 143,
- 143, 143, 143, 143, 144, 144, 144, 144, 144, 144,
- 144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
- 144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
- 144, 144, 144, 144, 144, 145, 145, 116, 116, 116,
- 116, 116, 148, 148, 149, 149, 149, 149, 147, 147,
- 150, 150, 151, 151, 152, 152, 152, 153, 153, 153,
- 153, 153, 153, 153, 153, 153, 153, 154, 154, 154,
- 154, 155, 155, 155, 156, 156, 156, 156, 157, 157,
- 157, 157, 157, 157, 157, 158, 158, 158, 158, 158,
- 158, 159, 159, 159, 159, 159, 160, 160, 160, 160,
- 160, 161, 161, 162, 162, 163, 163, 164, 164, 165,
- 165, 166, 166, 167, 167, 168, 168, 169, 169, 170,
- 170, 171, 171, 172, 172, 142, 142, 173, 173, 174,
- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 106, 106, 175, 175, 176, 176, 177, 177, 105,
- 105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 125, 186, 186, 185, 185, 136,
- 136, 187, 187, 188, 188, 190, 190, 189, 191, 194,
- 192, 192, 195, 193, 193, 126, 127, 127, 128, 128,
- 178, 178, 178, 178, 178, 178, 178, 178, 179, 179,
- 179, 179, 180, 180, 180, 180, 181, 181, 129, 130,
- 196, 196, 199, 199, 197, 197, 200, 198, 182, 182,
- 182, 183, 183, 131, 131, 131, 201, 202, 184, 184,
- 135, 146, 206, 206, 203, 203, 204, 204, 207, 109,
- 109, 208, 208, 107, 107, 205, 205, 140, 140, 209};
+ 105, 105, 105, 105, 105, 105, 106, 112, 112, 115,
+ 115, 117, 116, 116, 116, 116, 116, 116, 116, 116,
+ 119, 114, 113, 122, 122, 123, 123, 124, 124, 121,
+ 110, 110, 110, 110, 126, 126, 126, 126, 126, 126,
+ 126, 110, 134, 134, 134, 135, 135, 136, 136, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 120, 120, 120, 120,
+ 120, 120, 120, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 125, 141, 141, 141, 141, 140, 140, 145, 145,
+ 145, 143, 143, 146, 146, 146, 146, 149, 149, 149,
+ 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 149, 149, 149, 149, 150, 150,
+ 118, 118, 118, 118, 118, 153, 153, 154, 154, 154,
+ 154, 152, 152, 155, 155, 156, 156, 157, 157, 157,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 159, 159, 159, 159, 160, 160, 160, 161, 161, 161,
+ 161, 162, 162, 162, 162, 162, 162, 162, 163, 163,
+ 163, 163, 163, 163, 164, 164, 164, 164, 164, 165,
+ 165, 165, 165, 165, 166, 166, 167, 167, 168, 168,
+ 169, 169, 170, 170, 171, 171, 172, 172, 173, 173,
+ 174, 174, 175, 175, 176, 176, 177, 177, 144, 144,
+ 178, 178, 179, 179, 179, 179, 179, 179, 179, 179,
+ 179, 179, 179, 179, 108, 108, 180, 180, 181, 181,
+ 182, 182, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 127, 191, 191,
+ 190, 190, 138, 138, 192, 192, 193, 193, 195, 195,
+ 194, 196, 199, 197, 197, 200, 198, 198, 128, 129,
+ 129, 130, 130, 183, 183, 183, 183, 183, 183, 183,
+ 183, 184, 184, 184, 184, 185, 185, 185, 185, 186,
+ 186, 131, 132, 201, 201, 204, 204, 202, 202, 205,
+ 203, 187, 188, 188, 133, 133, 133, 206, 207, 189,
+ 189, 208, 137, 151, 151, 209, 209, 148, 148, 147,
+ 147, 210, 111, 111, 211, 211, 109, 109, 142, 142,
+ 212};
const short QQmlJSGrammar::rhs [] = {
2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
@@ -103,593 +104,600 @@ const short QQmlJSGrammar::rhs [] = {
6, 3, 3, 7, 7, 4, 4, 5, 5, 5,
6, 6, 10, 6, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 3, 3, 4, 5, 3, 4, 3, 1,
- 1, 2, 3, 4, 1, 2, 3, 5, 1, 1,
+ 1, 1, 1, 2, 3, 3, 4, 5, 3, 4,
+ 3, 1, 1, 2, 3, 4, 1, 2, 3, 7,
+ 8, 1, 3, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
- 3, 5, 1, 2, 4, 4, 4, 3, 0, 1,
- 1, 3, 1, 1, 1, 2, 2, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 1, 3, 3,
- 3, 1, 3, 3, 1, 3, 3, 3, 1, 3,
- 3, 3, 3, 3, 3, 1, 3, 3, 3, 3,
- 3, 1, 3, 3, 3, 3, 1, 3, 3, 3,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 5, 1, 5, 1, 3, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 3, 0, 1, 1, 3, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 1, 2, 0, 1, 3,
- 3, 1, 1, 1, 3, 1, 3, 2, 2, 2,
- 0, 1, 2, 0, 1, 1, 2, 2, 7, 5,
- 7, 7, 7, 5, 9, 10, 7, 8, 2, 2,
- 3, 3, 2, 2, 3, 3, 3, 3, 5, 5,
- 3, 5, 1, 2, 0, 1, 4, 3, 3, 3,
- 3, 3, 3, 3, 3, 4, 5, 2, 2, 2,
- 8, 8, 1, 3, 0, 1, 0, 1, 1, 1,
- 1, 1, 2, 1, 1, 0, 1, 0, 1, 2};
+ 1, 1, 4, 3, 5, 1, 2, 4, 4, 4,
+ 3, 0, 1, 1, 3, 1, 1, 1, 2, 2,
+ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 3, 3, 3, 1, 3, 3, 1, 3, 3,
+ 3, 1, 3, 3, 3, 3, 3, 3, 1, 3,
+ 3, 3, 3, 3, 1, 3, 3, 3, 3, 1,
+ 3, 3, 3, 3, 1, 3, 1, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
+ 1, 3, 1, 3, 1, 5, 1, 5, 1, 3,
+ 1, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 0, 1, 1, 3,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 1, 2,
+ 0, 1, 3, 3, 1, 1, 1, 3, 1, 3,
+ 2, 2, 2, 0, 1, 2, 0, 1, 1, 2,
+ 2, 7, 5, 7, 7, 7, 5, 9, 10, 7,
+ 8, 2, 2, 3, 3, 2, 2, 3, 3, 3,
+ 3, 5, 5, 3, 5, 1, 2, 0, 1, 4,
+ 3, 3, 3, 3, 3, 3, 4, 5, 2, 2,
+ 2, 1, 8, 8, 7, 1, 3, 0, 1, 0,
+ 1, 1, 1, 1, 1, 2, 1, 1, 0, 1,
+ 2};
const short QQmlJSGrammar::action_default [] = {
- 0, 0, 22, 0, 0, 0, 22, 0, 175, 242,
- 206, 214, 210, 154, 226, 202, 3, 139, 73, 155,
- 218, 222, 143, 172, 153, 158, 138, 192, 179, 0,
- 80, 81, 76, 346, 67, 348, 0, 0, 0, 0,
- 78, 0, 0, 74, 77, 71, 0, 0, 68, 70,
- 69, 79, 72, 0, 75, 0, 0, 168, 0, 0,
- 155, 174, 157, 156, 0, 0, 0, 170, 171, 169,
- 173, 0, 203, 0, 0, 0, 0, 193, 0, 0,
- 0, 0, 0, 0, 183, 0, 0, 0, 177, 178,
- 176, 181, 185, 184, 182, 180, 195, 194, 196, 0,
- 211, 0, 207, 0, 0, 149, 136, 148, 137, 105,
- 106, 107, 132, 108, 133, 109, 110, 111, 112, 113,
- 114, 115, 116, 117, 118, 119, 120, 121, 134, 122,
- 123, 124, 125, 126, 127, 128, 129, 130, 131, 135,
- 0, 0, 147, 243, 150, 0, 151, 0, 152, 146,
- 0, 239, 232, 230, 237, 238, 236, 235, 241, 234,
- 233, 231, 240, 227, 0, 215, 0, 0, 219, 0,
- 0, 223, 0, 0, 149, 141, 0, 140, 0, 145,
- 159, 0, 347, 335, 336, 0, 333, 0, 334, 0,
- 337, 250, 257, 256, 264, 252, 0, 253, 338, 0,
- 345, 254, 255, 260, 258, 342, 339, 344, 261, 0,
- 272, 0, 0, 0, 0, 346, 67, 0, 348, 68,
- 244, 286, 69, 0, 0, 0, 273, 0, 0, 262,
- 263, 0, 251, 259, 287, 288, 332, 343, 0, 303,
- 304, 305, 306, 0, 299, 300, 301, 302, 329, 330,
- 0, 0, 0, 0, 0, 291, 292, 293, 248, 246,
- 208, 216, 212, 228, 204, 249, 0, 155, 220, 224,
- 197, 186, 0, 0, 205, 0, 0, 0, 0, 198,
- 0, 0, 0, 0, 0, 190, 188, 191, 189, 187,
- 200, 199, 201, 0, 213, 0, 209, 0, 247, 155,
- 0, 229, 244, 245, 0, 244, 0, 0, 295, 0,
- 0, 0, 297, 0, 217, 0, 0, 221, 0, 0,
- 225, 284, 0, 276, 285, 279, 0, 283, 0, 244,
- 277, 0, 244, 0, 0, 296, 0, 0, 0, 298,
- 347, 335, 0, 0, 337, 0, 331, 0, 321, 0,
- 0, 0, 290, 0, 289, 0, 349, 0, 104, 266,
- 269, 0, 105, 272, 108, 133, 110, 111, 76, 115,
- 116, 67, 117, 120, 74, 77, 68, 244, 69, 79,
- 123, 72, 125, 75, 127, 128, 273, 130, 131, 135,
- 0, 97, 0, 0, 99, 103, 101, 88, 100, 102,
- 0, 98, 87, 267, 265, 143, 144, 149, 0, 142,
- 0, 320, 0, 307, 308, 0, 319, 0, 0, 0,
- 310, 315, 313, 316, 0, 0, 314, 315, 0, 311,
- 0, 312, 268, 318, 0, 268, 317, 0, 322, 323,
- 0, 268, 324, 325, 0, 0, 326, 0, 0, 0,
- 327, 328, 161, 160, 0, 0, 0, 294, 0, 0,
- 0, 309, 281, 274, 0, 282, 278, 0, 280, 270,
- 0, 271, 275, 91, 0, 0, 95, 82, 0, 84,
- 93, 0, 85, 94, 96, 86, 92, 83, 0, 89,
- 165, 163, 167, 164, 162, 166, 340, 6, 341, 4,
- 2, 65, 90, 0, 0, 68, 70, 69, 31, 5,
- 0, 66, 0, 45, 44, 43, 0, 0, 58, 0,
- 59, 35, 36, 37, 38, 40, 41, 62, 39, 0,
- 45, 0, 0, 0, 0, 0, 54, 0, 55, 0,
- 0, 26, 0, 0, 63, 27, 0, 30, 28, 24,
- 0, 29, 25, 0, 56, 0, 57, 143, 0, 60,
- 64, 0, 0, 0, 0, 61, 0, 52, 46, 53,
- 47, 0, 0, 0, 0, 49, 0, 50, 51, 48,
- 0, 0, 143, 268, 0, 0, 42, 105, 272, 108,
- 133, 110, 111, 76, 115, 116, 67, 117, 120, 74,
- 77, 68, 244, 69, 79, 123, 72, 125, 75, 127,
- 128, 273, 130, 131, 135, 0, 32, 33, 0, 34,
+ 0, 0, 22, 0, 0, 0, 22, 0, 178, 245,
+ 209, 217, 213, 157, 229, 205, 3, 142, 75, 158,
+ 221, 225, 146, 175, 156, 161, 141, 195, 182, 0,
+ 82, 83, 78, 0, 72, 67, 349, 0, 0, 0,
+ 0, 80, 0, 0, 76, 79, 71, 0, 0, 68,
+ 70, 73, 69, 81, 74, 0, 77, 0, 0, 171,
+ 0, 0, 158, 177, 160, 159, 0, 0, 0, 173,
+ 174, 172, 176, 0, 206, 0, 0, 0, 0, 196,
+ 0, 0, 0, 0, 0, 0, 186, 0, 0, 0,
+ 180, 181, 179, 184, 188, 187, 185, 183, 198, 197,
+ 199, 0, 214, 0, 210, 0, 0, 152, 139, 151,
+ 140, 108, 109, 110, 135, 111, 136, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 137, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+ 134, 138, 0, 0, 150, 246, 153, 0, 154, 0,
+ 155, 149, 0, 242, 235, 233, 240, 241, 239, 238,
+ 244, 237, 236, 234, 243, 230, 0, 218, 0, 0,
+ 222, 0, 0, 226, 0, 0, 152, 144, 0, 143,
+ 0, 148, 162, 0, 338, 338, 339, 0, 336, 0,
+ 337, 0, 340, 253, 260, 259, 267, 255, 0, 256,
+ 0, 341, 0, 348, 257, 258, 75, 263, 261, 345,
+ 342, 347, 264, 0, 275, 0, 0, 0, 0, 332,
+ 0, 349, 247, 289, 0, 0, 0, 276, 0, 0,
+ 265, 266, 0, 254, 262, 290, 291, 0, 338, 0,
+ 0, 340, 0, 333, 334, 0, 322, 346, 0, 306,
+ 307, 308, 309, 0, 302, 303, 304, 305, 330, 331,
+ 0, 0, 0, 0, 0, 294, 295, 296, 251, 249,
+ 211, 219, 215, 231, 207, 252, 0, 158, 223, 227,
+ 200, 189, 0, 0, 208, 0, 0, 0, 0, 201,
+ 0, 0, 0, 0, 0, 193, 191, 194, 192, 190,
+ 203, 202, 204, 0, 216, 0, 212, 0, 250, 158,
+ 0, 232, 247, 248, 0, 247, 0, 0, 298, 0,
+ 0, 0, 300, 0, 220, 0, 0, 224, 0, 0,
+ 228, 287, 0, 279, 288, 282, 0, 286, 0, 247,
+ 280, 0, 247, 0, 0, 299, 0, 0, 0, 301,
+ 0, 0, 0, 293, 0, 292, 75, 102, 350, 0,
+ 0, 107, 269, 272, 0, 108, 275, 111, 136, 113,
+ 114, 78, 118, 119, 72, 120, 123, 76, 79, 247,
+ 73, 81, 126, 74, 128, 77, 130, 131, 276, 133,
+ 134, 138, 0, 104, 103, 106, 90, 105, 89, 0,
+ 99, 270, 268, 0, 0, 0, 340, 0, 100, 146,
+ 147, 152, 0, 145, 0, 310, 311, 0, 338, 0,
+ 0, 340, 0, 101, 0, 0, 0, 313, 318, 316,
+ 319, 0, 0, 317, 318, 0, 314, 0, 315, 271,
+ 321, 0, 271, 320, 0, 323, 324, 0, 271, 325,
+ 326, 0, 0, 327, 0, 0, 0, 328, 329, 164,
+ 163, 0, 0, 0, 297, 0, 0, 0, 312, 284,
+ 277, 0, 285, 281, 0, 283, 273, 0, 274, 278,
+ 0, 0, 340, 0, 335, 93, 0, 0, 97, 84,
+ 0, 86, 95, 0, 87, 96, 98, 88, 94, 85,
+ 0, 91, 168, 166, 170, 167, 165, 169, 343, 6,
+ 344, 4, 2, 65, 92, 0, 0, 68, 70, 69,
+ 31, 5, 0, 66, 0, 45, 44, 43, 0, 0,
+ 58, 0, 59, 35, 36, 37, 38, 40, 41, 62,
+ 39, 0, 45, 0, 0, 0, 0, 0, 54, 0,
+ 55, 0, 0, 26, 0, 0, 63, 27, 0, 30,
+ 28, 24, 0, 29, 25, 0, 56, 0, 57, 146,
+ 0, 60, 64, 0, 0, 0, 0, 61, 0, 52,
+ 46, 53, 47, 0, 0, 0, 0, 49, 0, 50,
+ 51, 48, 0, 0, 146, 271, 0, 0, 42, 75,
+ 108, 275, 111, 136, 113, 114, 78, 118, 119, 120,
+ 123, 76, 79, 247, 81, 126, 74, 128, 77, 130,
+ 131, 276, 133, 134, 138, 0, 32, 33, 0, 34,
8, 0, 10, 0, 9, 0, 1, 21, 12, 0,
13, 0, 14, 0, 19, 20, 0, 15, 16, 0,
- 17, 18, 11, 23, 7, 350};
+ 17, 18, 11, 23, 7, 351};
const short QQmlJSGrammar::goto_default [] = {
- 7, 626, 207, 196, 205, 509, 497, 625, 644, 496,
- 624, 622, 627, 22, 623, 18, 508, 550, 540, 547,
- 542, 527, 191, 195, 197, 201, 233, 208, 230, 531,
- 571, 570, 200, 232, 26, 475, 474, 357, 356, 9,
- 355, 358, 107, 17, 145, 24, 13, 144, 19, 25,
- 57, 23, 8, 28, 27, 270, 15, 264, 10, 260,
- 12, 262, 11, 261, 20, 268, 21, 269, 14, 263,
- 259, 300, 412, 265, 266, 202, 193, 192, 204, 203,
- 229, 194, 361, 360, 231, 464, 463, 322, 323, 466,
- 325, 465, 324, 420, 424, 427, 423, 422, 442, 443,
- 185, 199, 181, 184, 198, 206, 0};
+ 7, 636, 211, 198, 209, 521, 509, 635, 654, 508,
+ 634, 632, 637, 22, 633, 18, 520, 562, 552, 559,
+ 554, 539, 193, 197, 199, 204, 234, 212, 231, 543,
+ 583, 582, 203, 233, 26, 487, 486, 359, 358, 9,
+ 357, 360, 202, 480, 361, 109, 17, 147, 24, 13,
+ 146, 19, 25, 59, 23, 8, 28, 27, 280, 15,
+ 274, 10, 270, 12, 272, 11, 271, 20, 278, 21,
+ 279, 14, 273, 269, 310, 414, 275, 276, 205, 195,
+ 194, 208, 207, 230, 196, 364, 363, 232, 471, 470,
+ 332, 333, 473, 335, 472, 334, 427, 431, 434, 430,
+ 429, 449, 450, 200, 186, 201, 210, 0};
const short QQmlJSGrammar::action_index [] = {
- 425, 1471, 2619, 2619, 2718, 1193, 69, 100, 86, -103,
- 97, 62, 60, 236, -103, 278, 93, -103, -103, 609,
- 83, 117, 266, 184, -103, -103, -103, 514, 179, 1471,
- -103, -103, -103, 392, -103, 2421, 1754, 1471, 1471, 1471,
- -103, 1001, 1471, -103, -103, -103, 1471, 1471, -103, -103,
- -103, -103, -103, 1471, -103, 1471, 1471, -103, 1471, 1471,
- 115, 169, -103, -103, 1471, 1471, 1471, -103, -103, -103,
- 152, 1471, 286, 1471, 1471, 1471, 1471, 562, 1471, 1471,
- 1471, 1471, 1471, 1471, 198, 1471, 1471, 1471, 87, 122,
- 138, 212, 197, 183, 227, 265, 562, 504, 472, 1471,
- 79, 1471, 102, 2322, 1471, 1471, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- 132, 1471, -103, -103, 94, 11, -103, 1471, -103, -103,
- 1471, -103, -103, -103, -103, -103, -103, -103, -103, -103,
- -103, -103, -103, -103, 1471, 31, 1471, 1471, 67, 68,
- 1471, -103, 2322, 1471, 1471, -103, 98, -103, 39, -103,
- -103, 61, -103, 296, 66, 30, -103, 376, -103, 35,
- 2619, -103, -103, -103, -103, -103, 237, -103, -103, 21,
- -103, -103, -103, -103, -103, -103, 2619, -103, -103, 513,
- -103, 541, 114, 2718, 36, 422, 59, 42, 2916, 75,
- 1471, -103, 77, 53, 1471, 63, -103, 57, 58, -103,
- -103, 407, -103, -103, -103, -103, -103, -103, 80, -103,
- -103, -103, -103, 82, -103, -103, -103, -103, -103, -103,
- 52, 51, 1471, 96, 200, -103, -103, -103, 1659, -103,
- 76, 44, 46, -103, 298, 73, 48, 736, 78, 95,
- 363, 233, 347, 1471, 303, 1471, 1471, 1471, 1471, 402,
- 1471, 1471, 1471, 1471, 1471, 248, 189, 159, 167, 174,
- 482, 482, 444, 1471, 7, 1471, 64, 1471, -103, 627,
- 1471, -103, 1471, 65, 34, 1471, 54, 2718, -103, 1471,
- 140, 2718, -103, 1471, 74, 1471, 1471, 81, 84, 1471,
- -103, 71, 116, 33, -103, -103, 1471, -103, 313, 1471,
- -103, 70, 1471, 72, 2718, -103, 1471, 234, 2718, -103,
- -16, 324, -42, -12, 2619, -39, -103, 2718, -103, 1471,
- 151, 2718, 12, 2718, -103, 20, 16, -32, -103, -103,
- 2718, -52, 521, -2, 505, 129, 1471, 2718, -5, -35,
- 497, 2, -24, 819, 6, 3, -103, 1567, -103, -1,
- -36, 26, 1471, 47, 22, 1471, 45, 1471, 17, 15,
- 1471, -103, 2520, 49, -103, -103, -103, -103, -103, -103,
- 1471, -103, -103, -103, -103, 322, -103, 1471, -25, -103,
- 2718, -103, 118, -103, -103, 2718, -103, 1471, 112, 8,
- -103, 40, -103, 41, 106, 1471, -103, 38, 32, -103,
- -38, -103, 2718, -103, 104, 2718, -103, 247, -103, -103,
- 99, 2718, -6, -103, -10, -18, -103, 387, 10, 9,
- -103, -103, -103, -103, 1471, 125, 2718, -103, 1471, 127,
- 2718, -103, -13, -103, 187, -103, -103, 1471, -103, -103,
- 398, -103, -103, -103, 110, 2039, -103, -103, 1849, -103,
- -103, 1944, -103, -103, -103, -103, -103, -103, 105, -103,
- -103, -103, -103, -103, -103, -103, -103, -103, 2619, -103,
- -103, -103, 113, -7, 1009, 145, -8, 19, -103, -103,
- 186, -103, 178, -103, -103, -103, 356, 226, -103, 2131,
- -103, -103, -103, -103, -103, -103, -103, -103, -103, 322,
- -26, 364, 205, 43, 316, 206, -103, -3, -103, 1009,
- 107, -103, -11, 827, -103, -103, 1379, -103, -103, -103,
- 1286, -103, -103, 195, -103, 2131, -103, 305, -4, -103,
- -103, 209, 379, 18, 2131, -103, 182, -103, 199, -103,
- 0, -53, 306, 154, 284, -103, 108, -103, -103, -103,
- 2223, 918, 300, 2817, 1754, 5, -103, 549, 139, 636,
- 114, 1471, 2718, 50, 24, 463, 55, -17, 910, 23,
- 56, -103, 1567, -103, 27, 1, 29, 1471, 37, 14,
- 1471, 25, 1471, 4, 13, 126, -103, -103, 28, -103,
- -103, 1100, -103, 267, -41, 714, -103, -103, 121, 301,
- -103, 215, -103, 91, -103, -103, 336, -103, -103, 89,
- -103, -103, -103, -103, -103, -103,
+ 235, 1289, 2663, 2663, 2562, 1005, 64, 90, 103, -105,
+ 88, 94, 79, 173, -105, 302, 69, -105, -105, 724,
+ 65, 135, 195, 239, -105, -105, -105, 367, 278, 1289,
+ -105, -105, -105, 485, -105, -105, 2360, 1772, 1289, 1289,
+ 1289, -105, 817, 1289, -105, -105, -105, 1289, 1289, -105,
+ -105, -105, -105, -105, -105, 1289, -105, 1289, 1289, -105,
+ 1289, 1289, 95, 207, -105, -105, 1289, 1289, 1289, -105,
+ -105, -105, 202, 1289, 300, 1289, 1289, 1289, 1289, 377,
+ 1289, 1289, 1289, 1289, 1289, 1289, 253, 1289, 1289, 1289,
+ 151, 147, 129, 196, 170, 199, 279, 270, 470, 470,
+ 387, 1289, 53, 1289, 80, 2158, 1289, 1289, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, 128, 1289, -105, -105, 74, 52, -105, 1289,
+ -105, -105, 1289, -105, -105, -105, -105, -105, -105, -105,
+ -105, -105, -105, -105, -105, -105, 1289, 51, 1289, 1289,
+ 77, 66, 1289, -105, 2158, 1289, 1289, -105, 125, -105,
+ 48, -105, -105, 47, 451, 374, 83, 87, -105, 397,
+ -105, 62, 2663, -105, -105, -105, -105, -105, 205, -105,
+ 415, -105, 68, -105, -105, -105, 86, -105, -105, -105,
+ 2663, -105, -105, 622, -105, 576, 102, 2562, 75, 89,
+ 81, 2865, 1289, -105, 70, 1289, 63, -105, 92, 93,
+ -105, -105, 546, -105, -105, -105, -105, 91, 546, 40,
+ 45, 2663, 49, -105, -105, 2562, -105, -105, 106, -105,
+ -105, -105, -105, 121, -105, -105, -105, -105, -105, -105,
+ 42, 44, 1289, 114, 222, -105, -105, -105, 1481, -105,
+ 84, 57, 56, -105, 388, 78, 54, 682, 82, 99,
+ 357, 247, 546, 1289, 295, 1289, 1289, 1289, 1289, 334,
+ 1289, 1289, 1289, 1289, 1289, 203, 217, 244, 263, 211,
+ 341, 319, 351, 1289, 56, 1289, 73, 1289, -105, 724,
+ 1289, -105, 1289, 67, 46, 1289, 61, 2562, -105, 1289,
+ 136, 2562, -105, 1289, 76, 1289, 1289, 85, 59, 1289,
+ -105, 71, 133, 72, -105, -105, 1289, -105, 546, 1289,
+ -105, -53, 1289, -60, 2562, -105, 1289, 143, 2562, -105,
+ 1289, 132, 2562, 8, 2562, -105, 7, -105, 12, -37,
+ 107, -105, -105, 2562, -33, 622, 22, 555, 115, 1289,
+ 2562, 23, -13, 502, 2259, -10, 817, 18, 6, 1387,
+ 2259, 0, 9, -6, 1289, -4, -23, 1289, 5, 1289,
+ -25, -27, 2461, -105, -105, -105, -105, -105, -105, 1289,
+ -105, -105, -105, -3, -1, 21, 2663, 1, -105, 218,
+ -105, 1289, 4, -105, 111, -105, -105, 26, 466, 16,
+ 38, 2663, 39, -105, 1289, 110, 37, -105, 55, -105,
+ 60, 116, 1289, -105, 58, 43, -105, -15, -105, 2562,
+ -105, 123, 2562, -105, 154, -105, -105, 96, 2562, 32,
+ -105, 3, 14, -105, 546, -11, 13, -105, -105, -105,
+ -105, 1289, 126, 2562, -105, 1289, 130, 2562, -105, 15,
+ -105, 301, -105, -105, 1289, -105, -105, 546, -105, -105,
+ -45, -12, 2663, -24, -105, -105, 204, 1578, -105, -105,
+ 1869, -105, -105, 1675, -105, -105, -105, -105, -105, -105,
+ 101, -105, -105, -105, -105, -105, -105, -105, -105, -105,
+ 2663, -105, -105, -105, 105, 2, 910, 206, -47, -2,
+ -105, -105, 246, -105, 214, -105, -105, -105, 364, 232,
+ -105, 1963, -105, -105, -105, -105, -105, -105, -105, -105,
+ -105, 191, 24, 394, 172, -18, 384, 215, -105, -30,
+ -105, 910, 149, -105, -16, 910, -105, -105, 1100, -105,
+ -105, -105, 1195, -105, -105, 225, -105, 1963, -105, 316,
+ -17, -105, -105, 269, 418, -5, 1963, -105, 184, -105,
+ 175, -105, 20, -9, 546, 182, 469, -105, 104, -105,
+ -105, -105, 2057, 910, 292, 2764, 1772, 10, -105, 35,
+ 622, 34, 525, 98, 1289, 2562, 50, 17, 536, 19,
+ 817, 31, 27, 1387, 28, 9, 29, 1289, 30, 11,
+ 1289, 41, 1289, 33, 36, 137, -105, -105, 25, -105,
+ -105, 910, -105, 268, -86, 910, -105, -105, 141, 546,
+ -105, 156, -105, 117, -105, -105, 546, -105, -105, 138,
+ -105, -105, -105, -105, -105, -105,
- -107, 12, -95, 3, 6, 275, 2, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -37,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, 96,
- -107, -107, -107, 8, -107, -107, -17, 24, 95, 74,
- -107, 85, 175, -107, -107, -107, 172, 168, -107, -107,
- -107, -107, -107, 169, -107, 165, 164, -107, 156, 176,
- -107, -107, -107, -107, 182, 178, 112, -107, -107, -107,
- -107, 121, -107, 144, 118, 116, 117, -107, 108, 133,
- 134, 137, 143, 152, -107, 147, 141, 136, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, 107,
- -107, 173, -107, 153, 84, 56, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, 36, -107, -107, -107, -107, -107, 30, -107, -107,
- 0, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, 79, -107, 99, 44, -107, -107,
- 46, -107, 194, 70, 64, -107, -107, -107, -107, -107,
- -107, -107, -107, 29, -107, -107, -107, 65, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, 80, -107, -107, 51,
- -107, 48, -107, 40, -107, 34, -107, -107, 86, -107,
- 88, -107, -107, -107, 78, 60, -107, -107, -107, -107,
- -107, -6, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, 21, -107, -107, -107, -107, -107, 104, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, 16, 201, -107, 202, 224, 223, 215, -107,
- 67, 73, 75, 59, 106, -107, -107, -107, -107, -107,
- -107, -107, -107, 185, -107, 208, -107, 233, -107, -107,
- 234, -107, 203, -107, -107, 299, -107, 90, -107, -2,
- -107, 11, -107, 181, -107, 200, 192, -107, -107, 189,
- -107, -107, -107, -107, -107, -107, 199, -107, 123, 131,
- -107, -107, 111, -107, 77, -107, 87, -107, 195, -107,
- -107, 110, -107, -107, -50, -107, -107, 39, -107, 42,
- -107, 63, -107, 66, -107, -107, -107, -107, -107, -107,
- 68, -107, 43, -107, 47, -107, 92, 35, -107, -107,
- 31, -107, -107, 105, -107, -107, -107, 94, -107, -107,
- -107, -107, 71, -107, 54, 101, -107, 89, -107, -107,
- 55, -107, 49, -107, -107, -107, -107, -107, -107, -107,
- 38, -107, -107, -107, -107, -107, -107, 114, -107, -107,
- 76, -107, -107, -107, -107, 91, -107, 93, -107, -107,
- -107, -107, -107, -57, -107, 50, -107, -44, -107, -107,
- -107, -107, 98, -107, -107, 97, -107, -107, -107, -107,
- -107, 52, -42, -107, -107, 45, -107, 41, -107, 37,
- -107, -107, -107, -107, 57, -107, 53, -107, 58, -107,
- 62, -107, -107, -107, -107, -107, -107, 9, -107, -107,
- 187, -107, -107, -107, -107, 33, -107, -107, 139, -107,
- -107, 32, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -107, -107, -107, -107, -107, -107, -107, 82, -107,
- -107, -107, -107, -107, -11, -107, -107, -107, -107, -107,
- -107, -107, -25, -107, -107, -107, -9, -107, -107, 297,
- -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
- -107, -3, -26, -107, -10, -107, -107, -107, -107, 160,
- -107, -107, -107, 120, -107, -107, 279, -107, -107, -107,
- 285, -107, -107, -107, -107, 329, -107, -107, 17, -107,
- -107, -13, 14, -107, 385, -107, -107, -107, 23, -107,
- -107, -107, 28, 18, 20, -107, -107, -107, -107, -107,
- 313, 188, -107, 26, 267, 7, -107, 5, -107, -1,
- -107, 69, 19, -107, -107, 10, -107, -107, 103, -107,
- -107, -107, 27, -107, -107, -107, -107, 15, -107, -5,
- 61, -107, 81, -107, -107, -107, -107, -107, 13, -107,
- -107, 25, -107, -107, 22, 119, -107, -107, -107, 4,
- -107, -107, -107, -107, -107, -107, -15, -107, -107, -107,
- -107, -107, -107, -107, -107, -107};
+ -108, 0, 79, 128, 132, 301, 2, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -47,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, 51,
+ -108, -108, -108, -3, -108, -108, 8, -23, 12, 78,
+ 106, -108, 69, 74, -108, -108, -108, 195, 204, -108,
+ -108, -108, -108, -108, -108, 188, -108, 201, 200, -108,
+ 127, 129, -108, -108, -108, -108, 140, 137, 133, -108,
+ -108, -108, -108, 146, -108, 177, 168, 170, 167, -108,
+ 144, 152, 166, 158, 160, 131, -108, 194, 187, 207,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, 88, -108, 112, -108, 121, 90, -38, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, 32, -108, -108, -108, -108, -108, 26,
+ -108, -108, 27, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, 102, -108, 103, 41,
+ -108, -108, 37, -108, 250, 38, 83, -108, -108, -108,
+ -108, -108, -108, -108, 42, 126, -108, -108, -108, 40,
+ -108, -108, 43, -108, -108, -108, -108, -108, -108, -108,
+ 39, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ 225, -108, -108, 30, -108, 24, -108, 211, -108, 55,
+ -108, 77, 60, -108, -108, 66, 34, -108, -108, -108,
+ -108, -108, -8, -108, -108, -108, -108, -108, 153, -108,
+ -108, 164, -108, -108, -108, 241, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, 11, -108, -108, -108, -108, -108, 179, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, 19, 259, -108, 255, 228, 240, 246, -108,
+ 52, 63, 67, 65, 50, -108, -108, -108, -108, -108,
+ -108, -108, -108, 210, -108, 256, -108, 226, -108, -108,
+ 252, -108, 161, -108, -108, 268, -108, 197, -108, 5,
+ -108, 218, -108, 222, -108, 213, 249, -108, -108, 236,
+ -108, -108, -108, -108, -108, -108, 212, -108, 80, 87,
+ -108, -108, 86, -108, 98, -108, 61, -108, 245, -108,
+ 59, -108, 208, -108, 192, -108, -108, -108, -108, -108,
+ -108, -108, -108, 257, -108, 33, -108, 28, -108, 73,
+ 71, -108, -108, 36, 57, -108, 62, -108, -108, 46,
+ 70, -108, -108, -108, 49, -108, 45, 99, -108, 84,
+ -108, -108, 100, -108, -108, -108, -108, -108, -108, 21,
+ -108, -108, -108, -108, -108, -108, 118, -108, -108, -108,
+ -108, 81, -108, -108, -108, -108, -108, -108, 123, -108,
+ -108, 134, -108, -108, 56, -108, -108, -108, -108, -108,
+ -58, -108, 47, -108, -57, -108, -108, -108, -108, 265,
+ -108, -108, 374, -108, -108, -108, -108, -108, 94, -66,
+ -108, -108, 25, -108, 22, -108, 31, -108, -108, -108,
+ -108, 58, -108, 229, -108, 35, -108, 235, -108, -108,
+ -108, -108, -108, -108, 29, -108, -108, 186, -108, -108,
+ -108, -108, 162, -108, -108, -108, -108, 48, -108, -108,
+ 163, -108, -108, 44, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ 141, -108, -108, -108, -108, -108, -7, -108, -108, -108,
+ -108, -108, -108, -108, -19, -108, -108, -108, -6, -108,
+ -108, 334, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -15, -27, -108, -10, -108, -108, -108,
+ -108, 159, -108, -108, -108, 176, -108, -108, 319, -108,
+ -108, -108, 322, -108, -108, -108, -108, 469, -108, -108,
+ 10, -108, -108, 6, 16, -108, 342, -108, -108, -108,
+ 17, -108, -108, -108, 15, 3, 9, -108, -108, -108,
+ -108, -108, 358, 68, -108, 82, 310, 1, -108, -108,
+ -2, -108, 7, -108, 54, 76, -108, -108, 4, -108,
+ 64, -108, -108, 23, -108, -108, -108, 18, -108, -5,
+ 95, -108, 91, -108, -108, -108, -108, -108, -1, -108,
+ -108, 20, -108, -108, 14, 142, -108, -108, -108, 13,
+ -108, -108, -108, -108, -108, -108, -11, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108};
const short QQmlJSGrammar::action_info [] = {
- 417, 258, -113, 404, 467, -132, -102, 576, 573, 347,
- -103, 532, 349, -121, 445, 441, 346, 431, 343, 349,
- 341, 344, 546, 402, 392, 564, 447, 390, 353, 546,
- -121, 539, -129, -124, -102, 409, -124, 417, 546, 432,
- 454, 421, 441, 425, -126, 425, 425, 441, 566, 458,
- 621, 458, -129, 454, -126, 441, 400, -113, 561, 512,
- 258, 546, 347, -103, 336, 273, 347, 534, 190, 164,
- 449, 149, 258, 141, 187, 170, 236, 273, 349, 99,
- 313, 297, 410, 313, 415, 164, 295, 252, 326, 417,
- 189, 319, 293, 454, 458, 305, 441, 183, 71, 179,
- 645, 141, 147, 71, 141, 444, 141, 0, 0, 302,
- 99, 435, 141, 141, 307, 543, 428, 0, 478, 445,
- 141, 0, 293, 0, 328, 295, 58, 58, 172, 251,
- 0, 332, 334, 141, 543, 141, 172, 59, 59, 101,
- 141, 242, 241, 247, 246, 315, -132, 173, 141, 316,
- 641, 640, 635, 634, 177, 173, 254, 62, 101, 141,
- 621, 429, 58, 544, 64, 489, 479, 166, 63, 578,
- 577, 167, 419, 59, 530, 249, 248, 329, 58, 414,
- 413, 64, 616, 513, 85, 456, 86, 460, 142, 59,
- 249, 248, 85, 580, 86, 470, 64, 87, 0, 85,
- 311, 86, 555, 0, 85, 87, 86, 513, 85, 65,
- 86, 351, 87, 537, 85, 66, 86, 87, 568, 546,
- 515, 87, 85, 85, 86, 86, 65, 87, 513, 515,
- 0, 514, 66, 519, 513, 87, 87, 85, 513, 86,
- 514, 65, 141, 569, 567, 141, 0, 66, 471, 469,
- 87, 103, 85, 515, 86, 141, 556, 554, 85, 0,
- 86, 257, 255, 0, 514, 87, 0, 538, 536, 0,
- 104, 87, 105, 85, 515, 86, 638, 637, 0, 581,
- 515, 172, 0, 0, 515, 514, 87, 520, 518, 256,
- 85, 514, 86, 0, 338, 514, 73, 74, 235, 234,
- 173, 0, 174, 87, 73, 74, 0, 636, 439, 438,
- 0, 0, 0, 34, 631, 172, 275, 276, 0, 0,
- 172, 275, 276, 75, 76, 34, 0, 0, 632, 630,
- 34, 75, 76, -90, 173, 34, 174, 172, -90, 173,
- 0, 174, 34, 277, 278, 34, 0, 0, 277, 278,
- 48, 50, 49, 34, 0, 0, 173, 0, 407, 629,
- 0, 0, 48, 50, 49, 34, 0, 48, 50, 49,
- 0, 0, 48, 50, 49, 0, 34, 45, 0, 48,
- 50, 49, 48, 50, 49, 34, 280, 281, 0, 45,
- 48, 50, 49, 34, 45, 282, 0, 0, 283, 45,
- 284, 0, 48, 50, 49, 34, 45, 0, 34, 45,
- 0, 0, 0, 48, 50, 49, 34, 45, 0, 0,
- 0, 34, 48, 50, 49, 280, 281, 34, 0, 45,
- 48, 50, 49, 0, 282, 0, 34, 283, 0, 284,
- 45, 0, 48, 50, 49, 48, 50, 49, 0, 45,
- 0, 34, 0, 48, 50, 49, 0, 45, 48, 50,
- 49, 0, 0, 0, 48, 50, 49, 280, 281, 45,
- 0, 0, 45, 48, 50, 49, 282, 0, 0, 283,
- 45, 284, 0, 0, 0, 45, 0, 0, 48, 50,
- 49, 45, 34, 0, 0, 78, 79, 0, 0, -346,
- 45, 0, 0, 80, 81, 280, 281, 82, 0, 83,
- 0, 0, 0, 0, 282, 45, 0, 283, 0, 284,
- 6, 5, 4, 1, 3, 2, 34, 78, 79, 48,
- 50, 49, 0, -346, 34, 80, 81, 78, 79, 82,
- 0, 83, 34, 0, 0, 80, 81, 0, 0, 82,
- 34, 83, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 48, 50, 49, 245, 244, 0, 0,
- 34, 48, 50, 49, 240, 239, 0, 0, 34, 48,
- 50, 49, 240, 239, 0, 78, 79, 48, 50, 49,
- 45, 0, 0, 80, 81, 0, 0, 82, 45, 83,
- 0, 0, 245, 244, 0, 0, 45, 48, 50, 49,
- 240, 239, 151, 0, 45, 48, 50, 49, 0, 0,
- 0, 0, 152, 0, 0, 0, 153, 0, 0, 0,
- 151, 0, 0, 0, 45, 154, 0, 155, 0, 0,
- 152, 0, 45, 0, 153, 0, 0, 0, 156, 0,
- 157, 62, 0, 154, 0, 155, 0, 0, 158, 0,
- 0, 159, 63, 0, 0, 34, 156, 160, 157, 62,
- 0, 0, 0, 161, 0, 0, 158, 0, 0, 159,
- 63, 0, 0, 0, 0, 160, 0, 0, 0, 162,
- 0, 161, 0, 0, 0, 0, 0, 245, 244, 0,
- 0, 0, 48, 50, 49, 0, 0, 162, 0, 0,
+ 344, -127, 576, -129, 551, 631, 546, -105, 342, 465,
+ 448, 461, -132, -106, 245, 481, 558, 558, 398, 573,
+ 392, 482, 402, 268, 354, -124, 350, 578, 585, -135,
+ -116, 484, 474, 404, -106, -105, -127, -129, -124, 454,
+ 438, -135, 245, 558, 448, 424, 448, 448, -132, 456,
+ 439, 588, 452, 268, 406, 350, 408, -116, 558, 405,
+ 432, 544, 418, 432, 413, 432, 329, 166, 524, 461,
+ 428, 421, 465, 172, 283, 143, 420, 143, 241, 166,
+ 262, 73, 149, 185, 323, 283, 307, 323, 336, 73,
+ 655, 189, 0, 245, 423, 192, 448, 0, 0, 101,
+ 240, 0, 451, 346, 243, 303, 424, 315, 181, 143,
+ 0, 268, 151, 0, 399, 312, 452, 350, 143, 261,
+ 174, 317, 143, 244, 303, 184, 435, 238, 461, 465,
+ 442, 143, 103, 143, 143, 305, 143, 64, 143, 175,
+ 143, 338, 101, 60, 143, 555, 0, 191, 65, 325,
+ 0, 143, 0, 326, 61, 631, 174, 555, 103, 259,
+ 258, 501, 143, 259, 258, 590, 589, 252, 251, 60,
+ 426, 436, 416, 415, 264, 175, 259, 258, 645, 644,
+ 61, 179, 257, 256, 144, 168, 463, 60, 105, 169,
+ 467, 60, 352, 626, 339, 87, 321, 88, 61, 651,
+ 650, 525, 61, 348, 525, 556, 174, 106, 89, 107,
+ 174, 525, 490, 143, 66, 446, 445, 648, 647, 66,
+ 580, 87, 549, 88, 87, 175, 88, 411, 87, 175,
+ 88, 176, 567, 174, 89, 542, 87, 89, 88, 531,
+ 0, 89, 87, 525, 88, 581, 579, 527, 646, 89,
+ 527, 66, 175, 592, 411, 89, 0, 527, 526, 67,
+ 491, 526, 0, 0, 67, 68, 236, 235, 526, 87,
+ 68, 88, 87, 0, 88, 0, 550, 548, 87, 558,
+ 88, 527, 89, 267, 265, 89, 568, 566, 87, 527,
+ 88, 89, 526, 532, 530, 87, 67, 88, 525, 0,
+ 526, 89, 68, 87, 87, 88, 88, 174, 89, 477,
+ 0, 266, 0, 285, 286, 641, 89, 89, 75, 76,
+ 75, 76, 0, 0, 0, -92, 175, 0, 176, 642,
+ 640, 174, 6, 5, 4, 1, 3, 2, 0, 593,
+ 287, 288, 290, 291, 527, 77, 78, 77, 78, -92,
+ 175, 292, 176, 0, 293, 526, 294, 290, 291, 0,
+ 639, 0, 478, 476, 290, 291, 292, 0, 0, 293,
+ 0, 294, 0, 292, 290, 291, 293, 0, 294, 0,
+ 290, 291, 0, 292, 0, 0, 293, 0, 294, 292,
+ 80, 81, 293, 35, 294, 0, 0, 0, 82, 83,
+ 80, 81, 84, 35, 85, 0, 285, 286, 82, 83,
+ 80, 81, 84, 35, 85, 0, 0, 0, 82, 83,
+ 0, 0, 84, 35, 85, 0, 35, 0, 0, 0,
+ 49, 52, 50, 287, 288, 0, 0, 0, 0, 0,
+ 49, 52, 50, 0, 35, 0, 0, 35, 0, 0,
+ 49, 52, 50, 0, 0, 0, 0, 46, 34, 51,
+ 49, 52, 50, 49, 52, 50, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 35, 49, 52, 50, 49, 52, 50, 46, 34, 51,
+ 46, 34, 51, 80, 81, 35, 0, 0, 35, 0,
+ 0, 82, 83, 0, 0, 84, 0, 85, 46, 34,
+ 51, 46, 34, 51, 35, 0, 0, 49, 52, 50,
+ 0, 184, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 35, 49, 52, 50, 49, 52, 50, 184, 0,
+ 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
+ 0, 49, 52, 50, 35, 0, 0, 0, 0, 46,
+ 34, 51, 46, 34, 51, 35, 0, 0, 49, 52,
+ 50, 0, 184, 0, 0, 35, 0, 0, 46, 34,
+ 51, 0, 0, 0, 35, 0, 255, 254, 0, 0,
+ 0, 49, 52, 50, 0, 46, 34, 51, 0, 0,
+ 0, 0, 49, 52, 50, 35, 0, 0, 0, 0,
+ 0, 0, 49, 52, 50, 0, 255, 254, 46, 34,
+ 51, 49, 52, 50, 0, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 255, 254, 46,
+ 34, 51, 49, 52, 50, 0, 0, 0, 46, 34,
+ 51, 35, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 250, 249, 153, 0, 0, 49, 52,
+ 50, 0, 0, 0, 0, 154, 0, 0, 0, 155,
+ 0, 0, 0, 0, 0, 0, 0, 0, 156, 0,
+ 157, 0, 0, 319, 0, 46, 34, 51, 0, 0,
+ 0, 158, 0, 159, 64, 0, 0, 153, 0, 0,
+ 0, 160, 0, 0, 161, 65, 0, 154, 0, 0,
+ 162, 155, 0, 0, 0, 0, 163, 0, 0, 0,
+ 156, 0, 157, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 164, 158, 0, 159, 64, 0, 0, 0,
+ 0, 0, 0, 160, 0, 0, 161, 65, 0, 0,
+ 0, 0, 162, 0, 0, 0, 0, 0, 163, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 30, 31, 0, 45,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 151,
- 0, 0, 0, 34, 0, 0, 0, 35, 36, 152,
- 37, 0, 0, 153, 0, 0, 0, 504, 0, 0,
- 0, 44, 154, 0, 155, 0, 0, 309, 0, 0,
- 0, 0, 0, 0, 0, 156, 0, 157, 62, 51,
- 48, 50, 49, 0, 52, 158, 0, 0, 159, 63,
- 0, 0, 0, 0, 160, 43, 54, 32, 0, 0,
- 161, 40, 0, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 162, 0, 0, 0,
+ 0, 0, 0, 0, 164, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 30, 31, 0, 0, 0, 0, 0, 0, 30,
- 31, 33, 0, 0, 0, 0, 0, 0, 34, 33,
- 0, 0, 35, 36, 0, 37, 34, 0, 0, 0,
- 35, 36, 41, 37, 0, 0, 44, 0, 0, 0,
- 504, 0, 0, 0, 44, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 48, 50, 49, 0, 52,
- 0, 0, 51, 48, 50, 49, 0, 52, 0, 0,
- 43, 54, 32, 0, 0, 0, 40, 0, 43, 54,
- 32, 0, 45, 0, 40, 0, 0, 0, 0, 0,
- 45, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 30, 31, 33, 0, 0, 0, 0, 0, 0, 34,
- 33, 0, 0, 35, 36, 0, 37, 34, 0, 0,
- 0, 35, 36, 41, 37, 0, 0, 44, 0, 0,
- 0, 504, 0, 0, 0, 44, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 51, 48, 50, 49, 0,
- 52, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 0, 43, 54, 32, 0, 0, 0, 40, 0, 43,
- 54, 32, 0, 45, 0, 40, 0, 0, 0, 0,
- 0, 45, 0, 30, 31, 0, 0, 0, 0, 0,
- 0, 30, 31, 33, 0, 0, 0, 0, 0, 0,
- 34, 33, 0, 0, 35, 36, 0, 37, 34, 0,
- 0, 0, 35, 36, 41, 37, 0, 0, 44, 0,
- 0, 0, 504, 0, 0, 0, 44, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
- 0, 52, 0, 0, 51, 48, 50, 49, 0, 52,
- 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
- 43, 54, 32, 0, 45, 0, 40, 0, 0, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
+ 36, 37, 0, 38, 0, 0, 0, 0, 0, 0,
+ 42, 0, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 53, 49, 52, 50, 0, 54, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 44, 56,
+ 32, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
0, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 33, 0, 0, 0, 0, 0, 0, 34,
- 0, 0, 0, 35, 36, 0, 37, 0, 0, 0,
- 0, 0, 0, 504, 0, 0, 0, 44, 0, 0,
+ 0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
+ 0, 0, 0, 36, 37, 0, 38, 0, 0, 0,
+ 0, 0, 0, 516, 0, 0, 0, 45, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 51, 48, 50, 49, 0,
- 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 43, 54, 32, 0, 0, 0, 40, 0, 0,
- 0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 503, 0, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 215, 0, 0, 0, 0,
- 0, 0, 34, 0, 0, 0, 35, 36, 0, 37,
- 0, 0, 0, 0, 0, 0, 504, 0, 0, 0,
- 44, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 51, 505,
- 507, 506, 0, 52, 0, 0, 0, 0, 226, 0,
- 0, 0, 0, 0, 43, 54, 32, 210, 0, 0,
- 40, 0, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 503, 0, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 215, 0,
- 0, 0, 0, 0, 0, 34, 0, 0, 0, 35,
- 36, 0, 37, 0, 0, 0, 0, 0, 0, 504,
- 0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
- 0, 551, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 51, 505, 507, 506, 0, 52, 0, 0, 0,
- 0, 226, 0, 0, 0, 0, 0, 43, 54, 32,
- 210, 0, 0, 40, 0, 0, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 503,
- 0, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 215, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 35, 36, 0, 37, 0, 0, 0, 0,
- 0, 0, 504, 0, 0, 0, 44, 0, 0, 0,
- 0, 0, 0, 0, 548, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 505, 507, 506, 0, 52,
- 0, 0, 0, 0, 226, 0, 0, 0, 0, 0,
- 43, 54, 32, 210, 0, 0, 40, 0, 0, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
- 0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
- 0, 0, 46, 0, 47, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
- 0, 52, 0, 53, 0, 55, 0, 56, 0, 0,
- 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
- 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, -122, 0, 0, 0, 29, 30,
- 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
- 35, 36, 0, 37, 0, 0, 0, 38, 0, 39,
- 41, 42, 0, 0, 44, 0, 0, 0, 46, 0,
- 47, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 51, 48, 50, 49, 0, 52, 0, 53,
- 0, 55, 0, 56, 0, 0, 0, 0, 43, 54,
- 32, 0, 0, 0, 40, 0, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 35, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 41, 42, 0, 0, 44, 0, 0, 0,
- 46, 0, 47, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 48, 50, 49, 0, 52,
- 0, 53, 0, 55, 272, 56, 0, 0, 0, 0,
- 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 49, 52, 50, 0,
+ 54, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 44, 56, 32, 0, 0, 0, 41, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 515, 0, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 219, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 0, 0, 0, 0, 516, 0,
0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 476, 0, 0, 29, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 0, 34, 0, 0, 0, 35, 36, 0,
- 37, 0, 0, 0, 38, 0, 39, 41, 42, 0,
- 0, 44, 0, 0, 0, 46, 0, 47, 0, 0,
- 477, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 48, 50, 49, 0, 52, 0, 53, 0, 55, 0,
- 56, 0, 0, 0, 0, 43, 54, 32, 0, 0,
- 0, 40, 0, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 476, 0, 0,
- 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 35, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 41, 42, 0, 0, 44, 0, 0, 0,
- 46, 0, 47, 0, 0, 482, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 48, 50, 49, 0, 52,
- 0, 53, 0, 55, 0, 56, 0, 0, 0, 0,
- 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 517, 519, 518, 0, 54, 0, 0, 0, 0,
+ 227, 0, 0, 0, 0, 0, 44, 56, 32, 214,
+ 0, 0, 41, 0, 0, 0, 0, 0, 46, 34,
+ 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 515, 0, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 219, 0, 0, 0, 0, 0, 0, 35,
+ 0, 0, 0, 36, 37, 0, 38, 0, 0, 0,
+ 0, 0, 0, 516, 0, 0, 0, 45, 0, 0,
+ 0, 0, 0, 0, 0, 560, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 517, 519, 518, 0,
+ 54, 0, 0, 0, 0, 227, 0, 0, 0, 0,
+ 0, 44, 56, 32, 214, 0, 0, 41, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 515, 0, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 219, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 0, 0, 0, 0, 516, 0,
0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 484, 0, 0, 29, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 0, 34, 0, 0, 0, 35, 36, 0,
- 37, 0, 0, 0, 38, 0, 39, 41, 42, 0,
- 0, 44, 0, 0, 0, 46, 0, 47, 0, 0,
- 485, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 48, 50, 49, 0, 52, 0, 53, 0, 55, 0,
- 56, 0, 0, 0, 0, 43, 54, 32, 0, 0,
- 0, 40, 0, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 484, 0, 0,
+ 563, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 517, 519, 518, 0, 54, 0, 0, 0, 0,
+ 227, 0, 0, 0, 0, 0, 44, 56, 32, 214,
+ 0, 0, 41, 0, 0, 0, 0, 0, 46, 34,
+ 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 35, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 41, 42, 0, 0, 44, 0, 0, 0,
- 46, 0, 47, 0, 0, 487, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 48, 50, 49, 0, 52,
- 0, 53, 0, 55, 0, 56, 0, 0, 0, 0,
- 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
+ 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
+ 47, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
+ 0, 55, 0, 57, 0, 58, 0, 0, 0, 0,
+ 44, 56, 32, 0, 0, 0, 41, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -125, 0, 0, 0, 29, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
+ 36, 37, 0, 38, 0, 0, 0, 39, 0, 40,
+ 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
+ 48, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 53, 49, 52, 50, 0, 54, 0, 55,
+ 0, 57, 0, 58, 0, 0, 0, 0, 44, 56,
+ 32, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 34, 217, 0, 0, 218, 36, 0, 37, 0, 0,
- 0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
- 0, 0, 46, 0, 47, 0, 0, 0, 0, 0,
- 0, 0, 221, 0, 0, 0, 51, 48, 50, 49,
- 223, 52, 0, 53, 225, 55, 0, 56, 0, 228,
- 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
- 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
+ 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
+ 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
+ 0, 0, 47, 0, 48, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 53, 49, 52, 50,
+ 0, 54, 0, 55, 0, 57, 282, 58, 0, 0,
+ 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
+ 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 496, 0, 0, 29,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+ 0, 36, 37, 0, 38, 0, 0, 0, 39, 0,
+ 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
+ 0, 48, 0, 0, 499, 0, 0, 0, 0, 0,
+ 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
+ 55, 0, 57, 0, 58, 0, 0, 0, 0, 44,
+ 56, 32, 0, 0, 0, 41, 0, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 496, 0, 0, 29, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 0, 39, 0, 40, 42, 43,
+ 0, 0, 45, 0, 0, 0, 47, 0, 48, 0,
+ 0, 497, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 49, 52, 50, 0, 54, 0, 55, 0, 57,
+ 0, 58, 0, 0, 0, 0, 44, 56, 32, 0,
+ 0, 0, 41, 0, 0, 0, 0, 0, 46, 34,
+ 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 488, 0, 0, 29, 30, 31, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
+ 0, 35, 0, 0, 0, 36, 37, 0, 38, 0,
+ 0, 0, 39, 0, 40, 42, 43, 0, 0, 45,
+ 0, 0, 0, 47, 0, 48, 0, 0, 489, 0,
+ 0, 0, 0, 0, 0, 0, 0, 53, 49, 52,
+ 50, 0, 54, 0, 55, 0, 57, 0, 58, 0,
+ 0, 0, 0, 44, 56, 32, 0, 0, 0, 41,
+ 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 488, 0, 0,
+ 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
+ 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
+ 47, 0, 48, 0, 0, 494, 0, 0, 0, 0,
+ 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
+ 0, 55, 0, 57, 0, 58, 0, 0, 0, 0,
+ 44, 56, 32, 0, 0, 0, 41, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
0, 0, 0, 0, 29, 30, 31, 0, 0, 0,
0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
- 0, 0, 34, 217, 0, 0, 583, 584, 0, 37,
- 0, 0, 0, 38, 0, 39, 41, 42, 0, 0,
- 44, 0, 0, 0, 46, 0, 47, 0, 0, 0,
- 0, 0, 0, 0, 221, 0, 0, 0, 51, 48,
- 50, 49, 223, 52, 0, 53, 225, 55, 0, 56,
- 0, 228, 0, 0, 43, 54, 32, 0, 0, 0,
- 40, 0, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 109, 110, 111, 0,
- 0, 113, 115, 116, 0, 0, 117, 0, 118, 0,
- 0, 0, 120, 121, 122, 0, 0, 0, 0, 0,
- 0, 34, 123, 124, 125, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 126, 0, 0, 0, 0,
+ 0, 0, 35, 220, 0, 0, 221, 37, 0, 38,
+ 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
+ 45, 0, 0, 0, 47, 0, 48, 0, 0, 0,
+ 0, 0, 0, 0, 223, 0, 0, 0, 53, 49,
+ 52, 50, 224, 54, 0, 55, 226, 57, 0, 58,
+ 0, 229, 0, 0, 44, 56, 32, 0, 0, 0,
+ 41, 0, 0, 0, 0, 0, 46, 34, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 35, 220, 0, 0,
+ 595, 596, 0, 38, 0, 0, 0, 39, 0, 40,
+ 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
+ 48, 0, 0, 0, 0, 0, 0, 0, 223, 0,
+ 0, 0, 53, 49, 52, 50, 224, 54, 0, 55,
+ 226, 57, 0, 58, 0, 229, 0, 0, 44, 56,
+ 32, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 111, 112, 113, 0, 0, 115, 117, 118,
+ 0, 0, 119, 0, 120, 0, 0, 0, 122, 123,
+ 124, 0, 0, 0, 0, 0, 0, 35, 125, 126,
+ 127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 128, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 131, 0, 0,
+ 0, 0, 0, 0, 49, 52, 50, 132, 133, 134,
+ 0, 136, 137, 138, 139, 140, 141, 0, 0, 129,
+ 135, 121, 114, 116, 130, 0, 0, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 111, 112, 113, 0, 0, 115, 117,
+ 118, 0, 0, 119, 0, 120, 0, 0, 0, 122,
+ 123, 124, 0, 0, 0, 0, 0, 0, 35, 125,
+ 126, 127, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 128, 0, 0, 0, 395, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 131, 0,
+ 0, 0, 0, 0, 397, 49, 52, 50, 132, 133,
+ 134, 0, 136, 137, 138, 139, 140, 141, 0, 0,
+ 129, 135, 121, 114, 116, 130, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 111, 112, 113, 0, 0, 115,
+ 117, 118, 0, 0, 119, 0, 120, 0, 0, 0,
+ 122, 123, 124, 0, 0, 0, 0, 0, 0, 35,
+ 125, 126, 127, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 128, 0, 0, 0, 395, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 131,
+ 0, 0, 0, 0, 0, 397, 49, 52, 50, 132,
+ 133, 134, 0, 136, 137, 138, 139, 140, 141, 0,
+ 0, 129, 135, 121, 114, 116, 130, 0, 0, 0,
+ 0, 0, 0, 46, 374, 380, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 111, 112, 113, 0, 0,
+ 115, 117, 118, 0, 0, 119, 0, 120, 0, 0,
+ 0, 122, 123, 124, 0, 0, 0, 0, 0, 0,
+ 35, 125, 126, 127, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 128, 0, 0, 0, 395, 0,
+ 0, 0, 0, 0, 0, 0, 396, 0, 0, 0,
+ 131, 0, 0, 0, 0, 0, 397, 49, 52, 50,
+ 132, 133, 134, 0, 136, 137, 138, 139, 140, 141,
+ 0, 0, 129, 135, 121, 114, 116, 130, 0, 0,
+ 0, 0, 0, 0, 46, 374, 380, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 213, 0, 0, 0,
+ 0, 215, 0, 29, 30, 31, 217, 0, 0, 0,
+ 0, 0, 0, 218, 33, 0, 0, 0, 0, 0,
+ 0, 35, 220, 0, 0, 221, 37, 0, 38, 0,
+ 0, 0, 39, 0, 40, 42, 43, 0, 0, 45,
+ 0, 0, 0, 47, 0, 48, 0, 0, 0, 0,
+ 0, 222, 0, 223, 0, 0, 0, 53, 49, 52,
+ 50, 224, 54, 225, 55, 226, 57, 227, 58, 228,
+ 229, 0, 0, 44, 56, 32, 214, 216, 0, 41,
+ 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 213, 0, 0,
+ 0, 0, 215, 0, 29, 30, 31, 217, 0, 0,
+ 0, 0, 0, 0, 218, 219, 0, 0, 0, 0,
+ 0, 0, 35, 220, 0, 0, 221, 37, 0, 38,
+ 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
+ 45, 0, 0, 0, 47, 0, 48, 0, 0, 0,
+ 0, 0, 222, 0, 223, 0, 0, 0, 53, 49,
+ 52, 50, 224, 54, 225, 55, 226, 57, 227, 58,
+ 228, 229, 0, 0, 44, 56, 32, 214, 216, 0,
+ 41, 0, 0, 0, 0, 0, 46, 34, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 600, 112,
+ 113, 0, 0, 602, 117, 604, 30, 31, 605, 0,
+ 120, 0, 0, 0, 122, 607, 608, 0, 0, 0,
+ 0, 0, 0, 35, 609, 126, 127, 221, 37, 0,
+ 38, 0, 0, 0, 39, 0, 40, 610, 43, 0,
+ 0, 612, 0, 0, 0, 47, 0, 48, 0, 0,
+ 0, 0, 0, 613, 0, 223, 0, 0, 0, 614,
+ 49, 52, 50, 615, 616, 617, 55, 619, 620, 621,
+ 622, 623, 624, 0, 0, 611, 618, 606, 601, 603,
+ 130, 41, 0, 0, 0, 0, 0, 46, 374, 380,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 365,
+ 112, 113, 0, 0, 367, 117, 369, 30, 31, 370,
+ 0, 120, 0, 0, 0, 122, 372, 373, 0, 0,
+ 0, 0, 0, 0, 35, 375, 126, 127, 221, 37,
+ 0, 38, 0, 0, 0, 39, 0, 40, 376, 43,
+ 0, 0, 378, 0, 0, 0, 47, 0, 48, 0,
+ -271, 0, 0, 0, 379, 0, 223, 0, 0, 0,
+ 381, 49, 52, 50, 382, 383, 384, 55, 386, 387,
+ 388, 389, 390, 391, 0, 0, 377, 385, 371, 366,
+ 368, 130, 41, 0, 0, 0, 0, 0, 46, 374,
+ 380, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 565, 148, 545, 16, 649, 547, 541, 469, 320, 529,
+ 528, 630, 183, 248, 263, 500, 485, 447, 629, 183,
+ 627, 444, 253, 393, 587, 652, 313, 152, 643, 572,
+ 591, 575, 586, 638, 331, 574, 453, 455, 466, 253,
+ 437, 178, 433, 253, 0, 248, 584, 458, 248, 313,
+ 441, 183, 444, 457, 237, 190, 447, 188, 206, 425,
+ 400, 462, 351, 313, 347, 150, 165, 447, 475, 444,
+ 183, 145, 393, 260, 0, 409, 173, 409, 260, 362,
+ 171, 514, 409, 495, 362, 393, 206, 498, 628, 313,
+ 313, 206, 356, 142, 206, 331, 362, 599, 403, 0,
+ 345, 62, 62, 62, 182, 62, 299, 182, 295, 206,
+ 410, 417, 410, 206, 62, 393, 62, 410, 62, 296,
+ 148, 298, 148, 297, 62, 62, 182, 504, 412, 62,
+ 180, 502, 511, 206, 512, 62, 108, 460, 188, 62,
+ 394, 188, 62, 206, 460, 247, 62, 206, 459, 206,
+ 62, 102, 459, 62, 62, 514, 206, 62, 653, 503,
+ 407, 343, 341, 62, 313, 110, 419, 167, 188, 187,
+ 170, 340, 514, 104, 0, 553, 422, 206, 62, 206,
+ 62, 63, 62, 72, 62, 510, 71, 97, 62, 514,
+ 70, 62, 557, 69, 355, 62, 239, 62, 493, 318,
+ 86, 469, 492, 62, 483, 74, 242, 206, 93, 62,
+ 353, 62, 206, 260, 95, 0, 96, 62, 62, 62,
+ 322, 62, 94, 206, 100, 98, 206, 99, 62, 247,
+ 277, 464, 0, 206, 79, 281, 314, 468, 62, 62,
+ 206, 507, 91, 246, 206, 62, 62, 349, 505, 90,
+ 206, 62, 62, 460, 459, 62, 206, 506, 62, 401,
+ 206, 62, 92, 309, 62, 108, 281, 362, 281, 281,
+ 0, 313, 206, 62, 304, 479, 0, 309, 281, 62,
+ 206, 327, 281, 0, 281, 337, 300, 309, 324, 0,
+ 0, 62, 281, 0, 110, 177, 281, 62, 301, 308,
+ 309, 0, 281, 309, 302, 281, 62, 62, 281, 330,
+ 62, 281, 281, 289, 514, 281, 0, 0, 306, 284,
+ 0, 522, 328, 569, 561, 311, 553, 564, 625, 0,
+ 0, 0, 514, 513, 523, 514, 0, 0, 0, 522,
+ 0, 0, 522, 316, 0, 0, 0, 0, 0, 485,
+ 440, 513, 523, 0, 513, 523, 533, 534, 535, 536,
+ 540, 537, 538, 577, 533, 534, 535, 536, 540, 537,
+ 538, 594, 0, 0, 0, 0, 362, 0, 597, 598,
+ 533, 534, 535, 536, 540, 537, 538, 0, 0, 206,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 129, 0, 0, 0, 0, 0, 0, 48, 50,
- 49, 130, 131, 132, 0, 134, 135, 136, 137, 138,
- 139, 0, 0, 127, 133, 119, 112, 114, 128, 0,
- 0, 0, 0, 0, 0, 45, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 109, 110, 111, 0, 0,
- 113, 115, 116, 0, 0, 117, 0, 118, 0, 0,
- 0, 120, 121, 122, 0, 0, 0, 0, 0, 0,
- 394, 123, 124, 125, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 126, 0, 0, 0, 395, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 129, 0, 0, 0, 0, 0, 399, 396, 398, 0,
- 130, 131, 132, 0, 134, 135, 136, 137, 138, 139,
- 0, 0, 127, 133, 119, 112, 114, 128, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 109, 110, 111, 0, 0, 113,
- 115, 116, 0, 0, 117, 0, 118, 0, 0, 0,
- 120, 121, 122, 0, 0, 0, 0, 0, 0, 394,
- 123, 124, 125, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 126, 0, 0, 0, 395, 0, 0,
- 0, 0, 0, 0, 0, 397, 0, 0, 0, 129,
- 0, 0, 0, 0, 0, 399, 396, 398, 0, 130,
- 131, 132, 0, 134, 135, 136, 137, 138, 139, 0,
- 0, 127, 133, 119, 112, 114, 128, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 209, 0, 0, 0, 0, 211, 0,
- 29, 30, 31, 213, 0, 0, 0, 0, 0, 0,
- 214, 215, 0, 0, 0, 0, 0, 0, 216, 217,
- 0, 0, 218, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 41, 42, 0, 0, 44, 0, 0, 0,
- 46, 0, 47, 0, 0, 0, 0, 0, 220, 0,
- 221, 0, 0, 0, 51, 219, 222, 49, 223, 52,
- 224, 53, 225, 55, 226, 56, 227, 228, 0, 0,
- 43, 54, 32, 210, 212, 0, 40, 0, 0, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 209, 0, 0, 0, 0, 211, 0, 29,
- 30, 31, 213, 0, 0, 0, 0, 0, 0, 214,
- 33, 0, 0, 0, 0, 0, 0, 216, 217, 0,
- 0, 218, 36, 0, 37, 0, 0, 0, 38, 0,
- 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
- 0, 47, 0, 0, 0, 0, 0, 220, 0, 221,
- 0, 0, 0, 51, 219, 222, 49, 223, 52, 224,
- 53, 225, 55, 226, 56, 227, 228, 0, 0, 43,
- 54, 32, 210, 212, 0, 40, 0, 0, 0, 0,
- 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 587, 110, 111, 0, 0, 589, 115, 591, 30,
- 31, 592, 0, 118, 0, 0, 0, 120, 594, 595,
- 0, 0, 0, 0, 0, 0, 596, 597, 124, 125,
- 218, 36, 0, 37, 0, 0, 0, 38, 0, 39,
- 598, 42, 0, 0, 600, 0, 0, 0, 46, 0,
- 47, 0, 0, 0, 0, 0, 602, 0, 221, 0,
- 0, 0, 604, 601, 603, 49, 605, 606, 607, 53,
- 609, 610, 611, 612, 613, 614, 0, 0, 599, 608,
- 593, 588, 590, 128, 40, 0, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 362, 110, 111, 0, 0, 364, 115, 366, 30, 31,
- 367, 0, 118, 0, 0, 0, 120, 369, 370, 0,
- 0, 0, 0, 0, 0, 371, 372, 124, 125, 218,
- 36, 0, 37, 0, 0, 0, 38, 0, 39, 373,
- 42, 0, 0, 375, 0, 0, 0, 46, 0, 47,
- 0, -268, 0, 0, 0, 377, 0, 221, 0, 0,
- 0, 379, 376, 378, 49, 380, 381, 382, 53, 384,
- 385, 386, 387, 388, 389, 0, 0, 374, 383, 368,
- 363, 365, 128, 40, 0, 0, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 639, 310, 529, 533, 516, 535, 517, 499, 500, 462,
- 498, 620, 553, 312, 243, 16, 562, 440, 437, 633,
- 238, 250, 473, 182, 253, 182, 617, 488, 359, 563,
- 303, 321, 619, 642, 150, 575, 560, 250, 628, 163,
- 426, 348, 250, 579, 186, 350, 182, 574, 468, 340,
- 430, 345, 572, 434, 359, 457, 448, 446, 238, 450,
- 455, 459, 243, 243, 461, 352, 238, 451, 354, 148,
- 403, 483, 486, 176, 437, 143, 440, 401, 411, 335,
- 188, 437, 440, 169, 237, 171, 237, 140, 359, 393,
- 337, 303, 308, 416, 391, 146, 418, 303, 405, 359,
- 359, 0, 0, 146, 0, 0, 0, 60, 178, 60,
- 0, 452, 288, 0, 303, 60, 405, 60, 405, 180,
- 285, 60, 60, 60, 491, 186, 286, 60, 287, 60,
- 406, 453, 502, 502, 303, 643, 545, 60, 321, 453,
- 60, 165, 180, 60, 60, 490, 180, 60, 406, 60,
- 406, 452, 267, 146, 60, 60, 60, 271, 408, 289,
- 60, 84, 69, 168, 60, 60, 60, 100, 106, 60,
- 97, 98, 96, 502, 481, 0, 541, 72, 480, 436,
- 433, 60, 60, 333, 60, 60, 91, 92, 90, 60,
- 93, 60, 60, 89, 108, 60, 94, 339, 77, 88,
- 60, 502, 462, 331, 60, 95, 303, 61, 618, 106,
- 342, 330, 60, 60, 453, 452, 60, 60, 494, 495,
- 60, 60, 493, 60, 60, 492, 60, 70, 68, 60,
- 60, 102, 67, 60, 271, 108, 175, 299, 271, 0,
- 299, 0, 271, 0, 314, 271, 294, 299, 60, 60,
- 60, 0, 271, 271, 271, 271, 60, 279, 274, 320,
- 0, 271, 318, 60, 0, 317, 0, 296, 271, 327,
- 292, 60, 60, 472, 0, 304, 271, 271, 291, 290,
- 557, 299, 299, 541, 549, 615, 271, 271, 502, 0,
- 552, 0, 502, 0, 0, 510, 0, 0, 502, 510,
- 0, 0, 303, 298, 301, 510, 473, 501, 511, 0,
- 0, 501, 511, 0, 0, 0, 0, 501, 511, 521,
- 522, 523, 524, 528, 525, 526, 582, 0, 0, 0,
- 0, 0, 0, 585, 586, 521, 522, 523, 524, 528,
- 525, 526, 557, 0, 0, 0, 0, 0, 0, 558,
- 559, 521, 522, 523, 524, 528, 525, 526, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 306, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 443,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 565, 521, 522, 523,
- 524, 528, 525, 526, 0, 0, 0, 0, 0, 0,
+ 0, 0, 569, 0, 0, 0, 0, 0, 0, 570,
+ 571, 533, 534, 535, 536, 540, 537, 538, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -697,120 +705,101 @@ const short QQmlJSGrammar::action_info [] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0};
+ 0, 0, 0, 0, 0, 0, 0};
const short QQmlJSGrammar::action_check [] = {
- 36, 36, 7, 55, 17, 7, 7, 60, 8, 7,
- 7, 37, 36, 7, 20, 33, 55, 55, 60, 36,
- 36, 33, 33, 55, 8, 7, 36, 7, 16, 33,
- 7, 34, 7, 7, 7, 60, 7, 36, 33, 7,
- 36, 33, 33, 5, 7, 5, 5, 33, 29, 36,
- 91, 36, 7, 36, 7, 33, 7, 7, 66, 66,
- 36, 33, 7, 7, 31, 1, 7, 24, 33, 2,
- 60, 60, 36, 8, 8, 7, 55, 1, 36, 48,
- 2, 8, 7, 2, 7, 2, 79, 36, 17, 36,
- 60, 7, 48, 36, 36, 61, 33, 36, 1, 60,
- 0, 8, 8, 1, 8, 6, 8, -1, -1, 61,
- 48, 7, 8, 8, 60, 8, 10, -1, 8, 20,
- 8, -1, 48, -1, 8, 79, 40, 40, 15, 77,
- -1, 61, 60, 8, 8, 8, 15, 51, 51, 79,
- 8, 61, 62, 61, 62, 50, 7, 34, 8, 54,
- 61, 62, 61, 62, 56, 34, 60, 42, 79, 8,
- 91, 55, 40, 56, 12, 60, 56, 50, 53, 61,
- 62, 54, 60, 51, 29, 61, 62, 61, 40, 61,
- 62, 12, 56, 29, 25, 60, 27, 60, 56, 51,
- 61, 62, 25, 7, 27, 8, 12, 38, -1, 25,
- 60, 27, 7, -1, 25, 38, 27, 29, 25, 57,
- 27, 60, 38, 7, 25, 63, 27, 38, 36, 33,
- 75, 38, 25, 25, 27, 27, 57, 38, 29, 75,
- -1, 86, 63, 7, 29, 38, 38, 25, 29, 27,
- 86, 57, 8, 61, 62, 8, -1, 63, 61, 62,
- 38, 15, 25, 75, 27, 8, 61, 62, 25, -1,
- 27, 61, 62, -1, 86, 38, -1, 61, 62, -1,
- 34, 38, 36, 25, 75, 27, 61, 62, -1, 93,
- 75, 15, -1, -1, 75, 86, 38, 61, 62, 89,
- 25, 86, 27, -1, 60, 86, 18, 19, 61, 62,
- 34, -1, 36, 38, 18, 19, -1, 92, 61, 62,
- -1, -1, -1, 29, 47, 15, 18, 19, -1, -1,
- 15, 18, 19, 45, 46, 29, -1, -1, 61, 62,
- 29, 45, 46, 33, 34, 29, 36, 15, 33, 34,
- -1, 36, 29, 45, 46, 29, -1, -1, 45, 46,
- 66, 67, 68, 29, -1, -1, 34, -1, 36, 92,
- -1, -1, 66, 67, 68, 29, -1, 66, 67, 68,
- -1, -1, 66, 67, 68, -1, 29, 93, -1, 66,
- 67, 68, 66, 67, 68, 29, 23, 24, -1, 93,
- 66, 67, 68, 29, 93, 32, -1, -1, 35, 93,
- 37, -1, 66, 67, 68, 29, 93, -1, 29, 93,
- -1, -1, -1, 66, 67, 68, 29, 93, -1, -1,
- -1, 29, 66, 67, 68, 23, 24, 29, -1, 93,
- 66, 67, 68, -1, 32, -1, 29, 35, -1, 37,
- 93, -1, 66, 67, 68, 66, 67, 68, -1, 93,
- -1, 29, -1, 66, 67, 68, -1, 93, 66, 67,
- 68, -1, -1, -1, 66, 67, 68, 23, 24, 93,
- -1, -1, 93, 66, 67, 68, 32, -1, -1, 35,
- 93, 37, -1, -1, -1, 93, -1, -1, 66, 67,
- 68, 93, 29, -1, -1, 23, 24, -1, -1, 36,
- 93, -1, -1, 31, 32, 23, 24, 35, -1, 37,
- -1, -1, -1, -1, 32, 93, -1, 35, -1, 37,
- 95, 96, 97, 98, 99, 100, 29, 23, 24, 66,
- 67, 68, -1, 36, 29, 31, 32, 23, 24, 35,
- -1, 37, 29, -1, -1, 31, 32, -1, -1, 35,
- 29, 37, -1, -1, -1, -1, 93, -1, -1, -1,
- -1, -1, -1, 66, 67, 68, 61, 62, -1, -1,
- 29, 66, 67, 68, 61, 62, -1, -1, 29, 66,
- 67, 68, 61, 62, -1, 23, 24, 66, 67, 68,
- 93, -1, -1, 31, 32, -1, -1, 35, 93, 37,
- -1, -1, 61, 62, -1, -1, 93, 66, 67, 68,
- 61, 62, 3, -1, 93, 66, 67, 68, -1, -1,
- -1, -1, 13, -1, -1, -1, 17, -1, -1, -1,
- 3, -1, -1, -1, 93, 26, -1, 28, -1, -1,
- 13, -1, 93, -1, 17, -1, -1, -1, 39, -1,
- 41, 42, -1, 26, -1, 28, -1, -1, 49, -1,
- -1, 52, 53, -1, -1, 29, 39, 58, 41, 42,
- -1, -1, -1, 64, -1, -1, 49, -1, -1, 52,
- 53, -1, -1, -1, -1, 58, -1, -1, -1, 80,
- -1, 64, -1, -1, -1, -1, -1, 61, 62, -1,
- -1, -1, 66, 67, 68, -1, -1, 80, -1, -1,
+ 60, 7, 7, 7, 34, 91, 24, 7, 61, 36,
+ 33, 36, 7, 7, 7, 60, 33, 33, 55, 66,
+ 8, 33, 55, 36, 16, 7, 36, 29, 8, 7,
+ 7, 55, 17, 36, 7, 7, 7, 7, 7, 36,
+ 55, 7, 7, 33, 33, 36, 33, 33, 7, 60,
+ 7, 60, 20, 36, 33, 36, 55, 7, 33, 60,
+ 5, 37, 36, 5, 60, 5, 7, 2, 66, 36,
+ 33, 33, 36, 7, 1, 8, 60, 8, 33, 2,
+ 36, 1, 8, 36, 2, 1, 8, 2, 17, 1,
+ 0, 8, -1, 7, 55, 33, 33, -1, -1, 48,
+ 60, -1, 6, 31, 55, 48, 36, 61, 60, 8,
+ -1, 36, 60, -1, 7, 61, 20, 36, 8, 77,
+ 15, 60, 8, 55, 48, 36, 10, 36, 36, 36,
+ 7, 8, 79, 8, 8, 79, 8, 42, 8, 34,
+ 8, 8, 48, 40, 8, 8, -1, 60, 53, 50,
+ -1, 8, -1, 54, 51, 91, 15, 8, 79, 61,
+ 62, 60, 8, 61, 62, 61, 62, 61, 62, 40,
+ 60, 55, 61, 62, 60, 34, 61, 62, 61, 62,
+ 51, 56, 61, 62, 56, 50, 60, 40, 15, 54,
+ 60, 40, 60, 56, 61, 25, 60, 27, 51, 61,
+ 62, 29, 51, 60, 29, 56, 15, 34, 38, 36,
+ 15, 29, 8, 8, 12, 61, 62, 61, 62, 12,
+ 36, 25, 7, 27, 25, 34, 27, 36, 25, 34,
+ 27, 36, 7, 15, 38, 29, 25, 38, 27, 7,
+ -1, 38, 25, 29, 27, 61, 62, 75, 92, 38,
+ 75, 12, 34, 7, 36, 38, -1, 75, 86, 57,
+ 56, 86, -1, -1, 57, 63, 61, 62, 86, 25,
+ 63, 27, 25, -1, 27, -1, 61, 62, 25, 33,
+ 27, 75, 38, 61, 62, 38, 61, 62, 25, 75,
+ 27, 38, 86, 61, 62, 25, 57, 27, 29, -1,
+ 86, 38, 63, 25, 25, 27, 27, 15, 38, 8,
+ -1, 89, -1, 18, 19, 47, 38, 38, 18, 19,
+ 18, 19, -1, -1, -1, 33, 34, -1, 36, 61,
+ 62, 15, 97, 98, 99, 100, 101, 102, -1, 93,
+ 45, 46, 23, 24, 75, 45, 46, 45, 46, 33,
+ 34, 32, 36, -1, 35, 86, 37, 23, 24, -1,
+ 92, -1, 61, 62, 23, 24, 32, -1, -1, 35,
+ -1, 37, -1, 32, 23, 24, 35, -1, 37, -1,
+ 23, 24, -1, 32, -1, -1, 35, -1, 37, 32,
+ 23, 24, 35, 29, 37, -1, -1, -1, 31, 32,
+ 23, 24, 35, 29, 37, -1, 18, 19, 31, 32,
+ 23, 24, 35, 29, 37, -1, -1, -1, 31, 32,
+ -1, -1, 35, 29, 37, -1, 29, -1, -1, -1,
+ 66, 67, 68, 45, 46, -1, -1, -1, -1, -1,
+ 66, 67, 68, -1, 29, -1, -1, 29, -1, -1,
+ 66, 67, 68, -1, -1, -1, -1, 93, 94, 95,
+ 66, 67, 68, 66, 67, 68, -1, 93, 94, 95,
+ -1, -1, -1, -1, -1, -1, -1, 93, 94, 95,
+ 29, 66, 67, 68, 66, 67, 68, 93, 94, 95,
+ 93, 94, 95, 23, 24, 29, -1, -1, 29, -1,
+ -1, 31, 32, -1, -1, 35, -1, 37, 93, 94,
+ 95, 93, 94, 95, 29, -1, -1, 66, 67, 68,
+ -1, 36, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 29, 66, 67, 68, 66, 67, 68, 36, -1,
+ -1, -1, -1, -1, 93, 94, 95, -1, -1, -1,
+ -1, 66, 67, 68, 29, -1, -1, -1, -1, 93,
+ 94, 95, 93, 94, 95, 29, -1, -1, 66, 67,
+ 68, -1, 36, -1, -1, 29, -1, -1, 93, 94,
+ 95, -1, -1, -1, 29, -1, 61, 62, -1, -1,
+ -1, 66, 67, 68, -1, 93, 94, 95, -1, -1,
+ -1, -1, 66, 67, 68, 29, -1, -1, -1, -1,
+ -1, -1, 66, 67, 68, -1, 61, 62, 93, 94,
+ 95, 66, 67, 68, -1, -1, -1, -1, -1, 93,
+ 94, 95, -1, -1, -1, -1, -1, 61, 62, 93,
+ 94, 95, 66, 67, 68, -1, -1, -1, 93, 94,
+ 95, 29, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 93,
+ 94, 95, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 61, 62, 3, -1, -1, 66, 67,
+ 68, -1, -1, -1, -1, 13, -1, -1, -1, 17,
+ -1, -1, -1, -1, -1, -1, -1, -1, 26, -1,
+ 28, -1, -1, 31, -1, 93, 94, 95, -1, -1,
+ -1, 39, -1, 41, 42, -1, -1, 3, -1, -1,
+ -1, 49, -1, -1, 52, 53, -1, 13, -1, -1,
+ 58, 17, -1, -1, -1, -1, 64, -1, -1, -1,
+ 26, -1, 28, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 80, 39, -1, 41, 42, -1, -1, -1,
+ -1, -1, -1, 49, -1, -1, 52, 53, -1, -1,
+ -1, -1, 58, -1, -1, -1, -1, -1, 64, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 12, 13, -1, 93,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, 3,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, 13,
- 36, -1, -1, 17, -1, -1, -1, 43, -1, -1,
- -1, 47, 26, -1, 28, -1, -1, 31, -1, -1,
- -1, -1, -1, -1, -1, 39, -1, 41, 42, 65,
- 66, 67, 68, -1, 70, 49, -1, -1, 52, 53,
- -1, -1, -1, -1, 58, 81, 82, 83, -1, -1,
- 64, 87, -1, -1, -1, -1, -1, 93, -1, -1,
- -1, -1, -1, -1, -1, -1, 80, -1, -1, -1,
+ -1, -1, -1, -1, 80, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 12, 13, -1, -1, -1, -1, -1, -1, 12,
- 13, 22, -1, -1, -1, -1, -1, -1, 29, 22,
- -1, -1, 33, 34, -1, 36, 29, -1, -1, -1,
- 33, 34, 43, 36, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, -1, -1, -1,
43, -1, -1, -1, 47, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 65, 66, 67, 68, -1, 70, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, 81, 82,
- 83, -1, 93, -1, 87, -1, -1, -1, -1, -1,
- 93, -1, 12, 13, -1, -1, -1, -1, -1, -1,
- 12, 13, 22, -1, -1, -1, -1, -1, -1, 29,
- 22, -1, -1, 33, 34, -1, 36, 29, -1, -1,
- -1, 33, 34, 43, 36, -1, -1, 47, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
- 70, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, 81, 82, 83, -1, -1, -1, 87, -1, 81,
- 82, 83, -1, 93, -1, 87, -1, -1, -1, -1,
- -1, 93, -1, 12, 13, -1, -1, -1, -1, -1,
- -1, 12, 13, 22, -1, -1, -1, -1, -1, -1,
- 29, 22, -1, -1, 33, 34, -1, 36, 29, -1,
- -1, -1, 33, 34, 43, 36, -1, -1, 47, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- 81, 82, 83, -1, 93, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 81, 82,
+ 83, -1, -1, -1, 87, -1, -1, -1, -1, -1,
+ 93, 94, 95, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 12, 13, -1, -1, -1, -1, -1, -1,
-1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
-1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
@@ -819,44 +808,45 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
70, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 81, 82, 83, -1, -1, -1, 87, -1, -1,
- -1, -1, -1, 93, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 10, -1, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
- -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
- 47, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
- 67, 68, -1, 70, -1, -1, -1, -1, 75, -1,
- -1, -1, -1, -1, 81, 82, 83, 84, -1, -1,
- 87, -1, -1, -1, -1, -1, 93, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 10, -1, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, -1, -1, -1, 43,
- -1, -1, -1, 47, -1, -1, -1, -1, -1, -1,
- -1, 55, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, -1, -1,
- -1, 75, -1, -1, -1, -1, -1, 81, 82, 83,
- 84, -1, -1, 87, -1, -1, -1, -1, -1, 93,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 10,
- -1, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 93, 94, 95, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
+ 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
+ -1, -1, 87, -1, -1, -1, -1, -1, 93, 94,
+ 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 10, -1, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
+ 70, -1, -1, -1, -1, 75, -1, -1, -1, -1,
+ -1, 81, 82, 83, 84, -1, -1, 87, -1, -1,
+ -1, -1, -1, 93, 94, 95, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
+ 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
+ -1, -1, 87, -1, -1, -1, -1, -1, 93, 94,
+ 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
-1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
- -1, -1, -1, -1, 55, -1, -1, -1, -1, -1,
+ -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
+ -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
+ 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, -1, -1, -1, 75, -1, -1, -1, -1, -1,
- 81, 82, 83, 84, -1, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, -1, -1, 93, -1, -1, -1, -1, -1,
+ -1, 72, -1, 74, -1, 76, -1, -1, -1, -1,
+ 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
+ -1, -1, 93, 94, 95, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 7, -1, -1, -1, 11, 12,
13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
-1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
@@ -866,44 +856,45 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, 65, 66, 67, 68, -1, 70, -1, 72,
-1, 74, -1, 76, -1, -1, -1, -1, 81, 82,
83, -1, -1, -1, 87, -1, -1, -1, -1, -1,
- 93, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, 72, -1, 74, 75, 76, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 8, -1, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
- 76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
- -1, 87, -1, -1, -1, -1, -1, 93, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 8, -1, -1,
- 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, 56, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, 72, -1, 74, -1, 76, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 8, -1, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
- 76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
- -1, 87, -1, -1, -1, -1, -1, 93, -1, -1,
+ 93, 94, 95, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, 72, -1, 74, 75, 76, -1, -1,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ -1, -1, -1, -1, 93, 94, 95, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8, -1, -1, 11,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
+ -1, 53, -1, -1, 56, -1, -1, -1, -1, -1,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
+ 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
+ -1, 93, 94, 95, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
+ -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, -1, 87, -1, -1, -1, -1, -1, 93, 94,
+ 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 8, -1, -1, 11, 12, 13, -1, -1, -1, -1,
+ -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
+ -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
+ -1, -1, -1, 51, -1, 53, -1, -1, 56, -1,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ 68, -1, 70, -1, 72, -1, 74, -1, 76, -1,
+ -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
+ -1, -1, -1, -1, -1, 93, 94, 95, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 8, -1, -1,
11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
-1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
@@ -913,16 +904,7 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
-1, 72, -1, 74, -1, 76, -1, -1, -1, -1,
81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, 30, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
- -1, -1, 61, -1, -1, -1, 65, 66, 67, 68,
- 69, 70, -1, 72, 73, 74, -1, 76, -1, 78,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, -1, -1, 93, -1, -1, -1, -1, -1,
+ -1, -1, 93, 94, 95, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 11, 12, 13, -1, -1, -1,
-1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
-1, -1, 29, 30, -1, -1, 33, 34, -1, 36,
@@ -931,120 +913,149 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, -1, -1, 61, -1, -1, -1, 65, 66,
67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
-1, 78, -1, -1, 81, 82, 83, -1, -1, -1,
- 87, -1, -1, -1, -1, -1, 93, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
- -1, 9, 10, 11, -1, -1, 14, -1, 16, -1,
- -1, -1, 20, 21, 22, -1, -1, -1, -1, -1,
- -1, 29, 30, 31, 32, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 43, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 59, -1, -1, -1, -1, -1, -1, 66, 67,
- 68, 69, 70, 71, -1, 73, 74, 75, 76, 77,
- 78, -1, -1, 81, 82, 83, 84, 85, 86, -1,
- -1, -1, -1, -1, -1, 93, -1, -1, -1, -1,
+ 87, -1, -1, -1, -1, -1, 93, 94, 95, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
+ 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
+ 53, -1, -1, -1, -1, -1, -1, -1, 61, -1,
+ -1, -1, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, 76, -1, 78, -1, -1, 81, 82,
+ 83, -1, -1, -1, 87, -1, -1, -1, -1, -1,
+ 93, 94, 95, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
+ -1, -1, 14, -1, 16, -1, -1, -1, 20, 21,
+ 22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
+ 32, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 43, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 59, -1, -1,
+ -1, -1, -1, -1, 66, 67, 68, 69, 70, 71,
+ -1, 73, 74, 75, 76, 77, 78, -1, -1, 81,
+ 82, 83, 84, 85, 86, -1, -1, -1, -1, -1,
+ -1, 93, 94, 95, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
+ 11, -1, -1, 14, -1, 16, -1, -1, -1, 20,
+ 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
+ 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, 69, 70,
+ 71, -1, 73, 74, 75, 76, 77, 78, -1, -1,
+ 81, 82, 83, 84, 85, 86, -1, -1, -1, -1,
+ -1, -1, 93, 94, 95, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 4, 5, 6, -1, -1, 9,
+ 10, 11, -1, -1, 14, -1, 16, -1, -1, -1,
+ 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, -1, 73, 74, 75, 76, 77, 78, -1,
+ -1, 81, 82, 83, 84, 85, 86, -1, -1, -1,
+ -1, -1, -1, 93, 94, 95, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 4, 5, 6, -1, -1,
9, 10, 11, -1, -1, 14, -1, 16, -1, -1,
-1, 20, 21, 22, -1, -1, -1, -1, -1, -1,
29, 30, 31, 32, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, -1, -1, -1, -1, -1, 65, 66, 67, -1,
+ -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
+ 59, -1, -1, -1, -1, -1, 65, 66, 67, 68,
69, 70, 71, -1, 73, 74, 75, 76, 77, 78,
-1, -1, 81, 82, 83, 84, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, 94, 95, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 4, -1, -1, -1,
+ -1, 9, -1, 11, 12, 13, 14, -1, -1, -1,
+ -1, -1, -1, 21, 22, -1, -1, -1, -1, -1,
+ -1, 29, 30, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
+ -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
+ -1, 59, -1, 61, -1, -1, -1, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+ 78, -1, -1, 81, 82, 83, 84, 85, -1, 87,
+ -1, -1, -1, -1, -1, 93, 94, 95, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 4, -1, -1,
+ -1, -1, 9, -1, 11, 12, 13, 14, -1, -1,
+ -1, -1, -1, -1, 21, 22, -1, -1, -1, -1,
+ -1, -1, 29, 30, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
+ 47, -1, -1, -1, 51, -1, 53, -1, -1, -1,
+ -1, -1, 59, -1, 61, -1, -1, -1, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, -1, -1, 81, 82, 83, 84, 85, -1,
+ 87, -1, -1, -1, -1, -1, 93, 94, 95, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
+ 6, -1, -1, 9, 10, 11, 12, 13, 14, -1,
+ 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
+ -1, -1, -1, 29, 30, 31, 32, 33, 34, -1,
+ 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
+ -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
+ -1, -1, -1, 59, -1, 61, -1, -1, -1, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
+ 86, 87, -1, -1, -1, -1, -1, 93, 94, 95,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
+ 5, 6, -1, -1, 9, 10, 11, 12, 13, 14,
+ -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
+ -1, -1, -1, -1, 29, 30, 31, 32, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ 55, -1, -1, -1, 59, -1, 61, -1, -1, -1,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
+ 85, 86, 87, -1, -1, -1, -1, -1, 93, 94,
+ 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+ 15, 39, 29, 3, 15, 15, 13, 15, 3, 15,
+ 29, 9, 15, 15, 3, 3, 39, 22, 19, 15,
+ 19, 3, 15, 15, 15, 11, 3, 74, 15, 19,
+ 15, 15, 29, 13, 15, 29, 102, 15, 3, 15,
+ 97, 3, 100, 15, -1, 15, 29, 22, 15, 3,
+ 3, 15, 3, 22, 15, 15, 22, 15, 15, 3,
+ 39, 3, 3, 3, 3, 39, 39, 22, 39, 3,
+ 15, 39, 15, 2, -1, 13, 39, 13, 2, 2,
+ 39, 13, 13, 39, 2, 15, 15, 39, 20, 3,
+ 3, 15, 15, 3, 15, 15, 2, 15, 41, -1,
+ 2, 51, 51, 51, 53, 51, 56, 53, 56, 15,
+ 48, 41, 48, 15, 51, 15, 51, 48, 51, 56,
+ 39, 56, 39, 56, 51, 51, 53, 53, 47, 51,
+ 47, 53, 4, 15, 2, 51, 15, 53, 15, 51,
+ 40, 15, 51, 15, 53, 4, 51, 15, 53, 15,
+ 51, 63, 53, 51, 51, 13, 15, 51, 16, 53,
+ 42, 75, 75, 51, 3, 44, 43, 65, 15, 43,
+ 67, 91, 13, 61, -1, 16, 42, 15, 51, 15,
+ 51, 54, 51, 54, 51, 106, 53, 56, 51, 13,
+ 53, 51, 16, 53, 2, 51, 43, 51, 35, 2,
+ 56, 15, 39, 51, 42, 59, 42, 15, 56, 51,
+ 2, 51, 15, 2, 56, -1, 56, 51, 51, 51,
+ 2, 51, 56, 15, 57, 57, 15, 57, 51, 4,
+ 51, 2, -1, 15, 57, 56, 75, 2, 51, 51,
+ 15, 53, 55, 2, 15, 51, 51, 2, 53, 55,
+ 15, 51, 51, 53, 53, 51, 15, 53, 51, 2,
+ 15, 51, 55, 51, 51, 15, 56, 2, 56, 56,
+ -1, 3, 15, 51, 64, 89, -1, 51, 56, 51,
+ 15, 68, 56, -1, 56, 73, 58, 51, 66, -1,
+ -1, 51, 56, -1, 44, 45, 56, 51, 58, 73,
+ 51, -1, 56, 51, 58, 56, 51, 51, 56, 73,
+ 51, 56, 56, 58, 13, 56, -1, -1, 62, 60,
+ -1, 20, 73, 13, 5, 73, 16, 5, 18, -1,
+ -1, -1, 13, 32, 33, 13, -1, -1, -1, 20,
+ -1, -1, 20, 75, -1, -1, -1, -1, -1, 39,
+ 85, 32, 33, -1, 32, 33, 22, 23, 24, 25,
+ 26, 27, 28, 21, 22, 23, 24, 25, 26, 27,
+ 28, 13, -1, -1, -1, -1, 2, -1, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, -1, -1, 15,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 4, 5, 6, -1, -1, 9,
- 10, 11, -1, -1, 14, -1, 16, -1, -1, -1,
- 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
- 30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, -1, -1, 55, -1, -1, -1, 59,
- -1, -1, -1, -1, -1, 65, 66, 67, -1, 69,
- 70, 71, -1, 73, 74, 75, 76, 77, 78, -1,
- -1, 81, 82, 83, 84, 85, 86, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 4, -1, -1, -1, -1, 9, -1,
- 11, 12, 13, 14, -1, -1, -1, -1, -1, -1,
- 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, -1, -1, -1, 59, -1,
- 61, -1, -1, -1, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, -1, -1,
- 81, 82, 83, 84, 85, -1, 87, -1, -1, -1,
- -1, -1, 93, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 4, -1, -1, -1, -1, 9, -1, 11,
- 12, 13, 14, -1, -1, -1, -1, -1, -1, 21,
- 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, -1, -1, -1, 59, -1, 61,
- -1, -1, -1, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, -1, -1, 81,
- 82, 83, 84, 85, -1, 87, -1, -1, -1, -1,
- -1, 93, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 4, 5, 6, -1, -1, 9, 10, 11, 12,
- 13, 14, -1, 16, -1, -1, -1, 20, 21, 22,
- -1, -1, -1, -1, -1, -1, 29, 30, 31, 32,
- 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
- 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
- 53, -1, -1, -1, -1, -1, 59, -1, 61, -1,
- -1, -1, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, -1, -1, 81, 82,
- 83, 84, 85, 86, 87, -1, -1, -1, -1, -1,
- 93, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 4, 5, 6, -1, -1, 9, 10, 11, 12, 13,
- 14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, 31, 32, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, 55, -1, -1, -1, 59, -1, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
- 84, 85, 86, 87, -1, -1, -1, -1, -1, 93,
- -1, -1, -1, -1, -1, -1, -1, -1, -1,
-
- 15, 3, 13, 29, 29, 15, 15, 4, 2, 15,
- 105, 9, 15, 2, 15, 3, 29, 22, 3, 15,
- 15, 2, 39, 15, 3, 15, 19, 3, 2, 15,
- 3, 15, 19, 11, 71, 15, 19, 2, 13, 39,
- 97, 2, 2, 15, 15, 3, 15, 29, 39, 15,
- 94, 101, 29, 3, 2, 2, 15, 99, 15, 22,
- 3, 3, 15, 15, 2, 2, 15, 22, 2, 39,
- 2, 39, 39, 3, 3, 39, 22, 39, 2, 2,
- 15, 3, 22, 39, 4, 39, 4, 3, 2, 40,
- 3, 3, 2, 2, 39, 39, 3, 3, 13, 2,
- 2, -1, -1, 39, -1, -1, -1, 48, 44, 48,
- -1, 50, 53, -1, 3, 48, 13, 48, 13, 50,
- 53, 48, 48, 48, 50, 15, 53, 48, 53, 48,
- 45, 50, 13, 13, 3, 16, 16, 48, 15, 50,
- 48, 62, 50, 48, 48, 50, 50, 48, 45, 48,
- 45, 50, 48, 39, 48, 48, 48, 53, 44, 53,
- 48, 53, 50, 64, 48, 48, 48, 60, 15, 48,
- 54, 54, 54, 13, 35, -1, 16, 56, 39, 82,
- 82, 48, 48, 72, 48, 48, 53, 53, 52, 48,
- 53, 48, 48, 52, 41, 48, 53, 2, 54, 52,
- 48, 13, 15, 72, 48, 53, 3, 51, 20, 15,
- 100, 88, 48, 48, 50, 50, 48, 48, 50, 50,
- 48, 48, 50, 48, 48, 50, 48, 51, 50, 48,
- 48, 58, 50, 48, 53, 41, 42, 48, 53, -1,
- 48, -1, 53, -1, 63, 53, 61, 48, 48, 48,
- 48, -1, 53, 53, 53, 53, 48, 55, 57, 70,
- -1, 53, 70, 48, -1, 65, -1, 59, 53, 70,
- 55, 48, 48, 86, -1, 72, 53, 53, 55, 55,
- 13, 48, 48, 16, 5, 18, 53, 53, 13, -1,
- 5, -1, 13, -1, -1, 20, -1, -1, 13, 20,
- -1, -1, 3, 70, 70, 20, 39, 32, 33, -1,
- -1, 32, 33, -1, -1, -1, -1, 32, 33, 22,
- 23, 24, 25, 26, 27, 28, 13, -1, -1, -1,
- -1, -1, -1, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 13, -1, -1, -1, -1, -1, -1, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 72, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 21, 22, 23, 24,
- 25, 26, 27, 28, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 85,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 13, -1, -1, -1, -1, -1, -1, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -1052,6 +1063,6 @@ const short QQmlJSGrammar::action_check [] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1};
+ -1, -1, -1, -1, -1, -1, -1};
QT_END_NAMESPACE
diff --git a/src/qml/qml/parser/qqmljsgrammar_p.h b/src/qml/qml/parser/qqmljsgrammar_p.h
index 651c6e391f..9ef4695d69 100644
--- a/src/qml/qml/parser/qqmljsgrammar_p.h
+++ b/src/qml/qml/parser/qqmljsgrammar_p.h
@@ -63,8 +63,8 @@ class QQmlJSGrammar
public:
enum VariousConstants {
EOF_SYMBOL = 0,
- REDUCE_HERE = 102,
- SHIFT_THERE = 101,
+ REDUCE_HERE = 104,
+ SHIFT_THERE = 103,
T_AND = 1,
T_AND_AND = 2,
T_AND_EQ = 3,
@@ -90,18 +90,19 @@ public:
T_EQ = 17,
T_EQ_EQ = 18,
T_EQ_EQ_EQ = 19,
- T_ERROR = 94,
+ T_ERROR = 96,
T_FALSE = 83,
- T_FEED_JS_EXPRESSION = 98,
- T_FEED_JS_PROGRAM = 100,
- T_FEED_JS_SOURCE_ELEMENT = 99,
- T_FEED_JS_STATEMENT = 97,
- T_FEED_UI_OBJECT_MEMBER = 96,
- T_FEED_UI_PROGRAM = 95,
+ T_FEED_JS_EXPRESSION = 100,
+ T_FEED_JS_PROGRAM = 102,
+ T_FEED_JS_SOURCE_ELEMENT = 101,
+ T_FEED_JS_STATEMENT = 99,
+ T_FEED_UI_OBJECT_MEMBER = 98,
+ T_FEED_UI_PROGRAM = 97,
T_FINALLY = 20,
T_FOR = 21,
T_FUNCTION = 22,
T_GE = 23,
+ T_GET = 94,
T_GT = 24,
T_GT_GT = 25,
T_GT_GT_EQ = 26,
@@ -148,6 +149,7 @@ public:
T_RETURN = 59,
T_RPAREN = 60,
T_SEMICOLON = 61,
+ T_SET = 95,
T_SIGNAL = 67,
T_STAR = 63,
T_STAR_EQ = 64,
@@ -166,15 +168,15 @@ public:
T_XOR = 79,
T_XOR_EQ = 80,
- ACCEPT_STATE = 645,
- RULE_COUNT = 350,
- STATE_COUNT = 646,
- TERMINAL_COUNT = 103,
- NON_TERMINAL_COUNT = 107,
+ ACCEPT_STATE = 655,
+ RULE_COUNT = 351,
+ STATE_COUNT = 656,
+ TERMINAL_COUNT = 105,
+ NON_TERMINAL_COUNT = 108,
- GOTO_INDEX_OFFSET = 646,
- GOTO_INFO_OFFSET = 3019,
- GOTO_CHECK_OFFSET = 3019
+ GOTO_INDEX_OFFSET = 656,
+ GOTO_INFO_OFFSET = 2970,
+ GOTO_CHECK_OFFSET = 2970
};
static const char *const spell [];
diff --git a/src/qml/qml/parser/qqmljskeywords_p.h b/src/qml/qml/parser/qqmljskeywords_p.h
index 8bbbe2355b..7fcf001303 100644
--- a/src/qml/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/qml/parser/qqmljskeywords_p.h
@@ -53,6 +53,12 @@
// We mean it.
//
+#include "qqmljslexer_p.h"
+
+QT_QML_BEGIN_NAMESPACE
+
+namespace QQmlJS {
+
static inline int classify2(const QChar *s, bool qmlMode) {
if (s[0].unicode() == 'a') {
if (s[1].unicode() == 's') {
@@ -88,6 +94,13 @@ static inline int classify3(const QChar *s, bool qmlMode) {
}
}
}
+ else if (s[0].unicode() == 'g') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 't') {
+ return Lexer::T_GET;
+ }
+ }
+ }
else if (s[0].unicode() == 'i') {
if (s[1].unicode() == 'n') {
if (s[2].unicode() == 't') {
@@ -102,6 +115,13 @@ static inline int classify3(const QChar *s, bool qmlMode) {
}
}
}
+ else if (s[0].unicode() == 's') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 't') {
+ return Lexer::T_SET;
+ }
+ }
+ }
else if (s[0].unicode() == 't') {
if (s[1].unicode() == 'r') {
if (s[2].unicode() == 'y') {
@@ -309,7 +329,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'p') {
if (s[3].unicode() == 'e') {
if (s[4].unicode() == 'r') {
- return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_IDENTIFIER);
+ return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD);
}
}
}
@@ -857,4 +877,8 @@ int Lexer::classify(const QChar *s, int n, bool qmlMode) {
} // switch
}
+} // namespace QQmlJS
+
+QT_QML_END_NAMESPACE
+
#endif // QQMLJSKEYWORDS_P_H
diff --git a/src/qml/qml/parser/qqmljslexer.cpp b/src/qml/qml/parser/qqmljslexer.cpp
index ec9b718917..cb78238f99 100644
--- a/src/qml/qml/parser/qqmljslexer.cpp
+++ b/src/qml/qml/parser/qqmljslexer.cpp
@@ -42,10 +42,11 @@
#include "qqmljslexer_p.h"
#include "qqmljsengine_p.h"
#include "qqmljsmemorypool_p.h"
+#include "qqmljskeywords_p.h"
-#include <QtCore/QCoreApplication>
-#include <QtCore/QVarLengthArray>
-#include <QtCore/QDebug>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
@@ -53,7 +54,7 @@ QT_END_NAMESPACE
using namespace QQmlJS;
-static int regExpFlagFromChar(const QChar &ch)
+static inline int regExpFlagFromChar(const QChar &ch)
{
switch (ch.unicode()) {
case 'g': return Lexer::RegExp_Global;
@@ -63,7 +64,7 @@ static int regExpFlagFromChar(const QChar &ch)
return 0;
}
-static unsigned char convertHex(ushort c)
+static inline unsigned char convertHex(ushort c)
{
if (c >= '0' && c <= '9')
return (c - '0');
@@ -73,12 +74,12 @@ static unsigned char convertHex(ushort c)
return (c - 'A' + 10);
}
-static QChar convertHex(QChar c1, QChar c2)
+static inline QChar convertHex(QChar c1, QChar c2)
{
return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
}
-static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
+static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
{
return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
(convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
@@ -136,6 +137,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_tokenSpell = QStringRef();
_codePtr = code.unicode();
+ _endPtr = _codePtr + code.length();
_lastLinePtr = _codePtr;
_tokenLinePtr = _codePtr;
_tokenStartPtr = _codePtr;
@@ -177,6 +179,52 @@ void Lexer::scanChar()
}
}
+namespace {
+inline bool isBinop(int tok)
+{
+ switch (tok) {
+ case Lexer::T_AND:
+ case Lexer::T_AND_AND:
+ case Lexer::T_AND_EQ:
+ case Lexer::T_DIVIDE_:
+ case Lexer::T_DIVIDE_EQ:
+ case Lexer::T_EQ:
+ case Lexer::T_EQ_EQ:
+ case Lexer::T_EQ_EQ_EQ:
+ case Lexer::T_GE:
+ case Lexer::T_GT:
+ case Lexer::T_GT_GT:
+ case Lexer::T_GT_GT_EQ:
+ case Lexer::T_GT_GT_GT:
+ case Lexer::T_GT_GT_GT_EQ:
+ case Lexer::T_LE:
+ case Lexer::T_LT:
+ case Lexer::T_LT_LT:
+ case Lexer::T_LT_LT_EQ:
+ case Lexer::T_MINUS:
+ case Lexer::T_MINUS_EQ:
+ case Lexer::T_NOT_EQ:
+ case Lexer::T_NOT_EQ_EQ:
+ case Lexer::T_OR:
+ case Lexer::T_OR_EQ:
+ case Lexer::T_OR_OR:
+ case Lexer::T_PLUS:
+ case Lexer::T_PLUS_EQ:
+ case Lexer::T_REMAINDER:
+ case Lexer::T_REMAINDER_EQ:
+ case Lexer::T_RETURN:
+ case Lexer::T_STAR:
+ case Lexer::T_STAR_EQ:
+ case Lexer::T_XOR:
+ case Lexer::T_XOR_EQ:
+ return true;
+
+ default:
+ return false;
+ }
+}
+} // anonymous namespace
+
int Lexer::lex()
{
const int previousTokenKind = _tokenKind;
@@ -193,9 +241,15 @@ int Lexer::lex()
switch (_tokenKind) {
case T_LBRACE:
case T_SEMICOLON:
+ case T_QUESTION:
case T_COLON:
+ case T_TILDE:
_delimited = true;
break;
+ default:
+ if (isBinop(_tokenKind))
+ _delimited = true;
+ break;
case T_IF:
case T_FOR:
@@ -275,6 +329,80 @@ QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
return QChar();
}
+QChar Lexer::decodeHexEscapeCharacter(bool *ok)
+{
+ if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
+ scanChar();
+
+ const QChar c1 = _char;
+ scanChar();
+
+ const QChar c2 = _char;
+ scanChar();
+
+ if (ok)
+ *ok = true;
+
+ return convertHex(c1, c2);
+ }
+
+ *ok = false;
+ return QChar();
+}
+
+static inline bool isIdentifierStart(QChar ch)
+{
+ // fast path for ascii
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
+ (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
+ ch == '$' || ch == '_')
+ return true;
+
+ switch (ch.category()) {
+ case QChar::Number_Letter:
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Titlecase:
+ case QChar::Letter_Modifier:
+ case QChar::Letter_Other:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static bool isIdentifierPart(QChar ch)
+{
+ // fast path for ascii
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
+ (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
+ (ch.unicode() >= '0' && ch.unicode() <= '9') ||
+ ch == '$' || ch == '_' ||
+ ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
+ return true;
+
+ switch (ch.category()) {
+ case QChar::Mark_NonSpacing:
+ case QChar::Mark_SpacingCombining:
+
+ case QChar::Number_DecimalDigit:
+ case QChar::Number_Letter:
+
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Titlecase:
+ case QChar::Letter_Modifier:
+ case QChar::Letter_Other:
+
+ case QChar::Punctuation_Connector:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
int Lexer::scanToken()
{
if (_stackToken != -1) {
@@ -310,7 +438,7 @@ again:
_tokenStartPtr = _codePtr - 1;
_tokenLine = _currentLineNumber;
- if (_char.isNull())
+ if (_codePtr > _endPtr)
return EOF_SYMBOL;
const QChar ch = _char;
@@ -395,7 +523,7 @@ again:
case '/':
if (_char == QLatin1Char('*')) {
scanChar();
- while (!_char.isNull()) {
+ while (_codePtr <= _endPtr) {
if (_char == QLatin1Char('*')) {
scanChar();
if (_char == QLatin1Char('/')) {
@@ -413,7 +541,7 @@ again:
}
}
} else if (_char == QLatin1Char('/')) {
- while (!_char.isNull() && !isLineTerminator()) {
+ while (_codePtr <= _endPtr && !isLineTerminator()) {
scanChar();
}
if (_engine) {
@@ -555,8 +683,14 @@ again:
const QChar *startCode = _codePtr;
if (_engine) {
- while (!_char.isNull()) {
- if (isLineTerminator() || _char == QLatin1Char('\\')) {
+ while (_codePtr <= _endPtr) {
+ if (isLineTerminator()) {
+ if (qmlMode())
+ break;
+ _errorCode = IllegalCharacter;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal");
+ return T_ERROR;
+ } else if (_char == QLatin1Char('\\')) {
break;
} else if (_char == quote) {
_tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
@@ -574,7 +708,7 @@ again:
while (startCode != _codePtr - 1)
_tokenText += *startCode++;
- while (! _char.isNull()) {
+ while (_codePtr <= _endPtr) {
if (unsigned sequenceLength = isLineTerminatorSequence()) {
multilineStringLiteral = true;
_tokenText += _char;
@@ -592,32 +726,29 @@ again:
scanChar();
QChar u;
- bool ok = false;
switch (_char.unicode()) {
// unicode escape sequence
- case 'u':
+ case 'u': {
+ bool ok = false;
u = decodeUnicodeEscapeCharacter(&ok);
- if (! ok)
- u = _char;
- break;
+ if (! ok) {
+ _errorCode = IllegalUnicodeEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
+ return T_ERROR;
+ }
+ } break;
// hex escape sequence
- case 'x':
- if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
- scanChar();
-
- const QChar c1 = _char;
- scanChar();
-
- const QChar c2 = _char;
- scanChar();
-
- u = convertHex(c1, c2);
- } else {
- u = _char;
+ case 'x': {
+ bool ok = false;
+ u = decodeHexEscapeCharacter(&ok);
+ if (!ok) {
+ _errorCode = IllegalHexadecimalEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence");
+ return T_ERROR;
}
- break;
+ } break;
// single character escape sequence
case '\\': u = QLatin1Char('\\'); scanChar(); break;
@@ -631,32 +762,31 @@ again:
case 'v': u = QLatin1Char('\v'); scanChar(); break;
case '0':
- if (! _codePtr[1].isDigit()) {
+ if (! _codePtr->isDigit()) {
scanChar();
u = QLatin1Char('\0');
- } else {
- // ### parse deprecated octal escape sequence ?
- u = _char;
+ break;
}
- break;
+ // fall through
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ _errorCode = IllegalEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed");
+ return T_ERROR;
case '\r':
- if (isLineTerminatorSequence() == 2) {
- _tokenText += QLatin1Char('\r');
- u = QLatin1Char('\n');
- } else {
- u = QLatin1Char('\r');
- }
- scanChar();
- break;
-
case '\n':
case 0x2028u:
case 0x2029u:
- u = _char;
scanChar();
- break;
-
+ continue;
default:
// non escape character
@@ -687,28 +817,28 @@ again:
case '9':
return scanNumber(ch);
- default:
- if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
- bool identifierWithEscapeChars = false;
- if (ch == QLatin1Char('\\')) {
- identifierWithEscapeChars = true;
+ default: {
+ QChar c = ch;
+ bool identifierWithEscapeChars = false;
+ if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) {
+ identifierWithEscapeChars = true;
+ bool ok = false;
+ c = decodeUnicodeEscapeCharacter(&ok);
+ if (! ok) {
+ _errorCode = IllegalUnicodeEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
+ return T_ERROR;
+ }
+ }
+ if (isIdentifierStart(c)) {
+ if (identifierWithEscapeChars) {
_tokenText.resize(0);
- bool ok = false;
- _tokenText += decodeUnicodeEscapeCharacter(&ok);
+ _tokenText += c;
_validTokenText = true;
- if (! ok) {
- _errorCode = IllegalUnicodeEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
- return T_ERROR;
- }
}
while (true) {
- if (_char.isLetterOrNumber() || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
- if (identifierWithEscapeChars)
- _tokenText += _char;
-
- scanChar();
- } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
+ c = _char;
+ if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
if (! identifierWithEscapeChars) {
identifierWithEscapeChars = true;
_tokenText.resize(0);
@@ -718,31 +848,41 @@ again:
scanChar(); // skip '\\'
bool ok = false;
- _tokenText += decodeUnicodeEscapeCharacter(&ok);
+ c = decodeUnicodeEscapeCharacter(&ok);
if (! ok) {
_errorCode = IllegalUnicodeEscapeSequence;
_errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
return T_ERROR;
}
- } else {
- _tokenLength = _codePtr - _tokenStartPtr - 1;
+ if (isIdentifierPart(c))
+ _tokenText += c;
+ continue;
+ } else if (isIdentifierPart(c)) {
+ if (identifierWithEscapeChars)
+ _tokenText += c;
- int kind = T_IDENTIFIER;
+ scanChar();
+ continue;
+ }
- if (! identifierWithEscapeChars)
- kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
- if (_engine) {
- if (kind == T_IDENTIFIER && identifierWithEscapeChars)
- _tokenSpell = _engine->newStringRef(_tokenText);
- else
- _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
- }
+ int kind = T_IDENTIFIER;
+
+ if (! identifierWithEscapeChars)
+ kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
- return kind;
+ if (_engine) {
+ if (kind == T_IDENTIFIER && identifierWithEscapeChars)
+ _tokenSpell = _engine->newStringRef(_tokenText);
+ else
+ _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
}
+
+ return kind;
}
}
+ }
break;
}
@@ -753,12 +893,14 @@ again:
int Lexer::scanNumber(QChar ch)
{
if (ch != QLatin1Char('0')) {
- double integer = ch.unicode() - '0';
+ QByteArray buf;
+ buf.reserve(64);
+ buf += ch.toLatin1();
QChar n = _char;
const QChar *code = _codePtr;
while (n.isDigit()) {
- integer = integer * 10 + (n.unicode() - '0');
+ buf += n.toLatin1();
n = *code++;
}
@@ -767,17 +909,23 @@ int Lexer::scanNumber(QChar ch)
_codePtr = code - 1;
scanChar();
}
- _tokenValue = integer;
+ buf.append('\0');
+ _tokenValue = strtod(buf.constData(), 0);
return T_NUMERIC_LITERAL;
}
+ } else if (_char.isDigit() && !qmlMode()) {
+ _errorCode = IllegalCharacter;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'");
+ return T_ERROR;
}
QVarLengthArray<char,32> chars;
chars.append(ch.unicode());
if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
- // parse hex integer literal
+ ch = _char; // remember the x or X to use it in the error message below.
+ // parse hex integer literal
chars.append(_char.unicode());
scanChar(); // consume `x'
@@ -786,6 +934,12 @@ int Lexer::scanNumber(QChar ch)
scanChar();
}
+ if (chars.size() < 3) {
+ _errorCode = IllegalHexNumber;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
+ return T_ERROR;
+ }
+
_tokenValue = integerFromString(chars.constData(), chars.size(), 16);
return T_NUMERIC_LITERAL;
}
@@ -900,7 +1054,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
_tokenText += _char;
scanChar();
- if (_char.isNull() || isLineTerminator()) {
+ if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression backslash sequence");
return false;
}
@@ -914,7 +1068,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
_tokenText += _char;
scanChar();
- while (! _char.isNull() && ! isLineTerminator()) {
+ while (_codePtr <= _endPtr && ! isLineTerminator()) {
if (_char == QLatin1Char(']'))
break;
else if (_char == QLatin1Char('\\')) {
@@ -922,7 +1076,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
_tokenText += _char;
scanChar();
- if (_char.isNull() || isLineTerminator()) {
+ if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression backslash sequence");
return false;
}
@@ -945,7 +1099,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
break;
default:
- if (_char.isNull() || isLineTerminator()) {
+ if (_codePtr > _endPtr || isLineTerminator()) {
_errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression literal");
return false;
} else {
@@ -1172,5 +1326,3 @@ bool Lexer::scanDirectives(Directives *directives)
return true;
}
-
-#include "qqmljskeywords_p.h"
diff --git a/src/qml/qml/parser/qqmljslexer_p.h b/src/qml/qml/parser/qqmljslexer_p.h
index c6ae0931c1..23af61d650 100644
--- a/src/qml/qml/parser/qqmljslexer_p.h
+++ b/src/qml/qml/parser/qqmljslexer_p.h
@@ -55,7 +55,8 @@
#include "qqmljsglobal_p.h"
#include "qqmljsgrammar_p.h"
-#include <QtCore/QString>
+
+#include <QtCore/qstring.h>
QT_QML_BEGIN_NAMESPACE
@@ -121,12 +122,14 @@ public:
enum Error {
NoError,
IllegalCharacter,
+ IllegalHexNumber,
UnclosedStringLiteral,
IllegalEscapeSequence,
IllegalUnicodeEscapeSequence,
UnclosedComment,
IllegalExponentIndicator,
- IllegalIdentifier
+ IllegalIdentifier,
+ IllegalHexadecimalEscapeSequence
};
enum RegExpBodyPrefix {
@@ -201,6 +204,7 @@ private:
void syncProhibitAutomaticSemicolon();
QChar decodeUnicodeEscapeCharacter(bool *ok);
+ QChar decodeHexEscapeCharacter(bool *ok);
private:
Engine *_engine;
@@ -211,6 +215,7 @@ private:
QStringRef _tokenSpell;
const QChar *_codePtr;
+ const QChar *_endPtr;
const QChar *_lastLinePtr;
const QChar *_tokenLinePtr;
const QChar *_tokenStartPtr;
diff --git a/src/qml/qml/parser/qqmljsparser.cpp b/src/qml/qml/parser/qqmljsparser.cpp
index 1ef760b80a..a0fa7a4711 100644
--- a/src/qml/qml/parser/qqmljsparser.cpp
+++ b/src/qml/qml/parser/qqmljsparser.cpp
@@ -39,20 +39,20 @@
**
****************************************************************************/
-#include <QtCore/QtDebug>
-#include <QtCore/QCoreApplication>
-
-#include <string.h>
-
#include "qqmljsengine_p.h"
#include "qqmljslexer_p.h"
#include "qqmljsast_p.h"
#include "qqmljsmemorypool_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <string.h>
#include "qqmljsparser_p.h"
-#include <QVarLengthArray>
+
+#include <QtCore/qvarlengtharray.h>
//
// W A R N I N G
@@ -537,49 +537,49 @@ case 65: {
sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
-case 71: {
+case 73: {
AST::ThisExpression *node = new (pool) AST::ThisExpression();
node->thisToken = loc(1);
sym(1).Node = node;
} break;
-case 72: {
+case 74: {
AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 73: {
+case 75: {
AST::NullExpression *node = new (pool) AST::NullExpression();
node->nullToken = loc(1);
sym(1).Node = node;
} break;
-case 74: {
+case 76: {
AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
node->trueToken = loc(1);
sym(1).Node = node;
} break;
-case 75: {
+case 77: {
AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
node->falseToken = loc(1);
sym(1).Node = node;
} break;
-case 76: {
+case 78: {
AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 77:
-case 78: {
+case 79:
+case 80: {
AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 79: {
+case 81: {
bool rx = lexer->scanRegExp(Lexer::NoPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -595,7 +595,7 @@ case 79: {
sym(1).Node = node;
} break;
-case 80: {
+case 82: {
bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -611,28 +611,28 @@ case 80: {
sym(1).Node = node;
} break;
-case 81: {
+case 83: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
} break;
-case 82: {
+case 84: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 83: {
+case 85: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 84: {
+case 86: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
@@ -641,7 +641,7 @@ case 84: {
sym(1).Node = node;
} break;
-case 85: {
+case 87: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
@@ -650,11 +650,11 @@ case 85: {
sym(1).Node = node;
} break;
-case 86: {
+case 88: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyNameAndValueList->finish ());
+ sym(2).PropertyAssignmentList->finish ());
else
node = new (pool) AST::ObjectLiteral();
node->lbraceToken = loc(1);
@@ -662,22 +662,22 @@ case 86: {
sym(1).Node = node;
} break;
-case 87: {
+case 89: {
AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyNameAndValueList->finish ());
+ sym(2).PropertyAssignmentList->finish ());
node->lbraceToken = loc(1);
node->rbraceToken = loc(4);
sym(1).Node = node;
} break;
-case 88: {
+case 90: {
AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
} break;
-case 89: {
+case 91: {
if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
QLatin1String("Ignored annotation")));
@@ -697,100 +697,119 @@ case 89: {
}
} break;
-case 90: {
+case 92: {
sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
} break;
-case 91: {
+case 93: {
sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
} break;
-case 92: {
+case 94: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 93: {
+case 95: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 94: {
+case 96: {
AST::Elision *node = new (pool) AST::Elision();
node->commaToken = loc(1);
sym(1).Node = node;
} break;
-case 95: {
+case 97: {
AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 96: {
- AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
+case 98: {
+ AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 97: {
- AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
- sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
- node->commaToken = loc(2);
- node->colonToken = loc(4);
+case 99: {
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
+ sym(2).PropertyName, sym(6).FunctionBody);
+ node->getSetToken = loc(1);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
sym(1).Node = node;
} break;
-case 98: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
+case 100: {
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
+ sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody);
+ node->getSetToken = loc(1);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(5);
+ node->lbraceToken = loc(6);
+ node->rbraceToken = loc(8);
sym(1).Node = node;
} break;
-case 99:
-case 100: {
+
+case 101: {
+ sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
+} break;
+
+case 102: {
+ AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
+ sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+} break;
+
+case 103: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 101: {
+case 104: {
AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 102: {
+case 105: {
AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 103: {
+case 106: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 139: {
+case 142: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 140: {
+case 143: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 141: {
+case 144: {
AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
@@ -798,384 +817,384 @@ case 141: {
sym(1).Node = node;
} break;
-case 143: {
+case 146: {
AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
-case 144: {
+case 147: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 145: {
+case 148: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 146: {
+case 149: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 147: {
+case 150: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 148: {
+case 151: {
sym(1).Node = 0;
} break;
-case 149: {
+case 152: {
sym(1).Node = sym(1).ArgumentList->finish();
} break;
-case 150: {
+case 153: {
sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
} break;
-case 151: {
+case 154: {
AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 155: {
+case 158: {
AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
-case 156: {
+case 159: {
AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
-case 158: {
+case 161: {
AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
-case 159: {
+case 162: {
AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
-case 160: {
+case 163: {
AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
-case 161: {
+case 164: {
AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
-case 162: {
+case 165: {
AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
-case 163: {
+case 166: {
AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
-case 164: {
+case 167: {
AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
-case 165: {
+case 168: {
AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
-case 166: {
+case 169: {
AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
-case 168: {
+case 171: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 169: {
+case 172: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 170: {
+case 173: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 172: {
+case 175: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 173: {
+case 176: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 175: {
+case 178: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 176: {
+case 179: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 177: {
+case 180: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 179: {
+case 182: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 180: {
+case 183: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 181: {
+case 184: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 182: {
+case 185: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 183: {
+case 186: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 184: {
+case 187: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 186: {
+case 189: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 187: {
+case 190: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 188: {
+case 191: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 189: {
+case 192: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 190: {
+case 193: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 192: {
+case 195: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 193: {
+case 196: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 194: {
+case 197: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 195: {
+case 198: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 197: {
+case 200: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 198: {
+case 201: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 199: {
+case 202: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 200: {
+case 203: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 202: {
+case 205: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 204: {
+case 207: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 206: {
+case 209: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 208: {
+case 211: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 210: {
+case 213: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 212: {
+case 215: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 214: {
+case 217: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 216: {
+case 219: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 218: {
+case 221: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 220: {
+case 223: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 222: {
+case 225: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1183,7 +1202,7 @@ case 222: {
sym(1).Node = node;
} break;
-case 224: {
+case 227: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1191,112 +1210,112 @@ case 224: {
sym(1).Node = node;
} break;
-case 226: {
+case 229: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 228: {
+case 231: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 229: {
+case 232: {
sym(1).ival = QSOperator::Assign;
} break;
-case 230: {
+case 233: {
sym(1).ival = QSOperator::InplaceMul;
} break;
-case 231: {
+case 234: {
sym(1).ival = QSOperator::InplaceDiv;
} break;
-case 232: {
+case 235: {
sym(1).ival = QSOperator::InplaceMod;
} break;
-case 233: {
+case 236: {
sym(1).ival = QSOperator::InplaceAdd;
} break;
-case 234: {
+case 237: {
sym(1).ival = QSOperator::InplaceSub;
} break;
-case 235: {
+case 238: {
sym(1).ival = QSOperator::InplaceLeftShift;
} break;
-case 236: {
+case 239: {
sym(1).ival = QSOperator::InplaceRightShift;
} break;
-case 237: {
+case 240: {
sym(1).ival = QSOperator::InplaceURightShift;
} break;
-case 238: {
+case 241: {
sym(1).ival = QSOperator::InplaceAnd;
} break;
-case 239: {
+case 242: {
sym(1).ival = QSOperator::InplaceXor;
} break;
-case 240: {
+case 243: {
sym(1).ival = QSOperator::InplaceOr;
} break;
-case 242: {
+case 245: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 243: {
+case 246: {
sym(1).Node = 0;
} break;
-case 246: {
+case 249: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 247: {
+case 250: {
sym(1).Node = 0;
} break;
-case 264: {
+case 267: {
AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 265: {
+case 268: {
sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
} break;
-case 266: {
+case 269: {
sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
} break;
-case 267: {
+case 270: {
sym(1).Node = 0;
} break;
-case 268: {
+case 271: {
sym(1).Node = sym(1).StatementList->finish ();
} break;
-case 270: {
+case 273: {
AST::VariableStatement *node = new (pool) AST::VariableStatement(
sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
node->declarationKindToken = loc(1);
@@ -1304,76 +1323,76 @@ case 270: {
sym(1).Node = node;
} break;
-case 271: {
+case 274: {
sym(1).ival = T_CONST;
} break;
-case 272: {
+case 275: {
sym(1).ival = T_VAR;
} break;
-case 273: {
+case 276: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 274: {
+case 277: {
AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 275: {
+case 278: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 276: {
+case 279: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
-case 277: {
+case 280: {
AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 278: {
+case 281: {
AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 279: {
+case 282: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 280: {
+case 283: {
sym(1).Node = 0;
} break;
-case 282: {
+case 285: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 283: {
+case 286: {
sym(1).Node = 0;
} break;
-case 285: {
+case 288: {
AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
-case 287: {
+case 290: {
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 288: {
+case 291: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1382,7 +1401,7 @@ case 288: {
sym(1).Node = node;
} break;
-case 289: {
+case 292: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1390,7 +1409,7 @@ case 289: {
sym(1).Node = node;
} break;
-case 292: {
+case 295: {
AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
@@ -1400,7 +1419,7 @@ case 292: {
sym(1).Node = node;
} break;
-case 293: {
+case 296: {
AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
@@ -1408,7 +1427,7 @@ case 293: {
sym(1).Node = node;
} break;
-case 294: {
+case 297: {
AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
@@ -1419,7 +1438,7 @@ case 294: {
sym(1).Node = node;
} break;
-case 295: {
+case 298: {
AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
@@ -1432,7 +1451,7 @@ case 295: {
sym(1).Node = node;
} break;
-case 296: {
+case 299: {
AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
@@ -1442,7 +1461,7 @@ case 296: {
sym(1).Node = node;
} break;
-case 297: {
+case 300: {
AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
@@ -1453,14 +1472,14 @@ case 297: {
sym(1).Node = node;
} break;
-case 299: {
+case 302: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 301: {
+case 304: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
node->continueToken = loc(1);
node->identifierToken = loc(2);
@@ -1468,14 +1487,14 @@ case 301: {
sym(1).Node = node;
} break;
-case 303: {
+case 306: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 305: {
+case 308: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
node->breakToken = loc(1);
node->identifierToken = loc(2);
@@ -1483,14 +1502,14 @@ case 305: {
sym(1).Node = node;
} break;
-case 307: {
+case 310: {
AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 308: {
+case 311: {
AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
@@ -1498,7 +1517,7 @@ case 308: {
sym(1).Node = node;
} break;
-case 309: {
+case 312: {
AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
@@ -1506,90 +1525,83 @@ case 309: {
sym(1).Node = node;
} break;
-case 310: {
+case 313: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 311: {
+case 314: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
} break;
-case 312: {
+case 315: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
} break;
-case 313: {
+case 316: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
} break;
-case 314: {
+case 317: {
sym(1).Node = 0;
} break;
-case 315: {
+case 318: {
sym(1).Node = sym(1).CaseClauses->finish ();
} break;
-case 316: {
+case 319: {
AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
} break;
-case 317: {
+case 320: {
AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 318:
-case 319: {
- AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
- node->identifierToken = loc(1);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-case 320: {
+case 321: {
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 322: {
+case 323: {
AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 323: {
+case 324: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 324: {
+case 325: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 325: {
+case 326: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 326: {
+case 327: {
AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
@@ -1598,20 +1610,20 @@ case 326: {
sym(1).Node = node;
} break;
-case 327: {
+case 328: {
AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
-case 329: {
+case 330: {
AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 330: {
+case 332: {
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
@@ -1622,7 +1634,7 @@ case 330: {
sym(1).Node = node;
} break;
-case 331: {
+case 333: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
if (! stringRef(2).isNull())
@@ -1634,60 +1646,66 @@ case 331: {
sym(1).Node = node;
} break;
-case 332: {
+case 334: {
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody);
+ node->functionToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
+ sym(1).Node = node;
+} break;
+
+case 335: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 333: {
+case 336: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 334: {
+case 337: {
sym(1).Node = 0;
} break;
-case 335: {
+case 338: {
sym(1).Node = sym(1).FormalParameterList->finish ();
} break;
-case 336: {
+case 339: {
sym(1).Node = 0;
} break;
-case 338: {
+case 341: {
sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
} break;
-case 340: {
+case 343: {
sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
} break;
-case 341: {
+case 344: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
} break;
-case 342: {
+case 345: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
} break;
-case 343: {
+case 346: {
sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
} break;
-case 344: {
+case 347: {
sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
} break;
-case 345: {
- stringRef(1) = QStringRef();
-} break;
-
-case 347: {
+case 348: {
sym(1).Node = 0;
} break;
diff --git a/src/qml/qml/parser/qqmljsparser_p.h b/src/qml/qml/parser/qqmljsparser_p.h
index 3da1b9a6a4..1b13690547 100644
--- a/src/qml/qml/parser/qqmljsparser_p.h
+++ b/src/qml/qml/parser/qqmljsparser_p.h
@@ -71,8 +71,8 @@
#include "qqmljsast_p.h"
#include "qqmljsengine_p.h"
-#include <QtCore/QList>
-#include <QtCore/QString>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
QT_QML_BEGIN_NAMESPACE
@@ -101,7 +101,8 @@ public:
AST::FunctionDeclaration *FunctionDeclaration;
AST::Node *Node;
AST::PropertyName *PropertyName;
- AST::PropertyNameAndValueList *PropertyNameAndValueList;
+ AST::PropertyAssignment *PropertyAssignment;
+ AST::PropertyAssignmentList *PropertyAssignmentList;
AST::SourceElement *SourceElement;
AST::SourceElements *SourceElements;
AST::Statement *Statement;
@@ -244,9 +245,9 @@ protected:
-#define J_SCRIPT_REGEXPLITERAL_RULE1 79
+#define J_SCRIPT_REGEXPLITERAL_RULE1 81
-#define J_SCRIPT_REGEXPLITERAL_RULE2 80
+#define J_SCRIPT_REGEXPLITERAL_RULE2 82
QT_QML_END_NAMESPACE
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 20b46f0939..aafc50db9b 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -1,12 +1,9 @@
SOURCES += \
$$PWD/qqmlinstruction.cpp \
- $$PWD/qquicklistmodel.cpp \
- $$PWD/qquicklistmodelworkeragent.cpp \
$$PWD/qqmlopenmetaobject.cpp \
$$PWD/qqmlvmemetaobject.cpp \
$$PWD/qqmlengine.cpp \
$$PWD/qqmlexpression.cpp \
- $$PWD/qqmlbinding.cpp \
$$PWD/qqmlproperty.cpp \
$$PWD/qqmlcomponent.cpp \
$$PWD/qqmlincubator.cpp \
@@ -38,7 +35,6 @@ SOURCES += \
$$PWD/qqmltypenotavailable.cpp \
$$PWD/qqmltypenamecache.cpp \
$$PWD/qqmlscriptstring.cpp \
- $$PWD/qquickworkerscript.cpp \
$$PWD/qqmlnetworkaccessmanagerfactory.cpp \
$$PWD/qqmldirparser.cpp \
$$PWD/qqmlextensionplugin.cpp \
@@ -53,20 +49,16 @@ SOURCES += \
$$PWD/qqmlfile.cpp \
$$PWD/qqmlbundle.cpp \
$$PWD/qqmlmemoryprofiler.cpp \
- $$PWD/qqmlconnections.cpp \
- $$PWD/qqmltimer.cpp \
- $$PWD/qqmlbind.cpp
+ $$PWD/qqmlplatform.cpp \
+ $$PWD/qqmlbinding.cpp \
+ $$PWD/qqmlapplicationengine.cpp
HEADERS += \
$$PWD/qqmlglobal_p.h \
$$PWD/qqmlinstruction_p.h \
- $$PWD/qquicklistmodel_p.h\
- $$PWD/qquicklistmodel_p_p.h\
- $$PWD/qquicklistmodelworkeragent_p.h \
$$PWD/qqmlopenmetaobject_p.h \
$$PWD/qqmlvmemetaobject_p.h \
$$PWD/qqml.h \
- $$PWD/qqmlbinding_p.h \
$$PWD/qqmlproperty.h \
$$PWD/qqmlcomponent.h \
$$PWD/qqmlcomponent_p.h \
@@ -111,7 +103,6 @@ HEADERS += \
$$PWD/qqmltypenotavailable_p.h \
$$PWD/qqmltypenamecache_p.h \
$$PWD/qqmlscriptstring.h \
- $$PWD/qquickworkerscript_p.h \
$$PWD/qqmlguard_p.h \
$$PWD/qqmlnetworkaccessmanagerfactory.h \
$$PWD/qqmldirparser_p.h \
@@ -129,9 +120,11 @@ HEADERS += \
$$PWD/qqmlfile.h \
$$PWD/qqmlbundle_p.h \
$$PWD/qqmlmemoryprofiler_p.h \
- $$PWD/qqmlconnections_p.h \
- $$PWD/qqmltimer_p.h \
- $$PWD/qqmlbind_p.h
+ $$PWD/qqmlplatform_p.h \
+ $$PWD/qqmlbinding_p.h \
+ $$PWD/qqmlextensionplugin_p.h \
+ $$PWD/qqmlapplicationengine_p.h \
+ $$PWD/qqmlapplicationengine.h
include(parser/parser.pri)
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 597c59eeff..7e6e0d1d36 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -49,8 +49,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qmetaobject.h>
-
-QT_BEGIN_HEADER
+#include <QtCore/qdebug.h>
#define QML_VERSION 0x020000
#define QML_VERSION_STR "2.0"
@@ -465,11 +464,29 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
}
+
+inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+{
+ if (url.isRelative()) {
+ // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
+ qWarning() << "qmlRegisterType requires absolute URLs.";
+ return 0;
+ }
+
+ QQmlPrivate::RegisterCompositeType type = {
+ url,
+ uri,
+ versionMajor,
+ versionMinor,
+ qmlName
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type);
+}
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QObject)
Q_DECLARE_METATYPE(QVariant)
-QT_END_HEADER
-
#endif // QQML_H
diff --git a/src/qml/qml/qqmlaccessors_p.h b/src/qml/qml/qqmlaccessors_p.h
index 24b548c58c..6df624eaf1 100644
--- a/src/qml/qml/qqmlaccessors_p.h
+++ b/src/qml/qml/qqmlaccessors_p.h
@@ -52,8 +52,6 @@
#include <stdint.h>
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QObject;
@@ -167,6 +165,4 @@ QQmlAccessorProperties::Properties::Properties()
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLACCESSORS_P_H
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
new file mode 100644
index 0000000000..7dc2c77922
--- /dev/null
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTranslator>
+#include <QQmlComponent>
+#include "qqmlapplicationengine.h"
+#include "qqmlapplicationengine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate(QQmlEngine *e)
+ : QQmlEnginePrivate(e)
+{
+}
+
+QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate()
+{
+ qDeleteAll(objects);
+#ifndef QT_NO_TRANSLATIONS
+ qDeleteAll(translators);
+#endif
+}
+
+void QQmlApplicationEnginePrivate::init()
+{
+ Q_Q(QQmlApplicationEngine);
+ q->connect(&statusMapper, SIGNAL(mapped(QObject*)),
+ q, SLOT(_q_finishLoad(QObject*)));
+ q->connect(q, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+#ifndef QT_NO_TRANSLATIONS
+ QTranslator* qtTranslator = new QTranslator;
+ if (qtTranslator->load(QLatin1String("qt_") + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ QCoreApplication::installTranslator(qtTranslator);
+ translators << qtTranslator;
+#endif
+}
+
+void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile)
+{
+#ifndef QT_NO_TRANSLATIONS
+ if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc"))
+ return;
+
+ QFileInfo fi(rootFile.toLocalFile());
+
+ QTranslator *translator = new QTranslator;
+ if (translator->load(QLatin1String("qml_") + QLocale::system().name(), fi.path() + QLatin1String("/i18n"))) {
+ QCoreApplication::installTranslator(translator);
+ translators << translator;
+ } else {
+ delete translator;
+ }
+#endif
+}
+
+void QQmlApplicationEnginePrivate::startLoad(const QUrl &url, const QByteArray &data, bool dataFlag)
+{
+ Q_Q(QQmlApplicationEngine);
+
+ loadTranslations(url); //Translations must be loaded before the QML file is
+ QQmlComponent *c = new QQmlComponent(q, q);
+
+ if (dataFlag)
+ c->setData(data,url);
+ else
+ c->loadUrl(url);
+
+ if (!c->isLoading()) {
+ _q_finishLoad(c);
+ return;
+ }
+ statusMapper.setMapping(c, c);
+ q->connect(c, SIGNAL(statusChanged(QQmlComponent::Status)),
+ &statusMapper, SLOT(map()));
+}
+
+void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
+{
+ Q_Q(QQmlApplicationEngine);
+ QQmlComponent *c = qobject_cast<QQmlComponent *>(o);
+ if (!c)
+ return;
+ switch (c->status()) {
+ case QQmlComponent::Error:
+ qWarning() << "QQmlApplicationEngine failed to load component";
+ qWarning() << qPrintable(c->errorString());
+ q->objectCreated(0, c->url());
+ break;
+ case QQmlComponent::Ready:
+ objects << c->create();
+ q->objectCreated(objects.last(), c->url());
+ break;
+ case QQmlComponent::Loading:
+ case QQmlComponent::Null:
+ return; //These cases just wait for the next status update
+ }
+ delete c;
+}
+
+/*!
+ \class QQmlApplicationEngine
+ \since 5.1
+ \inmodule QtQml
+ \brief QQmlApplicationEngine provides a convenient way to load an application from a single QML file.
+
+ This class combines a QQmlEngine and QQmlComponent to provide a convenient way to load a single QML file. It also exposes some central application functionality to QML, which a C++/QML hybrid application would normally control from C++.
+
+ It can be used like so:
+
+ \code
+ #include <QGuiApplication>
+ #include <QQmlApplicationEngine>
+
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+ QQmlApplicationEngine engine("main.qml");
+ return app.exec();
+ }
+ \endcode
+
+ You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as QtQuick).
+
+ List of configuration changes from a default QQmlEngine:
+
+ \list
+ \li Connecting Qt.quit() to QCoreApplication::quit()
+ \li Automatically loads translation files from an i18n directory adjacent to the main QML file.
+ \endlist
+
+ The engine behavior can be further tweaked by using the inherited methods from QQmlEngine.
+*/
+
+/*!
+ \fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url)
+
+ This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object.
+ Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the
+ QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath).
+*/
+
+/*!
+ Create a new QQmlApplicationEngine with the given \a parent. You will have to call load() later in
+ order to load a QML file.
+*/
+QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent)
+: QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent)
+{
+ Q_D(QQmlApplicationEngine);
+ d->init();
+}
+
+/*!
+ Create a new QQmlApplicationEngine and loads the QML file at the given \a url.
+ This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards.
+*/
+QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent)
+ : QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent)
+{
+ Q_D(QQmlApplicationEngine);
+ d->init();
+ load(url);
+}
+
+/*!
+ Create a new QQmlApplicationEngine and loads the QML file at the given
+ \a filePath, which must be a local file path. If a relative path is
+ given then it will be interpreted as relative to the working directory of the
+ application.
+
+ This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards.
+*/
+QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent)
+ : QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent)
+{
+ Q_D(QQmlApplicationEngine);
+ d->init();
+ load(QUrl::fromLocalFile(filePath));
+}
+
+/*!
+ Destroys the QQmlApplicationEngine and all QML objects it loaded.
+*/
+QQmlApplicationEngine::~QQmlApplicationEngine()
+{
+ //Instantiated root objects cleaned up in private class
+}
+
+/*!
+ Loads the root QML file located at \a url. The object tree defined by the file
+ is created immediately for local file urls. Remote urls are loaded asynchronously,
+ listen to the objectCreated signal to determine when the object
+ tree is ready.
+
+ If an error occurs, error messages are printed with qWarning.
+*/
+void QQmlApplicationEngine::load(const QUrl &url)
+{
+ Q_D(QQmlApplicationEngine);
+ d->startLoad(url);
+}
+
+/*!
+ Loads the root QML file located at \a filePath. \a filePath must be a path to
+ a local file. If \a filePath is a relative path, it is taken as relative to
+ the application's working directory. The object tree defined by the file is
+ instantiated immediately.
+
+ If an error occurs, error messages are printed with qWarning.
+*/
+void QQmlApplicationEngine::load(const QString &filePath)
+{
+ Q_D(QQmlApplicationEngine);
+ d->startLoad(QUrl::fromLocalFile(filePath));
+}
+
+/*!
+ Loads the QML given in \a data. The object tree defined by \a data is
+ instantiated immediately.
+
+ If a \a url is specified it is used as the base url of the component. This affects
+ relative paths within the data and error messages.
+
+ If an error occurs, error messages are printed with qWarning.
+*/
+void QQmlApplicationEngine::loadData(const QByteArray &data, const QUrl &url)
+{
+ Q_D(QQmlApplicationEngine);
+ d->startLoad(url, data, true);
+}
+
+/*!
+ Returns a list of all the root objects instantiated by the
+ QQmlApplicationEngine. This will only contain objects loaded via load() or a
+ convenience constructor.
+*/
+
+QList<QObject *> QQmlApplicationEngine::rootObjects()
+{
+ Q_D(QQmlApplicationEngine);
+ return d->objects;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qqmlapplicationengine.cpp"
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
new file mode 100644
index 0000000000..b5de998100
--- /dev/null
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLAPPLICATIONENGINE_H
+#define QQMLAPPLICATIONENGINE_H
+
+#include <QtQml/qqmlengine.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlApplicationEnginePrivate;
+class Q_QML_EXPORT QQmlApplicationEngine : public QQmlEngine
+{
+ Q_OBJECT
+public:
+ QQmlApplicationEngine(QObject *parent=0);
+ QQmlApplicationEngine(const QUrl &url, QObject *parent=0);
+ QQmlApplicationEngine(const QString &filePath, QObject *parent=0);
+ ~QQmlApplicationEngine();
+
+ QList<QObject*> rootObjects();
+public Q_SLOTS:
+ void load(const QUrl &url);
+ void load(const QString &filePath);
+ void loadData(const QByteArray &data, const QUrl &url = QUrl());
+
+Q_SIGNALS:
+ void objectCreated(QObject *object, const QUrl &url);
+
+private:
+ Q_DISABLE_COPY(QQmlApplicationEngine)
+ Q_DECLARE_PRIVATE(QQmlApplicationEngine)
+ Q_PRIVATE_SLOT(d_func(), void _q_finishLoad(QObject*))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
new file mode 100644
index 0000000000..db144af504
--- /dev/null
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLAPPLICATIONENGINE_P_H
+#define QQMLAPPLICATIONENGINE_P_H
+
+#include "qqmlapplicationengine.h"
+#include "qqmlengine_p.h"
+#include <QSignalMapper>
+#include <QCoreApplication>
+#include <QFileInfo>
+#include <QLibraryInfo>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QTranslator;
+class Q_QML_PRIVATE_EXPORT QQmlApplicationEnginePrivate : public QQmlEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QQmlApplicationEngine)
+public:
+ QQmlApplicationEnginePrivate(QQmlEngine *e);
+ ~QQmlApplicationEnginePrivate();
+ void init();
+
+ void startLoad(const QUrl &url, const QByteArray &data = QByteArray(), bool dataFlag = false);
+ void loadTranslations(const QUrl &rootFile);
+ void _q_finishLoad(QObject *component);
+ QList<QObject *> objects;
+ QSignalMapper statusMapper;
+ QObject *appObj;
+
+#ifndef QT_NO_TRANSLATIONS
+ QList<QTranslator *> translators;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/qqmlbundle.cpp b/src/qml/qml/qqmlbundle.cpp
index 62925ced1e..273462aa25 100644
--- a/src/qml/qml/qqmlbundle.cpp
+++ b/src/qml/qml/qqmlbundle.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qqmlbundle_p.h"
-#include <QtCore/QtCore>
#include <iostream>
#include <cstdlib>
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp
index 62150b1af1..7279762565 100644
--- a/src/qml/qml/qqmlcompileddata.cpp
+++ b/src/qml/qml/qqmlcompileddata.cpp
@@ -105,7 +105,7 @@ void QQmlCompiledData::destroy()
QQmlCompiledData::~QQmlCompiledData()
{
if (isRegisteredWithEngine)
- QQmlEnginePrivate::get(engine)->unregisterCompositeType(this);
+ QQmlEnginePrivate::get(engine)->unregisterInternalCompositeType(this);
clear();
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 7a65515634..6951c8c387 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -815,7 +815,10 @@ bool QQmlCompiler::compile(QQmlEngine *engine,
const QQmlTypeData::TypeReference &tref = resolvedTypes.at(ii);
QQmlScript::TypeReference *parserRef = referencedTypes.at(ii);
- if (tref.type) {
+ if (tref.typeData) { //QML-based type
+ ref.component = tref.typeData->compiledData();
+ ref.component->addref();
+ } else if (tref.type) {//C++-based type
ref.type = tref.type;
if (!ref.type->isCreatable()) {
QString err = ref.type->noCreationReason();
@@ -823,21 +826,18 @@ bool QQmlCompiler::compile(QQmlEngine *engine,
err = tr( "Element is not creatable.");
COMPILE_EXCEPTION(parserRef->firstUse, err);
}
-
+
if (ref.type->containsRevisionedAttributes()) {
QQmlError cacheError;
ref.typePropertyCache = enginePrivate->cache(ref.type,
resolvedTypes.at(ii).minorVersion,
cacheError);
- if (!ref.typePropertyCache)
+ if (!ref.typePropertyCache)
COMPILE_EXCEPTION(parserRef->firstUse, cacheError.description());
ref.typePropertyCache->addref();
}
-
- } else if (tref.typeData) {
- ref.component = tref.typeData->compiledData();
- ref.component->addref();
}
+
out->types << ref;
}
@@ -944,7 +944,7 @@ void QQmlCompiler::compileTree(QQmlScript::Object *tree)
Q_ASSERT(tree->metatype);
if (!tree->synthdata.isEmpty()) {
- enginePrivate->registerCompositeType(output);
+ enginePrivate->registerInternalCompositeType(output);
} else if (output->types.at(tree->type).component) {
output->metaTypeId = output->types.at(tree->type).component->metaTypeId;
output->listMetaTypeId = output->types.at(tree->type).component->listMetaTypeId;
@@ -954,7 +954,7 @@ void QQmlCompiler::compileTree(QQmlScript::Object *tree)
output->listMetaTypeId = output->types.at(tree->type).type->qListTypeId();
}
if (!tree->synthdata.isEmpty())
- enginePrivate->registerCompositeType(output);
+ enginePrivate->registerInternalCompositeType(output);
}
static bool QStringList_contains(const QStringList &list, const QHashedStringRef &string)
@@ -1752,7 +1752,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
QQmlType *type = 0;
QQmlImportNamespace *typeNamespace = 0;
- unit->imports().resolveType(prop->name(), &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name(), &type, 0, 0, &typeNamespace);
if (typeNamespace) {
COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
@@ -1874,7 +1874,7 @@ bool QQmlCompiler::buildPropertyInNamespace(QQmlImportNamespace *ns,
// Setup attached property data
QQmlType *type = 0;
- unit->imports().resolveType(ns, prop->name(), &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name(), &type, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -2527,7 +2527,7 @@ bool QQmlCompiler::buildPropertyLiteralAssignment(QQmlScript::Property *prop,
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
- { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
+ { return &staticQtMetaObject; }
};
bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
@@ -2572,10 +2572,12 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
}
QQmlType *type = 0;
- unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
+ unit->imports().resolveType(typeName, &type, 0, 0, 0);
if (!type && typeName != QLatin1String("Qt"))
return true;
+ if (type && type->isComposite()) //No enums on composite types
+ return true;
int value = 0;
bool ok = false;
@@ -2619,7 +2621,7 @@ int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray&
if (scope != QLatin1String("Qt")) {
QQmlType *type = 0;
- unit->imports().resolveType(scope, &type, 0, 0, 0, 0);
+ unit->imports().resolveType(scope, &type, 0, 0, 0);
return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
}
@@ -2636,7 +2638,7 @@ int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray&
const QMetaObject *QQmlCompiler::resolveType(const QString& name) const
{
QQmlType *qmltype = 0;
- if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
+ if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -3024,12 +3026,11 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
// lazily resolved type
Q_ASSERT(s->parameterTypes.at(i) == Object::DynamicProperty::Custom);
QQmlType *qmltype = 0;
- QString url;
- if (!unit->imports().resolveType(s->parameterTypeNames.at(i).toString(), &qmltype, &url, 0, 0, 0))
+ if (!unit->imports().resolveType(s->parameterTypeNames.at(i).toString(), &qmltype, 0, 0, 0))
COMPILE_EXCEPTION(s, tr("Invalid signal parameter type: %1").arg(s->parameterTypeNames.at(i).toString()));
- if (!qmltype) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(QUrl(url));
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -3121,12 +3122,12 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
p->type == Object::DynamicProperty::Custom);
QQmlType *qmltype = 0;
- QString url;
- if (!unit->imports().resolveType(p->customType.toString(), &qmltype, &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p->customType.toString(), &qmltype, 0, 0, 0))
COMPILE_EXCEPTION(p, tr("Invalid property type"));
- if (!qmltype) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(QUrl(url));
+ Q_ASSERT(qmltype);
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -3885,7 +3886,7 @@ QQmlType *QQmlCompiler::toQmlType(QQmlScript::Object *from)
type = QQmlMetaType::qmlType(mo);
mo = mo->superClass();
}
- return type;
+ return type;
}
QStringList QQmlCompiler::deferredProperties(QQmlScript::Object *obj)
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index e2d49b32db..aefad475b4 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -49,8 +49,6 @@
#include <QtCore/qstring.h>
#include <QtQml/qjsvalue.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -139,6 +137,4 @@ Q_DECLARE_METATYPE(QQmlComponent::Status)
QML_DECLARE_TYPE(QQmlComponent)
QML_DECLARE_TYPEINFO(QQmlComponent, QML_HAS_ATTACHED_PROPERTIES)
-QT_END_HEADER
-
#endif // QQMLCOMPONENT_H
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index 9901821b94..3c27e795c6 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -45,8 +45,6 @@
#include <QtQml/qqml.h>
#include <QtCore/QObject>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -80,6 +78,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLCOMPONENTATTACHED_P_H
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index 5477b46e92..e191807cf4 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -48,8 +48,6 @@
#include <QtCore/qmetatype.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -107,6 +105,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QList<QObject*>)
-QT_END_HEADER
-
#endif // QQMLCONTEXT_H
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 3114c52870..7a3fd47b46 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -61,8 +61,6 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qxmlstream.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -163,6 +161,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QQmlCustomParserProperty)
Q_DECLARE_METATYPE(QQmlCustomParserNode)
-QT_END_HEADER
-
#endif
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 145818aadf..25ef080cb5 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -55,8 +55,6 @@
#include "qqmlxmlhttprequest_p.h"
#include "qqmlscriptstring.h"
#include "qqmlglobal_p.h"
-#include "qquicklistmodel_p.h"
-#include "qquickworkerscript_p.h"
#include "qqmlcomponent_p.h"
#include "qqmlnetworkaccessmanagerfactory.h"
#include "qqmldirparser_p.h"
@@ -89,9 +87,16 @@
#include <private/qqmllocale_p.h>
-#include "qqmlbind_p.h"
-#include "qqmlconnections_p.h"
-#include "qqmltimer_p.h"
+#include <private/qqmlbind_p.h>
+#include <private/qqmlconnections_p.h>
+#include <private/qqmltimer_p.h>
+#include <private/qqmllistmodel_p.h>
+#include <private/qqmlplatform_p.h>
+#include <private/qquickpackage_p.h>
+#include <private/qqmldelegatemodel_p.h>
+#include <private/qqmlobjectmodel_p.h>
+#include <private/qquickworkerscript_p.h>
+#include <private/qqmlinstantiator_p.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
@@ -179,16 +184,22 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int
qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding");
qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections");
qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer");
+ qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1
qmlRegisterCustomType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections", new QQmlConnectionsParser);
+ qmlRegisterType<QQmlInstanceModel>();
}
// 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<QQmlListElement>(uri, versionMajor, versionMinor, "ListElement"); // Now in QtQml.Models, here for compatibility
+ qmlRegisterCustomType<QQmlListModel>(uri, versionMajor, versionMinor, "ListModel", new QQmlListModelParser); // Now in QtQml.Models, here for compatibility
qmlRegisterType<QQuickWorkerScript>(uri, versionMajor, versionMinor, "WorkerScript");
+ qmlRegisterType<QQuickPackage>(uri, versionMajor, versionMinor, "Package");
+ qmlRegisterType<QQmlDelegateModel>(uri, versionMajor, versionMinor, "VisualDataModel");
+ qmlRegisterType<QQmlDelegateModelGroup>(uri, versionMajor, versionMinor, "VisualDataGroup");
+ qmlRegisterType<QQmlObjectModel>(uri, versionMajor, versionMinor, "VisualItemModel");
}
void QQmlEnginePrivate::defineQtQuick2Module()
@@ -359,6 +370,36 @@ The following functions are also on the Qt object.
*/
/*!
+ \qmlproperty object Qt::platform
+ \since QtQml 2.1
+
+ The \c platform object provides info about the underlying platform.
+
+ Its properties are:
+
+ \table
+ \row
+ \li \c platform.os
+ \li
+
+ This read-only property contains the name of the operating system.
+
+ Possible values are:
+
+ \list
+ \li \c "android" - Android
+ \li \c "blackberry" - BlackBerry OS
+ \li \c "ios" - Apple iOS
+ \li \c "linux" - Linux
+ \li \c "mac" - Mac OS X
+ \li \c "unix" - Other Unix-based OS
+ \li \c "windows" - Windows
+ \li \c "wince" - Windows CE
+ \endlist
+ \endtable
+*/
+
+/*!
\qmlproperty object Qt::application
\since QtQuick 1.1
@@ -398,13 +439,31 @@ The following functions are also on the Qt object.
\li Qt.RightToLeft - Text and graphics elements should be positioned
from right to left.
\endlist
-
+ \row
+ \li \c application.arguments
+ \li This is a string list of the arguments the executable was invoked with.
+ \row
+ \li \c application.name
+ \li This is the application name set on the QCoreApplication instance. This property can be written
+ to in order to set the application name.
+ \row
+ \li \c application.version
+ \li This is the application version set on the QCoreApplication instance. This property can be written
+ to in order to set the application name.
\endtable
+ The object also has one signal, aboutToQuit(), which is the same as \l QCoreApplication::aboutToQuit().
+
The following example uses the \c application object to indicate
whether the application is currently active:
\snippet qml/application.qml document
+
+ Note that when using QML without a QGuiApplication, the following properties will be undefined:
+ \list
+ \li application.active
+ \li application.layoutDirection
+ \endlist
*/
/*!
@@ -757,6 +816,16 @@ QQmlEngine::QQmlEngine(QObject *parent)
}
/*!
+* \internal
+*/
+QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent)
+: QJSEngine(dd, parent)
+{
+ Q_D(QQmlEngine);
+ d->init();
+}
+
+/*!
Destroys the QQmlEngine.
Any QQmlContext's created on this engine will be
@@ -2023,7 +2092,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
}
}
-void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
+void QQmlEnginePrivate::registerInternalCompositeType(QQmlCompiledData *data)
{
QByteArray name = data->rootPropertyCache->className();
@@ -2058,7 +2127,7 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data)
m_compositeTypes.insert(ptr_type, data);
}
-void QQmlEnginePrivate::unregisterCompositeType(QQmlCompiledData *data)
+void QQmlEnginePrivate::unregisterInternalCompositeType(QQmlCompiledData *data)
{
int ptr_type = data->metaTypeId;
int lst_type = data->listMetaTypeId;
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 76e6ce1d75..45826a4a67 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -49,8 +49,6 @@
#include <QtQml/qqmlerror.h>
#include <QtQml/qqmldebug.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -144,6 +142,7 @@ public:
static void setObjectOwnership(QObject *, ObjectOwnership);
static ObjectOwnership objectOwnership(QObject *);
protected:
+ QQmlEngine(QQmlEnginePrivate &dd, QObject *p);
virtual bool event(QEvent *);
Q_SIGNALS:
@@ -157,6 +156,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLENGINE_H
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 43bcc0390f..b5af0bb7cd 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -235,8 +235,8 @@ public:
QQmlMetaObject metaObjectForType(int) const;
QQmlPropertyCache *propertyCacheForType(int);
QQmlPropertyCache *rawPropertyCacheForType(int);
- void registerCompositeType(QQmlCompiledData *);
- void unregisterCompositeType(QQmlCompiledData *);
+ void registerInternalCompositeType(QQmlCompiledData *);
+ void unregisterInternalCompositeType(QQmlCompiledData *);
bool isTypeLoaded(const QUrl &url) const;
bool isScriptLoaded(const QUrl &url) const;
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index c95e0c50b9..cea9ee4cc0 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -47,8 +47,6 @@
#include <QtCore/qurl.h>
#include <QtCore/qstring.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -84,6 +82,4 @@ Q_DECLARE_TYPEINFO(QQmlError, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLERROR_H
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index 8c3bf38581..b04abc1b98 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -48,8 +48,6 @@
#include <QtCore/qobject.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -113,7 +111,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLEXPRESSION_H
diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h
index 35facb0333..be2939d366 100644
--- a/src/qml/qml/qqmlextensioninterface.h
+++ b/src/qml/qml/qqmlextensioninterface.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -76,6 +74,4 @@ Q_DECLARE_INTERFACE(QQmlExtensionInterface, QQmlExtensionInterface_iid)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLEXTENSIONINTERFACE_H
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index bbc0fed768..edef5a91cd 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qqmlextensionplugin.h"
+#include "qqmlextensionplugin_p.h"
QT_BEGIN_NAMESPACE
@@ -144,7 +145,7 @@ QT_BEGIN_NAMESPACE
explicitly.
*/
QQmlExtensionPlugin::QQmlExtensionPlugin(QObject *parent)
- : QObject(parent)
+ : QObject(*(new QQmlExtensionPluginPrivate), parent)
{
}
@@ -155,6 +156,12 @@ QQmlExtensionPlugin::~QQmlExtensionPlugin()
{
}
+QUrl QQmlExtensionPlugin::baseUrl() const
+{
+ Q_D(const QQmlExtensionPlugin);
+ return d->baseUrl;
+}
+
/*!
\fn void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index a7f5da137a..170c7915a5 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -43,35 +43,34 @@
#define QQMLEXTENSIONPLUGIN_H
#include <QtCore/qplugin.h>
-
+#include <QtCore/QUrl>
#include <QtQml/qqmlextensioninterface.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-
class QQmlEngine;
+class QQmlExtensionPluginPrivate;
-class Q_QML_EXPORT QQmlExtensionPlugin : public QObject,
- public QQmlExtensionInterface
+class Q_QML_EXPORT QQmlExtensionPlugin
+ : public QObject
+ , public QQmlExtensionInterface
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlExtensionPlugin)
Q_INTERFACES(QQmlExtensionInterface)
Q_INTERFACES(QQmlTypesExtensionInterface)
public:
explicit QQmlExtensionPlugin(QObject *parent = 0);
~QQmlExtensionPlugin();
+ QUrl baseUrl() const;
+
virtual void registerTypes(const char *uri) = 0;
virtual void initializeEngine(QQmlEngine *engine, const char *uri);
-private:
Q_DISABLE_COPY(QQmlExtensionPlugin)
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLEXTENSIONPLUGIN_H
diff --git a/src/qml/qml/qqmlextensionplugin_p.h b/src/qml/qml/qqmlextensionplugin_p.h
new file mode 100644
index 0000000000..747bc78efb
--- /dev/null
+++ b/src/qml/qml/qqmlextensionplugin_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLEXTENSIONPLUGIN_P_H
+#define QQMLEXTENSIONPLUGIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qobject_p.h>
+#include "qqmlextensionplugin.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQmlExtensionPluginPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlExtensionPlugin)
+
+public:
+ static QQmlExtensionPluginPrivate* get(QQmlExtensionPlugin *e) { return e->d_func(); }
+
+ QUrl baseUrl;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLEXTENSIONPLUGIN_P_H
diff --git a/src/qml/qml/qqmlfile.h b/src/qml/qml/qqmlfile.h
index 777bc0db7b..5e7a42d6bd 100644
--- a/src/qml/qml/qqmlfile.h
+++ b/src/qml/qml/qqmlfile.h
@@ -44,8 +44,6 @@
#include <QtQml/qtqmlglobal.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QUrl;
@@ -119,6 +117,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLFILE_H
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 5d4b2a567b..607ee4d0ac 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qvariant.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
+#include <QtCore/QCoreApplication>
QT_BEGIN_NAMESPACE
@@ -54,6 +55,7 @@ QQmlValueTypeProvider::QQmlValueTypeProvider()
QQmlValueTypeProvider::~QQmlValueTypeProvider()
{
+ QQml_removeValueTypeProvider(this);
}
QQmlValueType *QQmlValueTypeProvider::createValueType(int type)
@@ -266,13 +268,13 @@ bool QQmlValueTypeProvider::store(int, const void *, void *, size_t) { return fa
bool QQmlValueTypeProvider::read(int, const void *, size_t, int, void *) { return false; }
bool QQmlValueTypeProvider::write(int, const void *, void *, size_t) { return false; }
+Q_GLOBAL_STATIC(QQmlValueTypeProvider, nullValueTypeProvider)
static QQmlValueTypeProvider *valueTypeProvider = 0;
static QQmlValueTypeProvider **getValueTypeProvider(void)
{
if (valueTypeProvider == 0) {
- static QQmlValueTypeProvider nullValueTypeProvider;
- valueTypeProvider = &nullValueTypeProvider;
+ valueTypeProvider = nullValueTypeProvider;
}
return &valueTypeProvider;
@@ -285,6 +287,34 @@ Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *newPr
*providerPtr = newProvider;
}
+Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *oldProvider)
+{
+ if (oldProvider == nullValueTypeProvider) {
+ // don't remove the null provider
+ // we get here when the QtQml library is being unloaded
+ return;
+ }
+
+ // the only entry with next = 0 is the null provider
+ Q_ASSERT(oldProvider->next);
+
+ QQmlValueTypeProvider *prev = valueTypeProvider;
+ if (prev == oldProvider) {
+ valueTypeProvider = oldProvider->next;
+ return;
+ }
+
+ // singly-linked list removal
+ for ( ; prev; prev = prev->next) {
+ if (prev->next != oldProvider)
+ continue; // this is not the provider you're looking for
+ prev->next = oldProvider->next;
+ return;
+ }
+
+ qWarning("QQml_removeValueTypeProvider: was asked to remove provider %p but it was not found", oldProvider);
+}
+
Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(void)
{
static QQmlValueTypeProvider **providerPtr = getValueTypeProvider();
@@ -328,7 +358,7 @@ Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(void)
QQmlGuiProvider::~QQmlGuiProvider() {}
-QObject *QQmlGuiProvider::application(QObject *) { return 0; }
+QObject *QQmlGuiProvider::application(QObject *) { return new QQmlApplication(); }
QStringList QQmlGuiProvider::fontFamilies() { return QStringList(); }
bool QQmlGuiProvider::openUrlExternally(QUrl &) { return false; }
@@ -354,8 +384,7 @@ Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newPr
static QQmlGuiProvider **getGuiProvider(void)
{
if (guiProvider == 0) {
- qWarning() << "Warning: QQml_guiProvider: no GUI provider has been set!";
- static QQmlGuiProvider nullGuiProvider;
+ static QQmlGuiProvider nullGuiProvider; //Still provides an application with no GUI support
guiProvider = &nullGuiProvider;
}
@@ -368,4 +397,51 @@ Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(void)
return *providerPtr;
}
+//Docs in qqmlengine.cpp
+QQmlApplication::QQmlApplication(QObject *parent)
+ : QObject(*(new QQmlApplicationPrivate),parent)
+{
+ connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
+ this, SIGNAL(aboutToQuit()));
+}
+
+QQmlApplication::QQmlApplication(QQmlApplicationPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+ connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()),
+ this, SIGNAL(aboutToQuit()));
+}
+
+QStringList QQmlApplication::args()
+{
+ Q_D(QQmlApplication);
+ if (!d->argsInit) {
+ d->argsInit = true;
+ d->args = QCoreApplication::arguments();
+ }
+ return d->args;
+}
+
+QString QQmlApplication::name() const
+{
+ return QCoreApplication::instance()->applicationName();
+}
+
+QString QQmlApplication::version() const
+{
+ return QCoreApplication::instance()->applicationVersion();
+}
+
+void QQmlApplication::setName(const QString &arg)
+{
+ QCoreApplication::instance()->setApplicationName(arg);
+ emit nameChanged(); //Note that we don't get notified if it's changed from C++
+}
+
+void QQmlApplication::setVersion(const QString &arg)
+{
+ QCoreApplication::instance()->setApplicationVersion(arg);
+ emit versionChanged(); //Note that we don't get notified if it's changed from C++
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 2631fc459f..6ca54f65cd 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -48,8 +48,6 @@
#include <private/qmetaobject_p.h>
#include <private/qv8engine_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -273,6 +271,7 @@ private:
virtual bool write(int, const void *, void *, size_t);
friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *);
+ friend Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *);
QQmlValueTypeProvider *next;
};
@@ -314,8 +313,53 @@ public:
Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *);
Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider();
-QT_END_NAMESPACE
+class QQmlApplicationPrivate;
+
+class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject
+{
+ //Application level logic, subclassed by QtQuick if available via QQmlGuiProvider
+ Q_OBJECT
+ Q_PROPERTY(QStringList arguments READ args CONSTANT)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
+public:
+ QQmlApplication(QObject* parent=0);
+
+ QStringList args();
+
+ QString name() const;
+ QString version() const;
+
+public Q_SLOTS:
+ void setName(const QString &arg);
+ void setVersion(const QString &arg);
+
+Q_SIGNALS:
+ void aboutToQuit();
+
+ void nameChanged();
+ void versionChanged();
+
+protected:
+ QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0);
-QT_END_HEADER
+private:
+ Q_DISABLE_COPY(QQmlApplication);
+ Q_DECLARE_PRIVATE(QQmlApplication);
+};
+
+class QQmlApplicationPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlApplication)
+public:
+ QQmlApplicationPrivate() {
+ argsInit = false;
+ }
+
+ bool argsInit;
+ QStringList args;
+};
+
+QT_END_NAMESPACE
#endif // QQMLGLOBAL_H
diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h
index cef4c8fb8d..455f5c93a8 100644
--- a/src/qml/qml/qqmlguard_p.h
+++ b/src/qml/qml/qqmlguard_p.h
@@ -201,7 +201,7 @@ template<class T>
T *QQmlGuard<T>::object() const
{
return static_cast<T *>(o);
-};
+}
template<class T>
void QQmlGuard<T>::setObject(T *g)
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 52d07b23ec..f793ca9604 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -49,6 +49,8 @@
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qreadwritelock.h>
#include <QtQml/qqmlextensioninterface.h>
+#include <QtQml/qqmlextensionplugin.h>
+#include <private/qqmlextensionplugin_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmltypenamecache_p.h>
#include <private/qqmlengine_p.h>
@@ -124,6 +126,39 @@ bool isPathAbsolute(const QString &path)
#endif
}
+// If the type does not already exist as a file import, add the type and return the new type
+QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeName, QList<QQmlError> *errors)
+{
+ QUrl url(urlString);
+ QQmlType *ret = QQmlMetaType::qmlType(url);
+ if (!ret) { //QQmlType not yet existing for composite type
+ int dot = typeName.indexOf(QLatin1Char('.'));
+ QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1);
+
+ //XXX: The constData of the string ref is pointing somewhere unsafe in qmlregister, so we need to create a temporary copy
+ QByteArray buf(unqualifiedtype.toUtf8().constData());
+
+ QQmlPrivate::RegisterCompositeType reg = {
+ url,
+ "", //Empty URI indicates loaded via file imports
+ -1,
+ -1,
+ buf.constData()
+ };
+ ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
+ }
+ if (!ret) {//Usually when a type name is "found" but invalid
+ //qDebug() << ret << urlString << QQmlMetaType::qmlType(url);
+ if (!errors) // Cannot list errors properly, just quit
+ qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData());
+ QQmlError error;
+ error.setDescription(QQmlMetaType::typeRegistrationFailures().join('\n'));
+ errors->prepend(error);
+ }
+ return ret;
+
+}
+
}
typedef QMap<QString, QString> StringStringMap;
@@ -150,8 +185,7 @@ public:
static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
- int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
+ int *vmajor, int *vminor, QQmlType** type_return,
QString *base = 0, bool *typeRecursionDetected = 0) const;
};
QList<Import *> imports;
@@ -159,8 +193,7 @@ public:
Import *findImport(const QString &uri);
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
+ int *vmajor, int *vminor, QQmlType** type_return,
QString *base = 0, QList<QQmlError> *errors = 0);
// Prefix when used as a qualified import. Otherwise empty.
@@ -194,8 +227,7 @@ public:
QList<QQmlError> *errors);
bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QList<QQmlError> *errors);
+ QQmlType** type_return, QList<QQmlError> *errors);
QUrl baseUrl;
QString base;
@@ -228,7 +260,7 @@ public:
QQmlImportNamespace::Import *addImportToNamespace(QQmlImportNamespace *nameSpace,
const QString &uri, const QString &url,
int vmaj, int vmin, QQmlScript::Import::Type type,
- QList<QQmlError> *errors);
+ QList<QQmlError> *errors, bool lowPrecedence = false);
};
/*!
@@ -379,9 +411,8 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base,
The given (namespace qualified) \a type is resolved to either
\list
- \li a QQmlImportNamespace stored at \a ns_return,
- \li a QQmlType stored at \a type_return, or
- \li a component located at \a url_return.
+ \li a QQmlImportNamespace stored at \a ns_return, or
+ \li a QQmlType stored at \a type_return,
\endlist
If any return pointer is 0, the corresponding search is not done.
@@ -389,7 +420,7 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base,
\sa addFileImport(), addLibraryImport
*/
bool QQmlImports::resolveType(const QHashedStringRef &type,
- QQmlType** type_return, QString* url_return, int *vmaj, int *vmin,
+ QQmlType** type_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors) const
{
QQmlImportNamespace* ns = d->findQualifiedNamespace(type);
@@ -398,19 +429,16 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
*ns_return = ns;
return true;
}
- if (type_return || url_return) {
- if (d->resolveType(type,vmaj,vmin,type_return,url_return, errors)) {
+ if (type_return) {
+ if (d->resolveType(type,vmaj,vmin,type_return, errors)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
<< ')' << "::resolveType: " << type.toString() << " => "
- if (type_return && *type_return && url_return && !url_return->isEmpty())
- RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << *url_return << " TYPE/URL";
- if (type_return && *type_return)
+ if (type_return && *type_return && (*type_return)->isComposite())
+ RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << (*type_return)->sourceUrl() << " TYPE/URL";
+ else if (type_return && *type_return)
RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << " TYPE";
- if (url_return && !url_return->isEmpty())
- RESOLVE_TYPE_DEBUG << *url_return << " URL";
-
#undef RESOLVE_TYPE_DEBUG
}
return true;
@@ -469,23 +497,21 @@ QQmlDirScripts QQmlImportNamespace::Import::getVersionedScripts(const QQmlDirScr
\internal
Searching \e only in the namespace \a ns (previously returned in a call to
- resolveType(), \a type is found and returned to either
- a QQmlType stored at \a type_return, or
- a component located at \a url_return.
+ resolveType(), \a type is found and returned to
+ a QQmlType stored at \a type_return. If the type is from a QML file, the returned
+ type will be a CompositeType.
- If either return pointer is 0, the corresponding search is not done.
+ If the return pointer is 0, the corresponding search is not done.
*/
bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QHashedStringRef &type,
- QQmlType** type_return, QString* url_return,
- int *vmaj, int *vmin) const
+ QQmlType** type_return, int *vmaj, int *vmin) const
{
- return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return,url_return);
+ return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return);
}
bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QString *base, bool *typeRecursionDetected) const
+ QQmlType** type_return, QString *base, bool *typeRecursionDetected) const
{
if (majversion >= 0 && minversion >= 0) {
QQmlType *t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
@@ -530,9 +556,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
if (candidate != end) {
- if (url_return)
- *url_return = componentUrl;
- return true;
+ if (type_return)
+ *type_return = getTypeForUrl(componentUrl, type, 0);
+ return (*type_return != 0);
}
} else if (!isLibrary) {
QString qmlUrl = url + QString::fromRawData(type.constData(), type.length()) + dotqml_string;
@@ -550,9 +576,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
if (typeRecursionDetected)
*typeRecursionDetected = true;
} else {
- if (url_return)
- *url_return = qmlUrl;
- return true;
+ if (type_return)
+ *type_return = getTypeForUrl(qmlUrl, type, 0);
+ return (*type_return) != 0;
}
}
}
@@ -561,8 +587,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
- QQmlType** type_return, QString* url_return,
- QList<QQmlError> *errors)
+ QQmlType** type_return, QList<QQmlError> *errors)
{
QQmlImportNamespace *s = 0;
int dot = type.indexOf(Dot);
@@ -591,12 +616,12 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
}
QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
if (s) {
- if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
+ if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return, &base, errors))
return true;
- if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && url_return && s != &unqualifiedset) {
+ if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *url_return = resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml"));
- return true;
+ *type_return = getTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, errors);
+ return (*type_return != 0);
}
}
@@ -615,18 +640,18 @@ QQmlImportNamespace::Import *QQmlImportNamespace::findImport(const QString &uri)
bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType** type_return,
- QString* url_return, QString *base, QList<QQmlError> *errors)
+ QString *base, QList<QQmlError> *errors)
{
bool typeRecursionDetected = false;
for (int i=0; i<imports.count(); ++i) {
const Import *import = imports.at(i);
- if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, url_return,
+ if (import->resolveType(typeLoader, type, vmajor, vminor, type_return,
base, &typeRecursionDetected)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<imports.count(); ++j) {
const Import *import2 = imports.at(j);
- if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, 0, base)) {
+ if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, base)) {
if (errors) {
QString u1 = import->url;
QString u2 = import2->url;
@@ -978,7 +1003,7 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix)
QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace,
const QString &uri, const QString &url, int vmaj, int vmin,
QQmlScript::Import::Type type,
- QList<QQmlError> *errors)
+ QList<QQmlError> *errors, bool lowPrecedence)
{
Q_ASSERT(nameSpace);
Q_ASSERT(errors);
@@ -992,7 +1017,11 @@ QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImport
import->minversion = vmin;
import->isLibrary = (type == QQmlScript::Import::Library);
- nameSpace->imports.prepend(import);
+ if (lowPrecedence)
+ nameSpace->imports.append(import);
+ else
+ nameSpace->imports.prepend(import);
+
return import;
}
@@ -1137,7 +1166,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
if (!url.endsWith(Slash) && !url.endsWith(Backslash))
url += Slash;
- QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QQmlScript::Import::File, errors);
+ QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QQmlScript::Import::File, errors, isImplicitImport);
Q_ASSERT(inserted);
if (!incomplete && !qmldirIdentifier.isEmpty()) {
@@ -1213,6 +1242,8 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString &
Adds an implicit "." file import. This is equivalent to calling addFileImport(), but error
messages related to the path or qmldir file not existing are suppressed.
+
+ Additionally, this will add the import with lowest instead of highest precedence.
*/
bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors)
{
@@ -1660,6 +1691,10 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
QQmlMetaType::setTypeRegistrationNamespace(typeNamespace);
+ if (QQmlExtensionPlugin *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) {
+ // Set the directory, not the library file itself
+ QQmlExtensionPluginPrivate::get(plugin)->baseUrl = QUrl::fromLocalFile(fileInfo.absolutePath());
+ }
iface->registerTypes(moduleId);
registrationFailures = QQmlMetaType::typeRegistrationFailures();
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index ad4b3dfee9..140ca6695e 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -85,14 +85,13 @@ public:
QUrl baseUrl() const;
bool resolveType(const QHashedStringRef &type,
- QQmlType** type_return, QString* url_return,
+ QQmlType** type_return,
int *version_major, int *version_minor,
QQmlImportNamespace** ns_return,
QList<QQmlError> *errors = 0) const;
bool resolveType(QQmlImportNamespace*,
const QHashedStringRef& type,
- QQmlType** type_return, QString* url_return,
- int *version_major, int *version_minor) const;
+ QQmlType** type_return, int *version_major, int *version_minor) const;
bool addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors);
diff --git a/src/qml/qml/qqmlincubator.h b/src/qml/qml/qqmlincubator.h
index bbb232bfa2..4d3287a394 100644
--- a/src/qml/qml/qqmlincubator.h
+++ b/src/qml/qml/qqmlincubator.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtQml/qqmlerror.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -125,6 +123,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLINCUBATOR_H
diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h
index c2b2cb353e..16fca9428e 100644
--- a/src/qml/qml/qqmlinfo.h
+++ b/src/qml/qml/qqmlinfo.h
@@ -46,8 +46,6 @@
#include <QtCore/qurl.h>
#include <QtQml/qqmlerror.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -98,6 +96,4 @@ Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLINFO_H
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index d2425bc6bf..a27a2da9ae 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -46,8 +46,6 @@
#include <QtCore/qlist.h>
#include <QtCore/qvariant.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -150,6 +148,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QQmlListReference)
-QT_END_HEADER
-
#endif // QQMLLIST_H
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index e1ac75f5f0..c9ce4773c3 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -464,8 +464,11 @@ v8::Handle<v8::Value> QQmlNumberExtension::toLocaleString(const v8::Arguments& a
if (!args[1]->IsString())
V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
v8::Local<v8::String> fs = args[1]->ToString();
- if (!fs.IsEmpty() && fs->Length())
- format = fs->GetCharacter(0);
+ if (!fs.IsEmpty() && fs->Length()) {
+ v8::String::Value value(fs);
+ Q_ASSERT(*value != NULL);
+ format = **value;
+ }
}
int prec = 2;
if (args.Length() > 2) {
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 8015ca2bbe..25f98d9168 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -49,8 +49,6 @@
#include <private/qv8engine_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -133,6 +131,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/qml/qml/qqmlmemoryprofiler_p.h b/src/qml/qml/qqmlmemoryprofiler_p.h
index d0d96f20f9..dfc26aa8fb 100644
--- a/src/qml/qml/qqmlmemoryprofiler_p.h
+++ b/src/qml/qml/qqmlmemoryprofiler_p.h
@@ -44,7 +44,6 @@
#include <private/qtqmlglobal_p.h>
-QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QUrl;
@@ -76,6 +75,4 @@ public:
#define QML_MEMORY_SCOPE_STRING(s) QQmlMemoryScope _qml_memory_scope(s)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLMEMORYPROFILER_H
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 2389c45574..372475d85c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -75,6 +75,8 @@ struct QQmlMetaTypeData
Ids idToType;
typedef QHash<QHashedStringRef,QQmlType *> Names;
Names nameToType;
+ typedef QHash<QUrl, QQmlType *> Files; //For file imported composite types only
+ Files urlToType;
typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
@@ -148,48 +150,68 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
class QQmlTypePrivate
{
public:
- QQmlTypePrivate();
+ QQmlTypePrivate(QQmlType::RegistrationType type);
~QQmlTypePrivate();
void init() const;
void initEnums() const;
void insertEnums(const QMetaObject *metaObject) const;
- bool m_isInterface : 1;
- const char *m_iid;
- QHashedString m_module;
- QString m_name;
- QString m_elementName;
- int m_version_maj;
- int m_version_min;
- int m_typeId; int m_listId;
- int m_revision;
- mutable bool m_containsRevisionedAttributes;
- mutable QQmlType *m_superType;
-
- int m_allocationSize;
- void (*m_newFunc)(void *);
- QString m_noCreationReason;
-
- const QMetaObject *m_baseMetaObject;
- QQmlAttachedPropertiesFunc m_attachedPropertiesFunc;
- const QMetaObject *m_attachedPropertiesType;
- int m_attachedPropertiesId;
- int m_parserStatusCast;
- int m_propertyValueSourceCast;
- int m_propertyValueInterceptorCast;
- QObject *(*m_extFunc)(QObject *);
- const QMetaObject *m_extMetaObject;
- int m_index;
- QQmlCustomParser *m_customParser;
- mutable volatile bool m_isSetup:1;
- mutable volatile bool m_isEnumSetup:1;
- mutable bool m_haveSuperType:1;
- mutable QList<QQmlProxyMetaObject::ProxyData> m_metaObjects;
- mutable QStringHash<int> m_enums;
- QQmlType::SingletonInstanceInfo *m_singletonInstanceInfo;
-
- static QHash<const QMetaObject *, int> m_attachedPropertyIds;
+ QQmlType::RegistrationType regType;
+
+ struct QQmlCppTypeData
+ {
+ int allocationSize;
+ void (*newFunc)(void *);
+ QString noCreationReason;
+ int parserStatusCast;
+ QObject *(*extFunc)(QObject *);
+ const QMetaObject *extMetaObject;
+ QQmlCustomParser *customParser;
+ QQmlAttachedPropertiesFunc attachedPropertiesFunc;
+ const QMetaObject *attachedPropertiesType;
+ int attachedPropertiesId;
+ int propertyValueSourceCast;
+ int propertyValueInterceptorCast;
+ };
+
+ struct QQmlSingletonTypeData
+ {
+ QQmlType::SingletonInstanceInfo *singletonInstanceInfo;
+ };
+
+ struct QQmlCompositeTypeData
+ {
+ QUrl url;
+ };
+
+ union extraData {
+ QQmlCppTypeData* cd;
+ QQmlSingletonTypeData* sd;
+ QQmlCompositeTypeData* fd;
+ } extraData;
+
+ const char *iid;
+ QHashedString module;
+ QString name;
+ QString elementName;
+ int version_maj;
+ int version_min;
+ int typeId;
+ int listId;
+ int revision;
+ mutable bool containsRevisionedAttributes;
+ mutable QQmlType *superType;
+ const QMetaObject *baseMetaObject;
+
+ int index;
+ mutable volatile bool isSetup:1;
+ mutable volatile bool isEnumSetup:1;
+ mutable bool haveSuperType:1;
+ mutable QList<QQmlProxyMetaObject::ProxyData> metaObjects;
+ mutable QStringHash<int> enums;
+
+ static QHash<const QMetaObject *, int> attachedPropertyIds;
};
// Avoid multiple fromUtf8(), copies and hashing of the module name.
@@ -250,147 +272,195 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const
return scriptApis.value(e);
}
-QHash<const QMetaObject *, int> QQmlTypePrivate::m_attachedPropertyIds;
-
-QQmlTypePrivate::QQmlTypePrivate()
-: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_revision(0), m_containsRevisionedAttributes(false),
- m_superType(0), m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0),
- m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1),
- m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0),
- m_isSetup(false), m_isEnumSetup(false), m_haveSuperType(false), m_singletonInstanceInfo(0)
-{
+QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds;
+
+QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
+: regType(type), iid(0), typeId(0), listId(0), revision(0),
+ containsRevisionedAttributes(false), superType(0), baseMetaObject(0),
+ index(-1), isSetup(false), isEnumSetup(false), haveSuperType(false)
+{
+ switch (type) {
+ case QQmlType::CppType:
+ extraData.cd = new QQmlCppTypeData;
+ extraData.cd->allocationSize = 0;
+ extraData.cd->newFunc = 0;
+ extraData.cd->parserStatusCast = -1;
+ extraData.cd->extFunc = 0;
+ extraData.cd->extMetaObject = 0;
+ extraData.cd->customParser = 0;
+ extraData.cd->attachedPropertiesFunc = 0;
+ extraData.cd->attachedPropertiesType = 0;
+ extraData.cd->propertyValueSourceCast = -1;
+ extraData.cd->propertyValueInterceptorCast = -1;
+ break;
+ case QQmlType::SingletonType:
+ extraData.sd = new QQmlSingletonTypeData;
+ extraData.sd->singletonInstanceInfo = 0;
+ break;
+ case QQmlType::InterfaceType:
+ extraData.cd = 0;
+ break;
+ case QQmlType::CompositeType:
+ extraData.fd = new QQmlCompositeTypeData;
+ break;
+ default: qFatal("QQmlTypePrivate Internal Error.");
+ }
}
QQmlTypePrivate::~QQmlTypePrivate()
{
- delete m_singletonInstanceInfo;
+ switch (regType) {
+ case QQmlType::CppType:
+ delete extraData.cd->customParser;
+ delete extraData.cd;
+ break;
+ case QQmlType::SingletonType:
+ delete extraData.sd->singletonInstanceInfo;
+ delete extraData.sd;
+ break;
+ case QQmlType::CompositeType:
+ delete extraData.fd;
+ break;
+ default: //Also InterfaceType, because it has no extra data
+ break;
+ }
}
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
-: d(new QQmlTypePrivate)
+: d(new QQmlTypePrivate(InterfaceType))
{
- d->m_isInterface = true;
- d->m_iid = interface.iid;
- d->m_typeId = interface.typeId;
- d->m_listId = interface.listId;
- d->m_newFunc = 0;
- d->m_index = index;
- d->m_isSetup = true;
- d->m_version_maj = 0;
- d->m_version_min = 0;
+ d->iid = interface.iid;
+ d->typeId = interface.typeId;
+ d->listId = interface.listId;
+ d->index = index;
+ d->isSetup = true;
+ d->version_maj = 0;
+ d->version_min = 0;
}
QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
-: d(new QQmlTypePrivate)
+: d(new QQmlTypePrivate(SingletonType))
{
- d->m_elementName = elementName;
- d->m_module = moduleFromUtf8(type.uri);
+ d->elementName = elementName;
+ d->module = moduleFromUtf8(type.uri);
- d->m_version_maj = type.versionMajor;
- d->m_version_min = type.versionMinor;
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
if (type.qobjectApi) {
if (type.version >= 1) // static metaobject added in version 1
- d->m_baseMetaObject = type.instanceMetaObject;
+ d->baseMetaObject = type.instanceMetaObject;
if (type.version >= 2) // typeId added in version 2
- d->m_typeId = type.typeId;
+ d->typeId = type.typeId;
if (type.version >= 2) // revisions added in version 2
- d->m_revision = type.revision;
+ d->revision = type.revision;
}
- d->m_newFunc = 0;
- d->m_index = index;
+ d->index = index;
- d->m_singletonInstanceInfo = new SingletonInstanceInfo;
- d->m_singletonInstanceInfo->scriptCallback = type.scriptApi;
- d->m_singletonInstanceInfo->qobjectCallback = type.qobjectApi;
- d->m_singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
- d->m_singletonInstanceInfo->instanceMetaObject = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
+ d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
+ d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
+ d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
+ d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
+ d->extraData.sd->singletonInstanceInfo->instanceMetaObject
+ = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
}
QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type)
-: d(new QQmlTypePrivate)
+: d(new QQmlTypePrivate(CppType))
{
- d->m_elementName = elementName;
- d->m_module = moduleFromUtf8(type.uri);
+ d->elementName = elementName;
+ d->module = moduleFromUtf8(type.uri);
- d->m_version_maj = type.versionMajor;
- d->m_version_min = type.versionMinor;
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
if (type.version >= 1) // revisions added in version 1
- d->m_revision = type.revision;
- d->m_typeId = type.typeId;
- d->m_listId = type.listId;
- d->m_allocationSize = type.objectSize;
- d->m_newFunc = type.create;
- d->m_noCreationReason = type.noCreationReason;
- d->m_baseMetaObject = type.metaObject;
- d->m_attachedPropertiesFunc = type.attachedPropertiesFunction;
- d->m_attachedPropertiesType = type.attachedPropertiesMetaObject;
- if (d->m_attachedPropertiesType) {
- QHash<const QMetaObject *, int>::Iterator iter = d->m_attachedPropertyIds.find(d->m_baseMetaObject);
- if (iter == d->m_attachedPropertyIds.end())
- iter = d->m_attachedPropertyIds.insert(d->m_baseMetaObject, index);
- d->m_attachedPropertiesId = *iter;
+ d->revision = type.revision;
+ d->typeId = type.typeId;
+ d->listId = type.listId;
+ d->extraData.cd->allocationSize = type.objectSize;
+ d->extraData.cd->newFunc = type.create;
+ d->extraData.cd->noCreationReason = type.noCreationReason;
+ d->baseMetaObject = type.metaObject;
+ d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction;
+ d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject;
+ if (d->extraData.cd->attachedPropertiesType) {
+ QHash<const QMetaObject *, int>::Iterator iter = d->attachedPropertyIds.find(d->baseMetaObject);
+ if (iter == d->attachedPropertyIds.end())
+ iter = d->attachedPropertyIds.insert(d->baseMetaObject, index);
+ d->extraData.cd->attachedPropertiesId = *iter;
} else {
- d->m_attachedPropertiesId = -1;
+ d->extraData.cd->attachedPropertiesId = -1;
}
- d->m_parserStatusCast = type.parserStatusCast;
- d->m_propertyValueSourceCast = type.valueSourceCast;
- d->m_propertyValueInterceptorCast = type.valueInterceptorCast;
- d->m_extFunc = type.extensionObjectCreate;
- d->m_index = index;
- d->m_customParser = type.customParser;
+ d->extraData.cd->parserStatusCast = type.parserStatusCast;
+ d->extraData.cd->propertyValueSourceCast = type.valueSourceCast;
+ d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast;
+ d->extraData.cd->extFunc = type.extensionObjectCreate;
+ d->extraData.cd->customParser = type.customParser;
+ d->index = index;
if (type.extensionMetaObject)
- d->m_extMetaObject = type.extensionMetaObject;
+ d->extraData.cd->extMetaObject = type.extensionMetaObject;
+}
+
+QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type)
+: d(new QQmlTypePrivate(CompositeType))
+{
+ d->index = index;
+ d->elementName = elementName;
+
+ d->module = moduleFromUtf8(type.uri);
+ d->version_maj = type.versionMajor;
+ d->version_min = type.versionMinor;
+
+ d->extraData.fd->url = type.url;
}
QQmlType::~QQmlType()
{
- delete d->m_customParser;
delete d;
}
const QHashedString &QQmlType::module() const
{
- return d->m_module;
+ return d->module;
}
int QQmlType::majorVersion() const
{
- return d->m_version_maj;
+ return d->version_maj;
}
int QQmlType::minorVersion() const
{
- return d->m_version_min;
+ return d->version_min;
}
bool QQmlType::availableInVersion(int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
- return vmajor == d->m_version_maj && vminor >= d->m_version_min;
+ return vmajor == d->version_maj && vminor >= d->version_min;
}
bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
- return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min;
+ return module == d->module && vmajor == d->version_maj && vminor >= d->version_min;
}
// returns the nearest _registered_ super class
QQmlType *QQmlType::superType() const
{
- if (!d->m_haveSuperType && d->m_baseMetaObject) {
- const QMetaObject *mo = d->m_baseMetaObject->superClass();
- while (mo && !d->m_superType) {
- d->m_superType = QQmlMetaType::qmlType(mo, d->m_module, d->m_version_maj, d->m_version_min);
+ if (!d->haveSuperType && d->baseMetaObject) {
+ const QMetaObject *mo = d->baseMetaObject->superClass();
+ while (mo && !d->superType) {
+ d->superType = QQmlMetaType::qmlType(mo, d->module, d->version_maj, d->version_min);
mo = mo->superClass();
}
- d->m_haveSuperType = true;
+ d->haveSuperType = true;
}
- return d->m_superType;
+ return d->superType;
}
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
@@ -481,92 +551,95 @@ static bool isPropertyRevisioned(const QMetaObject *mo, int index)
void QQmlTypePrivate::init() const
{
- if (m_isSetup) return;
+ if (isSetup)
+ return;
QWriteLocker lock(metaTypeDataLock());
- if (m_isSetup)
+ if (isSetup)
return;
- const QMetaObject *mo = m_baseMetaObject;
+ const QMetaObject *mo = baseMetaObject;
if (!mo) {
- // singleton type without metaobject information
+ // version 0 singleton type without metaobject information
return;
}
- // Setup extended meta object
- // XXX - very inefficient
- if (m_extFunc) {
- QMetaObjectBuilder builder;
- clone(builder, m_extMetaObject, m_extMetaObject, m_extMetaObject);
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- QMetaObject *mmo = builder.toMetaObject();
- mmo->d.superdata = mo;
- QQmlProxyMetaObject::ProxyData data = { mmo, m_extFunc, 0, 0 };
- m_metaObjects << data;
+ if (regType == QQmlType::CppType) {
+ // Setup extended meta object
+ // XXX - very inefficient
+ if (extraData.cd->extFunc) {
+ QMetaObjectBuilder builder;
+ clone(builder, extraData.cd->extMetaObject, extraData.cd->extMetaObject, extraData.cd->extMetaObject);
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ QMetaObject *mmo = builder.toMetaObject();
+ mmo->d.superdata = mo;
+ QQmlProxyMetaObject::ProxyData data = { mmo, extraData.cd->extFunc, 0, 0 };
+ metaObjects << data;
+ }
}
mo = mo->d.superdata;
while(mo) {
QQmlType *t = metaTypeData()->metaObjectToType.value(mo);
if (t) {
- if (t->d->m_extFunc) {
+ if (t->d->extraData.cd->extFunc) {
QMetaObjectBuilder builder;
- clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject);
+ clone(builder, t->d->extraData.cd->extMetaObject, t->d->baseMetaObject, baseMetaObject);
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
QMetaObject *mmo = builder.toMetaObject();
- mmo->d.superdata = m_baseMetaObject;
- if (!m_metaObjects.isEmpty())
- m_metaObjects.last().metaObject->d.superdata = mmo;
- QQmlProxyMetaObject::ProxyData data = { mmo, t->d->m_extFunc, 0, 0 };
- m_metaObjects << data;
+ mmo->d.superdata = baseMetaObject;
+ if (!metaObjects.isEmpty())
+ metaObjects.last().metaObject->d.superdata = mmo;
+ QQmlProxyMetaObject::ProxyData data = { mmo, t->d->extraData.cd->extFunc, 0, 0 };
+ metaObjects << data;
}
}
mo = mo->d.superdata;
}
- for (int ii = 0; ii < m_metaObjects.count(); ++ii) {
- m_metaObjects[ii].propertyOffset =
- m_metaObjects.at(ii).metaObject->propertyOffset();
- m_metaObjects[ii].methodOffset =
- m_metaObjects.at(ii).metaObject->methodOffset();
+ for (int ii = 0; ii < metaObjects.count(); ++ii) {
+ metaObjects[ii].propertyOffset =
+ metaObjects.at(ii).metaObject->propertyOffset();
+ metaObjects[ii].methodOffset =
+ metaObjects.at(ii).metaObject->methodOffset();
}
-
+
// Check for revisioned details
{
const QMetaObject *mo = 0;
- if (m_metaObjects.isEmpty())
- mo = m_baseMetaObject;
+ if (metaObjects.isEmpty())
+ mo = baseMetaObject;
else
- mo = m_metaObjects.first().metaObject;
+ mo = metaObjects.first().metaObject;
- for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
+ for (int ii = 0; !containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
if (isPropertyRevisioned(mo, ii))
- m_containsRevisionedAttributes = true;
+ containsRevisionedAttributes = true;
}
- for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->methodCount(); ++ii) {
+ for (int ii = 0; !containsRevisionedAttributes && ii < mo->methodCount(); ++ii) {
if (mo->method(ii).revision() != 0)
- m_containsRevisionedAttributes = true;
+ containsRevisionedAttributes = true;
}
}
- m_isSetup = true;
+ isSetup = true;
lock.unlock();
}
void QQmlTypePrivate::initEnums() const
{
- if (m_isEnumSetup) return;
+ if (isEnumSetup) return;
init();
QWriteLocker lock(metaTypeDataLock());
- if (m_isEnumSetup) return;
+ if (isEnumSetup) return;
- if (m_baseMetaObject) // could be singleton type without metaobject
- insertEnums(m_baseMetaObject);
+ if (baseMetaObject) // could be singleton type without metaobject
+ insertEnums(baseMetaObject);
- m_isEnumSetup = true;
+ isEnumSetup = true;
}
void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
@@ -584,157 +657,182 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
QMetaEnum e = metaObject->enumerator(ii);
for (int jj = 0; jj < e.keyCount(); ++jj)
- m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+ enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
}
}
QByteArray QQmlType::typeName() const
{
- if (d->m_singletonInstanceInfo)
- return d->m_singletonInstanceInfo->typeName.toUtf8();
- if (d->m_baseMetaObject)
- return d->m_baseMetaObject->className();
+ if (d->regType == SingletonType)
+ return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8();
+ else if (d->baseMetaObject)
+ return d->baseMetaObject->className();
else
return QByteArray();
}
const QString &QQmlType::elementName() const
{
- return d->m_elementName;
+ return d->elementName;
}
const QString &QQmlType::qmlTypeName() const
{
- if (d->m_name.isEmpty()) {
- if (!d->m_module.isEmpty())
- d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName;
+ if (d->name.isEmpty()) {
+ if (!d->module.isEmpty())
+ d->name = static_cast<QString>(d->module) + QLatin1Char('/') + d->elementName;
else
- d->m_name = d->m_elementName;
+ d->name = d->elementName;
}
- return d->m_name;
+ return d->name;
}
QObject *QQmlType::create() const
{
+ if (!isCreatable())
+ return 0;
+
d->init();
- QObject *rv = (QObject *)operator new(d->m_allocationSize);
- d->m_newFunc(rv);
+ QObject *rv = (QObject *)operator new(d->extraData.cd->allocationSize);
+ d->extraData.cd->newFunc(rv);
- if (rv && !d->m_metaObjects.isEmpty())
- (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
+ if (rv && !d->metaObjects.isEmpty())
+ (void)new QQmlProxyMetaObject(rv, &d->metaObjects);
return rv;
}
void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) const
{
+ if (!isCreatable())
+ return;
+
d->init();
- QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory);
- d->m_newFunc(rv);
+ QObject *rv = (QObject *)operator new(d->extraData.cd->allocationSize + additionalMemory);
+ d->extraData.cd->newFunc(rv);
- if (rv && !d->m_metaObjects.isEmpty())
- (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
+ if (rv && !d->metaObjects.isEmpty())
+ (void)new QQmlProxyMetaObject(rv, &d->metaObjects);
*out = rv;
- *memory = ((char *)rv) + d->m_allocationSize;
+ *memory = ((char *)rv) + d->extraData.cd->allocationSize;
}
QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
{
- return d->m_singletonInstanceInfo;
+ if (d->regType != SingletonType)
+ return 0;
+ return d->extraData.sd->singletonInstanceInfo;
}
QQmlCustomParser *QQmlType::customParser() const
{
- return d->m_customParser;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->customParser;
}
QQmlType::CreateFunc QQmlType::createFunction() const
{
- return d->m_newFunc;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->newFunc;
}
QString QQmlType::noCreationReason() const
{
- return d->m_noCreationReason;
+ if (d->regType != CppType)
+ return QString();
+ return d->extraData.cd->noCreationReason;
}
int QQmlType::createSize() const
{
- return d->m_allocationSize;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->allocationSize;
}
bool QQmlType::isCreatable() const
{
- return d->m_newFunc != 0;
+ return d->regType == CppType && d->extraData.cd->newFunc;
}
bool QQmlType::isExtendedType() const
{
d->init();
- return !d->m_metaObjects.isEmpty();
+ return !d->metaObjects.isEmpty();
}
bool QQmlType::isSingleton() const
{
- return d->m_singletonInstanceInfo != 0;
+ return d->regType == SingletonType;
}
bool QQmlType::isInterface() const
{
- return d->m_isInterface;
+ return d->regType == InterfaceType;
+}
+
+bool QQmlType::isComposite() const
+{
+ return d->regType == CompositeType;
}
int QQmlType::typeId() const
{
- return d->m_typeId;
+ return d->typeId;
}
int QQmlType::qListTypeId() const
{
- return d->m_listId;
+ return d->listId;
}
const QMetaObject *QQmlType::metaObject() const
{
d->init();
- if (d->m_metaObjects.isEmpty())
- return d->m_baseMetaObject;
+ if (d->metaObjects.isEmpty())
+ return d->baseMetaObject;
else
- return d->m_metaObjects.first().metaObject;
+ return d->metaObjects.first().metaObject;
}
const QMetaObject *QQmlType::baseMetaObject() const
{
- return d->m_baseMetaObject;
+ return d->baseMetaObject;
}
bool QQmlType::containsRevisionedAttributes() const
{
d->init();
- return d->m_containsRevisionedAttributes;
+ return d->containsRevisionedAttributes;
}
int QQmlType::metaObjectRevision() const
{
- return d->m_revision;
+ return d->revision;
}
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction() const
{
- return d->m_attachedPropertiesFunc;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->attachedPropertiesFunc;
}
const QMetaObject *QQmlType::attachedPropertiesType() const
{
- return d->m_attachedPropertiesType;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->attachedPropertiesType;
}
/*
@@ -744,32 +842,49 @@ Qt 4.7 and QtQuick 1.0).
*/
int QQmlType::attachedPropertiesId() const
{
- return d->m_attachedPropertiesId;
+ if (d->regType != CppType)
+ return 0;
+ return d->extraData.cd->attachedPropertiesId;
}
int QQmlType::parserStatusCast() const
{
- return d->m_parserStatusCast;
+ if (d->regType != CppType)
+ return -1;
+ return d->extraData.cd->parserStatusCast;
}
int QQmlType::propertyValueSourceCast() const
{
- return d->m_propertyValueSourceCast;
+ if (d->regType != CppType)
+ return -1;
+ return d->extraData.cd->propertyValueSourceCast;
}
int QQmlType::propertyValueInterceptorCast() const
{
- return d->m_propertyValueInterceptorCast;
+ if (d->regType != CppType)
+ return -1;
+ return d->extraData.cd->propertyValueInterceptorCast;
}
const char *QQmlType::interfaceIId() const
{
- return d->m_iid;
+ if (d->regType != InterfaceType)
+ return 0;
+ return d->iid;
}
int QQmlType::index() const
{
- return d->m_index;
+ return d->index;
+}
+
+QUrl QQmlType::sourceUrl() const
+{
+ if (d->regType != CompositeType)
+ return QUrl();
+ return d->extraData.fd->url;
}
int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
@@ -779,7 +894,7 @@ int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
d->initEnums();
- int *rv = d->m_enums.value(name);
+ int *rv = d->enums.value(name);
if (rv)
return *rv;
@@ -794,7 +909,7 @@ int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const
d->initEnums();
- int *rv = d->m_enums.value(name);
+ int *rv = d->enums.value(name);
if (rv)
return *rv;
@@ -809,7 +924,7 @@ int QQmlType::enumValue(const QHashedV8String &name, bool *ok) const
d->initEnums();
- int *rv = d->m_enums.value(name);
+ int *rv = d->enums.value(name);
if (rv)
return *rv;
@@ -998,6 +1113,8 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
typeStr = QStringLiteral("element");
else if (typeType == QQmlType::SingletonType)
typeStr = QStringLiteral("singleton type");
+ else
+ typeStr = QStringLiteral("type");
return typeStr;
}
@@ -1007,7 +1124,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (!typeName.isEmpty()) {
int typeNameLen = typeName.length();
for (int ii = 0; ii < typeNameLen; ++ii) {
- if (!typeName.at(ii).isLetterOrNumber()) {
+ if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == '_')) {
QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\""));
data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName));
return false;
@@ -1040,46 +1157,59 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
return true;
}
-int registerType(const QQmlPrivate::RegisterType &type)
+// NOTE: caller must hold a QWriteLocker on "data"
+void addTypeToData(QQmlType* type, QQmlMetaTypeData *data)
{
- QWriteLocker lock(metaTypeDataLock());
- QQmlMetaTypeData *data = metaTypeData();
- QString elementName = QString::fromUtf8(type.elementName);
- if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName))
- return -1;
-
- int index = data->types.count();
-
- QQmlType *dtype = new QQmlType(index, elementName, type);
-
- data->types.append(dtype);
- data->idToType.insert(dtype->typeId(), dtype);
- if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
+ if (!type->elementName().isEmpty())
+ data->nameToType.insertMulti(type->elementName(), type);
- if (!dtype->elementName().isEmpty())
- data->nameToType.insertMulti(dtype->elementName(), dtype);
+ if (type->baseMetaObject())
+ data->metaObjectToType.insertMulti(type->baseMetaObject(), type);
- data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
+ if (type->typeId()) {
+ data->idToType.insert(type->typeId(), type);
+ if (data->objects.size() <= type->typeId())
+ data->objects.resize(type->typeId() + 16);
+ data->objects.setBit(type->typeId(), true);
+ }
- if (data->objects.size() <= type.typeId)
- data->objects.resize(type.typeId + 16);
- if (data->lists.size() <= type.listId)
- data->lists.resize(type.listId + 16);
- data->objects.setBit(type.typeId, true);
- if (type.listId) data->lists.setBit(type.listId, true);
+ if (type->qListTypeId()) {
+ if (data->lists.size() <= type->qListTypeId())
+ data->lists.resize(type->qListTypeId() + 16);
+ data->lists.setBit(type->qListTypeId(), true);
+ data->idToType.insert(type->qListTypeId(), type);
+ }
- if (!dtype->module().isEmpty()) {
- const QHashedString &mod = dtype->module();
+ if (!type->module().isEmpty()) {
+ const QHashedString &mod = type->module();
- QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
+ QQmlMetaTypeData::VersionedUri versionedUri(mod, type->majorVersion());
QQmlTypeModule *module = data->uriToModule.value(versionedUri);
if (!module) {
module = new QQmlTypeModule;
module->d->uri = versionedUri;
data->uriToModule.insert(versionedUri, module);
}
- module->d->add(dtype);
+ module->d->add(type);
}
+}
+
+int registerType(const QQmlPrivate::RegisterType &type)
+{
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ QString elementName = QString::fromUtf8(type.elementName);
+ if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName))
+ return -1;
+
+ int index = data->types.count();
+
+ QQmlType *dtype = new QQmlType(index, elementName, type);
+
+ data->types.append(dtype);
+ addTypeToData(dtype, data);
+ if (!type.typeId)
+ data->idToType.insert(dtype->typeId(), dtype);
return index;
}
@@ -1097,32 +1227,31 @@ int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
QQmlType *dtype = new QQmlType(index, typeName, type);
data->types.append(dtype);
- data->idToType.insert(dtype->typeId(), dtype);
+ addTypeToData(dtype, data);
- if (!dtype->elementName().isEmpty())
- data->nameToType.insertMulti(dtype->elementName(), dtype);
+ return index;
+}
- if (dtype->baseMetaObject())
- data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
+int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
+{
+ // Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type.
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ QString typeName = QString::fromUtf8(type.typeName);
+ bool fileImport = false;
+ if (*(type.uri) == '\0')
+ fileImport = true;
+ if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName))
+ return -1;
- if (type.typeId) {
- if (data->objects.size() <= type.typeId)
- data->objects.resize(type.typeId + 16);
- data->objects.setBit(type.typeId, true);
- }
+ int index = data->types.count();
- if (!dtype->module().isEmpty()) {
- const QHashedString &mod = dtype->module();
+ QQmlType *dtype = new QQmlType(index, typeName, type);
+ data->types.append(dtype);
+ addTypeToData(dtype, data);
- QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
- QQmlTypeModule *module = data->uriToModule.value(versionedUri);
- if (!module) {
- module = new QQmlTypeModule;
- module->d->uri = versionedUri;
- data->uriToModule.insert(versionedUri, module);
- }
- module->d->add(dtype);
- }
+ if (fileImport)
+ data->urlToType.insertMulti(type.url, dtype);
return index;
}
@@ -1142,6 +1271,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
} else if (type == SingletonRegistration) {
return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
+ } else if (type == CompositeRegistration) {
+ return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data));
}
return -1;
}
@@ -1455,10 +1586,10 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.find(name);
+ QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
while (it != data->nameToType.end() && it.key() == name) {
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
- if (version_major < 0 || (*it)->availableInVersion(module, version_major,version_minor))
+ if (version_major < 0 || module.isEmpty() || (*it)->availableInVersion(module, version_major,version_minor))
return (*it);
++it;
}
@@ -1489,10 +1620,10 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.find(metaObject);
+ QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
while (it != data->metaObjectToType.end() && it.key() == metaObject) {
QQmlType *t = *it;
- if (version_major < 0 || t->availableInVersion(module, version_major,version_minor))
+ if (version_major < 0 || module.isEmpty() || t->availableInVersion(module, version_major,version_minor))
return t;
++it;
}
@@ -1517,6 +1648,39 @@ QQmlType *QQmlMetaType::qmlType(int userType)
}
/*!
+ Returns the type (if any) that corresponds to the given \a url in the set of
+ composite types added through file imports.
+
+ Returns null if no such type is registered.
+*/
+QQmlType *QQmlMetaType::qmlType(const QUrl &url)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ QQmlType *type = data->urlToType.value(url);
+ if (type && type->sourceUrl() == url)
+ return type;
+ else
+ return 0;
+}
+
+/*!
+ Returns the type (if any) with the given \a index in the global type store.
+ This is for use when you just got the index back from a qmlRegister function.
+ Returns null if the index is out of bounds.
+*/
+QQmlType *QQmlMetaType::qmlTypeFromIndex(int idx)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ if (idx < 0 || idx >= data->types.count())
+ return 0;
+ return data->types[idx];
+}
+
+/*!
Returns the list of registered QML type names.
*/
QList<QString> QQmlMetaType::qmlTypeNames()
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 474eac184c..497afffb5d 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -84,6 +84,8 @@ public:
static QQmlType *qmlType(const QMetaObject *);
static QQmlType *qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
static QQmlType *qmlType(int);
+ static QQmlType *qmlType(const QUrl &url);
+ static QQmlType *qmlTypeFromIndex(int);
static QMetaProperty defaultProperty(const QMetaObject *);
static QMetaProperty defaultProperty(QObject *);
@@ -164,6 +166,7 @@ public:
bool isSingleton() const;
bool isInterface() const;
+ bool isComposite() const;
int typeId() const;
int qListTypeId() const;
@@ -206,6 +209,7 @@ public:
QHash<QQmlEngine *, QObject *> qobjectApis;
};
SingletonInstanceInfo *singletonInstanceInfo() const;
+ QUrl sourceUrl() const;
int enumValue(const QHashedStringRef &, bool *ok) const;
int enumValue(const QHashedCStringRef &, bool *ok) const;
@@ -217,17 +221,20 @@ private:
enum RegistrationType {
CppType = 0,
- SingletonType = 1
- // In the future, we should register all types via QQmlType, including Composite types.
+ SingletonType = 1,
+ InterfaceType = 2,
+ CompositeType = 3
};
friend QString registrationTypeString(RegistrationType);
friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &);
friend int registerType(const QQmlPrivate::RegisterType &);
friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
friend int registerInterface(const QQmlPrivate::RegisterInterface &);
+ friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
QQmlType(int, const QQmlPrivate::RegisterInterface &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterType &);
+ QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &);
~QQmlType();
QQmlTypePrivate *d;
@@ -249,8 +256,8 @@ public:
QList<QQmlType*> singletonTypes(int) const;
private:
- friend int registerType(const QQmlPrivate::RegisterType &);
- friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
+ //Used by register functions and creates the QQmlTypeModule for them
+ friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data);
friend struct QQmlMetaTypeData;
QQmlTypeModule();
diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h
index 6a79118c50..4c12e00c09 100644
--- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h
+++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -61,6 +59,4 @@ public:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLNETWORKACCESSMANAGERFACTORY_H
diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h
index fd442e4ad9..a8c5744078 100644
--- a/src/qml/qml/qqmlopenmetaobject_p.h
+++ b/src/qml/qml/qqmlopenmetaobject_p.h
@@ -50,8 +50,6 @@
#include <private/qtqmlglobal_p.h>
#include <private/qobject_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -130,6 +128,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLOPENMETAOBJECT_H
diff --git a/src/qml/qml/qqmlparserstatus.h b/src/qml/qml/qqmlparserstatus.h
index 253fe64022..d3447e7752 100644
--- a/src/qml/qml/qqmlparserstatus.h
+++ b/src/qml/qml/qqmlparserstatus.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -72,6 +70,4 @@ Q_DECLARE_INTERFACE(QQmlParserStatus, QQmlParserStatus_iid)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPARSERSTATUS_H
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
new file mode 100644
index 0000000000..de48f60f56
--- /dev/null
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlplatform_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*
+ This object and its properties are documented as part of the Qt object,
+ in qqmlengine.cpp
+*/
+
+QQmlPlatform::QQmlPlatform(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QQmlPlatform::~QQmlPlatform()
+{
+}
+
+QString QQmlPlatform::os()
+{
+#if defined(Q_OS_ANDROID)
+ return QLatin1String("android");
+#elif defined(Q_OS_BLACKBERRY)
+ return QLatin1String("blackberry");
+#elif defined(Q_OS_IOS)
+ return QLatin1String("ios");
+#elif defined(Q_OS_MAC)
+ return QLatin1String("mac");
+#elif defined(Q_OS_WINCE)
+ return QLatin1String("wince");
+#elif defined(Q_OS_WIN)
+ return QLatin1String("windows");
+#elif defined(Q_OS_LINUX)
+ return QLatin1String("linux");
+#elif defined(Q_OS_UNIX)
+ return QLatin1String("unix");
+#else
+ return QLatin1String("unknown");
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlplatform_p.h b/src/qml/qml/qqmlplatform_p.h
new file mode 100644
index 0000000000..7a212d5bdf
--- /dev/null
+++ b/src/qml/qml/qqmlplatform_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPLATFORM_P_H
+#define QQMLPLATFORM_P_H
+
+#include <QtCore/QObject>
+#include <qqml.h>
+#include <private/qtqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QML_PRIVATE_EXPORT QQmlPlatform : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString os READ os CONSTANT)
+
+public:
+ explicit QQmlPlatform(QObject *parent = 0);
+ virtual ~QQmlPlatform();
+
+ static QString os();
+
+private:
+ Q_DISABLE_COPY(QQmlPlatform)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQmlPlatform)
+
+#endif // QQMLPLATFORM_P_H
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index e548f860be..570435ae81 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -57,8 +57,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
@@ -253,11 +252,20 @@ namespace QQmlPrivate
// If this is extended ensure "version" is bumped!!!
};
+ struct RegisterCompositeType {
+ const QUrl &url;
+ const char *uri;
+ int versionMajor;
+ int versionMinor;
+ const char *typeName;
+ };
+
enum RegistrationType {
- TypeRegistration = 0,
+ TypeRegistration = 0,
InterfaceRegistration = 1,
AutoParentRegistration = 2,
- SingletonRegistration = 3
+ SingletonRegistration = 3,
+ CompositeRegistration = 4
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
@@ -265,6 +273,4 @@ namespace QQmlPrivate
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPRIVATE_H
diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h
index 0079fed09a..c3322c0048 100644
--- a/src/qml/qml/qqmlproperty.h
+++ b/src/qml/qml/qqmlproperty.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qmetaobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -140,6 +138,4 @@ Q_DECLARE_TYPEINFO(QQmlProperty, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPROPERTY_H
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index e1aa310e3e..b1ffc9a2d5 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -1055,7 +1055,7 @@ QStringList QQmlPropertyCache::propertyNames() const
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
- { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
+ { return &staticQtMetaObject; }
};
static int EnumType(const QMetaObject *metaobj, const QByteArray &str, int type)
diff --git a/src/qml/qml/qqmlpropertyvaluesource.h b/src/qml/qml/qqmlpropertyvaluesource.h
index 38f06d0b02..ccf40eb6f8 100644
--- a/src/qml/qml/qqmlpropertyvaluesource.h
+++ b/src/qml/qml/qqmlpropertyvaluesource.h
@@ -45,8 +45,6 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -65,6 +63,4 @@ Q_DECLARE_INTERFACE(QQmlPropertyValueSource, QQmlPropertyValueSource_iid)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPROPERTYVALUESOURCE_H
diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h
index 9f9c346d9f..c7b266835d 100644
--- a/src/qml/qml/qqmlproxymetaobject_p.h
+++ b/src/qml/qml/qqmlproxymetaobject_p.h
@@ -61,8 +61,6 @@
#include <private/qobject_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -93,7 +91,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QQMLPROXYMETAOBJECT_P_H
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index 2f8750ee0f..613ff24f20 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -651,7 +651,7 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const
QString s;
for (AST::UiQualifiedId *it = node; it; it = it->next) {
- s.append(it->name.toString());
+ s.append(it->name);
if (it->next)
s.append(QLatin1Char('.'));
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
index 20cec3703d..54e7a67b65 100644
--- a/src/qml/qml/qqmlscript_p.h
+++ b/src/qml/qml/qqmlscript_p.h
@@ -62,8 +62,6 @@
#include <QtCore/QList>
#include <QtCore/QUrl>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -520,6 +518,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QQmlScript::Variant)
-QT_END_HEADER
-
#endif // QQMLSCRIPT_P_H
diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h
index fc732877ab..5421ef95fc 100644
--- a/src/qml/qml/qqmlscriptstring.h
+++ b/src/qml/qml/qqmlscriptstring.h
@@ -47,8 +47,6 @@
#include <QtCore/qshareddata.h>
#include <QtCore/qmetatype.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -86,7 +84,5 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QQmlScriptString)
-QT_END_HEADER
-
#endif // QQMLSCRIPTSTRING_H
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index aa7a2d95c7..e800eb815d 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -124,6 +124,7 @@ public:
public slots:
void finished();
void downloadProgress(qint64, qint64);
+ void manualFinished(QNetworkReply*);
private:
QQmlDataLoader *l;
@@ -183,6 +184,14 @@ void QQmlDataLoaderNetworkReplyProxy::downloadProgress(qint64 bytesReceived, qin
l->networkReplyProgress(reply, bytesReceived, bytesTotal);
}
+// This function is for when you want to shortcut the signals and call directly
+void QQmlDataLoaderNetworkReplyProxy::manualFinished(QNetworkReply *reply)
+{
+ qint64 replySize = reply->size();
+ l->networkReplyProgress(reply, replySize, replySize);
+ l->networkReplyFinished(reply);
+}
+
/*!
\class QQmlDataBlob
@@ -1008,17 +1017,23 @@ void QQmlDataLoader::loadThread(QQmlDataBlob *blob)
} else {
QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(blob->m_url));
- QObject *nrp = m_thread->networkReplyProxy();
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- nrp, SLOT(downloadProgress(qint64,qint64)));
- QObject::connect(reply, SIGNAL(finished()),
- nrp, SLOT(finished()));
+ QQmlDataLoaderNetworkReplyProxy *nrp = m_thread->networkReplyProxy();
+ blob->addref();
m_networkReplies.insert(reply, blob);
+
+ if (reply->isFinished()) {
+ nrp->manualFinished(reply);
+ } else {
+ QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
+ nrp, SLOT(downloadProgress(qint64,qint64)));
+ QObject::connect(reply, SIGNAL(finished()),
+ nrp, SLOT(finished()));
+ }
+
#ifdef DATABLOB_DEBUG
qWarning("QQmlDataBlob: requested %s", qPrintable(blob->url().toString()));
#endif
- blob->addref();
}
}
@@ -1887,7 +1902,7 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback()
QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader::Options options,
QQmlTypeLoader *manager)
: QQmlTypeLoader::Blob(url, QmlFile, manager), m_options(options),
- m_typesResolved(false), m_compiledData(0), m_implicitImport(0)
+ m_typesResolved(false), m_compiledData(0), m_implicitImport(0), m_implicitImportLoaded(false)
{
}
@@ -1993,23 +2008,14 @@ void QQmlTypeData::completed()
}
}
-void QQmlTypeData::dataReceived(const Data &data)
+bool QQmlTypeData::loadImplicitImport()
{
- QString code = QString::fromUtf8(data.data(), data.size());
- QByteArray preparseData;
-
- if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse"));
-
- if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) {
- setError(scriptParser.errors());
- return;
- }
+ m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error)
m_imports.setBaseUrl(finalUrl(), finalUrlString());
QQmlImportDatabase *importDatabase = typeLoader()->importDatabase();
-
- // For local urls, add an implicit import "." as first (most overridden) lookup.
+ // For local urls, add an implicit import "." as most overridden lookup.
// This will also trigger the loading of the qmldir and the import of any native
// types from available plugins.
QList<QQmlError> implicitImportErrors;
@@ -2017,20 +2023,41 @@ void QQmlTypeData::dataReceived(const Data &data)
if (!implicitImportErrors.isEmpty()) {
setError(implicitImportErrors);
+ return false;
+ }
+
+ return true;
+}
+
+void QQmlTypeData::dataReceived(const Data &data)
+{
+ QString code = QString::fromUtf8(data.data(), data.size());
+ QByteArray preparseData;
+
+ if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse"));
+
+ if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) {
+ setError(scriptParser.errors());
return;
}
- QList<QQmlError> errors;
+ m_imports.setBaseUrl(finalUrl(), finalUrlString());
+ // For remote URLs, we don't delay the loading of the implicit import
+ // because the loading probably requires an asynchronous fetch of the
+ // qmldir (so we can't load it just in time).
if (!finalUrl().scheme().isEmpty()) {
QUrl qmldirUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir")));
if (!QQmlImports::isLocal(qmldirUrl)) {
+ if (!loadImplicitImport())
+ return;
// This qmldir is for the implicit import
m_implicitImport = new QQmlScript::Import;
m_implicitImport->uri = QLatin1String(".");
m_implicitImport->qualifier = QString();
m_implicitImport->majorVersion = -1;
m_implicitImport->minorVersion = -1;
+ QList<QQmlError> errors;
if (!fetchQmldir(qmldirUrl, m_implicitImport, 1, &errors)) {
setError(errors);
@@ -2039,6 +2066,8 @@ void QQmlTypeData::dataReceived(const Data &data)
}
}
+ QList<QQmlError> errors;
+
foreach (const QQmlScript::Import &import, scriptParser.imports()) {
if (!addImport(import, &errors)) {
Q_ASSERT(errors.size());
@@ -2135,13 +2164,26 @@ void QQmlTypeData::resolveTypes()
TypeReference ref;
QString url;
- int majorVersion;
- int minorVersion;
+ int majorVersion = -1;
+ int minorVersion = -1;
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
- if (!m_imports.resolveType(parserRef->name, &ref.type, &url, &majorVersion, &minorVersion,
- &typeNamespace, &errors) || typeNamespace) {
+ bool typeFound = m_imports.resolveType(parserRef->name, &ref.type,
+ &majorVersion, &minorVersion, &typeNamespace, &errors);
+ if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
+ // Lazy loading of implicit import
+ if (loadImplicitImport()) {
+ // Try again to find the type
+ errors.clear();
+ typeFound = m_imports.resolveType(parserRef->name, &ref.type,
+ &majorVersion, &minorVersion, &typeNamespace, &errors);
+ } else {
+ return; //loadImplicitImport() hit an error, and called setError already
+ }
+ }
+
+ if (!typeFound || typeNamespace) {
// Known to not be a type:
// - known to be a namespace (Namespace {})
// - type with unknown namespace (UnknownNamespace.SomeType {})
@@ -2169,13 +2211,12 @@ void QQmlTypeData::resolveTypes()
return;
}
- if (ref.type) {
- ref.majorVersion = majorVersion;
- ref.minorVersion = minorVersion;
- } else {
- ref.typeData = typeLoader()->getType(QUrl(url));
+ if (ref.type->isComposite()) {
+ ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
addDependency(ref.typeData);
}
+ ref.majorVersion = majorVersion;
+ ref.minorVersion = minorVersion;
Q_ASSERT(parserRef->firstUse);
ref.location = parserRef->firstUse->location.start;
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index b4ecfb77d1..68b8f33f88 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -465,6 +465,8 @@ private:
QList<TypeDataCallback *> m_callbacks;
QQmlScript::Import *m_implicitImport;
+ bool m_implicitImportLoaded;
+ bool loadImplicitImport();
};
// QQmlScriptData instances are created, uninitialized, by the loader in the
diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h
index f2e829e2ac..2529db3e5f 100644
--- a/src/qml/qml/qqmltypenotavailable_p.h
+++ b/src/qml/qml/qqmltypenotavailable_p.h
@@ -44,8 +44,6 @@
#include <qqml.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -59,6 +57,4 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlTypeNotAvailable)
-QT_END_HEADER
-
#endif // QQMLTYPENOTAVAILABLE_H
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 4abc6f46fa..8198eeca66 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -558,6 +558,11 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QObject *o = 0;
void *memory = 0;
type.type->create(&o, &memory, sizeof(QQmlData));
+
+ if (!o)
+ VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.type->elementName()),
+ instr.line);
+
QQmlData *ddata = new (memory) QQmlData;
ddata->ownMemory = false;
QObjectPrivate::get(o)->declarativeData = ddata;
@@ -572,10 +577,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
ddata->propertyCache->addref();
}
- if (!o)
- VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.type->elementName()),
- instr.line);
-
if (states.count() == 1) {
// Keep a reference to the compiled data we rely on
ddata->compiledData = states[0].compiledData;
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 9bd769f157..80f5deccdb 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -496,25 +496,25 @@ v8::Handle<v8::Object> Node::prototype(QV8Engine *engine)
if (d->nodePrototype.IsEmpty()) {
d->nodePrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->nodePrototype->SetAccessor(v8::String::New("nodeName"), nodeName,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("nodeValue"), nodeValue,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("nodeType"), nodeType,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("parentNode"), parentNode,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("childNodes"), childNodes,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("firstChild"), firstChild,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("lastChild"), lastChild,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("previousSibling"), previousSibling,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("nextSibling"), nextSibling,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->nodePrototype->SetAccessor(v8::String::New("attributes"), attributes,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->nodePrototype);
}
return d->nodePrototype;
@@ -564,7 +564,7 @@ v8::Handle<v8::Object> Element::prototype(QV8Engine *engine)
d->elementPrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->elementPrototype->SetPrototype(Node::prototype(engine));
d->elementPrototype->SetAccessor(v8::String::New("tagName"), nodeName,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->elementPrototype);
}
return d->elementPrototype;
@@ -577,11 +577,11 @@ v8::Handle<v8::Object> Attr::prototype(QV8Engine *engine)
d->attrPrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->attrPrototype->SetPrototype(Node::prototype(engine));
d->attrPrototype->SetAccessor(v8::String::New("name"), name,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->attrPrototype->SetAccessor(v8::String::New("value"), value,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->attrPrototype->SetAccessor(v8::String::New("ownerElement"), ownerElement,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->attrPrototype);
}
return d->attrPrototype;
@@ -630,9 +630,9 @@ v8::Handle<v8::Object> CharacterData::prototype(QV8Engine *engine)
d->characterDataPrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->characterDataPrototype->SetPrototype(Node::prototype(engine));
d->characterDataPrototype->SetAccessor(v8::String::New("data"), nodeValue,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->characterDataPrototype->SetAccessor(v8::String::New("length"), length,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->characterDataPrototype);
}
return d->characterDataPrototype;
@@ -663,9 +663,9 @@ v8::Handle<v8::Object> Text::prototype(QV8Engine *engine)
d->textPrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->textPrototype->SetPrototype(CharacterData::prototype(engine));
d->textPrototype->SetAccessor(v8::String::New("isElementContentWhitespace"), isElementContentWhitespace,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->textPrototype->SetAccessor(v8::String::New("wholeText"), wholeText,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->textPrototype);
}
return d->textPrototype;
@@ -689,13 +689,13 @@ v8::Handle<v8::Object> Document::prototype(QV8Engine *engine)
d->documentPrototype = qPersistentNew<v8::Object>(v8::Object::New());
d->documentPrototype->SetPrototype(Node::prototype(engine));
d->documentPrototype->SetAccessor(v8::String::New("xmlVersion"), xmlVersion,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->documentPrototype->SetAccessor(v8::String::New("xmlEncoding"), xmlEncoding,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->documentPrototype->SetAccessor(v8::String::New("xmlStandalone"), xmlStandalone,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
d->documentPrototype->SetAccessor(v8::String::New("documentElement"), documentElement,
- 0, v8::External::Wrap(engine));
+ 0, v8::External::New(engine));
engine->freezeObject(d->documentPrototype);
}
return d->documentPrototype;
@@ -854,9 +854,9 @@ v8::Handle<v8::Object> NamedNodeMap::prototype(QV8Engine *engine)
QQmlXMLHttpRequestData *d = xhrdata(engine);
if (d->namedNodeMapPrototype.IsEmpty()) {
v8::Local<v8::ObjectTemplate> ot = v8::ObjectTemplate::New();
- ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::Wrap(engine));
- ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::Wrap(engine));
- ot->SetFallbackPropertyHandler(named, 0, 0, 0, 0, v8::External::Wrap(engine));
+ ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::New(engine));
+ ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::New(engine));
+ ot->SetFallbackPropertyHandler(named, 0, 0, 0, 0, v8::External::New(engine));
d->namedNodeMapPrototype = qPersistentNew<v8::Object>(ot->NewInstance());
engine->freezeObject(d->namedNodeMapPrototype);
}
@@ -903,8 +903,8 @@ v8::Handle<v8::Object> NodeList::prototype(QV8Engine *engine)
QQmlXMLHttpRequestData *d = xhrdata(engine);
if (d->nodeListPrototype.IsEmpty()) {
v8::Local<v8::ObjectTemplate> ot = v8::ObjectTemplate::New();
- ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::Wrap(engine));
- ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::Wrap(engine));
+ ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::New(engine));
+ ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::New(engine));
d->nodeListPrototype = qPersistentNew<v8::Object>(ot->NewInstance());
engine->freezeObject(d->nodeListPrototype);
}
@@ -1790,7 +1790,7 @@ void *qt_add_qmlxmlhttprequest(QV8Engine *engine)
// XMLHttpRequest
v8::Local<v8::FunctionTemplate> xmlhttprequest = v8::FunctionTemplate::New(qmlxmlhttprequest_new,
- v8::External::Wrap(engine));
+ v8::External::New(engine));
xmlhttprequest->InstanceTemplate()->SetHasExternalResource(true);
// Methods
diff --git a/src/qml/qml/rewriter/textwriter_p.h b/src/qml/qml/rewriter/textwriter_p.h
index 5c22a62a02..fdfd955d9f 100644
--- a/src/qml/qml/rewriter/textwriter_p.h
+++ b/src/qml/qml/rewriter/textwriter_p.h
@@ -47,7 +47,6 @@
#include <QtCore/QString>
#include <QtCore/QList>
-QT_BEGIN_HEADER
QT_QML_BEGIN_NAMESPACE
namespace QQmlJS {
@@ -92,6 +91,4 @@ public:
} // end of namespace QQmlJS
QT_QML_END_NAMESPACE
-QT_END_HEADER
-
#endif // TEXTWRITER_H
diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h
index 6ea548c642..adb05ba1f4 100644
--- a/src/qml/qml/v4/qv4bindings_p.h
+++ b/src/qml/qml/v4/qv4bindings_p.h
@@ -59,8 +59,6 @@
#include "private/qv4instruction_p.h"
#include "private/qpointervaluepair_p.h"
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
struct QV4Program;
@@ -170,7 +168,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4BINDINGS_P_H
diff --git a/src/qml/qml/v4/qv4compiler_p.h b/src/qml/qml/v4/qv4compiler_p.h
index c5175b2bbd..5b6cee2a55 100644
--- a/src/qml/qml/v4/qv4compiler_p.h
+++ b/src/qml/qml/v4/qv4compiler_p.h
@@ -61,8 +61,6 @@
Q_DECLARE_METATYPE(v8::Handle<v8::Value>)
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QQmlTypeNameCache;
@@ -103,7 +101,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4COMPILER_P_H
diff --git a/src/qml/qml/v4/qv4compiler_p_p.h b/src/qml/qml/v4/qv4compiler_p_p.h
index c2d6b8c362..58ec521a97 100644
--- a/src/qml/qml/v4/qv4compiler_p_p.h
+++ b/src/qml/qml/v4/qv4compiler_p_p.h
@@ -59,8 +59,6 @@
#include <private/qqmlimport_p.h>
#include <private/qqmlengine_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
template <typename _Key, typename _Value>
@@ -243,7 +241,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4COMPILER_P_P_H
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index be3b4bef1e..9797abf69d 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -60,8 +60,6 @@
#include <private/qqmlpropertycache_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
#define FOR_EACH_V4_INSTR(F) \
@@ -481,7 +479,5 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4INSTRUCTION_P_H
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 08cfe43091..701f76d9e4 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -69,8 +69,6 @@
# undef CONST
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QTextStream;
@@ -614,6 +612,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4IR_P_H
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 50d799c8d9..4aa257d54a 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -358,7 +358,19 @@ bool QV4IRBuilder::visit(AST::StatementSourceElement *)
}
// object literals
-bool QV4IRBuilder::visit(AST::PropertyNameAndValueList *)
+bool QV4IRBuilder::visit(AST::PropertyAssignmentList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QV4IRBuilder::visit(AST::PropertyNameAndValue *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QV4IRBuilder::visit(AST::PropertyGetterSetter *)
{
Q_ASSERT(!"unreachable");
return false;
diff --git a/src/qml/qml/v4/qv4irbuilder_p.h b/src/qml/qml/v4/qv4irbuilder_p.h
index 3aee38b269..86baae463d 100644
--- a/src/qml/qml/v4/qv4irbuilder_p.h
+++ b/src/qml/qml/v4/qv4irbuilder_p.h
@@ -46,8 +46,6 @@
#include "qv4ir_p.h"
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QV4IRBuilder : public QQmlJS::AST::Visitor
@@ -139,7 +137,9 @@ protected:
virtual bool visit(QQmlJS::AST::StatementSourceElement *ast);
// object literals
- virtual bool visit(QQmlJS::AST::PropertyNameAndValueList *ast);
+ virtual bool visit(QQmlJS::AST::PropertyAssignmentList *ast);
+ virtual bool visit(QQmlJS::AST::PropertyNameAndValue *ast);
+ virtual bool visit(QQmlJS::AST::PropertyGetterSetter *ast);
virtual bool visit(QQmlJS::AST::IdentifierPropertyName *ast);
virtual bool visit(QQmlJS::AST::StringLiteralPropertyName *ast);
virtual bool visit(QQmlJS::AST::NumericLiteralPropertyName *ast);
@@ -236,6 +236,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4IRBUILDER_P_H
diff --git a/src/qml/qml/v4/qv4program_p.h b/src/qml/qml/v4/qv4program_p.h
index d04ada487e..fb23e863af 100644
--- a/src/qml/qml/v4/qv4program_p.h
+++ b/src/qml/qml/v4/qv4program_p.h
@@ -60,8 +60,6 @@
# pragma warning( disable : 4200 )
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
struct QV4Program {
@@ -126,7 +124,5 @@ QV4Program::BindingReferenceList *QV4Program::signalTable(int signalIndex) const
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV4PROGRAM_P_H
diff --git a/src/qml/qml/v8/qjsengine.h b/src/qml/qml/v8/qjsengine.h
index 23ee289d6c..0a575f84e9 100644
--- a/src/qml/qml/v8/qjsengine.h
+++ b/src/qml/qml/v8/qjsengine.h
@@ -49,8 +49,6 @@
#include <QtCore/qobject.h>
#include <QtQml/qjsvalue.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -137,6 +135,4 @@ inline QVariant qjsvalue_cast<QVariant>(const QJSValue &value)
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QJSENGINE_H
diff --git a/src/qml/qml/v8/qjsvalue.h b/src/qml/qml/v8/qjsvalue.h
index 0a57e3533e..efd52ce880 100644
--- a/src/qml/qml/v8/qjsvalue.h
+++ b/src/qml/qml/v8/qjsvalue.h
@@ -48,8 +48,6 @@
#include <QtCore/qsharedpointer.h>
#include <QtCore/qshareddata.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -157,6 +155,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QJSValue)
-QT_END_HEADER
-
#endif
diff --git a/src/qml/qml/v8/qjsvalueiterator.h b/src/qml/qml/v8/qjsvalueiterator.h
index e9a67738ab..b4f90a44b7 100644
--- a/src/qml/qml/v8/qjsvalueiterator.h
+++ b/src/qml/qml/v8/qjsvalueiterator.h
@@ -46,8 +46,6 @@
#include <QtQml/qjsvalue.h>
#include <QtCore/qscopedpointer.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -77,6 +75,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSCRIPTVALUEITERATOR_H
diff --git a/src/qml/qml/v8/qv8bindings_p.h b/src/qml/qml/v8/qv8bindings_p.h
index f3e62faa3b..98b367ac72 100644
--- a/src/qml/qml/v8/qv8bindings_p.h
+++ b/src/qml/qml/v8/qv8bindings_p.h
@@ -61,8 +61,6 @@
#include <private/qflagpointer_p.h>
#include <private/qqmlbinding_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QQmlCompiledData;
@@ -158,8 +156,6 @@ void QV8Bindings::release()
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV8BINDINGS_P_H
diff --git a/src/qml/qml/v8/qv8domerrors_p.h b/src/qml/qml/v8/qv8domerrors_p.h
index 0542863c32..8fd1ccb6d6 100644
--- a/src/qml/qml/v8/qv8domerrors_p.h
+++ b/src/qml/qml/v8/qv8domerrors_p.h
@@ -55,8 +55,6 @@
#include <QtCore/qglobal.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
// From DOM-Level-3-Core spec
// http://www.w3.org/TR/DOM-Level-3-Core/core.html
@@ -89,6 +87,4 @@ void qt_add_domexceptions(QV8Engine *engine);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV8DOMERRORS_P_H
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 2619c1a484..e80da46fc9 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -54,6 +54,7 @@
#include <private/qqmllocale_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlmemoryprofiler_p.h>
+#include <private/qqmlplatform_p.h>
#include "qscript_impl_p.h"
#include "qv8domerrors_p.h"
@@ -125,6 +126,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership)
, m_ownsV8Context(ownership == CreateNewContext)
, m_xmlHttpRequestData(0)
, m_listModelData(0)
+ , m_platform(0)
, m_application(0)
{
QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine");
@@ -561,7 +563,7 @@ QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value)
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
- { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
+ { return &staticQtMetaObject; }
};
void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
@@ -629,6 +631,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
qt->Set(v8::String::New("binding"), V8FUNCTION(binding, this));
if (m_engine) {
+ qt->SetAccessor(v8::String::New("platform"), getPlatform, 0, v8::External::New(this));
qt->SetAccessor(v8::String::New("application"), getApplication, 0, v8::External::New(this));
#ifndef QT_NO_IM
qt->SetAccessor(v8::String::New("inputMethod"), getInputMethod, 0, v8::External::New(this));
@@ -1446,9 +1449,19 @@ int QV8Engine::consoleCountHelper(const QString &file, quint16 line, quint16 col
return number;
}
+v8::Handle<v8::Value> QV8Engine::getPlatform(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
+ if (!engine->m_platform) {
+ // Only allocate a platform object once
+ engine->m_platform = new QQmlPlatform(engine->m_engine);
+ }
+ return engine->newQObject(engine->m_platform);
+}
+
v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data()));
+ QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
if (!engine->m_application) {
// Only allocate an application object once
engine->m_application = QQml_guiProvider()->application(engine->m_engine);
@@ -1459,7 +1472,7 @@ v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8:
#ifndef QT_NO_IM
v8::Handle<v8::Value> QV8Engine::getInputMethod(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data()));
+ QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
return engine->newQObject(QQml_guiProvider()->inputMethod(), CppOwnership);
}
#endif
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 43c978c757..5ae0963178 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -102,8 +102,8 @@ QT_BEGIN_NAMESPACE
// a handle, qFatal() is called.
// #define QML_GLOBAL_HANDLE_DEBUGGING
-#define V8ENGINE() ((QV8Engine *)v8::External::Unwrap(args.Data()))
-#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::Wrap((QV8Engine*)engine))->GetFunction()
+#define V8ENGINE() ((QV8Engine *)v8::External::Cast(*args.Data())->Value())
+#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::New((QV8Engine*)engine))->GetFunction()
#define V8THROW_ERROR(string) { \
v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \
return v8::Handle<v8::Value>(); \
@@ -112,7 +112,7 @@ QT_BEGIN_NAMESPACE
v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \
return v8::Handle<v8::Value>(); \
}
-#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Unwrap(info.Data()));
+#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Cast(*info.Data())->Value());
#define V8THROW_ERROR_SETTER(string) { \
v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \
return; \
@@ -427,6 +427,7 @@ public:
void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle);
void addRelationshipForGC(QObject *object, QObject *other);
+ static v8::Handle<v8::Value> getPlatform(v8::Local<v8::String> property, const v8::AccessorInfo &info);
static v8::Handle<v8::Value> getApplication(v8::Local<v8::String> property, const v8::AccessorInfo &info);
#ifndef QT_NO_IM
static v8::Handle<v8::Value> getInputMethod(v8::Local<v8::String> property, const v8::AccessorInfo &info);
@@ -480,6 +481,7 @@ protected:
QHash<QString, quint32> m_consoleCount;
+ QObject *m_platform;
QObject *m_application;
QVariant toBasicVariant(v8::Handle<v8::Value>);
@@ -627,8 +629,10 @@ v8::Handle<v8::String> QV8Engine::bindingFlagKey() const
// unqualified name in QV8ContextWrapper.
bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string)
{
- uint16_t c = string->GetCharacter(0);
- return (c >= 'A' && c <= 'Z') ||
+ v8::String::Value value(string);
+ Q_ASSERT(*value != NULL);
+ uint16_t c = **value;
+ return (c >= 'A' && c <= 'Z') ||
(c > 127 && QChar::category(c) == QChar::Letter_Uppercase);
}
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
index 4539401a3b..0982f177d3 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -277,7 +277,7 @@ static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8:
if (QQmlData::wasDeleted(object)) return v8::Undefined();
QQmlPropertyData *property =
- (QQmlPropertyData *)v8::External::Unwrap(info.Data());
+ (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value();
QQmlEngine *engine = resource->engine->engine();
QQmlEnginePrivate *ep = engine?QQmlEnginePrivate::get(engine):0;
@@ -894,7 +894,7 @@ static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
QObject *object = resource->object;
QQmlPropertyData *property =
- (QQmlPropertyData *)v8::External::Unwrap(info.Data());
+ (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value();
int index = property->coreIndex;
@@ -1029,7 +1029,7 @@ v8::Local<v8::Object> QQmlPropertyCache::newQObject(QObject *object, QV8Engine *
// this type and the property accessor checks if the object is 0 (deleted) before
// dereferencing the pointer.
ft->InstanceTemplate()->SetAccessor(engine->toString(iter.key()), fastgetter, fastsetter,
- v8::External::Wrap(property));
+ v8::External::New(property));
}
}
diff --git a/src/qml/qml/v8/qv8sqlerrors_p.h b/src/qml/qml/v8/qv8sqlerrors_p.h
index b2ffbf9233..8a612d69ab 100644
--- a/src/qml/qml/v8/qv8sqlerrors_p.h
+++ b/src/qml/qml/v8/qv8sqlerrors_p.h
@@ -55,8 +55,6 @@
#include <QtCore/qglobal.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
#define SQLEXCEPTION_UNKNOWN_ERR 1
#define SQLEXCEPTION_DATABASE_ERR 2
@@ -72,6 +70,4 @@ void qt_add_sqlexceptions(QV8Engine *engine);
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QV8SQLERRORS_P_H
diff --git a/src/qml/qml/v8/qv8worker.cpp b/src/qml/qml/v8/qv8worker.cpp
index bf3379b312..9556e146ef 100644
--- a/src/qml/qml/v8/qv8worker.cpp
+++ b/src/qml/qml/v8/qv8worker.cpp
@@ -41,8 +41,8 @@
#include "qv8worker_p.h"
-#include <private/qquicklistmodel_p.h>
-#include <private/qquicklistmodelworkeragent_p.h>
+#include <private/qqmllistmodel_p.h>
+#include <private/qqmllistmodelworkeragent_p.h>
QT_BEGIN_NAMESPACE
@@ -242,9 +242,9 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *
} else if (engine->isQObject(v)) {
// XXX TODO: Generalize passing objects between the main thread and worker scripts so
// that others can trivially plug in their elements.
- QQuickListModel *lm = qobject_cast<QQuickListModel *>(engine->toQObject(v));
+ QQmlListModel *lm = qobject_cast<QQmlListModel *>(engine->toQObject(v));
if (lm && lm->agent()) {
- QQuickListModelWorkerAgent *agent = lm->agent();
+ QQmlListModelWorkerAgent *agent = lm->agent();
agent->addref();
push(data, valueheader(WorkerListModel));
push(data, (void *)agent);
@@ -347,10 +347,10 @@ v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engin
case WorkerListModel:
{
void *ptr = popPtr(data);
- QQuickListModelWorkerAgent *agent = (QQuickListModelWorkerAgent *)ptr;
+ QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
v8::Handle<v8::Value> rv = engine->newQObject(agent);
if (rv->IsObject()) {
- QQuickListModelWorkerAgent::VariantRef ref(agent);
+ QQmlListModelWorkerAgent::VariantRef ref(agent);
QVariant var = qVariantFromValue(ref);
rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var));
}
diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h
index e0668dfb90..07a4136e3a 100644
--- a/src/qml/qtqmlglobal.h
+++ b/src/qml/qtqmlglobal.h
@@ -44,7 +44,6 @@
#include <QtCore/qglobal.h>
-QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
#ifndef QT_STATIC
@@ -58,6 +57,4 @@ QT_BEGIN_NAMESPACE
#endif
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QTQMLGLOBAL_H
diff --git a/src/qml/qml/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 7eb182b034..fcb3079891 100644
--- a/src/qml/qml/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -77,7 +77,7 @@ public:
/*!
\qmltype Binding
\instantiates QQmlBind
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\ingroup qtquick-interceptors
\brief Enables the arbitrary creation of property bindings
@@ -151,7 +151,7 @@ QQmlBind::~QQmlBind()
}
/*!
- \qmlproperty bool QtQuick2::Binding::when
+ \qmlproperty bool QtQml2::Binding::when
This property holds when the binding is active.
This should be set to an expression that evaluates to true when you want the binding to be active.
@@ -183,7 +183,7 @@ void QQmlBind::setWhen(bool v)
}
/*!
- \qmlproperty Object QtQuick2::Binding::target
+ \qmlproperty Object QtQml2::Binding::target
The object to be updated.
*/
@@ -210,7 +210,7 @@ void QQmlBind::setObject(QObject *obj)
}
/*!
- \qmlproperty string QtQuick2::Binding::property
+ \qmlproperty string QtQml2::Binding::property
The property to be updated.
*/
@@ -237,7 +237,7 @@ void QQmlBind::setProperty(const QString &p)
}
/*!
- \qmlproperty any QtQuick2::Binding::value
+ \qmlproperty any QtQml2::Binding::value
The value to be set on the target object and property. This can be a
constant (which isn't very useful), or a bound expression.
diff --git a/src/qml/qml/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h
index 04dc72a4c0..1e29c257f0 100644
--- a/src/qml/qml/qqmlbind_p.h
+++ b/src/qml/types/qqmlbind_p.h
@@ -46,8 +46,6 @@
#include <QtCore/qobject.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QQmlBindPrivate;
@@ -91,6 +89,4 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlBind)
-QT_END_HEADER
-
#endif
diff --git a/src/qml/qml/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index f2d29bf393..286933e557 100644
--- a/src/qml/qml/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -73,7 +73,7 @@ public:
/*!
\qmltype Connections
\instantiates QQmlConnections
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\ingroup qtquick-interceptors
\brief Describes generalized connections to signals
@@ -138,7 +138,7 @@ QQmlConnections::~QQmlConnections()
}
/*!
- \qmlproperty Object QtQuick2::Connections::target
+ \qmlproperty Object QtQml2::Connections::target
This property holds the object that sends the signal.
If this property is not set, the \c target defaults to the parent of the Connection.
@@ -183,7 +183,7 @@ void QQmlConnections::setTarget(QObject *obj)
}
/*!
- \qmlproperty bool QtQuick2::Connections::ignoreUnknownSignals
+ \qmlproperty bool QtQml2::Connections::ignoreUnknownSignals
Normally, a connection to a non-existent signal produces runtime errors.
diff --git a/src/qml/qml/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 15fba24df8..9bc668e5f4 100644
--- a/src/qml/qml/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -48,8 +48,6 @@
#include <QtCore/qobject.h>
#include <QtCore/qstring.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QQmlBoundSignal;
@@ -95,6 +93,4 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlConnections)
-QT_END_HEADER
-
#endif
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
new file mode 100644
index 0000000000..efbd98bdbc
--- /dev/null
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -0,0 +1,3189 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldelegatemodel_p_p.h"
+
+#include <QtQml/qqmlinfo.h>
+
+#include <private/qquickpackage_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qqmladaptormodel_p.h>
+#include <private/qqmlchangeset_p.h>
+#include <private/qqmlengine_p.h>
+#include <private/qqmlcomponent_p.h>
+#include <private/qqmlincubator_p.h>
+#include <private/qqmlcompiler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlDelegateModelEngineData : public QV8Engine::Deletable
+{
+public:
+ enum
+ {
+ Model,
+ Groups,
+ IsUnresolved,
+ ItemsIndex,
+ PersistedItemsIndex,
+ InItems,
+ InPersistedItems,
+ StringCount
+ };
+
+ QQmlDelegateModelEngineData(QV8Engine *engine);
+ ~QQmlDelegateModelEngineData();
+
+ v8::Local<v8::Object> array(
+ QV8Engine *engine, const QVector<QQmlChangeSet::Remove> &changes);
+ v8::Local<v8::Object> array(
+ QV8Engine *engine, const QVector<QQmlChangeSet::Insert> &changes);
+ v8::Local<v8::Object> array(
+ QV8Engine *engine, const QVector<QQmlChangeSet::Change> &changes);
+
+
+ inline v8::Local<v8::String> model() { return strings->Get(Model)->ToString(); }
+ inline v8::Local<v8::String> groups() { return strings->Get(Groups)->ToString(); }
+ inline v8::Local<v8::String> isUnresolved() { return strings->Get(IsUnresolved)->ToString(); }
+ inline v8::Local<v8::String> itemsIndex() { return strings->Get(ItemsIndex)->ToString(); }
+ inline v8::Local<v8::String> persistedItemsIndex() { return strings->Get(PersistedItemsIndex)->ToString(); }
+ inline v8::Local<v8::String> inItems() { return strings->Get(InItems)->ToString(); }
+ inline v8::Local<v8::String> inPersistedItems() { return strings->Get(InPersistedItems)->ToString(); }
+
+ v8::Persistent<v8::Array> strings;
+ v8::Persistent<v8::Function> constructorChange;
+ v8::Persistent<v8::Function> constructorChangeArray;
+};
+
+V8_DEFINE_EXTENSION(QQmlDelegateModelEngineData, engineData)
+
+
+void QQmlDelegateModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
+{
+ prop.setWritable(false);
+}
+
+QVariant QQmlDelegateModelPartsMetaObject::initialValue(int id)
+{
+ QQmlDelegateModelParts *parts = static_cast<QQmlDelegateModelParts *>(object());
+ QQmlPartsModel *m = new QQmlPartsModel(
+ parts->model, QString::fromUtf8(name(id)), parts);
+ parts->models.append(m);
+ return QVariant::fromValue(static_cast<QObject *>(m));
+}
+
+QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
+: QObject(parent), model(parent)
+{
+ new QQmlDelegateModelPartsMetaObject(this);
+}
+
+//---------------------------------------------------------------------------
+
+/*!
+ \qmltype VisualDataModel
+ \instantiates QQmlDelegateModel
+ \inqmlmodule QtQuick 2
+ \ingroup qtquick-models
+ \brief Encapsulates a model and delegate
+
+ The VisualDataModel type encapsulates a model and the delegate that will
+ be instantiated for items in a model.
+
+ This type is provided by QtQuick 2 for compatibility reasons. The same implementation
+ is now primarily available as DelegateModel in the QtQml.Models module.
+
+ \sa {QtQml.Models2::DelegateModel}
+*/
+/*!
+ \qmltype DelegateModel
+ \instantiates QQmlDelegateModel
+ \inqmlmodule QtQml.Models 2
+ \brief Encapsulates a model and delegate
+
+ The DelegateModel type encapsulates a model and the delegate that will
+ be instantiated for items in the model.
+
+ This element is also available as DelegateModel in the QtQuick module. For full details,
+ see the \l DelegateModel documentation.
+
+ The DelegateModel type encapsulates a model and the delegate that will
+ be instantiated for items in the model.
+
+ It is usually not necessary to create a DelegateModel.
+ However, it can be useful for manipulating and accessing the \l modelIndex
+ when a QAbstractItemModel subclass is used as the
+ model. Also, DelegateModel is used together with \l Package to
+ provide delegates to multiple views, and with DelegateModelGroup to sort and filter
+ delegate items.
+
+ The example below illustrates using a DelegateModel with a ListView.
+
+ \snippet qml/visualdatamodel.qml 0
+*/
+
+QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt)
+ : m_delegate(0)
+ , m_cacheMetaType(0)
+ , m_context(ctxt)
+ , m_parts(0)
+ , m_filterGroup(QStringLiteral("items"))
+ , m_count(0)
+ , m_groupCount(Compositor::MinimumGroupCount)
+ , m_compositorGroup(Compositor::Cache)
+ , m_complete(false)
+ , m_delegateValidated(false)
+ , m_reset(false)
+ , m_transaction(false)
+ , m_incubatorCleanupScheduled(false)
+ , m_cacheItems(0)
+ , m_items(0)
+ , m_persistedItems(0)
+{
+}
+
+QQmlDelegateModelPrivate::~QQmlDelegateModelPrivate()
+{
+ qDeleteAll(m_finishedIncubating);
+
+ if (m_cacheMetaType)
+ m_cacheMetaType->release();
+}
+
+void QQmlDelegateModelPrivate::init()
+{
+ Q_Q(QQmlDelegateModel);
+ m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
+
+ m_items = new QQmlDelegateModelGroup(QStringLiteral("items"), q, Compositor::Default, q);
+ m_items->setDefaultInclude(true);
+ m_persistedItems = new QQmlDelegateModelGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
+ QQmlDelegateModelGroupPrivate::get(m_items)->emitters.insert(this);
+}
+
+QQmlDelegateModel::QQmlDelegateModel()
+: QQmlInstanceModel(*(new QQmlDelegateModelPrivate(0)))
+{
+ Q_D(QQmlDelegateModel);
+ d->init();
+}
+
+QQmlDelegateModel::QQmlDelegateModel(QQmlContext *ctxt, QObject *parent)
+: QQmlInstanceModel(*(new QQmlDelegateModelPrivate(ctxt)), parent)
+{
+ Q_D(QQmlDelegateModel);
+ d->init();
+}
+
+QQmlDelegateModel::~QQmlDelegateModel()
+{
+ Q_D(QQmlDelegateModel);
+
+ foreach (QQmlDelegateModelItem *cacheItem, d->m_cache) {
+ if (cacheItem->object) {
+ delete cacheItem->object;
+
+ cacheItem->object = 0;
+ cacheItem->contextData->destroy();
+ cacheItem->contextData = 0;
+ cacheItem->scriptRef -= 1;
+ }
+ cacheItem->groups &= ~Compositor::UnresolvedFlag;
+ cacheItem->objectRef = 0;
+ if (!cacheItem->isReferenced())
+ delete cacheItem;
+ }
+}
+
+
+void QQmlDelegateModel::classBegin()
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_context)
+ d->m_context = qmlContext(this);
+}
+
+void QQmlDelegateModel::componentComplete()
+{
+ Q_D(QQmlDelegateModel);
+ d->m_complete = true;
+
+ int defaultGroups = 0;
+ QStringList groupNames;
+ groupNames.append(QStringLiteral("items"));
+ groupNames.append(QStringLiteral("persistedItems"));
+ if (QQmlDelegateModelGroupPrivate::get(d->m_items)->defaultInclude)
+ defaultGroups |= Compositor::DefaultFlag;
+ if (QQmlDelegateModelGroupPrivate::get(d->m_persistedItems)->defaultInclude)
+ defaultGroups |= Compositor::PersistedFlag;
+ for (int i = Compositor::MinimumGroupCount; i < d->m_groupCount; ++i) {
+ QString name = d->m_groups[i]->name();
+ if (name.isEmpty()) {
+ d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
+ --d->m_groupCount;
+ --i;
+ } else if (name.at(0).isUpper()) {
+ qmlInfo(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
+ d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
+ --d->m_groupCount;
+ --i;
+ } else {
+ groupNames.append(name);
+
+ QQmlDelegateModelGroupPrivate *group = QQmlDelegateModelGroupPrivate::get(d->m_groups[i]);
+ group->setModel(this, Compositor::Group(i));
+ if (group->defaultInclude)
+ defaultGroups |= (1 << i);
+ }
+ }
+
+ d->m_cacheMetaType = new QQmlDelegateModelItemMetaType(
+ QQmlEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames);
+
+ d->m_compositor.setGroupCount(d->m_groupCount);
+ d->m_compositor.setDefaultGroups(defaultGroups);
+ d->updateFilterGroup();
+
+ while (!d->m_pendingParts.isEmpty())
+ static_cast<QQmlPartsModel *>(d->m_pendingParts.first())->updateFilterGroup();
+
+ QVector<Compositor::Insert> inserts;
+ d->m_count = d->m_adaptorModel.count();
+ d->m_compositor.append(
+ &d->m_adaptorModel,
+ 0,
+ d->m_count,
+ defaultGroups | Compositor::AppendFlag | Compositor::PrependFlag,
+ &inserts);
+ d->itemsInserted(inserts);
+ d->emitChanges();
+
+ if (d->m_adaptorModel.canFetchMore())
+ QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+}
+
+/*!
+ \qmlproperty model QtQml.Models2::DelegateModel::model
+ This property holds the model providing data for the DelegateModel.
+
+ The model provides a set of data that is used to create the items
+ for a view. For large or dynamic datasets the model is usually
+ provided by a C++ model object. The C++ model object must be a \l
+ {QAbstractItemModel} subclass or a simple list.
+
+ Models can also be created directly in QML, using a \l{ListModel} or
+ \l{XmlListModel}.
+
+ \sa {qml-data-models}{Data Models}
+*/
+QVariant QQmlDelegateModel::model() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_adaptorModel.model();
+}
+
+void QQmlDelegateModel::setModel(const QVariant &model)
+{
+ Q_D(QQmlDelegateModel);
+
+ if (d->m_complete)
+ _q_itemsRemoved(0, d->m_count);
+
+ d->m_adaptorModel.setModel(model, this, d->m_context->engine());
+ d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles);
+ for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) {
+ d->m_adaptorModel.replaceWatchedRoles(
+ QList<QByteArray>(), d->m_parts->models.at(i)->watchedRoles());
+ }
+
+ if (d->m_complete) {
+ _q_itemsInserted(0, d->m_adaptorModel.count());
+ if (d->m_adaptorModel.canFetchMore())
+ QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+ }
+}
+
+/*!
+ \qmlproperty Component QtQml.Models2::DelegateModel::delegate
+
+ The delegate provides a template defining each item instantiated by a view.
+ The index is exposed as an accessible \c index property. Properties of the
+ model are also available depending upon the type of \l {qml-data-models}{Data Model}.
+*/
+QQmlComponent *QQmlDelegateModel::delegate() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_delegate;
+}
+
+void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
+{
+ Q_D(QQmlDelegateModel);
+ if (d->m_transaction) {
+ qmlInfo(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
+ return;
+ }
+ bool wasValid = d->m_delegate != 0;
+ d->m_delegate = delegate;
+ d->m_delegateValidated = false;
+ if (wasValid && d->m_complete) {
+ for (int i = 1; i < d->m_groupCount; ++i) {
+ QQmlDelegateModelGroupPrivate::get(d->m_groups[i])->changeSet.remove(
+ 0, d->m_compositor.count(Compositor::Group(i)));
+ }
+ }
+ if (d->m_complete && d->m_delegate) {
+ for (int i = 1; i < d->m_groupCount; ++i) {
+ QQmlDelegateModelGroupPrivate::get(d->m_groups[i])->changeSet.insert(
+ 0, d->m_compositor.count(Compositor::Group(i)));
+ }
+ }
+ d->emitChanges();
+}
+
+/*!
+ \qmlproperty QModelIndex QtQml.Models2::DelegateModel::rootIndex
+
+ QAbstractItemModel provides a hierarchical tree of data, whereas
+ QML only operates on list data. \c rootIndex allows the children of
+ any node in a QAbstractItemModel to be provided by this model.
+
+ This property only affects models of type QAbstractItemModel that
+ are hierarchical (e.g, a tree model).
+
+ For example, here is a simple interactive file system browser.
+ When a directory name is clicked, the view's \c rootIndex is set to the
+ QModelIndex node of the clicked directory, thus updating the view to show
+ the new directory's contents.
+
+ \c main.cpp:
+ \snippet qml/visualdatamodel_rootindex/main.cpp 0
+
+ \c view.qml:
+ \snippet qml/visualdatamodel_rootindex/view.qml 0
+
+ If the \l model is a QAbstractItemModel subclass, the delegate can also
+ reference a \c hasModelChildren property (optionally qualified by a
+ \e model. prefix) that indicates whether the delegate's model item has
+ any child nodes.
+
+
+ \sa modelIndex(), parentModelIndex()
+*/
+QVariant QQmlDelegateModel::rootIndex() const
+{
+ Q_D(const QQmlDelegateModel);
+ return QVariant::fromValue(QModelIndex(d->m_adaptorModel.rootIndex));
+}
+
+void QQmlDelegateModel::setRootIndex(const QVariant &root)
+{
+ Q_D(QQmlDelegateModel);
+
+ QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
+ const bool changed = d->m_adaptorModel.rootIndex != modelIndex;
+ if (changed || !d->m_adaptorModel.isValid()) {
+ const int oldCount = d->m_count;
+ d->m_adaptorModel.rootIndex = modelIndex;
+ if (!d->m_adaptorModel.isValid() && d->m_adaptorModel.aim()) // The previous root index was invalidated, so we need to reconnect the model.
+ d->m_adaptorModel.setModel(d->m_adaptorModel.list.list(), this, d->m_context->engine());
+ if (d->m_adaptorModel.canFetchMore())
+ d->m_adaptorModel.fetchMore();
+ if (d->m_complete) {
+ const int newCount = d->m_adaptorModel.count();
+ if (oldCount)
+ _q_itemsRemoved(0, oldCount);
+ if (newCount)
+ _q_itemsInserted(0, newCount);
+ }
+ if (changed)
+ emit rootIndexChanged();
+ }
+}
+
+/*!
+ \qmlmethod QModelIndex QtQml.Models2::DelegateModel::modelIndex(int index)
+
+ QAbstractItemModel provides a hierarchical tree of data, whereas
+ QML only operates on list data. This function assists in using
+ tree models in QML.
+
+ Returns a QModelIndex for the specified index.
+ This value can be assigned to rootIndex.
+
+ \sa rootIndex
+*/
+QVariant QQmlDelegateModel::modelIndex(int idx) const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_adaptorModel.modelIndex(idx);
+}
+
+/*!
+ \qmlmethod QModelIndex QtQml.Models2::DelegateModel::parentModelIndex()
+
+ QAbstractItemModel provides a hierarchical tree of data, whereas
+ QML only operates on list data. This function assists in using
+ tree models in QML.
+
+ Returns a QModelIndex for the parent of the current rootIndex.
+ This value can be assigned to rootIndex.
+
+ \sa rootIndex
+*/
+QVariant QQmlDelegateModel::parentModelIndex() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_adaptorModel.parentModelIndex();
+}
+
+/*!
+ \qmlproperty int QtQml.Models2::DelegateModel::count
+*/
+
+int QQmlDelegateModel::count() const
+{
+ Q_D(const QQmlDelegateModel);
+ if (!d->m_delegate)
+ return 0;
+ return d->m_compositor.count(d->m_compositorGroup);
+}
+
+QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *object)
+{
+ QQmlDelegateModel::ReleaseFlags stat = 0;
+ if (!object)
+ return stat;
+
+ if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(object)) {
+ if (cacheItem->releaseObject()) {
+ cacheItem->destroyObject();
+ emitDestroyingItem(object);
+ if (cacheItem->incubationTask) {
+ releaseIncubator(cacheItem->incubationTask);
+ cacheItem->incubationTask = 0;
+ }
+ cacheItem->Dispose();
+ stat |= QQmlInstanceModel::Destroyed;
+ } else {
+ stat |= QQmlDelegateModel::Referenced;
+ }
+ }
+ return stat;
+}
+
+/*
+ Returns ReleaseStatus flags.
+*/
+
+QQmlDelegateModel::ReleaseFlags QQmlDelegateModel::release(QObject *item)
+{
+ Q_D(QQmlDelegateModel);
+ QQmlInstanceModel::ReleaseFlags stat = d->release(item);
+ return stat;
+}
+
+// Cancel a requested async item
+void QQmlDelegateModel::cancel(int index)
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
+ qWarning() << "DelegateModel::cancel: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
+ return;
+ }
+
+ Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index);
+ QQmlDelegateModelItem *cacheItem = it->inCache() ? d->m_cache.at(it.cacheIndex) : 0;
+ if (cacheItem) {
+ if (cacheItem->incubationTask && !cacheItem->isObjectReferenced()) {
+ d->releaseIncubator(cacheItem->incubationTask);
+ cacheItem->incubationTask = 0;
+
+ if (cacheItem->object) {
+ QObject *object = cacheItem->object;
+ cacheItem->destroyObject();
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
+ d->emitDestroyingPackage(package);
+ else
+ d->emitDestroyingItem(object);
+ }
+
+ cacheItem->scriptRef -= 1;
+ }
+ if (!cacheItem->isReferenced()) {
+ d->m_compositor.clearFlags(Compositor::Cache, it.cacheIndex, 1, Compositor::CacheFlag);
+ d->m_cache.removeAt(it.cacheIndex);
+ delete cacheItem;
+ Q_ASSERT(d->m_cache.count() == d->m_compositor.count(Compositor::Cache));
+ }
+ }
+}
+
+void QQmlDelegateModelPrivate::group_append(
+ QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group)
+{
+ QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
+ if (d->m_complete)
+ return;
+ if (d->m_groupCount == Compositor::MaximumGroupCount) {
+ qmlInfo(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
+ return;
+ }
+ d->m_groups[d->m_groupCount] = group;
+ d->m_groupCount += 1;
+}
+
+int QQmlDelegateModelPrivate::group_count(
+ QQmlListProperty<QQmlDelegateModelGroup> *property)
+{
+ QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
+ return d->m_groupCount - 1;
+}
+
+QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
+ QQmlListProperty<QQmlDelegateModelGroup> *property, int index)
+{
+ QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
+ return index >= 0 && index < d->m_groupCount - 1
+ ? d->m_groups[index + 1]
+ : 0;
+}
+
+/*!
+ \qmlproperty list<DelegateModelGroup> QtQml.Models2::DelegateModel::groups
+
+ This property holds a visual data model's group definitions.
+
+ Groups define a sub-set of the items in a visual data model and can be used to filter
+ a model.
+
+ For every group defined in a DelegateModel two attached properties are added to each
+ delegate item. The first of the form DelegateModel.in\e{GroupName} holds whether the
+ item belongs to the group and the second DelegateModel.\e{groupName}Index holds the
+ index of the item in that group.
+
+ The following example illustrates using groups to select items in a model.
+
+ \snippet qml/visualdatagroup.qml 0
+*/
+
+QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
+{
+ Q_D(QQmlDelegateModel);
+ return QQmlListProperty<QQmlDelegateModelGroup>(
+ this,
+ d,
+ QQmlDelegateModelPrivate::group_append,
+ QQmlDelegateModelPrivate::group_count,
+ QQmlDelegateModelPrivate::group_at,
+ 0);
+}
+
+/*!
+ \qmlproperty DelegateModelGroup QtQml.Models2::DelegateModel::items
+
+ This property holds visual data model's default group to which all new items are added.
+*/
+
+QQmlDelegateModelGroup *QQmlDelegateModel::items()
+{
+ Q_D(QQmlDelegateModel);
+ return d->m_items;
+}
+
+/*!
+ \qmlproperty DelegateModelGroup QtQml.Models2::DelegateModel::persistedItems
+
+ This property holds visual data model's persisted items group.
+
+ Items in this group are not destroyed when released by a view, instead they are persisted
+ until removed from the group.
+
+ An item can be removed from the persistedItems group by setting the
+ DelegateModel.inPersistedItems property to false. If the item is not referenced by a view
+ at that time it will be destroyed. Adding an item to this group will not create a new
+ instance.
+
+ Items returned by the \l QtQml.Models2::DelegateModelGroup::create() function are automatically added
+ to this group.
+*/
+
+QQmlDelegateModelGroup *QQmlDelegateModel::persistedItems()
+{
+ Q_D(QQmlDelegateModel);
+ return d->m_persistedItems;
+}
+
+/*!
+ \qmlproperty string QtQml.Models2::DelegateModel::filterOnGroup
+
+ This property holds the name of the group used to filter the visual data model.
+
+ Only items which belong to this group are visible to a view.
+
+ By default this is the \l items group.
+*/
+
+QString QQmlDelegateModel::filterGroup() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_filterGroup;
+}
+
+void QQmlDelegateModel::setFilterGroup(const QString &group)
+{
+ Q_D(QQmlDelegateModel);
+
+ if (d->m_transaction) {
+ qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ return;
+ }
+
+ if (d->m_filterGroup != group) {
+ d->m_filterGroup = group;
+ d->updateFilterGroup();
+ emit filterGroupChanged();
+ }
+}
+
+void QQmlDelegateModel::resetFilterGroup()
+{
+ setFilterGroup(QStringLiteral("items"));
+}
+
+void QQmlDelegateModelPrivate::updateFilterGroup()
+{
+ Q_Q(QQmlDelegateModel);
+ if (!m_cacheMetaType)
+ return;
+
+ QQmlListCompositor::Group previousGroup = m_compositorGroup;
+ m_compositorGroup = Compositor::Default;
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (m_filterGroup == m_cacheMetaType->groupNames.at(i - 1)) {
+ m_compositorGroup = Compositor::Group(i);
+ break;
+ }
+ }
+
+ QQmlDelegateModelGroupPrivate::get(m_groups[m_compositorGroup])->emitters.insert(this);
+ if (m_compositorGroup != previousGroup) {
+ QVector<QQmlChangeSet::Remove> removes;
+ QVector<QQmlChangeSet::Insert> inserts;
+ m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
+
+ QQmlChangeSet changeSet;
+ changeSet.move(removes, inserts);
+ emit q->modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+
+ if (m_parts) {
+ foreach (QQmlPartsModel *model, m_parts->models)
+ model->updateFilterGroup(m_compositorGroup, changeSet);
+ }
+ }
+}
+
+/*!
+ \qmlproperty object QtQml.Models2::DelegateModel::parts
+
+ The \a parts property selects a DelegateModel which creates
+ delegates from the part named. This is used in conjunction with
+ the \l Package type.
+
+ For example, the code below selects a model which creates
+ delegates named \e list from a \l Package:
+
+ \code
+ DelegateModel {
+ id: visualModel
+ delegate: Package {
+ Item { Package.name: "list" }
+ }
+ model: myModel
+ }
+
+ ListView {
+ width: 200; height:200
+ model: visualModel.parts.list
+ }
+ \endcode
+
+ \sa Package
+*/
+
+QObject *QQmlDelegateModel::parts()
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_parts)
+ d->m_parts = new QQmlDelegateModelParts(this);
+ return d->m_parts;
+}
+
+void QQmlDelegateModelPrivate::emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
+{
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->createdPackage(incubationTask->index[i], package);
+}
+
+void QQmlDelegateModelPrivate::emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
+{
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->initPackage(incubationTask->index[i], package);
+}
+
+void QQmlDelegateModelPrivate::emitDestroyingPackage(QQuickPackage *package)
+{
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->destroyingPackage(package);
+}
+
+void QQDMIncubationTask::statusChanged(Status status)
+{
+ vdm->incubatorStatusChanged(this, status);
+}
+
+void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTask)
+{
+ Q_Q(QQmlDelegateModel);
+ if (!incubationTask->isError())
+ incubationTask->clear();
+ m_finishedIncubating.append(incubationTask);
+ if (!m_incubatorCleanupScheduled) {
+ m_incubatorCleanupScheduled = true;
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User));
+ }
+}
+
+void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
+{
+ int cidx = m_cache.indexOf(cacheItem);
+ if (cidx >= 0) {
+ m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
+ m_cache.removeAt(cidx);
+ }
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+}
+
+void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
+{
+ Q_Q(QQmlDelegateModel);
+ if (status != QQmlIncubator::Ready && status != QQmlIncubator::Error)
+ return;
+
+ QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
+ cacheItem->incubationTask = 0;
+ incubationTask->incubating = 0;
+ releaseIncubator(incubationTask);
+
+ if (status == QQmlIncubator::Ready) {
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
+ emitCreatedPackage(incubationTask, package);
+ else
+ emitCreatedItem(incubationTask, cacheItem->object);
+ } else if (status == QQmlIncubator::Error) {
+ qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
+ }
+
+ if (!cacheItem->isObjectReferenced()) {
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
+ emitDestroyingPackage(package);
+ else
+ emitDestroyingItem(cacheItem->object);
+ delete cacheItem->object;
+ cacheItem->object = 0;
+ cacheItem->scriptRef -= 1;
+ cacheItem->contextData->destroy();
+ cacheItem->contextData = 0;
+ if (!cacheItem->isReferenced()) {
+ removeCacheItem(cacheItem);
+ delete cacheItem;
+ }
+ }
+}
+
+void QQDMIncubationTask::setInitialState(QObject *o)
+{
+ vdm->setInitialState(this, o);
+}
+
+void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTask, QObject *o)
+{
+ QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
+ cacheItem->object = o;
+
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object))
+ emitInitPackage(incubationTask, package);
+ else
+ emitInitItem(incubationTask, cacheItem->object);
+}
+
+QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bool asynchronous)
+{
+ Q_Q(QQmlDelegateModel);
+ if (!m_delegate || index < 0 || index >= m_compositor.count(group)) {
+ qWarning() << "DelegateModel::item: index out range" << index << m_compositor.count(group);
+ return 0;
+ } else if (!m_context->isValid()) {
+ return 0;
+ }
+
+ Compositor::iterator it = m_compositor.find(group, index);
+
+ QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
+
+ if (!cacheItem) {
+ cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), it.modelIndex());
+ if (!cacheItem)
+ return 0;
+
+ cacheItem->groups = it->flags;
+
+ m_cache.insert(it.cacheIndex, cacheItem);
+ m_compositor.setFlags(it, 1, Compositor::CacheFlag);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ }
+
+ // Bump the reference counts temporarily so neither the content data or the delegate object
+ // are deleted if incubatorStatusChanged() is called synchronously.
+ cacheItem->scriptRef += 1;
+ cacheItem->referenceObject();
+
+ if (cacheItem->incubationTask) {
+ if (!asynchronous && cacheItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous) {
+ // previously requested async - now needed immediately
+ cacheItem->incubationTask->forceCompletion();
+ }
+ } else if (!cacheItem->object) {
+ QQmlContext *creationContext = m_delegate->creationContext();
+
+ cacheItem->scriptRef += 1;
+
+ cacheItem->incubationTask = new QQDMIncubationTask(this, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
+ cacheItem->incubationTask->incubating = cacheItem;
+ cacheItem->incubationTask->clear();
+
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->incubationTask->index[i] = it.index[i];
+
+ QQmlContextData *ctxt = new QQmlContextData;
+ ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context));
+ ctxt->contextObject = cacheItem;
+ cacheItem->contextData = ctxt;
+
+ if (m_adaptorModel.hasProxyObject()) {
+ if (QQmlAdaptorModelProxyInterface *proxy
+ = qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) {
+ ctxt = new QQmlContextData;
+ ctxt->setParent(cacheItem->contextData, true);
+ ctxt->contextObject = proxy->proxiedObject();
+ }
+ }
+
+ cacheItem->incubateObject(
+ m_delegate,
+ m_context->engine(),
+ ctxt,
+ QQmlContextData::get(m_context));
+ }
+
+ if (index == m_compositor.count(group) - 1 && m_adaptorModel.canFetchMore())
+ QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
+
+ // Remove the temporary reference count.
+ cacheItem->scriptRef -= 1;
+ if (cacheItem->object)
+ return cacheItem->object;
+
+ cacheItem->releaseObject();
+ if (!cacheItem->isReferenced()) {
+ removeCacheItem(cacheItem);
+ delete cacheItem;
+ }
+
+ return 0;
+}
+
+/*
+ If asynchronous is true or the component is being loaded asynchronously due
+ to an ancestor being loaded asynchronously, item() may return 0. In this
+ case itemCreated() will be emitted when the item is available. The item
+ at this stage does not have any references, so item() must be called again
+ to ensure a reference is held. Any call to item() which returns a valid item
+ must be matched by a call to release() in order to destroy the item.
+*/
+QObject *QQmlDelegateModel::object(int index, bool asynchronous)
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
+ qWarning() << "DelegateModel::item: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
+ return 0;
+ }
+
+ QObject *object = d->object(d->m_compositorGroup, index, asynchronous);
+ if (!object)
+ return 0;
+
+ return object;
+}
+
+QString QQmlDelegateModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
+{
+ Compositor::iterator it = m_compositor.find(group, index);
+ if (QQmlAdaptorModel *model = it.list<QQmlAdaptorModel>()) {
+ QString role = name;
+ int dot = name.indexOf(QLatin1Char('.'));
+ if (dot > 0)
+ role = name.left(dot);
+ QVariant value = model->value(it.modelIndex(), role);
+ while (dot > 0) {
+ QObject *obj = qvariant_cast<QObject*>(value);
+ if (!obj)
+ return QString();
+ int from = dot+1;
+ dot = name.indexOf(QLatin1Char('.'), from);
+ value = obj->property(name.mid(from, dot-from).toUtf8());
+ }
+ return value.toString();
+ }
+ return QString();
+}
+
+QString QQmlDelegateModel::stringValue(int index, const QString &name)
+{
+ Q_D(QQmlDelegateModel);
+ return d->stringValue(d->m_compositorGroup, index, name);
+}
+
+int QQmlDelegateModel::indexOf(QObject *item, QObject *) const
+{
+ Q_D(const QQmlDelegateModel);
+ if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(item))
+ return cacheItem->groupIndex(d->m_compositorGroup);
+ return -1;
+}
+
+void QQmlDelegateModel::setWatchedRoles(QList<QByteArray> roles)
+{
+ Q_D(QQmlDelegateModel);
+ d->m_adaptorModel.replaceWatchedRoles(d->m_watchedRoles, roles);
+ d->m_watchedRoles = roles;
+}
+
+void QQmlDelegateModelPrivate::addGroups(
+ Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
+{
+ QVector<Compositor::Insert> inserts;
+ m_compositor.setFlags(from, count, group, groupFlags, &inserts);
+ itemsInserted(inserts);
+ emitChanges();
+}
+
+void QQmlDelegateModelPrivate::removeGroups(
+ Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
+{
+ QVector<Compositor::Remove> removes;
+ m_compositor.clearFlags(from, count, group, groupFlags, &removes);
+ itemsRemoved(removes);
+ emitChanges();
+}
+
+void QQmlDelegateModelPrivate::setGroups(
+ Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
+{
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+
+ m_compositor.setFlags(from, count, group, groupFlags, &inserts);
+ itemsInserted(inserts);
+ const int removeFlags = ~groupFlags & Compositor::GroupMask;
+
+ from = m_compositor.find(from.group, from.index[from.group]);
+ m_compositor.clearFlags(from, count, group, removeFlags, &removes);
+ itemsRemoved(removes);
+ emitChanges();
+}
+
+bool QQmlDelegateModel::event(QEvent *e)
+{
+ Q_D(QQmlDelegateModel);
+ if (e->type() == QEvent::UpdateRequest) {
+ d->m_adaptorModel.fetchMore();
+ } else if (e->type() == QEvent::User) {
+ d->m_incubatorCleanupScheduled = false;
+ qDeleteAll(d->m_finishedIncubating);
+ d->m_finishedIncubating.clear();
+ }
+ return QQmlInstanceModel::event(e);
+}
+
+void QQmlDelegateModelPrivate::itemsChanged(const QVector<Compositor::Change> &changes)
+{
+ if (!m_delegate)
+ return;
+
+ QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> translatedChanges(m_groupCount);
+
+ foreach (const Compositor::Change &change, changes) {
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (change.inGroup(i)) {
+ translatedChanges[i].append(QQmlChangeSet::Change(change.index[i], change.count));
+ }
+ }
+ }
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.change(translatedChanges.at(i));
+}
+
+void QQmlDelegateModel::_q_itemsChanged(int index, int count, const QVector<int> &roles)
+{
+ Q_D(QQmlDelegateModel);
+ if (count <= 0 || !d->m_complete)
+ return;
+
+ if (d->m_adaptorModel.notify(d->m_cache, index, count, roles)) {
+ QVector<Compositor::Change> changes;
+ d->m_compositor.listItemsChanged(&d->m_adaptorModel, index, count, &changes);
+ d->itemsChanged(changes);
+ d->emitChanges();
+ }
+}
+
+static void incrementIndexes(QQmlDelegateModelItem *cacheItem, int count, const int *deltas)
+{
+ if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
+ for (int i = 1; i < count; ++i)
+ incubationTask->index[i] += deltas[i];
+ }
+ if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
+ for (int i = 1; i < count; ++i)
+ attached->m_currentIndex[i] += deltas[i];
+ }
+}
+
+void QQmlDelegateModelPrivate::itemsInserted(
+ const QVector<Compositor::Insert> &inserts,
+ QVarLengthArray<QVector<QQmlChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems)
+{
+ int cacheIndex = 0;
+
+ int inserted[Compositor::MaximumGroupCount];
+ for (int i = 1; i < m_groupCount; ++i)
+ inserted[i] = 0;
+
+ foreach (const Compositor::Insert &insert, inserts) {
+ for (; cacheIndex < insert.cacheIndex; ++cacheIndex)
+ incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted);
+
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (insert.inGroup(i)) {
+ (*translatedInserts)[i].append(
+ QQmlChangeSet::Insert(insert.index[i], insert.count, insert.moveId));
+ inserted[i] += insert.count;
+ }
+ }
+
+ if (!insert.inCache())
+ continue;
+
+ if (movedItems && insert.isMove()) {
+ QList<QQmlDelegateModelItem *> items = movedItems->take(insert.moveId);
+ Q_ASSERT(items.count() == insert.count);
+ m_cache = m_cache.mid(0, insert.cacheIndex) + items + m_cache.mid(insert.cacheIndex);
+ }
+ if (insert.inGroup()) {
+ for (int offset = 0; cacheIndex < insert.cacheIndex + insert.count; ++cacheIndex, ++offset) {
+ QQmlDelegateModelItem *cacheItem = m_cache.at(cacheIndex);
+ cacheItem->groups |= insert.flags & Compositor::GroupMask;
+
+ if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
+ for (int i = 1; i < m_groupCount; ++i)
+ incubationTask->index[i] = cacheItem->groups & (1 << i)
+ ? insert.index[i] + offset
+ : insert.index[i];
+ }
+ if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
+ for (int i = 1; i < m_groupCount; ++i)
+ attached->m_currentIndex[i] = cacheItem->groups & (1 << i)
+ ? insert.index[i] + offset
+ : insert.index[i];
+ }
+ }
+ } else {
+ cacheIndex = insert.cacheIndex + insert.count;
+ }
+ }
+ for (; cacheIndex < m_cache.count(); ++cacheIndex)
+ incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted);
+}
+
+void QQmlDelegateModelPrivate::itemsInserted(const QVector<Compositor::Insert> &inserts)
+{
+ QVarLengthArray<QVector<QQmlChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
+ itemsInserted(inserts, &translatedInserts);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.insert(translatedInserts.at(i));
+}
+
+void QQmlDelegateModel::_q_itemsInserted(int index, int count)
+{
+
+ Q_D(QQmlDelegateModel);
+ if (count <= 0 || !d->m_complete)
+ return;
+
+ d->m_count += count;
+
+ for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = d->m_cache.at(i);
+ if (item->modelIndex() >= index)
+ item->setModelIndex(item->modelIndex() + count);
+ }
+
+ QVector<Compositor::Insert> inserts;
+ d->m_compositor.listItemsInserted(&d->m_adaptorModel, index, count, &inserts);
+ d->itemsInserted(inserts);
+ d->emitChanges();
+}
+
+void QQmlDelegateModelPrivate::itemsRemoved(
+ const QVector<Compositor::Remove> &removes,
+ QVarLengthArray<QVector<QQmlChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems)
+{
+ int cacheIndex = 0;
+ int removedCache = 0;
+
+ int removed[Compositor::MaximumGroupCount];
+ for (int i = 1; i < m_groupCount; ++i)
+ removed[i] = 0;
+
+ foreach (const Compositor::Remove &remove, removes) {
+ for (; cacheIndex < remove.cacheIndex; ++cacheIndex)
+ incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed);
+
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (remove.inGroup(i)) {
+ (*translatedRemoves)[i].append(
+ QQmlChangeSet::Remove(remove.index[i], remove.count, remove.moveId));
+ removed[i] -= remove.count;
+ }
+ }
+
+ if (!remove.inCache())
+ continue;
+
+ if (movedItems && remove.isMove()) {
+ movedItems->insert(remove.moveId, m_cache.mid(remove.cacheIndex, remove.count));
+ QList<QQmlDelegateModelItem *>::iterator begin = m_cache.begin() + remove.cacheIndex;
+ QList<QQmlDelegateModelItem *>::iterator end = begin + remove.count;
+ m_cache.erase(begin, end);
+ } else {
+ for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
+ QQmlDelegateModelItem *cacheItem = m_cache.at(cacheIndex);
+ if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0 && cacheItem->object) {
+ QObject *object = cacheItem->object;
+ cacheItem->destroyObject();
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object))
+ emitDestroyingPackage(package);
+ else
+ emitDestroyingItem(object);
+ cacheItem->scriptRef -= 1;
+ }
+ if (!cacheItem->isReferenced()) {
+ m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
+ m_cache.removeAt(cacheIndex);
+ delete cacheItem;
+ --cacheIndex;
+ ++removedCache;
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ } else if (remove.groups() == cacheItem->groups) {
+ cacheItem->groups = 0;
+ if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
+ for (int i = 1; i < m_groupCount; ++i)
+ incubationTask->index[i] = -1;
+ }
+ if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
+ for (int i = 1; i < m_groupCount; ++i)
+ attached->m_currentIndex[i] = -1;
+ }
+ } else {
+ if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (remove.inGroup(i))
+ incubationTask->index[i] = remove.index[i];
+ }
+ }
+ if (QQmlDelegateModelAttached *attached = cacheItem->attached) {
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (remove.inGroup(i))
+ attached->m_currentIndex[i] = remove.index[i];
+ }
+ }
+ cacheItem->groups &= ~remove.flags;
+ }
+ }
+ }
+ }
+
+ for (; cacheIndex < m_cache.count(); ++cacheIndex)
+ incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed);
+}
+
+void QQmlDelegateModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &removes)
+{
+ QVarLengthArray<QVector<QQmlChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
+ itemsRemoved(removes, &translatedRemoves);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.remove(translatedRemoves.at(i));
+}
+
+void QQmlDelegateModel::_q_itemsRemoved(int index, int count)
+{
+ Q_D(QQmlDelegateModel);
+ if (count <= 0|| !d->m_complete)
+ return;
+
+ d->m_count -= count;
+
+ for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = d->m_cache.at(i);
+ if (item->modelIndex() >= index + count)
+ item->setModelIndex(item->modelIndex() - count);
+ else if (item->modelIndex() >= index)
+ item->setModelIndex(-1);
+ }
+
+ QVector<Compositor::Remove> removes;
+ d->m_compositor.listItemsRemoved(&d->m_adaptorModel, index, count, &removes);
+ d->itemsRemoved(removes);
+
+ d->emitChanges();
+}
+
+void QQmlDelegateModelPrivate::itemsMoved(
+ const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts)
+{
+ QHash<int, QList<QQmlDelegateModelItem *> > movedItems;
+
+ QVarLengthArray<QVector<QQmlChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
+ itemsRemoved(removes, &translatedRemoves, &movedItems);
+
+ QVarLengthArray<QVector<QQmlChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
+ itemsInserted(inserts, &translatedInserts, &movedItems);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(movedItems.isEmpty());
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i) {
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->changeSet.move(
+ translatedRemoves.at(i),
+ translatedInserts.at(i));
+ }
+}
+
+void QQmlDelegateModel::_q_itemsMoved(int from, int to, int count)
+{
+ Q_D(QQmlDelegateModel);
+ if (count <= 0 || !d->m_complete)
+ return;
+
+ const int minimum = qMin(from, to);
+ const int maximum = qMax(from, to) + count;
+ const int difference = from > to ? count : -count;
+
+ for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = d->m_cache.at(i);
+ if (item->modelIndex() >= from && item->modelIndex() < from + count)
+ item->setModelIndex(item->modelIndex() - from + to);
+ else if (item->modelIndex() >= minimum && item->modelIndex() < maximum)
+ item->setModelIndex(item->modelIndex() + difference);
+ }
+
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+ d->m_compositor.listItemsMoved(&d->m_adaptorModel, from, to, count, &removes, &inserts);
+ d->itemsMoved(removes, inserts);
+ d->emitChanges();
+}
+
+template <typename T> v8::Local<v8::Array>
+QQmlDelegateModelPrivate::buildChangeList(const QVector<T> &changes)
+{
+ v8::Local<v8::Array> indexes = v8::Array::New(changes.count());
+ v8::Local<v8::String> indexKey = v8::String::New("index");
+ v8::Local<v8::String> countKey = v8::String::New("count");
+ v8::Local<v8::String> moveIdKey = v8::String::New("moveId");
+
+ for (int i = 0; i < changes.count(); ++i) {
+ v8::Local<v8::Object> object = v8::Object::New();
+ object->Set(indexKey, v8::Integer::New(changes.at(i).index));
+ object->Set(countKey, v8::Integer::New(changes.at(i).count));
+ object->Set(moveIdKey, changes.at(i).moveId != -1 ? v8::Integer::New(changes.at(i).count) : v8::Undefined());
+ indexes->Set(i, object);
+ }
+ return indexes;
+}
+
+void QQmlDelegateModelPrivate::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset)
+{
+ Q_Q(QQmlDelegateModel);
+ emit q->modelUpdated(changeSet, reset);
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+}
+
+void QQmlDelegateModelPrivate::emitChanges()
+{
+ if (m_transaction || !m_complete || !m_context->isValid())
+ return;
+
+ m_transaction = true;
+ QV8Engine *engine = QQmlEnginePrivate::getV8Engine(m_context->engine());
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitChanges(engine);
+ m_transaction = false;
+
+ const bool reset = m_reset;
+ m_reset = false;
+ for (int i = 1; i < m_groupCount; ++i)
+ QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
+
+ foreach (QQmlDelegateModelItem *cacheItem, m_cache) {
+ if (cacheItem->attached)
+ cacheItem->attached->emitChanges();
+ }
+}
+
+void QQmlDelegateModel::_q_modelReset()
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_delegate)
+ return;
+
+ int oldCount = d->m_count;
+ d->m_adaptorModel.rootIndex = QModelIndex();
+
+ if (d->m_complete) {
+ d->m_count = d->m_adaptorModel.count();
+
+ for (int i = 0, c = d->m_cache.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = d->m_cache.at(i);
+ if (item->modelIndex() != -1)
+ item->setModelIndex(-1);
+ }
+
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+ if (oldCount)
+ d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes);
+ if (d->m_count)
+ d->m_compositor.listItemsInserted(&d->m_adaptorModel, 0, d->m_count, &inserts);
+ d->itemsMoved(removes, inserts);
+ d->m_reset = true;
+
+ if (d->m_adaptorModel.canFetchMore())
+ d->m_adaptorModel.fetchMore();
+
+ d->emitChanges();
+ }
+ emit rootIndexChanged();
+}
+
+void QQmlDelegateModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
+{
+ Q_D(QQmlDelegateModel);
+ if (parent == d->m_adaptorModel.rootIndex)
+ _q_itemsInserted(begin, end - begin + 1);
+}
+
+void QQmlDelegateModel::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end)
+{
+ Q_D(QQmlDelegateModel);
+ if (!d->m_adaptorModel.rootIndex.isValid())
+ return;
+ const QModelIndex index = d->m_adaptorModel.rootIndex;
+ if (index.parent() == parent && index.row() >= begin && index.row() <= end) {
+ const int oldCount = d->m_count;
+ d->m_count = 0;
+ d->m_adaptorModel.invalidateModel(this);
+
+ if (d->m_complete && oldCount > 0) {
+ QVector<Compositor::Remove> removes;
+ d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes);
+ d->itemsRemoved(removes);
+ d->emitChanges();
+ }
+ }
+}
+
+void QQmlDelegateModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
+{
+ Q_D(QQmlDelegateModel);
+ if (parent == d->m_adaptorModel.rootIndex)
+ _q_itemsRemoved(begin, end - begin + 1);
+}
+
+void QQmlDelegateModel::_q_rowsMoved(
+ const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationRow)
+{
+ Q_D(QQmlDelegateModel);
+ const int count = sourceEnd - sourceStart + 1;
+ if (destinationParent == d->m_adaptorModel.rootIndex && sourceParent == d->m_adaptorModel.rootIndex) {
+ _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow - count, count);
+ } else if (sourceParent == d->m_adaptorModel.rootIndex) {
+ _q_itemsRemoved(sourceStart, count);
+ } else if (destinationParent == d->m_adaptorModel.rootIndex) {
+ _q_itemsInserted(destinationRow, count);
+ }
+}
+
+void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
+{
+ Q_D(QQmlDelegateModel);
+ if (begin.parent() == d->m_adaptorModel.rootIndex)
+ _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, roles);
+}
+
+void QQmlDelegateModel::_q_layoutChanged()
+{
+ Q_D(QQmlDelegateModel);
+ _q_itemsChanged(0, d->m_count, QVector<int>());
+}
+
+QQmlDelegateModelAttached *QQmlDelegateModel::qmlAttachedProperties(QObject *obj)
+{
+ if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(obj)) {
+ if (cacheItem->object == obj) { // Don't create attached item for child objects.
+ cacheItem->attached = new QQmlDelegateModelAttached(cacheItem, obj);
+ return cacheItem->attached;
+ }
+ }
+ return new QQmlDelegateModelAttached(obj);
+}
+
+bool QQmlDelegateModelPrivate::insert(
+ Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups)
+{
+ if (!m_context->isValid())
+ return false;
+
+ QQmlDelegateModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), -1);
+ if (!cacheItem)
+ return false;
+
+ v8::Local<v8::Array> propertyNames = object->GetPropertyNames();
+ for (uint i = 0; i < propertyNames->Length(); ++i) {
+ v8::Local<v8::String> propertyName = propertyNames->Get(i)->ToString();
+ cacheItem->setValue(
+ m_cacheMetaType->v8Engine->toString(propertyName),
+ m_cacheMetaType->v8Engine->toVariant(object->Get(propertyName), QVariant::Invalid));
+ }
+
+ cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
+
+ // Must be before the new object is inserted into the cache or its indexes will be adjusted too.
+ itemsInserted(QVector<Compositor::Insert>() << Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag));
+
+ before = m_compositor.insert(before, 0, 0, 1, cacheItem->groups);
+ m_cache.insert(before.cacheIndex, cacheItem);
+
+ return true;
+}
+
+//============================================================================
+
+QQmlDelegateModelItemMetaType::QQmlDelegateModelItemMetaType(
+ QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
+ : model(model)
+ , groupCount(groupNames.count() + 1)
+ , v8Engine(engine)
+ , metaObject(0)
+ , groupNames(groupNames)
+{
+}
+
+QQmlDelegateModelItemMetaType::~QQmlDelegateModelItemMetaType()
+{
+ if (metaObject)
+ metaObject->release();
+ qPersistentDispose(constructor);
+}
+
+void QQmlDelegateModelItemMetaType::initializeMetaObject()
+{
+ QMetaObjectBuilder builder;
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ builder.setClassName(QQmlDelegateModelAttached::staticMetaObject.className());
+ builder.setSuperClass(&QQmlDelegateModelAttached::staticMetaObject);
+
+ int notifierId = 0;
+ for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ QString propertyName = QStringLiteral("in") + groupNames.at(i);
+ propertyName.replace(2, 1, propertyName.at(2).toUpper());
+ builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
+ QMetaPropertyBuilder propertyBuilder = builder.addProperty(
+ propertyName.toUtf8(), "bool", notifierId);
+ propertyBuilder.setWritable(true);
+ }
+ for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ const QString propertyName = groupNames.at(i) + QStringLiteral("Index");
+ builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
+ QMetaPropertyBuilder propertyBuilder = builder.addProperty(
+ propertyName.toUtf8(), "int", notifierId);
+ propertyBuilder.setWritable(true);
+ }
+
+ metaObject = new QQmlDelegateModelAttachedMetaObject(this, builder.toMetaObject());
+}
+
+void QQmlDelegateModelItemMetaType::initializeConstructor()
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(v8Engine->context());
+
+ QQmlDelegateModelEngineData *data = engineData(v8Engine);
+
+ constructor = qPersistentNew(v8::ObjectTemplate::New());
+
+ constructor->SetHasExternalResource(true);
+ constructor->SetAccessor(data->model(), get_model);
+ constructor->SetAccessor(data->groups(), get_groups, set_groups);
+ constructor->SetAccessor(data->isUnresolved(), get_member, 0, v8::Int32::New(30));
+ constructor->SetAccessor(data->inItems(), get_member, set_member, v8::Int32::New(1));
+ constructor->SetAccessor(data->inPersistedItems(), get_member, set_member, v8::Int32::New(2));
+ constructor->SetAccessor(data->itemsIndex(), get_index, 0, v8::Int32::New(1));
+ constructor->SetAccessor(data->persistedItemsIndex(), get_index, 0, v8::Int32::New(2));
+
+ for (int i = 2; i < groupNames.count(); ++i) {
+ QString propertyName = QStringLiteral("in") + groupNames.at(i);
+ propertyName.replace(2, 1, propertyName.at(2).toUpper());
+ constructor->SetAccessor(
+ v8Engine->toString(propertyName), get_member, set_member, v8::Int32::New(i + 1));
+ }
+ for (int i = 2; i < groupNames.count(); ++i) {
+ const QString propertyName = groupNames.at(i) + QStringLiteral("Index");
+ constructor->SetAccessor(
+ v8Engine->toString(propertyName), get_index, 0, v8::Int32::New(i + 1));
+ }
+}
+
+int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
+{
+ int groupFlags = 0;
+ foreach (const QString &groupName, groups) {
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ }
+ return groupFlags;
+}
+
+int QQmlDelegateModelItemMetaType::parseGroups(const v8::Local<v8::Value> &groups) const
+{
+ int groupFlags = 0;
+ if (groups->IsString()) {
+ const QString groupName = v8Engine->toString(groups);
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ } else if (groups->IsArray()) {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(groups);
+ for (uint i = 0; i < array->Length(); ++i) {
+ const QString groupName = v8Engine->toString(array->Get(i));
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ }
+ }
+ return groupFlags;
+}
+
+v8::Handle<v8::Value> QQmlDelegateModelItemMetaType::get_model(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object");
+ if (!cacheItem->metaType->model)
+ return v8::Undefined();
+
+ return cacheItem->get();
+}
+
+v8::Handle<v8::Value> QQmlDelegateModelItemMetaType::get_groups(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object");
+
+ QStringList groups;
+ for (int i = 1; i < cacheItem->metaType->groupCount; ++i) {
+ if (cacheItem->groups & (1 << i))
+ groups.append(cacheItem->metaType->groupNames.at(i - 1));
+ }
+
+ return cacheItem->engine->fromVariant(groups);
+}
+
+void QQmlDelegateModelItemMetaType::set_groups(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE_SETTER(cacheItem, "Not a valid VisualData object");
+
+ if (!cacheItem->metaType->model)
+ return;
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model);
+
+ const int groupFlags = model->m_cacheMetaType->parseGroups(value);
+ const int cacheIndex = model->m_cache.indexOf(cacheItem);
+ Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
+ model->setGroups(it, 1, Compositor::Cache, groupFlags);
+}
+
+v8::Handle<v8::Value> QQmlDelegateModelItemMetaType::get_member(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object");
+
+ return v8::Boolean::New(cacheItem->groups & (1 << info.Data()->Int32Value()));
+}
+
+void QQmlDelegateModelItemMetaType::set_member(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE_SETTER(cacheItem, "Not a valid VisualData object");
+
+ if (!cacheItem->metaType->model)
+ return;
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model);
+
+ Compositor::Group group = Compositor::Group(info.Data()->Int32Value());
+ const bool member = value->BooleanValue();
+ const int groupFlag = (1 << group);
+ if (member == ((cacheItem->groups & groupFlag) != 0))
+ return;
+
+ const int cacheIndex = model->m_cache.indexOf(cacheItem);
+ Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
+ if (member)
+ model->addGroups(it, 1, Compositor::Cache, groupFlag);
+ else
+ model->removeGroups(it, 1, Compositor::Cache, groupFlag);
+}
+
+v8::Handle<v8::Value> QQmlDelegateModelItemMetaType::get_index(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *cacheItem = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object");
+
+ return v8::Integer::New(cacheItem->groupIndex(Compositor::Group(info.Data()->Int32Value())));
+}
+
+
+//---------------------------------------------------------------------------
+
+QQmlDelegateModelItem::QQmlDelegateModelItem(
+ QQmlDelegateModelItemMetaType *metaType, int modelIndex)
+ : QV8ObjectResource(metaType->v8Engine)
+ , metaType(metaType)
+ , contextData(0)
+ , object(0)
+ , attached(0)
+ , incubationTask(0)
+ , objectRef(0)
+ , scriptRef(0)
+ , groups(0)
+ , index(modelIndex)
+{
+ metaType->addref();
+}
+
+QQmlDelegateModelItem::~QQmlDelegateModelItem()
+{
+ Q_ASSERT(scriptRef == 0);
+ Q_ASSERT(objectRef == 0);
+ Q_ASSERT(!object);
+
+ if (incubationTask && metaType->model)
+ QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
+
+ metaType->release();
+
+}
+
+void QQmlDelegateModelItem::Dispose()
+{
+ --scriptRef;
+ if (isReferenced())
+ return;
+
+ if (metaType->model) {
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(metaType->model);
+ model->removeCacheItem(this);
+ }
+ delete this;
+}
+
+/*
+ This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData
+ arguments instead of QQmlContext which means we don't have to construct the rather weighty
+ wrapper class for every delegate item.
+*/
+void QQmlDelegateModelItem::incubateObject(
+ QQmlComponent *component,
+ QQmlEngine *engine,
+ QQmlContextData *context,
+ QQmlContextData *forContext)
+{
+ QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask);
+ QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
+ QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component);
+
+ incubatorPriv->compiledData = componentPriv->cc;
+ incubatorPriv->compiledData->addref();
+ incubatorPriv->vme.init(
+ context,
+ componentPriv->cc,
+ componentPriv->start,
+ componentPriv->creationContext);
+
+ enginePriv->incubate(*incubationTask, forContext);
+}
+
+void QQmlDelegateModelItem::destroyObject()
+{
+ Q_ASSERT(object);
+ Q_ASSERT(contextData);
+
+ QObjectPrivate *p = QObjectPrivate::get(object);
+ Q_ASSERT(p->declarativeData);
+ QQmlData *data = static_cast<QQmlData*>(p->declarativeData);
+ if (data->ownContext && data->context)
+ data->context->clearContext();
+ object->deleteLater();
+
+ if (attached) {
+ attached->m_cacheItem = 0;
+ attached = 0;
+ }
+
+ contextData->destroy();
+ contextData = 0;
+ object = 0;
+}
+
+QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object)
+{
+ QObjectPrivate *p = QObjectPrivate::get(object);
+ QQmlContextData *context = p->declarativeData
+ ? static_cast<QQmlData *>(p->declarativeData)->context
+ : 0;
+ for (context = context ? context->parent : 0; context; context = context->parent) {
+ if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>(
+ context->contextObject)) {
+ return cacheItem;
+ }
+ }
+ return 0;
+}
+
+int QQmlDelegateModelItem::groupIndex(Compositor::Group group)
+{
+ if (QQmlDelegateModelPrivate * const model = metaType->model
+ ? QQmlDelegateModelPrivate::get(metaType->model)
+ : 0) {
+ return model->m_compositor.find(Compositor::Cache, model->m_cache.indexOf(this)).index[group];
+ }
+ return -1;
+}
+
+//---------------------------------------------------------------------------
+
+QQmlDelegateModelAttachedMetaObject::QQmlDelegateModelAttachedMetaObject(
+ QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject)
+ : metaType(metaType)
+ , metaObject(metaObject)
+ , memberPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount())
+ , indexPropertyOffset(QQmlDelegateModelAttached::staticMetaObject.propertyCount() + metaType->groupNames.count())
+{
+ // Don't reference count the meta-type here as that would create a circular reference.
+ // Instead we rely the fact that the meta-type's reference count can't reach 0 without first
+ // destroying all delegates with attached objects.
+ *static_cast<QMetaObject *>(this) = *metaObject;
+}
+
+QQmlDelegateModelAttachedMetaObject::~QQmlDelegateModelAttachedMetaObject()
+{
+ ::free(metaObject);
+}
+
+void QQmlDelegateModelAttachedMetaObject::objectDestroyed(QObject *)
+{
+ release();
+}
+
+int QQmlDelegateModelAttachedMetaObject::metaCall(QObject *object, QMetaObject::Call call, int _id, void **arguments)
+{
+ QQmlDelegateModelAttached *attached = static_cast<QQmlDelegateModelAttached *>(object);
+ if (call == QMetaObject::ReadProperty) {
+ if (_id >= indexPropertyOffset) {
+ Compositor::Group group = Compositor::Group(_id - indexPropertyOffset + 1);
+ *static_cast<int *>(arguments[0]) = attached->m_currentIndex[group];
+ return -1;
+ } else if (_id >= memberPropertyOffset) {
+ Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1);
+ *static_cast<bool *>(arguments[0]) = attached->m_cacheItem->groups & (1 << group);
+ return -1;
+ }
+ } else if (call == QMetaObject::WriteProperty) {
+ if (_id >= memberPropertyOffset) {
+ if (!metaType->model)
+ return -1;
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(metaType->model);
+ Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1);
+ const int groupFlag = 1 << group;
+ const bool member = attached->m_cacheItem->groups & groupFlag;
+ if (member && !*static_cast<bool *>(arguments[0])) {
+ Compositor::iterator it = model->m_compositor.find(
+ group, attached->m_currentIndex[group]);
+ model->removeGroups(it, 1, group, groupFlag);
+ } else if (!member && *static_cast<bool *>(arguments[0])) {
+ for (int i = 1; i < metaType->groupCount; ++i) {
+ if (attached->m_cacheItem->groups & (1 << i)) {
+ Compositor::iterator it = model->m_compositor.find(
+ Compositor::Group(i), attached->m_currentIndex[i]);
+ model->addGroups(it, 1, Compositor::Group(i), groupFlag);
+ break;
+ }
+ }
+ }
+ return -1;
+ }
+ }
+ return attached->qt_metacall(call, _id, arguments);
+}
+
+QQmlDelegateModelAttached::QQmlDelegateModelAttached(QObject *parent)
+ : m_cacheItem(0)
+ , m_previousGroups(0)
+{
+ QQml_setParent_noEvent(this, parent);
+}
+
+QQmlDelegateModelAttached::QQmlDelegateModelAttached(
+ QQmlDelegateModelItem *cacheItem, QObject *parent)
+ : m_cacheItem(cacheItem)
+ , m_previousGroups(cacheItem->groups)
+{
+ QQml_setParent_noEvent(this, parent);
+ if (QQDMIncubationTask *incubationTask = m_cacheItem->incubationTask) {
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i)
+ m_currentIndex[i] = m_previousIndex[i] = incubationTask->index[i];
+ } else {
+ QQmlDelegateModelPrivate * const model = QQmlDelegateModelPrivate::get(m_cacheItem->metaType->model);
+ Compositor::iterator it = model->m_compositor.find(
+ Compositor::Cache, model->m_cache.indexOf(m_cacheItem));
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i)
+ m_currentIndex[i] = m_previousIndex[i] = it.index[i];
+ }
+
+ if (!cacheItem->metaType->metaObject)
+ cacheItem->metaType->initializeMetaObject();
+
+ QObjectPrivate::get(this)->metaObject = cacheItem->metaType->metaObject;
+ cacheItem->metaType->metaObject->addref();
+}
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::DelegateModel::model
+
+ This attached property holds the visual data model this delegate instance belongs to.
+
+ It is attached to each instance of the delegate.
+*/
+
+QQmlDelegateModel *QQmlDelegateModelAttached::model() const
+{
+ return m_cacheItem ? m_cacheItem->metaType->model : 0;
+}
+
+/*!
+ \qmlattachedproperty stringlist QtQml.Models2::DelegateModel::groups
+
+ This attached property holds the name of DelegateModelGroups the item belongs to.
+
+ It is attached to each instance of the delegate.
+*/
+
+QStringList QQmlDelegateModelAttached::groups() const
+{
+ QStringList groups;
+
+ if (!m_cacheItem)
+ return groups;
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ if (m_cacheItem->groups & (1 << i))
+ groups.append(m_cacheItem->metaType->groupNames.at(i - 1));
+ }
+ return groups;
+}
+
+void QQmlDelegateModelAttached::setGroups(const QStringList &groups)
+{
+ if (!m_cacheItem)
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_cacheItem->metaType->model);
+
+ const int groupFlags = model->m_cacheMetaType->parseGroups(groups);
+ const int cacheIndex = model->m_cache.indexOf(m_cacheItem);
+ Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
+ model->setGroups(it, 1, Compositor::Cache, groupFlags);
+}
+
+/*!
+ \qmlattachedproperty bool QtQml.Models2::DelegateModel::isUnresolved
+
+ This attached property holds whether the visual item is bound to a data model index.
+ Returns true if the item is not bound to the model, and false if it is.
+
+ An unresolved item can be bound to the data model using the DelegateModelGroup::resolve()
+ function.
+
+ It is attached to each instance of the delegate.
+*/
+
+bool QQmlDelegateModelAttached::isUnresolved() const
+{
+ if (!m_cacheItem)
+ return false;
+
+ return m_cacheItem->groups & Compositor::UnresolvedFlag;
+}
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::DelegateModel::inItems
+
+ This attached property holds whether the item belongs to the default \l items DelegateModelGroup.
+
+ Changing this property will add or remove the item from the items group.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::DelegateModel::itemsIndex
+
+ This attached property holds the index of the item in the default \l items DelegateModelGroup.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::DelegateModel::inPersistedItems
+
+ This attached property holds whether the item belongs to the \l persistedItems DelegateModelGroup.
+
+ Changing this property will add or remove the item from the items group. Change with caution
+ as removing an item from the persistedItems group will destroy the current instance if it is
+ not referenced by a model.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::DelegateModel::persistedItemsIndex
+
+ This attached property holds the index of the item in the \l persistedItems DelegateModelGroup.
+
+ It is attached to each instance of the delegate.
+*/
+
+void QQmlDelegateModelAttached::emitChanges()
+{
+ const int groupChanges = m_previousGroups ^ m_cacheItem->groups;
+ m_previousGroups = m_cacheItem->groups;
+
+ int indexChanges = 0;
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ if (m_previousIndex[i] != m_currentIndex[i]) {
+ m_previousIndex[i] = m_currentIndex[i];
+ indexChanges |= (1 << i);
+ }
+ }
+
+ int notifierId = 0;
+ const QMetaObject *meta = metaObject();
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ if (groupChanges & (1 << i))
+ QMetaObject::activate(this, meta, notifierId, 0);
+ }
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ if (indexChanges & (1 << i))
+ QMetaObject::activate(this, meta, notifierId, 0);
+ }
+
+ if (groupChanges)
+ emit groupsChanged();
+}
+
+//============================================================================
+
+void QQmlDelegateModelGroupPrivate::setModel(QQmlDelegateModel *m, Compositor::Group g)
+{
+ Q_ASSERT(!model);
+ model = m;
+ group = g;
+}
+
+bool QQmlDelegateModelGroupPrivate::isChangedConnected()
+{
+ Q_Q(QQmlDelegateModelGroup);
+ IS_SIGNAL_CONNECTED(q, QQmlDelegateModelGroup, changed, (const QQmlV8Handle &,const QQmlV8Handle &));
+}
+
+void QQmlDelegateModelGroupPrivate::emitChanges(QV8Engine *engine)
+{
+ Q_Q(QQmlDelegateModelGroup);
+ if (isChangedConnected() && !changeSet.isEmpty()) {
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(engine->context());
+ v8::Local<v8::Object> removed = engineData(engine)->array(engine, changeSet.removes());
+ v8::Local<v8::Object> inserted = engineData(engine)->array(engine, changeSet.inserts());
+ emit q->changed(QQmlV8Handle::fromHandle(removed), QQmlV8Handle::fromHandle(inserted));
+ }
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+}
+
+void QQmlDelegateModelGroupPrivate::emitModelUpdated(bool reset)
+{
+ for (QQmlDelegateModelGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->emitModelUpdated(changeSet, reset);
+ changeSet.clear();
+}
+
+void QQmlDelegateModelGroupPrivate::createdPackage(int index, QQuickPackage *package)
+{
+ for (QQmlDelegateModelGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->createdPackage(index, package);
+}
+
+void QQmlDelegateModelGroupPrivate::initPackage(int index, QQuickPackage *package)
+{
+ for (QQmlDelegateModelGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->initPackage(index, package);
+}
+
+void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
+{
+ for (QQmlDelegateModelGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->destroyingPackage(package);
+}
+
+/*!
+ \qmltype DelegateModelGroup
+ \instantiates QQmlDelegateModelGroup
+ \inqmlmodule QtQuick 2
+ \ingroup qtquick-models
+ \brief Encapsulates a filtered set of visual data items
+
+ The DelegateModelGroup type provides a means to address the model data of a DelegateModel's
+ delegate items, as well as sort and filter these delegate items.
+
+ The initial set of instantiable delegate items in a DelegateModel is represented
+ by its \l {QtQml.Models2::DelegateModel::items}{items} group, which normally directly reflects
+ the contents of the model assigned to DelegateModel::model. This set can be changed to
+ the contents of any other member of DelegateModel::groups by assigning the \l name of that
+ DelegateModelGroup to the DelegateModel::filterOnGroup property.
+
+ The data of an item in a DelegateModelGroup can be accessed using the get() function, which returns
+ information about group membership and indexes as well as model data. In combination
+ with the move() function this can be used to implement view sorting, with remove() to filter
+ items out of a view, or with setGroups() and \l Package delegates to categorize items into
+ different views.
+
+ Data from models can be supplemented by inserting data directly into a DelegateModelGroup
+ with the insert() function. This can be used to introduce mock items into a view, or
+ placeholder items that are later \l {resolve()}{resolved} to real model data when it becomes
+ available.
+
+ Delegate items can also be be instantiated directly from a DelegateModelGroup using the
+ create() function, making it possible to use DelegateModel without an accompanying view
+ type or to cherry-pick specific items that should be instantiated irregardless of whether
+ they're currently within a view's visible area.
+
+ \sa {QML Dynamic View Ordering Tutorial}
+*/
+/*!
+ \qmltype DelegateModelGroup
+ \instantiates QQmlDelegateModelGroup
+ \inqmlmodule QtQml.Models 2
+ \brief Encapsulates a filtered set of visual data items
+
+ The DelegateModelGroup type provides a means to address the model data of a DelegateModel's
+ delegate items, as well as sort and filter these delegate items.
+
+ This element is also available as DelegateModelGroup in the QtQuick module. For full details,
+ see the \l DelegateModelGroup documentation.
+
+ \sa {QtQuick::DelegateModelGroup}
+*/
+
+
+QQmlDelegateModelGroup::QQmlDelegateModelGroup(QObject *parent)
+ : QObject(*new QQmlDelegateModelGroupPrivate, parent)
+{
+}
+
+QQmlDelegateModelGroup::QQmlDelegateModelGroup(
+ const QString &name, QQmlDelegateModel *model, int index, QObject *parent)
+ : QObject(*new QQmlDelegateModelGroupPrivate, parent)
+{
+ Q_D(QQmlDelegateModelGroup);
+ d->name = name;
+ d->setModel(model, Compositor::Group(index));
+}
+
+QQmlDelegateModelGroup::~QQmlDelegateModelGroup()
+{
+}
+
+/*!
+ \qmlproperty string QtQml.Models2::DelegateModelGroup::name
+
+ This property holds the name of the group.
+
+ Each group in a model must have a unique name starting with a lower case letter.
+*/
+
+QString QQmlDelegateModelGroup::name() const
+{
+ Q_D(const QQmlDelegateModelGroup);
+ return d->name;
+}
+
+void QQmlDelegateModelGroup::setName(const QString &name)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (d->model)
+ return;
+ if (d->name != name) {
+ d->name = name;
+ emit nameChanged();
+ }
+}
+
+/*!
+ \qmlproperty int QtQml.Models2::DelegateModelGroup::count
+
+ This property holds the number of items in the group.
+*/
+
+int QQmlDelegateModelGroup::count() const
+{
+ Q_D(const QQmlDelegateModelGroup);
+ if (!d->model)
+ return 0;
+ return QQmlDelegateModelPrivate::get(d->model)->m_compositor.count(d->group);
+}
+
+/*!
+ \qmlproperty bool QtQml.Models2::DelegateModelGroup::includeByDefault
+
+ This property holds whether new items are assigned to this group by default.
+*/
+
+bool QQmlDelegateModelGroup::defaultInclude() const
+{
+ Q_D(const QQmlDelegateModelGroup);
+ return d->defaultInclude;
+}
+
+void QQmlDelegateModelGroup::setDefaultInclude(bool include)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (d->defaultInclude != include) {
+ d->defaultInclude = include;
+
+ if (d->model) {
+ if (include)
+ QQmlDelegateModelPrivate::get(d->model)->m_compositor.setDefaultGroup(d->group);
+ else
+ QQmlDelegateModelPrivate::get(d->model)->m_compositor.clearDefaultGroup(d->group);
+ }
+ emit defaultIncludeChanged();
+ }
+}
+
+/*!
+ \qmlmethod object QtQml.Models2::DelegateModelGroup::get(int index)
+
+ Returns a javascript object describing the item at \a index in the group.
+
+ The returned object contains the same information that is available to a delegate from the
+ DelegateModel attached as well as the model for that item. It has the properties:
+
+ \list
+ \li \b model The model data of the item. This is the same as the model context property in
+ a delegate
+ \li \b groups A list the of names of groups the item is a member of. This property can be
+ written to change the item's membership.
+ \li \b inItems Whether the item belongs to the \l {QtQml.Models2::DelegateModel::items}{items} group.
+ Writing to this property will add or remove the item from the group.
+ \li \b itemsIndex The index of the item within the \l {QtQml.Models2::DelegateModel::items}{items} group.
+ \li \b {in<GroupName>} Whether the item belongs to the dynamic group \e groupName. Writing to
+ this property will add or remove the item from the group.
+ \li \b {<groupName>Index} The index of the item within the dynamic group \e groupName.
+ \li \b isUnresolved Whether the item is bound to an index in the model assigned to
+ DelegateModel::model. Returns true if the item is not bound to the model, and false if it is.
+ \endlist
+*/
+
+QQmlV8Handle QQmlDelegateModelGroup::get(int index)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (!d->model)
+ return QQmlV8Handle::fromHandle(v8::Undefined());;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+ if (!model->m_context->isValid()) {
+ return QQmlV8Handle::fromHandle(v8::Undefined());
+ } else if (index < 0 || index >= model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("get: index out of range");
+ return QQmlV8Handle::fromHandle(v8::Undefined());
+ }
+
+ Compositor::iterator it = model->m_compositor.find(d->group, index);
+ QQmlDelegateModelItem *cacheItem = it->inCache()
+ ? model->m_cache.at(it.cacheIndex)
+ : 0;
+
+ if (!cacheItem) {
+ cacheItem = model->m_adaptorModel.createItem(
+ model->m_cacheMetaType, model->m_context->engine(), it.modelIndex());
+ if (!cacheItem)
+ return QQmlV8Handle::fromHandle(v8::Undefined());
+ cacheItem->groups = it->flags;
+
+ model->m_cache.insert(it.cacheIndex, cacheItem);
+ model->m_compositor.setFlags(it, 1, Compositor::CacheFlag);
+ }
+
+ if (model->m_cacheMetaType->constructor.IsEmpty())
+ model->m_cacheMetaType->initializeConstructor();
+ v8::Local<v8::Object> handle = model->m_cacheMetaType->constructor->NewInstance();
+ handle->SetExternalResource(cacheItem);
+ ++cacheItem->scriptRef;
+
+ return QQmlV8Handle::fromHandle(handle);
+}
+
+bool QQmlDelegateModelGroupPrivate::parseIndex(
+ const v8::Local<v8::Value> &value, int *index, Compositor::Group *group) const
+{
+ if (value->IsInt32()) {
+ *index = value->Int32Value();
+ return true;
+ } else if (value->IsObject()) {
+ v8::Local<v8::Object> object = value->ToObject();
+ QQmlDelegateModelItem * const cacheItem = v8_resource_cast<QQmlDelegateModelItem>(object);
+ if (QQmlDelegateModelPrivate *model = cacheItem && cacheItem->metaType->model
+ ? QQmlDelegateModelPrivate::get(cacheItem->metaType->model)
+ : 0) {
+ *index = model->m_cache.indexOf(cacheItem);
+ *group = Compositor::Cache;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::insert(int index, jsdict data, array groups = undefined)
+ \qmlmethod QtQml.Models2::DelegateModelGroup::insert(jsdict data, var groups = undefined)
+
+ Creates a new entry at \a index in a DelegateModel with the values from \a data that
+ correspond to roles in the model assigned to DelegateModel::model.
+
+ If no index is supplied the data is appended to the model.
+
+ The optional \a groups parameter identifies the groups the new entry should belong to,
+ if unspecified this is equal to the group insert was called on.
+
+ Data inserted into a DelegateModel can later be merged with an existing entry in
+ DelegateModel::model using the \l resolve() function. This can be used to create placeholder
+ items that are later replaced by actual data.
+*/
+
+void QQmlDelegateModelGroup::insert(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+
+ int index = model->m_compositor.count(d->group);
+ Compositor::Group group = d->group;
+
+ if (args->Length() == 0)
+ return;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (d->parseIndex(v, &index, &group)) {
+ if (index < 0 || index > model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("insert: index out of range");
+ return;
+ }
+ if (++i == args->Length())
+ return;
+ v = (*args)[i];
+ }
+
+ Compositor::insert_iterator before = index < model->m_compositor.count(group)
+ ? model->m_compositor.findInsertPosition(group, index)
+ : model->m_compositor.end();
+
+ int groups = 1 << d->group;
+ if (++i < args->Length())
+ groups |= model->m_cacheMetaType->parseGroups((*args)[i]);
+
+ if (v->IsArray()) {
+ return;
+ } else if (v->IsObject()) {
+ model->insert(before, v->ToObject(), groups);
+ model->emitChanges();
+ }
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::create(int index)
+ \qmlmethod QtQml.Models2::DelegateModelGroup::create(int index, jsdict data, array groups = undefined)
+ \qmlmethod QtQml.Models2::DelegateModelGroup::create(jsdict data, array groups = undefined)
+
+ Returns a reference to the instantiated item at \a index in the group.
+
+ If a \a data object is provided it will be \l {insert}{inserted} at \a index and an item
+ referencing this new entry will be returned. The optional \a groups parameter identifies
+ the groups the new entry should belong to, if unspecified this is equal to the group create()
+ was called on.
+
+ All items returned by create are added to the
+ \l {QtQml.Models2::DelegateModel::persistedItems}{persistedItems} group. Items in this
+ group remain instantiated when not referenced by any view.
+*/
+
+void QQmlDelegateModelGroup::create(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (!d->model)
+ return;
+
+ if (args->Length() == 0)
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+
+ int index = model->m_compositor.count(d->group);
+ Compositor::Group group = d->group;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (d->parseIndex(v, &index, &group))
+ ++i;
+
+ if (i < args->Length() && index >= 0 && index <= model->m_compositor.count(group)) {
+ v = (*args)[i];
+ if (v->IsObject()) {
+ int groups = 1 << d->group;
+ if (++i < args->Length())
+ groups |= model->m_cacheMetaType->parseGroups((*args)[i]);
+
+ Compositor::insert_iterator before = index < model->m_compositor.count(group)
+ ? model->m_compositor.findInsertPosition(group, index)
+ : model->m_compositor.end();
+
+ index = before.index[d->group];
+ group = d->group;
+
+ if (!model->insert(before, v->ToObject(), groups)) {
+ return;
+ }
+ }
+ }
+ if (index < 0 || index >= model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("create: index out of range");
+ return;
+ }
+
+ QObject *object = model->object(group, index, false);
+ if (object) {
+ QVector<Compositor::Insert> inserts;
+ Compositor::iterator it = model->m_compositor.find(group, index);
+ model->m_compositor.setFlags(it, 1, d->group, Compositor::PersistedFlag, &inserts);
+ model->itemsInserted(inserts);
+ model->m_cache.at(it.cacheIndex)->releaseObject();
+ }
+
+ args->returnValue(args->engine()->newQObject(object));
+ model->emitChanges();
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::resolve(int from, int to)
+
+ Binds an unresolved item at \a from to an item in DelegateModel::model at index \a to.
+
+ Unresolved items are entries whose data has been \l {insert()}{inserted} into a DelegateModelGroup
+ instead of being derived from a DelegateModel::model index. Resolving an item will replace
+ the item at the target index with the unresolved item. A resolved an item will reflect the data
+ of the source model at its bound index and will move when that index moves like any other item.
+
+ If a new item is replaced in the DelegateModelGroup onChanged() handler its insertion and
+ replacement will be communicated to views as an atomic operation, creating the appearance
+ that the model contents have not changed, or if the unresolved and model item are not adjacent
+ that the previously unresolved item has simply moved.
+
+*/
+void QQmlDelegateModelGroup::resolve(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (!d->model)
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+
+ if (args->Length() < 2)
+ return;
+
+ int from = -1;
+ int to = -1;
+ Compositor::Group fromGroup = d->group;
+ Compositor::Group toGroup = d->group;
+
+ v8::Local<v8::Value> v = (*args)[0];
+ if (d->parseIndex(v, &from, &fromGroup)) {
+ if (from < 0 || from >= model->m_compositor.count(fromGroup)) {
+ qmlInfo(this) << tr("resolve: from index out of range");
+ return;
+ }
+ } else {
+ qmlInfo(this) << tr("resolve: from index invalid");
+ return;
+ }
+
+ v = (*args)[1];
+ if (d->parseIndex(v, &to, &toGroup)) {
+ if (to < 0 || to >= model->m_compositor.count(toGroup)) {
+ qmlInfo(this) << tr("resolve: to index out of range");
+ return;
+ }
+ } else {
+ qmlInfo(this) << tr("resolve: to index invalid");
+ return;
+ }
+
+ Compositor::iterator fromIt = model->m_compositor.find(fromGroup, from);
+ Compositor::iterator toIt = model->m_compositor.find(toGroup, to);
+
+ if (!fromIt->isUnresolved()) {
+ qmlInfo(this) << tr("resolve: from is not an unresolved item");
+ return;
+ }
+ if (!toIt->list) {
+ qmlInfo(this) << tr("resolve: to is not a model item");
+ return;
+ }
+
+ const int unresolvedFlags = fromIt->flags;
+ const int resolvedFlags = toIt->flags;
+ const int resolvedIndex = toIt.modelIndex();
+ void * const resolvedList = toIt->list;
+
+ QQmlDelegateModelItem *cacheItem = model->m_cache.at(fromIt.cacheIndex);
+ cacheItem->groups &= ~Compositor::UnresolvedFlag;
+
+ if (toIt.cacheIndex > fromIt.cacheIndex)
+ toIt.decrementIndexes(1, unresolvedFlags);
+ if (!toIt->inGroup(fromGroup) || toIt.index[fromGroup] > from)
+ from += 1;
+
+ model->itemsMoved(
+ QVector<Compositor::Remove>() << Compositor::Remove(fromIt, 1, unresolvedFlags, 0),
+ QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, unresolvedFlags, 0));
+ model->itemsInserted(
+ QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, (resolvedFlags & ~unresolvedFlags) | Compositor::CacheFlag));
+ toIt.incrementIndexes(1, resolvedFlags | unresolvedFlags);
+ model->itemsRemoved(QVector<Compositor::Remove>() << Compositor::Remove(toIt, 1, resolvedFlags));
+
+ model->m_compositor.setFlags(toGroup, to, 1, unresolvedFlags & ~Compositor::UnresolvedFlag);
+ model->m_compositor.clearFlags(fromGroup, from, 1, unresolvedFlags);
+
+ if (resolvedFlags & Compositor::CacheFlag)
+ model->m_compositor.insert(Compositor::Cache, toIt.cacheIndex, resolvedList, resolvedIndex, 1, Compositor::CacheFlag);
+
+ Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
+
+ if (!cacheItem->isReferenced()) {
+ Q_ASSERT(toIt.cacheIndex == model->m_cache.indexOf(cacheItem));
+ model->m_cache.removeAt(toIt.cacheIndex);
+ model->m_compositor.clearFlags(Compositor::Cache, toIt.cacheIndex, 1, Compositor::CacheFlag);
+ delete cacheItem;
+ Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache));
+ } else {
+ cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex);
+ if (cacheItem->attached)
+ cacheItem->attached->emitUnresolvedChanged();
+ }
+
+ model->emitChanges();
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::remove(int index, int count)
+
+ Removes \a count items starting at \a index from the group.
+*/
+
+void QQmlDelegateModelGroup::remove(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ if (!d->model)
+ return;
+ Compositor::Group group = d->group;
+ int index = -1;
+ int count = 1;
+
+ if (args->Length() == 0)
+ return;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (!d->parseIndex(v, &index, &group)) {
+ qmlInfo(this) << tr("remove: invalid index");
+ return;
+ }
+
+ if (++i < args->Length()) {
+ v = (*args)[i];
+ if (v->IsInt32())
+ count = v->Int32Value();
+ }
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("remove: index out of range");
+ } else if (count != 0) {
+ Compositor::iterator it = model->m_compositor.find(group, index);
+ if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
+ qmlInfo(this) << tr("remove: invalid count");
+ } else {
+ model->removeGroups(it, count, d->group, 1 << d->group);
+ }
+ }
+}
+
+bool QQmlDelegateModelGroupPrivate::parseGroupArgs(
+ QQmlV8Function *args, Compositor::Group *group, int *index, int *count, int *groups) const
+{
+ if (!model || !QQmlDelegateModelPrivate::get(model)->m_cacheMetaType)
+ return false;
+
+ if (args->Length() < 2)
+ return false;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (!parseIndex(v, index, group))
+ return false;
+
+ v = (*args)[++i];
+ if (v->IsInt32()) {
+ *count = v->Int32Value();
+
+ if (++i == args->Length())
+ return false;
+ v = (*args)[i];
+ }
+
+ *groups = QQmlDelegateModelPrivate::get(model)->m_cacheMetaType->parseGroups(v);
+
+ return true;
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::addGroups(int index, int count, stringlist groups)
+
+ Adds \a count items starting at \a index to \a groups.
+*/
+
+void QQmlDelegateModelGroup::addGroups(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ Compositor::Group group = d->group;
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("addGroups: index out of range");
+ } else if (count != 0) {
+ Compositor::iterator it = model->m_compositor.find(group, index);
+ if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
+ qmlInfo(this) << tr("addGroups: invalid count");
+ } else {
+ model->addGroups(it, count, d->group, groups);
+ }
+ }
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::removeGroups(int index, int count, stringlist groups)
+
+ Removes \a count items starting at \a index from \a groups.
+*/
+
+void QQmlDelegateModelGroup::removeGroups(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ Compositor::Group group = d->group;
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("removeGroups: index out of range");
+ } else if (count != 0) {
+ Compositor::iterator it = model->m_compositor.find(group, index);
+ if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
+ qmlInfo(this) << tr("removeGroups: invalid count");
+ } else {
+ model->removeGroups(it, count, d->group, groups);
+ }
+ }
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::setGroups(int index, int count, stringlist groups)
+
+ Sets the \a groups \a count items starting at \a index belong to.
+*/
+
+void QQmlDelegateModelGroup::setGroups(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+ Compositor::Group group = d->group;
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &group, &index, &count, &groups))
+ return;
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(group)) {
+ qmlInfo(this) << tr("setGroups: index out of range");
+ } else if (count != 0) {
+ Compositor::iterator it = model->m_compositor.find(group, index);
+ if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
+ qmlInfo(this) << tr("setGroups: invalid count");
+ } else {
+ model->setGroups(it, count, d->group, groups);
+ }
+ }
+}
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::setGroups(int index, int count, stringlist groups)
+
+ Sets the \a groups \a count items starting at \a index belong to.
+*/
+
+/*!
+ \qmlmethod QtQml.Models2::DelegateModelGroup::move(var from, var to, int count)
+
+ Moves \a count at \a from in a group \a to a new position.
+*/
+
+void QQmlDelegateModelGroup::move(QQmlV8Function *args)
+{
+ Q_D(QQmlDelegateModelGroup);
+
+ if (args->Length() < 2)
+ return;
+
+ Compositor::Group fromGroup = d->group;
+ Compositor::Group toGroup = d->group;
+ int from = -1;
+ int to = -1;
+ int count = 1;
+
+ if (!d->parseIndex((*args)[0], &from, &fromGroup)) {
+ qmlInfo(this) << tr("move: invalid from index");
+ return;
+ }
+
+ if (!d->parseIndex((*args)[1], &to, &toGroup)) {
+ qmlInfo(this) << tr("move: invalid to index");
+ return;
+ }
+
+ if (args->Length() > 2) {
+ v8::Local<v8::Value> v = (*args)[2];
+ if (v->IsInt32())
+ count = v->Int32Value();
+ }
+
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
+
+ if (count < 0) {
+ qmlInfo(this) << tr("move: invalid count");
+ } else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) {
+ qmlInfo(this) << tr("move: from index out of range");
+ } else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count, d->group)) {
+ qmlInfo(this) << tr("move: to index out of range");
+ } else if (count > 0) {
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+
+ model->m_compositor.move(fromGroup, from, toGroup, to, count, d->group, &removes, &inserts);
+ model->itemsMoved(removes, inserts);
+ model->emitChanges();
+ }
+
+}
+
+/*!
+ \qmlsignal QtQml.Models2::DelegateModelGroup::onChanged(array removed, array inserted)
+
+ This handler is called when items have been removed from or inserted into the group.
+
+ Each object in the \a removed and \a inserted arrays has two values; the \e index of the first
+ item inserted or removed and a \e count of the number of consecutive items inserted or removed.
+
+ Each index is adjusted for previous changes with all removed items preceding any inserted
+ items.
+*/
+
+//============================================================================
+
+QQmlPartsModel::QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent)
+ : QQmlInstanceModel(*new QObjectPrivate, parent)
+ , m_model(model)
+ , m_part(part)
+ , m_compositorGroup(Compositor::Cache)
+ , m_inheritGroup(true)
+{
+ QQmlDelegateModelPrivate *d = QQmlDelegateModelPrivate::get(m_model);
+ if (d->m_cacheMetaType) {
+ QQmlDelegateModelGroupPrivate::get(d->m_groups[1])->emitters.insert(this);
+ m_compositorGroup = Compositor::Default;
+ } else {
+ d->m_pendingParts.insert(this);
+ }
+}
+
+QQmlPartsModel::~QQmlPartsModel()
+{
+}
+
+QString QQmlPartsModel::filterGroup() const
+{
+ if (m_inheritGroup)
+ return m_model->filterGroup();
+ return m_filterGroup;
+}
+
+void QQmlPartsModel::setFilterGroup(const QString &group)
+{
+ if (QQmlDelegateModelPrivate::get(m_model)->m_transaction) {
+ qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ return;
+ }
+
+ if (m_filterGroup != group || m_inheritGroup) {
+ m_filterGroup = group;
+ m_inheritGroup = false;
+ updateFilterGroup();
+
+ emit filterGroupChanged();
+ }
+}
+
+void QQmlPartsModel::resetFilterGroup()
+{
+ if (!m_inheritGroup) {
+ m_inheritGroup = true;
+ updateFilterGroup();
+ emit filterGroupChanged();
+ }
+}
+
+void QQmlPartsModel::updateFilterGroup()
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ if (!model->m_cacheMetaType)
+ return;
+
+ if (m_inheritGroup) {
+ if (m_filterGroup == model->m_filterGroup)
+ return;
+ m_filterGroup = model->m_filterGroup;
+ }
+
+ QQmlListCompositor::Group previousGroup = m_compositorGroup;
+ m_compositorGroup = Compositor::Default;
+ QQmlDelegateModelGroupPrivate::get(model->m_groups[Compositor::Default])->emitters.insert(this);
+ for (int i = 1; i < model->m_groupCount; ++i) {
+ if (m_filterGroup == model->m_cacheMetaType->groupNames.at(i - 1)) {
+ m_compositorGroup = Compositor::Group(i);
+ break;
+ }
+ }
+
+ QQmlDelegateModelGroupPrivate::get(model->m_groups[m_compositorGroup])->emitters.insert(this);
+ if (m_compositorGroup != previousGroup) {
+ QVector<QQmlChangeSet::Remove> removes;
+ QVector<QQmlChangeSet::Insert> inserts;
+ model->m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
+
+ QQmlChangeSet changeSet;
+ changeSet.move(removes, inserts);
+ if (!changeSet.isEmpty())
+ emit modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit countChanged();
+ }
+}
+
+void QQmlPartsModel::updateFilterGroup(
+ Compositor::Group group, const QQmlChangeSet &changeSet)
+{
+ if (!m_inheritGroup)
+ return;
+
+ m_compositorGroup = group;
+ QQmlDelegateModelGroupPrivate::get(QQmlDelegateModelPrivate::get(m_model)->m_groups[m_compositorGroup])->emitters.insert(this);
+
+ if (!changeSet.isEmpty())
+ emit modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit countChanged();
+
+ emit filterGroupChanged();
+}
+
+int QQmlPartsModel::count() const
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ return model->m_delegate
+ ? model->m_compositor.count(m_compositorGroup)
+ : 0;
+}
+
+bool QQmlPartsModel::isValid() const
+{
+ return m_model->isValid();
+}
+
+QObject *QQmlPartsModel::object(int index, bool asynchronous)
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+
+ if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) {
+ qWarning() << "DelegateModel::item: index out range" << index << model->m_compositor.count(m_compositorGroup);
+ return 0;
+ }
+
+ QObject *object = model->object(m_compositorGroup, index, asynchronous);
+
+ if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) {
+ QObject *part = package->part(m_part);
+ if (!part)
+ return 0;
+ m_packaged.insertMulti(part, package);
+ return part;
+ }
+
+ model->release(object);
+ if (!model->m_delegateValidated) {
+ if (object)
+ qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+ model->m_delegateValidated = true;
+ }
+
+ return 0;
+}
+
+QQmlInstanceModel::ReleaseFlags QQmlPartsModel::release(QObject *item)
+{
+ QQmlInstanceModel::ReleaseFlags flags = 0;
+
+ QHash<QObject *, QQuickPackage *>::iterator it = m_packaged.find(item);
+ if (it != m_packaged.end()) {
+ QQuickPackage *package = *it;
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ flags = model->release(package);
+ m_packaged.erase(it);
+ if (!m_packaged.contains(item))
+ flags &= ~Referenced;
+ if (flags & Destroyed)
+ QQmlDelegateModelPrivate::get(m_model)->emitDestroyingPackage(package);
+ }
+ return flags;
+}
+
+QString QQmlPartsModel::stringValue(int index, const QString &role)
+{
+ return QQmlDelegateModelPrivate::get(m_model)->stringValue(m_compositorGroup, index, role);
+}
+
+void QQmlPartsModel::setWatchedRoles(QList<QByteArray> roles)
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ model->m_adaptorModel.replaceWatchedRoles(m_watchedRoles, roles);
+ m_watchedRoles = roles;
+}
+
+int QQmlPartsModel::indexOf(QObject *item, QObject *) const
+{
+ QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
+ if (it != m_packaged.end()) {
+ if (QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(*it))
+ return cacheItem->groupIndex(m_compositorGroup);
+ }
+ return -1;
+}
+
+void QQmlPartsModel::createdPackage(int index, QQuickPackage *package)
+{
+ emit createdItem(index, package->part(m_part));
+}
+
+void QQmlPartsModel::initPackage(int index, QQuickPackage *package)
+{
+ emit initItem(index, package->part(m_part));
+}
+
+void QQmlPartsModel::destroyingPackage(QQuickPackage *package)
+{
+ QObject *item = package->part(m_part);
+ Q_ASSERT(!m_packaged.contains(item));
+ emit destroyingItem(item);
+}
+
+void QQmlPartsModel::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset)
+{
+ emit modelUpdated(changeSet, reset);
+ if (changeSet.difference() != 0)
+ emit countChanged();
+}
+
+//============================================================================
+
+v8::Handle<v8::Value> get_change_index(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ return info.This()->GetInternalField(0);
+}
+
+v8::Handle<v8::Value> get_change_count(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ return info.This()->GetInternalField(1);
+}
+
+v8::Handle<v8::Value> get_change_moveId(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ return info.This()->GetInternalField(2);
+}
+
+class QQmlDelegateModelGroupChangeArray : public QV8ObjectResource
+{
+ V8_RESOURCE_TYPE(ChangeSetArrayType)
+public:
+ QQmlDelegateModelGroupChangeArray(QV8Engine *engine)
+ : QV8ObjectResource(engine)
+ {
+ }
+
+ virtual quint32 count() const = 0;
+ virtual const QQmlChangeSet::Change &at(int index) const = 0;
+
+ static v8::Handle<v8::Value> get_change(quint32 index, const v8::AccessorInfo &info)
+ {
+ QQmlDelegateModelGroupChangeArray *array = v8_resource_cast<QQmlDelegateModelGroupChangeArray>(info.This());
+ V8ASSERT_TYPE(array, "Not a valid change array");
+
+ if (index >= array->count())
+ return v8::Undefined();
+
+ const QQmlChangeSet::Change &change = array->at(index);
+
+ v8::Local<v8::Object> object = engineData(array->engine)->constructorChange->NewInstance();
+ object->SetInternalField(0, v8::Int32::New(change.index));
+ object->SetInternalField(1, v8::Int32::New(change.count));
+ if (change.isMove())
+ object->SetInternalField(2, v8::Int32::New(change.moveId));
+
+ return object;
+ }
+
+ static v8::Handle<v8::Value> get_length(v8::Local<v8::String>, const v8::AccessorInfo &info)
+ {
+ QQmlDelegateModelGroupChangeArray *array = v8_resource_cast<QQmlDelegateModelGroupChangeArray>(info.This());
+ V8ASSERT_TYPE(array, "Not a valid change array");
+
+ return v8::Integer::New(array->count());
+ }
+
+ static v8::Local<v8::Function> constructor()
+ {
+ v8::Local<v8::FunctionTemplate> changeArray = v8::FunctionTemplate::New();
+ changeArray->InstanceTemplate()->SetHasExternalResource(true);
+ changeArray->InstanceTemplate()->SetIndexedPropertyHandler(get_change);
+ changeArray->InstanceTemplate()->SetAccessor(v8::String::New("length"), get_length);
+ return changeArray->GetFunction();
+ }
+};
+
+class QQmlDelegateModelGroupRemoveArray : public QQmlDelegateModelGroupChangeArray
+{
+public:
+ QQmlDelegateModelGroupRemoveArray(QV8Engine *engine, const QVector<QQmlChangeSet::Remove> &changes)
+ : QQmlDelegateModelGroupChangeArray(engine)
+ , changes(changes)
+ {
+ }
+
+ quint32 count() const { return changes.count(); }
+ const QQmlChangeSet::Change &at(int index) const { return changes.at(index); }
+
+private:
+ QVector<QQmlChangeSet::Remove> changes;
+};
+
+class QQmlDelegateModelGroupInsertArray : public QQmlDelegateModelGroupChangeArray
+{
+public:
+ QQmlDelegateModelGroupInsertArray(QV8Engine *engine, const QVector<QQmlChangeSet::Insert> &changes)
+ : QQmlDelegateModelGroupChangeArray(engine)
+ , changes(changes)
+ {
+ }
+
+ quint32 count() const { return changes.count(); }
+ const QQmlChangeSet::Change &at(int index) const { return changes.at(index); }
+
+private:
+ QVector<QQmlChangeSet::Insert> changes;
+};
+
+QQmlDelegateModelEngineData::QQmlDelegateModelEngineData(QV8Engine *)
+{
+ strings = qPersistentNew(v8::Array::New(StringCount));
+ strings->Set(Model, v8::String::New("model"));
+ strings->Set(Groups, v8::String::New("groups"));
+ strings->Set(IsUnresolved, v8::String::New("isUnresolved"));
+ strings->Set(ItemsIndex, v8::String::New("itemsIndex"));
+ strings->Set(PersistedItemsIndex, v8::String::New("persistedItemsIndex"));
+ strings->Set(InItems, v8::String::New("inItems"));
+ strings->Set(InPersistedItems, v8::String::New("inPersistedItems"));
+
+ v8::Local<v8::FunctionTemplate> change = v8::FunctionTemplate::New();
+ change->InstanceTemplate()->SetAccessor(v8::String::New("index"), get_change_index);
+ change->InstanceTemplate()->SetAccessor(v8::String::New("count"), get_change_count);
+ change->InstanceTemplate()->SetAccessor(v8::String::New("moveId"), get_change_moveId);
+ change->InstanceTemplate()->SetInternalFieldCount(3);
+ constructorChange = qPersistentNew(change->GetFunction());
+ constructorChangeArray = qPersistentNew(QQmlDelegateModelGroupChangeArray::constructor());
+}
+
+QQmlDelegateModelEngineData::~QQmlDelegateModelEngineData()
+{
+ qPersistentDispose(strings);
+ qPersistentDispose(constructorChange);
+ qPersistentDispose(constructorChangeArray);
+}
+
+v8::Local<v8::Object> QQmlDelegateModelEngineData::array(
+ QV8Engine *engine, const QVector<QQmlChangeSet::Remove> &changes)
+{
+ v8::Local<v8::Object> array = constructorChangeArray->NewInstance();
+ array->SetExternalResource(new QQmlDelegateModelGroupRemoveArray(engine, changes));
+ return array;
+}
+
+v8::Local<v8::Object> QQmlDelegateModelEngineData::array(
+ QV8Engine *engine, const QVector<QQmlChangeSet::Insert> &changes)
+{
+ v8::Local<v8::Object> array = constructorChangeArray->NewInstance();
+ array->SetExternalResource(new QQmlDelegateModelGroupInsertArray(engine, changes));
+ return array;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
new file mode 100644
index 0000000000..5702c59787
--- /dev/null
+++ b/src/qml/types/qqmldelegatemodel_p.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDATAMODEL_P_H
+#define QQMLDATAMODEL_P_H
+
+#include <private/qtqmlglobal_p.h>
+#include <private/qqmllistcompositor_p.h>
+#include <private/qqmlobjectmodel_p.h>
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qstringlist.h>
+
+#include <private/qv8engine_p.h>
+#include <private/qqmlglobal_p.h>
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+QT_BEGIN_NAMESPACE
+
+class QQmlChangeSet;
+class QQmlComponent;
+class QQuickPackage;
+class QQmlV8Function;
+class QQmlDelegateModelGroup;
+class QQmlDelegateModelAttached;
+class QQmlDelegateModelPrivate;
+
+
+class Q_QML_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlDelegateModel)
+
+ Q_PROPERTY(QVariant model READ model WRITE setModel)
+ Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate)
+ Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
+ Q_PROPERTY(QQmlDelegateModelGroup *items READ items CONSTANT) //TODO : worth renaming?
+ Q_PROPERTY(QQmlDelegateModelGroup *persistedItems READ persistedItems CONSTANT)
+ Q_PROPERTY(QQmlListProperty<QQmlDelegateModelGroup> groups READ groups CONSTANT)
+ Q_PROPERTY(QObject *parts READ parts CONSTANT)
+ Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
+ Q_CLASSINFO("DefaultProperty", "delegate")
+ Q_INTERFACES(QQmlParserStatus)
+public:
+ QQmlDelegateModel();
+ QQmlDelegateModel(QQmlContext *, QObject *parent=0);
+ virtual ~QQmlDelegateModel();
+
+ void classBegin();
+ void componentComplete();
+
+ QVariant model() const;
+ void setModel(const QVariant &);
+
+ QQmlComponent *delegate() const;
+ void setDelegate(QQmlComponent *);
+
+ QVariant rootIndex() const;
+ void setRootIndex(const QVariant &root);
+
+ Q_INVOKABLE QVariant modelIndex(int idx) const;
+ Q_INVOKABLE QVariant parentModelIndex() const;
+
+ int count() const;
+ bool isValid() const { return delegate() != 0; }
+ QObject *object(int index, bool asynchronous=false);
+ ReleaseFlags release(QObject *object);
+ void cancel(int index);
+ virtual QString stringValue(int index, const QString &role);
+ virtual void setWatchedRoles(QList<QByteArray> roles);
+
+ int indexOf(QObject *object, QObject *objectContext) const;
+
+ QString filterGroup() const;
+ void setFilterGroup(const QString &group);
+ void resetFilterGroup();
+
+ QQmlDelegateModelGroup *items();
+ QQmlDelegateModelGroup *persistedItems();
+ QQmlListProperty<QQmlDelegateModelGroup> groups();
+ QObject *parts();
+
+ bool event(QEvent *);
+
+ static QQmlDelegateModelAttached *qmlAttachedProperties(QObject *obj);
+
+Q_SIGNALS:
+ void filterGroupChanged();
+ void defaultGroupsChanged();
+ void rootIndexChanged();
+
+private Q_SLOTS:
+ void _q_itemsChanged(int index, int count, const QVector<int> &roles);
+ void _q_itemsInserted(int index, int count);
+ void _q_itemsRemoved(int index, int count);
+ void _q_itemsMoved(int from, int to, int count);
+ void _q_modelReset();
+ void _q_rowsInserted(const QModelIndex &,int,int);
+ void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
+ void _q_rowsRemoved(const QModelIndex &,int,int);
+ void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+ void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &);
+ void _q_layoutChanged();
+
+private:
+ Q_DISABLE_COPY(QQmlDelegateModel)
+};
+
+class QQmlDelegateModelGroupPrivate;
+class Q_QML_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
+public:
+ QQmlDelegateModelGroup(QObject *parent = 0);
+ QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = 0);
+ ~QQmlDelegateModelGroup();
+
+ QString name() const;
+ void setName(const QString &name);
+
+ int count() const;
+
+ bool defaultInclude() const;
+ void setDefaultInclude(bool include);
+
+ Q_INVOKABLE QQmlV8Handle get(int index);
+
+public Q_SLOTS:
+ void insert(QQmlV8Function *);
+ void create(QQmlV8Function *);
+ void resolve(QQmlV8Function *);
+ void remove(QQmlV8Function *);
+ void addGroups(QQmlV8Function *);
+ void removeGroups(QQmlV8Function *);
+ void setGroups(QQmlV8Function *);
+ void move(QQmlV8Function *);
+
+Q_SIGNALS:
+ void countChanged();
+ void nameChanged();
+ void defaultIncludeChanged();
+ void changed(const QQmlV8Handle &removed, const QQmlV8Handle &inserted);
+private:
+ Q_DECLARE_PRIVATE(QQmlDelegateModelGroup)
+};
+
+class QQmlDelegateModelItem;
+class QQmlDelegateModelAttachedMetaObject;
+class QQmlDelegateModelAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlDelegateModel *model READ model CONSTANT)
+ Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
+ Q_PROPERTY(bool isUnresolved READ isUnresolved NOTIFY unresolvedChanged)
+public:
+ QQmlDelegateModelAttached(QObject *parent);
+ QQmlDelegateModelAttached(QQmlDelegateModelItem *cacheItem, QObject *parent);
+ ~QQmlDelegateModelAttached() {}
+
+ void setCacheItem(QQmlDelegateModelItem *item);
+
+ QQmlDelegateModel *model() const;
+
+ QStringList groups() const;
+ void setGroups(const QStringList &groups);
+
+ bool isUnresolved() const;
+
+ void emitChanges();
+
+ void emitUnresolvedChanged() { emit unresolvedChanged(); }
+
+Q_SIGNALS:
+ void groupsChanged();
+ void unresolvedChanged();
+
+public:
+ QQmlDelegateModelItem *m_cacheItem;
+ int m_previousGroups;
+ int m_currentIndex[QQmlListCompositor::MaximumGroupCount];
+ int m_previousIndex[QQmlListCompositor::MaximumGroupCount];
+
+ friend class QQmlDelegateModelAttachedMetaObject;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQmlDelegateModel)
+QML_DECLARE_TYPEINFO(QQmlDelegateModel, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQmlDelegateModelGroup)
+
+#endif // QQMLDATAMODEL_P_H
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
new file mode 100644
index 0000000000..68242f433d
--- /dev/null
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -0,0 +1,411 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDATAMODEL_P_P_H
+#define QQMLDATAMODEL_P_P_H
+
+#include "qqmldelegatemodel_p.h"
+
+
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlincubator.h>
+
+#include <private/qqmladaptormodel_p.h>
+#include <private/qqmlopenmetaobject_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+typedef QQmlListCompositor Compositor;
+
+class QQmlDelegateModelAttachedMetaObject;
+
+class QQmlDelegateModelItemMetaType : public QQmlRefCount
+{
+public:
+ QQmlDelegateModelItemMetaType(QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
+ ~QQmlDelegateModelItemMetaType();
+
+ void initializeMetaObject();
+ void initializeConstructor();
+
+ int parseGroups(const QStringList &groupNames) const;
+ int parseGroups(const v8::Local<v8::Value> &groupNames) const;
+
+ static void release_index(v8::Persistent<v8::Value> object, void *parameter);
+ static void release_model(v8::Persistent<v8::Value> object, void *parameter);
+
+ static v8::Handle<v8::Value> get_model(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_groups(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static void set_groups(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_member(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static void set_member(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info);
+
+ QQmlGuard<QQmlDelegateModel> model;
+ const int groupCount;
+ QV8Engine * const v8Engine;
+ QQmlDelegateModelAttachedMetaObject *metaObject;
+ const QStringList groupNames;
+ v8::Persistent<v8::ObjectTemplate> constructor;
+};
+
+class QQmlAdaptorModel;
+class QQDMIncubationTask;
+
+class QQmlDelegateModelItem : public QObject, public QV8ObjectResource
+{
+ Q_OBJECT
+ Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
+ Q_PROPERTY(QObject *model READ modelObject CONSTANT)
+ V8_RESOURCE_TYPE(VisualDataItemType)
+public:
+ QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, int modelIndex);
+ ~QQmlDelegateModelItem();
+
+ void referenceObject() { ++objectRef; }
+ bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); }
+ bool isObjectReferenced() const { return objectRef != 0 || (groups & Compositor::PersistedFlag); }
+
+ bool isReferenced() const {
+ return scriptRef
+ || incubationTask
+ || ((groups & Compositor::UnresolvedFlag) && (groups & Compositor::GroupMask));
+ }
+
+ void Dispose();
+
+ QObject *modelObject() { return this; }
+
+ void incubateObject(
+ QQmlComponent *component,
+ QQmlEngine *engine,
+ QQmlContextData *context,
+ QQmlContextData *forContext);
+ void destroyObject();
+
+ static QQmlDelegateModelItem *dataForObject(QObject *object);
+
+ int groupIndex(Compositor::Group group);
+
+ int modelIndex() const { return index; }
+ void setModelIndex(int idx) { index = idx; emit modelIndexChanged(); }
+
+ virtual v8::Handle<v8::Value> get() { return engine->newQObject(this); }
+
+ virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
+ virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
+
+ QQmlDelegateModelItemMetaType * const metaType;
+ QQmlContextData *contextData;
+ QObject *object;
+ QQmlDelegateModelAttached *attached;
+ QQDMIncubationTask *incubationTask;
+ int objectRef;
+ int scriptRef;
+ int groups;
+ int index;
+
+
+Q_SIGNALS:
+ void modelIndexChanged();
+
+protected:
+ void objectDestroyed(QObject *);
+};
+
+
+class QQmlDelegateModelPrivate;
+class QQDMIncubationTask : public QQmlIncubator
+{
+public:
+ QQDMIncubationTask(QQmlDelegateModelPrivate *l, IncubationMode mode)
+ : QQmlIncubator(mode)
+ , incubating(0)
+ , vdm(l) {}
+
+ virtual void statusChanged(Status);
+ virtual void setInitialState(QObject *);
+
+ QQmlDelegateModelItem *incubating;
+ QQmlDelegateModelPrivate *vdm;
+ int index[QQmlListCompositor::MaximumGroupCount];
+};
+
+
+class QQmlDelegateModelGroupEmitter
+{
+public:
+ virtual ~QQmlDelegateModelGroupEmitter() {}
+ virtual void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) = 0;
+ virtual void createdPackage(int, QQuickPackage *) {}
+ virtual void initPackage(int, QQuickPackage *) {}
+ virtual void destroyingPackage(QQuickPackage *) {}
+
+ QIntrusiveListNode emitterNode;
+};
+
+typedef QIntrusiveList<QQmlDelegateModelGroupEmitter, &QQmlDelegateModelGroupEmitter::emitterNode> QQmlDelegateModelGroupEmitterList;
+
+class QQmlDelegateModelGroupPrivate : public QObjectPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QQmlDelegateModelGroup)
+
+ QQmlDelegateModelGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
+
+ static QQmlDelegateModelGroupPrivate *get(QQmlDelegateModelGroup *group) {
+ return static_cast<QQmlDelegateModelGroupPrivate *>(QObjectPrivate::get(group)); }
+
+ void setModel(QQmlDelegateModel *model, Compositor::Group group);
+ bool isChangedConnected();
+ void emitChanges(QV8Engine *engine);
+ void emitModelUpdated(bool reset);
+
+ void createdPackage(int index, QQuickPackage *package);
+ void initPackage(int index, QQuickPackage *package);
+ void destroyingPackage(QQuickPackage *package);
+
+ bool parseIndex(const v8::Local<v8::Value> &value, int *index, Compositor::Group *group) const;
+ bool parseGroupArgs(
+ QQmlV8Function *args, Compositor::Group *group, int *index, int *count, int *groups) const;
+
+ Compositor::Group group;
+ QQmlGuard<QQmlDelegateModel> model;
+ QQmlDelegateModelGroupEmitterList emitters;
+ QQmlChangeSet changeSet;
+ QString name;
+ bool defaultInclude;
+};
+
+class QQmlDelegateModelParts;
+
+class QQmlDelegateModelPrivate : public QObjectPrivate, public QQmlDelegateModelGroupEmitter
+{
+ Q_DECLARE_PUBLIC(QQmlDelegateModel)
+public:
+ QQmlDelegateModelPrivate(QQmlContext *);
+ ~QQmlDelegateModelPrivate();
+
+ static QQmlDelegateModelPrivate *get(QQmlDelegateModel *m) {
+ return static_cast<QQmlDelegateModelPrivate *>(QObjectPrivate::get(m));
+ }
+
+ void init();
+ void connectModel(QQmlAdaptorModel *model);
+
+ QObject *object(Compositor::Group group, int index, bool asynchronous);
+ QQmlDelegateModel::ReleaseFlags release(QObject *object);
+ QString stringValue(Compositor::Group group, int index, const QString &name);
+ void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
+ void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
+ void emitCreatedItem(QQDMIncubationTask *incubationTask, QObject *item) {
+ emit q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
+ void emitInitItem(QQDMIncubationTask *incubationTask, QObject *item) {
+ emit q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
+ void emitDestroyingPackage(QQuickPackage *package);
+ void emitDestroyingItem(QObject *item) { emit q_func()->destroyingItem(item); }
+ void removeCacheItem(QQmlDelegateModelItem *cacheItem);
+
+ void updateFilterGroup();
+
+ void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
+ void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
+ void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
+
+ void itemsInserted(
+ const QVector<Compositor::Insert> &inserts,
+ QVarLengthArray<QVector<QQmlChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = 0);
+ void itemsInserted(const QVector<Compositor::Insert> &inserts);
+ void itemsRemoved(
+ const QVector<Compositor::Remove> &removes,
+ QVarLengthArray<QVector<QQmlChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = 0);
+ void itemsRemoved(const QVector<Compositor::Remove> &removes);
+ void itemsMoved(
+ const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts);
+ void itemsChanged(const QVector<Compositor::Change> &changes);
+ template <typename T> static v8::Local<v8::Array> buildChangeList(const QVector<T> &changes);
+ void emitChanges();
+ void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset);
+
+ bool insert(Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups);
+
+ static void group_append(QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group);
+ static int group_count(QQmlListProperty<QQmlDelegateModelGroup> *property);
+ static QQmlDelegateModelGroup *group_at(QQmlListProperty<QQmlDelegateModelGroup> *property, int index);
+
+ void releaseIncubator(QQDMIncubationTask *incubationTask);
+ void incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status);
+ void setInitialState(QQDMIncubationTask *incubationTask, QObject *o);
+
+ QQmlAdaptorModel m_adaptorModel;
+ QQmlListCompositor m_compositor;
+ QQmlComponent *m_delegate;
+ QQmlDelegateModelItemMetaType *m_cacheMetaType;
+ QQmlContext *m_context;
+ QQmlDelegateModelParts *m_parts;
+ QQmlDelegateModelGroupEmitterList m_pendingParts;
+
+ QList<QQmlDelegateModelItem *> m_cache;
+ QList<QQDMIncubationTask *> m_finishedIncubating;
+ QList<QByteArray> m_watchedRoles;
+
+ QString m_filterGroup;
+
+ int m_count;
+ int m_groupCount;
+
+ QQmlListCompositor::Group m_compositorGroup;
+ bool m_complete : 1;
+ bool m_delegateValidated : 1;
+ bool m_reset : 1;
+ bool m_transaction : 1;
+ bool m_incubatorCleanupScheduled : 1;
+
+ union {
+ struct {
+ QQmlDelegateModelGroup *m_cacheItems;
+ QQmlDelegateModelGroup *m_items;
+ QQmlDelegateModelGroup *m_persistedItems;
+ };
+ QQmlDelegateModelGroup *m_groups[Compositor::MaximumGroupCount];
+ };
+};
+
+class QQmlPartsModel : public QQmlInstanceModel, public QQmlDelegateModelGroupEmitter
+{
+ Q_OBJECT
+ Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
+public:
+ QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent = 0);
+ ~QQmlPartsModel();
+
+ QString filterGroup() const;
+ void setFilterGroup(const QString &group);
+ void resetFilterGroup();
+ void updateFilterGroup();
+ void updateFilterGroup(Compositor::Group group, const QQmlChangeSet &changeSet);
+
+ int count() const;
+ bool isValid() const;
+ QObject *object(int index, bool asynchronous=false);
+ ReleaseFlags release(QObject *item);
+ QString stringValue(int index, const QString &role);
+ QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
+ void setWatchedRoles(QList<QByteArray> roles);
+
+ int indexOf(QObject *item, QObject *objectContext) const;
+
+ void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset);
+
+ void createdPackage(int index, QQuickPackage *package);
+ void initPackage(int index, QQuickPackage *package);
+ void destroyingPackage(QQuickPackage *package);
+
+Q_SIGNALS:
+ void filterGroupChanged();
+
+private:
+ QQmlDelegateModel *m_model;
+ QHash<QObject *, QQuickPackage *> m_packaged;
+ QString m_part;
+ QString m_filterGroup;
+ QList<QByteArray> m_watchedRoles;
+ Compositor::Group m_compositorGroup;
+ bool m_inheritGroup;
+};
+
+class QMetaPropertyBuilder;
+
+class QQmlDelegateModelPartsMetaObject : public QQmlOpenMetaObject
+{
+public:
+ QQmlDelegateModelPartsMetaObject(QObject *parent)
+ : QQmlOpenMetaObject(parent) {}
+
+ virtual void propertyCreated(int, QMetaPropertyBuilder &);
+ virtual QVariant initialValue(int);
+};
+
+class QQmlDelegateModelParts : public QObject
+{
+Q_OBJECT
+public:
+ QQmlDelegateModelParts(QQmlDelegateModel *parent);
+
+ QQmlDelegateModel *model;
+ QList<QQmlPartsModel *> models;
+};
+
+class QQmlDelegateModelAttachedMetaObject : public QAbstractDynamicMetaObject, public QQmlRefCount
+{
+public:
+ QQmlDelegateModelAttachedMetaObject(
+ QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject);
+ ~QQmlDelegateModelAttachedMetaObject();
+
+ void objectDestroyed(QObject *);
+ int metaCall(QObject *, QMetaObject::Call, int _id, void **);
+
+private:
+ QQmlDelegateModelItemMetaType * const metaType;
+ QMetaObject * const metaObject;
+ const int memberPropertyOffset;
+ const int indexPropertyOffset;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/types/qqmlinstantiator.cpp b/src/qml/types/qqmlinstantiator.cpp
new file mode 100644
index 0000000000..a2a1fa23ad
--- /dev/null
+++ b/src/qml/types/qqmlinstantiator.cpp
@@ -0,0 +1,459 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlinstantiator_p.h"
+#include "qqmlinstantiator_p_p.h"
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlComponent>
+#include <QtQml/QQmlInfo>
+#include <QtQml/QQmlError>
+#include <QtQml/private/qqmlobjectmodel_p.h>
+#include <QtQml/private/qqmldelegatemodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlInstantiatorPrivate::QQmlInstantiatorPrivate()
+ : componentComplete(true)
+ , active(true)
+ , async(false)
+ , ownModel(false)
+ , model(QVariant(1))
+ , instanceModel(0)
+ , delegate(0)
+{
+}
+
+QQmlInstantiatorPrivate::~QQmlInstantiatorPrivate()
+{
+ qDeleteAll(objects);
+}
+
+void QQmlInstantiatorPrivate::clear()
+{
+ Q_Q(QQmlInstantiator);
+ if (!instanceModel)
+ return;
+ if (!objects.count())
+ return;
+
+ for (int i=0; i < objects.count(); i++) {
+ q->objectRemoved(i, objects[i]);
+ instanceModel->release(objects[i]);
+ }
+ objects.clear();
+ q->objectChanged();
+}
+
+void QQmlInstantiatorPrivate::regenerate()
+{
+ Q_Q(QQmlInstantiator);
+ if (!componentComplete)
+ return;
+
+ int prevCount = q->count();
+
+ clear();
+
+ if (!active || !instanceModel || !instanceModel->count() || !instanceModel->isValid()) {
+ if (prevCount)
+ q->countChanged();
+ return;
+ }
+
+ for (int i = 0; i < instanceModel->count(); i++) {
+ QObject *object = instanceModel->object(i, async);
+ // If the item was already created we won't get a createdItem
+ if (object)
+ _q_createdItem(i, object);
+ }
+ if (q->count() != prevCount)
+ q->countChanged();
+}
+
+void QQmlInstantiatorPrivate::_q_createdItem(int idx, QObject* item)
+{
+ Q_Q(QQmlInstantiator);
+ if (objects.contains(item)) //Case when it was created synchronously in regenerate
+ return;
+ item->setParent(q);
+ objects << item;
+ if (objects.count() == 1)
+ q->objectChanged();
+ q->objectAdded(idx, item);
+}
+
+void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bool reset)
+{
+ Q_Q(QQmlInstantiator);
+
+ if (componentComplete)
+ return;
+
+ if (reset) {
+ regenerate();
+ if (changeSet.difference() != 0)
+ q->countChanged();
+ return;
+ }
+
+ int difference = 0;
+ QHash<int, QVector<QPointer<QObject> > > moved;
+ foreach (const QQmlChangeSet::Remove &remove, changeSet.removes()) {
+ int index = qMin(remove.index, objects.count());
+ int count = qMin(remove.index + remove.count, objects.count()) - index;
+ if (remove.isMove()) {
+ moved.insert(remove.moveId, objects.mid(index, count));
+ objects.erase(
+ objects.begin() + index,
+ objects.begin() + index + count);
+ } else while (count--) {
+ QObject *obj = objects.at(index);
+ objects.remove(index);
+ q->objectRemoved(index, obj);
+ if (obj)
+ instanceModel->release(obj);
+ }
+
+ difference -= remove.count;
+ }
+
+ foreach (const QQmlChangeSet::Insert &insert, changeSet.inserts()) {
+ int index = qMin(insert.index, objects.count());
+ if (insert.isMove()) {
+ QVector<QPointer<QObject> > movedObjects = moved.value(insert.moveId);
+ objects = objects.mid(0, index) + movedObjects + objects.mid(index);
+ } else for (int i = 0; i < insert.count; ++i) {
+ int modelIndex = index + i;
+ QObject* obj = instanceModel->object(i, async);
+ if (obj)
+ _q_createdItem(modelIndex, obj);
+ }
+ difference += insert.count;
+ }
+
+ if (difference != 0)
+ q->countChanged();
+}
+
+void QQmlInstantiatorPrivate::makeModel()
+{
+ Q_Q(QQmlInstantiator);
+ QQmlDelegateModel* delegateModel = new QQmlDelegateModel(qmlContext(q));
+ instanceModel = delegateModel;
+ ownModel = true;
+ delegateModel->setDelegate(delegate);
+ delegateModel->classBegin(); //Pretend it was made in QML
+ if (componentComplete)
+ delegateModel->componentComplete();
+}
+
+
+/*!
+ \qmltype Instantiator
+ \instantiates QQmlInstantiator
+ \inqmlmodule QtQml 2
+ \brief Dynamically creates objects
+
+ A Instantiator can be used to control the dynamic creation of objects, or to dynamically
+ create multiple objects from a template.
+
+ The Instantiator element will manage the objects it creates. Those objects are parented to the
+ Instantiator and can also be deleted by the Instantiator if the Instantiator's properties change. Objects
+ can also be destroyed dynamically through other means, and the Instantiator will not recreate
+ them unless the properties of the Instantiator change.
+
+*/
+QQmlInstantiator::QQmlInstantiator(QObject *parent)
+ : QObject(*(new QQmlInstantiatorPrivate), parent)
+{
+}
+
+QQmlInstantiator::~QQmlInstantiator()
+{
+}
+
+/*!
+ \qmlsignal QtQml2::Instantiator::onObjectAdded(int index, QtObject object)
+
+ This handler is called when an object is added to the Instantiator. The \a index
+ parameter holds the index which the object has been given, and the \a object
+ parameter holds the \l QtObject that has been added.
+*/
+
+/*!
+ \qmlsignal QtQml2::Instantiator::onObjectRemoved(int index, QtObject object)
+
+ This handler is called when an object is added to the Instantiator. The \a index
+ parameter holds the index which the object had been given, and the \a object
+ parameter holds the \l QtObject that has been removed.
+
+ Do not keep a reference to \a object if it was created by this Instantiator, as
+ in these cases it will be deleted shortly after the handler is called.
+*/
+/*!
+ \qmlproperty bool QtQml2::Instantiator::active
+
+ When active is true, and the delegate component is ready, the Instantiator will
+ create objects according to the model. When active is false, no objects
+ will be created and any previously created objects will be destroyed.
+
+ Default is true.
+*/
+bool QQmlInstantiator::isActive() const
+{
+ Q_D(const QQmlInstantiator);
+ return d->active;
+}
+
+void QQmlInstantiator::setActive(bool newVal)
+{
+ Q_D(QQmlInstantiator);
+ if (newVal == d->active)
+ return;
+ d->active = newVal;
+ emit activeChanged();
+ d->regenerate();
+}
+
+/*!
+ \qmlproperty bool QtQml2::Instantiator::asynchronous
+
+ When asynchronous is true the Instantiator will attempt to create objects
+ asynchronously. This means that objects may not be available immediately,
+ even if active is set to true.
+
+ You can use the objectAdded signal to respond to items being created.
+
+ Default is false.
+*/
+bool QQmlInstantiator::isAsync() const
+{
+ Q_D(const QQmlInstantiator);
+ return d->async;
+}
+
+void QQmlInstantiator::setAsync(bool newVal)
+{
+ Q_D(QQmlInstantiator);
+ if (newVal == d->async)
+ return;
+ d->async = newVal;
+ emit asynchronousChanged();
+}
+
+
+/*!
+ \qmlproperty int QtQml2::Instantiator::count
+
+ The number of objects the Instantiator is currently managing.
+*/
+
+int QQmlInstantiator::count() const
+{
+ Q_D(const QQmlInstantiator);
+ return d->objects.count();
+}
+
+/*!
+ \qmlproperty QtQml2::Component QtQml2::Instantiator::delegate
+ \default
+
+ The component used to create all objects.
+
+ Note that an extra variable, index, will be available inside instances of the
+ delegate. This variable refers to the index of the instance inside the Instantiator,
+ and can be used to obtain the object through the itemAt method of the Instantiator.
+
+ If this property is changed, all instances using the old delegate will be destroyed
+ and new instances will be created using the new delegate.
+*/
+QQmlComponent* QQmlInstantiator::delegate()
+{
+ Q_D(QQmlInstantiator);
+ return d->delegate;
+}
+
+void QQmlInstantiator::setDelegate(QQmlComponent* c)
+{
+ Q_D(QQmlInstantiator);
+ if (c == d->delegate)
+ return;
+
+ d->delegate = c;
+ emit delegateChanged();
+
+ if (!d->ownModel)
+ return;
+
+ if (QQmlDelegateModel *dModel = qobject_cast<QQmlDelegateModel*>(d->instanceModel))
+ dModel->setDelegate(c);
+ if (d->componentComplete)
+ d->regenerate();
+}
+
+/*!
+ \qmlproperty variant QtQml2::Instantiator::model
+
+ This property can be set to any of the supported \l {qml-data-models}{data models}:
+
+ \list
+ \li A number that indicates the number of delegates to be created by the repeater
+ \li A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
+ \li A string list
+ \li An object list
+ \endlist
+
+ The type of model affects the properties that are exposed to the \l delegate.
+
+ Default value is 1, which creates a single delegate instance.
+
+ \sa {qml-data-models}{Data Models}
+*/
+
+QVariant QQmlInstantiator::model() const
+{
+ Q_D(const QQmlInstantiator);
+ return d->model;
+}
+
+void QQmlInstantiator::setModel(const QVariant &v)
+{
+ Q_D(QQmlInstantiator);
+ if (d->model == v)
+ return;
+
+ d->model = v;
+ //Don't actually set model until componentComplete in case it wants to create its delegates immediately
+ if (!d->componentComplete)
+ return;
+
+ QQmlInstanceModel *prevModel = d->instanceModel;
+ QObject *object = qvariant_cast<QObject*>(v);
+ QQmlInstanceModel *vim = 0;
+ if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
+ if (d->ownModel) {
+ delete d->instanceModel;
+ d->ownModel = false;
+ }
+ d->instanceModel = vim;
+ } else if (v != QVariant(0)){
+ if (!d->ownModel)
+ d->makeModel();
+
+ if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel *>(d->instanceModel))
+ dataModel->setModel(v);
+ }
+
+ if (d->instanceModel != prevModel) {
+ if (prevModel) {
+ disconnect(prevModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
+ this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
+ disconnect(prevModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
+ //disconnect(prevModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
+ }
+
+ connect(d->instanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
+ this, SLOT(_q_modelUpdated(QQmlChangeSet,bool)));
+ connect(d->instanceModel, SIGNAL(createdItem(int,QObject*)), this, SLOT(_q_createdItem(int,QObject*)));
+ //connect(d->instanceModel, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*)));
+ }
+
+ d->regenerate();
+ emit modelChanged();
+}
+
+/*!
+ \qmlproperty QtQml2::QtObject QtQml2::Instantiator::object
+
+ This is a reference to the first created object, intended as a convenience
+ for the case where only one object has been created.
+*/
+QObject *QQmlInstantiator::object() const
+{
+ Q_D(const QQmlInstantiator);
+ if (d->objects.count())
+ return d->objects[0];
+ return 0;
+}
+
+/*!
+ \qmlmethod QtQml2::QtObject QtQml2::Instantiator::objectAt
+
+ Returns a reference to the object with the given \a index.
+*/
+QObject *QQmlInstantiator::objectAt(int index) const
+{
+ Q_D(const QQmlInstantiator);
+ if (index >= 0 && index < d->objects.count())
+ return d->objects[index];
+ return 0;
+}
+
+/*!
+ \internal
+*/
+void QQmlInstantiator::classBegin()
+{
+ Q_D(QQmlInstantiator);
+ d->componentComplete = false;
+}
+
+/*!
+ \internal
+*/
+void QQmlInstantiator::componentComplete()
+{
+ Q_D(QQmlInstantiator);
+ d->componentComplete = true;
+ if (d->ownModel) {
+ static_cast<QQmlDelegateModel*>(d->instanceModel)->componentComplete();
+ d->regenerate();
+ } else {
+ QVariant realModel = d->model;
+ d->model = QVariant(0);
+ setModel(realModel); //If realModel == d->model this won't do anything, but that's fine since the model's 0
+ //setModel calls regenerate
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qqmlinstantiator_p.cpp"
diff --git a/src/qml/types/qqmlinstantiator_p.h b/src/qml/types/qqmlinstantiator_p.h
new file mode 100644
index 0000000000..d4eb793357
--- /dev/null
+++ b/src/qml/types/qqmlinstantiator_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLINSTANTIATOR_P_H
+#define QQMLINSTANTIATOR_P_H
+
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlparserstatus.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlInstantiatorPrivate;
+class Q_AUTOTEST_EXPORT QQmlInstantiator : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(bool asynchronous READ isAsync WRITE setAsync NOTIFY asynchronousChanged)
+ Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+ Q_PROPERTY(QObject *object READ object NOTIFY objectChanged)
+ Q_CLASSINFO("DefaultProperty", "delegate")
+
+public:
+ QQmlInstantiator(QObject *parent = 0);
+ virtual ~QQmlInstantiator();
+
+ bool isActive() const;
+ void setActive(bool newVal);
+
+ bool isAsync() const;
+ void setAsync(bool newVal);
+
+ int count() const;
+
+ QQmlComponent* delegate();
+ void setDelegate(QQmlComponent* c);
+
+ QVariant model() const;
+ void setModel(const QVariant &v);
+
+ QObject *object() const;
+
+ Q_INVOKABLE QObject *objectAt(int index) const;
+
+ void classBegin();
+ void componentComplete();
+
+Q_SIGNALS:
+ void modelChanged();
+ void delegateChanged();
+ void countChanged();
+ void objectChanged();
+ void activeChanged();
+ void asynchronousChanged();
+
+ void objectAdded(int index, QObject* object);
+ void objectRemoved(int index, QObject* object);
+
+private:
+ Q_DISABLE_COPY(QQmlInstantiator)
+ Q_DECLARE_PRIVATE(QQmlInstantiator)
+ Q_PRIVATE_SLOT(d_func(), void _q_createdItem(int, QObject *))
+ Q_PRIVATE_SLOT(d_func(), void _q_modelUpdated(const QQmlChangeSet &, bool))
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLCREATOR_P_H
diff --git a/src/qml/types/qqmlinstantiator_p_p.h b/src/qml/types/qqmlinstantiator_p_p.h
new file mode 100644
index 0000000000..79459299dc
--- /dev/null
+++ b/src/qml/types/qqmlinstantiator_p_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLINSTANTIATOR_P_P_H
+#define QQMLINSTANTIATOR_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qqmlinstantiator_p.h"
+#include <QObject>
+#include <private/qobject_p.h>
+#include <private/qqmlchangeset_p.h>
+#include <private/qqmlobjectmodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlInstantiatorPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlInstantiator)
+
+public:
+ QQmlInstantiatorPrivate();
+ ~QQmlInstantiatorPrivate();
+
+ void clear();
+ void regenerate();
+ void makeModel();
+ void _q_createdItem(int, QObject *);
+ void _q_modelUpdated(const QQmlChangeSet &, bool);
+
+ bool componentComplete;
+ bool active;
+ bool async;
+ bool ownModel;
+ QVariant model;
+ QQmlInstanceModel *instanceModel;
+ QQmlComponent *delegate;
+ QVector<QPointer<QObject> > objects;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLCREATOR_P_P_H
diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 91c1a9c476..9609e91b1c 100644
--- a/src/qml/qml/qquicklistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "qquicklistmodel_p_p.h"
-#include "qquicklistmodelworkeragent_p.h"
-#include "qqmlopenmetaobject_p.h"
+#include "qqmllistmodel_p_p.h"
+#include "qqmllistmodelworkeragent_p.h"
+#include <private/qqmlopenmetaobject_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmljsengine_p.h>
@@ -246,7 +246,7 @@ const ListLayout::Role *ListLayout::getExistingRole(v8::Handle<v8::String> key)
return r;
}
-ModelObject *ListModel::getOrCreateModelObject(QQuickListModel *model, int elementIndex)
+ModelObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementIndex)
{
ListElement *e = elements[elementIndex];
if (e->m_objectCache == 0) {
@@ -326,7 +326,7 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
}
}
-ListModel::ListModel(ListLayout *layout, QQuickListModel *modelCache, int uid) : m_layout(layout), m_modelCache(modelCache)
+ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid) : m_layout(layout), m_modelCache(modelCache)
{
if (uid == -1)
uid = uidCounter.fetchAndAddOrdered(1);
@@ -394,7 +394,7 @@ void ListModel::updateCacheIndices()
}
}
-QVariant ListModel::getProperty(int elementIndex, int roleIndex, const QQuickListModel *owner, QV8Engine *eng)
+QVariant ListModel::getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV8Engine *eng)
{
ListElement *e = elements[elementIndex];
const ListLayout::Role &r = m_layout->getExistingRole(roleIndex);
@@ -698,7 +698,7 @@ ListModel *ListElement::getListProperty(const ListLayout::Role &role)
return *value;
}
-QVariant ListElement::getProperty(const ListLayout::Role &role, const QQuickListModel *owner, QV8Engine *eng)
+QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV8Engine *eng)
{
char *mem = getPropertyMemory(role);
@@ -731,7 +731,7 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQuickList
if (model) {
if (model->m_modelCache == 0) {
- model->m_modelCache = new QQuickListModel(owner, model, eng);
+ model->m_modelCache = new QQmlListModel(owner, model, eng);
QQmlEngine::setContextForObject(model->m_modelCache, QQmlEngine::contextForObject(owner));
}
@@ -1207,7 +1207,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Valu
return roleIndex;
}
-ModelObject::ModelObject(QQuickListModel *model, int elementIndex)
+ModelObject::ModelObject(QQmlListModel *model, int elementIndex)
: m_model(model), m_elementIndex(elementIndex), m_meta(new ModelNodeMetaObject(this))
{
updateValues();
@@ -1269,12 +1269,12 @@ void ModelNodeMetaObject::propertyWritten(int index)
}
}
-DynamicRoleModelNode::DynamicRoleModelNode(QQuickListModel *owner, int uid) : m_owner(owner), m_uid(uid), m_meta(new DynamicRoleModelNodeMetaObject(this))
+DynamicRoleModelNode::DynamicRoleModelNode(QQmlListModel *owner, int uid) : m_owner(owner), m_uid(uid), m_meta(new DynamicRoleModelNodeMetaObject(this))
{
setNodeUpdatesEnabled(true);
}
-DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQuickListModel *owner)
+DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQmlListModel *owner)
{
DynamicRoleModelNode *object = new DynamicRoleModelNode(owner, uidCounter.fetchAndAddOrdered(1));
QVector<int> roles;
@@ -1282,20 +1282,20 @@ DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQuic
return object;
}
-void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQuickListModel *> *targetModelHash)
+void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash)
{
for (int i=0 ; i < src->m_meta->count() ; ++i) {
const QByteArray &name = src->m_meta->name(i);
QVariant value = src->m_meta->value(i);
- QQuickListModel *srcModel = qobject_cast<QQuickListModel *>(value.value<QObject *>());
- QQuickListModel *targetModel = qobject_cast<QQuickListModel *>(target->m_meta->value(i).value<QObject *>());
+ QQmlListModel *srcModel = qobject_cast<QQmlListModel *>(value.value<QObject *>());
+ QQmlListModel *targetModel = qobject_cast<QQmlListModel *>(target->m_meta->value(i).value<QObject *>());
if (srcModel) {
if (targetModel == 0)
- targetModel = QQuickListModel::createWithOwner(target->m_owner);
+ targetModel = QQmlListModel::createWithOwner(target->m_owner);
- QQuickListModel::sync(srcModel, targetModel, targetModelHash);
+ QQmlListModel::sync(srcModel, targetModel, targetModelHash);
QObject *targetModelObject = targetModel;
value = QVariant::fromValue(targetModelObject);
@@ -1326,7 +1326,7 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
QVariant value = object[key];
if (value.type() == QVariant::List) {
- QQuickListModel *subModel = QQuickListModel::createWithOwner(m_owner);
+ QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
QVariantList subArray = value.toList();
QVariantList::const_iterator subIt = subArray.begin();
@@ -1343,7 +1343,7 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
const QByteArray &keyUtf8 = key.toUtf8();
- QQuickListModel *existingModel = qobject_cast<QQuickListModel *>(m_meta->value(keyUtf8).value<QObject *>());
+ QQmlListModel *existingModel = qobject_cast<QQmlListModel *>(m_meta->value(keyUtf8).value<QObject *>());
if (existingModel)
delete existingModel;
@@ -1362,7 +1362,7 @@ DynamicRoleModelNodeMetaObject::DynamicRoleModelNodeMetaObject(DynamicRoleModelN
DynamicRoleModelNodeMetaObject::~DynamicRoleModelNodeMetaObject()
{
for (int i=0 ; i < count() ; ++i) {
- QQuickListModel *subModel = qobject_cast<QQuickListModel *>(value(i).value<QObject *>());
+ QQmlListModel *subModel = qobject_cast<QQmlListModel *>(value(i).value<QObject *>());
if (subModel)
delete subModel;
}
@@ -1374,7 +1374,7 @@ void DynamicRoleModelNodeMetaObject::propertyWrite(int index)
return;
QVariant v = value(index);
- QQuickListModel *model = qobject_cast<QQuickListModel *>(v.value<QObject *>());
+ QQmlListModel *model = qobject_cast<QQmlListModel *>(v.value<QObject *>());
if (model)
delete model;
}
@@ -1384,11 +1384,11 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
if (!m_enabled)
return;
- QQuickListModel *parentModel = m_owner->m_owner;
+ QQmlListModel *parentModel = m_owner->m_owner;
QVariant v = value(index);
if (v.type() == QVariant::List) {
- QQuickListModel *subModel = QQuickListModel::createWithOwner(parentModel);
+ QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
QVariantList subArray = v.toList();
QVariantList::const_iterator subIt = subArray.begin();
@@ -1417,14 +1417,25 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
}
}
-QQuickListModelParser::ListInstruction *QQuickListModelParser::ListModelData::instructions() const
+QQmlListModelParser::ListInstruction *QQmlListModelParser::ListModelData::instructions() const
{
- return (QQuickListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
+ return (QQmlListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
}
/*!
\qmltype ListModel
- \instantiates QQuickListModel
+ \instantiates QQmlListModel
+ \inqmlmodule QtQml.Models 2
+ \brief Defines a free-form list data source
+
+ The ListModel is a simple container of ListElement definitions, each containing data roles.
+ The contents can be defined dynamically, or explicitly in QML.
+
+ This type is also available in the QtQuick 2 import. For full documentation, see \l QtQuick2::ListModel
+*/
+/*!
+ \qmltype ListModel
+ \instantiates QQmlListModel
\inqmlmodule QtQuick 2
\brief Defines a free-form list data source
\ingroup qtquick-models
@@ -1515,7 +1526,7 @@ QQuickListModelParser::ListInstruction *QQuickListModelParser::ListModelData::in
\sa {qml-data-models}{Data Models}, {declarative/threading/threadedlistmodel}{Threaded ListModel example}, QtQml
*/
-QQuickListModel::QQuickListModel(QObject *parent)
+QQmlListModel::QQmlListModel(QObject *parent)
: QAbstractListModel(parent)
{
m_mainThread = true;
@@ -1530,7 +1541,7 @@ QQuickListModel::QQuickListModel(QObject *parent)
m_engine = 0;
}
-QQuickListModel::QQuickListModel(const QQuickListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent)
+QQmlListModel::QQmlListModel(const QQmlListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent)
: QAbstractListModel(parent)
{
m_mainThread = owner->m_mainThread;
@@ -1545,7 +1556,7 @@ QQuickListModel::QQuickListModel(const QQuickListModel *owner, ListModel *data,
m_engine = eng;
}
-QQuickListModel::QQuickListModel(QQuickListModel *orig, QQuickListModelWorkerAgent *agent)
+QQmlListModel::QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent)
: QAbstractListModel(agent)
{
m_mainThread = false;
@@ -1564,7 +1575,7 @@ QQuickListModel::QQuickListModel(QQuickListModel *orig, QQuickListModelWorkerAge
m_engine = 0;
}
-QQuickListModel::~QQuickListModel()
+QQmlListModel::~QQmlListModel()
{
for (int i=0 ; i < m_modelObjects.count() ; ++i)
delete m_modelObjects[i];
@@ -1585,9 +1596,9 @@ QQuickListModel::~QQuickListModel()
m_layout = 0;
}
-QQuickListModel *QQuickListModel::createWithOwner(QQuickListModel *newOwner)
+QQmlListModel *QQmlListModel::createWithOwner(QQmlListModel *newOwner)
{
- QQuickListModel *model = new QQuickListModel;
+ QQmlListModel *model = new QQmlListModel;
model->m_mainThread = newOwner->m_mainThread;
model->m_engine = newOwner->m_engine;
@@ -1602,7 +1613,7 @@ QQuickListModel *QQuickListModel::createWithOwner(QQuickListModel *newOwner)
return model;
}
-QV8Engine *QQuickListModel::engine() const
+QV8Engine *QQmlListModel::engine() const
{
if (m_engine == 0) {
m_engine = QQmlEnginePrivate::getV8Engine(qmlEngine(this));
@@ -1611,7 +1622,7 @@ QV8Engine *QQuickListModel::engine() const
return m_engine;
}
-void QQuickListModel::sync(QQuickListModel *src, QQuickListModel *target, QHash<int, QQuickListModel *> *targetModelHash)
+void QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash)
{
Q_ASSERT(src->m_dynamicRoles && target->m_dynamicRoles);
@@ -1672,7 +1683,7 @@ void QQuickListModel::sync(QQuickListModel *src, QQuickListModel *target, QHash<
}
}
-void QQuickListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
+void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
{
if (count <= 0)
return;
@@ -1685,7 +1696,7 @@ void QQuickListModel::emitItemsChanged(int index, int count, const QVector<int>
}
}
-void QQuickListModel::emitItemsRemoved(int index, int count)
+void QQmlListModel::emitItemsRemoved(int index, int count)
{
if (count <= 0)
return;
@@ -1702,7 +1713,7 @@ void QQuickListModel::emitItemsRemoved(int index, int count)
}
}
-void QQuickListModel::emitItemsInserted(int index, int count)
+void QQmlListModel::emitItemsInserted(int index, int count)
{
if (count <= 0)
return;
@@ -1717,7 +1728,7 @@ void QQuickListModel::emitItemsInserted(int index, int count)
}
}
-void QQuickListModel::emitItemsMoved(int from, int to, int n)
+void QQmlListModel::emitItemsMoved(int from, int to, int n)
{
if (n <= 0)
return;
@@ -1731,33 +1742,33 @@ void QQuickListModel::emitItemsMoved(int from, int to, int n)
}
}
-QQuickListModelWorkerAgent *QQuickListModel::agent()
+QQmlListModelWorkerAgent *QQmlListModel::agent()
{
if (m_agent)
return m_agent;
- m_agent = new QQuickListModelWorkerAgent(this);
+ m_agent = new QQmlListModelWorkerAgent(this);
return m_agent;
}
-QModelIndex QQuickListModel::index(int row, int column, const QModelIndex &parent) const
+QModelIndex QQmlListModel::index(int row, int column, const QModelIndex &parent) const
{
return row >= 0 && row < count() && column == 0 && !parent.isValid()
? createIndex(row, column)
: QModelIndex();
}
-int QQuickListModel::rowCount(const QModelIndex &parent) const
+int QQmlListModel::rowCount(const QModelIndex &parent) const
{
return !parent.isValid() ? count() : 0;
}
-QVariant QQuickListModel::data(const QModelIndex &index, int role) const
+QVariant QQmlListModel::data(const QModelIndex &index, int role) const
{
return data(index.row(), role);
}
-QVariant QQuickListModel::data(int index, int role) const
+QVariant QQmlListModel::data(int index, int role) const
{
QVariant v;
@@ -1772,7 +1783,7 @@ QVariant QQuickListModel::data(int index, int role) const
return v;
}
-QHash<int, QByteArray> QQuickListModel::roleNames() const
+QHash<int, QByteArray> QQmlListModel::roleNames() const
{
QHash<int, QByteArray> roleNames;
@@ -1790,7 +1801,7 @@ QHash<int, QByteArray> QQuickListModel::roleNames() const
}
/*!
- \qmlproperty bool QtQuick2::ListModel::dynamicRoles
+ \qmlproperty bool QtQml2::ListModel::dynamicRoles
By default, the type of a role is fixed the first time
the role is used. For example, if you create a role called
@@ -1815,7 +1826,7 @@ QHash<int, QByteArray> QQuickListModel::roleNames() const
Due to the performance cost of using dynamic roles,
they are disabled by default.
*/
-void QQuickListModel::setDynamicRoles(bool enableDynamicRoles)
+void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
{
if (m_mainThread && m_agent == 0) {
if (enableDynamicRoles) {
@@ -1836,10 +1847,10 @@ void QQuickListModel::setDynamicRoles(bool enableDynamicRoles)
}
/*!
- \qmlproperty int QtQuick2::ListModel::count
+ \qmlproperty int QtQml2::ListModel::count
The number of data entries in the model.
*/
-int QQuickListModel::count() const
+int QQmlListModel::count() const
{
int count;
@@ -1853,13 +1864,13 @@ int QQuickListModel::count() const
}
/*!
- \qmlmethod QtQuick2::ListModel::clear()
+ \qmlmethod QtQml2::ListModel::clear()
Deletes all content from the model.
\sa append(), remove()
*/
-void QQuickListModel::clear()
+void QQmlListModel::clear()
{
int cleared = count();
@@ -1875,13 +1886,13 @@ void QQuickListModel::clear()
}
/*!
- \qmlmethod QtQuick2::ListModel::remove(int index, int count = 1)
+ \qmlmethod QtQml2::ListModel::remove(int index, int count = 1)
Deletes the content at \a index from the model.
\sa clear()
*/
-void QQuickListModel::remove(QQmlV8Function *args)
+void QQmlListModel::remove(QQmlV8Function *args)
{
int argLength = args->Length();
@@ -1909,7 +1920,7 @@ void QQuickListModel::remove(QQmlV8Function *args)
}
/*!
- \qmlmethod QtQuick2::ListModel::insert(int index, jsobject dict)
+ \qmlmethod QtQml2::ListModel::insert(int index, jsobject dict)
Adds a new item to the list model at position \a index, with the
values in \a dict.
@@ -1924,7 +1935,7 @@ void QQuickListModel::remove(QQmlV8Function *args)
\sa set(), append()
*/
-void QQuickListModel::insert(QQmlV8Function *args)
+void QQmlListModel::insert(QQmlV8Function *args)
{
if (args->Length() == 2) {
@@ -1970,7 +1981,7 @@ void QQuickListModel::insert(QQmlV8Function *args)
}
/*!
- \qmlmethod QtQuick2::ListModel::move(int from, int to, int n)
+ \qmlmethod QtQml2::ListModel::move(int from, int to, int n)
Moves \a n items \a from one position \a to another.
@@ -1983,7 +1994,7 @@ void QQuickListModel::insert(QQmlV8Function *args)
\sa append()
*/
-void QQuickListModel::move(int from, int to, int n)
+void QQmlListModel::move(int from, int to, int n)
{
if (n==0 || from==to)
return;
@@ -2023,7 +2034,7 @@ void QQuickListModel::move(int from, int to, int n)
}
/*!
- \qmlmethod QtQuick2::ListModel::append(jsobject dict)
+ \qmlmethod QtQml2::ListModel::append(jsobject dict)
Adds a new item to the end of the list model, with the
values in \a dict.
@@ -2034,7 +2045,7 @@ void QQuickListModel::move(int from, int to, int n)
\sa set(), remove()
*/
-void QQuickListModel::append(QQmlV8Function *args)
+void QQmlListModel::append(QQmlV8Function *args)
{
if (args->Length() == 1) {
v8::Handle<v8::Value> arg = (*args)[0];
@@ -2077,7 +2088,7 @@ void QQuickListModel::append(QQmlV8Function *args)
}
/*!
- \qmlmethod object QtQuick2::ListModel::get(int index)
+ \qmlmethod object QtQml2::ListModel::get(int index)
Returns the item at \a index in the list model. This allows the item
data to be accessed or modified from JavaScript:
@@ -2107,7 +2118,7 @@ void QQuickListModel::append(QQmlV8Function *args)
\sa append()
*/
-QQmlV8Handle QQuickListModel::get(int index) const
+QQmlV8Handle QQmlListModel::get(int index) const
{
v8::Handle<v8::Value> result = v8::Undefined();
@@ -2118,7 +2129,7 @@ QQmlV8Handle QQuickListModel::get(int index) const
DynamicRoleModelNode *object = m_modelObjects[index];
result = v8engine->newQObject(object);
} else {
- ModelObject *object = m_listModel->getOrCreateModelObject(const_cast<QQuickListModel *>(this), index);
+ ModelObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
result = v8engine->newQObject(object);
}
}
@@ -2127,7 +2138,7 @@ QQmlV8Handle QQuickListModel::get(int index) const
}
/*!
- \qmlmethod QtQuick2::ListModel::set(int index, jsobject dict)
+ \qmlmethod QtQml2::ListModel::set(int index, jsobject dict)
Changes the item at \a index in the list model with the
values in \a dict. Properties not appearing in \a dict
@@ -2142,7 +2153,7 @@ QQmlV8Handle QQuickListModel::get(int index) const
\sa append()
*/
-void QQuickListModel::set(int index, const QQmlV8Handle &handle)
+void QQmlListModel::set(int index, const QQmlV8Handle &handle)
{
v8::Handle<v8::Value> valuemap = handle.toHandle();
@@ -2182,7 +2193,7 @@ void QQuickListModel::set(int index, const QQmlV8Handle &handle)
}
/*!
- \qmlmethod QtQuick2::ListModel::setProperty(int index, string property, variant value)
+ \qmlmethod QtQml2::ListModel::setProperty(int index, string property, variant value)
Changes the \a property of the item at \a index in the list model to \a value.
@@ -2194,7 +2205,7 @@ void QQuickListModel::set(int index, const QQmlV8Handle &handle)
\sa append()
*/
-void QQuickListModel::setProperty(int index, const QString& property, const QVariant& value)
+void QQmlListModel::setProperty(int index, const QString& property, const QVariant& value)
{
if (count() == 0 || index >= count() || index < 0) {
qmlInfo(this) << tr("set: index %1 out of range").arg(index);
@@ -2225,20 +2236,20 @@ void QQuickListModel::setProperty(int index, const QString& property, const QVar
}
/*!
- \qmlmethod QtQuick2::ListModel::sync()
+ \qmlmethod QtQml2::ListModel::sync()
Writes any unsaved changes to the list model after it has been modified
from a worker script.
*/
-void QQuickListModel::sync()
+void QQmlListModel::sync()
{
// This is just a dummy method to make it look like sync() exists in
- // ListModel (and not just QQuickListModelWorkerAgent) and to let
+ // ListModel (and not just QQmlListModelWorkerAgent) and to let
// us document sync().
qmlInfo(this) << "List sync() can only be called from a WorkerScript";
}
-bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
+bool QQmlListModelParser::compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
{
QList<QVariant> values = prop.assignedValues();
for(int ii = 0; ii < values.count(); ++ii) {
@@ -2250,8 +2261,8 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
if (node.name() != listElementTypeName) {
const QMetaObject *mo = resolveType(node.name());
- if (mo != &QQuickListElement::staticMetaObject) {
- error(node, QQuickListModel::tr("ListElement: cannot contain nested elements"));
+ if (mo != &QQmlListElement::staticMetaObject) {
+ error(node, QQmlListModel::tr("ListElement: cannot contain nested elements"));
return false;
}
listElementTypeName = node.name(); // cache right name for next time
@@ -2268,11 +2279,11 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
for(int jj = 0; jj < props.count(); ++jj) {
const QQmlCustomParserProperty &nodeProp = props.at(jj);
if (nodeProp.name().isEmpty()) {
- error(nodeProp, QQuickListModel::tr("ListElement: cannot contain nested elements"));
+ error(nodeProp, QQmlListModel::tr("ListElement: cannot contain nested elements"));
return false;
}
if (nodeProp.name() == QStringLiteral("id")) {
- error(nodeProp, QQuickListModel::tr("ListElement: cannot use reserved \"id\" property"));
+ error(nodeProp, QQmlListModel::tr("ListElement: cannot use reserved \"id\" property"));
return false;
}
@@ -2331,14 +2342,14 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
if (callExpr->arguments && !callExpr->arguments->next)
literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression);
if (!literal) {
- error(prop, QQuickListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString()));
+ error(prop, QQmlListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString()));
return false;
}
} else if (idExpr->name == QLatin1String("QT_TRANSLATE_NOOP")) {
if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next)
literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression);
if (!literal) {
- error(prop, QQuickListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP"));
+ error(prop, QQmlListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP"));
return false;
}
}
@@ -2349,7 +2360,7 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
d[0] = char(QQmlScript::Variant::String);
d += literal->value.toUtf8();
} else {
- error(prop, QQuickListModel::tr("ListElement: cannot use script for property value"));
+ error(prop, QQmlListModel::tr("ListElement: cannot use script for property value"));
return false;
}
} else {
@@ -2371,7 +2382,7 @@ bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop
return true;
}
-QByteArray QQuickListModelParser::compile(const QList<QQmlCustomParserProperty> &customProps)
+QByteArray QQmlListModelParser::compile(const QList<QQmlCustomParserProperty> &customProps)
{
QList<ListInstruction> instr;
QByteArray data;
@@ -2380,7 +2391,7 @@ QByteArray QQuickListModelParser::compile(const QList<QQmlCustomParserProperty>
for(int ii = 0; ii < customProps.count(); ++ii) {
const QQmlCustomParserProperty &prop = customProps.at(ii);
if(!prop.name().isEmpty()) { // isn't default property
- error(prop, QQuickListModel::tr("ListModel: undefined property '%1'").arg(prop.name()));
+ error(prop, QQmlListModel::tr("ListModel: undefined property '%1'").arg(prop.name()));
return QByteArray();
}
@@ -2407,9 +2418,9 @@ QByteArray QQuickListModelParser::compile(const QList<QQmlCustomParserProperty>
return rv;
}
-void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d)
+void QQmlListModelParser::setCustomData(QObject *obj, const QByteArray &d)
{
- QQuickListModel *rv = static_cast<QQuickListModel *>(obj);
+ QQmlListModel *rv = static_cast<QQmlListModel *>(obj);
QV8Engine *engine = QQmlEnginePrivate::getV8Engine(qmlEngine(rv));
rv->m_engine = engine;
@@ -2508,7 +2519,7 @@ void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d)
qmlInfo(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
}
-bool QQuickListModelParser::definesEmptyList(const QString &s)
+bool QQmlListModelParser::definesEmptyList(const QString &s)
{
if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) {
for (int i=1; i<s.length()-1; i++) {
@@ -2523,7 +2534,17 @@ bool QQuickListModelParser::definesEmptyList(const QString &s)
/*!
\qmltype ListElement
- \instantiates QQuickListElement
+ \instantiates QQmlListElement
+ \inqmlmodule QtQml.Models 2
+ \brief Defines a data item in a ListModel
+
+ List elements are defined inside ListModel definitions, and represent items in a list.
+
+ This type is also available in the QtQuick 2 import. For full documentation, see \l QtQuick2::ListElement
+*/
+/*!
+ \qmltype ListElement
+ \instantiates QQmlListElement
\inqmlmodule QtQuick 2
\brief Defines a data item in a ListModel
\ingroup qtquick-models
diff --git a/src/qml/qml/qquicklistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 8649238b80..70477115bd 100644
--- a/src/qml/qml/qquicklistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QQUICKLISTMODEL_H
-#define QQUICKLISTMODEL_H
+#ifndef QQMLLISTMODEL_H
+#define QQMLLISTMODEL_H
#include <qqml.h>
#include <private/qqmlcustomparser_p.h>
@@ -55,24 +55,22 @@
#include <private/qv8engine_p.h>
#include <private/qpodvector_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-class QQuickListModelWorkerAgent;
+class QQmlListModelWorkerAgent;
class ListModel;
class ListLayout;
-class Q_QML_PRIVATE_EXPORT QQuickListModel : public QAbstractListModel
+class Q_QML_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
public:
- QQuickListModel(QObject *parent=0);
- ~QQuickListModel();
+ QQmlListModel(QObject *parent=0);
+ ~QQmlListModel();
QModelIndex index(int row, int column, const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
@@ -92,7 +90,7 @@ public:
Q_INVOKABLE void move(int from, int to, int count);
Q_INVOKABLE void sync();
- QQuickListModelWorkerAgent *agent();
+ QQmlListModelWorkerAgent *agent();
bool dynamicRoles() const { return m_dynamicRoles; }
void setDynamicRoles(bool enableDynamicRoles);
@@ -101,8 +99,8 @@ Q_SIGNALS:
void countChanged();
private:
- friend class QQuickListModelParser;
- friend class QQuickListModelWorkerAgent;
+ friend class QQmlListModelParser;
+ friend class QQmlListModelWorkerAgent;
friend class ModelObject;
friend class ModelNodeMetaObject;
friend class ListModel;
@@ -111,14 +109,14 @@ private:
friend class DynamicRoleModelNodeMetaObject;
// Constructs a flat list model for a worker agent
- QQuickListModel(QQuickListModel *orig, QQuickListModelWorkerAgent *agent);
- QQuickListModel(const QQuickListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent=0);
+ QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent);
+ QQmlListModel(const QQmlListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent=0);
QV8Engine *engine() const;
inline bool canMove(int from, int to, int n) const { return !(from+n > count() || to+n > count() || from < 0 || to < 0 || n < 0); }
- QQuickListModelWorkerAgent *m_agent;
+ QQmlListModelWorkerAgent *m_agent;
mutable QV8Engine *m_engine;
bool m_mainThread;
bool m_primary;
@@ -142,8 +140,8 @@ private:
int getUid() const { return m_uid; }
- static void sync(QQuickListModel *src, QQuickListModel *target, QHash<int, QQuickListModel *> *targetModelHash);
- static QQuickListModel *createWithOwner(QQuickListModel *newOwner);
+ static void sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash);
+ static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
void emitItemsChanged(int index, int count, const QVector<int> &roles);
void emitItemsRemoved(int index, int count);
@@ -152,15 +150,15 @@ private:
};
// ### FIXME
-class QQuickListElement : public QObject
+class QQmlListElement : public QObject
{
Q_OBJECT
};
-class QQuickListModelParser : public QQmlCustomParser
+class QQmlListModelParser : public QQmlCustomParser
{
public:
- QQuickListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
+ QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
QByteArray compile(const QList<QQmlCustomParserProperty> &);
void setCustomData(QObject *, const QByteArray &);
@@ -194,9 +192,7 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickListModel)
-QML_DECLARE_TYPE(QQuickListElement)
-
-QT_END_HEADER
+QML_DECLARE_TYPE(QQmlListModel)
+QML_DECLARE_TYPE(QQmlListElement)
-#endif // QQUICKLISTMODEL_H
+#endif // QQMLLISTMODEL_H
diff --git a/src/qml/qml/qquicklistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index ff312f98e5..0190081320 100644
--- a/src/qml/qml/qquicklistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QQUICKLISTMODEL_P_P_H
-#define QQUICKLISTMODEL_P_P_H
+#ifndef QQMLLISTMODEL_P_P_H
+#define QQMLLISTMODEL_P_P_H
//
// W A R N I N G
@@ -53,13 +53,11 @@
// We mean it.
//
-#include "qquicklistmodel_p.h"
+#include "qqmllistmodel_p.h"
#include <private/qqmlengine_p.h>
-#include "qqmlopenmetaobject_p.h"
+#include <private/qqmlopenmetaobject_p.h>
#include <qqml.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -85,9 +83,9 @@ class DynamicRoleModelNode : public QObject
{
Q_OBJECT
public:
- DynamicRoleModelNode(QQuickListModel *owner, int uid);
+ DynamicRoleModelNode(QQmlListModel *owner, int uid);
- static DynamicRoleModelNode *create(const QVariantMap &obj, QQuickListModel *owner);
+ static DynamicRoleModelNode *create(const QVariantMap &obj, QQmlListModel *owner);
void updateValues(const QVariantMap &object, QVector<int> &roles);
@@ -111,10 +109,10 @@ public:
return m_uid;
}
- static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQuickListModel *> *targetModelHash);
+ static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash);
private:
- QQuickListModel *m_owner;
+ QQmlListModel *m_owner;
int m_uid;
DynamicRoleModelNodeMetaObject *m_meta;
@@ -143,7 +141,7 @@ class ModelObject : public QObject
{
Q_OBJECT
public:
- ModelObject(QQuickListModel *model, int elementIndex);
+ ModelObject(QQmlListModel *model, int elementIndex);
void setValue(const QByteArray &name, const QVariant &val, bool force)
{
@@ -164,7 +162,7 @@ public:
void updateValues();
void updateValues(const QVector<int> &roles);
- QQuickListModel *m_model;
+ QQmlListModel *m_model;
int m_elementIndex;
private:
@@ -273,7 +271,7 @@ private:
void clearProperty(const ListLayout::Role &role);
- QVariant getProperty(const ListLayout::Role &role, const QQuickListModel *owner, QV8Engine *eng);
+ QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV8Engine *eng);
ListModel *getListProperty(const ListLayout::Role &role);
QString *getStringProperty(const ListLayout::Role &role);
QObject *getQObjectProperty(const ListLayout::Role &role);
@@ -298,7 +296,7 @@ class ListModel
{
public:
- ListModel(ListLayout *layout, QQuickListModel *modelCache, int uid);
+ ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid);
~ListModel() {}
void destroy();
@@ -306,7 +304,7 @@ public:
int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data);
int setExistingProperty(int uid, const QString &key, v8::Handle<v8::Value> data, QV8Engine *eng);
- QVariant getProperty(int elementIndex, int roleIndex, const QQuickListModel *owner, QV8Engine *eng);
+ QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV8Engine *eng);
ListModel *getListProperty(int elementIndex, const ListLayout::Role &role);
int roleCount() const
@@ -347,14 +345,14 @@ public:
static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash);
- ModelObject *getOrCreateModelObject(QQuickListModel *model, int elementIndex);
+ ModelObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
private:
QPODVector<ListElement *, 4> elements;
ListLayout *m_layout;
int m_uid;
- QQuickListModel *m_modelCache;
+ QQmlListModel *m_modelCache;
struct ElementSync
{
@@ -369,14 +367,12 @@ private:
void updateCacheIndices();
friend class ListElement;
- friend class QQuickListModelWorkerAgent;
+ friend class QQmlListModelWorkerAgent;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(ListModel *);
-QT_END_HEADER
-
#endif // QQUICKLISTMODEL_P_P_H
diff --git a/src/qml/qml/qquicklistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp
index e0ab882b92..9554e6d1e5 100644
--- a/src/qml/qml/qquicklistmodelworkeragent.cpp
+++ b/src/qml/types/qqmllistmodelworkeragent.cpp
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#include "qquicklistmodelworkeragent_p.h"
-#include "qquicklistmodel_p_p.h"
+#include "qqmllistmodelworkeragent_p.h"
+#include "qqmllistmodel_p_p.h"
#include <private/qqmldata_p.h>
#include <private/qqmlengine_p.h>
#include <qqmlinfo.h>
@@ -53,7 +53,7 @@
QT_BEGIN_NAMESPACE
-void QQuickListModelWorkerAgent::Data::clearChange(int uid)
+void QQmlListModelWorkerAgent::Data::clearChange(int uid)
{
for (int i=0 ; i < changes.count() ; ++i) {
if (changes[i].modelUid == uid) {
@@ -63,53 +63,53 @@ void QQuickListModelWorkerAgent::Data::clearChange(int uid)
}
}
-void QQuickListModelWorkerAgent::Data::insertChange(int uid, int index, int count)
+void QQmlListModelWorkerAgent::Data::insertChange(int uid, int index, int count)
{
Change c = { uid, Change::Inserted, index, count, 0, QVector<int>() };
changes << c;
}
-void QQuickListModelWorkerAgent::Data::removeChange(int uid, int index, int count)
+void QQmlListModelWorkerAgent::Data::removeChange(int uid, int index, int count)
{
Change c = { uid, Change::Removed, index, count, 0, QVector<int>() };
changes << c;
}
-void QQuickListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to)
+void QQmlListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to)
{
Change c = { uid, Change::Moved, index, count, to, QVector<int>() };
changes << c;
}
-void QQuickListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles)
+void QQmlListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles)
{
Change c = { uid, Change::Changed, index, count, 0, roles };
changes << c;
}
-QQuickListModelWorkerAgent::QQuickListModelWorkerAgent(QQuickListModel *model)
-: m_ref(1), m_orig(model), m_copy(new QQuickListModel(model, this))
+QQmlListModelWorkerAgent::QQmlListModelWorkerAgent(QQmlListModel *model)
+: m_ref(1), m_orig(model), m_copy(new QQmlListModel(model, this))
{
}
-QQuickListModelWorkerAgent::~QQuickListModelWorkerAgent()
+QQmlListModelWorkerAgent::~QQmlListModelWorkerAgent()
{
mutex.lock();
syncDone.wakeAll();
mutex.unlock();
}
-void QQuickListModelWorkerAgent::setV8Engine(QV8Engine *eng)
+void QQmlListModelWorkerAgent::setV8Engine(QV8Engine *eng)
{
m_copy->m_engine = eng;
}
-void QQuickListModelWorkerAgent::addref()
+void QQmlListModelWorkerAgent::addref()
{
m_ref.ref();
}
-void QQuickListModelWorkerAgent::release()
+void QQmlListModelWorkerAgent::release()
{
bool del = !m_ref.deref();
@@ -117,57 +117,57 @@ void QQuickListModelWorkerAgent::release()
deleteLater();
}
-void QQuickListModelWorkerAgent::modelDestroyed()
+void QQmlListModelWorkerAgent::modelDestroyed()
{
m_orig = 0;
}
-int QQuickListModelWorkerAgent::count() const
+int QQmlListModelWorkerAgent::count() const
{
return m_copy->count();
}
-void QQuickListModelWorkerAgent::clear()
+void QQmlListModelWorkerAgent::clear()
{
m_copy->clear();
}
-void QQuickListModelWorkerAgent::remove(QQmlV8Function *args)
+void QQmlListModelWorkerAgent::remove(QQmlV8Function *args)
{
m_copy->remove(args);
}
-void QQuickListModelWorkerAgent::append(QQmlV8Function *args)
+void QQmlListModelWorkerAgent::append(QQmlV8Function *args)
{
m_copy->append(args);
}
-void QQuickListModelWorkerAgent::insert(QQmlV8Function *args)
+void QQmlListModelWorkerAgent::insert(QQmlV8Function *args)
{
m_copy->insert(args);
}
-QQmlV8Handle QQuickListModelWorkerAgent::get(int index) const
+QQmlV8Handle QQmlListModelWorkerAgent::get(int index) const
{
return m_copy->get(index);
}
-void QQuickListModelWorkerAgent::set(int index, const QQmlV8Handle &value)
+void QQmlListModelWorkerAgent::set(int index, const QQmlV8Handle &value)
{
m_copy->set(index, value);
}
-void QQuickListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
+void QQmlListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
{
m_copy->setProperty(index, property, value);
}
-void QQuickListModelWorkerAgent::move(int from, int to, int count)
+void QQmlListModelWorkerAgent::move(int from, int to, int count)
{
m_copy->move(from, to, count);
}
-void QQuickListModelWorkerAgent::sync()
+void QQmlListModelWorkerAgent::sync()
{
Sync *s = new Sync;
s->data = data;
@@ -180,7 +180,7 @@ void QQuickListModelWorkerAgent::sync()
mutex.unlock();
}
-bool QQuickListModelWorkerAgent::event(QEvent *e)
+bool QQmlListModelWorkerAgent::event(QEvent *e)
{
if (e->type() == QEvent::User) {
bool cc = false;
@@ -191,19 +191,19 @@ bool QQuickListModelWorkerAgent::event(QEvent *e)
cc = m_orig->count() != s->list->count();
- QHash<int, QQuickListModel *> targetModelDynamicHash;
+ QHash<int, QQmlListModel *> targetModelDynamicHash;
QHash<int, ListModel *> targetModelStaticHash;
Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
if (m_orig->m_dynamicRoles)
- QQuickListModel::sync(s->list, m_orig, &targetModelDynamicHash);
+ QQmlListModel::sync(s->list, m_orig, &targetModelDynamicHash);
else
ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
for (int ii = 0; ii < changes.count(); ++ii) {
const Change &change = changes.at(ii);
- QQuickListModel *model = 0;
+ QQmlListModel *model = 0;
if (m_orig->m_dynamicRoles) {
model = targetModelDynamicHash.value(change.modelUid);
} else {
diff --git a/src/qml/qml/qquicklistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index 7cff9be8f4..614017069c 100644
--- a/src/qml/qml/qquicklistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -60,21 +60,19 @@
#include <private/qv8engine_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-class QQuickListModel;
+class QQmlListModel;
-class QQuickListModelWorkerAgent : public QObject
+class QQmlListModelWorkerAgent : public QObject
{
Q_OBJECT
Q_PROPERTY(int count READ count)
public:
- QQuickListModelWorkerAgent(QQuickListModel *);
- ~QQuickListModelWorkerAgent();
+ QQmlListModelWorkerAgent(QQmlListModel *);
+ ~QQmlListModelWorkerAgent();
void setV8Engine(QV8Engine *eng);
void addref();
@@ -96,7 +94,7 @@ public:
{
VariantRef() : a(0) {}
VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
- VariantRef(QQuickListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
+ VariantRef(QQmlListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
~VariantRef() { if (a) a->release(); }
VariantRef &operator=(const VariantRef &o) {
@@ -105,7 +103,7 @@ public:
return *this;
}
- QQuickListModelWorkerAgent *a;
+ QQmlListModelWorkerAgent *a;
};
void modelDestroyed();
protected:
@@ -113,7 +111,7 @@ protected:
private:
friend class QQuickWorkerScriptEnginePrivate;
- friend class QQuickListModel;
+ friend class QQmlListModel;
struct Change
{
@@ -140,21 +138,19 @@ private:
struct Sync : public QEvent {
Sync() : QEvent(QEvent::User) {}
Data data;
- QQuickListModel *list;
+ QQmlListModel *list;
};
QAtomicInt m_ref;
- QQuickListModel *m_orig;
- QQuickListModel *m_copy;
+ QQmlListModel *m_orig;
+ QQmlListModel *m_copy;
QMutex mutex;
QWaitCondition syncDone;
};
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QQuickListModelWorkerAgent::VariantRef)
-
-QT_END_HEADER
+Q_DECLARE_METATYPE(QQmlListModelWorkerAgent::VariantRef)
#endif // QQUICKLISTMODELWORKERAGENT_P_H
diff --git a/src/qml/types/qqmlmodelsmodule.cpp b/src/qml/types/qqmlmodelsmodule.cpp
new file mode 100644
index 0000000000..4f6b0a5580
--- /dev/null
+++ b/src/qml/types/qqmlmodelsmodule.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlmodelsmodule_p.h"
+#include <private/qqmllistmodel_p.h>
+#include <private/qqmldelegatemodel_p.h>
+#include <private/qqmlobjectmodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQmlModelsModule::defineModule()
+{
+ const char uri[] = "QtQml.Models";
+
+ qmlRegisterType<QQmlListElement>(uri, 2, 1, "ListElement");
+ qmlRegisterCustomType<QQmlListModel>(uri, 2, 1, "ListModel", new QQmlListModelParser);
+ qmlRegisterType<QQmlDelegateModel>(uri, 2, 1, "DelegateModel");
+ qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 1, "DelegateModelGroup");
+ qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/types/qqmlmodelsmodule_p.h b/src/qml/types/qqmlmodelsmodule_p.h
new file mode 100644
index 0000000000..6e72dadf8b
--- /dev/null
+++ b/src/qml/types/qqmlmodelsmodule_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLMODELSMODULE_H
+#define QQMLMODELSMODULE_H
+
+#include <private/qtqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QML_PRIVATE_EXPORT QQmlModelsModule
+{
+public:
+ static void defineModule();
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
new file mode 100644
index 0000000000..7f7bf92fa3
--- /dev/null
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -0,0 +1,269 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlobjectmodel_p.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+
+#include <private/qqmlchangeset_p.h>
+#include <private/qqmlglobal_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+QHash<QObject*, QQmlObjectModelAttached*> QQmlObjectModelAttached::attachedProperties;
+
+
+class QQmlObjectModelPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlObjectModel)
+public:
+ class Item {
+ public:
+ Item(QObject *i) : item(i), ref(0) {}
+
+ void addRef() { ++ref; }
+ bool deref() { return --ref == 0; }
+
+ QObject *item;
+ int ref;
+ };
+
+ QQmlObjectModelPrivate() : QObjectPrivate() {}
+
+ static void children_append(QQmlListProperty<QObject> *prop, QObject *item) {
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->children.append(Item(item));
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->itemAppended();
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->emitChildrenChanged();
+ }
+
+ static int children_count(QQmlListProperty<QObject> *prop) {
+ return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
+ }
+
+ static QObject *children_at(QQmlListProperty<QObject> *prop, int index) {
+ return static_cast<QQmlObjectModelPrivate *>(prop->data)->children.at(index).item;
+ }
+
+ static void children_clear(QQmlListProperty<QObject> *prop) {
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->itemCleared(static_cast<QQmlObjectModelPrivate *>(prop->data)->children);
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->children.clear();
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->emitChildrenChanged();
+ }
+
+ void itemAppended() {
+ Q_Q(QQmlObjectModel);
+ QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.last().item);
+ attached->setIndex(children.count()-1);
+ QQmlChangeSet changeSet;
+ changeSet.insert(children.count() - 1, 1);
+ emit q->modelUpdated(changeSet, false);
+ emit q->countChanged();
+ }
+
+ void itemCleared(const QList<Item> &children) {
+ Q_Q(QQmlObjectModel);
+ foreach (const Item &child, children)
+ emit q->destroyingItem(child.item);
+ emit q->countChanged();
+ }
+
+ void emitChildrenChanged() {
+ Q_Q(QQmlObjectModel);
+ emit q->childrenChanged();
+ }
+
+ int indexOf(QObject *item) const {
+ for (int i = 0; i < children.count(); ++i)
+ if (children.at(i).item == item)
+ return i;
+ return -1;
+ }
+
+
+ QList<Item> children;
+};
+
+
+/*!
+ \qmltype ObjectModel
+ \instantiates QQmlObjectModel
+ \inqmlmodule QtQml.Models 2
+ \ingroup qtquick-models
+ \brief Defines a set of items to be used as a model
+
+ A ObjectModel contains the visual items to be used in a view.
+ When a ObjectModel is used in a view, the view does not require
+ a delegate since the ObjectModel already contains the visual
+ delegate (items).
+
+ An item can determine its index within the
+ model via the \l{ObjectModel::index}{index} attached property.
+
+ The example below places three colored rectangles in a ListView.
+ \code
+ import QtQuick 2.0
+
+ Rectangle {
+ ObjectModel {
+ id: itemModel
+ Rectangle { height: 30; width: 80; color: "red" }
+ Rectangle { height: 30; width: 80; color: "green" }
+ Rectangle { height: 30; width: 80; color: "blue" }
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: itemModel
+ }
+ }
+ \endcode
+
+ \image visualitemmodel.png
+
+ \sa {quick/views/objectmodel}{ObjectModel example}
+*/
+/*!
+ \qmltype VisualItemModel
+ \instantiates QQmlObjectModel
+ \inqmlmodule QtQuick 2
+ \brief Defines a set of objects to be used as a model
+
+ The VisualItemModel type encapsulates contains the objects to be used
+ as a model.
+
+ This element is now primarily available as ObjectModel in the QtQml.Models module.
+ VisualItemModel continues to be provided, with the same implementation, in QtQuick for
+ compatibility reasons.
+
+ For full details about the type, see the \l ObjectModel documentation.
+
+ \sa {QtQml.Models2::ObjectModel}
+*/
+
+QQmlObjectModel::QQmlObjectModel(QObject *parent)
+ : QQmlInstanceModel(*(new QQmlObjectModelPrivate), parent)
+{
+}
+
+/*!
+ \qmlattachedproperty int QtQml.Models2::ObjectModel::index
+ This attached property holds the index of this delegate's item within the model.
+
+ It is attached to each instance of the delegate.
+*/
+
+QQmlListProperty<QObject> QQmlObjectModel::children()
+{
+ Q_D(QQmlObjectModel);
+ return QQmlListProperty<QObject>(this,
+ d,
+ d->children_append,
+ d->children_count,
+ d->children_at,
+ d->children_clear);
+}
+
+/*!
+ \qmlproperty int QtQml.Models2::ObjectModel::count
+
+ The number of items in the model. This property is readonly.
+*/
+int QQmlObjectModel::count() const
+{
+ Q_D(const QQmlObjectModel);
+ return d->children.count();
+}
+
+bool QQmlObjectModel::isValid() const
+{
+ return true;
+}
+
+QObject *QQmlObjectModel::object(int index, bool)
+{
+ Q_D(QQmlObjectModel);
+ QQmlObjectModelPrivate::Item &item = d->children[index];
+ item.addRef();
+ if (item.ref == 1) {
+ emit initItem(index, item.item);
+ emit createdItem(index, item.item);
+ }
+ return item.item;
+}
+
+QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item)
+{
+ Q_D(QQmlObjectModel);
+ int idx = d->indexOf(item);
+ if (idx >= 0) {
+ if (!d->children[idx].deref())
+ return QQmlInstanceModel::Referenced;
+ }
+ return 0;
+}
+
+QString QQmlObjectModel::stringValue(int index, const QString &name)
+{
+ Q_D(QQmlObjectModel);
+ if (index < 0 || index >= d->children.count())
+ return QString();
+ return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
+}
+
+int QQmlObjectModel::indexOf(QObject *item, QObject *) const
+{
+ Q_D(const QQmlObjectModel);
+ return d->indexOf(item);
+}
+
+QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
+{
+ return QQmlObjectModelAttached::properties(obj);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/qml/types/qqmlobjectmodel_p.h b/src/qml/types/qqmlobjectmodel_p.h
new file mode 100644
index 0000000000..59a4a551a7
--- /dev/null
+++ b/src/qml/types/qqmlobjectmodel_p.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLINSTANCEMODEL_P_H
+#define QQMLINSTANCEMODEL_P_H
+
+#include <private/qtqmlglobal_p.h>
+#include <QtQml/qqml.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+class QQmlChangeSet;
+
+class Q_QML_PRIVATE_EXPORT QQmlInstanceModel : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+
+public:
+ virtual ~QQmlInstanceModel() {}
+
+ enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 };
+ Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag)
+
+ virtual int count() const = 0;
+ virtual bool isValid() const = 0;
+ virtual QObject *object(int index, bool asynchronous=false) = 0;
+ virtual ReleaseFlags release(QObject *object) = 0;
+ virtual void cancel(int) {}
+ virtual QString stringValue(int, const QString &) = 0;
+ virtual void setWatchedRoles(QList<QByteArray> roles) = 0;
+
+ virtual int indexOf(QObject *object, QObject *objectContext) const = 0;
+
+Q_SIGNALS:
+ void countChanged();
+ void modelUpdated(const QQmlChangeSet &changeSet, bool reset);
+ void createdItem(int index, QObject *object);
+ void initItem(int index, QObject *object);
+ void destroyingItem(QObject *object);
+
+protected:
+ QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = 0)
+ : QObject(dd, parent) {}
+
+private:
+ Q_DISABLE_COPY(QQmlInstanceModel)
+};
+
+class QQmlObjectModelAttached;
+class QQmlObjectModelPrivate;
+class Q_QML_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlObjectModel)
+
+ Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false)
+ Q_CLASSINFO("DefaultProperty", "children")
+
+public:
+ QQmlObjectModel(QObject *parent=0);
+ virtual ~QQmlObjectModel() {}
+
+ virtual int count() const;
+ virtual bool isValid() const;
+ virtual QObject *object(int index, bool asynchronous=false);
+ virtual ReleaseFlags release(QObject *object);
+ virtual QString stringValue(int index, const QString &role);
+ virtual void setWatchedRoles(QList<QByteArray>) {}
+
+ virtual int indexOf(QObject *object, QObject *objectContext) const;
+
+ QQmlListProperty<QObject> children();
+
+ static QQmlObjectModelAttached *qmlAttachedProperties(QObject *obj);
+
+Q_SIGNALS:
+ void childrenChanged();
+
+private:
+ Q_DISABLE_COPY(QQmlObjectModel)
+};
+
+class QQmlObjectModelAttached : public QObject
+{
+ Q_OBJECT
+
+public:
+ QQmlObjectModelAttached(QObject *parent)
+ : QObject(parent), m_index(0) {}
+ ~QQmlObjectModelAttached() {
+ attachedProperties.remove(parent());
+ }
+
+ Q_PROPERTY(int index READ index NOTIFY indexChanged)
+ int index() const { return m_index; }
+ void setIndex(int idx) {
+ if (m_index != idx) {
+ m_index = idx;
+ emit indexChanged();
+ }
+ }
+
+ static QQmlObjectModelAttached *properties(QObject *obj) {
+ QQmlObjectModelAttached *rv = attachedProperties.value(obj);
+ if (!rv) {
+ rv = new QQmlObjectModelAttached(obj);
+ attachedProperties.insert(obj, rv);
+ }
+ return rv;
+ }
+
+Q_SIGNALS:
+ void indexChanged();
+
+public:
+ int m_index;
+
+ static QHash<QObject*, QQmlObjectModelAttached*> attachedProperties;
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQmlInstanceModel)
+QML_DECLARE_TYPE(QQmlObjectModel)
+QML_DECLARE_TYPEINFO(QQmlObjectModel, QML_HAS_ATTACHED_PROPERTIES)
+
+#endif // QQMLINSTANCEMODEL_P_H
diff --git a/src/qml/qml/qqmltimer.cpp b/src/qml/types/qqmltimer.cpp
index c9f6bc7982..a1cb8532f7 100644
--- a/src/qml/qml/qqmltimer.cpp
+++ b/src/qml/types/qqmltimer.cpp
@@ -75,7 +75,7 @@ public:
/*!
\qmltype Timer
\instantiates QQmlTimer
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQml 2
\ingroup qtquick-interceptors
\brief Triggers a handler at a specified interval
@@ -122,7 +122,7 @@ QQmlTimer::QQmlTimer(QObject *parent)
}
/*!
- \qmlproperty int QtQuick2::Timer::interval
+ \qmlproperty int QtQml2::Timer::interval
Sets the \a interval between triggers, in milliseconds.
@@ -145,7 +145,7 @@ int QQmlTimer::interval() const
}
/*!
- \qmlproperty bool QtQuick2::Timer::running
+ \qmlproperty bool QtQml2::Timer::running
If set to true, starts the timer; otherwise stops the timer.
For a non-repeating timer, \a running is set to false after the
@@ -173,7 +173,7 @@ void QQmlTimer::setRunning(bool running)
}
/*!
- \qmlproperty bool QtQuick2::Timer::repeat
+ \qmlproperty bool QtQml2::Timer::repeat
If \a repeat is true the timer is triggered repeatedly at the
specified interval; otherwise, the timer will trigger once at the
@@ -200,7 +200,7 @@ void QQmlTimer::setRepeating(bool repeating)
}
/*!
- \qmlproperty bool QtQuick2::Timer::triggeredOnStart
+ \qmlproperty bool QtQml2::Timer::triggeredOnStart
When a timer is started, the first trigger is usually after the specified
interval has elapsed. It is sometimes desirable to trigger immediately
@@ -233,7 +233,7 @@ void QQmlTimer::setTriggeredOnStart(bool triggeredOnStart)
}
/*!
- \qmlmethod QtQuick2::Timer::start()
+ \qmlmethod QtQml2::Timer::start()
\brief Starts the timer
If the timer is already running, calling this method has no effect. The
@@ -245,7 +245,7 @@ void QQmlTimer::start()
}
/*!
- \qmlmethod QtQuick2::Timer::stop()
+ \qmlmethod QtQml2::Timer::stop()
\brief Stops the timer
If the timer is not running, calling this method has no effect. The
@@ -257,7 +257,7 @@ void QQmlTimer::stop()
}
/*!
- \qmlmethod QtQuick2::Timer::restart()
+ \qmlmethod QtQml2::Timer::restart()
\brief Restarts the timer
If the Timer is not running it will be started, otherwise it will be
@@ -302,7 +302,7 @@ void QQmlTimer::componentComplete()
}
/*!
- \qmlsignal QtQuick2::Timer::onTriggered()
+ \qmlsignal QtQml2::Timer::onTriggered()
This handler is called when the Timer is triggered.
*/
diff --git a/src/qml/qml/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h
index ff6d6207ff..c625522851 100644
--- a/src/qml/qml/qqmltimer_p.h
+++ b/src/qml/types/qqmltimer_p.h
@@ -48,8 +48,6 @@
#include <private/qtqmlglobal_p.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QQmlTimerPrivate;
@@ -106,6 +104,4 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlTimer)
-QT_END_HEADER
-
#endif
diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp
new file mode 100644
index 0000000000..e885524b27
--- /dev/null
+++ b/src/qml/types/qquickpackage.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpackage_p.h"
+
+#include <private/qobject_p.h>
+#include <private/qqmlguard_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype Package
+ \instantiates QQuickPackage
+ \inqmlmodule QtQuick 2
+ \ingroup qtquick-views
+ \brief Specifies a collection of named items
+
+ The Package class is used in conjunction with
+ VisualDataModel to enable delegates with a shared context
+ to be provided to multiple views.
+
+ Any item within a Package may be assigned a name via the
+ \l{Package::name}{Package.name} attached property.
+
+ The example below creates a Package containing two named items;
+ \e list and \e grid. The third item in the package (the \l Rectangle) is parented to whichever
+ delegate it should appear in. This allows an item to move
+ between views.
+
+ \snippet quick/views/package/Delegate.qml 0
+
+ These named items are used as the delegates by the two views who
+ reference the special \l{VisualDataModel::parts} property to select
+ a model which provides the chosen delegate.
+
+ \snippet quick/views/package/view.qml 0
+
+ \sa {quick/views/package}{Package example}, {quick/demos/photoviewer}{Photo Viewer example}, QtQml
+*/
+
+/*!
+ \qmlattachedproperty string QtQuick2::Package::name
+ This attached property holds the name of an item within a Package.
+*/
+
+
+class QQuickPackagePrivate : public QObjectPrivate
+{
+public:
+ QQuickPackagePrivate() {}
+
+ struct DataGuard : public QQmlGuard<QObject>
+ {
+ DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; }
+ QList<DataGuard> *list;
+ void objectDestroyed(QObject *) {
+ // we assume priv will always be destroyed after objectDestroyed calls
+ list->removeOne(*this);
+ }
+ };
+
+ QList<DataGuard> dataList;
+ static void data_append(QQmlListProperty<QObject> *prop, QObject *o) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->append(DataGuard(o, list));
+ }
+ static void data_clear(QQmlListProperty<QObject> *prop) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ list->clear();
+ }
+ static QObject *data_at(QQmlListProperty<QObject> *prop, int index) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ return list->at(index);
+ }
+ static int data_count(QQmlListProperty<QObject> *prop) {
+ QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data);
+ return list->count();
+ }
+};
+
+QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached;
+
+QQuickPackageAttached::QQuickPackageAttached(QObject *parent)
+: QObject(parent)
+{
+ attached.insert(parent, this);
+}
+
+QQuickPackageAttached::~QQuickPackageAttached()
+{
+ attached.remove(parent());
+}
+
+QString QQuickPackageAttached::name() const
+{
+ return _name;
+}
+
+void QQuickPackageAttached::setName(const QString &n)
+{
+ _name = n;
+}
+
+QQuickPackage::QQuickPackage(QObject *parent)
+ : QObject(*(new QQuickPackagePrivate), parent)
+{
+}
+
+QQuickPackage::~QQuickPackage()
+{
+}
+
+QQmlListProperty<QObject> QQuickPackage::data()
+{
+ Q_D(QQuickPackage);
+ return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append,
+ QQuickPackagePrivate::data_count,
+ QQuickPackagePrivate::data_at,
+ QQuickPackagePrivate::data_clear);
+}
+
+bool QQuickPackage::hasPart(const QString &name)
+{
+ Q_D(QQuickPackage);
+ for (int ii = 0; ii < d->dataList.count(); ++ii) {
+ QObject *obj = d->dataList.at(ii);
+ QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
+ if (a && a->name() == name)
+ return true;
+ }
+ return false;
+}
+
+QObject *QQuickPackage::part(const QString &name)
+{
+ Q_D(QQuickPackage);
+ if (name.isEmpty() && !d->dataList.isEmpty())
+ return d->dataList.at(0);
+
+ for (int ii = 0; ii < d->dataList.count(); ++ii) {
+ QObject *obj = d->dataList.at(ii);
+ QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj);
+ if (a && a->name() == name)
+ return obj;
+ }
+
+ if (name == QLatin1String("default") && !d->dataList.isEmpty())
+ return d->dataList.at(0);
+
+ return 0;
+}
+
+QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o)
+{
+ return new QQuickPackageAttached(o);
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/qml/types/qquickpackage_p.h b/src/qml/types/qquickpackage_p.h
new file mode 100644
index 0000000000..9427c886a8
--- /dev/null
+++ b/src/qml/types/qquickpackage_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPACKAGE_H
+#define QQUICKPACKAGE_H
+
+#include <qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPackagePrivate;
+class QQuickPackageAttached;
+class Q_AUTOTEST_EXPORT QQuickPackage : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQuickPackage)
+
+ Q_CLASSINFO("DefaultProperty", "data")
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data)
+
+public:
+ QQuickPackage(QObject *parent=0);
+ virtual ~QQuickPackage();
+
+ QQmlListProperty<QObject> data();
+
+ QObject *part(const QString & = QString());
+ bool hasPart(const QString &);
+
+ static QQuickPackageAttached *qmlAttachedProperties(QObject *);
+};
+
+class QQuickPackageAttached : public QObject
+{
+Q_OBJECT
+Q_PROPERTY(QString name READ name WRITE setName)
+public:
+ QQuickPackageAttached(QObject *parent);
+ virtual ~QQuickPackageAttached();
+
+ QString name() const;
+ void setName(const QString &n);
+
+ static QHash<QObject *, QQuickPackageAttached *> attached;
+private:
+ QString _name;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPackage)
+QML_DECLARE_TYPEINFO(QQuickPackage, QML_HAS_ATTACHED_PROPERTIES)
+
+#endif // QQUICKPACKAGE_H
diff --git a/src/qml/qml/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index f7559f1d36..ad09e1ec0c 100644
--- a/src/qml/qml/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -40,10 +40,10 @@
****************************************************************************/
#include "qquickworkerscript_p.h"
-#include "qquicklistmodel_p.h"
-#include "qquicklistmodelworkeragent_p.h"
-#include "qqmlengine_p.h"
-#include "qqmlexpression_p.h"
+#include "qqmllistmodel_p.h"
+#include "qqmllistmodelworkeragent_p.h"
+#include <private/qqmlengine_p.h>
+#include <private/qqmlexpression_p.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
@@ -484,7 +484,7 @@ QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine()
//We have to force to cleanup the main thread's event queue here
//to make sure the main GUI release all pending locks/wait conditions which
- //some worker script/agent are waiting for (QQuickListModelWorkerAgent::sync() for example).
+ //some worker script/agent are waiting for (QQmlListModelWorkerAgent::sync() for example).
while (!isFinished()) {
// We can't simply wait here, because the worker thread will not terminate
// until the main thread processes the last data event it generates
diff --git a/src/qml/qml/qquickworkerscript_p.h b/src/qml/types/qquickworkerscript_p.h
index e643751953..1ab5208e45 100644
--- a/src/qml/qml/qquickworkerscript_p.h
+++ b/src/qml/types/qquickworkerscript_p.h
@@ -54,14 +54,12 @@
//
#include "qqml.h"
-#include "qqmlparserstatus.h"
+#include <QtQml/qqmlparserstatus.h>
#include <QtCore/qthread.h>
#include <QtQml/qjsvalue.h>
#include <QtCore/qurl.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -125,6 +123,4 @@ QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickWorkerScript)
-QT_END_HEADER
-
#endif // QQUICKWORKERSCRIPT_P_H
diff --git a/src/qml/types/types.pri b/src/qml/types/types.pri
new file mode 100644
index 0000000000..3e6153759d
--- /dev/null
+++ b/src/qml/types/types.pri
@@ -0,0 +1,28 @@
+SOURCES += \
+ $$PWD/qqmlbind.cpp \
+ $$PWD/qqmlconnections.cpp \
+ $$PWD/qqmldelegatemodel.cpp \
+ $$PWD/qqmllistmodel.cpp \
+ $$PWD/qqmllistmodelworkeragent.cpp \
+ $$PWD/qqmlmodelsmodule.cpp \
+ $$PWD/qqmlobjectmodel.cpp \
+ $$PWD/qqmltimer.cpp \
+ $$PWD/qquickpackage.cpp \
+ $$PWD/qquickworkerscript.cpp \
+ $$PWD/qqmlinstantiator.cpp
+
+HEADERS += \
+ $$PWD/qqmlbind_p.h \
+ $$PWD/qqmlconnections_p.h \
+ $$PWD/qqmldelegatemodel_p.h \
+ $$PWD/qqmldelegatemodel_p_p.h \
+ $$PWD/qqmllistmodel_p.h \
+ $$PWD/qqmllistmodel_p_p.h \
+ $$PWD/qqmllistmodelworkeragent_p.h \
+ $$PWD/qqmlmodelsmodule_p.h \
+ $$PWD/qqmlobjectmodel_p.h \
+ $$PWD/qqmltimer_p.h \
+ $$PWD/qquickpackage_p.h \
+ $$PWD/qquickworkerscript_p.h \
+ $$PWD/qqmlinstantiator_p.h \
+ $$PWD/qqmlinstantiator_p_p.h
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
new file mode 100644
index 0000000000..5b6ef79338
--- /dev/null
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -0,0 +1,977 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmladaptormodel_p.h"
+
+#include <private/qqmldelegatemodel_p_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qqmlproperty_p.h>
+#include <private/qv8engine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlAdaptorModelEngineData : public QV8Engine::Deletable
+{
+public:
+ enum
+ {
+ Index,
+ ModelData,
+ HasModelChildren,
+ StringCount
+ };
+
+ QQmlAdaptorModelEngineData(QV8Engine *engine);
+ ~QQmlAdaptorModelEngineData();
+
+ v8::Local<v8::String> index() { return strings->Get(Index)->ToString(); }
+ v8::Local<v8::String> modelData() { return strings->Get(ModelData)->ToString(); }
+ v8::Local<v8::String> hasModelChildren() { return strings->Get(HasModelChildren)->ToString(); }
+
+ v8::Persistent<v8::Function> constructorListItem;
+ v8::Persistent<v8::Array> strings;
+};
+
+V8_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
+
+static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(data, "Not a valid VisualData object");
+
+ return v8::Int32::New(data->index);
+}
+
+template <typename T, typename M> static void setModelDataType(QMetaObjectBuilder *builder, M *metaType)
+{
+ builder->setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ builder->setClassName(T::staticMetaObject.className());
+ builder->setSuperClass(&T::staticMetaObject);
+ metaType->propertyOffset = T::staticMetaObject.propertyCount();
+ metaType->signalOffset = T::staticMetaObject.methodCount();
+}
+
+static void addProperty(QMetaObjectBuilder *builder, int propertyId, const QByteArray &propertyName, const QByteArray &propertyType)
+{
+ builder->addSignal("__" + QByteArray::number(propertyId) + "()");
+ QMetaPropertyBuilder property = builder->addProperty(
+ propertyName, propertyType, propertyId);
+ property.setWritable(true);
+}
+
+class VDMModelDelegateDataType;
+
+class QQmlDMCachedModelData : public QQmlDelegateModelItem
+{
+public:
+ QQmlDMCachedModelData(
+ QQmlDelegateModelItemMetaType *metaType,
+ VDMModelDelegateDataType *dataType,
+ int index);
+
+ int metaCall(QMetaObject::Call call, int id, void **arguments);
+
+ virtual QVariant value(int role) const = 0;
+ virtual void setValue(int role, const QVariant &value) = 0;
+
+ void setValue(const QString &role, const QVariant &value);
+ bool resolveIndex(const QQmlAdaptorModel &model, int idx);
+
+ static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static void set_property(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
+
+ VDMModelDelegateDataType *type;
+ QVector<QVariant> cachedData;
+};
+
+class VDMModelDelegateDataType
+ : public QQmlRefCount
+ , public QQmlAdaptorModel::Accessors
+ , public QAbstractDynamicMetaObject
+{
+public:
+ VDMModelDelegateDataType(QQmlAdaptorModel *model)
+ : model(model)
+ , metaObject(0)
+ , propertyCache(0)
+ , propertyOffset(0)
+ , signalOffset(0)
+ , hasModelData(false)
+ {
+ }
+
+ ~VDMModelDelegateDataType()
+ {
+ if (propertyCache)
+ propertyCache->release();
+ free(metaObject);
+
+ qPersistentDispose(constructor);
+ }
+
+ bool notify(
+ const QQmlAdaptorModel &,
+ const QList<QQmlDelegateModelItem *> &items,
+ int index,
+ int count,
+ const QVector<int> &roles) const
+ {
+ bool changed = roles.isEmpty() && !watchedRoles.isEmpty();
+ if (!changed && !watchedRoles.isEmpty() && watchedRoleIds.isEmpty()) {
+ QList<int> roleIds;
+ foreach (const QByteArray &r, watchedRoles) {
+ QHash<QByteArray, int>::const_iterator it = roleNames.find(r);
+ if (it != roleNames.end())
+ roleIds << it.value();
+ }
+ const_cast<VDMModelDelegateDataType *>(this)->watchedRoleIds = roleIds;
+ }
+
+ QVector<int> signalIndexes;
+ for (int i = 0; i < roles.count(); ++i) {
+ const int role = roles.at(i);
+ if (!changed && watchedRoleIds.contains(role))
+ changed = true;
+
+ int propertyId = propertyRoles.indexOf(role);
+ if (propertyId != -1)
+ signalIndexes.append(propertyId + signalOffset);
+ }
+ if (roles.isEmpty()) {
+ for (int propertyId = 0; propertyId < propertyRoles.count(); ++propertyId)
+ signalIndexes.append(propertyId + signalOffset);
+ }
+
+ for (int i = 0, c = items.count(); i < c; ++i) {
+ QQmlDelegateModelItem *item = items.at(i);
+ const int idx = item->modelIndex();
+ if (idx >= index && idx < index + count) {
+ for (int i = 0; i < signalIndexes.count(); ++i)
+ QMetaObject::activate(item, signalIndexes.at(i), 0);
+ }
+ }
+ return changed;
+ }
+
+ void replaceWatchedRoles(
+ QQmlAdaptorModel &,
+ const QList<QByteArray> &oldRoles,
+ const QList<QByteArray> &newRoles) const
+ {
+ VDMModelDelegateDataType *dataType = const_cast<VDMModelDelegateDataType *>(this);
+
+ dataType->watchedRoleIds.clear();
+ foreach (const QByteArray &oldRole, oldRoles)
+ dataType->watchedRoles.removeOne(oldRole);
+ dataType->watchedRoles += newRoles;
+ }
+
+ void initializeConstructor(QQmlAdaptorModelEngineData *const data)
+ {
+ constructor = qPersistentNew(v8::ObjectTemplate::New());
+ constructor->SetHasExternalResource(true);
+ constructor->SetAccessor(data->index(), get_index);
+
+ typedef QHash<QByteArray, int>::const_iterator iterator;
+ for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) {
+ const int propertyId = propertyRoles.indexOf(it.value());
+ const QByteArray &propertyName = it.key();
+
+ constructor->SetAccessor(
+ v8::String::New(propertyName.constData(), propertyName.length()),
+ QQmlDMCachedModelData::get_property,
+ QQmlDMCachedModelData::set_property,
+ v8::Int32::New(propertyId));
+ }
+ }
+
+ // QAbstractDynamicMetaObject
+
+ void objectDestroyed(QObject *)
+ {
+ release();
+ }
+
+ int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments)
+ {
+ return static_cast<QQmlDMCachedModelData *>(object)->metaCall(call, id, arguments);
+ }
+
+ v8::Persistent<v8::ObjectTemplate> constructor;
+ QList<int> propertyRoles;
+ QList<int> watchedRoleIds;
+ QList<QByteArray> watchedRoles;
+ QHash<QByteArray, int> roleNames;
+ QQmlAdaptorModel *model;
+ QMetaObject *metaObject;
+ QQmlPropertyCache *propertyCache;
+ int propertyOffset;
+ int signalOffset;
+ bool hasModelData;
+};
+
+QQmlDMCachedModelData::QQmlDMCachedModelData(
+ QQmlDelegateModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index)
+ : QQmlDelegateModelItem(metaType, index)
+ , type(dataType)
+{
+ if (index == -1)
+ cachedData.resize(type->hasModelData ? 1 : type->propertyRoles.count());
+
+ QObjectPrivate::get(this)->metaObject = type;
+
+ type->addref();
+
+ QQmlData *qmldata = QQmlData::get(this, true);
+ qmldata->propertyCache = dataType->propertyCache;
+ qmldata->propertyCache->addref();
+}
+
+int QQmlDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **arguments)
+{
+ if (call == QMetaObject::ReadProperty && id >= type->propertyOffset) {
+ const int propertyIndex = id - type->propertyOffset;
+ if (index == -1) {
+ if (!cachedData.isEmpty()) {
+ *static_cast<QVariant *>(arguments[0]) = cachedData.at(
+ type->hasModelData ? 0 : propertyIndex);
+ }
+ } else if (*type->model) {
+ *static_cast<QVariant *>(arguments[0]) = value(type->propertyRoles.at(propertyIndex));
+ }
+ return -1;
+ } else if (call == QMetaObject::WriteProperty && id >= type->propertyOffset) {
+ const int propertyIndex = id - type->propertyOffset;
+ if (index == -1) {
+ const QMetaObject *meta = metaObject();
+ if (cachedData.count() > 1) {
+ cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]);
+ QMetaObject::activate(this, meta, propertyIndex, 0);
+ } else if (cachedData.count() == 1) {
+ cachedData[0] = *static_cast<QVariant *>(arguments[0]);
+ QMetaObject::activate(this, meta, 0, 0);
+ QMetaObject::activate(this, meta, 1, 0);
+ }
+ } else if (*type->model) {
+ setValue(type->propertyRoles.at(propertyIndex), *static_cast<QVariant *>(arguments[0]));
+ }
+ return -1;
+ } else {
+ return qt_metacall(call, id, arguments);
+ }
+}
+
+void QQmlDMCachedModelData::setValue(const QString &role, const QVariant &value)
+{
+ QHash<QByteArray, int>::iterator it = type->roleNames.find(role.toUtf8());
+ if (it != type->roleNames.end()) {
+ for (int i = 0; i < type->propertyRoles.count(); ++i) {
+ if (type->propertyRoles.at(i) == *it) {
+ cachedData[i] = value;
+ return;
+ }
+ }
+ }
+}
+
+bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
+{
+ if (index == -1) {
+ Q_ASSERT(idx >= 0);
+ index = idx;
+ cachedData.clear();
+ emit modelIndexChanged();
+ const QMetaObject *meta = metaObject();
+ const int propertyCount = type->propertyRoles.count();
+ for (int i = 0; i < propertyCount; ++i)
+ QMetaObject::activate(this, meta, i, 0);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+v8::Handle<v8::Value> QQmlDMCachedModelData::get_property(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(data, "Not a valid VisualData object");
+
+ QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data);
+ const int propertyId = info.Data()->Int32Value();
+ if (data->index == -1) {
+ if (!modelData->cachedData.isEmpty()) {
+ return data->engine->fromVariant(
+ modelData->cachedData.at(modelData->type->hasModelData ? 0 : propertyId));
+ }
+ } else if (*modelData->type->model) {
+ return data->engine->fromVariant(
+ modelData->value(modelData->type->propertyRoles.at(propertyId)));
+ }
+ return v8::Undefined();
+}
+
+void QQmlDMCachedModelData::set_property(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object");
+
+ const int propertyId = info.Data()->Int32Value();
+ if (data->index == -1) {
+ QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(data);
+ if (!modelData->cachedData.isEmpty()) {
+ if (modelData->cachedData.count() > 1) {
+ modelData->cachedData[propertyId] = data->engine->toVariant(value, QVariant::Invalid);
+ QMetaObject::activate(data, data->metaObject(), propertyId, 0);
+ } else if (modelData->cachedData.count() == 1) {
+ modelData->cachedData[0] = data->engine->toVariant(value, QVariant::Invalid);
+ QMetaObject::activate(data, data->metaObject(), 0, 0);
+ QMetaObject::activate(data, data->metaObject(), 1, 0);
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------
+// QAbstractItemModel
+//-----------------------------------------------------------------
+
+class QQmlDMAbstractItemModelData : public QQmlDMCachedModelData
+{
+ Q_OBJECT
+ Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
+public:
+ QQmlDMAbstractItemModelData(
+ QQmlDelegateModelItemMetaType *metaType,
+ VDMModelDelegateDataType *dataType,
+ int index)
+ : QQmlDMCachedModelData(metaType, dataType, index)
+ {
+ }
+
+ bool hasModelChildren() const
+ {
+ if (index >= 0 && *type->model) {
+ const QAbstractItemModel * const model = type->model->aim();
+ return model->hasChildren(model->index(index, 0, type->model->rootIndex));
+ } else {
+ return false;
+ }
+ }
+
+ QVariant value(int role) const
+ {
+ return type->model->aim()->index(index, 0, type->model->rootIndex).data(role);
+ }
+
+ void setValue(int role, const QVariant &value)
+ {
+ type->model->aim()->setData(
+ type->model->aim()->index(index, 0, type->model->rootIndex), value, role);
+ }
+
+ v8::Handle<v8::Value> get()
+ {
+ if (type->constructor.IsEmpty()) {
+ QQmlAdaptorModelEngineData * const data = engineData(engine);
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(engine->context());
+ type->initializeConstructor(data);
+ type->constructor->SetAccessor(data->hasModelChildren(), get_hasModelChildren);
+ }
+ v8::Local<v8::Object> data = type->constructor->NewInstance();
+ data->SetExternalResource(this);
+ ++scriptRef;
+ return data;
+ }
+
+ static v8::Handle<v8::Value> get_hasModelChildren(v8::Local<v8::String>, const v8::AccessorInfo &info)
+ {
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(data, "Not a valid VisualData object");
+
+ const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(data)->type->model;
+ if (data->index >= 0 && *model) {
+ const QAbstractItemModel * const aim = model->aim();
+ return v8::Boolean::New(aim->hasChildren(aim->index(data->index, 0, model->rootIndex)));
+ } else {
+ return v8::Boolean::New(false);
+ }
+ }
+};
+
+class VDMAbstractItemModelDataType : public VDMModelDelegateDataType
+{
+public:
+ VDMAbstractItemModelDataType(QQmlAdaptorModel *model)
+ : VDMModelDelegateDataType(model)
+ {
+ }
+
+ int count(const QQmlAdaptorModel &model) const
+ {
+ return model.aim()->rowCount(model.rootIndex);
+ }
+
+ void cleanup(QQmlAdaptorModel &model, QQmlDelegateModel *vdm) const
+ {
+ QAbstractItemModel * const aim = model.aim();
+ if (aim && vdm) {
+ QObject::disconnect(aim, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ vdm, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ vdm, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ vdm, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ vdm, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+ vdm, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+ QObject::disconnect(aim, SIGNAL(modelReset()),
+ vdm, SLOT(_q_modelReset()));
+ QObject::disconnect(aim, SIGNAL(layoutChanged()),
+ vdm, SLOT(_q_layoutChanged()));
+ }
+
+ const_cast<VDMAbstractItemModelDataType *>(this)->release();
+ }
+
+ QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const
+ {
+ QHash<QByteArray, int>::const_iterator it = roleNames.find(role.toUtf8());
+ if (it != roleNames.end()) {
+ return model.aim()->index(index, 0, model.rootIndex).data(*it);
+ } else if (role == QLatin1String("hasModelChildren")) {
+ return QVariant(model.aim()->hasChildren(model.aim()->index(index, 0, model.rootIndex)));
+ } else {
+ return QVariant();
+ }
+ }
+
+ QVariant parentModelIndex(const QQmlAdaptorModel &model) const
+ {
+ return model
+ ? QVariant::fromValue(model.aim()->parent(model.rootIndex))
+ : QVariant();
+ }
+
+ QVariant modelIndex(const QQmlAdaptorModel &model, int index) const
+ {
+ return model
+ ? QVariant::fromValue(model.aim()->index(index, 0, model.rootIndex))
+ : QVariant();
+ }
+
+ bool canFetchMore(const QQmlAdaptorModel &model) const
+ {
+ return model && model.aim()->canFetchMore(model.rootIndex);
+ }
+
+ void fetchMore(QQmlAdaptorModel &model) const
+ {
+ if (model)
+ model.aim()->fetchMore(model.rootIndex);
+ }
+
+ QQmlDelegateModelItem *createItem(
+ QQmlAdaptorModel &model,
+ QQmlDelegateModelItemMetaType *metaType,
+ QQmlEngine *engine,
+ int index) const
+ {
+ VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
+ if (!metaObject)
+ dataType->initializeMetaType(model, engine);
+ return new QQmlDMAbstractItemModelData(metaType, dataType, index);
+ }
+
+ void initializeMetaType(QQmlAdaptorModel &model, QQmlEngine *engine)
+ {
+ QMetaObjectBuilder builder;
+ setModelDataType<QQmlDMAbstractItemModelData>(&builder, this);
+
+ const QByteArray propertyType = QByteArrayLiteral("QVariant");
+ const QHash<int, QByteArray> names = model.aim()->roleNames();
+ for (QHash<int, QByteArray>::const_iterator it = names.begin(); it != names.end(); ++it) {
+ const int propertyId = propertyRoles.count();
+ propertyRoles.append(it.key());
+ roleNames.insert(it.value(), it.key());
+ addProperty(&builder, propertyId, it.value(), propertyType);
+ }
+ if (propertyRoles.count() == 1) {
+ hasModelData = true;
+ const int role = names.begin().key();
+ const QByteArray propertyName = QByteArrayLiteral("modelData");
+
+ propertyRoles.append(role);
+ roleNames.insert(propertyName, role);
+ addProperty(&builder, 1, propertyName, propertyType);
+ }
+
+ metaObject = builder.toMetaObject();
+ *static_cast<QMetaObject *>(this) = *metaObject;
+ propertyCache = new QQmlPropertyCache(engine, metaObject);
+ }
+};
+
+//-----------------------------------------------------------------
+// QQmlListAccessor
+//-----------------------------------------------------------------
+
+class QQmlDMListAccessorData : public QQmlDelegateModelItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
+public:
+ QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType, int index, const QVariant &value)
+ : QQmlDelegateModelItem(metaType, index)
+ , cachedData(value)
+ {
+ }
+
+ QVariant modelData() const
+ {
+ return cachedData;
+ }
+
+ void setModelData(const QVariant &data)
+ {
+ if (index == -1 && data != cachedData) {
+ cachedData = data;
+ emit modelDataChanged();
+ }
+ }
+
+ static v8::Handle<v8::Value> get_modelData(v8::Local<v8::String>, const v8::AccessorInfo &info)
+ {
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE(data, "Not a valid VisualData object");
+
+ return data->engine->fromVariant(static_cast<QQmlDMListAccessorData *>(data)->cachedData);
+ }
+
+ static void set_modelData(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+ {
+ QQmlDelegateModelItem *data = v8_resource_cast<QQmlDelegateModelItem>(info.This());
+ V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object");
+
+ static_cast<QQmlDMListAccessorData *>(data)->setModelData(
+ data->engine->toVariant(value, QVariant::Invalid));
+ }
+
+ v8::Handle<v8::Value> get()
+ {
+ v8::Local<v8::Object> data = engineData(engine)->constructorListItem->NewInstance();
+ data->SetExternalResource(this);
+ ++scriptRef;
+ return data;
+ }
+
+ void setValue(const QString &role, const QVariant &value)
+ {
+ if (role == QLatin1String("modelData"))
+ cachedData = value;
+ }
+
+ bool resolveIndex(const QQmlAdaptorModel &model, int idx)
+ {
+ if (index == -1) {
+ index = idx;
+ cachedData = model.list.at(idx);
+ emit modelIndexChanged();
+ emit modelDataChanged();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+Q_SIGNALS:
+ void modelDataChanged();
+
+private:
+ QVariant cachedData;
+};
+
+
+class VDMListDelegateDataType : public QQmlAdaptorModel::Accessors
+{
+public:
+ inline VDMListDelegateDataType() {}
+
+ int count(const QQmlAdaptorModel &model) const
+ {
+ return model.list.count();
+ }
+
+ QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const
+ {
+ return role == QLatin1String("modelData")
+ ? model.list.at(index)
+ : QVariant();
+ }
+
+ QQmlDelegateModelItem *createItem(
+ QQmlAdaptorModel &model,
+ QQmlDelegateModelItemMetaType *metaType,
+ QQmlEngine *,
+ int index) const
+ {
+ return new QQmlDMListAccessorData(
+ metaType,
+ index,
+ index >= 0 && index < model.list.count() ? model.list.at(index) : QVariant());
+ }
+};
+
+//-----------------------------------------------------------------
+// QObject
+//-----------------------------------------------------------------
+
+class VDMObjectDelegateDataType;
+class QQmlDMObjectData : public QQmlDelegateModelItem, public QQmlAdaptorModelProxyInterface
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject *modelData READ modelData CONSTANT)
+ Q_INTERFACES(QQmlAdaptorModelProxyInterface)
+public:
+ QQmlDMObjectData(
+ QQmlDelegateModelItemMetaType *metaType,
+ VDMObjectDelegateDataType *dataType,
+ int index,
+ QObject *object);
+
+ QObject *modelData() const { return object; }
+ QObject *proxiedObject() { return object; }
+
+ QQmlGuard<QObject> object;
+};
+
+class VDMObjectDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Accessors
+{
+public:
+ QMetaObject *metaObject;
+ int propertyOffset;
+ int signalOffset;
+ bool shared;
+ QMetaObjectBuilder builder;
+
+ VDMObjectDelegateDataType()
+ : metaObject(0)
+ , propertyOffset(0)
+ , signalOffset(0)
+ , shared(true)
+ {
+ }
+
+ VDMObjectDelegateDataType(const VDMObjectDelegateDataType &type)
+ : QQmlRefCount()
+ , QQmlAdaptorModel::Accessors()
+ , metaObject(0)
+ , propertyOffset(type.propertyOffset)
+ , signalOffset(type.signalOffset)
+ , shared(false)
+ , builder(type.metaObject, QMetaObjectBuilder::Properties
+ | QMetaObjectBuilder::Signals
+ | QMetaObjectBuilder::SuperClass
+ | QMetaObjectBuilder::ClassName)
+ {
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ }
+
+ ~VDMObjectDelegateDataType()
+ {
+ free(metaObject);
+ }
+
+ int count(const QQmlAdaptorModel &model) const
+ {
+ return model.list.count();
+ }
+
+ QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const
+ {
+ if (QObject *object = model.list.at(index).value<QObject *>())
+ return object->property(role.toUtf8());
+ return QVariant();
+ }
+
+ QQmlDelegateModelItem *createItem(
+ QQmlAdaptorModel &model,
+ QQmlDelegateModelItemMetaType *metaType,
+ QQmlEngine *,
+ int index) const
+ {
+ VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this);
+ if (!metaObject)
+ dataType->initializeMetaType(model);
+ return index >= 0 && index < model.list.count()
+ ? new QQmlDMObjectData(metaType, dataType, index, qvariant_cast<QObject *>(model.list.at(index)))
+ : 0;
+ }
+
+ void initializeMetaType(QQmlAdaptorModel &)
+ {
+ setModelDataType<QQmlDMObjectData>(&builder, this);
+
+ metaObject = builder.toMetaObject();
+ }
+
+ void cleanup(QQmlAdaptorModel &, QQmlDelegateModel *) const
+ {
+ const_cast<VDMObjectDelegateDataType *>(this)->release();
+ }
+};
+
+class QQmlDMObjectDataMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+ QQmlDMObjectDataMetaObject(QQmlDMObjectData *data, VDMObjectDelegateDataType *type)
+ : m_data(data)
+ , m_type(type)
+ {
+ QObjectPrivate *op = QObjectPrivate::get(m_data);
+ *static_cast<QMetaObject *>(this) = *type->metaObject;
+ op->metaObject = this;
+ m_type->addref();
+ }
+
+ ~QQmlDMObjectDataMetaObject()
+ {
+ m_type->release();
+ }
+
+ int metaCall(QMetaObject::Call call, int id, void **arguments)
+ {
+ static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount();
+ if (id >= m_type->propertyOffset
+ && (call == QMetaObject::ReadProperty
+ || call == QMetaObject::WriteProperty
+ || call == QMetaObject::ResetProperty)) {
+ if (m_data->object)
+ QMetaObject::metacall(m_data->object, call, id - m_type->propertyOffset + objectPropertyOffset, arguments);
+ return -1;
+ } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
+ QMetaObject::activate(m_data, this, id - m_type->signalOffset, 0);
+ return -1;
+ } else {
+ return m_data->qt_metacall(call, id, arguments);
+ }
+ }
+
+ int createProperty(const char *name, const char *)
+ {
+ if (!m_data->object)
+ return -1;
+ const QMetaObject *metaObject = m_data->object->metaObject();
+ static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount();
+
+ const int previousPropertyCount = propertyCount() - propertyOffset();
+ int propertyIndex = metaObject->indexOfProperty(name);
+ if (propertyIndex == -1)
+ return -1;
+ if (previousPropertyCount + objectPropertyOffset == metaObject->propertyCount())
+ return propertyIndex + m_type->propertyOffset - objectPropertyOffset;
+
+ if (m_type->shared) {
+ VDMObjectDelegateDataType *type = m_type;
+ m_type = new VDMObjectDelegateDataType(*m_type);
+ type->release();
+ }
+
+ const int previousMethodCount = methodCount();
+ int notifierId = previousMethodCount - methodOffset();
+ for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - objectPropertyOffset; ++propertyId) {
+ QMetaProperty property = metaObject->property(propertyId + objectPropertyOffset);
+ QMetaPropertyBuilder propertyBuilder;
+ if (property.hasNotifySignal()) {
+ m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
+ propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
+ ++notifierId;
+ } else {
+ propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
+ }
+ propertyBuilder.setWritable(property.isWritable());
+ propertyBuilder.setResettable(property.isResettable());
+ propertyBuilder.setConstant(property.isConstant());
+ }
+
+ if (m_type->metaObject)
+ free(m_type->metaObject);
+ m_type->metaObject = m_type->builder.toMetaObject();
+ *static_cast<QMetaObject *>(this) = *m_type->metaObject;
+
+ notifierId = previousMethodCount;
+ for (int i = previousPropertyCount; i < metaObject->propertyCount() - objectPropertyOffset; ++i) {
+ QMetaProperty property = metaObject->property(i + objectPropertyOffset);
+ if (property.hasNotifySignal()) {
+ QQmlPropertyPrivate::connect(
+ m_data->object, property.notifySignalIndex(), m_data, notifierId);
+ ++notifierId;
+ }
+ }
+ return propertyIndex + m_type->propertyOffset - objectPropertyOffset;
+ }
+
+ QQmlDMObjectData *m_data;
+ VDMObjectDelegateDataType *m_type;
+};
+
+QQmlDMObjectData::QQmlDMObjectData(
+ QQmlDelegateModelItemMetaType *metaType,
+ VDMObjectDelegateDataType *dataType,
+ int index,
+ QObject *object)
+ : QQmlDelegateModelItem(metaType, index)
+ , object(object)
+{
+ new QQmlDMObjectDataMetaObject(this, dataType);
+}
+
+//-----------------------------------------------------------------
+// QQmlAdaptorModel
+//-----------------------------------------------------------------
+
+static const QQmlAdaptorModel::Accessors qt_vdm_null_accessors;
+static const VDMListDelegateDataType qt_vdm_list_accessors;
+
+QQmlAdaptorModel::Accessors::~Accessors()
+{
+}
+
+QQmlAdaptorModel::QQmlAdaptorModel()
+ : accessors(&qt_vdm_null_accessors)
+{
+}
+
+QQmlAdaptorModel::~QQmlAdaptorModel()
+{
+ accessors->cleanup(*this);
+}
+
+void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm, QQmlEngine *engine)
+{
+ accessors->cleanup(*this, vdm);
+
+ list.setList(variant, engine);
+
+ if (QObject *object = qvariant_cast<QObject *>(variant)) {
+ setObject(object);
+ if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(object)) {
+ accessors = new VDMAbstractItemModelDataType(this);
+
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ vdm, QQmlDelegateModel, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ vdm, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ vdm, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
+ vdm, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+ vdm, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(modelReset()),
+ vdm, QQmlDelegateModel, SLOT(_q_modelReset()));
+ qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutChanged()),
+ vdm, QQmlDelegateModel, SLOT(_q_layoutChanged()));
+ } else {
+ accessors = new VDMObjectDelegateDataType;
+ }
+ } else if (list.type() == QQmlListAccessor::ListProperty) {
+ setObject(static_cast<const QQmlListReference *>(variant.constData())->object());
+ accessors = new VDMObjectDelegateDataType;
+ } else if (list.type() != QQmlListAccessor::Invalid) {
+ Q_ASSERT(list.type() != QQmlListAccessor::Instance); // Should have cast to QObject.
+ setObject(0);
+ accessors = &qt_vdm_list_accessors;
+ } else {
+ setObject(0);
+ accessors = &qt_vdm_null_accessors;
+ }
+}
+
+void QQmlAdaptorModel::invalidateModel(QQmlDelegateModel *vdm)
+{
+ accessors->cleanup(*this, vdm);
+ accessors = &qt_vdm_null_accessors;
+ // Don't clear the model object as we still need the guard to clear the list variant if the
+ // object is destroyed.
+}
+
+bool QQmlAdaptorModel::isValid() const
+{
+ return accessors != &qt_vdm_null_accessors;
+}
+
+void QQmlAdaptorModel::objectDestroyed(QObject *)
+{
+ setModel(QVariant(), 0, 0);
+}
+
+QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV8Engine *)
+{
+ strings = qPersistentNew(v8::Array::New(StringCount));
+ strings->Set(Index, v8::String::New("index"));
+ strings->Set(ModelData, v8::String::New("modelData"));
+ strings->Set(HasModelChildren, v8::String::New("hasModelChildren"));
+
+ v8::Local<v8::FunctionTemplate> listItem = v8::FunctionTemplate::New();
+ listItem->InstanceTemplate()->SetHasExternalResource(true);
+ listItem->InstanceTemplate()->SetAccessor(index(), get_index);
+ listItem->InstanceTemplate()->SetAccessor(
+ modelData(),
+ QQmlDMListAccessorData::get_modelData,
+ QQmlDMListAccessorData::set_modelData);
+ constructorListItem = qPersistentNew(listItem->GetFunction());
+}
+
+QQmlAdaptorModelEngineData::~QQmlAdaptorModelEngineData()
+{
+ qPersistentDispose(constructorListItem);
+ qPersistentDispose(strings);
+}
+
+QT_END_NAMESPACE
+
+#include <qqmladaptormodel.moc>
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
new file mode 100644
index 0000000000..399350d725
--- /dev/null
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLADAPTORMODEL_P_H
+#define QQMLADAPTORMODEL_P_H
+
+#include <QtCore/qabstractitemmodel.h>
+
+#include "private/qqmllistaccessor_p.h"
+
+#include <private/qqmlguard_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+
+class QQmlDelegateModel;
+class QQmlDelegateModelItem;
+class QQmlDelegateModelItemMetaType;
+
+class QQmlAdaptorModel : public QQmlGuard<QObject>
+{
+public:
+ class Accessors
+ {
+ public:
+ inline Accessors() {}
+ virtual ~Accessors();
+ virtual int count(const QQmlAdaptorModel &) const { return 0; }
+ virtual void cleanup(QQmlAdaptorModel &, QQmlDelegateModel * = 0) const {}
+
+ virtual QVariant value(const QQmlAdaptorModel &, int, const QString &) const {
+ return QVariant(); }
+
+ virtual QQmlDelegateModelItem *createItem(
+ QQmlAdaptorModel &,
+ QQmlDelegateModelItemMetaType *,
+ QQmlEngine *,
+ int) const { return 0; }
+
+ virtual bool notify(
+ const QQmlAdaptorModel &,
+ const QList<QQmlDelegateModelItem *> &,
+ int,
+ int,
+ const QVector<int> &) const { return false; }
+ virtual void replaceWatchedRoles(
+ QQmlAdaptorModel &,
+ const QList<QByteArray> &,
+ const QList<QByteArray> &) const {}
+ virtual QVariant parentModelIndex(const QQmlAdaptorModel &) const {
+ return QVariant(); }
+ virtual QVariant modelIndex(const QQmlAdaptorModel &, int) const {
+ return QVariant(); }
+ virtual bool canFetchMore(const QQmlAdaptorModel &) const { return false; }
+ virtual void fetchMore(QQmlAdaptorModel &) const {}
+ };
+
+ const Accessors *accessors;
+ QPersistentModelIndex rootIndex;
+ QQmlListAccessor list;
+
+ QQmlAdaptorModel();
+ ~QQmlAdaptorModel();
+
+ inline QVariant model() const { return list.list(); }
+ void setModel(const QVariant &variant, QQmlDelegateModel *vdm, QQmlEngine *engine);
+ void invalidateModel(QQmlDelegateModel *vdm);
+
+ bool isValid() const;
+
+ inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
+ inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); }
+
+ inline int count() const { return qMax(0, accessors->count(*this)); }
+ inline QVariant value(int index, const QString &role) const {
+ return accessors->value(*this, index, role); }
+ inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, QQmlEngine *engine, int index) {
+ return accessors->createItem(*this, metaType, engine, index); }
+ inline bool hasProxyObject() const {
+ return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; }
+
+ inline bool notify(
+ const QList<QQmlDelegateModelItem *> &items,
+ int index,
+ int count,
+ const QVector<int> &roles) const {
+ return accessors->notify(*this, items, index, count, roles); }
+ inline void replaceWatchedRoles(
+ const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles) {
+ accessors->replaceWatchedRoles(*this, oldRoles, newRoles); }
+
+ inline QVariant modelIndex(int index) const { return accessors->modelIndex(*this, index); }
+ inline QVariant parentModelIndex() const { return accessors->parentModelIndex(*this); }
+ inline bool canFetchMore() const { return accessors->canFetchMore(*this); }
+ inline void fetchMore() { return accessors->fetchMore(*this); }
+
+protected:
+ void objectDestroyed(QObject *);
+};
+
+class QQmlAdaptorModelProxyInterface
+{
+public:
+ virtual ~QQmlAdaptorModelProxyInterface() {}
+
+ virtual QObject *proxiedObject() = 0;
+};
+
+#define QQmlAdaptorModelProxyInterface_iid "org.qt-project.Qt.QQmlAdaptorModelProxyInterface"
+
+Q_DECLARE_INTERFACE(QQmlAdaptorModelProxyInterface, QQmlAdaptorModelProxyInterface_iid)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/util/qqmlchangeset.cpp b/src/qml/util/qqmlchangeset.cpp
new file mode 100644
index 0000000000..831cb063a5
--- /dev/null
+++ b/src/qml/util/qqmlchangeset.cpp
@@ -0,0 +1,621 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlchangeset_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \class QQmlChangeSet
+ \brief The QQmlChangeSet class stores an ordered list of notifications about
+ changes to a linear data set.
+ \internal
+
+ QQmlChangeSet can be used to record a series of notifications about items in an indexed list
+ being inserted, removed, moved, and changed. Notifications in the set are re-ordered so that
+ all notifications of a single type are grouped together and sorted in order of ascending index,
+ with remove notifications preceding all others, followed by insert notification, and then
+ change notifications.
+
+ Moves in a change set are represented by a remove notification paired with an insert
+ notification by way of a shared unique moveId. Re-ordering may result in one or both of the
+ paired notifications being divided, when this happens the offset member of the notification
+ will indicate the relative offset of the divided notification from the beginning of the
+ original.
+*/
+
+/*!
+ Constructs an empty change set.
+*/
+
+QQmlChangeSet::QQmlChangeSet()
+ : m_difference(0)
+{
+}
+
+/*!
+ Constructs a copy of a \a changeSet.
+*/
+
+QQmlChangeSet::QQmlChangeSet(const QQmlChangeSet &changeSet)
+ : m_removes(changeSet.m_removes)
+ , m_inserts(changeSet.m_inserts)
+ , m_changes(changeSet.m_changes)
+ , m_difference(changeSet.m_difference)
+{
+}
+
+/*!
+ Destroys a change set.
+*/
+
+QQmlChangeSet::~QQmlChangeSet()
+{
+}
+
+/*!
+ Assigns the value of a \a changeSet to another.
+*/
+
+QQmlChangeSet &QQmlChangeSet::operator =(const QQmlChangeSet &changeSet)
+{
+ m_removes = changeSet.m_removes;
+ m_inserts = changeSet.m_inserts;
+ m_changes = changeSet.m_changes;
+ m_difference = changeSet.m_difference;
+ return *this;
+}
+
+/*!
+ Appends a notification that \a count items were inserted at \a index.
+*/
+
+void QQmlChangeSet::insert(int index, int count)
+{
+ insert(QVector<Insert>() << Insert(index, count));
+}
+
+/*!
+ Appends a notification that \a count items were removed at \a index.
+*/
+
+void QQmlChangeSet::remove(int index, int count)
+{
+ QVector<Remove> removes;
+ removes.append(Remove(index, count));
+ remove(&removes, 0);
+}
+
+/*!
+ Appends a notification that \a count items were moved \a from one index \a to another.
+
+ The \a moveId must be unique across the lifetime of the change set and any related
+ change sets.
+*/
+
+void QQmlChangeSet::move(int from, int to, int count, int moveId)
+{
+ QVector<Remove> removes;
+ removes.append(Remove(from, count, moveId));
+ QVector<Insert> inserts;
+ inserts.append(Insert(to, count, moveId));
+ remove(&removes, &inserts);
+ insert(inserts);
+}
+
+/*!
+ Appends a notification that \a count items were changed at \a index.
+*/
+
+void QQmlChangeSet::change(int index, int count)
+{
+ QVector<Change> changes;
+ changes.append(Change(index, count));
+ change(changes);
+}
+
+/*!
+ Applies the changes in a \a changeSet to another.
+*/
+
+void QQmlChangeSet::apply(const QQmlChangeSet &changeSet)
+{
+ QVector<Remove> r = changeSet.m_removes;
+ QVector<Insert> i = changeSet.m_inserts;
+ QVector<Change> c = changeSet.m_changes;
+ remove(&r, &i);
+ insert(i);
+ change(c);
+}
+
+/*!
+ Applies a list of \a removes to a change set.
+
+ If a remove contains a moveId then any intersecting insert in the set will replace the
+ corresponding intersection in the optional \a inserts list.
+*/
+
+void QQmlChangeSet::remove(const QVector<Remove> &removes, QVector<Insert> *inserts)
+{
+ QVector<Remove> r = removes;
+ remove(&r, inserts);
+}
+
+void QQmlChangeSet::remove(QVector<Remove> *removes, QVector<Insert> *inserts)
+{
+ int removeCount = 0;
+ int insertCount = 0;
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ QVector<Change>::iterator change = m_changes.begin();
+ QVector<Remove>::iterator rit = removes->begin();
+ for (; rit != removes->end(); ++rit) {
+ int index = rit->index + removeCount;
+ int count = rit->count;
+
+ // Decrement the accumulated remove count from the indexes of any changes prior to the
+ // current remove.
+ for (; change != m_changes.end() && change->end() < rit->index; ++change)
+ change->index -= removeCount;
+ // Remove any portion of a change notification that intersects the current remove.
+ for (; change != m_changes.end() && change->index > rit->end(); ++change) {
+ change->count -= qMin(change->end(), rit->end()) - qMax(change->index, rit->index);
+ if (change->count == 0) {
+ change = m_changes.erase(change);
+ } else if (rit->index < change->index) {
+ change->index = rit->index;
+ }
+ }
+
+ // Decrement the accumulated remove count from the indexes of any inserts prior to the
+ // current remove.
+ for (; insert != m_inserts.end() && insert->end() <= index; ++insert) {
+ insertCount += insert->count;
+ insert->index -= removeCount;
+ }
+
+ rit->index -= insertCount;
+
+ // Remove any portion of a insert notification that intersects the current remove.
+ while (insert != m_inserts.end() && insert->index < index + count) {
+ int offset = index - insert->index;
+ const int difference = qMin(insert->end(), index + count) - qMax(insert->index, index);
+
+ // If part of the remove or insert that precedes the intersection has a moveId create
+ // a new delta for that portion and subtract the size of that delta from the current
+ // one.
+ if (offset < 0 && rit->moveId != -1) {
+ rit = removes->insert(rit, Remove(
+ rit->index, -offset, rit->moveId, rit->offset));
+ ++rit;
+ rit->count -= -offset;
+ rit->offset += -offset;
+ index += -offset;
+ count -= -offset;
+ removeCount += -offset;
+ offset = 0;
+ } else if (offset > 0 && insert->moveId != -1) {
+ insert = m_inserts.insert(insert, Insert(
+ insert->index - removeCount, offset, insert->moveId, insert->offset));
+ ++insert;
+ insert->index += offset;
+ insert->count -= offset;
+ insert->offset += offset;
+ rit->index -= offset;
+ insertCount += offset;
+ }
+
+ // If the current remove has a move id, find any inserts with the same move id and
+ // replace the corresponding sections with the insert removed from the change set.
+ if (rit->moveId != -1 && difference > 0 && inserts) {
+ for (QVector<Insert>::iterator iit = inserts->begin(); iit != inserts->end(); ++iit) {
+ if (iit->moveId != rit->moveId
+ || rit->offset > iit->offset + iit->count
+ || iit->offset > rit->offset + difference) {
+ continue;
+ }
+ // If the intersecting insert starts before the replacement one create
+ // a new insert for the portion prior to the replacement insert.
+ const int overlapOffset = rit->offset - iit->offset;
+ if (overlapOffset > 0) {
+ iit = inserts->insert(iit, Insert(
+ iit->index, overlapOffset, iit->moveId, iit->offset));
+ ++iit;
+ iit->index += overlapOffset;
+ iit->count -= overlapOffset;
+ iit->offset += overlapOffset;
+ }
+ if (iit->offset >= rit->offset
+ && iit->offset + iit->count <= rit->offset + difference) {
+ // If the replacement insert completely encapsulates the existing
+ // one just change the moveId.
+ iit->moveId = insert->moveId;
+ iit->offset = insert->offset + qMax(0, -overlapOffset);
+ } else {
+ // Create a new insertion before the intersecting one with the number of intersecting
+ // items and remove that number from that insert.
+ const int count
+ = qMin(iit->offset + iit->count, rit->offset + difference)
+ - qMax(iit->offset, rit->offset);
+ iit = inserts->insert(iit, Insert(
+ iit->index,
+ count,
+ insert->moveId,
+ insert->offset + qMax(0, -overlapOffset)));
+ ++iit;
+ iit->index += count;
+ iit->count -= count;
+ iit->offset += count;
+ }
+ }
+ }
+
+ // Subtract the number of intersecting items from the current remove and insert.
+ insert->count -= difference;
+ insert->offset += difference;
+ rit->count -= difference;
+ rit->offset += difference;
+
+ index += difference;
+ count -= difference;
+ removeCount += difference;
+
+ if (insert->count == 0) {
+ insert = m_inserts.erase(insert);
+ } else if (rit->count == -offset || rit->count == 0) {
+ insert->index += difference;
+ break;
+ } else {
+ insert->index -= removeCount - difference;
+ rit->index -= insert->count;
+ insertCount += insert->count;
+ ++insert;
+ }
+ }
+ removeCount += rit->count;
+ }
+ for (; insert != m_inserts.end(); ++insert)
+ insert->index -= removeCount;
+
+ removeCount = 0;
+ QVector<Remove>::iterator remove = m_removes.begin();
+ for (rit = removes->begin(); rit != removes->end(); ++rit) {
+ if (rit->count == 0)
+ continue;
+ // Accumulate consecutive removes into a single delta before attempting to apply.
+ for (QVector<Remove>::iterator next = rit + 1; next != removes->end()
+ && next->index == rit->index
+ && next->moveId == -1
+ && rit->moveId == -1; ++next) {
+ next->count += rit->count;
+ rit = next;
+ }
+ int index = rit->index + removeCount;
+ // Decrement the accumulated remove count from the indexes of any inserts prior to the
+ // current remove.
+ for (; remove != m_removes.end() && index > remove->index; ++remove)
+ remove->index -= removeCount;
+ while (remove != m_removes.end() && index + rit->count >= remove->index) {
+ int count = 0;
+ const int offset = remove->index - index;
+ QVector<Remove>::iterator rend = remove;
+ for (; rend != m_removes.end()
+ && rit->moveId == -1
+ && rend->moveId == -1
+ && index + rit->count >= rend->index; ++rend) {
+ count += rend->count;
+ }
+ if (remove != rend) {
+ // Accumulate all existing non-move removes that are encapsulated by or immediately
+ // follow the current remove into it.
+ int difference = 0;
+ if (rend == m_removes.end()) {
+ difference = rit->count;
+ } else if (rit->index + rit->count < rend->index - removeCount) {
+ difference = rit->count;
+ } else if (rend->moveId != -1) {
+ difference = rend->index - removeCount - rit->index;
+ index += difference;
+ }
+ count += difference;
+
+ rit->count -= difference;
+ removeCount += difference;
+ remove->index = rit->index;
+ remove->count = count;
+ remove = m_removes.erase(++remove, rend);
+ } else {
+ // Insert a remove for the portion of the unmergable current remove prior to the
+ // point of intersection.
+ if (offset > 0) {
+ remove = m_removes.insert(remove, Remove(
+ rit->index, offset, rit->moveId, rit->offset));
+ ++remove;
+ rit->count -= offset;
+ rit->offset += offset;
+ removeCount += offset;
+ index += offset;
+ }
+ remove->index = rit->index;
+
+ ++remove;
+ }
+ }
+
+ if (rit->count > 0) {
+ remove = m_removes.insert(remove, *rit);
+ ++remove;
+ }
+ removeCount += rit->count;
+ }
+ for (; remove != m_removes.end(); ++remove)
+ remove->index -= removeCount;
+ m_difference -= removeCount;
+}
+
+/*!
+ Applies a list of \a inserts to a change set.
+*/
+
+void QQmlChangeSet::insert(const QVector<Insert> &inserts)
+{
+ int insertCount = 0;
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ QVector<Change>::iterator change = m_changes.begin();
+ for (QVector<Insert>::const_iterator iit = inserts.begin(); iit != inserts.end(); ++iit) {
+ if (iit->count == 0)
+ continue;
+ int index = iit->index - insertCount;
+
+ Insert current = *iit;
+ // Accumulate consecutive inserts into a single delta before attempting to insert.
+ for (QVector<Insert>::const_iterator next = iit + 1; next != inserts.end()
+ && next->index == iit->index + iit->count
+ && next->moveId == -1
+ && iit->moveId == -1; ++next) {
+ current.count += next->count;
+ iit = next;
+ }
+
+ // Increment the index of any changes before the current insert by the accumlated insert
+ // count.
+ for (; change != m_changes.end() && change->index >= index; ++change)
+ change->index += insertCount;
+ // If the current insert index is in the middle of a change split it in two at that
+ // point and increment the index of the latter half.
+ if (change != m_changes.end() && change->index < index + iit->count) {
+ int offset = index - change->index;
+ change = m_changes.insert(change, Change(change->index + insertCount, offset));
+ ++change;
+ change->index += iit->count + offset;
+ change->count -= offset;
+ }
+
+ // Increment the index of any inserts before the current insert by the accumlated insert
+ // count.
+ for (; insert != m_inserts.end() && index > insert->index + insert->count; ++insert)
+ insert->index += insertCount;
+ if (insert == m_inserts.end()) {
+ insert = m_inserts.insert(insert, current);
+ ++insert;
+ } else {
+ const int offset = index - insert->index;
+
+ if (offset < 0) {
+ // If the current insert is before an existing insert and not adjacent just insert
+ // it into the list.
+ insert = m_inserts.insert(insert, current);
+ ++insert;
+ } else if (iit->moveId == -1 && insert->moveId == -1) {
+ // If neither the current nor existing insert has a moveId add the current insert
+ // to the existing one.
+ if (offset < insert->count) {
+ insert->index -= current.count;
+ insert->count += current.count;
+ } else {
+ insert->index += insertCount;
+ insert->count += current.count;
+ ++insert;
+ }
+ } else if (offset < insert->count) {
+ // If either insert has a moveId then split the existing insert and insert the
+ // current one in the middle.
+ if (offset > 0) {
+ insert = m_inserts.insert(insert, Insert(
+ insert->index + insertCount, offset, insert->moveId, insert->offset));
+ ++insert;
+ insert->index += offset;
+ insert->count -= offset;
+ insert->offset += offset;
+ }
+ insert = m_inserts.insert(insert, current);
+ ++insert;
+ } else {
+ insert->index += insertCount;
+ ++insert;
+ insert = m_inserts.insert(insert, current);
+ ++insert;
+ }
+ }
+ insertCount += current.count;
+ }
+ for (; insert != m_inserts.end(); ++insert)
+ insert->index += insertCount;
+ m_difference += insertCount;
+}
+
+/*!
+ Applies a combined list of \a removes and \a inserts to a change set. This is equivalent
+ calling \l remove() followed by \l insert() with the same lists.
+*/
+
+void QQmlChangeSet::move(const QVector<Remove> &removes, const QVector<Insert> &inserts)
+{
+ QVector<Remove> r = removes;
+ QVector<Insert> i = inserts;
+ remove(&r, &i);
+ insert(i);
+}
+
+/*!
+ Applies a list of \a changes to a change set.
+*/
+
+void QQmlChangeSet::change(const QVector<Change> &changes)
+{
+ QVector<Change> c = changes;
+ change(&c);
+}
+
+void QQmlChangeSet::change(QVector<Change> *changes)
+{
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ QVector<Change>::iterator change = m_changes.begin();
+ for (QVector<Change>::iterator cit = changes->begin(); cit != changes->end(); ++cit) {
+ for (; insert != m_inserts.end() && insert->end() < cit->index; ++insert) {}
+ for (; insert != m_inserts.end() && insert->index < cit->end(); ++insert) {
+ const int offset = insert->index - cit->index;
+ const int count = cit->count + cit->index - insert->index - insert->count;
+ if (offset == 0) {
+ cit->index = insert->index + insert->count;
+ cit->count = count;
+ } else {
+ cit = changes->insert(++cit, Change(insert->index + insert->count, count));
+ --cit;
+ cit->count = offset;
+ }
+ }
+
+ for (; change != m_changes.end() && change->index + change->count < cit->index; ++change) {}
+ if (change == m_changes.end() || change->index > cit->index + cit->count) {
+ if (cit->count > 0) {
+ change = m_changes.insert(change, *cit);
+ ++change;
+ }
+ } else {
+ if (cit->index < change->index) {
+ change->count += change->index - cit->index;
+ change->index = cit->index;
+ }
+
+ if (cit->index + cit->count > change->index + change->count) {
+ change->count = cit->index + cit->count - change->index;
+ QVector<Change>::iterator cbegin = change;
+ QVector<Change>::iterator cend = ++cbegin;
+ for (; cend != m_changes.end() && cend->index <= change->index + change->count; ++cend) {
+ if (cend->index + cend->count > change->index + change->count)
+ change->count = cend->index + cend->count - change->index;
+ }
+ if (cbegin != cend) {
+ change = m_changes.erase(cbegin, cend);
+ --change;
+ }
+ }
+ }
+ }
+}
+
+/*!
+ Prints the contents of a change \a set to the \a debug stream.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlChangeSet &set)
+{
+ debug.nospace() << "QQmlChangeSet(";
+ foreach (const QQmlChangeSet::Remove &remove, set.removes()) debug << remove;
+ foreach (const QQmlChangeSet::Insert &insert, set.inserts()) debug << insert;
+ foreach (const QQmlChangeSet::Change &change, set.changes()) debug << change;
+ return debug.nospace() << ')';
+}
+
+/*!
+ Prints a \a remove to the \a debug stream.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlChangeSet::Remove &remove)
+{
+ if (remove.moveId == -1) {
+ return (debug.nospace()
+ << "Remove(" << remove.index
+ << ',' << remove.count
+ << ')').space();
+ } else {
+ return (debug.nospace()
+ << "Remove(" << remove.index
+ << ',' << remove.count
+ << ',' << remove.moveId
+ << ',' << remove.offset
+ << ')').space();
+ }
+}
+
+/*!
+ Prints an \a insert to the \a debug stream.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlChangeSet::Insert &insert)
+{
+ if (insert.moveId == -1) {
+ return (debug.nospace()
+ << "Insert(" << insert.index
+ << ',' << insert.count
+ << ')').space();
+ } else {
+ return (debug.nospace()
+ << "Insert(" << insert.index
+ << ',' << insert.count
+ << ',' << insert.moveId
+ << ',' << insert.offset
+ << ')').space();
+ }
+}
+
+/*!
+ Prints a \a change to the \a debug stream.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlChangeSet::Change &change)
+{
+ return (debug.nospace() << "Change(" << change.index << ',' << change.count << ')').space();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/qml/util/qqmlchangeset_p.h b/src/qml/util/qqmlchangeset_p.h
new file mode 100644
index 0000000000..acafbd4eec
--- /dev/null
+++ b/src/qml/util/qqmlchangeset_p.h
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLCHANGESET_P_H
+#define QQMLCHANGESET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
+#include <QtQml/private/qtqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QML_PRIVATE_EXPORT QQmlChangeSet
+{
+public:
+ struct MoveKey
+ {
+ MoveKey() : moveId(-1), offset(0) {}
+ MoveKey(int moveId, int offset) : moveId(moveId), offset(offset) {}
+ int moveId;
+ int offset;
+ };
+
+ struct Change
+ {
+ Change() : index(0), count(0), moveId(-1) {}
+ Change(int index, int count, int moveId = -1, int offset = 0)
+ : index(index), count(count), moveId(moveId), offset(offset) {}
+
+ int index;
+ int count;
+ int moveId;
+ int offset;
+
+ bool isMove() const { return moveId >= 0; }
+
+ MoveKey moveKey(int index) const {
+ return MoveKey(moveId, index - Change::index + offset); }
+
+ int start() const { return index; }
+ int end() const { return index + count; }
+ };
+
+
+ struct Insert : public Change
+ {
+ Insert() {}
+ Insert(int index, int count, int moveId = -1, int offset = 0)
+ : Change(index, count, moveId, offset) {}
+ };
+
+ struct Remove : public Change
+ {
+ Remove() {}
+ Remove(int index, int count, int moveId = -1, int offset = 0)
+ : Change(index, count, moveId, offset) {}
+ };
+
+ QQmlChangeSet();
+ QQmlChangeSet(const QQmlChangeSet &changeSet);
+ ~QQmlChangeSet();
+
+ QQmlChangeSet &operator =(const QQmlChangeSet &changeSet);
+
+ const QVector<Remove> &removes() const { return m_removes; }
+ const QVector<Insert> &inserts() const { return m_inserts; }
+ const QVector<Change> &changes() const { return m_changes; }
+
+ void insert(int index, int count);
+ void remove(int index, int count);
+ void move(int from, int to, int count, int moveId);
+ void change(int index, int count);
+
+ void insert(const QVector<Insert> &inserts);
+ void remove(const QVector<Remove> &removes, QVector<Insert> *inserts = 0);
+ void move(const QVector<Remove> &removes, const QVector<Insert> &inserts);
+ void change(const QVector<Change> &changes);
+ void apply(const QQmlChangeSet &changeSet);
+
+ bool isEmpty() const { return m_removes.empty() && m_inserts.empty() && m_changes.isEmpty(); }
+
+ void clear()
+ {
+ m_removes.clear();
+ m_inserts.clear();
+ m_changes.clear();
+ m_difference = 0;
+ }
+
+ int difference() const { return m_difference; }
+
+private:
+ void remove(QVector<Remove> *removes, QVector<Insert> *inserts);
+ void change(QVector<Change> *changes);
+
+ QVector<Remove> m_removes;
+ QVector<Insert> m_inserts;
+ QVector<Change> m_changes;
+ int m_difference;
+};
+
+Q_DECLARE_TYPEINFO(QQmlChangeSet::Change, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQmlChangeSet::Remove, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQmlChangeSet::Insert, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQmlChangeSet::MoveKey, Q_PRIMITIVE_TYPE);
+
+inline uint qHash(const QQmlChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
+inline bool operator ==(const QQmlChangeSet::MoveKey &l, const QQmlChangeSet::MoveKey &r) {
+ return l.moveId == r.moveId && l.offset == r.offset; }
+
+Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet::Remove &remove);
+Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet::Insert &insert);
+Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet::Change &change);
+Q_QML_PRIVATE_EXPORT QDebug operator <<(QDebug debug, const QQmlChangeSet &change);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/util/qqmllistaccessor.cpp b/src/qml/util/qqmllistaccessor.cpp
new file mode 100644
index 0000000000..2a2bd74a54
--- /dev/null
+++ b/src/qml/util/qqmllistaccessor.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmllistaccessor_p.h"
+
+#include <private/qqmlmetatype_p.h>
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
+
+// ### Remove me
+#include <private/qqmlengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQmlListAccessor::QQmlListAccessor()
+: m_type(Invalid)
+{
+}
+
+QQmlListAccessor::~QQmlListAccessor()
+{
+}
+
+QVariant QQmlListAccessor::list() const
+{
+ return d;
+}
+
+void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
+{
+ d = v;
+
+ QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):0;
+
+ if (!d.isValid()) {
+ m_type = Invalid;
+ } else if (d.userType() == QVariant::StringList) {
+ m_type = StringList;
+ } else if (d.userType() == QMetaType::QVariantList) {
+ m_type = VariantList;
+ } else if (d.canConvert(QVariant::Int)) {
+ m_type = Integer;
+ } else if ((!enginePrivate && QQmlMetaType::isQObject(d.userType())) ||
+ (enginePrivate && enginePrivate->isQObject(d.userType()))) {
+ QObject *data = enginePrivate?enginePrivate->toQObject(v):QQmlMetaType::toQObject(v);
+ d = QVariant::fromValue(data);
+ m_type = Instance;
+ } else if (d.userType() == qMetaTypeId<QQmlListReference>()) {
+ m_type = ListProperty;
+ } else {
+ m_type = Instance;
+ }
+}
+
+int QQmlListAccessor::count() const
+{
+ switch(m_type) {
+ case StringList:
+ return qvariant_cast<QStringList>(d).count();
+ case VariantList:
+ return qvariant_cast<QVariantList>(d).count();
+ case ListProperty:
+ return ((QQmlListReference *)d.constData())->count();
+ case Instance:
+ return 1;
+ case Integer:
+ return d.toInt();
+ default:
+ case Invalid:
+ return 0;
+ }
+}
+
+QVariant QQmlListAccessor::at(int idx) const
+{
+ Q_ASSERT(idx >= 0 && idx < count());
+ switch(m_type) {
+ case StringList:
+ return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx));
+ case VariantList:
+ return qvariant_cast<QVariantList>(d).at(idx);
+ case ListProperty:
+ return QVariant::fromValue(((QQmlListReference *)d.constData())->at(idx));
+ case Instance:
+ return d;
+ case Integer:
+ return QVariant(idx);
+ default:
+ case Invalid:
+ return QVariant();
+ }
+}
+
+bool QQmlListAccessor::isValid() const
+{
+ return m_type != Invalid;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/util/qqmllistaccessor_p.h b/src/qml/util/qqmllistaccessor_p.h
new file mode 100644
index 0000000000..8f3fb41186
--- /dev/null
+++ b/src/qml/util/qqmllistaccessor_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLLISTACCESSOR_H
+#define QQMLLISTACCESSOR_H
+
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+class Q_AUTOTEST_EXPORT QQmlListAccessor
+{
+public:
+ QQmlListAccessor();
+ ~QQmlListAccessor();
+
+ QVariant list() const;
+ void setList(const QVariant &, QQmlEngine * = 0);
+
+ bool isValid() const;
+
+ int count() const;
+ QVariant at(int) const;
+
+ enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer };
+ Type type() const { return m_type; }
+
+private:
+ Type m_type;
+ QVariant d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLLISTACCESSOR_H
diff --git a/src/qml/util/qqmllistcompositor.cpp b/src/qml/util/qqmllistcompositor.cpp
new file mode 100644
index 0000000000..75d2f67b51
--- /dev/null
+++ b/src/qml/util/qqmllistcompositor.cpp
@@ -0,0 +1,1484 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmllistcompositor_p.h"
+
+#include <QtCore/qvarlengtharray.h>
+
+//#define QT_QML_VERIFY_MINIMAL
+//#define QT_QML_VERIFY_INTEGRITY
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlListCompositor
+ \brief The QQmlListCompositor class provides a lookup table for filtered, or re-ordered list
+ indexes.
+ \internal
+
+ QQmlListCompositor is intended as an aid for developing proxy models. It doesn't however
+ directly proxy a list or model, instead a range of indexes from one or many lists can be
+ inserted into the compositor and then categorized and shuffled around and it will manage the
+ task of translating from an index in the combined space into an index in a particular list.
+
+ Within a compositor indexes are categorized into groups where a group is a sub-set of the
+ total indexes referenced by the compositor, each with an address space ranging from 0 to
+ the number of indexes in the group - 1. Group memberships are independent of each other with
+ the one exception that items always retain the same order so if an index is moved within a
+ group, its position in other groups will change as well.
+
+ The iterator classes encapsulate information about a specific position in a compositor group.
+ This includes a source list, the index of an item within that list and the groups that item
+ is a member of. The iterator for a specific position in a group can be retrieved with the
+ find() function and the addition and subtraction operators of the iterators can be used to
+ navigate to adjacent items in the same group.
+
+ Items can be added to the compositor with the append() and insert() functions, group
+ membership can be changed with the setFlags() and clearFlags() functions, and the position
+ of items in the compositor can be changed with the move() function. Each of these functions
+ optionally returns a list of the changes made to indexes within each group which can then
+ be propagated to view so that it can correctly refresh its contents; e.g. 3 items
+ removed at index 6, and 5 items inserted at index 1. The notification changes are always
+ ordered from the start of the list to the end and accumulate, so if 5 items are removed at
+ index 4, one is skipped and then 3 move are removed, the changes returned are 5 items removed
+ at index 4, followed by 3 items removed at index 4.
+
+ When the contents of a source list change, the mappings within the compositor can be updated
+ with the listItemsInserted(), listItemsRemoved(), listItemsMoved(), and listItemsChanged()
+ functions. Like the direct manipulation functions these too return a list of group indexes
+ affected by the change. If items are removed from a source list they are also removed from
+ any groups they belong to with the one exception being items belonging to the \l Cache group.
+ When items belonging to this group are removed the list, index, and other group membership
+ information are discarded but Cache membership is retained until explicitly removed. This
+ allows the cache index to be retained until cached resources for that item are actually
+ released.
+
+ Internally the index mapping is stored as a list of Range objects, each has a list identifier,
+ a start index, a count, and a set of flags which represent group membership and some other
+ properties. The group index of a range is the sum of all preceding ranges that are members of
+ that group. To avoid the inefficiency of iterating over potentially all ranges when looking
+ for a specific index, each time a lookup is done the range and its indexes are cached and the
+ next lookup is done relative to this. This works out to near constant time in most relevant
+ use cases because successive index lookups are most frequently adjacent. The total number of
+ ranges is often quite small, which helps as well. If there is a need for faster random access
+ then a skip list like index may be an appropriate addition.
+
+ \sa VisualDataModel
+*/
+
+#ifdef QT_QML_VERIFY_MINIMAL
+#define QT_QML_VERIFY_INTEGRITY
+/*
+ Diagnostic to verify there are no consecutive ranges, or that the compositor contains the
+ most compact representation possible.
+
+ Returns false and prints a warning if any range has a starting index equal to the end
+ (index + count) index of the previous range, and both ranges also have the same flags and list
+ property.
+
+ If there are no consecutive ranges this will return true.
+*/
+
+static bool qt_verifyMinimal(
+ const QQmlListCompositor::iterator &begin,
+ const QQmlListCompositor::iterator &end)
+{
+ bool minimal = true;
+ int index = 0;
+
+ for (const QQmlListCompositor::Range *range = begin->next; range != *end; range = range->next, ++index) {
+ if (range->previous->list == range->list
+ && range->previous->flags == (range->flags & ~QQmlListCompositor::AppendFlag)
+ && range->previous->end() == range->index) {
+ qWarning() << index << "Consecutive ranges";
+ qWarning() << *range->previous;
+ qWarning() << *range;
+ minimal = false;
+ }
+ }
+
+ return minimal;
+}
+
+#endif
+
+#ifdef QT_QML_VERIFY_INTEGRITY
+static bool qt_printInfo(const QQmlListCompositor &compositor)
+{
+ qWarning() << compositor;
+ return true;
+}
+
+/*
+ Diagnostic to verify the integrity of a compositor.
+
+ Per range this verifies there are no invalid range combinations, that non-append ranges have
+ positive non-zero counts, and that list ranges have non-negative indexes.
+
+ Accumulatively this verifies that the cached total group counts match the sum of counts
+ of member ranges.
+*/
+
+static bool qt_verifyIntegrity(
+ const QQmlListCompositor::iterator &begin,
+ const QQmlListCompositor::iterator &end,
+ const QQmlListCompositor::iterator &cachedIt)
+{
+ bool valid = true;
+
+ int index = 0;
+ QQmlListCompositor::iterator it;
+ for (it = begin; *it != *end; *it = it->next) {
+ if (it->count == 0 && !it->append()) {
+ qWarning() << index << "Empty non-append range";
+ valid = false;
+ }
+ if (it->count < 0) {
+ qWarning() << index << "Negative count";
+ valid = false;
+ }
+ if (it->list && it->flags != QQmlListCompositor::CacheFlag && it->index < 0) {
+ qWarning() << index <<"Negative index";
+ valid = false;
+ }
+ if (it->previous->next != it.range) {
+ qWarning() << index << "broken list: it->previous->next != it.range";
+ valid = false;
+ }
+ if (it->next->previous != it.range) {
+ qWarning() << index << "broken list: it->next->previous != it.range";
+ valid = false;
+ }
+ if (*it == *cachedIt) {
+ for (int i = 0; i < end.groupCount; ++i) {
+ int groupIndex = it.index[i];
+ if (cachedIt->flags & (1 << i))
+ groupIndex += cachedIt.offset;
+ if (groupIndex != cachedIt.index[i]) {
+ qWarning() << index
+ << "invalid cached index"
+ << QQmlListCompositor::Group(i)
+ << "Expected:"
+ << groupIndex
+ << "Actual"
+ << cachedIt.index[i]
+ << cachedIt;
+ valid = false;
+ }
+ }
+ }
+ it.incrementIndexes(it->count);
+ ++index;
+ }
+
+ for (int i = 0; i < end.groupCount; ++i) {
+ if (end.index[i] != it.index[i]) {
+ qWarning() << "Group" << i << "count invalid. Expected:" << end.index[i] << "Actual:" << it.index[i];
+ valid = false;
+ }
+ }
+ return valid;
+}
+#endif
+
+#if defined(QT_QML_VERIFY_MINIMAL)
+# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
+ && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \
+ && qt_printInfo(*this)));
+#elif defined(QT_QML_VERIFY_INTEGRITY)
+# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
+ && qt_printInfo(*this)));
+#else
+# define QT_QML_VERIFY_LISTCOMPOSITOR
+#endif
+
+//#define QT_QML_TRACE_LISTCOMPOSITOR(args) qDebug() << m_end.index[1] << m_end.index[0] << Q_FUNC_INFO args;
+#define QT_QML_TRACE_LISTCOMPOSITOR(args)
+
+QQmlListCompositor::iterator &QQmlListCompositor::iterator::operator +=(int difference)
+{
+ // Update all indexes to the start of the range.
+ decrementIndexes(offset);
+
+ // If the iterator group isn't a member of the current range ignore the current offset.
+ if (!(range->flags & groupFlag))
+ offset = 0;
+
+ offset += difference;
+
+ // Iterate backwards looking for a range with a positive offset.
+ while (offset <= 0 && range->previous->flags) {
+ range = range->previous;
+ if (range->flags & groupFlag)
+ offset += range->count;
+ decrementIndexes(range->count);
+ }
+
+ // Iterate forwards looking for the first range which contains both the offset and the
+ // iterator group.
+ while (range->flags && (offset >= range->count || !(range->flags & groupFlag))) {
+ if (range->flags & groupFlag)
+ offset -= range->count;
+ incrementIndexes(range->count);
+ range = range->next;
+ }
+
+ // Update all the indexes to inclue the remaining offset.
+ incrementIndexes(offset);
+
+ return *this;
+}
+
+QQmlListCompositor::insert_iterator &QQmlListCompositor::insert_iterator::operator +=(int difference)
+{
+ iterator::operator +=(difference);
+
+ // If the previous range contains the append flag move the iterator to the tail of the previous
+ // range so that appended appear after the insert position.
+ if (offset == 0 && range->previous->append()) {
+ range = range->previous;
+ offset = range->inGroup() ? range->count : 0;
+ }
+
+ return *this;
+}
+
+
+/*!
+ Constructs an empty list compositor.
+*/
+
+QQmlListCompositor::QQmlListCompositor()
+ : m_end(m_ranges.next, 0, Default, 2)
+ , m_cacheIt(m_end)
+ , m_groupCount(2)
+ , m_defaultFlags(PrependFlag | DefaultFlag)
+ , m_removeFlags(AppendFlag | PrependFlag | GroupMask)
+ , m_moveId(0)
+{
+}
+
+/*!
+ Destroys a list compositor.
+*/
+
+QQmlListCompositor::~QQmlListCompositor()
+{
+ for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) {
+ next = range->next;
+ delete range;
+ }
+}
+
+/*!
+ Inserts a range with the given source \a list, start \a index, \a count and \a flags, in front
+ of the existing range \a before.
+*/
+
+inline QQmlListCompositor::Range *QQmlListCompositor::insert(
+ Range *before, void *list, int index, int count, uint flags)
+{
+ return new Range(before, list, index, count, flags);
+}
+
+/*!
+ Erases a \a range from the compositor.
+
+ Returns a pointer to the next range in the compositor.
+*/
+
+inline QQmlListCompositor::Range *QQmlListCompositor::erase(
+ Range *range)
+{
+ Range *next = range->next;
+ next->previous = range->previous;
+ next->previous->next = range->next;
+ delete range;
+ return next;
+}
+
+/*!
+ Sets the number (\a count) of possible groups that items may belong to in a compositor.
+*/
+
+void QQmlListCompositor::setGroupCount(int count)
+{
+ m_groupCount = count;
+ m_end = iterator(&m_ranges, 0, Default, m_groupCount);
+ m_cacheIt = m_end;
+}
+
+/*!
+ Returns the number of items that belong to a \a group.
+*/
+
+int QQmlListCompositor::count(Group group) const
+{
+ return m_end.index[group];
+}
+
+/*!
+ Returns an iterator representing the item at \a index in a \a group.
+
+ The index must be between 0 and count(group) - 1.
+*/
+
+QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
+ Q_ASSERT(index >=0 && index < count(group));
+ if (m_cacheIt == m_end) {
+ m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
+ m_cacheIt += index;
+ } else {
+ const int offset = index - m_cacheIt.index[group];
+ m_cacheIt.setGroup(group);
+ m_cacheIt += offset;
+ }
+ Q_ASSERT(m_cacheIt.index[group] == index);
+ Q_ASSERT(m_cacheIt->inGroup(group));
+ QT_QML_VERIFY_LISTCOMPOSITOR
+ return m_cacheIt;
+}
+
+/*!
+ Returns an iterator representing the item at \a index in a \a group.
+
+ The index must be between 0 and count(group) - 1.
+*/
+
+QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index) const
+{
+ return const_cast<QQmlListCompositor *>(this)->find(group, index);
+}
+
+/*!
+ Returns an iterator representing an insert position in front of the item at \a index in a
+ \a group.
+
+ The iterator for an insert position can sometimes resolve to a different Range than a regular
+ iterator. This is because when items are inserted on a boundary between Ranges, if the first
+ range has the Append flag set then the items should be inserted into that range to ensure
+ that the append position for the existing range remains after the insert position.
+
+ The index must be between 0 and count(group) - 1.
+*/
+
+QQmlListCompositor::insert_iterator QQmlListCompositor::findInsertPosition(Group group, int index)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
+ Q_ASSERT(index >=0 && index <= count(group));
+ insert_iterator it;
+ if (m_cacheIt == m_end) {
+ it = iterator(m_ranges.next, 0, group, m_groupCount);
+ it += index;
+ } else {
+ const int offset = index - m_cacheIt.index[group];
+ it = m_cacheIt;
+ it.setGroup(group);
+ it += offset;
+ }
+ Q_ASSERT(it.index[group] == index);
+ return it;
+}
+
+/*!
+ Appends a range of \a count indexes starting at \a index from a \a list into a compositor
+ with the given \a flags.
+
+ If supplied the \a inserts list will be populated with the positions of the inserted items
+ in each group.
+*/
+
+void QQmlListCompositor::append(
+ void *list, int index, int count, uint flags, QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count << flags)
+ insert(m_end, list, index, count, flags, inserts);
+}
+
+/*!
+ Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
+ into a \a group at index \a before.
+
+ If supplied the \a inserts list will be populated with the positions of items inserted into
+ each group.
+*/
+
+void QQmlListCompositor::insert(
+ Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags)
+ insert(findInsertPosition(group, before), list, index, count, flags, inserts);
+}
+
+/*!
+ Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
+ into a compositor at position \a before.
+
+ If supplied the \a inserts list will be populated with the positions of items inserted into
+ each group.
+*/
+
+QQmlListCompositor::iterator QQmlListCompositor::insert(
+ iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags)
+ if (inserts) {
+ inserts->append(Insert(before, count, flags & GroupMask));
+ }
+ if (before.offset > 0) {
+ // Inserting into the middle of a range. Split it two and update the iterator so it's
+ // positioned at the start of the second half.
+ *before = insert(
+ *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next;
+ before->index += before.offset;
+ before->count -= before.offset;
+ before.offset = 0;
+ }
+
+
+ if (!(flags & AppendFlag) && *before != m_ranges.next
+ && before->previous->list == list
+ && before->previous->flags == flags
+ && (!list || before->previous->end() == index)) {
+ // The insert arguments represent a continuation of the previous range so increment
+ // its count instead of inserting a new range.
+ before->previous->count += count;
+ before.incrementIndexes(count, flags);
+ } else {
+ *before = insert(*before, list, index, count, flags);
+ before.offset = 0;
+ }
+
+ if (!(flags & AppendFlag) && before->next != &m_ranges
+ && before->list == before->next->list
+ && before->flags == before->next->flags
+ && (!list || before->end() == before->next->index)) {
+ // The current range and the next are continuous so add their counts and delete one.
+ before->next->index = before->index;
+ before->next->count += before->count;
+ *before = erase(*before);
+ }
+
+ m_end.incrementIndexes(count, flags);
+ m_cacheIt = before;
+ QT_QML_VERIFY_LISTCOMPOSITOR
+ return before;
+}
+
+/*!
+ Sets the given flags \a flags on \a count items belonging to \a group starting at the position
+ identified by \a fromGroup and the index \a from.
+
+ If supplied the \a inserts list will be populated with insert notifications for affected groups.
+*/
+
+void QQmlListCompositor::setFlags(
+ Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
+ setFlags(find(fromGroup, from), count, group, flags, inserts);
+}
+
+/*!
+ Sets the given flags \a flags on \a count items belonging to \a group starting at the position
+ \a from.
+
+ If supplied the \a inserts list will be populated with insert notifications for affected groups.
+*/
+
+void QQmlListCompositor::setFlags(
+ iterator from, int count, Group group, uint flags, QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
+ if (!flags || !count)
+ return;
+
+ if (from != group) {
+ // Skip to the next full range if the start one is not a member of the target group.
+ from.incrementIndexes(from->count - from.offset);
+ from.offset = 0;
+ *from = from->next;
+ } else if (from.offset > 0) {
+ // If the start position is mid range split off the portion unaffected.
+ *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
+ from->index += from.offset;
+ from->count -= from.offset;
+ from.offset = 0;
+ }
+
+ for (; count > 0; *from = from->next) {
+ if (from != from.group) {
+ // Skip ranges that are not members of the target group.
+ from.incrementIndexes(from->count);
+ continue;
+ }
+ // Find the number of items affected in the current range.
+ const int difference = qMin(count, from->count);
+ count -= difference;
+
+ // Determine the actual changes made to the range and increment counts accordingly.
+ const uint insertFlags = ~from->flags & flags;
+ const uint setFlags = (from->flags | flags) & ~AppendFlag;
+ if (insertFlags && inserts)
+ inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag)));
+ m_end.incrementIndexes(difference, insertFlags);
+ from.incrementIndexes(difference, setFlags);
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == setFlags) {
+ // If the additional flags make the current range a continuation of the previous
+ // then move the affected items over to the previous range.
+ from->previous->count += difference;
+ from->index += difference;
+ from->count -= difference;
+ if (from->count == 0) {
+ // Delete the current range if it is now empty, preserving the append flag
+ // in the previous range.
+ if (from->append())
+ from->previous->flags |= AppendFlag;
+ *from = erase(*from)->previous;
+ continue;
+ } else {
+ break;
+ }
+ } else if (!insertFlags) {
+ // No new flags, so roll onto the next range.
+ from.incrementIndexes(from->count - difference);
+ continue;
+ } else if (difference < from->count) {
+ // Create a new range with the updated flags, and remove the affected items
+ // from the current range.
+ *from = insert(*from, from->list, from->index, difference, setFlags)->next;
+ from->index += difference;
+ from->count -= difference;
+ } else {
+ // The whole range is affected so simply update the flags.
+ from->flags |= flags;
+ continue;
+ }
+ from.incrementIndexes(from->count);
+ }
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == (from->flags & ~AppendFlag)) {
+ // If the following range is now a continuation, merge it with its previous range.
+ from.offset = from->previous->count;
+ from->previous->count += from->count;
+ from->previous->flags = from->flags;
+ *from = erase(*from)->previous;
+ }
+ m_cacheIt = from;
+ QT_QML_VERIFY_LISTCOMPOSITOR
+}
+
+/*!
+ Clears the given flags \a flags on \a count items belonging to \a group starting at the position
+ \a from.
+
+ If supplied the \a removes list will be populated with remove notifications for affected groups.
+*/
+
+void QQmlListCompositor::clearFlags(
+ Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removes)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
+ clearFlags(find(fromGroup, from), count, group, flags, removes);
+}
+
+/*!
+ Clears the given flags \a flags on \a count items belonging to \a group starting at the position
+ identified by \a fromGroup and the index \a from.
+
+ If supplied the \a removes list will be populated with remove notifications for affected groups.
+*/
+
+void QQmlListCompositor::clearFlags(
+ iterator from, int count, Group group, uint flags, QVector<Remove> *removes)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
+ if (!flags || !count)
+ return;
+
+ const bool clearCache = flags & CacheFlag;
+
+ if (from != group) {
+ // Skip to the next full range if the start one is not a member of the target group.
+ from.incrementIndexes(from->count - from.offset);
+ from.offset = 0;
+ *from = from->next;
+ } else if (from.offset > 0) {
+ // If the start position is mid range split off the portion unaffected.
+ *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
+ from->index += from.offset;
+ from->count -= from.offset;
+ from.offset = 0;
+ }
+
+ for (; count > 0; *from = from->next) {
+ if (from != group) {
+ // Skip ranges that are not members of the target group.
+ from.incrementIndexes(from->count);
+ continue;
+ }
+ // Find the number of items affected in the current range.
+ const int difference = qMin(count, from->count);
+ count -= difference;
+
+
+ // Determine the actual changes made to the range and decrement counts accordingly.
+ const uint removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag);
+ const uint clearedFlags = from->flags & ~(flags | AppendFlag | UnresolvedFlag);
+ if (removeFlags && removes) {
+ const int maskedFlags = clearCache
+ ? (removeFlags & ~CacheFlag)
+ : (removeFlags | (from->flags & CacheFlag));
+ if (maskedFlags)
+ removes->append(Remove(from, difference, maskedFlags));
+ }
+ m_end.decrementIndexes(difference, removeFlags);
+ from.incrementIndexes(difference, clearedFlags);
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index)
+ && from->previous->flags == clearedFlags) {
+ // If the removed flags make the current range a continuation of the previous
+ // then move the affected items over to the previous range.
+ from->previous->count += difference;
+ from->index += difference;
+ from->count -= difference;
+ if (from->count == 0) {
+ // Delete the current range if it is now empty, preserving the append flag
+ if (from->append())
+ from->previous->flags |= AppendFlag;
+ *from = erase(*from)->previous;
+ } else {
+ from.incrementIndexes(from->count);
+ }
+ } else if (difference < from->count) {
+ // Create a new range with the reduced flags, and remove the affected items from
+ // the current range.
+ if (clearedFlags)
+ *from = insert(*from, from->list, from->index, difference, clearedFlags)->next;
+ from->index += difference;
+ from->count -= difference;
+ from.incrementIndexes(from->count);
+ } else if (clearedFlags) {
+ // The whole range is affected so simply update the flags.
+ from->flags &= ~flags;
+ } else {
+ // All flags have been removed from the range so remove it.
+ *from = erase(*from)->previous;
+ }
+ }
+
+ if (*from != &m_ranges && from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == (from->flags & ~AppendFlag)) {
+ // If the following range is now a continuation, merge it with its previous range.
+ from.offset = from->previous->count;
+ from->previous->count += from->count;
+ from->previous->flags = from->flags;
+ *from = erase(*from)->previous;
+ }
+ m_cacheIt = from;
+ QT_QML_VERIFY_LISTCOMPOSITOR
+}
+
+bool QQmlListCompositor::verifyMoveTo(
+ Group fromGroup, int from, Group toGroup, int to, int count, Group group) const
+{
+ if (group != toGroup) {
+ // determine how many items from the destination group intersect with the source group.
+ iterator fromIt = find(fromGroup, from);
+
+ int intersectingCount = 0;
+
+ for (; count > 0; *fromIt = fromIt->next) {
+ if (*fromIt == &m_ranges)
+ return false;
+ if (!fromIt->inGroup(group))
+ continue;
+ if (fromIt->inGroup(toGroup))
+ intersectingCount += qMin(count, fromIt->count - fromIt.offset);
+ count -= fromIt->count - fromIt.offset;
+ fromIt.offset = 0;
+ }
+ count = intersectingCount;
+ }
+
+ return to >= 0 && to + count <= m_end.index[toGroup];
+}
+
+/*!
+ \internal
+
+ Moves \a count items belonging to \a moveGroup from the index \a from in \a fromGroup
+ to the index \a to in \a toGroup.
+
+ If \a removes and \a inserts are not null they will be populated with per group notifications
+ of the items moved.
+ */
+
+void QQmlListCompositor::move(
+ Group fromGroup,
+ int from,
+ Group toGroup,
+ int to,
+ int count,
+ Group moveGroup,
+ QVector<Remove> *removes,
+ QVector<Insert> *inserts)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << toGroup << to << count)
+ Q_ASSERT(count > 0);
+ Q_ASSERT(from >=0);
+ Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count, moveGroup));
+
+ // Find the position of the first item to move.
+ iterator fromIt = find(fromGroup, from);
+
+ if (fromIt != moveGroup) {
+ // If the range at the from index doesn't contain items from the move group; skip
+ // to the next range.
+ fromIt.incrementIndexes(fromIt->count - fromIt.offset);
+ fromIt.offset = 0;
+ *fromIt = fromIt->next;
+ } else if (fromIt.offset > 0) {
+ // If the range at the from index contains items from the move group and the index isn't
+ // at the start of the range; split the range at the index and move the iterator to start
+ // of the second range.
+ *fromIt = insert(
+ *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next;
+ fromIt->index += fromIt.offset;
+ fromIt->count -= fromIt.offset;
+ fromIt.offset = 0;
+ }
+
+ // Remove count items belonging to the move group from the list.
+ Range movedFlags;
+ for (int moveId = m_moveId; count > 0;) {
+ if (fromIt != moveGroup) {
+ // Skip ranges not containing items from the move group.
+ fromIt.incrementIndexes(fromIt->count);
+ *fromIt = fromIt->next;
+ continue;
+ }
+ int difference = qMin(count, fromIt->count);
+
+ // Create a new static range containing the moved items from an existing range.
+ new Range(
+ &movedFlags,
+ fromIt->list,
+ fromIt->index,
+ difference,
+ fromIt->flags & ~(PrependFlag | AppendFlag));
+ // Remove moved items from the count, the existing range, and a remove notification.
+ if (removes)
+ removes->append(Remove(fromIt, difference, fromIt->flags, ++moveId));
+ count -= difference;
+ fromIt->count -= difference;
+
+ // If the existing range contains the prepend flag replace the removed items with
+ // a placeholder range for new items inserted into the source model.
+ int removeIndex = fromIt->index;
+ if (fromIt->prepend()
+ && fromIt->previous != &m_ranges
+ && fromIt->previous->flags == PrependFlag
+ && fromIt->previous->list == fromIt->list
+ && fromIt->previous->end() == fromIt->index) {
+ // Grow the previous range instead of creating a new one if possible.
+ fromIt->previous->count += difference;
+ } else if (fromIt->prepend()) {
+ *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next;
+ }
+ fromIt->index += difference;
+
+ if (fromIt->count == 0) {
+ // If the existing range has no items remaining; remove it from the list.
+ if (fromIt->append())
+ fromIt->previous->flags |= AppendFlag;
+ *fromIt = erase(*fromIt);
+
+ // If the ranges before and after the removed range can be joined, do so.
+ if (*fromIt != m_ranges.next && fromIt->flags == PrependFlag
+ && fromIt->previous != &m_ranges
+ && fromIt->previous->flags == PrependFlag
+ && fromIt->previous->list == fromIt->list
+ && fromIt->previous->end() == fromIt->index) {
+ fromIt.incrementIndexes(fromIt->count);
+ fromIt->previous->count += fromIt->count;
+ *fromIt = erase(*fromIt);
+ }
+ } else if (count > 0) {
+ *fromIt = fromIt->next;
+ }
+ }
+
+ // Try and join the range following the removed items to the range preceding it.
+ if (*fromIt != m_ranges.next
+ && *fromIt != &m_ranges
+ && fromIt->previous->list == fromIt->list
+ && (!fromIt->list || fromIt->previous->end() == fromIt->index)
+ && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) {
+ if (fromIt == fromIt.group)
+ fromIt.offset = fromIt->previous->count;
+ fromIt.offset = fromIt->previous->count;
+ fromIt->previous->count += fromIt->count;
+ fromIt->previous->flags = fromIt->flags;
+ *fromIt = erase(*fromIt)->previous;
+ }
+
+ // Find the destination position of the move.
+ insert_iterator toIt = fromIt;
+ toIt.setGroup(toGroup);
+
+ const int difference = to - toIt.index[toGroup];
+ toIt += difference;
+
+ // If the insert position is part way through a range; split it and move the iterator to the
+ // start of the second range.
+ if (toIt.offset > 0) {
+ *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next;
+ toIt->index += toIt.offset;
+ toIt->count -= toIt.offset;
+ toIt.offset = 0;
+ }
+
+ // Insert the moved ranges before the insert iterator, growing the previous range if that
+ // is an option.
+ for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) {
+ if (*toIt != &m_ranges
+ && range->list == toIt->list
+ && (!range->list || range->end() == toIt->index)
+ && range->flags == (toIt->flags & ~AppendFlag)) {
+ toIt->index -= range->count;
+ toIt->count += range->count;
+ } else {
+ *toIt = insert(*toIt, range->list, range->index, range->count, range->flags);
+ }
+ }
+
+ // Try and join the range after the inserted ranges to the last range inserted.
+ if (*toIt != m_ranges.next
+ && toIt->previous->list == toIt->list
+ && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) {
+ toIt.offset = toIt->previous->count;
+ toIt->previous->count += toIt->count;
+ toIt->previous->flags = toIt->flags;
+ *toIt = erase(*toIt)->previous;
+ }
+ // Create insert notification for the ranges moved.
+ Insert insert(toIt, 0, 0, 0);
+ for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) {
+ insert.count = range->count;
+ insert.flags = range->flags;
+ if (inserts) {
+ insert.moveId = ++m_moveId;
+ inserts->append(insert);
+ }
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (insert.inGroup(i))
+ insert.index[i] += range->count;
+ }
+
+ next = range->next;
+ delete range;
+ }
+
+ m_cacheIt = toIt;
+
+ QT_QML_VERIFY_LISTCOMPOSITOR
+}
+
+/*!
+ Clears the contents of a compositor.
+*/
+
+void QQmlListCompositor::clear()
+{
+ QT_QML_TRACE_LISTCOMPOSITOR( )
+ for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {}
+ m_end = iterator(m_ranges.next, 0, Default, m_groupCount);
+ m_cacheIt = m_end;
+}
+
+void QQmlListCompositor::listItemsInserted(
+ QVector<Insert> *translatedInsertions,
+ void *list,
+ const QVector<QQmlChangeSet::Insert> &insertions,
+ const QVector<MovedFlags> *movedFlags)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << insertions)
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ // Skip ranges that don't reference list.
+ it.incrementIndexes(it->count);
+ continue;
+ } else if (it->flags & MovedFlag) {
+ // Skip ranges that were already moved in listItemsRemoved.
+ it->flags &= ~MovedFlag;
+ it.incrementIndexes(it->count);
+ continue;
+ }
+ foreach (const QQmlChangeSet::Insert &insertion, insertions) {
+ int offset = insertion.index - it->index;
+ if ((offset > 0 && offset < it->count)
+ || (offset == 0 && it->prepend())
+ || (offset == it->count && it->append())) {
+ // The insert index is within the current range.
+ if (it->prepend()) {
+ // The range has the prepend flag set so we insert new items into the range.
+ uint flags = m_defaultFlags;
+ if (insertion.isMove()) {
+ // If the insert was part of a move replace the default flags with
+ // the flags from the source range.
+ for (QVector<MovedFlags>::const_iterator move = movedFlags->begin();
+ move != movedFlags->end();
+ ++move) {
+ if (move->moveId == insertion.moveId) {
+ flags = move->flags;
+ break;
+ }
+ }
+ }
+ if (flags & ~(AppendFlag | PrependFlag)) {
+ // If any items are added to groups append an insert notification.
+ Insert translatedInsert(it, insertion.count, flags, insertion.moveId);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedInsert.index[i] += offset;
+ }
+ translatedInsertions->append(translatedInsert);
+ }
+ if ((it->flags & ~AppendFlag) == flags) {
+ // Accumulate items on the current range it its flags are the same as
+ // the insert flags.
+ it->count += insertion.count;
+ } else if (offset == 0
+ && it->previous != &m_ranges
+ && it->previous->list == list
+ && it->previous->end() == insertion.index
+ && it->previous->flags == flags) {
+ // Attempt to append to the previous range if the insert position is at
+ // the start of the current range.
+ it->previous->count += insertion.count;
+ it->index += insertion.count;
+ it.incrementIndexes(insertion.count);
+ } else {
+ if (offset > 0) {
+ // Divide the current range at the insert position.
+ it.incrementIndexes(offset);
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ }
+ // Insert a new range, and increment the start index of the current range.
+ *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next;
+ it.incrementIndexes(insertion.count, flags);
+ it->index += offset + insertion.count;
+ it->count -= offset;
+ }
+ m_end.incrementIndexes(insertion.count, flags);
+ } else {
+ // The range doesn't have the prepend flag set so split the range into parts;
+ // one before the insert position and one after the last inserted item.
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags)->next;
+ it->index += offset;
+ it->count -= offset;
+ }
+ it->index += insertion.count;
+ }
+ } else if (offset <= 0) {
+ // The insert position was before the current range so increment the start index.
+ it->index += insertion.count;
+ }
+ }
+ it.incrementIndexes(it->count);
+ }
+ m_cacheIt = m_end;
+ QT_QML_VERIFY_LISTCOMPOSITOR
+}
+
+/*!
+ Updates the contents of a compositor when \a count items are inserted into a \a list at
+ \a index.
+
+ This corrects the indexes of each range for that list in the compositor, splitting the range
+ in two if the insert index is in the middle of that range. If a range at the insert position
+ has the Prepend flag set then a new range will be inserted at that position with the groups
+ specified in defaultGroups(). If the insert index corresponds to the end of a range with
+ the Append flag set a new range will be inserted before the end of the append range.
+
+ The \a translatedInsertions list is populated with insert notifications for affected
+ groups.
+*/
+
+void QQmlListCompositor::listItemsInserted(
+ void *list, int index, int count, QVector<Insert> *translatedInsertions)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count > 0);
+
+ QVector<QQmlChangeSet::Insert> insertions;
+ insertions.append(QQmlChangeSet::Insert(index, count));
+
+ listItemsInserted(translatedInsertions, list, insertions);
+}
+
+void QQmlListCompositor::listItemsRemoved(
+ QVector<Remove> *translatedRemovals,
+ void *list,
+ QVector<QQmlChangeSet::Remove> *removals,
+ QVector<QQmlChangeSet::Insert> *insertions,
+ QVector<MovedFlags> *movedFlags)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << *removals)
+
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ // Skip ranges that don't reference list.
+ it.incrementIndexes(it->count);
+ continue;
+ }
+ bool removed = false;
+ for (QVector<QQmlChangeSet::Remove>::iterator removal = removals->begin();
+ !removed && removal != removals->end();
+ ++removal) {
+ int relativeIndex = removal->index - it->index;
+ int itemsRemoved = removal->count;
+ if (relativeIndex + removal->count > 0 && relativeIndex < it->count) {
+ // If the current range intersects the remove; remove the intersecting items.
+ const int offset = qMax(0, relativeIndex);
+ int removeCount = qMin(it->count, relativeIndex + removal->count) - offset;
+ it->count -= removeCount;
+ int removeFlags = it->flags & m_removeFlags;
+ Remove translatedRemoval(it, removeCount, it->flags);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedRemoval.index[i] += offset;
+ }
+ if (removal->isMove()) {
+ // If the removal was part of a move find the corresponding insert.
+ QVector<QQmlChangeSet::Insert>::iterator insertion = insertions->begin();
+ for (; insertion != insertions->end() && insertion->moveId != removal->moveId;
+ ++insertion) {}
+ Q_ASSERT(insertion != insertions->end());
+ Q_ASSERT(insertion->count == removal->count);
+
+ if (relativeIndex < 0) {
+ // If the remove started before the current range, split it and the
+ // corresponding insert so we're only working with intersecting part.
+ int splitMoveId = ++m_moveId;
+ removal = removals->insert(removal, QQmlChangeSet::Remove(
+ removal->index, -relativeIndex, splitMoveId));
+ ++removal;
+ removal->count -= -relativeIndex;
+ insertion = insertions->insert(insertion, QQmlChangeSet::Insert(
+ insertion->index, -relativeIndex, splitMoveId));
+ ++insertion;
+ insertion->index += -relativeIndex;
+ insertion->count -= -relativeIndex;
+ }
+
+ if (it->prepend()) {
+ // If the current range has the prepend flag preserve its flags to transfer
+ // to its new location.
+ removeFlags |= it->flags & CacheFlag;
+ translatedRemoval.moveId = ++m_moveId;
+ movedFlags->append(MovedFlags(m_moveId, it->flags & ~AppendFlag));
+
+ if (removeCount < removal->count) {
+ // If the remove doesn't encompass all of the current range,
+ // split it and the corresponding insert.
+ removal = removals->insert(removal, QQmlChangeSet::Remove(
+ removal->index, removeCount, translatedRemoval.moveId));
+ ++removal;
+ insertion = insertions->insert(insertion, QQmlChangeSet::Insert(
+ insertion->index, removeCount, translatedRemoval.moveId));
+ ++insertion;
+
+ removal->count -= removeCount;
+ insertion->index += removeCount;
+ insertion->count -= removeCount;
+ } else {
+ // If there's no need to split the move simply replace its moveId
+ // with that of the translated move.
+ removal->moveId = translatedRemoval.moveId;
+ insertion->moveId = translatedRemoval.moveId;
+ }
+ } else {
+ // If the current range doesn't have prepend flags then insert a new range
+ // with list indexes from the corresponding insert location. The MoveFlag
+ // is to notify listItemsInserted that it can skip evaluation of that range.
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ it->index += offset;
+ it->count -= offset;
+ it.incrementIndexes(offset);
+ }
+ if (it->previous != &m_ranges
+ && it->previous->list == it->list
+ && it->end() == insertion->index
+ && it->previous->flags == (it->flags | MovedFlag)) {
+ it->previous->count += removeCount;
+ } else {
+ *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next;
+ }
+ // Clear the changed flags as the item hasn't been removed.
+ translatedRemoval.flags = 0;
+ removeFlags = 0;
+ }
+ } else if (it->inCache()) {
+ // If not moving and the current range has the cache flag, insert a new range
+ // with just the cache flag set to retain caching information for the removed
+ // range.
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ it->index += offset;
+ it->count -= offset;
+ it.incrementIndexes(offset);
+ }
+ if (it->previous != &m_ranges
+ && it->previous->list == it->list
+ && it->previous->flags == CacheFlag) {
+ it->previous->count += removeCount;
+ } else {
+ *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next;
+ }
+ it.index[Cache] += removeCount;
+ }
+ if (removeFlags & GroupMask)
+ translatedRemovals->append(translatedRemoval);
+ m_end.decrementIndexes(removeCount, removeFlags);
+ if (it->count == 0 && !it->append()) {
+ // Erase empty non-append ranges.
+ *it = erase(*it)->previous;
+ removed = true;
+ } else if (relativeIndex <= 0) {
+ // If the remove started before the current range move the start index of
+ // the range to the remove index.
+ it->index = removal->index;
+ }
+ } else if (relativeIndex < 0) {
+ // If the remove was before the current range decrement the start index by the
+ // number of items removed.
+ it->index -= itemsRemoved;
+
+ if (it->previous != &m_ranges
+ && it->previous->list == it->list
+ && it->previous->end() == it->index
+ && it->previous->flags == (it->flags & ~AppendFlag)) {
+ // Compress ranges made continuous by the removal of separating ranges.
+ it.decrementIndexes(it->previous->count);
+ it->previous->count += it->count;
+ it->previous->flags = it->flags;
+ *it = erase(*it)->previous;
+ }
+ }
+ }
+ if (it->flags == CacheFlag && it->next->flags == CacheFlag && it->next->list == it->list) {
+ // Compress consecutive cache only ranges.
+ it.index[Cache] += it->next->count;
+ it->count += it->next->count;
+ erase(it->next);
+ } else if (!removed) {
+ it.incrementIndexes(it->count);
+ }
+ }
+ m_cacheIt = m_end;
+ QT_QML_VERIFY_LISTCOMPOSITOR
+}
+
+
+/*!
+ Updates the contents of a compositor when \a count items are removed from a \a list at
+ \a index.
+
+ Ranges that intersect the specified range are removed from the compositor and the indexes of
+ ranges after index + count are updated.
+
+ The \a translatedRemovals list is populated with remove notifications for the affected
+ groups.
+*/
+
+
+void QQmlListCompositor::listItemsRemoved(
+ void *list, int index, int count, QVector<Remove> *translatedRemovals)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count >= 0);
+
+ QVector<QQmlChangeSet::Remove> removals;
+ removals.append(QQmlChangeSet::Remove(index, count));
+ listItemsRemoved(translatedRemovals, list, &removals, 0, 0);
+}
+
+/*!
+ Updates the contents of a compositor when \a count items are removed from a \a list at
+ \a index.
+
+ Ranges that intersect the specified range are removed from the compositor and the indexes of
+ ranges after index + count are updated.
+
+ The \a translatedRemovals and translatedInserts lists are populated with move
+ notifications for the affected groups.
+*/
+
+void QQmlListCompositor::listItemsMoved(
+ void *list,
+ int from,
+ int to,
+ int count,
+ QVector<Remove> *translatedRemovals,
+ QVector<Insert> *translatedInsertions)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << from << to << count)
+ Q_ASSERT(count >= 0);
+
+ QVector<QQmlChangeSet::Remove> removals;
+ QVector<QQmlChangeSet::Insert> insertions;
+ QVector<MovedFlags> movedFlags;
+ removals.append(QQmlChangeSet::Remove(from, count, 0));
+ insertions.append(QQmlChangeSet::Insert(to, count, 0));
+
+ listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags);
+ listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
+}
+
+void QQmlListCompositor::listItemsChanged(
+ QVector<Change> *translatedChanges,
+ void *list,
+ const QVector<QQmlChangeSet::Change> &changes)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << changes)
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ it.incrementIndexes(it->count);
+ continue;
+ } else if (!it->inGroup()) {
+ continue;
+ }
+ foreach (const QQmlChangeSet::Change &change, changes) {
+ const int offset = change.index - it->index;
+ if (offset + change.count > 0 && offset < it->count) {
+ const int changeOffset = qMax(0, offset);
+ const int changeCount = qMin(it->count, offset + change.count) - changeOffset;
+
+ Change translatedChange(it, changeCount, it->flags);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedChange.index[i] += changeOffset;
+ }
+ translatedChanges->append(translatedChange);
+ }
+ }
+ it.incrementIndexes(it->count);
+ }
+}
+
+
+/*!
+ Translates the positions of \a count changed items at \a index in a \a list.
+
+ The \a translatedChanges list is populated with change notifications for the
+ affected groups.
+*/
+
+void QQmlListCompositor::listItemsChanged(
+ void *list, int index, int count, QVector<Change> *translatedChanges)
+{
+ QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count >= 0);
+ QVector<QQmlChangeSet::Change> changes;
+ changes.append(QQmlChangeSet::Change(index, count));
+ listItemsChanged(translatedChanges, list, changes);
+}
+
+void QQmlListCompositor::transition(
+ Group from,
+ Group to,
+ QVector<QQmlChangeSet::Remove> *removes,
+ QVector<QQmlChangeSet::Insert> *inserts)
+{
+ int removeCount = 0;
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it == from && it != to) {
+ removes->append(QQmlChangeSet::Remove(it.index[from]- removeCount, it->count));
+ removeCount += it->count;
+ } else if (it != from && it == to) {
+ inserts->append(QQmlChangeSet::Insert(it.index[to], it->count));
+ }
+ it.incrementIndexes(it->count);
+ }
+}
+
+/*!
+ \internal
+ Writes the name of \a group to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group)
+{
+ switch (group) {
+ case QQmlListCompositor::Cache: return debug << "Cache";
+ case QQmlListCompositor::Default: return debug << "Default";
+ default: return (debug.nospace() << "Group" << int(group)).space();
+ }
+
+}
+
+/*!
+ \internal
+ Writes the contents of \a range to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range)
+{
+ (debug.nospace()
+ << "Range("
+ << range.list) << ' '
+ << range.index << ' '
+ << range.count << ' '
+ << (range.isUnresolved() ? 'U' : '0')
+ << (range.append() ? 'A' : '0')
+ << (range.prepend() ? 'P' : '0');
+ for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
+ debug << (range.inGroup(i) ? '1' : '0');
+ return (debug
+ << (range.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
+ << (range.inGroup(QQmlListCompositor::Cache) ? 'C' : '0'));
+}
+
+static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
+{
+ for (int i = count - 1; i >= 0; --i)
+ debug << indexes[i];
+}
+
+/*!
+ \internal
+ Writes the contents of \a it to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it)
+{
+ (debug.nospace() << "iterator(" << it.group).space() << "offset:" << it.offset;
+ qt_print_indexes(debug, it.groupCount, it.index);
+ return ((debug << **it).nospace() << ')').space();
+}
+
+static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
+{
+ debug.nospace() << name << '(' << change.moveId << ' ' << change.count << ' ';
+ for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
+ debug << (change.inGroup(i) ? '1' : '0');
+ debug << (change.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
+ << (change.inGroup(QQmlListCompositor::Cache) ? 'C' : '0');
+ int i = QQmlListCompositor::MaximumGroupCount - 1;
+ for (; i >= 0 && !change.inGroup(i); --i) {}
+ for (; i >= 0; --i)
+ debug << ' ' << change.index[i];
+ return (debug << ')').maybeSpace();
+}
+
+/*!
+ \internal
+ Writes the contents of \a change to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change)
+{
+ return qt_print_change(debug, "Change", change);
+}
+
+/*!
+ \internal
+ Writes the contents of \a remove to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove)
+{
+ return qt_print_change(debug, "Remove", remove);
+}
+
+/*!
+ \internal
+ Writes the contents of \a insert to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert)
+{
+ return qt_print_change(debug, "Insert", insert);
+}
+
+/*!
+ \internal
+ Writes the contents of \a list to \a debug.
+*/
+
+QDebug operator <<(QDebug debug, const QQmlListCompositor &list)
+{
+ int indexes[QQmlListCompositor::MaximumGroupCount];
+ for (int i = 0; i < QQmlListCompositor::MaximumGroupCount; ++i)
+ indexes[i] = 0;
+ debug.nospace() << "QQmlListCompositor(";
+ qt_print_indexes(debug, list.m_groupCount, list.m_end.index);
+ for (QQmlListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) {
+ (debug << '\n').space();
+ qt_print_indexes(debug, list.m_groupCount, indexes);
+ debug << ' ' << *range;
+
+ for (int i = 0; i < list.m_groupCount; ++i) {
+ if (range->inGroup(i))
+ indexes[i] += range->count;
+ }
+ }
+ return (debug << ')').maybeSpace();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/util/qqmllistcompositor_p.h b/src/qml/util/qqmllistcompositor_p.h
new file mode 100644
index 0000000000..5d87051582
--- /dev/null
+++ b/src/qml/util/qqmllistcompositor_p.h
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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
+** 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, 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLLISTCOMPOSITOR_P_H
+#define QQMLLISTCOMPOSITOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qvector.h>
+
+#include <private/qqmlchangeset_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQmlListCompositor
+{
+public:
+ enum { MinimumGroupCount = 3, MaximumGroupCount = 11 };
+
+ enum Group
+ {
+ Cache = 0,
+ Default = 1,
+ Persisted = 2
+ };
+
+ enum Flag
+ {
+ CacheFlag = 1 << Cache,
+ DefaultFlag = 1 << Default,
+ PersistedFlag = 1 << Persisted,
+ PrependFlag = 0x10000000,
+ AppendFlag = 0x20000000,
+ UnresolvedFlag = 0x40000000,
+ MovedFlag = 0x80000000,
+ GroupMask = ~(PrependFlag | AppendFlag | UnresolvedFlag | MovedFlag | CacheFlag)
+ };
+
+ class Range
+ {
+ public:
+ Range() : next(this), previous(this), list(0), index(0), count(0), flags(0) {}
+ Range(Range *next, void *list, int index, int count, uint flags)
+ : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
+ next->previous = this; previous->next = this; }
+
+ Range *next;
+ Range *previous;
+ void *list;
+ int index;
+ int count;
+ uint flags;
+
+ inline int start() const { return index; }
+ inline int end() const { return index + count; }
+
+ inline int groups() const { return flags & GroupMask; }
+
+ inline bool inGroup() const { return flags & GroupMask; }
+ inline bool inCache() const { return flags & CacheFlag; }
+ inline bool inGroup(int group) const { return flags & (1 << group); }
+ inline bool isUnresolved() const { return flags & UnresolvedFlag; }
+
+ inline bool prepend() const { return flags & PrependFlag; }
+ inline bool append() const { return flags & AppendFlag; }
+ };
+
+ class Q_AUTOTEST_EXPORT iterator
+ {
+ public:
+ inline iterator();
+ inline iterator(const iterator &it);
+ inline iterator(Range *range, int offset, Group group, int groupCount);
+ inline ~iterator() {}
+
+ bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; }
+ bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; }
+
+ bool operator ==(Group group) const { return range->flags & (1 << group); }
+ bool operator !=(Group group) const { return !(range->flags & (1 << group)); }
+
+ Range *&operator *() { return range; }
+ Range * const &operator *() const { return range; }
+ Range *operator ->() { return range; }
+ const Range *operator ->() const { return range; }
+
+ iterator &operator +=(int difference);
+
+ template<typename T> T *list() const { return static_cast<T *>(range->list); }
+ int modelIndex() const { return range->index + offset; }
+
+ void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); }
+ void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); }
+
+ inline void incrementIndexes(int difference, uint flags);
+ inline void decrementIndexes(int difference, uint flags);
+
+ void setGroup(Group g) { group = g; groupFlag = 1 << g; }
+
+ Range *range;
+ int offset;
+ Group group;
+ int groupFlag;
+ int groupCount;
+ union {
+ struct {
+ int cacheIndex;
+ };
+ int index[MaximumGroupCount];
+ };
+ };
+
+ class Q_AUTOTEST_EXPORT insert_iterator : public iterator
+ {
+ public:
+ inline insert_iterator() {}
+ inline insert_iterator(const iterator &it) : iterator(it) {}
+ inline insert_iterator(Range *, int, Group, int);
+ inline ~insert_iterator() {}
+
+ insert_iterator &operator +=(int difference);
+ };
+
+ struct Change
+ {
+ inline Change() {}
+ inline Change(iterator it, int count, uint flags, int moveId = -1);
+ int count;
+ uint flags;
+ int moveId;
+ union {
+ struct {
+ int cacheIndex;
+ };
+ int index[MaximumGroupCount];
+ };
+
+ inline bool isMove() const { return moveId >= 0; }
+ inline bool inCache() const { return flags & CacheFlag; }
+ inline bool inGroup() const { return flags & GroupMask; }
+ inline bool inGroup(int group) const { return flags & (CacheFlag << group); }
+
+ inline int groups() const { return flags & GroupMask; }
+ };
+
+ struct Insert : public Change
+ {
+ Insert() {}
+ Insert(iterator it, int count, uint flags, int moveId = -1)
+ : Change(it, count, flags, moveId) {}
+ };
+
+ struct Remove : public Change
+ {
+ Remove() {}
+ Remove(iterator it, int count, uint flags, int moveId = -1)
+ : Change(it, count, flags, moveId) {}
+ };
+
+ QQmlListCompositor();
+ ~QQmlListCompositor();
+
+ int defaultGroups() const { return m_defaultFlags & ~PrependFlag; }
+ void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; }
+ void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); }
+ void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); }
+ void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; }
+ void setGroupCount(int count);
+
+ int count(Group group) const;
+ iterator find(Group group, int index);
+ iterator find(Group group, int index) const;
+ insert_iterator findInsertPosition(Group group, int index);
+
+ const iterator &end() { return m_end; }
+
+ void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
+ void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
+ iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
+
+ void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = 0);
+ void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = 0);
+ void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = 0) {
+ setFlags(fromGroup, from, count, fromGroup, flags, inserts); }
+ void setFlags(iterator from, int count, uint flags, QVector<Insert> *inserts = 0) {
+ setFlags(from, count, from.group, flags, inserts); }
+
+ void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
+ void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
+ void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = 0) {
+ clearFlags(fromGroup, from, count, fromGroup, flags, removals); }
+ void clearFlags(iterator from, int count, uint flags, QVector<Remove> *removals = 0) {
+ clearFlags(from, count, from.group, flags, removals); }
+
+ bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const;
+
+ void move(
+ Group fromGroup,
+ int from,
+ Group toGroup,
+ int to,
+ int count,
+ Group group,
+ QVector<Remove> *removals = 0,
+ QVector<Insert> *inserts = 0);
+ void clear();
+
+ void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
+ void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals);
+ void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts);
+ void listItemsChanged(void *list, int index, int count, QVector<Change> *changes);
+
+ void transition(
+ Group from,
+ Group to,
+ QVector<QQmlChangeSet::Remove> *removes,
+ QVector<QQmlChangeSet::Insert> *inserts);
+
+private:
+ Range m_ranges;
+ iterator m_end;
+ iterator m_cacheIt;
+ int m_groupCount;
+ int m_defaultFlags;
+ int m_removeFlags;
+ int m_moveId;
+
+ inline Range *insert(Range *before, void *list, int index, int count, uint flags);
+ inline Range *erase(Range *range);
+
+ struct MovedFlags
+ {
+ MovedFlags() {}
+ MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {}
+
+ int moveId;
+ uint flags;
+ };
+
+ void listItemsRemoved(
+ QVector<Remove> *translatedRemovals,
+ void *list,
+ QVector<QQmlChangeSet::Remove> *removals,
+ QVector<QQmlChangeSet::Insert> *insertions = 0,
+ QVector<MovedFlags> *movedFlags = 0);
+ void listItemsInserted(
+ QVector<Insert> *translatedInsertions,
+ void *list,
+ const QVector<QQmlChangeSet::Insert> &insertions,
+ const QVector<MovedFlags> *movedFlags = 0);
+ void listItemsChanged(
+ QVector<Change> *translatedChanges,
+ void *list,
+ const QVector<QQmlChangeSet::Change> &changes);
+
+ friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
+};
+
+Q_DECLARE_TYPEINFO(QQmlListCompositor::Change, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQmlListCompositor::Remove, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQmlListCompositor::Insert, Q_PRIMITIVE_TYPE);
+
+inline QQmlListCompositor::iterator::iterator()
+ : range(0), offset(0), group(Default), groupCount(0) {}
+inline QQmlListCompositor::iterator::iterator(const iterator &it)
+ : range(it.range)
+ , offset(it.offset)
+ , group(it.group)
+ , groupFlag(it.groupFlag)
+ , groupCount(it.groupCount)
+{
+ for (int i = 0; i < groupCount; ++i)
+ index[i] = it.index[i];
+}
+
+inline QQmlListCompositor::iterator::iterator(
+ Range *range, int offset, Group group, int groupCount)
+ : range(range)
+ , offset(offset)
+ , group(group)
+ , groupFlag(1 << group)
+ , groupCount(groupCount)
+{
+ for (int i = 0; i < groupCount; ++i)
+ index[i] = 0;
+}
+
+inline void QQmlListCompositor::iterator::incrementIndexes(int difference, uint flags)
+{
+ for (int i = 0; i < groupCount; ++i) {
+ if (flags & (1 << i))
+ index[i] += difference;
+ }
+}
+
+inline void QQmlListCompositor::iterator::decrementIndexes(int difference, uint flags)
+{
+ for (int i = 0; i < groupCount; ++i) {
+ if (flags & (1 << i))
+ index[i] -= difference;
+ }
+}
+
+inline QQmlListCompositor::insert_iterator::insert_iterator(
+ Range *range, int offset, Group group, int groupCount)
+ : iterator(range, offset, group, groupCount) {}
+
+inline QQmlListCompositor::Change::Change(iterator it, int count, uint flags, int moveId)
+ : count(count), flags(flags), moveId(moveId)
+{
+ for (int i = 0; i < MaximumGroupCount; ++i)
+ index[i] = it.index[i];
+}
+
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQmlListCompositor &list);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index cd3516a907..f963e9074a 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -49,8 +49,6 @@
#include <QtCore/QStringList>
#include <QtCore/QVariant>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
@@ -83,8 +81,8 @@ protected:
virtual QVariant updateValue(const QString &key, const QVariant &input);
template<class DerivedType>
- QQmlPropertyMap(DerivedType *derived, QObject *parent)
- : QObject(*allocatePrivate(), parent)
+ QQmlPropertyMap(DerivedType *derived, QObject *parentObj)
+ : QObject(*allocatePrivate(), parentObj)
{
Q_UNUSED(derived)
init(&DerivedType::staticMetaObject);
@@ -100,6 +98,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif
diff --git a/src/qml/util/util.pri b/src/qml/util/util.pri
index 3b121ba3cb..a9c5ffe9b7 100644
--- a/src/qml/util/util.pri
+++ b/src/qml/util/util.pri
@@ -1,5 +1,13 @@
SOURCES += \
+ $$PWD/qqmlchangeset.cpp \
+ $$PWD/qqmllistaccessor.cpp \
+ $$PWD/qqmllistcompositor.cpp \
+ $$PWD/qqmladaptormodel.cpp \
$$PWD/qqmlpropertymap.cpp
HEADERS += \
+ $$PWD/qqmlchangeset_p.h \
+ $$PWD/qqmllistaccessor_p.h \
+ $$PWD/qqmllistcompositor_p.h \
+ $$PWD/qqmladaptormodel_p.h \
$$PWD/qqmlpropertymap.h