QmlDesigner: Annotations for States

- Added Annotations support for States

Task: QDS-2312

Change-Id: I204ec958f85bd0f05eae0abbb3848d6d59e7e397
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
Aleksei German
2020-07-28 17:03:35 +02:00
committed by Thomas Hartmann
parent ac5d35a53d
commit f642c02eb6
8 changed files with 184 additions and 15 deletions

View File

@@ -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()
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -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());