ClangTools: Move run settings to projects mode

Make the global run settings available per project in project mode and
thus remove the diagnostic config selection from the
selectable-files-dialog:

 * Extract the classes RunSettings and RunSettingsWidget instead of
   duplicating stuff.
 * Ensure to pick up the old settings
 * Add some convenience buttons/links in projects mode allowing to
   restore the global settings, to open the global settings and to
   navigate (back) to the analyzer mode.

Change-Id: I1b91b6f8e58a87a025774e4643c46e176b2a8885
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-09-13 10:49:14 +02:00
parent bdea56794f
commit 4750969c2b
24 changed files with 630 additions and 508 deletions

View File

@@ -29,6 +29,7 @@ add_qtc_plugin(ClangTools
clangtoolsprojectsettingswidget.cpp clangtoolsprojectsettingswidget.h clangtoolsprojectsettingswidget.ui clangtoolsprojectsettingswidget.cpp clangtoolsprojectsettingswidget.h clangtoolsprojectsettingswidget.ui
clangtoolssettings.cpp clangtoolssettings.h clangtoolssettings.cpp clangtoolssettings.h
clangtoolsutils.cpp clangtoolsutils.h clangtoolsutils.cpp clangtoolsutils.h
runsettingswidget.cpp runsettingswidget.h runsettingswidget.ui
settingswidget.cpp settingswidget.h settingswidget.ui settingswidget.cpp settingswidget.h settingswidget.ui
) )

View File

