forked from qt-creator/qt-creator
Valgrind: Create a SuppressionsAspect
This is a fairly complex use case, as the corresponding widget looks the same in global settings and Project settings, but behaves differently (Project only stores a diff, is auto-apply). It also use two(!) settings keys in the project case. So while it works, it takes manual help for the cancel/apply and toMap/fromMap. Looks like there is still some basic infrastructure missing. Change-Id: I25ab7b41616ee09ff9133e93b84f34947fc32988 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -128,7 +128,7 @@ public:
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
QStringList suppressionFiles() const;
|
||||
const QStringList suppressionFiles() const;
|
||||
|
||||
signals:
|
||||
void internalParserError(const QString &errorString);
|
||||
@@ -212,7 +212,7 @@ QStringList MemcheckToolRunner::toolArguments() const
|
||||
}
|
||||
arguments << "--leak-check=" + leakCheckValue;
|
||||
|
||||
foreach (const QString &file, m_settings.suppressionFiles())
|
||||
for (const QString &file : m_settings.suppressions.value())
|
||||
arguments << QString("--suppressions=%1").arg(file);
|
||||
|
||||
arguments << QString("--num-callers=%1").arg(m_settings.numCallers.value());
|
||||
@@ -225,9 +225,9 @@ QStringList MemcheckToolRunner::toolArguments() const
|
||||
return arguments;
|
||||
}
|
||||
|
||||
QStringList MemcheckToolRunner::suppressionFiles() const
|
||||
const QStringList MemcheckToolRunner::suppressionFiles() const
|
||||
{
|
||||
return m_settings.suppressionFiles();
|
||||
return m_settings.suppressions.value();
|
||||
}
|
||||
|
||||
void MemcheckToolRunner::startDebugger(qint64 valgrindPid)
|
||||
|
@@ -44,13 +44,12 @@
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFile>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
using namespace Valgrind::XmlProtocol;
|
||||
|
||||
@@ -217,7 +216,7 @@ void SuppressionDialog::accept()
|
||||
}
|
||||
}
|
||||
|
||||
m_settings->addSuppressionFiles(QStringList(path));
|
||||
m_settings->suppressions.addSuppressionFile(path);
|
||||
|
||||
QModelIndexList indices = m_view->selectionModel()->selectedRows();
|
||||
Utils::sort(indices, [](const QModelIndex &l, const QModelIndex &r) {
|
||||
|
@@ -30,26 +30,17 @@
|
||||
|
||||
#include <debugger/analyzer/analyzericons.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFileDialog>
|
||||
#include <QListView>
|
||||
#include <QPushButton>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Valgrind {
|
||||
namespace Internal {
|
||||
|
||||
class ValgrindBaseSettings;
|
||||
|
||||
class ValgrindConfigWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Valgrind::Internal::ValgrindConfigWidget)
|
||||
@@ -63,37 +54,14 @@ public:
|
||||
ValgrindGlobalSettings::instance()->writeSettings();
|
||||
}
|
||||
|
||||
void setSuppressions(const QStringList &files);
|
||||
QStringList suppressions() const;
|
||||
|
||||
void slotAddSuppression();
|
||||
void slotRemoveSuppression();
|
||||
void slotSuppressionsRemoved(const QStringList &files);
|
||||
void slotSuppressionsAdded(const QStringList &files);
|
||||
void slotSuppressionSelectionChanged();
|
||||
|
||||
private:
|
||||
void updateUi();
|
||||
|
||||
ValgrindBaseSettings *m_settings;
|
||||
|
||||
QPushButton *addSuppression;
|
||||
QPushButton *removeSuppression;
|
||||
QListView *suppressionList;
|
||||
|
||||
QStandardItemModel m_model;
|
||||
void finish() final
|
||||
{
|
||||
ValgrindGlobalSettings::instance()->group.finish();
|
||||
}
|
||||
};
|
||||
|
||||
ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings)
|
||||
: m_settings(settings)
|
||||
{
|
||||
addSuppression = new QPushButton(tr("Add..."));
|
||||
removeSuppression = new QPushButton(tr("Remove"));
|
||||
|
||||
suppressionList = new QListView;
|
||||
suppressionList->setModel(&m_model);
|
||||
suppressionList->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
|
||||
using namespace Layouting;
|
||||
const Break nl;
|
||||
ValgrindBaseSettings &s = *settings;
|
||||
@@ -111,16 +79,7 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings)
|
||||
s.leakCheckOnFinish, nl,
|
||||
s.numCallers, nl,
|
||||
s.filterExternalIssues, nl,
|
||||
Item {
|
||||
Group {
|
||||
Title(tr("Suppression files:")),
|
||||
Row {
|
||||
suppressionList,
|
||||
Column { addSuppression, removeSuppression, Stretch() }
|
||||
}
|
||||
},
|
||||
2 // Span.
|
||||
}
|
||||
s.suppressions
|
||||
};
|
||||
|
||||
Grid callgrind {
|
||||
@@ -146,111 +105,6 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings)
|
||||
Group { Title(tr("CallGrind Profiling Options")), callgrind },
|
||||
Stretch(),
|
||||
}.attachTo(this);
|
||||
|
||||
|
||||
updateUi();
|
||||
connect(m_settings, &ValgrindBaseSettings::changed, this, &ValgrindConfigWidget::updateUi);
|
||||
|
||||
connect(addSuppression, &QPushButton::clicked,
|
||||
this, &ValgrindConfigWidget::slotAddSuppression);
|
||||
connect(removeSuppression, &QPushButton::clicked,
|
||||
this, &ValgrindConfigWidget::slotRemoveSuppression);
|
||||
|
||||
connect(&s, &ValgrindBaseSettings::suppressionFilesRemoved,
|
||||
this, &ValgrindConfigWidget::slotSuppressionsRemoved);
|
||||
connect(&s, &ValgrindBaseSettings::suppressionFilesAdded,
|
||||
this, &ValgrindConfigWidget::slotSuppressionsAdded);
|
||||
|
||||
connect(suppressionList->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &ValgrindConfigWidget::slotSuppressionSelectionChanged);
|
||||
|
||||
slotSuppressionSelectionChanged();
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::updateUi()
|
||||
{
|
||||
m_model.clear();
|
||||
foreach (const QString &file, m_settings->suppressionFiles())
|
||||
m_model.appendRow(new QStandardItem(file));
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::slotAddSuppression()
|
||||
{
|
||||
ValgrindGlobalSettings *conf = ValgrindGlobalSettings::instance();
|
||||
QTC_ASSERT(conf, return);
|
||||
QStringList files = QFileDialog::getOpenFileNames(this,
|
||||
tr("Valgrind Suppression Files"),
|
||||
conf->lastSuppressionDirectory.value(),
|
||||
tr("Valgrind Suppression File (*.supp);;All Files (*)"));
|
||||
//dialog.setHistory(conf->lastSuppressionDialogHistory());
|
||||
if (!files.isEmpty()) {
|
||||
foreach (const QString &file, files)
|
||||
m_model.appendRow(new QStandardItem(file));
|
||||
m_settings->addSuppressionFiles(files);
|
||||
conf->lastSuppressionDirectory.setValue(QFileInfo(files.at(0)).absolutePath());
|
||||
//conf->setLastSuppressionDialogHistory(dialog.history());
|
||||
}
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::slotSuppressionsAdded(const QStringList &files)
|
||||
{
|
||||
QStringList filesToAdd = files;
|
||||
for (int i = 0, c = m_model.rowCount(); i < c; ++i)
|
||||
filesToAdd.removeAll(m_model.item(i)->text());
|
||||
|
||||
foreach (const QString &file, filesToAdd)
|
||||
m_model.appendRow(new QStandardItem(file));
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::slotRemoveSuppression()
|
||||
{
|
||||
// remove from end so no rows get invalidated
|
||||
QList<int> rows;
|
||||
|
||||
QStringList removed;
|
||||
foreach (const QModelIndex &index, suppressionList->selectionModel()->selectedIndexes()) {
|
||||
rows << index.row();
|
||||
removed << index.data().toString();
|
||||
}
|
||||
|
||||
Utils::sort(rows, std::greater<int>());
|
||||
|
||||
foreach (int row, rows)
|
||||
m_model.removeRow(row);
|
||||
|
||||
m_settings->removeSuppressionFiles(removed);
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files)
|
||||
{
|
||||
for (int i = 0; i < m_model.rowCount(); ++i) {
|
||||
if (files.contains(m_model.item(i)->text())) {
|
||||
m_model.removeRow(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::setSuppressions(const QStringList &files)
|
||||
{
|
||||
m_model.clear();
|
||||
foreach (const QString &file, files)
|
||||
m_model.appendRow(new QStandardItem(file));
|
||||
}
|
||||
|
||||
QStringList ValgrindConfigWidget::suppressions() const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < m_model.rowCount(); ++i)
|
||||
ret << m_model.item(i)->text();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ValgrindConfigWidget::slotSuppressionSelectionChanged()
|
||||
{
|
||||
removeSuppression->setEnabled(suppressionList->selectionModel()->hasSelection());
|
||||
}
|
||||
|
||||
// ValgrindOptionsPage
|
||||
|
@@ -30,32 +30,277 @@
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/treemodel.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <valgrind/xmlprotocol/error.h>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
#include <QFileDialog>
|
||||
#include <QListView>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Valgrind {
|
||||
namespace Internal {
|
||||
|
||||
//
|
||||
// SuppressionAspect
|
||||
//
|
||||
|
||||
// This is somewhat unusual, as it looks the same in Global Settings and Project
|
||||
// settings, but behaves differently (Project only stores a diff) depending on
|
||||
// context.
|
||||
|
||||
const char globalSuppressionKey[] = "Analyzer.Valgrind.SupressionFiles";
|
||||
const char removedProjectSuppressionKey[] = "Analyzer.Valgrind.RemovedSuppressionFiles";
|
||||
const char addedProjectSuppressionKey[] = "Analyzer.Valgrind.AddedSuppressionFiles";
|
||||
|
||||
class SuppressionAspectPrivate : public QObject
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Valgrind::Internal::ValgrindConfigWidget)
|
||||
|
||||
public:
|
||||
SuppressionAspectPrivate(SuppressionAspect *q, bool global) : q(q), isGlobal(global) {}
|
||||
|
||||
void slotAddSuppression();
|
||||
void slotRemoveSuppression();
|
||||
void slotSuppressionSelectionChanged();
|
||||
|
||||
SuppressionAspect *q;
|
||||
const bool isGlobal;
|
||||
|
||||
QPointer<QPushButton> addEntry;
|
||||
QPointer<QPushButton> removeEntry;
|
||||
QPointer<QListView> entryList;
|
||||
|
||||
QStandardItemModel m_model; // The volatile value of this aspect.
|
||||
|
||||
QStringList globalSuppressionFiles; // Real value, only used for global settings
|
||||
|
||||
QStringList removedProjectSuppressionFiles; // Part of real value for project settings
|
||||
QStringList addedProjectSuppressionFiles; // Part of real value for project settings
|
||||
};
|
||||
|
||||
void SuppressionAspect::addSuppressionFile(const QString &suppression)
|
||||
{
|
||||
if (d->isGlobal) {
|
||||
d->globalSuppressionFiles.append(suppression);
|
||||
} else {
|
||||
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressions.value();
|
||||
if (!d->addedProjectSuppressionFiles.contains(suppression))
|
||||
d->addedProjectSuppressionFiles.append(suppression);
|
||||
d->removedProjectSuppressionFiles.removeAll(suppression);
|
||||
}
|
||||
setVolatileValue(value());
|
||||
}
|
||||
|
||||
void SuppressionAspectPrivate::slotAddSuppression()
|
||||
{
|
||||
ValgrindGlobalSettings *conf = ValgrindGlobalSettings::instance();
|
||||
QTC_ASSERT(conf, return);
|
||||
const QStringList files =
|
||||
QFileDialog::getOpenFileNames(Core::ICore::dialogParent(),
|
||||
tr("Valgrind Suppression Files"),
|
||||
conf->lastSuppressionDirectory.value(),
|
||||
tr("Valgrind Suppression File (*.supp);;All Files (*)"));
|
||||
//dialog.setHistory(conf->lastSuppressionDialogHistory());
|
||||
if (!files.isEmpty()) {
|
||||
for (const QString &file : files)
|
||||
m_model.appendRow(new QStandardItem(file));
|
||||
conf->lastSuppressionDirectory.setValue(QFileInfo(files.at(0)).absolutePath());
|
||||
//conf->setLastSuppressionDialogHistory(dialog.history());
|
||||
if (!isGlobal)
|
||||
q->apply();
|
||||
}
|
||||
}
|
||||
|
||||
void SuppressionAspectPrivate::slotRemoveSuppression()
|
||||
{
|
||||
// remove from end so no rows get invalidated
|
||||
QList<int> rows;
|
||||
|
||||
QStringList removed;
|
||||
const QModelIndexList selected = entryList->selectionModel()->selectedIndexes();
|
||||
for (const QModelIndex &index : selected) {
|
||||
rows << index.row();
|
||||
removed << index.data().toString();
|
||||
}
|
||||
|
||||
Utils::sort(rows, std::greater<int>());
|
||||
|
||||
for (int row : qAsConst(rows))
|
||||
m_model.removeRow(row);
|
||||
|
||||
if (!isGlobal)
|
||||
q->apply();
|
||||
}
|
||||
|
||||
void SuppressionAspectPrivate::slotSuppressionSelectionChanged()
|
||||
{
|
||||
removeEntry->setEnabled(entryList->selectionModel()->hasSelection());
|
||||
}
|
||||
|
||||
//
|
||||
// SuppressionAspect
|
||||
//
|
||||
|
||||
SuppressionAspect::SuppressionAspect(bool global)
|
||||
{
|
||||
d = new SuppressionAspectPrivate(this, global);
|
||||
}
|
||||
|
||||
SuppressionAspect::~SuppressionAspect()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QStringList SuppressionAspect::value() const
|
||||
{
|
||||
// Note: BaseAspect::d->value is /not/ used.
|
||||
if (d->isGlobal)
|
||||
return d->globalSuppressionFiles;
|
||||
|
||||
QStringList ret = ValgrindGlobalSettings::instance()->suppressions.value();
|
||||
for (const QString &s : d->removedProjectSuppressionFiles)
|
||||
ret.removeAll(s);
|
||||
ret.append(d->addedProjectSuppressionFiles);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SuppressionAspect::setValue(const QStringList &val)
|
||||
{
|
||||
if (d->isGlobal) {
|
||||
d->globalSuppressionFiles = val;
|
||||
} else {
|
||||
const QStringList globals = ValgrindGlobalSettings::instance()->suppressions.value();
|
||||
d->addedProjectSuppressionFiles.clear();
|
||||
for (const QString &s : val) {
|
||||
if (!globals.contains(s))
|
||||
d->addedProjectSuppressionFiles.append(s);
|
||||
}
|
||||
d->removedProjectSuppressionFiles.clear();
|
||||
for (const QString &s : globals) {
|
||||
if (!val.contains(s))
|
||||
d->removedProjectSuppressionFiles.append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuppressionAspect::addToLayout(LayoutBuilder &builder)
|
||||
{
|
||||
QTC_CHECK(!d->addEntry);
|
||||
QTC_CHECK(!d->removeEntry);
|
||||
QTC_CHECK(!d->entryList);
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
d->addEntry = new QPushButton(tr("Add..."));
|
||||
d->removeEntry = new QPushButton(tr("Remove"));
|
||||
|
||||
d->entryList = new QListView;
|
||||
d->entryList->setModel(&d->m_model);
|
||||
d->entryList->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
|
||||
connect(d->addEntry, &QPushButton::clicked,
|
||||
d, &SuppressionAspectPrivate::slotAddSuppression);
|
||||
connect(d->removeEntry, &QPushButton::clicked,
|
||||
d, &SuppressionAspectPrivate::slotRemoveSuppression);
|
||||
connect(d->entryList->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
d, &SuppressionAspectPrivate::slotSuppressionSelectionChanged);
|
||||
|
||||
Group group {
|
||||
Title(tr("Suppression files:")),
|
||||
Row {
|
||||
d->entryList.data(),
|
||||
Column { d->addEntry.data(), d->removeEntry.data(), Stretch() }
|
||||
}
|
||||
};
|
||||
builder.addItem(Item { group, 2 });
|
||||
}
|
||||
|
||||
void SuppressionAspect::fromMap(const QVariantMap &map)
|
||||
{
|
||||
if (d->isGlobal) {
|
||||
d->globalSuppressionFiles = map.value(globalSuppressionKey).toStringList();
|
||||
} else {
|
||||
d->addedProjectSuppressionFiles = map.value(addedProjectSuppressionKey).toStringList();
|
||||
d->removedProjectSuppressionFiles = map.value(removedProjectSuppressionKey).toStringList();
|
||||
}
|
||||
setVolatileValue(value());
|
||||
}
|
||||
|
||||
void SuppressionAspect::toMap(QVariantMap &map) const
|
||||
{
|
||||
auto save = [&map](const QStringList &data, const QString &key) {
|
||||
if (data.isEmpty())
|
||||
map.remove(key);
|
||||
else
|
||||
map.insert(key, data);
|
||||
};
|
||||
|
||||
if (d->isGlobal) {
|
||||
save(d->globalSuppressionFiles, globalSuppressionKey);
|
||||
} else {
|
||||
save(d->addedProjectSuppressionFiles, addedProjectSuppressionKey);
|
||||
save(d->removedProjectSuppressionFiles, removedProjectSuppressionKey);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant SuppressionAspect::volatileValue() const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < d->m_model.rowCount(); ++i)
|
||||
ret << d->m_model.item(i)->text();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SuppressionAspect::setVolatileValue(const QVariant &val)
|
||||
{
|
||||
const QStringList files = val.toStringList();
|
||||
d->m_model.clear();
|
||||
for (const QString &file : files)
|
||||
d->m_model.appendRow(new QStandardItem(file));
|
||||
}
|
||||
|
||||
void SuppressionAspect::cancel()
|
||||
{
|
||||
setVolatileValue(value());
|
||||
}
|
||||
|
||||
void SuppressionAspect::apply()
|
||||
{
|
||||
setValue(volatileValue().toStringList());
|
||||
}
|
||||
|
||||
void SuppressionAspect::finish()
|
||||
{
|
||||
setVolatileValue(value()); // Clean up m_model content
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ValgrindBaseSettings
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
ValgrindBaseSettings::ValgrindBaseSettings()
|
||||
ValgrindBaseSettings::ValgrindBaseSettings(bool global)
|
||||
: suppressions(global)
|
||||
{
|
||||
// Note that this is used twice, once for project settings in the .user files
|
||||
// and once for global settings in QtCreator.ini. This uses intentionally
|
||||
// the same key to facilitate copying using fromMap/toMap.
|
||||
QString base = "Analyzer.Valgrind.";
|
||||
|
||||
group.registerAspect(&suppressions);
|
||||
|
||||
group.registerAspect(&valgrindExecutable);
|
||||
valgrindExecutable.setSettingsKey(base + "ValgrindExecutable");
|
||||
valgrindExecutable.setDefaultValue("valgrind");
|
||||
@@ -236,14 +481,12 @@ void ValgrindBaseSettings::toMap(QVariantMap &map) const
|
||||
static ValgrindGlobalSettings *theGlobalSettings = nullptr;
|
||||
|
||||
ValgrindGlobalSettings::ValgrindGlobalSettings()
|
||||
: ValgrindBaseSettings(true)
|
||||
{
|
||||
theGlobalSettings = this;
|
||||
|
||||
const QString base = "Analyzer.Valgrind";
|
||||
|
||||
group.registerAspect(&suppressionFiles_);
|
||||
suppressionFiles_.setSettingsKey(base + "SupressionFiles");
|
||||
|
||||
group.registerAspect(&lastSuppressionDirectory);
|
||||
lastSuppressionDirectory.setSettingsKey(base + "LastSuppressionDirectory");
|
||||
|
||||
@@ -282,20 +525,6 @@ ValgrindGlobalSettings *ValgrindGlobalSettings::instance()
|
||||
//
|
||||
// Memcheck
|
||||
//
|
||||
QStringList ValgrindGlobalSettings::suppressionFiles() const
|
||||
{
|
||||
return suppressionFiles_.value();
|
||||
}
|
||||
|
||||
void ValgrindGlobalSettings::addSuppressionFiles(const QStringList &suppressions)
|
||||
{
|
||||
suppressionFiles_.appendValues(suppressions);
|
||||
}
|
||||
|
||||
void ValgrindGlobalSettings::removeSuppressionFiles(const QStringList &suppressions)
|
||||
{
|
||||
suppressionFiles_.removeValues(suppressions);
|
||||
}
|
||||
|
||||
QVariantMap ValgrindBaseSettings::defaultSettings() const
|
||||
{
|
||||
@@ -310,14 +539,13 @@ static const char groupC[] = "Analyzer";
|
||||
|
||||
void ValgrindGlobalSettings::readSettings()
|
||||
{
|
||||
QVariantMap defaults = defaultSettings();
|
||||
|
||||
// Read stored values
|
||||
QSettings *settings = Core::ICore::settings();
|
||||
settings->beginGroup(groupC);
|
||||
QVariantMap map = defaults;
|
||||
for (QVariantMap::ConstIterator it = defaults.constBegin(); it != defaults.constEnd(); ++it)
|
||||
map.insert(it.key(), settings->value(it.key(), it.value()));
|
||||
QVariantMap map;
|
||||
const QStringList childKey = settings->childKeys();
|
||||
for (const QString &key : childKey)
|
||||
map.insert(key, settings->value(key));
|
||||
settings->endGroup();
|
||||
|
||||
fromMap(map);
|
||||
@@ -343,49 +571,9 @@ void ValgrindGlobalSettings::writeSettings() const
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
ValgrindProjectSettings::ValgrindProjectSettings()
|
||||
: ValgrindBaseSettings(false)
|
||||
{
|
||||
setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); });
|
||||
|
||||
group.registerAspect(&disabledGlobalSuppressionFiles);
|
||||
disabledGlobalSuppressionFiles.setSettingsKey("Analyzer.Valgrind.RemovedSuppressionFiles");
|
||||
|
||||
group.registerAspect(&addedSuppressionFiles);
|
||||
addedSuppressionFiles.setSettingsKey("Analyzer.Valgrind.AddedSuppressionFiles");
|
||||
}
|
||||
|
||||
//
|
||||
// Memcheck
|
||||
//
|
||||
|
||||
void ValgrindProjectSettings::addSuppressionFiles(const QStringList &suppressions)
|
||||
{
|
||||
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles();
|
||||
for (const QString &s : suppressions) {
|
||||
if (addedSuppressionFiles.value().contains(s))
|
||||
continue;
|
||||
disabledGlobalSuppressionFiles.removeValue(s);
|
||||
if (!globalSuppressions.contains(s))
|
||||
addedSuppressionFiles.appendValue(s);
|
||||
}
|
||||
}
|
||||
|
||||
void ValgrindProjectSettings::removeSuppressionFiles(const QStringList &suppressions)
|
||||
{
|
||||
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles();
|
||||
for (const QString &s : suppressions) {
|
||||
addedSuppressionFiles.removeValue(s);
|
||||
if (globalSuppressions.contains(s))
|
||||
disabledGlobalSuppressionFiles.appendValue(s);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ValgrindProjectSettings::suppressionFiles() const
|
||||
{
|
||||
QStringList ret = ValgrindGlobalSettings::instance()->suppressionFiles();
|
||||
for (const QString &s : disabledGlobalSuppressionFiles.value())
|
||||
ret.removeAll(s);
|
||||
ret.append(addedSuppressionFiles.value());
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -36,6 +36,36 @@ namespace Internal {
|
||||
|
||||
const char ANALYZER_VALGRIND_SETTINGS[] = "Analyzer.Valgrind.Settings";
|
||||
|
||||
class SuppressionAspectPrivate;
|
||||
|
||||
class SuppressionAspect final : public Utils::BaseAspect
|
||||
{
|
||||
public:
|
||||
explicit SuppressionAspect(bool global);
|
||||
~SuppressionAspect() final;
|
||||
|
||||
QStringList value() const;
|
||||
void setValue(const QStringList &val);
|
||||
|
||||
void addToLayout(Utils::LayoutBuilder &builder) final;
|
||||
|
||||
void fromMap(const QVariantMap &map) final;
|
||||
void toMap(QVariantMap &map) const final;
|
||||
|
||||
QVariant volatileValue() const final;
|
||||
void setVolatileValue(const QVariant &val) final;
|
||||
|
||||
void cancel() final;
|
||||
void apply() final;
|
||||
void finish() final;
|
||||
|
||||
void addSuppressionFile(const QString &suppressionFile);
|
||||
|
||||
private:
|
||||
friend class ValgrindBaseSettings;
|
||||
SuppressionAspectPrivate *d = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Valgrind settings shared for global and per-project.
|
||||
*/
|
||||
@@ -44,7 +74,7 @@ class ValgrindBaseSettings : public ProjectExplorer::ISettingsAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ValgrindBaseSettings();
|
||||
explicit ValgrindBaseSettings(bool global);
|
||||
|
||||
enum SelfModifyingCodeDetection {
|
||||
DetectSmcNo,
|
||||
@@ -73,6 +103,8 @@ public:
|
||||
Utils::StringAspect valgrindArguments;
|
||||
Utils::SelectionAspect selfModifyingCodeDetection;
|
||||
|
||||
SuppressionAspect suppressions;
|
||||
|
||||
/**
|
||||
* Base memcheck settings
|
||||
*/
|
||||
@@ -85,16 +117,8 @@ public:
|
||||
Utils::BoolAspect filterExternalIssues;
|
||||
Utils::IntegersAspect visibleErrorKinds;
|
||||
|
||||
virtual QStringList suppressionFiles() const = 0;
|
||||
virtual void addSuppressionFiles(const QStringList &) = 0;
|
||||
virtual void removeSuppressionFiles(const QStringList &) = 0;
|
||||
|
||||
void setVisibleErrorKinds(const QList<int> &);
|
||||
|
||||
signals:
|
||||
void suppressionFilesRemoved(const QStringList &);
|
||||
void suppressionFilesAdded(const QStringList &);
|
||||
|
||||
/**
|
||||
* Base callgrind settings
|
||||
*/
|
||||
@@ -130,15 +154,10 @@ public:
|
||||
/**
|
||||
* Global memcheck settings
|
||||
*/
|
||||
QStringList suppressionFiles() const override;
|
||||
// in the global settings we change the internal list directly
|
||||
void addSuppressionFiles(const QStringList &) override;
|
||||
void removeSuppressionFiles(const QStringList &) override;
|
||||
|
||||
void writeSettings() const;
|
||||
void readSettings();
|
||||
|
||||
Utils::StringListAspect suppressionFiles_;
|
||||
Utils::StringAspect lastSuppressionDirectory;
|
||||
Utils::StringAspect lastSuppressionHistory;
|
||||
|
||||
@@ -161,18 +180,6 @@ class ValgrindProjectSettings : public ValgrindBaseSettings
|
||||
|
||||
public:
|
||||
ValgrindProjectSettings();
|
||||
|
||||
/**
|
||||
* Per-project memcheck settings, saves a diff to the global suppression files list
|
||||
*/
|
||||
QStringList suppressionFiles() const override;
|
||||
// in the project-specific settings we store a diff to the global list
|
||||
void addSuppressionFiles(const QStringList &suppressions) override;
|
||||
void removeSuppressionFiles(const QStringList &suppressions) override;
|
||||
|
||||
private:
|
||||
Utils::StringListAspect disabledGlobalSuppressionFiles;
|
||||
Utils::StringListAspect addedSuppressionFiles;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
Reference in New Issue
Block a user