decryptverifyfilescontroller.cpp 16.8 KB
Newer Older
1
/* -*- mode: c++; c-basic-offset:4 -*-
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    decryptverifyfilescontroller.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2008 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "decryptverifyfilescontroller.h"
36

37
#include <crypto/gui/decryptverifyoperationwidget.h>
38
#include <crypto/gui/decryptverifyfileswizard.h>
39
#include <crypto/decryptverifytask.h>
40
#include <crypto/taskcollection.h>
41
42

#include <utils/classify.h>
43
#include <utils/gnupg-helper.h>
44
#include <utils/path-helper.h>
45
46
47
#include <utils/input.h>
#include <utils/output.h>
#include <utils/kleo_assert.h>
Thomas McGuire's avatar
Thomas McGuire committed
48
#include <utils/archivedefinition.h>
49
50

#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
51
#include "kleopatra_debug.h"
52
53
54

#include <QDir>
#include <QFile>
55
#include <QFileInfo>
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <QPointer>
#include <QTimer>

#include <boost/shared_ptr.hpp>

#include <memory>
#include <vector>

using namespace boost;
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;

Laurent Montel's avatar
Laurent Montel committed
70
71
72
class DecryptVerifyFilesController::Private
{
    DecryptVerifyFilesController *const q;
73
74
public:

Laurent Montel's avatar
Laurent Montel committed
75
    static shared_ptr<AbstractDecryptVerifyTask> taskFromOperationWidget(const DecryptVerifyOperationWidget *w, const QString &fileName, const QDir &outDir, const shared_ptr<OverwritePolicy> &overwritePolicy);
76

Laurent Montel's avatar
Laurent Montel committed
77
    explicit Private(DecryptVerifyFilesController *qq);
78
79
80
81
82

    void slotWizardOperationPrepared();
    void slotWizardCanceled();
    void schedule();

83
    QStringList prepareWizardFromPassedFiles();
Laurent Montel's avatar
Laurent Montel committed
84
    std::vector<shared_ptr<Task> > buildTasks(const QStringList &, const shared_ptr<OverwritePolicy> &);
85
86
87

    void ensureWizardCreated();
    void ensureWizardVisible();
Laurent Montel's avatar
Laurent Montel committed
88
89
90
    void reportError(int err, const QString &details)
    {
        q->setLastError(err, details);
Thomas McGuire's avatar
Thomas McGuire committed
91
        q->emitDoneOrError();
92
    }
93
    void cancelAllTasks();
94

95
    QStringList m_passedFiles, m_filesAfterPreparation;
96
    QPointer<DecryptVerifyFilesWizard> m_wizard;
97
    std::vector<shared_ptr<const DecryptVerifyResult> > m_results;
98
99
    std::vector<shared_ptr<Task> > m_runnableTasks, m_completedTasks;
    shared_ptr<Task> m_runningTask;
100
101
    bool m_errorDetected;
    DecryptVerifyOperation m_operation;
102
103
104
};

// static
Laurent Montel's avatar
Laurent Montel committed
105
106
shared_ptr<AbstractDecryptVerifyTask> DecryptVerifyFilesController::Private::taskFromOperationWidget(const DecryptVerifyOperationWidget *w, const QString &fileName, const QDir &outDir, const shared_ptr<OverwritePolicy> &overwritePolicy)
{
107

Laurent Montel's avatar
Laurent Montel committed
108
    kleo_assert(w);
109

110
    shared_ptr<AbstractDecryptVerifyTask> task;
111

Laurent Montel's avatar
Laurent Montel committed
112
113
    switch (w->mode()) {
    case DecryptVerifyOperationWidget::VerifyDetachedWithSignature: {
114

Laurent Montel's avatar
Laurent Montel committed
115
116
117
        shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
        t->setInput(Input::createFromFile(fileName));
        t->setSignedData(Input::createFromFile(w->signedDataFileName()));
118
        task = t;
119

Laurent Montel's avatar
Laurent Montel committed
120
        kleo_assert(fileName == w->inputFileName());
121
122
    }
    break;
Laurent Montel's avatar
Laurent Montel committed
123
124
125
126
    case DecryptVerifyOperationWidget::VerifyDetachedWithSignedData: {
        shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
        t->setInput(Input::createFromFile(w->inputFileName()));
        t->setSignedData(Input::createFromFile(fileName));
127
        task = t;
128

Laurent Montel's avatar
Laurent Montel committed
129
        kleo_assert(fileName == w->signedDataFileName());
130
131
    }
    break;
Laurent Montel's avatar
Laurent Montel committed
132
133
    case DecryptVerifyOperationWidget::DecryptVerifyOpaque: {
        const unsigned int classification = classify(fileName);
Laurent Montel's avatar
Laurent Montel committed
134
        qCDebug(KLEOPATRA_LOG) << "classified" << fileName << "as" << printableClassification(classification);
Thomas McGuire's avatar
Thomas McGuire committed
135

Thomas McGuire's avatar
Thomas McGuire committed
136
137
138
        const shared_ptr<ArchiveDefinition> ad = w->selectedArchiveDefinition();

        const Protocol proto =
Laurent Montel's avatar
Laurent Montel committed
139
140
141
            isOpenPGP(classification) ? OpenPGP :
            isCMS(classification)     ? CMS :
            ad /* _needs_ the info */   ? throw Exception(gpg_error(GPG_ERR_CONFLICT), i18n("Cannot determine whether input data is OpenPGP or CMS")) :
