diff options
-rw-r--r-- | src/declarative/fx/qfxgridview.cpp | 9 | ||||
-rw-r--r-- | src/declarative/fx/qfxlistview.cpp | 9 | ||||
-rw-r--r-- | src/declarative/fx/qfxpathview.cpp | 8 | ||||
-rw-r--r-- | src/declarative/qml/qml.h | 16 | ||||
-rw-r--r-- | src/declarative/qml/qml.pri | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext_p.h | 8 | ||||
-rw-r--r-- | src/declarative/qml/qmldeclarativedata_p.h | 70 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 72 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.cpp | 12 | ||||
-rw-r--r-- | src/declarative/qml/qmlmetatype.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmlvme.cpp | 8 | ||||
-rw-r--r-- | src/declarative/widgets/graphicslayouts.cpp | 28 |
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 |