2023-02-13 00:49:09 +01:00
|
|
|
// 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"
|
2023-05-23 08:49:27 +02:00
|
|
|
#include "../qmlprojectconstants.h"
|
2023-02-13 00:49:09 +01:00
|
|
|
|
|
|
|
|
#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>
|
2023-05-23 15:05:38 +02:00
|
|
|
#include <coreplugin/session.h>
|
2023-02-13 00:49:09 +01:00
|
|
|
|
2023-05-03 12:17:28 +02:00
|
|
|
#include <extensionsystem/iplugin.h>
|
|
|
|
|
#include <extensionsystem/pluginmanager.h>
|
|
|
|
|
#include <extensionsystem/pluginspec.h>
|
|
|
|
|
|
2023-02-13 00:49:09 +01:00
|
|
|
#include <projectexplorer/deploymentdata.h>
|
|
|
|
|
#include <projectexplorer/devicesupport/idevice.h>
|
|
|
|
|
#include <projectexplorer/kitinformation.h>
|
|
|
|
|
#include <projectexplorer/kitmanager.h>
|
|
|
|
|
#include <projectexplorer/projectexplorerconstants.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"
|
|
|
|
|
|
2023-05-23 09:26:30 +02:00
|
|
|
#include <QAction>
|
|
|
|
|
|
2023-02-13 00:49:09 +01:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
namespace QmlProjectManager {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
Q_LOGGING_CATEGORY(infoLogger, "QmlProjectManager.QmlBuildSystem", QtInfoMsg)
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 12:17:28 +02:00
|
|
|
ExtensionSystem::IPlugin *findMcuSupportPlugin()
|
|
|
|
|
{
|
|
|
|
|
const ExtensionSystem::PluginSpec *pluginSpec = Utils::findOrDefault(
|
|
|
|
|
ExtensionSystem::PluginManager::plugins(),
|
|
|
|
|
Utils::equal(&ExtensionSystem::PluginSpec::name, QString("McuSupport")));
|
|
|
|
|
|
|
|
|
|
if (pluginSpec)
|
|
|
|
|
return pluginSpec->plugin();
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void updateMcuBuildStep(Target *target, bool mcuEnabled)
|
|
|
|
|
{
|
|
|
|
|
if (auto plugin = findMcuSupportPlugin()) {
|
|
|
|
|
QMetaObject::invokeMethod(
|
|
|
|
|
plugin,
|
|
|
|
|
"updateDeployStep",
|
|
|
|
|
Qt::DirectConnection,
|
|
|
|
|
Q_ARG(ProjectExplorer::Target*, target),
|
|
|
|
|
Q_ARG(bool, mcuEnabled));
|
|
|
|
|
} else if (mcuEnabled) {
|
|
|
|
|
qWarning() << "Failed to find McuSupport plugin but qtForMCUs is enabled in the project";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 00:49:09 +01:00
|
|
|
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();
|
|
|
|
|
|
2023-02-23 10:34:53 +01:00
|
|
|
connect(target->project(), &Project::activeTargetChanged, [this](Target *target) {
|
|
|
|
|
refresh(RefreshOptions::NoFileRefresh);
|
2023-05-03 12:17:28 +02:00
|
|
|
updateMcuBuildStep(target, qtForMCUs());
|
2023-02-23 10:34:53 +01:00
|
|
|
});
|
2023-02-13 00:49:09 +01:00
|
|
|
connect(target->project(), &Project::projectFileIsDirty, [this]() {
|
|
|
|
|
refresh(RefreshOptions::Project);
|
2023-05-03 12:17:28 +02:00
|
|
|
updateMcuBuildStep(project()->activeTarget(), qtForMCUs());
|
2023-02-13 00:49:09 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 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;
|
2023-06-07 19:29:21 +02:00
|
|
|
for (const auto &file : m_projectItem->files()) {
|
|
|
|
|
deploymentData.addFile(file, targetFile(file).parentDir().path());
|
|
|
|
|
}
|
2023-02-13 00:49:09 +01:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2023-06-01 17:56:58 +02:00
|
|
|
return projectFilePath()
|
2023-02-13 00:49:09 +01:00
|
|
|
.canonicalPath()
|
|
|
|
|
.normalizedPathName()
|
|
|
|
|
.parentDir();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlBuildSystem::refresh(RefreshOptions options)
|
|
|
|
|
{
|
|
|
|
|
ParseGuard guard = guardParsingRun();
|
|
|
|
|
switch (options) {
|
|
|
|
|
case RefreshOptions::NoFileRefresh:
|
|
|
|
|
break;
|
|
|
|
|
case RefreshOptions::Project:
|
|
|
|
|
initProjectItem();
|
2023-04-06 13:58:19 +02:00
|
|
|
[[fallthrough]];
|
2023-02-13 00:49:09 +01:00
|
|
|
case RefreshOptions::Files:
|
|
|
|
|
parseProjectFiles();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
|
|
|
|
if (!modelManager)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QmlJS::ModelManagerInterface::ProjectInfo projectInfo
|
|
|
|
|
= modelManager->defaultProjectInfoForProject(project(),
|
|
|
|
|
project()->files(Project::HiddenRccFolders));
|
2023-06-01 17:56:58 +02:00
|
|
|
|
|
|
|
|
for (const QString &searchPath : customImportPaths()) {
|
2023-06-07 19:29:21 +02:00
|
|
|
projectInfo.importPaths.maybeInsert(projectDirectory().pathAppended(searchPath),
|
2023-02-13 00:49:09 +01:00
|
|
|
QmlJS::Dialect::Qml);
|
2023-06-01 17:56:58 +02:00
|
|
|
}
|
2023-02-13 00:49:09 +01:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2023-04-27 14:09:09 +02:00
|
|
|
return projectDirectory().pathAppended(mainUiFile());
|
2023-02-13 00:49:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2023-06-01 17:56:58 +02:00
|
|
|
Utils::FilePath result;
|
|
|
|
|
if (DeviceTypeKitAspect::deviceTypeId(kit()) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
|
|
|
|
|
result = canonicalProjectDir();
|
|
|
|
|
} else if (IDevice::ConstPtr device = DeviceKitAspect::device(kit())) {
|
|
|
|
|
if (m_projectItem)
|
|
|
|
|
result = device->filePath(m_projectItem->targetDirectory());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2023-02-13 00:49:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Utils::FilePath QmlBuildSystem::targetFile(const Utils::FilePath &sourceFile) const
|
|
|
|
|
{
|
2023-06-01 17:56:58 +02:00
|
|
|
const Utils::FilePath sourceDir = m_projectItem ? m_projectItem->sourceDirectory()
|
|
|
|
|
: canonicalProjectDir();
|
|
|
|
|
const Utils::FilePath relative = sourceFile.relativePathFrom(sourceDir);
|
|
|
|
|
return targetDirectory().resolvePath(relative);
|
2023-02-13 00:49:09 +01:00
|
|
|
}
|
|
|
|
|
void QmlBuildSystem::setSupportedLanguages(QStringList languages)
|
|
|
|
|
{
|
|
|
|
|
m_projectItem->setSupportedLanguages(languages);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlBuildSystem::setPrimaryLanguage(QString language)
|
|
|
|
|
{
|
|
|
|
|
m_projectItem->setPrimaryLanguage(language);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-27 14:09:09 +02:00
|
|
|
QString QmlBuildSystem::mainUiFile() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectItem->mainUiFile();
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 00:49:09 +01:00
|
|
|
bool QmlBuildSystem::qtForMCUs() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectItem->isQt4McuProject();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool QmlBuildSystem::qt6Project() const
|
|
|
|
|
{
|
2023-04-25 15:47:52 +02:00
|
|
|
return m_projectItem->versionQt() == "6";
|
2023-02-13 00:49:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-25 15:47:52 +02:00
|
|
|
QString QmlBuildSystem::versionQt() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectItem->versionQt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString QmlBuildSystem::versionQtQuick() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectItem->versionQtQuick();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString QmlBuildSystem::versionDesignStudio() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectItem->versionDesignStudio();
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 00:49:09 +01:00
|
|
|
} // namespace QmlProjectManager
|