QmlDesigner: Add import difference

In some cases we want to use only a sub set of imports. In that case we
compute the differences on demand. To compute the differences the
imports have to be sorted.

Task-number: QDS-9542
Change-Id: I8b3e501b7657522317847b0b788cd3ff5b47b003
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2023-04-19 14:33:07 +02:00
parent 9817df63fb
commit ece03f55ac
9 changed files with 81 additions and 36 deletions

View File

@@ -920,19 +920,23 @@ void Edit3DView::addQuick3DImport()
{
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
if (document && !document->inFileComponentModelActive() && model()) {
const Imports imports = model()->possibleImports();
for (const auto &import : imports) {
if (import.url() == "QtQuick3D") {
if (!import.version().isEmpty() && import.majorVersion() >= 6) {
// Prefer empty version number in Qt6 and beyond
model()->changeImports({Import::createLibraryImport(
import.url(), {}, import.alias(),
import.importPaths())}, {});
} else {
model()->changeImports({import}, {});
}
return;
Import qtQuick3DImport;
differenceCall(model()->possibleImports(), model()->imports(), [&](const auto &import) {
if (import.url() == "QtQuick3D")
qtQuick3DImport = import;
});
if (!qtQuick3DImport.isEmpty()) {
if (!qtQuick3DImport.version().isEmpty() && qtQuick3DImport.majorVersion() >= 6) {
// Prefer empty version number in Qt6 and beyond
model()->changeImports({Import::createLibraryImport(qtQuick3DImport.url(),
{},
qtQuick3DImport.alias(),
qtQuick3DImport.importPaths())},
{});
} else {
model()->changeImports({qtQuick3DImport}, {});
}
return;
}
}
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),

View File

@@ -62,7 +62,7 @@ void ItemLibraryView::modelAttached(Model *model)
m_widget->setModel(model);
updateImports();
if (model)
m_widget->updatePossibleImports(model->possibleImports());
m_widget->updatePossibleImports(difference(model->possibleImports(), model->imports()));
m_hasErrors = !rewriterView()->errors().isEmpty();
m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView());
}

View File

@@ -368,7 +368,7 @@ void ItemLibraryWidget::handlePriorityImportsChanged()
{
if (!m_itemLibraryInfo.isNull()) {
m_addModuleModel->setPriorityImports(m_itemLibraryInfo->priorityImports());
m_addModuleModel->update(m_model->possibleImports());
m_addModuleModel->update(difference(m_model->possibleImports(), m_model->imports()));
}
}

View File

