1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 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 "itemlibraryinfo.h"
27 #include "nodemetainfo.h"
28
29 #include <QSharedData>
30
31 #include <utils/algorithm.h>
32 #include <utils/fileutils.h>
33
34 namespace QmlDesigner {
35
36 namespace Internal {
37
38 class ItemLibraryEntryData
39 {
40 public:
41 QString name;
42 TypeName typeName;
43 QString category;
44 int majorVersion{-1};
45 int minorVersion{-1};
46 QString libraryEntryIconPath;
47 QIcon typeIcon = QIcon(":/ItemLibrary/images/item-default-icon.png");
48 QList<PropertyContainer> properties;
49 QString qml;
50 QString qmlSource;
51 QString requiredImport;
52 QHash<QString, QString> hints;
53 QString customComponentSource;
54 QStringList extraFilePaths;
55 };
56
57 } // namespace Internal
58
setTypeIcon(const QIcon & icon)59 void ItemLibraryEntry::setTypeIcon(const QIcon &icon)
60 {
61 m_data->typeIcon = icon;
62 }
63
addProperty(const Property & property)64 void ItemLibraryEntry::addProperty(const Property &property)
65 {
66 m_data->properties.append(property);
67 }
68
properties() const69 QList<ItemLibraryEntry::Property> ItemLibraryEntry::properties() const
70 {
71 return m_data->properties;
72 }
73
hints() const74 QHash<QString, QString> ItemLibraryEntry::hints() const
75 {
76 return m_data->hints;
77 }
78
ItemLibraryEntry()79 ItemLibraryEntry::ItemLibraryEntry() : m_data(new Internal::ItemLibraryEntryData)
80 {
81 m_data->name.clear();
82 }
83
name() const84 QString ItemLibraryEntry::name() const
85 {
86 return m_data->name;
87 }
88
typeName() const89 TypeName ItemLibraryEntry::typeName() const
90 {
91 return m_data->typeName;
92 }
93
qmlPath() const94 QString ItemLibraryEntry::qmlPath() const
95 {
96 return m_data->qml;
97 }
98
qmlSource() const99 QString ItemLibraryEntry::qmlSource() const
100 {
101 return m_data->qmlSource;
102 }
103
requiredImport() const104 QString ItemLibraryEntry::requiredImport() const
105 {
106 return m_data->requiredImport;
107 }
108
customComponentSource() const109 QString ItemLibraryEntry::customComponentSource() const
110 {
111 return m_data->customComponentSource;
112 }
113
extraFilePaths() const114 QStringList ItemLibraryEntry::extraFilePaths() const
115 {
116 return m_data->extraFilePaths;
117 }
118
majorVersion() const119 int ItemLibraryEntry::majorVersion() const
120 {
121 return m_data->majorVersion;
122 }
123
minorVersion() const124 int ItemLibraryEntry::minorVersion() const
125 {
126 return m_data->minorVersion;
127 }
128
category() const129 QString ItemLibraryEntry::category() const
130 {
131 return m_data->category;
132 }
133
setCategory(const QString & category)134 void ItemLibraryEntry::setCategory(const QString &category)
135 {
136 m_data->category = category;
137 }
138
typeIcon() const139 QIcon ItemLibraryEntry::typeIcon() const
140 {
141 return m_data->typeIcon;
142 }
143
libraryEntryIconPath() const144 QString ItemLibraryEntry::libraryEntryIconPath() const
145 {
146 return m_data->libraryEntryIconPath;
147 }
148
setName(const QString & name)149 void ItemLibraryEntry::setName(const QString &name)
150 {
151 m_data->name = name;
152 }
153
setType(const TypeName & typeName,int majorVersion,int minorVersion)154 void ItemLibraryEntry::setType(const TypeName &typeName, int majorVersion, int minorVersion)
155 {
156 m_data->typeName = typeName;
157 m_data->majorVersion = majorVersion;
158 m_data->minorVersion = minorVersion;
159 }
160
setLibraryEntryIconPath(const QString & iconPath)161 void ItemLibraryEntry::setLibraryEntryIconPath(const QString &iconPath)
162 {
163 m_data->libraryEntryIconPath = iconPath;
164 }
165
getSourceForUrl(const QString & fileURl)166 static QByteArray getSourceForUrl(const QString &fileURl)
167 {
168 Utils::FileReader fileReader;
169
170 if (fileReader.fetch(Utils::FilePath::fromString(fileURl)))
171 return fileReader.data();
172 else
173 return Utils::FileReader::fetchQrc(fileURl);
174 }
175
setQmlPath(const QString & qml)176 void ItemLibraryEntry::setQmlPath(const QString &qml)
177 {
178 m_data->qml = qml;
179
180 m_data->qmlSource = QString::fromUtf8(getSourceForUrl(qml));
181 }
182
setRequiredImport(const QString & requiredImport)183 void ItemLibraryEntry::setRequiredImport(const QString &requiredImport)
184 {
185 m_data->requiredImport = requiredImport;
186 }
187
addHints(const QHash<QString,QString> & hints)188 void ItemLibraryEntry::addHints(const QHash<QString, QString> &hints)
189 {
190 Utils::addToHash(&m_data->hints, hints);
191 }
192
setCustomComponentSource(const QString & source)193 void ItemLibraryEntry::setCustomComponentSource(const QString &source)
194 {
195 m_data->customComponentSource = source;
196 }
197
addExtraFilePath(const QString & extraFile)198 void ItemLibraryEntry::addExtraFilePath(const QString &extraFile)
199 {
200 m_data->extraFilePaths.append(extraFile);
201 }
202
addProperty(PropertyName & name,QString & type,QVariant & value)203 void ItemLibraryEntry::addProperty(PropertyName &name, QString &type, QVariant &value)
204 {
205 Property property;
206 property.set(name, type, value);
207 addProperty(property);
208 }
209
operator <<(QDataStream & stream,const ItemLibraryEntry & itemLibraryEntry)210 QDataStream& operator<<(QDataStream& stream, const ItemLibraryEntry &itemLibraryEntry)
211 {
212 stream << itemLibraryEntry.name();
213 stream << itemLibraryEntry.typeName();
214 stream << itemLibraryEntry.majorVersion();
215 stream << itemLibraryEntry.minorVersion();
216 stream << itemLibraryEntry.typeIcon();
217 stream << itemLibraryEntry.libraryEntryIconPath();
218 stream << itemLibraryEntry.category();
219 stream << itemLibraryEntry.requiredImport();
220 stream << itemLibraryEntry.hints();
221
222 stream << itemLibraryEntry.m_data->properties;
223 stream << itemLibraryEntry.m_data->qml;
224 stream << itemLibraryEntry.m_data->qmlSource;
225 stream << itemLibraryEntry.m_data->customComponentSource;
226 stream << itemLibraryEntry.m_data->extraFilePaths;
227
228 return stream;
229 }
230
operator >>(QDataStream & stream,ItemLibraryEntry & itemLibraryEntry)231 QDataStream& operator>>(QDataStream& stream, ItemLibraryEntry &itemLibraryEntry)
232 {
233 // Clear containers so that we don't simply append to them in case the object is reused
234 itemLibraryEntry.m_data->hints.clear();
235 itemLibraryEntry.m_data->properties.clear();
236
237 stream >> itemLibraryEntry.m_data->name;
238 stream >> itemLibraryEntry.m_data->typeName;
239 stream >> itemLibraryEntry.m_data->majorVersion;
240 stream >> itemLibraryEntry.m_data->minorVersion;
241 stream >> itemLibraryEntry.m_data->typeIcon;
242 stream >> itemLibraryEntry.m_data->libraryEntryIconPath;
243 stream >> itemLibraryEntry.m_data->category;
244 stream >> itemLibraryEntry.m_data->requiredImport;
245 stream >> itemLibraryEntry.m_data->hints;
246
247 stream >> itemLibraryEntry.m_data->properties;
248 stream >> itemLibraryEntry.m_data->qml;
249 stream >> itemLibraryEntry.m_data->qmlSource;
250 stream >> itemLibraryEntry.m_data->customComponentSource;
251 stream >> itemLibraryEntry.m_data->extraFilePaths;
252
253 return stream;
254 }
255
operator <<(QDebug debug,const ItemLibraryEntry & itemLibraryEntry)256 QDebug operator<<(QDebug debug, const ItemLibraryEntry &itemLibraryEntry)
257 {
258 debug << itemLibraryEntry.m_data->name;
259 debug << itemLibraryEntry.m_data->typeName;
260 debug << itemLibraryEntry.m_data->majorVersion;
261 debug << itemLibraryEntry.m_data->minorVersion;
262 debug << itemLibraryEntry.m_data->typeIcon;
263 debug << itemLibraryEntry.m_data->libraryEntryIconPath;
264 debug << itemLibraryEntry.m_data->category;
265 debug << itemLibraryEntry.m_data->requiredImport;
266 debug << itemLibraryEntry.m_data->hints;
267
268 debug << itemLibraryEntry.m_data->properties;
269 debug << itemLibraryEntry.m_data->qml;
270 debug << itemLibraryEntry.m_data->qmlSource;
271 debug << itemLibraryEntry.m_data->customComponentSource;
272 debug << itemLibraryEntry.m_data->extraFilePaths;
273
274 return debug.space();
275 }
276
277 //
278 // ItemLibraryInfo
279 //
280
ItemLibraryInfo(QObject * parent)281 ItemLibraryInfo::ItemLibraryInfo(QObject *parent)
282 : QObject(parent)
283 {
284 }
285
286
287
entriesForType(const QByteArray & typeName,int majorVersion,int minorVersion) const288 QList<ItemLibraryEntry> ItemLibraryInfo::entriesForType(const QByteArray &typeName, int majorVersion, int minorVersion) const
289 {
290 QList<ItemLibraryEntry> entries;
291
292 foreach (const ItemLibraryEntry &entry, m_nameToEntryHash) {
293 if (entry.typeName() == typeName)
294 entries += entry;
295 }
296
297 if (m_baseInfo)
298 entries += m_baseInfo->entriesForType(typeName, majorVersion, minorVersion);
299
300 return entries;
301 }
302
entries() const303 QList<ItemLibraryEntry> ItemLibraryInfo::entries() const
304 {
305 QList<ItemLibraryEntry> list = m_nameToEntryHash.values();
306 if (m_baseInfo)
307 list += m_baseInfo->entries();
308 return list;
309 }
310
keyForEntry(const ItemLibraryEntry & entry)311 static inline QString keyForEntry(const ItemLibraryEntry &entry)
312 {
313 return entry.name() + entry.category() + QString::number(entry.majorVersion());
314 }
315
addEntries(const QList<ItemLibraryEntry> & entries,bool overwriteDuplicate)316 void ItemLibraryInfo::addEntries(const QList<ItemLibraryEntry> &entries, bool overwriteDuplicate)
317 {
318 foreach (const ItemLibraryEntry &entry, entries) {
319 const QString key = keyForEntry(entry);
320 if (!overwriteDuplicate && m_nameToEntryHash.contains(key))
321 throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
322 m_nameToEntryHash.insert(key, entry);
323 }
324 emit entriesChanged();
325 }
326
containsEntry(const ItemLibraryEntry & entry)327 bool ItemLibraryInfo::containsEntry(const ItemLibraryEntry &entry)
328 {
329 const QString key = keyForEntry(entry);
330 return m_nameToEntryHash.contains(key);
331 }
332
clearEntries()333 void ItemLibraryInfo::clearEntries()
334 {
335 m_nameToEntryHash.clear();
336 emit entriesChanged();
337 }
338
blacklistImports() const339 QStringList ItemLibraryInfo::blacklistImports() const
340 {
341 auto list = m_blacklistImports;
342 if (m_baseInfo)
343 list.append(m_baseInfo->m_blacklistImports);
344 return list;
345 }
346
priorityImports() const347 QSet<QString> ItemLibraryInfo::priorityImports() const
348 {
349 QSet<QString> set = m_priorityImports;
350 if (m_baseInfo)
351 set.unite(m_baseInfo->m_priorityImports);
352 return set;
353 }
354
addBlacklistImports(const QStringList & list)355 void ItemLibraryInfo::addBlacklistImports(const QStringList &list)
356 {
357 m_blacklistImports.append(list);
358 }
359
addPriorityImports(const QSet<QString> & set)360 void ItemLibraryInfo::addPriorityImports(const QSet<QString> &set)
361 {
362 if (!set.isEmpty()) {
363 m_priorityImports.unite(set);
364 emit priorityImportsChanged();
365 }
366 }
367
setBaseInfo(ItemLibraryInfo * baseInfo)368 void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo)
369 {
370 m_baseInfo = baseInfo;
371 }
372
373 } // namespace QmlDesigner
374