Laurent Montel's avatar
Laurent Montel committed
142
            /* else we don't care */      UnknownProtocol;
Thomas McGuire's avatar
Thomas McGuire committed
143

Laurent Montel's avatar
Laurent Montel committed
144
        const shared_ptr<Input> input = Input::createFromFile(fileName);
Thomas McGuire's avatar
Thomas McGuire committed
145
        const shared_ptr<Output> output =
Laurent Montel's avatar
Laurent Montel committed
146
147
            ad       ? ad->createOutputFromUnpackCommand(proto, fileName, outDir) :
            /*else*/   Output::createFromFile(outDir.absoluteFilePath(outputFileName(QFileInfo(fileName).fileName())), overwritePolicy);
Thomas McGuire's avatar
Thomas McGuire committed
148

Laurent Montel's avatar
Laurent Montel committed
149
        if (mayBeCipherText(classification)) {
Laurent Montel's avatar
Laurent Montel committed
150
            qCDebug(KLEOPATRA_LOG) << "creating a DecryptVerifyTask";
Laurent Montel's avatar
Laurent Montel committed
151
152
153
            shared_ptr<DecryptVerifyTask> t(new DecryptVerifyTask);
            t->setInput(input);
            t->setOutput(output);
Thomas McGuire's avatar
Thomas McGuire committed
154
155
            task = t;
        } else {
Laurent Montel's avatar
Laurent Montel committed
156
            qCDebug(KLEOPATRA_LOG) << "creating a VerifyOpaqueTask";
Laurent Montel's avatar
Laurent Montel committed
157
158
159
            shared_ptr<VerifyOpaqueTask> t(new VerifyOpaqueTask);
            t->setInput(input);
            t->setOutput(output);
Thomas McGuire's avatar
Thomas McGuire committed
160
161
            task = t;
        }
162

Laurent Montel's avatar
Laurent Montel committed
163
        kleo_assert(fileName == w->inputFileName());
164
    }
165
166
    break;
    }
167

168
    task->autodetectProtocolFromInput();
169
170
171
    return task;
}

Laurent Montel's avatar
Laurent Montel committed
172
DecryptVerifyFilesController::Private::Private(DecryptVerifyFilesController *qq) : q(qq), m_errorDetected(false), m_operation(DecryptVerify)
173
{
174
    qRegisterMetaType<VerificationResult>();
175
176
177
178
}

void DecryptVerifyFilesController::Private::slotWizardOperationPrepared()
{
179
180
181
182
183
184
185
    ensureWizardCreated();
    std::vector<shared_ptr<Task> > tasks = buildTasks(m_filesAfterPreparation, shared_ptr<OverwritePolicy>(new OverwritePolicy(m_wizard)));
    if (tasks.empty()) {
        reportError(makeGnuPGError(GPG_ERR_ASS_NO_INPUT), i18n("No usable inputs found"));
    }
    kleo_assert(m_runnableTasks.empty());
    m_runnableTasks.swap(tasks);
Laurent Montel's avatar
Laurent Montel committed
186

187
188
189
    shared_ptr<TaskCollection> coll(new TaskCollection);
    Q_FOREACH (const shared_ptr<Task> &i, m_runnableTasks) {
        q->connectTask(i);
190
    }
191
192
193
194
    coll->setTasks(m_runnableTasks);
    m_wizard->setTaskCollection(coll);

    QTimer::singleShot(0, q, SLOT(schedule()));
195
196
197
198
}

