QmlDesigner: Move the static function from ModeNode to ModelUtils

ModelNode is already quite big and there is no need add more utility
functions.

Change-Id: I5e81c320c4934fc452c05f21b3c878354f857424
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2023-09-20 11:05:22 +02:00
parent 794cb89c2a
commit 53e2115f63
13 changed files with 150 additions and 140 deletions

View File

@@ -23,10 +23,11 @@
#include <formeditortoolbutton.h> #include <formeditortoolbutton.h>
#include <documentmanager.h>
#include <qmldesignerplugin.h>
#include <viewmanager.h>
#include <actioneditor.h> #include <actioneditor.h>
#include <documentmanager.h>
#include <model/modelutils.h>
#include <viewmanager.h>
#include <qmldesignerplugin.h>
#include <listmodeleditor/listmodeleditordialog.h> #include <listmodeleditor/listmodeleditordialog.h>
#include <listmodeleditor/listmodeleditormodel.h> #include <listmodeleditor/listmodeleditormodel.h>
@@ -419,7 +420,7 @@ public:
parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode(); parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode();
if (!ModelNode::isThisOrAncestorLocked(parentNode)) { if (!ModelUtils::isThisOrAncestorLocked(parentNode)) {
ActionTemplate *selectionAction = new ActionTemplate("SELECTION", {}, &ModelNodeOperations::select); ActionTemplate *selectionAction = new ActionTemplate("SELECTION", {}, &ModelNodeOperations::select);
selectionAction->setParent(menu()); selectionAction->setParent(menu());
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Parent"))); selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Parent")));
@@ -432,11 +433,9 @@ public:
} }
} }
for (const ModelNode &node : selectionContext().view()->allModelNodes()) { for (const ModelNode &node : selectionContext().view()->allModelNodes()) {
if (node != selectionContext().currentSingleSelectedNode() if (node != selectionContext().currentSingleSelectedNode() && node != parentNode
&& node != parentNode && contains(node, selectionContext().scenePosition()) && !node.isRootNode()
&& contains(node, selectionContext().scenePosition()) && !ModelUtils::isThisOrAncestorLocked(node)) {
&& !node.isRootNode()
&& !ModelNode::isThisOrAncestorLocked(node)) {
selectionContext().setTargetNode(node); selectionContext().setTargetNode(node);
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node)); QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
ActionTemplate *selectionAction = new ActionTemplate("SELECT", what, &ModelNodeOperations::select); ActionTemplate *selectionAction = new ActionTemplate("SELECT", what, &ModelNodeOperations::select);

View File

@@ -8,6 +8,7 @@
#include <bindingproperty.h> #include <bindingproperty.h>
#include <connectioneditorevaluator.h> #include <connectioneditorevaluator.h>
#include <exception.h> #include <exception.h>
#include <model/modelutils.h>
#include <nodeabstractproperty.h> #include <nodeabstractproperty.h>
#include <nodelistproperty.h> #include <nodelistproperty.h>
#include <nodemetainfo.h> #include <nodemetainfo.h>
@@ -69,7 +70,7 @@ Qt::ItemFlags ConnectionModel::flags(const QModelIndex &modelIndex) const
const int internalId = data(index(modelIndex.row(), TargetModelNodeRow), UserRoles::InternalIdRole).toInt(); const int internalId = data(index(modelIndex.row(), TargetModelNodeRow), UserRoles::InternalIdRole).toInt();
ModelNode modelNode = m_connectionView->modelNodeForInternalId(internalId); ModelNode modelNode = m_connectionView->modelNodeForInternalId(internalId);
if (modelNode.isValid() && ModelNode::isThisOrAncestorLocked(modelNode)) if (modelNode.isValid() && ModelUtils::isThisOrAncestorLocked(modelNode))
return Qt::ItemIsEnabled; return Qt::ItemIsEnabled;
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;

View File

@@ -25,6 +25,7 @@
#include <designeractionmanager.h> #include <designeractionmanager.h>
#include <designermcumanager.h> #include <designermcumanager.h>
#include <import.h> #include <import.h>
#include <model/modelutils.h>
#include <nodeinstanceview.h> #include <nodeinstanceview.h>
#include <seekerslider.h> #include <seekerslider.h>
@@ -44,7 +45,8 @@
namespace QmlDesigner { namespace QmlDesigner {
static inline QIcon contextIcon(const DesignerIcons::IconId &iconId) { inline static QIcon contextIcon(const DesignerIcons::IconId &iconId)
{
return DesignerActionManager::instance().contextIcon(iconId); return DesignerActionManager::instance().contextIcon(iconId);
}; };
@@ -257,17 +259,16 @@ void Edit3DWidget::createContextMenu()
m_contextMenu->addSeparator(); m_contextMenu->addSeparator();
m_selectParentAction = m_contextMenu->addAction( m_selectParentAction = m_contextMenu->addAction(
contextIcon(DesignerIcons::ParentIcon), contextIcon(DesignerIcons::ParentIcon), tr("Select Parent"), [&] {
tr("Select Parent"), [&] { ModelNode parentNode = ModelUtils::lowestCommonAncestor(view()->selectedModelNodes());
ModelNode parentNode = ModelNode::lowestCommonAncestor(view()->selectedModelNodes()); if (!parentNode.isValid())
if (!parentNode.isValid()) return;
return;
if (!parentNode.isRootNode() && view()->isSelectedModelNode(parentNode)) if (!parentNode.isRootNode() && view()->isSelectedModelNode(parentNode))
parentNode = parentNode.parentProperty().parentModelNode(); parentNode = parentNode.parentProperty().parentModelNode();
view()->setSelectedModelNode(parentNode); view()->setSelectedModelNode(parentNode);
}); });
QAction *defaultToggleGroupAction = view()->edit3DAction(View3DActionType::SelectionModeToggle)->action(); QAction *defaultToggleGroupAction = view()->edit3DAction(View3DActionType::SelectionModeToggle)->action();
m_toggleGroupAction = m_contextMenu->addAction( m_toggleGroupAction = m_contextMenu->addAction(
@@ -291,7 +292,7 @@ bool Edit3DWidget::isSceneLocked() const
{ {
if (m_view && m_view->hasModelNodeForInternalId(m_canvas->activeScene())) { if (m_view && m_view->hasModelNodeForInternalId(m_canvas->activeScene())) {
ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene()); ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene());
if (ModelNode::isThisOrAncestorLocked(node)) if (ModelUtils::isThisOrAncestorLocked(node))
return true; return true;
} }
return false; return false;
@@ -525,7 +526,7 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
// Block all drags if scene root node is locked // Block all drags if scene root node is locked
if (m_view->hasModelNodeForInternalId(m_canvas->activeScene())) { if (m_view->hasModelNodeForInternalId(m_canvas->activeScene())) {
ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene()); ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene());
if (ModelNode::isThisOrAncestorLocked(node)) if (ModelUtils::isThisOrAncestorLocked(node))
return; return;
} }

View File

@@ -9,6 +9,8 @@
#include "modelnodecontextmenu.h" #include "modelnodecontextmenu.h"
#include "qmldesignerconstants.h" #include "qmldesignerconstants.h"
#include <model/modelutils.h>
#include <QDebug> #include <QDebug>
#include <QGraphicsSceneDragDropEvent> #include <QGraphicsSceneDragDropEvent>
#include <QMimeData> #include <QMimeData>
@@ -180,7 +182,7 @@ FormEditorItem* AbstractFormEditorTool::nearestFormEditorItem(const QPointF &poi
if (formEditorItem->parentItem() && !formEditorItem->parentItem()->isContentVisible()) if (formEditorItem->parentItem() && !formEditorItem->parentItem()->isContentVisible())
continue; continue;
if (formEditorItem && ModelNode::isThisOrAncestorLocked(formEditorItem->qmlItemNode().modelNode())) if (formEditorItem && ModelUtils::isThisOrAncestorLocked(formEditorItem->qmlItemNode().modelNode()))
continue; continue;
if (!nearestItem) if (!nearestItem)

View File

@@ -12,10 +12,11 @@
#include "qproxystyle.h" #include "qproxystyle.h"
#include <metainfo.h> #include <metainfo.h>
#include <model/modelutils.h>
#include <modelnodecontextmenu.h> #include <modelnodecontextmenu.h>
#include <theme.h>
#include <qmldesignerconstants.h> #include <qmldesignerconstants.h>
#include <qmlobjectnode.h> #include <qmlobjectnode.h>
#include <theme.h>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -212,7 +213,7 @@ void NameItemDelegate::paint(QPainter *painter,
} }
ModelNode node = getModelNode(modelIndex); ModelNode node = getModelNode(modelIndex);
if (!ModelNode::isThisOrAncestorLocked(node)) { if (!ModelUtils::isThisOrAncestorLocked(node)) {
NavigatorWidget *widget = qobject_cast<NavigatorWidget *>(styleOption.widget->parent()); NavigatorWidget *widget = qobject_cast<NavigatorWidget *>(styleOption.widget->parent());
if (widget && !widget->dragType().isEmpty()) { if (widget && !widget->dragType().isEmpty()) {
QByteArray dragType = widget->dragType(); QByteArray dragType = widget->dragType();

View File

@@ -200,7 +200,7 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked; return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked;
if (role == ItemOrAncestorLocked) if (role == ItemOrAncestorLocked)
return ModelNode::isThisOrAncestorLocked(modelNode); return ModelUtils::isThisOrAncestorLocked(modelNode);
if (role == ModelNodeRole) if (role == ModelNodeRole)
return QVariant::fromValue<ModelNode>(modelNode); return QVariant::fromValue<ModelNode>(modelNode);
@@ -273,13 +273,13 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const
if (index.column() == ColumnType::Alias if (index.column() == ColumnType::Alias
|| index.column() == ColumnType::Visibility || index.column() == ColumnType::Visibility
|| index.column() == ColumnType::Lock) { || index.column() == ColumnType::Lock) {
if (ModelNode::isThisOrAncestorLocked(modelNode)) if (ModelUtils::isThisOrAncestorLocked(modelNode))
return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
else else
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
} }
if (ModelNode::isThisOrAncestorLocked(modelNode)) if (ModelUtils::isThisOrAncestorLocked(modelNode))
return Qt::NoItemFlags; return Qt::NoItemFlags;
if (index.column() == ColumnType::Name) if (index.column() == ColumnType::Name)

View File

@@ -15,6 +15,7 @@
#include <qmltimeline.h> #include <qmltimeline.h>
#include <qmltimelinekeyframegroup.h> #include <qmltimelinekeyframegroup.h>
#include <model/modelutils.h>
#include <rewritingexception.h> #include <rewritingexception.h>
#include <theme.h> #include <theme.h>
@@ -301,7 +302,7 @@ void TimelineSectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
event->accept(); event->accept();
if (!ModelNode::isThisOrAncestorLocked(m_targetNode)) if (!ModelUtils::isThisOrAncestorLocked(m_targetNode))
toggleCollapsed(); toggleCollapsed();
} }
} }
@@ -334,7 +335,7 @@ void TimelineSectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
if (m_targetNode.isValid()) if (m_targetNode.isValid())
m_targetNode.view()->setSelectedModelNode(m_targetNode); m_targetNode.view()->setSelectedModelNode(m_targetNode);
} else { } else {
if (!ModelNode::isThisOrAncestorLocked(m_targetNode)) if (!ModelUtils::isThisOrAncestorLocked(m_targetNode))
toggleCollapsed(); toggleCollapsed();
} }
update(); update();

View File

@@ -13,6 +13,7 @@
#include <abstractview.h> #include <abstractview.h>
#include <bindingproperty.h> #include <bindingproperty.h>
#include <model/modelutils.h>
#include <variantproperty.h> #include <variantproperty.h>
#include <qmltimeline.h> #include <qmltimeline.h>
#include <qmltimelinekeyframegroup.h> #include <qmltimelinekeyframegroup.h>
@@ -349,7 +350,7 @@ void TransitionEditorSectionItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
event->accept(); event->accept();
if (!ModelNode::isThisOrAncestorLocked(m_targetNode)) if (!ModelUtils::isThisOrAncestorLocked(m_targetNode))
toggleCollapsed(); toggleCollapsed();
} }
} }
@@ -382,7 +383,7 @@ void TransitionEditorSectionItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *ev
if (m_targetNode.isValid()) if (m_targetNode.isValid())
m_targetNode.view()->setSelectedModelNode(m_targetNode); m_targetNode.view()->setSelectedModelNode(m_targetNode);
} else { } else {
if (!ModelNode::isThisOrAncestorLocked(m_targetNode)) if (!ModelUtils::isThisOrAncestorLocked(m_targetNode))
toggleCollapsed(); toggleCollapsed();
} }
update(); update();

