From 780899b1db6f685fce1296412f2571527da5fdbe Mon Sep 17 00:00:00 2001
From: Marco Bubke <marco.bubke@nokia.com>
Date: Tue, 16 Feb 2010 19:52:21 +0100
Subject: [PATCH] Refactor state changes in Bauhaus

---
 .../core/include/nodeinstanceview.h           |  3 +
 .../qmldesigner/core/include/qmlmodelview.h   |  2 +
 .../core/instances/nodeinstanceview.cpp       | 11 +++-
 .../core/instances/qmlstatenodeinstance.cpp   |  2 +
 .../qmldesigner/core/model/qmlmodelview.cpp   | 66 +++++++++++++------
 5 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/src/plugins/qmldesigner/core/include/nodeinstanceview.h b/src/plugins/qmldesigner/core/include/nodeinstanceview.h
index c68c11b8c78..daca5049944 100644
--- a/src/plugins/qmldesigner/core/include/nodeinstanceview.h
+++ b/src/plugins/qmldesigner/core/include/nodeinstanceview.h
@@ -114,6 +114,8 @@ public:
     void setQmlModelView(QmlModelView *qmlModelView);
     QmlModelView *qmlModelView() const ;
 
+    void setBlockStatePropertyChanges(bool block);
+
 signals:
     void instanceRemoved(const NodeInstance &nodeInstance);
 
@@ -148,6 +150,7 @@ private: //variables
     QWeakPointer<QmlModelView> m_qmlModelView;
 
     bool m_blockChangeSignal;
+    bool m_blockStatePropertyChanges;
 };
 
 }
diff --git a/src/plugins/qmldesigner/core/include/qmlmodelview.h b/src/plugins/qmldesigner/core/include/qmlmodelview.h
index ff236d9aa5c..ba32f40c31f 100644
--- a/src/plugins/qmldesigner/core/include/qmlmodelview.h
+++ b/src/plugins/qmldesigner/core/include/qmlmodelview.h
@@ -99,6 +99,8 @@ protected:
     virtual void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
     virtual void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
 
+    void activateState(const QmlModelState &state);
+    void changeToState(const ModelNode &node, const QString &stateName);
 
 private:
     QmlModelState m_state;
diff --git a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp
index 3e5c09cb2ab..a047423da95 100644
--- a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp
+++ b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp
@@ -92,7 +92,8 @@ NodeInstanceView::NodeInstanceView(QObject *parent)
         : AbstractView(parent),
     m_graphicsView(new QGraphicsView),
     m_engine(new QmlEngine(this)),
-    m_blockChangeSignal(false)
+    m_blockChangeSignal(false),
+    m_blockStatePropertyChanges(false)
 {
     m_graphicsView->setAttribute(Qt::WA_DontShowOnScreen, true);
     m_graphicsView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
@@ -500,6 +501,9 @@ void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node)
 
 void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString &propertyName)
 {
+    if (m_blockStatePropertyChanges && propertyName == "state")
+        return;
+
     if (qmlModelView()) {
         qmlModelView()->nodeInstancePropertyChanged(ModelNode(node,qmlModelView()), propertyName);
     }
@@ -516,6 +520,11 @@ QmlModelView *NodeInstanceView::qmlModelView() const
     return m_qmlModelView.data();
 }
 
