From 34638aa497f94d51316156eddea961720990a172 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Tue, 10 Jan 2023 14:29:49 +0100 Subject: [PATCH] ClangFormat: Add use global settings check box for a project Change-Id: Ie2872de3574aaad058a9fca17247db00e9559ba7 Reviewed-by: Christian Kandeler --- .../clangformat/clangformatbaseindenter.cpp | 18 +++---- .../clangformat/clangformatconstants.h | 1 + .../clangformatglobalconfigwidget.cpp | 48 ++++++++++++----- .../clangformatglobalconfigwidget.h | 2 + .../clangformat/clangformatindenter.cpp | 11 ++-- src/plugins/clangformat/clangformatutils.cpp | 54 ++++++++++++++++++- src/plugins/clangformat/clangformatutils.h | 12 +++++ 7 files changed, 110 insertions(+), 36 deletions(-) diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 7caa8483380..d61cbf2f1a8 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -2,8 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "clangformatbaseindenter.h" -#include "clangformatconstants.h" -#include "clangformatsettings.h" #include "clangformatutils.h" #include "llvmfilesystem.h" @@ -739,8 +737,11 @@ void ClangFormatBaseIndenter::autoIndent(const QTextCursor &cursor, } } -clang::format::FormatStyle overrideStyle(const ProjectExplorer::Project *projectForFile) +clang::format::FormatStyle overrideStyle(const Utils::FilePath &fileName) { + const ProjectExplorer::Project *projectForFile + = ProjectExplorer::SessionManager::projectForFile(fileName); + const TextEditor::ICodeStylePreferences *preferences = projectForFile ? projectForFile->editorConfiguration()->codeStyle("Cpp")->currentPreferences() @@ -765,15 +766,8 @@ clang::format::FormatStyle overrideStyle(const ProjectExplorer::Project *project clang::format::FormatStyle ClangFormatBaseIndenter::styleForFile() const { - const ProjectExplorer::Project *projectForFile - = ProjectExplorer::SessionManager::projectForFile(m_fileName); - - const bool overrideStyleFile - = projectForFile ? projectForFile->namedSettings(Constants::OVERRIDE_FILE_ID).toBool() - : ClangFormatSettings::instance().overrideDefaultFile(); - - if (overrideStyleFile) - return overrideStyle(projectForFile); + if (getCurrentOverriddenSettings(m_fileName)) + return overrideStyle(m_fileName); llvm::Expected styleFromProjectFolder = clang::format::getStyle("file", diff --git a/src/plugins/clangformat/clangformatconstants.h b/src/plugins/clangformat/clangformatconstants.h index e43d3c03826..5bd8b1246c3 100644 --- a/src/plugins/clangformat/clangformatconstants.h +++ b/src/plugins/clangformat/clangformatconstants.h @@ -13,6 +13,7 @@ static const char OVERRIDE_FILE_ID[] = "ClangFormat.OverrideFile"; static const char FORMAT_CODE_ON_SAVE_ID[] = "ClangFormat.FormatCodeOnSave"; static const char FORMAT_WHILE_TYPING_ID[] = "ClangFormat.FormatWhileTyping"; static const char MODE_ID[] = "ClangFormat.Mode"; +static const char USE_GLOBAL_SETTINGS[] = "ClangFormat.UseGlobalSettings"; static const char OPEN_CURRENT_CONFIG_ID[] = "ClangFormat.OpenCurrentConfig"; } // namespace Constants } // namespace ClangFormat diff --git a/src/plugins/clangformat/clangformatglobalconfigwidget.cpp b/src/plugins/clangformat/clangformatglobalconfigwidget.cpp index 6352cd35791..dcff7db6e6c 100644 --- a/src/plugins/clangformat/clangformatglobalconfigwidget.cpp +++ b/src/plugins/clangformat/clangformatglobalconfigwidget.cpp @@ -36,13 +36,16 @@ ClangFormatGlobalConfigWidget::ClangFormatGlobalConfigWidget(ProjectExplorer::Pr m_formatWhileTyping = new QCheckBox(tr("Format while typing")); m_formatOnSave = new QCheckBox(tr("Format edited code on file save")); m_overrideDefault = new QCheckBox(tr("Override Clang Format configuration file")); + m_useGlobalSettings = new QCheckBox(tr("Use global settings")); + m_useGlobalSettings->hide(); using namespace Layouting; Group globalSettingsGroupBox { title(tr("ClangFormat settings:")), Column { - Row { m_formattingModeLabel, m_indentingOrFormatting, st }, + m_useGlobalSettings, + Row { m_formattingModeLabel, m_indentingOrFormatting, st }, m_formatWhileTyping, m_formatOnSave, m_projectHasClangFormat, @@ -57,11 +60,14 @@ ClangFormatGlobalConfigWidget::ClangFormatGlobalConfigWidget(ProjectExplorer::Pr initCheckBoxes(); initIndentationOrFormattingCombobox(); initOverrideCheckBox(); + initUseGlobalSettingsCheckBox(); if (project) { m_formattingModeLabel->hide(); m_formatOnSave->hide(); m_formatWhileTyping->hide(); + + m_useGlobalSettings->show(); return; } globalSettingsGroupBox.widget->show(); @@ -94,13 +100,8 @@ void ClangFormatGlobalConfigWidget::initIndentationOrFormattingCombobox() m_indentingOrFormatting->insertItem(static_cast(ClangFormatSettings::Mode::Disable), tr("Disable")); - if (m_project) { - m_indentingOrFormatting->setCurrentIndex( - m_project->namedSettings(Constants::MODE_ID).toInt()); - } else { - m_indentingOrFormatting->setCurrentIndex( - static_cast(ClangFormatSettings::instance().mode())); - } + m_indentingOrFormatting->setCurrentIndex( + static_cast(getProjectIndentationOrFormattingSettings(m_project))); connect(m_indentingOrFormatting, &QComboBox::currentIndexChanged, this, [this](int index) { if (m_project) @@ -108,6 +109,29 @@ void ClangFormatGlobalConfigWidget::initIndentationOrFormattingCombobox() }); } +void ClangFormatGlobalConfigWidget::initUseGlobalSettingsCheckBox() +{ + if (!m_project) + return; + + const auto enableProjectSettings = [this] { + const bool isDisabled = m_project && m_useGlobalSettings->isChecked(); + m_indentingOrFormatting->setDisabled(isDisabled); + m_overrideDefault->setDisabled(isDisabled + || (m_indentingOrFormatting->currentIndex() + == static_cast(ClangFormatSettings::Mode::Disable))); + }; + + m_useGlobalSettings->setChecked(getProjectUseGlobalSettings(m_project)); + enableProjectSettings(); + + connect(m_useGlobalSettings, &QCheckBox::toggled, + this, [this, enableProjectSettings] (bool checked) { + m_project->setNamedSettings(Constants::USE_GLOBAL_SETTINGS, checked); + enableProjectSettings(); + }); +} + bool ClangFormatGlobalConfigWidget::projectClangFormatFileExists() { llvm::Expected styleFromProjectFolder @@ -128,7 +152,7 @@ void ClangFormatGlobalConfigWidget::initOverrideCheckBox() auto setEnableOverrideCheckBox = [this](int index) { bool isDisable = index == static_cast(ClangFormatSettings::Mode::Disable); - m_overrideDefault->setEnabled(!isDisable); + m_overrideDefault->setDisabled(isDisable); }; setEnableOverrideCheckBox(m_indentingOrFormatting->currentIndex()); @@ -138,11 +162,7 @@ void ClangFormatGlobalConfigWidget::initOverrideCheckBox() m_overrideDefault->setToolTip( tr("Override Clang Format configuration file with the chosen configuration.")); - if (m_project) - m_overrideDefault->setChecked( - m_project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool()); - else - m_overrideDefault->setChecked(ClangFormatSettings::instance().overrideDefaultFile()); + m_overrideDefault->setChecked(getProjectOverriddenSettings(m_project)); connect(m_overrideDefault, &QCheckBox::toggled, this, [this](bool checked) { if (m_project) diff --git a/src/plugins/clangformat/clangformatglobalconfigwidget.h b/src/plugins/clangformat/clangformatglobalconfigwidget.h index 39687c77367..49657cfe201 100644 --- a/src/plugins/clangformat/clangformatglobalconfigwidget.h +++ b/src/plugins/clangformat/clangformatglobalconfigwidget.h @@ -31,6 +31,7 @@ private: void initCheckBoxes(); void initIndentationOrFormattingCombobox(); void initOverrideCheckBox(); + void initUseGlobalSettingsCheckBox(); bool projectClangFormatFileExists(); @@ -42,6 +43,7 @@ private: QCheckBox *m_formatWhileTyping; QCheckBox *m_formatOnSave; QCheckBox *m_overrideDefault; + QCheckBox *m_useGlobalSettings; }; } // namespace ClangFormat diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp index 45e74817605..94e0fafd8e0 100644 --- a/src/plugins/clangformat/clangformatindenter.cpp +++ b/src/plugins/clangformat/clangformatindenter.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "clangformatindenter.h" -#include "clangformatconstants.h" #include "clangformatsettings.h" #include "clangformatutils.h" @@ -60,7 +59,8 @@ ClangFormatIndenter::ClangFormatIndenter(QTextDocument *doc) bool ClangFormatIndenter::formatCodeInsteadOfIndent() const { - return ClangFormatSettings::instance().mode() == ClangFormatSettings::Mode::Formatting; + return getCurrentIndentationOrFormattingSettings(m_fileName) + == ClangFormatSettings::Mode::Formatting; } std::optional ClangFormatIndenter::tabSettings() const @@ -128,12 +128,7 @@ void ClangFormatForwardingIndenter::setFileName(const Utils::FilePath &fileName) TextEditor::Indenter *ClangFormatForwardingIndenter::currentIndenter() const { - const ProjectExplorer::Project *projectForFile - = ProjectExplorer::SessionManager::projectForFile(m_fileName); - - ClangFormatSettings::Mode mode = projectForFile ? static_cast( - projectForFile->namedSettings(Constants::MODE_ID).toInt()) - : ClangFormatSettings::instance().mode(); + ClangFormatSettings::Mode mode = getCurrentIndentationOrFormattingSettings(m_fileName); if (mode == ClangFormatSettings::Disable) return m_cppIndenter.get(); diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp index 00ee6f94c85..00396e04a61 100644 --- a/src/plugins/clangformat/clangformatutils.cpp +++ b/src/plugins/clangformat/clangformatutils.cpp @@ -4,7 +4,6 @@ #include "clangformatutils.h" #include "clangformatconstants.h" -#include "clangformatsettings.h" #include #include @@ -203,7 +202,58 @@ void saveStyleToFile(clang::format::FormatStyle style, Utils::FilePath filePath) static bool useProjectOverriddenSettings() { const Project *project = SessionManager::startupProject(); - return project ? project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool() : false; + return getProjectOverriddenSettings(project); +} + +bool getProjectUseGlobalSettings(const ProjectExplorer::Project *project) +{ + const QVariant projectUseGlobalSettings = project ? project->namedSettings( + Constants::USE_GLOBAL_SETTINGS) + : QVariant(); + + return projectUseGlobalSettings.isValid() ? projectUseGlobalSettings.toBool() : true; +} + +bool getProjectOverriddenSettings(const ProjectExplorer::Project *project) +{ + const QVariant projectOverride = project ? project->namedSettings(Constants::OVERRIDE_FILE_ID) + : QVariant(); + + return projectOverride.isValid() + ? projectOverride.toBool() + : ClangFormatSettings::instance().overrideDefaultFile(); +} + +bool getCurrentOverriddenSettings(const Utils::FilePath &filePath) +{ + const ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile( + filePath); + + return getProjectUseGlobalSettings(project) + ? ClangFormatSettings::instance().overrideDefaultFile() + : getProjectOverriddenSettings(project); +} + +ClangFormatSettings::Mode getProjectIndentationOrFormattingSettings( + const ProjectExplorer::Project *project) +{ + const QVariant projectIndentationOrFormatting = project + ? project->namedSettings(Constants::MODE_ID) + : QVariant(); + + return projectIndentationOrFormatting.isValid() + ? static_cast(projectIndentationOrFormatting.toInt()) + : ClangFormatSettings::instance().mode(); +} + +ClangFormatSettings::Mode getCurrentIndentationOrFormattingSettings(const Utils::FilePath &filePath) +{ + const ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile( + filePath); + + return getProjectUseGlobalSettings(project) + ? ClangFormatSettings::instance().mode() + : getProjectIndentationOrFormattingSettings(project); } static Utils::FilePath globalPath() diff --git a/src/plugins/clangformat/clangformatutils.h b/src/plugins/clangformat/clangformatutils.h index cce60ef0e20..4668b11e9ef 100644 --- a/src/plugins/clangformat/clangformatutils.h +++ b/src/plugins/clangformat/clangformatutils.h @@ -3,6 +3,8 @@ #pragma once +#include "clangformatsettings.h" + #include #include @@ -13,6 +15,7 @@ #include namespace TextEditor { class ICodeStylePreferences; } +namespace ProjectExplorer { class Project; } namespace ClangFormat { // Creates the style for the current project or the global style if needed. @@ -27,6 +30,15 @@ clang::format::FormatStyle currentProjectStyle(); clang::format::FormatStyle currentGlobalStyle(); std::string readFile(const QString &path); +bool getProjectUseGlobalSettings(const ProjectExplorer::Project *project); + +bool getProjectOverriddenSettings(const ProjectExplorer::Project *project); +bool getCurrentOverriddenSettings(const Utils::FilePath &filePath); + +ClangFormatSettings::Mode getProjectIndentationOrFormattingSettings( + const ProjectExplorer::Project *project); +ClangFormatSettings::Mode getCurrentIndentationOrFormattingSettings(const Utils::FilePath &filePath); + // Is the style from the matching .clang-format file or global one if it's not found. QString configForFile(Utils::FilePath fileName); clang::format::FormatStyle styleForFile(Utils::FilePath fileName);