@@ -266,16 +266,6 @@ private:
} }
}; };
enum { GlobalSettings , CustomSettings };
static Core::Id diagnosticConfiguration(ClangToolsProjectSettings *settings)
{
Core::Id id = settings->diagnosticConfig();
if (id.isValid())
return id;
return ClangToolsSettings::instance()->savedDiagnosticConfigId();
}
SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo, SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
const FileInfos &allFileInfos) const FileInfos &allFileInfos)
: QDialog(nullptr) : QDialog(nullptr)
@@ -292,36 +282,7 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
m_ui->buttons->setStandardButtons(QDialogButtonBox::Cancel); m_ui->buttons->setStandardButtons(QDialogButtonBox::Cancel);
m_ui->buttons->addButton(m_analyzeButton, QDialogButtonBox::AcceptRole); m_ui->buttons->addButton(m_analyzeButton, QDialogButtonBox::AcceptRole);
CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget;
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
m_customDiagnosticConfig = diagnosticConfiguration(settings);
if (settings->useGlobalSettings()) {
m_ui->globalOrCustom->setCurrentIndex(GlobalSettings);
diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId());
diagnosticWidget->setEnabled(false);
} else {
m_ui->globalOrCustom->setCurrentIndex(CustomSettings);
diagnosticWidget->refresh(m_customDiagnosticConfig);
diagnosticWidget->setEnabled(true);
}
connect(m_ui->globalOrCustom,
QOverload<int>::of(&QComboBox::currentIndexChanged),
[=](int index){
diagnosticWidget->setEnabled(index == CustomSettings);
if (index == CustomSettings)
diagnosticWidget->refresh(m_customDiagnosticConfig);
else
diagnosticWidget->refresh(ClangToolsSettings::instance()->savedDiagnosticConfigId());
});
connect(diagnosticWidget,
&ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
[this](const Core::Id &currentConfigId) {
if (m_ui->globalOrCustom->currentIndex() == CustomSettings)
m_customDiagnosticConfig = currentConfigId;
});
// Restore selection // Restore selection
if (settings->selectedDirs().isEmpty() && settings->selectedFiles().isEmpty()) if (settings->selectedDirs().isEmpty() && settings->selectedFiles().isEmpty())
@@ -333,16 +294,6 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
connect(m_filesModel.get(), &QAbstractItemModel::dataChanged, [this]() { connect(m_filesModel.get(), &QAbstractItemModel::dataChanged, [this]() {
m_analyzeButton->setEnabled(m_filesModel->hasCheckedFiles()); m_analyzeButton->setEnabled(m_filesModel->hasCheckedFiles());
}); });
connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed,
this, [=]() {
if (m_ui->globalOrCustom->currentIndex() == CustomSettings) {
diagnosticWidget->refresh(m_customDiagnosticConfig);
} else {
diagnosticWidget->refresh(
ClangToolsSettings::instance()->savedDiagnosticConfigId());
}
});
} }
SelectableFilesDialog::~SelectableFilesDialog() = default; SelectableFilesDialog::~SelectableFilesDialog() = default;
@@ -356,11 +307,6 @@ void SelectableFilesDialog::accept()
{ {
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project); ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
// Save diagnostic configuration
settings->setUseGlobalSettings(m_ui->globalOrCustom->currentIndex() == GlobalSettings);
settings->setDiagnosticConfig(m_customDiagnosticConfig);
// Save file selection
QSet<FilePath> checkedDirs; QSet<FilePath> checkedDirs;
QSet<FilePath> checkedFiles; QSet<FilePath> checkedFiles;
m_filesModel->minimalSelection(checkedDirs, checkedFiles); m_filesModel->minimalSelection(checkedDirs, checkedFiles);

View File

@@ -11,66 +11,14 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Analyzer Configuration</string> <string>Files to Analyze</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QGroupBox" name="groupBox_3"> <widget class="QTreeView" name="filesView">
<property name="title"> <property name="headerHidden">
<string>General</string> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="globalOrCustom">
<item>
<property name="text">
<string>Global Settings</string>
</property>
</item>
<item>
<property name="text">
<string>Custom Settings</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticWidget" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Files to Analyze</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTreeView" name="filesView">
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item> <item>
@@ -85,13 +33,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
<extends>QWidget</extends>
<header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>

View File

@@ -40,11 +40,6 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
#include <cpptools/clangdiagnosticconfigsmodel.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h>
#include <debugger/analyzer/analyzermanager.h> #include <debugger/analyzer/analyzermanager.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
@@ -362,22 +357,17 @@ ClangTidyClazyTool *ClangTidyClazyTool::instance()
return s_instance; return s_instance;
} }
static ClangDiagnosticConfig getDiagnosticConfig(Project *project) void ClangTidyClazyTool::selectPerspective()
{ {
ClangToolsProjectSettings *projectSettings = ClangToolsProjectSettingsManager::getSettings( m_perspective.select();
project); }
Core::Id diagnosticConfigId; static RunSettings runSettings(Project *project)
{
auto *projectSettings = ClangToolsProjectSettingsManager::getSettings(project);
if (projectSettings->useGlobalSettings()) if (projectSettings->useGlobalSettings())
diagnosticConfigId = ClangToolsSettings::instance()->savedDiagnosticConfigId(); return ClangToolsSettings::instance()->runSettings();
else return projectSettings->runSettings();
diagnosticConfigId = projectSettings->diagnosticConfig();
const ClangDiagnosticConfigsModel configsModel(
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
QTC_ASSERT(configsModel.hasConfigWithId(diagnosticConfigId), return ClangDiagnosticConfig());
return configsModel.configWithId(diagnosticConfigId);
} }
void ClangTidyClazyTool::startTool(FileSelection fileSelection) void ClangTidyClazyTool::startTool(FileSelection fileSelection)
@@ -397,7 +387,7 @@ void ClangTidyClazyTool::startTool(FileSelection fileSelection)
const bool preventBuild = fileSelection == FileSelection::CurrentFile; const bool preventBuild = fileSelection == FileSelection::CurrentFile;
auto clangTool = new ClangToolRunWorker(runControl, auto clangTool = new ClangToolRunWorker(runControl,
getDiagnosticConfig(project), runSettings(project),
fileInfos, fileInfos,
preventBuild); preventBuild);

View File

@@ -51,6 +51,8 @@ public:
static ClangTidyClazyTool *instance(); static ClangTidyClazyTool *instance();
void selectPerspective();
void startTool(FileSelection fileSelection) final; void startTool(FileSelection fileSelection) final;
Diagnostics read(OutputFileFormat outputFileFormat, Diagnostics read(OutputFileFormat outputFileFormat,

View File

@@ -29,6 +29,7 @@
#include "clangtidyclazytool.h" #include "clangtidyclazytool.h"
#include "clangtool.h" #include "clangtool.h"
#include "clangtoolslogfilereader.h" #include "clangtoolslogfilereader.h"
#include "clangtoolsprojectsettings.h"
#include "clangtoolssettings.h" #include "clangtoolssettings.h"
#include "clangtoolsutils.h" #include "clangtoolsutils.h"
@@ -40,7 +41,9 @@
#include <coreplugin/progressmanager/futureprogress.h> #include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/clangdiagnosticconfigsmodel.h>
#include <cpptools/compileroptionsbuilder.h> #include <cpptools/compileroptionsbuilder.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojectfile.h> #include <cpptools/cppprojectfile.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
@@ -219,19 +222,28 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
return debug; return debug;
} }
static ClangDiagnosticConfig diagnosticConfig(const Core::Id &diagConfigId)
{
const ClangDiagnosticConfigsModel configsModel(
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
QTC_ASSERT(configsModel.hasConfigWithId(diagConfigId), return ClangDiagnosticConfig());
return configsModel.configWithId(diagConfigId);
}
ClangToolRunWorker::ClangToolRunWorker(RunControl *runControl, ClangToolRunWorker::ClangToolRunWorker(RunControl *runControl,
const ClangDiagnosticConfig &diagnosticConfig, const RunSettings &runSettings,
const FileInfos &fileInfos, const FileInfos &fileInfos,
bool preventBuild) bool preventBuild)
: RunWorker(runControl) : RunWorker(runControl)
, m_temporaryDir("clangtools-XXXXXX") , m_diagnosticConfig(diagnosticConfig(runSettings.diagnosticConfigId()))
, m_diagnosticConfig(diagnosticConfig)
, m_fileInfos(fileInfos) , m_fileInfos(fileInfos)
, m_temporaryDir("clangtools-XXXXXX")
{ {
setId("ClangTidyClazyRunner"); setId("ClangTidyClazyRunner");
setSupportsReRunning(false); setSupportsReRunning(false);
if (!preventBuild && ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { if (!preventBuild && runSettings.buildBeforeAnalysis()) {
m_projectBuilder = new ProjectBuilder(runControl); m_projectBuilder = new ProjectBuilder(runControl);
addStartDependency(m_projectBuilder); addStartDependency(m_projectBuilder);
} }
@@ -272,11 +284,9 @@ void ClangToolRunWorker::start()
TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID); TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID);
ProjectExplorerPlugin::saveModifiedFiles(); ProjectExplorerPlugin::saveModifiedFiles();
if (ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { if (m_projectBuilder && !m_projectBuilder->success()) {
if (m_projectBuilder && !m_projectBuilder->success()) { reportFailure();
reportFailure(); return;
return;
}
} }
const QString &toolName = tool()->name(); const QString &toolName = tool()->name();
@@ -337,7 +347,7 @@ void ClangToolRunWorker::start()
// Start process(es) // Start process(es)
qCDebug(LOG) << "Environment:" << m_environment; qCDebug(LOG) << "Environment:" << m_environment;
m_runners.clear(); m_runners.clear();
const int parallelRuns = ClangToolsSettings::instance()->savedSimultaneousProcesses(); const int parallelRuns = m_runSettings.parallelJobs();
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return); QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
m_success = true; m_success = true;
@@ -491,7 +501,7 @@ void ClangToolRunWorker::finalize()
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID); TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
Target *target = runControl()->target(); Target *target = runControl()->target();
if (target && !target->activeBuildConfiguration()->buildDirectory().exists() if (target && !target->activeBuildConfiguration()->buildDirectory().exists()
&& !ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) { && !m_runSettings.buildBeforeAnalysis()) {
msg = tr("%1: You might need to build the project to generate or update source " msg = tr("%1: You might need to build the project to generate or update source "
"files. To build automatically, enable \"Build the project before starting " "files. To build automatically, enable \"Build the project before starting "
"analysis\".") "analysis\".")

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "clangfileinfo.h" #include "clangfileinfo.h"
#include "clangtoolssettings.h"
#include <cpptools/clangdiagnosticconfig.h> #include <cpptools/clangdiagnosticconfig.h>
#include <cpptools/projectinfo.h> #include <cpptools/projectinfo.h>
@@ -66,7 +67,7 @@ class ClangToolRunWorker : public ProjectExplorer::RunWorker
public: public:
ClangToolRunWorker(ProjectExplorer::RunControl *runControl, ClangToolRunWorker(ProjectExplorer::RunControl *runControl,
const CppTools::ClangDiagnosticConfig &diagnosticConfig, const RunSettings &runSettings,
const FileInfos &fileInfos, const FileInfos &fileInfos,
bool preventBuild); bool preventBuild);
@@ -93,15 +94,15 @@ private:
void finalize(); void finalize();
protected: private:
RunSettings m_runSettings;
CppTools::ClangDiagnosticConfig m_diagnosticConfig;
FileInfos m_fileInfos;
ProjectBuilder *m_projectBuilder = nullptr; ProjectBuilder *m_projectBuilder = nullptr;
Utils::Environment m_environment; Utils::Environment m_environment;
Utils::TemporaryDirectory m_temporaryDir; Utils::TemporaryDirectory m_temporaryDir;
private:
CppTools::ClangDiagnosticConfig m_diagnosticConfig;
FileInfos m_fileInfos;
CppTools::ProjectInfo m_projectInfoBeforeBuild; CppTools::ProjectInfo m_projectInfoBeforeBuild;
CppTools::ProjectInfo m_projectInfo; CppTools::ProjectInfo m_projectInfo;
QString m_targetTriple; QString m_targetTriple;

View File

@@ -32,6 +32,7 @@ SOURCES += \
clangtoolsprojectsettings.cpp \ clangtoolsprojectsettings.cpp \
clangtoolssettings.cpp \ clangtoolssettings.cpp \
clangtoolsutils.cpp \ clangtoolsutils.cpp \
runsettingswidget.cpp \
settingswidget.cpp \ settingswidget.cpp \
HEADERS += \ HEADERS += \
@@ -54,11 +55,13 @@ HEADERS += \
clangtoolsprojectsettings.h \ clangtoolsprojectsettings.h \
clangtoolssettings.h \ clangtoolssettings.h \
clangtoolsutils.h \ clangtoolsutils.h \
runsettingswidget.h \
settingswidget.h \ settingswidget.h \
FORMS += \ FORMS += \
clangselectablefilesdialog.ui \ clangselectablefilesdialog.ui \
clangtoolsprojectsettingswidget.ui \ clangtoolsprojectsettingswidget.ui \
runsettingswidget.ui \
settingswidget.ui \ settingswidget.ui \
equals(TEST, 1) { equals(TEST, 1) {

View File

@@ -68,6 +68,9 @@ QtcPlugin {
"clangtoolsutils.h", "clangtoolsutils.h",
"clangtoolsplugin.cpp", "clangtoolsplugin.cpp",
"clangtoolsplugin.h", "clangtoolsplugin.h",
"runsettingswidget.cpp",
"runsettingswidget.h",
"runsettingswidget.ui",
"settingswidget.cpp", "settingswidget.cpp",
"settingswidget.h", "settingswidget.h",
"settingswidget.ui", "settingswidget.ui",

View File

@@ -88,18 +88,11 @@ public:
return m_widget; return m_widget;
} }
void apply() override void apply() override { m_widget->apply(); }
{ void finish() override { delete m_widget; }
ClangToolsSettings::instance()->writeSettings();
}
void finish() override
{
delete m_widget;
}
private: private:
QPointer<QWidget> m_widget; QPointer<SettingsWidget> m_widget;
}; };
class ClangToolsPluginPrivate class ClangToolsPluginPrivate

View File

@@ -34,8 +34,9 @@
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
static const char SETTINGS_KEY_MAIN[] = "ClangTools";
static const char SETTINGS_PREFIX[] = "ClangTools.";
static const char SETTINGS_KEY_USE_GLOBAL_SETTINGS[] = "ClangTools.UseGlobalSettings"; static const char SETTINGS_KEY_USE_GLOBAL_SETTINGS[] = "ClangTools.UseGlobalSettings";
static const char SETTINGS_KEY_DIAGNOSTIC_CONFIG[] = "ClangTools.DiagnosticConfig";
static const char SETTINGS_KEY_SELECTED_DIRS[] = "ClangTools.SelectedDirs"; static const char SETTINGS_KEY_SELECTED_DIRS[] = "ClangTools.SelectedDirs";
static const char SETTINGS_KEY_SELECTED_FILES[] = "ClangTools.SelectedFiles"; static const char SETTINGS_KEY_SELECTED_FILES[] = "ClangTools.SelectedFiles";
static const char SETTINGS_KEY_SUPPRESSED_DIAGS[] = "ClangTools.SuppressedDiagnostics"; static const char SETTINGS_KEY_SUPPRESSED_DIAGS[] = "ClangTools.SuppressedDiagnostics";
@@ -78,22 +79,53 @@ void ClangToolsProjectSettings::removeAllSuppressedDiagnostics()
emit suppressedDiagnosticsChanged(); emit suppressedDiagnosticsChanged();
} }
static QVariantMap convertToMapFromVersionBefore410(ProjectExplorer::Project *p)
{
// These keys haven't changed.
const QStringList keys = {
SETTINGS_KEY_SELECTED_DIRS,
SETTINGS_KEY_SELECTED_FILES,
SETTINGS_KEY_SUPPRESSED_DIAGS,
SETTINGS_KEY_USE_GLOBAL_SETTINGS,
"ClangTools.BuildBeforeAnalysis",
};
QVariantMap map;
for (const QString &key : keys)
map.insert(key, p->namedSettings(key));
map.insert(SETTINGS_PREFIX + QString(diagnosticConfigIdKey),
p->namedSettings("ClangTools.DiagnosticConfig"));
return map;
}
void ClangToolsProjectSettings::load() void ClangToolsProjectSettings::load()
{ {
const QVariant useGlobalVariant = m_project->namedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS); // Load map
m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true; QVariantMap map = m_project->namedSettings(SETTINGS_KEY_MAIN).toMap();
m_diagnosticConfig = Core::Id::fromSetting(
m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG)); bool write;
if (map.isEmpty()) {
if (!m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).isNull()) {
map = convertToMapFromVersionBefore410(m_project);
write = true;
} else {
return; // Use defaults
}
}
// Read map
m_useGlobalSettings = map.value(SETTINGS_KEY_USE_GLOBAL_SETTINGS).toBool();
auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); }; auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); };
const QStringList dirs = map.value(SETTINGS_KEY_SELECTED_DIRS).toStringList();
const QStringList dirs = m_project->namedSettings(SETTINGS_KEY_SELECTED_DIRS).toStringList();
m_selectedDirs = Utils::transform<QSet>(dirs, toFileName); m_selectedDirs = Utils::transform<QSet>(dirs, toFileName);
const QStringList files = m_project->namedSettings(SETTINGS_KEY_SELECTED_FILES).toStringList(); const QStringList files = map.value(SETTINGS_KEY_SELECTED_FILES).toStringList();
m_selectedFiles = Utils::transform<QSet>(files, toFileName); m_selectedFiles = Utils::transform<QSet>(files, toFileName);
const QVariantList list = m_project->namedSettings(SETTINGS_KEY_SUPPRESSED_DIAGS).toList(); const QVariantList list = map.value(SETTINGS_KEY_SUPPRESSED_DIAGS).toList();
foreach (const QVariant &v, list) { foreach (const QVariant &v, list) {
const QVariantMap diag = v.toMap(); const QVariantMap diag = v.toMap();
const QString fp = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH).toString(); const QString fp = diag.value(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH).toString();
@@ -113,48 +145,37 @@ void ClangToolsProjectSettings::load()
uniquifier); uniquifier);
} }
emit suppressedDiagnosticsChanged(); emit suppressedDiagnosticsChanged();
m_runSettings.fromMap(map, SETTINGS_PREFIX);
if (write)
store(); // Store new settings format
} }
void ClangToolsProjectSettings::store() void ClangToolsProjectSettings::store()
{ {
m_project->setNamedSettings(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings); QVariantMap map;
m_project->setNamedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG, m_diagnosticConfig.toSetting()); map.insert(SETTINGS_KEY_USE_GLOBAL_SETTINGS, m_useGlobalSettings);
const QStringList dirs = Utils::transform<QList>(m_selectedDirs, &Utils::FilePath::toString); const QStringList dirs = Utils::transform<QList>(m_selectedDirs, &Utils::FilePath::toString);
m_project->setNamedSettings(SETTINGS_KEY_SELECTED_DIRS, dirs); map.insert(SETTINGS_KEY_SELECTED_DIRS, dirs);
const QStringList files = Utils::transform<QList>(m_selectedFiles, &Utils::FilePath::toString); const QStringList files = Utils::transform<QList>(m_selectedFiles, &Utils::FilePath::toString);
m_project->setNamedSettings(SETTINGS_KEY_SELECTED_FILES, files); map.insert(SETTINGS_KEY_SELECTED_FILES, files);
QVariantList list; QVariantList list;
foreach (const SuppressedDiagnostic &diag, m_suppressedDiagnostics) { for (const SuppressedDiagnostic &diag : m_suppressedDiagnostics) {
QVariantMap diagMap; QVariantMap diagMap;
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH, diag.filePath.toString()); diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_FILEPATH, diag.filePath.toString());
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_MESSAGE, diag.description); diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_MESSAGE, diag.description);
diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER, diag.uniquifier); diagMap.insert(SETTINGS_KEY_SUPPRESSED_DIAGS_UNIQIFIER, diag.uniquifier);
list << diagMap; list << diagMap;
} }
m_project->setNamedSettings(SETTINGS_KEY_SUPPRESSED_DIAGS, list); map.insert(SETTINGS_KEY_SUPPRESSED_DIAGS, list);
}
bool ClangToolsProjectSettings::useGlobalSettings() const m_runSettings.toMap(map, SETTINGS_PREFIX);
{
return m_useGlobalSettings;
}
void ClangToolsProjectSettings::setUseGlobalSettings(bool useGlobalSettings) m_project->setNamedSettings(SETTINGS_KEY_MAIN, map);
{
m_useGlobalSettings = useGlobalSettings;
}
Core::Id ClangToolsProjectSettings::diagnosticConfig() const
{
return m_diagnosticConfig;
}
void ClangToolsProjectSettings::setDiagnosticConfig(const Core::Id &diagnosticConfig)
{
m_diagnosticConfig = diagnosticConfig;
} }
ClangToolsProjectSettingsManager::ClangToolsProjectSettingsManager() ClangToolsProjectSettingsManager::ClangToolsProjectSettingsManager()