void DecryptVerifyFilesController::Private::slotWizardCanceled()
{
Laurent Montel's avatar
Laurent Montel committed
199
    qCDebug(KLEOPATRA_LOG);
200
201
}

Laurent Montel's avatar
Laurent Montel committed
202
void DecryptVerifyFilesController::doTaskDone(const Task *task, const shared_ptr<const Task::Result> &result)
203
{
Laurent Montel's avatar
Laurent Montel committed
204
205
206
    assert(task);
    assert(task == d->m_runningTask.get());
    Q_UNUSED(task);
207

208
209
210
211
    // We could just delete the tasks here, but we can't use
    // Qt::QueuedConnection here (we need sender()) and other slots
    // might not yet have executed. Therefore, we push completed tasks
    // into a burial container
212

Laurent Montel's avatar
Laurent Montel committed
213
    d->m_completedTasks.push_back(d->m_runningTask);
214
    d->m_runningTask.reset();
215

Laurent Montel's avatar
Laurent Montel committed
216
217
218
    if (const shared_ptr<const DecryptVerifyResult> &dvr = boost::dynamic_pointer_cast<const DecryptVerifyResult>(result)) {
        d->m_results.push_back(dvr);
    }
219

Laurent Montel's avatar
Laurent Montel committed
220
    QTimer::singleShot(0, this, SLOT(schedule()));
221
222
}

223
224
void DecryptVerifyFilesController::Private::schedule()
{
Laurent Montel's avatar
Laurent Montel committed
225
    if (!m_runningTask && !m_runnableTasks.empty()) {
226
        const shared_ptr<Task> t = m_runnableTasks.back();
227
        m_runnableTasks.pop_back();
228
        t->start();
229
230
        m_runningTask = t;
    }
Laurent Montel's avatar
Laurent Montel committed
231
232
233
    if (!m_runningTask) {
        kleo_assert(m_runnableTasks.empty());
        Q_FOREACH (const shared_ptr<const DecryptVerifyResult> &i, m_results) {
Laurent Montel's avatar
Laurent Montel committed
234
            Q_EMIT q->verificationResult(i->verificationResult());
Laurent Montel's avatar
Laurent Montel committed
235
        }
236
        q->emitDoneOrError();
237
238
239
240
241
    }
}

void DecryptVerifyFilesController::Private::ensureWizardCreated()
{
Laurent Montel's avatar
Laurent Montel committed
242
    if (m_wizard) {
243
        return;
Laurent Montel's avatar
Laurent Montel committed
244
    }
245

Laurent Montel's avatar
Laurent Montel committed
246
    std::unique_ptr<DecryptVerifyFilesWizard> w(new DecryptVerifyFilesWizard);
Laurent Montel's avatar
Laurent Montel committed
247
248
    w->setWindowTitle(i18n("Decrypt/Verify Files"));
    w->setAttribute(Qt::WA_DeleteOnClose);
249

Laurent Montel's avatar
Laurent Montel committed
250
251
    connect(w.get(), SIGNAL(operationPrepared()), q, SLOT(slotWizardOperationPrepared()), Qt::QueuedConnection);
    connect(w.get(), SIGNAL(canceled()), q, SLOT(slotWizardCanceled()), Qt::QueuedConnection);
252
253
254
255
    m_wizard = w.release();

}

