1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "modelmerger.h"
36 #include "modelmerger.h"
37 #include "modelnode.h"
38 #include "abstractview.h"
40 #include "nodeproperty.h"
41 #include "nodelistproperty.h"
42 #include "bindingproperty.h"
43 #include "variantproperty.h"
44 #include "rewritertransaction.h"
45 #include <rewritingexception.h>
48 #include <QStringList>
52 namespace QmlDesigner {
54 static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QString, QString> &idRenamingHash, AbstractView *view);
56 static QString fixExpression(const QString &expression, const QHash<QString, QString> &idRenamingHash)
58 QString newExpression = expression;
59 foreach (const QString &id, idRenamingHash.keys()) {
60 if (newExpression.contains(id))
61 newExpression = newExpression.replace(id, idRenamingHash.value(id));
66 static void syncVariantProperties(ModelNode &outputNode, const ModelNode &inputNode)
68 foreach (const VariantProperty &variantProperty, inputNode.variantProperties()) {
69 outputNode.variantProperty(variantProperty.name()) = variantProperty.value();
73 static void syncBindingProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash)
75 foreach (const BindingProperty &bindingProperty, inputNode.bindingProperties()) {
76 outputNode.bindingProperty(bindingProperty.name()).setExpression(fixExpression(bindingProperty.expression(), idRenamingHash));
80 static void syncId(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash)
82 if (!inputNode.id().isEmpty()) {
83 outputNode.setId(idRenamingHash.value(inputNode.id()));
87 static void splitIdInBaseNameAndNumber(const QString &id, QString *baseId, int *number)
91 while(counter < id.count()) {
92 bool canConvertToInteger = false;
93 int newNumber = id.right(counter +1).toInt(&canConvertToInteger);
94 if (canConvertToInteger)
102 *baseId = id.left(id.count() - counter);
105 static void setupIdRenamingHash(const ModelNode &modelNode, QHash<QString, QString> &idRenamingHash, AbstractView *view)
107 QList<ModelNode> allNodes(modelNode.allSubModelNodes());
108 allNodes.append(modelNode);
109 foreach (const ModelNode &node, allNodes) {
110 if (!node.id().isEmpty()) {
111 QString newId = node.id();
114 splitIdInBaseNameAndNumber(newId, &baseId, &number);
116 while (view->hasId(newId) || idRenamingHash.values().contains(newId)) {
117 newId = baseId + QString::number(number);
121 idRenamingHash.insert(node.id(), newId);
126 static void syncNodeProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash, AbstractView *view)
128 foreach (const NodeProperty &nodeProperty, inputNode.nodeProperties()) {
129 ModelNode newNode = createNodeFromNode(nodeProperty.modelNode(), idRenamingHash, view);
130 outputNode.nodeProperty(nodeProperty.name()).reparentHere(newNode);
134 static void syncNodeListProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash, AbstractView *view)
136 foreach (const NodeListProperty &nodeListProperty, inputNode.nodeListProperties()) {
137 foreach (const ModelNode &node, nodeListProperty.toModelNodeList()) {
138 ModelNode newNode = createNodeFromNode(node, idRenamingHash, view);
139 outputNode.nodeListProperty(nodeListProperty.name()).reparentHere(newNode);
144 static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QString, QString> &idRenamingHash, AbstractView *view)
146 QList<QPair<QString, QVariant> > propertyList;
147 foreach (const VariantProperty &variantProperty, modelNode.variantProperties()) {
148 propertyList.append(QPair<QString, QVariant>(variantProperty.name(), variantProperty.value()));
150 ModelNode newNode(view->createModelNode(modelNode.type(),modelNode.majorVersion(),modelNode.minorVersion(), propertyList));
151 syncBindingProperties(newNode, modelNode, idRenamingHash);
152 syncId(newNode, modelNode, idRenamingHash);
153 syncNodeProperties(newNode, modelNode, idRenamingHash, view);
154 syncNodeListProperties(newNode, modelNode, idRenamingHash, view);
159 ModelNode ModelMerger::insertModel(const ModelNode &modelNode)
161 RewriterTransaction transaction(view()->beginRewriterTransaction());
163 view()->model()->changeImports(modelNode.model()->imports(), QList<Import>());
165 QHash<QString, QString> idRenamingHash;
166 setupIdRenamingHash(modelNode, idRenamingHash, view());
167 qDebug() << idRenamingHash;
168 ModelNode newNode(createNodeFromNode(modelNode, idRenamingHash, view()));
173 void ModelMerger::replaceModel(const ModelNode &modelNode)
175 view()->model()->changeImports(modelNode.model()->imports(), QList<Import>());
176 view()->model()->setFileUrl(modelNode.model()->fileUrl());
179 RewriterTransaction transaction(view()->beginRewriterTransaction());
181 ModelNode rootNode(view()->rootModelNode());
183 foreach (const QString &propertyName, rootNode.propertyNames())
184 rootNode.removeProperty(propertyName);
186 QHash<QString, QString> idRenamingHash;
187 setupIdRenamingHash(modelNode, idRenamingHash, view());
189 syncVariantProperties(rootNode, modelNode);
190 syncBindingProperties(rootNode, modelNode, idRenamingHash);
191 syncId(rootNode, modelNode, idRenamingHash);
192 syncNodeProperties(rootNode, modelNode, idRenamingHash, view());
193 syncNodeListProperties(rootNode, modelNode, idRenamingHash, view());
194 m_view->changeRootNodeType(modelNode.type(), modelNode.majorVersion(), modelNode.minorVersion());
195 } catch (RewritingException &e) {
196 qWarning() << e.description(); //silent error
200 } //namespace QmlDesigner