View File

@@ -25,7 +25,7 @@
#pragma once #pragma once
#include <QObject> #include "clangtoolssettings.h"
#include <coreplugin/id.h> #include <coreplugin/id.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
@@ -70,11 +70,11 @@ public:
ClangToolsProjectSettings(ProjectExplorer::Project *project); ClangToolsProjectSettings(ProjectExplorer::Project *project);
~ClangToolsProjectSettings() override; ~ClangToolsProjectSettings() override;
bool useGlobalSettings() const; bool useGlobalSettings() const { return m_useGlobalSettings; }
void setUseGlobalSettings(bool useGlobalSettings); void setUseGlobalSettings(bool useGlobalSettings) { m_useGlobalSettings = useGlobalSettings; }
Core::Id diagnosticConfig() const; RunSettings runSettings() const { return m_runSettings; }
void setDiagnosticConfig(const Core::Id &diagnosticConfig); void setRunSettings(const RunSettings &settings) { m_runSettings = settings; }
QSet<Utils::FilePath> selectedDirs() const { return m_selectedDirs; } QSet<Utils::FilePath> selectedDirs() const { return m_selectedDirs; }
void setSelectedDirs(const QSet<Utils::FilePath> &value) { m_selectedDirs = value; } void setSelectedDirs(const QSet<Utils::FilePath> &value) { m_selectedDirs = value; }
@@ -95,10 +95,14 @@ private:
void store(); void store();
ProjectExplorer::Project *m_project; ProjectExplorer::Project *m_project;
bool m_useGlobalSettings = true; bool m_useGlobalSettings = true;
Core::Id m_diagnosticConfig;
RunSettings m_runSettings;
QSet<Utils::FilePath> m_selectedDirs; QSet<Utils::FilePath> m_selectedDirs;
QSet<Utils::FilePath> m_selectedFiles; QSet<Utils::FilePath> m_selectedFiles;
SuppressedDiagnosticsList m_suppressedDiagnostics; SuppressedDiagnosticsList m_suppressedDiagnostics;
}; };

