From 562d0c5fbd5a6581a9efe539047d1b8651d421c8 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 8 Dec 2010 16:46:25 +0100 Subject: [PATCH] QmlDesigner: Refactor states editor Reviewed-By: Thomas Hartmann --- .../components/integration/componentview.cpp | 2 +- .../components/integration/componentview.h | 1 + .../integration/designdocumentcontroller.cpp | 10 +- .../integration/designdocumentcontroller.h | 4 +- .../integration/designdocumentcontrollerview.cpp | 1 + .../integration/designdocumentcontrollerview.h | 1 + .../components/navigator/navigatorview.cpp | 4 + .../components/navigator/navigatorview.h | 2 +- .../components/stateseditor/stateseditormodel.cpp | 141 +++++--- .../components/stateseditor/stateseditormodel.h | 21 +- .../components/stateseditor/stateseditorview.cpp | 387 +++++++++------------ .../components/stateseditor/stateseditorview.h | 42 ++- .../components/stateseditor/stateseditorwidget.cpp | 148 ++------ .../components/stateseditor/stateseditorwidget.h | 21 +- .../components/stateseditor/stateslist.qml | 48 +-- .../designercore/include/abstractview.h | 1 + .../designercore/include/nodeabstractproperty.h | 2 + .../designercore/include/nodeinstanceview.h | 1 + .../designercore/include/nodelistproperty.h | 3 +- .../qmldesigner/designercore/include/qmlitemnode.h | 2 + .../designercore/include/qmlmodelview.h | 2 + .../designercore/include/rewriterview.h | 1 + .../designercore/instances/nodeinstanceview.cpp | 5 + .../designercore/instances/objectnodeinstance.cpp | 22 +- .../designercore/model/internalnode_p.h | 1 - .../model/internalnodeabstractproperty.h | 2 + .../model/internalnodelistproperty.cpp | 19 + .../designercore/model/internalnodelistproperty.h | 3 + .../designercore/model/internalnodeproperty.cpp | 16 + .../designercore/model/internalnodeproperty.h | 2 + .../qmldesigner/designercore/model/model.cpp | 61 ++++ .../qmldesigner/designercore/model/model_p.h | 1 + .../designercore/model/nodeabstractproperty.cpp | 18 + .../designercore/model/nodelistproperty.cpp | 11 +- .../qmldesigner/designercore/model/qmlanchors.cpp | 2 +- .../designercore/model/qmlmodelview.cpp | 44 +-- .../designercore/model/rewriterview.cpp | 5 + .../qmldesigner/designercore/model/viewlogger.cpp | 6 + .../qmldesigner/designercore/model/viewlogger.h | 1 + src/plugins/qmldesigner/designmodewidget.cpp | 17 +- src/plugins/qmldesigner/designmodewidget.h | 4 +- 41 files changed, 547 insertions(+), 538 deletions(-) diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index 77ae505eff..8741d72142 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -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& /*propertyList*/) {} diff --git a/src/plugins/qmldesigner/components/integration/componentview.h b/src/plugins/qmldesigner/components/integration/componentview.h index d4612d0a63..40a0ffc0c0 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.h +++ b/src/plugins/qmldesigner/components/integration/componentview.h @@ -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& propertyList); diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp index ddb75459eb..fe776a4bc9 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -87,7 +87,7 @@ public: QWeakPointer itemLibrary; QWeakPointer navigator; QWeakPointer allPropertiesBox; - QWeakPointer statesEditorWidget; + QWeakPointer statesEditorView; QWeakPointer stackedWidget; QWeakPointer 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()); diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h index 76bed22727..50b67ee810 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h @@ -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); diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp index 6e63157a2b..fea1e712d4 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.cpp @@ -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& /*propertyList*/) {}; diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h index 6fc0273029..9d61a58159 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontrollerview.h @@ -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& propertyList); diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 3fe7926201..7b57375e74 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -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); diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 5b142e18b0..ea1ca45fb5 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -69,9 +69,9 @@ public: void bindingPropertiesChanged(const QList &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); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index 36ac4ab481..69f5831ceb 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -33,107 +33,143 @@ #include #include +#include +#include +#include + 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 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 diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h index 556bea6812..2a6bd09040 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h @@ -33,11 +33,10 @@ #include #include -#include 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 m_stateNames; - QWeakPointer m_statesView; + QWeakPointer m_statesEditorView; int m_updateCounter; }; -} // namespace Itnernal } // namespace QmlDesigner #endif // STATESEDITORMODEL_H diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index d6a6e0c923..f8827ec92d 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "stateseditorview.h" +#include "stateseditorwidget.h" #include "stateseditormodel.h" #include #include @@ -38,6 +39,8 @@ #include #include +#include + #include #include @@ -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 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 &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 &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 &/*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 diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index cae5e5cbc9..c149c33cea 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -34,24 +34,18 @@ 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& 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 &propertyList, PropertyChangeFlags propertyChange); void selectedNodesChanged(const QList &selectedNodeList, const QList &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 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 m_statesEditorModel; + QWeakPointer m_statesEditorWidget; + int m_lastIndex; }; -} // namespace Internal } // namespace QmlDesigner #endif // STATESEDITORVIEW_H diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index dbdff9efd8..615ac9af23 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -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; - QWeakPointer listView; - QWeakPointer statesEditorModel; - QWeakPointer 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 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 { diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h index 15654935f4..0a7d0d832b 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h @@ -33,31 +33,34 @@ #include #include +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 m_declarativeView; + QWeakPointer m_statesEditorView; }; } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateslist.qml b/src/plugins/qmldesigner/components/stateseditor/stateslist.qml index 2a552c32bb..19b6bfb068 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateslist.qml +++ b/src/plugins/qmldesigner/components/stateseditor/stateslist.qml @@ -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) diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index dd20dde3eb..2e27e015ce 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -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& propertyList) = 0; diff --git a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h index 1b2bdb3cda..9df588e089 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h @@ -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 allSubNodes(); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 5fc75d55a8..0f37eb4152 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -85,6 +85,7 @@ public: void propertiesRemoved(const QList& propertyList); void variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange); void bindingPropertiesChanged(const QList& 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); diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index 7c2ee5937b..8bdfa291a7 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -59,8 +59,7 @@ public: const QList 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); diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 91fdc853b8..83b850dc04 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -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()) {} diff --git a/src/plugins/qmldesigner/designercore/include/qmlmodelview.h b/src/plugins/qmldesigner/designercore/include/qmlmodelview.h index c7a752e568..f5e9510320 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlmodelview.h +++ b/src/plugins/qmldesigner/designercore/include/qmlmodelview.h @@ -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 &propertyList); void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion); diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 6def1990c6..f5e77193c5 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -126,6 +126,7 @@ public: void propertiesRemoved(const QList& propertyList); void variantPropertiesChanged(const QList& propertyList, PropertyChangeFlags propertyChange); void bindingPropertiesChanged(const QList& 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); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 9d95a92dbd..20465dd7ac 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -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!!! diff --git a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp index 312c023e58..4cee3f127c 100644 --- a/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/objectnodeinstance.cpp @@ -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)); diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 4402ac611f..181b4ff7cf 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -145,7 +145,6 @@ private: uint qHash(const InternalNodePointer& node); bool operator <(const InternalNodePointer &firstNode, const InternalNodePointer &secondNode); - } // Internal } // QtQmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h index d71b425feb..edebcfcdc2 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h @@ -50,6 +50,8 @@ public: virtual QList 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: diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp index 4a604e14a8..81dbb19dbd 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp @@ -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; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h index 64f0b3fd93..77a6b03e22 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h @@ -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; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp index a0c502c92a..1102a0f7e4 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp @@ -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(); diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h index 9123e22ee0..72c24fa7f3 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h @@ -44,6 +44,8 @@ public: bool isValid() const; bool isEmpty() const; + int count() const; + int indexOf(const InternalNodePointer &node) const; bool isNodeProperty() const; QList allSubNodes() const; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index d8cb95c231..f1c0558bdb 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -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 &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); diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 25e6864028..74531b9ac8 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -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); diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp index 0cc02b781c..e97d84d387 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp @@ -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 NodeAbstractProperty::allSubNodes() { if (!internalNode() diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index c81a8806f9..a24125e039 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -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__, ""); - return toModelNodeList().empty(); -} + Internal::InternalNodeListProperty::Pointer internalProperty = internalNode()->nodeListProperty(name()); + if (internalProperty) + return ModelNode(internalProperty->at(index), model(), view()); + + + return ModelNode(); +} } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp index e328d709df..e7551ebed8 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlanchors.cpp @@ -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); diff --git a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp index 072d99694b..9cadcf3671 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlmodelview.cpp @@ -40,10 +40,6 @@ #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 &nodeList, const QList & /* 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& /*propertyList*/) {} @@ -360,9 +365,6 @@ void QmlModelView::instancePropertyChange(const QList 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 diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index 07d7669b13..470c3f6d8a 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -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()); diff --git a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp index dd477e6951..3977d7737d 100644 --- a/src/plugins/qmldesigner/designercore/model/viewlogger.cpp +++ b/src/plugins/qmldesigner/designercore/model/viewlogger.cpp @@ -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; diff --git a/src/plugins/qmldesigner/designercore/model/viewlogger.h b/src/plugins/qmldesigner/designercore/model/viewlogger.h index 5bff84bad5..a20b7b2a89 100644 --- a/src/plugins/qmldesigner/designercore/model/viewlogger.h +++ b/src/plugins/qmldesigner/designercore/model/viewlogger.h @@ -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& propertyList); diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 08779e9685..889560216c 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -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 &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); diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index d10c73b7cd..203da51b7c 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include @@ -177,7 +177,7 @@ private: QWeakPointer m_itemLibrary; QWeakPointer m_navigator; QWeakPointer m_allPropertiesBox; - QWeakPointer m_statesEditorWidget; + QWeakPointer m_statesEditorView; QWeakPointer m_formEditorView; QWeakPointer m_nodeInstanceView; -- 2.11.0