File indexing completed on 2024-06-23 05:14:04

0001 /*
0002     dialogs/groupdetailsdialog.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2021 g10 Code GmbH
0006     SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "groupdetailsdialog.h"
0012 
0013 #include "commands/detailscommand.h"
0014 #include "view/keytreeview.h"
0015 
0016 #include <Libkleo/KeyGroup>
0017 #include <Libkleo/KeyListModel>
0018 
0019 #include <KConfigGroup>
0020 #include <KGuiItem>
0021 #include <KLocalizedString>
0022 #include <KSharedConfig>
0023 #include <KStandardGuiItem>
0024 
0025 #include <QDialogButtonBox>
0026 #include <QLabel>
0027 #include <QPushButton>
0028 #include <QTreeView>
0029 #include <QVBoxLayout>
0030 
0031 #include "kleopatra_debug.h"
0032 
0033 using namespace Kleo;
0034 using namespace Kleo::Commands;
0035 using namespace Kleo::Dialogs;
0036 
0037 Q_DECLARE_METATYPE(GpgME::Key)
0038 
0039 class GroupDetailsDialog::Private
0040 {
0041     friend class ::Kleo::Dialogs::GroupDetailsDialog;
0042     GroupDetailsDialog *const q;
0043 
0044     struct {
0045         QLabel *groupNameLabel = nullptr;
0046         QLabel *groupCommentLabel = nullptr;
0047         KeyTreeView *treeView = nullptr;
0048         QDialogButtonBox *buttonBox = nullptr;
0049     } ui;
0050     KeyGroup group;
0051 
0052 public:
0053     Private(GroupDetailsDialog *qq)
0054         : q(qq)
0055     {
0056         auto mainLayout = new QVBoxLayout(q);
0057 
0058         ui.groupNameLabel = new QLabel();
0059         ui.groupNameLabel->setWordWrap(true);
0060         mainLayout->addWidget(ui.groupNameLabel);
0061 
0062         ui.groupCommentLabel = new QLabel();
0063         ui.groupCommentLabel->setWordWrap(true);
0064         ui.groupCommentLabel->setVisible(false);
0065         mainLayout->addWidget(ui.groupCommentLabel);
0066 
0067         ui.treeView = new KeyTreeView(q);
0068         ui.treeView->view()->setRootIsDecorated(false);
0069         ui.treeView->view()->setSelectionMode(QAbstractItemView::SingleSelection);
0070         ui.treeView->setFlatModel(AbstractKeyListModel::createFlatKeyListModel(ui.treeView));
0071         ui.treeView->setHierarchicalView(false);
0072         connect(ui.treeView->view(), &QAbstractItemView::doubleClicked, q, [this](const QModelIndex &index) {
0073             showKeyDetails(index);
0074         });
0075         mainLayout->addWidget(ui.treeView);
0076 
0077         ui.buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
0078         KGuiItem::assign(ui.buttonBox->button(QDialogButtonBox::Close), KStandardGuiItem::close());
0079         connect(ui.buttonBox, &QDialogButtonBox::rejected, q, &QDialog::close);
0080         mainLayout->addWidget(ui.buttonBox);
0081 
0082         // calculate default size with enough space for the key list
0083         const auto fm = ui.treeView->fontMetrics();
0084         const QSize sizeHint = q->sizeHint();
0085         const QSize defaultSize = QSize(qMax(sizeHint.width(), 150 * fm.horizontalAdvance(QLatin1Char('x'))),
0086                                         sizeHint.height() - ui.treeView->sizeHint().height() + 20 * fm.lineSpacing());
0087         restoreLayout(defaultSize);
0088     }
0089 
0090     ~Private()
0091     {
0092         saveLayout();
0093     }
0094 
0095 private:
0096     void saveLayout()
0097     {
0098         KConfigGroup configGroup(KSharedConfig::openStateConfig(), QStringLiteral("GroupDetailsDialog"));
0099         configGroup.writeEntry("Size", q->size());
0100         configGroup.sync();
0101     }
0102 
0103     void restoreLayout(const QSize &defaultSize)
0104     {
0105         const KConfigGroup configGroup(KSharedConfig::openStateConfig(), QStringLiteral("GroupDetailsDialog"));
0106         ui.treeView->restoreLayout(configGroup);
0107         const QSize size = configGroup.readEntry("Size", defaultSize);
0108         if (size.isValid()) {
0109             q->resize(size);
0110         }
0111     }
0112 
0113     void showKeyDetails(const QModelIndex &index)
0114     {
0115         const auto key = ui.treeView->view()->model()->data(index, KeyList::KeyRole).value<GpgME::Key>();
0116         if (!key.isNull()) {
0117             auto cmd = new DetailsCommand(key);
0118             cmd->setParentWidget(q);
0119             cmd->start();
0120         }
0121     }
0122 };
0123 
0124 GroupDetailsDialog::GroupDetailsDialog(QWidget *parent)
0125     : QDialog(parent)
0126     , d(new Private(this))
0127 {
0128     setWindowTitle(i18nc("@title:window", "Group Details"));
0129 }
0130 
0131 GroupDetailsDialog::~GroupDetailsDialog()
0132 {
0133 }
0134 
0135 namespace
0136 {
0137 QString groupComment(const KeyGroup &group)
0138 {
0139     switch (group.source()) {
0140     case KeyGroup::GnuPGConfig:
0141         return i18n("Note: This group is defined in the configuration files of gpg.");
0142     default:
0143         return QString();
0144     }
0145 }
0146 }
0147 
0148 void GroupDetailsDialog::setGroup(const KeyGroup &group)
0149 {
0150     d->group = group;
0151     d->ui.groupNameLabel->setText(group.name());
0152     d->ui.groupCommentLabel->setText(groupComment(group));
0153     d->ui.groupCommentLabel->setVisible(!d->ui.groupCommentLabel->text().isEmpty());
0154     const KeyGroup::Keys &keys = group.keys();
0155     d->ui.treeView->setKeys(std::vector<GpgME::Key>(keys.cbegin(), keys.cend()));
0156 }
0157 
0158 #include "moc_groupdetailsdialog.cpp"