From 0ff51c1932accca771382050efbc093404e440f1 Mon Sep 17 00:00:00 2001
From: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Date: Thu, 28 Jan 2010 17:50:09 +0100
Subject: [PATCH] QmlDesigner.propertyEditor: refactoring of PropertyEditor

---
 .../propertyeditor/propertyeditor.cpp         | 83 +++++++++----------
 .../propertyeditor/propertyeditor.h           |  7 +-
 .../propertyeditor/propertyeditorvalue.cpp    | 21 +----
 .../propertyeditor/propertyeditorvalue.h      |  5 +-
 4 files changed, 49 insertions(+), 67 deletions(-)

diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
index 6e2b53dfdc3..5e5cd134c34 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp
@@ -74,7 +74,7 @@ PropertyEditor::NodeType::~NodeType()
 {
 }
 
-void createPropertyEditorValue(const QmlObjectNode &fxObjectNode, const QString &name, const QVariant &value, QmlPropertyMap *propertyMap)
+void createPropertyEditorValue(const QmlObjectNode &fxObjectNode, const QString &name, const QVariant &value, QmlPropertyMap *propertyMap, PropertyEditor *propertyEditor)
 {
     QString propertyName(name);
     propertyName.replace(".", "_");
@@ -82,12 +82,11 @@ void createPropertyEditorValue(const QmlObjectNode &fxObjectNode, const QString
     if (!valueObject) {
         valueObject = new PropertyEditorValue(propertyMap);
         QObject::connect(valueObject, SIGNAL(valueChanged(QString)), propertyMap, SIGNAL(valueChanged(QString)));
+        QObject::connect(valueObject, SIGNAL(expressionChanged(QString)), propertyEditor, SLOT(changeExpression(QString)));
         propertyMap->insert(propertyName, QmlMetaType::qmlType(valueObject->metaObject())->fromObject(valueObject));
     }
     valueObject->setName(propertyName);
-    valueObject->setIsInModel(fxObjectNode.modelNode().hasProperty(name));
-    valueObject->setIsInSubState(fxObjectNode.propertyAffectedByCurrentState(name));
-    valueObject->setModelNode(fxObjectNode.modelNode());
+    valueObject->setModelNode(fxObjectNode);
 
     if (fxObjectNode.propertyAffectedByCurrentState(name) && !(fxObjectNode.modelNode().property(name).isBindingProperty())) {
         valueObject->setValue(fxObjectNode.modelValue(name));
@@ -113,22 +112,16 @@ void PropertyEditor::NodeType::setValue(const QmlObjectNode &fxObjectNode, const
         propertyValue->setValue(value);
 }
 
-void PropertyEditor::NodeType::setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile)
+void PropertyEditor::NodeType::setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditor *propertyEditor)
 {
     if (!fxObjectNode.isValid())
         return;
 
     QmlContext *ctxt = m_view->rootContext();
 
-    // First remove complex objects from backend, so that we don't trigger a flood of updates    
-
-    //foreach (const QString &propertyName, m_backendValuesPropertyMap.keys())
-    //    m_backendValuesPropertyMap.clear(propertyName);
-    //qDeleteAll(m_backendValuesPropertyMap.children());
-
     if (fxObjectNode.isValid()) {
         foreach (const QString &propertyName, fxObjectNode.modelNode().metaInfo().properties(true).keys())
-            createPropertyEditorValue(fxObjectNode, propertyName, fxObjectNode.instanceValue(propertyName), &m_backendValuesPropertyMap);
+            createPropertyEditorValue(fxObjectNode, propertyName, fxObjectNode.instanceValue(propertyName), &m_backendValuesPropertyMap, propertyEditor);
 
         // className
         PropertyEditorValue *valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
@@ -141,9 +134,7 @@ void PropertyEditor::NodeType::setup(const QmlObjectNode &fxObjectNode, const QS
         // id
         valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
         valueObject->setName("id");
-        valueObject->setIsInModel(!fxObjectNode.modelNode().id().isEmpty());
-        valueObject->setModelNode(fxObjectNode.modelNode());
-        valueObject->setValue(fxObjectNode.modelNode().id());
+        valueObject->setValue(fxObjectNode.id());
         QObject::connect(valueObject, SIGNAL(valueChanged(QString)), &m_backendValuesPropertyMap, SIGNAL(valueChanged(QString)));
         m_backendValuesPropertyMap.insert("id", QmlMetaType::qmlType(valueObject->metaObject())->fromObject(valueObject));
 
@@ -168,7 +159,8 @@ PropertyEditor::PropertyEditor(QWidget *parent) :
         m_updateShortcut(0),
         m_timerId(0),
         m_stackedWidget(new QStackedWidget(parent)),
-        m_currentType(0)
+        m_currentType(0),
+        m_locked(false)
 {
     m_updateShortcut = new QShortcut(QKeySequence("F5"), m_stackedWidget);
     connect(m_updateShortcut, SIGNAL(activated()), this, SLOT(reloadQml()));
@@ -190,6 +182,10 @@ void PropertyEditor::changeValue(const QString &name)
 {
     if (name.isNull())
         return;
+
+    if (m_locked)
+        return;
+
     if (name == "type")
         return;
 
@@ -249,7 +245,9 @@ void PropertyEditor::changeValue(const QString &name)
             fxObjectNode.removeVariantProperty(propertyName);
         } else {
             if (castedValue.isValid() && !castedValue.isNull())
+                m_locked = true;
                 fxObjectNode.setVariantProperty(propertyName, castedValue);
+                m_locked = false;
         }
     }
 
@@ -260,6 +258,12 @@ void PropertyEditor::changeValue(const QString &name)
 
 void PropertyEditor::changeExpression(const QString &name)
 {
+    if (name.isNull())
+        return;
+
+    if (m_locked)
+        return;
+
     QmlObjectNode fxObjectNode(m_selectedNode);
     PropertyEditorValue *value = qobject_cast<PropertyEditorValue*>(QmlMetaType::toQObject(m_currentType->m_backendValuesPropertyMap.value(name)));
     if (fxObjectNode.currentState().isBaseState()) {
@@ -267,42 +271,33 @@ void PropertyEditor::changeExpression(const QString &name)
     }
 }
 
-void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode)
+void PropertyEditor::anyPropertyChanged(const QmlObjectNode &fxObjectNode)
 {
     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") {
-                QString name(propertyName);
-                name.replace(".", "_");
-                QVariant backendValue(m_currentType->m_backendValuesPropertyMap.value(propertyName));
-                PropertyEditorValue *valueObject = 0;
-                if (backendValue.isValid())
-                    valueObject = qobject_cast<PropertyEditorValue*>(QmlMetaType::toQObject(backendValue));
-                else
-                    valueObject = new PropertyEditorValue(&m_currentType->m_backendValuesPropertyMap);
-
-                if (valueObject == 0) {
-                    qWarning() << "PropertyEditor: you propably assigned a wrong value to backendValues";
-                    return;
+                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()));
                 }
-
-                valueObject->setName(propertyName);
-                valueObject->setIsInModel(fxObjectNode.hasProperty(propertyName));
-                valueObject->setIsInSubState(fxObjectNode.propertyAffectedByCurrentState(propertyName));
-                valueObject->setModelNode(fxObjectNode.modelNode());
-
-                if (fxObjectNode.modelNode().property(propertyName).isBindingProperty())
-                    valueObject->setValue(fxObjectNode.instanceValue(propertyName));
-                else
-                    valueObject->setValue(fxObjectNode.modelValue(propertyName));
-
-                connect(valueObject, SIGNAL(valueChanged(QString)), &m_currentType->m_backendValuesPropertyMap, SIGNAL(valueChanged(QString)));
-                m_currentType->m_backendValuesPropertyMap.insert(propertyName, QmlMetaType::qmlType(valueObject->metaObject())->fromObject(valueObject));
             }
         }
     }
 }
 
