File indexing completed on 2024-06-23 05:13:47

0001 /*
0002     conf/groupsconfigdialog.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 <config-kleopatra.h>
0012 
0013 #include "groupsconfigdialog.h"
0014 
0015 #include "groupsconfigwidget.h"
0016 
0017 #include <kleopatra_debug.h>
0018 #include <utils/gui-helper.h>
0019 #include <utils/scrollarea.h>
0020 
0021 #include <Libkleo/DocAction>
0022 #include <Libkleo/KeyCache>
0023 #include <Libkleo/KeyGroup>
0024 
0025 #include <KConfigGroup>
0026 #include <KLocalizedString>
0027 #include <KSharedConfig>
0028 
0029 #include <QDialogButtonBox>
0030 #include <QPushButton>
0031 #include <QVBoxLayout>
0032 
0033 using namespace Kleo;
0034 
0035 class GroupsConfigDialog::Private
0036 {
0037     friend class ::GroupsConfigDialog;
0038     GroupsConfigDialog *const q;
0039 
0040 public:
0041     Private(GroupsConfigDialog *qq)
0042         : q(qq)
0043     {
0044     }
0045 
0046 private:
0047     void saveLayout();
0048     void restoreLayout(const QSize &defaultSize = {});
0049 
0050     void loadGroups();
0051     void saveGroups();
0052 
0053     void onKeysMayHaveChanged();
0054 
0055 private:
0056     GroupsConfigWidget *configWidget = nullptr;
0057 
0058     bool savingChanges = false;
0059 };
0060 
0061 void GroupsConfigDialog::Private::saveLayout()
0062 {
0063     KConfigGroup configGroup(KSharedConfig::openStateConfig(), QLatin1StringView("GroupsConfigDialog"));
0064     configGroup.writeEntry("Size", q->size());
0065     configGroup.sync();
0066 }
0067 
0068 void GroupsConfigDialog::Private::restoreLayout(const QSize &defaultSize)
0069 {
0070     const KConfigGroup configGroup(KSharedConfig::openStateConfig(), QLatin1StringView("GroupsConfigDialog"));
0071     const QSize size = configGroup.readEntry("Size", defaultSize);
0072     if (size.isValid()) {
0073         q->resize(size);
0074     }
0075 }
0076 
0077 void GroupsConfigDialog::Private::loadGroups()
0078 {
0079     qCDebug(KLEOPATRA_LOG) << q << __func__;
0080     configWidget->setGroups(KeyCache::instance()->configurableGroups());
0081 }
0082 
0083 void GroupsConfigDialog::Private::saveGroups()
0084 {
0085     qCDebug(KLEOPATRA_LOG) << q << __func__;
0086     savingChanges = true;
0087     KeyCache::mutableInstance()->saveConfigurableGroups(configWidget->groups());
0088     savingChanges = false;
0089 
0090     // reload after saving to ensure that the groups reflect the saved groups (e.g. in case of immutable entries)
0091     loadGroups();
0092 }
0093 
0094 void GroupsConfigDialog::Private::onKeysMayHaveChanged()
0095 {
0096     if (savingChanges) {
0097         qCDebug(KLEOPATRA_LOG) << __func__ << "ignoring changes caused by ourselves";
0098         return;
0099     }
0100     qCDebug(KLEOPATRA_LOG) << "Reloading groups";
0101     loadGroups();
0102 }
0103 
0104 GroupsConfigDialog::GroupsConfigDialog(QWidget *parent)
0105     : QDialog(parent)
0106     , d(new Private(this))
0107 {
0108     setWindowTitle(i18nc("@title:window", "Configure Groups"));
0109 
0110     auto mainLayout = new QVBoxLayout{this};
0111 
0112     auto scrollArea = new ScrollArea{this};
0113     scrollArea->setFocusPolicy(Qt::NoFocus);
0114     scrollArea->setFrameStyle(QFrame::NoFrame);
0115     scrollArea->setBackgroundRole(backgroundRole());
0116     scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0117     scrollArea->setSizeAdjustPolicy(QScrollArea::AdjustToContents);
0118     auto scrollAreaLayout = qobject_cast<QBoxLayout *>(scrollArea->widget()->layout());
0119     scrollAreaLayout->setContentsMargins({});
0120 
0121     d->configWidget = new GroupsConfigWidget{this};
0122     d->configWidget->setContentsMargins({});
0123     scrollAreaLayout->addWidget(d->configWidget);
0124 
0125     mainLayout->addWidget(scrollArea);
0126 
0127     auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Close, this};
0128 
0129     mainLayout->addWidget(buttonBox);
0130 
0131     auto helpAction = std::make_unique<Kleo::DocAction>(
0132         QIcon::fromTheme(QStringLiteral("help")),
0133         i18n("Help"),
0134         i18nc("Only available in German and English. Leave to English for other languages.", "handout_group-feature_gnupg_en.pdf"),
0135         QStringLiteral("../share/doc/gnupg-vsd"),
0136         this);
0137     if (helpAction->isEnabled()) {
0138         auto helpButton = buttonBox->addButton(QDialogButtonBox::Help);
0139         disconnect(helpButton, &QAbstractButton::clicked, nullptr, nullptr);
0140         connect(helpButton, &QAbstractButton::clicked, helpAction.get(), &QAction::trigger);
0141         helpAction.release();
0142     }
0143 
0144     // prevent accidental closing of dialog when pressing Enter while the search field has focus
0145     Kleo::unsetAutoDefaultButtons(this);
0146 
0147     // Close button (defined with RejectRole) should close the dialog
0148     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::accept);
0149 
0150     connect(d->configWidget, &GroupsConfigWidget::changed, this, [this]() {
0151         d->saveGroups();
0152     });
0153 
0154     connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged, this, [this]() {
0155         d->onKeysMayHaveChanged();
0156     });
0157 
0158     d->restoreLayout();
0159     d->loadGroups();
0160 }
0161 
0162 GroupsConfigDialog::~GroupsConfigDialog()
0163 {
0164     d->saveLayout();
0165 }
0166 
0167 #include "moc_groupsconfigdialog.cpp"