From 2d97b5950ca0d6c147c8f9c0253b11009016f55a Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Thu, 21 Jun 2018 13:53:41 +0200 Subject: [PATCH] Clang: Add checkbox for fix-its column header Make possible to select or deselect all fix-its. Change-Id: I2ff88afb0c451092752ee2cd7c9f083e24033500 Reviewed-by: Alessandro Portale --- src/plugins/clangtools/clangtidyclazytool.cpp | 5 +- .../clangtools/clangtoolsdiagnosticmodel.cpp | 3 + .../clangtools/clangtoolsdiagnosticview.cpp | 72 +++++++++++++++++++ .../clangtools/clangtoolsdiagnosticview.h | 3 + 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp index 575cd68dc5b..e15b968a0d9 100644 --- a/src/plugins/clangtools/clangtidyclazytool.cpp +++ b/src/plugins/clangtools/clangtidyclazytool.cpp @@ -251,7 +251,10 @@ ClangTidyClazyTool::ClangTidyClazyTool() m_applyFixitsButton->setEnabled(false); connect(m_diagnosticModel, &ClangToolsDiagnosticModel::fixItsToApplyCountChanged, - [this](int c) { m_applyFixitsButton->setEnabled(c); }); + [this](int c) { + m_applyFixitsButton->setEnabled(c); + static_cast(m_diagnosticView)->setSelectedFixItsCount(c); + }); connect(m_applyFixitsButton, &QToolButton::clicked, [this]() { QVector diagnosticItems; m_diagnosticModel->rootItem()->forChildrenAtLevel(1, [&](TreeItem *item){ diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index 690f48e584d..bf56f8fb909 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -328,6 +328,9 @@ QVariant DiagnosticItem::data(int column, int role) const bool DiagnosticItem::setData(int column, const QVariant &data, int role) { if (column == DiagnosticView::FixItColumn && role == Qt::CheckStateRole) { + if (m_fixitStatus != FixitStatus::Scheduled && m_fixitStatus != FixitStatus::NotScheduled) + return false; + const FixitStatus newStatus = data.value() == Qt::Checked ? FixitStatus::Scheduled : FixitStatus::NotScheduled; diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp index 67d20c9671a..6314697593f 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticview.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticview.cpp @@ -35,12 +35,60 @@ #include #include #include +#include using namespace Debugger; namespace ClangTools { namespace Internal { +class ClickableFixItHeader : public QHeaderView +{ + Q_OBJECT + +public: + ClickableFixItHeader(Qt::Orientation orientation, QWidget *parent = 0) + : QHeaderView(orientation, parent) + { + } + + void setState(QFlags newState) + { + state = newState; + } + +protected: + void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const + { + painter->save(); + QHeaderView::paintSection(painter, rect, logicalIndex); + painter->restore(); + if (logicalIndex == DiagnosticView::FixItColumn) { + QStyleOptionButton option; + const int side = sizeHint().height(); + option.rect = QRect(rect.left() + 1, 1, side - 3, side - 3); + option.state = state; + style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); + } + } + + void mousePressEvent(QMouseEvent *event) + { + if (event->localPos().x() > sectionPosition(DiagnosticView::FixItColumn)) { + state = (state != QStyle::State_On) ? QStyle::State_On : QStyle::State_Off; + viewport()->update(); + emit fixItColumnClicked(state == QStyle::State_On); + } + QHeaderView::mousePressEvent(event); + } + +signals: + void fixItColumnClicked(bool checked); + +private: + QFlags state = QStyle::State_Off; +}; + DiagnosticView::DiagnosticView(QWidget *parent) : Debugger::DetailedErrorView(parent) { @@ -104,12 +152,36 @@ bool DiagnosticView::eventFilter(QObject *watched, QEvent *event) } } +void DiagnosticView::setSelectedFixItsCount(int fixItsCount) +{ + if (m_ignoreSetSelectedFixItsCount) + return; + auto *clickableFixItHeader = static_cast(header()); + clickableFixItHeader->setState(fixItsCount + ? (QStyle::State_NoChange | QStyle::State_On | QStyle::State_Off) + : QStyle::State_Off); + clickableFixItHeader->viewport()->update(); +} + void DiagnosticView::setModel(QAbstractItemModel *model) { Debugger::DetailedErrorView::setModel(model); + auto *clickableFixItHeader = new ClickableFixItHeader(Qt::Horizontal, this); + connect(clickableFixItHeader, &ClickableFixItHeader::fixItColumnClicked, + this, [=](bool checked) { + m_ignoreSetSelectedFixItsCount = true; + for (int row = 0; row < model->rowCount(); ++row) { + QModelIndex index = model->index(row, FixItColumn, QModelIndex()); + model->setData(index, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); + } + m_ignoreSetSelectedFixItsCount = false; + }); + setHeader(clickableFixItHeader); header()->setStretchLastSection(false); header()->setSectionResizeMode(0, QHeaderView::Stretch); } } // namespace Internal } // namespace ClangTools + +#include "clangtoolsdiagnosticview.moc" diff --git a/src/plugins/clangtools/clangtoolsdiagnosticview.h b/src/plugins/clangtools/clangtoolsdiagnosticview.h index 0947d179518..581775c0aee 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticview.h +++ b/src/plugins/clangtools/clangtoolsdiagnosticview.h @@ -41,6 +41,8 @@ public: FixItColumn = LocationColumn + 1, }; + void setSelectedFixItsCount(int fixItsCount); + private: void suppressCurrentDiagnostic(); @@ -49,6 +51,7 @@ private: void setModel(QAbstractItemModel *model) override; QAction *m_suppressAction; + bool m_ignoreSetSelectedFixItsCount = false; }; } // namespace Internal