1 /*
2 SPDX-FileCopyrightText: 2018 Friedrich W. H. Kossebau <kossebau@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "checkselection.h"
8
9 // plugin
10 #include "checklistfilterproxysearchline.h"
11 #include "checklistitemproxystyle.h"
12 #include "checklistmodel.h"
13 #include <checkset.h>
14 #include <debug.h>
15 // KF
16 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
17 #include <KRecursiveFilterProxyModel>
18 #endif
19 // Qt
20 #include <QEvent>
21 #include <QVBoxLayout>
22 #include <QTreeView>
23 #include <QHeaderView>
24 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
25 #include <QSortFilterProxyModel>
26 #endif
27
28 namespace ClangTidy
29 {
30
CheckSelection(QWidget * parent)31 CheckSelection::CheckSelection(QWidget* parent)
32 : QWidget(parent)
33 , m_checkListModel(new CheckListModel(this))
34 {
35 auto* layout = new QVBoxLayout;
36 layout->setContentsMargins(0, 0, 0, 0);
37
38 auto* checkFilterEdit = new CheckListFilterProxySearchLine(this);
39 layout->addWidget(checkFilterEdit);
40
41 m_checkListView = new QTreeView(this);
42 m_checkListView->setAllColumnsShowFocus(true);
43 m_checkListView->setRootIsDecorated(true);
44 m_checkListView->setHeaderHidden(true);
45 m_checkListView->setUniformRowHeights(true);
46 m_proxyStyle = new CheckListItemProxyStyle;
47 m_proxyStyle->setParent(this);
48 m_checkListView->setStyle(m_proxyStyle);
49 layout->addWidget(m_checkListView);
50
51 setLayout(layout);
52
53 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
54 m_checksFilterProxyModel = new QSortFilterProxyModel(this);
55 m_checksFilterProxyModel->setRecursiveFilteringEnabled(true);
56 #else
57 m_checksFilterProxyModel = new KRecursiveFilterProxyModel(this);
58 #endif
59 checkFilterEdit->setFilterProxyModel(m_checksFilterProxyModel);
60 m_checksFilterProxyModel->setSourceModel(m_checkListModel);
61 m_checksFilterProxyModel->setFilterKeyColumn(CheckListModel::NameColumnId);
62 m_checksFilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
63
64 m_checkListView->setModel(m_checksFilterProxyModel);
65 auto* header = m_checkListView->header();
66 header->setStretchLastSection(false);
67 header->setSectionResizeMode(CheckListModel::NameColumnId, QHeaderView::Stretch);
68 header->setSectionResizeMode(CheckListModel::CountColumnId, QHeaderView::ResizeToContents);
69
70 connect(m_checkListModel, &CheckListModel::enabledChecksChanged,
71 this, &CheckSelection::onEnabledChecksChanged);
72 }
73
74 CheckSelection::~CheckSelection() = default;
75
setEditable(bool editable)76 void CheckSelection::setEditable(bool editable)
77 {
78 m_checkListModel->setEditable(editable);
79 }
80
setCheckSet(const CheckSet * checkSet)81 void CheckSelection::setCheckSet(const CheckSet* checkSet)
82 {
83 m_checkListModel->setCheckSet(checkSet);
84 expandSubGroupsWithExplicitlyEnabledStates();
85 }
86
expandSubGroupsWithExplicitlyEnabledStates()87 void CheckSelection::expandSubGroupsWithExplicitlyEnabledStates()
88 {
89 const QModelIndex allChecksIndex = m_checksFilterProxyModel->index(0, 0, QModelIndex());
90 expandSubGroupsWithExplicitlyEnabledStates(allChecksIndex);
91 }
92
expandSubGroupsWithExplicitlyEnabledStates(const QModelIndex & groupIndex)93 void CheckSelection::expandSubGroupsWithExplicitlyEnabledStates(const QModelIndex& groupIndex)
94 {
95 if (groupIndex.data(CheckListModel::HasExplicitEnabledStateRole).toBool()) {
96 m_checkListView->setExpanded(groupIndex, true);
97 const int rowCount = m_checksFilterProxyModel->rowCount(groupIndex);
98 for (int c = 0; c < rowCount; ++c) {
99 const auto childIndex = m_checksFilterProxyModel->index(c, 0, groupIndex);
100 if (m_checksFilterProxyModel->hasChildren(childIndex)) {
101 expandSubGroupsWithExplicitlyEnabledStates(childIndex);
102 }
103 }
104 }
105 }
106
setChecks(const QString & checks)107 void CheckSelection::setChecks(const QString& checks)
108 {
109 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
110 m_checkListModel->setEnabledChecks(checks.split(QLatin1Char(','), Qt::SkipEmptyParts));
111 #else
112 m_checkListModel->setEnabledChecks(checks.split(QLatin1Char(','), QString::SkipEmptyParts));
113 #endif
114 expandSubGroupsWithExplicitlyEnabledStates();
115 }
116
checks() const117 QString CheckSelection::checks() const
118 {
119 return m_checkListModel->enabledChecks().join(QLatin1Char(','));
120 }
121
122
event(QEvent * event)123 bool CheckSelection::event(QEvent* event)
124 {
125 if (event->type() == QEvent::StyleChange) {
126 // no recursion protection needed as the style is set on the subchild only
127 m_checkListView->setStyle(nullptr);
128 delete m_proxyStyle;
129 m_proxyStyle = new CheckListItemProxyStyle;
130 m_proxyStyle->setParent(this);
131 m_checkListView->setStyle(m_proxyStyle);
132 }
133
134 return QWidget::event(event);
135 }
136
onEnabledChecksChanged()137 void CheckSelection::onEnabledChecksChanged()
138 {
139 emit checksChanged(checks());
140 }
141
142 }
143