OSDN Git Service

QmlDesigner: Refactor states editor
authorMarco Bubke <marco.bubke@nokia.com>
Wed, 8 Dec 2010 15:46:25 +0000 (16:46 +0100)
committerMarco Bubke <marco.bubke@nokia.com>
Wed, 8 Dec 2010 16:28:50 +0000 (17:28 +0100)
Reviewed-By: Thomas Hartmann
41 files changed:
src/plugins/qmldesigner/components/integration/componentview.cpp
src/plugins/qmldesigner/components/integration/componentview.h
src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp
src/plugins/qmldesigner/components/integration/designdocumentcontroller.h
src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp
src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h
src/plugins/qmldesigner/components/navigator/navigatorview.cpp
src/plugins/qmldesigner/components/navigator/navigatorview.h
src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp
src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h
src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp
src/plugins/qmldesigner/components/stateseditor/stateseditorview.h
src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp
src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h
src/plugins/qmldesigner/components/stateseditor/stateslist.qml
src/plugins/qmldesigner/designercore/include/abstractview.h
src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h
src/plugins/qmldesigner/designercore/include/nodeinstanceview.h
src/plugins/qmldesigner/designercore/include/nodelistproperty.h
src/plugins/qmldesigner/designercore/include/qmlitemnode.h
src/plugins/qmldesigner/designercore/include/qmlmodelview.h
src/plugins/qmldesigner/designercore/include/rewriterview.h
src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp
src/plugins/qmldesigner/designercore/model/internalnode_p.h
src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h
src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp
src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h
src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp
src/plugins/qmldesigner/designercore/model/internalnodeproperty.h
src/plugins/qmldesigner/designercore/model/model.cpp
src/plugins/qmldesigner/designercore/model/model_p.h
src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp
src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp
src/plugins/qmldesigner/designercore/model/qmlanchors.cpp
src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp
src/plugins/qmldesigner/designercore/model/rewriterview.cpp
src/plugins/qmldesigner/designercore/model/viewlogger.cpp
src/plugins/qmldesigner/designercore/model/viewlogger.h
src/plugins/qmldesigner/designmodewidget.cpp
src/plugins/qmldesigner/designmodewidget.h

index 77ae505..8741d72 100644 (file)
@@ -151,7 +151,7 @@ void ComponentView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbs
 //    }
 //    }
 //}
-
+void ComponentView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
 void ComponentView::nodeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
 void ComponentView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}
 void ComponentView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
index d4612d0..40a0ffc 100644 (file)
@@ -59,6 +59,7 @@ public:
     void nodeCreated(const ModelNode &createdNode);
     void nodeAboutToBeRemoved(const ModelNode &removedNode);
     void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId);
     void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
index ddb7545..fe776a4 100644 (file)
@@ -37,7 +37,7 @@
 #include <allpropertiesbox.h>
 #include <itemlibrary.h>
 #include <navigatorview.h>
-#include <stateseditorwidget.h>
+#include <stateseditorview.h>
 #include <formeditorview.h>
 #include <formeditorwidget.h>
 #include <basetexteditmodifier.h>
@@ -87,7 +87,7 @@ public:
     QWeakPointer<ItemLibrary> itemLibrary;
     QWeakPointer<NavigatorView> navigator;
     QWeakPointer<AllPropertiesBox> allPropertiesBox;
-    QWeakPointer<StatesEditorWidget> statesEditorWidget;
+    QWeakPointer<StatesEditorView> statesEditorView;
     QWeakPointer<QStackedWidget> stackedWidget;
     QWeakPointer<NodeInstanceView> nodeInstanceView;
 
@@ -205,9 +205,9 @@ void DesignDocumentController::setAllPropertiesBox(AllPropertiesBox* allProperti
     m_d->allPropertiesBox = allPropertiesBox;
 }
 
-void DesignDocumentController::setStatesEditorWidget(StatesEditorWidget* statesEditorWidget)
+void DesignDocumentController::setStatesEditorView(StatesEditorView* statesEditorView)
 {
-    m_d->statesEditorWidget = statesEditorWidget;
+    m_d->statesEditorView = statesEditorView;
 }
 
 void DesignDocumentController::setFormEditorView(FormEditorView *formEditorView)
@@ -375,7 +375,7 @@ void DesignDocumentController::loadCurrentModel()
         m_d->stackedWidget->addWidget(m_d->textEdit.data());
 
     // Will call setCurrentState (formEditorView etc has to be constructed first)
-    m_d->statesEditorWidget->setup(m_d->model.data());
+    m_d->model->attachView(m_d->statesEditorView.data());
 
     m_d->allPropertiesBox->setModel(m_d->model.data());
 
index 76bed22..50b67ee 100644 (file)
@@ -54,7 +54,7 @@ class RewriterView;
 class ItemLibrary;
 class NavigatorView;
 class AllPropertiesBox;
-class StatesEditorWidget;
+class StatesEditorView;
 class FormEditorView;
 
 class DesignDocumentController: public QObject
@@ -92,7 +92,7 @@ public:
     void setItemLibrary(ItemLibrary* itemLibrary);
     void setNavigator(NavigatorView* navigatorView);
     void setAllPropertiesBox(AllPropertiesBox* allPropertiesBox);
-    void setStatesEditorWidget(StatesEditorWidget* statesEditorWidget);
+    void setStatesEditorView(StatesEditorView* statesEditorView);
     void setFormEditorView(FormEditorView *formEditorView);
     void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
 
index 6e63157..fea1e71 100644 (file)
@@ -43,6 +43,7 @@ namespace QmlDesigner {
 void DesignDocumentControllerView::nodeCreated(const ModelNode & /*createdNode*/) {};
 void DesignDocumentControllerView::nodeAboutToBeRemoved(const ModelNode & /*removedNode*/) {};
 void DesignDocumentControllerView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty & /*parentProperty*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {};
+void DesignDocumentControllerView::nodeAboutToBeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {};
 void DesignDocumentControllerView::nodeReparented(const ModelNode & /*node*/, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {};
 void DesignDocumentControllerView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {};
 void DesignDocumentControllerView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/) {};
index 6fc0273..9d61a58 100644 (file)
@@ -45,6 +45,7 @@ public:
     virtual void nodeCreated(const ModelNode &createdNode);
     virtual void nodeAboutToBeRemoved(const ModelNode &removedNode);
     virtual void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
+    virtual void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     virtual void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     virtual void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId);
     virtual void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
index 3fe7926..7b57375 100644 (file)
@@ -130,6 +130,10 @@ void NavigatorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
         m_treeModel->removeSubTree(removedNode);
 }
 