View File

@@ -26,8 +26,12 @@
#include "clangtoolsprojectsettingswidget.h" #include "clangtoolsprojectsettingswidget.h"
#include "ui_clangtoolsprojectsettingswidget.h" #include "ui_clangtoolsprojectsettingswidget.h"
#include "clangtidyclazytool.h"
#include "clangtoolsconstants.h"
#include "clangtoolsprojectsettings.h" #include "clangtoolsprojectsettings.h"
#include <coreplugin/icore.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QAbstractTableModel> #include <QAbstractTableModel>
@@ -56,12 +60,46 @@ private:
SuppressedDiagnosticsList m_diagnostics; SuppressedDiagnosticsList m_diagnostics;
}; };
enum { UseGlobalSettings, UseCustomSettings }; // Values in sync with m_ui->globalCustomComboBox
ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project, QWidget *parent) : ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project, QWidget *parent) :
QWidget(parent), QWidget(parent),
m_ui(new Ui::ProjectSettingsWidget) m_ui(new Ui::ProjectSettingsWidget)
, m_projectSettings(ClangToolsProjectSettingsManager::getSettings(project)) , m_projectSettings(ClangToolsProjectSettingsManager::getSettings(project))
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
// Use global/custom settings
const int globalOrCustomIndex = m_projectSettings->useGlobalSettings() ? UseGlobalSettings
: UseCustomSettings;
m_ui->globalCustomComboBox->setCurrentIndex(globalOrCustomIndex);
onGlobalCustomChanged(globalOrCustomIndex);
connect(m_ui->globalCustomComboBox,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
&ProjectSettingsWidget::onGlobalCustomChanged);
// Restore global settings
connect(m_ui->restoreGlobal, &QPushButton::clicked, this, [this]() {
m_ui->runSettingsWidget->fromSettings(ClangToolsSettings::instance()->runSettings());
});
// Links
connect(m_ui->gotoGlobalSettingsLabel, &QLabel::linkActivated, [](const QString &){
Core::ICore::showOptionsDialog(ClangTools::Constants::SETTINGS_PAGE_ID);
});
connect(m_ui->gotoAnalyzerModeLabel, &QLabel::linkActivated, [](const QString &){
ClangTidyClazyTool::instance()->selectPerspective();
});
// Run options
m_ui->runSettingsWidget->fromSettings(m_projectSettings->runSettings());
connect(m_ui->runSettingsWidget, &RunSettingsWidget::changed, [this]() {
m_projectSettings->setRunSettings(m_ui->runSettingsWidget->toSettings());
});
// Suppressed diagnostics
auto * const model = new SuppressedDiagnosticsModel(this); auto * const model = new SuppressedDiagnosticsModel(this);
model->setDiagnostics(m_projectSettings->suppressedDiagnostics()); model->setDiagnostics(m_projectSettings->suppressedDiagnostics());
connect(m_projectSettings, &ClangToolsProjectSettings::suppressedDiagnosticsChanged, connect(m_projectSettings, &ClangToolsProjectSettings::suppressedDiagnosticsChanged,
@@ -86,6 +124,14 @@ ProjectSettingsWidget::~ProjectSettingsWidget()
delete m_ui; delete m_ui;
} }
void ProjectSettingsWidget::onGlobalCustomChanged(int index)
{
const bool useGlobal = index == UseGlobalSettings;
m_ui->runSettingsWidget->setEnabled(!useGlobal);
m_ui->restoreGlobal->setEnabled(!useGlobal);
m_projectSettings->setUseGlobalSettings(useGlobal);
}
void ProjectSettingsWidget::updateButtonStates() void ProjectSettingsWidget::updateButtonStates()
{ {
updateButtonStateRemoveSelected(); updateButtonStateRemoveSelected();

View File

@@ -44,6 +44,8 @@ public:
~ProjectSettingsWidget() override; ~ProjectSettingsWidget() override;
private: private:
void onGlobalCustomChanged(int index);
void updateButtonStates(); void updateButtonStates();
void updateButtonStateRemoveSelected(); void updateButtonStateRemoveSelected();
void updateButtonStateRemoveAll(); void updateButtonStateRemoveAll();

View File

@@ -6,20 +6,41 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>615</width>
<height>300</height> <height>399</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string/> <string/>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QComboBox" name="globalCustomComboBox">
<item>
<property name="text">
<string>Use Global Settings</string>
</property>
</item>
<item>
<property name="text">
<string>Use Customized Settings</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="restoreGlobal">
<property name="text"> <property name="text">
<string>Suppressed diagnostics:</string> <string>Restore Global Settings</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gotoGlobalSettingsLabel">
<property name="text">
<string>&lt;a href=&quot;target&quot;&gt;Show Global Settings&lt;/a&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -36,52 +57,79 @@
</property> </property>
</spacer> </spacer>
</item> </item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QTreeView" name="diagnosticsView"> <widget class="QLabel" name="gotoAnalyzerModeLabel">
<property name="selectionMode"> <property name="text">
<enum>QAbstractItemView::SingleSelection</enum> <string>&lt;a href=&quot;target&quot;&gt;Go to Analyzer&lt;/a&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="removeSelectedButton">
<property name="text">
<string>Remove Selected</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeAllButton">
<property name="text">
<string>Remove All</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
<item>
<widget class="ClangTools::Internal::RunSettingsWidget" name="runSettingsWidget" native="true"/>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Suppressed diagnostics</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTreeView" name="diagnosticsView">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="removeSelectedButton">
<property name="text">
<string>Remove Selected</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeAllButton">
<property name="text">
<string>Remove All</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>ClangTools::Internal::RunSettingsWidget</class>
<extends>QWidget</extends>
<header>clangtools/runsettingswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@@ -29,21 +29,38 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <QFileInfo>
#include <QThread> #include <QThread>
static const char simultaneousProcessesKey[] = "simultaneousProcesses"; static const char clangTidyExecutableKey[] = "ClangTidyExecutable";
static const char buildBeforeAnalysisKey[] = "buildBeforeAnalysis"; static const char clazyStandaloneExecutableKey[] = "ClazyStandaloneExecutable";
static const char diagnosticConfigIdKey[] = "diagnosticConfigId";
static const char clangTidyExecutableKey[] = "clangTidyExecutable"; static const char parallelJobsKey[] = "ParallelJobs";
static const char clazyStandaloneExecutableKey[] = "clazyStandaloneExecutable"; static const char buildBeforeAnalysisKey[] = "BuildBeforeAnalysis";
static const char oldDiagnosticConfigIdKey[] = "diagnosticConfigId";
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
RunSettings::RunSettings()
: m_parallelJobs(qMax(0, QThread::idealThreadCount() / 2))
{
}
void RunSettings::fromMap(const QVariantMap &map, const QString &prefix)
{
m_diagnosticConfigId = Core::Id::fromSetting(map.value(prefix + diagnosticConfigIdKey));
m_parallelJobs = map.value(prefix + parallelJobsKey).toInt();
m_buildBeforeAnalysis = map.value(prefix + buildBeforeAnalysisKey).toBool();
}
void RunSettings::toMap(QVariantMap &map, const QString &prefix) const
{
map.insert(prefix + diagnosticConfigIdKey, m_diagnosticConfigId.toSetting());
map.insert(prefix + parallelJobsKey, m_parallelJobs);
map.insert(prefix + buildBeforeAnalysisKey, m_buildBeforeAnalysis);
}
ClangToolsSettings::ClangToolsSettings() ClangToolsSettings::ClangToolsSettings()
{ {
readSettings(); readSettings();
@@ -55,134 +72,69 @@ ClangToolsSettings *ClangToolsSettings::instance()
return &instance; return &instance;
} }
int ClangToolsSettings::savedSimultaneousProcesses() const static QVariantMap convertToMapFromVersionBefore410(QSettings *s)
{ {
return m_savedSimultaneousProcesses; const char oldParallelJobsKey[] = "simultaneousProcesses";
} const char oldBuildBeforeAnalysisKey[] = "buildBeforeAnalysis";
int ClangToolsSettings::simultaneousProcesses() const QVariantMap map;
{ map.insert(diagnosticConfigIdKey, s->value(oldDiagnosticConfigIdKey));
return m_simultaneousProcesses; map.insert(parallelJobsKey, s->value(oldParallelJobsKey));
} map.insert(buildBeforeAnalysisKey, s->value(oldBuildBeforeAnalysisKey));
void ClangToolsSettings::setSimultaneousProcesses(int processes) s->remove(oldDiagnosticConfigIdKey);
{ s->remove(oldParallelJobsKey);
m_simultaneousProcesses = processes; s->remove(oldBuildBeforeAnalysisKey);
}
bool ClangToolsSettings::savedBuildBeforeAnalysis() const return map;
{
return m_savedBuildBeforeAnalysis;
}
bool ClangToolsSettings::buildBeforeAnalysis() const
{
return m_buildBeforeAnalysis;
}
void ClangToolsSettings::setBuildBeforeAnalysis(bool build)
{
m_buildBeforeAnalysis = build;
}
Core::Id ClangToolsSettings::savedDiagnosticConfigId() const
{
return m_savedDiagnosticConfigId;
}
Core::Id ClangToolsSettings::diagnosticConfigId() const
{
return m_diagnosticConfigId;
}
void ClangToolsSettings::setDiagnosticConfigId(Core::Id id)
{
m_diagnosticConfigId = id;
}
void ClangToolsSettings::updateSavedBuildBeforeAnalysiIfRequired()
{
if (m_savedBuildBeforeAnalysis == m_buildBeforeAnalysis)
return;
m_savedBuildBeforeAnalysis = m_buildBeforeAnalysis;
emit buildBeforeAnalysisChanged(m_savedBuildBeforeAnalysis);
}
QString ClangToolsSettings::savedClazyStandaloneExecutable() const
{
return m_savedClazyStandaloneExecutable;
}
QString ClangToolsSettings::savedClangTidyExecutable() const
{
return m_savedClangTidyExecutable;
}
QString ClangToolsSettings::clazyStandaloneExecutable() const
{
return m_clazyStandaloneExecutable;
}
void ClangToolsSettings::setClazyStandaloneExecutable(const QString &path)
{
m_clazyStandaloneExecutable = path;
}
QString ClangToolsSettings::clangTidyExecutable() const
{
return m_clangTidyExecutable;
}
void ClangToolsSettings::setClangTidyExecutable(const QString &path)
{
m_clangTidyExecutable = path;
} }
void ClangToolsSettings::readSettings() void ClangToolsSettings::readSettings()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *s = Core::ICore::settings();
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID)); s->beginGroup(Constants::SETTINGS_ID);
m_clangTidyExecutable = s->value(clangTidyExecutableKey).toString();
m_clazyStandaloneExecutable = s->value(clazyStandaloneExecutableKey).toString();
const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2); bool write = false;
m_savedSimultaneousProcesses = m_simultaneousProcesses
= settings->value(QString(simultaneousProcessesKey),
defaultSimultaneousProcesses).toInt();
m_buildBeforeAnalysis = settings->value(QString(buildBeforeAnalysisKey), true).toBool(); QVariantMap map;
if (!s->value(oldDiagnosticConfigIdKey).isNull()) {
map = convertToMapFromVersionBefore410(s);
write = true;
} else {
QVariantMap defaults;
defaults.insert(diagnosticConfigIdKey, m_runSettings.diagnosticConfigId().toSetting());
defaults.insert(parallelJobsKey, m_runSettings.parallelJobs());
defaults.insert(buildBeforeAnalysisKey, m_runSettings.buildBeforeAnalysis());
map = defaults;
for (QVariantMap::ConstIterator it = defaults.constBegin(); it != defaults.constEnd(); ++it)
map.insert(it.key(), s->value(it.key(), it.value()));
}
m_savedClangTidyExecutable = m_clangTidyExecutable // Run settings
= settings->value(QLatin1String(clangTidyExecutableKey)).toString(); m_runSettings.fromMap(map);
m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable
= settings->value(QLatin1String(clazyStandaloneExecutableKey)).toString();
m_diagnosticConfigId = Core::Id::fromSetting(settings->value(QString(diagnosticConfigIdKey))); s->endGroup();
if (!m_diagnosticConfigId.isValid())
m_diagnosticConfigId = "Builtin.TidyAndClazy";
m_savedDiagnosticConfigId = m_diagnosticConfigId; if (write)
writeSettings();
updateSavedBuildBeforeAnalysiIfRequired();
settings->endGroup();
} }
void ClangToolsSettings::writeSettings() void ClangToolsSettings::writeSettings()
{ {
QSettings *settings = Core::ICore::settings(); QSettings *s = Core::ICore::settings();
settings->beginGroup(QString(Constants::SETTINGS_ID)); s->beginGroup(Constants::SETTINGS_ID);
settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses);
settings->setValue(QString(buildBeforeAnalysisKey), m_buildBeforeAnalysis);
settings->setValue(QString(clangTidyExecutableKey), m_clangTidyExecutable);
settings->setValue(QString(clazyStandaloneExecutableKey), m_clazyStandaloneExecutable);
settings->setValue(QString(diagnosticConfigIdKey), m_diagnosticConfigId.toSetting());
m_savedSimultaneousProcesses = m_simultaneousProcesses; s->setValue(clangTidyExecutableKey, m_clangTidyExecutable);
m_savedDiagnosticConfigId = m_diagnosticConfigId; s->setValue(clazyStandaloneExecutableKey, m_clazyStandaloneExecutable);
m_savedClangTidyExecutable = m_clangTidyExecutable;
m_savedClazyStandaloneExecutable = m_clazyStandaloneExecutable;
updateSavedBuildBeforeAnalysiIfRequired();
settings->endGroup(); QVariantMap map;
m_runSettings.toMap(map);
for (QVariantMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it)
s->setValue(it.key(), it.value());
s->endGroup();
} }
} // namespace Internal } // namespace Internal

