diff options
8 files changed, 184 insertions, 15 deletions
diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml index ef624574ac..6b01f322f8 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml @@ -41,6 +41,8 @@ Rectangle { property int delegateStateImageSize property bool delegateHasWhenCondition property string delegateWhenConditionString + property bool hasAnnotation: checkAnnotation() + readonly property bool isDefaultState: isDefault signal delegateInteraction @@ -53,6 +55,10 @@ Rectangle { return stringList } + function checkAnnotation() { + return statesEditorModel.hasAnnotation(internalNodeId) + } + MouseArea { id: mouseArea anchors.fill: parent @@ -120,11 +126,31 @@ Rectangle { } } + StudioControls.MenuItem { + enabled: !isBaseState + text: (hasAnnotation ? qsTr("Edit Annotation") + : qsTr("Add Annotation")) + onTriggered: { + statesEditorModel.setAnnotation(internalNodeId) + hasAnnotation = checkAnnotation() + } + } + + StudioControls.MenuItem { + enabled: !isBaseState && hasAnnotation + text: qsTr("Remove Annotation") + onTriggered: { + statesEditorModel.removeAnnotation(internalNodeId) + hasAnnotation = checkAnnotation() + } + } + onClosed: { stateNameField.actionIndicator.forceVisible = false } onOpened: { + hasAnnotation = checkAnnotation() myRoot.delegateInteraction() } } diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.cpp b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.cpp index c119dfdca1..21add0a752 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.cpp +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.cpp @@ -38,7 +38,8 @@ namespace QmlDesigner { -AnnotationEditor::AnnotationEditor(QObject *) +AnnotationEditor::AnnotationEditor(QObject *parent) + : QObject(parent) { } @@ -55,9 +56,9 @@ void AnnotationEditor::registerDeclarativeType() void AnnotationEditor::showWidget() { m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(), - modelNode().validId(), - modelNode().customId(), - modelNode().annotation()); + m_modelNode.id(), + m_modelNode.customId(), + m_modelNode.annotation()); QObject::connect(m_dialog, &AnnotationEditorDialog::accepted, this, &AnnotationEditor::acceptedClicked); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index f2a83d0518..1828317a9e 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -249,4 +249,19 @@ bool StatesEditorModel::hasDefaultState() const return m_statesEditorView->hasDefaultState(); } +void StatesEditorModel::setAnnotation(int internalNodeId) +{ + m_statesEditorView->setAnnotation(internalNodeId); +} + +void StatesEditorModel::removeAnnotation(int internalNodeId) +{ + m_statesEditorView->removeAnnotation(internalNodeId); +} + +bool StatesEditorModel::hasAnnotation(int internalNodeId) const +{ + return m_statesEditorView->hasAnnotation(internalNodeId); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h index 97c4c6a9ec..65c1385e89 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.h @@ -67,6 +67,9 @@ public: Q_INVOKABLE void setStateAsDefault(int internalNodeId); Q_INVOKABLE void resetDefaultState(); Q_INVOKABLE bool hasDefaultState() const; + Q_INVOKABLE void setAnnotation(int internalNodeId); + Q_INVOKABLE void removeAnnotation(int internalNodeId); + Q_INVOKABLE bool hasAnnotation(int internalNodeId) const; void reset(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 8a2ca50c15..78ac9da230 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -30,6 +30,7 @@ #include <QDebug> #include <QRegExp> +#include <QScopeGuard> #include <cmath> #include <nodemetainfo.h> @@ -40,6 +41,7 @@ #include <qmlitemnode.h> #include <qmlstate.h> +#include <annotationeditor/annotationeditor.h> namespace QmlDesigner { @@ -51,7 +53,8 @@ namespace QmlDesigner { StatesEditorView::StatesEditorView(QObject *parent) : AbstractView(parent), m_statesEditorModel(new StatesEditorModel(this)), - m_lastIndex(-1) + m_lastIndex(-1), + m_editor(nullptr) { Q_ASSERT(m_statesEditorModel); // base state @@ -59,6 +62,8 @@ StatesEditorView::StatesEditorView(QObject *parent) : StatesEditorView::~StatesEditorView() { + if (m_editor) + delete m_editor; delete m_statesEditorWidget.data(); } @@ -274,6 +279,8 @@ void StatesEditorView::setWhenCondition(int internalNodeId, const QString &condi return; m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); if (hasModelNodeForInternalId(internalNodeId)) { QmlModelState state(modelNodeForInternalId(internalNodeId)); @@ -285,8 +292,6 @@ void StatesEditorView::setWhenCondition(int internalNodeId, const QString &condi e.showException(); } } - - m_block = false; } void StatesEditorView::resetWhenCondition(int internalNodeId) @@ -295,6 +300,8 @@ void StatesEditorView::resetWhenCondition(int internalNodeId) return; m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); if (hasModelNodeForInternalId(internalNodeId)) { QmlModelState state(modelNodeForInternalId(internalNodeId)); @@ -306,8 +313,6 @@ void StatesEditorView::resetWhenCondition(int internalNodeId) e.showException(); } } - - m_block = false; } void StatesEditorView::setStateAsDefault(int internalNodeId) @@ -316,6 +321,8 @@ void StatesEditorView::setStateAsDefault(int internalNodeId) return; m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); if (hasModelNodeForInternalId(internalNodeId)) { QmlModelState state(modelNodeForInternalId(internalNodeId)); @@ -327,8 +334,6 @@ void StatesEditorView::setStateAsDefault(int internalNodeId) e.showException(); } } - - m_block = false; } void StatesEditorView::resetDefaultState() @@ -337,6 +342,8 @@ void StatesEditorView::resetDefaultState() return; m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); try { if (rootModelNode().hasProperty("state")) @@ -345,8 +352,6 @@ void StatesEditorView::resetDefaultState() } catch (const RewritingException &e) { e.showException(); } - - m_block = false; } bool StatesEditorView::hasDefaultState() const @@ -354,6 +359,70 @@ bool StatesEditorView::hasDefaultState() const return rootModelNode().hasProperty("state"); } +void StatesEditorView::setAnnotation(int internalNodeId) +{ + if (m_block) + return; + + m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); + + if (hasModelNodeForInternalId(internalNodeId)) { + QmlModelState state(modelNodeForInternalId(internalNodeId)); + try { + if (state.isValid()) { + ModelNode modelNode = state.modelNode(); + + if (modelNode.isValid()) { + if (!m_editor) + m_editor = new AnnotationEditor(this); + + m_editor->setModelNode(modelNode); + m_editor->showWidget(); + } + } + + } catch (const RewritingException &e) { + e.showException(); + } + } +} + +void StatesEditorView::removeAnnotation(int internalNodeId) +{ + if (m_block) + return; + + m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); + + if (hasModelNodeForInternalId(internalNodeId)) { + QmlModelState state(modelNodeForInternalId(internalNodeId)); + try { + if (state.isValid()) { + state.removeAnnotation(); + } + + } catch (const RewritingException &e) { + e.showException(); + } + } +} + +bool StatesEditorView::hasAnnotation(int internalNodeId) const +{ + if (hasModelNodeForInternalId(internalNodeId)) { + QmlModelState state(modelNodeForInternalId(internalNodeId)); + if (state.isValid()) { + return state.hasAnnotation(); + } + } + + return false; +} + void StatesEditorView::modelAttached(Model *model) { if (model == AbstractView::model()) @@ -444,7 +513,12 @@ void StatesEditorView::bindingPropertiesChanged(const QList<BindingProperty> &pr void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList, AbstractView::PropertyChangeFlags /*propertyChange*/) { + if (m_block) + return; + m_block = true; + auto guard = [this]() { m_block = false; }; + QScopeGuard<decltype(guard)> lock(guard); for (const VariantProperty &property : propertyList) { if (property.name() == "name" && QmlModelState::isValidQmlModelState(property.parentModelNode())) @@ -452,8 +526,6 @@ void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &pr else if (property.name() == "state" && property.parentModelNode().isRootNode()) resetModel(); } - - m_block = false; } void StatesEditorView::currentStateChanged(const ModelNode &node) diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index 66ab998e04..44b4a3a380 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -33,6 +33,7 @@ namespace QmlDesigner { class StatesEditorModel; class StatesEditorWidget; +class AnnotationEditor; class StatesEditorView : public AbstractView { Q_OBJECT @@ -47,6 +48,9 @@ public: void setStateAsDefault(int internalNodeId); void resetDefaultState(); bool hasDefaultState() const; + void setAnnotation(int internalNodeId); + void removeAnnotation(int internalNodeId); + bool hasAnnotation(int internalNodeId) const; bool validStateName(const QString &name) const; QString currentStateName() const; void setCurrentState(const QmlModelState &state); @@ -102,6 +106,7 @@ private: QPointer<StatesEditorWidget> m_statesEditorWidget; int m_lastIndex; bool m_block = false; + QPointer<AnnotationEditor> m_editor; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/qmlstate.h b/src/plugins/qmldesigner/designercore/include/qmlstate.h index 156e441615..7c43ac8776 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlstate.h +++ b/src/plugins/qmldesigner/designercore/include/qmlstate.h @@ -34,6 +34,8 @@ namespace QmlDesigner { class AbstractViewAbstractVieweGroup; class QmlObjectNode; class QmlModelStateGroup; +class Annotation; +class AnnotationEditor; class QMLDESIGNERCORE_EXPORT QmlModelState : public QmlModelNodeFacade { @@ -72,6 +74,12 @@ public: void setAsDefault(); bool isDefault() const; + void setAnnotation(const Annotation &annotation, const QString &id); + Annotation annotation() const; + QString annotationName() const; + bool hasAnnotation() const; + void removeAnnotation(); + protected: void addChangeSetIfNotExists(const ModelNode &node); static QmlModelState createBaseState(const AbstractView *view); diff --git a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp index 89bbec351e..4a38985ad1 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp @@ -32,6 +32,8 @@ #include "bindingproperty.h" #include "qmlchangeset.h" #include "qmlitemnode.h" +#include "annotation.h" +#include "annotationeditor/annotationeditor.h" #include <utils/qtcassert.h> @@ -304,6 +306,43 @@ bool QmlModelState::isDefault() const return false; } +void QmlModelState::setAnnotation(const Annotation &annotation, const QString &id) +{ + if (modelNode().isValid()) { + modelNode().setCustomId(id); + modelNode().setAnnotation(annotation); + } +} + +Annotation QmlModelState::annotation() const +{ + if (modelNode().isValid()) + return modelNode().annotation(); + return {}; +} + +QString QmlModelState::annotationName() const +{ + if (modelNode().isValid()) + return modelNode().customId(); + return {}; +} + +bool QmlModelState::hasAnnotation() const +{ + if (modelNode().isValid()) + return modelNode().hasAnnotation() || modelNode().hasCustomId(); + return false; +} + +void QmlModelState::removeAnnotation() +{ + if (modelNode().isValid()) { + modelNode().removeCustomId(); + modelNode().removeAnnotation(); + } +} + QmlModelState QmlModelState::createBaseState(const AbstractView *view) { QmlModelState qmlModelState(view->rootModelNode()); |