1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "designermcumanager.h"
27 #include "qmldesignerconstants.h"
28 #include "qmldesignerplugin.h"
29 #include "designersettings.h"
30 #include "designdocument.h"
31
32 #include <qmljs/qmljssimplereader.h>
33
34 #include <utils/qtcassert.h>
35
36 namespace QmlDesigner {
37
readProperty(const QString property,const QmlJS::SimpleReaderNode::Ptr & node)38 static QString readProperty(const QString property, const QmlJS::SimpleReaderNode::Ptr &node)
39 {
40 const QVariant propertyVar = node->property(property);
41
42 if (!propertyVar.isNull() && propertyVar.isValid())
43 return propertyVar.value<QString>();
44
45 return {};
46 }
47
readPropertyList(const QString & property,const QmlJS::SimpleReaderNode::Ptr & node)48 static QStringList readPropertyList(const QString &property, const QmlJS::SimpleReaderNode::Ptr &node)
49 {
50 const QVariant propertyVar = node->property(property);
51
52 if (!propertyVar.isNull() && propertyVar.isValid())
53 return propertyVar.value<QStringList>();
54
55 return {};
56 }
57
instance()58 DesignerMcuManager &DesignerMcuManager::instance()
59 {
60 static DesignerMcuManager instance;
61
62 return instance;
63 }
64
mcuResourcesPath()65 QString DesignerMcuManager::mcuResourcesPath()
66 {
67 return Core::ICore::resourcePath("qmldesigner/qt4mcu").toString();
68 }
69
isMCUProject() const70 bool DesignerMcuManager::isMCUProject() const
71 {
72 QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance()
73 ->documentManager().currentDesignDocument();
74 if (designDocument)
75 return designDocument->isQtForMCUsProject();
76
77 return false;
78 }
79
readMetadata()80 void DesignerMcuManager::readMetadata()
81 {
82 const QString mainMetadataFileName = "metadata.qml";
83
84 m_defaultVersion = {};
85 m_versionsList.clear();
86
87 QmlJS::SimpleReader reader;
88 const QmlJS::SimpleReaderNode::Ptr metadata =
89 reader.readFile(mcuResourcesPath() + "/" + mainMetadataFileName);
90 if (!metadata) {
91 qWarning() << "Designer MCU metadata:" << reader.errors();
92 return;
93 }
94
95 const QmlJS::SimpleReaderNode::List versions = metadata->children();
96
97 if (versions.isEmpty()) {
98 qWarning() << "Designer MCU metadata: metadata list is empty";
99 return;
100 }
101
102 const QVariant defaultVersion = metadata->property("defaultVersion");
103 if (!defaultVersion.isNull() && defaultVersion.isValid()) {
104 for (const auto& version : versions) {
105 Version newVersion;
106
107 const QVariant vId = version->property("id");
108 if (vId.isNull() || !vId.isValid())
109 continue;
110
111 const QVariant vName = version->property("name");
112 if (!vName.isNull() && vName.isValid())
113 newVersion.name = vName.value<QString>();
114 else
115 continue;
116
117 const QVariant vPath = version->property("path");
118 if (!vPath.isNull() && vPath.isValid())
119 newVersion.fileName = vPath.value<QString>();
120 else
121 continue;
122
123 m_versionsList.push_back(newVersion);
124
125 if (vId == defaultVersion)
126 m_defaultVersion = newVersion;
127 }
128 }
129 }
130
readVersionData(const DesignerMcuManager::Version & version)131 void DesignerMcuManager::readVersionData(const DesignerMcuManager::Version &version)
132 {
133 m_currentVersion = {};
134 m_bannedItems.clear();
135 m_allowedImports.clear();
136 m_bannedImports.clear();
137 m_bannedProperties.clear();
138 m_allowedItemProperties.clear();
139 m_bannedComplexProperties.clear();
140
141 QmlJS::SimpleReader reader;
142 const QmlJS::SimpleReaderNode::Ptr versionData =
143 reader.readFile(mcuResourcesPath() + "/" + version.fileName);
144 if (!versionData) {
145 qWarning() << "Designer MCU metadata:" << reader.errors();
146 return;
147 }
148
149 const QmlJS::SimpleReaderNode::List info = versionData->children();
150
151 if (info.isEmpty()) {
152 qWarning() << "Designer MCU metadata: metadata list is empty";
153 return;
154 }
155
156 for (const auto& child : info) {
157 //handling specific item types:
158 if (child->name() == "ComplexProperty") {
159 if (child->propertyNames().contains("prefix")
160 && child->propertyNames().contains("bannedProperties")) {
161 const QString complexPropPrefix(readProperty("prefix", child));
162 const QStringList complexPropBans(readPropertyList("bannedProperties", child));
163
164 if (!complexPropPrefix.isEmpty() && !complexPropBans.isEmpty())
165 m_bannedComplexProperties.insert(complexPropPrefix, complexPropBans);
166 }
167
168 continue;
169 }
170
171 //handling allowed properties:
172 if (child->propertyNames().contains("allowedProperties")) {
173 ItemProperties allowedProperties;
174
175 const QVariant childrenPropertyVar = child->property("allowChildren");
176
177 if (!childrenPropertyVar.isNull() && childrenPropertyVar.isValid())
178 allowedProperties.allowChildren = childrenPropertyVar.toBool();
179
180 allowedProperties.properties = readPropertyList("allowedProperties", child);
181
182 if (!allowedProperties.properties.isEmpty())
183 m_allowedItemProperties.insert(child->name(), allowedProperties);
184 }
185
186 //handling banned properties:
187 const QStringList bannedProperties = readPropertyList("bannedProperties", child);
188
189 m_bannedProperties.unite(QSet<QString>(bannedProperties.begin(), bannedProperties.end()));
190 }
191
192 const QList<QString> bannedItems = readPropertyList("bannedItems", versionData);
193
194 m_bannedItems = QSet<QString>(bannedItems.begin(), bannedItems.end());
195 m_allowedImports = readPropertyList("allowedImports", versionData);
196 m_bannedImports = readPropertyList("bannedImports", versionData);
197 m_currentVersion = version;
198 }
199
currentVersion() const200 DesignerMcuManager::Version DesignerMcuManager::currentVersion() const
201 {
202 return m_currentVersion;
203 }
204
defaultVersion() const205 DesignerMcuManager::Version DesignerMcuManager::defaultVersion() const
206 {
207 return m_defaultVersion;
208 }
209
versions() const210 DesignerMcuManager::VersionsList DesignerMcuManager::versions() const
211 {
212 return m_versionsList;
213 }
214
bannedItems() const215 QSet<QString> DesignerMcuManager::bannedItems() const
216 {
217 return m_bannedItems;
218 }
219
bannedProperties() const220 QSet<QString> DesignerMcuManager::bannedProperties() const
221 {
222 return m_bannedProperties;
223 }
224
allowedImports() const225 QStringList DesignerMcuManager::allowedImports() const
226 {
227 return m_allowedImports;
228 }
229
bannedImports() const230 QStringList DesignerMcuManager::bannedImports() const
231 {
232 return m_bannedImports;
233 }
234
allowedItemProperties() const235 QHash<QString, DesignerMcuManager::ItemProperties> DesignerMcuManager::allowedItemProperties() const
236 {
237 return m_allowedItemProperties;
238 }
239
bannedComplexProperties() const240 QHash<QString, QStringList> DesignerMcuManager::bannedComplexProperties() const
241 {
242 return m_bannedComplexProperties;
243 }
244
DesignerMcuManager()245 DesignerMcuManager::DesignerMcuManager()
246 {
247 readMetadata();
248
249 readVersionData(m_defaultVersion);
250 }
251
~DesignerMcuManager()252 DesignerMcuManager::~DesignerMcuManager()
253 {
254
255 }
256
257 } // QmlDesigner
258