Merge remote-tracking branch 'origin/14.0'

Conflicts:
	src/plugins/qmljseditor/qmljseditorsettings.cpp

Change-Id: I443424afdfe48cdfc3d083d8e91335e937fcfdb6
This commit is contained in:
Eike Ziller
2024-06-27 11:41:54 +02:00
108 changed files with 1869 additions and 1222 deletions

View File

@@ -1585,7 +1585,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
if (info.buildDirectory.isEmpty()) {
setBuildDirectory(shadowBuildDirectory(target->project()->projectFilePath(),
k,
info.typeName,
info.displayName,
info.buildType));
}
@@ -1960,6 +1960,9 @@ CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory()
k,
info.typeName,
info.buildType);
} else {
info.displayName.clear(); // ask for a name
info.buildDirectory.clear(); // This depends on the displayName
}
result << info;
}

View File

@@ -642,6 +642,25 @@ bool CMakeBuildSystem::addTsFiles(Node *context, const FilePaths &filePaths, Fil
return false;
}
static bool isGlobbingFunction(const cmListFile &cmakeListFile, const cmListFileFunction &func)
{
// Check if the filename is part of globbing variable result
const auto globFunctions = std::get<0>(
Utils::partition(cmakeListFile.Functions, [](const auto &f) {
return f.LowerCaseName() == "file" && f.Arguments().size() > 2
&& (f.Arguments().front().Value == "GLOB"
|| f.Arguments().front().Value == "GLOB_RECURSE");
}));
const auto globVariables = Utils::transform<QSet>(globFunctions, [](const auto &func) {
return std::string("${") + func.Arguments()[1].Value + "}";
});
return Utils::anyOf(func.Arguments(), [globVariables](const auto &arg) {
return globVariables.contains(arg.Value);
});
}
bool CMakeBuildSystem::addSrcFiles(Node *context, const FilePaths &filePaths, FilePaths *notAdded)
{
if (notAdded)
@@ -670,26 +689,32 @@ bool CMakeBuildSystem::addSrcFiles(Node *context, const FilePaths &filePaths, Fi
return false;
}
const std::string target_name = function->Arguments().front().Value;
auto qtAddModule = [target_name](const auto &func) {
return (func.LowerCaseName() == "qt_add_qml_module"
|| func.LowerCaseName() == "qt6_add_qml_module")
&& func.Arguments().front().Value == target_name;
};
// Special case: when qt_add_executable and qt_add_qml_module use the same target name
// then qt_add_qml_module function should be used
function = findFunction(*cmakeListFile, qtAddModule).value_or(*function);
const bool haveGlobbing = isGlobbingFunction(cmakeListFile.value(), function.value());
n->setVisibleAfterAddFileAction(!haveGlobbing);
if (haveGlobbing && settings(project()).autorunCMake()) {
runCMake();
} else {
const std::string target_name = function->Arguments().front().Value;
auto qtAddModule = [target_name](const auto &func) {
return (func.LowerCaseName() == "qt_add_qml_module"
|| func.LowerCaseName() == "qt6_add_qml_module")
&& func.Arguments().front().Value == target_name;
};
// Special case: when qt_add_executable and qt_add_qml_module use the same target name
// then qt_add_qml_module function should be used
function = findFunction(*cmakeListFile, qtAddModule).value_or(*function);
const QString newSourceFiles = newFilesForFunction(function->LowerCaseName(),
filePaths,
n->filePath().canonicalPath());
const QString newSourceFiles = newFilesForFunction(function->LowerCaseName(),
filePaths,
n->filePath().canonicalPath());
const SnippetAndLocation snippetLocation = generateSnippetAndLocationForSources(
newSourceFiles, *cmakeListFile, *function, targetName);
expected_str<bool> inserted = insertSnippetSilently(targetCMakeFile, snippetLocation);
if (!inserted) {
qCCritical(cmakeBuildSystemLog) << inserted.error();
return false;
const SnippetAndLocation snippetLocation = generateSnippetAndLocationForSources(
newSourceFiles, *cmakeListFile, *function, targetName);
expected_str<bool> inserted = insertSnippetSilently(targetCMakeFile, snippetLocation);
if (!inserted) {
qCCritical(cmakeBuildSystemLog) << inserted.error();
return false;
}
}
if (notAdded)
@@ -770,22 +795,7 @@ CMakeBuildSystem::projectFileArgumentPosition(const QString &targetName, const Q
return ProjectFileArgumentPosition{filePathArgument, targetCMakeFile, fileName};
} else {
// Check if the filename is part of globbing variable result
const auto globFunctions = std::get<0>(
Utils::partition(cmakeListFile->Functions, [](const auto &f) {
return f.LowerCaseName() == "file" && f.Arguments().size() > 2
&& (f.Arguments().front().Value == "GLOB"
|| f.Arguments().front().Value == "GLOB_RECURSE");
}));
const auto globVariables = Utils::transform<QSet>(globFunctions, [](const auto &func) {
return std::string("${") + func.Arguments()[1].Value + "}";
});
const auto haveGlobbing = Utils::anyOf(func->Arguments(),
[globVariables](const auto &arg) {
return globVariables.contains(arg.Value);
});
const auto haveGlobbing = isGlobbingFunction(cmakeListFile.value(), func.value());
if (haveGlobbing) {
return ProjectFileArgumentPosition{filePathArgument,
targetCMakeFile,
@@ -833,6 +843,7 @@ RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
const FilePath projDir = n->filePath().canonicalPath();
const QString targetName = n->buildKey();
bool haveGlobbing = false;
for (const auto &file : filePaths) {
const QString fileName
= file.canonicalPath().relativePathFrom(projDir).cleanPath().toString();
@@ -847,6 +858,11 @@ RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
continue;
}
if (filePos.value().fromGlobbing) {
haveGlobbing = true;
continue;
}
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(
Core::EditorManager::openEditorAt({filePos.value().cmakeFile,
static_cast<int>(filePos.value().argumentPosition.Line),
@@ -869,8 +885,7 @@ RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
if (filePos->argumentPosition.Delim == cmListFileArgument::Quoted)
extraChars = 2;
if (!filePos.value().fromGlobbing)
editor->replace(filePos.value().relativeFileName.length() + extraChars, "");
editor->replace(filePos.value().relativeFileName.length() + extraChars, "");
editor->editorWidget()->autoIndent();
if (!Core::DocumentManager::saveDocument(editor->document())) {
@@ -889,6 +904,9 @@ RemovedFilesFromProject CMakeBuildSystem::removeFiles(Node *context,
if (notRemoved && !badFiles.isEmpty())
*notRemoved = badFiles;
if (haveGlobbing && settings(project()).autorunCMake())
runCMake();
return badFiles.isEmpty() ? RemovedFilesFromProject::Ok : RemovedFilesFromProject::Error;
}
@@ -936,10 +954,6 @@ bool CMakeBuildSystem::renameFile(Node *context,
const FilePath newRelPath = newFilePath.canonicalPath().relativePathFrom(projDir).cleanPath();
const QString newRelPathName = newRelPath.toString();
// FilePath needs the file to exist on disk, the old file has already been renamed
const QString oldRelPathName
= newRelPath.parentDir().pathAppended(oldFilePath.fileName()).cleanPath().toString();
const QString targetName = n->buildKey();
const QString key
= QStringList{projDir.path(), targetName, oldFilePath.path(), newFilePath.path()}.join(
@@ -953,40 +967,47 @@ bool CMakeBuildSystem::renameFile(Node *context,
return false;
}
bool haveGlobbing = false;
do {
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(
Core::EditorManager::openEditorAt(
{fileToRename->cmakeFile,
static_cast<int>(fileToRename->argumentPosition.Line),
static_cast<int>(fileToRename->argumentPosition.Column - 1)},
Constants::CMAKE_EDITOR_ID,
Core::EditorManager::DoNotMakeVisible));
if (!editor) {
qCCritical(cmakeBuildSystemLog).noquote()
<< "BaseTextEditor cannot be obtained for" << fileToRename->cmakeFile.path()
<< fileToRename->argumentPosition.Line
<< int(fileToRename->argumentPosition.Column);
return false;
}
if (!fileToRename->fromGlobbing) {
BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(
Core::EditorManager::openEditorAt(
{fileToRename->cmakeFile,
static_cast<int>(fileToRename->argumentPosition.Line),
static_cast<int>(fileToRename->argumentPosition.Column - 1)},
Constants::CMAKE_EDITOR_ID,
Core::EditorManager::DoNotMakeVisible));
if (!editor) {
qCCritical(cmakeBuildSystemLog).noquote()
<< "BaseTextEditor cannot be obtained for" << fileToRename->cmakeFile.path()
<< fileToRename->argumentPosition.Line
<< int(fileToRename->argumentPosition.Column);
return false;
}
// If quotes were used for the source file, skip the starting quote
if (fileToRename->argumentPosition.Delim == cmListFileArgument::Quoted)
editor->setCursorPosition(editor->position() + 1);
// If quotes were used for the source file, skip the starting quote
if (fileToRename->argumentPosition.Delim == cmListFileArgument::Quoted)
editor->setCursorPosition(editor->position() + 1);
if (!fileToRename->fromGlobbing)
editor->replace(fileToRename->relativeFileName.length(), newRelPathName);
editor->editorWidget()->autoIndent();
if (!Core::DocumentManager::saveDocument(editor->document())) {
qCCritical(cmakeBuildSystemLog).noquote()
<< "Changes to" << fileToRename->cmakeFile.path() << "could not be saved.";
return false;
editor->editorWidget()->autoIndent();
if (!Core::DocumentManager::saveDocument(editor->document())) {
qCCritical(cmakeBuildSystemLog).noquote()
<< "Changes to" << fileToRename->cmakeFile.path() << "could not be saved.";
return false;
}
} else {
haveGlobbing = true;
}
// Try the next occurrence. This can happen if set_source_file_properties is used
fileToRename = projectFileArgumentPosition(targetName, oldRelPathName);
fileToRename = projectFileArgumentPosition(targetName, fileToRename->relativeFileName);
} while (fileToRename && !fileToRename->fromGlobbing);
if (haveGlobbing && settings(project()).autorunCMake())
runCMake();
return true;
}

View File

@@ -330,7 +330,8 @@ void CMakeEditorWidget::findLinkAt(const QTextCursor &cursor,
if (auto project = ProjectTree::currentProject()) {
buffer.replace("${CMAKE_SOURCE_DIR}", project->projectDirectory().path());
if (auto bs = ProjectTree::currentBuildSystem(); bs && bs->buildConfiguration()) {
auto bs = ProjectTree::currentBuildSystem();
if (bs && bs->buildConfiguration()) {
buffer.replace("${CMAKE_BINARY_DIR}", bs->buildConfiguration()->buildDirectory().path());
// Get the path suffix from current source dir to project source dir and apply it

View File

@@ -187,9 +187,16 @@ void CMakeTargetNode::setConfig(const CMakeConfig &config)
m_config = config;
}
void CMakeTargetNode::setVisibleAfterAddFileAction(bool visibleAfterAddFileAction)
{
m_visibleAfterAddFileAction = visibleAfterAddFileAction;
}
std::optional<FilePath> CMakeTargetNode::visibleAfterAddFileAction() const
{
return filePath().pathAppended(Constants::CMAKE_LISTS_TXT);
if (m_visibleAfterAddFileAction)
return filePath().pathAppended(Constants::CMAKE_LISTS_TXT);
return std::nullopt;
}
void CMakeTargetNode::build()

View File

@@ -57,11 +57,14 @@ public:
QVariant data(Utils::Id role) const override;
void setConfig(const CMakeConfig &config);
void setVisibleAfterAddFileAction(bool visibleAfterAddFileAction);
private:
QString m_tooltip;
Utils::FilePath m_buildDirectory;
Utils::FilePath m_artifact;
CMakeConfig m_config;
bool m_visibleAfterAddFileAction = true;
};
} // CMakeProjectManager::Internal

View File

@@ -142,8 +142,9 @@ void CMakeSpecificSettings::readSettings()
} else {
Store data = storeFromVariant(project->namedSettings(Constants::Settings::GENERAL_ID));
if (data.isEmpty()) {
CMakeProject *cmakeProject = static_cast<CMakeProject *>(project);
if (cmakeProject->presetsData().havePresets && cmakeProject->presetsData().vendor) {
CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(project);
if (cmakeProject && cmakeProject->presetsData().havePresets
&& cmakeProject->presetsData().vendor) {
useGlobalSettings = false;
data = storeFromMap(cmakeProject->presetsData().vendor.value());
fromMap(data);

View File

@@ -518,7 +518,7 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage
m_presetsData.configurePresets,
jsonFile.parentDir())) {
errorMessage = ::CMakeProjectManager::Tr::tr(
"Invalid \"configurePresets\" section in %1 file")
"Invalid \"configurePresets\" section in file \"%1\".")
.arg(jsonFile.fileName());
return false;
}
@@ -527,14 +527,15 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage
if (!parseBuildPresets(root.value("buildPresets"),
m_presetsData.buildPresets,
jsonFile.parentDir())) {
errorMessage = ::CMakeProjectManager::Tr::tr("Invalid \"buildPresets\" section in %1 file")
errorMessage = ::CMakeProjectManager::Tr::tr(
"Invalid \"buildPresets\" section in file \"%1\".")
.arg(jsonFile.fileName());
return false;
}
// optional
if (!parseVendor(root.value("vendor"), m_presetsData.vendor)) {
errorMessage = ::CMakeProjectManager::Tr::tr("Invalid \"vendor\" section in %1 file")
errorMessage = ::CMakeProjectManager::Tr::tr("Invalid \"vendor\" section in file \"%1\".")
.arg(jsonFile.fileName());
}