From eb744cb41293b59feed2759e4453e1a7c15efa88 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 1 Oct 2019 18:05:32 +0200 Subject: [PATCH] QmlDesigner: Introduce QmlVisualNode and Qml3DNode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have to support QQuick3DNodes for the timeline and states editor. QmlVisualNode aggregates the shared properties between QQuickItem and QQuick3DNodes. Both have states and are visual nodes shown in the navigator. Task-number: QDS-1102 Change-Id: Iab8c20921012bb751caeafb1c2ee91c0d8922b2e Reviewed-by: Miikka Heikkinen Reviewed-by: Henning Gründl Reviewed-by: Alessandro Portale --- src/plugins/qmldesigner/CMakeLists.txt | 4 + .../timelineeditor/timelineanimationform.cpp | 2 +- .../timelineeditor/timelinesettingsmodel.cpp | 4 +- .../timelineeditor/timelineview.cpp | 2 +- .../designercore/designercore-lib.pri | 4 + .../designercore/include/qml3dnode.h | 59 ++++ .../designercore/include/qmlitemnode.h | 32 +-- .../designercore/include/qmlvisualnode.h | 96 +++++++ .../designercore/model/qml3dnode.cpp | 83 ++++++ .../designercore/model/qmlitemnode.cpp | 84 ------ .../designercore/model/qmlobjectnode.cpp | 23 +- .../designercore/model/qmlstate.cpp | 2 +- .../designercore/model/qmlvisualnode.cpp | 251 ++++++++++++++++++ src/plugins/qmldesigner/qmldesignerplugin.qbs | 4 + 14 files changed, 521 insertions(+), 129 deletions(-) create mode 100644 src/plugins/qmldesigner/designercore/include/qml3dnode.h create mode 100644 src/plugins/qmldesigner/designercore/include/qmlvisualnode.h create mode 100644 src/plugins/qmldesigner/designercore/model/qml3dnode.cpp create mode 100644 src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index c677105d6b0..f4035777653 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -425,6 +425,8 @@ extend_qtc_plugin(QmlDesigner include/qmlchangeset.h include/qmldesignercorelib_global.h include/qmlitemnode.h + include/qmlvisualnode.h + include/qml3dnode.h include/qmlmodelnodefacade.h include/qmlobjectnode.h include/qmlstate.h @@ -493,6 +495,8 @@ extend_qtc_plugin(QmlDesigner model/qmlanchors.cpp model/qmlchangeset.cpp model/qmlitemnode.cpp + model/qmlvisualnode.h + model/qml3dnode.h model/qmlmodelnodefacade.cpp model/qmlobjectnode.cpp model/qmlstate.cpp diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineanimationform.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineanimationform.cpp index 032a133f893..1797ae9bff4 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineanimationform.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineanimationform.cpp @@ -238,7 +238,7 @@ void TimelineAnimationForm::populateStateComboBox() return; QmlObjectNode rootNode = QmlObjectNode(m_animation.view()->rootModelNode()); if (rootNode.isValid() && rootNode.modelNode().hasId()) { - for (const QmlModelState &state : QmlItemNode(rootNode).states().allStates()) { + for (const QmlModelState &state : QmlVisualNode(rootNode).states().allStates()) { ui->transitionToState ->addItem(state.modelNode().variantProperty("name").value().toString(), QVariant::fromValue(state.modelNode())); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp index f75d1299839..e308d657725 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include @@ -152,7 +152,7 @@ void TimelineSettingsModel::resetModel() if (timelineView()->isAttached() && timelineView()->rootModelNode().hasId()) { addState(ModelNode()); for (const QmlModelState &state : - QmlItemNode(timelineView()->rootModelNode()).states().allStates()) + QmlVisualNode(timelineView()->rootModelNode()).states().allStates()) addState(state); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index afb04d4258b..eb4b270a990 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -500,7 +500,7 @@ QmlModelState TimelineView::stateForTimeline(const QmlTimeline &timeline) return QmlModelState(rootModelNode()); } - for (const QmlModelState &state : QmlItemNode(rootModelNode()).states().allStates()) { + for (const QmlModelState &state : QmlVisualNode(rootModelNode()).states().allStates()) { if (timelineForState(state) == timeline) return state; } diff --git a/src/plugins/qmldesigner/designercore/designercore-lib.pri b/src/plugins/qmldesigner/designercore/designercore-lib.pri index 935b29728e6..4a30a7ecc47 100644 --- a/src/plugins/qmldesigner/designercore/designercore-lib.pri +++ b/src/plugins/qmldesigner/designercore/designercore-lib.pri @@ -61,6 +61,8 @@ SOURCES += $$PWD/model/abstractview.cpp \ $$PWD/model/componenttextmodifier.cpp \ $$PWD/model/textmodifier.cpp \ $$PWD/model/qmlitemnode.cpp \ + $$PWD/model/qmlvisualnode.cpp \ + $$PWD/model/qml3dnode.cpp \ $$PWD/model/qmlstate.cpp \ $$PWD/model/qmlchangeset.cpp \ $$PWD/model/qmlmodelnodefacade.cpp \ @@ -134,6 +136,8 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \ $$PWD/model/modeltotextmerger.h \ $$PWD/model/texttomodelmerger.h \ $$PWD/include/qmlitemnode.h \ + $$PWD/model/qmlvisualnode.h \ + $$PWD/model/qml3dnode.h \ $$PWD/include/qmlstate.h \ $$PWD/include/qmlchangeset.h \ $$PWD/include/qmlmodelnodefacade.h \ diff --git a/src/plugins/qmldesigner/designercore/include/qml3dnode.h b/src/plugins/qmldesigner/designercore/include/qml3dnode.h new file mode 100644 index 00000000000..d487666ae1a --- /dev/null +++ b/src/plugins/qmldesigner/designercore/include/qml3dnode.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include "qmlobjectnode.h" +#include "qmlstate.h" +#include "qmlvisualnode.h" + +#include +#include +#include + +namespace QmlDesigner { + +class QmlModelStateGroup; +class QmlAnchors; +class ItemLibraryEntry; + +class QMLDESIGNERCORE_EXPORT Qml3DNode : public QmlVisualNode +{ + friend class QmlAnchors; +public: + Qml3DNode() : QmlVisualNode() {} + Qml3DNode(const ModelNode &modelNode) : QmlVisualNode(modelNode) {} + bool isValid() const override; + static bool isValidQml3DNode(const ModelNode &modelNode); +}; + +QMLDESIGNERCORE_EXPORT uint qHash(const Qml3DNode &node); + +QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); +QMLDESIGNERCORE_EXPORT QList toQml3DNodeList(const QList &modelNodeList); + +} //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 3e19515147e..88afc72cb11 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -29,6 +29,7 @@ #include #include "qmlobjectnode.h" #include "qmlstate.h" +#include "qmlvisualnode.h" #include #include @@ -40,15 +41,14 @@ class QmlModelStateGroup; class QmlAnchors; class ItemLibraryEntry; -class QMLDESIGNERCORE_EXPORT QmlItemNode : public QmlObjectNode +class QMLDESIGNERCORE_EXPORT QmlItemNode : public QmlVisualNode { friend class QmlAnchors; public: - QmlItemNode() : QmlObjectNode() {} - QmlItemNode(const ModelNode &modelNode) : QmlObjectNode(modelNode) {} + QmlItemNode() : QmlVisualNode() {} + QmlItemNode(const ModelNode &modelNode) : QmlVisualNode(modelNode) {} bool isValid() const override; static bool isValidQmlItemNode(const ModelNode &modelNode); - bool isRootNode() const; static bool isItemOrWindow(const ModelNode &modelNode); @@ -74,7 +74,6 @@ public: const QPointF &position, NodeAbstractProperty parentproperty); - QmlModelStateGroup states() const; QList children() const; QList resources() const; QList allDirectSubNodes() const; @@ -131,29 +130,6 @@ public: QMLDESIGNERCORE_EXPORT uint qHash(const QmlItemNode &node); -class QMLDESIGNERCORE_EXPORT QmlModelStateGroup -{ - friend class QmlItemNode; - friend class StatesEditorView; - -public: - - QmlModelStateGroup() : m_modelNode(ModelNode()) {} - - ModelNode modelNode() const { return m_modelNode; } - QStringList names() const; - QList allStates() const; - QmlModelState state(const QString &name) const; - QmlModelState addState(const QString &name); - void removeState(const QString &name); - -protected: - QmlModelStateGroup(const ModelNode &modelNode) : m_modelNode(modelNode) {} - -private: - ModelNode m_modelNode; -}; - QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); QMLDESIGNERCORE_EXPORT QList toQmlItemNodeList(const QList &modelNodeList); diff --git a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h new file mode 100644 index 00000000000..df6db763f8f --- /dev/null +++ b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include "qmlobjectnode.h" +#include "qmlstate.h" + +#include +#include +#include + +namespace QmlDesigner { + +class QmlModelStateGroup; +class QmlAnchors; +class ItemLibraryEntry; + +class QMLDESIGNERCORE_EXPORT QmlVisualNode : public QmlObjectNode +{ + friend class QmlAnchors; +public: + QmlVisualNode() : QmlObjectNode() {} + QmlVisualNode(const ModelNode &modelNode) : QmlObjectNode(modelNode) {} + bool isValid() const override; + static bool isValidQmlVisualNode(const ModelNode &modelNode); + bool isRootNode() const; + + QmlModelStateGroup states() const; + QList children() const; + QList resources() const; + QList allDirectSubNodes() const; + + bool hasChildren() const; + bool hasResources() const; + + const QList allDirectSubModelNodes() const; + const QList allSubModelNodes() const; + bool hasAnySubModelNodes() const; + + static bool isItemOr3DNode(const ModelNode &modelNode); +}; + +QMLDESIGNERCORE_EXPORT uint qHash(const QmlItemNode &node); + +class QMLDESIGNERCORE_EXPORT QmlModelStateGroup +{ + friend class QmlVisualNode; + friend class StatesEditorView; + +public: + + QmlModelStateGroup() : m_modelNode(ModelNode()) {} + + ModelNode modelNode() const { return m_modelNode; } + QStringList names() const; + QList allStates() const; + QmlModelState state(const QString &name) const; + QmlModelState addState(const QString &name); + void removeState(const QString &name); + +protected: + QmlModelStateGroup(const ModelNode &modelNode) : m_modelNode(modelNode) {} + +private: + ModelNode m_modelNode; +}; + +QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); +QMLDESIGNERCORE_EXPORT QList toQmlVisualNodeList(const QList &modelNodeList); + +} //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp b/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp new file mode 100644 index 00000000000..d05048fe31a --- /dev/null +++ b/src/plugins/qmldesigner/designercore/model/qml3dnode.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qml3dnode.h" +#include +#include "qmlchangeset.h" +#include "nodelistproperty.h" +#include "nodehints.h" +#include "variantproperty.h" +#include "bindingproperty.h" +#include "qmlanchors.h" +#include "invalidmodelnodeexception.h" +#include "itemlibraryinfo.h" + +#include "plaintexteditmodifier.h" +#include "rewriterview.h" +#include "modelmerger.h" +#include "rewritingexception.h" + +#include +#include +#include +#include + +namespace QmlDesigner { + +bool Qml3DNode::isValid() const +{ + return isValidQml3DNode(modelNode()); +} + +bool Qml3DNode::isValidQml3DNode(const ModelNode &modelNode) +{ + return isValidQmlObjectNode(modelNode) + && modelNode.metaInfo().isValid() + && (modelNode.metaInfo().isSubclassOf("QtQuick3D.Node")); +} + +QList toModelNodeList(const QList &qmlVisualNodeList) +{ + QList modelNodeList; + + for (const Qml3DNode &qml3DNode : qmlVisualNodeList) + modelNodeList.append(qml3DNode.modelNode()); + + return modelNodeList; +} + +QList toQml3DNodeList(const QList &modelNodeList) +{ + QList qml3DNodeList; + + for (const ModelNode &modelNode : modelNodeList) { + if (Qml3DNode::isValidQml3DNode(modelNode)) + qml3DNodeList.append(modelNode); + } + + return qml3DNodeList; +} + +} //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index 3b682afcfb8..0b33aa655a8 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -216,39 +216,6 @@ bool QmlItemNode::isValidQmlItemNode(const ModelNode &modelNode) return isValidQmlObjectNode(modelNode) && modelNode.metaInfo().isValid() && isItemOrWindow(modelNode); } -bool QmlItemNode::isRootNode() const -{ - return modelNode().isValid() && modelNode().isRootNode(); -} - -QStringList QmlModelStateGroup::names() const -{ - QStringList returnList; - - if (!modelNode().isValid()) - throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); - - if (modelNode().property("states").isNodeListProperty()) { - foreach (const ModelNode &node, modelNode().nodeListProperty("states").toModelNodeList()) { - if (QmlModelState::isValidQmlModelState(node)) - returnList.append(QmlModelState(node).name()); - } - } - return returnList; -} - -/** - \brief Returns list of states (without 'base state'). - The list contains all states defined by this item. - */ -QmlModelStateGroup QmlItemNode::states() const -{ - if (isValid()) - return QmlModelStateGroup(modelNode()); - else - return QmlModelStateGroup(); -} - QList QmlItemNode::children() const { QList childrenList; @@ -492,62 +459,11 @@ QPixmap QmlItemNode::instanceBlurredRenderPixmap() const return nodeInstance().blurredRenderPixmap(); } -QList QmlModelStateGroup::allStates() const -{ - QList returnList; - - if (!modelNode().isValid()) - throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); - - if (modelNode().property("states").isNodeListProperty()) { - foreach (const ModelNode &node, modelNode().nodeListProperty("states").toModelNodeList()) { - if (QmlModelState::isValidQmlModelState(node)) - returnList.append(node); - } - } - return returnList; -} - uint qHash(const QmlItemNode &node) { return qHash(node.modelNode()); } -QmlModelState QmlModelStateGroup::addState(const QString &name) -{ - if (!modelNode().isValid()) - throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); - - ModelNode newState = QmlModelState::createQmlState( - modelNode().view(), {{PropertyName("name"), QVariant(name)}}); - modelNode().nodeListProperty("states").reparentHere(newState); - - return newState; -} - -void QmlModelStateGroup::removeState(const QString &name) -{ - if (!modelNode().isValid()) - throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); - - if (state(name).isValid()) - state(name).modelNode().destroy(); -} - -QmlModelState QmlModelStateGroup::state(const QString &name) const -{ - if (!modelNode().isValid()) - throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); - - if (modelNode().property("states").isNodeListProperty()) { - foreach (const ModelNode &node, modelNode().nodeListProperty("states").toModelNodeList()) { - if (QmlModelState(node).name() == name) - return node; - } - } - return QmlModelState(); -} - QList toModelNodeList(const QList &qmlItemNodeList) { QList modelNodeList; diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index 8174c9a1a59..74f0943ae28 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -442,20 +442,20 @@ QList QmlObjectNode::allAffectingStatesOperations() cons return returnList; } -static QList allQmlItemsRecursive(const QmlItemNode &qmlItemNode) +static QList allQmlVisualNodesRecursive(const QmlItemNode &qmlItemNode) { - QList qmlItemNodeList; + QList qmlVisualNodeList; if (qmlItemNode.isValid()) { - qmlItemNodeList.append(qmlItemNode); + qmlVisualNodeList.append(qmlItemNode); foreach (const ModelNode &modelNode, qmlItemNode.modelNode().directSubModelNodes()) { - if (QmlItemNode::isValidQmlItemNode(modelNode)) - qmlItemNodeList.append(allQmlItemsRecursive(modelNode)); + if (QmlVisualNode::isValidQmlVisualNode(modelNode)) + qmlVisualNodeList.append(allQmlVisualNodesRecursive(modelNode)); } } - return qmlItemNodeList; + return qmlVisualNodeList; } QList QmlObjectNode::allDefinedStates() const @@ -465,14 +465,13 @@ QList QmlObjectNode::allDefinedStates() const QList returnList; - QList allQmlItems; + QList allVisualNodes; - if (QmlItemNode::isValidQmlItemNode(view()->rootModelNode())) - allQmlItems.append(allQmlItemsRecursive(view()->rootModelNode())); + if (QmlVisualNode::isValidQmlVisualNode(view()->rootModelNode())) + allVisualNodes.append(allQmlVisualNodesRecursive(view()->rootModelNode())); - foreach (const QmlItemNode &item, allQmlItems) { - returnList.append(item.states().allStates()); - } + for (const QmlVisualNode &node : qAsConst(allVisualNodes)) + returnList.append(node.states().allStates()); return returnList; } diff --git a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp index adb56076eb1..a4135e3a322 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlstate.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlstate.cpp @@ -275,7 +275,7 @@ QmlModelState QmlModelState::duplicate(const QString &name) const QmlModelStateGroup QmlModelState::stateGroup() const { - QmlItemNode parentNode(modelNode().parentProperty().parentModelNode()); + QmlVisualNode parentNode(modelNode().parentProperty().parentModelNode()); return parentNode.states(); } diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp new file mode 100644 index 00000000000..a1d351907ba --- /dev/null +++ b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qmlvisualnode.h" +#include +#include "qmlchangeset.h" +#include "nodelistproperty.h" +#include "nodehints.h" +#include "variantproperty.h" +#include "bindingproperty.h" +#include "qmlanchors.h" +#include "invalidmodelnodeexception.h" +#include "itemlibraryinfo.h" + +#include "plaintexteditmodifier.h" +#include "rewriterview.h" +#include "modelmerger.h" +#include "rewritingexception.h" + +#include +#include +#include +#include + +namespace QmlDesigner { + +bool QmlVisualNode::isItemOr3DNode(const ModelNode &modelNode) +{ + if (modelNode.metaInfo().isSubclassOf("QtQuick.Item")) + return true; + + if (modelNode.metaInfo().isSubclassOf("QtQuick3D.Node")) + return true; + + return false; +} + +bool QmlVisualNode::isValid() const +{ + return isValidQmlVisualNode(modelNode()); +} + +bool QmlVisualNode::isValidQmlVisualNode(const ModelNode &modelNode) +{ + return isValidQmlObjectNode(modelNode) + && modelNode.metaInfo().isValid() + && isItemOr3DNode(modelNode); +} + +bool QmlVisualNode::isRootNode() const +{ + return modelNode().isValid() && modelNode().isRootNode(); +} + + +QList QmlVisualNode::children() const +{ + QList childrenList; + + if (isValid()) { + + if (modelNode().hasNodeListProperty("children")) + childrenList.append(modelNode().nodeListProperty("children").toModelNodeList()); + + if (modelNode().hasNodeListProperty("data")) { + for (const ModelNode &node : modelNode().nodeListProperty("data").toModelNodeList()) { + if (QmlVisualNode::isValidQmlVisualNode(node)) + childrenList.append(node); + } + } + } + + return toQmlVisualNodeList(childrenList); +} + +QList QmlVisualNode::resources() const +{ + QList resourcesList; + + if (isValid()) { + + if (modelNode().hasNodeListProperty("resources")) + resourcesList.append(modelNode().nodeListProperty("resources").toModelNodeList()); + + if (modelNode().hasNodeListProperty("data")) { + for (const ModelNode &node : modelNode().nodeListProperty("data").toModelNodeList()) { + if (!QmlItemNode::isValidQmlItemNode(node)) + resourcesList.append(node); + } + } + } + + return toQmlObjectNodeList(resourcesList); +} + +QList QmlVisualNode::allDirectSubNodes() const +{ + return toQmlObjectNodeList(modelNode().directSubModelNodes()); +} + +bool QmlVisualNode::hasChildren() const +{ + if (modelNode().hasNodeListProperty("children")) + return true; + + return !children().isEmpty(); +} + +bool QmlVisualNode::hasResources() const +{ + if (modelNode().hasNodeListProperty("resources")) + return true; + + return !resources().isEmpty(); +} + +const QList QmlVisualNode::allDirectSubModelNodes() const +{ + return toQmlVisualNodeList(modelNode().directSubModelNodes()); +} + +const QList QmlVisualNode::allSubModelNodes() const +{ + return toQmlVisualNodeList(modelNode().allSubModelNodes()); +} + +bool QmlVisualNode::hasAnySubModelNodes() const +{ + return modelNode().hasAnySubModelNodes(); +} + +QmlModelStateGroup QmlVisualNode::states() const +{ + if (isValid()) + return QmlModelStateGroup(modelNode()); + else + return QmlModelStateGroup(); +} + +QList toModelNodeList(const QList &qmlVisualNodeList) +{ + QList modelNodeList; + + for (const QmlVisualNode &QmlVisualNode : qmlVisualNodeList) + modelNodeList.append(QmlVisualNode.modelNode()); + + return modelNodeList; +} + +QList toQmlVisualNodeList(const QList &modelNodeList) +{ + QList QmlVisualNodeList; + + for (const ModelNode &modelNode : modelNodeList) { + if (QmlVisualNode::isValidQmlVisualNode(modelNode)) + QmlVisualNodeList.append(modelNode); + } + + return QmlVisualNodeList; +} + +QStringList QmlModelStateGroup::names() const +{ + QStringList returnList; + + if (!modelNode().isValid()) + throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + if (modelNode().property("states").isNodeListProperty()) { + for (const ModelNode &node : modelNode().nodeListProperty("states").toModelNodeList()) { + if (QmlModelState::isValidQmlModelState(node)) + returnList.append(QmlModelState(node).name()); + } + } + return returnList; +} + +QList QmlModelStateGroup::allStates() const +{ + QList returnList; + + if (!modelNode().isValid()) + throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + if (modelNode().property("states").isNodeListProperty()) { + for (const ModelNode &node : modelNode().nodeListProperty("states").toModelNodeList()) { + if (QmlModelState::isValidQmlModelState(node)) + returnList.append(node); + } + } + return returnList; +} + +QmlModelState QmlModelStateGroup::addState(const QString &name) +{ + if (!modelNode().isValid()) + throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + ModelNode newState = QmlModelState::createQmlState( + modelNode().view(), {{PropertyName("name"), QVariant(name)}}); + modelNode().nodeListProperty("states").reparentHere(newState); + + return newState; +} + +void QmlModelStateGroup::removeState(const QString &name) +{ + if (!modelNode().isValid()) + throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + if (state(name).isValid()) + state(name).modelNode().destroy(); +} + +QmlModelState QmlModelStateGroup::state(const QString &name) const +{ + if (!modelNode().isValid()) + throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + if (modelNode().property("states").isNodeListProperty()) { + for (const ModelNode &node : modelNode().nodeListProperty("states").toModelNodeList()) { + if (QmlModelState(node).name() == name) + return node; + } + } + return QmlModelState(); +} + +} //QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index a89bd8bb9e6..d198e8c09de 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -272,6 +272,8 @@ Project { "include/qmlanchors.h", "include/qmlchangeset.h", "include/qmlitemnode.h", + "include/qmlvisualnode.h", + "include/qml3dnode.h", "include/qmlmodelnodefacade.h", "include/qmlobjectnode.h", "include/qmlstate.h", @@ -346,6 +348,8 @@ Project { "model/qmlanchors.cpp", "model/qmlchangeset.cpp", "model/qmlitemnode.cpp", + "model/qmlvisualnode.h", + "model/qml3dnode.h", "model/qmlmodelnodefacade.cpp", "model/qmlobjectnode.cpp", "model/qmlstate.cpp",