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 <QtCore/QVariant>
35 #include <QtGui/QColor>
37 #include "bindingproperty.h"
38 #include "nodeproperty.h"
39 #include "nodelistproperty.h"
40 #include "qmltextgenerator.h"
41 #include "variantproperty.h"
42 #include <nodemetainfo.h>
45 using namespace QmlDesigner;
46 using namespace QmlDesigner::Internal;
48 inline static QString properColorName(const QColor &color)
51 if (color.alpha() == 255)
52 s.sprintf("#%02x%02x%02x", color.red(), color.green(), color.blue());
54 s.sprintf("#%02x%02x%02x%02x", color.alpha(), color.red(), color.green(), color.blue());
58 QmlTextGenerator::QmlTextGenerator(const QStringList &propertyOrder, int indentDepth):
59 m_propertyOrder(propertyOrder),
60 m_indentDepth(indentDepth)
64 QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDepth) const
66 if (property.isBindingProperty()) {
67 return property.toBindingProperty().expression();
68 } else if (property.isNodeProperty()) {
69 return toQml(property.toNodeProperty().modelNode(), indentDepth);
70 } else if (property.isNodeListProperty()) {
71 const QList<ModelNode> nodes = property.toNodeListProperty().toModelNodeList();
72 if (property.isDefaultProperty()) {
74 for (int i = 0; i < nodes.length(); ++i) {
76 result += QLatin1String("\n\n");
77 result += QString(indentDepth, QLatin1Char(' '));
78 result += toQml(nodes.at(i), indentDepth);
82 QString result = QLatin1String("[");
83 const int arrayContentDepth = indentDepth + 4;
84 const QString arrayContentIndentation(arrayContentDepth, QLatin1Char(' '));
85 for (int i = 0; i < nodes.length(); ++i) {
87 result += QLatin1Char(',');
88 result += QLatin1Char('\n');
89 result += arrayContentIndentation;
90 result += toQml(nodes.at(i), arrayContentDepth);
92 return result + QLatin1Char(']');
94 } else if (property.isVariantProperty()) {
95 const VariantProperty variantProperty = property.toVariantProperty();
96 const QVariant value = variantProperty.value();
97 const QString stringValue = value.toString();
99 if (property.name() == QLatin1String("id"))
104 if (variantProperty.parentModelNode().metaInfo().isValid() &&
105 variantProperty.parentModelNode().metaInfo().propertyIsEnumType(variantProperty.name())) {
106 return variantProperty.parentModelNode().metaInfo().propertyEnumScope(variantProperty.name()) + '.' + stringValue;
109 switch (value.type()) {
111 if (value.value<bool>())
112 return QLatin1String("true");
114 return QLatin1String("false");
116 case QVariant::Color:
117 return QString(QLatin1String("\"%1\"")).arg(properColorName(value.value<QColor>()));
119 case QVariant::Double:
121 case QVariant::LongLong:
123 case QVariant::ULongLong:
127 return QString(QLatin1String("\"%1\"")).arg(escape(stringValue));
131 Q_ASSERT("Unknown property type");
136 QString QmlTextGenerator::toQml(const ModelNode &node, int indentDepth) const
138 QString type = node.type();
140 if (type.contains('.')) {
141 QStringList nameComponents = type.split('.');
142 url = nameComponents.first();
143 type = nameComponents.last();
147 if (!url.isEmpty()) {
148 const QString &versionUrl = QString("%1.%2").arg(QString::number(node.majorVersion()), QString::number(node.minorVersion()));
149 foreach (const Import &import, node.model()->imports()) {
150 if (import.url() == url
151 && import.version() == versionUrl) {
152 alias = import.alias();
160 if (!alias.isEmpty())
161 result = alias + '.';
164 result += QLatin1String(" {\n");
166 const int propertyIndentDepth = indentDepth + 4;
168 const QString properties = propertiesToQml(node, propertyIndentDepth);
170 return result + properties + QString(indentDepth, QLatin1Char(' ')) + QLatin1Char('}');
173 QString QmlTextGenerator::propertiesToQml(const ModelNode &node, int indentDepth) const
178 QStringList nodePropertyNames = node.propertyNames();
179 bool addToTop = true;
181 foreach (const QString &propertyName, m_propertyOrder) {
182 if (QLatin1String("id") == propertyName) {
183 // the model handles the id property special, so:
184 if (!node.id().isEmpty()) {
185 QString idLine(indentDepth, QLatin1Char(' '));
186 idLine += QLatin1String("id: ");
188 idLine += QLatin1Char('\n');
191 topPart.append(idLine);
193 bottomPart.append(idLine);
195 } else if (propertyName.isEmpty()) {
197 } else if (nodePropertyNames.removeAll(propertyName)) {
198 const QString newContent = propertyToQml(node.property(propertyName), indentDepth);
201 topPart.append(newContent);
203 bottomPart.append(newContent);
207 foreach (const QString &propertyName, nodePropertyNames) {
208 bottomPart.prepend(propertyToQml(node.property(propertyName), indentDepth));
211 return topPart + bottomPart;
214 QString QmlTextGenerator::propertyToQml(const AbstractProperty &property, int indentDepth) const
218 if (property.isDefaultProperty())
219 result = toQml(property, indentDepth);
221 result = QString(indentDepth, QLatin1Char(' ')) + property.name() + QLatin1String(": ") + toQml(property, indentDepth);
223 result += QLatin1Char('\n');
228 QString QmlTextGenerator::escape(const QString &value)
230 QString result = value;
232 result.replace(QLatin1String("\\"), QLatin1String("\\\\"));
233 result.replace(QLatin1String("\""), QLatin1String("\\\""));
234 result.replace(QLatin1String("\t"), QLatin1String("\\\t"));
235 result.replace(QLatin1String("\r"), QLatin1String("\\\r"));
236 result.replace(QLatin1String("\n"), QLatin1String("\\\n"));