@@ -901,7 +901,8 @@ void NavigatorTreeModel::addImport(const QString &importName)
{
Import import = Import::createLibraryImport(importName);
if (!m_view->model()->hasImport(import, true, true)) {
const Imports possImports = m_view->model()->possibleImports();
const Imports possImports = difference(m_view->model()->possibleImports(),
m_view->model()->imports());
for (const auto &possImport : possImports) {
if (possImport.url() == import.url()) {
import = possImport;

View File

@@ -3,6 +3,8 @@
#pragma once
#include <utils/set_algorithm.h>
#include <QString>
#include <QStringList>
#include <QMetaType>
@@ -26,16 +28,15 @@ public:
bool hasVersion() const { return !m_version.isEmpty(); }
bool hasAlias() const { return !m_alias.isEmpty(); }
QString url() const { return m_url; }
QString file() const { return m_file; }
QString version() const { return m_version; }
QString alias() const { return m_alias; }
QStringList importPaths() const { return m_importPathList; }
const QString &url() const { return m_url; }
const QString &file() const { return m_file; }
const QString &version() const { return m_version; }
const QString &alias() const { return m_alias; }
const QStringList &importPaths() const { return m_importPathList; }
QString toString(bool skipAlias = false, bool skipVersion = false) const;
QString toImportString() const;
bool operator==(const Import &other) const;
bool isSameModule(const Import &other) const;
int majorVersion() const;
@@ -43,6 +44,18 @@ public:
static int majorFromVersion(const QString &version);
static int minorFromVersion(const QString &version);
friend bool operator==(const Import &first, const Import &second)
{
return first.m_url == second.m_url && first.m_file == second.m_file
&& (first.m_version == second.m_version || first.m_version.isEmpty()
|| second.m_version.isEmpty());
}
friend bool operator<(const Import &first, const Import &second)
{
return std::tie(first.m_url, first.m_file) < std::tie(second.m_url, second.m_file);
}
private:
Import(const QString &url, const QString &file, const QString &version, const QString &alias, const QStringList &importPaths);
@@ -58,6 +71,21 @@ QMLDESIGNERCORE_EXPORT size_t qHash(const Import &import);
using Imports = QList<Import>;
QMLDESIGNERCORE_EXPORT Imports difference(const Imports &first, const Imports &second);
template<typename Callable>
void differenceCall(const Imports &first, const Imports &second, Callable callable)
{
Imports difference;
difference.reserve(first.size());
std::set_difference(first.begin(),
first.end(),
second.begin(),
second.end(),
Utils::make_iterator(callable));
}
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::Import)

View File

@@ -119,8 +119,8 @@ public:
const Imports &possibleImports() const;
const Imports &usedImports() const;
void changeImports(const Imports &importsToBeAdded, const Imports &importsToBeRemoved);
void setPossibleImports(const Imports &possibleImports);
void setUsedImports(const Imports &usedImports);
void setPossibleImports(Imports possibleImports);
void setUsedImports(Imports usedImports);
bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const;
bool isImportPossible(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const;
QString pathForImport(const Import &import);

View File

@@ -62,11 +62,6 @@ QString Import::toString(bool skipAlias, bool skipVersion) const
return result;
}
bool Import::operator==(const Import &other) const
{
return url() == other.url() && file() == other.file() && (version() == other.version() || version().isEmpty() || other.version().isEmpty());
}
bool Import::isSameModule(const Import &other) const
{
if (isLibraryImport())
@@ -107,4 +102,17 @@ size_t qHash(const Import &import)
return ::qHash(import.url()) ^ ::qHash(import.file()) ^ ::qHash(import.version()) ^ ::qHash(import.alias());
}
Imports difference(const Imports &first, const Imports &second)
{
Imports difference;
difference.reserve(first.size());
std::set_difference(first.begin(),
first.end(),
second.begin(),
second.end(),
std::back_inserter(difference));
return difference;
}
} // namespace QmlDesigner

View File

@@ -127,6 +127,8 @@ void ModelPrivate::changeImports(const Imports &toBeAddedImportList,
}
}
std::sort(m_imports.begin(), m_imports.end());
if (!removedImportList.isEmpty() || !addedImportList.isEmpty())
notifyImportsChanged(addedImportList, removedImportList);
}
@@ -1419,19 +1421,23 @@ void Model::changeImports(const Imports &importsToBeAdded, const Imports &import
d->changeImports(importsToBeAdded, importsToBeRemoved);
}
void Model::setPossibleImports(const Imports &possibleImports)
void Model::setPossibleImports(Imports possibleImports)
{
std::sort(possibleImports.begin(), possibleImports.end());
if (d->m_possibleImportList != possibleImports) {
d->m_possibleImportList = possibleImports;
d->notifyPossibleImportsChanged(possibleImports);
d->m_possibleImportList = std::move(possibleImports);
d->notifyPossibleImportsChanged(d->m_possibleImportList);
}
}
void Model::setUsedImports(const Imports &usedImports)
void Model::setUsedImports(Imports usedImports)
{
std::sort(usedImports.begin(), usedImports.end());
if (d->m_usedImportList != usedImports) {
d->m_usedImportList = usedImports;
d->notifyUsedImportsChanged(usedImports);
d->m_usedImportList = std::move(usedImports);
d->notifyUsedImportsChanged(d->m_usedImportList);
}
}

View File

@@ -203,8 +203,6 @@ public:
// Imports:
const Imports &imports() const { return m_imports; }
void addImport(const Import &import);
void removeImport(const Import &import);
void changeImports(const Imports &importsToBeAdded, const Imports &importToBeRemoved);
void notifyImportsChanged(const Imports &addedImports, const Imports &removedImports);
void notifyPossibleImportsChanged(const Imports &possibleImports);