+void NodeInstanceView::setBlockStatePropertyChanges(bool block)
+{
+    m_blockStatePropertyChanges = block;
+}
+
 void NodeInstanceView::emitParentChanged(QObject *child)
 {
     if (hasInstanceForObject(child)) {
diff --git a/src/plugins/qmldesigner/core/instances/qmlstatenodeinstance.cpp b/src/plugins/qmldesigner/core/instances/qmlstatenodeinstance.cpp
index 33ae98274ff..cfd973bb669 100644
--- a/src/plugins/qmldesigner/core/instances/qmlstatenodeinstance.cpp
+++ b/src/plugins/qmldesigner/core/instances/qmlstatenodeinstance.cpp
@@ -76,8 +76,10 @@ void QmlStateNodeInstance::deactivateState()
 
 void QmlStateNodeInstance::refreshState()
 {
+    nodeInstanceView()->setBlockStatePropertyChanges(true);
     deactivateState();
     activateState();
+    nodeInstanceView()->setBlockStatePropertyChanges(false);
 }
 
 QmlState *QmlStateNodeInstance::stateObject() const
diff --git a/src/plugins/qmldesigner/core/model/qmlmodelview.cpp b/src/plugins/qmldesigner/core/model/qmlmodelview.cpp
index 58fa14c13da..1d04a20e7d9 100644
--- a/src/plugins/qmldesigner/core/model/qmlmodelview.cpp
+++ b/src/plugins/qmldesigner/core/model/qmlmodelview.cpp
@@ -49,9 +49,9 @@ QmlModelView::QmlModelView(QObject *parent)
 
 void QmlModelView::setCurrentState(const QmlModelState &state)
 {
-    if (m_state == state)
+    if (!state.isValid())
         return;
-    QmlModelState oldState = m_state;
+
     emitCustomNotification("__state changed__", QList<ModelNode>() << state.modelNode());
 }
 
@@ -223,9 +223,9 @@ void QmlModelView::customNotification(const AbstractView * /* view */, const QSt
     if (identifier == "__state changed__") {
         QmlModelState state(nodeList.first());
         if (state.isValid())
-            stateChanged(state, currentState());
+            activateState(state);
         else
-            stateChanged(baseState(), currentState());
+            activateState(baseState());
     }
 }
 
@@ -283,10 +283,52 @@ void QmlModelView::nodeInstancePropertyChanged(const ModelNode &node, const QStr
         transformChanged(qmlObjectNode, propertyName);
     else if (propertyName == "parent")
         parentChanged(qmlObjectNode);
+    else if (propertyName == "state")
+        changeToState(node, qmlObjectNode.instanceValue(propertyName).toString());
     else
         otherPropertyChanged(qmlObjectNode, propertyName);
 }
 
+void QmlModelView::activateState(const QmlModelState &state)
+{
+    if (!state.isValid())
+        return;
+
+    if (m_state == state)
+        return;
+
+    QmlModelState oldState = m_state;
+
+    NodeInstance newStateInstance = instanceForModelNode(state.modelNode());
+    NodeInstance oldStateInstance = instanceForModelNode(oldState.modelNode());
+    if (state.isBaseState()) {
+        oldStateInstance.deactivateState();
+    } else {
+        newStateInstance.activateState();
+    }
+}
+
+void QmlModelView::changeToState(const ModelNode &node, const QString &stateName)
+{
+    QmlItemNode itemNode(node);
+
+
+    QmlModelState newState;
+    if (stateName.isEmpty())
+        newState = baseState();
+    else
+        newState = itemNode.states().state(stateName);
+
+
+    QmlModelState  oldState = m_state;
+
+    if (newState.isValid())
+        m_state = newState;
+
+    stateChanged(newState, oldState);
+}
+
+
 void QmlModelView::transformChanged(const QmlObjectNode &/*qmlObjectNode*/, const QString &/*propertyName*/)
 {
 }
@@ -302,22 +344,8 @@ void QmlModelView::otherPropertyChanged(const QmlObjectNode &/*qmlObjectNode*/,
 }
 
 
-void  QmlModelView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
+void  QmlModelView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &/*oldQmlModelState*/)
 {
-    m_state = newQmlModelState;
-    if (newQmlModelState.isValid()) {
-        NodeInstance newStateInstance = instanceForModelNode(newQmlModelState.modelNode());
-        Q_ASSERT(newStateInstance.isValid());
-        if (!newQmlModelState.isBaseState())
-            newStateInstance.activateState();
-    }
-
-    if (oldQmlModelState.isValid()) {
-        NodeInstance oldStateInstance = instanceForModelNode(oldQmlModelState.modelNode());
-        Q_ASSERT(oldStateInstance.isValid());
-        if (!oldQmlModelState.isBaseState())
-            oldStateInstance.deactivateState();
-    }
 }
 
 } //QmlDesigner
-- 
GitLab