forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -914,16 +914,30 @@ static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &pat
|
||||
usedImportsSet.insert(i.info.path());
|
||||
|
||||
QList<QmlDesigner::Import> possibleImports;
|
||||
const QStringList qmlList("*.qml");
|
||||
const QStringList qmldirList("qmldir");
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user