2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2022 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
#include "clangformatglobalconfigwidget.h"
|
|
|
|
|
|
|
|
|
|
#include "clangformatconstants.h"
|
|
|
|
|
#include "clangformatsettings.h"
|
2022-08-19 15:20:22 +02:00
|
|
|
#include "clangformatutils.h"
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
#include <projectexplorer/project.h>
|
|
|
|
|
|
2022-07-22 09:44:47 +02:00
|
|
|
#include <utils/layoutbuilder.h>
|
|
|
|
|
|
|
|
|
|
#include <QCheckBox>
|
|
|
|
|
#include <QComboBox>
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
2022-07-28 16:13:35 +02:00
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
using namespace ProjectExplorer;
|
2022-07-22 09:44:47 +02:00
|
|
|
using namespace Utils;
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
namespace ClangFormat {
|
|
|
|
|
|
|
|
|
|
ClangFormatGlobalConfigWidget::ClangFormatGlobalConfigWidget(ProjectExplorer::Project *project,
|
|
|
|
|
QWidget *parent)
|
|
|
|
|
: CppCodeStyleWidget(parent)
|
2022-08-19 15:20:22 +02:00
|
|
|
, m_project(project)
|
2022-07-28 16:13:35 +02:00
|
|
|
{
|
2022-07-22 09:44:47 +02:00
|
|
|
resize(489, 305);
|
|
|
|
|
|
2022-08-19 15:20:22 +02:00
|
|
|
m_projectHasClangFormat = new QLabel(this);
|
2022-07-22 09:44:47 +02:00
|
|
|
m_formattingModeLabel = new QLabel(tr("Formatting mode:"));
|
|
|
|
|
m_indentingOrFormatting = new QComboBox(this);
|
|
|
|
|
m_formatWhileTyping = new QCheckBox(tr("Format while typing"));
|
|
|
|
|
m_formatOnSave = new QCheckBox(tr("Format edited code on file save"));
|
2022-08-19 15:20:22 +02:00
|
|
|
m_overrideDefault = new QCheckBox(tr("Override Clang Format configuration file"));
|
2023-01-10 14:29:49 +01:00
|
|
|
m_useGlobalSettings = new QCheckBox(tr("Use global settings"));
|
|
|
|
|
m_useGlobalSettings->hide();
|
2022-07-22 09:44:47 +02:00
|
|
|
|
|
|
|
|
using namespace Layouting;
|
|
|
|
|
|
|
|
|
|
Group globalSettingsGroupBox {
|
2022-12-12 15:30:29 +01:00
|
|
|
title(tr("ClangFormat settings:")),
|
2022-07-22 09:44:47 +02:00
|
|
|
Column {
|
2023-01-10 14:29:49 +01:00
|
|
|
m_useGlobalSettings,
|
|
|
|
|
Row { m_formattingModeLabel, m_indentingOrFormatting, st },
|
2022-07-22 09:44:47 +02:00
|
|
|
m_formatWhileTyping,
|
2022-08-19 15:20:22 +02:00
|
|
|
m_formatOnSave,
|
|
|
|
|
m_projectHasClangFormat,
|
|
|
|
|
m_overrideDefault
|
2022-07-22 09:44:47 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Column {
|
|
|
|
|
globalSettingsGroupBox
|
2022-09-15 20:26:55 +02:00
|
|
|
}.attachTo(this, Layouting::WithoutMargins);
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
initCheckBoxes();
|
|
|
|
|
initIndentationOrFormattingCombobox();
|
2022-08-19 15:20:22 +02:00
|
|
|
initOverrideCheckBox();
|
2023-01-10 14:29:49 +01:00
|
|
|
initUseGlobalSettingsCheckBox();
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
if (project) {
|
2022-08-19 15:20:22 +02:00
|
|
|
m_formattingModeLabel->hide();
|
|
|
|
|
m_formatOnSave->hide();
|
|
|
|
|
m_formatWhileTyping->hide();
|
2023-01-10 14:29:49 +01:00
|
|
|
|
|
|
|
|
m_useGlobalSettings->show();
|
2022-07-28 16:13:35 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2022-07-22 09:44:47 +02:00
|
|
|
globalSettingsGroupBox.widget->show();
|
2022-07-28 16:13:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ClangFormatGlobalConfigWidget::~ClangFormatGlobalConfigWidget() = default;
|
|
|
|
|
|
|
|
|
|
void ClangFormatGlobalConfigWidget::initCheckBoxes()
|
|
|
|
|
{
|
|
|
|
|
auto setEnableCheckBoxes = [this](int index) {
|
|
|
|
|
bool isFormatting = index == static_cast<int>(ClangFormatSettings::Mode::Formatting);
|
|
|
|
|
|
2022-07-22 09:44:47 +02:00
|
|
|
m_formatOnSave->setEnabled(isFormatting);
|
|
|
|
|
m_formatWhileTyping->setEnabled(isFormatting);
|
2022-07-28 16:13:35 +02:00
|
|
|
};
|
2022-07-22 09:44:47 +02:00
|
|
|
setEnableCheckBoxes(m_indentingOrFormatting->currentIndex());
|
|
|
|
|
connect(m_indentingOrFormatting, &QComboBox::currentIndexChanged,
|
2022-07-28 16:13:35 +02:00
|
|
|
this, setEnableCheckBoxes);
|
|
|
|
|
|
2022-07-22 09:44:47 +02:00
|
|
|
m_formatOnSave->setChecked(ClangFormatSettings::instance().formatOnSave());
|
|
|
|
|
m_formatWhileTyping->setChecked(ClangFormatSettings::instance().formatWhileTyping());
|
2022-07-28 16:13:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangFormatGlobalConfigWidget::initIndentationOrFormattingCombobox()
|
|
|
|
|
{
|
2022-07-22 09:44:47 +02:00
|
|
|
m_indentingOrFormatting->insertItem(static_cast<int>(ClangFormatSettings::Mode::Indenting),
|
|
|
|
|
tr("Indenting only"));
|
|
|
|
|
m_indentingOrFormatting->insertItem(static_cast<int>(ClangFormatSettings::Mode::Formatting),
|
|
|
|
|
tr("Full formatting"));
|
|
|
|
|
m_indentingOrFormatting->insertItem(static_cast<int>(ClangFormatSettings::Mode::Disable),
|
|
|
|
|
tr("Disable"));
|
|
|
|
|
|
2023-01-10 14:29:49 +01:00
|
|
|
m_indentingOrFormatting->setCurrentIndex(
|
|
|
|
|
static_cast<int>(getProjectIndentationOrFormattingSettings(m_project)));
|
2022-12-12 15:30:29 +01:00
|
|
|
|
|
|
|
|
connect(m_indentingOrFormatting, &QComboBox::currentIndexChanged, this, [this](int index) {
|
|
|
|
|
if (m_project)
|
|
|
|
|
m_project->setNamedSettings(Constants::MODE_ID, index);
|
|
|
|
|
});
|
2022-07-28 16:13:35 +02:00
|
|
|
}
|
|
|
|
|
|
2023-01-10 14:29:49 +01:00
|
|
|
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<int>(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();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-19 15:20:22 +02:00
|
|
|
bool ClangFormatGlobalConfigWidget::projectClangFormatFileExists()
|
|
|
|
|
{
|
|
|
|
|
llvm::Expected<clang::format::FormatStyle> styleFromProjectFolder
|
|
|
|
|
= clang::format::getStyle("file", m_project->projectFilePath().path().toStdString(), "none");
|
|
|
|
|
|
|
|
|
|
return styleFromProjectFolder && !(*styleFromProjectFolder == clang::format::getNoStyle());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClangFormatGlobalConfigWidget::initOverrideCheckBox()
|
|
|
|
|
{
|
|
|
|
|
if (!m_project || !projectClangFormatFileExists()) {
|
|
|
|
|
m_projectHasClangFormat->hide();
|
|
|
|
|
} else {
|
|
|
|
|
m_projectHasClangFormat->show();
|
|
|
|
|
m_projectHasClangFormat->setText(tr("The current project has its own .clang-format file which "
|
|
|
|
|
"can be overridden by the settings below."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto setEnableOverrideCheckBox = [this](int index) {
|
|
|
|
|
bool isDisable = index == static_cast<int>(ClangFormatSettings::Mode::Disable);
|
2023-01-10 14:29:49 +01:00
|
|
|
m_overrideDefault->setDisabled(isDisable);
|
2022-08-19 15:20:22 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
setEnableOverrideCheckBox(m_indentingOrFormatting->currentIndex());
|
|
|
|
|
connect(m_indentingOrFormatting, &QComboBox::currentIndexChanged,
|
|
|
|
|
this, setEnableOverrideCheckBox);
|
|
|
|
|
|
|
|
|
|
m_overrideDefault->setToolTip(
|
|
|
|
|
tr("Override Clang Format configuration file with the chosen configuration."));
|
|
|
|
|
|
2023-01-10 14:29:49 +01:00
|
|
|
m_overrideDefault->setChecked(getProjectOverriddenSettings(m_project));
|
2022-08-19 15:20:22 +02:00
|
|
|
|
|
|
|
|
connect(m_overrideDefault, &QCheckBox::toggled, this, [this](bool checked) {
|
|
|
|
|
if (m_project)
|
|
|
|
|
m_project->setNamedSettings(Constants::OVERRIDE_FILE_ID, checked);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-28 16:13:35 +02:00
|
|
|
|
|
|
|
|
void ClangFormatGlobalConfigWidget::apply()
|
|
|
|
|
{
|
|
|
|
|
ClangFormatSettings &settings = ClangFormatSettings::instance();
|
2022-07-22 09:44:47 +02:00
|
|
|
settings.setFormatOnSave(m_formatOnSave->isChecked());
|
|
|
|
|
settings.setFormatWhileTyping(m_formatWhileTyping->isChecked());
|
2022-12-12 15:30:29 +01:00
|
|
|
if (!m_project) {
|
|
|
|
|
settings.setMode(
|
|
|
|
|
static_cast<ClangFormatSettings::Mode>(m_indentingOrFormatting->currentIndex()));
|
|
|
|
|
settings.setOverrideDefaultFile(m_overrideDefault->isChecked());
|
|
|
|
|
}
|
2022-07-28 16:13:35 +02:00
|
|
|
settings.write();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace ClangFormat
|