forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/14.0'
Conflicts: src/plugins/qmljseditor/qmljseditorsettings.cpp Change-Id: I443424afdfe48cdfc3d083d8e91335e937fcfdb6
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user