+void NavigatorView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
+{
+}
+
 void NavigatorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty & /*newPropertyParent*/, const NodeAbstractProperty & /*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
 {
     bool blocked = blockSelectionChangedSignal(true);
index 5b142e1..ea1ca45 100644 (file)
@@ -69,9 +69,9 @@ public:
     void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags propertyChange);
 
     void nodeAboutToBeRemoved(const ModelNode &removedNode);
-    void nodeReparented(const ModelNode &node, const ModelNode &oldParent, const ModelNode &newParent);
     void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex);
 
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
     void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId);
index 36ac4ab..69f5831 100644 (file)
 #include <QtCore/QDebug>
 #include <QMessageBox>
 
+#include <nodelistproperty.h>
+#include <modelnode.h>
+#include <variantproperty.h>
+
 enum {
     debug = false
 };
 
 
 namespace QmlDesigner {
-namespace Internal {
 
-StatesEditorModel::StatesEditorModel(QObject *parent) :
-        QAbstractListModel(parent),
-        m_updateCounter(0)
+StatesEditorModel::StatesEditorModel(StatesEditorView *view)
+    : QAbstractListModel(view),
+      m_statesEditorView(view),
+      m_updateCounter(0)
 {
     QHash<int, QByteArray> roleNames;
     roleNames.insert(StateNameRole, "stateName");
     roleNames.insert(StateImageSourceRole, "stateImageSource");
+    roleNames.insert(NodeId, "nodeId");
     setRoleNames(roleNames);
 }
 
 
 int StatesEditorModel::count() const
 {
-    return m_stateNames.count();
+    return rowCount();
+}
+
+QModelIndex StatesEditorModel::index(int row, int column, const QModelIndex &parent) const
+{
+    if (m_statesEditorView.isNull())
+        return QModelIndex();
+
+
+    int internalId = 0;
+    if (row > 0)
+        internalId = m_statesEditorView->rootModelNode().nodeListProperty("states").at(row - 1).internalId();
+
+    return hasIndex(row, column, parent) ? createIndex(row, column,  internalId) : QModelIndex();
 }
 
 int StatesEditorModel::rowCount(const QModelIndex &parent) const
 {
-    if (parent.isValid())
+    if (parent.isValid() || m_statesEditorView.isNull() || !m_statesEditorView->model())
         return 0;
-    return m_stateNames.count();
+
+    if (!m_statesEditorView->rootModelNode().hasNodeListProperty("states"))
+        return 1;
+
+    return m_statesEditorView->rootModelNode().nodeListProperty("states").count() + 1;
+}
+
+void StatesEditorModel::reset()
+{
+    QAbstractListModel::reset();
 }
 
 QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
 {
-    if (index.parent().isValid() || index.column() != 0)
+    if (index.parent().isValid() || index.column() != 0 || m_statesEditorView.isNull() || !m_statesEditorView->hasModelNodeForInternalId(index.internalId()))
         return QVariant();
 
-    QVariant result;
+    ModelNode stateNode;
+
+    if (index.internalId() > 0)
+        stateNode = m_statesEditorView->modelNodeForInternalId(index.internalId());
+
     switch (role) {
     case StateNameRole: {
-            if (index.row()==0)
-                result = QString(tr("base state", "Implicit default state"));
-            else
-                result = m_stateNames.at(index.row());
-            break;
-        }
-    case StateImageSourceRole: {
-            if (!m_statesView.isNull())
-                return QString("image://qmldesigner_stateseditor/%1-%2").arg(index.row()).arg(m_updateCounter);
-            break;
+            if (index.row() == 0) {
+                return QString(tr("base state", "Implicit default state"));
+            } else {
+                if (stateNode.hasVariantProperty("name")) {
+                    return stateNode.variantProperty("name").value();
+                } else {
+                    return QVariant();
+                }
+            }
+
         }
+    case StateImageSourceRole: return QString("image://qmldesigner_stateseditor/%1").arg(index.internalId());
+    case NodeId : return index.internalId();
     }
 
-    return result;
+
+    return QVariant();
 }
 
-void StatesEditorModel::insertState(int i, const QString &name)
+void StatesEditorModel::insertState(int stateIndex)
 {
-    beginInsertRows(QModelIndex(), i, i);
+    if (stateIndex >= 0) {
 
-    m_stateNames.insert(i, name);
+        const int index = stateIndex + 1;
+        beginInsertRows(QModelIndex(), index, index);
 
-    endInsertRows();
+        endInsertRows();
 
-    emit dataChanged(createIndex(i, 0), createIndex(i, 0));
-    emit countChanged();
+        emit dataChanged(createIndex(index, 0), createIndex(index, 0));
+        emit countChanged();
+    }
 }
 
-void StatesEditorModel::removeState(int i)
+void StatesEditorModel::updateState(int stateIndex)
 {
-    beginRemoveRows(QModelIndex(), i, i);
+    if (stateIndex >= 0) {
+        const int index = stateIndex + 1;
 
-    m_stateNames.removeAt(i);
-
-    endRemoveRows();
-
-    emit dataChanged(createIndex(i, 0), createIndex(i, 0));
-    emit countChanged();
+        emit dataChanged(createIndex(index, 0), createIndex(index, 0));
+    }
 }
 
-void StatesEditorModel::renameState(int i, const QString &newName)
+void StatesEditorModel::removeState(int stateIndex)
 {
-    Q_ASSERT(i > 0 && i < m_stateNames.count());
-
-    if (m_stateNames[i] != newName) {
-        if (m_stateNames.contains(newName) || newName.isEmpty()) {
-            QMessageBox::warning(0, tr("Invalid state name"),
-                                 newName.isEmpty() ?
-                                     tr("The empty string as a name is reserved for the base state.") :
-                                     tr("Name already used in another state"));
-        } else {
-            m_stateNames.replace(i, newName);
-            m_statesView->renameState(i,newName);
-
-            emit dataChanged(createIndex(i, 0), createIndex(i, 0));
-        }
+    if (stateIndex >= 0) {
+        const int index = stateIndex + 1;
+        beginRemoveRows(QModelIndex(), index, index);
+
+
+        endRemoveRows();
+
+        emit dataChanged(createIndex(index, 0), createIndex(index, 0));
+        emit countChanged();
     }
 }
 
-void StatesEditorModel::setStatesEditorView(StatesEditorView *statesView)
-{
-    m_statesView = statesView;
+void StatesEditorModel::renameState(int nodeId, const QString &newName)
+{    
+    if (newName.isEmpty() ||! m_statesEditorView->validStateName(newName)) {
+        QMessageBox::warning(0, tr("Invalid state name"),
+                             newName.isEmpty() ?
+                                 tr("The empty string as a name is reserved for the base state.") :
+                                 tr("Name already used in another state"));
+    } else {
+        m_statesEditorView->renameState(nodeId, newName);
+    }
+
 }
 
 void StatesEditorModel::emitChangedToState(int n)
@@ -141,5 +177,4 @@ void StatesEditorModel::emitChangedToState(int n)
     emit changedToState(n);
 }
 
-} // namespace Internal
 } // namespace QmlDesigner
index 556bea6..2a6bd09 100644 (file)
 #include <QAbstractListModel>
 #include <QWeakPointer>
 
-#include <stateseditorview.h>
 
 namespace QmlDesigner {
 
-namespace Internal {
+class StatesEditorView;
 
 class StatesEditorModel : public QAbstractListModel
 {
@@ -48,32 +47,34 @@ class StatesEditorModel : public QAbstractListModel
     enum {
         StateNameRole = Qt::DisplayRole,
         StateImageSourceRole = Qt::UserRole,
+        NodeId
     };
 
 public:
-    StatesEditorModel(QObject *parent);
+    StatesEditorModel(StatesEditorView *view);
 
     int count() const;
+    QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
     int rowCount(const QModelIndex &parent = QModelIndex()) const;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 
-    void insertState(int i, const QString &name);
-    void removeState(int i);
-    Q_INVOKABLE void renameState(int i, const QString &newName);
-    void setStatesEditorView(StatesEditorView *statesView);
+    void insertState(int stateIndex);
+    void removeState(int stateIndex);
+    void updateState(int stateIndex);
+    Q_INVOKABLE void renameState(int nodeId, const QString &newName);
     void emitChangedToState(int n);
 
+    void reset();
+
 signals:
     void countChanged();
     void changedToState(int n);
 
 private:
-    QList<QString> m_stateNames;
-    QWeakPointer<StatesEditorView> m_statesView;
+    QWeakPointer<StatesEditorView> m_statesEditorView;
     int m_updateCounter;
 };
 
-} // namespace Itnernal
 } // namespace QmlDesigner
 
 #endif // STATESEDITORMODEL_H
index d6a6e0c..f8827ec 100644 (file)
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "stateseditorview.h"
+#include "stateseditorwidget.h"
 #include "stateseditormodel.h"
 #include <customnotifications.h>
 #include <rewritingexception.h>
@@ -38,6 +39,8 @@
 #include <QDebug>
 #include <math.h>
 
+#include <nodemetainfo.h>
+
 #include <variantproperty.h>
 #include <nodelistproperty.h>
 
@@ -46,108 +49,124 @@ enum {
 };
 
 namespace QmlDesigner {
-namespace Internal {
 
 /**
   We always have 'one' current state, where we get updates from (see sceneChanged()). In case
   the current state is the base state, we render the base state + all other states.
   */
-StatesEditorView::StatesEditorView(StatesEditorModel *editorModel, QObject *parent) :
+StatesEditorView::StatesEditorView(QObject *parent) :
         QmlModelView(parent),
-        m_editorModel(editorModel)
+        m_statesEditorModel(new StatesEditorModel(this)),
+        m_lastIndex(-1)
 {
-    Q_ASSERT(m_editorModel);
+    Q_ASSERT(m_statesEditorModel);
     // base state
 }
 
-void StatesEditorView::setCurrentState(int index)
+StatesEditorWidget *StatesEditorView::widget()
 {
-    if (debug)
-        qDebug() << __FUNCTION__ << index;
+    if (m_statesEditorWidget.isNull())
+        m_statesEditorWidget = new StatesEditorWidget(this, m_statesEditorModel.data());
 
-    // happens to be the case for an invalid document / no base state
-    if (m_modelStates.isEmpty())
-        return;
-
-    Q_ASSERT(index < m_modelStates.count());
-    if (index == -1)
-        return;
-
-    if (m_modelStates.indexOf(currentState()) == index)
-        return;
-
-    QmlModelState state(m_modelStates.at(index));
-    Q_ASSERT(state.isValid());
-    QmlModelView::setCurrentState(state);
+    return m_statesEditorWidget.data();
 }
 
-void StatesEditorView::createState(const QString &name)
+void StatesEditorView::removeState(int nodeId)
 {
-    if (debug)
-        qDebug() << __FUNCTION__ << name;
-
     try {
-        model()->addImport(Import::createLibraryImport("QtQuick", "1.0"));
-        stateRootNode().states().addState(name);
+        if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
+            ModelNode stateNode(modelNodeForInternalId(nodeId));
+            Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick/State", 4, 7));
+            NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();
+
+            if (parentProperty.count() <= 1) {
+                setCurrentState(baseState());
+            } else if (parentProperty.isValid()){
+                int index = parentProperty.indexOf(stateNode);
+                if (index == 0) {
+                    setCurrentState(parentProperty.at(1));
+                } else {
+                    setCurrentState(parentProperty.at(index - 1));
+                }
+            }
+
+
+            stateNode.destroy();
+        }
     }  catch (RewritingException &e) {
         QMessageBox::warning(0, "Error", e.description());
     }
 }
 
