summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/debugger/qjsdebuggeragent.cpp33
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp31
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h30
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeguard_p.h107
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp114
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp72
-rw-r--r--src/declarative/qml/qdeclarativevme_p.h32
-rw-r--r--src/declarative/qml/qdeclarativewatcher.cpp3
-rw-r--r--src/declarative/util/qdeclarativebind.cpp3
-rw-r--r--src/declarative/util/qdeclarativestate_p_p.h4
-rw-r--r--src/declarative/util/qdeclarativestategroup.cpp35
-rw-r--r--src/declarative/util/qdeclarativeview.cpp2
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp315
17 files changed, 518 insertions, 281 deletions
diff --git a/src/declarative/debugger/qjsdebuggeragent.cpp b/src/declarative/debugger/qjsdebuggeragent.cpp
index 683032b..5fc64e1 100644
--- a/src/declarative/debugger/qjsdebuggeragent.cpp
+++ b/src/declarative/debugger/qjsdebuggeragent.cpp
@@ -511,27 +511,24 @@ void QJSDebuggerAgentPrivate::positionChange(qint64 scriptId, int lineNumber, in
// check breakpoints
if (!breakpoints.isEmpty()) {
- QHash<qint64, QString>::const_iterator it = filenames.constFind(scriptId);
- QScriptContext *ctx = engine()->currentContext();
- QScriptContextInfo info(ctx);
- if (it == filenames.constEnd()) {
- // It is possible that the scripts are loaded before the agent is attached
- QString filename = info.fileName();
+ const QScriptContext *ctx = engine()->currentContext();
+ const QScriptContextInfo info(ctx);
- JSAgentStackData frame;
- frame.functionName = info.functionName().toUtf8();
-
- QPair<QString, qint32> key = qMakePair(filename, lineNumber);
- it = filenames.insert(scriptId, filename);
- }
+ if (info.functionType() == QScriptContextInfo::ScriptFunction) {
+ QHash<qint64, QString>::const_iterator it = filenames.constFind(scriptId);
+ // It is possible that the scripts are loaded before the agent is attached
+ if (it == filenames.constEnd()) {
+ it = filenames.insert(scriptId, info.fileName());
+ }
- const QString filePath = it.value();
- JSAgentBreakpoints bps = fileNameToBreakpoints.values(fileName(filePath)).toSet();
+ const QString filePath = it.value();
+ const JSAgentBreakpoints bps = fileNameToBreakpoints.values(fileName(filePath)).toSet();
- foreach (const JSAgentBreakpointData &bp, bps) {
- if (bp.lineNumber == lineNumber) {
- stopped();
- return;
+ foreach (const JSAgentBreakpointData &bp, bps) {
+ if (bp.lineNumber == lineNumber) {
+ stopped();
+ return;
+ }
}
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
index 731d956..412d33c 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
@@ -77,7 +77,7 @@ public:
yoff(0)
{
#ifdef Q_OS_SYMBIAN
- if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
+ if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_1) {
showInputPanelOnFocus = false;
}
#endif
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 4712c65..0325016 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -80,7 +80,7 @@ public:
selectPressed(false)
{
#ifdef Q_OS_SYMBIAN
- if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
+ if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_1) {
showInputPanelOnFocus = false;
}
#endif
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 313fe58..51ffc10 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -143,17 +143,17 @@ struct Register {
void setNaN() { setqreal(qSNaN()); }
bool isUndefined() const { return type == 0; }
- void setQObject(QObject *o) { *((QObject **)data) = o; type = QMetaType::QObjectStar; }
- QObject *getQObject() const { return *((QObject **)data); }
+ void setQObject(QObject *o) { qobjectValue = o; type = QMetaType::QObjectStar; }
+ QObject *getQObject() const { return qobjectValue; }
- void setqreal(qreal v) { *((qreal *)data) = v; type = QMetaType::QReal; }
- qreal getqreal() const { return *((qreal *)data); }
+ void setqreal(qreal v) { qrealValue = v; type = QMetaType::QReal; }
+ qreal getqreal() const { return qrealValue; }
- void setint(int v) { *((int *)data) = v; type = QMetaType::Int; }
- int getint() const { return *((int *)data); }
+ void setint(int v) { intValue = v; type = QMetaType::Int; }
+ int getint() const { return intValue; }
- void setbool(bool v) { *((bool *)data) = v; type = QMetaType::Bool; }
- bool getbool() const { return *((bool *)data); }
+ void setbool(bool v) { boolValue = v; type = QMetaType::Bool; }
+ bool getbool() const { return boolValue; }
QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
QString *getstringptr() { return (QString *)typeDataPtr(); }
@@ -171,7 +171,15 @@ struct Register {
void settype(int t) { type = t; }
int type; // Optional type
- void *data[2]; // Object stored here
+ union {
+ QObject *qobjectValue;
+ qreal qrealValue;
+ int intValue;
+ bool boolValue;
+ char data[sizeof(QVariant)];
+ qint64 q_for_alignment_1;
+ double q_for_alignment_2;
+ };
#ifdef REGISTER_CLEANUP_DEBUG
Register() {
@@ -2388,7 +2396,7 @@ bool QDeclarativeBindingCompilerPrivate::parseConditional(QDeclarativeJS::AST::N
skip.skip.reg = -1;
bytecode << skip;
- // Release to allow reuse of reg
+ // Release to allow reuse of reg in else path
releaseReg(ok.reg);
bytecode[skipIdx].skip.count = bytecode.count() - skipIdx - 1;
@@ -2398,8 +2406,7 @@ bool QDeclarativeBindingCompilerPrivate::parseConditional(QDeclarativeJS::AST::N
if (!parseExpression(expression->ko, ko)) return false;
if (ko.unknownType) return false;
- // Release to allow reuse of reg
- releaseReg(ko.reg);
+ // Do not release reg here, so that its ownership passes to the caller
bytecode[skipIdx2].skip.count = bytecode.count() - skipIdx2 - 1;
if (ok != ko)
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index 2a5eace..4f22b8f 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -55,10 +55,10 @@
#include <QtScript/qscriptvalue.h>
#include <private/qobject_p.h>
-#include "private/qdeclarativeguard_p.h"
QT_BEGIN_NAMESPACE
+class QDeclarativeGuardImpl;
class QDeclarativeCompiledData;
class QDeclarativeAbstractBinding;
class QDeclarativeContext;
@@ -134,7 +134,7 @@ public:
quint32 objectDataRefCount;
QDeclarativePropertyCache *propertyCache;
- QDeclarativeGuard<QObject> *guards;
+ QDeclarativeGuardImpl *guards;
static QDeclarativeData *get(const QObject *object, bool create = false) {
QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
@@ -160,32 +160,6 @@ private:
mutable QDeclarativeDataExtended *extendedData;
};
-template<class T>
-void QDeclarativeGuard<T>::addGuard()
-{
- Q_ASSERT(!prev);
-
- if (QObjectPrivate::get(o)->wasDeleted)
- return;
-
- QDeclarativeData *data = QDeclarativeData::get(o, true);
- next = data->guards;
- if (next) reinterpret_cast<QDeclarativeGuard<T> *>(next)->prev = &next;
- data->guards = reinterpret_cast<QDeclarativeGuard<QObject> *>(this);
- prev = &data->guards;
-}
-
-template<class T>
-void QDeclarativeGuard<T>::remGuard()
-{
- Q_ASSERT(prev);
-
- if (next) reinterpret_cast<QDeclarativeGuard<T> *>(next)->prev = prev;
- *prev = next;
- next = 0;
- prev = 0;
-}
-
QT_END_NAMESPACE
#endif // QDECLARATIVEDATA_P_H
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 8679445..34014f7 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -1154,7 +1154,7 @@ void QDeclarativeData::destroyed(QObject *object)
context->destroy();
while (guards) {
- QDeclarativeGuard<QObject> *guard = guards;
+ QDeclarativeGuard<QObject> *guard = static_cast<QDeclarativeGuard<QObject> *>(guards);
*guard = (QObject *)0;
guard->objectDestroyed(object);
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 8f22314..8707a7f 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -147,12 +147,6 @@ QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx)
if (binding)
rv.binding = binding->expression();
- QVariant value;
- if (prop.userType() != 0) {
- value = prop.read(obj);
- }
- rv.value = valueContents(value);
-
if (QDeclarativeValueTypeFactory::isValueType(prop.userType())) {
rv.type = QDeclarativeObjectProperty::Basic;
} else if (QDeclarativeMetaType::isQObject(prop.userType())) {
@@ -161,6 +155,12 @@ QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx)
rv.type = QDeclarativeObjectProperty::List;
}
+ QVariant value;
+ if (rv.type != QDeclarativeObjectProperty::Unknown && prop.userType() != 0) {
+ value = prop.read(obj);
+ }
+ rv.value = valueContents(value);
+
return rv;
}
diff --git a/src/declarative/qml/qdeclarativeguard_p.h b/src/declarative/qml/qdeclarativeguard_p.h
index a085258..4d84951 100644
--- a/src/declarative/qml/qdeclarativeguard_p.h
+++ b/src/declarative/qml/qdeclarativeguard_p.h
@@ -55,16 +55,30 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
+#include <private/qdeclarativedata_p.h>
QT_BEGIN_NAMESPACE
+class QDeclarativeGuardImpl
+{
+public:
+ inline QDeclarativeGuardImpl();
+ inline QDeclarativeGuardImpl(QObject *);
+ inline QDeclarativeGuardImpl(const QDeclarativeGuardImpl &);
+ inline ~QDeclarativeGuardImpl();
+
+ QObject *o;
+ QDeclarativeGuardImpl *next;
+ QDeclarativeGuardImpl **prev;
+
+ inline void addGuard();
+ inline void remGuard();
+};
+
class QObject;
template<class T>
-class QDeclarativeGuard
+class QDeclarativeGuard : private QDeclarativeGuardImpl
{
- QObject *o;
- QDeclarativeGuard<QObject> *next;
- QDeclarativeGuard<QObject> **prev;
friend class QDeclarativeData;
public:
inline QDeclarativeGuard();
@@ -74,6 +88,9 @@ public:
inline QDeclarativeGuard<T> &operator=(const QDeclarativeGuard<T> &o);
inline QDeclarativeGuard<T> &operator=(T *);
+
+ inline T *object() const;
+ inline void setObject(T *g);
inline bool isNull() const
{ return !o; }
@@ -89,69 +106,109 @@ public:
protected:
virtual void objectDestroyed(T *) {}
-
-private:
- inline void addGuard();
- inline void remGuard();
};
-QT_END_NAMESPACE
+QDeclarativeGuardImpl::QDeclarativeGuardImpl()
+: o(0), next(0), prev(0)
+{
+}
-Q_DECLARE_METATYPE(QDeclarativeGuard<QObject>)
+QDeclarativeGuardImpl::QDeclarativeGuardImpl(QObject *g)
+: o(g), next(0), prev(0)
+{
+ if (o) addGuard();
+}
-#include "private/qdeclarativedata_p.h"
+QDeclarativeGuardImpl::QDeclarativeGuardImpl(const QDeclarativeGuardImpl &g)
+: o(g.o), next(0), prev(0)
+{
+ if (o) addGuard();
+}
-QT_BEGIN_NAMESPACE
+QDeclarativeGuardImpl::~QDeclarativeGuardImpl()
+{
+ if (prev) remGuard();
+ o = 0;
+}
+
+void QDeclarativeGuardImpl::addGuard()
+{
+ Q_ASSERT(!prev);
+
+ if (QObjectPrivate::get(o)->wasDeleted)
+ return;
+
+ QDeclarativeData *data = QDeclarativeData::get(o, true);
+ next = data->guards;
+ if (next) next->prev = &next;
+ data->guards = this;
+ prev = &data->guards;
+}
+
+void QDeclarativeGuardImpl::remGuard()
+{
+ Q_ASSERT(prev);
+
+ if (next) next->prev = prev;
+ *prev = next;
+ next = 0;
+ prev = 0;
+}
template<class T>
QDeclarativeGuard<T>::QDeclarativeGuard()
-: o(0), next(0), prev(0)
{
}
template<class T>
QDeclarativeGuard<T>::QDeclarativeGuard(T *g)
-: o(g), next(0), prev(0)
+: QDeclarativeGuardImpl(g)
{
- if (o) addGuard();
}
template<class T>
QDeclarativeGuard<T>::QDeclarativeGuard(const QDeclarativeGuard<T> &g)
-: o(g.o), next(0), prev(0)
+: QDeclarativeGuardImpl(g)
{
- if (o) addGuard();
}
template<class T>
QDeclarativeGuard<T>::~QDeclarativeGuard()
{
- if (prev) remGuard();
- o = 0;
}
template<class T>
QDeclarativeGuard<T> &QDeclarativeGuard<T>::operator=(const QDeclarativeGuard<T> &g)
{
- if (g.o != o) {
- if (prev) remGuard();
- o = g.o;
- if (o) addGuard();
- }
+ setObject(g.object());
return *this;
}
template<class T>
QDeclarativeGuard<T> &QDeclarativeGuard<T>::operator=(T *g)
{
+ setObject(g);
+ return *this;
+}
+
+template<class T>
+T *QDeclarativeGuard<T>::object() const
+{
+ return static_cast<T *>(o);
+};
+
+template<class T>
+void QDeclarativeGuard<T>::setObject(T *g)
+{
if (g != o) {
if (prev) remGuard();
o = g;
if (o) addGuard();
}
- return *this;
}
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QDeclarativeGuard<QObject>)
+
#endif // QDECLARATIVEGUARD_P_H
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 53f702c..f6f593c 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -680,14 +680,30 @@ private:
inline void cleanup();
- char data[4 * sizeof(void *)];
+ union {
+ float floatValue;
+ double doubleValue;
+ quint32 intValue;
+ bool boolValue;
+ QObject *qobjectPtr;
+
+ char allocData[sizeof(QVariant)];
+ };
+
+ // Pointers to allocData
+ union {
+ QString *qstringPtr;
+ QVariant *qvariantPtr;
+ QList<QObject *> *qlistPtr;
+ QScriptValue *qscriptValuePtr;
+ };
+
int type;
- bool isObjectType;
};
}
MetaCallArgument::MetaCallArgument()
-: type(QVariant::Invalid), isObjectType(false)
+: type(QVariant::Invalid)
{
}
@@ -699,22 +715,22 @@ MetaCallArgument::~MetaCallArgument()
void MetaCallArgument::cleanup()
{
if (type == QMetaType::QString) {
- ((QString *)&data)->~QString();
- } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
- ((QVariant *)&data)->~QVariant();
+ qstringPtr->~QString();
+ } else if (type == -1 || type == QMetaType::QVariant) {
+ qvariantPtr->~QVariant();
} else if (type == qMetaTypeId<QScriptValue>()) {
- ((QScriptValue *)&data)->~QScriptValue();
+ qscriptValuePtr->~QScriptValue();
} else if (type == qMetaTypeId<QList<QObject *> >()) {
- ((QList<QObject *> *)&data)->~QList<QObject *>();
+ qlistPtr->~QList<QObject *>();
}
}
void *MetaCallArgument::dataPtr()
{
if (type == -1)
- return ((QVariant *)data)->data();
- else
- return (void *)&data;
+ return qvariantPtr->data();
+ else
+ return (void *)&allocData;
}
void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
@@ -725,7 +741,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);
if (callType == qMetaTypeId<QScriptValue>()) {
- new (&data) QScriptValue(engine->undefinedValue());
+ qscriptValuePtr = new (&allocData) QScriptValue(engine->undefinedValue());
type = callType;
} else if (callType == QMetaType::Int ||
callType == QMetaType::UInt ||
@@ -734,20 +750,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
callType == QMetaType::Float) {
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- *((QObject **)&data) = 0;
+ qobjectPtr = 0;
type = callType;
} else if (callType == QMetaType::QString) {
- new (&data) QString();
+ qstringPtr = new (&allocData) QString();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
type = callType;
- new (&data) QVariant();
+ qvariantPtr = new (&allocData) QVariant();
} else if (callType == qMetaTypeId<QList<QObject *> >()) {
type = callType;
- new (&data) QList<QObject *>();
+ qlistPtr = new (&allocData) QList<QObject *>();
} else {
type = -1;
- new (&data) QVariant(callType, (void *)0);
+ qvariantPtr = new (&allocData) QVariant(callType, (void *)0);
}
}
@@ -756,59 +772,60 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
if (type != 0) { cleanup(); type = 0; }
if (callType == qMetaTypeId<QScriptValue>()) {
- new (&data) QScriptValue(value);
+ qscriptValuePtr = new (&allocData) QScriptValue(value);
type = qMetaTypeId<QScriptValue>();
} else if (callType == QMetaType::Int) {
- *((int *)&data) = int(value.toInt32());
+ intValue = quint32(value.toInt32());
type = callType;
} else if (callType == QMetaType::UInt) {
- *((uint *)&data) = uint(value.toUInt32());
+ intValue = quint32(value.toUInt32());
type = callType;
} else if (callType == QMetaType::Bool) {
- *((bool *)&data) = value.toBool();
+ boolValue = value.toBool();
type = callType;
} else if (callType == QMetaType::Double) {
- *((double *)&data) = double(value.toNumber());
+ doubleValue = double(value.toNumber());
type = callType;
} else if (callType == QMetaType::Float) {
- *((float *)&data) = float(value.toNumber());
+ floatValue = float(value.toNumber());
type = callType;
} else if (callType == QMetaType::QString) {
if (value.isNull() || value.isUndefined())
- new (&data) QString();
+ qstringPtr = new (&allocData) QString();
else
- new (&data) QString(value.toString());
+ qstringPtr = new (&allocData) QString(value.toString());
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- *((QObject **)&data) = value.toQObject();
+ qobjectPtr = value.toQObject();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
- new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value));
+ QVariant other = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);
+ qvariantPtr = new (&allocData) QVariant(other);
type = callType;
} else if (callType == qMetaTypeId<QList<QObject*> >()) {
- QList<QObject *> *list = new (&data) QList<QObject *>();
+ qlistPtr = new (&allocData) QList<QObject *>();
if (value.isArray()) {
int length = value.property(QLatin1String("length")).toInt32();
for (int ii = 0; ii < length; ++ii) {
QScriptValue arrayItem = value.property(ii);
QObject *d = arrayItem.toQObject();
- list->append(d);
+ qlistPtr->append(d);
}
} else if (QObject *d = value.toQObject()) {
- list->append(d);
+ qlistPtr->append(d);
}
type = callType;
} else {
- new (&data) QVariant();
+ qvariantPtr = new (&allocData) QVariant();
type = -1;
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine);
QVariant v = priv->scriptValueToVariant(value);
if (v.userType() == callType) {
- *((QVariant *)&data) = v;
+ *qvariantPtr = v;
} else if (v.canConvert((QVariant::Type)callType)) {
- *((QVariant *)&data) = v;
- ((QVariant *)&data)->convert((QVariant::Type)callType);
+ *qvariantPtr = v;
+ qvariantPtr->convert((QVariant::Type)callType);
} else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) {
QObject *obj = priv->toQObject(v);
@@ -818,9 +835,9 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
if (!objMo) obj = 0;
}
- *((QVariant *)&data) = QVariant(callType, &obj);
+ *qvariantPtr = QVariant(callType, &obj);
} else {
- *((QVariant *)&data) = QVariant(callType, (void *)0);
+ *qvariantPtr = QVariant(callType, (void *)0);
}
}
}
@@ -830,27 +847,26 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);
if (type == qMetaTypeId<QScriptValue>()) {
- return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data));
+ return QScriptDeclarativeClass::Value(engine, *qscriptValuePtr);
} else if (type == QMetaType::Int) {
- return QScriptDeclarativeClass::Value(engine, *((int *)&data));
+ return QScriptDeclarativeClass::Value(engine, int(intValue));
} else if (type == QMetaType::UInt) {
- return QScriptDeclarativeClass::Value(engine, *((uint *)&data));
+ return QScriptDeclarativeClass::Value(engine, uint(intValue));
} else if (type == QMetaType::Bool) {
- return QScriptDeclarativeClass::Value(engine, *((bool *)&data));
+ return QScriptDeclarativeClass::Value(engine, boolValue);
} else if (type == QMetaType::Double) {
- return QScriptDeclarativeClass::Value(engine, *((double *)&data));
+ return QScriptDeclarativeClass::Value(engine, doubleValue);
} else if (type == QMetaType::Float) {
- return QScriptDeclarativeClass::Value(engine, *((float *)&data));
+ return QScriptDeclarativeClass::Value(engine, floatValue);
} else if (type == QMetaType::QString) {
- return QScriptDeclarativeClass::Value(engine, *((QString *)&data));
+ return QScriptDeclarativeClass::Value(engine, *qstringPtr);
} else if (type == QMetaType::QObjectStar) {
- QObject *object = *((QObject **)&data);
- if (object)
- QDeclarativeData::get(object, true)->setImplicitDestructible();
+ if (qobjectPtr)
+ QDeclarativeData::get(qobjectPtr, true)->setImplicitDestructible();
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
- return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object));
+ return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(qobjectPtr));
} else if (type == qMetaTypeId<QList<QObject *> >()) {
- QList<QObject *> &list = *(QList<QObject *>*)&data;
+ QList<QObject *> &list = *qlistPtr;
QScriptValue rv = engine->newArray(list.count());
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
for (int ii = 0; ii < list.count(); ++ii) {
@@ -861,7 +877,7 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
return QScriptDeclarativeClass::Value(engine, rv);
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e);
- QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data));
+ QScriptValue rv = ep->scriptValueFromVariant(*qvariantPtr);
if (rv.isQObject()) {
QObject *object = rv.toQObject();
if (object)
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 06aed98..a23f89d 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -74,6 +74,27 @@
QT_BEGIN_NAMESPACE
+// A simple stack wrapper around QVarLengthArray
+template<typename T>
+class QDeclarativeVMEStack : private QVarLengthArray<T, 128>
+{
+private:
+ typedef QVarLengthArray<T, 128> VLA;
+ int _index;
+
+public:
+ inline QDeclarativeVMEStack();
+ inline bool isEmpty() const;
+ inline const T &top() const;
+ inline void push(const T &o);
+ inline T pop();
+ inline int count() const;
+ inline const T &at(int index) const;
+};
+
+// We do this so we can forward declare the type in the qdeclarativevme_p.h header
+class QDeclarativeVMEObjectStack : public QDeclarativeVMEStack<QObject *> {};
+
QDeclarativeVME::QDeclarativeVME()
{
}
@@ -99,10 +120,12 @@ struct ListInstance
QDeclarativeListProperty<void> qListProperty;
};
+Q_DECLARE_TYPEINFO(ListInstance, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
+
QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp,
int start, int count, const QBitField &bindingSkipList)
{
- QDeclarativeVMEStack<QObject *> stack;
+ QDeclarativeVMEObjectStack stack;
if (start == -1) start = 0;
if (count == -1) count = comp->bytecode.count();
@@ -121,7 +144,7 @@ void QDeclarativeVME::runDeferred(QObject *object)
QDeclarativeCompiledData *comp = data->deferredComponent;
int start = data->deferredIdx + 1;
int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount;
- QDeclarativeVMEStack<QObject *> stack;
+ QDeclarativeVMEObjectStack stack;
stack.push(object);
run(stack, ctxt, comp, start, count, QBitField());
@@ -143,7 +166,7 @@ static void removeBindingOnProperty(QObject *o, int index)
#define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
-QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
+QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QDeclarativeContextData *ctxt,
QDeclarativeCompiledData *comp,
int start, int count,
@@ -1054,5 +1077,48 @@ QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData
}
}
+template<typename T>
+QDeclarativeVMEStack<T>::QDeclarativeVMEStack()
+: _index(-1)
+{
+}
+
+template<typename T>
+bool QDeclarativeVMEStack<T>::isEmpty() const {
+ return _index == -1;
+}
+
+template<typename T>
+const T &QDeclarativeVMEStack<T>::top() const {
+ return at(_index);
+}
+
+template<typename T>
+void QDeclarativeVMEStack<T>::push(const T &o) {
+ _index++;
+
+ Q_ASSERT(_index <= VLA::size());
+ if (_index == VLA::size())
+ VLA::append(o);
+ else
+ VLA::data()[_index] = o;
+}
+
+template<typename T>
+T QDeclarativeVMEStack<T>::pop() {
+ Q_ASSERT(_index >= 0);
+ --_index;
+ return VLA::data()[_index + 1];
+}
+
+template<typename T>
+int QDeclarativeVMEStack<T>::count() const {
+ return _index + 1;
+}
+
+template<typename T>
+const T &QDeclarativeVMEStack<T>::at(int index) const {
+ return VLA::data()[index];
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h
index 6b7b93f..b7f110f 100644
--- a/src/declarative/qml/qdeclarativevme_p.h
+++ b/src/declarative/qml/qdeclarativevme_p.h
@@ -58,6 +58,7 @@
#include <QtCore/QString>
#include <QtCore/QStack>
+#include <QtCore/QVarLengthArray>
QT_BEGIN_NAMESPACE
@@ -67,34 +68,7 @@ class QDeclarativeCompiledData;
class QDeclarativeCompiledData;
class QDeclarativeContextData;
-template<typename T, int N = 128>
-class QDeclarativeVMEStack {
-public:
- QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {}
- ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); }
-
- bool isEmpty() const { return index == -1; }
- const T &top() const { return data[index]; }
- void push(const T &i) { ++index; if (index == maxSize) realloc(); data[index] = i; }
- const T &pop() { --index; return data[index + 1]; }
- int count() const { return index + 1; }
- const T &at(int idx) { return data[idx]; }
-
-private:
- void realloc() {
- maxSize += N;
- if (data != (T *)fixedData) {
- data = (T*)qRealloc(data, maxSize * sizeof(T));
- } else {
- data = (T*)qMalloc(maxSize * sizeof(T));
- }
- }
- int index;
- int maxSize;
- T *data;
- char fixedData[N * sizeof(T)];
-};
-
+class QDeclarativeVMEObjectStack;
class QDeclarativeVME
{
public:
@@ -109,7 +83,7 @@ public:
QList<QDeclarativeError> errors() const;
private:
- QObject *run(QDeclarativeVMEStack<QObject *> &,
+ QObject *run(QDeclarativeVMEObjectStack &,
QDeclarativeContextData *, QDeclarativeCompiledData *,
int start, int count,
const QBitField &);
diff --git a/src/declarative/qml/qdeclarativewatcher.cpp b/src/declarative/qml/qdeclarativewatcher.cpp
index c174998..33f0358 100644
--- a/src/declarative/qml/qdeclarativewatcher.cpp
+++ b/src/declarative/qml/qdeclarativewatcher.cpp
@@ -47,6 +47,7 @@
#include <qdeclarativedebugservice_p.h>
#include "private/qdeclarativeproperty_p.h"
+#include "private/qdeclarativevaluetype_p.h"
#include <QtCore/qmetaobject.h>
#include <QtCore/qdebug.h>
@@ -112,7 +113,7 @@ void QDeclarativeWatchProxy::notifyValueChanged()
QVariant v;
if (m_expr)
v = m_expr->evaluate();
- else
+ else if (QDeclarativeValueTypeFactory::isValueType(m_property.userType()))
v = m_property.read(m_object);
emit m_watch->propertyChanged(m_id, m_debugId, m_property, v);
diff --git a/src/declarative/util/qdeclarativebind.cpp b/src/declarative/util/qdeclarativebind.cpp
index b7199ac..051df60 100644
--- a/src/declarative/util/qdeclarativebind.cpp
+++ b/src/declarative/util/qdeclarativebind.cpp
@@ -42,6 +42,7 @@
#include "private/qdeclarativebind_p.h"
#include "private/qdeclarativenullablevalue_p_p.h"
+#include "private/qdeclarativeguard_p.h"
#include <qdeclarativeengine.h>
#include <qdeclarativecontext.h>
@@ -64,7 +65,7 @@ public:
bool when : 1;
bool componentComplete : 1;
- QObject *obj;
+ QDeclarativeGuard<QObject> obj;
QString prop;
QDeclarativeNullableValue<QVariant> value;
};
diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h
index ec18f59..195b935 100644
--- a/src/declarative/util/qdeclarativestate_p_p.h
+++ b/src/declarative/util/qdeclarativestate_p_p.h
@@ -206,7 +206,9 @@ public:
struct OperationGuard : public QDeclarativeGuard<QDeclarativeStateOperation>
{
- OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) { (QDeclarativeGuard<QObject>&)*this = obj; }
+ OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) {
+ setObject(static_cast<QDeclarativeStateOperation *>(obj));
+ }
QList<OperationGuard> *list;
void objectDestroyed(QDeclarativeStateOperation *) {
// we assume priv will always be destroyed after objectDestroyed calls
diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp
index a3f57d4..c098a38 100644
--- a/src/declarative/util/qdeclarativestategroup.cpp
+++ b/src/declarative/util/qdeclarativestategroup.cpp
@@ -73,6 +73,11 @@ public:
static QDeclarativeState *at_state(QDeclarativeListProperty<QDeclarativeState> *list, int index);
static void clear_states(QDeclarativeListProperty<QDeclarativeState> *list);
+ static void append_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, QDeclarativeTransition *state);
+ static int count_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list);
+ static QDeclarativeTransition *at_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, int index);
+ static void clear_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list);
+
QList<QDeclarativeState *> states;
QList<QDeclarativeTransition *> transitions;
@@ -218,7 +223,35 @@ void QDeclarativeStateGroupPrivate::clear_states(QDeclarativeListProperty<QDecla
QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeStateGroup::transitionsProperty()
{
Q_D(QDeclarativeStateGroup);
- return QDeclarativeListProperty<QDeclarativeTransition>(this, d->transitions);
+ return QDeclarativeListProperty<QDeclarativeTransition>(this, &d->transitions, &QDeclarativeStateGroupPrivate::append_transition,
+ &QDeclarativeStateGroupPrivate::count_transitions,
+ &QDeclarativeStateGroupPrivate::at_transition,
+ &QDeclarativeStateGroupPrivate::clear_transitions);
+}
+
+void QDeclarativeStateGroupPrivate::append_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, QDeclarativeTransition *trans)
+{
+ QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+ if (trans)
+ _this->d_func()->transitions.append(trans);
+}
+
+int QDeclarativeStateGroupPrivate::count_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list)
+{
+ QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+ return _this->d_func()->transitions.count();
+}
+
+QDeclarativeTransition *QDeclarativeStateGroupPrivate::at_transition(QDeclarativeListProperty<QDeclarativeTransition> *list, int index)
+{
+ QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+ return _this->d_func()->transitions.at(index);
+}
+
+void QDeclarativeStateGroupPrivate::clear_transitions(QDeclarativeListProperty<QDeclarativeTransition> *list)
+{
+ QDeclarativeStateGroup *_this = static_cast<QDeclarativeStateGroup *>(list->object);
+ _this->d_func()->transitions.clear();
}
/*!
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index bab991b..45995ce 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -319,6 +319,8 @@ QDeclarativeView::~QDeclarativeView()
Ensure that the URL provided is full and correct, in particular, use
\l QUrl::fromLocalFile() when loading a file from the local filesystem.
+
+ \sa {Network Transparency}{Loading Resources in QML}
*/
/*!
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 6f9245b..658dcad 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -147,114 +147,217 @@ struct XmlQueryJob
QString prefix;
};
-class QDeclarativeXmlQuery : public QObject
+
+class QDeclarativeXmlQueryEngine;
+class QDeclarativeXmlQueryThreadObject : public QObject
{
Q_OBJECT
public:
- QDeclarativeXmlQuery(QObject *parent=0)
- : QObject(parent), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
- qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
- moveToThread(&m_thread);
- m_thread.start(QThread::IdlePriority);
- }
+ QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *);
- ~QDeclarativeXmlQuery() {
- if(m_thread.isRunning()) {
- m_thread.quit();
- m_thread.wait();
- }
- }
-
- void abort(int id) {
- QMutexLocker ml(&m_mutex);
- if (id != -1) {
- m_jobs.remove(id);
- }
- }
-
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
- {
- QMutexLocker m1(&m_mutex);
- m_queryIds.ref();
- if (m_queryIds <= 0)
- m_queryIds = 1;
- }
-
- XmlQueryJob job;
- job.queryId = m_queryIds;
- job.data = data;
- job.query = QLatin1String("doc($src)") + query;
- job.namespaces = namespaces;
- job.keyRoleResultsCache = keyRoleResultsCache;
-
- for (int i=0; i<roleObjects->count(); i++) {
- if (!roleObjects->at(i)->isValid()) {
- job.roleQueries << QString();
- continue;
- }
- job.roleQueries << roleObjects->at(i)->query();
- job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
- if (roleObjects->at(i)->isKey())
- job.keyRoleQueries << job.roleQueries.last();
- }
+ void processJobs();
+ virtual bool event(QEvent *e);
- {
- QMutexLocker ml(&m_mutex);
- m_jobs.insert(m_queryIds, job);
- }
+private:
+ QDeclarativeXmlQueryEngine *m_queryEngine;
+};
- QMetaObject::invokeMethod(this, "processQuery", Qt::QueuedConnection, Q_ARG(int, job.queryId));
- return job.queryId;
- }
-private slots:
- void processQuery(int queryId) {
- XmlQueryJob job;
+class QDeclarativeXmlQueryEngine : public QThread
+{
+ Q_OBJECT
+public:
+ QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng);
+ ~QDeclarativeXmlQueryEngine();
- {
- QMutexLocker ml(&m_mutex);
- if (!m_jobs.contains(queryId))
- return;
- job = m_jobs.value(queryId);
- }
+ int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache);
+ void abort(int id);
- QDeclarativeXmlQueryResult result;
- result.queryId = job.queryId;
- doQueryJob(&job, &result);
- doSubQueryJob(&job, &result);
+ void processJobs();
- {
- QMutexLocker ml(&m_mutex);
- if (m_jobs.contains(queryId)) {
- emit queryCompleted(result);
- m_jobs.remove(queryId);
- }
- }
- }
+ static QDeclarativeXmlQueryEngine *instance(QDeclarativeEngine *engine);
-Q_SIGNALS:
+signals:
void queryCompleted(const QDeclarativeXmlQueryResult &);
void error(void*, const QString&);
protected:
-
+ void run();
private:
+ void processQuery(XmlQueryJob *job);
void doQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
void doSubQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
void addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const;
-private:
QMutex m_mutex;
- QThread m_thread;
- QMap<int, XmlQueryJob> m_jobs;
+ QDeclarativeXmlQueryThreadObject *m_threadObject;
+ QList<XmlQueryJob> m_jobs;
+ QSet<int> m_cancelledJobs;
QAtomicInt m_queryIds;
+
+ QDeclarativeEngine *m_engine;
+ QObject *m_eventLoopQuitHack;
+
+ static QHash<QDeclarativeEngine *,QDeclarativeXmlQueryEngine*> queryEngines;
+ static QMutex queryEnginesMutex;
};
+QHash<QDeclarativeEngine *,QDeclarativeXmlQueryEngine*> QDeclarativeXmlQueryEngine::queryEngines;
+QMutex QDeclarativeXmlQueryEngine::queryEnginesMutex;
+
+
+QDeclarativeXmlQueryThreadObject::QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *e)
+ : m_queryEngine(e)
+{
+}
+
+void QDeclarativeXmlQueryThreadObject::processJobs()
+{
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+}
+
+bool QDeclarativeXmlQueryThreadObject::event(QEvent *e)
+{
+ if (e->type() == QEvent::User) {
+ m_queryEngine->processJobs();
+ return true;
+ } else {
+ return QObject::event(e);
+ }
+}
+
+
+
+QDeclarativeXmlQueryEngine::QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng)
+: QThread(eng), m_threadObject(0), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1), m_engine(eng), m_eventLoopQuitHack(0)
+{
+ qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
+
+ m_eventLoopQuitHack = new QObject;
+ m_eventLoopQuitHack->moveToThread(this);
+ connect(m_eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
+ start(QThread::IdlePriority);
+}
+
+QDeclarativeXmlQueryEngine::~QDeclarativeXmlQueryEngine()
+{
+ queryEnginesMutex.lock();
+ queryEngines.remove(m_engine);
+ queryEnginesMutex.unlock();
+
+ m_eventLoopQuitHack->deleteLater();
+ wait();
+}
-Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
+int QDeclarativeXmlQueryEngine::doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
+ {
+ QMutexLocker m1(&m_mutex);
+ m_queryIds.ref();
+ if (m_queryIds <= 0)
+ m_queryIds = 1;
+ }
+
+ XmlQueryJob job;
+ job.queryId = m_queryIds;
+ job.data = data;
+ job.query = QLatin1String("doc($src)") + query;
+ job.namespaces = namespaces;
+ job.keyRoleResultsCache = keyRoleResultsCache;
+
+ for (int i=0; i<roleObjects->count(); i++) {
+ if (!roleObjects->at(i)->isValid()) {
+ job.roleQueries << QString();
+ continue;
+ }
+ job.roleQueries << roleObjects->at(i)->query();
+ job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
+ if (roleObjects->at(i)->isKey())
+ job.keyRoleQueries << job.roleQueries.last();
+ }
+
+ {
+ QMutexLocker ml(&m_mutex);
+ m_jobs.append(job);
+ if (m_threadObject)
+ m_threadObject->processJobs();
+ }
+
+ return job.queryId;
+}
+
+void QDeclarativeXmlQueryEngine::abort(int id)
+{
+ QMutexLocker ml(&m_mutex);
+ if (id != -1)
+ m_cancelledJobs.insert(id);
+}
+
+void QDeclarativeXmlQueryEngine::run()
+{
+ m_mutex.lock();
+ m_threadObject = new QDeclarativeXmlQueryThreadObject(this);
+ m_mutex.unlock();
+
+ processJobs();
+ exec();
+
+ delete m_threadObject;
+ m_threadObject = 0;
+}
+
+void QDeclarativeXmlQueryEngine::processJobs()
+{
+ QMutexLocker locker(&m_mutex);
+
+ while (true) {
+ if (m_jobs.isEmpty())
+ return;
+
+ XmlQueryJob currentJob = m_jobs.takeLast();
+ while (m_cancelledJobs.remove(currentJob.queryId)) {
+ if (m_jobs.isEmpty())
+ return;
+ currentJob = m_jobs.takeLast();
+ }
+
+ locker.unlock();
+ processQuery(&currentJob);
+ locker.relock();
+ }
+}
-void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
+QDeclarativeXmlQueryEngine *QDeclarativeXmlQueryEngine::instance(QDeclarativeEngine *engine)
+{
+ queryEnginesMutex.lock();
+ QDeclarativeXmlQueryEngine *queryEng = queryEngines.value(engine);
+ if (!queryEng) {
+ queryEng = new QDeclarativeXmlQueryEngine(engine);
+ queryEngines.insert(engine, queryEng);
+ }
+ queryEnginesMutex.unlock();
+
+ return queryEng;
+}
+
+void QDeclarativeXmlQueryEngine::processQuery(XmlQueryJob *job)
+{
+ QDeclarativeXmlQueryResult result;
+ result.queryId = job->queryId;
+ doQueryJob(job, &result);
+ doSubQueryJob(job, &result);
+
+ {
+ QMutexLocker ml(&m_mutex);
+ if (m_cancelledJobs.contains(job->queryId)) {
+ m_cancelledJobs.remove(job->queryId);
+ } else {
+ emit queryCompleted(result);
+ }
+ }
+}
+
+void QDeclarativeXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
{
Q_ASSERT(currentJob->queryId != -1);
@@ -293,7 +396,7 @@ void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQu
currentResult->size = (count > 0 ? count : 0);
}
-void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
+void QDeclarativeXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
{
const QStringList &keysQueries = currentJob.keyRoleQueries;
QString keysQuery;
@@ -314,7 +417,7 @@ void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QS
}
}
-void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const {
+void QDeclarativeXmlQueryEngine::addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const {
if (ranges->isEmpty())
ranges->append(qMakePair(index, 1));
else if (ranges->last().first + ranges->last().second == index)
@@ -323,7 +426,7 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *
ranges->append(qMakePair(index, 1));
}
-void QDeclarativeXmlQuery::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
+void QDeclarativeXmlQueryEngine::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
{
Q_ASSERT(currentJob->queryId != -1);
@@ -434,6 +537,15 @@ public:
emit q->statusChanged(status);
}
+ void deleteReply() {
+ Q_Q(QDeclarativeXmlListModel);
+ if (reply) {
+ QObject::disconnect(reply, 0, q, 0);
+ reply->deleteLater();
+ reply = 0;
+ }
+ }
+
bool isComponentComplete;
QUrl src;
QString xml;
@@ -443,6 +555,7 @@ public:
QList<int> roles;
QStringList roleNames;
int highestRole;
+
QNetworkReply *reply;
QDeclarativeXmlListModel::Status status;
QString errorString;
@@ -450,6 +563,7 @@ public:
int queryId;
QStringList keyRoleResultsCache;
QList<QDeclarativeXmlListModelRole *> roleObjects;
+
static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role);
static void clear_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list);
QList<QList<QVariant> > data;
@@ -583,10 +697,6 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
: QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent)
{
- connect(globalXmlQuery(), SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)),
- this, SLOT(queryCompleted(QDeclarativeXmlQueryResult)));
- connect(globalXmlQuery(), SIGNAL(error(void*,QString)),
- this, SLOT(queryError(void*,QString)));
}
QDeclarativeXmlListModel::~QDeclarativeXmlListModel()
@@ -852,6 +962,12 @@ void QDeclarativeXmlListModel::classBegin()
{
Q_D(QDeclarativeXmlListModel);
d->isComponentComplete = false;
+
+ QDeclarativeXmlQueryEngine *queryEngine = QDeclarativeXmlQueryEngine::instance(qmlEngine(this));
+ connect(queryEngine, SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)),
+ SLOT(queryCompleted(QDeclarativeXmlQueryResult)));
+ connect(queryEngine, SIGNAL(error(void*,QString)),
+ SLOT(queryError(void*,QString)));
}
void QDeclarativeXmlListModel::componentComplete()
@@ -881,7 +997,7 @@ void QDeclarativeXmlListModel::reload()
if (!d->isComponentComplete)
return;
- globalXmlQuery()->abort(d->queryId);
+ QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->abort(d->queryId);
d->queryId = -1;
if (d->size < 0)
@@ -889,15 +1005,11 @@ void QDeclarativeXmlListModel::reload()
if (d->reply) {
d->reply->abort();
- if (d->reply) {
- // abort will generally have already done this (and more)
- d->reply->deleteLater();
- d->reply = 0;
- }
+ d->deleteReply();
}
if (!d->xml.isEmpty()) {
- d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
+ d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
d->notifyQueryStarted(false);
} else if (d->src.isEmpty()) {
@@ -927,8 +1039,7 @@ void QDeclarativeXmlListModel::requestFinished()
QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = d->reply->url().resolved(redirect.toUrl());
- d->reply->deleteLater();
- d->reply = 0;
+ d->deleteReply();
setSource(url);
return;
}
@@ -937,9 +1048,7 @@ void QDeclarativeXmlListModel::requestFinished()
if (d->reply->error() != QNetworkReply::NoError) {
d->errorString = d->reply->errorString();
- disconnect(d->reply, 0, this, 0);
- d->reply->deleteLater();
- d->reply = 0;
+ d->deleteReply();
int count = this->count();
d->data.clear();
@@ -958,11 +1067,9 @@ void QDeclarativeXmlListModel::requestFinished()
d->queryId = XMLLISTMODEL_CLEAR_ID;
QTimer::singleShot(0, this, SLOT(dataCleared()));
} else {
- d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
+ d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
}
- disconnect(d->reply, 0, this, 0);
- d->reply->deleteLater();
- d->reply = 0;
+ d->deleteReply();
d->progress = 1.0;
emit progressChanged(d->progress);