File indexing completed on 2025-03-09 04:54:30
0001 /* 0002 SPDX-FileCopyrightText: 2019-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "dkimmanageruleswidget.h" 0008 #include "dkimmanagerulescombobox.h" 0009 #include "dkimruledialog.h" 0010 #include "messageviewer_dkimcheckerdebug.h" 0011 #include <KLineEditEventHandler> 0012 #include <KLocalizedString> 0013 #include <KMessageBox> 0014 #include <KTreeWidgetSearchLine> 0015 #include <MessageViewer/DKIMManagerRules> 0016 #include <QHeaderView> 0017 #include <QMenu> 0018 #include <QPointer> 0019 #include <QTreeWidget> 0020 #include <QVBoxLayout> 0021 using namespace MessageViewer; 0022 DKIMManageRulesWidgetItem::DKIMManageRulesWidgetItem(QTreeWidget *parent) 0023 : QTreeWidgetItem(parent) 0024 , mRuleTypeCombobox(new DKIMManageRulesComboBox) 0025 { 0026 treeWidget()->setItemWidget(this, ColumnType::RuleType, mRuleTypeCombobox); 0027 } 0028 0029 DKIMManageRulesWidgetItem::~DKIMManageRulesWidgetItem() = default; 0030 0031 MessageViewer::DKIMRule DKIMManageRulesWidgetItem::rule() const 0032 { 0033 MessageViewer::DKIMRule rule; 0034 rule.setEnabled(checkState(ColumnType::Enabled) == Qt::Checked); 0035 rule.setDomain(text(ColumnType::Domain)); 0036 rule.setFrom(text(ColumnType::From)); 0037 rule.setListId(text(ColumnType::ListId)); 0038 rule.setPriority(text(ColumnType::Priority).toInt()); 0039 rule.setRuleType(mRuleTypeCombobox->ruleType()); 0040 rule.setSignedDomainIdentifier(text(ColumnType::SDid).split(QLatin1Char(' '))); 0041 return rule; 0042 } 0043 0044 void DKIMManageRulesWidgetItem::setRule(const MessageViewer::DKIMRule &rule) 0045 { 0046 if (mRule != rule) { 0047 mRule = rule; 0048 updateInfo(); 0049 } 0050 } 0051 0052 void DKIMManageRulesWidgetItem::updateInfo() 0053 { 0054 setCheckState(ColumnType::Enabled, mRule.enabled() ? Qt::Checked : Qt::Unchecked); 0055 setText(ColumnType::Domain, mRule.domain()); 0056 setText(ColumnType::ListId, mRule.listId()); 0057 setText(ColumnType::From, mRule.from()); 0058 setText(ColumnType::SDid, mRule.signedDomainIdentifier().join(QLatin1Char(' '))); 0059 setText(ColumnType::Priority, QString::number(mRule.priority())); 0060 mRuleTypeCombobox->setRuleType(mRule.ruleType()); 0061 } 0062 0063 DKIMManageRulesWidget::DKIMManageRulesWidget(QWidget *parent) 0064 : QWidget(parent) 0065 , mTreeWidget(new QTreeWidget(this)) 0066 { 0067 auto mainLayout = new QVBoxLayout(this); 0068 mainLayout->setObjectName(QLatin1StringView("mainLayout")); 0069 mainLayout->setContentsMargins({}); 0070 0071 mTreeWidget->setObjectName(QLatin1StringView("treewidget")); 0072 mTreeWidget->setRootIsDecorated(false); 0073 mTreeWidget->setHeaderLabels({i18n("Active"), i18n("Domain"), i18n("List-ID"), i18n("From"), i18n("SDID"), i18n("Rule type"), i18n("Priority")}); 0074 mTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); 0075 mTreeWidget->setAlternatingRowColors(true); 0076 0077 auto searchLineEdit = new KTreeWidgetSearchLine(this, mTreeWidget); 0078 searchLineEdit->setObjectName(QLatin1StringView("searchlineedit")); 0079 searchLineEdit->setClearButtonEnabled(true); 0080 mainLayout->addWidget(searchLineEdit); 0081 KLineEditEventHandler::catchReturnKey(searchLineEdit); 0082 0083 mainLayout->addWidget(mTreeWidget); 0084 connect(mTreeWidget, &QTreeWidget::customContextMenuRequested, this, &DKIMManageRulesWidget::slotCustomContextMenuRequested); 0085 connect(mTreeWidget, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem *item) { 0086 if (item) { 0087 auto rulesItem = static_cast<DKIMManageRulesWidgetItem *>(item); 0088 modifyRule(rulesItem); 0089 } 0090 }); 0091 } 0092 0093 DKIMManageRulesWidget::~DKIMManageRulesWidget() = default; 0094 0095 void DKIMManageRulesWidget::updateRules() 0096 { 0097 const QList<MessageViewer::DKIMRule> rules = MessageViewer::DKIMManagerRules::self()->rules(); 0098 0099 for (const MessageViewer::DKIMRule &rule : rules) { 0100 auto item = new DKIMManageRulesWidgetItem(mTreeWidget); 0101 item->setRule(rule); 0102 } 0103 emitUpdateExportButton(); 0104 } 0105 0106 void DKIMManageRulesWidget::loadSettings() 0107 { 0108 mTreeWidget->setSortingEnabled(true); 0109 mTreeWidget->header()->setSortIndicatorShown(true); 0110 mTreeWidget->header()->setSectionsClickable(true); 0111 mTreeWidget->sortByColumn(0, Qt::AscendingOrder); 0112 updateRules(); 0113 } 0114 0115 QList<MessageViewer::DKIMRule> DKIMManageRulesWidget::rules() const 0116 { 0117 QList<MessageViewer::DKIMRule> rules; 0118 const int total = mTreeWidget->topLevelItemCount(); 0119 rules.reserve(total); 0120 for (int i = 0; i < total; ++i) { 0121 QTreeWidgetItem *item = mTreeWidget->topLevelItem(i); 0122 auto ruleItem = static_cast<DKIMManageRulesWidgetItem *>(item); 0123 rules.append(ruleItem->rule()); 0124 } 0125 return rules; 0126 } 0127 0128 void DKIMManageRulesWidget::saveSettings() 0129 { 0130 MessageViewer::DKIMManagerRules::self()->saveRules(rules()); 0131 } 0132 0133 QByteArray DKIMManageRulesWidget::saveHeaders() const 0134 { 0135 return mTreeWidget->header()->saveState(); 0136 } 0137 0138 void DKIMManageRulesWidget::restoreHeaders(const QByteArray &header) 0139 { 0140 mTreeWidget->header()->restoreState(header); 0141 } 0142 0143 void DKIMManageRulesWidget::addRule() 0144 { 0145 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this); 0146 if (dlg->exec()) { 0147 const MessageViewer::DKIMRule rule = dlg->rule(); 0148 if (rule.isValid()) { 0149 auto item = new DKIMManageRulesWidgetItem(mTreeWidget); 0150 item->setRule(rule); 0151 emitUpdateExportButton(); 0152 } else { 0153 qCDebug(MESSAGEVIEWER_DKIMCHECKER_LOG) << "Rule is not valid"; 0154 } 0155 } 0156 delete dlg; 0157 } 0158 0159 void DKIMManageRulesWidget::duplicateRule(DKIMManageRulesWidgetItem *rulesItem) 0160 { 0161 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this); 0162 dlg->loadRule(rulesItem->rule()); 0163 if (dlg->exec()) { 0164 const MessageViewer::DKIMRule rule = dlg->rule(); 0165 if (rule.isValid()) { 0166 auto item = new DKIMManageRulesWidgetItem(mTreeWidget); 0167 item->setRule(rule); 0168 emitUpdateExportButton(); 0169 } 0170 } 0171 delete dlg; 0172 } 0173 0174 void DKIMManageRulesWidget::emitUpdateExportButton() 0175 { 0176 Q_EMIT updateExportButton(mTreeWidget->topLevelItemCount() > 0); 0177 } 0178 0179 void DKIMManageRulesWidget::modifyRule(DKIMManageRulesWidgetItem *rulesItem) 0180 { 0181 QPointer<DKIMRuleDialog> dlg = new DKIMRuleDialog(this); 0182 dlg->loadRule(rulesItem->rule()); 0183 if (dlg->exec()) { 0184 const MessageViewer::DKIMRule rule = dlg->rule(); 0185 if (rule.isValid()) { 0186 rulesItem->setRule(rule); 0187 } 0188 } 0189 delete dlg; 0190 } 0191 0192 void DKIMManageRulesWidget::slotCustomContextMenuRequested(const QPoint &pos) 0193 { 0194 QTreeWidgetItem *item = mTreeWidget->itemAt(pos); 0195 QMenu menu(this); 0196 menu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add..."), this, [this]() { 0197 addRule(); 0198 }); 0199 auto rulesItem = dynamic_cast<DKIMManageRulesWidgetItem *>(item); 0200 if (rulesItem) { 0201 menu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Modify..."), this, [this, rulesItem]() { 0202 modifyRule(rulesItem); 0203 }); 0204 menu.addSeparator(); 0205 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-duplicate")), i18n("Duplicate Rule"), this, [this, rulesItem]() { 0206 duplicateRule(rulesItem); 0207 }); 0208 menu.addSeparator(); 0209 menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove Rule"), this, [this, item]() { 0210 const int answer = KMessageBox::warningTwoActions(this, 0211 i18n("Do you want to delete this rule?"), 0212 i18nc("@title:window", "Delete Rule"), 0213 KStandardGuiItem::del(), 0214 KStandardGuiItem::cancel()); 0215 if (answer == KMessageBox::ButtonCode::PrimaryAction) { 0216 delete item; 0217 emitUpdateExportButton(); 0218 } 0219 }); 0220 } 0221 if (mTreeWidget->topLevelItemCount() > 0) { 0222 menu.addSeparator(); 0223 menu.addAction(i18n("Delete All"), this, [this]() { 0224 const int answer = KMessageBox::warningTwoActions(this, 0225 i18n("Do you want to delete all the rules?"), 0226 i18nc("@title:window", "Delete Rules"), 0227 KStandardGuiItem::del(), 0228 KStandardGuiItem::cancel()); 0229 if (answer == KMessageBox::ButtonCode::PrimaryAction) { 0230 mTreeWidget->clear(); 0231 emitUpdateExportButton(); 0232 } 0233 }); 0234 } 0235 menu.exec(QCursor::pos()); 0236 } 0237 0238 #include "moc_dkimmanageruleswidget.cpp"