Laurent Montel's avatar
Laurent Montel committed
256
257
258
259
260
261
262
263
namespace
{
struct FindExtension : std::unary_function<shared_ptr<ArchiveDefinition>, bool> {
    const QString ext;
    const Protocol proto;
    FindExtension(const QString &ext, Protocol proto) : ext(ext), proto(proto) {}
    bool operator()(const shared_ptr<ArchiveDefinition> &ad) const
    {
264
        qCDebug(KLEOPATRA_LOG) << "   considering" << (ad ? ad->label() : QStringLiteral("<null>")) << "for" << ext;
Laurent Montel's avatar
Laurent Montel committed
265
266
267
268
269
        bool result;
        if (proto == UnknownProtocol) {
            result = ad && (ad->extensions(OpenPGP).contains(ext, Qt::CaseInsensitive) || ad->extensions(CMS).contains(ext, Qt::CaseInsensitive));
        } else {
            result = ad && ad->extensions(proto).contains(ext, Qt::CaseInsensitive);
Thomas McGuire's avatar
Thomas McGuire committed
270
        }
Laurent Montel's avatar
Laurent Montel committed
271
        qCDebug(KLEOPATRA_LOG) << (result ? "   -> matches" : "   -> doesn't match");
Laurent Montel's avatar
Laurent Montel committed
272
273
274
        return result;
    }
};
Thomas McGuire's avatar
Thomas McGuire committed
275
276
}

Laurent Montel's avatar
Laurent Montel committed
277
278
279
shared_ptr<ArchiveDefinition> pick_archive_definition(GpgME::Protocol proto, const std::vector< shared_ptr<ArchiveDefinition> > &ads, const QString &filename)
{
    const QFileInfo fi(outputFileName(filename));
Thomas McGuire's avatar
Thomas McGuire committed
280
281
    QString extension = fi.completeSuffix();

Laurent Montel's avatar
Laurent Montel committed
282
    if (extension == QLatin1String("out")) { // added by outputFileName() -> useless
Thomas McGuire's avatar
Thomas McGuire committed
283
        return shared_ptr<ArchiveDefinition>();
Laurent Montel's avatar
Laurent Montel committed
284
    }
Thomas McGuire's avatar
Thomas McGuire committed
285

Laurent Montel's avatar
Laurent Montel committed
286
    if (extension.endsWith(QStringLiteral(".out"))) {     // added by outputFileName() -> remove
Thomas McGuire's avatar
Thomas McGuire committed
287
        extension.chop(4);
Laurent Montel's avatar
Laurent Montel committed
288
    }
Thomas McGuire's avatar
Thomas McGuire committed
289

Laurent Montel's avatar
Laurent Montel committed
290
    for (;;) {
Thomas McGuire's avatar
Thomas McGuire committed
291
        const std::vector<shared_ptr<ArchiveDefinition> >::const_iterator it
Laurent Montel's avatar
Laurent Montel committed
292
293
            = std::find_if(ads.begin(), ads.end(), FindExtension(extension, proto));
        if (it != ads.end()) {
Thomas McGuire's avatar
Thomas McGuire committed
294
            return *it;
Laurent Montel's avatar
Laurent Montel committed
295
296
297
        }
        const int idx = extension.indexOf(QLatin1Char('.'));
        if (idx < 0) {
Thomas McGuire's avatar
Thomas McGuire committed
298
            return shared_ptr<ArchiveDefinition>();
Laurent Montel's avatar
Laurent Montel committed
299
300
        }
        extension = extension.mid(idx + 1);
Thomas McGuire's avatar
Thomas McGuire committed
301
302
    }
}
303

