CMakePM: Add project CMake settings support

This is useful if projects do not to have "Auto Run" CMake or want to
have Junctions enabled.

Change-Id: I4a636e7bf64fe2d29d15d39fe9aa46807684c716
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Cristian Adam
2024-05-22 09:48:53 +02:00
parent 97caf327ba
commit 1712402b35
17 changed files with 208 additions and 47 deletions

View File

@@ -1,30 +1,44 @@
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "cmakeproject.h"
#include "cmakespecificsettings.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectmanagertr.h"
#include <coreplugin/icore.h>
#include <coreplugin/dialogs/ioptionspage.h>
#include <coreplugin/icore.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectpanelfactory.h>
#include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h>
#include <QVBoxLayout>
using namespace ProjectExplorer;
using namespace Utils;
namespace CMakeProjectManager::Internal {
CMakeSpecificSettings &settings()
CMakeSpecificSettings &settings(Project *project)
{
static CMakeSpecificSettings theSettings;
return theSettings;
static CMakeSpecificSettings theSettings(nullptr, false);
if (!project)
return theSettings;
CMakeProject *cmakeProject = qobject_cast<CMakeProject *>(project);
if (!cmakeProject || cmakeProject->settings().useGlobalSettings)
return theSettings;
return cmakeProject->settings();
}
CMakeSpecificSettings::CMakeSpecificSettings()
CMakeSpecificSettings::CMakeSpecificSettings(Project *p, bool autoApply)
: project(p)
{
setLayouter([this] {
using namespace Layouting;
@@ -43,8 +57,8 @@ CMakeSpecificSettings::CMakeSpecificSettings()
// TODO: fixup of QTCREATORBUG-26289 , remove in Qt Creator 7 or so
Core::ICore::settings()->remove("CMakeSpecificSettings/NinjaPath");
setSettingsGroup("CMakeSpecificSettings");
setAutoApply(false);
setSettingsGroup(Constants::Settings::GENERAL_ID);
setAutoApply(autoApply);
autorunCMake.setSettingsKey("AutorunCMake");
autorunCMake.setDefaultValue(true);
@@ -105,6 +119,36 @@ CMakeSpecificSettings::CMakeSpecificSettings()
"Junctions are used for CMake configure, build and install operations."));
readSettings();
if (project) {
// Re-read the settings. Reading in constructor is too early
connect(project, &Project::settingsLoaded, this, [this] {
readSettings();
});
}
}
void CMakeSpecificSettings::readSettings()
{
if (!project) {
AspectContainer::readSettings();
} else {
const Store data = storeFromVariant(project->namedSettings(Constants::Settings::GENERAL_ID));
useGlobalSettings = data.value(Constants::Settings::USE_GLOBAL_SETTINGS, true).toBool();
fromMap(data);
}
}
void CMakeSpecificSettings::writeSettings() const
{
if (!project) {
AspectContainer::writeSettings();
} else {
Store data;
toMap(data);
data.insert(Constants::Settings::USE_GLOBAL_SETTINGS, useGlobalSettings);
project->setNamedSettings(Constants::Settings::GENERAL_ID, variantFromStore(data));
}
}
class CMakeSpecificSettingsPage final : public Core::IOptionsPage
@@ -117,10 +161,87 @@ public:
setDisplayCategory("CMake");
setCategory(Constants::Settings::CATEGORY);
setCategoryIconPath(Constants::Icons::SETTINGS_CATEGORY);
setSettingsProvider([] { return &settings(); });
setSettingsProvider([] { return &settings(nullptr); });
}
};
const CMakeSpecificSettingsPage settingsPage;
class CMakeProjectSettingsWidget : public ProjectSettingsWidget
{
public:
explicit CMakeProjectSettingsWidget(Project *project)
: m_widget(new QWidget)
, m_project(qobject_cast<CMakeProject *>(project))
, m_displayedSettings(project, true)
{
setGlobalSettingsId(Constants::Settings::GENERAL_ID);
// Construct the widget layout from the aspect container
const auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
if (auto layouter = m_displayedSettings.layouter())
layouter().attachTo(m_widget);
layout->addWidget(m_widget);
setUseGlobalSettings(m_displayedSettings.useGlobalSettings);
m_widget->setEnabled(!useGlobalSettings());
if (m_project) {
connect(
this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, [this](bool useGlobal) {
m_widget->setEnabled(!useGlobal);
m_displayedSettings.useGlobalSettings = useGlobal;
m_displayedSettings.copyFrom(
useGlobal ? settings(nullptr) : m_project->settings());
m_project->settings().useGlobalSettings = useGlobal;
m_project->settings().writeSettings();
});
// React on Global settings changes
connect(&settings(nullptr), &AspectContainer::changed, this, [this] {
if (m_displayedSettings.useGlobalSettings)
m_displayedSettings.copyFrom(settings(nullptr));
});
// Reflect changes to the project settings in the displayed settings
connect(&m_project->settings(), &AspectContainer::changed, this, [this] {
if (!m_displayedSettings.useGlobalSettings)
m_displayedSettings.copyFrom(m_project->settings());
});
// React on project settings changes in the "CMake" project settings
connect(&m_displayedSettings, &AspectContainer::changed, this, [this] {
if (!m_displayedSettings.useGlobalSettings) {
m_project->settings().copyFrom(m_displayedSettings);
m_project->settings().writeSettings();
}
});
} else {
// Only for CMake projects
setUseGlobalSettingsCheckBoxEnabled(false);
}
}
QWidget *m_widget = nullptr;
CMakeProject *m_project = nullptr;
CMakeSpecificSettings m_displayedSettings;
};
class CMakeProjectSettingsPanelFactory final : public ProjectPanelFactory
{
public:
CMakeProjectSettingsPanelFactory()
{
setPriority(120);
setDisplayName("CMake");
setCreateWidgetFunction([](Project *project) {
return new CMakeProjectSettingsWidget(project);
});
}
};
const CMakeProjectSettingsPanelFactory projectSettingsPane;
} // CMakeProjectManager::Internal