-void StatesEditorView::removeState(int index)
+void StatesEditorView::synchonizeCurrentStateFromWidget()
 {
-    if (debug)
-        qDebug() << __FUNCTION__ << index;
+    int internalId = m_statesEditorWidget->currentStateInternalId();
+
+    if (internalId > 0 && hasModelNodeForInternalId(internalId)) {
+        ModelNode node = modelNodeForInternalId(internalId);
+        QmlModelState modelState(node);
+        if (modelState.isValid() && modelState != currentState())
+            setCurrentState(modelState);
+    } else {
+        setCurrentState(baseState());
+    }
+}
 
-    Q_ASSERT(index > 0 && index < m_modelStates.size());
-    QmlModelState state = m_modelStates.at(index);
-    Q_ASSERT(state.isValid());
+void StatesEditorView::createNewState()
+{
+    if (currentState().isBaseState()) {
+        addState();
+    } else {
+        duplicateCurrentState();
+    }
+}
 
-    setCurrentState(0);
+void StatesEditorView::addState()
+{
+    // can happen when root node is e.g. a ListModel
+    if (!rootQmlItemNode().isValid())
+        return;
 
-    try {
-        m_modelStates.removeAll(state);
-        state.destroy();
+    QStringList modelStateNames = rootStateGroup().names();
 
-        m_editorModel->removeState(index);
+    QString newStateName;
+    int index = 1;
+    while (true) {
+        newStateName = tr("State%1", "Default name for newly created states").arg(index++);
+        if (!modelStateNames.contains(newStateName))
+            break;
+    }
 
-        int newIndex = (index < m_modelStates.count()) ? index : m_modelStates.count() - 1;
-        setCurrentState(newIndex);
+    try {
+        if (rootStateGroup().allStates().count() < 1)
+            model()->addImport(Import::createLibraryImport("QtQuick", "1.0"));
+        ModelNode newState = rootStateGroup().addState(newStateName);
+        setCurrentState(newState);
     }  catch (RewritingException &e) {
         QMessageBox::warning(0, "Error", e.description());
     }
 }
 
-void StatesEditorView::renameState(int index, const QString &newName)
+void StatesEditorView::resetModel()
 {
-    if (debug)
-        qDebug() << __FUNCTION__ << index << newName;
-
-    Q_ASSERT(index > 0 && index < m_modelStates.size());
-    QmlModelState state = m_modelStates.at(index);
-    Q_ASSERT(state.isValid());
-
-    try {
-        if (state.name() != newName) {
-            // Jump to base state for the change
-            QmlModelState oldState = currentState();
-            state.setName(newName);
-            setCurrentState(m_modelStates.indexOf(oldState));
+    if (m_statesEditorModel)
+        m_statesEditorModel->reset();
+
+    if (m_statesEditorWidget) {
+        if (currentState().isBaseState()) {
+            m_statesEditorWidget->setCurrentStateInternalId(currentState().modelNode().internalId());
+        } else {
+            m_statesEditorWidget->setCurrentStateInternalId(0);
         }
-    }  catch (RewritingException &e) {
-        QMessageBox::warning(0, "Error", e.description());
     }
 }
 
-void StatesEditorView::duplicateCurrentState(int index)
+void StatesEditorView::duplicateCurrentState()
 {
-    if (debug)
-        qDebug() << __FUNCTION__ << index;
+    QmlModelState state = currentState();
 
-    Q_ASSERT(index > 0 && index < m_modelStates.size());
+    Q_ASSERT(!state.isBaseState());
 
-    QmlModelState state = m_modelStates.at(index);
-    Q_ASSERT(state.isValid());
     QString newName = state.name();
 
     // Strip out numbers at the end of the string
@@ -157,153 +176,125 @@ void StatesEditorView::duplicateCurrentState(int index)
         newName = newName.left(numberIndex);
 
     int i = 1;
-    QStringList stateNames = state.stateGroup().names();
+    QStringList stateNames = rootStateGroup().names();
     while (stateNames.contains(newName + QString::number(i)))
         i++;
-    state.duplicate(newName + QString::number(i));
+
+    QmlModelState newState = state.duplicate(newName + QString::number(i));
+    setCurrentState(newState);
 }
 
-void StatesEditorView::modelAttached(Model *model)
+bool StatesEditorView::validStateName(const QString &name) const
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
+    if (name == tr("base state"))
+        return false;
+    QList<QmlModelState> modelStates = rootStateGroup().allStates();
+    foreach (const QmlModelState &state, modelStates) {
+        if (state.name() == name)
+            return false;
+    }
+    return true;
+}
 
+void StatesEditorView::renameState(int nodeId, const QString &newName)
+{
+    if (hasModelNodeForInternalId(nodeId)) {
+        QmlModelState state(modelNodeForInternalId(nodeId));
+        try {
+            if (state.isValid() && state.name() != newName) {
+                // Jump to base state for the change
+                QmlModelState oldState = currentState();
+                setCurrentState(baseState());
+                state.setName(newName);
+                setCurrentState(oldState);
+            }
+        }  catch (RewritingException &e) {
+            QMessageBox::warning(0, "Error", e.description());
+        }
+    }
+}
+
+void StatesEditorView::modelAttached(Model *model)
+{
     if (model == QmlModelView::model())
         return;
 
     Q_ASSERT(model);
     QmlModelView::modelAttached(model);
-    clearModelStates();
-
-    // Add base state
-    if (!baseState().isValid())
-        return;
-
-    m_modelStates.insert(0, baseState());
-    m_editorModel->insertState(0, baseState().name());
-
-    // Add custom states
-    m_stateRootNode = QmlItemNode(rootModelNode());
-    if (!m_stateRootNode.isValid())
-        return;    
 
-    for (int i = 0; i < m_stateRootNode.states().allStates().size(); ++i) {
-        QmlModelState state = QmlItemNode(rootModelNode()).states().allStates().at(i);
-        insertModelState(i, state);
-    }
+    resetModel();
 }
 
 void StatesEditorView::modelAboutToBeDetached(Model *model)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-    clearModelStates();
-
     QmlModelView::modelAboutToBeDetached(model);
+    resetModel();
 }
 
 void StatesEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
     foreach (const AbstractProperty &property, propertyList) {
-        // remove all states except base state
-        if ((property.name()=="states") && (property.parentModelNode().isRootNode())) {
-            foreach (const QmlModelState &state, m_modelStates) {
-                if (!state.isBaseState())
-                    removeModelState(state);
-            }
-        }
+        if (property.name() == "states" && property.parentModelNode().isRootNode())
+            m_statesEditorModel->reset();
     }
-
-    QmlModelView::propertiesAboutToBeRemoved(propertyList);
 }
 
 
 void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList, PropertyChangeFlags propertyChange)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-    QmlModelView::variantPropertiesChanged(propertyList, propertyChange);
     foreach (const VariantProperty &property, propertyList) {
-        ModelNode node (property.parentModelNode());
-        if (QmlModelState(node).isValid() && (property.name() == QLatin1String("name"))) {
-            int index = m_modelStates.indexOf(node);
-            if (index != -1)
-                m_editorModel->renameState(index, property.value().toString());
+        if (property.name() == "name" && property.parentModelNode().hasParentProperty()) {
+            NodeAbstractProperty parentProperty = property.parentModelNode().parentProperty();
+            if (parentProperty.name() == "states" && parentProperty.parentModelNode().isRootNode()) {
+                m_statesEditorModel->updateState(parentProperty.indexOf(property.parentModelNode()));
+            }
         }
     }
 }
 
+
 void StatesEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-    if (QmlModelState(removedNode).isValid())
-        removeModelState(removedNode);
-
-    QmlModelView::nodeAboutToBeRemoved(removedNode);
+    if (removedNode.hasParentProperty()) {
+        const NodeAbstractProperty propertyParent = removedNode.parentProperty();
+        if (propertyParent.parentModelNode().isRootNode() && propertyParent.name() == "states") {
+            m_lastIndex = propertyParent.indexOf(removedNode);
+        }
+    }
 }
 
+void StatesEditorView::nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags /*propertyChange*/)
+{
+    if (parentProperty.isValid() && parentProperty.parentModelNode().isRootNode() && parentProperty.name() == "states") {
+        m_statesEditorModel->removeState(m_lastIndex);
+        m_lastIndex = -1;
+    }
+}
 
-void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
+void StatesEditorView::nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
+    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
+        m_lastIndex = oldPropertyParent.indexOf(node);
+}
 
-    QmlModelView::nodeReparented(node, newPropertyParent, oldPropertyParent, propertyChange);
 
