File indexing completed on 2024-05-05 17:43:13

0001 /*
0002  *   SPDX-FileCopyrightText: 2017 Ivan Cukic <ivan.cukic (at) kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "vaultconfigurationdialog.h"
0008 #include "ui_vaultconfigurationdialog.h"
0009 
0010 #include <QMap>
0011 #include <QPushButton>
0012 #include <QStackedLayout>
0013 #include <QTabWidget>
0014 #include <QVector>
0015 
0016 #include "dialogdsl.h"
0017 #include "vault.h"
0018 
0019 using namespace DialogDsl;
0020 using namespace DialogDsl::operators;
0021 
0022 #include "activitieslinkingwidget.h"
0023 #include "backendchooserwidget.h"
0024 #include "cryfscypherchooserwidget.h"
0025 #include "directorychooserwidget.h"
0026 #include "namechooserwidget.h"
0027 #include "noticewidget.h"
0028 #include "offlineonlywidget.h"
0029 #include "passwordchooserwidget.h"
0030 #include "vaultdeletionwidget.h"
0031 
0032 using PlasmaVault::Vault;
0033 
0034 class VaultConfigurationDialog::Private
0035 {
0036 public:
0037     VaultConfigurationDialog *const q;
0038     Vault *vault;
0039 
0040     Ui::VaultConfigurationDialog ui;
0041     QStackedLayout *layout;
0042 
0043     steps currentSteps;
0044     QVector<DialogDsl::DialogModule *> currentModuleDialogs;
0045     QSet<DialogDsl::DialogModule *> invalidModules;
0046 
0047     steps defaultSteps{i18n("General") / step{nameChooser(), directoryChooser(DirectoryChooserWidget::RequireEmptyMountPoint)},
0048 
0049                        i18n("Advanced") / step{activitiesChooser(), offlineOnlyChooser()},
0050 
0051                        i18n("Delete") / step{vaultDeletion()}};
0052 
0053     Logic logic{{"encfs" / i18n("EncFS"), defaultSteps},
0054 
0055                 {"cryfs" / i18n("CryFS"), defaultSteps},
0056 
0057                 {"gocryptfs" / i18n("gocryptfs"), defaultSteps}};
0058 
0059     Private(Vault *vault, VaultConfigurationDialog *parent)
0060         : q(parent)
0061         , vault(vault)
0062     {
0063         ui.setupUi(parent);
0064         ui.message->hide();
0065 
0066         layout = new QStackedLayout();
0067         layout->setContentsMargins(0, 0, 0, 0);
0068         ui.container->setLayout(layout);
0069 
0070         auto tabs = new QTabWidget();
0071         layout->addWidget(tabs);
0072 
0073         // Loading the backends
0074         auto modules = logic[Key(vault->backend().toLatin1())];
0075 
0076         Vault::Payload payload{
0077             {KEY_DEVICE, QVariant(vault->device().data())},
0078             {KEY_NAME, QVariant(vault->name())},
0079             {KEY_MOUNT_POINT, QVariant(vault->mountPoint().data())},
0080             {KEY_ACTIVITIES, QVariant(vault->activities())},
0081             {KEY_OFFLINEONLY, QVariant(vault->isOfflineOnly())},
0082         };
0083 
0084         for (const auto &module : modules) {
0085             DialogModule *stepWidget = new CompoundDialogModule(module);
0086             stepWidget->init(payload);
0087             tabs->addTab(stepWidget, module.title());
0088             currentModuleDialogs << stepWidget;
0089 
0090             QObject::connect(stepWidget, &DialogModule::isValidChanged, q, [this, stepWidget](bool valid) {
0091                 if (valid) {
0092                     invalidModules.remove(stepWidget);
0093                 } else {
0094                     invalidModules << stepWidget;
0095                 }
0096 
0097                 ui.buttons->button(QDialogButtonBox::Ok)->setEnabled(invalidModules.isEmpty());
0098             });
0099 
0100             QObject::connect(stepWidget, &DialogModule::requestCancellation, q, [this] {
0101                 q->reject();
0102             });
0103         }
0104     }
0105 
0106     void setVaultOpened(bool vaultOpened)
0107     {
0108         bool configurationEnabled = !vaultOpened;
0109         ui.buttons->button(QDialogButtonBox::Ok)->setEnabled(configurationEnabled);
0110         ui.frameUnlockVault->setVisible(!configurationEnabled);
0111         ui.container->setEnabled(configurationEnabled);
0112     }
0113 
0114     void saveConfiguration()
0115     {
0116         Vault::Payload collectedPayload;
0117         qDebug() << "Getting the data";
0118         for (const auto *module : currentModuleDialogs) {
0119             qDebug() << "Data: " << module->fields();
0120             collectedPayload.insert(module->fields());
0121         }
0122 
0123         const auto name = collectedPayload[KEY_NAME].toString();
0124         const PlasmaVault::MountPoint mountPoint(collectedPayload[KEY_MOUNT_POINT].toString());
0125         const auto activities = collectedPayload[KEY_ACTIVITIES].toStringList();
0126         const auto isOfflineOnly = collectedPayload[KEY_OFFLINEONLY].toBool();
0127 
0128         if (name.isEmpty() || mountPoint.isEmpty())
0129             return;
0130 
0131         vault->setName(name);
0132         vault->setMountPoint(mountPoint);
0133         vault->setActivities(activities);
0134         vault->setIsOfflineOnly(isOfflineOnly);
0135     }
0136 };
0137 
0138 VaultConfigurationDialog::VaultConfigurationDialog(Vault *vault, QWidget *parent)
0139     : QDialog(parent)
0140     , d(new Private(vault, this))
0141 {
0142     setWindowTitle(i18n("Configure"));
0143 
0144     d->setVaultOpened(vault->isOpened());
0145 
0146     connect(d->ui.buttonCloseVault, &QPushButton::clicked, this, [=]() {
0147         vault->close();
0148     });
0149 
0150     connect(vault, &Vault::isOpenedChanged, this, [=](bool isOpened) {
0151         d->setVaultOpened(isOpened);
0152     });
0153 
0154     connect(d->ui.buttons, &QDialogButtonBox::accepted, this, [=] {
0155         d->saveConfiguration();
0156     });
0157 }
0158 
0159 VaultConfigurationDialog::~VaultConfigurationDialog()
0160 {
0161 }