From 00c07ca53eb0eeaad3db3e8212abd4d100fb9569 Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Mon, 28 Sep 2020 17:33:40 +0200 Subject: [PATCH] QmlDesigner: MCU configurations metadata -Removed c++ hardcoded info about QDS MCU restrictions -Instead replaced it with dynamically loaded qml files -Replaced QLists with QSet/QHash to improve performance Task: QDS-2794 Change-Id: Ifc23d1299155001b6573dc0ed789dda5d2cfaf24 Reviewed-by: Miikka Heikkinen Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../qtcreator/qmldesigner/qt4mcu/metadata.qml | 37 +++ share/qtcreator/qmldesigner/qt4mcu/qul-14.qml | 154 +++++++++++ src/plugins/qmldesigner/CMakeLists.txt | 1 + .../importmanager/importswidget.cpp | 15 +- .../itemlibrary/itemlibrarymodel.cpp | 49 +--- .../itemlibrary/itemlibrarywidget.cpp | 6 +- .../propertyeditor/propertyeditorvalue.cpp | 112 ++------ .../qmldesigner/designermcumanager.cpp | 260 ++++++++++++++++++ src/plugins/qmldesigner/designermcumanager.h | 90 ++++++ src/plugins/qmldesigner/qmldesignerplugin.pri | 6 +- src/plugins/qmldesigner/qmldesignerplugin.qbs | 2 + 11 files changed, 593 insertions(+), 139 deletions(-) create mode 100644 share/qtcreator/qmldesigner/qt4mcu/metadata.qml create mode 100644 share/qtcreator/qmldesigner/qt4mcu/qul-14.qml create mode 100644 src/plugins/qmldesigner/designermcumanager.cpp create mode 100644 src/plugins/qmldesigner/designermcumanager.h diff --git a/share/qtcreator/qmldesigner/qt4mcu/metadata.qml b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml new file mode 100644 index 00000000000..09c612ab401 --- /dev/null +++ b/share/qtcreator/qmldesigner/qt4mcu/metadata.qml @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +//list of files in the current system +Metadata { + id: metadataFile + + defaultVersion: v14 + + VersionData { + id: v14 + name: "QUL 1.4" + path: "qul-14.qml" + } +} diff --git a/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml b/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml new file mode 100644 index 00000000000..f01f3b53ced --- /dev/null +++ b/share/qtcreator/qmldesigner/qt4mcu/qul-14.qml @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +VersionData { + name: "QUL 1.4" + + bannedItems: ["QtQuick.AnimatedImage", + "QtQuick.BorderImage", + "QtQuick.FocusScope", + "QtQuick.TextInput", + "QtQuick.TextEdit", + "QtQuick.Flow", + "QtQuick.Grid", + "QtQuick.GridView", + "QtQuick.PathView", + "QtQuick.Controls", + "QtQuick.Controls.BusyIndicator", + "QtQuick.Controls.ButtonGroup", + "QtQuick.Controls.CheckDelegate", + "QtQuick.Controls.Container", + "QtQuick.Controls.ComboBox", + "QtQuick.Controls.DelayButton", + "QtQuick.Controls.Frame", + "QtQuick.Controls.GroupBox", + "QtQuick.Controls.ItemDelegate", + "QtQuick.Controls.Label", + "QtQuick.Controls.Page", + "QtQuick.Controls.PageIndicator", + "QtQuick.Controls.Pane", + "QtQuick.Controls.RadioDelegate", + "QtQuick.Controls.RangeSlider", + "QtQuick.Controls.RoundButton", + "QtQuick.Controls.ScrollView", + "QtQuick.Controls.SpinBox", + "QtQuick.Controls.StackView", + "QtQuick.Controls.SwipeDelegate", + "QtQuick.Controls.SwitchDelegate", + "QtQuick.Controls.ToolBar", + "QtQuick.Controls.ToolButton", + "QtQuick.Controls.TabBar", + "QtQuick.Controls.TabButton", + "QtQuick.Controls.TextArea", + "QtQuick.Controls.TextField", + "QtQuick.Controls.ToolSeparator", + "QtQuick.Controls.Tumbler"] + + allowedImports: ["QtQuick", + "QtQuick.Controls", + "QtQuick.Timeline"] + + bannedImports: ["FlowView"] + + //ComplexProperty is not a type, it's just a way to handle bigger props + ComplexProperty { + prefix: "font" + bannedProperties: ["wordSpacing", "letterSpacing", "hintingPreference", + "kerning", "preferShaping", "capitalization", + "strikeout", "underline", "styleName"] + } + + QtQuick.Item { + bannedProperties: ["layer", "opacity", "gradient", "smooth", "antialiasing", + "border", "baselineOffset", "focus", "activeFocusOnTab", + "rotation", "scale", "transformOrigin"] + } + + QtQuick.Flickable { + bannedProperties: ["boundsBehavior", "boundsMovement", "flickDeceleration", + "flickableDirection", "leftMargin", "rightMargin", "bottomMargin", "topMargin", + "originX", "originY", "pixelAligned", "pressDelay", "synchronousDrag"] + } + + QtQuick.MouseArea { + bannedProperties: ["propagateComposedEvents", "preventStealing", "cursorShape", + "scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"] + } + + QtQuick.Image { + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["mirror", "mipmap", "cache", "autoTransform", "asynchronous", + "sourceSize", "smooth"] + } + + QtQuick.Text { + allowedProperties: ["rotation", "scale", "transformOrigin"] + bannedProperties: ["elide", "lineHeight", "lineHeightMode", "wrapMode", "style", + "styleColor", "minimumPointSize", "minimumPixelSize", "styleColor", + "fontSizeMode", "renderType", "textFormat", "maximumLineCount"] + } + + //Padding is not an actual item, but rather set of properties in Text + Padding { + bannedProperties: ["bottomPadding", "topPadding", "leftPadding", "rightPadding"] + } + + QtQuick.Column { + bannedProperties: ["layoutDirection"] + } + + QtQuick.Row { + bannedProperties: ["layoutDirection"] + } + + QtQuick.ListView { + bannedProperties: ["cacheBuffer", "highlightRangeMode", "highlightMoveDuration", + "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", + "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", + "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"] + } + + QtQuick.Animation { + bannedProperties: ["paused"] + } + + //Quick Controls2 Items and properties: + + QtQuick.Controls.Control { + bannedProperties: ["focusPolicy", "hoverEnabled", "wheelEnabled"] + } + + QtQuick.Controls.AbstractButton { + bannedProperties: ["display", "autoExclusive"] + } + + QtQuick.Controls.ProgressBar { + bannedProperties: ["indeterminate"] + } + + QtQuick.Controls.Slider { + bannedProperties: ["live", "snapMode", "touchDragThreshold"] + } +} diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index d1c96d9410b..11be30c80e1 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -30,6 +30,7 @@ add_qtc_plugin(QmlDesigner settingspage.cpp settingspage.h settingspage.ui shortcutmanager.cpp shortcutmanager.h switchsplittabwidget.cpp switchsplittabwidget.h + designermcumanager.cpp designermcumanager.h EXPLICIT_MOC components/propertyeditor/propertyeditorvalue.h components/connectioneditor/connectionviewwidget.h diff --git a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp b/src/plugins/qmldesigner/components/importmanager/importswidget.cpp index d69511acd67..283a0501150 100644 --- a/src/plugins/qmldesigner/components/importmanager/importswidget.cpp +++ b/src/plugins/qmldesigner/components/importmanager/importswidget.cpp @@ -29,6 +29,7 @@ #include #include +#include #include @@ -94,20 +95,20 @@ void ImportsWidget::setPossibleImports(QList possibleImports) Utils::sort(possibleImports, importLess); m_addImportComboBox->clear(); - const DesignDocument *designDocument = QmlDesignerPlugin::instance()->currentDesignDocument(); - const bool isQtForMCUs = designDocument && designDocument->isQtForMCUsProject(); + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); + const bool isQtForMCUs = mcuManager.isMCUProject(); QList filteredImports; - const QStringList mcuPostiveList = {"QtQuick", "QtQuick.Controls", "QtQuick.Timeline"}; - const QStringList mcuNegativeList = {"FlowView"}; + const QStringList mcuAllowedList = mcuManager.allowedImports(); + const QStringList mcuBannedList = mcuManager.bannedImports(); if (isQtForMCUs) { filteredImports = Utils::filtered(possibleImports, - [mcuPostiveList, mcuNegativeList](const Import &import) { - return (mcuPostiveList.contains(import.url()) + [mcuAllowedList, mcuBannedList](const Import &import) { + return (mcuAllowedList.contains(import.url()) || !import.url().startsWith("Qt")) - && !mcuNegativeList.contains(import.url()); + && !mcuBannedList.contains(import.url()); }); } else { filteredImports = possibleImports; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 7f09bc0b493..a01ce38fc72 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -200,52 +201,12 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) forceVisiblity = isItem; } - DesignDocument *designDocument = QmlDesignerPlugin::instance() - ->documentManager() - .currentDesignDocument(); + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); - if (designDocument && designDocument->isQtForMCUsProject()) { - const QList blockTypes = {"QtQuick.AnimatedImage", - "QtQuick.BorderImage", - "QtQuick.FocusScope", - "QtQuick.TextInput", - "QtQuick.TextEdit", - "QtQuick.Flow", - "QtQuick.Grid", - "QtQuick.GridView", - "QtQuick.PathView", - "QtQuick.Controls", - "QtQuick.Controls.BusyIndicator", - "QtQuick.Controls.ButtonGroup", - "QtQuick.Controls.CheckDelegate", - "QtQuick.Controls.Container", - "QtQuick.Controls.ComboBox", - "QtQuick.Controls.DelayButton", - "QtQuick.Controls.Frame", - "QtQuick.Controls.GroupBox", - "QtQuick.Controls.ItemDelegate", - "QtQuick.Controls.Label", - "QtQuick.Controls.Page", - "QtQuick.Controls.PageIndicator", - "QtQuick.Controls.Pane", - "QtQuick.Controls.RadioDelegate", - "QtQuick.Controls.RangeSlider", - "QtQuick.Controls.RoundButton", - "QtQuick.Controls.ScrollView", - "QtQuick.Controls.SpinBox", - "QtQuick.Controls.StackView", - "QtQuick.Controls.SwipeDelegate", - "QtQuick.Controls.SwitchDelegate", - "QtQuick.Controls.ToolBar", - "QtQuick.Controls.ToolButton", - "QtQuick.Controls.TabBar", - "QtQuick.Controls.TabButton", - "QtQuick.Controls.TextArea", - "QtQuick.Controls.TextField", - "QtQuick.Controls.ToolSeparator", - "QtQuick.Controls.Tumbler"}; + if (mcuManager.isMCUProject()) { + const QSet blockTypes = mcuManager.bannedItems(); - if (blockTypes.contains(entry.typeName())) + if (blockTypes.contains(QString::fromUtf8(entry.typeName()))) valid = false; } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 8526e8a1f51..45e56011351 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -351,8 +352,9 @@ void ItemLibraryWidget::reloadQmlSource() void ItemLibraryWidget::setupImportTagWidget() { QTC_ASSERT(m_model, return); - const DesignDocument *designDocument = QmlDesignerPlugin::instance()->currentDesignDocument(); - const bool isQtForMCUs = designDocument && designDocument->isQtForMCUsProject(); + + const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); + const bool isQtForMCUs = mcuManager.isMCUProject(); const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 56a17e3d11c..7c0b75c4e80 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -261,76 +262,12 @@ bool PropertyEditorValue::isTranslated() const return false; } -static bool itemOrImage(const QmlDesigner::NodeMetaInfo &metaInfo) +static bool isAllowedSubclassType(const QString &type, const QmlDesigner::NodeMetaInfo &metaInfo) { if (!metaInfo.isValid()) return false; - if (metaInfo.isSubclassOf("QtQuick.Image") || metaInfo.isSubclassOf("QtQuick.Text")) - return true; - - return false; -} - -static QList prepareNonMcuProperties() -{ - QList result; - - //Builtins: - const QList itemProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing", - "border", "baselineOffset", "focus", "activeFocusOnTab"}; - const QList mouseAreaProperties = {"propagateComposedEvents", "preventStealing", "cursorShape", - "scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"}; - const QList flickableProperties = {"boundsBehavior", "boundsMovement", - "flickDeceleration", "flickableDirection", - "leftMargin", "rightMargin", "bottomMargin", "topMargin", - "originX", "originY", - "pixelAligned", "pressDelay", "synchronousDrag"}; - const QList imageProperties = {"mirror", "mipmap", "cache", "autoTransform", "asynchronous", - "sourceSize", "smooth"}; - const QList textProperties = {"elide", "lineHeight", "lineHeightMode", "wrapMode", "style", - "styleColor", "minimumPointSize", "minimumPixelSize", "styleColor", - "fontSizeMode", "renderType", "textFormat", "maximumLineCount"}; - const QList paddingProperties = {"bottomPadding", "topPadding", "leftPadding", "rightPadding"}; - const QList columnRowProperties = {"layoutDirection"}; - const QList listViewProperties = {"cacheBuffer", "highlightRangeMode", "highlightMoveDuration", - "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", - "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", - "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"}; - //Animations: - const QList animationProperties = {"paused"}; - - //QtQuick.Controls: - const QList controlProperties = {"focusPolicy", "hoverEnabled", "wheelEnabled"}; - const QList abstractButtonProperties = {"display", "autoExclusive"}; - const QList buttonProperties = {"flat", "highlighted"}; - const QList dialProperties = {}; //nothing in propeditor - const QList progressBarProperties = {"indeterminate"}; - const QList radioButton = {}; //nothing in propeditor - const QList sliderProperties = {"live", "snapMode", "touchDragThreshold"}; - const QList swipeViewProperties = {}; //nothing in propeditor - const QList switchProperties = {}; //nothing in propeditor - - result.append(itemProperties); - result.append(mouseAreaProperties); - result.append(flickableProperties); - result.append(imageProperties); - result.append(textProperties); - result.append(paddingProperties); - result.append(columnRowProperties); - result.append(listViewProperties); - result.append(animationProperties); - result.append(controlProperties); - result.append(abstractButtonProperties); - result.append(buttonProperties); - result.append(dialProperties); - result.append(progressBarProperties); - result.append(radioButton); - result.append(sliderProperties); - result.append(swipeViewProperties); - result.append(switchProperties); - - return result; + return (metaInfo.isSubclassOf(type.toUtf8())); } bool PropertyEditorValue::isAvailable() const @@ -338,31 +275,38 @@ bool PropertyEditorValue::isAvailable() const if (!m_modelNode.isValid()) return true; - const QList nonMcuProperties = prepareNonMcuProperties(); + const QmlDesigner::DesignerMcuManager &mcuManager = QmlDesigner::DesignerMcuManager::instance(); - const QByteArray fontPrefix = {"font"}; - const QList nonMcuFontProperties = {"wordSpacing", "letterSpacing", "hintingPreference", - "kerning", "preferShaping", "capitalization", - "strikeout", "underline", "styleName"}; + if (mcuManager.isMCUProject()) { + const QSet nonMcuProperties = mcuManager.bannedProperties(); + const auto mcuAllowedItemProperties = mcuManager.allowedItemProperties(); + const auto mcuBannedComplexProperties = mcuManager.bannedComplexProperties(); - const QList mcuTransformProperties = {"rotation", "scale", "transformOrigin"}; + const QList list = name().split('.'); + const QByteArray pureName = list.constFirst(); + const QString pureNameStr = QString::fromUtf8(pureName); - const QList list = name().split('.'); - const QByteArray pureName = list.constFirst(); + const QByteArray ending = list.constLast(); + const QString endingStr = QString::fromUtf8(ending); - QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance() - ->documentManager() - .currentDesignDocument(); - - if (designDocument && designDocument->isQtForMCUsProject()) { - if (pureName == fontPrefix) { - if (nonMcuFontProperties.contains(list.constLast())) - return false; + //allowed item properties: + const auto itemTypes = mcuAllowedItemProperties.keys(); + for (const auto &itemType : itemTypes) { + if (isAllowedSubclassType(itemType, m_modelNode.metaInfo()) + && mcuAllowedItemProperties.value(itemType).contains(pureNameStr)) { + return true; + } } - if (nonMcuProperties.contains(pureName)) + + //banned properties: + //with prefixes: + if (mcuBannedComplexProperties.value(pureNameStr).contains(endingStr)) return false; - if (mcuTransformProperties.contains(pureName) && !itemOrImage(m_modelNode.metaInfo())) + + //general group: + if (nonMcuProperties.contains(pureNameStr)) return false; + } return true; diff --git a/src/plugins/qmldesigner/designermcumanager.cpp b/src/plugins/qmldesigner/designermcumanager.cpp new file mode 100644 index 00000000000..dccdd140840 --- /dev/null +++ b/src/plugins/qmldesigner/designermcumanager.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "designermcumanager.h" +#include "qmldesignerconstants.h" +#include "qmldesignerplugin.h" +#include "designersettings.h" +#include "designdocument.h" + +#include + +#include + +namespace QmlDesigner { + +static QString readProperty(const QString property, const QmlJS::SimpleReaderNode::Ptr &node) +{ + const QVariant propertyVar = node->property(property); + + if (!propertyVar.isNull() && propertyVar.isValid()) + return propertyVar.value(); + + return {}; +} + +static QStringList readPropertyList(const QString &property, const QmlJS::SimpleReaderNode::Ptr &node) +{ + const QVariant propertyVar = node->property(property); + + if (!propertyVar.isNull() && propertyVar.isValid()) + return propertyVar.value(); + + return {}; +} + +DesignerMcuManager &DesignerMcuManager::instance() +{ + static DesignerMcuManager instance; + + return instance; +} + +QString DesignerMcuManager::mcuResourcesPath() +{ + return Core::ICore::resourcePath() + QStringLiteral("/qmldesigner/qt4mcu"); +} + +bool DesignerMcuManager::isMCUProject() const +{ + QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance() + ->documentManager().currentDesignDocument(); + if (designDocument) + return designDocument->isQtForMCUsProject(); + + return false; +} + +void DesignerMcuManager::readMetadata() +{ + const QString mainMetadataFileName = "metadata.qml"; + + m_defaultVersion = {}; + m_versionsList.clear(); + + QmlJS::SimpleReader reader; + const QmlJS::SimpleReaderNode::Ptr metadata = + reader.readFile(mcuResourcesPath() + "/" + mainMetadataFileName); + if (!metadata) { + qWarning() << "Designer MCU metadata:" << reader.errors(); + return; + } + + const QmlJS::SimpleReaderNode::List versions = metadata->children(); + + if (versions.isEmpty()) { + qWarning() << "Designer MCU metadata: metadata list is empty"; + return; + } + + const QVariant defaultVersion = metadata->property("defaultVersion"); + if (!defaultVersion.isNull() && defaultVersion.isValid()) { + for (const auto& version : versions) { + Version newVersion; + + const QVariant vId = version->property("id"); + if (vId.isNull() || !vId.isValid()) + continue; + + const QVariant vName = version->property("name"); + if (!vName.isNull() && vName.isValid()) + newVersion.name = vName.value(); + else + continue; + + const QVariant vPath = version->property("path"); + if (!vPath.isNull() && vPath.isValid()) + newVersion.fileName = vPath.value(); + else + continue; + + m_versionsList.push_back(newVersion); + + if (vId == defaultVersion) + m_defaultVersion = newVersion; + } + } +} + +void DesignerMcuManager::readVersionData(const DesignerMcuManager::Version &version) +{ + m_currentVersion = {}; + m_bannedItems.clear(); + m_allowedImports.clear(); + m_bannedImports.clear(); + m_bannedProperties.clear(); + m_allowedItemProperties.clear(); + m_bannedComplexProperties.clear(); + + QmlJS::SimpleReader reader; + const QmlJS::SimpleReaderNode::Ptr versionData = + reader.readFile(mcuResourcesPath() + "/" + version.fileName); + if (!versionData) { + qWarning() << "Designer MCU metadata:" << reader.errors(); + return; + } + + const QmlJS::SimpleReaderNode::List info = versionData->children(); + + if (info.isEmpty()) { + qWarning() << "Designer MCU metadata: metadata list is empty"; + return; + } + + for (const auto& child : info) { + //handling specific item types: + if (child->name() == "ComplexProperty") { + if (child->propertyNames().contains("prefix") + && child->propertyNames().contains("bannedProperties")) { + const QString complexPropPrefix(readProperty("prefix", child)); + const QStringList complexPropBans(readPropertyList("bannedProperties", child)); + + if (!complexPropPrefix.isEmpty() && !complexPropBans.isEmpty()) + m_bannedComplexProperties.insert(complexPropPrefix, complexPropBans); + } + + continue; + } + + //handling allowed properties: + if (child->propertyNames().contains("allowedProperties")) { + const QStringList allowedProperties(readPropertyList("allowedProperties", child)); + + if (!allowedProperties.isEmpty()) + m_allowedItemProperties.insert(child->name(), allowedProperties); + } + + //handling banned properties: + const QStringList bannedProperties = readPropertyList("bannedProperties", child); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + m_bannedProperties.unite(QSet(bannedProperties.begin(), bannedProperties.end())); +#elif + m_bannedProperties.unite(QSet::fromList(bannedProperties)); +#endif + + } + + const QList bannedItems = readPropertyList("bannedItems", versionData); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + m_bannedItems = QSet(bannedItems.begin(), bannedItems.end()); +#elif + m_bannedItems = QSet::fromList(bannedItems); +#endif + + m_allowedImports = readPropertyList("allowedImports", versionData); + m_bannedImports = readPropertyList("bannedImports", versionData); + m_currentVersion = version; +} + +DesignerMcuManager::Version DesignerMcuManager::currentVersion() const +{ + return m_currentVersion; +} + +DesignerMcuManager::Version DesignerMcuManager::defaultVersion() const +{ + return m_defaultVersion; +} + +DesignerMcuManager::VersionsList DesignerMcuManager::versions() const +{ + return m_versionsList; +} + +QSet DesignerMcuManager::bannedItems() const +{ + return m_bannedItems; +} + +QSet DesignerMcuManager::bannedProperties() const +{ + return m_bannedProperties; +} + +QStringList DesignerMcuManager::allowedImports() const +{ + return m_allowedImports; +} + +QStringList DesignerMcuManager::bannedImports() const +{ + return m_bannedImports; +} + +QHash DesignerMcuManager::allowedItemProperties() const +{ + return m_allowedItemProperties; +} + +QHash DesignerMcuManager::bannedComplexProperties() const +{ + return m_bannedComplexProperties; +} + +DesignerMcuManager::DesignerMcuManager() +{ + readMetadata(); + + readVersionData(m_defaultVersion); +} + +DesignerMcuManager::~DesignerMcuManager() +{ + +} + +} // QmlDesigner diff --git a/src/plugins/qmldesigner/designermcumanager.h b/src/plugins/qmldesigner/designermcumanager.h new file mode 100644 index 00000000000..63b5e54ff87 --- /dev/null +++ b/src/plugins/qmldesigner/designermcumanager.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include +#include + +namespace QmlDesigner { + +class DesignerMcuManager +{ +public: + struct Version { + QString name; + QString fileName; + }; + using VersionsList = QList; + + static DesignerMcuManager& instance(); + + static QString mcuResourcesPath(); + + bool isMCUProject() const; + + void readMetadata(); + void readVersionData(const DesignerMcuManager::Version &version); + + DesignerMcuManager::Version currentVersion() const; + DesignerMcuManager::Version defaultVersion() const; + DesignerMcuManager::VersionsList versions() const; + + QSet bannedItems() const; + QSet bannedProperties() const; + + QStringList allowedImports() const; + QStringList bannedImports() const; + + QHash allowedItemProperties() const; + QHash bannedComplexProperties() const; + + DesignerMcuManager(DesignerMcuManager const&) = delete; + void operator=(DesignerMcuManager const&) = delete; + +private: + DesignerMcuManager(); + ~DesignerMcuManager(); + +private: + DesignerMcuManager::Version m_currentVersion; + DesignerMcuManager::Version m_defaultVersion; + + QSet m_bannedItems; + QSet m_bannedProperties; + QStringList m_allowedImports; + QStringList m_bannedImports; + QHash m_allowedItemProperties; + QHash m_bannedComplexProperties; + + DesignerMcuManager::VersionsList m_versionsList; + +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pri b/src/plugins/qmldesigner/qmldesignerplugin.pri index 9eba4c9a811..8c99395c58d 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pri +++ b/src/plugins/qmldesigner/qmldesignerplugin.pri @@ -10,7 +10,8 @@ HEADERS += $$PWD/qmldesignerconstants.h \ $$PWD/documentmanager.h \ $$PWD/documentwarningwidget.h \ $$PWD/qmldesignericons.h \ - $$PWD/openuiqmlfiledialog.h + $$PWD/openuiqmlfiledialog.h \ + $$PWD/designermcumanager.h SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/shortcutmanager.cpp \ @@ -22,7 +23,8 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \ $$PWD/designmodecontext.cpp \ $$PWD/documentmanager.cpp \ $$PWD/documentwarningwidget.cpp \ - $$PWD/openuiqmlfiledialog.cpp + $$PWD/openuiqmlfiledialog.cpp \ + $$PWD/designermcumanager.cpp FORMS += $$PWD/settingspage.ui \ $$PWD/openuiqmlfiledialog.ui diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index f95f853c7d6..ea57599bd08 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -928,6 +928,8 @@ Project { "settingspage.ui", "shortcutmanager.cpp", "shortcutmanager.h", + "designermcumanager.cpp", + "designermcumanager.h", ] } }