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

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     commands/decryptverifyfilescommand.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "decryptverifyfilescommand.h"
0013 #include "viewemailfilescommand.h"
0014 
0015 #include "command_p.h"
0016 #include "fileoperationspreferences.h"
0017 
0018 #include "crypto/autodecryptverifyfilescontroller.h"
0019 #include "crypto/decryptverifyfilescontroller.h"
0020 
0021 #include <utils/filedialog.h>
0022 
0023 #include <Libkleo/Classify>
0024 #include <Libkleo/Stl_Util>
0025 
0026 #include "kleopatra_debug.h"
0027 #include <KLocalizedString>
0028 
0029 #include <exception>
0030 
0031 using namespace Kleo;
0032 using namespace Kleo::Commands;
0033 using namespace Kleo::Crypto;
0034 
0035 class DecryptVerifyFilesCommand::Private : public Command::Private
0036 {
0037     friend class ::Kleo::Commands::DecryptVerifyFilesCommand;
0038     DecryptVerifyFilesCommand *q_func() const
0039     {
0040         return static_cast<DecryptVerifyFilesCommand *>(q);
0041     }
0042 
0043 public:
0044     explicit Private(DecryptVerifyFilesCommand *qq, KeyListController *c, bool forceManualMode = false);
0045     ~Private() override;
0046 
0047     QStringList selectFiles() const;
0048 
0049     void init();
0050 
0051 private:
0052     void finishIfEverythingIsDone()
0053     {
0054         if (files.empty() && emailFiles.empty()) {
0055             finished();
0056         }
0057     }
0058 
0059     void slotControllerDone()
0060     {
0061         files.clear();
0062         finishIfEverythingIsDone();
0063     }
0064 
0065     void slotControllerError(int, const QString &msg)
0066     {
0067         KMessageBox::error(parentWidgetOrView(), msg, i18nc("@title:window", "Decrypt/Verify Failed"));
0068         files.clear();
0069         finishIfEverythingIsDone();
0070     }
0071 
0072 private:
0073     QStringList files;
0074     QStringList emailFiles;
0075     std::shared_ptr<const ExecutionContext> shared_qq;
0076     DecryptVerifyFilesController *mController;
0077 };
0078 
0079 DecryptVerifyFilesCommand::Private *DecryptVerifyFilesCommand::d_func()
0080 {
0081     return static_cast<Private *>(d.get());
0082 }
0083 const DecryptVerifyFilesCommand::Private *DecryptVerifyFilesCommand::d_func() const
0084 {
0085     return static_cast<const Private *>(d.get());
0086 }
0087 
0088 #define d d_func()
0089 #define q q_func()
0090 
0091 DecryptVerifyFilesCommand::Private::Private(DecryptVerifyFilesCommand *qq, KeyListController *c, bool forceManualMode)
0092     : Command::Private(qq, c)
0093     , files()
0094     , shared_qq(qq, [](DecryptVerifyFilesCommand *) {})
0095 {
0096     FileOperationsPreferences prefs;
0097     if (!forceManualMode && prefs.autoDecryptVerify()) {
0098         mController = new AutoDecryptVerifyFilesController();
0099     } else {
0100         mController = new DecryptVerifyFilesController();
0101     }
0102 }
0103 
0104 DecryptVerifyFilesCommand::Private::~Private()
0105 {
0106     qCDebug(KLEOPATRA_LOG);
0107     delete mController;
0108 }
0109 
0110 DecryptVerifyFilesCommand::DecryptVerifyFilesCommand(KeyListController *c)
0111     : Command(new Private(this, c))
0112 {
0113     d->init();
0114 }
0115 
0116 DecryptVerifyFilesCommand::DecryptVerifyFilesCommand(QAbstractItemView *v, KeyListController *c)
0117     : Command(v, new Private(this, c))
0118 {
0119     d->init();
0120 }
0121 
0122 DecryptVerifyFilesCommand::DecryptVerifyFilesCommand(const QStringList &files, KeyListController *c, bool forceManualMode)
0123     : Command(new Private(this, c, forceManualMode))
0124 {
0125     d->init();
0126     d->files = files;
0127 }
0128 
0129 DecryptVerifyFilesCommand::DecryptVerifyFilesCommand(const QStringList &files, QAbstractItemView *v, KeyListController *c)
0130     : Command(v, new Private(this, c))
0131 {
0132     d->init();
0133     d->files = files;
0134 }
0135 
0136 void DecryptVerifyFilesCommand::Private::init()
0137 {
0138     mController->setExecutionContext(shared_qq);
0139     connect(mController, &Controller::done, q, [this]() {
0140         slotControllerDone();
0141     });
0142     connect(mController, &Controller::error, q, [this](int err, const QString &details) {
0143         slotControllerError(err, details);
0144     });
0145 }
0146 
0147 DecryptVerifyFilesCommand::~DecryptVerifyFilesCommand()
0148 {
0149     qCDebug(KLEOPATRA_LOG);
0150 }
0151 
0152 void DecryptVerifyFilesCommand::setFiles(const QStringList &files)
0153 {
0154     d->files = files;
0155 }
0156 
0157 void DecryptVerifyFilesCommand::setOperation(DecryptVerifyOperation op)
0158 {
0159     try {
0160         d->mController->setOperation(op);
0161     } catch (...) {
0162     }
0163 }
0164 
0165 DecryptVerifyOperation DecryptVerifyFilesCommand::operation() const
0166 {
0167     return d->mController->operation();
0168 }
0169 
0170 void DecryptVerifyFilesCommand::doStart()
0171 {
0172     try {
0173         if (d->files.empty()) {
0174             d->files = d->selectFiles();
0175         }
0176         if (d->files.empty()) {
0177             d->finished();
0178             return;
0179         }
0180 
0181         for (const auto &file : std::as_const(d->files)) {
0182             const unsigned int classification = classify(file);
0183             if (classification & Class::MimeFile) {
0184                 d->emailFiles << file;
0185                 d->files.removeAll(file);
0186             }
0187         }
0188 
0189         if (!d->emailFiles.empty()) {
0190             const auto viewEmailCommand = new ViewEmailFilesCommand(d->emailFiles, nullptr);
0191             connect(viewEmailCommand, &ViewEmailFilesCommand::finished, this, [this] {
0192                 d->emailFiles.clear();
0193                 d->finishIfEverythingIsDone();
0194             });
0195             viewEmailCommand->start();
0196         }
0197 
0198         if (d->files.empty()) {
0199             return;
0200         }
0201 
0202         d->mController->setFiles(d->files);
0203         d->mController->start();
0204 
0205     } catch (const std::exception &e) {
0206         d->information(i18n("An error occurred: %1", QString::fromLocal8Bit(e.what())), i18n("Decrypt/Verify Files Error"));
0207         d->finished();
0208     }
0209 }
0210 
0211 void DecryptVerifyFilesCommand::doCancel()
0212 {
0213     qCDebug(KLEOPATRA_LOG);
0214     d->mController->cancel();
0215 }
0216 
0217 QStringList DecryptVerifyFilesCommand::Private::selectFiles() const
0218 {
0219     return FileDialog::getOpenFileNames(parentWidgetOrView(), i18n("Select One or More Files to Decrypt and/or Verify"), QStringLiteral("enc"));
0220 }
0221 
0222 #undef d
0223 #undef q
0224 
0225 #include "moc_decryptverifyfilescommand.cpp"