forked from qt-creator/qt-creator
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:
committed by
Thomas Hartmann
parent
ac5d35a53d
commit
f642c02eb6
@@ -41,6 +41,8 @@ Rectangle {
|
|||||||
property int delegateStateImageSize
|
property int delegateStateImageSize
|
||||||
property bool delegateHasWhenCondition
|
property bool delegateHasWhenCondition
|
||||||
property string delegateWhenConditionString
|
property string delegateWhenConditionString
|
||||||
|
property bool hasAnnotation: checkAnnotation()
|
||||||
|
|
||||||
readonly property bool isDefaultState: isDefault
|
readonly property bool isDefaultState: isDefault
|
||||||
|
|
||||||
signal delegateInteraction
|
signal delegateInteraction
|
||||||
@@ -53,6 +55,10 @@ Rectangle {
|
|||||||
return stringList
|
return stringList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkAnnotation() {
|
||||||
|
return statesEditorModel.hasAnnotation(internalNodeId)
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
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: {
|
onClosed: {
|
||||||
stateNameField.actionIndicator.forceVisible = false
|
stateNameField.actionIndicator.forceVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpened: {
|
onOpened: {
|
||||||
|
hasAnnotation = checkAnnotation()
|
||||||
myRoot.delegateInteraction()
|
myRoot.delegateInteraction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,8 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
AnnotationEditor::AnnotationEditor(QObject *)
|
AnnotationEditor::AnnotationEditor(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +56,9 @@ void AnnotationEditor::registerDeclarativeType()
|
|||||||
void AnnotationEditor::showWidget()
|
void AnnotationEditor::showWidget()
|
||||||
{
|
{
|
||||||
m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(),
|
m_dialog = new AnnotationEditorDialog(Core::ICore::dialogParent(),
|
||||||
modelNode().validId(),
|
m_modelNode.id(),
|
||||||
modelNode().customId(),
|
m_modelNode.customId(),
|
||||||
modelNode().annotation());
|
m_modelNode.annotation());
|
||||||
|
|
||||||
QObject::connect(m_dialog, &AnnotationEditorDialog::accepted,
|
QObject::connect(m_dialog, &AnnotationEditorDialog::accepted,
|
||||||
this, &AnnotationEditor::acceptedClicked);
|
this, &AnnotationEditor::acceptedClicked);
|
||||||
|
@@ -249,4 +249,19 @@ bool StatesEditorModel::hasDefaultState() const
|
|||||||
return m_statesEditorView->hasDefaultState();
|
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
|
} // namespace QmlDesigner
|
||||||
|
@@ -67,6 +67,9 @@ public:
|
|||||||
Q_INVOKABLE void setStateAsDefault(int internalNodeId);
|
Q_INVOKABLE void setStateAsDefault(int internalNodeId);
|
||||||
Q_INVOKABLE void resetDefaultState();
|
Q_INVOKABLE void resetDefaultState();
|
||||||
Q_INVOKABLE bool hasDefaultState() const;
|
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();
|
void reset();
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
#include <QScopeGuard>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
|
|
||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
#include <qmlstate.h>
|
#include <qmlstate.h>
|
||||||
|
#include <annotationeditor/annotationeditor.h>
|
||||||
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -51,7 +53,8 @@ namespace QmlDesigner {
|
|||||||
StatesEditorView::StatesEditorView(QObject *parent) :
|
StatesEditorView::StatesEditorView(QObject *parent) :
|
||||||
AbstractView(parent),
|
AbstractView(parent),
|
||||||
m_statesEditorModel(new StatesEditorModel(this)),
|
m_statesEditorModel(new StatesEditorModel(this)),
|
||||||
m_lastIndex(-1)
|
m_lastIndex(-1),
|
||||||
|
m_editor(nullptr)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_statesEditorModel);
|
Q_ASSERT(m_statesEditorModel);
|
||||||
// base state
|
// base state
|
||||||
@@ -59,6 +62,8 @@ StatesEditorView::StatesEditorView(QObject *parent) :
|
|||||||
|
|
||||||
StatesEditorView::~StatesEditorView()
|
StatesEditorView::~StatesEditorView()
|
||||||
{
|
{
|
||||||
|
if (m_editor)
|
||||||
|
delete m_editor;
|
||||||
delete m_statesEditorWidget.data();
|
delete m_statesEditorWidget.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +279,8 @@ void StatesEditorView::setWhenCondition(int internalNodeId, const QString &condi
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_block = true;
|
m_block = true;
|
||||||
|
auto guard = [this]() { m_block = false; };
|
||||||
|
QScopeGuard<decltype(guard)> lock(guard);
|
||||||
|
|
||||||
if (hasModelNodeForInternalId(internalNodeId)) {
|
if (hasModelNodeForInternalId(internalNodeId)) {
|
||||||
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
||||||
@@ -285,8 +292,6 @@ void StatesEditorView::setWhenCondition(int internalNodeId, const QString &condi
|
|||||||
e.showException();
|
e.showException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorView::resetWhenCondition(int internalNodeId)
|
void StatesEditorView::resetWhenCondition(int internalNodeId)
|
||||||
@@ -295,6 +300,8 @@ void StatesEditorView::resetWhenCondition(int internalNodeId)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_block = true;
|
m_block = true;
|
||||||
|
auto guard = [this]() { m_block = false; };
|
||||||
|
QScopeGuard<decltype(guard)> lock(guard);
|
||||||
|
|
||||||
if (hasModelNodeForInternalId(internalNodeId)) {
|
if (hasModelNodeForInternalId(internalNodeId)) {
|
||||||
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
||||||
@@ -306,8 +313,6 @@ void StatesEditorView::resetWhenCondition(int internalNodeId)
|
|||||||
e.showException();
|
e.showException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorView::setStateAsDefault(int internalNodeId)
|
void StatesEditorView::setStateAsDefault(int internalNodeId)
|
||||||
@@ -316,6 +321,8 @@ void StatesEditorView::setStateAsDefault(int internalNodeId)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_block = true;
|
m_block = true;
|
||||||
|
auto guard = [this]() { m_block = false; };
|
||||||
|
QScopeGuard<decltype(guard)> lock(guard);
|
||||||
|
|
||||||
if (hasModelNodeForInternalId(internalNodeId)) {
|
if (hasModelNodeForInternalId(internalNodeId)) {
|
||||||
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
QmlModelState state(modelNodeForInternalId(internalNodeId));
|
||||||
@@ -327,8 +334,6 @@ void StatesEditorView::setStateAsDefault(int internalNodeId)
|
|||||||
e.showException();
|
e.showException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorView::resetDefaultState()
|
void StatesEditorView::resetDefaultState()
|
||||||
@@ -337,6 +342,8 @@ void StatesEditorView::resetDefaultState()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_block = true;
|
m_block = true;
|
||||||
|
auto guard = [this]() { m_block = false; };
|
||||||
|
QScopeGuard<decltype(guard)> lock(guard);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (rootModelNode().hasProperty("state"))
|
if (rootModelNode().hasProperty("state"))
|
||||||
@@ -345,8 +352,6 @@ void StatesEditorView::resetDefaultState()
|
|||||||
} catch (const RewritingException &e) {
|
} catch (const RewritingException &e) {
|
||||||
e.showException();
|
e.showException();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StatesEditorView::hasDefaultState() const
|
bool StatesEditorView::hasDefaultState() const
|
||||||
@@ -354,6 +359,70 @@ bool StatesEditorView::hasDefaultState() const
|
|||||||
return rootModelNode().hasProperty("state");
|
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)
|
void StatesEditorView::modelAttached(Model *model)
|
||||||
{
|
{
|
||||||
if (model == AbstractView::model())
|
if (model == AbstractView::model())
|
||||||
@@ -444,7 +513,12 @@ void StatesEditorView::bindingPropertiesChanged(const QList<BindingProperty> &pr
|
|||||||
void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList,
|
void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList,
|
||||||
AbstractView::PropertyChangeFlags /*propertyChange*/)
|
AbstractView::PropertyChangeFlags /*propertyChange*/)
|
||||||
{
|
{
|
||||||
|
if (m_block)
|
||||||
|
return;
|
||||||
|
|
||||||
m_block = true;
|
m_block = true;
|
||||||
|
auto guard = [this]() { m_block = false; };
|
||||||
|
QScopeGuard<decltype(guard)> lock(guard);
|
||||||
|
|
||||||
for (const VariantProperty &property : propertyList) {
|
for (const VariantProperty &property : propertyList) {
|
||||||
if (property.name() == "name" && QmlModelState::isValidQmlModelState(property.parentModelNode()))
|
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())
|
else if (property.name() == "state" && property.parentModelNode().isRootNode())
|
||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_block = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorView::currentStateChanged(const ModelNode &node)
|
void StatesEditorView::currentStateChanged(const ModelNode &node)
|
||||||
|
@@ -33,6 +33,7 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
class StatesEditorModel;
|
class StatesEditorModel;
|
||||||
class StatesEditorWidget;
|
class StatesEditorWidget;
|
||||||
|
class AnnotationEditor;
|
||||||
|
|
||||||
class StatesEditorView : public AbstractView {
|
class StatesEditorView : public AbstractView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -47,6 +48,9 @@ public:
|
|||||||
void setStateAsDefault(int internalNodeId);
|
void setStateAsDefault(int internalNodeId);
|
||||||
void resetDefaultState();
|
void resetDefaultState();
|
||||||
bool hasDefaultState() const;
|
bool hasDefaultState() const;
|
||||||
|
void setAnnotation(int internalNodeId);
|
||||||
|
void removeAnnotation(int internalNodeId);
|
||||||
|
bool hasAnnotation(int internalNodeId) const;
|
||||||
bool validStateName(const QString &name) const;
|
bool validStateName(const QString &name) const;
|
||||||
QString currentStateName() const;
|
QString currentStateName() const;
|
||||||
void setCurrentState(const QmlModelState &state);
|
void setCurrentState(const QmlModelState &state);
|
||||||
@@ -102,6 +106,7 @@ private:
|
|||||||
QPointer<StatesEditorWidget> m_statesEditorWidget;
|
QPointer<StatesEditorWidget> m_statesEditorWidget;
|
||||||
int m_lastIndex;
|
int m_lastIndex;
|
||||||
bool m_block = false;
|
bool m_block = false;
|
||||||
|
QPointer<AnnotationEditor> m_editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -34,6 +34,8 @@ namespace QmlDesigner {
|
|||||||
class AbstractViewAbstractVieweGroup;
|
class AbstractViewAbstractVieweGroup;
|
||||||
class QmlObjectNode;
|
class QmlObjectNode;
|
||||||
class QmlModelStateGroup;
|
class QmlModelStateGroup;
|
||||||
|
class Annotation;
|
||||||
|
class AnnotationEditor;
|
||||||
|
|
||||||
class QMLDESIGNERCORE_EXPORT QmlModelState : public QmlModelNodeFacade
|
class QMLDESIGNERCORE_EXPORT QmlModelState : public QmlModelNodeFacade
|
||||||
{
|
{
|
||||||
@@ -72,6 +74,12 @@ public:
|
|||||||
void setAsDefault();
|
void setAsDefault();
|
||||||
bool isDefault() const;
|
bool isDefault() const;
|
||||||
|
|
||||||
|
void setAnnotation(const Annotation &annotation, const QString &id);
|
||||||
|
Annotation annotation() const;
|
||||||
|
QString annotationName() const;
|
||||||
|
bool hasAnnotation() const;
|
||||||
|
void removeAnnotation();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addChangeSetIfNotExists(const ModelNode &node);
|
void addChangeSetIfNotExists(const ModelNode &node);
|
||||||
static QmlModelState createBaseState(const AbstractView *view);
|
static QmlModelState createBaseState(const AbstractView *view);
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
#include "bindingproperty.h"
|
#include "bindingproperty.h"
|
||||||
#include "qmlchangeset.h"
|
#include "qmlchangeset.h"
|
||||||
#include "qmlitemnode.h"
|
#include "qmlitemnode.h"
|
||||||
|
#include "annotation.h"
|
||||||
|
#include "annotationeditor/annotationeditor.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -304,6 +306,43 @@ bool QmlModelState::isDefault() const
|
|||||||
return false;
|
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::createBaseState(const AbstractView *view)
|
||||||
{
|
{
|
||||||
QmlModelState qmlModelState(view->rootModelNode());
|
QmlModelState qmlModelState(view->rootModelNode());
|
||||||
|
Reference in New Issue
Block a user