+void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode)
+{
+    anyPropertyChanged(fxObjectNode);
+}
+
+void PropertyEditor::transformChanged(const QmlObjectNode &fxObjectNode)
+{
+    anyPropertyChanged(fxObjectNode);
+}
+
 void PropertyEditor::setQmlDir(const QString &qmlDir)
 {
     m_qmlDir = qmlDir;
@@ -356,7 +351,7 @@ void PropertyEditor::resetView()
             fxObjectNode = QmlObjectNode(m_selectedNode);
             Q_ASSERT(fxObjectNode.isValid());
         }
-        type->setup(fxObjectNode, currentState().name(), qmlSpecificsFile);
+        type->setup(fxObjectNode, currentState().name(), qmlSpecificsFile, this);
 
         QmlContext *ctxt = type->m_view->rootContext();
         ctxt->setContextProperty("finishedNotify", QVariant(false));
@@ -367,7 +362,7 @@ void PropertyEditor::resetView()
         if (m_selectedNode.isValid()) {
             fxObjectNode = QmlObjectNode(m_selectedNode);
         }
-        type->setup(fxObjectNode, currentState().name(), qmlSpecificsFile);
+        type->setup(fxObjectNode, currentState().name(), qmlSpecificsFile, this);
     }
 
     m_stackedWidget->setCurrentWidget(type->m_view);
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
index 6f3672ed8f8..0026f509b41 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h
@@ -51,7 +51,7 @@ class PropertyEditor: public QmlModelView
         NodeType(const QUrl &qmlFile, PropertyEditor *propertyEditor);
         ~NodeType();
 
