diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri index 7a2a5189b02db3f23fa485a40611cc4af9722ca4..2bb894ef1bc863507fb34e10e2f23e3a5a0f8ee1 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/instances.pri @@ -14,6 +14,7 @@ HEADERS += $$PWD/componentnodeinstance.h HEADERS += $$PWD/dummynodeinstance.h HEADERS += $$PWD/nodeinstancemetaobject.h HEADERS += $$PWD/nodeinstanceserver.h +HEADERS += $$PWD/nodeinstancesignalspy.h HEADERS += $$PWD/objectnodeinstance.h HEADERS += $$PWD/qmlpropertychangesnodeinstance.h HEADERS += $$PWD/qmlstatenodeinstance.h @@ -38,6 +39,7 @@ SOURCES += $$PWD/componentnodeinstance.cpp SOURCES += $$PWD/dummynodeinstance.cpp SOURCES += $$PWD/nodeinstancemetaobject.cpp SOURCES += $$PWD/nodeinstanceserver.cpp +SOURCES += $$PWD/nodeinstancesignalspy.cpp SOURCES += $$PWD/objectnodeinstance.cpp SOURCES += $$PWD/qmlpropertychangesnodeinstance.cpp SOURCES += $$PWD/qmlstatenodeinstance.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..40de94aecc0333a6b656b323d5a7f1de2bd6478b --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "nodeinstancesignalspy.h" +#include "objectnodeinstance.h" + +#include <QMetaProperty> +#include <QMetaObject> +#include <QDebug> +#include <QSharedPointer> +#include <private/qqmlmetatype_p.h> + +namespace QmlDesigner { +namespace Internal { + +NodeInstanceSignalSpy::NodeInstanceSignalSpy() : + QObject() +{ + blockSignals(true); +} + +void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Pointer &nodeInstance) +{ + methodeOffset = QObject::staticMetaObject.methodCount() + 1; + registerObject(nodeInstance->object()); + m_objectNodeInstance = nodeInstance; + +} + +void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const PropertyName &prefix) +{ + if (m_registeredObjectList.contains(spiedObject)) // prevent cycles + return; + + m_registeredObjectList.append(spiedObject); + for (int index = QObject::staticMetaObject.propertyOffset(); + index < spiedObject->metaObject()->propertyCount(); + index++) { + QMetaProperty metaProperty = spiedObject->metaObject()->property(index); + + // handle dot properties and connect the signals to the object + if (metaProperty.isReadable() + && !metaProperty.isWritable() + && QQmlMetaType::isQObject(metaProperty.userType())) { + QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject)); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + '.'); + } else if (metaProperty.hasNotifySignal()) { + QMetaMethod metaMethod = metaProperty.notifySignal(); + bool isConnecting = QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection); + Q_ASSERT(isConnecting); + Q_UNUSED(isConnecting); + m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name()); + methodeOffset++; + } + + // search recursive in objects + if (metaProperty.isReadable() + && metaProperty.isWritable() + && QQmlMetaType::isQObject(metaProperty.userType()) + && QLatin1String(metaProperty.name()) != QLatin1String("parent")) { + QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject)); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + '/'); + } + + // search recursive in objects list + if (metaProperty.isReadable() + && QQmlMetaType::isList(metaProperty.userType())) { + QQmlListReference list(spiedObject, metaProperty.name()); + + if (list.canCount() && list.canAt()) { + + for (int i = 0; i < list.count(); i++) { + QObject *propertyObject = list.at(i); + if (propertyObject) + registerObject(propertyObject, prefix + metaProperty.name() + '/'); + } + } + } + } +} + +int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, void **a) +{ + if (call == QMetaObject::InvokeMetaMethod && methodId > QObject::staticMetaObject.methodCount()) { + ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef(); + + if (nodeInstance && nodeInstance->nodeInstanceServer() && nodeInstance->isValid()) { + nodeInstance->nodeInstanceServer()->notifyPropertyChange(nodeInstance->instanceId(), m_indexPropertyHash.value(methodId)); + } + + } + + return QObject::qt_metacall(call, methodId, a); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.h new file mode 100644 index 0000000000000000000000000000000000000000..8c1bb7c059b483ea121765e539178c4c94dcf4cc --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstancesignalspy.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef NODEINSTANCESIGNALSPY_H +#define NODEINSTANCESIGNALSPY_H + +#include <QObject> +#include <QHash> +#include <QSharedPointer> + +#include "nodeinstanceglobal.h" + +namespace QmlDesigner { + +namespace Internal { + +class ObjectNodeInstance; +typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer; +typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer; + +class NodeInstanceSignalSpy : public QObject +{ +public: + explicit NodeInstanceSignalSpy(); + + void setObjectNodeInstance(const ObjectNodeInstancePointer &nodeInstance); + + virtual int qt_metacall(QMetaObject::Call, int, void **); + +protected: + void registerObject(QObject *spiedObject, const PropertyName &prefix = PropertyName()); + +private: + int methodeOffset; + QHash<int, PropertyName> m_indexPropertyHash; + QObjectList m_registeredObjectList; + ObjectNodeInstanceWeakPointer m_objectNodeInstance; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // NODEINSTANCESIGNALSPY_H diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index b4eeffdb25652a6ad3b28fcdf60fcf6b68d7d884..76762c3b60a3c36c7e6da726f26f00fb58d21e34 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -178,6 +178,8 @@ void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Poi } } } + + m_signalSpy.setObjectNodeInstance(objectNodeInstance); } void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h index 34a4c87839733a2fb4656f170d9b2221cb965d31..b7f6b51307b05a7a20634a236ff1cbc0bbe9286d 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.h @@ -32,6 +32,7 @@ #include "nodeinstanceserver.h" #include "nodeinstancemetaobject.h" +#include "nodeinstancesignalspy.h" #include <QPainter> #include <QSharedPointer> @@ -202,6 +203,7 @@ private: QPointer<QObject> m_object; NodeInstanceMetaObject *m_metaObject; + NodeInstanceSignalSpy m_signalSpy; qint32 m_instanceId; bool m_deleteHeldInstance; bool m_isInLayoutable;