summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/fx/qfxgridview.cpp9
-rw-r--r--src/declarative/fx/qfxlistview.cpp9
-rw-r--r--src/declarative/fx/qfxpathview.cpp8
-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
-rw-r--r--src/declarative/widgets/graphicslayouts.cpp28
16 files changed, 196 insertions, 60 deletions
diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp
index 5e4baac..25c1565 100644
--- a/src/declarative/fx/qfxgridview.cpp
+++ b/src/declarative/fx/qfxgridview.cpp
@@ -79,12 +79,9 @@ public:
}
static QFxGridViewAttached *properties(QObject *obj) {
- if(!attachedProperties.contains(obj)) {
- QFxGridViewAttached *rv = new QFxGridViewAttached(obj);
- attachedProperties.insert(obj, rv);
- return rv;
- }
- return attachedProperties.value(obj);
+ QFxGridViewAttached *rv = new QFxGridViewAttached(obj);
+ attachedProperties.insert(obj, rv);
+ return rv;
}
void emitAdd() { emit add(); }
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index e03ec47..c85d8ce 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -98,12 +98,9 @@ public:
}
static QFxListViewAttached *properties(QObject *obj) {
- if(!attachedProperties.contains(obj)) {
- QFxListViewAttached *rv = new QFxListViewAttached(obj);
- attachedProperties.insert(obj, rv);
- return rv;
- }
- return attachedProperties.value(obj);
+ QFxListViewAttached *rv = new QFxListViewAttached(obj);
+ attachedProperties.insert(obj, rv);
+ return rv;
}
void emitAdd() { emit add(); }
diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp
index 1bf7dda..59c7cd1 100644
--- a/src/declarative/fx/qfxpathview.cpp
+++ b/src/declarative/fx/qfxpathview.cpp
@@ -830,11 +830,9 @@ void QFxPathViewPrivate::snapToCurrent()
QHash<QObject*, QObject*> QFxPathView::attachedProperties;
QObject *QFxPathView::qmlAttachedProperties(QObject *obj)
{
- if(!attachedProperties.contains(obj)) {
- QFxPathViewAttached *rv = new QFxPathViewAttached(obj);
- attachedProperties.insert(obj, rv);
- }
- return attachedProperties.value(obj);
+ QFxPathViewAttached *rv = new QFxPathViewAttached(obj);
+ attachedProperties.insert(obj, rv);
+ return rv;
}
QT_END_NAMESPACE
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 65e6763..c44e8c5 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 5436227..7535bc7 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -909,8 +909,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 66c41f2..ad4a627 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);
}
diff --git a/src/declarative/widgets/graphicslayouts.cpp b/src/declarative/widgets/graphicslayouts.cpp
index 1ecde71..8e0081b 100644
--- a/src/declarative/widgets/graphicslayouts.cpp
+++ b/src/declarative/widgets/graphicslayouts.cpp
@@ -150,18 +150,17 @@ void QGraphicsLinearLayoutObject::updateAlignment(QGraphicsLayoutItem *item, Qt:
QHash<QGraphicsLayoutItem*, QObject*> QGraphicsLinearLayoutObject::attachedProperties;
QObject *QGraphicsLinearLayoutObject::qmlAttachedProperties(QObject *obj)
{
+ // ### This is not allowed - you must attach to any object
if (!qobject_cast<QGraphicsLayoutItem*>(obj))
return 0;
- if(!attachedProperties.contains(qobject_cast<QGraphicsLayoutItem*>(obj))) {
- LinearLayoutAttached *rv = new LinearLayoutAttached(obj);
- /*if (QGraphicsLinearLayoutObject *lo = qobject_cast<QGraphicsLinearLayoutObject*>(obj->parent()))
- QObject::connect(rv, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)),
- lo, SLOT(updateStretch(QGraphicsLayoutItem*,int)));
- QObject::connect(rv, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)),
- lo, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment)));*/
- attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv);
- }
- return attachedProperties.value(qobject_cast<QGraphicsLayoutItem*>(obj));
+ LinearLayoutAttached *rv = new LinearLayoutAttached(obj);
+ /*if (QGraphicsLinearLayoutObject *lo = qobject_cast<QGraphicsLinearLayoutObject*>(obj->parent()))
+ QObject::connect(rv, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)),
+ lo, SLOT(updateStretch(QGraphicsLayoutItem*,int)));
+ QObject::connect(rv, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)),
+ lo, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment)));*/
+ attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv);
+ return rv;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -311,13 +310,12 @@ qreal QGraphicsGridLayoutObject::spacing() const
QHash<QGraphicsLayoutItem*, QObject*> QGraphicsGridLayoutObject::attachedProperties;
QObject *QGraphicsGridLayoutObject::qmlAttachedProperties(QObject *obj)
{
+ // ### This is not allowed - you must attach to any object
if (!qobject_cast<QGraphicsLayoutItem*>(obj))
return 0;
- if(!attachedProperties.contains(qobject_cast<QGraphicsLayoutItem*>(obj))) {
- GridLayoutAttached *rv = new GridLayoutAttached(obj);
- attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv);
- }
- return attachedProperties.value(qobject_cast<QGraphicsLayoutItem*>(obj));
+ GridLayoutAttached *rv = new GridLayoutAttached(obj);
+ attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv);
+ return rv;
}
QT_END_NAMESPACE