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
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<Import> &possibleImports)
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
const bool isQtForMCUs = mcuManager.isMCUProject();
QList<Import> filteredImports;
if (isQtForMCUs) {
const QStringList mcuAllowedList = mcuManager.allowedImports();
const QStringList mcuBannedList = mcuManager.bannedImports();
if (isQtForMCUs) {
filteredImports = Utils::filtered(possibleImports,
[&](const Import &import) {
return (mcuAllowedList.contains(import.url())
@@ -96,7 +100,7 @@ void ItemLibraryAddImportModel::update(const QList<Import> &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<Import> &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<Import> &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<QString> &priorityImports)
{
m_priorityImports = priorityImports;
}
} // namespace QmlDesigner

View File

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

View File

@@ -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()) {

View File

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

View File

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

View File

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

View File

@@ -344,11 +344,27 @@ QStringList ItemLibraryInfo::blacklistImports() const
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)
{
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)
{
m_baseInfo = baseInfo;

View File

@@ -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);