View File

@@ -27,61 +27,61 @@
#include <coreplugin/id.h> #include <coreplugin/id.h>
#include <QObject>
#include <QString> #include <QString>
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
// TODO: Remove need for "saved* members const char diagnosticConfigIdKey[] = "DiagnosticConfigId";
class ClangToolsSettings : public QObject
class RunSettings
{
public:
RunSettings();
void fromMap(const QVariantMap &map, const QString &prefix = QString());
void toMap(QVariantMap &map, const QString &prefix = QString()) const;
Core::Id diagnosticConfigId() const { return m_diagnosticConfigId; }
void setDiagnosticConfigId(const Core::Id &id) { m_diagnosticConfigId = id; }
bool buildBeforeAnalysis() const { return m_buildBeforeAnalysis; }
void setBuildBeforeAnalysis(bool yesno) { m_buildBeforeAnalysis = yesno; }
int parallelJobs() const { return m_parallelJobs; }
void setParallelJobs(int jobs) { m_parallelJobs = jobs; }
private:
Core::Id m_diagnosticConfigId = "Builtin.TidyAndClazy"; // TODO
int m_parallelJobs = -1;
bool m_buildBeforeAnalysis = true;
};
class ClangToolsSettings
{ {
Q_OBJECT
public: public:
static ClangToolsSettings *instance(); static ClangToolsSettings *instance();
void writeSettings(); void writeSettings();
int savedSimultaneousProcesses() const; QString clangTidyExecutable() const { return m_clangTidyExecutable; }
bool savedBuildBeforeAnalysis() const; void setClangTidyExecutable(const QString &path) { m_clangTidyExecutable = path; }
Core::Id savedDiagnosticConfigId() const;
QString savedClangTidyExecutable() const;
QString savedClazyStandaloneExecutable() const;
int simultaneousProcesses() const; QString clazyStandaloneExecutable() const { return m_clazyStandaloneExecutable; }
void setSimultaneousProcesses(int processes); void setClazyStandaloneExecutable(const QString &path) { m_clazyStandaloneExecutable = path; }
bool buildBeforeAnalysis() const; RunSettings runSettings() const { return m_runSettings; }
void setBuildBeforeAnalysis(bool build); void setRunSettings(const RunSettings &settings) { m_runSettings = settings; }
Core::Id diagnosticConfigId() const;
void setDiagnosticConfigId(Core::Id id);
QString clangTidyExecutable() const;
void setClangTidyExecutable(const QString &path);
QString clazyStandaloneExecutable() const;
void setClazyStandaloneExecutable(const QString &path);
signals:
void buildBeforeAnalysisChanged(bool checked) const;
private: private:
ClangToolsSettings(); ClangToolsSettings();
void readSettings(); void readSettings();
void updateSavedBuildBeforeAnalysiIfRequired(); // Executables
int m_simultaneousProcesses = -1;
int m_savedSimultaneousProcesses = -1;
bool m_buildBeforeAnalysis = false;
bool m_savedBuildBeforeAnalysis= false;
QString m_clangTidyExecutable; QString m_clangTidyExecutable;
QString m_savedClangTidyExecutable;
QString m_clazyStandaloneExecutable; QString m_clazyStandaloneExecutable;
QString m_savedClazyStandaloneExecutable;
Core::Id m_diagnosticConfigId; // Run settings
Core::Id m_savedDiagnosticConfigId; RunSettings m_runSettings;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -87,7 +87,8 @@ static CppTools::ClangDiagnosticConfig configFor(const QString &tidyChecks,
config.setIsReadOnly(true); config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")}); config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")});
config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList); config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
config.setClangTidyChecks("-*," + tidyChecks); const QString theTidyChecks = tidyChecks.isEmpty() ? tidyChecks : "-*," + tidyChecks;
config.setClangTidyChecks(theTidyChecks);
config.setClazyChecks(clazyChecks); config.setClazyChecks(clazyChecks);
return config; return config;
} }
@@ -115,7 +116,7 @@ void ClangToolsUnitTests::testProject()
ClangToolsSettings *clangToolsSettings = ClangToolsSettings::instance(); ClangToolsSettings *clangToolsSettings = ClangToolsSettings::instance();
const CppTools::ClangDiagnosticConfigs originalConfigs = cppToolsSettings const CppTools::ClangDiagnosticConfigs originalConfigs = cppToolsSettings
->clangCustomDiagnosticConfigs(); ->clangCustomDiagnosticConfigs();
const Core::Id originalId = clangToolsSettings->diagnosticConfigId(); const Core::Id originalId = clangToolsSettings->runSettings().diagnosticConfigId();
CppTools::ClangDiagnosticConfigs modifiedConfigs = originalConfigs; CppTools::ClangDiagnosticConfigs modifiedConfigs = originalConfigs;
modifiedConfigs.push_back(diagnosticConfig); modifiedConfigs.push_back(diagnosticConfig);
@@ -123,12 +124,16 @@ void ClangToolsUnitTests::testProject()
ExecuteOnDestruction executeOnDestruction([=]() { ExecuteOnDestruction executeOnDestruction([=]() {
// Restore configs // Restore configs
cppToolsSettings->setClangCustomDiagnosticConfigs(originalConfigs); cppToolsSettings->setClangCustomDiagnosticConfigs(originalConfigs);
clangToolsSettings->setDiagnosticConfigId(originalId); RunSettings runSettings = clangToolsSettings->runSettings();
runSettings.setDiagnosticConfigId(originalId);
clangToolsSettings->setRunSettings(runSettings);
clangToolsSettings->writeSettings(); clangToolsSettings->writeSettings();
}); });
cppToolsSettings->setClangCustomDiagnosticConfigs(modifiedConfigs); cppToolsSettings->setClangCustomDiagnosticConfigs(modifiedConfigs);
clangToolsSettings->setDiagnosticConfigId(diagnosticConfig.id()); RunSettings runSettings = clangToolsSettings->runSettings();
runSettings.setDiagnosticConfigId(diagnosticConfig.id());
clangToolsSettings->setRunSettings(runSettings);
clangToolsSettings->writeSettings(); clangToolsSettings->writeSettings();
tool->startTool(ClangTidyClazyTool::FileSelection::AllFiles); tool->startTool(ClangTidyClazyTool::FileSelection::AllFiles);

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "runsettingswidget.h"
#include "ui_runsettingswidget.h"
#include "clangtoolssettings.h"
#include "clangtoolsutils.h"
#include <QThread>
namespace ClangTools {
namespace Internal {
RunSettingsWidget::RunSettingsWidget(QWidget *parent)
: QWidget(parent)
, m_ui(new Ui::RunSettingsWidget)
{
m_ui->setupUi(this);
connect(m_ui->diagnosticWidget,
&CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
[this](const Core::Id &) { emit changed(); });
// m_ui->buildBeforeAnalysis is handled in fromSettings()
connect(m_ui->parallelJobsSpinBox,
QOverload<int>::of(&QSpinBox::valueChanged),
[this](int) { emit changed(); });
}
RunSettingsWidget::~RunSettingsWidget()
{
delete m_ui;
}
void RunSettingsWidget::fromSettings(const RunSettings &s)
{
m_ui->diagnosticWidget->refresh(s.diagnosticConfigId());
disconnect(m_ui->buildBeforeAnalysis, 0, 0, 0);
m_ui->buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
m_ui->buildBeforeAnalysis->setCheckState(s.buildBeforeAnalysis() ? Qt::Checked : Qt::Unchecked);
connect(m_ui->buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) {
if (!checked)
showHintAboutBuildBeforeAnalysis();
emit changed();
});
m_ui->parallelJobsSpinBox->setValue(s.parallelJobs());
m_ui->parallelJobsSpinBox->setMinimum(1);
m_ui->parallelJobsSpinBox->setMaximum(QThread::idealThreadCount());
}
RunSettings RunSettingsWidget::toSettings() const
{
RunSettings s;
s.setDiagnosticConfigId(m_ui->diagnosticWidget->currentConfigId());
s.setBuildBeforeAnalysis(m_ui->buildBeforeAnalysis->checkState() == Qt::CheckState::Checked);
s.setParallelJobs(m_ui->parallelJobsSpinBox->value());
return s;
}
} // namespace Internal
} // namespace ClangTools

