1 /*
2 SPDX-FileCopyrightText: 2019-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "dkimmanageruleswidget.h"
8 #include "dkimmanagerulescombobox.h"
9 #include "dkimruledialog.h"
10 #include "messageviewer_dkimcheckerdebug.h"
11 #include <KLocalizedString>
12 #include <KMessageBox>
13 #include <KTreeWidgetSearchLine>
14 #include <MessageViewer/DKIMManagerRules>
15 #include <QHeaderView>
16 #include <QMenu>
17 #include <QPointer>
18 #include <QTreeWidget>
19 #include <QVBoxLayout>
20 using namespace MessageViewer;
DKIMManageRulesWidgetItem(QTreeWidget * parent)21 DKIMManageRulesWidgetItem::DKIMManageRulesWidgetItem(QTreeWidget *parent)
22 : QTreeWidgetItem(parent)
23 , mRuleTypeCombobox(new DKIMManageRulesComboBox)
24 {
25 treeWidget()->setItemWidget(this, ColumnType::RuleType, mRuleTypeCombobox);
26 }
27
~DKIMManageRulesWidgetItem()28 DKIMManageRulesWidgetItem::~DKIMManageRulesWidgetItem()
29 {
30 }
31
rule() const32 MessageViewer::DKIMRule DKIMManageRulesWidgetItem::rule() const
33 {
34 MessageViewer::DKIMRule rule;
35 rule.setEnabled(checkState(ColumnType::Enabled) == Qt::Checked);
36 rule.setDomain(text(ColumnType::Domain));
37 rule.setFrom(text(ColumnType::From));
38 rule.setListId(text(ColumnType::ListId));
39 rule.setPriority(text(ColumnType::Priority).toInt());
40 rule.setRuleType(mRuleTypeCombobox->ruleType());
41 rule.setSignedDomainIdentifier(text(ColumnType::SDid).split(QLatin1Char(' ')));
42 return rule;
43 }
44
setRule(const MessageViewer::DKIMRule & rule)45 void DKIMManageRulesWidgetItem::setRule(const MessageViewer::DKIMRule &rule)
46 {
47 if (mRule != rule) {
48 mRule = rule;
49 updateInfo();
50 }
51 }
52
updateInfo()53 void DKIMManageRulesWidgetItem::updateInfo()
54 {
55 setCheckState(ColumnType::Enabled, mRule.enabled() ? Qt::Checked : Qt::Unchecked);
56 setText(ColumnType::Domain, mRule.domain());
57 setText(ColumnType::ListId, mRule.listId());
58 setText(ColumnType::From, mRule.from());
59 setText(ColumnType::SDid, mRule.signedDomainIdentifier().join(QLatin1Char(' ')));
60 setText(ColumnType::Priority, QString::number(mRule.priority()));
61 mRuleTypeCombobox->setRuleType(mRule.ruleType());
62 }
63
DKIMManageRulesWidget(QWidget * parent)64 DKIMManageRulesWidget::DKIMManageRulesWidget(QWidget *parent)
65 : QWidget(parent)
66 , mTreeWidget(new QTreeWidget(this))
67 {
68 auto mainLayout = new QVBoxLayout(this);
69 mainLayout->setObjectName(QStringLiteral("mainLayout"));
70 mainLayout->setContentsMargins({});
71
72 mTreeWidget->setObjectName(QStringLiteral("treewidget"));
73 mTreeWidget->setRootIsDecorated(false);
74 mTreeWidget->setHeaderLabels({i18n("Active"), i18n("Domain"), i18n("List-ID"), i18n("From"), i18n("SDID"), i18n("Rule type"), i18n("Priority")});
75 mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
76 mTreeWidget->setAlternatingRowColors(true);
77
78 auto searchLineEdit = new KTreeWidgetSearchLine(this, mTreeWidget);
79 searchLineEdit->setObjectName(QStringLiteral("searchlineedit"));
80 searchLineEdit->setClearButtonEnabled(true);
81 mainLayout->addWidget(searchLineEdit);
82
83 mainLayout->addWidget(mTreeWidget);
84 connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &DKIMManageRulesWidget::slotCustomContextMenuRequested);
85 connect(mTreeWidget, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem *item) {
86 if (item) {
87 auto rulesItem = static_cast<DKIMManageRulesWidgetItem *>(item);
88 modifyRule(rulesItem);
89 }
90 });
91 }
92
~DKIMManageRulesWidget()93 DKIMManageRulesWidget::~DKIMManageRulesWidget()
94 {
95 }
96
loadSettings()97 void DKIMManageRulesWidget::loadSettings()
98 {
99 const QVector<MessageViewer::DKIMRule> rules = MessageViewer::DKIMManagerRules::self()->rules();
100
101 for (const MessageViewer::DKIMRule &rule : rules) {
102 auto item = new DKIMManageRulesWidgetItem(mTreeWidget);
103 item->setRule(rule);
104 }
105 mTreeWidget->setSortingEnabled(true);
106 mTreeWidget->header()->setSortIndicatorShown(true);
107 mTreeWidget->header()->setSectionsClickable(true);
108 mTreeWidget->sortByColumn(0, Qt::AscendingOrder);
109 }
110
rules() const111 QVector<MessageViewer::DKIMRule> DKIMManageRulesWidget::rules() const
112 {
113 QVector<MessageViewer::DKIMRule> rules;
114 const int total = mTreeWidget->topLevelItemCount();
115 rules.reserve(total);
116 for (int i = 0; i < total; ++i) {
117 QTreeWidgetItem *item = mTreeWidget->topLevelItem(i);
118 auto ruleItem = static_cast<DKIMManageRulesWidgetItem *>(item);
119 rules.append(ruleItem->rule());
120 }
121 return rules;
122 }
123
saveSettings()124 void DKIMManageRulesWidget::saveSettings()
125 {
126 MessageViewer::DKIMManagerRules::self()->saveRules(rules());
127 }
128
saveHeaders() const129 QByteArray DKIMManageRulesWidget::saveHeaders() const
130 {
131 return mTreeWidget->header()->saveState();
132 }
133
restoreHeaders(const QByteArray & header)134 void DKIMManageRulesWidget::restoreHeaders(const QByteArray &header)
135 {
136 mTreeWidget->header()->restoreState(header);
137 }
138
addRule()139 void DKIMManageRulesWidget::addRule()
140 {
141 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this);
142 if (dlg->exec()) {
143 const MessageViewer::DKIMRule rule = dlg->rule();
144 if (rule.isValid()) {
145 auto item = new DKIMManageRulesWidgetItem(mTreeWidget);
146 item->setRule(rule);
147 } else {
148 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Rule is not valid";
149 }
150 }
151 delete dlg;
152 }
153
duplicateRule(DKIMManageRulesWidgetItem * rulesItem)154 void DKIMManageRulesWidget::duplicateRule(DKIMManageRulesWidgetItem *rulesItem)
155 {
156 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this);
157 dlg->loadRule(rulesItem->rule());
158 if (dlg->exec()) {
159 const MessageViewer::DKIMRule rule = dlg->rule();
160 if (rule.isValid()) {
161 auto item = new DKIMManageRulesWidgetItem(mTreeWidget);
162 item->setRule(rule);
163 }
164 }
165 delete dlg;
166 }
167
modifyRule(DKIMManageRulesWidgetItem * rulesItem)168 void DKIMManageRulesWidget::modifyRule(DKIMManageRulesWidgetItem *rulesItem)
169 {
170 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this);
171 dlg->loadRule(rulesItem->rule());
172 if (dlg->exec()) {
173 const MessageViewer::DKIMRule rule = dlg->rule();
174 if (rule.isValid()) {
175 rulesItem->setRule(rule);
176 }
177 }
178 delete dlg;
179 }
180
slotCustomContextMenuRequested(const QPoint & pos)181 void DKIMManageRulesWidget::slotCustomContextMenuRequested(const QPoint &pos)
182 {
183 QTreeWidgetItem *item = mTreeWidget->itemAt(pos);
184 QMenu menu(this);
185 menu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add..."), this, [this]() {
186 addRule();
187 });
188 auto rulesItem = dynamic_cast<DKIMManageRulesWidgetItem *>(item);
189 if (rulesItem) {
190 menu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Modify..."), this, [this, rulesItem]() {
191 modifyRule(rulesItem);
192 });
193 menu.addSeparator();
194 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-duplicate")), i18n("Duplicate Rule"), this, [this, rulesItem]() {
195 duplicateRule(rulesItem);
196 });
197 menu.addSeparator();
198 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove Rule"), this, [this, item]() {
199 const int answer = KMessageBox::warningYesNo(this,
200 i18n("Do you want to delete this rule?"),
201 i18n("Delete Rule"),
202 KStandardGuiItem::del(),
203 KStandardGuiItem::cancel());
204 if (answer == KMessageBox::Yes) {
205 delete item;
206 }
207 });
208 }
209 if (mTreeWidget->topLevelItemCount() > 0) {
210 menu.addSeparator();
211 menu.addAction(i18n("Delete All"), this, [this]() {
212 const int answer = KMessageBox::warningYesNo(this,
213 i18n("Do you want to delete all the rules?"),
214 i18n("Delete Rules"),
215 KStandardGuiItem::del(),
216 KStandardGuiItem::cancel());
217 if (answer == KMessageBox::Yes) {
218 mTreeWidget->clear();
219 }
220 });
221 }
222 menu.exec(QCursor::pos());
223 }
224