304
QStringList DecryptVerifyFilesController::Private::prepareWizardFromPassedFiles()
305
306
307
{
    ensureWizardCreated();

Thomas McGuire's avatar
Thomas McGuire committed
308
309
    const std::vector< shared_ptr<ArchiveDefinition> > archiveDefinitions = ArchiveDefinition::getArchiveDefinitions();

310
    QStringList fileNames;
311
    unsigned int counter = 0;
Laurent Montel's avatar
Laurent Montel committed
312
    Q_FOREACH (const QString &fname, m_passedFiles) {
313

Laurent Montel's avatar
Laurent Montel committed
314
        kleo_assert(!fname.isEmpty());
315

Laurent Montel's avatar
Laurent Montel committed
316
317
        const unsigned int classification = classify(fname);
        const Protocol proto = findProtocol(classification);
318

Laurent Montel's avatar
Laurent Montel committed
319
        if (mayBeOpaqueSignature(classification) || mayBeCipherText(classification) || mayBeDetachedSignature(classification)) {
320

Laurent Montel's avatar
Laurent Montel committed
321
322
            DecryptVerifyOperationWidget *const op = m_wizard->operationWidget(counter++);
            kleo_assert(op != 0);
323

Laurent Montel's avatar
Laurent Montel committed
324
            op->setArchiveDefinitions(archiveDefinitions);
Thomas McGuire's avatar
Thomas McGuire committed
325

Laurent Montel's avatar
Laurent Montel committed
326
            const QString signedDataFileName = findSignedData(fname);
327
328
329
330
331

            // this breaks opaque signatures whose source files still
            // happen to exist in the same directory. Until we have
            // content-based classification, this is the most unlikely
            // case, so that's the case we break. ### FIXME remove when content-classify is done
Laurent Montel's avatar
Laurent Montel committed
332
333
334
            if (mayBeDetachedSignature(classification) && !signedDataFileName.isEmpty()) {
                op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignature);
            }
335
            // ### end FIXME
Laurent Montel's avatar
Laurent Montel committed
336
337
338
339
340
            else if (mayBeOpaqueSignature(classification) || mayBeCipherText(classification)) {
                op->setMode(DecryptVerifyOperationWidget::DecryptVerifyOpaque, pick_archive_definition(proto, archiveDefinitions, fname));
            } else {
                op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignature);
            }
341

Laurent Montel's avatar
Laurent Montel committed
342
343
            op->setInputFileName(fname);
            op->setSignedDataFileName(signedDataFileName);
344

Laurent Montel's avatar
Laurent Montel committed
345
            fileNames.push_back(fname);
346
347
348
349

        } else {

            // probably the signed data file was selected:
Laurent Montel's avatar
Laurent Montel committed
350
            const QStringList signatures = findSignatures(fname);
351

Laurent Montel's avatar
Laurent Montel committed
352
            if (signatures.empty()) {
353
354
355
356
                // We are assuming this is a detached signature file, but
                // there were no signature files for it. Let's guess it's encrypted after all.
                // ### FIXME once we have a proper heuristic for this, this should move into
                // classify() and/or classifyContent()
Laurent Montel's avatar
Laurent Montel committed
357
358
359
360
361
362
                DecryptVerifyOperationWidget *const op = m_wizard->operationWidget(counter++);
                kleo_assert(op != 0);
                op->setArchiveDefinitions(archiveDefinitions);
                op->setMode(DecryptVerifyOperationWidget::DecryptVerifyOpaque, pick_archive_definition(proto, archiveDefinitions, fname));
                op->setInputFileName(fname);
                fileNames.push_back(fname);
363
            } else {
364

Laurent Montel's avatar
Laurent Montel committed
365
366
367
                Q_FOREACH (const QString &s, signatures) {
                    DecryptVerifyOperationWidget *op = m_wizard->operationWidget(counter++);
                    kleo_assert(op != 0);
368

Laurent Montel's avatar
Laurent Montel committed
369
370
371
372
                    op->setArchiveDefinitions(archiveDefinitions);
                    op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignedData);
                    op->setInputFileName(s);
                    op->setSignedDataFileName(fname);
373

Laurent Montel's avatar
Laurent Montel committed
374
                    fileNames.push_back(fname);
375
                }
376
377
378
379
380

            }
        }
    }

Laurent Montel's avatar
Laurent Montel committed
381
    kleo_assert(counter == static_cast<unsigned>(fileNames.size()));
382

Laurent Montel's avatar
Laurent Montel committed
383
    m_wizard->setOutputDirectory(heuristicBaseDirectory(m_passedFiles));
384
    return fileNames;
385
386
}

