diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-10-12 17:15:50 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-10-26 14:26:10 +0000 |
commit | a393bcec38f5972724c01c15c682804981109cf8 (patch) | |
tree | 77f50435acad344a5edef8f3dc7fe0613d9eb484 | |
parent | 74e29eaa26c56b0cb3c70bf5de8a23c571c2a174 (diff) |
QmlDesigner: Recognize subfolders as modules at any depth
Fixes: QDS-4787
Change-Id: If4e474ba0bc5f23e8a3cbf7bc6b5c7715fe467dd
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io>
3 files changed, 46 insertions, 15 deletions
diff --git a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h index f1b694c688..66e93abda3 100644 --- a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h +++ b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h @@ -36,6 +36,7 @@ #include <QMultiHash> #include <QPointer> #include <QFileInfo> +#include <QDir> namespace QmlDesigner { @@ -69,6 +70,7 @@ private: // functions void parseQuick3DAssetsDir(const QString &quick3DAssetsPath); void parseQuick3DAssetsItem(const QString &importUrl, const QString &quick3DAssetsPath = {}); QStringList quick3DAssetPaths() const; + TypeName resolveDirQualifier(const QString &dirPath) const; private: // variables QFileSystemWatcher m_watcher; @@ -76,6 +78,7 @@ private: // variables // key: canonical directory path QMultiHash<QString,QString> m_dirToQualifier; QUrl m_filePath; + QDir m_filePathDir; QPointer<Model> m_model; }; diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index 7466604d05..bb4e202c86 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -134,8 +134,11 @@ void SubComponentManager::parseDirectories() if (dirInfo.exists() && dirInfo.isDir()) parseDirectory(canonicalPath); - foreach (const QString &subDir, QDir(QFileInfo(file).path()).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot)) { - parseDirectory(canonicalPath + QLatin1Char('/') + subDir, true, subDir.toUtf8()); + const QStringList subDirs = QDir(QFileInfo(file).path()).entryList(QDir::Dirs | QDir::NoDot + | QDir::NoDotDot); + for (const QString &subDir : subDirs) { + const QString canSubPath = canonicalPath + QLatin1Char('/') + subDir; + parseDirectory(canSubPath, true, resolveDirQualifier(canSubPath)); } } @@ -146,8 +149,10 @@ void SubComponentManager::parseDirectories() foreach (const Import &import, m_imports) { if (import.isFileImport()) { QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile()); - if (dirInfo.exists() && dirInfo.isDir()) - parseDirectory(dirInfo.canonicalFilePath(), true, dirInfo.baseName().toUtf8()); + if (dirInfo.exists() && dirInfo.isDir()) { + const QString canPath = dirInfo.canonicalFilePath(); + parseDirectory(canPath, true, resolveDirQualifier(canPath)); + } } else { QString url = import.url(); url.replace(QLatin1Char('.'), QLatin1Char('/')); @@ -445,6 +450,11 @@ QStringList SubComponentManager::quick3DAssetPaths() const return retPaths; } +TypeName SubComponentManager::resolveDirQualifier(const QString &dirPath) const +{ + return m_filePathDir.relativeFilePath(dirPath).toUtf8(); +} + /*! \class SubComponentManager @@ -472,10 +482,12 @@ void SubComponentManager::update(const QUrl &filePath, const QList<Import> &impo if (!m_filePath.isEmpty()) { const QString file = m_filePath.toLocalFile(); oldDir = QFileInfo(QFileInfo(file).path()); + m_filePathDir = {}; } if (!filePath.isEmpty()) { const QString file = filePath.toLocalFile(); newDir = QFileInfo(QFileInfo(file).path()); + m_filePathDir = {newDir.absoluteFilePath()}; } m_filePath = filePath; @@ -538,8 +550,10 @@ void SubComponentManager::updateImport(const Import &import) if (import.isFileImport()) { QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile()); - if (dirInfo.exists() && dirInfo.isDir()) - parseDirectory(dirInfo.canonicalFilePath(), true, dirInfo.baseName().toUtf8()); + if (dirInfo.exists() && dirInfo.isDir()) { + const QString canPath = dirInfo.canonicalFilePath(); + parseDirectory(canPath, true, resolveDirQualifier(canPath)); + } } else { QString url = import.url(); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 3c2ad6fc84..3f6a04fde4 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -914,16 +914,30 @@ static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &pat usedImportsSet.insert(i.info.path()); QList<QmlDesigner::Import> possibleImports; - - foreach (const QString &subDir, QDir(path).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot)) { - QDir dir(path + "/" + subDir); - if (!dir.entryInfoList(QStringList("*.qml"), QDir::Files).isEmpty() - && dir.entryInfoList(QStringList("qmldir"), QDir::Files).isEmpty() - && !usedImportsSet.contains(dir.path())) { - QmlDesigner::Import import = QmlDesigner::Import::createFileImport(subDir); - possibleImports.append(import); + const QStringList qmlList("*.qml"); + const QStringList qmldirList("qmldir"); + + QStringList fileImportPaths; + const QChar delimeter('/'); + + std::function<void(const QString &)> checkDir; + checkDir = [&](const QString &checkPath) { + const QStringList entries = QDir(checkPath).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot); + const QString checkPathDelim = checkPath + delimeter; + for (const QString &entry : entries) { + QDir dir(checkPathDelim + entry); + const QString dirPath = dir.path(); + if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty() + && dir.entryInfoList(qmldirList, QDir::Files).isEmpty() + && !usedImportsSet.contains(dirPath)) { + const QString importName = dir.path().mid(path.size() + 1); + QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName); + possibleImports.append(import); + } + checkDir(dirPath); } - } + }; + checkDir(path); return possibleImports; } |