View File

@@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QWidget>
namespace ClangTools {
namespace Internal {
class RunSettings;
namespace Ui {
class RunSettingsWidget;
}
class RunSettingsWidget : public QWidget
{
Q_OBJECT
public:
explicit RunSettingsWidget(QWidget *parent = nullptr);
~RunSettingsWidget();
void fromSettings(const RunSettings &s);
RunSettings toSettings() const;
signals:
void changed();
private:
Ui::RunSettingsWidget *m_ui;
};
} // namespace Internal
} // namespace ClangTools

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ClangTools::Internal::RunSettingsWidget</class>
<widget class="QWidget" name="ClangTools::Internal::RunSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>383</width>
<height>125</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Run Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticWidget" native="true"/>
</item>
<item>
<widget class="QCheckBox" name="buildBeforeAnalysis">
<property name="text">
<string>Build the project before analysis</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="processesLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Parallel jobs:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="parallelJobsSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>32</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
<extends>QWidget</extends>
<header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -30,17 +30,6 @@
#include "clangtoolsconstants.h" #include "clangtoolsconstants.h"
#include "clangtoolsutils.h" #include "clangtoolsutils.h"
#include <coreplugin/icore.h>
#include <cpptools/clangdiagnosticconfigswidget.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cpptoolsreuse.h>
#include <QDir>
#include <QThread>
#include <memory>
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
@@ -48,15 +37,13 @@ static void setupPathChooser(Utils::PathChooser *const chooser,
const QString &promptDiaglogTitle, const QString &promptDiaglogTitle,
const QString &placeHolderText, const QString &placeHolderText,
const QString &pathFromSettings, const QString &pathFromSettings,
const QString &historyCompleterId, const QString &historyCompleterId)
std::function<void(const QString &path)> savePath)
{ {
chooser->setPromptDialogTitle(promptDiaglogTitle); chooser->setPromptDialogTitle(promptDiaglogTitle);
chooser->lineEdit()->setPlaceholderText(placeHolderText); chooser->lineEdit()->setPlaceholderText(placeHolderText);
chooser->setPath(pathFromSettings); chooser->setPath(pathFromSettings);
chooser->setExpectedKind(Utils::PathChooser::ExistingCommand); chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
chooser->setHistoryCompleter(historyCompleterId); chooser->setHistoryCompleter(historyCompleterId);
QObject::connect(chooser, &Utils::PathChooser::rawPathChanged, savePath),
chooser->setValidationFunction([chooser](Utils::FancyLineEdit *edit, QString *errorMessage) { chooser->setValidationFunction([chooser](Utils::FancyLineEdit *edit, QString *errorMessage) {
const QString currentFilePath = chooser->fileName().toString(); const QString currentFilePath = chooser->fileName().toString();
Utils::PathChooser pc; Utils::PathChooser pc;
@@ -92,8 +79,7 @@ SettingsWidget::SettingsWidget(ClangToolsSettings *settings, QWidget *parent)
tr("Clang-Tidy Executable"), tr("Clang-Tidy Executable"),
placeHolderText, placeHolderText,
path, path,
"ClangTools.ClangTidyExecutable.History", "ClangTools.ClangTidyExecutable.History");
[settings](const QString &path) { settings->setClangTidyExecutable(path); });
if (qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) { if (qEnvironmentVariable("QTC_USE_CLAZY_STANDALONE_PATH").isEmpty()) {
m_ui->clazyStandalonePathChooser->setVisible(false); m_ui->clazyStandalonePathChooser->setVisible(false);
@@ -107,47 +93,23 @@ SettingsWidget::SettingsWidget(ClangToolsSettings *settings, QWidget *parent)
tr("Clazy Executable"), tr("Clazy Executable"),
placeHolderText, placeHolderText,
path, path,
"ClangTools.ClazyStandaloneExecutable.History", "ClangTools.ClazyStandaloneExecutable.History");
[settings](const QString &path) {
settings->setClazyStandaloneExecutable(path);
});
} }
// //
// Group box "Run Options" // Group box "Run Options"
// //
m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses());
m_ui->simultaneousProccessesSpinBox->setMinimum(1);
m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
connect(m_ui->simultaneousProccessesSpinBox,
QOverload<int>::of(&QSpinBox::valueChanged),
[settings](int count) { settings->setSimultaneousProcesses(count); });
QCheckBox *buildBeforeAnalysis = m_ui->buildBeforeAnalysis; m_ui->runSettingsWidget->fromSettings(m_settings->runSettings());
buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis()); }
buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis()
? Qt::Checked : Qt::Unchecked);
connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) {
if (!checked)
showHintAboutBuildBeforeAnalysis();
settings->setBuildBeforeAnalysis(checked);
});
CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticWidget = m_ui->diagnosticWidget; void SettingsWidget::apply()
diagnosticWidget->refresh(settings->savedDiagnosticConfigId()); {
m_settings->setClangTidyExecutable(m_ui->clangTidyPathChooser->rawPath());
m_settings->setClazyStandaloneExecutable(m_ui->clazyStandalonePathChooser->rawPath());
m_settings->setRunSettings(m_ui->runSettingsWidget->toSettings());
connect(diagnosticWidget, m_settings->writeSettings();
&CppTools::ClangDiagnosticConfigsSelectionWidget::currentConfigChanged,
this, [this](const Core::Id &currentConfigId) {
m_settings->setDiagnosticConfigId(currentConfigId);
});
connect(CppTools::codeModelSettings().data(), &CppTools::CppCodeModelSettings::changed,
this, [=]() {
// Settings were applied so apply also the current selection if possible.
diagnosticWidget->refresh(m_settings->diagnosticConfigId());
m_settings->writeSettings();
});
} }
SettingsWidget::~SettingsWidget() = default; SettingsWidget::~SettingsWidget() = default;

