diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp index 377662b032b..4c89d339353 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp @@ -40,6 +40,7 @@ ItemLibraryAddImportModel::ItemLibraryAddImportModel(QObject *parent) // add role names m_roleNames.insert(Qt::UserRole + 1, "importUrl"); m_roleNames.insert(Qt::UserRole + 2, "importVisible"); + m_roleNames.insert(Qt::UserRole + 3, "isSeparator"); } ItemLibraryAddImportModel::~ItemLibraryAddImportModel() @@ -63,7 +64,10 @@ QVariant ItemLibraryAddImportModel::data(const QModelIndex &index, int role) con return importUrl; if (m_roleNames[role] == "importVisible") - return m_searchText.isEmpty() || m_importFilterList.contains(importUrl); + return m_searchText.isEmpty() || importUrl.isEmpty() || m_importFilterList.contains(importUrl); + + if (m_roleNames[role] == "isSeparator") + return importUrl.isEmpty(); qWarning() << Q_FUNC_INFO << "invalid role requested"; @@ -83,9 +87,9 @@ void ItemLibraryAddImportModel::update(const QList &possibleImports) const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); const bool isQtForMCUs = mcuManager.isMCUProject(); QList filteredImports; - const QStringList mcuAllowedList = mcuManager.allowedImports(); - const QStringList mcuBannedList = mcuManager.bannedImports(); if (isQtForMCUs) { + const QStringList mcuAllowedList = mcuManager.allowedImports(); + const QStringList mcuBannedList = mcuManager.bannedImports(); filteredImports = Utils::filtered(possibleImports, [&](const Import &import) { return (mcuAllowedList.contains(import.url()) @@ -96,7 +100,7 @@ void ItemLibraryAddImportModel::update(const QList &possibleImports) filteredImports = possibleImports; } - Utils::sort(filteredImports, [](const Import &firstImport, const Import &secondImport) { + Utils::sort(filteredImports, [this](const Import &firstImport, const Import &secondImport) { if (firstImport.url() == secondImport.url()) return firstImport.toString() < secondImport.toString(); @@ -106,6 +110,10 @@ void ItemLibraryAddImportModel::update(const QList &possibleImports) if (secondImport.url() == "QtQuick") return false; + const bool firstPriority = m_priorityImports.contains(firstImport.url()); + if (firstPriority != m_priorityImports.contains(secondImport.url())) + return firstPriority; + if (firstImport.isLibraryImport() && secondImport.isFileImport()) return false; @@ -122,9 +130,15 @@ void ItemLibraryAddImportModel::update(const QList &possibleImports) }); // create import sections + bool previousIsPriority = false; for (const Import &import : std::as_const(filteredImports)) { - if (import.isLibraryImport()) + if (import.isLibraryImport()) { + bool currentIsPriority = m_priorityImports.contains(import.url()); + if (previousIsPriority && !currentIsPriority) + m_importList.append(Import::empty()); // empty import acts as a separator m_importList.append(import); + previousIsPriority = currentIsPriority; + } } endResetModel(); @@ -153,4 +167,9 @@ Import ItemLibraryAddImportModel::getImportAt(int index) const return m_importList.at(index); } +void ItemLibraryAddImportModel::setPriorityImports(const QSet &priorityImports) +{ + m_priorityImports = priorityImports; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h index bab5ecf73c5..3ed6b3f3b5e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h @@ -50,11 +50,14 @@ public: void setSearchText(const QString &searchText); Import getImportAt(int index) const; + void setPriorityImports(const QSet &priorityImports); + private: QString m_searchText; QList m_importList; QSet m_importFilterList; QHash m_roleNames; + QSet m_priorityImports; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 9fdef025483..1eb8813bda0 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -229,11 +229,16 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) if (m_itemLibraryInfo) { disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, this, &ItemLibraryWidget::delayedUpdateModel); + disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged, + this, &ItemLibraryWidget::handlePriorityImportsChanged); } m_itemLibraryInfo = itemLibraryInfo; if (itemLibraryInfo) { connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, this, &ItemLibraryWidget::delayedUpdateModel); + connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged, + this, &ItemLibraryWidget::handlePriorityImportsChanged); + m_itemLibraryAddImportModel->setPriorityImports(m_itemLibraryInfo->priorityImports()); } delayedUpdateModel(); } @@ -365,6 +370,14 @@ void ItemLibraryWidget::updateSearch() } } +void ItemLibraryWidget::handlePriorityImportsChanged() +{ + if (!m_itemLibraryInfo.isNull()) { + m_itemLibraryAddImportModel->setPriorityImports(m_itemLibraryInfo->priorityImports()); + m_itemLibraryAddImportModel->update(m_model->possibleImports()); + } +} + void ItemLibraryWidget::setResourcePath(const QString &resourcePath) { if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 5bde054fc9b..66d95d0cd4b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -102,6 +102,7 @@ private: void addResources(const QStringList &files); void importDroppedFiles(const QList &files); void updateSearch(); + void handlePriorityImportsChanged(); QTimer m_compressionTimer; QSize m_itemIconSize; diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml index 60712394abd..e73623bd7ee 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/addimport.qml @@ -57,9 +57,11 @@ Column { delegate: Rectangle { width: listView.width - height: 25 - color: mouseArea.containsMouse ? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3) - : Theme.qmlDesignerButtonColor() + height: isSeparator ? 4 : 25 + color: isSeparator ? Theme.color(Theme.BackgroundColorNormal) + : mouseArea.containsMouse + ? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3) + : Theme.qmlDesignerButtonColor() visible: importVisible Text { @@ -77,6 +79,7 @@ Column { anchors.fill: parent hoverEnabled: true onClicked: addImport(index) + enabled: !isSeparator } } } diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h index e7d0c3e2927..b31b3d916c3 100644 --- a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h +++ b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h @@ -29,6 +29,7 @@ #include "propertycontainer.h" #include +#include #include namespace QmlDesigner { @@ -108,11 +109,14 @@ public: void clearEntries(); QStringList blacklistImports() const; + QSet priorityImports() const; void addBlacklistImports(const QStringList &list); + void addPriorityImports(const QSet &set); signals: void entriesChanged(); + void priorityImportsChanged(); private: // functions ItemLibraryInfo(QObject *parent = nullptr); @@ -123,6 +127,7 @@ private: // variables QPointer m_baseInfo; QStringList m_blacklistImports; + QSet m_priorityImports; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp index 4fc5e7c0887..5bdb5530f60 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp @@ -344,11 +344,27 @@ QStringList ItemLibraryInfo::blacklistImports() const return list; } +QSet ItemLibraryInfo::priorityImports() const +{ + QSet set = m_priorityImports; + if (m_baseInfo) + set.unite(m_baseInfo->m_priorityImports); + return set; +} + void ItemLibraryInfo::addBlacklistImports(const QStringList &list) { m_blacklistImports.append(list); } +void ItemLibraryInfo::addPriorityImports(const QSet &set) +{ + if (!set.isEmpty()) { + m_priorityImports.unite(set); + emit priorityImportsChanged(); + } +} + void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo) { m_baseInfo = baseInfo; diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp index 83d826ad9ac..7c4e1130725 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp @@ -230,8 +230,10 @@ void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &va if (name == "blacklistImports" && !values.isEmpty()) { m_metaInfo.itemLibraryInfo()->addBlacklistImports(values); - } else if (name == "showTagsForImports" && !values.isEmpty()) { - // Flow tags removed, but keeping this for now to avoid errors parsing old metadata files + } else if ((name == "priorityImports" || name == "showTagsForImports") && !values.isEmpty()) { + // Flow tags are no longer shown, but the old property is still supported for prioritizing + // imports to keep compatibility with old metainfo files. + m_metaInfo.itemLibraryInfo()->addPriorityImports(values.toSet()); } else { addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation()); setParserState(Error);