View File

@@ -223,9 +223,6 @@ public:
bool locked() const; bool locked() const;
void setLocked(bool value); void setLocked(bool value);
static bool isThisOrAncestorLocked(const ModelNode &node);
static ModelNode lowestCommonAncestor(const QList<ModelNode> &nodes);
qint32 internalId() const; qint32 internalId() const;
void setNodeSource(const QString&); void setNodeSource(const QString&);

View File

@@ -8,12 +8,13 @@
#include "internalnode_p.h" #include "internalnode_p.h"
#include "model.h" #include "model.h"
#include "model_p.h" #include "model_p.h"
#include "modelutils.h"
#include "nodeinstanceview.h" #include "nodeinstanceview.h"
#include "nodelistproperty.h" #include "nodelistproperty.h"
#include "nodemetainfo.h" #include "nodemetainfo.h"
#include "qmldesignerconstants.h"
#include "qmlstate.h" #include "qmlstate.h"
#include "qmltimeline.h" #include "qmltimeline.h"
#include "qmldesignerconstants.h"
#include "rewritertransaction.h" #include "rewritertransaction.h"
#include "variantproperty.h" #include "variantproperty.h"
@@ -412,7 +413,7 @@ void AbstractView::setSelectedModelNodes(const QList<ModelNode> &selectedNodeLis
QList<ModelNode> unlockedNodes; QList<ModelNode> unlockedNodes;
for (const auto &modelNode : selectedNodeList) { for (const auto &modelNode : selectedNodeList) {
if (!ModelNode::isThisOrAncestorLocked(modelNode)) if (!ModelUtils::isThisOrAncestorLocked(modelNode))
unlockedNodes.push_back(modelNode); unlockedNodes.push_back(modelNode);
} }
@@ -421,7 +422,7 @@ void AbstractView::setSelectedModelNodes(const QList<ModelNode> &selectedNodeLis
void AbstractView::setSelectedModelNode(const ModelNode &modelNode) void AbstractView::setSelectedModelNode(const ModelNode &modelNode)
{ {
if (ModelNode::isThisOrAncestorLocked(modelNode)) { if (ModelUtils::isThisOrAncestorLocked(modelNode)) {
clearSelectedModelNodes(); clearSelectedModelNodes();
return; return;
} }

View File

@@ -1230,108 +1230,6 @@ void ModelNode::setLocked(bool value)
} }
} }
bool ModelNode::isThisOrAncestorLocked(const ModelNode &node)
{
if (!node.isValid())
return false;
if (node.locked())
return true;
if (node.isRootNode() || !node.hasParentProperty())
return false;
return isThisOrAncestorLocked(node.parentProperty().parentModelNode());
}
/*!
* \brief The lowest common ancestor node for node1 and node2. If one of the nodes (Node A) is
* the ancestor of the other node, the return value is Node A and not the parent of Node A.
* \param node1 First node
* \param node2 Second node
* \param depthOfLCA Depth of the return value
* \param depthOfNode1 Depth of node1. Use this parameter for optimization
* \param depthOfNode2 Depth of node2. Use this parameter for optimization
*/
static ModelNode lowestCommonAncestor(const ModelNode &node1,
const ModelNode &node2,
int &depthOfLCA,
const int &depthOfNode1 = -1,
const int &depthOfNode2 = -1)
{
Q_ASSERT(node1.isValid() && node2.isValid());
auto depthOfNode = [](const ModelNode &node) -> int {
int depth = 0;
ModelNode parentNode = node;
while (!parentNode.isRootNode()) {
depth++;
parentNode = parentNode.parentProperty().parentModelNode();
}
return depth;
};
if (node1 == node2) {
depthOfLCA = (depthOfNode1 < 0) ? ((depthOfNode2 < 0) ? depthOfNode(node1) : depthOfNode2)
: depthOfNode1;
return node1;
}
if (node1.isRootNode()) {
depthOfLCA = 0;
return node1;
}
if (node2.isRootNode()) {
depthOfLCA = 0;
return node2;
}
ModelNode nodeLower = node1;
ModelNode nodeHigher = node2;
int depthLower = (depthOfNode1 < 0) ? depthOfNode(nodeLower) : depthOfNode1;
int depthHigher = (depthOfNode2 < 0) ? depthOfNode(nodeHigher) : depthOfNode2;
if (depthLower > depthHigher) {
std::swap(depthLower, depthHigher);
std::swap(nodeLower, nodeHigher);
}
int depthDiff = depthHigher - depthLower;
while (depthDiff--)
nodeHigher = nodeHigher.parentProperty().parentModelNode();
while (nodeLower != nodeHigher) {
nodeLower = nodeLower.parentProperty().parentModelNode();
nodeHigher = nodeHigher.parentProperty().parentModelNode();
--depthLower;
}
depthOfLCA = depthLower;
return nodeLower;
}
/*!
* \brief The lowest common node containing all nodes. If one of the nodes (Node A) is
* the ancestor of the other nodes, the return value is Node A and not the parent of Node A.
*/
ModelNode ModelNode::lowestCommonAncestor(const QList<ModelNode> &nodes)
{
if (nodes.isEmpty())
return {};
ModelNode accumulatedNode = nodes.first();
int accumulatedNodeDepth = -1;
for (const ModelNode &node : Utils::span<const ModelNode>(nodes).subspan(1)) {
accumulatedNode = QmlDesigner::lowestCommonAncestor(accumulatedNode,
node,
accumulatedNodeDepth,
accumulatedNodeDepth);
}
return accumulatedNode;
}
void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList) void ModelNode::setScriptFunctions(const QStringList &scriptFunctionList)
{ {
if (!isValid()) if (!isValid())

View File

@@ -4,6 +4,7 @@
#include "modelutils.h" #include "modelutils.h"
#include <abstractview.h> #include <abstractview.h>
#include <nodeabstractproperty.h>
#include <nodemetainfo.h> #include <nodemetainfo.h>
#include <projectstorage/projectstorage.h> #include <projectstorage/projectstorage.h>
#include <projectstorage/sourcepathcache.h> #include <projectstorage/sourcepathcache.h>
@@ -162,4 +163,108 @@ QList<ModelNode> allModelNodesWithId(AbstractView *view)
[&](const ModelNode &node) { return node.hasId(); }); [&](const ModelNode &node) { return node.hasId(); });
} }
bool isThisOrAncestorLocked(const ModelNode &node)
{
if (!node.isValid())
return false;
if (node.locked())
return true;
if (node.isRootNode() || !node.hasParentProperty())
return false;
return isThisOrAncestorLocked(node.parentProperty().parentModelNode());
}
/*!
* \brief The lowest common ancestor node for node1 and node2. If one of the nodes (Node A) is
* the ancestor of the other node, the return value is Node A and not the parent of Node A.
* \param node1 First node
* \param node2 Second node
* \param depthOfLCA Depth of the return value
* \param depthOfNode1 Depth of node1. Use this parameter for optimization
* \param depthOfNode2 Depth of node2. Use this parameter for optimization
*/
namespace {
ModelNode lowestCommonAncestor(const ModelNode &node1,
const ModelNode &node2,
int &depthOfLCA,
const int &depthOfNode1 = -1,
const int &depthOfNode2 = -1)
{
Q_ASSERT(node1.isValid() && node2.isValid());
auto depthOfNode = [](const ModelNode &node) -> int {
int depth = 0;
ModelNode parentNode = node;
while (!parentNode.isRootNode()) {
depth++;
parentNode = parentNode.parentProperty().parentModelNode();
}
return depth;
};
if (node1 == node2) {
depthOfLCA = (depthOfNode1 < 0) ? ((depthOfNode2 < 0) ? depthOfNode(node1) : depthOfNode2)
: depthOfNode1;
return node1;
}
if (node1.isRootNode()) {
depthOfLCA = 0;
return node1;
}
if (node2.isRootNode()) {
depthOfLCA = 0;
return node2;
}
ModelNode nodeLower = node1;
ModelNode nodeHigher = node2;
int depthLower = (depthOfNode1 < 0) ? depthOfNode(nodeLower) : depthOfNode1;
int depthHigher = (depthOfNode2 < 0) ? depthOfNode(nodeHigher) : depthOfNode2;
if (depthLower > depthHigher) {
std::swap(depthLower, depthHigher);
std::swap(nodeLower, nodeHigher);
}
int depthDiff = depthHigher - depthLower;
while (depthDiff--)
nodeHigher = nodeHigher.parentProperty().parentModelNode();
while (nodeLower != nodeHigher) {
nodeLower = nodeLower.parentProperty().parentModelNode();
nodeHigher = nodeHigher.parentProperty().parentModelNode();
--depthLower;
}
depthOfLCA = depthLower;
return nodeLower;
}
} // namespace
/*!
* \brief The lowest common node containing all nodes. If one of the nodes (Node A) is
* the ancestor of the other nodes, the return value is Node A and not the parent of Node A.
*/
ModelNode lowestCommonAncestor(const QList<ModelNode> &nodes)
{
if (nodes.isEmpty())
return {};
ModelNode accumulatedNode = nodes.first();
int accumulatedNodeDepth = -1;
for (const ModelNode &node : Utils::span<const ModelNode>(nodes).subspan(1)) {
accumulatedNode = lowestCommonAncestor(accumulatedNode,
node,
accumulatedNodeDepth,
accumulatedNodeDepth);
}
return accumulatedNode;
}
} // namespace QmlDesigner::ModelUtils } // namespace QmlDesigner::ModelUtils

View File

@@ -38,4 +38,7 @@ QMLDESIGNERCORE_EXPORT QList<ModelNode> pruneChildren(const QList<ModelNode> &no
QMLDESIGNERCORE_EXPORT QList<ModelNode> allModelNodesWithId(AbstractView *view); QMLDESIGNERCORE_EXPORT QList<ModelNode> allModelNodesWithId(AbstractView *view);
QMLDESIGNERCORE_EXPORT bool isThisOrAncestorLocked(const ModelNode &node);
QMLDESIGNERCORE_EXPORT ModelNode lowestCommonAncestor(const QList<ModelNode> &nodes);
} // namespace QmlDesigner::ModelUtils } // namespace QmlDesigner::ModelUtils