QmlDesigner: Sort previously flow-tagged imports to top of the list

Allow prioritizing certain modules in the possible imports list.
The obsolete "showTagsForImports" metainfo property was repurposed for
this to keep compatibility with old metainfos. A new metainfo property
"priorityImports" does the same thing.

Fixes: QDS-3801
Change-Id: I96aafcb8e6d10117e29203f55f60e73843b3aae5
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2021-03-01 16:32:41 +02:00
parent a1561d97e9
commit ee07604f79
8 changed files with 72 additions and 10 deletions

View File

@@ -40,6 +40,7 @@ ItemLibraryAddImportModel::ItemLibraryAddImportModel(QObject *parent)
// add role names // add role names
m_roleNames.insert(Qt::UserRole + 1, "importUrl"); m_roleNames.insert(Qt::UserRole + 1, "importUrl");
m_roleNames.insert(Qt::UserRole + 2, "importVisible"); m_roleNames.insert(Qt::UserRole + 2, "importVisible");
m_roleNames.insert(Qt::UserRole + 3, "isSeparator");
} }
ItemLibraryAddImportModel::~ItemLibraryAddImportModel() ItemLibraryAddImportModel::~ItemLibraryAddImportModel()
@@ -63,7 +64,10 @@ QVariant ItemLibraryAddImportModel::data(const QModelIndex &index, int role) con
return importUrl; return importUrl;
if (m_roleNames[role] == "importVisible") 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"; qWarning() << Q_FUNC_INFO << "invalid role requested";
@@ -83,9 +87,9 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
const bool isQtForMCUs = mcuManager.isMCUProject(); const bool isQtForMCUs = mcuManager.isMCUProject();
QList<Import> filteredImports; QList<Import> filteredImports;
if (isQtForMCUs) {
const QStringList mcuAllowedList = mcuManager.allowedImports(); const QStringList mcuAllowedList = mcuManager.allowedImports();
const QStringList mcuBannedList = mcuManager.bannedImports(); const QStringList mcuBannedList = mcuManager.bannedImports();
if (isQtForMCUs) {
filteredImports = Utils::filtered(possibleImports, filteredImports = Utils::filtered(possibleImports,
[&](const Import &import) { [&](const Import &import) {
return (mcuAllowedList.contains(import.url()) return (mcuAllowedList.contains(import.url())
@@ -96,7 +100,7 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
filteredImports = 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()) if (firstImport.url() == secondImport.url())
return firstImport.toString() < secondImport.toString(); return firstImport.toString() < secondImport.toString();
@@ -106,6 +110,10 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
if (secondImport.url() == "QtQuick") if (secondImport.url() == "QtQuick")
return false; return false;
const bool firstPriority = m_priorityImports.contains(firstImport.url());
if (firstPriority != m_priorityImports.contains(secondImport.url()))
return firstPriority;
if (firstImport.isLibraryImport() && secondImport.isFileImport()) if (firstImport.isLibraryImport() && secondImport.isFileImport())
return false; return false;
@@ -122,9 +130,15 @@ void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
}); });
// create import sections // create import sections
bool previousIsPriority = false;
for (const Import &import : std::as_const(filteredImports)) { 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); m_importList.append(import);
previousIsPriority = currentIsPriority;
}
} }
endResetModel(); endResetModel();
@@ -153,4 +167,9 @@ Import ItemLibraryAddImportModel::getImportAt(int index) const
return m_importList.at(index); return m_importList.at(index);
} }
void ItemLibraryAddImportModel::setPriorityImports(const QSet<QString> &priorityImports)
{
m_priorityImports = priorityImports;
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -50,11 +50,14 @@ public:
void setSearchText(const QString &searchText); void setSearchText(const QString &searchText);
Import getImportAt(int index) const; Import getImportAt(int index) const;
void setPriorityImports(const QSet<QString> &priorityImports);
private: private:
QString m_searchText; QString m_searchText;
QList<Import> m_importList; QList<Import> m_importList;
QSet<QString> m_importFilterList; QSet<QString> m_importFilterList;
QHash<int, QByteArray> m_roleNames; QHash<int, QByteArray> m_roleNames;
QSet<QString> m_priorityImports;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -229,11 +229,16 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
if (m_itemLibraryInfo) { if (m_itemLibraryInfo) {
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
this, &ItemLibraryWidget::delayedUpdateModel); this, &ItemLibraryWidget::delayedUpdateModel);
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged,
this, &ItemLibraryWidget::handlePriorityImportsChanged);
} }
m_itemLibraryInfo = itemLibraryInfo; m_itemLibraryInfo = itemLibraryInfo;
if (itemLibraryInfo) { if (itemLibraryInfo) {
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged, connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
this, &ItemLibraryWidget::delayedUpdateModel); this, &ItemLibraryWidget::delayedUpdateModel);
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::priorityImportsChanged,
this, &ItemLibraryWidget::handlePriorityImportsChanged);
m_itemLibraryAddImportModel->setPriorityImports(m_itemLibraryInfo->priorityImports());
} }
delayedUpdateModel(); 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) void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
{ {
if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) { if (m_resourcesView->model() == m_resourcesFileSystemModel.data()) {

View File

@@ -102,6 +102,7 @@ private:
void addResources(const QStringList &files); void addResources(const QStringList &files);
void importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files); void importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &files);
void updateSearch(); void updateSearch();
void handlePriorityImportsChanged();
QTimer m_compressionTimer; QTimer m_compressionTimer;
QSize m_itemIconSize; QSize m_itemIconSize;

View File

@@ -57,8 +57,10 @@ Column {
delegate: Rectangle { delegate: Rectangle {
width: listView.width width: listView.width
height: 25 height: isSeparator ? 4 : 25
color: mouseArea.containsMouse ? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3) color: isSeparator ? Theme.color(Theme.BackgroundColorNormal)
: mouseArea.containsMouse
? Qt.lighter(Theme.qmlDesignerButtonColor(), 1.3)
: Theme.qmlDesignerButtonColor() : Theme.qmlDesignerButtonColor()
visible: importVisible visible: importVisible
@@ -77,6 +79,7 @@ Column {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: addImport(index) onClicked: addImport(index)
enabled: !isSeparator
} }
} }
} }