View File

@@ -43,6 +43,9 @@ class SettingsWidget : public QWidget
public: public:
SettingsWidget(ClangToolsSettings *settings, QWidget *parent = nullptr); SettingsWidget(ClangToolsSettings *settings, QWidget *parent = nullptr);
~SettingsWidget() override; ~SettingsWidget() override;
void apply();
private: private:
std::unique_ptr<Ui::SettingsWidget> m_ui; std::unique_ptr<Ui::SettingsWidget> m_ui;
ClangToolsSettings *m_settings; ClangToolsSettings *m_settings;

View File

@@ -44,57 +44,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="ClangTools::Internal::RunSettingsWidget" name="runSettingsWidget" native="true"/>
<property name="title">
<string>Run Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="CppTools::ClangDiagnosticConfigsSelectionWidget" name="diagnosticWidget" native="true"/>
</item>
<item>
<widget class="QCheckBox" name="buildBeforeAnalysis">
<property name="text">
<string>Build the project before analysis</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="processesLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Simultaneous processes:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>32</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
@@ -112,17 +62,18 @@
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>CppTools::ClangDiagnosticConfigsSelectionWidget</class>
<extends>QWidget</extends>
<header>cpptools/clangdiagnosticconfigsselectionwidget.h</header>
</customwidget>
<customwidget> <customwidget>
<class>Utils::PathChooser</class> <class>Utils::PathChooser</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header> <header location="global">utils/pathchooser.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>ClangTools::Internal::RunSettingsWidget</class>
<extends>QWidget</extends>
<header>clangtools/runsettingswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>