-        void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile);
+        void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditor *propertyEditor);
         void setValue(const QmlObjectNode &fxObjectNode, const QString &name, const QVariant &value);
 
         QmlView *m_view;
@@ -82,6 +82,10 @@ public:
     ModelState modelState() const;
 
     void otherPropertyChanged(const QmlObjectNode &);
+    void transformChanged(const QmlObjectNode &qmlObjectNode);
+
+    void anyPropertyChanged(const QmlObjectNode &qmlObjectNode);
+
 
     void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
 
@@ -119,6 +123,7 @@ private: //variables
     QString m_qmlDir;
     QHash<QString, NodeType *> m_typeHash;
     NodeType *m_currentType;
+    bool m_locked;
 };
 
 }
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp
index 65c7b9b31a1..b2191943042 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp
@@ -82,7 +82,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
 {
     if ( m_value != value) {
         QVariant newValue = value;
-        if (modelNode().metaInfo().isValid() && modelNode().metaInfo().property(name()).isValid())
+        if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().property(name()).isValid())
             if (modelNode().metaInfo().property(name()).type() == QLatin1String("QUrl")) {
             newValue = QUrl(newValue.toString());
         }
@@ -115,7 +115,6 @@ void PropertyEditorValue::setExpressionWithEmit(const QString &expression)
 {
     if ( m_expression != expression) {
         setExpression(expression);
-        m_isBound = true;
         emit expressionChanged(name());
     }
 }
@@ -130,7 +129,7 @@ void PropertyEditorValue::setExpression(const QString &expression)
 
 bool PropertyEditorValue::isInSubState() const
 {
-    return m_isInSubState;
+    return modelNode().isValid() && QmlDesigner::QmlObjectNode(modelNode()).propertyAffectedByCurrentState(name());
 }
 
 bool PropertyEditorValue::isBound() const
@@ -138,22 +137,11 @@ bool PropertyEditorValue::isBound() const
     return modelNode().isValid() && modelNode().property(name()).isValid() && modelNode().property(name()).isBindingProperty();
 }
 
-void PropertyEditorValue::setIsInSubState(bool isInSubState)
-{
-    m_isInSubState = isInSubState;
-}
-
 bool PropertyEditorValue::isInModel() const
 {
-    return m_isInModel;
+    return modelNode().isValid() && modelNode().hasProperty(name());
 }
 
-void PropertyEditorValue::setIsInModel(bool isInModel)
-{
-    m_isInModel = isInModel;
-}
-
-
 QString PropertyEditorValue::name() const
 {
     return m_name;
@@ -315,9 +303,6 @@ void PropertyEditorNodeWrapper::setup()
         foreach (const QString &propertyName, m_modelNode.metaInfo().properties().keys()) {
             PropertyEditorValue *valueObject = new PropertyEditorValue(&m_valuesPropertyMap);
             valueObject->setName(propertyName);
-            valueObject->setIsInModel(fxObjectNode.hasProperty(propertyName));
-            valueObject->setIsInSubState(fxObjectNode.propertyAffectedByCurrentState(propertyName));
-            valueObject->setModelNode(fxObjectNode.modelNode());
             valueObject->setValue(fxObjectNode.instanceValue(propertyName));
 
             connect(valueObject, SIGNAL(valueChanged(QString)), &m_valuesPropertyMap, SIGNAL(valueChanged(QString)));
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h
index d9ec46b052e..7da8f9d4b42 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h
@@ -77,7 +77,7 @@ private:
 
 
 class PropertyEditorValue : public QObject
-{
+{ 
     Q_OBJECT
     Q_PROPERTY(QVariant value READ value WRITE setValueWithEmit NOTIFY valueChanged)
     Q_PROPERTY(QString expression READ expression WRITE setExpressionWithEmit NOTIFY expressionChanged FINAL)
@@ -100,7 +100,6 @@ public:
     void setExpression(const QString &expression);
 
     bool isInSubState() const;
-    void setIsInSubState(bool isInSubState);
 
     bool isInModel() const;
 
@@ -109,8 +108,6 @@ public:
 
     void setIsValid(bool valid);
 
-    void setIsInModel(bool isInModel);
-
     QString name() const;
     void setName(const QString &name);
 
-- 
GitLab