-    // this would be sliding
-    Q_ASSERT(newPropertyParent != oldPropertyParent);
+void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
+{
+    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
+        m_statesEditorModel->removeState(m_lastIndex);
 
-    if (QmlModelState(node).isValid()) {
-        if (oldPropertyParent.parentModelNode() == m_stateRootNode) {
-            if (oldPropertyParent.isNodeListProperty()
-                && oldPropertyParent.name() == "states") {
-                removeModelState(node);
-            } else {
-                qWarning() << "States Editor: Reparented model state was not in states property list";
-            }
-        }
+    m_lastIndex = -1;
 
-        if (newPropertyParent.parentModelNode() == m_stateRootNode) {
-            if (newPropertyParent.isNodeListProperty()
-                && newPropertyParent.name() == "states") {
-                NodeListProperty statesProperty = newPropertyParent.toNodeListProperty();
-                int index = statesProperty.toModelNodeList().indexOf(node);
-                Q_ASSERT(index >= 0);
-                insertModelState(index, node);
-            } else {
-                qWarning() << "States Editor: Reparented model state is not in the states property list";
-            }
-        }
+    if (newPropertyParent.isValid() && newPropertyParent.parentModelNode().isRootNode() && newPropertyParent.name() == "states") {
+        int index = newPropertyParent.indexOf(node);
+        m_statesEditorModel->insertState(index);
     }
 }
 
 void StatesEditorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-    QmlModelView::nodeOrderChanged(listProperty, movedNode, oldIndex);
-    if (listProperty.parentModelNode() == m_stateRootNode
-        && listProperty.name() == "states") {
-
-        int newIndex = listProperty.toModelNodeList().indexOf(movedNode);
-        Q_ASSERT(newIndex >= 0);
-
-        QmlModelState state = QmlModelState(movedNode);
-        if (state.isValid()) {
-            Q_ASSERT(oldIndex == modelStateIndex(state));
-            removeModelState(state);
-            insertModelState(newIndex, state);
-            Q_ASSERT(newIndex == modelStateIndex(state));
-        }
-    }
+    if (listProperty.isValid() && listProperty.parentModelNode().isRootNode() && listProperty.name() == "states")
+        resetModel();
 }
 
 void StatesEditorView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName)
@@ -314,40 +305,26 @@ void StatesEditorView::nodeInstancePropertyChanged(const ModelNode &node, const
 
 void StatesEditorView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-    QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
-
-    if (!m_settingSilentState) {
-        if (newQmlModelState.isBaseState())
-            m_editorModel->emitChangedToState(0);
-        else
-            m_editorModel->emitChangedToState(m_modelStates.indexOf(newQmlModelState));
+    if (newQmlModelState.isBaseState()) {
+        m_statesEditorWidget->setCurrentStateInternalId(0);
+    } else {
+        m_statesEditorWidget->setCurrentStateInternalId(newQmlModelState.modelNode().internalId());
     }
+    QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
 }
 
 void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
     QmlModelView::transformChanged(qmlObjectNode, propertyName);
 }
 
 void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
     QmlModelView::parentChanged(qmlObjectNode);
 }
 
 void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
 {
-    if (debug)
-        qDebug() << __FUNCTION__;
-
     QmlModelView::otherPropertyChanged(qmlObjectNode, propertyName);
 }
 
@@ -398,54 +375,4 @@ void StatesEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNo
 
 }
 
-
-// index without base state
-void StatesEditorView::insertModelState(int i, const QmlModelState &state)
-{
-    if (debug)
-        qDebug() << __FUNCTION__ << i << state.name();
-
-    Q_ASSERT(state.isValid());
-    Q_ASSERT(!state.isBaseState());
-    // For m_modelStates / m_editorModel, i=0 is base state
-    m_modelStates.insert(i+1, state);
-    m_editorModel->insertState(i+1, state.name());
-}
-
-void StatesEditorView::removeModelState(const QmlModelState &state)
-{
-    if (debug)
-        qDebug() << __FUNCTION__ << state.name();
-
-    Q_ASSERT(state.isValid());
-    Q_ASSERT(!state.isBaseState());
-    int index = m_modelStates.indexOf(state);
-    if (index != -1) {
-        m_modelStates.removeOne(state);
-        m_editorModel->removeState(index);
-    }
-}
-
-void StatesEditorView::clearModelStates()
-{
-    if (debug)
-        qDebug() << __FUNCTION__;
-
-
-    // Remove all states
-    const int modelStateCount = m_modelStates.size();
-    for (int i=modelStateCount-1; i>=0; --i) {
-        m_modelStates.removeAt(i);
-        m_editorModel->removeState(i);
-    }
-}
-
-// index without base state
-int StatesEditorView::modelStateIndex(const QmlModelState &state)
-{
-    return m_modelStates.indexOf(state) - 1;
-}
-
-
-} // namespace Internal
 } // namespace QmlDesigner
index cae5e5c..c149c33 100644 (file)
 
 namespace QmlDesigner {
 
-namespace Internal {
 
 class StatesEditorModel;
+class StatesEditorWidget;
 
 class StatesEditorView : public QmlModelView {
     Q_OBJECT
 
 public:
-    explicit StatesEditorView(StatesEditorModel *model, QObject *parent = 0);
+    explicit StatesEditorView(QObject *parent = 0);
 
-    void setCurrentState(int index);
-    void createState(const QString &name);
-    void removeState(int index);
-    void renameState(int index,const QString &newName);
-    void duplicateCurrentState(int index);
-
-    QmlItemNode stateRootNode() { return m_stateRootNode; }
-    bool isAttachedToModel() const { return m_attachedToModel; }
+    void renameState(int nodeId,const QString &newName);
+    bool validStateName(const QString &name) const;
 
     void nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName);
 
@@ -62,9 +56,12 @@ public:
     void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
 
     void nodeAboutToBeRemoved(const ModelNode &removedNode);
+    void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex);
 
+
     // QmlModelView
     void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
     void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
@@ -77,23 +74,24 @@ public:
     void bindingPropertiesChanged(const QList<BindingProperty> &propertyList, PropertyChangeFlags propertyChange);
     void selectedNodesChanged(const QList<ModelNode> &selectedNodeList, const QList<ModelNode> &lastSelectedNodeList);
 
-private:
-    void insertModelState(int i, const QmlModelState &state);
-    void removeModelState(const QmlModelState &state);
-    void clearModelStates();
-    int modelStateIndex(const QmlModelState &state);
+    StatesEditorWidget *widget();
 
+public slots:
+    void synchonizeCurrentStateFromWidget();
+    void createNewState();
+    void removeState(int nodeId);
 
-    QList<QmlModelState> m_modelStates;
-    StatesEditorModel *m_editorModel;
-    QmlItemNode m_stateRootNode;
+private:
+    void resetModel();
+    void addState();
+    void duplicateCurrentState();
 
-    QmlModelState m_oldRewriterAmendState;
-    bool m_attachedToModel;
-    bool m_settingSilentState;
+private:
+    QWeakPointer<StatesEditorModel> m_statesEditorModel;
+    QWeakPointer<StatesEditorWidget> m_statesEditorWidget;
+    int m_lastIndex;
 };
 
-} // namespace Internal
 } // namespace QmlDesigner
 
 #endif // STATESEDITORVIEW_H
