forked from qt-creator/qt-creator
Introduce mockImports and allow resources in the root folder
mockImports is a secial import path which is only considered by Design Studio and ignored by the cmake exporter. This prevents name clashes between qml mock modules and their c++/python counter parts. Fixes: QDS-13466 Fixes: QDS-13469 Change-Id: I64026ea9d8823f3d5e818a352ccb565fa29c1933 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -147,6 +147,7 @@ QString jsonToQmlProject(const QJsonObject &rootObject)
|
||||
appendBool("enablePythonGeneration", deploymentConfig["enablePythonGeneration"].toBool());
|
||||
appendBool("widgetApp", runConfig["widgetApp"].toBool());
|
||||
appendStringArray("importPaths", rootObject["importPaths"].toVariant().toStringList());
|
||||
appendStringArray("mockImports", rootObject["mockImports"].toVariant().toStringList());
|
||||
appendBreak();
|
||||
appendString("qdsVersion", versionConfig["designStudio"].toString());
|
||||
appendString("quickVersion", versionConfig["qtQuick"].toString());
|
||||
@@ -411,6 +412,8 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile)
|
||||
} else if (propName.contains("importpaths", Qt::CaseInsensitive)) {
|
||||
objKey = "importPaths";
|
||||
importPaths = value.toVariant().toStringList();
|
||||
} else if (propName.contains("mockImports", Qt::CaseInsensitive)) {
|
||||
objKey = "mockImports";
|
||||
} else {
|
||||
currentObj = &otherProperties;
|
||||
objKey = propName; // With prefix
|
||||
|
@@ -212,6 +212,16 @@ void QmlProjectItem::setImportPaths(const QStringList &importPaths)
|
||||
insertAndUpdateProjectFile("importPaths", QJsonArray::fromStringList(importPaths));
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::mockImports() const
|
||||
{
|
||||
return m_project["mockImports"].toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMockImports(const QStringList &paths)
|
||||
{
|
||||
insertAndUpdateProjectFile("mockImports", QJsonArray::fromStringList(paths));
|
||||
}
|
||||
|
||||
void QmlProjectItem::addImportPath(const QString &importPath)
|
||||
{
|
||||
QJsonArray importPaths = m_project["importPaths"].toArray();
|
||||
|
@@ -46,6 +46,9 @@ public:
|
||||
void setImportPaths(const QStringList &paths);
|
||||
void addImportPath(const QString &importPath);
|
||||
|
||||
QStringList mockImports() const;
|
||||
void setMockImports(const QStringList &paths);
|
||||
|
||||
QStringList qmlProjectModules() const;
|
||||
|
||||
QStringList fileSelectors() const;
|
||||
|
@@ -716,14 +716,24 @@ QStringList QmlBuildSystem::shaderToolFiles() const
|
||||
return m_projectItem->shaderToolFiles();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::allImports() const
|
||||
{
|
||||
return m_projectItem->importPaths() + m_projectItem->mockImports();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::importPaths() const
|
||||
{
|
||||
return m_projectItem->importPaths();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::mockImports() const
|
||||
{
|
||||
return m_projectItem->mockImports();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::absoluteImportPaths() const
|
||||
{
|
||||
return Utils::transform<QStringList>(m_projectItem->importPaths(), [&](const QString &importPath) {
|
||||
return Utils::transform<QStringList>(allImports(), [&](const QString &importPath) {
|
||||
Utils::FilePath filePath = Utils::FilePath::fromString(importPath);
|
||||
if (!filePath.isAbsolutePath())
|
||||
return (projectDirectory() / importPath).toString();
|
||||
|
@@ -73,7 +73,9 @@ public:
|
||||
|
||||
Utils::EnvironmentItems environment() const;
|
||||
|
||||
QStringList allImports() const;
|
||||
QStringList importPaths() const;
|
||||
QStringList mockImports() const;
|
||||
QStringList absoluteImportPaths() const;
|
||||
QStringList fileSelectors() const;
|
||||
|
||||
|
@@ -172,7 +172,7 @@ bool CMakeGenerator::checkUri(const QString& uri, const Utils::FilePath &path) c
|
||||
Utils::FilePath relative = path.relativeChildPath(m_root->dir);
|
||||
QList<QStringView> pathComponents = relative.pathView().split('/', Qt::SkipEmptyParts);
|
||||
|
||||
for (const auto& import : buildSystem()->importPaths()) {
|
||||
for (const auto& import : buildSystem()->allImports()) {
|
||||
Utils::FilePath importPath = Utils::FilePath::fromUserInput(import);
|
||||
for (const auto& component : importPath.pathView().split('/', Qt::SkipEmptyParts)) {
|
||||
if (component == pathComponents.first())
|
||||
@@ -219,9 +219,25 @@ void CMakeGenerator::createSourceFiles() const
|
||||
m_writer->writeSourceFiles(sourceNode, m_root);
|
||||
}
|
||||
|
||||
bool CMakeGenerator::isMockModule(const NodePtr &node) const
|
||||
{
|
||||
QTC_ASSERT(buildSystem(), return false);
|
||||
|
||||
Utils::FilePath dir = node->dir.parentDir();
|
||||
QString mockDir = dir.relativeChildPath(m_root->dir).path();
|
||||
for (const QString &import : buildSystem()->mockImports()) {
|
||||
if (import == mockDir)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMakeGenerator::readQmlDir(const Utils::FilePath &filePath, NodePtr &node) const
|
||||
{
|
||||
node->type = Node::Type::Module;
|
||||
if (isMockModule(node))
|
||||
node->type = Node::Type::MockModule;
|
||||
else
|
||||
node->type = Node::Type::Module;
|
||||
|
||||
QFile f(filePath.toString());
|
||||
f.open(QIODevice::ReadOnly);
|
||||
|
@@ -42,6 +42,7 @@ public:
|
||||
private:
|
||||
bool ignore(const Utils::FilePath &path) const;
|
||||
bool checkUri(const QString& uri, const Utils::FilePath &path) const;
|
||||
bool isMockModule(const NodePtr &node) const;
|
||||
|
||||
void createCMakeFiles(const NodePtr &node) const;
|
||||
void createSourceFiles() const;
|
||||
|
@@ -17,6 +17,13 @@ namespace QmlProjectManager {
|
||||
|
||||
namespace QmlProjectExporter {
|
||||
|
||||
const char TEMPLATE_RESOURCES[] = R"(
|
||||
qt6_add_resources(%1 %2
|
||||
PREFIX "%3"
|
||||
VERSION 1.0
|
||||
FILES %4
|
||||
))";
|
||||
|
||||
const char TEMPLATE_BIG_RESOURCES[] = R"(
|
||||
qt6_add_resources(%1 %2
|
||||
BIG_RESOURCES
|
||||
@@ -235,36 +242,64 @@ QString CMakeWriter::makeSetEnvironmentFn() const
|
||||
return out;
|
||||
}
|
||||
|
||||
std::tuple<QString, QString> CMakeWriter::makeResourcesBlocks(const NodePtr &node) const
|
||||
std::tuple<QString, QString> CMakeWriter::makeResourcesBlocksRoot(const NodePtr &node) const
|
||||
{
|
||||
QString resourcesOut;
|
||||
QString bigResourcesOut;
|
||||
|
||||
QString resourceFiles;
|
||||
std::vector<QString> bigResources;
|
||||
for (const Utils::FilePath &path : assets(node)) {
|
||||
if (path.fileSize() > 5000000) {
|
||||
bigResources.push_back(makeRelative(node, path));
|
||||
continue;
|
||||
}
|
||||
resourceFiles.append(QString("\t\t%1\n").arg(makeRelative(node, path)));
|
||||
QStringList res;
|
||||
QStringList bigRes;
|
||||
collectResources(node, res, bigRes);
|
||||
|
||||
if (!res.isEmpty()) {
|
||||
QString resourceContent;
|
||||
for (const QString &r : res)
|
||||
resourceContent.append(QString("\n\t\t%1").arg(r));
|
||||
|
||||
const QString resourceName = node->name + "Resource";
|
||||
resourcesOut = QString::fromUtf8(TEMPLATE_RESOURCES, -1)
|
||||
.arg("${CMAKE_PROJECT_NAME}", resourceName, "/qt/qml", resourceContent);
|
||||
}
|
||||
|
||||
if (!resourceFiles.isEmpty())
|
||||
resourcesOut.append(QString("\tRESOURCES\n%1").arg(resourceFiles));
|
||||
if (!bigRes.isEmpty()) {
|
||||
QString bigResourceContent;
|
||||
for (const QString &r : bigRes)
|
||||
bigResourceContent.append(QString("\n\t\t%1").arg(r));
|
||||
|
||||
QString templatePostfix;
|
||||
if (!bigResources.empty()) {
|
||||
const QString resourceName = node->name + "BigResource";
|
||||
bigResourcesOut = QString::fromUtf8(TEMPLATE_BIG_RESOURCES, -1)
|
||||
.arg("${CMAKE_PROJECT_NAME}", resourceName, "/qt/qml", bigResourceContent);
|
||||
}
|
||||
|
||||
return {resourcesOut, bigResourcesOut};
|
||||
}
|
||||
|
||||
std::tuple<QString, QString> CMakeWriter::makeResourcesBlocksModule(const NodePtr &node) const
|
||||
{
|
||||
QString resourcesOut;
|
||||
QString bigResourcesOut;
|
||||
|
||||
QStringList res;
|
||||
QStringList bigRes;
|
||||
collectResources(node, res, bigRes);
|
||||
|
||||
if (!res.isEmpty()) {
|
||||
resourcesOut = "\tRESOURCES\n";
|
||||
for (const QString &r : res)
|
||||
resourcesOut.append(QString("\t\t%1\n").arg(r));
|
||||
}
|
||||
|
||||
if (!bigRes.isEmpty()) {
|
||||
QString resourceContent;
|
||||
for (const QString &res : bigResources)
|
||||
resourceContent.append(QString("\n %1").arg(res));
|
||||
for (const QString &res : bigRes)
|
||||
resourceContent.append(QString("\n\t\t%1").arg(res));
|
||||
|
||||
const QString prefixPath = QString(node->uri).replace('.', '/');
|
||||
const QString prefix = "/qt/qml/" + prefixPath;
|
||||
const QString resourceName = node->name + "BigResource";
|
||||
|
||||
bigResourcesOut = QString::fromUtf8(TEMPLATE_BIG_RESOURCES, -1)
|
||||
.arg(node->name, resourceName, prefix, resourceContent);
|
||||
.arg(node->name, resourceName, prefix, resourceContent);
|
||||
}
|
||||
|
||||
return {resourcesOut, bigResourcesOut};
|
||||
@@ -278,6 +313,17 @@ void CMakeWriter::collectPlugins(const NodePtr &node, std::vector<QString> &out)
|
||||
collectPlugins(child, out);
|
||||
}
|
||||
|
||||
void CMakeWriter::collectResources(const NodePtr &node, QStringList &res, QStringList &bigRes) const
|
||||
{
|
||||
for (const Utils::FilePath &path : assets(node)) {
|
||||
if (path.fileSize() > 5000000) {
|
||||
bigRes.push_back(makeRelative(node, path));
|
||||
} else {
|
||||
res.append(makeRelative(node, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace QmlProjectExporter.
|
||||
|
||||
} // End namespace QmlProjectManager.
|
||||
|
@@ -20,6 +20,7 @@ struct Node
|
||||
Module,
|
||||
Library,
|
||||
Folder,
|
||||
MockModule
|
||||
};
|
||||
|
||||
std::shared_ptr<Node> parent = nullptr;
|
||||
@@ -63,6 +64,8 @@ public:
|
||||
static void writeFile(const Utils::FilePath &path, const QString &content);
|
||||
|
||||
CMakeWriter(CMakeGenerator *parent);
|
||||
virtual ~CMakeWriter() = default;
|
||||
|
||||
const CMakeGenerator *parent() const;
|
||||
|
||||
virtual bool isPlugin(const NodePtr &node) const;
|
||||
@@ -89,11 +92,12 @@ protected:
|
||||
QString makeSingletonBlock(const NodePtr &node) const;
|
||||
QString makeSubdirectoriesBlock(const NodePtr &node) const;
|
||||
QString makeSetEnvironmentFn() const;
|
||||
std::tuple<QString, QString> makeResourcesBlocks(const NodePtr &node) const;
|
||||
|
||||
std::tuple<QString, QString> makeResourcesBlocksRoot(const NodePtr &node) const;
|
||||
std::tuple<QString, QString> makeResourcesBlocksModule(const NodePtr &node) const;
|
||||
|
||||
private:
|
||||
void collectPlugins(const NodePtr &node, std::vector<QString> &out) const;
|
||||
void collectResources(const NodePtr &node, QStringList &res, QStringList &bigRes) const;
|
||||
const CMakeGenerator *m_parent = nullptr;
|
||||
};
|
||||
|
||||
|
@@ -106,7 +106,7 @@ void CMakeWriterV0::writeModuleCMakeFile(const NodePtr &node, const NodePtr &roo
|
||||
QString qmlModulesContent;
|
||||
qmlModulesContent.append(makeQmlFilesBlock(node));
|
||||
|
||||
auto [resources, bigResources] = makeResourcesBlocks(node);
|
||||
auto [resources, bigResources] = makeResourcesBlocksModule(node);
|
||||
qmlModulesContent.append(resources);
|
||||
|
||||
if (!qmlModulesContent.isEmpty()) {
|
||||
|
@@ -88,7 +88,17 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c
|
||||
const Utils::FilePath userFile = node->dir.pathAppended("qds.cmake");
|
||||
QString userFileContent(DO_NOT_EDIT_FILE);
|
||||
userFileContent.append(makeSubdirectoriesBlock(node));
|
||||
userFileContent.append("\n");
|
||||
|
||||
auto [resources, bigResources] = makeResourcesBlocksRoot(node);
|
||||
if (!resources.isEmpty()) {
|
||||
userFileContent.append(resources);
|
||||
userFileContent.append("\n");
|
||||
}
|
||||
|
||||
if (!bigResources.isEmpty()) {
|
||||
userFileContent.append(bigResources);
|
||||
userFileContent.append("\n");
|
||||
}
|
||||
|
||||
QString pluginNames;
|
||||
std::vector<QString> plugs = plugins(node);
|
||||
@@ -102,6 +112,7 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c
|
||||
"target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE\n"
|
||||
"%1)");
|
||||
|
||||
userFileContent.append("\n");
|
||||
userFileContent.append(linkLibrariesTemplate.arg(pluginNames));
|
||||
writeFile(userFile, userFileContent);
|
||||
return;
|
||||
@@ -119,7 +130,7 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c
|
||||
prefix.append(makeSubdirectoriesBlock(node));
|
||||
prefix.append(makeSingletonBlock(node));
|
||||
|
||||
auto [resources, bigResources] = makeResourcesBlocks(node);
|
||||
auto [resources, bigResources] = makeResourcesBlocksModule(node);
|
||||
QString moduleContent;
|
||||
moduleContent.append(makeQmlFilesBlock(node));
|
||||
moduleContent.append(resources);
|
||||
|
@@ -33,7 +33,7 @@ bool isAssetFile(const Utils::FilePath &path)
|
||||
{
|
||||
static const QStringList suffixes = {
|
||||
"js", "ts", "json", "hints", "mesh", "qad", "qsb", "frag",
|
||||
"frag.qsb", "vert", "vert.qsb", "mng"
|
||||
"frag.qsb", "vert", "vert.qsb", "mng", "wav"
|
||||
};
|
||||
return
|
||||
suffixes.contains(path.suffix(), Qt::CaseInsensitive) ||
|
||||
|
Reference in New Issue
Block a user