View File

@@ -29,6 +29,7 @@
#include "propertycontainer.h" #include "propertycontainer.h"
#include <QPointer> #include <QPointer>
#include <QSet>
#include <memory> #include <memory>
namespace QmlDesigner { namespace QmlDesigner {
@@ -108,11 +109,14 @@ public:
void clearEntries(); void clearEntries();
QStringList blacklistImports() const; QStringList blacklistImports() const;
QSet<QString> priorityImports() const;
void addBlacklistImports(const QStringList &list); void addBlacklistImports(const QStringList &list);
void addPriorityImports(const QSet<QString> &set);
signals: signals:
void entriesChanged(); void entriesChanged();
void priorityImportsChanged();
private: // functions private: // functions
ItemLibraryInfo(QObject *parent = nullptr); ItemLibraryInfo(QObject *parent = nullptr);
@@ -123,6 +127,7 @@ private: // variables
QPointer<ItemLibraryInfo> m_baseInfo; QPointer<ItemLibraryInfo> m_baseInfo;
QStringList m_blacklistImports; QStringList m_blacklistImports;
QSet<QString> m_priorityImports;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -344,11 +344,27 @@ QStringList ItemLibraryInfo::blacklistImports() const
return list; return list;
} }
QSet<QString> ItemLibraryInfo::priorityImports() const
{
QSet<QString> set = m_priorityImports;
if (m_baseInfo)
set.unite(m_baseInfo->m_priorityImports);
return set;
}
void ItemLibraryInfo::addBlacklistImports(const QStringList &list) void ItemLibraryInfo::addBlacklistImports(const QStringList &list)
{ {
m_blacklistImports.append(list); m_blacklistImports.append(list);
} }
void ItemLibraryInfo::addPriorityImports(const QSet<QString> &set)
{
if (!set.isEmpty()) {
m_priorityImports.unite(set);
emit priorityImportsChanged();
}
}
void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo) void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo)
{ {
m_baseInfo = baseInfo; m_baseInfo = baseInfo;

View File

@@ -230,8 +230,10 @@ void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &va
if (name == "blacklistImports" && !values.isEmpty()) { if (name == "blacklistImports" && !values.isEmpty()) {
m_metaInfo.itemLibraryInfo()->addBlacklistImports(values); m_metaInfo.itemLibraryInfo()->addBlacklistImports(values);
} else if (name == "showTagsForImports" && !values.isEmpty()) { } else if ((name == "priorityImports" || name == "showTagsForImports") && !values.isEmpty()) {
// Flow tags removed, but keeping this for now to avoid errors parsing old metadata files // 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 { } else {
addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation()); addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation());
setParserState(Error); setParserState(Error);