forked from qt-creator/qt-creator
QmlProject: Refactor QmlProjectManager
- feature: JSON based project manager plugin - feature: functionality to write QmlProject file - tests: tests for QmlProjectItem Task-number: QDS-8810 Change-Id: I8989e54577e9cd883bd76346e22774cc7f7ed93f Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -1,23 +1,13 @@
|
||||
add_qtc_plugin(QmlProjectManager
|
||||
CONDITION TARGET Qt::QuickWidgets
|
||||
CONDITION TARGET Qt5::QuickWidgets
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
PLUGIN_CLASS QmlProjectPlugin
|
||||
DEPENDS QmlJS Qt::QuickWidgets
|
||||
DEPENDS QmlJS Qt5::QuickWidgets Utils
|
||||
PLUGIN_DEPENDS Core ProjectExplorer QtSupport QmlDesignerBase
|
||||
SOURCES
|
||||
fileformat/filefilteritems.cpp fileformat/filefilteritems.h
|
||||
fileformat/qmlprojectfileformat.cpp fileformat/qmlprojectfileformat.h
|
||||
fileformat/qmlprojectitem.cpp fileformat/qmlprojectitem.h
|
||||
cmakegen/checkablefiletreeitem.cpp cmakegen/checkablefiletreeitem.h
|
||||
cmakegen/cmakegeneratordialog.cpp cmakegen/cmakegeneratordialog.h
|
||||
cmakegen/cmakegeneratordialogtreemodel.cpp cmakegen/cmakegeneratordialogtreemodel.h
|
||||
cmakegen/cmakeprojectconverter.cpp cmakegen/cmakeprojectconverter.h
|
||||
cmakegen/cmakeprojectconverterdialog.cpp cmakegen/cmakeprojectconverterdialog.h
|
||||
cmakegen/generatecmakelists.cpp cmakegen/generatecmakelists.h
|
||||
cmakegen/generatecmakelistsconstants.h
|
||||
cmakegen/boilerplate.qrc
|
||||
qmlprojectgen/qmlprojectgenerator.cpp qmlprojectgen/qmlprojectgenerator.h
|
||||
qmlprojectgen/templates.qrc
|
||||
|
||||
projectfilecontenttools.cpp projectfilecontenttools.h
|
||||
qdslandingpage.cpp qdslandingpage.h
|
||||
qdslandingpagetheme.cpp qdslandingpagetheme.h
|
||||
@@ -29,8 +19,33 @@ add_qtc_plugin(QmlProjectManager
|
||||
qmlprojectmanager_global.h
|
||||
qmlprojectmanagertr.h
|
||||
qmlprojectmanagerconstants.h
|
||||
qmlprojectnodes.cpp qmlprojectnodes.h
|
||||
qmlprojectplugin.cpp qmlprojectplugin.h
|
||||
qmlprojectrunconfiguration.cpp qmlprojectrunconfiguration.h
|
||||
buildsystem/qmlbuildsystem.cpp buildsystem/qmlbuildsystem.h
|
||||
|
||||
"${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc"
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlProjectManager
|
||||
PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/buildsystem
|
||||
SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/buildsystem
|
||||
SOURCES
|
||||
projectitem/filefilteritems.cpp projectitem/filefilteritems.h
|
||||
projectitem/qmlprojectitem.cpp projectitem/qmlprojectitem.h
|
||||
projectitem/converters.h projectitem/converters.cpp
|
||||
projectnode/qmlprojectnodes.cpp projectnode/qmlprojectnodes.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlProjectManager
|
||||
PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/cmakegen
|
||||
SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/cmakegen
|
||||
SOURCES
|
||||
checkablefiletreeitem.cpp checkablefiletreeitem.h
|
||||
cmakegeneratordialog.cpp cmakegeneratordialog.h
|
||||
cmakegeneratordialogtreemodel.cpp cmakegeneratordialogtreemodel.h
|
||||
cmakeprojectconverter.cpp cmakeprojectconverter.h
|
||||
cmakeprojectconverterdialog.cpp cmakeprojectconverterdialog.h
|
||||
generatecmakelists.cpp generatecmakelists.h
|
||||
generatecmakelistsconstants.h
|
||||
boilerplate.qrc
|
||||
)
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "converters.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace QmlProjectManager::Converters {
|
||||
|
||||
using PropsPair = QPair<QString, QStringList>;
|
||||
struct FileProps
|
||||
{
|
||||
const PropsPair image{"image", QStringList{"*.jpeg", "*.jpg", "*.png", "*.svg", "*.hdr", ".ktx"}};
|
||||
const PropsPair qml{"qml", QStringList{"*.qml"}};
|
||||
const PropsPair qmlDir{"qmldir", QStringList{"qmldir"}};
|
||||
const PropsPair javaScr{"javaScript", QStringList{"*.js", "*.ts"}};
|
||||
const PropsPair video{"video", QStringList{"*.mp4"}};
|
||||
const PropsPair sound{"sound", QStringList{"*.mp3", "*.wav"}};
|
||||
const PropsPair font{"font", QStringList{"*.ttf", "*.otf"}};
|
||||
const PropsPair config{"config", QStringList{"*.conf"}};
|
||||
const PropsPair styling{"styling", QStringList{"*.css"}};
|
||||
const PropsPair mesh{"meshes", QStringList{"*.mesh"}};
|
||||
const PropsPair
|
||||
shader{"shader",
|
||||
QStringList{"*.glsl", "*.glslv", "*.glslf", "*.vsh", "*.fsh", "*.vert", "*.frag"}};
|
||||
};
|
||||
|
||||
QString jsonToQmlProject(const QJsonObject &rootObject)
|
||||
{
|
||||
QString qmlProjectString;
|
||||
QTextStream ts{&qmlProjectString};
|
||||
|
||||
QJsonObject runConfig = rootObject["runConfig"].toObject();
|
||||
QJsonObject languageConfig = rootObject["language"].toObject();
|
||||
QJsonObject shaderConfig = rootObject["shaderTool"].toObject();
|
||||
QJsonObject versionConfig = rootObject["versions"].toObject();
|
||||
QJsonObject environmentConfig = rootObject["environment"].toObject();
|
||||
QJsonObject deploymentConfig = rootObject["deployment"].toObject();
|
||||
QJsonObject filesConfig = rootObject["fileGroups"].toObject();
|
||||
|
||||
int indentationLevel = 0;
|
||||
|
||||
auto appendBreak = [&ts]() { ts << Qt::endl; };
|
||||
|
||||
auto appendComment = [&ts, &indentationLevel](const QString &comment) {
|
||||
ts << QString(" ").repeated(indentationLevel * 4) << "\\\\ " << comment << Qt::endl;
|
||||
};
|
||||
|
||||
auto appendItem =
|
||||
[&ts, &indentationLevel](const QString &key, const QString &value, const bool isEnclosed) {
|
||||
ts << QString(" ").repeated(indentationLevel * 4) << key << ": "
|
||||
<< (isEnclosed ? "\"" : "") << value << (isEnclosed ? "\"" : "") << Qt::endl;
|
||||
};
|
||||
|
||||
auto appendString = [&appendItem](const QString &key, const QString &val) {
|
||||
appendItem(key, val, true);
|
||||
};
|
||||
|
||||
auto appendBool = [&appendItem](const QString &key, const bool &val) {
|
||||
appendItem(key, QString::fromStdString(val ? "true" : "false"), false);
|
||||
};
|
||||
|
||||
auto appendArray = [&appendItem](const QString &key, const QStringList &vals) {
|
||||
QString finalString;
|
||||
foreach (const QString &value, vals) {
|
||||
finalString.append("\"").append(value).append("\"").append(",");
|
||||
}
|
||||
finalString.remove(finalString.length() - 1, 1);
|
||||
finalString.prepend("[ ").append(" ]");
|
||||
appendItem(key, finalString, false);
|
||||
};
|
||||
|
||||
auto startObject = [&ts, &indentationLevel](const QString &objectName) {
|
||||
ts << Qt::endl
|
||||
<< QString(" ").repeated(indentationLevel * 4) << objectName << " {" << Qt::endl;
|
||||
indentationLevel++;
|
||||
};
|
||||
|
||||
auto endObject = [&ts, &indentationLevel]() {
|
||||
indentationLevel--;
|
||||
ts << QString(" ").repeated(indentationLevel * 4) << "}" << Qt::endl;
|
||||
};
|
||||
|
||||
auto appendDirectories =
|
||||
[&startObject, &endObject, &appendString, &filesConfig](const QString &jsonKey,
|
||||
const QString &qmlKey) {
|
||||
QJsonValue dirsObj = filesConfig[jsonKey].toObject()["directories"];
|
||||
QStringList dirs = dirsObj.toVariant().toStringList();
|
||||
foreach (const QString &directory, dirs) {
|
||||
startObject(qmlKey);
|
||||
appendString("directory", directory);
|
||||
endObject();
|
||||
}
|
||||
};
|
||||
|
||||
auto appendFiles = [&startObject,
|
||||
&endObject,
|
||||
&appendString,
|
||||
&appendArray,
|
||||
&filesConfig](const QString &jsonKey, const QString &qmlKey) {
|
||||
QJsonValue dirsObj = filesConfig[jsonKey].toObject()["directories"];
|
||||
QJsonValue filesObj = filesConfig[jsonKey].toObject()["files"];
|
||||
QJsonValue filtersObj = filesConfig[jsonKey].toObject()["filters"];
|
||||
|
||||
foreach (const QString &directory, dirsObj.toVariant().toStringList()) {
|
||||
startObject(qmlKey);
|
||||
appendString("directory", directory);
|
||||
appendString("filters", filtersObj.toVariant().toStringList().join(";"));
|
||||
|
||||
if (!filesObj.toArray().isEmpty()) {
|
||||
QStringList fileList;
|
||||
foreach (const QJsonValue &file, filesObj.toArray()) {
|
||||
fileList.append(file.toObject()["name"].toString());
|
||||
}
|
||||
appendArray("files", fileList);
|
||||
}
|
||||
endObject();
|
||||
}
|
||||
};
|
||||
|
||||
// start creating the file content
|
||||
appendComment("prop: json-converted");
|
||||
appendComment("prop: auto-generated");
|
||||
|
||||
ts << Qt::endl << "import QmlProject" << Qt::endl;
|
||||
{
|
||||
startObject("Project");
|
||||
|
||||
{ // append non-object props
|
||||
appendString("mainFile", runConfig["mainFile"].toString());
|
||||
appendString("mainUiFile", runConfig["mainUiFile"].toString());
|
||||
appendString("targetDirectory", deploymentConfig["targetDirectory"].toString());
|
||||
appendBool("widgetApp", runConfig["widgetApp"].toBool());
|
||||
appendArray("importPaths", rootObject["importPaths"].toVariant().toStringList());
|
||||
appendBreak();
|
||||
appendString("qdsVersion", versionConfig["designStudio"].toString());
|
||||
appendString("quickVersion", versionConfig["qtQuick"].toString());
|
||||
appendBool("qt6Project", versionConfig["qtQuick"].toString().startsWith("6."));
|
||||
appendBool("qtForMCUs", rootObject["mcuConfig"].toObject().isEmpty());
|
||||
appendBreak();
|
||||
appendBool("multilanguageSupport", languageConfig["multiLanguageSupport"].toBool());
|
||||
appendString("primaryLanguage", languageConfig["primaryLanguage"].toString());
|
||||
appendArray("supportedLanguages",
|
||||
languageConfig["supportedLanguages"].toVariant().toStringList());
|
||||
}
|
||||
|
||||
{ // append Environment object
|
||||
startObject("Environment");
|
||||
foreach (const QString &key, environmentConfig.keys()) {
|
||||
appendItem(key, environmentConfig[key].toString(), true);
|
||||
}
|
||||
endObject();
|
||||
}
|
||||
|
||||
{ // append ShaderTool object
|
||||
startObject("ShaderTool");
|
||||
appendString("args", shaderConfig["args"].toVariant().toStringList().join(" "));
|
||||
appendArray("files", shaderConfig["files"].toVariant().toStringList());
|
||||
endObject();
|
||||
}
|
||||
|
||||
{ // append files objects
|
||||
appendDirectories("qml", "QmlFiles");
|
||||
appendDirectories("javaScript", "JavaScriptFiles");
|
||||
appendDirectories("image", "ImageFiles");
|
||||
appendFiles("config", "Files");
|
||||
appendFiles("font", "Files");
|
||||
appendFiles("meshes", "Files");
|
||||
appendFiles("qmldir", "Files");
|
||||
appendFiles("shader", "Files");
|
||||
appendFiles("sound", "Files");
|
||||
appendFiles("video", "Files");
|
||||
}
|
||||
|
||||
endObject(); // Closing 'Project'
|
||||
}
|
||||
return qmlProjectString;
|
||||
}
|
||||
|
||||
QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile)
|
||||
{
|
||||
QmlJS::SimpleReader simpleQmlJSReader;
|
||||
|
||||
const QmlJS::SimpleReaderNode::Ptr rootNode = simpleQmlJSReader.readFile(projectFile.toString());
|
||||
|
||||
if (!simpleQmlJSReader.errors().isEmpty() || !rootNode->isValid()) {
|
||||
qCritical() << "Unable to parse:" << projectFile;
|
||||
qCritical() << simpleQmlJSReader.errors();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (rootNode->name() != QLatin1String("Project")) {
|
||||
qCritical() << "Cannot find root 'Proejct' item in the project file: " << projectFile;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto nodeToJsonObject = [](const QmlJS::SimpleReaderNode::Ptr &node) {
|
||||
QJsonObject tObj;
|
||||
foreach (const QString &childPropName, node->propertyNames()) {
|
||||
tObj.insert(childPropName, node->property(childPropName).value.toJsonValue());
|
||||
}
|
||||
return tObj;
|
||||
};
|
||||
|
||||
auto toCamelCase = [](const QString &s) { return QString(s).replace(0, 1, s[0].toLower()); };
|
||||
|
||||
QJsonObject rootObject; // root object
|
||||
QJsonObject fileGroupsObject;
|
||||
QJsonObject languageObject;
|
||||
QJsonObject versionObject;
|
||||
QJsonObject runConfigObject;
|
||||
QJsonObject deploymentObject;
|
||||
QJsonObject mcuObject;
|
||||
QJsonObject shaderToolObject;
|
||||
|
||||
// convert the the non-object props
|
||||
for (const QString &propName : rootNode->propertyNames()) {
|
||||
QJsonObject *currentObj = &rootObject;
|
||||
QString objKey = propName;
|
||||
|
||||
if (propName.contains("language", Qt::CaseInsensitive)) {
|
||||
currentObj = &languageObject;
|
||||
if (propName.toLower() == "multilanguagesupport") // fixing the camelcase
|
||||
objKey = "multiLanguageSupport";
|
||||
} else if (propName.contains("version", Qt::CaseInsensitive)) {
|
||||
currentObj = &versionObject;
|
||||
if (propName.toLower() == "qdsversion")
|
||||
objKey = "designStudio";
|
||||
else if (propName.toLower() == "quickversion")
|
||||
objKey = "qtQuick";
|
||||
} else if (propName.contains("widgetapp", Qt::CaseInsensitive)
|
||||
|| propName.contains("fileselector", Qt::CaseInsensitive)
|
||||
|| propName.contains("mainfile", Qt::CaseInsensitive)
|
||||
|| propName.contains("mainuifile", Qt::CaseInsensitive)
|
||||
|| propName.contains("forcefreetype", Qt::CaseInsensitive)) {
|
||||
currentObj = &runConfigObject;
|
||||
} else if (propName.contains("targetdirectory", Qt::CaseInsensitive)) {
|
||||
currentObj = &deploymentObject;
|
||||
} else if (propName.contains("qtformcus", Qt::CaseInsensitive)) {
|
||||
currentObj = &mcuObject;
|
||||
objKey = "mcuEnabled";
|
||||
} else if (propName.contains("qt6project", Qt::CaseInsensitive)) {
|
||||
// we are skipping these ones in the new json format
|
||||
continue;
|
||||
}
|
||||
|
||||
currentObj->insert(objKey, rootNode->property(propName).value.toJsonValue());
|
||||
}
|
||||
|
||||
// add missing non-object props if any
|
||||
if (!runConfigObject.contains("fileSelectors")) {
|
||||
runConfigObject.insert("fileSelectors", QJsonArray{});
|
||||
}
|
||||
|
||||
// convert the the object props
|
||||
for (const QmlJS::SimpleReaderNode::Ptr &childNode : rootNode->children()) {
|
||||
if (childNode->name().contains("files", Qt::CaseInsensitive)) {
|
||||
PropsPair propsPair;
|
||||
FileProps fileProps;
|
||||
const QString childNodeName = childNode->name().toLower();
|
||||
const QmlJS::SimpleReaderNode::Property childNodeFilter = childNode->property("filter");
|
||||
const QmlJS::SimpleReaderNode::Property childNodeDirectory = childNode->property("directory");
|
||||
const QmlJS::SimpleReaderNode::Property childNodeFiles = childNode->property("files");
|
||||
const QString childNodeFilterValue = childNodeFilter.value.toString();
|
||||
|
||||
if (childNodeName == "qmlfiles" || childNodeFilterValue.contains("*.qml")) {
|
||||
propsPair = fileProps.qml;
|
||||
} else if (childNodeName == "javascriptfiles") {
|
||||
propsPair = fileProps.javaScr;
|
||||
} else if (childNodeName == "imagefiles") {
|
||||
propsPair = fileProps.image;
|
||||
} else {
|
||||
if (childNodeFilter.isValid()) {
|
||||
if (childNodeFilterValue.contains(".conf"))
|
||||
propsPair = fileProps.config;
|
||||
else if (childNodeFilterValue.contains(".ttf"))
|
||||
propsPair = fileProps.font;
|
||||
else if (childNodeFilterValue.contains("qmldir"))
|
||||
propsPair = fileProps.qmlDir;
|
||||
else if (childNodeFilterValue.contains(".wav"))
|
||||
propsPair = fileProps.sound;
|
||||
else if (childNodeFilterValue.contains(".mp4"))
|
||||
propsPair = fileProps.video;
|
||||
else if (childNodeFilterValue.contains(".mesh"))
|
||||
propsPair = fileProps.mesh;
|
||||
else if (childNodeFilterValue.contains(".glsl"))
|
||||
propsPair = fileProps.shader;
|
||||
else if (childNodeFilterValue.contains(".css"))
|
||||
propsPair = fileProps.styling;
|
||||
}
|
||||
}
|
||||
|
||||
// get all objects we'll work on
|
||||
QJsonObject targetObject = fileGroupsObject[propsPair.first].toObject();
|
||||
QJsonArray directories = targetObject["directories"].toArray();
|
||||
QJsonArray filters = targetObject["filters"].toArray();
|
||||
QJsonArray files = targetObject["files"].toArray();
|
||||
|
||||
// populate & update filters
|
||||
if (filters.isEmpty()) {
|
||||
filters = QJsonArray::fromStringList(propsPair.second); // populate the filters with the predefined ones
|
||||
}
|
||||
|
||||
if (childNodeFilter.isValid()) { // append filters from qmlproject (merge)
|
||||
const QStringList filtersFromProjectFile = childNodeFilterValue.split(
|
||||
";");
|
||||
for (const QString &filter : filtersFromProjectFile) {
|
||||
if (!filters.contains(QJsonValue(filter))) {
|
||||
filters.append(QJsonValue(filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// populate & update directories
|
||||
if (childNodeDirectory.isValid()) {
|
||||
directories.append(childNodeDirectory.value.toJsonValue());
|
||||
}
|
||||
if (directories.isEmpty())
|
||||
directories.append(".");
|
||||
|
||||
// populate & update files
|
||||
if (childNodeFiles.isValid()) {
|
||||
foreach (const QJsonValue &file, childNodeFiles.value.toJsonArray()) {
|
||||
files.append(QJsonObject{{"name", file.toString()}});
|
||||
}
|
||||
}
|
||||
|
||||
// put everything back into the root object
|
||||
targetObject.insert("directories", directories);
|
||||
targetObject.insert("filters", filters);
|
||||
targetObject.insert("files", files);
|
||||
fileGroupsObject.insert(propsPair.first, targetObject);
|
||||
} else if (childNode->name().contains("shadertool", Qt::CaseInsensitive)) {
|
||||
QStringList quotedArgs = childNode->property("args").value.toString().split('\"');
|
||||
QStringList args;
|
||||
for (int i = 0; i < quotedArgs.size(); ++i) {
|
||||
// Each odd arg in this list is a single quoted argument, which we should
|
||||
// not be split further
|
||||
if (i % 2 == 0)
|
||||
args.append(quotedArgs[i].trimmed().split(' '));
|
||||
else
|
||||
args.append(quotedArgs[i].prepend("\"").append("\""));
|
||||
}
|
||||
|
||||
shaderToolObject.insert("args", QJsonArray::fromStringList(args));
|
||||
shaderToolObject.insert("files", childNode->property("files").value.toJsonValue());
|
||||
} else {
|
||||
rootObject.insert(toCamelCase(childNode->name()), nodeToJsonObject(childNode));
|
||||
}
|
||||
}
|
||||
|
||||
rootObject.insert("fileGroups", fileGroupsObject);
|
||||
rootObject.insert("language", languageObject);
|
||||
rootObject.insert("versions", versionObject);
|
||||
rootObject.insert("runConfig", runConfigObject);
|
||||
rootObject.insert("deployment", deploymentObject);
|
||||
rootObject.insert("mcuConfig", mcuObject);
|
||||
rootObject.insert("shaderTool", shaderToolObject);
|
||||
rootObject.insert("fileVersion", 1);
|
||||
return rootObject;
|
||||
}
|
||||
} // namespace QmlProjectManager::Converters
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <qmljs/qmljssimplereader.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace QmlProjectManager::Converters {
|
||||
|
||||
QString jsonToQmlProject(const QJsonObject &rootObject);
|
||||
QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile);
|
||||
|
||||
} // namespace QmlProjectManager::Converters
|
||||
@@ -15,36 +15,46 @@
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
FileFilterBaseItem::FileFilterBaseItem()
|
||||
FileFilterItem::FileFilterItem(){
|
||||
initTimer();
|
||||
}
|
||||
|
||||
FileFilterItem::FileFilterItem(const QString &directory, const QStringList &filters)
|
||||
{
|
||||
setDirectory(directory);
|
||||
setFilters(filters);
|
||||
initTimer();
|
||||
}
|
||||
|
||||
void FileFilterItem::initTimer(){
|
||||
m_updateFileListTimer.setSingleShot(true);
|
||||
m_updateFileListTimer.setInterval(50);
|
||||
|
||||
connect(&m_updateFileListTimer, &QTimer::timeout, this, &FileFilterBaseItem::updateFileListNow);
|
||||
connect(&m_updateFileListTimer, &QTimer::timeout, this, &FileFilterItem::updateFileListNow);
|
||||
}
|
||||
|
||||
Utils::FileSystemWatcher *FileFilterBaseItem::dirWatcher()
|
||||
Utils::FileSystemWatcher *FileFilterItem::dirWatcher()
|
||||
{
|
||||
if (!m_dirWatcher) {
|
||||
m_dirWatcher = new Utils::FileSystemWatcher(1, this); // Separate id, might exceed OS limits.
|
||||
m_dirWatcher->setObjectName(QLatin1String("FileFilterBaseItemWatcher"));
|
||||
connect(m_dirWatcher, &Utils::FileSystemWatcher::directoryChanged,
|
||||
this, &FileFilterBaseItem::updateFileList);
|
||||
this, &FileFilterItem::updateFileList);
|
||||
}
|
||||
return m_dirWatcher;
|
||||
}
|
||||
|
||||
QStringList FileFilterBaseItem::watchedDirectories() const
|
||||
QStringList FileFilterItem::watchedDirectories() const
|
||||
{
|
||||
return m_dirWatcher ? m_dirWatcher->directories() : QStringList();
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::directory() const
|
||||
QString FileFilterItem::directory() const
|
||||
{
|
||||
return m_rootDir;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setDirectory(const QString &dirPath)
|
||||
void FileFilterItem::setDirectory(const QString &dirPath)
|
||||
{
|
||||
if (m_rootDir == dirPath)
|
||||
return;
|
||||
@@ -54,7 +64,7 @@ void FileFilterBaseItem::setDirectory(const QString &dirPath)
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setDefaultDirectory(const QString &dirPath)
|
||||
void FileFilterItem::setDefaultDirectory(const QString &dirPath)
|
||||
{
|
||||
if (m_defaultDir == dirPath)
|
||||
return;
|
||||
@@ -63,12 +73,12 @@ void FileFilterBaseItem::setDefaultDirectory(const QString &dirPath)
|
||||
updateFileListNow();
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::filter() const
|
||||
QStringList FileFilterItem::filters() const
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setFilter(const QString &filter)
|
||||
void FileFilterItem::setFilters(const QStringList &filter)
|
||||
{
|
||||
if (filter == m_filter)
|
||||
return;
|
||||
@@ -77,7 +87,7 @@ void FileFilterBaseItem::setFilter(const QString &filter)
|
||||
m_regExpList.clear();
|
||||
m_fileSuffixes.clear();
|
||||
|
||||
for (const QString &pattern : filter.split(QLatin1Char(';'))) {
|
||||
for (const QString &pattern : filter) {
|
||||
if (pattern.isEmpty())
|
||||
continue;
|
||||
// decide if it's a canonical pattern like *.x
|
||||
@@ -96,7 +106,7 @@ void FileFilterBaseItem::setFilter(const QString &filter)
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
bool FileFilterBaseItem::recursive() const
|
||||
bool FileFilterItem::recursive() const
|
||||
{
|
||||
bool recursive;
|
||||
if (m_recurse == Recurse) {
|
||||
@@ -112,7 +122,7 @@ bool FileFilterBaseItem::recursive() const
|
||||
return recursive;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setRecursive(bool recurse)
|
||||
void FileFilterItem::setRecursive(bool recurse)
|
||||
{
|
||||
bool oldRecursive = recursive();
|
||||
|
||||
@@ -125,18 +135,18 @@ void FileFilterBaseItem::setRecursive(bool recurse)
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
QStringList FileFilterBaseItem::pathsProperty() const
|
||||
QStringList FileFilterItem::pathsProperty() const
|
||||
{
|
||||
return m_explicitFiles;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setPathsProperty(const QStringList &path)
|
||||
void FileFilterItem::setPathsProperty(const QStringList &path)
|
||||
{
|
||||
m_explicitFiles = path;
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
QStringList FileFilterBaseItem::files() const
|
||||
QStringList FileFilterItem::files() const
|
||||
{
|
||||
return Utils::toList(m_files);
|
||||
}
|
||||
@@ -146,7 +156,7 @@ QStringList FileFilterBaseItem::files() const
|
||||
|
||||
@param filePath: absolute file path
|
||||
*/
|
||||
bool FileFilterBaseItem::matchesFile(const QString &filePath) const
|
||||
bool FileFilterItem::matchesFile(const QString &filePath) const
|
||||
{
|
||||
for (const QString &explicitFile : m_explicitFiles) {
|
||||
if (absolutePath(explicitFile) == filePath)
|
||||
@@ -167,14 +177,14 @@ bool FileFilterBaseItem::matchesFile(const QString &filePath) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::absolutePath(const QString &path) const
|
||||
QString FileFilterItem::absolutePath(const QString &path) const
|
||||
{
|
||||
if (QFileInfo(path).isAbsolute())
|
||||
return path;
|
||||
return QDir(absoluteDir()).absoluteFilePath(path);
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::absoluteDir() const
|
||||
QString FileFilterItem::absoluteDir() const
|
||||
{
|
||||
QString absoluteDir;
|
||||
if (QFileInfo(m_rootDir).isAbsolute())
|
||||
@@ -185,13 +195,15 @@ QString FileFilterBaseItem::absoluteDir() const
|
||||
return QDir::cleanPath(absoluteDir);
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::updateFileList()
|
||||
void FileFilterItem::updateFileList()
|
||||
{
|
||||
#ifndef TESTS_ENABLED_QMLPROJECTITEM
|
||||
if (!m_updateFileListTimer.isActive())
|
||||
m_updateFileListTimer.start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::updateFileListNow()
|
||||
void FileFilterItem::updateFileListNow()
|
||||
{
|
||||
if (m_updateFileListTimer.isActive())
|
||||
m_updateFileListTimer.stop();
|
||||
@@ -233,7 +245,7 @@ void FileFilterBaseItem::updateFileListNow()
|
||||
dirWatcher()->addDirectories(Utils::toList(watchDirs), Utils::FileSystemWatcher::WatchAllChanges);
|
||||
}
|
||||
|
||||
bool FileFilterBaseItem::fileMatches(const QString &fileName) const
|
||||
bool FileFilterItem::fileMatches(const QString &fileName) const
|
||||
{
|
||||
for (const QString &suffix : std::as_const(m_fileSuffixes)) {
|
||||
if (fileName.endsWith(suffix, Qt::CaseInsensitive))
|
||||
@@ -248,7 +260,7 @@ bool FileFilterBaseItem::fileMatches(const QString &fileName) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs)
|
||||
QSet<QString> FileFilterItem::filesInSubTree(const QDir &rootDir, const QDir &dir, QSet<QString> *parsedDirs)
|
||||
{
|
||||
QSet<QString> fileSet;
|
||||
|
||||
@@ -270,22 +282,5 @@ QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir
|
||||
return fileSet;
|
||||
}
|
||||
|
||||
ImageFileFilterItem::ImageFileFilterItem()
|
||||
{
|
||||
QString filter;
|
||||
// supported image formats according to
|
||||
QList<QByteArray> extensions = QImageReader::supportedImageFormats();
|
||||
extensions.append("hdr");
|
||||
extensions.append("ktx");
|
||||
for (const QByteArray &extension : std::as_const(extensions))
|
||||
filter.append(QString::fromLatin1("*.%1;").arg(QString::fromLatin1(extension)));
|
||||
setFilter(filter);
|
||||
}
|
||||
|
||||
FileFilterItem::FileFilterItem(const QString &fileFilter)
|
||||
{
|
||||
setFilter(fileFilter);
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
#include <QJsonArray>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QDir)
|
||||
|
||||
@@ -14,16 +15,10 @@ namespace Utils { class FileSystemWatcher; }
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectContentItem : public QObject
|
||||
{
|
||||
// base class for all elements that should be direct children of Project element
|
||||
Q_OBJECT
|
||||
using FileFilterItemPtr = std::unique_ptr<class FileFilterItem>;
|
||||
using FileFilterItems = std::vector<FileFilterItemPtr>;
|
||||
|
||||
public:
|
||||
QmlProjectContentItem() {}
|
||||
};
|
||||
|
||||
class FileFilterBaseItem : public QmlProjectContentItem {
|
||||
class FileFilterItem : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString directory READ directory WRITE setDirectory NOTIFY directoryChanged)
|
||||
@@ -33,15 +28,16 @@ class FileFilterBaseItem : public QmlProjectContentItem {
|
||||
Q_PROPERTY(QStringList files READ files NOTIFY filesChanged DESIGNABLE false)
|
||||
|
||||
public:
|
||||
FileFilterBaseItem();
|
||||
FileFilterItem();
|
||||
FileFilterItem(const QString &directory, const QStringList &filters);
|
||||
|
||||
QString directory() const;
|
||||
void setDirectory(const QString &directoryPath);
|
||||
|
||||
void setDefaultDirectory(const QString &directoryPath);
|
||||
|
||||
QString filter() const;
|
||||
void setFilter(const QString &filter);
|
||||
QStringList filters() const;
|
||||
void setFilters(const QStringList &filter);
|
||||
|
||||
bool recursive() const;
|
||||
void setRecursive(bool recursive);
|
||||
@@ -73,7 +69,7 @@ private:
|
||||
QString m_rootDir;
|
||||
QString m_defaultDir;
|
||||
|
||||
QString m_filter;
|
||||
QStringList m_filter;
|
||||
// simple "*.png" patterns are stored in m_fileSuffixes, otherwise store in m_regExpList
|
||||
QList<QString> m_fileSuffixes;
|
||||
QList<QRegularExpression> m_regExpList;
|
||||
@@ -93,16 +89,7 @@ private:
|
||||
QTimer m_updateFileListTimer;
|
||||
|
||||
friend class ProjectItem;
|
||||
};
|
||||
|
||||
class FileFilterItem : public FileFilterBaseItem {
|
||||
public:
|
||||
FileFilterItem(const QString &fileFilter);
|
||||
};
|
||||
|
||||
class ImageFileFilterItem : public FileFilterBaseItem {
|
||||
public:
|
||||
ImageFileFilterItem();
|
||||
void initTimer();
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -0,0 +1,381 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmlprojectitem.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "converters.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <qmljs/qmljssimplereader.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
//#define REWRITE_PROJECT_FILE_IN_JSON_FORMAT
|
||||
|
||||
QmlProjectItem::QmlProjectItem(const Utils::FilePath &filePath)
|
||||
: m_projectFile(filePath)
|
||||
{
|
||||
if (initProjectObject())
|
||||
setupFileFilters();
|
||||
}
|
||||
|
||||
bool QmlProjectItem::initProjectObject()
|
||||
{
|
||||
auto contents = m_projectFile.fileContents();
|
||||
if (!contents) {
|
||||
qWarning() << "Cannot open project file. Path:" << m_projectFile.fileName();
|
||||
return false;
|
||||
}
|
||||
|
||||
QString fileContent{QString::fromUtf8(contents.value())};
|
||||
QJsonObject rootObj;
|
||||
QJsonParseError parseError;
|
||||
|
||||
if (fileContent.contains("import qmlproject", Qt::CaseInsensitive)) {
|
||||
rootObj = Converters::qmlProjectTojson(m_projectFile);
|
||||
#ifdef REWRITE_PROJECT_FILE_IN_JSON_FORMAT
|
||||
m_projectFile.writeFileContents(QJsonDocument(rootObj).toJson());
|
||||
#endif
|
||||
} else {
|
||||
rootObj
|
||||
= QJsonDocument::fromJson(m_projectFile.fileContents()->data(), &parseError).object();
|
||||
}
|
||||
|
||||
if (rootObj.isEmpty()) {
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "Cannot parse the json formatted project file. Error:"
|
||||
<< parseError.errorString();
|
||||
} else {
|
||||
qWarning() << "Cannot convert QmlProject to Json.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
m_project = rootObj;
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setupFileFilters()
|
||||
{
|
||||
auto setupFileFilterItem = [this](const QJsonObject &fileGroup) {
|
||||
for (const QString &directory : fileGroup["directories"].toVariant().toStringList()) {
|
||||
std::unique_ptr<FileFilterItem> fileFilterItem{new FileFilterItem};
|
||||
|
||||
QStringList filesArr;
|
||||
for (const QJsonValue &file : fileGroup["files"].toArray()) {
|
||||
filesArr.append(file["name"].toString());
|
||||
}
|
||||
|
||||
fileFilterItem->setDirectory(directory);
|
||||
fileFilterItem->setFilters(fileGroup["filters"].toVariant().toStringList());
|
||||
fileFilterItem->setRecursive(fileGroup["recursive"].toBool(true));
|
||||
fileFilterItem->setPathsProperty(fileGroup["directories"].toVariant().toStringList());
|
||||
fileFilterItem->setPathsProperty(filesArr);
|
||||
fileFilterItem->setDefaultDirectory(m_projectFile.parentDir().toString());
|
||||
#ifndef TESTS_ENABLED_QMLPROJECTITEM
|
||||
connect(fileFilterItem.get(),
|
||||
&FileFilterItem::filesChanged,
|
||||
this,
|
||||
&QmlProjectItem::qmlFilesChanged);
|
||||
#endif
|
||||
m_content.push_back(std::move(fileFilterItem));
|
||||
};
|
||||
};
|
||||
|
||||
QJsonObject fileGroups = m_project["fileGroups"].toObject();
|
||||
for (const QString &groupName : fileGroups.keys()) {
|
||||
setupFileFilterItem(fileGroups[groupName].toObject());
|
||||
}
|
||||
}
|
||||
|
||||
Utils::FilePath QmlProjectItem::sourceDirectory() const
|
||||
{
|
||||
return m_projectFile.parentDir();
|
||||
}
|
||||
|
||||
QString QmlProjectItem::targetDirectory() const
|
||||
{
|
||||
return m_project["deployment"].toObject()["targetDirectory"].toString();
|
||||
}
|
||||
|
||||
bool QmlProjectItem::isQt4McuProject() const
|
||||
{
|
||||
return m_project["mcuConfig"].toObject()["mcuEnabled"].toBool();
|
||||
}
|
||||
|
||||
Utils::EnvironmentItems QmlProjectItem::environment() const
|
||||
{
|
||||
Utils::EnvironmentItems envItems;
|
||||
QJsonObject envVariables = m_project["environment"].toObject();
|
||||
foreach (const QString &variableName, envVariables.keys()) {
|
||||
envItems.append(Utils::EnvironmentItem(variableName, envVariables[variableName].toString()));
|
||||
}
|
||||
return envItems;
|
||||
}
|
||||
|
||||
void QmlProjectItem::addToEnviroment(const QString &key, const QString &value)
|
||||
{
|
||||
QJsonObject envVariables = m_project["environment"].toObject();
|
||||
envVariables.insert(key, value);
|
||||
insertAndUpdateProjectFile("environment", envVariables);
|
||||
}
|
||||
|
||||
QJsonObject QmlProjectItem::project() const
|
||||
{
|
||||
return m_project;
|
||||
}
|
||||
|
||||
bool QmlProjectItem::isQt6Project() const
|
||||
{
|
||||
return m_project["versions"].toObject()["qtQuick"].toString().startsWith("6.");
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::importPaths() const
|
||||
{
|
||||
return m_project["importPaths"].toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setImportPaths(const QStringList &importPaths)
|
||||
{
|
||||
insertAndUpdateProjectFile("importPaths", QJsonArray::fromStringList(importPaths));
|
||||
}
|
||||
|
||||
void QmlProjectItem::addImportPath(const QString &importPath)
|
||||
{
|
||||
QJsonArray importPaths = m_project["importPaths"].toArray();
|
||||
|
||||
if (importPaths.contains(importPath))
|
||||
return;
|
||||
|
||||
importPaths.append(importPath);
|
||||
insertAndUpdateProjectFile("importPaths", importPaths);
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::fileSelectors() const
|
||||
{
|
||||
return m_project["runConfig"].toObject()["fileSelectors"].toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setFileSelectors(const QStringList &selectors)
|
||||
{
|
||||
QJsonObject targetObj = m_project["runConfig"].toObject();
|
||||
targetObj["fileSelectors"] = QJsonArray::fromStringList(selectors);
|
||||
insertAndUpdateProjectFile("runConfig", targetObj);
|
||||
}
|
||||
|
||||
void QmlProjectItem::addFileSelector(const QString &selector)
|
||||
{
|
||||
QJsonObject targetObj = m_project["runConfig"].toObject();
|
||||
QJsonArray fileSelectors = targetObj["fileSelectors"].toArray();
|
||||
|
||||
if (fileSelectors.contains(selector))
|
||||
return;
|
||||
|
||||
fileSelectors.append(selector);
|
||||
targetObj["fileSelectors"] = fileSelectors;
|
||||
insertAndUpdateProjectFile("runConfig", targetObj);
|
||||
}
|
||||
|
||||
bool QmlProjectItem::multilanguageSupport() const
|
||||
{
|
||||
return m_project["language"].toObject()["multiLanguageSupport"].toBool();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMultilanguageSupport(const bool &isEnabled)
|
||||
{
|
||||
QJsonObject targetObj = m_project["language"].toObject();
|
||||
targetObj["multiLanguageSupport"] = isEnabled;
|
||||
insertAndUpdateProjectFile("language", targetObj);
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::supportedLanguages() const
|
||||
{
|
||||
return m_project["language"].toObject()["supportedLanguages"].toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setSupportedLanguages(const QStringList &languages)
|
||||
{
|
||||
QJsonObject targetObj = m_project["language"].toObject();
|
||||
targetObj["supportedLanguages"] = QJsonArray::fromStringList(languages);
|
||||
insertAndUpdateProjectFile("language", targetObj);
|
||||
}
|
||||
|
||||
void QmlProjectItem::addSupportedLanguage(const QString &language)
|
||||
{
|
||||
QJsonObject targetObj = m_project["language"].toObject();
|
||||
QJsonArray suppLangs = targetObj["supportedLanguages"].toArray();
|
||||
|
||||
if (suppLangs.contains(language))
|
||||
return;
|
||||
|
||||
suppLangs.append(language);
|
||||
targetObj["supportedLanguages"] = suppLangs;
|
||||
insertAndUpdateProjectFile("language", targetObj);
|
||||
}
|
||||
|
||||
QString QmlProjectItem::primaryLanguage() const
|
||||
{
|
||||
return m_project["language"].toObject()["primaryLanguage"].toString();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setPrimaryLanguage(const QString &language)
|
||||
{
|
||||
QJsonObject targetObj = m_project["language"].toObject();
|
||||
targetObj["primaryLanguage"] = language;
|
||||
insertAndUpdateProjectFile("language", targetObj);
|
||||
}
|
||||
|
||||
Utils::FilePaths QmlProjectItem::files() const
|
||||
{
|
||||
QSet<QString> filesSet;
|
||||
for (const auto &fileFilter : m_content) {
|
||||
const QStringList fileList = fileFilter->files();
|
||||
for (const QString &file : fileList) {
|
||||
filesSet.insert(file);
|
||||
}
|
||||
}
|
||||
|
||||
Utils::FilePaths files;
|
||||
for (const auto &fileName : filesSet) {
|
||||
files.append(Utils::FilePath::fromString(fileName));
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the project would include a file path
|
||||
- regardless whether the file already exists or not.
|
||||
|
||||
@param filePath: absolute file path to check
|
||||
*/
|
||||
bool QmlProjectItem::matchesFile(const QString &filePath) const
|
||||
{
|
||||
return Utils::contains(m_content, [&filePath](const auto &fileFilter) {
|
||||
return fileFilter->matchesFile(filePath);
|
||||
});
|
||||
}
|
||||
|
||||
bool QmlProjectItem::forceFreeType() const
|
||||
{
|
||||
return m_project["runConfig"].toObject()["forceFreeType"].toBool();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setForceFreeType(const bool &isForced)
|
||||
{
|
||||
QJsonObject runConfig = m_project["runConfig"].toObject();
|
||||
runConfig["forceFreeType"] = isForced;
|
||||
insertAndUpdateProjectFile("runConfig", runConfig);
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMainFile(const QString &mainFile)
|
||||
{
|
||||
QJsonObject runConfig = m_project["runConfig"].toObject();
|
||||
runConfig["mainFile"] = mainFile;
|
||||
insertAndUpdateProjectFile("runConfig", runConfig);
|
||||
}
|
||||
|
||||
QString QmlProjectItem::mainFile() const
|
||||
{
|
||||
return m_project["runConfig"].toObject()["mainFile"].toString();
|
||||
}
|
||||
|
||||
Utils::FilePath QmlProjectItem::mainFilePath() const
|
||||
{
|
||||
return m_projectFile;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMainUiFile(const QString &mainUiFile)
|
||||
{
|
||||
QJsonObject runConfig = m_project["runConfig"].toObject();
|
||||
runConfig["mainUiFile"] = mainUiFile;
|
||||
insertAndUpdateProjectFile("runConfig", runConfig);
|
||||
}
|
||||
|
||||
QString QmlProjectItem::mainUiFile() const
|
||||
{
|
||||
return m_project["runConfig"].toObject()["mainUiFile"].toString();
|
||||
}
|
||||
|
||||
Utils::FilePath QmlProjectItem::mainUiFilePath() const
|
||||
{
|
||||
return Utils::FilePath::fromString(m_project["runConfig"].toObject()["mainUiFile"].toString());
|
||||
}
|
||||
|
||||
bool QmlProjectItem::widgetApp() const
|
||||
{
|
||||
return m_project["runConfig"].toObject()["widgetApp"].toBool();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setWidgetApp(const bool &widgetApp)
|
||||
{
|
||||
QJsonObject runConfig = m_project["runConfig"].toObject();
|
||||
runConfig["widgetApp"] = widgetApp;
|
||||
insertAndUpdateProjectFile("runConfig", runConfig);
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::shaderToolArgs() const
|
||||
{
|
||||
return m_project["shaderTool"].toObject()["args"].toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setShaderToolArgs(const QStringList &args)
|
||||
{
|
||||
QJsonObject shaderTool = m_project["shaderTool"].toObject();
|
||||
shaderTool["args"] = QJsonArray::fromStringList(args);
|
||||
insertAndUpdateProjectFile("shaderTool", shaderTool);
|
||||
}
|
||||
|
||||
void QmlProjectItem::addShaderToolArg(const QString &arg)
|
||||
{
|
||||
QJsonObject targetObj = m_project["shaderTool"].toObject();
|
||||
QJsonArray toolArgs = targetObj["args"].toArray();
|
||||
|
||||
if (toolArgs.contains(arg))
|
||||
return;
|
||||
|
||||
toolArgs.append(arg);
|
||||
targetObj["args"] = toolArgs;
|
||||
insertAndUpdateProjectFile("shaderTool", targetObj);
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::shaderToolFiles() const
|
||||
{
|
||||
return m_project.value("shaderTool").toObject().value("files").toVariant().toStringList();
|
||||
}
|
||||
|
||||
void QmlProjectItem::setShaderToolFiles(const QStringList &files)
|
||||
{
|
||||
QJsonObject shaderTool = m_project["shaderTool"].toObject();
|
||||
shaderTool["files"] = QJsonArray::fromStringList(files);
|
||||
insertAndUpdateProjectFile("shaderTool", shaderTool);
|
||||
}
|
||||
|
||||
void QmlProjectItem::addShaderToolFile(const QString &file)
|
||||
{
|
||||
QJsonObject targetObj = m_project["shaderTool"].toObject();
|
||||
QJsonArray toolArgs = targetObj["files"].toArray();
|
||||
|
||||
if (toolArgs.contains(file))
|
||||
return;
|
||||
|
||||
toolArgs.append(file);
|
||||
targetObj["files"] = toolArgs;
|
||||
insertAndUpdateProjectFile("shaderTool", targetObj);
|
||||
}
|
||||
|
||||
void QmlProjectItem::insertAndUpdateProjectFile(const QString &key, const QJsonValue &value)
|
||||
{
|
||||
m_project[key] = value;
|
||||
#ifndef TESTS_ENABLED_QMLPROJECTITEM
|
||||
m_projectFile.writeFileContents(Converters::jsonToQmlProject(m_project).toUtf8());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "filefilteritems.h"
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
#include <QSharedPointer>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace QmlJS {
|
||||
class SimpleReaderNode;
|
||||
}
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QmlProjectItem(const Utils::FilePath &filePath);
|
||||
|
||||
bool isQt4McuProject() const;
|
||||
bool isQt6Project() const;
|
||||
|
||||
Utils::FilePath sourceDirectory() const;
|
||||
QString targetDirectory() const;
|
||||
|
||||
QStringList importPaths() const;
|
||||
void setImportPaths(const QStringList &paths);
|
||||
void addImportPath(const QString &importPath);
|
||||
|
||||
QStringList fileSelectors() const;
|
||||
void setFileSelectors(const QStringList &selectors);
|
||||
void addFileSelector(const QString &selector);
|
||||
|
||||
bool multilanguageSupport() const;
|
||||
void setMultilanguageSupport(const bool &isEnabled);
|
||||
|
||||
QStringList supportedLanguages() const;
|
||||
void setSupportedLanguages(const QStringList &languages);
|
||||
void addSupportedLanguage(const QString &language);
|
||||
|
||||
QString primaryLanguage() const;
|
||||
void setPrimaryLanguage(const QString &language);
|
||||
|
||||
Utils::FilePaths files() const;
|
||||
bool matchesFile(const QString &filePath) const;
|
||||
|
||||
bool forceFreeType() const;
|
||||
void setForceFreeType(const bool &isForced);
|
||||
|
||||
void setMainFile(const QString &mainFile);
|
||||
QString mainFile() const;
|
||||
Utils::FilePath mainFilePath() const;
|
||||
|
||||
void setMainUiFile(const QString &mainUiFile);
|
||||
QString mainUiFile() const;
|
||||
Utils::FilePath mainUiFilePath() const;
|
||||
|
||||
bool widgetApp() const;
|
||||
void setWidgetApp(const bool &widgetApp);
|
||||
|
||||
QStringList shaderToolArgs() const;
|
||||
void setShaderToolArgs(const QStringList &args);
|
||||
void addShaderToolArg(const QString &arg);
|
||||
|
||||
QStringList shaderToolFiles() const;
|
||||
void setShaderToolFiles(const QStringList &files);
|
||||
void addShaderToolFile(const QString &file);
|
||||
|
||||
Utils::EnvironmentItems environment() const;
|
||||
void addToEnviroment(const QString &key, const QString &value);
|
||||
|
||||
QJsonObject project() const;
|
||||
|
||||
signals:
|
||||
void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
|
||||
|
||||
private:
|
||||
typedef QSharedPointer<QmlProjectItem> ShrdPtrQPI;
|
||||
typedef std::unique_ptr<FileFilterItem> UnqPtrFFBI;
|
||||
typedef std::unique_ptr<FileFilterItem> UnqPtrFFI;
|
||||
|
||||
// files & props
|
||||
std::vector<std::unique_ptr<FileFilterItem>> m_content; // content property
|
||||
|
||||
// runtime variables
|
||||
Utils::FilePath m_projectFile; // design studio project file
|
||||
QJsonObject m_project; // root project object
|
||||
|
||||
// initializing functions
|
||||
bool initProjectObject();
|
||||
void setupFileFilters();
|
||||
|
||||
// file update functions
|
||||
void insertAndUpdateProjectFile(const QString &key, const QJsonValue &value);
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -10,8 +10,7 @@
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace QmlProjectManager {
|
||||
namespace Internal {
|
||||
namespace QmlProjectManager::Internal {
|
||||
|
||||
QmlProjectNode::QmlProjectNode(Project *project)
|
||||
: ProjectNode(project->projectDirectory())
|
||||
@@ -21,5 +20,4 @@ QmlProjectNode::QmlProjectNode(Project *project)
|
||||
setIcon(DirectoryIcon(":/projectexplorer/images/fileoverlay_qml.png"));
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlProjectManager
|
||||
544
src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp
Normal file
544
src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmlbuildsystem.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
|
||||
#include <QtCore5Compat/qtextcodec.h>
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/documentmodel.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <projectexplorer/deploymentdata.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include "projectitem/qmlprojectitem.h"
|
||||
#include "projectnode/qmlprojectnodes.h"
|
||||
|
||||
#include "utils/algorithm.h"
|
||||
#include "utils/qtcassert.h"
|
||||
|
||||
#include "texteditor/textdocument.h"
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
namespace QmlProjectManager {
|
||||
|
||||
namespace {
|
||||
Q_LOGGING_CATEGORY(infoLogger, "QmlProjectManager.QmlBuildSystem", QtInfoMsg)
|
||||
}
|
||||
|
||||
QmlBuildSystem::QmlBuildSystem(Target *target)
|
||||
: BuildSystem(target)
|
||||
{
|
||||
// refresh first - project information is used e.g. to decide the default RC's
|
||||
refresh(RefreshOptions::Project);
|
||||
|
||||
updateDeploymentData();
|
||||
registerMenuButtons();
|
||||
|
||||
connect(target->project(), &Project::activeTargetChanged, [this]() { refresh(RefreshOptions::NoFileRefresh); });
|
||||
connect(target->project(), &Project::projectFileIsDirty, [this]() {
|
||||
refresh(RefreshOptions::Project);
|
||||
});
|
||||
|
||||
// FIXME: Check. Probably bogus after the BuildSystem move.
|
||||
// // addedTarget calls updateEnabled on the runconfigurations
|
||||
// // which needs to happen after refresh
|
||||
// foreach (Target *t, targets())
|
||||
// addedTarget(t);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::updateDeploymentData()
|
||||
{
|
||||
if (!m_projectItem)
|
||||
return;
|
||||
|
||||
if (DeviceTypeKitAspect::deviceTypeId(kit())
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectExplorer::DeploymentData deploymentData;
|
||||
for (const auto &file : m_projectItem->files()) {
|
||||
deploymentData.addFile(file, targetFile(file).parentDir().toString());
|
||||
}
|
||||
|
||||
setDeploymentData(deploymentData);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::registerMenuButtons()
|
||||
{
|
||||
Core::ActionContainer *menu = Core::ActionManager::actionContainer(Core::Constants::M_FILE);
|
||||
|
||||
// QML Project file update button
|
||||
// This button saves the current configuration into the .qmlproject file
|
||||
auto action = new QAction("Update QmlProject File", this);
|
||||
Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.ProjectManager");
|
||||
menu->addAction(cmd, Core::Constants::G_FILE_SAVE);
|
||||
QObject::connect(action, &QAction::triggered, this, &QmlBuildSystem::updateProjectFile);
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::updateProjectFile()
|
||||
{
|
||||
qDebug() << "debug#1-mainfilepath" << mainFilePath();
|
||||
|
||||
QFile file(mainFilePath().fileName().append("project-test"));
|
||||
if (file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
|
||||
qCritical() << "Cannot open Qml Project file for editing!";
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream ts(&file);
|
||||
// License
|
||||
ts << "/* "
|
||||
"File generated by Qt Creator"
|
||||
"Copyright (C) 2016 The Qt Company Ltd."
|
||||
"SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH "
|
||||
"Qt-GPL-exception-1.0"
|
||||
"*/"
|
||||
<< Qt::endl
|
||||
<< Qt::endl;
|
||||
|
||||
// Components
|
||||
ts << "import QmlProject 1.1" << Qt::endl << Qt::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::triggerParsing()
|
||||
{
|
||||
refresh(RefreshOptions::Project);
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::canonicalProjectDir() const
|
||||
{
|
||||
return BuildSystem::target()
|
||||
->project()
|
||||
->projectFilePath()
|
||||
.canonicalPath()
|
||||
.normalizedPathName()
|
||||
.parentDir();
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refresh(RefreshOptions options)
|
||||
{
|
||||
ParseGuard guard = guardParsingRun();
|
||||
switch (options) {
|
||||
case RefreshOptions::NoFileRefresh:
|
||||
break;
|
||||
case RefreshOptions::Project:
|
||||
initProjectItem();
|
||||
case RefreshOptions::Files:
|
||||
parseProjectFiles();
|
||||
}
|
||||
|
||||
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
if (!modelManager)
|
||||
return;
|
||||
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(project(),
|
||||
project()->files(Project::HiddenRccFolders));
|
||||
const QStringList searchPaths = makeAbsolute(canonicalProjectDir(), customImportPaths());
|
||||
for (const QString &searchPath : searchPaths)
|
||||
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
|
||||
QmlJS::Dialect::Qml);
|
||||
|
||||
modelManager->updateProjectInfo(projectInfo, project());
|
||||
|
||||
guard.markAsSuccess();
|
||||
|
||||
emit projectChanged();
|
||||
}
|
||||
|
||||
void QmlBuildSystem::initProjectItem()
|
||||
{
|
||||
m_projectItem.reset(new QmlProjectItem{projectFilePath()});
|
||||
connect(m_projectItem.get(),
|
||||
&QmlProjectItem::qmlFilesChanged,
|
||||
this,
|
||||
&QmlBuildSystem::refreshFiles);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::parseProjectFiles()
|
||||
{
|
||||
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
|
||||
modelManager->updateSourceFiles(m_projectItem->files(), true);
|
||||
}
|
||||
|
||||
|
||||
Utils::FilePath mainFilePath{Utils::FilePath::fromString(m_projectItem->mainFile())};
|
||||
if (!mainFilePath.isEmpty()) {
|
||||
mainFilePath = canonicalProjectDir().resolvePath(m_projectItem->mainFile());
|
||||
Utils::FileReader reader;
|
||||
QString errorMessage;
|
||||
if (!reader.fetch(mainFilePath, &errorMessage)) {
|
||||
Core::MessageManager::writeFlashing(
|
||||
tr("Warning while loading project file %1.").arg(projectFilePath().toUserOutput()));
|
||||
Core::MessageManager::writeSilently(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
generateProjectTree();
|
||||
}
|
||||
|
||||
void QmlBuildSystem::generateProjectTree()
|
||||
{
|
||||
auto newRoot = std::make_unique<Internal::QmlProjectNode>(project());
|
||||
|
||||
for (const auto &file : m_projectItem->files()) {
|
||||
const FileType fileType = (file == projectFilePath())
|
||||
? FileType::Project
|
||||
: FileNode::fileTypeForFileName(file);
|
||||
newRoot->addNestedNode(std::make_unique<FileNode>(file, fileType));
|
||||
}
|
||||
newRoot->addNestedNode(std::make_unique<FileNode>(projectFilePath(), FileType::Project));
|
||||
|
||||
setRootProjectNode(std::move(newRoot));
|
||||
updateDeploymentData();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setFileSettingInProjectFile(const QString &setting,
|
||||
const Utils::FilePath &mainFilePath,
|
||||
const QString &oldFile)
|
||||
{
|
||||
// make sure to change it also in the qmlproject file
|
||||
const Utils::FilePath qmlProjectFilePath = project()->projectFilePath();
|
||||
Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(
|
||||
qmlProjectFilePath);
|
||||
TextEditor::TextDocument *document = nullptr;
|
||||
if (!editors.isEmpty()) {
|
||||
document = qobject_cast<TextEditor::TextDocument *>(editors.first()->document());
|
||||
if (document && document->isModified())
|
||||
if (!Core::DocumentManager::saveDocument(document))
|
||||
return false;
|
||||
}
|
||||
|
||||
QString fileContent;
|
||||
QString error;
|
||||
Utils::TextFileFormat textFileFormat;
|
||||
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||
Utils::TextFileFormat::ReadResult readResult = Utils::TextFileFormat::readFile(qmlProjectFilePath,
|
||||
codec,
|
||||
&fileContent,
|
||||
&textFileFormat,
|
||||
&error);
|
||||
if (readResult != Utils::TextFileFormat::ReadSuccess) {
|
||||
qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
|
||||
}
|
||||
|
||||
const QString settingQmlCode = setting + ":";
|
||||
|
||||
const Utils::FilePath projectDir = project()->projectFilePath().parentDir();
|
||||
const QString relativePath = mainFilePath.relativeChildPath(projectDir).path();
|
||||
|
||||
if (fileContent.indexOf(settingQmlCode) < 0) {
|
||||
QString addedText = QString("\n %1 \"%2\"\n").arg(settingQmlCode).arg(relativePath);
|
||||
auto index = fileContent.lastIndexOf("}");
|
||||
fileContent.insert(index, addedText);
|
||||
} else {
|
||||
QString originalFileName = oldFile;
|
||||
originalFileName.replace(".", "\\.");
|
||||
const QRegularExpression expression(
|
||||
QString("%1\\s*\"(%2)\"").arg(settingQmlCode).arg(originalFileName));
|
||||
|
||||
const QRegularExpressionMatch match = expression.match(fileContent);
|
||||
|
||||
fileContent.replace(match.capturedStart(1), match.capturedLength(1), relativePath);
|
||||
}
|
||||
|
||||
if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
|
||||
qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
|
||||
|
||||
refresh(RefreshOptions::Project);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::blockFilesUpdate() const
|
||||
{
|
||||
return m_blockFilesUpdate;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setBlockFilesUpdate(bool newBlockFilesUpdate)
|
||||
{
|
||||
m_blockFilesUpdate = newBlockFilesUpdate;
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::mainFilePath() const
|
||||
{
|
||||
return projectDirectory().pathAppended(mainFile());
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::mainUiFilePath() const
|
||||
{
|
||||
return m_projectItem->mainUiFilePath();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainFileInProjectFile(const Utils::FilePath &newMainFilePath)
|
||||
{
|
||||
return setFileSettingInProjectFile("mainFile", newMainFilePath, mainFile());
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainUiFileInProjectFile(const Utils::FilePath &newMainUiFilePath)
|
||||
{
|
||||
return setMainUiFileInMainFile(newMainUiFilePath)
|
||||
&& setFileSettingInProjectFile("mainUiFile", newMainUiFilePath, m_projectItem->mainUiFile());
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainUiFileInMainFile(const Utils::FilePath &newMainUiFilePath)
|
||||
{
|
||||
Core::FileChangeBlocker fileChangeBlocker(mainFilePath());
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(mainFilePath());
|
||||
TextEditor::TextDocument *document = nullptr;
|
||||
if (!editors.isEmpty()) {
|
||||
document = qobject_cast<TextEditor::TextDocument *>(editors.first()->document());
|
||||
if (document && document->isModified())
|
||||
if (!Core::DocumentManager::saveDocument(document))
|
||||
return false;
|
||||
}
|
||||
|
||||
QString fileContent;
|
||||
QString error;
|
||||
Utils::TextFileFormat textFileFormat;
|
||||
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||
if (Utils::TextFileFormat::readFile(mainFilePath(), codec, &fileContent, &textFileFormat, &error)
|
||||
!= Utils::TextFileFormat::ReadSuccess) {
|
||||
qWarning() << "Failed to read file" << mainFilePath() << ":" << error;
|
||||
}
|
||||
|
||||
const QString currentMain = QString("%1 {").arg(mainUiFilePath().baseName());
|
||||
const QString newMain = QString("%1 {").arg(newMainUiFilePath.baseName());
|
||||
|
||||
if (fileContent.contains(currentMain))
|
||||
fileContent.replace(currentMain, newMain);
|
||||
|
||||
if (!textFileFormat.writeFile(mainFilePath(), fileContent, &error))
|
||||
qWarning() << "Failed to write file" << mainFilePath() << ":" << error;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::targetDirectory() const
|
||||
{
|
||||
if (DeviceTypeKitAspect::deviceTypeId(kit()) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
return canonicalProjectDir();
|
||||
|
||||
return m_projectItem ? Utils::FilePath::fromString(m_projectItem->targetDirectory())
|
||||
: Utils::FilePath();
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::targetFile(const Utils::FilePath &sourceFile) const
|
||||
{
|
||||
const QDir sourceDir(m_projectItem ? m_projectItem->sourceDirectory().path()
|
||||
: canonicalProjectDir().toString());
|
||||
const QDir targetDir(targetDirectory().toString());
|
||||
const QString relative = sourceDir.relativeFilePath(sourceFile.toString());
|
||||
return Utils::FilePath::fromString(QDir::cleanPath(targetDir.absoluteFilePath(relative)));
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setSupportedLanguages(QStringList languages)
|
||||
{
|
||||
m_projectItem->setSupportedLanguages(languages);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setPrimaryLanguage(QString language)
|
||||
{
|
||||
m_projectItem->setPrimaryLanguage(language);
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::makeAbsolute(const Utils::FilePath &path,
|
||||
const QStringList &relativePaths)
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return relativePaths;
|
||||
|
||||
const QDir baseDir(path.toString());
|
||||
return Utils::transform(relativePaths, [&baseDir](const QString &path) {
|
||||
return QDir::cleanPath(baseDir.absoluteFilePath(path));
|
||||
});
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refreshFiles(const QSet<QString> & /*added*/, const QSet<QString> &removed)
|
||||
{
|
||||
if (m_blockFilesUpdate) {
|
||||
qCDebug(infoLogger) << "Auto files refresh blocked.";
|
||||
return;
|
||||
}
|
||||
refresh(RefreshOptions::Files);
|
||||
if (!removed.isEmpty()) {
|
||||
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
|
||||
modelManager->removeFiles(
|
||||
Utils::transform<QList<Utils::FilePath>>(removed, [](const QString &s) {
|
||||
return Utils::FilePath::fromString(s);
|
||||
}));
|
||||
}
|
||||
}
|
||||
updateDeploymentData();
|
||||
}
|
||||
|
||||
QVariant QmlBuildSystem::additionalData(Utils::Id id) const
|
||||
{
|
||||
if (id == Constants::customFileSelectorsData)
|
||||
return customFileSelectors();
|
||||
if (id == Constants::supportedLanguagesData)
|
||||
return supportedLanguages();
|
||||
if (id == Constants::primaryLanguageData)
|
||||
return primaryLanguage();
|
||||
if (id == Constants::customForceFreeTypeData)
|
||||
return forceFreeType();
|
||||
if (id == Constants::customQtForMCUs)
|
||||
return qtForMCUs();
|
||||
if (id == Constants::customQt6Project)
|
||||
return qt6Project();
|
||||
if (id == Constants::mainFilePath)
|
||||
return mainFilePath().toString();
|
||||
if (id == Constants::customImportPaths)
|
||||
return customImportPaths();
|
||||
if (id == Constants::canonicalProjectDir)
|
||||
return canonicalProjectDir().toString();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||
{
|
||||
if (dynamic_cast<Internal::QmlProjectNode *>(context)) {
|
||||
if (action == AddNewFile || action == EraseFile)
|
||||
return true;
|
||||
QTC_ASSERT(node, return false);
|
||||
|
||||
if (action == Rename && node->asFileNode()) {
|
||||
const FileNode *fileNode = node->asFileNode();
|
||||
QTC_ASSERT(fileNode, return false);
|
||||
return fileNode->fileType() != FileType::Project;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return BuildSystem::supportsAction(context, action, node);
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::addFiles(Node *context, const Utils::FilePaths &filePaths, Utils::FilePaths *)
|
||||
{
|
||||
if (!dynamic_cast<Internal::QmlProjectNode *>(context))
|
||||
return false;
|
||||
|
||||
Utils::FilePaths toAdd;
|
||||
for (const Utils::FilePath &filePath : filePaths) {
|
||||
if (!m_projectItem->matchesFile(filePath.toString()))
|
||||
toAdd << filePaths;
|
||||
}
|
||||
return toAdd.isEmpty();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::deleteFiles(Node *context, const Utils::FilePaths &filePaths)
|
||||
{
|
||||
if (dynamic_cast<Internal::QmlProjectNode *>(context))
|
||||
return true;
|
||||
|
||||
return BuildSystem::deleteFiles(context, filePaths);
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::renameFile(Node *context,
|
||||
const Utils::FilePath &oldFilePath,
|
||||
const Utils::FilePath &newFilePath)
|
||||
{
|
||||
if (dynamic_cast<Internal::QmlProjectNode *>(context)) {
|
||||
if (oldFilePath.endsWith(mainFile()))
|
||||
return setMainFileInProjectFile(newFilePath);
|
||||
if (oldFilePath.endsWith(m_projectItem->mainUiFile()))
|
||||
return setMainUiFileInProjectFile(newFilePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return BuildSystem::renameFile(context, oldFilePath, newFilePath);
|
||||
}
|
||||
|
||||
QString QmlBuildSystem::mainFile() const
|
||||
{
|
||||
return m_projectItem->mainFile();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::qtForMCUs() const
|
||||
{
|
||||
return m_projectItem->isQt4McuProject();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::qt6Project() const
|
||||
{
|
||||
return m_projectItem->isQt6Project();
|
||||
}
|
||||
|
||||
Utils::EnvironmentItems QmlBuildSystem::environment() const
|
||||
{
|
||||
return m_projectItem->environment();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::customImportPaths() const
|
||||
{
|
||||
return m_projectItem->importPaths();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::customFileSelectors() const
|
||||
{
|
||||
return m_projectItem->fileSelectors();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::multilanguageSupport() const
|
||||
{
|
||||
return m_projectItem->multilanguageSupport();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::supportedLanguages() const
|
||||
{
|
||||
return m_projectItem->supportedLanguages();
|
||||
}
|
||||
|
||||
QString QmlBuildSystem::primaryLanguage() const
|
||||
{
|
||||
return m_projectItem->primaryLanguage();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::forceFreeType() const
|
||||
{
|
||||
return m_projectItem->forceFreeType();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::widgetApp() const
|
||||
{
|
||||
return m_projectItem->widgetApp();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::shaderToolArgs() const
|
||||
{
|
||||
return m_projectItem->shaderToolArgs();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::shaderToolFiles() const
|
||||
{
|
||||
return m_projectItem->shaderToolFiles();
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::importPaths() const
|
||||
{
|
||||
return m_projectItem->importPaths();
|
||||
}
|
||||
|
||||
Utils::FilePaths QmlBuildSystem::files() const
|
||||
{
|
||||
return m_projectItem->files();
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
115
src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h
Normal file
115
src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../qmlprojectmanager_global.h"
|
||||
#include <projectexplorer/buildsystem.h>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProject;
|
||||
class QmlProjectItem;
|
||||
class QmlProjectFile;
|
||||
|
||||
class QMLPROJECTMANAGER_EXPORT QmlBuildSystem : public ProjectExplorer::BuildSystem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QmlBuildSystem(ProjectExplorer::Target *target);
|
||||
~QmlBuildSystem() = default;
|
||||
|
||||
void triggerParsing() final;
|
||||
|
||||
bool supportsAction(ProjectExplorer::Node *context,
|
||||
ProjectExplorer::ProjectAction action,
|
||||
const ProjectExplorer::Node *node) const override;
|
||||
bool addFiles(ProjectExplorer::Node *context,
|
||||
const Utils::FilePaths &filePaths,
|
||||
Utils::FilePaths *notAdded = nullptr) override;
|
||||
bool deleteFiles(ProjectExplorer::Node *context, const Utils::FilePaths &filePaths) override;
|
||||
bool renameFile(ProjectExplorer::Node *context,
|
||||
const Utils::FilePath &oldFilePath,
|
||||
const Utils::FilePath &newFilePath) override;
|
||||
|
||||
bool updateProjectFile();
|
||||
|
||||
QString name() const override { return QLatin1String("qml"); }
|
||||
|
||||
QmlProject *qmlProject() const;
|
||||
|
||||
QVariant additionalData(Utils::Id id) const override;
|
||||
|
||||
enum class RefreshOptions {
|
||||
NoFileRefresh,
|
||||
Files,
|
||||
Project,
|
||||
};
|
||||
|
||||
void refresh(RefreshOptions options);
|
||||
|
||||
bool setMainFileInProjectFile(const Utils::FilePath &newMainFilePath);
|
||||
bool setMainUiFileInProjectFile(const Utils::FilePath &newMainUiFilePath);
|
||||
bool setMainUiFileInMainFile(const Utils::FilePath &newMainUiFilePath);
|
||||
|
||||
Utils::FilePath canonicalProjectDir() const;
|
||||
QString mainFile() const;
|
||||
Utils::FilePath mainFilePath() const;
|
||||
Utils::FilePath mainUiFilePath() const;
|
||||
|
||||
bool qtForMCUs() const;
|
||||
bool qt6Project() const;
|
||||
|
||||
Utils::FilePath targetDirectory() const;
|
||||
Utils::FilePath targetFile(const Utils::FilePath &sourceFile) const;
|
||||
|
||||
Utils::EnvironmentItems environment() const;
|
||||
QStringList customImportPaths() const;
|
||||
QStringList customFileSelectors() const;
|
||||
bool multilanguageSupport() const;
|
||||
QStringList supportedLanguages() const;
|
||||
void setSupportedLanguages(QStringList languages);
|
||||
QString primaryLanguage() const;
|
||||
void setPrimaryLanguage(QString language);
|
||||
bool forceFreeType() const;
|
||||
bool widgetApp() const;
|
||||
QStringList shaderToolArgs() const;
|
||||
QStringList shaderToolFiles() const;
|
||||
QStringList importPaths() const;
|
||||
Utils::FilePaths files() const;
|
||||
|
||||
bool addFiles(const QStringList &filePaths);
|
||||
void refreshProjectFile();
|
||||
|
||||
static Utils::FilePath activeMainFilePath();
|
||||
static QStringList makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths);
|
||||
|
||||
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
|
||||
|
||||
bool blockFilesUpdate() const;
|
||||
void setBlockFilesUpdate(bool newBlockFilesUpdate);
|
||||
|
||||
signals:
|
||||
void projectChanged();
|
||||
|
||||
private:
|
||||
bool setFileSettingInProjectFile(const QString &setting,
|
||||
const Utils::FilePath &mainFilePath,
|
||||
const QString &oldFile);
|
||||
|
||||
QSharedPointer<QmlProjectItem> m_projectItem;
|
||||
bool m_blockFilesUpdate = false;
|
||||
|
||||
void initProjectItem();
|
||||
void parseProjectFiles();
|
||||
void generateProjectTree();
|
||||
|
||||
void registerMenuButtons();
|
||||
void updateDeploymentData();
|
||||
friend class FilesUpdateBlocker;
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -1,198 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmlprojectfileformat.h"
|
||||
|
||||
#include "filefilteritems.h"
|
||||
#include "qmlprojectitem.h"
|
||||
#include "../qmlprojectmanagertr.h"
|
||||
|
||||
#include <qmljs/qmljssimplereader.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVariant>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
enum {
|
||||
debug = false
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<QmlProjectManager::FileFilterBaseItem> setupFileFilterItem(
|
||||
std::unique_ptr<QmlProjectManager::FileFilterBaseItem> fileFilterItem,
|
||||
const QmlJS::SimpleReaderNode::Ptr &node)
|
||||
{
|
||||
const auto directoryProperty = node->property(QLatin1String("directory"));
|
||||
if (directoryProperty.isValid())
|
||||
fileFilterItem->setDirectory(directoryProperty.value.toString());
|
||||
|
||||
const auto recursiveProperty = node->property(QLatin1String("recursive"));
|
||||
if (recursiveProperty.isValid())
|
||||
fileFilterItem->setRecursive(recursiveProperty.value.toBool());
|
||||
|
||||
const auto pathsProperty = node->property(QLatin1String("paths"));
|
||||
if (pathsProperty.isValid())
|
||||
fileFilterItem->setPathsProperty(pathsProperty.value.toStringList());
|
||||
|
||||
// "paths" and "files" have the same functionality
|
||||
const auto filesProperty = node->property(QLatin1String("files"));
|
||||
if (filesProperty.isValid())
|
||||
fileFilterItem->setPathsProperty(filesProperty.value.toStringList());
|
||||
|
||||
const auto filterProperty = node->property(QLatin1String("filter"));
|
||||
if (filterProperty.isValid())
|
||||
fileFilterItem->setFilter(filterProperty.value.toString());
|
||||
|
||||
if (debug)
|
||||
qDebug() << "directory:" << directoryProperty.value << "recursive" << recursiveProperty.value
|
||||
<< "paths" << pathsProperty.value << "files" << filesProperty.value;
|
||||
return fileFilterItem;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
std::unique_ptr<QmlProjectItem> QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fileName,
|
||||
QString *errorMessage)
|
||||
{
|
||||
QmlJS::SimpleReader simpleQmlJSReader;
|
||||
|
||||
const QmlJS::SimpleReaderNode::Ptr rootNode = simpleQmlJSReader.readFile(fileName.toString());
|
||||
|
||||
if (!simpleQmlJSReader.errors().isEmpty() || !rootNode->isValid()) {
|
||||
qWarning() << "unable to parse:" << fileName;
|
||||
qWarning() << simpleQmlJSReader.errors();
|
||||
if (errorMessage)
|
||||
*errorMessage = simpleQmlJSReader.errors().join(QLatin1String(", "));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (rootNode->name() == QLatin1String("Project")) {
|
||||
auto projectItem = std::make_unique<QmlProjectItem>();
|
||||
|
||||
const auto mainFileProperty = rootNode->property(QLatin1String("mainFile"));
|
||||
if (mainFileProperty.isValid())
|
||||
projectItem->setMainFile(mainFileProperty.value.toString());
|
||||
|
||||
const auto mainUiFileProperty = rootNode->property(QLatin1String("mainUiFile"));
|
||||
if (mainUiFileProperty.isValid())
|
||||
projectItem->setMainUiFile(mainUiFileProperty.value.toString());
|
||||
|
||||
const auto importPathsProperty = rootNode->property(QLatin1String("importPaths"));
|
||||
if (importPathsProperty.isValid()) {
|
||||
QStringList list = importPathsProperty.value.toStringList();
|
||||
list.removeAll(".");
|
||||
projectItem->setImportPaths(list);
|
||||
}
|
||||
|
||||
const auto fileSelectorsProperty = rootNode->property(QLatin1String("fileSelectors"));
|
||||
if (fileSelectorsProperty.isValid())
|
||||
projectItem->setFileSelectors(fileSelectorsProperty.value.toStringList());
|
||||
|
||||
const auto multilanguageSupportProperty = rootNode->property(
|
||||
QLatin1String("multilanguageSupport"));
|
||||
if (multilanguageSupportProperty.isValid())
|
||||
projectItem->setMultilanguageSupport(multilanguageSupportProperty.value.toBool());
|
||||
|
||||
const auto languagesProperty = rootNode->property(QLatin1String("supportedLanguages"));
|
||||
if (languagesProperty.isValid())
|
||||
projectItem->setSupportedLanguages(languagesProperty.value.toStringList());
|
||||
|
||||
const auto primaryLanguageProperty = rootNode->property(QLatin1String("primaryLanguage"));
|
||||
if (primaryLanguageProperty.isValid())
|
||||
projectItem->setPrimaryLanguage(primaryLanguageProperty.value.toString());
|
||||
|
||||
const auto forceFreeTypeProperty = rootNode->property("forceFreeType");
|
||||
if (forceFreeTypeProperty.isValid())
|
||||
projectItem->setForceFreeType(forceFreeTypeProperty.value.toBool());
|
||||
|
||||
const auto targetDirectoryPropery = rootNode->property("targetDirectory");
|
||||
if (targetDirectoryPropery.isValid())
|
||||
projectItem->setTargetDirectory(FilePath::fromSettings(targetDirectoryPropery.value));
|
||||
|
||||
const auto qtForMCUProperty = rootNode->property("qtForMCUs");
|
||||
if (qtForMCUProperty.isValid() && qtForMCUProperty.value.toBool())
|
||||
projectItem->setQtForMCUs(qtForMCUProperty.value.toBool());
|
||||
|
||||
const auto qt6ProjectProperty = rootNode->property("qt6Project");
|
||||
if (qt6ProjectProperty.isValid() && qt6ProjectProperty.value.toBool())
|
||||
projectItem->setQt6Project(qt6ProjectProperty.value.toBool());
|
||||
|
||||
const auto widgetAppProperty = rootNode->property("widgetApp");
|
||||
if (widgetAppProperty.isValid())
|
||||
projectItem->setWidgetApp(widgetAppProperty.value.toBool());
|
||||
|
||||
if (debug)
|
||||
qDebug() << "importPath:" << importPathsProperty.value << "mainFile:" << mainFileProperty.value;
|
||||
|
||||
const QList<QmlJS::SimpleReaderNode::Ptr> childNodes = rootNode->children();
|
||||
for (const QmlJS::SimpleReaderNode::Ptr &childNode : childNodes) {
|
||||
if (debug)
|
||||
qDebug() << "reading type:" << childNode->name();
|
||||
|
||||
if (childNode->name() == QLatin1String("QmlFiles")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<FileFilterItem>("*.qml"), childNode));
|
||||
} else if (childNode->name() == QLatin1String("JavaScriptFiles")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<FileFilterItem>("*.js"), childNode));
|
||||
} else if (childNode->name() == QLatin1String("ImageFiles")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<ImageFileFilterItem>(), childNode));
|
||||
} else if (childNode->name() == QLatin1String("CssFiles")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<FileFilterItem>("*.css"), childNode));
|
||||
} else if (childNode->name() == QLatin1String("FontFiles")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<FileFilterItem>("*.ttf;*.otf"), childNode));
|
||||
} else if (childNode->name() == QLatin1String("Files")) {
|
||||
projectItem->appendContent(
|
||||
setupFileFilterItem(std::make_unique<FileFilterBaseItem>(), childNode));
|
||||
} else if (childNode->name() == "Environment") {
|
||||
const auto properties = childNode->properties();
|
||||
auto i = properties.constBegin();
|
||||
while (i != properties.constEnd()) {
|
||||
projectItem->addToEnviroment(i.key(), i.value().value.toString());
|
||||
++i;
|
||||
}
|
||||
} else if (childNode->name() == "ShaderTool") {
|
||||
QmlJS::SimpleReaderNode::Property commandLine = childNode->property("args");
|
||||
if (commandLine.isValid()) {
|
||||
const QStringList quotedArgs = commandLine.value.toString().split('\"');
|
||||
QStringList args;
|
||||
for (int i = 0; i < quotedArgs.size(); ++i) {
|
||||
// Each odd arg in this list is a single quoted argument, which we should
|
||||
// not be split further
|
||||
if (i % 2 == 0)
|
||||
args.append(quotedArgs[i].trimmed().split(' '));
|
||||
else
|
||||
args.append(quotedArgs[i]);
|
||||
}
|
||||
args.removeAll({});
|
||||
args.append("-o"); // Prepare for adding output file as next arg
|
||||
projectItem->setShaderToolArgs(args);
|
||||
}
|
||||
QmlJS::SimpleReaderNode::Property files = childNode->property("files");
|
||||
if (files.isValid())
|
||||
projectItem->setShaderToolFiles(files.value.toStringList());
|
||||
} else {
|
||||
qWarning() << "Unknown type:" << childNode->name();
|
||||
}
|
||||
}
|
||||
return projectItem;
|
||||
}
|
||||
|
||||
if (errorMessage)
|
||||
*errorMessage = Tr::tr("Invalid root element: %1").arg(rootNode->name());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectItem;
|
||||
|
||||
class QmlProjectFileFormat
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<QmlProjectItem> parseProjectFile(const Utils::FilePath &fileName,
|
||||
QString *errorMessage = nullptr);
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -1,118 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmlprojectitem.h"
|
||||
#include "filefilteritems.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
// kind of initialization
|
||||
void QmlProjectItem::setSourceDirectory(const FilePath &directoryPath)
|
||||
{
|
||||
if (m_sourceDirectory == directoryPath)
|
||||
return;
|
||||
|
||||
m_sourceDirectory = directoryPath;
|
||||
|
||||
for (auto &fileFilter : m_content) {
|
||||
fileFilter->setDefaultDirectory(directoryPath.toFSPathString());
|
||||
connect(fileFilter.get(),
|
||||
&FileFilterBaseItem::filesChanged,
|
||||
this,
|
||||
&QmlProjectItem::qmlFilesChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProjectItem::setTargetDirectory(const FilePath &directoryPath)
|
||||
{
|
||||
m_targetDirectory = directoryPath;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setQtForMCUs(bool b)
|
||||
{
|
||||
m_qtForMCUs = b;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setQt6Project(bool qt6Project)
|
||||
{
|
||||
m_qt6Project = qt6Project;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setImportPaths(const QStringList &importPaths)
|
||||
{
|
||||
if (m_importPaths != importPaths)
|
||||
m_importPaths = importPaths;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setFileSelectors(const QStringList &selectors)
|
||||
{
|
||||
if (m_fileSelectors != selectors)
|
||||
m_fileSelectors = selectors;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMultilanguageSupport(const bool isEnabled)
|
||||
{
|
||||
m_multilanguageSupport = isEnabled;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setSupportedLanguages(const QStringList &languages)
|
||||
{
|
||||
if (m_supportedLanguages != languages)
|
||||
m_supportedLanguages = languages;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setPrimaryLanguage(const QString &language)
|
||||
{
|
||||
if (m_primaryLanguage != language)
|
||||
m_primaryLanguage = language;
|
||||
}
|
||||
|
||||
/* Returns list of absolute paths */
|
||||
QStringList QmlProjectItem::files() const
|
||||
{
|
||||
QSet<QString> files;
|
||||
|
||||
for (const auto &fileFilter : m_content) {
|
||||
const QStringList fileList = fileFilter->files();
|
||||
for (const QString &file : fileList) {
|
||||
files.insert(file);
|
||||
}
|
||||
}
|
||||
return Utils::toList(files);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the project would include a file path
|
||||
- regardless whether the file already exists or not.
|
||||
|
||||
@param filePath: absolute file path to check
|
||||
*/
|
||||
bool QmlProjectItem::matchesFile(const QString &filePath) const
|
||||
{
|
||||
return Utils::contains(m_content, [&filePath](const auto &fileFilter) {
|
||||
return fileFilter->matchesFile(filePath);
|
||||
});
|
||||
}
|
||||
|
||||
void QmlProjectItem::setForceFreeType(bool b)
|
||||
{
|
||||
m_forceFreeType = b;
|
||||
}
|
||||
|
||||
Utils::EnvironmentItems QmlProjectItem::environment() const
|
||||
{
|
||||
return m_environment;
|
||||
}
|
||||
|
||||
void QmlProjectItem::addToEnviroment(const QString &key, const QString &value)
|
||||
{
|
||||
m_environment.append(Utils::EnvironmentItem(key, value));
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -1,103 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "filefilteritems.h"
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
const Utils::FilePath &sourceDirectory() const { return m_sourceDirectory; }
|
||||
void setSourceDirectory(const Utils::FilePath &directoryPath);
|
||||
const Utils::FilePath &targetDirectory() const { return m_targetDirectory; }
|
||||
void setTargetDirectory(const Utils::FilePath &directoryPath);
|
||||
|
||||
bool qtForMCUs() const { return m_qtForMCUs; }
|
||||
void setQtForMCUs(bool qtForMCUs);
|
||||
|
||||
bool qt6Project() const { return m_qt6Project; }
|
||||
void setQt6Project(bool qt6Project);
|
||||
|
||||
QStringList importPaths() const { return m_importPaths; }
|
||||
void setImportPaths(const QStringList &paths);
|
||||
|
||||
QStringList fileSelectors() const { return m_fileSelectors; }
|
||||
void setFileSelectors(const QStringList &selectors);
|
||||
|
||||
bool multilanguageSupport() const { return m_multilanguageSupport; }
|
||||
void setMultilanguageSupport(const bool isEnabled);
|
||||
|
||||
QStringList supportedLanguages() const { return m_supportedLanguages; }
|
||||
void setSupportedLanguages(const QStringList &languages);
|
||||
|
||||
QString primaryLanguage() const { return m_primaryLanguage; }
|
||||
void setPrimaryLanguage(const QString &language);
|
||||
|
||||
QStringList files() const;
|
||||
bool matchesFile(const QString &filePath) const;
|
||||
|
||||
bool forceFreeType() const { return m_forceFreeType; };
|
||||
void setForceFreeType(bool);
|
||||
|
||||
QString mainFile() const { return m_mainFile; }
|
||||
void setMainFile(const QString &mainFilePath) { m_mainFile = mainFilePath; }
|
||||
|
||||
QString mainUiFile() const { return m_mainUiFile; }
|
||||
void setMainUiFile(const QString &mainUiFilePath) { m_mainUiFile = mainUiFilePath; }
|
||||
|
||||
bool widgetApp() const { return m_widgetApp; }
|
||||
void setWidgetApp(bool widgetApp) { m_widgetApp = widgetApp; }
|
||||
|
||||
QStringList shaderToolArgs() const { return m_shaderToolArgs; }
|
||||
void setShaderToolArgs(const QStringList &args) {m_shaderToolArgs = args; }
|
||||
|
||||
QStringList shaderToolFiles() const { return m_shaderToolFiles; }
|
||||
void setShaderToolFiles(const QStringList &files) { m_shaderToolFiles = files; }
|
||||
|
||||
void appendContent(std::unique_ptr<FileFilterBaseItem> item)
|
||||
{
|
||||
m_content.push_back(std::move(item));
|
||||
}
|
||||
|
||||
Utils::EnvironmentItems environment() const;
|
||||
void addToEnviroment(const QString &key, const QString &value);
|
||||
|
||||
signals:
|
||||
void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
|
||||
|
||||
protected:
|
||||
Utils::FilePath m_sourceDirectory;
|
||||
Utils::FilePath m_targetDirectory;
|
||||
QStringList m_importPaths;
|
||||
QStringList m_fileSelectors;
|
||||
bool m_multilanguageSupport;
|
||||
QStringList m_supportedLanguages;
|
||||
QString m_primaryLanguage;
|
||||
QString m_mainFile;
|
||||
QString m_mainUiFile;
|
||||
Utils::EnvironmentItems m_environment;
|
||||
std::vector<std::unique_ptr<FileFilterBaseItem>> m_content; // content property
|
||||
bool m_forceFreeType = false;
|
||||
bool m_qtForMCUs = false;
|
||||
bool m_qt6Project = false;
|
||||
bool m_widgetApp = false;
|
||||
QStringList m_shaderToolArgs;
|
||||
QStringList m_shaderToolFiles;
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
@@ -181,7 +181,7 @@ void QmlMainFileAspect::setScriptSource(MainScriptSource source, const QString &
|
||||
FilePath QmlMainFileAspect::mainScript() const
|
||||
{
|
||||
if (!qmlBuildSystem()->mainFile().isEmpty()) {
|
||||
const FilePath pathInProject = qmlBuildSystem()->mainFile();
|
||||
const FilePath pathInProject = qmlBuildSystem()->mainFilePath();
|
||||
return qmlBuildSystem()->canonicalProjectDir().resolvePath(pathInProject);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,554 +1,163 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmlproject.h"
|
||||
|
||||
#include "fileformat/qmlprojectfileformat.h"
|
||||
#include "fileformat/qmlprojectitem.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
#include "qmlprojectmanagerconstants.h"
|
||||
#include "qmlprojectmanagertr.h"
|
||||
#include "qmlprojectnodes.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/documentmodel.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
|
||||
#include <projectexplorer/deploymentdata.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
#include <qtsupport/qtsupportconstants.h>
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <texteditor/textdocument.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/infobar.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextCodec>
|
||||
#include <QTimer>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include "projectexplorer/devicesupport/idevice.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
#include "qmlprojectmanagerconstants.h"
|
||||
#include "qmlprojectmanagertr.h"
|
||||
#include "utils/algorithm.h"
|
||||
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QmlProjectManager::Internal;
|
||||
using namespace Utils;
|
||||
|
||||
namespace {
|
||||
Q_LOGGING_CATEGORY(infoLogger, "QmlProjectManager.QmlBuildSystem", QtInfoMsg)
|
||||
}
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
static int preferedQtTarget(Target *target)
|
||||
{
|
||||
if (target) {
|
||||
const QmlBuildSystem *buildSystem = qobject_cast<QmlBuildSystem *>(target->buildSystem());
|
||||
if (buildSystem && buildSystem->qt6Project())
|
||||
return 6;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
static bool allowOnlySingleProject()
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
const QString qdsAllowMultipleProjects = "QML/Designer/AllowMultipleProjects";
|
||||
|
||||
return !settings->value(qdsAllowMultipleProjects, false).toBool();
|
||||
}
|
||||
|
||||
Utils::FilePaths QmlProject::collectUiQmlFilesForFolder(const Utils::FilePath &folder) const
|
||||
{
|
||||
const Utils::FilePaths uiFiles = files([&](const ProjectExplorer::Node *node) {
|
||||
return node->filePath().completeSuffix() == "ui.qml"
|
||||
&& node->filePath().parentDir() == folder;
|
||||
});
|
||||
return uiFiles;
|
||||
}
|
||||
|
||||
FilePaths QmlProject::collectQmlFiles() const
|
||||
{
|
||||
return files([](const Node *node) { return node->filePath().suffix() == "qml"; });
|
||||
}
|
||||
|
||||
QmlProject::QmlProject(const Utils::FilePath &fileName)
|
||||
: Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName)
|
||||
{
|
||||
setId(QmlProjectManager::Constants::QML_PROJECT_ID);
|
||||
setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
|
||||
setProjectLanguages(Core::Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
|
||||
setDisplayName(fileName.completeBaseName());
|
||||
|
||||
setNeedsBuildConfigurations(false);
|
||||
setBuildSystemCreator([](Target *t) { return new QmlBuildSystem(t); });
|
||||
|
||||
if (QmlProject::isQtDesignStudio()) {
|
||||
// FIXME: why checking this?
|
||||
// this should not even be the case. if that's possible, then what?
|
||||
// what are the follow-up actions?
|
||||
if (!QmlProject::isQtDesignStudio())
|
||||
return;
|
||||
|
||||
if (allowOnlySingleProject()) {
|
||||
EditorManager::closeAllDocuments();
|
||||
Core::EditorManager::closeAllDocuments();
|
||||
SessionManager::closeAllProjects();
|
||||
}
|
||||
|
||||
m_openFileConnection
|
||||
= connect(this,
|
||||
&QmlProject::anyParsingFinished,
|
||||
this,
|
||||
[this](Target *target, bool success) {
|
||||
if (m_openFileConnection)
|
||||
disconnect(m_openFileConnection);
|
||||
connect(this, &QmlProject::anyParsingFinished, this, &QmlProject::parsingFinished);
|
||||
}
|
||||
|
||||
if (target && success) {
|
||||
void QmlProject::parsingFinished(const Target *target, bool success)
|
||||
{
|
||||
// trigger only once
|
||||
disconnect(this, &QmlProject::anyParsingFinished, this, &QmlProject::parsingFinished);
|
||||
|
||||
auto target = activeTarget();
|
||||
if (!target)
|
||||
// FIXME: what to do in this case?
|
||||
if (!target || !success || !activeTarget())
|
||||
return;
|
||||
|
||||
auto targetActive = activeTarget();
|
||||
auto qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(
|
||||
target->buildSystem());
|
||||
targetActive->buildSystem());
|
||||
|
||||
const Utils::FilePath mainUiFile = qmlBuildSystem->mainUiFilePath();
|
||||
|
||||
if (mainUiFile.completeSuffix() == "ui.qml" && mainUiFile.exists()) {
|
||||
QTimer::singleShot(1000, [mainUiFile]() {
|
||||
Core::EditorManager::openEditor(mainUiFile,
|
||||
Utils::Id());
|
||||
Core::EditorManager::openEditor(mainUiFile, Utils::Id());
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::FilePaths uiFiles = collectUiQmlFilesForFolder(
|
||||
projectDirectory().pathAppended("content"));
|
||||
if (uiFiles.isEmpty())
|
||||
if (uiFiles.isEmpty()) {
|
||||
uiFiles = collectUiQmlFilesForFolder(projectDirectory());
|
||||
|
||||
if (uiFiles.isEmpty())
|
||||
uiFiles = collectQmlFiles();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!uiFiles.isEmpty()) {
|
||||
Utils::FilePath currentFile;
|
||||
if (auto cd = Core::EditorManager::currentDocument())
|
||||
currentFile = cd->filePath();
|
||||
|
||||
if (currentFile.isEmpty() || !isKnownFile(currentFile))
|
||||
if (currentFile.isEmpty() || !isKnownFile(currentFile)) {
|
||||
QTimer::singleShot(1000, [uiFiles]() {
|
||||
Core::EditorManager::openEditor(uiFiles.first(),
|
||||
Utils::Id());
|
||||
Core::ModeManager::activateMode(
|
||||
Core::Constants::MODE_DESIGN);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Core::EditorManager::openEditor(uiFiles.first(), Utils::Id());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
QmlBuildSystem::QmlBuildSystem(Target *target)
|
||||
: BuildSystem(target)
|
||||
Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *errorMessage)
|
||||
{
|
||||
m_canonicalProjectDir =
|
||||
target->project()->projectFilePath().canonicalPath().normalizedPathName().parentDir();
|
||||
RestoreResult result = Project::fromMap(map, errorMessage);
|
||||
if (result != RestoreResult::Ok)
|
||||
return result;
|
||||
|
||||
connect(target->project(), &Project::projectFileIsDirty,
|
||||
this, &QmlBuildSystem::refreshProjectFile);
|
||||
if (activeTarget())
|
||||
return RestoreResult::Ok;
|
||||
|
||||
// refresh first - project information is used e.g. to decide the default RC's
|
||||
refresh(Everything);
|
||||
// find a kit that matches prerequisites (prefer default one)
|
||||
const QList<Kit *> kits = Utils::filtered(KitManager::kits(), [this](const Kit *k) {
|
||||
return !containsType(projectIssues(k), Task::TaskType::Error)
|
||||
&& DeviceTypeKitAspect::deviceTypeId(k)
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
|
||||
});
|
||||
|
||||
// FIXME: Check. Probably bogus after the BuildSystem move.
|
||||
// // addedTarget calls updateEnabled on the runconfigurations
|
||||
// // which needs to happen after refresh
|
||||
// const QLis<Target> targetList = targets();
|
||||
// for (Target *t : targetList)
|
||||
// addedTarget(t);
|
||||
if (!kits.isEmpty()) {
|
||||
if (kits.contains(KitManager::defaultKit()))
|
||||
addTargetForDefaultKit();
|
||||
else
|
||||
addTargetForKit(kits.first());
|
||||
}
|
||||
|
||||
connect(target->project(), &Project::activeTargetChanged,
|
||||
this, &QmlBuildSystem::onActiveTargetChanged);
|
||||
updateDeploymentData();
|
||||
// FIXME: are there any other way?
|
||||
// What if it's not a Design Studio project? What should we do then?
|
||||
if (QmlProject::isQtDesignStudio()) {
|
||||
int preferedVersion = preferedQtTarget(activeTarget());
|
||||
|
||||
// if (activeTarget())
|
||||
// removeTarget(activeTarget());
|
||||
setKitWithVersion(preferedVersion, kits);
|
||||
}
|
||||
|
||||
return RestoreResult::Ok;
|
||||
}
|
||||
|
||||
QmlBuildSystem::~QmlBuildSystem() = default;
|
||||
|
||||
void QmlBuildSystem::triggerParsing()
|
||||
bool QmlProject::setKitWithVersion(const int qtMajorVersion, const QList<Kit *> kits)
|
||||
{
|
||||
refresh(Everything);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::onActiveTargetChanged(Target *)
|
||||
{
|
||||
// make sure e.g. the default qml imports are adapted
|
||||
refresh(Configuration);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::onKitChanged()
|
||||
{
|
||||
// make sure e.g. the default qml imports are adapted
|
||||
refresh(Configuration);
|
||||
}
|
||||
|
||||
Utils::FilePath QmlBuildSystem::canonicalProjectDir() const
|
||||
{
|
||||
return m_canonicalProjectDir;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::parseProject(RefreshOptions options)
|
||||
{
|
||||
if (options & Files) {
|
||||
if (options & ProjectFile)
|
||||
m_projectItem.reset();
|
||||
if (!m_projectItem) {
|
||||
QString errorMessage;
|
||||
m_projectItem = QmlProjectFileFormat::parseProjectFile(projectFilePath(), &errorMessage);
|
||||
if (m_projectItem) {
|
||||
connect(m_projectItem.get(),
|
||||
&QmlProjectItem::qmlFilesChanged,
|
||||
this,
|
||||
&QmlBuildSystem::refreshFiles);
|
||||
|
||||
} else {
|
||||
MessageManager::writeFlashing(
|
||||
Tr::tr("Error while loading project file %1.").arg(projectFilePath().toUserOutput()));
|
||||
MessageManager::writeSilently(errorMessage);
|
||||
}
|
||||
}
|
||||
if (m_projectItem) {
|
||||
m_projectItem->setSourceDirectory(canonicalProjectDir());
|
||||
if (m_projectItem->targetDirectory().isEmpty())
|
||||
m_projectItem->setTargetDirectory(canonicalProjectDir());
|
||||
|
||||
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
|
||||
QStringList files = m_projectItem->files();
|
||||
modelManager
|
||||
->updateSourceFiles(Utils::transform(files,
|
||||
[](const QString &p) {
|
||||
return Utils::FilePath::fromString(p);
|
||||
}),
|
||||
true);
|
||||
}
|
||||
QString mainFilePath = m_projectItem->mainFile();
|
||||
if (!mainFilePath.isEmpty()) {
|
||||
mainFilePath
|
||||
= QDir(canonicalProjectDir().toString()).absoluteFilePath(mainFilePath);
|
||||
Utils::FileReader reader;
|
||||
QString errorMessage;
|
||||
if (!reader.fetch(Utils::FilePath::fromString(mainFilePath), &errorMessage)) {
|
||||
MessageManager::writeFlashing(Tr::tr("Warning while loading project file %1.")
|
||||
.arg(projectFilePath().toUserOutput()));
|
||||
MessageManager::writeSilently(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
generateProjectTree();
|
||||
}
|
||||
|
||||
if (options & Configuration) {
|
||||
// update configuration
|
||||
}
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setFileSettingInProjectFile(const QString &setting,
|
||||
const FilePath &mainFilePath,
|
||||
const FilePath &oldFile)
|
||||
{
|
||||
// make sure to change it also in the qmlproject file
|
||||
const Utils::FilePath qmlProjectFilePath = project()->projectFilePath();
|
||||
Core::FileChangeBlocker fileChangeBlocker(qmlProjectFilePath);
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(qmlProjectFilePath);
|
||||
TextEditor::TextDocument *document = nullptr;
|
||||
if (!editors.isEmpty()) {
|
||||
document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
|
||||
if (document && document->isModified())
|
||||
if (!Core::DocumentManager::saveDocument(document))
|
||||
const QList<Kit *> qtVersionkits = Utils::filtered(kits, [qtMajorVersion](const Kit *k) {
|
||||
if (!k->isAutoDetected())
|
||||
return false;
|
||||
}
|
||||
|
||||
QString fileContent;
|
||||
QString error;
|
||||
Utils::TextFileFormat textFileFormat;
|
||||
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||
if (Utils::TextFileFormat::readFile(qmlProjectFilePath, codec, &fileContent, &textFileFormat, &error)
|
||||
!= Utils::TextFileFormat::ReadSuccess) {
|
||||
qWarning() << "Failed to read file" << qmlProjectFilePath << ":" << error;
|
||||
}
|
||||
|
||||
const QString settingQmlCode = setting + ":";
|
||||
|
||||
const Utils::FilePath projectDir = project()->projectFilePath().parentDir();
|
||||
const QString relativePath = mainFilePath.relativeChildPath(projectDir).path();
|
||||
|
||||
if (fileContent.indexOf(settingQmlCode) < 0) {
|
||||
QString addedText = QString("\n %1 \"%2\"\n").arg(settingQmlCode).arg(relativePath);
|
||||
auto index = fileContent.lastIndexOf("}");
|
||||
fileContent.insert(index, addedText);
|
||||
} else {
|
||||
QString originalFileName = oldFile.path();
|
||||
originalFileName.replace(".", "\\.");
|
||||
const QRegularExpression expression(QString("%1\\s*\"(%2)\"").arg(settingQmlCode).arg(originalFileName));
|
||||
|
||||
const QRegularExpressionMatch match = expression.match(fileContent);
|
||||
|
||||
fileContent.replace(match.capturedStart(1),
|
||||
match.capturedLength(1),
|
||||
relativePath);
|
||||
}
|
||||
|
||||
if (!textFileFormat.writeFile(qmlProjectFilePath, fileContent, &error))
|
||||
qWarning() << "Failed to write file" << qmlProjectFilePath << ":" << error;
|
||||
|
||||
refresh(Everything);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refresh(RefreshOptions options)
|
||||
{
|
||||
ParseGuard guard = guardParsingRun();
|
||||
parseProject(options);
|
||||
|
||||
if (options & Files)
|
||||
generateProjectTree();
|
||||
|
||||
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
if (!modelManager)
|
||||
return;
|
||||
|
||||
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
||||
= modelManager->defaultProjectInfoForProject(project(),
|
||||
project()->files(Project::HiddenRccFolders));
|
||||
const QStringList searchPaths = makeAbsolute(canonicalProjectDir(), customImportPaths());
|
||||
for (const QString &searchPath : searchPaths)
|
||||
projectInfo.importPaths.maybeInsert(Utils::FilePath::fromString(searchPath),
|
||||
QmlJS::Dialect::Qml);
|
||||
|
||||
modelManager->updateProjectInfo(projectInfo, project());
|
||||
|
||||
guard.markAsSuccess();
|
||||
|
||||
emit projectChanged();
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::mainFile() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return FilePath::fromString(m_projectItem->mainFile());
|
||||
return {};
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::mainUiFile() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return FilePath::fromString(m_projectItem->mainUiFile());
|
||||
return {};
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::mainFilePath() const
|
||||
{
|
||||
const auto mainFileString = mainFile();
|
||||
|
||||
if (mainFileString.isEmpty())
|
||||
return {};
|
||||
|
||||
return projectDirectory().resolvePath(mainFileString);
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::mainUiFilePath() const
|
||||
{
|
||||
const auto mainUiFileString = mainUiFile();
|
||||
|
||||
if (mainUiFileString.isEmpty())
|
||||
return {};
|
||||
|
||||
return projectDirectory().resolvePath(mainUiFileString);
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainFileInProjectFile(const FilePath &newMainFilePath)
|
||||
{
|
||||
return setFileSettingInProjectFile("mainFile", newMainFilePath, mainFile());
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainUiFileInProjectFile(const FilePath &newMainUiFilePath)
|
||||
{
|
||||
return setMainUiFileInMainFile(newMainUiFilePath)
|
||||
&& setFileSettingInProjectFile("mainUiFile", newMainUiFilePath, mainUiFile());
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::setMainUiFileInMainFile(const FilePath &newMainUiFilePath)
|
||||
{
|
||||
Core::FileChangeBlocker fileChangeBlocker(mainFilePath());
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForFilePath(mainFilePath());
|
||||
TextEditor::TextDocument *document = nullptr;
|
||||
if (!editors.isEmpty()) {
|
||||
document = qobject_cast<TextEditor::TextDocument*>(editors.first()->document());
|
||||
if (document && document->isModified())
|
||||
if (!Core::DocumentManager::saveDocument(document))
|
||||
if (k->isReplacementKit())
|
||||
return false;
|
||||
|
||||
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
|
||||
return (version && version->qtVersion().majorVersion() == qtMajorVersion);
|
||||
});
|
||||
|
||||
if (!qtVersionkits.isEmpty()) {
|
||||
if (qtVersionkits.contains(KitManager::defaultKit()))
|
||||
addTargetForDefaultKit();
|
||||
else
|
||||
addTargetForKit(qtVersionkits.first());
|
||||
}
|
||||
|
||||
QString fileContent;
|
||||
QString error;
|
||||
Utils::TextFileFormat textFileFormat;
|
||||
const QTextCodec *codec = QTextCodec::codecForName("UTF-8"); // qml files are defined to be utf-8
|
||||
if (Utils::TextFileFormat::readFile(mainFilePath(), codec, &fileContent, &textFileFormat, &error)
|
||||
!= Utils::TextFileFormat::ReadSuccess) {
|
||||
qWarning() << "Failed to read file" << mainFilePath() << ":" << error;
|
||||
}
|
||||
|
||||
const QString currentMain = QString("%1 {").arg(mainUiFilePath().baseName());
|
||||
const QString newMain = QString("%1 {").arg(newMainUiFilePath.baseName());
|
||||
|
||||
if (fileContent.contains(currentMain))
|
||||
fileContent.replace(currentMain, newMain);
|
||||
|
||||
if (!textFileFormat.writeFile(mainFilePath(), fileContent, &error))
|
||||
qWarning() << "Failed to write file" << mainFilePath() << ":" << error;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::qtForMCUs() const
|
||||
Utils::FilePaths QmlProject::collectUiQmlFilesForFolder(const Utils::FilePath &folder) const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->qtForMCUs();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::qt6Project() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->qt6Project();
|
||||
return false;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setMainFile(const QString &mainFilePath)
|
||||
{
|
||||
if (m_projectItem)
|
||||
m_projectItem->setMainFile(mainFilePath);
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::targetDirectory() const
|
||||
{
|
||||
if (DeviceTypeKitAspect::deviceTypeId(kit())
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
return canonicalProjectDir();
|
||||
|
||||
return m_projectItem ? m_projectItem->targetDirectory() : FilePath();
|
||||
}
|
||||
|
||||
FilePath QmlBuildSystem::targetFile(const FilePath &sourceFile) const
|
||||
{
|
||||
const FilePath sourceDir = m_projectItem ? m_projectItem->sourceDirectory()
|
||||
: canonicalProjectDir();
|
||||
const FilePath targetDir = targetDirectory();
|
||||
const FilePath relative = sourceFile.relativePathFrom(sourceDir);
|
||||
return targetDir.resolvePath(relative);
|
||||
}
|
||||
|
||||
Utils::EnvironmentItems QmlBuildSystem::environment() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->environment();
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::customImportPaths() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->importPaths();
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::customFileSelectors() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->fileSelectors();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::multilanguageSupport() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->multilanguageSupport();
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::supportedLanguages() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->supportedLanguages();
|
||||
return {};
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setSupportedLanguages(QStringList languages)
|
||||
{
|
||||
if (m_projectItem)
|
||||
m_projectItem->setSupportedLanguages(languages);
|
||||
}
|
||||
|
||||
QString QmlBuildSystem::primaryLanguage() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->primaryLanguage();
|
||||
return {};
|
||||
}
|
||||
|
||||
void QmlBuildSystem::setPrimaryLanguage(QString language)
|
||||
{
|
||||
if (m_projectItem)
|
||||
m_projectItem->setPrimaryLanguage(language);
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refreshProjectFile()
|
||||
{
|
||||
refresh(QmlBuildSystem::ProjectFile | Files);
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths)
|
||||
{
|
||||
if (path.isEmpty())
|
||||
return relativePaths;
|
||||
|
||||
const QDir baseDir(path.toString());
|
||||
return Utils::transform(relativePaths, [&baseDir](const QString &path) {
|
||||
return QDir::cleanPath(baseDir.absoluteFilePath(path));
|
||||
const Utils::FilePaths uiFiles = files([&](const Node *node) {
|
||||
return node->filePath().completeSuffix() == "ui.qml"
|
||||
&& node->filePath().parentDir() == folder;
|
||||
});
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
|
||||
{
|
||||
if (m_blockFilesUpdate) {
|
||||
qCDebug(infoLogger) << "Auto files refresh blocked.";
|
||||
return;
|
||||
}
|
||||
refresh(Files);
|
||||
if (!removed.isEmpty()) {
|
||||
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
|
||||
modelManager->removeFiles(
|
||||
Utils::transform<QList<Utils::FilePath>>(removed, [](const QString &s) {
|
||||
return Utils::FilePath::fromString(s);
|
||||
}));
|
||||
}
|
||||
}
|
||||
refreshTargetDirectory();
|
||||
}
|
||||
|
||||
void QmlBuildSystem::refreshTargetDirectory()
|
||||
{
|
||||
updateDeploymentData();
|
||||
return uiFiles;
|
||||
}
|
||||
|
||||
Tasks QmlProject::projectIssues(const Kit *k) const
|
||||
@@ -572,8 +181,8 @@ Tasks QmlProject::projectIssues(const Kit *k) const
|
||||
if (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
|
||||
if (version->type() == QtSupport::Constants::DESKTOPQT) {
|
||||
if (version->qmlRuntimeFilePath().isEmpty()) {
|
||||
result.append(createProjectTask(Task::TaskType::Error,
|
||||
Tr::tr("Qt version has no QML utility.")));
|
||||
result.append(
|
||||
createProjectTask(Task::TaskType::Error, tr("Qt version has no QML utility.")));
|
||||
}
|
||||
} else {
|
||||
// Non-desktop Qt on a desktop device? We don't support that.
|
||||
@@ -589,68 +198,10 @@ Tasks QmlProject::projectIssues(const Kit *k) const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmlProject::isEditModePreferred() const
|
||||
{
|
||||
return !isQtDesignStudio();
|
||||
}
|
||||
|
||||
Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *errorMessage)
|
||||
{
|
||||
RestoreResult result = Project::fromMap(map, errorMessage);
|
||||
if (result != RestoreResult::Ok)
|
||||
return result;
|
||||
|
||||
if (!activeTarget()) {
|
||||
// find a kit that matches prerequisites (prefer default one)
|
||||
const QList<Kit *> kits = Utils::filtered(KitManager::kits(), [this](const Kit *k) {
|
||||
return !containsType(projectIssues(k), Task::TaskType::Error)
|
||||
&& DeviceTypeKitAspect::deviceTypeId(k)
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
|
||||
});
|
||||
|
||||
if (!kits.isEmpty()) {
|
||||
if (kits.contains(KitManager::defaultKit()))
|
||||
addTargetForDefaultKit();
|
||||
else
|
||||
addTargetForKit(kits.first());
|
||||
}
|
||||
|
||||
if (QmlProject::isQtDesignStudio()) {
|
||||
auto setKitWithVersion = [&](int qtMajorVersion) {
|
||||
const QList<Kit *> qtVersionkits
|
||||
= Utils::filtered(kits, [qtMajorVersion](const Kit *k) {
|
||||
if (!k->isAutoDetected())
|
||||
return false;
|
||||
if (k->isReplacementKit())
|
||||
return false;
|
||||
QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
|
||||
return (version && version->qtVersion().majorVersion() == qtMajorVersion);
|
||||
});
|
||||
if (!qtVersionkits.isEmpty()) {
|
||||
if (qtVersionkits.contains(KitManager::defaultKit()))
|
||||
addTargetForDefaultKit();
|
||||
else
|
||||
addTargetForKit(qtVersionkits.first());
|
||||
}
|
||||
};
|
||||
|
||||
int preferedVersion = preferedQtTarget(activeTarget());
|
||||
|
||||
if (activeTarget())
|
||||
removeTarget(activeTarget());
|
||||
|
||||
setKitWithVersion(preferedVersion);
|
||||
}
|
||||
}
|
||||
|
||||
return RestoreResult::Ok;
|
||||
}
|
||||
|
||||
bool QmlProject::isQtDesignStudio()
|
||||
{
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
const QString qdsStandaloneEntry = "QML/Designer/StandAloneMode";
|
||||
|
||||
return settings->value(qdsStandaloneEntry, false).toBool();
|
||||
}
|
||||
|
||||
@@ -659,172 +210,30 @@ bool QmlProject::isQtDesignStudioStartedFromQtC()
|
||||
return qEnvironmentVariableIsSet(Constants::enviromentLaunchedQDS);
|
||||
}
|
||||
|
||||
ProjectExplorer::DeploymentKnowledge QmlProject::deploymentKnowledge() const
|
||||
DeploymentKnowledge QmlProject::deploymentKnowledge() const
|
||||
{
|
||||
return DeploymentKnowledge::Perfect;
|
||||
}
|
||||
|
||||
void QmlBuildSystem::generateProjectTree()
|
||||
bool QmlProject::isEditModePreferred() const
|
||||
{
|
||||
if (!m_projectItem)
|
||||
return;
|
||||
|
||||
auto newRoot = std::make_unique<QmlProjectNode>(project());
|
||||
|
||||
for (const QString &f : m_projectItem->files()) {
|
||||
const Utils::FilePath fileName = Utils::FilePath::fromString(f);
|
||||
const FileType fileType = (fileName == projectFilePath())
|
||||
? FileType::Project : FileNode::fileTypeForFileName(fileName);
|
||||
newRoot->addNestedNode(std::make_unique<FileNode>(fileName, fileType));
|
||||
}
|
||||
newRoot->addNestedNode(std::make_unique<FileNode>(projectFilePath(), FileType::Project));
|
||||
|
||||
setRootProjectNode(std::move(newRoot));
|
||||
refreshTargetDirectory();
|
||||
return !isQtDesignStudio();
|
||||
}
|
||||
|
||||
void QmlBuildSystem::updateDeploymentData()
|
||||
int QmlProject::preferedQtTarget(Target *target)
|
||||
{
|
||||
if (!m_projectItem)
|
||||
return;
|
||||
if (!target)
|
||||
return -1;
|
||||
|
||||
if (DeviceTypeKitAspect::deviceTypeId(kit())
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectExplorer::DeploymentData deploymentData;
|
||||
for (const QString &file : m_projectItem->files()) {
|
||||
deploymentData.addFile(
|
||||
FilePath::fromString(file),
|
||||
targetFile(Utils::FilePath::fromString(file)).parentDir().toString());
|
||||
}
|
||||
|
||||
setDeploymentData(deploymentData);
|
||||
auto buildSystem = qobject_cast<QmlBuildSystem *>(target->buildSystem());
|
||||
return (buildSystem && buildSystem->qt6Project()) ? 6 : 5;
|
||||
}
|
||||
|
||||
QVariant QmlBuildSystem::additionalData(Id id) const
|
||||
bool QmlProject::allowOnlySingleProject()
|
||||
{
|
||||
if (id == Constants::customFileSelectorsData)
|
||||
return customFileSelectors();
|
||||
if (id == Constants::supportedLanguagesData)
|
||||
return supportedLanguages();
|
||||
if (id == Constants::primaryLanguageData)
|
||||
return primaryLanguage();
|
||||
if (id == Constants::customForceFreeTypeData)
|
||||
return forceFreeType();
|
||||
if (id == Constants::customQtForMCUs)
|
||||
return qtForMCUs();
|
||||
if (id == Constants::customQt6Project)
|
||||
return qt6Project();
|
||||
if (id == Constants::mainFilePath)
|
||||
return mainFilePath().toString();
|
||||
if (id == Constants::customImportPaths)
|
||||
return customImportPaths();
|
||||
if (id == Constants::canonicalProjectDir)
|
||||
return canonicalProjectDir().toString();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const
|
||||
{
|
||||
if (dynamic_cast<QmlProjectNode *>(context)) {
|
||||
if (action == AddNewFile || action == EraseFile)
|
||||
return true;
|
||||
QTC_ASSERT(node, return false);
|
||||
|
||||
if (action == Rename && node->asFileNode()) {
|
||||
const FileNode *fileNode = node->asFileNode();
|
||||
QTC_ASSERT(fileNode, return false);
|
||||
return fileNode->fileType() != FileType::Project;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return BuildSystem::supportsAction(context, action, node);
|
||||
}
|
||||
|
||||
QmlProject *QmlBuildSystem::qmlProject() const
|
||||
{
|
||||
return static_cast<QmlProject *>(BuildSystem::project());
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::forceFreeType() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->forceFreeType();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::widgetApp() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->widgetApp();
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::shaderToolArgs() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->shaderToolArgs();
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::shaderToolFiles() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->shaderToolFiles();
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::importPaths() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->importPaths();
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList QmlBuildSystem::files() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem->files();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::addFiles(Node *context, const FilePaths &filePaths, FilePaths *)
|
||||
{
|
||||
if (!dynamic_cast<QmlProjectNode *>(context))
|
||||
return false;
|
||||
|
||||
FilePaths toAdd;
|
||||
for (const FilePath &filePath : filePaths) {
|
||||
if (!m_projectItem->matchesFile(filePath.toString()))
|
||||
toAdd << filePaths;
|
||||
}
|
||||
return toAdd.isEmpty();
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::deleteFiles(Node *context, const FilePaths &filePaths)
|
||||
{
|
||||
if (dynamic_cast<QmlProjectNode *>(context))
|
||||
return true;
|
||||
|
||||
return BuildSystem::deleteFiles(context, filePaths);
|
||||
}
|
||||
|
||||
bool QmlBuildSystem::renameFile(Node * context, const FilePath &oldFilePath, const FilePath &newFilePath)
|
||||
{
|
||||
if (dynamic_cast<QmlProjectNode *>(context)) {
|
||||
if (oldFilePath.endsWith(mainFile().path()))
|
||||
return setMainFileInProjectFile(newFilePath);
|
||||
if (oldFilePath.endsWith(mainUiFile().path()))
|
||||
return setMainUiFileInProjectFile(newFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return BuildSystem::renameFile(context, oldFilePath, newFilePath);
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
auto key = "QML/Designer/AllowMultipleProjects";
|
||||
return !settings->value(key, false).toBool();
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
@@ -1,150 +1,31 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "buildsystem/qmlbuildsystem.h" // IWYU pragma: keep
|
||||
#include "qmlprojectmanager_global.h"
|
||||
|
||||
#include <projectexplorer/buildsystem.h>
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProject;
|
||||
class QmlProjectItem;
|
||||
|
||||
class QMLPROJECTMANAGER_EXPORT QmlBuildSystem : public ProjectExplorer::BuildSystem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QmlBuildSystem(ProjectExplorer::Target *target);
|
||||
~QmlBuildSystem();
|
||||
|
||||
void triggerParsing() final;
|
||||
|
||||
bool supportsAction(ProjectExplorer::Node *context,
|
||||
ProjectExplorer::ProjectAction action,
|
||||
const ProjectExplorer::Node *node) const override;
|
||||
bool addFiles(ProjectExplorer::Node *context,
|
||||
const Utils::FilePaths &filePaths, Utils::FilePaths *notAdded = nullptr) override;
|
||||
bool deleteFiles(ProjectExplorer::Node *context,
|
||||
const Utils::FilePaths &filePaths) override;
|
||||
bool renameFile(ProjectExplorer::Node *context,
|
||||
const Utils::FilePath &oldFilePath, const Utils::FilePath &newFilePath) override;
|
||||
QString name() const override { return QLatin1String("qml"); }
|
||||
|
||||
QmlProject *qmlProject() const;
|
||||
|
||||
QVariant additionalData(Utils::Id id) const override;
|
||||
|
||||
enum RefreshOption {
|
||||
ProjectFile = 0x01,
|
||||
Files = 0x02,
|
||||
Configuration = 0x04,
|
||||
Everything = ProjectFile | Files | Configuration
|
||||
};
|
||||
Q_DECLARE_FLAGS(RefreshOptions,RefreshOption)
|
||||
|
||||
void refresh(RefreshOptions options);
|
||||
|
||||
Utils::FilePath canonicalProjectDir() const;
|
||||
Utils::FilePath mainFile() const;
|
||||
Utils::FilePath mainUiFile() const;
|
||||
Utils::FilePath mainFilePath() const;
|
||||
Utils::FilePath mainUiFilePath() const;
|
||||
|
||||
bool setMainFileInProjectFile(const Utils::FilePath &newMainFilePath);
|
||||
bool setMainUiFileInProjectFile(const Utils::FilePath &newMainUiFilePath);
|
||||
bool setMainUiFileInMainFile(const Utils::FilePath &newMainUiFilePath);
|
||||
|
||||
bool qtForMCUs() const;
|
||||
bool qt6Project() const;
|
||||
void setMainFile(const QString &mainFilePath);
|
||||
Utils::FilePath targetDirectory() const;
|
||||
Utils::FilePath targetFile(const Utils::FilePath &sourceFile) const;
|
||||
|
||||
Utils::EnvironmentItems environment() const;
|
||||
QStringList customImportPaths() const;
|
||||
QStringList customFileSelectors() const;
|
||||
bool multilanguageSupport() const;
|
||||
QStringList supportedLanguages() const;
|
||||
void setSupportedLanguages(QStringList languages);
|
||||
QString primaryLanguage() const;
|
||||
void setPrimaryLanguage(QString language);
|
||||
bool forceFreeType() const;
|
||||
bool widgetApp() const;
|
||||
QStringList shaderToolArgs() const;
|
||||
QStringList shaderToolFiles() const;
|
||||
QStringList importPaths() const;
|
||||
QStringList files() const;
|
||||
|
||||
bool addFiles(const QStringList &filePaths);
|
||||
|
||||
void refreshProjectFile();
|
||||
|
||||
static Utils::FilePath activeMainFilePath();
|
||||
static QStringList makeAbsolute(const Utils::FilePath &path, const QStringList &relativePaths);
|
||||
|
||||
void generateProjectTree();
|
||||
void updateDeploymentData();
|
||||
void refreshFiles(const QSet<QString> &added, const QSet<QString> &removed);
|
||||
void refreshTargetDirectory();
|
||||
void onActiveTargetChanged(ProjectExplorer::Target *target);
|
||||
void onKitChanged();
|
||||
|
||||
// plain format
|
||||
void parseProject(RefreshOptions options);
|
||||
|
||||
signals:
|
||||
void projectChanged();
|
||||
|
||||
private:
|
||||
bool setFileSettingInProjectFile(const QString &setting,
|
||||
const Utils::FilePath &mainFilePath,
|
||||
const Utils::FilePath &oldFile);
|
||||
|
||||
std::unique_ptr<QmlProjectItem> m_projectItem;
|
||||
Utils::FilePath m_canonicalProjectDir;
|
||||
bool m_blockFilesUpdate = false;
|
||||
friend class FilesUpdateBlocker;
|
||||
};
|
||||
|
||||
class FilesUpdateBlocker {
|
||||
public:
|
||||
FilesUpdateBlocker(QmlBuildSystem* bs): m_bs(bs) {
|
||||
if (m_bs)
|
||||
m_bs->m_blockFilesUpdate = true;
|
||||
}
|
||||
|
||||
~FilesUpdateBlocker() {
|
||||
if (m_bs) {
|
||||
m_bs->m_blockFilesUpdate = false;
|
||||
m_bs->refresh(QmlBuildSystem::Everything);
|
||||
}
|
||||
}
|
||||
private:
|
||||
QPointer<QmlBuildSystem> m_bs;
|
||||
};
|
||||
|
||||
class QMLPROJECTMANAGER_EXPORT QmlProject : public ProjectExplorer::Project
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QmlProject(const Utils::FilePath &filename);
|
||||
|
||||
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
|
||||
~QmlProject(){
|
||||
qDebug() << "Closing the project";
|
||||
};
|
||||
|
||||
static bool isQtDesignStudio();
|
||||
static bool isQtDesignStudioStartedFromQtC();
|
||||
|
||||
bool isEditModePreferred() const override;
|
||||
|
||||
ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final;
|
||||
|
||||
protected:
|
||||
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override;
|
||||
|
||||
@@ -153,9 +34,35 @@ private:
|
||||
Utils::FilePaths collectUiQmlFilesForFolder(const Utils::FilePath &folder) const;
|
||||
Utils::FilePaths collectQmlFiles() const;
|
||||
|
||||
QMetaObject::Connection m_openFileConnection;
|
||||
bool setKitWithVersion(const int qtMajorVersion, const QList<ProjectExplorer::Kit *> kits);
|
||||
|
||||
bool allowOnlySingleProject();
|
||||
int preferedQtTarget(ProjectExplorer::Target *target);
|
||||
|
||||
private slots:
|
||||
void parsingFinished(const ProjectExplorer::Target *target, bool success);
|
||||
};
|
||||
|
||||
class FilesUpdateBlocker
|
||||
{
|
||||
public:
|
||||
FilesUpdateBlocker(QmlBuildSystem *bs)
|
||||
: m_bs(bs)
|
||||
{
|
||||
if (m_bs)
|
||||
m_bs->m_blockFilesUpdate = true;
|
||||
}
|
||||
|
||||
~FilesUpdateBlocker()
|
||||
{
|
||||
if (m_bs) {
|
||||
m_bs->m_blockFilesUpdate = false;
|
||||
m_bs->refresh(QmlBuildSystem::RefreshOptions::Project);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QPointer<QmlBuildSystem> m_bs;
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QmlProjectManager::QmlBuildSystem::RefreshOptions)
|
||||
|
||||
@@ -33,12 +33,14 @@ QtcPlugin {
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "File Format"
|
||||
prefix: "fileformat/"
|
||||
name: "Build System"
|
||||
prefix: "buildsystem/"
|
||||
files: [
|
||||
"filefilteritems.cpp", "filefilteritems.h",
|
||||
"qmlprojectfileformat.cpp", "qmlprojectfileformat.h",
|
||||
"qmlprojectitem.cpp", "qmlprojectitem.h",
|
||||
"qmlbuildsystem.cpp", "qmlbuildsystem.h",
|
||||
"projectitem/filefilteritems.cpp", "projectitem/filefilteritems.h",
|
||||
"projectitem/qmlprojectitem.cpp", "projectitem/qmlprojectitem.h",
|
||||
"projectitem/converters.h",
|
||||
"projectnode/qmlprojectnodes.cpp", "projectnode/qmlprojectnodes.h"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "projectfilecontenttools.h"
|
||||
#include "cmakegen/cmakeprojectconverter.h"
|
||||
#include "cmakegen/generatecmakelists.h"
|
||||
#include "qmlprojectgen/qmlprojectgenerator.h"
|
||||
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
add_subdirectory(fileformat)
|
||||
add_subdirectory(projectitem)
|
||||
|
||||
@@ -9,11 +9,12 @@ foreach(source IN LISTS QmlProjectManagerSources)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_qtc_test(tst_qml_fileformat
|
||||
DEPENDS QmlJS Utils
|
||||
INCLUDES "${PROJECT_SOURCE_DIR}/src/plugins/qmlprojectmanager/fileformat"
|
||||
DEFINES
|
||||
QT_CREATOR
|
||||
SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
SOURCES tst_fileformat.cpp ${fileformat_sources}
|
||||
)
|
||||
#add_qtc_test(tst_qml_fileformat
|
||||
# DEPENDS QmlJS Utils
|
||||
# INCLUDES "${PROJECT_SOURCE_DIR}/src/plugins/qmlprojectmanager/fileformat"
|
||||
# DEFINES
|
||||
# QT_CREATOR
|
||||
# SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
# SOURCES tst_fileformat.cpp ${fileformat_sources}
|
||||
#)
|
||||
|
||||
|
||||
25
tests/auto/qml/qmlprojectmanager/projectitem/CMakeLists.txt
Normal file
25
tests/auto/qml/qmlprojectmanager/projectitem/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
set(WITH_TESTS ON)
|
||||
|
||||
find_package(Googletest MODULE)
|
||||
|
||||
set(QmlProjectItemDir "${PROJECT_SOURCE_DIR}/src/plugins/qmlprojectmanager/buildsystem/projectitem")
|
||||
|
||||
add_qtc_test(tst_qml_projectitem
|
||||
DEPENDS QmlProjectManager Utils QmlJS Googletest
|
||||
INCLUDES "${QmlProjectItemDir}"
|
||||
DEFINES
|
||||
QT_CREATOR
|
||||
SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
TESTDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
|
||||
TESTS_ENABLED_QMLPROJECTITEM
|
||||
SOURCES
|
||||
tst_projectitem.cpp
|
||||
test-getters.cpp
|
||||
test-setters.cpp
|
||||
test-converters.cpp
|
||||
test-filefilters.cpp
|
||||
common.h
|
||||
"${QmlProjectItemDir}/qmlprojectitem.cpp"
|
||||
"${QmlProjectItemDir}/converters.cpp"
|
||||
"${QmlProjectItemDir}/filefilteritems.cpp"
|
||||
)
|
||||
46
tests/auto/qml/qmlprojectmanager/projectitem/README.md
Normal file
46
tests/auto/qml/qmlprojectmanager/projectitem/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# QmlProject ProjectItem Tests
|
||||
|
||||
## Content
|
||||
|
||||
This test bundle covers following functionalities of QmlProjectItem class;
|
||||
|
||||
* **Getter Functions**: Tests if getter functions are returning correct types with correct values
|
||||
* **Setter Functions**: Tests if setter functions are updating the internal JSON object as expected
|
||||
* **Converter Functions:** Tests if QmlProjectToJson and JsonToQmlProject functions are working as expected
|
||||
* **File Filter Functions:** Tests if file filters are initialized properly
|
||||
|
||||
## Data set folder structure
|
||||
|
||||
The current folder hierarchy is as following;
|
||||
|
||||
```text
|
||||
| data
|
||||
| -> converter
|
||||
| | -> test-set-1
|
||||
| | | -> testfile.qmlproject
|
||||
| | | -> testfile.qmltojson
|
||||
| | | -> testfile.jsontoqml
|
||||
| | -> test-set-2
|
||||
| | | -> testfile.qmlproject
|
||||
| | | -> testfile.qmltojson
|
||||
| | | -> testfile.jsontoqml
|
||||
| | -> test-set-..
|
||||
| | -> test-set-..
|
||||
| -> getter-setter
|
||||
| | -> testfile-1.qmlproject
|
||||
| | -> testfile-2.qmlproject
|
||||
| -> file-filters
|
||||
| | -> test-set-1
|
||||
| | -> test-set-...
|
||||
```
|
||||
|
||||
## Further information
|
||||
|
||||
Please see [data/README.md](data/README.md) for more information on the test set content.
|
||||
|
||||
## Contribution
|
||||
|
||||
Please update;
|
||||
|
||||
* This README whenever you change the test content
|
||||
* [data/README.md](data/README.md) whenever you update the `data` folder
|
||||
20
tests/auto/qml/qmlprojectmanager/projectitem/common.h
Normal file
20
tests/auto/qml/qmlprojectmanager/projectitem/common.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <gtest/gtest-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
static QDir testDataRootDir(QLatin1String(TESTDATA_DIR));
|
||||
|
||||
inline void PrintTo(const QString &qString, ::std::ostream *os)
|
||||
{
|
||||
*os << qUtf8Printable(qString);
|
||||
}
|
||||
47
tests/auto/qml/qmlprojectmanager/projectitem/data/README.md
Normal file
47
tests/auto/qml/qmlprojectmanager/projectitem/data/README.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Test Set Information
|
||||
|
||||
This document contains information about the purpose of each test sets.
|
||||
|
||||
## Getter/Setter test data
|
||||
|
||||
* **testfile-1.qmlproject**: QmlProject file with properly filled out object
|
||||
* **testfile-2.qmlproject**: QmlProject file with empty objects
|
||||
|
||||
## Converter test data
|
||||
|
||||
Test functions iterate over the "test-set-*" folders and run the tests by using the files inside them.
|
||||
|
||||
* **testfile.qmlproject**: Original QmlProject file that'll be converted
|
||||
* **testfile.qmltojson**: JSON-converted version of the .qmlproject file
|
||||
* **testfile.jsontoqml**: QmlProject-converted version of the .qmltojson file
|
||||
|
||||
### test-set-1
|
||||
|
||||
* **purpose**: testing complex qmlproject file convertion
|
||||
* **origin**: custom project
|
||||
|
||||
### test-set-2
|
||||
|
||||
* **purpose**: testing complex qmlproject file convertion
|
||||
* **origin**: material bundle example
|
||||
|
||||
### test-set-3
|
||||
|
||||
* **purpose**: testing complex qmlproject file convertion
|
||||
* **origin**: robot arm example
|
||||
|
||||
### test-set-4
|
||||
|
||||
* **purpose**: testing complex qmlproject file convertion
|
||||
* **origin**: outrun hvac example
|
||||
|
||||
### test-set-5
|
||||
|
||||
* **purpose**: testing fileselectors
|
||||
* **origin**: file selectors example from playground
|
||||
|
||||
## File Filters test data
|
||||
|
||||
Test data contains an example project folders that file filters will be initialized and tested.
|
||||
|
||||
* **filelist.txt**: List of the files need to be found by the file filters.
|
||||
@@ -0,0 +1,98 @@
|
||||
\\ prop: json-converted
|
||||
\\ prop: auto-generated
|
||||
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "content/Screen01.ui.qml"
|
||||
targetDirectory: "/opt/UntitledProject13"
|
||||
widgetApp: true
|
||||
importPaths: [ "imports","asset_imports" ]
|
||||
|
||||
qdsVersion: "4.0"
|
||||
quickVersion: "6.2"
|
||||
qt6Project: true
|
||||
qtForMCUs: true
|
||||
|
||||
multilanguageSupport: true
|
||||
primaryLanguage: "en"
|
||||
supportedLanguages: [ "en" ]
|
||||
|
||||
Environment {
|
||||
QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT: "1"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
}
|
||||
|
||||
ShaderTool {
|
||||
args: "-s --glsl "100 es,120,150" --hlsl 50 --msl 12"
|
||||
files: [ "content/shaders/*" ]
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.conf"
|
||||
files: [ "qtquickcontrols2.conf" ]
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.ttf;*.otf;*.ctf"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "asset_imports"
|
||||
filters: "*.mesh"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "qmldir"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag;*.trag"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp3;*.wav"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "content/Screen01.ui.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.ttf;*.otf;*.ctf"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.wav;*.mp3"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mp4"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag;*.trag"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.qml"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT: "1"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
/* Useful for debugging
|
||||
QSG_VISUALIZE=batches
|
||||
QSG_VISUALIZE=clip
|
||||
QSG_VISUALIZE=changes
|
||||
QSG_VISUALIZE=overdraw
|
||||
*/
|
||||
}
|
||||
|
||||
qt6Project: true
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports", "asset_imports" ]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/UntitledProject13"
|
||||
|
||||
qdsVersion: "4.0"
|
||||
|
||||
quickVersion: "6.2"
|
||||
|
||||
/* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */
|
||||
widgetApp: true
|
||||
|
||||
/* args: Specifies command line arguments for qsb tool to generate shaders.
|
||||
files: Specifies target files for qsb tool. If path is included, it must be relative to this file.
|
||||
Wildcard '*' can be used in the file name part of the path.
|
||||
e.g. files: [ "content/shaders/*.vert", "*.frag" ] */
|
||||
ShaderTool {
|
||||
args: "-s --glsl \"100 es,120,150\" --hlsl 50 --msl 12"
|
||||
files: [ "content/shaders/*" ]
|
||||
}
|
||||
|
||||
multilanguageSupport: true
|
||||
supportedLanguages: ["en"]
|
||||
primaryLanguage: "en"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
{
|
||||
"deployment": {
|
||||
"targetDirectory": "/opt/UntitledProject13"
|
||||
},
|
||||
"environment": {
|
||||
"QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT": "1",
|
||||
"QT_AUTO_SCREEN_SCALE_FACTOR": "1",
|
||||
"QT_ENABLE_HIGHDPI_SCALING": "0",
|
||||
"QT_LOGGING_RULES": "qt.qml.connections=false",
|
||||
"QT_QUICK_CONTROLS_CONF": "qtquickcontrols2.conf"
|
||||
},
|
||||
"fileGroups": {
|
||||
"config": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "qtquickcontrols2.conf"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
"*.conf"
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.ttf",
|
||||
"*.otf",
|
||||
"*.ctf"
|
||||
]
|
||||
},
|
||||
"image": {
|
||||
"directories": [
|
||||
"content",
|
||||
"asset_imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.jpeg",
|
||||
"*.jpg",
|
||||
"*.png",
|
||||
"*.svg",
|
||||
"*.hdr",
|
||||
".ktx"
|
||||
]
|
||||
},
|
||||
"javaScript": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
},
|
||||
"meshes": {
|
||||
"directories": [
|
||||
"asset_imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mesh"
|
||||
]
|
||||
},
|
||||
"qml": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports",
|
||||
"asset_imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.qml"
|
||||
]
|
||||
},
|
||||
"qmldir": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"qmldir"
|
||||
]
|
||||
},
|
||||
"shader": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.glsl",
|
||||
"*.glslv",
|
||||
"*.glslf",
|
||||
"*.vsh",
|
||||
"*.fsh",
|
||||
"*.vert",
|
||||
"*.frag",
|
||||
"*.trag"
|
||||
]
|
||||
},
|
||||
"sound": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp3",
|
||||
"*.wav"
|
||||
]
|
||||
},
|
||||
"video": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fileVersion": 1,
|
||||
"importPaths": [
|
||||
"imports",
|
||||
"asset_imports"
|
||||
],
|
||||
"language": {
|
||||
"multiLanguageSupport": true,
|
||||
"primaryLanguage": "en",
|
||||
"supportedLanguages": [
|
||||
"en"
|
||||
]
|
||||
},
|
||||
"mcuConfig": {
|
||||
},
|
||||
"runConfig": {
|
||||
"fileSelectors": [
|
||||
],
|
||||
"mainFile": "content/App.qml",
|
||||
"mainUiFile": "content/Screen01.ui.qml",
|
||||
"widgetApp": true
|
||||
},
|
||||
"shaderTool": {
|
||||
"args": [
|
||||
"-s",
|
||||
"--glsl",
|
||||
"\"100 es,120,150\"",
|
||||
"--hlsl",
|
||||
"50",
|
||||
"--msl",
|
||||
"12"
|
||||
],
|
||||
"files": [
|
||||
"content/shaders/*"
|
||||
]
|
||||
},
|
||||
"versions": {
|
||||
"designStudio": "4.0",
|
||||
"qtQuick": "6.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
\\ prop: json-converted
|
||||
\\ prop: auto-generated
|
||||
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "Screen01.ui.qml"
|
||||
targetDirectory: "/opt/MaterialLibrary"
|
||||
widgetApp: true
|
||||
importPaths: [ "imports","asset_imports" ]
|
||||
|
||||
qdsVersion: "3.9"
|
||||
quickVersion: ""
|
||||
qt6Project: false
|
||||
qtForMCUs: true
|
||||
|
||||
multilanguageSupport: true
|
||||
primaryLanguage: "en"
|
||||
supportedLanguages: [ "en" ]
|
||||
|
||||
Environment {
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
}
|
||||
|
||||
ShaderTool {
|
||||
args: "-s --glsl "100 es,120,150" --hlsl 50 --msl 12"
|
||||
files: [ "content/shaders/*" ]
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.conf"
|
||||
files: [ "qtquickcontrols2.conf" ]
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "asset_imports"
|
||||
filters: "*.mesh"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "content"
|
||||
filters: "*.mesh"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "qmldir"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp3;*.wav"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "Screen01.ui.qml"
|
||||
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.wav;*.mp3"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mp4"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.qml"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
/* Useful for debugging
|
||||
QSG_VISUALIZE=batches
|
||||
QSG_VISUALIZE=clip
|
||||
QSG_VISUALIZE=changes
|
||||
QSG_VISUALIZE=overdraw
|
||||
*/
|
||||
}
|
||||
|
||||
qt6Project: true
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports", "asset_imports" ]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/MaterialLibrary"
|
||||
|
||||
qdsVersion: "3.9"
|
||||
|
||||
/* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */
|
||||
widgetApp: true
|
||||
|
||||
/* args: Specifies command line arguments for qsb tool to generate shaders.
|
||||
files: Specifies target files for qsb tool. If path is included, it must be relative to this file.
|
||||
Wildcard '*' can be used in the file name part of the path.
|
||||
e.g. files: [ "content/shaders/*.vert", "*.frag" ] */
|
||||
ShaderTool {
|
||||
args: "-s --glsl \"100 es,120,150\" --hlsl 50 --msl 12"
|
||||
files: [ "content/shaders/*" ]
|
||||
}
|
||||
|
||||
multilanguageSupport: true
|
||||
supportedLanguages: ["en"]
|
||||
primaryLanguage: "en"
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"deployment": {
|
||||
"targetDirectory": "/opt/MaterialLibrary"
|
||||
},
|
||||
"environment": {
|
||||
"QT_AUTO_SCREEN_SCALE_FACTOR": "1",
|
||||
"QT_ENABLE_HIGHDPI_SCALING": "0",
|
||||
"QT_LOGGING_RULES": "qt.qml.connections=false",
|
||||
"QT_QUICK_CONTROLS_CONF": "qtquickcontrols2.conf"
|
||||
},
|
||||
"fileGroups": {
|
||||
"config": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "qtquickcontrols2.conf"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
"*.conf"
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.ttf",
|
||||
"*.otf"
|
||||
]
|
||||
},
|
||||
"image": {
|
||||
"directories": [
|
||||
"content",
|
||||
"asset_imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.jpeg",
|
||||
"*.jpg",
|
||||
"*.png",
|
||||
"*.svg",
|
||||
"*.hdr",
|
||||
".ktx"
|
||||
]
|
||||
},
|
||||
"javaScript": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
},
|
||||
"meshes": {
|
||||
"directories": [
|
||||
"asset_imports",
|
||||
"content"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mesh"
|
||||
]
|
||||
},
|
||||
"qml": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports",
|
||||
"asset_imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.qml"
|
||||
]
|
||||
},
|
||||
"qmldir": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"qmldir"
|
||||
]
|
||||
},
|
||||
"shader": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.glsl",
|
||||
"*.glslv",
|
||||
"*.glslf",
|
||||
"*.vsh",
|
||||
"*.fsh",
|
||||
"*.vert",
|
||||
"*.frag"
|
||||
]
|
||||
},
|
||||
"sound": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp3",
|
||||
"*.wav"
|
||||
]
|
||||
},
|
||||
"video": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fileVersion": 1,
|
||||
"importPaths": [
|
||||
"imports",
|
||||
"asset_imports"
|
||||
],
|
||||
"language": {
|
||||
"multiLanguageSupport": true,
|
||||
"primaryLanguage": "en",
|
||||
"supportedLanguages": [
|
||||
"en"
|
||||
]
|
||||
},
|
||||
"mcuConfig": {
|
||||
},
|
||||
"runConfig": {
|
||||
"fileSelectors": [
|
||||
],
|
||||
"mainFile": "content/App.qml",
|
||||
"mainUiFile": "Screen01.ui.qml",
|
||||
"widgetApp": true
|
||||
},
|
||||
"shaderTool": {
|
||||
"args": [
|
||||
"-s",
|
||||
"--glsl",
|
||||
"\"100 es,120,150\"",
|
||||
"--hlsl",
|
||||
"50",
|
||||
"--msl",
|
||||
"12"
|
||||
],
|
||||
"files": [
|
||||
"content/shaders/*"
|
||||
]
|
||||
},
|
||||
"versions": {
|
||||
"designStudio": "3.9"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
\\ prop: json-converted
|
||||
\\ prop: auto-generated
|
||||
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "content/MainScreen.ui.qml"
|
||||
targetDirectory: "/opt/RobotArm"
|
||||
widgetApp: true
|
||||
importPaths: [ "imports","asset_imports","backend_mock" ]
|
||||
|
||||
qdsVersion: "3.0"
|
||||
quickVersion: ""
|
||||
qt6Project: false
|
||||
qtForMCUs: true
|
||||
|
||||
multilanguageSupport: true
|
||||
primaryLanguage: "en"
|
||||
supportedLanguages: [ "en" ]
|
||||
|
||||
Environment {
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
}
|
||||
|
||||
ShaderTool {
|
||||
args: ""
|
||||
files: [ ]
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "backend_mock"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.conf"
|
||||
files: [ "qtquickcontrols2.conf" ]
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "content"
|
||||
filters: "*.mesh"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "qmldir"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp3;*.wav"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mp4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "content/MainScreen.ui.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "backend_mock"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.wav;*.mp3"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mp4"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
/* Useful for debugging
|
||||
QSG_VISUALIZE=batches
|
||||
QSG_VISUALIZE=clip
|
||||
QSG_VISUALIZE=changes
|
||||
QSG_VISUALIZE=overdraw
|
||||
*/
|
||||
}
|
||||
|
||||
qt6Project: true
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports", "asset_imports", "backend_mock" ]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/RobotArm"
|
||||
|
||||
qdsVersion: "3.0"
|
||||
|
||||
/* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */
|
||||
widgetApp: true
|
||||
|
||||
multilanguageSupport: true
|
||||
supportedLanguages: ["en"]
|
||||
primaryLanguage: "en"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"deployment": {
|
||||
"targetDirectory": "/opt/RobotArm"
|
||||
},
|
||||
"environment": {
|
||||
"QT_AUTO_SCREEN_SCALE_FACTOR": "1",
|
||||
"QT_ENABLE_HIGHDPI_SCALING": "0",
|
||||
"QT_LOGGING_RULES": "qt.qml.connections=false",
|
||||
"QT_QUICK_CONTROLS_CONF": "qtquickcontrols2.conf"
|
||||
},
|
||||
"fileGroups": {
|
||||
"config": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "qtquickcontrols2.conf"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
"*.conf"
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.ttf",
|
||||
"*.otf"
|
||||
]
|
||||
},
|
||||
"image": {
|
||||
"directories": [
|
||||
"content"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.jpeg",
|
||||
"*.jpg",
|
||||
"*.png",
|
||||
"*.svg",
|
||||
"*.hdr",
|
||||
".ktx"
|
||||
]
|
||||
},
|
||||
"javaScript": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
},
|
||||
"meshes": {
|
||||
"directories": [
|
||||
"content"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mesh"
|
||||
]
|
||||
},
|
||||
"qml": {
|
||||
"directories": [
|
||||
"content",
|
||||
"imports",
|
||||
"backend_mock"
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.qml"
|
||||
]
|
||||
},
|
||||
"qmldir": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"qmldir"
|
||||
]
|
||||
},
|
||||
"shader": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.glsl",
|
||||
"*.glslv",
|
||||
"*.glslf",
|
||||
"*.vsh",
|
||||
"*.fsh",
|
||||
"*.vert",
|
||||
"*.frag"
|
||||
]
|
||||
},
|
||||
"sound": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp3",
|
||||
"*.wav"
|
||||
]
|
||||
},
|
||||
"video": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mp4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fileVersion": 1,
|
||||
"importPaths": [
|
||||
"imports",
|
||||
"asset_imports",
|
||||
"backend_mock"
|
||||
],
|
||||
"language": {
|
||||
"multiLanguageSupport": true,
|
||||
"primaryLanguage": "en",
|
||||
"supportedLanguages": [
|
||||
"en"
|
||||
]
|
||||
},
|
||||
"mcuConfig": {
|
||||
},
|
||||
"runConfig": {
|
||||
"fileSelectors": [
|
||||
],
|
||||
"mainFile": "content/App.qml",
|
||||
"mainUiFile": "content/MainScreen.ui.qml",
|
||||
"widgetApp": true
|
||||
},
|
||||
"shaderTool": {
|
||||
},
|
||||
"versions": {
|
||||
"designStudio": "3.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
\\ prop: json-converted
|
||||
\\ prop: auto-generated
|
||||
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "OutrunHVAC.qml"
|
||||
mainUiFile: "Screen01.ui.qml"
|
||||
targetDirectory: "/opt/OutrunHVAC"
|
||||
widgetApp: false
|
||||
importPaths: [ "imports","asset_imports" ]
|
||||
|
||||
qdsVersion: ""
|
||||
quickVersion: ""
|
||||
qt6Project: false
|
||||
qtForMCUs: true
|
||||
|
||||
multilanguageSupport: false
|
||||
primaryLanguage: ""
|
||||
supportedLanguages: [ ]
|
||||
|
||||
Environment {
|
||||
QMLSCENE_CORE_PROFILE: "true"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
}
|
||||
|
||||
ShaderTool {
|
||||
args: ""
|
||||
files: [ ]
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.conf"
|
||||
files: [ "qtquickcontrols2.conf" ]
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.mesh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "qmldir"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* File generated by Qt Creator */
|
||||
|
||||
import QmlProject 1.1
|
||||
|
||||
Project {
|
||||
mainFile: "OutrunHVAC.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh;*.vert;*.frag"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QMLSCENE_CORE_PROFILE: "true"
|
||||
}
|
||||
|
||||
qt6Project: true
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports", "asset_imports" ]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/OutrunHVAC"
|
||||
|
||||
mainUiFile: "Screen01.ui.qml"
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"deployment": {
|
||||
"targetDirectory": "/opt/OutrunHVAC"
|
||||
},
|
||||
"environment": {
|
||||
"QMLSCENE_CORE_PROFILE": "true",
|
||||
"QT_AUTO_SCREEN_SCALE_FACTOR": "1",
|
||||
"QT_QUICK_CONTROLS_CONF": "qtquickcontrols2.conf"
|
||||
},
|
||||
"fileGroups": {
|
||||
"config": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "qtquickcontrols2.conf"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
"*.conf"
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.ttf",
|
||||
"*.otf"
|
||||
]
|
||||
},
|
||||
"image": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.jpeg",
|
||||
"*.jpg",
|
||||
"*.png",
|
||||
"*.svg",
|
||||
"*.hdr",
|
||||
".ktx"
|
||||
]
|
||||
},
|
||||
"javaScript": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
},
|
||||
"meshes": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.mesh",
|
||||
"*.vert",
|
||||
"*.frag"
|
||||
]
|
||||
},
|
||||
"qml": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.qml"
|
||||
]
|
||||
},
|
||||
"qmldir": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"qmldir"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fileVersion": 1,
|
||||
"importPaths": [
|
||||
"imports",
|
||||
"asset_imports"
|
||||
],
|
||||
"language": {
|
||||
},
|
||||
"mcuConfig": {
|
||||
},
|
||||
"runConfig": {
|
||||
"fileSelectors": [
|
||||
],
|
||||
"mainFile": "OutrunHVAC.qml",
|
||||
"mainUiFile": "Screen01.ui.qml"
|
||||
},
|
||||
"shaderTool": {
|
||||
},
|
||||
"versions": {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
\\ prop: json-converted
|
||||
\\ prop: auto-generated
|
||||
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "fileSelectors.qml"
|
||||
mainUiFile: ""
|
||||
targetDirectory: "/opt/fileSelectors"
|
||||
widgetApp: false
|
||||
importPaths: [ "imports" ]
|
||||
|
||||
qdsVersion: ""
|
||||
quickVersion: ""
|
||||
qt6Project: false
|
||||
qtForMCUs: true
|
||||
|
||||
multilanguageSupport: false
|
||||
primaryLanguage: ""
|
||||
supportedLanguages: [ ]
|
||||
|
||||
Environment {
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
}
|
||||
|
||||
ShaderTool {
|
||||
args: ""
|
||||
files: [ ]
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "*.conf"
|
||||
files: [ "qtquickcontrols2.conf" ]
|
||||
}
|
||||
|
||||
Files {
|
||||
directory: "."
|
||||
filters: "qmldir"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/* File generated by Qt Creator */
|
||||
|
||||
import QmlProject 1.1
|
||||
|
||||
Project {
|
||||
mainFile: "fileSelectors.qml"
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
}
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports" ]
|
||||
|
||||
//fileSelectors: [ "WXGA", "darkTheme" ]
|
||||
fileSelectors: [ "WXGA", "darkTheme", "ShowIndicator"]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/fileSelectors"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"deployment": {
|
||||
"targetDirectory": "/opt/fileSelectors"
|
||||
},
|
||||
"environment": {
|
||||
"QT_AUTO_SCREEN_SCALE_FACTOR": "1",
|
||||
"QT_QUICK_CONTROLS_CONF": "qtquickcontrols2.conf"
|
||||
},
|
||||
"fileGroups": {
|
||||
"config": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "qtquickcontrols2.conf"
|
||||
}
|
||||
],
|
||||
"filters": [
|
||||
"*.conf"
|
||||
]
|
||||
},
|
||||
"image": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.jpeg",
|
||||
"*.jpg",
|
||||
"*.png",
|
||||
"*.svg",
|
||||
"*.hdr",
|
||||
".ktx"
|
||||
]
|
||||
},
|
||||
"javaScript": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
},
|
||||
"qml": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"*.qml"
|
||||
]
|
||||
},
|
||||
"qmldir": {
|
||||
"directories": [
|
||||
"."
|
||||
],
|
||||
"files": [
|
||||
],
|
||||
"filters": [
|
||||
"qmldir"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fileVersion": 1,
|
||||
"importPaths": [
|
||||
"imports"
|
||||
],
|
||||
"language": {
|
||||
},
|
||||
"mcuConfig": {
|
||||
},
|
||||
"runConfig": {
|
||||
"fileSelectors": [
|
||||
"WXGA",
|
||||
"darkTheme",
|
||||
"ShowIndicator"
|
||||
],
|
||||
"mainFile": "fileSelectors.qml"
|
||||
},
|
||||
"shaderTool": {
|
||||
},
|
||||
"versions": {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import QmlProject
|
||||
|
||||
Project {
|
||||
mainFile: "content/App.qml"
|
||||
mainUiFile: "Screen01.ui.qml"
|
||||
|
||||
|
||||
/* Include .qml, .js, and image files from current directory and subdirectories */
|
||||
QmlFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
QmlFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
JavaScriptFiles {
|
||||
directory: "imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.conf"
|
||||
files: ["qtquickcontrols2.conf"]
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "qmldir"
|
||||
directory: "."
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.ttf;*.otf"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.wav;*.mp3"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mp4"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.glsl;*.glslv;*.glslf;*.vsh;*.fsh;*.vert;*.frag"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.mesh"
|
||||
directory: "content"
|
||||
}
|
||||
|
||||
Files {
|
||||
filter: "*.qml"
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
ImageFiles {
|
||||
directory: "asset_imports"
|
||||
}
|
||||
|
||||
Environment {
|
||||
QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR: "1"
|
||||
QT_LOGGING_RULES: "qt.qml.connections=false"
|
||||
QT_ENABLE_HIGHDPI_SCALING: "0"
|
||||
/* Useful for debugging
|
||||
QSG_VISUALIZE=batches
|
||||
QSG_VISUALIZE=clip
|
||||
QSG_VISUALIZE=changes
|
||||
QSG_VISUALIZE=overdraw
|
||||
*/
|
||||
}
|
||||
|
||||
qt6Project: true
|
||||
|
||||
/* List of plugin directories passed to QML runtime */
|
||||
importPaths: [ "imports", "asset_imports" ]
|
||||
|
||||
/* Required for deployment */
|
||||
targetDirectory: "/opt/MaterialLibrary"
|
||||
|
||||
qdsVersion: "3.9"
|
||||
|
||||
/* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */
|
||||
widgetApp: true
|
||||
|
||||
/* args: Specifies command line arguments for qsb tool to generate shaders.
|
||||
files: Specifies target files for qsb tool. If path is included, it must be relative to this file.
|
||||
Wildcard '*' can be used in the file name part of the path.
|
||||
e.g. files: [ "content/shaders/*.vert", "*.frag" ] */
|
||||
ShaderTool {
|
||||
args: "-s --glsl \"100 es,120,150\" --hlsl 50 --msl 12"
|
||||
files: [ "content/shaders/*" ]
|
||||
}
|
||||
|
||||
multilanguageSupport: true
|
||||
supportedLanguages: ["en"]
|
||||
primaryLanguage: "en"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user