summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-04-28 05:05:53 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-04-28 05:05:53 (GMT)
commit2b8abf28d10a6d064fe116892161289be5ffb391 (patch)
tree6a1123766682c82bddbdf358316f26e11f6976c7 /src/declarative/qml
parentd7ffaa8ccbf881d25004b9a710259701d1a8c9bc (diff)
parenta6ffd7c7c28066f2794579bc40e7b9517e76d1ff (diff)
downloadQt-2b8abf28d10a6d064fe116892161289be5ffb391.zip
Qt-2b8abf28d10a6d064fe116892161289be5ffb391.tar.gz
Qt-2b8abf28d10a6d064fe116892161289be5ffb391.tar.bz2
Merge branch 'kinetic-declarativeui' of ../kinetic into kinetic-declarativeui-qfx
Conflicts: examples/declarative/mouseregion/mouse.qml
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.h16
-rw-r--r--src/declarative/qml/qml.pri3
-rw-r--r--src/declarative/qml/qmlcompiler.cpp6
-rw-r--r--src/declarative/qml/qmlcontext_p.h8
-rw-r--r--src/declarative/qml/qmldeclarativedata_p.h70
-rw-r--r--src/declarative/qml/qmlengine.cpp72
-rw-r--r--src/declarative/qml/qmlinstruction.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction_p.h2
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp2
-rw-r--r--src/declarative/qml/qmlmetatype.cpp12
-rw-r--r--src/declarative/qml/qmlmetatype.h1
-rw-r--r--src/declarative/qml/qmlvme.cpp8
12 files changed, 174 insertions, 28 deletions
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h
index fb288b7..2d8d83e 100644
--- a/src/declarative/qml/qml.h
+++ b/src/declarative/qml/qml.h
@@ -92,6 +92,22 @@ class QmlContext;
class QmlEngine;
Q_DECLARATIVE_EXPORT QmlContext *qmlContext(const QObject *);
Q_DECLARATIVE_EXPORT QmlEngine *qmlEngine(const QObject *);
+Q_DECLARATIVE_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *);
+
+template<typename T>
+QObject *qmlAttachedPropertiesObject(const QObject *obj)
+{
+ // ### is this threadsafe?
+ static int idx = -1;
+
+ if(idx == -1)
+ idx = QmlMetaType::attachedPropertiesFuncId(&T::staticMetaObject);
+
+ if(idx == -1 || !obj)
+ return 0;
+
+ return qmlAttachedPropertiesObjectById(obj, idx);
+}
QML_DECLARE_TYPE(QObject);
Q_DECLARE_METATYPE(QVariant);
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 523a31b..00e3ccb 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -56,7 +56,8 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlmetaproperty_p.h \
qml/qmlcontext_p.h \
qml/qmlcompositetypemanager_p.h \
- qml/qmllist.h
+ qml/qmllist.h \
+ qml/qmldeclarativedata_p.h
# for qtscript debugger
QT += scripttools
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 7d9dd5f..d55647c 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -911,8 +911,10 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchAttached;
fetch.line = prop->line;
- int ref = output->indexForByteArray(prop->name);
- fetch.fetchAttached.idx = ref;
+ int id = QmlMetaType::attachedPropertiesFuncId(prop->name);
+ if(id == -1)
+ COMPILE_EXCEPTION("Non-existant attached property object" << prop->name);
+ fetch.fetchAttached.id = id;
output->bytecode << fetch;
COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1));
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index aa0bf3e..3772885 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -44,6 +44,7 @@
#include <qmlcontext.h>
#include <private/qobject_p.h>
+#include <private/qmldeclarativedata_p.h>
#include <qhash.h>
#include <qscriptvalue.h>
@@ -82,12 +83,7 @@ public:
};
void addDefaultObject(QObject *, Priority);
- class ContextData : public QDeclarativeData
- {
- public:
- QmlContext *context;
- };
- ContextData contextData;
+ QmlSimpleDeclarativeData contextData;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h
new file mode 100644
index 0000000..a934442
--- /dev/null
+++ b/src/declarative/qml/qmldeclarativedata_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLDECLARATIVEDATA_P_H
+#define QMLDECLARATIVEDATA_P_H
+
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlSimpleDeclarativeData : public QDeclarativeData
+{
+public:
+ QmlSimpleDeclarativeData() : flags(0), context(0) {}
+
+ enum Flag { Extended = 0x00000001 };
+ quint32 flags;
+ QmlContext *context;
+};
+
+class QmlExtendedDeclarativeData : public QmlSimpleDeclarativeData
+{
+public:
+ QmlExtendedDeclarativeData() { flags = Extended; }
+
+ virtual void destroyed(QObject *);
+ QHash<int, QObject *> attachedProperties;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLDECLARATIVEDATA_P_H
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index db229ba..5e698c2 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -599,10 +599,32 @@ QNetworkAccessManager *QmlEngine::networkAccessManager() const
QmlContext *QmlEngine::contextForObject(const QObject *object)
{
QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
- if(priv->declarativeData) {
- return static_cast<QmlContextPrivate::ContextData *>(priv->declarativeData)->context;
+
+ QmlSimpleDeclarativeData *data =
+ static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+
+ return data?data->context:0;
+}
+
+void QmlEngine::setContextForObject(QObject *object, QmlContext *context)
+{
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+
+ QmlSimpleDeclarativeData *data =
+ static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+
+ if(data && data->context) {
+ qWarning("QmlEngine::setContextForObject(): Object already has a QmlContext");
+ return;
+ }
+
+ if(!data) {
+ priv->declarativeData = &context->d_func()->contextData;
} else {
- return 0;
+ // ### - Don't have to use extended data here
+ QmlExtendedDeclarativeData *data = new QmlExtendedDeclarativeData;
+ data->context = context;
+ priv->declarativeData = data;
}
}
@@ -617,15 +639,45 @@ QmlEngine *qmlEngine(const QObject *obj)
return context?context->engine():0;
}
-
-void QmlEngine::setContextForObject(QObject *object, QmlContext *context)
+QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object)
{
- QObjectPrivate *priv = QObjectPrivate::get(object);
- if(priv->declarativeData) {
- qWarning("QmlEngine::setContextForObject(): Object already has a QmlContext");
- return;
+ QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
+
+
+ QmlSimpleDeclarativeData *data = static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData);
+
+ QmlExtendedDeclarativeData *edata = (data && data->flags & QmlSimpleDeclarativeData::Extended)?static_cast<QmlExtendedDeclarativeData *>(data):0;
+
+ if(edata) {
+ QObject *rv = edata->attachedProperties.value(id);
+ if(rv)
+ return rv;
}
- priv->declarativeData = &context->d_func()->contextData;
+
+ QmlAttachedPropertiesFunc pf = QmlMetaType::attachedPropertiesFuncById(id);
+ if(!pf)
+ return 0;
+
+ QObject *rv = pf(const_cast<QObject *>(object));
+
+ if(rv) {
+ if(!edata) {
+
+ edata = new QmlExtendedDeclarativeData;
+ if(data) edata->context = data->context;
+ priv->declarativeData = edata;
+
+ }
+
+ edata->attachedProperties.insert(id, rv);
+ }
+
+ return rv;
+}
+
+void QmlExtendedDeclarativeData::destroyed(QObject *)
+{
+ delete this;
}
/*! \internal */
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 9938022..848c8db 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -173,7 +173,7 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property));
break;
case QmlInstruction::FetchAttached:
- qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.idx << "\t\t\t" << primitives.at(instr->fetchAttached.idx);
+ qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
break;
case QmlInstruction::FetchQmlList:
qWarning() << idx << "\t" << line << "\t" << "FETCH_QMLLIST\t\t" << instr->fetchQmlList.property << "\t" << instr->fetchQmlList.type;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 40a0b84..440b54a 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -280,7 +280,7 @@ public:
int count;
} createComponent;
struct {
- int idx;
+ int id;
} fetchAttached;
struct {
int property;
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index e7f7cfb..780f8a8 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -550,7 +550,7 @@ QObject *QmlMetaPropertyPrivate::attachedObject() const
if(attachedFunc == -1)
return 0;
else
- return QmlMetaType::attachedPropertiesFuncById(attachedFunc)(object);
+ return qmlAttachedPropertiesObjectById(attachedFunc, object);
}
/*!
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index 51d5607..c12f01a 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -643,6 +643,18 @@ int QmlMetaType::attachedPropertiesFuncId(const QByteArray &name)
return -1;
}
+int QmlMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QmlMetaTypeData *data = metaTypeData();
+
+ QmlType *type = data->metaObjectToType.value(mo);
+ if(type && type->attachedPropertiesFunction())
+ return type->index();
+ else
+ return -1;
+}
+
QmlAttachedPropertiesFunc QmlMetaType::attachedPropertiesFuncById(int id)
{
if(id < 0)
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index 3daa14b..c17d47f 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -90,6 +90,7 @@ public:
static const QMetaObject *metaObjectForType(const QByteArray &);
static const QMetaObject *metaObjectForType(int);
static int attachedPropertiesFuncId(const QByteArray &);
+ static int attachedPropertiesFuncId(const QMetaObject *);
static QmlAttachedPropertiesFunc attachedPropertiesFuncById(int);
static QmlAttachedPropertiesFunc attachedPropertiesFunc(const QByteArray &);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index b6d9173..62a0864 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -860,14 +860,10 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
#endif
QObject *target = stack.top();
- QmlAttachedPropertiesFunc attachFunc =
- QmlMetaType::attachedPropertiesFunc(datas.at(instr.fetchAttached.idx));
- if(!attachFunc)
- VME_EXCEPTION("No such attached object" << primitives.at(instr.fetchAttached.idx));
+ QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
- QObject *qmlObject = attachFunc(target);
if(!qmlObject)
- VME_EXCEPTION("Internal error - unable to create attached object" << primitives.at(instr.fetchAttached.idx));
+ VME_EXCEPTION("Unable to create attached object");
stack.push(qmlObject);
}