diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-04-28 05:05:53 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-04-28 05:05:53 (GMT) |
commit | 2b8abf28d10a6d064fe116892161289be5ffb391 (patch) | |
tree | 6a1123766682c82bddbdf358316f26e11f6976c7 /src/declarative/qml | |
parent | d7ffaa8ccbf881d25004b9a710259701d1a8c9bc (diff) | |
parent | a6ffd7c7c28066f2794579bc40e7b9517e76d1ff (diff) | |
download | Qt-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.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 |
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); } |