Laurent Montel's avatar
Laurent Montel committed
387
std::vector< shared_ptr<Task> > DecryptVerifyFilesController::Private::buildTasks(const QStringList &fileNames, const shared_ptr<OverwritePolicy> &overwritePolicy)
388
{
389
    const bool useOutDir = m_wizard->useOutputDirectory();
Laurent Montel's avatar
Laurent Montel committed
390
    const QFileInfo outDirInfo(m_wizard->outputDirectory());
391

Laurent Montel's avatar
Laurent Montel committed
392
    kleo_assert(!useOutDir || outDirInfo.isDir());
393

Laurent Montel's avatar
Laurent Montel committed
394
395
    const QDir outDir(outDirInfo.absoluteFilePath());
    kleo_assert(!useOutDir || outDir.exists());
396

397
    std::vector<shared_ptr<Task> > tasks;
Laurent Montel's avatar
Laurent Montel committed
398
    for (unsigned int i = 0, end  = fileNames.size(); i != end; ++i)
399
        try {
Laurent Montel's avatar
Laurent Montel committed
400
401
402
403
404
            const QDir fileDir = QFileInfo(fileNames[i]).absoluteDir();
            kleo_assert(fileDir.exists());
            tasks.push_back(taskFromOperationWidget(m_wizard->operationWidget(i), fileNames[i], useOutDir ? outDir : fileDir, overwritePolicy));
        } catch (const GpgME::Exception &e) {
            tasks.push_back(Task::makeErrorTask(e.error().code(), QString::fromLocal8Bit(e.what()), fileNames[i]));
405
406
407
408
409
        }

    return tasks;
}

Laurent Montel's avatar
Laurent Montel committed
410
void DecryptVerifyFilesController::setFiles(const QStringList &files)
411
412
413
414
415
416
417
{
    d->m_passedFiles = files;
}

void DecryptVerifyFilesController::Private::ensureWizardVisible()
{
    ensureWizardCreated();
Laurent Montel's avatar
Laurent Montel committed
418
    q->bringToForeground(m_wizard);
419
420
}

Laurent Montel's avatar
Laurent Montel committed
421
DecryptVerifyFilesController::DecryptVerifyFilesController(QObject *parent) : Controller(parent), d(new Private(this))
422
423
424
{
}

Laurent Montel's avatar
Laurent Montel committed
425
DecryptVerifyFilesController::DecryptVerifyFilesController(const shared_ptr<const ExecutionContext> &ctx, QObject *parent) : Controller(ctx, parent), d(new Private(this))
426
427
428
{
}

Laurent Montel's avatar
Laurent Montel committed
429
430
DecryptVerifyFilesController::~DecryptVerifyFilesController()
{
Laurent Montel's avatar
Laurent Montel committed
431
    qCDebug(KLEOPATRA_LOG);
Laurent Montel's avatar
Laurent Montel committed
432
}
433
434
435
436
437
438
439

void DecryptVerifyFilesController::start()
{
    d->m_filesAfterPreparation = d->prepareWizardFromPassedFiles();
    d->ensureWizardVisible();
}

Laurent Montel's avatar
Laurent Montel committed
440
void DecryptVerifyFilesController::setOperation(DecryptVerifyOperation op)
441
442
443
444
{
    d->m_operation = op;
}

445
446
447
448
449
DecryptVerifyOperation DecryptVerifyFilesController::operation() const
{
    return d->m_operation;
}

Laurent Montel's avatar
Laurent Montel committed
450
451
void DecryptVerifyFilesController::Private::cancelAllTasks()
{
452
453
454
455
456

    // we just kill all runnable tasks - this will not result in
    // signal emissions.
    m_runnableTasks.clear();

457
    // a cancel() will result in a call to
Laurent Montel's avatar
Laurent Montel committed
458
    if (m_runningTask) {
459
        m_runningTask->cancel();
Laurent Montel's avatar
Laurent Montel committed
460
    }
461
462
463
464
}

void DecryptVerifyFilesController::cancel()
{
Laurent Montel's avatar
Laurent Montel committed
465
    qCDebug(KLEOPATRA_LOG);
466
467
    try {
        d->m_errorDetected = true;
Laurent Montel's avatar
Laurent Montel committed
468
        if (d->m_wizard) {
469
            d->m_wizard->close();
Laurent Montel's avatar
Laurent Montel committed
470
        }
471
        d->cancelAllTasks();
Laurent Montel's avatar
Laurent Montel committed
472
    } catch (const std::exception &e) {
Laurent Montel's avatar
Laurent Montel committed
473
        qCDebug(KLEOPATRA_LOG) << "Caught exception: " << e.what();
474
475
476
    }
}

Stephen Kelly's avatar
Stephen Kelly committed
477
#include "moc_decryptverifyfilescontroller.cpp"