diff --git a/src/dialogs/deletecertificatesdialog.cpp b/src/dialogs/deletecertificatesdialog.cpp index 7204c89f2..d340e33c9 100644 --- a/src/dialogs/deletecertificatesdialog.cpp +++ b/src/dialogs/deletecertificatesdialog.cpp @@ -1,265 +1,279 @@ /* -*- mode: c++; c-basic-offset:4 -*- dialogs/deletecertificatesdialog.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "deletecertificatesdialog.h" #include #include #include +#include #include #include #include #include "kleopatra_debug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kleo; using namespace Kleo::Dialogs; using namespace GpgME; class DeleteCertificatesDialog::Private { friend class ::Kleo::Dialogs::DeleteCertificatesDialog; DeleteCertificatesDialog *const q; public: explicit Private(DeleteCertificatesDialog *qq) : q(qq) , ui(q) { } void slotWhatsThisRequested() { qCDebug(KLEOPATRA_LOG); if (QWidget *const widget = qobject_cast(q->sender())) if (!widget->whatsThis().isEmpty()) { showToolTip(QCursor::pos(), widget->whatsThis(), widget); } } void readConfig() { KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("DeleteCertificatesDialog")); - ui.selectedKTV.restoreLayout(dialog); - ui.unselectedKTV.restoreLayout(dialog); const QSize size = dialog.readEntry("Size", QSize(600, 400)); if (size.isValid()) { q->resize(size); } } void writeConfig() { KConfigGroup dialog(KSharedConfig::openStateConfig(), QStringLiteral("DeleteCertificatesDialog")); dialog.writeEntry("Size", q->size()); dialog.sync(); } void checkGroups(const std::vector &keys) { const auto &groups = KeyCache::instance()->groups(); for (const auto &key : keys) { - if (Kleo::any_of(groups, [key](const auto &group) { - return group.keys().contains(key); + QStringList foundGroups; + if (Kleo::any_of(groups, [key, &foundGroups](const auto &group) { + if (group.keys().contains(key)) { + foundGroups.append(group.name()); + return true; + } + return false; })) { - ui.groupsKTV.addKeysUnselected({key}); + ui.groupsList->addWidget( + new QLabel(i18nc(", contained in: (list of groups)", "\t• %1, contained in:").arg(Formatting::prettyNameAndEMail(key)))); + for (const auto &group : foundGroups) { + ui.groupsList->addWidget(new QLabel(QStringLiteral("\t\t• %1").arg(group))); + } + keyInGroups++; + ui.groupsLB.setVisible(true); } } - if (!ui.groupsKTV.keys().empty()) { - ui.groupsLB.setVisible(true); - ui.groupsKTV.setVisible(true); - } + ui.groupsLB.setText( + i18np("The following certificate is part of at least one group. Deleting it may cause receivers to be unable to decrypt messages:", + "The following certificates are part of at least one group. Deleting them may cause receivers to be unable to decrypt messages:", + keyInGroups)); } private: + std::vector selectedKeys; + std::vector unselectedKeys; + int keyInGroups = 0; struct UI { QLabel selectedLB; - KeyTreeView selectedKTV; + QVBoxLayout *selectedList; QLabel unselectedLB; - KeyTreeView unselectedKTV; + QVBoxLayout *unselectedList; QLabel groupsLB; - KeyTreeView groupsKTV; + QVBoxLayout *groupsList; QDialogButtonBox buttonBox; QVBoxLayout vlay; explicit UI(DeleteCertificatesDialog *qq) - : selectedLB(i18n("These are the certificates you have selected for deletion:"), qq) - , selectedKTV(qq) - , unselectedLB(i18n("These certificates will be deleted even though you did not " - "explicitly select them (Why?):"), - qq) - , unselectedKTV(qq) - , groupsLB(i18n("These certificates are part of groups. Deleting them may cause receivers to be unable to decrypt messages:")) - , groupsKTV(qq) + : selectedLB({}, qq) + , unselectedLB({}, qq) + , groupsLB({}, qq) , buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel) , vlay(qq) + , selectedList(new QVBoxLayout) + , unselectedList(new QVBoxLayout) + , groupsList(new QVBoxLayout) { KDAB_SET_OBJECT_NAME(selectedLB); - KDAB_SET_OBJECT_NAME(selectedKTV); + KDAB_SET_OBJECT_NAME(selectedList); KDAB_SET_OBJECT_NAME(unselectedLB); - KDAB_SET_OBJECT_NAME(unselectedKTV); + KDAB_SET_OBJECT_NAME(unselectedList); KDAB_SET_OBJECT_NAME(groupsLB); - KDAB_SET_OBJECT_NAME(groupsKTV); + KDAB_SET_OBJECT_NAME(groupsList); KDAB_SET_OBJECT_NAME(buttonBox); KDAB_SET_OBJECT_NAME(vlay); vlay.addWidget(&selectedLB); - vlay.addWidget(&selectedKTV, 1); + vlay.addLayout(selectedList, 0); vlay.addWidget(&unselectedLB); - vlay.addWidget(&unselectedKTV, 1); + vlay.addLayout(unselectedList, 0); vlay.addWidget(&groupsLB); - vlay.addWidget(&groupsKTV, 1); + vlay.addLayout(groupsList, 0); vlay.addWidget(&buttonBox); const QString unselectedWhatsThis = xi18nc("@info:whatsthis", "Why do you want to delete more certificates than I selected?" "When you delete CA certificates (both root CAs and intermediate CAs), " "the certificates issued by them will also be deleted." "This can be nicely seen in Kleopatra's " "hierarchical view mode: In this mode, if you delete a certificate that has " "children, those children will also be deleted. Think of CA certificates as " "folders containing other certificates: When you delete the folder, you " "delete its contents, too."); unselectedLB.setContextMenuPolicy(Qt::NoContextMenu); unselectedLB.setWhatsThis(unselectedWhatsThis); - unselectedKTV.setWhatsThis(unselectedWhatsThis); buttonBox.button(QDialogButtonBox::Ok)->setText(i18nc("@action:button", "Delete")); connect(&unselectedLB, SIGNAL(linkActivated(QString)), qq, SLOT(slotWhatsThisRequested())); - selectedKTV.setFlatModel(AbstractKeyListModel::createFlatKeyListModel(&selectedKTV)); - unselectedKTV.setFlatModel(AbstractKeyListModel::createFlatKeyListModel(&unselectedKTV)); - - selectedKTV.setHierarchicalView(false); - selectedKTV.view()->setSelectionMode(QAbstractItemView::NoSelection); - unselectedKTV.setHierarchicalView(false); - unselectedKTV.view()->setSelectionMode(QAbstractItemView::NoSelection); - groupsLB.setVisible(false); - groupsKTV.setFlatModel(AbstractKeyListModel::createFlatKeyListModel(&groupsKTV)); - groupsKTV.setHierarchicalView(false); - groupsKTV.setVisible(false); connect(&buttonBox, SIGNAL(accepted()), qq, SLOT(accept())); connect(&buttonBox, &QDialogButtonBox::rejected, qq, &QDialog::reject); } } ui; }; DeleteCertificatesDialog::DeleteCertificatesDialog(QWidget *p) : QDialog(p) , d(new Private(this)) { d->readConfig(); } DeleteCertificatesDialog::~DeleteCertificatesDialog() { d->writeConfig(); } void DeleteCertificatesDialog::setSelectedKeys(const std::vector &keys) { - d->ui.selectedKTV.setKeys(keys); + d->selectedKeys = keys; + for (const auto &key : keys) { + d->ui.selectedList->addWidget(new QLabel(QStringLiteral("\t• %1").arg(Formatting::prettyNameAndEMail(key)))); + } + d->ui.selectedLB.setText( + i18np("The following certificate was selected for deletion:", "The following certificates were selected for deletion:", keys.size())); d->checkGroups(keys); + resize(sizeHint()); } void DeleteCertificatesDialog::setUnselectedKeys(const std::vector &keys) { + d->unselectedKeys = keys; d->ui.unselectedLB.setVisible(!keys.empty()); - d->ui.unselectedKTV.setVisible(!keys.empty()); - d->ui.unselectedKTV.setKeys(keys); + for (const auto &key : keys) { + d->ui.unselectedList->addWidget(new QLabel(QStringLiteral("\t• %1").arg(Formatting::prettyNameAndEMail(key)))); + } + d->ui.unselectedLB.setText( + i18np("The following certificate will be deleted even though you did not " + "explicitly select it (Why?):", + "The following certificates will be deleted even though you did not " + "explicitly select them (Why?):", + keys.size())); d->checkGroups(keys); + resize(sizeHint()); } std::vector DeleteCertificatesDialog::keys() const { - const std::vector sel = d->ui.selectedKTV.keys(); - const std::vector uns = d->ui.unselectedKTV.keys(); + const std::vector sel = d->selectedKeys; + const std::vector uns = d->unselectedKeys; std::vector result; result.reserve(sel.size() + uns.size()); result.insert(result.end(), sel.begin(), sel.end()); result.insert(result.end(), uns.begin(), uns.end()); return result; } void DeleteCertificatesDialog::accept() { - const std::vector sel = d->ui.selectedKTV.keys(); - const std::vector uns = d->ui.unselectedKTV.keys(); + const std::vector sel = d->selectedKeys; + const std::vector uns = d->unselectedKeys; const uint secret = std::count_if(sel.cbegin(), sel.cend(), std::mem_fn(&Key::hasSecret)) + std::count_if(uns.cbegin(), uns.cend(), std::mem_fn(&Key::hasSecret)); const uint total = sel.size() + uns.size(); int ret = KMessageBox::Continue; if (secret) ret = KMessageBox::warningContinueCancel(this, secret == total ? i18np("The certificate to be deleted is your own. " "It contains private key material, " "which is needed to decrypt past communication " "encrypted to the certificate, and should therefore " "not be deleted.", "All of the certificates to be deleted " "are your own. " "They contain private key material, " "which is needed to decrypt past communication " "encrypted to the certificate, and should therefore " "not be deleted.", secret) : i18np("One of the certificates to be deleted " "is your own. " "It contains private key material, " "which is needed to decrypt past communication " "encrypted to the certificate, and should therefore " "not be deleted.", "Some of the certificates to be deleted " "are your own. " "They contain private key material, " "which is needed to decrypt past communication " "encrypted to the certificate, and should therefore " "not be deleted.", secret), i18nc("@title:window", "Secret Key Deletion"), KStandardGuiItem::guiItem(KStandardGuiItem::Delete), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous); if (ret == KMessageBox::Continue) { QDialog::accept(); } else { QDialog::reject(); } } #include "moc_deletecertificatesdialog.cpp"