Commit 6585742f authored by Marco Bubke's avatar Marco Bubke
Browse files

Allways use a NodeInstanceMetaObject in ObjectNodeInstance

parent d43a4710
......@@ -498,7 +498,7 @@ QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode)
return QmlItemNode();
}
void FormEditorView::transformChanged(const QmlObjectNode &qmlObjectNode)
void FormEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &/*propertyName*/)
{
QmlItemNode itemNode = qmlObjectNode.toQmlItemNode();
if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) {
......@@ -523,7 +523,7 @@ void FormEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
}
}
void FormEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode)
void FormEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &/*propertyName*/)
{
Q_ASSERT(qmlObjectNode.isValid());
......@@ -546,19 +546,6 @@ void FormEditorView::setSelectOnlyContentItemsAction(bool selectOnlyContentItems
m_selectionTool->setSelectOnlyContentItems(selectOnlyContentItems);
}
void FormEditorView::updateItem(const QmlObjectNode &qmlObjectNode)
{
Q_ASSERT(qmlObjectNode.isValid());
QmlItemNode itemNode = findRecursiveQmlItemNode(qmlObjectNode);
if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) {
m_scene->synchronizeOtherProperty(itemNode);
m_currentTool->formEditorItemsChanged(QList<FormEditorItem*>() << m_scene->itemForQmlItemNode(itemNode));
}
}
void FormEditorView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
{
QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
......
......@@ -110,10 +110,9 @@ signals:
void ItemCreatorDeActivated();
protected:
void transformChanged(const QmlObjectNode &qmlObjectNode);
void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void parentChanged(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &qmlObjectNode);
void updateItem(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
protected slots:
......
......@@ -351,54 +351,36 @@ void PropertyEditor::changeExpression(const QString &name)
}
}
void PropertyEditor::anyPropertyChanged(const QmlObjectNode &fxObjectNode)
void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode, const QString &propertyName)
{
QmlModelView::otherPropertyChanged(fxObjectNode, propertyName);
if (fxObjectNode.isValid() && m_currentType && fxObjectNode == m_selectedNode && fxObjectNode.currentState().isValid()) {
foreach (const QString &propertyName, fxObjectNode.modelNode().metaInfo().properties(true).keys()) {
if ( propertyName != "id" && propertyName != "objectName") {
AbstractProperty property = fxObjectNode.modelNode().property(propertyName);
if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) {
if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName))
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
else
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
}
}
AbstractProperty property = fxObjectNode.modelNode().property(propertyName);
if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) {
if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName))
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
else
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
}
}
}
void PropertyEditor::geometryPropertyChanged(const QmlObjectNode &fxObjectNode)
void PropertyEditor::transformChanged(const QmlObjectNode &fxObjectNode, const QString &propertyName)
{
QmlModelView::transformChanged(fxObjectNode, propertyName);
if (fxObjectNode.isValid() && m_currentType && fxObjectNode == m_selectedNode && fxObjectNode.currentState().isValid()) {
QStringList geometryProperties;
geometryProperties << "x" << "y" << "width" << "height" << "rotation" << "scale";
foreach (const QString &propertyName, geometryProperties) {
if ( propertyName != "id" && propertyName != "objectName") {
AbstractProperty property = fxObjectNode.modelNode().property(propertyName);
if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) {
if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName))
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
else
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
}
}
AbstractProperty property = fxObjectNode.modelNode().property(propertyName);
if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) {
if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName))
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name()));
else
m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name()));
}
}
}
void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode)
{
QmlModelView::otherPropertyChanged(fxObjectNode);
anyPropertyChanged(fxObjectNode);
}
void PropertyEditor::transformChanged(const QmlObjectNode &fxObjectNode)
{
QmlModelView::transformChanged(fxObjectNode);
geometryPropertyChanged(fxObjectNode);
}
void PropertyEditor::setQmlDir(const QString &qmlDir)
{
m_qmlDir = qmlDir;
......
......@@ -86,10 +86,6 @@ public:
void anyPropertyChanged(const QmlObjectNode &qmlObjectNode);
void geometryPropertyChanged(const QmlObjectNode &fxObjectNode);
void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
......@@ -99,8 +95,8 @@ public:
protected:
void timerEvent(QTimerEvent *event);
void otherPropertyChanged(const QmlObjectNode &);
void transformChanged(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &, const QString &propertyName);
void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void setupPane(const QString &typeName);
void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
......
......@@ -52,13 +52,6 @@ StatesEditorView::StatesEditorView(StatesEditorModel *editorModel, QObject *pare
m_editorModel(editorModel)
{
Q_ASSERT(m_editorModel);
connect(nodeInstanceView(), SIGNAL(instanceRemoved(NodeInstance)), this, SLOT(sceneChanged()));
connect(nodeInstanceView(), SIGNAL(transformPropertyChanged(NodeInstance)), this, SLOT(sceneChanged()));
connect(nodeInstanceView(), SIGNAL(parentPropertyChanged(NodeInstance)), this, SLOT(sceneChanged()));
connect(nodeInstanceView(), SIGNAL(otherPropertyChanged(NodeInstance)), this, SLOT(sceneChanged()));
connect(nodeInstanceView(), SIGNAL(updateItem(NodeInstance)), this, SLOT(sceneChanged()));
}
void StatesEditorView::setCurrentStateSilent(int index)
......@@ -304,9 +297,9 @@ void StatesEditorView::stateChanged(const QmlModelState &newQmlModelState, const
m_editorModel->emitChangedToState(m_modelStates.indexOf(newQmlModelState));
}
void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode)
void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
QmlModelView::transformChanged(qmlObjectNode);
QmlModelView::transformChanged(qmlObjectNode, propertyName);
}
void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
......@@ -314,15 +307,11 @@ void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
QmlModelView::parentChanged(qmlObjectNode);
}
void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode)
void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
QmlModelView::otherPropertyChanged(qmlObjectNode);
QmlModelView::otherPropertyChanged(qmlObjectNode, propertyName);
}
void StatesEditorView::updateItem(const QmlObjectNode &qmlObjectNode)
{
QmlModelView::updateItem(qmlObjectNode);
}
void StatesEditorView::customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data)
{
......
......@@ -69,10 +69,9 @@ protected:
// QmlModelView
void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
void transformChanged(const QmlObjectNode &qmlObjectNode) ;
void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void parentChanged(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &qmlObjectNode);
void updateItem(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data);
......
......@@ -94,7 +94,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/instances/qmltransitionnodeinstance.cpp \
$$PWD/exceptions/rewritingexception.cpp \
$$PWD/instances/nodeinstancemetaobject.cpp \
$$PWD/instances/behaviornodeinstance.cpp
$$PWD/instances/behaviornodeinstance.cpp \
$$PWD/instances/nodeinstancesignalspy.cpp
HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/abstractview.h \
$$PWD/include/nodeinstanceview.h \
......@@ -185,7 +186,8 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/customnotifications.h \
$$PWD/include/rewritingexception.h \
$$PWD/instances/nodeinstancemetaobject.h \
$$PWD/instances/behaviornodeinstance.h
$$PWD/instances/behaviornodeinstance.h \
$$PWD/instances/nodeinstancesignalspy.h
DISTFILES += $$PWD/metafile/widget.metafile
RESOURCES += $$PWD/core.qrc
OTHER_FILES += $$PWD/metainfo/gui.metainfo
......@@ -109,18 +109,16 @@ public:
QRectF sceneRect() const;
void setBlockChangeSignal(bool block);
void notifyPropertyChange(const ModelNode &modelNode, const QString &propertyName);
void setQmlModelView(QmlModelView *qmlModelView);
QmlModelView *qmlModelView() const ;
signals:
void instanceRemoved(const NodeInstance &nodeInstance);
void transformPropertyChanged(const NodeInstance &nodeInstance);
void parentPropertyChanged(const NodeInstance &nodeInstance);
void otherPropertyChanged(const NodeInstance &nodeInstance);
void updateItem(const NodeInstance &nodeInstance);
private slots:
void emitOtherPropertyChanged();
void emitParentPropertyChanged();
void emitTransformPropertyChanged();
void emitUpdateItem(QObject *object);
void emitParentChanged(QObject *child);
private: // functions
NodeInstance loadNode(const ModelNode &rootNode, QObject *objectToBeWrapped = 0);
......@@ -147,6 +145,8 @@ private: //variables
QWeakPointer<QmlEngine> m_engine;
QWeakPointer<Internal::ChildrenChangeEventFilter> m_childrenChangeEventFilter;
QWeakPointer<QmlModelView> m_qmlModelView;
bool m_blockChangeSignal;
};
......
......@@ -88,22 +88,17 @@ public:
void modelAttached(Model *model);
void modelAboutToBeDetached(Model *model);
virtual void nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName);
protected:
NodeInstance instanceForModelNode(const ModelNode &modelNode);
bool hasInstanceForModelNode(const ModelNode &modelNode);
NodeInstanceView *nodeInstanceView() const;
virtual void transformChanged(const QmlObjectNode &qmlObjectNode) ;
virtual void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName) ;
virtual void parentChanged(const QmlObjectNode &qmlObjectNode);
virtual void otherPropertyChanged(const QmlObjectNode &qmlObjectNode);
virtual void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
virtual void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
virtual void updateItem(const QmlObjectNode &qmlObjectNode);
private slots:
void notifyTransformChanged(const NodeInstance &nodeInstance);
void notifyParentChanged(const NodeInstance &nodeInstance);
void notifyOtherPropertyChanged(const NodeInstance &nodeInstance);
void notifyUpdateItem(const NodeInstance &nodeInstance);
private:
QmlModelState m_state;
......
......@@ -183,6 +183,8 @@ NodeInstance NodeInstance::create(NodeInstanceView *nodeInstanceView, const Mode
instance.m_nodeInstance->setNodeInstanceView(nodeInstanceView);
instance.m_nodeInstance->initializePropertyWatcher(instance.m_nodeInstance);
instance.setId(node.id());
foreach (const VariantProperty &property, node.variantProperties()) {
......
#include "nodeinstancemetaobject.h"
#include "objectnodeinstance.h"
#include <QSharedPointer>
#include <qnumeric.h>
namespace QmlDesigner {
namespace Internal {
NodeInstanceMetaObject::NodeInstanceMetaObject(QObject *object, QmlContext *context)
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstance::Pointer &nodeInstance)
: QmlOpenMetaObject(nodeInstance->object()),
m_nodeInstance(nodeInstance),
m_context(nodeInstance->modelNode().isRootNode() ? nodeInstance->context() : 0)
{
}
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix)
: QmlOpenMetaObject(object),
m_context(context)
m_nodeInstance(nodeInstance),
m_prefix(prefix)
{
}
......@@ -14,37 +26,73 @@ void NodeInstanceMetaObject::createNewProperty(const QString &name)
createProperty(name.toLatin1(), 0);
}
int NodeInstanceMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
{
if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
int metaCallReturnValue = -1;
if (call == QMetaObject::WriteProperty
&& reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
&& qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
return -1;
}
QVariant oldValue;
if (call == QMetaObject::WriteProperty && !property(id).hasNotifySignal())
{
oldValue = property(id).read(m_nodeInstance->object());
}
if (( call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty)
&& id >= type()->propertyOffset()) {
int propId = id - type()->propertyOffset();
if (c == QMetaObject::ReadProperty) {
if (call == QMetaObject::ReadProperty) {
propertyRead(propId);
*reinterpret_cast<QVariant *>(a[0]) = value(propId);
} else if (c == QMetaObject::WriteProperty) {
} else if (call == QMetaObject::WriteProperty) {
if (value(propId) != *reinterpret_cast<QVariant *>(a[0])) {
propertyWrite(propId);
setValue(propId, *reinterpret_cast<QVariant *>(a[0]));
propertyWritten(propId);
dynamicPropertyWritten(propId);
notifyPropertyChange(id);
activate(object(), type()->signalOffset() + propId, 0);
}
}
return -1;
} else {
if (parent())
return parent()->metaCall(c, id, a);
metaCallReturnValue = parent()->metaCall(call, id, a);
else
return object()->qt_metacall(c, id, a);
metaCallReturnValue = object()->qt_metacall(call, id, a);
if (call == QMetaObject::WriteProperty
&& !property(id).hasNotifySignal()
&& oldValue != property(id).read(m_nodeInstance->object()))
notifyPropertyChange(id);
}
return metaCallReturnValue;
}
void NodeInstanceMetaObject::propertyWritten(int propertyId)
void NodeInstanceMetaObject::dynamicPropertyWritten(int propertyId)
{
if (m_context)
m_context->setContextProperty(name(propertyId), value(propertyId));
}
void NodeInstanceMetaObject::notifyPropertyChange(int id)
{
ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef();
if (objectNodeInstance && objectNodeInstance->nodeInstanceView()) {
if (id < type()->propertyOffset()) {
objectNodeInstance->nodeInstanceView()->notifyPropertyChange(objectNodeInstance->modelNode(), m_prefix + property(id).name());
} else {
objectNodeInstance->nodeInstanceView()->notifyPropertyChange(objectNodeInstance->modelNode(), m_prefix + name(id - type()->propertyOffset()));
}
}
}
} // namespace Internal
} // namespace QmlDesigner
......@@ -7,17 +7,25 @@
namespace QmlDesigner {
namespace Internal {
class ObjectNodeInstance;
typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer;
typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer;
class NodeInstanceMetaObject : public QmlOpenMetaObject
{
public:
NodeInstanceMetaObject(QObject *object, QmlContext *context);
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance);
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix);
void createNewProperty(const QString &name);
protected:
int metaCall(QMetaObject::Call _c, int _id, void **_a);
void propertyWritten(int);
void dynamicPropertyWritten(int);
void notifyPropertyChange(int id);
private:
ObjectNodeInstanceWeakPointer m_nodeInstance;
QString m_prefix;
QWeakPointer<QmlContext> m_context;
};
......
#include "nodeinstancesignalspy.h"
#include <QMetaProperty>
#include <QMetaObject>
#include <QtDebug>
#include <private/qmlmetaproperty_p.h>
#include "objectnodeinstance.h"
#include <QSharedPointer>
namespace QmlDesigner {
namespace Internal {
NodeInstanceSignalSpy::NodeInstanceSignalSpy() :
QObject()
{
}
void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Pointer &nodeInstance)
{
methodeOffset = QObject::staticMetaObject.methodCount() + 1;
registerObject(nodeInstance->object());
m_objectNodeInstance = nodeInstance;
}
void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix)
{
for (int index = QObject::staticMetaObject.propertyOffset();
index < spiedObject->metaObject()->propertyCount();
index++) {
QMetaProperty metaProperty = spiedObject->metaObject()->property(index);
if (metaProperty.isReadable()
&& !metaProperty.isWritable()
&& QmlMetaType::isQObject(metaProperty.userType())) {
QObject *propertyObject = QmlMetaType::toQObject(metaProperty.read(spiedObject));
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);
m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name());
methodeOffset++;
}
}
}
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->nodeInstanceView()) {
nodeInstance->nodeInstanceView()->notifyPropertyChange(nodeInstance->modelNode(), m_indexPropertyHash.value(methodId));
}
}
return QObject::qt_metacall(call, methodId, a);
}
} // namespace Internal
} // namespace QmlDesigner
#ifndef NODEINSTANCESIGNALSPY_H
#define NODEINSTANCESIGNALSPY_H
#include <QObject>
#include <QHash>
#include <QSharedPointer>
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 QString &prefix = QString());
private:
int methodeOffset;
QHash<int, QString> m_indexPropertyHash;
ObjectNodeInstanceWeakPointer m_objectNodeInstance;
};
} // namespace Internal
} // namespace QmlDesigner
#endif // NODEINSTANCESIGNALSPY_H
......@@ -56,6 +56,8 @@
#include "objectnodeinstance.h"
#include "qmlmodelview.h"
enum {
debug = false
};
......@@ -459,43 +461,13 @@ NodeInstance NodeInstanceView::rootNodeInstance() const
\see NodeInstance
*/
static bool isTransformProperty(const QString &name)
{
static QStringList transformProperties(QStringList() << "xChanged()"
<< "yChanged()"
<< "zChanged()"
<< "rotationChanged()"
<< "scaleChanged()"
<< "widthChanged()"
<< "heightChanged()"
<< "transformOriginChanged(TransformOrigin)");
return transformProperties.contains(name);
}
void NodeInstanceView::insertInstanceNodeRelationship(const ModelNode &node, const NodeInstance &instance)
{
// connect with every signal of the object to get the formeditor updated
int otherPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitOtherPropertyChanged()");
int transformPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitTransformPropertyChanged()");
int parentPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitParentPropertyChanged()");
for (int index = QObject::staticMetaObject.methodCount();
index < instance.internalObject()->metaObject()->methodCount();