index dbdff9e..615ac9a 100644 (file)
@@ -55,139 +55,58 @@ enum {
 
 namespace QmlDesigner {
 
-namespace Internal {
-
-class StatesEditorWidgetPrivate : QObject
-{
-    Q_OBJECT
-
-private:
-    StatesEditorWidgetPrivate(StatesEditorWidget *q);
-
-    int currentIndex() const;
-    void setCurrentIndex(int i);
-
-    bool validStateName(const QString &name) const;
-
-private slots:
-    void currentStateChanged();
-    void addState();
-    void removeState(int);
-    void duplicateCurrentState();
-
-private:
-    StatesEditorWidget *m_q;
-    QWeakPointer<Model> model;
-    QWeakPointer<QDeclarativeView> listView;
-    QWeakPointer<Internal::StatesEditorModel> statesEditorModel;
-    QWeakPointer<Internal::StatesEditorView> statesEditorView;
-    friend class QmlDesigner::StatesEditorWidget;
-};
-
-StatesEditorWidgetPrivate::StatesEditorWidgetPrivate(StatesEditorWidget *q) :
-        QObject(q),
-        m_q(q)
+int StatesEditorWidget::currentStateInternalId() const
 {
-}
+    Q_ASSERT(m_declarativeView->rootObject());
+    Q_ASSERT(m_declarativeView->rootObject()->property("currentStateInternalId").isValid());
 
-int StatesEditorWidgetPrivate::currentIndex() const
-{
-    Q_ASSERT(listView->rootObject());
-    Q_ASSERT(listView->rootObject()->property("currentStateIndex").isValid());
-    return listView->rootObject()->property("currentStateIndex").toInt();
-}
-
-void StatesEditorWidgetPrivate::setCurrentIndex(int i)
-{
-    listView->rootObject()->setProperty("currentStateIndex", i);
+    return m_declarativeView->rootObject()->property("currentStateInternalId").toInt();
 }
 
-bool StatesEditorWidgetPrivate::validStateName(const QString &name) const
+void StatesEditorWidget::setCurrentStateInternalId(int internalId)
 {
-    if (name == tr("base state"))
-        return false;
-    QList<QmlModelState> modelStates = statesEditorView->stateRootNode().states().allStates();
-    foreach (const QmlModelState &state, modelStates) {
-        if (state.name() == name)
-            return false;
-    }
-    return true;
+    m_declarativeView->rootObject()->setProperty("currentStateInternalId", internalId);
 }
 
-void StatesEditorWidgetPrivate::currentStateChanged()
+StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, StatesEditorModel *statesEditorModel):
+        QWidget()
 {
-    if (statesEditorView->isAttachedToModel())
-        statesEditorView->setCurrentState(currentIndex());
-}
-
-void StatesEditorWidgetPrivate::addState()
-{
-    // can happen when root node is e.g. a ListModel
-    if (!statesEditorView->stateRootNode().isValid())
-        return;
-
-    QStringList modelStateNames = statesEditorView->stateRootNode().states().names();
-
-    QString newStateName;
-    int index = 1;
-    while (1) {
-        newStateName = tr("State%1", "Default name for newly created states").arg(index++);
-        if (!modelStateNames.contains(newStateName))
-            break;
-    }
-    statesEditorView->createState(newStateName);
-}
+    m_declarativeView = new QDeclarativeView(this);
 
-void StatesEditorWidgetPrivate::removeState(int i)
-{
-    statesEditorView->removeState(i);
-}
-
-void StatesEditorWidgetPrivate::duplicateCurrentState()
-{
-    statesEditorView->duplicateCurrentState(currentIndex());
-}
-
-} // namespace Internal
+    m_declarativeView->engine()->addImageProvider(
+            QLatin1String("qmldesigner_stateseditor"), new Internal::StatesEditorImageProvider);
 
-StatesEditorWidget::StatesEditorWidget(QWidget *parent):
-        QWidget(parent),
-        m_d(new Internal::StatesEditorWidgetPrivate(this))
-{
-    m_d->statesEditorModel = new Internal::StatesEditorModel(this);
-    m_d->listView = new QDeclarativeView(this);
 
-    m_d->listView->setAcceptDrops(false);
+    m_declarativeView->setAcceptDrops(false);
 
     QVBoxLayout *layout = new QVBoxLayout(this);
     layout->setMargin(0);
     layout->setSpacing(0);
-    layout->addWidget(m_d->listView.data());
+    layout->addWidget(m_declarativeView.data());
 
-    m_d->listView->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+    m_declarativeView->setResizeMode(QDeclarativeView::SizeRootObjectToView);
 
-    m_d->listView->rootContext()->setContextProperty(QLatin1String("statesEditorModel"), m_d->statesEditorModel.data());
+    m_declarativeView->rootContext()->setContextProperty(QLatin1String("statesEditorModel"), statesEditorModel);
     QColor highlightColor = palette().highlight().color();
     if (0.5*highlightColor.saturationF()+0.75-highlightColor.valueF() < 0)
         highlightColor.setHsvF(highlightColor.hsvHueF(),0.1 + highlightColor.saturationF()*2.0, highlightColor.valueF());
-    m_d->listView->rootContext()->setContextProperty(QLatin1String("highlightColor"), highlightColor);
+    m_declarativeView->rootContext()->setContextProperty(QLatin1String("highlightColor"), highlightColor);
 
     // Work around ASSERT in the internal QGraphicsScene that happens when
     // the scene is created + items set dirty in one event loop run (BAUHAUS-459)
-    QApplication::processEvents();
+    //QApplication::processEvents();
 
-    m_d->listView->setSource(QUrl("qrc:/stateseditor/stateslist.qml"));
+    m_declarativeView->setSource(QUrl("qrc:/stateseditor/stateslist.qml"));
 
-    if (!m_d->listView->rootObject())
+    if (!m_declarativeView->rootObject())
         throw InvalidQmlSourceException(__LINE__, __FUNCTION__, __FILE__);
 
-    m_d->listView->setFocusPolicy(Qt::ClickFocus);
-    QApplication::sendEvent(m_d->listView->scene(), new QEvent(QEvent::WindowActivate));
+    m_declarativeView->setFocusPolicy(Qt::ClickFocus);
+    QApplication::sendEvent(m_declarativeView->scene(), new QEvent(QEvent::WindowActivate));
 
-    connect(m_d->listView->rootObject(), SIGNAL(currentStateIndexChanged()), m_d, SLOT(currentStateChanged()));
-    connect(m_d->listView->rootObject(), SIGNAL(createNewState()), m_d, SLOT(addState()));
-    connect(m_d->listView->rootObject(), SIGNAL(duplicateCurrentState()), m_d, SLOT(duplicateCurrentState()));
-    connect(m_d->listView->rootObject(), SIGNAL(deleteState(int)), m_d, SLOT(removeState(int)));
+    connect(m_declarativeView->rootObject(), SIGNAL(currentStateInternalIdChanged()), statesEditorView, SLOT(synchonizeCurrentStateFromWidget()));
+    connect(m_declarativeView->rootObject(), SIGNAL(createNewState()), statesEditorView, SLOT(createNewState()));
+    connect(m_declarativeView->rootObject(), SIGNAL(deleteState(int)), statesEditorView, SLOT(removeState(int)));
 
     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
 
@@ -196,27 +115,8 @@ StatesEditorWidget::StatesEditorWidget(QWidget *parent):
 
 StatesEditorWidget::~StatesEditorWidget()
 {
-    delete m_d;
 }
 
-void StatesEditorWidget::setup(Model *model)
-{
-    m_d->model = model;
-    if (m_d->statesEditorView.isNull())
-        m_d->statesEditorView = new Internal::StatesEditorView(m_d->statesEditorModel.data(), this);
-
-    m_d->listView->engine()->addImageProvider(
-            QLatin1String("qmldesigner_stateseditor"), new Internal::StatesEditorImageProvider);
-
-    m_d->statesEditorModel->setStatesEditorView(m_d->statesEditorView.data());
-
-    m_d->model->attachView(m_d->statesEditorView.data());
-
-    // select first state (which is the base state)
-    m_d->currentStateChanged();
-}
-
-
 
 QSize StatesEditorWidget::sizeHint() const
 {
index 1565493..0a7d0d8 100644 (file)
 #include <QtGui/QWidget>
 #include <QtGui/QListWidgetItem>
 
+QT_BEGIN_NAMESPACE
+class QDeclarativeView;
+QT_END_NAMESPACE
+
 namespace QmlDesigner {
 
-class FormWindow;
 class Model;
 class ModelState;
+class StatesEditorModel;
+class StatesEditorView;
 
-namespace Internal {
-class StatesEditorWidgetPrivate;
-}
 
 class StatesEditorWidget : public QWidget
 {
     Q_OBJECT
 
 public:
-    StatesEditorWidget(QWidget *parent = 0);
+    StatesEditorWidget(StatesEditorView *m_statesEditorView, StatesEditorModel *statesEditorModel);
     virtual ~StatesEditorWidget();
 
-    void setup(Model *model);
-
     QSize sizeHint() const;
 
+    int currentStateInternalId() const;
+    void setCurrentStateInternalId(int internalId);
+
 private:
-    friend class Internal::StatesEditorWidgetPrivate;
-    class Internal::StatesEditorWidgetPrivate *m_d;
+    QWeakPointer<QDeclarativeView> m_declarativeView;
+    QWeakPointer<StatesEditorView> m_statesEditorView;
 };
 
 }
index 2a552c3..19b6bfb 100644 (file)
@@ -3,28 +3,18 @@ import Qt 4.7
 Rectangle {
     id: root
 
-    property int currentStateIndex : 0
+    property int currentStateInternalId : 0
     signal createNewState
-    signal deleteState(int index)
+    signal deleteState(int nodeId)
     signal duplicateCurrentState
     signal startRenaming
 
     color: "#4f4f4f";
     property color colorAlpha: "#994f4f4f";
 
-    function adjustCurrentStateIndex() {
-        if (currentStateIndex >= statesEditorModel.count)
-        currentStateIndex = statesEditorModel.count-1;
-    }
-
     Connections {
         target: statesEditorModel
-        onCountChanged: adjustCurrentStateIndex()
-    }
-
-    Connections {
-        target: statesEditorModel
-        onChangedToState: root.currentStateIndex = n;
+        onChangedToState: root.currentStateInternalId = n;
     }
 
     signal unFocus
@@ -33,9 +23,9 @@ Rectangle {
         hoverEnabled:true
         onExited: root.unFocus();
     }
-    onCurrentStateIndexChanged: {
-        if (currentStateIndex <= 0)
-        currentStateIndex = 0;
+    onCurrentStateInternalIdChanged: {
+        if (currentStateInternalId <= 0)
+        currentStateInternalId = 0;
         else
         unFocus();
 
@@ -97,7 +87,7 @@ Rectangle {
             height: img.height + txt.height + 29 //(index==0?29:25)
             //y:(index==0?0:4)
 
-            property bool isCurrentState: root.currentStateIndex == index;
+            property bool isCurrentState: root.currentStateInternalId == nodeId;
             onXChanged: scrollBarAdjuster.adjustScrollBar();
             onIsCurrentStateChanged: scrollBarAdjuster.adjustScrollBar();
 
@@ -115,7 +105,7 @@ Rectangle {
 
             Connections {
                 target: root
-                onStartRenaming: if (root.currentStateIndex == index) startRenaming();
+                onStartRenaming: if (root.currentStateInternalId == index) startRenaming();
             }
 
             function startRenaming() {
@@ -160,7 +150,7 @@ Rectangle {
                 anchors.fill: container
                 onClicked: {
                     root.unFocus();
-                    root.currentStateIndex = index;
+                    root.currentStateInternalId = nodeId;
                 }
             }
 
@@ -184,7 +174,7 @@ Rectangle {
                     anchors.topMargin: 2
                     anchors.horizontalCenter: textLimits.horizontalCenter
                     id: txt
-                    color: root.currentStateIndex==index ? "white" : "#E1E1E1";
+                    color: root.currentStateInternalId==nodeId ? "white" : "#E1E1E1";
                     text: stateName
                     width:parent.width
                     elide:Qt.ElideMiddle
@@ -205,9 +195,9 @@ Rectangle {
                     id: txtRegion
                     anchors.fill:parent
                     onClicked: {
-                        if (root.currentStateIndex != index)
+                        if (root.currentStateInternalId != nodeId)
                         root.unFocus();
-                        root.currentStateIndex = index;
+                        root.currentStateInternalId = nodeId;
                     }
                     onDoubleClicked: if (index!=0) {
                         startRenaming();
@@ -233,7 +223,7 @@ Rectangle {
                     function unFocus() {
                         if (visible) {
                             visible=false;
-                            statesEditorModel.renameState(index, stateNameInput.text);
+                            statesEditorModel.renameState(nodeId, stateNameInput.text);
                         }
                     }
 
@@ -273,7 +263,7 @@ Rectangle {
                             onAccepted: {
                                 if (stateNameEditor.visible) {
                                     stateNameEditor.visible = false;
-                                    statesEditorModel.renameState(index,text);
+                                    statesEditorModel.renameState(nodeId,text);
                                 }
                             }
                         }
@@ -285,7 +275,7 @@ Rectangle {
             Item {
                 id: removeState
 
-                visible: (index != 0 && root.currentStateIndex==index)
+                visible: (index != 0 && root.currentStateInternalId==nodeId)
 
                 anchors.right: parent.right
                 anchors.top: parent.top
@@ -372,7 +362,7 @@ Rectangle {
                     onClicked: {
                         root.unFocus();
 
-                        root.deleteState(index);
+                        root.deleteState(nodeId);
                         horizontalScrollbar.contentSizeDecreased();
                     }
                     onPressed: {parent.state="Pressed"}
@@ -569,12 +559,10 @@ Rectangle {
                 onClicked: {
                     // force close textinput
                     root.unFocus();
-                    if (root.currentStateIndex == 0)
                     root.createNewState(); //create new state
-                    else
-                    root.duplicateCurrentState(); //duplicate current state
+
                     // select the new state
-                    root.currentStateIndex = statesEditorModel.count - 1;
+                   // root.currentStateInternalId = statesEditorModel.count - 1;
 
                     // this should happen automatically
                     if (floatingNewStateBox.visible)
index dd20dde..2e27e01 100644 (file)
@@ -114,6 +114,7 @@ public:
     virtual void nodeCreated(const ModelNode &createdNode) = 0;
     virtual void nodeAboutToBeRemoved(const ModelNode &removedNode) = 0;
     virtual void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) = 0;
+    virtual void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) = 0;
     virtual void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) = 0;
     virtual void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) = 0;
     virtual void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList) = 0;
index 1b2bdb3..9df588e 100644 (file)
@@ -49,6 +49,8 @@ public:
     NodeAbstractProperty(const NodeAbstractProperty &property, AbstractView *view);
     void reparentHere(const ModelNode &modelNode);
     bool isEmpty() const;
+    int count() const;
+    int indexOf(const ModelNode &node) const;
 
     QList<ModelNode> allSubNodes();
 
index 5fc75d5..0f37eb4 100644 (file)
@@ -85,6 +85,7 @@ public:
     void propertiesRemoved(const QList<AbstractProperty>& propertyList);
     void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
     void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
     void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl);
index 7c2ee59..8bdfa29 100644 (file)
@@ -59,8 +59,7 @@ public:
     const QList<QmlObjectNode> toQmlObjectNodeList() const;
     void slide(int, int) const;
     void reparentHere(const ModelNode &modelNode);
-
-    bool isEmpty() const;
+    ModelNode at(int index) const;
 
 protected:
     NodeListProperty(const QString &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
index 91fdc85..83b850d 100644 (file)
@@ -98,6 +98,8 @@ CORESHARED_EXPORT uint qHash(const QmlItemNode &node);
 class CORESHARED_EXPORT QmlModelStateGroup
 {
     friend class QmlItemNode;
+    friend class QmlModelView;
+
 public:
 
     QmlModelStateGroup() : m_modelNode(ModelNode()) {}
index c7a752e..f5e9510 100644 (file)
@@ -54,6 +54,7 @@ public:
     QmlModelState currentState() const;
 
     QmlModelState baseState() const;
+    QmlModelStateGroup rootStateGroup() const;
 
     QmlObjectNode createQmlObjectNode(const QString &typeString,
                                       int majorVersion,
@@ -93,6 +94,7 @@ public:
 
     void nodeCreated(const ModelNode &createdNode);
     void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList);
     void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
index 6def199..f5e7719 100644 (file)
@@ -126,6 +126,7 @@ public:
     void propertiesRemoved(const QList<AbstractProperty>& propertyList);
     void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
     void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId);
     void nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int oldIndex);
index 9d95a92..20465dd 100644 (file)
@@ -359,6 +359,11 @@ void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractP
 //    nodeInstance.reparent(oldParentInstance, oldPropertyParent.name(), newParentInstance, newPropertyParent.name());
 }
 
+void NodeInstanceView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
+{
+}
+
+
 void NodeInstanceView::fileUrlChanged(const QUrl &/*oldUrl*/, const QUrl &newUrl)
 {
     // TODO: We have to probably reload everything, so that images etc are updated!!!
index 312c023..4cee3f1 100644 (file)
@@ -575,9 +575,11 @@ QStringList allPropertyNames(QObject *object, const QString &baseName = QString(
         QMetaProperty metaProperty = metaObject->property(index);
         QDeclarativeProperty declarativeProperty(object, QLatin1String(metaProperty.name()));
         if (declarativeProperty.isValid() && declarativeProperty.propertyTypeCategory() == QDeclarativeProperty::Object) {
-            QObject *childObject = QDeclarativeMetaType::toQObject(declarativeProperty.read());
-            if (childObject)
-                propertyNameList.append(allPropertyNames(childObject, baseName +  QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects));
+            if (declarativeProperty.name() != "parent") {
+                QObject *childObject = QDeclarativeMetaType::toQObject(declarativeProperty.read());
+                if (childObject)
+                    propertyNameList.append(allPropertyNames(childObject, baseName +  QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects));
+            }
         } else if (QDeclarativeValueTypeFactory::valueType(metaProperty.userType())) {
             QDeclarativeValueType *valueType = QDeclarativeValueTypeFactory::valueType(metaProperty.userType());
             valueType->setValue(metaProperty.read(object));
@@ -668,8 +670,10 @@ void allSubObject(QObject *object, QObjectList &objectList)
         if (metaProperty.isReadable()
                 && metaProperty.isWritable()
                 && QDeclarativeMetaType::isQObject(metaProperty.userType())) {
-            QObject *propertyObject = QDeclarativeMetaType::toQObject(metaProperty.read(object));
-            allSubObject(propertyObject, objectList);
+            if (metaProperty.name() != QLatin1String("parent")) {
+                QObject *propertyObject = QDeclarativeMetaType::toQObject(metaProperty.read(object));
+                allSubObject(propertyObject, objectList);
+            }
 
         }
 
@@ -848,9 +852,11 @@ QStringList propertyNameForWritableProperties(QObject *object, const QString &ba
         QMetaProperty metaProperty = metaObject->property(index);
         QDeclarativeProperty declarativeProperty(object, QLatin1String(metaProperty.name()));
         if (declarativeProperty.isValid() && declarativeProperty.isWritable() && declarativeProperty.propertyTypeCategory() == QDeclarativeProperty::Object) {
-            QObject *childObject = QDeclarativeMetaType::toQObject(declarativeProperty.read());
-            if (childObject)
-                propertyNameList.append(propertyNameForWritableProperties(childObject, baseName +  QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects));
+            if (declarativeProperty.name() != "parent") {
+                QObject *childObject = QDeclarativeMetaType::toQObject(declarativeProperty.read());
+                if (childObject)
+                    propertyNameList.append(propertyNameForWritableProperties(childObject, baseName +  QString::fromUtf8(metaProperty.name()) + '.', inspectedObjects));
+            }
         } else if (QDeclarativeValueTypeFactory::valueType(metaProperty.userType())) {
             QDeclarativeValueType *valueType = QDeclarativeValueTypeFactory::valueType(metaProperty.userType());
             valueType->setValue(metaProperty.read(object));
index 4402ac6..181b4ff 100644 (file)
@@ -145,7 +145,6 @@ private:
 
 uint qHash(const InternalNodePointer& node);
 bool operator <(const InternalNodePointer &firstNode, const InternalNodePointer &secondNode);
-
 } // Internal
 } // QtQmlDesigner
 
index d71b425..edebcfc 100644 (file)
@@ -50,6 +50,8 @@ public:
     virtual QList<InternalNodePointer> allDirectSubNodes() const = 0;
 
     virtual bool isEmpty() const = 0;
+    virtual int count() const = 0;
+    virtual int indexOf(const InternalNodePointer &node) const = 0;
 
     virtual bool isValid() const;
 protected:
index 4a604e1..81dbb19 100644 (file)
@@ -59,6 +59,25 @@ bool InternalNodeListProperty::isEmpty() const
     return m_nodeList.isEmpty();
 }
 
+int InternalNodeListProperty::count() const
+{
+    return m_nodeList.count();
+}
+
+int InternalNodeListProperty::indexOf(const InternalNode::Pointer &node) const
+{
+    if (node.isNull())
+        return -1;
+
+    return m_nodeList.indexOf(node);
+}
+
+InternalNode::Pointer InternalNodeListProperty::at(int index) const
+{
+    Q_ASSERT(index >=0 || index < m_nodeList.count());
+    return InternalNode::Pointer(m_nodeList.at(index));
+}
+
 bool InternalNodeListProperty::isNodeListProperty() const
 {
     return true;
index 64f0b3f..77a6b03 100644 (file)
@@ -48,6 +48,9 @@ public:
     bool isValid() const;
 
     bool isEmpty() const;
+    int count() const;
+    int indexOf(const InternalNodePointer &node) const;
+    InternalNodePointer at(int index) const;
 
     bool isNodeListProperty() const;
 
index a0c502c..1102a0f 100644 (file)
@@ -53,6 +53,22 @@ bool InternalNodeProperty::isEmpty() const
     return m_node.isNull();
 }
 
+int InternalNodeProperty::count() const
+{
+    if (isEmpty())
+        return 0;
+
+    return 1;
+}
+
+int InternalNodeProperty::indexOf(const InternalNode::Pointer &node) const
+{
+    if (!node.isNull() && node == m_node)
+        return 0;
+
+    return -1;
+}
+
 bool InternalNodeProperty::isValid() const
 {
     return InternalProperty::isValid() && isNodeProperty();
index 9123e22..72c24fa 100644 (file)
@@ -44,6 +44,8 @@ public:
 
     bool isValid() const;
     bool isEmpty() const;
+    int count() const;
+    int indexOf(const InternalNodePointer &node) const;
     bool isNodeProperty() const;
 
     QList<InternalNodePointer> allSubNodes() const;
index d8cb95c..f1c0558 100644 (file)
@@ -836,6 +836,64 @@ void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &int
     }
 }
 
+void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &internalNodePointer, const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange)
+{
+    bool resetModel = false;
+    QString description;
+
+    try {
+        if (rewriterView()) {
+            NodeAbstractProperty newProperty;
+            NodeAbstractProperty oldProperty;
+
+            if (!oldPropertyName.isEmpty() && oldParent->isValid())
+                oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), rewriterView());
+
+            if (!newPropertyParent.isNull())
+                newProperty = NodeAbstractProperty(newPropertyParent, model(), rewriterView());
+            ModelNode node(internalNodePointer, model(), rewriterView());
+            rewriterView()->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
+        }
+    } catch (RewritingException &e) {
+        description = e.description();
+        resetModel = true;
+    }
+
+    foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
+        NodeAbstractProperty newProperty;
+        NodeAbstractProperty oldProperty;
+
+        Q_ASSERT(!view.isNull());
+        if (!oldPropertyName.isEmpty() && oldParent->isValid())
+            oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), view.data());
+
+        if (!newPropertyParent.isNull())
+            newProperty = NodeAbstractProperty(newPropertyParent, model(), view.data());
+        ModelNode node(internalNodePointer, model(), view.data());
+
+        view->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
+
+    }
+
+    if (nodeInstanceView()) {
+        NodeAbstractProperty newProperty;
+        NodeAbstractProperty oldProperty;
+
+        if (!oldPropertyName.isEmpty() && oldParent->isValid())
+            oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), nodeInstanceView());
+
+        if (!newPropertyParent.isNull())
+            newProperty = NodeAbstractProperty(newPropertyParent, model(), nodeInstanceView());
+        ModelNode node(internalNodePointer, model(), nodeInstanceView());
+        nodeInstanceView()->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
+    }
+
+    if (resetModel) {
+        resetModelByRewriter(description);
+    }
+}
+
+
 void ModelPrivate::notifyNodeReparent(const InternalNode::Pointer &internalNodePointer, const InternalNodeAbstractProperty::Pointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange)
 {
     bool resetModel = false;
@@ -1121,6 +1179,9 @@ void ModelPrivate::reparentNode(const InternalNode::Pointer &newParentNode, cons
 
     InternalNodeAbstractProperty::Pointer newParentProperty(newParentNode->nodeAbstractProperty(name));
     Q_ASSERT(!newParentProperty.isNull());
+
+    notifyNodeAboutToBeReparent(node, newParentProperty, oldParentNode, oldParentPropertyName, propertyChange);
+
     if (newParentProperty)
         node->setParentProperty(newParentProperty);
 
index 25e6864..74531b9 100644 (file)
@@ -125,6 +125,7 @@ public:
     void setModel(Model *q) { m_q = q; }
 
     void notifyNodeCreated(const InternalNodePointer &newInternalNodePointer);
+    void notifyNodeAboutToBeReparent(const InternalNodePointer &internalNodePointer, const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange);
     void notifyNodeReparent(const InternalNodePointer &internalNodePointer, const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange);
     void notifyNodeAboutToBeRemoved(const InternalNodePointer &nodePointer);
     void notifyNodeRemoved(const InternalNodePointer &nodePointer, const InternalNodePointer &parentNodePointer, const QString &parentPropertyName, AbstractView::PropertyChangeFlags propertyChange);
index 0cc02b7..e97d84d 100644 (file)
@@ -106,6 +106,24 @@ bool NodeAbstractProperty::isEmpty() const
         return property->isEmpty();
 }
 
+int NodeAbstractProperty::indexOf(const ModelNode &node) const
+{
+    Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name());
+    if (property.isNull())
+        return 0;
+
+    return property->indexOf(node.internalNode());
+}
+
+int NodeAbstractProperty::count() const
+{
+    Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name());
+    if (property.isNull())
+        return 0;
+    else
+        return property->count();
+}
+
 QList<ModelNode> NodeAbstractProperty::allSubNodes()
 {
     if (!internalNode()
index c81a880..a24125e 100644 (file)
@@ -115,12 +115,17 @@ void NodeListProperty::reparentHere(const ModelNode &modelNode)
     NodeAbstractProperty::reparentHere(modelNode, true);
 }
 
-bool NodeListProperty::isEmpty() const
+ModelNode NodeListProperty::at(int index) const
 {
     if (!isValid())
         throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, "<invalid node list property>");
-    return toModelNodeList().empty();
-}
 
+    Internal::InternalNodeListProperty::Pointer internalProperty = internalNode()->nodeListProperty(name());
+    if (internalProperty)
+        return ModelNode(internalProperty->at(index), model(), view());
+
+
+    return ModelNode();
+}
 
 } // namespace QmlDesigner
index e328d70..e7551eb 100644 (file)
@@ -326,7 +326,7 @@ AnchorLine QmlAnchors::instanceAnchor(AnchorLine::Type sourceAnchorLine) const
     if (targetAnchorLine == AnchorLine::Invalid )
         return AnchorLine();
 
-    if (!targetAnchorLinePair.second >= 0) //there might be no node instance for the parent
+    if (targetAnchorLinePair.second < 0) //there might be no node instance for the parent
         return AnchorLine();
 
     return AnchorLine(QmlItemNode(qmlItemNode().nodeForInstance(qmlItemNode().qmlModelView()->nodeInstanceView()->instanceForId(targetAnchorLinePair.second))), targetAnchorLine);
index 072d996..9cadcf3 100644 (file)
 #include "nodeabstractproperty.h"
 #include "variantproperty.h"
 
-enum {
-    debug = false
-};
-
 
 namespace QmlDesigner {
 
@@ -70,6 +66,11 @@ QmlModelState QmlModelView::baseState() const
     return QmlModelState::createBaseState(this);
 }
 
+QmlModelStateGroup QmlModelView::rootStateGroup() const
+{
+    return QmlModelStateGroup(rootModelNode());
+}
+
 QmlObjectNode QmlModelView::createQmlObjectNode(const QString &typeString,
                      int majorVersion,
                      int minorVersion,
@@ -278,16 +279,19 @@ QmlObjectNode QmlModelView::fxObjectNodeForId(const QString &id)
 
 void QmlModelView::customNotification(const AbstractView * /* view */, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> & /* data */)
 {
-    if (debug)
-        qDebug() << this << __FUNCTION__ << identifier << nodeList;
-
     if (identifier == "__state changed__") {
-        QmlModelState state(nodeList.first());
-        if (state.isValid()) {
-            activateState(state);
-        } else {
-            activateState(baseState());
-        }
+        QmlModelState newState(nodeList.first());
+        QmlModelState oldState = currentState();
+
+        if (!newState.isValid())
+            newState = baseState();
+
+        activateState(newState);
+
+        m_state = newState;
+
+        if (newState != oldState)
+            stateChanged(newState, oldState);
     }
 }
 
@@ -340,6 +344,7 @@ void QmlModelView::nodeOrderChanged(const NodeListProperty &/*listProperty*/, co
 void QmlModelView::nodeCreated(const ModelNode &/*createdNode*/) {}
 void QmlModelView::nodeAboutToBeRemoved(const ModelNode &/*removedNode*/) {}
 void QmlModelView::nodeRemoved(const ModelNode &/*removedNode*/, const NodeAbstractProperty &/*parentProperty*/, PropertyChangeFlags /*propertyChange*/) {}
+void QmlModelView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
 void QmlModelView::nodeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/) {}
 void QmlModelView::nodeIdChanged(const ModelNode& /*node*/, const QString& /*newId*/, const QString& /*oldId*/) {}
 void QmlModelView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& /*propertyList*/) {}
@@ -360,9 +365,6 @@ void QmlModelView::instancePropertyChange(const QList<QPair<ModelNode, QString>
 
 void QmlModelView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName)
 {
-    if (debug)
-        qDebug() << this << __FUNCTION__ << node << propertyName;
-
     QmlObjectNode qmlObjectNode(node);
 
     if (!qmlObjectNode.isValid())
@@ -372,17 +374,12 @@ 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 (debug)
-        qDebug() << this << __FUNCTION__ << state;
-
     if (!state.isValid())
         return;
 
@@ -405,9 +402,6 @@ void QmlModelView::activateState(const QmlModelState &state)
 
 void QmlModelView::changeToState(const ModelNode &node, const QString &stateName)
 {
-    if (debug)
-        qDebug() << this << __FUNCTION__ << node << stateName;
-
     QmlItemNode itemNode(node);
 
     QmlModelState newState;
@@ -439,8 +433,6 @@ void QmlModelView::otherPropertyChanged(const QmlObjectNode &/*qmlObjectNode*/,
 
 void  QmlModelView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
 {
-    if (debug)
-        qDebug() << this << __FUNCTION__ << oldQmlModelState << "to" << newQmlModelState;
 }
 
 } //QmlDesigner
index 07d7669..470c3f6 100644 (file)
@@ -275,6 +275,11 @@ void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractPrope
         applyChanges();
 }
 
+void RewriterView::nodeAboutToBeReparented(const ModelNode &/*node*/, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &/*oldPropertyParent*/, AbstractView::PropertyChangeFlags /*propertyChange*/)
+{
+}
+
+
 void RewriterView::importAdded(const Import &import)
 {
     Q_ASSERT(textModifier());
index dd477e6..3977d77 100644 (file)
@@ -110,6 +110,12 @@ void ViewLogger::nodeRemoved(const ModelNode &removedNode, const NodeAbstractPro
     m_output << time() << indent("nodeRemoved:") << removedNode << parentProperty << serialize(propertyChange) << endl;
 }
 
+void ViewLogger::nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
+{
+    m_output << time() << indent("nodeAboutToBeReparented:") << node << "\t" << newPropertyParent << "\t" << oldPropertyParent << "\t" << serialize(propertyChange) << endl;
+}
+
+
 void ViewLogger::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
 {
     m_output << time() << indent("nodeReparented:") << node << "\t" << newPropertyParent << "\t" << oldPropertyParent << "\t" << serialize(propertyChange) << endl;
index 5bff84b..a20b7b2 100644 (file)
@@ -50,6 +50,7 @@ public:
     void nodeCreated(const ModelNode &createdNode);
     void nodeAboutToBeRemoved(const ModelNode &removedNode);
     void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange);
+    void nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange);
     void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId);
     void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
index 08779e9..8895602 100644 (file)
@@ -35,6 +35,7 @@
 #include <model.h>
 #include <rewriterview.h>
 #include <formeditorwidget.h>
+#include <stateseditorwidget.h>
 
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/modemanager.h>
@@ -211,8 +212,8 @@ void DesignModeWidget::toggleSidebars()
         m_leftSideBar->setVisible(m_showSidebars);
     if (m_rightSideBar)
         m_rightSideBar->setVisible(m_showSidebars);
-    if (!m_statesEditorWidget.isNull())
-        m_statesEditorWidget->setVisible(m_showSidebars);
+    if (!m_statesEditorView.isNull())
+        m_statesEditorView->widget()->setVisible(m_showSidebars);
 
 }
 
@@ -261,7 +262,7 @@ void DesignModeWidget::showEditor(Core::IEditor *editor)
             newDocument->setNodeInstanceView(m_nodeInstanceView.data());
             newDocument->setAllPropertiesBox(m_allPropertiesBox.data());
             newDocument->setNavigator(m_navigator.data());
-            newDocument->setStatesEditorWidget(m_statesEditorWidget.data());
+            newDocument->setStatesEditorView(m_statesEditorView.data());
             newDocument->setItemLibrary(m_itemLibrary.data());
             newDocument->setFormEditorView(m_formEditorView.data());
 
@@ -448,7 +449,7 @@ void DesignModeWidget::enable()
         qDebug() << Q_FUNC_INFO;
     m_warningWidget->setVisible(false);
     m_formEditorView->widget()->setEnabled(true);
-    m_statesEditorWidget->setEnabled(true);
+    m_statesEditorView->widget()->setEnabled(true);
     m_leftSideBar->setEnabled(true);
     m_rightSideBar->setEnabled(true);
     m_isDisabled = false;
@@ -463,7 +464,7 @@ void DesignModeWidget::disable(const QList<RewriterView::Error> &errors)
     m_warningWidget->setVisible(true);
     m_warningWidget->move(width() / 2, height() / 2);
     m_formEditorView->widget()->setEnabled(false);
-    m_statesEditorWidget->setEnabled(false);
+    m_statesEditorView->widget()->setEnabled(false);
     m_leftSideBar->setEnabled(false);
     m_rightSideBar->setEnabled(false);
     m_isDisabled = true;
@@ -627,7 +628,7 @@ void DesignModeWidget::setup()
     m_allPropertiesBox = new AllPropertiesBox;
     m_itemLibrary = new ItemLibrary;
 
-    m_statesEditorWidget = new StatesEditorWidget(this);
+    m_statesEditorView = new StatesEditorView(this);
     
     m_formEditorView = new FormEditorView(this);
 
@@ -685,7 +686,7 @@ void DesignModeWidget::setup()
         rightLayout->setSpacing(0);
         rightLayout->addWidget(m_fakeToolBar);
         //### we now own these here
-        rightLayout->addWidget(m_statesEditorWidget.data());
+        rightLayout->addWidget(m_statesEditorView->widget());
 
         FormEditorContext *context = new FormEditorContext(m_formEditorView->widget());
         Core::ICore::instance()->addContextObject(context);
@@ -715,7 +716,7 @@ void DesignModeWidget::setup()
     mainLayout->addWidget(m_mainSplitter);
 
     m_warningWidget->setVisible(false);
-    m_statesEditorWidget->setEnabled(true);
+    m_statesEditorView->widget()->setEnabled(true);
     m_leftSideBar->setEnabled(true);
     m_rightSideBar->setEnabled(true);
     m_leftSideBar->setCloseWhenEmpty(true);
index d10c73b..203da51 100644 (file)
@@ -41,7 +41,7 @@
 #include <itemlibrary.h>
 #include <navigatorwidget.h>
 #include <navigatorview.h>
-#include <stateseditorwidget.h>
+#include <stateseditorview.h>
 #include <modelnode.h>
 #include <formeditorview.h>
 
@@ -177,7 +177,7 @@ private:
     QWeakPointer<ItemLibrary> m_itemLibrary;
     QWeakPointer<NavigatorView> m_navigator;
     QWeakPointer<AllPropertiesBox> m_allPropertiesBox;
-    QWeakPointer<StatesEditorWidget> m_statesEditorWidget;
+    QWeakPointer<StatesEditorView> m_statesEditorView;
     QWeakPointer<FormEditorView> m_formEditorView;
     QWeakPointer<NodeInstanceView> m_nodeInstanceView;