aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-03-27 16:43:26 +0200
committerKent Hansen <kent.hansen@nokia.com>2012-03-27 16:56:14 +0200
commit24fb8dc27eddfdd62bd2c3a6e863cbf433762cd6 (patch)
tree917eff8c50fe4699547b9de852ee53257c1585cf /src/qml
parent3e6a8eca00334df344a45f09afbcf8fd8e2b7c54 (diff)
parentffdbf216dc80b3d781307bb6b4b7150281c874a3 (diff)
Merge master into api_changes
Conflicts: src/qml/debugger/qqmlenginedebugservice.cpp src/qml/debugger/qqmlprofilerservice_p.h src/qml/qml/qqmlboundsignal.cpp src/qml/qml/qqmlpropertycache.cpp src/quick/util/qquickimageprovider.cpp Change-Id: I0609aa5ed54c7769f1e2773a96a7cd43a69f133c
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/debugger/qqmldebug.h8
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp52
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h33
-rw-r--r--src/qml/qml/qqml.h19
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp122
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h58
-rw-r--r--src/qml/qml/qqmlcomponent.cpp5
-rw-r--r--src/qml/qml/qqmlcontext.h1
-rw-r--r--src/qml/qml/qqmldata_p.h4
-rw-r--r--src/qml/qml/qqmlengine.cpp21
-rw-r--r--src/qml/qml/qqmlerror.cpp5
-rw-r--r--src/qml/qml/qqmlexpression.cpp5
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp11
-rw-r--r--src/qml/qml/qqmllist.cpp9
-rw-r--r--src/qml/qml/qqmlmetatype.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype_p.h12
-rw-r--r--src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp7
-rw-r--r--src/qml/qml/qqmlparserstatus.cpp5
-rw-r--r--src/qml/qml/qqmlprivate.h1
-rw-r--r--src/qml/qml/qqmlproperty.cpp51
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp24
-rw-r--r--src/qml/qml/qqmlvme.cpp9
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp20
23 files changed, 352 insertions, 134 deletions
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index 8036032150..318e0bd71f 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -51,12 +51,14 @@ QT_BEGIN_NAMESPACE
struct Q_QML_EXPORT QQmlDebuggingEnabler
{
- QQmlDebuggingEnabler();
+ QQmlDebuggingEnabler(bool printWarning = true);
};
// Execute code in constructor before first QQmlEngine is instantiated
-#if defined(QT_DECLARATIVE_DEBUG)
-static QQmlDebuggingEnabler qmlEnableDebuggingHelper;
+#if defined(QT_DECLARATIVE_DEBUG_NO_WARNING)
+static QQmlDebuggingEnabler qmlEnableDebuggingHelper(false);
+#elif defined(QT_DECLARATIVE_DEBUG)
+static QQmlDebuggingEnabler qmlEnableDebuggingHelper(true);
#endif
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp
index 7f0bf7ca33..cd09b69e48 100644
--- a/src/qml/debugger/qqmlenginedebugservice.cpp
+++ b/src/qml/debugger/qqmlenginedebugservice.cpp
@@ -223,7 +223,7 @@ void QQmlEngineDebugService::buildObjectDump(QDataStream &message,
int childrenCount = children.count();
for (int ii = 0; ii < children.count(); ++ii) {
- if (qobject_cast<QQmlContext*>(children[ii]) || QQmlBoundSignal::cast(children[ii]))
+ if (qobject_cast<QQmlContext*>(children[ii]))
--childrenCount;
}
@@ -235,19 +235,41 @@ void QQmlEngineDebugService::buildObjectDump(QDataStream &message,
QObject *child = children.at(ii);
if (qobject_cast<QQmlContext*>(child))
continue;
- QQmlBoundSignal *signal = QQmlBoundSignal::cast(child);
- if (signal) {
- if (!dumpProperties)
+ if (recur)
+ buildObjectDump(message, child, recur, dumpProperties);
+ else
+ message << objectData(child);
+ }
+
+ if (!dumpProperties) {
+ message << 0;
+ return;
+ }
+
+ QList<int> propertyIndexes;
+ for (int ii = 0; ii < object->metaObject()->propertyCount(); ++ii) {
+ if (object->metaObject()->property(ii).isScriptable())
+ propertyIndexes << ii;
+ }
+
+ QQmlData *ddata = QQmlData::get(object);
+ if (ddata && ddata->signalHandlers) {
+ QQmlAbstractBoundSignal *signalHandler = ddata->signalHandlers;
+
+ while (signalHandler) {
+ if (!dumpProperties) {
+ signalHandler = signalHandler->m_nextSignal;
continue;
+ }
QQmlObjectProperty prop;
prop.type = QQmlObjectProperty::SignalProperty;
prop.hasNotifySignal = false;
- QQmlExpression *expr = signal->expression();
+ QQmlExpression *expr = signalHandler->expression();
if (expr) {
prop.value = expr->expression();
QObject *scope = expr->scopeObject();
if (scope) {
- QString methodName = QString::fromLatin1(scope->metaObject()->method(signal->index()).name());
+ QString methodName = QString::fromLatin1(scope->metaObject()->method(signalHandler->index()).name());
if (!methodName.isEmpty()) {
prop.name = QLatin1String("on") + methodName[0].toUpper()
+ methodName.mid(1);
@@ -255,23 +277,9 @@ void QQmlEngineDebugService::buildObjectDump(QDataStream &message,
}
}
fakeProperties << prop;
- } else {
- if (recur)
- buildObjectDump(message, child, recur, dumpProperties);
- else
- message << objectData(child);
- }
- }
- if (!dumpProperties) {
- message << 0;
- return;
- }
-
- QList<int> propertyIndexes;
- for (int ii = 0; ii < object->metaObject()->propertyCount(); ++ii) {
- if (object->metaObject()->property(ii).isScriptable())
- propertyIndexes << ii;
+ signalHandler = signalHandler->m_nextSignal;
+ }
}
message << propertyIndexes.size() + fakeProperties.count();
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index 2b4cafb615..2e351792cc 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -205,16 +205,16 @@ struct QQmlHandlingSignalProfiler {
{
enabled = QQmlProfilerService::instance
? QQmlProfilerService::instance->profilingEnabled() : false;
- if (enabled) {
- QQmlProfilerService *service = QQmlProfilerService::instance;
- service->startRange(QQmlProfilerService::HandlingSignal);
- service->rangeData(QQmlProfilerService::HandlingSignal,
- QString::fromLatin1(signal.methodSignature()) + QLatin1String(": ")
- + expression->expression());
- service->rangeLocation(QQmlProfilerService::HandlingSignal,
- expression->sourceFile(), expression->lineNumber(),
- expression->columnNumber());
- }
+ if (enabled)
+ init(signal, expression);
+ }
+
+ QQmlHandlingSignalProfiler(QObject *object, int index, QQmlExpression *expression)
+ {
+ enabled = QQmlProfilerService::instance
+ ? QQmlProfilerService::instance->profilingEnabled() : false;
+ if (enabled)
+ init(object->metaObject()->method(index), expression);
}
~QQmlHandlingSignalProfiler()
@@ -224,6 +224,19 @@ struct QQmlHandlingSignalProfiler {
}
bool enabled;
+
+private:
+ void init(const QMetaMethod &signal, QQmlExpression *expression)
+ {
+ QQmlProfilerService *service = QQmlProfilerService::instance;
+ service->startRange(QQmlProfilerService::HandlingSignal);
+ service->rangeData(QQmlProfilerService::HandlingSignal,
+ QString::fromLatin1(signal.methodSignature()) + QLatin1String(": ")
+ + expression->expression());
+ service->rangeLocation(QQmlProfilerService::HandlingSignal,
+ expression->sourceFile(), expression->lineNumber(),
+ expression->columnNumber());
+ }
};
struct QQmlObjectCreatingProfiler {
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 32da2c616e..5b500e0814 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -421,7 +421,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
uri, versionMajor, versionMinor,
- callback, 0
+ callback, 0, 0
};
return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api);
@@ -435,7 +435,22 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
uri, versionMajor, versionMinor,
- 0, callback
+ 0, callback, 0 // unknown QObject instance type
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api);
+}
+
+template <typename T>
+inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
+ QObject *(*callback)(QQmlEngine *, QJSEngine *))
+{
+ QQmlPrivate::RegisterModuleApi api = {
+ 1,
+
+ uri, versionMajor, versionMinor,
+
+ 0, callback, &T::staticMetaObject
};
return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api);
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index f7d0c00a5c..3a3bf403e6 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -55,6 +55,8 @@
#include <QtCore/qstringbuilder.h>
#include <QtCore/qdebug.h>
+Q_DECLARE_METATYPE(QJSValue)
+
QT_BEGIN_NAMESPACE
class QQmlBoundSignalParameters : public QObject
@@ -87,42 +89,45 @@ private:
static int evaluateIdx = -1;
-QQmlAbstractBoundSignal::QQmlAbstractBoundSignal(QObject *parent)
-: QObject(parent)
+QQmlAbstractBoundSignal::QQmlAbstractBoundSignal()
+: m_prevSignal(0), m_nextSignal(0)
{
}
QQmlAbstractBoundSignal::~QQmlAbstractBoundSignal()
{
+ if (m_prevSignal) {
+ *m_prevSignal = m_nextSignal;
+ if (m_nextSignal) m_nextSignal->m_prevSignal = m_prevSignal;
+ m_prevSignal = 0;
+ m_nextSignal = 0;
+ }
}
-QQmlBoundSignal::QQmlBoundSignal(QObject *scope, const QMetaMethod &signal,
- QObject *parent)
-: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0)
+void QQmlAbstractBoundSignal::addToObject()
{
- // This is thread safe. Although it may be updated by two threads, they
- // will both set it to the same value - so the worst thing that can happen
- // is that they both do the work to figure it out. Boo hoo.
- if (evaluateIdx == -1) evaluateIdx = metaObject()->methodCount();
+ Q_ASSERT(!m_prevSignal);
+ QObject *obj = object();
+ Q_ASSERT(obj);
- QQml_setParent_noEvent(this, parent);
- QQmlPropertyPrivate::connect(scope, m_signal.methodIndex(), this, evaluateIdx);
+ QQmlData *data = QQmlData::get(obj, true);
+
+ m_nextSignal = data->signalHandlers;
+ if (m_nextSignal) m_nextSignal->m_prevSignal = &m_nextSignal;
+ m_prevSignal = &data->signalHandlers;
+ data->signalHandlers = this;
}
-QQmlBoundSignal::QQmlBoundSignal(QQmlContext *ctxt, const QString &val,
- QObject *scope, const QMetaMethod &signal,
- QObject *parent)
-: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0)
+QQmlBoundSignal::QQmlBoundSignal(QObject *scope, const QMetaMethod &signal,
+ QObject *owner)
+: m_expression(0), m_signal(signal), m_paramsValid(false), m_isEvaluating(false), m_params(0), m_owner(owner)
{
// This is thread safe. Although it may be updated by two threads, they
// will both set it to the same value - so the worst thing that can happen
// is that they both do the work to figure it out. Boo hoo.
if (evaluateIdx == -1) evaluateIdx = metaObject()->methodCount();
- QQml_setParent_noEvent(this, parent);
QQmlPropertyPrivate::connect(scope, m_signal.methodIndex(), this, evaluateIdx);
-
- m_expression = new QQmlExpression(ctxt, scope, val);
}
QQmlBoundSignal::~QQmlBoundSignal()
@@ -159,12 +164,6 @@ QQmlExpression *QQmlBoundSignal::setExpression(QQmlExpression *e)
return rv;
}
-QQmlBoundSignal *QQmlBoundSignal::cast(QObject *o)
-{
- QQmlAbstractBoundSignal *s = qobject_cast<QQmlAbstractBoundSignal*>(o);
- return static_cast<QQmlBoundSignal *>(s);
-}
-
int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
{
if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) {
@@ -227,10 +226,14 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method,
prop.setWritable(false);
} else {
QByteArray propType = type;
- if ((QMetaType::typeFlags(t) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration) {
+ QMetaType::TypeFlags flags = QMetaType::typeFlags(t);
+ if (flags & QMetaType::IsEnumeration) {
t = QVariant::Int;
propType = "int";
- } else if (t == QMetaType::UnknownType) {
+ } else if (t == QMetaType::UnknownType ||
+ (t >= int(QMetaType::User) && !(flags & QMetaType::PointerToQObject) &&
+ t != qMetaTypeId<QJSValue>())) {
+ //the UserType clause is to catch registered QFlags
QByteArray scope;
QByteArray name;
int scopeIdx = propType.lastIndexOf("::");
@@ -244,7 +247,7 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method,
if (scope == "Qt")
meta = &QObject::staticQtMetaObject;
else
- meta = parent->parent()->metaObject(); //### assumes parent->parent()
+ meta = static_cast<QQmlBoundSignal*>(parent)->object()->metaObject();
for (int i = meta->enumeratorCount() - 1; i >= 0; --i) {
QMetaEnum m = meta->enumerator(i);
if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) {
@@ -297,6 +300,71 @@ int QQmlBoundSignalParameters::metaCall(QMetaObject::Call c, int id, void **a)
}
}
+////////////////////////////////////////////////////////////////////////
+
+QQmlBoundSignalNoParams::QQmlBoundSignalNoParams(QObject *scope, const QMetaMethod &signal,
+ QObject *owner)
+: m_expression(0), m_owner(owner), m_index(signal.methodIndex()), m_isEvaluating(false)
+{
+ callback = &subscriptionCallback;
+ QQmlNotifierEndpoint::connect(scope, m_index);
+}
+
+QQmlBoundSignalNoParams::~QQmlBoundSignalNoParams()
+{
+ delete m_expression;
+ m_expression = 0;
+}
+
+int QQmlBoundSignalNoParams::index() const
+{
+ return m_index;
+}
+
+/*!
+ Returns the signal expression.
+*/
+QQmlExpression *QQmlBoundSignalNoParams::expression() const
+{
+ return m_expression;
+}
+
+/*!
+ Sets the signal expression to \a e. Returns the current signal expression,
+ or null if there is no signal expression.
+
+ The QQmlBoundSignalNoParams instance takes ownership of \a e. The caller is
+ assumes ownership of the returned QQmlExpression.
+*/
+QQmlExpression *QQmlBoundSignalNoParams::setExpression(QQmlExpression *e)
+{
+ QQmlExpression *rv = m_expression;
+ m_expression = e;
+ if (m_expression) m_expression->setNotifyOnValueChanged(false);
+ return rv;
+}
+
+void QQmlBoundSignalNoParams::subscriptionCallback(QQmlNotifierEndpoint *e)
+{
+ QQmlBoundSignalNoParams *s = static_cast<QQmlBoundSignalNoParams*>(e);
+ if (!s->m_expression)
+ return;
+
+ if (QQmlDebugService::isDebuggingEnabled())
+ QV8DebugService::instance()->signalEmitted(QString::fromAscii(s->m_owner->metaObject()->method(s->m_index).methodSignature()));
+
+ QQmlHandlingSignalProfiler prof(s->m_owner, s->m_index, s->m_expression);
+
+ s->m_isEvaluating = true;
+
+ if (s->m_expression && s->m_expression->engine()) {
+ QQmlExpressionPrivate::get(s->m_expression)->value();
+ if (s->m_expression && s->m_expression->hasError())
+ QQmlEnginePrivate::warning(s->m_expression->engine(), s->m_expression->error());
+ }
+ s->m_isEvaluating = false;
+}
+
QT_END_NAMESPACE
#include <qqmlboundsignal.moc>
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index 11386159cb..5fc8c3522f 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -57,36 +57,48 @@
#include <QtCore/qmetaobject.h>
+#include <private/qqmlnotifier_p.h>
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
-class Q_QML_EXPORT QQmlAbstractBoundSignal : public QObject
+class Q_QML_EXPORT QQmlAbstractBoundSignal
{
- Q_OBJECT
public:
- QQmlAbstractBoundSignal(QObject *parent = 0);
- virtual ~QQmlAbstractBoundSignal() = 0;
+ QQmlAbstractBoundSignal();
+ virtual ~QQmlAbstractBoundSignal();
+
+ virtual int index() const = 0;
+ virtual QQmlExpression *expression() const = 0;
+ virtual QQmlExpression *setExpression(QQmlExpression *) = 0;
+ virtual QObject *object() = 0;
+
+ void addToObject();
+
+private:
+ friend class QQmlData;
+ friend class QQmlPropertyPrivate;
+ friend class QQmlEngineDebugService;
+ QQmlAbstractBoundSignal **m_prevSignal;
+ QQmlAbstractBoundSignal *m_nextSignal;
};
class QQmlBoundSignalParameters;
-class Q_QML_EXPORT QQmlBoundSignal : public QQmlAbstractBoundSignal
+class Q_QML_EXPORT QQmlBoundSignal : public QObject,
+ public QQmlAbstractBoundSignal
{
public:
- QQmlBoundSignal(QObject *scope, const QMetaMethod &signal, QObject *parent);
- QQmlBoundSignal(QQmlContext *ctxt, const QString &val, QObject *scope,
- const QMetaMethod &signal, QObject *parent);
+ QQmlBoundSignal(QObject *scope, const QMetaMethod &signal, QObject *owner);
virtual ~QQmlBoundSignal();
int index() const;
QQmlExpression *expression() const;
QQmlExpression *setExpression(QQmlExpression *);
+ QObject *object() { return m_owner; }
bool isEvaluating() const { return m_isEvaluating; }
- static QQmlBoundSignal *cast(QObject *);
-
protected:
virtual int qt_metacall(QMetaObject::Call c, int id, void **a);
@@ -96,8 +108,34 @@ private:
bool m_paramsValid : 1;
bool m_isEvaluating : 1;
QQmlBoundSignalParameters *m_params;
+ QObject *m_owner;
};
+class Q_QML_EXPORT QQmlBoundSignalNoParams : public QQmlAbstractBoundSignal,
+ public QQmlNotifierEndpoint
+{
+public:
+ QQmlBoundSignalNoParams(QObject *scope, const QMetaMethod &signal, QObject *owner);
+ virtual ~QQmlBoundSignalNoParams();
+
+ int index() const;
+
+ QQmlExpression *expression() const;
+ QQmlExpression *setExpression(QQmlExpression *);
+ QObject *object() { return m_owner; }
+
+ static void subscriptionCallback(QQmlNotifierEndpoint *e);
+
+ bool isEvaluating() const { return m_isEvaluating; }
+
+private:
+ QQmlExpression *m_expression;
+ QObject *m_owner;
+ int m_index;
+ bool m_isEvaluating;
+};
+
+
QT_END_NAMESPACE
#endif // QQMLBOUNDSIGNAL_P_H
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 416178e3e1..7bddaadcd0 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -110,8 +110,9 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
/*!
\class QQmlComponent
- \since 4.7
+ \since 5.0
\brief The QQmlComponent class encapsulates a QML component definition.
+ \inmodule QtQml
\mainclass
Components are reusable, encapsulated QML elements with well-defined interfaces.
@@ -179,6 +180,8 @@ static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
}
\endcode
+ Note that the QtQuick 1 version is named QDeclarativeComponent.
+
\sa {Using QML Bindings in C++ Applications}, {Integrating QML Code with Existing Qt UI Code}
*/
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index f6d8aa1d3a..4b11095ec2 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -98,7 +98,6 @@ private:
friend class QQmlComponent;
friend class QQmlComponentPrivate;
friend class QQmlScriptPrivate;
- friend class QQmlBoundSignalProxy;
friend class QQmlContextData;
QQmlContext(QQmlContextData *);
QQmlContext(QQmlEngine *, bool);
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 09d1a23510..e7e001c4f2 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -63,6 +63,7 @@ template <class Key, class T> class QHash;
class QQmlGuardImpl;
class QQmlCompiledData;
class QQmlAbstractBinding;
+class QQmlAbstractBoundSignal;
class QQmlContext;
class QQmlPropertyCache;
class QQmlContextData;
@@ -79,7 +80,7 @@ public:
QQmlData()
: ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
hasTaintedV8Object(false), isQueuedForDeletion(false), notifyList(0), context(0), outerContext(0),
- bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0),
+ bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0),
lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), v8objectid(0),
propertyCache(0), guards(0), extendedData(0) {
init();
@@ -136,6 +137,7 @@ public:
QQmlContextData *outerContext;
QQmlAbstractBinding *bindings;
+ QQmlAbstractBoundSignal *signalHandlers;
// Linked list for QQmlContext::contextObjects
QQmlData *nextContextObject;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 672996085f..955c8ce414 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -69,6 +69,7 @@
#include <private/qdebugmessageservice_p.h>
#include "qqmlincubator.h"
#include <private/qv8profilerservice_p.h>
+#include <private/qqmlboundsignal_p.h>
#include <QtCore/qstandardpaths.h>
#include <QtCore/qsettings.h>
@@ -507,7 +508,8 @@ QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine()
/*!
\class QQmlEngine
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\brief The QQmlEngine class provides an environment for instantiating QML components.
\mainclass
@@ -533,6 +535,8 @@ QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine()
In this case, the Text item will be created in the engine's
\l {QQmlEngine::rootContext()}{root context}.
+ Note that the QtQuick 1 version is called QDeclarativeEngine.
+
\sa QQmlComponent QQmlContext
*/
@@ -1020,10 +1024,11 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
return qmlAttachedPropertiesObjectById(*idCache, object, create);
}
-QQmlDebuggingEnabler::QQmlDebuggingEnabler()
+QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
{
#ifndef QQML_NO_DEBUG_PROTOCOL
- if (!QQmlEnginePrivate::qml_debugging_enabled) {
+ if (!QQmlEnginePrivate::qml_debugging_enabled
+ && printWarning) {
qDebug("QML debugging is enabled. Only use this in a safe environment.");
}
QQmlEnginePrivate::qml_debugging_enabled = true;
@@ -1153,6 +1158,15 @@ void QQmlData::destroyed(QObject *object)
binding = next;
}
+ QQmlAbstractBoundSignal *signalHandler = signalHandlers;
+ while (signalHandler) {
+ QQmlAbstractBoundSignal *next = signalHandler->m_nextSignal;
+ signalHandler->m_prevSignal = 0;
+ signalHandler->m_nextSignal = 0;
+ delete signalHandler;
+ signalHandler = next;
+ }
+
if (bindingBits)
free(bindingBits);
@@ -1690,6 +1704,7 @@ QQmlEnginePrivate::moduleApiInstance(const QQmlMetaType::ModuleApi &module)
a = new QQmlMetaType::ModuleApiInstance;
a->scriptCallback = module.script;
a->qobjectCallback = module.qobject;
+ a->instanceMetaObject = module.instanceMetaObject;
moduleApiInstances.insert(module, a);
}
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 79424913f8..ce7fd01fdf 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -49,7 +49,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QQmlError
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\brief The QQmlError class encapsulates a QML error.
QQmlError includes a textual description of the error, as well
@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
^
\endcode
+ Note that the QtQuick 1 version is named QDeclarativeError
+
\sa QQuickView::errors(), QQmlComponent::errors()
*/
class QQmlErrorPrivate
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 60a0fe1c89..d760486605 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -137,7 +137,8 @@ QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object,
/*!
\class QQmlExpression
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\brief The QQmlExpression class evaluates JavaScript in a QML context.
For example, given a file \c main.qml like this:
@@ -161,6 +162,8 @@ QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object,
QQmlExpression *expr = new QQmlExpression(engine->rootContext(), myObject, "width * 2");
int result = expr->evaluate().toInt(); // result = 400
\endcode
+
+ Note that the QtQuick 1 version is called QDeclarativeExpression.
*/
/*!
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 86d9f9588d..73d74f9e21 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -44,7 +44,8 @@
QT_BEGIN_NAMESPACE
/*!
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\class QQmlExtensionPlugin
\brief The QQmlExtensionPlugin class provides an abstract base for custom QML extension plugins.
@@ -75,7 +76,7 @@ QT_BEGIN_NAMESPACE
as a new QML element. It provides the current time through \c hour and \c minute
properties, like this:
- \snippet examples/declarative/cppextensions/plugins/plugin.cpp 0
+ \snippet examples/qml/cppextensions/plugins/plugin.cpp 0
\dots
To make this class available as a QML type, create a plugin that registers
@@ -83,9 +84,9 @@ QT_BEGIN_NAMESPACE
module will be named \c com.nokia.TimeExample (as defined in the project
file further below).
- \snippet examples/declarative/cppextensions/plugins/plugin.cpp plugin
+ \snippet examples/qml/cppextensions/plugins/plugin.cpp plugin
\codeline
- \snippet examples/declarative/cppextensions/plugins/plugin.cpp export
+ \snippet examples/qml/cppextensions/plugins/plugin.cpp export
This registers the \c TimeModel class with the 1.0 version of this
plugin library, as a QML type called \c Time. The Q_ASSERT statement
@@ -121,6 +122,8 @@ QT_BEGIN_NAMESPACE
The \l {Tutorial: Writing QML extensions with C++} also contains a chapter
on creating QML plugins.
+ Note that the QtQuick 1 version is called QDeclarativeExtensionPlugin.
+
\sa QQmlEngine::importPlugin(), {How to Create Qt Plugins}
*/
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index 00fd805ee0..ad28e38a64 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -87,7 +87,7 @@ void QQmlListReferencePrivate::release()
/*!
\class QQmlListReference
-\since 4.7
+\since 5.0
\module QtQml
\brief The QQmlListReference class allows the manipulation of QQmlListProperty properties.
@@ -111,6 +111,8 @@ Attempting to add objects of the incorrect type to a list property will fail.
Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
that it does not request an out of range element using the count() method before calling at().
+
+The QtQuick 1 version of this class is named QDeclarativeListReference.
*/
/*!
@@ -306,7 +308,8 @@ int QQmlListReference::count() const
/*!
\class QQmlListProperty
-\since 4.7
+\since 5.0
+\inmodule QtQml
\brief The QQmlListProperty class allows applications to expose list-like
properties to QML.
@@ -340,6 +343,8 @@ Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
\c {Apple}, \c {Orange} and \c {Banana} all derive from.
+The QtQuick 1 version of this class is named QDeclarativeListProperty.
+
\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
\sa {Object and List Property Types}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 4af08c28bf..856f75fc16 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -908,6 +908,10 @@ int registerModuleApi(const QQmlPrivate::RegisterModuleApi &api)
import.minor = api.versionMinor;
import.script = api.scriptApi;
import.qobject = api.qobjectApi;
+ import.instanceMetaObject = (api.qobjectApi && api.version >= 1) ? api.instanceMetaObject : 0; // BC with version 0.
+
+ if (import.qobject && !import.instanceMetaObject) // BC - check import.iMO rather than api.iMO.
+ qWarning() << "qmlRegisterModuleApi(): sub-optimal: use the templated version of this function instead!";
int index = data->moduleApiCount++;
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index b715d0c8f2..03017cafab 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -115,20 +115,23 @@ public:
struct ModuleApiInstance {
ModuleApiInstance()
- : scriptCallback(0), qobjectCallback(0), qobjectApi(0) {}
+ : scriptCallback(0), qobjectCallback(0), qobjectApi(0), instanceMetaObject(0) {}
QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *);
QObject *(*qobjectCallback)(QQmlEngine *, QJSEngine *);
- QJSValue scriptApi;
QObject *qobjectApi;
+ const QMetaObject *instanceMetaObject;
+ QJSValue scriptApi;
+
};
struct ModuleApi {
inline ModuleApi();
inline bool operator==(const ModuleApi &) const;
int major;
int minor;
- QJSValue (*script)(QQmlEngine *, QJSEngine *);
QObject *(*qobject)(QQmlEngine *, QJSEngine *);
+ const QMetaObject *instanceMetaObject;
+ QJSValue (*script)(QQmlEngine *, QJSEngine *);
};
static ModuleApi moduleApi(const QString &, int, int);
static QHash<QString, QList<ModuleApi> > moduleApis();
@@ -247,8 +250,9 @@ QQmlMetaType::ModuleApi::ModuleApi()
{
major = 0;
minor = 0;
- script = 0;
qobject = 0;
+ instanceMetaObject = 0;
+ script = 0;
}
bool QQmlMetaType::ModuleApi::operator==(const ModuleApi &other) const
diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
index e5d0d708e2..4c31e557bc 100644
--- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
+++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
@@ -45,7 +45,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QQmlNetworkAccessManagerFactory
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\brief The QQmlNetworkAccessManagerFactory class creates QNetworkAccessManager instances for a QML engine.
A QML engine uses QNetworkAccessManager for all network access.
@@ -79,7 +80,9 @@ QT_BEGIN_NAMESPACE
For more information about signals and threads, see
\l {Threads and QObjects} and \l {Signals and Slots Across Threads}.
- \sa {declarative/cppextensions/networkaccessmanagerfactory}{NetworkAccessManagerFactory example}
+ The QtQuick 1 version of this class is named QDeclarativeNetworkAccessManagerFactory.
+
+ \sa {qml/cppextensions/networkaccessmanagerfactory}{NetworkAccessManagerFactory example}
*/
/*!
diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp
index d4e415a069..8468a1da00 100644
--- a/src/qml/qml/qqmlparserstatus.cpp
+++ b/src/qml/qml/qqmlparserstatus.cpp
@@ -45,7 +45,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QQmlParserStatus
- \since 4.7
+ \since 5.0
+ \inmodule QtQml
\brief The QQmlParserStatus class provides updates on the QML parser state.
QQmlParserStatus provides a mechanism for classes instantiated by
@@ -75,6 +76,8 @@ QT_BEGIN_NAMESPACE
void componentComplete();
}
\endcode
+
+ The QtQuick 1.0 version of this class is named QDeclarativeParserStatus.
*/
/*! \internal */
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index b4c6fc3a12..82da62ff45 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -246,6 +246,7 @@ namespace QQmlPrivate
QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *);
+ const QMetaObject *instanceMetaObject;
};
enum RegistrationType {
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index d3778fa5c5..f68c345f3a 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -72,7 +72,8 @@ QT_BEGIN_NAMESPACE
/*!
\class QQmlProperty
-\since 4.7
+\since 5.0
+\inmodule QtQml
\brief The QQmlProperty class abstracts accessing properties on objects created from QML.
As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect
@@ -108,6 +109,8 @@ qWarning() << "Current pixel size:" << property.read().toInt();
property.write(24);
qWarning() << "Pixel size should now be 24:" << property.read().toInt();
\endcode
+
+The QtQuick 1 version of this class was named QDeclarativeProperty.
*/
/*!
@@ -923,15 +926,17 @@ QQmlPropertyPrivate::signalExpression(const QQmlProperty &that)
if (!(that.type() & QQmlProperty::SignalProperty))
return 0;
- const QObjectList &children = that.d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
+ QQmlData *data = QQmlData::get(that.d->object);
+ if (!data)
+ return 0;
- QQmlBoundSignal *signal = QQmlBoundSignal::cast(child);
- if (signal && signal->index() == that.index())
- return signal->expression();
- }
+ QQmlAbstractBoundSignal *signalHandler = data->signalHandlers;
+
+ while (signalHandler && signalHandler->index() != that.index())
+ signalHandler = signalHandler->m_nextSignal;
+
+ if (signalHandler)
+ return signalHandler->expression();
return 0;
}
@@ -952,19 +957,27 @@ QQmlPropertyPrivate::setSignalExpression(const QQmlProperty &that,
return 0;
}
- const QObjectList &children = that.d->object->children();
-
- for (int ii = 0; ii < children.count(); ++ii) {
- QObject *child = children.at(ii);
+ QQmlData *data = QQmlData::get(that.d->object, 0 != expr);
+ if (!data)
+ return 0;
- QQmlBoundSignal *signal = QQmlBoundSignal::cast(child);
- if (signal && signal->index() == that.index())
- return signal->setExpression(expr);
- }
+ QQmlAbstractBoundSignal *signalHandler = data->signalHandlers;
+
+ while (signalHandler && signalHandler->index() != that.index())
+ signalHandler = signalHandler->m_nextSignal;
+
+ if (signalHandler)
+ return signalHandler->setExpression(expr);
if (expr) {
- QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, that.method(), that.d->object);
- return signal->setExpression(expr);
+ QQmlAbstractBoundSignal *signal = 0;
+ if (that.method().parameterTypes().count())
+ signal = new QQmlBoundSignal(that.d->object, that.method(), that.d->object);
+ else
+ signal = new QQmlBoundSignalNoParams(that.d->object, that.method(), that.d->object);
+ QQmlExpression *oldExpr = signal->setExpression(expr);
+ signal->addToObject();
+ return oldExpr;
} else {
return 0;
}
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 4a1eb79213..1e8cfb6c20 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -680,7 +680,7 @@ struct StaticQtMetaObject : public QObject
{ return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
};
-static int EnumType(const QMetaObject *metaobj, const QByteArray &str)
+static int EnumType(const QMetaObject *metaobj, const QByteArray &str, int type)
{
QByteArray scope;
QByteArray name;
@@ -701,7 +701,7 @@ static int EnumType(const QMetaObject *metaobj, const QByteArray &str)
if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope)))
return QVariant::Int;
}
- return QVariant::Invalid;
+ return type;
}
// Returns an array of the arguments for method \a index. The first entry in the array
@@ -738,12 +738,16 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration)
+ QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
+ if (flags & QMetaType::IsEnumeration)
type = QVariant::Int;
- else if (type == QMetaType::UnknownType) {
+ else if (type == QMetaType::UnknownType ||
+ (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) &&
+ type != qMetaTypeId<QJSValue>())) {
+ //the UserType clause is to catch registered QFlags
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
- type = EnumType(object->metaObject(), argTypeNames.at(ii));
+ type = EnumType(object->metaObject(), argTypeNames.at(ii), type);
}
if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
@@ -767,12 +771,16 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration)
+ QMetaType::TypeFlags flags = QMetaType::typeFlags(type);
+ if (flags & QMetaType::IsEnumeration)
type = QVariant::Int;
- else if (type == QMetaType::UnknownType) {
+ else if (type == QMetaType::UnknownType ||
+ (type >= (int)QVariant::UserType && !(flags & QMetaType::PointerToQObject) &&
+ type != qMetaTypeId<QJSValue>())) {
+ //the UserType clause is to catch registered QFlags)
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
- type = EnumType(object->metaObject(), argTypeNames.at(ii));
+ type = EnumType(object->metaObject(), argTypeNames.at(ii), type);
}
if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 352684ed5e..5412315d31 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -724,10 +724,15 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QMetaMethod signal = target->metaObject()->method(instr.signalIndex);
- QQmlBoundSignal *bs = new QQmlBoundSignal(target, signal, target);
- QQmlExpression *expr =
+ QQmlAbstractBoundSignal *bs = 0;
+ if (signal.parameterTypes().count())
+ bs = new QQmlBoundSignal(target, signal, target);
+ else
+ bs = new QQmlBoundSignalNoParams(target, signal, target);
+ QQmlExpression *expr =
new QQmlExpression(CTXT, context, DATAS.at(instr.value), true, COMP->name, instr.line, instr.column, *new QQmlExpressionPrivate);
bs->setExpression(expr);
+ bs->addToObject();
QML_END_INSTR(StoreSignal)
QML_BEGIN_INSTR(StoreImportedScript)
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index ea4d1afbbc..453120c6c7 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -428,18 +428,18 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
if (r.isValid()) {
if (r.type) {
_expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column);
- } /*else if (r.importNamespace) {
+ } else if (r.importNamespace) {
QQmlMetaType::ModuleApiInstance *moduleApi = m_expression->importCache->moduleApi(r.importNamespace);
- if (moduleApi) {
- if (moduleApi->qobjectCallback) {
- moduleApi->qobjectApi = moduleApi->qobjectCallback(QQmlEnginePrivate::get(m_engine), QQmlEnginePrivate::get(m_engine));
- moduleApi->qobjectCallback = 0;
- moduleApi->scriptCallback = 0;
- }
- if (moduleApi->qobjectApi)
- _expr.code = _block->MODULE_OBJECT(name, moduleApi->qobjectApi->metaObject(), IR::Name::MemberStorage, line, column);
+ if (moduleApi && moduleApi->instanceMetaObject) {
+ // Note: we don't need to check moduleApi->qobjectCallback here, since
+ // we did that check in registerModuleApi() in qqmlmetatype.cpp.
+ // We cannot create the QObject Module Api Instance here,
+ // as we might be running in a loader thread.
+ // Thus, V4 can only handle bindings which use Module APIs which
+ // were registered with the templated registration function.
+ _expr.code = _block->MODULE_OBJECT(name, moduleApi->instanceMetaObject, IR::Name::MemberStorage, line, column);
}
- }*/ //### we can't create the actual QObject here, as we may be running in a thread (can be reenabled once QTBUG-24894 is handled)
+ }
// We don't support anything else
} else {
bool found = false;