forked from qt-creator/qt-creator
QmlDesigner: Use predicate to walk nodes for merging
Task-number: QDS-3776 Change-Id: I59f647042d5975f953c4c9e2f24e60a0003b85c8 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -28,19 +28,24 @@
|
|||||||
#include <qmldesignercorelib_global.h>
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class AbstractView;
|
class AbstractView;
|
||||||
class ModelNode;
|
class ModelNode;
|
||||||
|
|
||||||
|
using MergePredicate = std::function<bool(const ModelNode &)>;
|
||||||
|
|
||||||
class QMLDESIGNERCORE_EXPORT ModelMerger
|
class QMLDESIGNERCORE_EXPORT ModelMerger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ModelMerger(AbstractView *view) : m_view(view) {}
|
ModelMerger(AbstractView *view) : m_view(view) {}
|
||||||
|
|
||||||
ModelNode insertModel(const ModelNode &modelNode);
|
ModelNode insertModel(const ModelNode &modelNode,
|
||||||
void replaceModel(const ModelNode &modelNode);
|
const MergePredicate &predicate = [](const ModelNode &) { return true; });
|
||||||
|
void replaceModel(const ModelNode &modelNode,
|
||||||
|
const MergePredicate &predicate = [](const ModelNode &) { return true; });
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AbstractView *view() const
|
AbstractView *view() const
|
||||||
|
@@ -43,7 +43,9 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QString, QString> &idRenamingHash, AbstractView *view);
|
static ModelNode createNodeFromNode(const ModelNode &modelNode,
|
||||||
|
const QHash<QString, QString> &idRenamingHash,
|
||||||
|
AbstractView *view, const MergePredicate &mergePredicate);
|
||||||
|
|
||||||
static QString fixExpression(const QString &expression, const QHash<QString, QString> &idRenamingHash)
|
static QString fixExpression(const QString &expression, const QHash<QString, QString> &idRenamingHash)
|
||||||
{
|
{
|
||||||
@@ -130,25 +132,36 @@ static void setupIdRenamingHash(const ModelNode &modelNode, QHash<QString, QStri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncNodeProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash, AbstractView *view)
|
static void syncNodeProperties(ModelNode &outputNode, const ModelNode &inputNode,
|
||||||
|
const QHash<QString, QString> &idRenamingHash,
|
||||||
|
AbstractView *view, const MergePredicate &mergePredicate)
|
||||||
{
|
{
|
||||||
foreach (const NodeProperty &nodeProperty, inputNode.nodeProperties()) {
|
foreach (const NodeProperty &nodeProperty, inputNode.nodeProperties()) {
|
||||||
ModelNode newNode = createNodeFromNode(nodeProperty.modelNode(), idRenamingHash, view);
|
ModelNode node = nodeProperty.modelNode();
|
||||||
|
if (!mergePredicate(node))
|
||||||
|
continue;
|
||||||
|
ModelNode newNode = createNodeFromNode(node, idRenamingHash, view, mergePredicate);
|
||||||
outputNode.nodeProperty(nodeProperty.name()).reparentHere(newNode);
|
outputNode.nodeProperty(nodeProperty.name()).reparentHere(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syncNodeListProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash, AbstractView *view)
|
static void syncNodeListProperties(ModelNode &outputNode, const ModelNode &inputNode,
|
||||||
|
const QHash<QString, QString> &idRenamingHash,
|
||||||
|
AbstractView *view, const MergePredicate &mergePredicate)
|
||||||
{
|
{
|
||||||
foreach (const NodeListProperty &nodeListProperty, inputNode.nodeListProperties()) {
|
foreach (const NodeListProperty &nodeListProperty, inputNode.nodeListProperties()) {
|
||||||
foreach (const ModelNode &node, nodeListProperty.toModelNodeList()) {
|
foreach (const ModelNode &node, nodeListProperty.toModelNodeList()) {
|
||||||
ModelNode newNode = createNodeFromNode(node, idRenamingHash, view);
|
if (!mergePredicate(node))
|
||||||
|
continue;
|
||||||
|
ModelNode newNode = createNodeFromNode(node, idRenamingHash, view, mergePredicate);
|
||||||
outputNode.nodeListProperty(nodeListProperty.name()).reparentHere(newNode);
|
outputNode.nodeListProperty(nodeListProperty.name()).reparentHere(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QString, QString> &idRenamingHash, AbstractView *view)
|
static ModelNode createNodeFromNode(const ModelNode &modelNode,
|
||||||
|
const QHash<QString, QString> &idRenamingHash,
|
||||||
|
AbstractView *view, const MergePredicate &mergePredicate)
|
||||||
{
|
{
|
||||||
QList<QPair<PropertyName, QVariant> > propertyList;
|
QList<QPair<PropertyName, QVariant> > propertyList;
|
||||||
QList<QPair<PropertyName, QVariant> > variantPropertyList;
|
QList<QPair<PropertyName, QVariant> > variantPropertyList;
|
||||||
@@ -162,14 +175,17 @@ static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QStri
|
|||||||
syncBindingProperties(newNode, modelNode, idRenamingHash);
|
syncBindingProperties(newNode, modelNode, idRenamingHash);
|
||||||
syncSignalHandlerProperties(newNode, modelNode, idRenamingHash);
|
syncSignalHandlerProperties(newNode, modelNode, idRenamingHash);
|
||||||
syncId(newNode, modelNode, idRenamingHash);
|
syncId(newNode, modelNode, idRenamingHash);
|
||||||
syncNodeProperties(newNode, modelNode, idRenamingHash, view);
|
syncNodeProperties(newNode, modelNode, idRenamingHash, view, mergePredicate);
|
||||||
syncNodeListProperties(newNode, modelNode, idRenamingHash, view);
|
syncNodeListProperties(newNode, modelNode, idRenamingHash, view, mergePredicate);
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNode ModelMerger::insertModel(const ModelNode &modelNode)
|
|
||||||
|
ModelNode ModelMerger::insertModel(const ModelNode &modelNode, const MergePredicate &predicate)
|
||||||
{
|
{
|
||||||
|
if (!predicate(modelNode))
|
||||||
|
return {};
|
||||||
RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::insertModel")));
|
RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::insertModel")));
|
||||||
|
|
||||||
QList<Import> newImports;
|
QList<Import> newImports;
|
||||||
@@ -183,16 +199,20 @@ ModelNode ModelMerger::insertModel(const ModelNode &modelNode)
|
|||||||
|
|
||||||
QHash<QString, QString> idRenamingHash;
|
QHash<QString, QString> idRenamingHash;
|
||||||
setupIdRenamingHash(modelNode, idRenamingHash, view());
|
setupIdRenamingHash(modelNode, idRenamingHash, view());
|
||||||
ModelNode newNode(createNodeFromNode(modelNode, idRenamingHash, view()));
|
ModelNode newNode(createNodeFromNode(modelNode, idRenamingHash, view(), predicate));
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
void ModelMerger::replaceModel(const ModelNode &modelNode)
|
|
||||||
|
void ModelMerger::replaceModel(const ModelNode &modelNode, const MergePredicate &predicate)
|
||||||
{
|
{
|
||||||
|
if (!predicate(modelNode))
|
||||||
|
return;
|
||||||
|
|
||||||
view()->model()->changeImports(modelNode.model()->imports(), {});
|
view()->model()->changeImports(modelNode.model()->imports(), {});
|
||||||
view()->model()->setFileUrl(modelNode.model()->fileUrl());
|
view()->model()->setFileUrl(modelNode.model()->fileUrl());
|
||||||
|
|
||||||
view()->executeInTransaction("ModelMerger::replaceModel", [this, modelNode](){
|
view()->executeInTransaction("ModelMerger::replaceModel", [this, modelNode, &predicate](){
|
||||||
ModelNode rootNode(view()->rootModelNode());
|
ModelNode rootNode(view()->rootModelNode());
|
||||||
|
|
||||||
foreach (const PropertyName &propertyName, rootNode.propertyNames())
|
foreach (const PropertyName &propertyName, rootNode.propertyNames())
|
||||||
@@ -205,8 +225,8 @@ void ModelMerger::replaceModel(const ModelNode &modelNode)
|
|||||||
syncVariantProperties(rootNode, modelNode);
|
syncVariantProperties(rootNode, modelNode);
|
||||||
syncBindingProperties(rootNode, modelNode, idRenamingHash);
|
syncBindingProperties(rootNode, modelNode, idRenamingHash);
|
||||||
syncId(rootNode, modelNode, idRenamingHash);
|
syncId(rootNode, modelNode, idRenamingHash);
|
||||||
syncNodeProperties(rootNode, modelNode, idRenamingHash, view());
|
syncNodeProperties(rootNode, modelNode, idRenamingHash, view(), predicate);
|
||||||
syncNodeListProperties(rootNode, modelNode, idRenamingHash, view());
|
syncNodeListProperties(rootNode, modelNode, idRenamingHash, view(), predicate);
|
||||||
m_view->changeRootNodeType(modelNode.type(), modelNode.majorVersion(), modelNode.minorVersion());
|
m_view->changeRootNodeType(modelNode.type(), modelNode.majorVersion(), modelNode.minorVersion());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user