Warning, file /utilities/symmy/src/compositejob.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Elvis Angelaccio <elvis.angelaccio@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 * 0006 */ 0007 0008 #include "compositejob.h" 0009 #include "decryptjob.h" 0010 #include "encryptjob.h" 0011 #include "symmydebug.h" 0012 0013 #include <KIO/JobTracker> 0014 #include <KJobTrackerInterface> 0015 #include <KLocalizedString> 0016 #include <KMessageBox> 0017 #include <KNewPasswordDialog> 0018 #include <KPasswordDialog> 0019 0020 #include <QTimer> 0021 0022 namespace Symmy 0023 { 0024 0025 CompositeJob::CompositeJob(const QStringList &filenames, Task task) 0026 : KCompositeJob {} 0027 , m_filenames {filenames} 0028 , m_task {task} 0029 { 0030 setCapabilities(Killable); 0031 KIO::getJobTracker()->registerJob(this); 0032 } 0033 0034 CompositeJob::~CompositeJob() 0035 { 0036 } 0037 0038 void CompositeJob::start() 0039 { 0040 QTimer::singleShot(0, this, &CompositeJob::slotStart); 0041 } 0042 0043 bool CompositeJob::doKill() 0044 { 0045 qCDebug(SYMMY) << "Killing composite job..."; 0046 0047 if (!hasSubjobs()) { 0048 const bool canBeKilled = !m_passwordDialog.isNull() && m_passwordDialog->isVisible(); 0049 return canBeKilled; 0050 } 0051 0052 return subjobs().at(0)->kill(); 0053 } 0054 0055 void CompositeJob::slotResult(KJob *job) 0056 { 0057 if (job->error() == KJob::UserDefinedError) { 0058 qCDebug(SYMMY) << "Job failed:" << job->errorText(); 0059 if (task() == Task::Encryption) { 0060 setError(KJob::UserDefinedError); 0061 KMessageBox::error(nullptr, xi18nc("@info", "Encryption operation failed. Please check whether the <application>gpg-agent</application> process is running.")); 0062 emitResult(); 0063 return; 0064 } 0065 0066 auto decryptJob = qobject_cast<Symmy::DecryptJob*>(job); 0067 if (decryptJob) { 0068 qCDebug(SYMMY) << "Subjob failed to decrypt" << decryptJob->ciphertextFilename(); 0069 m_failedDecryptions << decryptJob->ciphertextFilename(); 0070 } 0071 } 0072 0073 removeSubjob(job); 0074 0075 if (hasSubjobs()) { 0076 qCDebug(SYMMY) << "Starting next subjob..."; 0077 startSubjob(); 0078 return; 0079 } 0080 0081 qCDebug(SYMMY) << "Composite job finished"; 0082 0083 if (!m_failedDecryptions.isEmpty()) { 0084 // Nothing was decrypted, mark the composite job as failed. 0085 if (m_failedDecryptions.size() == filenames().size()) { 0086 setError(KJob::UserDefinedError); 0087 KMessageBox::error(nullptr, xi18nc("@info", "Decryption operation failed. Please check whether the decryption key is correct.<nl/>" 0088 "You should also check whether the <application>gpg-agent</application> process is running.")); 0089 } else { 0090 KMessageBox::errorList(nullptr, xi18nc("@info", "Could not decrypt the following ciphertexts.<nl/>Please check whether the decryption key is correct."), m_failedDecryptions); 0091 } 0092 } 0093 0094 emitResult(); 0095 } 0096 0097 void CompositeJob::slotAccepted() 0098 { 0099 for (const auto &filename : qAsConst(m_filenames)) { 0100 Symmy::Job *job = nullptr; 0101 if (task() == Task::Encryption) { 0102 job = new Symmy::EncryptJob(qobject_cast<KNewPasswordDialog*>(m_passwordDialog)->password(), filename); 0103 } else { 0104 job = new Symmy::DecryptJob(qobject_cast<KPasswordDialog*>(m_passwordDialog)->password(), filename); 0105 } 0106 0107 addSubjob(job); 0108 connect(job, SIGNAL(percent(KJob*,ulong)), this, SLOT(slotPercent(KJob*,ulong))); 0109 } 0110 0111 qCDebug(SYMMY) << "Got a passphrase, starting first subjob..."; 0112 startSubjob(); 0113 } 0114 0115 void CompositeJob::slotRejected() 0116 { 0117 qCDebug(SYMMY) << "Passphrase dialog rejected."; 0118 setError(KilledJobError); 0119 emitResult(); 0120 } 0121 0122 void CompositeJob::slotStart() 0123 { 0124 if (filenames().isEmpty()) { 0125 emitResult(); 0126 return; 0127 } 0128 0129 qCDebug(SYMMY) << "Starting composite job..."; 0130 emit description(this, i18n("Asking Passphrase")); 0131 0132 if (task() == Task::Encryption) { 0133 auto passwordDialog = new KNewPasswordDialog {}; 0134 passwordDialog->setPrompt(i18n("Please supply a password or passphrase to be used as encryption key.")); 0135 passwordDialog->setAllowEmptyPasswords(false); 0136 m_passwordDialog = passwordDialog; 0137 } else { 0138 auto passwordDialog = new KPasswordDialog {}; 0139 passwordDialog->setPrompt(i18n("Please supply a password or passphrase to be used as decryption key.")); 0140 m_passwordDialog = passwordDialog; 0141 } 0142 0143 connect(m_passwordDialog, &QDialog::accepted, this, &CompositeJob::slotAccepted); 0144 connect(m_passwordDialog, &QDialog::rejected, this, &CompositeJob::slotRejected); 0145 connect(m_passwordDialog, &QDialog::finished, m_passwordDialog, &QObject::deleteLater); 0146 0147 m_passwordDialog->open(); 0148 } 0149 0150 void CompositeJob::slotPercent(KJob *, unsigned long percent) 0151 { 0152 setPercent(percent); 0153 } 0154 0155 void CompositeJob::startSubjob() 0156 { 0157 auto job = qobject_cast<Symmy::Job*>(subjobs().at(0)); 0158 0159 if (task() == Task::Encryption) { 0160 emit description(this, i18nc("description of an encryption job", "Encrypting"), 0161 qMakePair(i18nc("File used as input of the encryption algorithm", "Plaintext"), job->plaintextFilename()), 0162 qMakePair(i18nc("File created by the encryption algorithm", "Ciphertext"), job->ciphertextFilename())); 0163 } else { 0164 emit description(this, i18nc("description of a decryption job", "Decrypting"), 0165 qMakePair(i18nc("File used as input of the decryption algorithm", "Ciphertext"), job->ciphertextFilename()), 0166 qMakePair(i18nc("File created by the decryption algorithm", "Plaintext"), job->plaintextFilename())); 0167 } 0168 0169 job->start(); 0170 } 0171 0172 QStringList CompositeJob::filenames() const 0173 { 0174 return m_filenames; 0175 } 0176 0177 CompositeJob::Task CompositeJob::task() const 0178 { 0179 return m_task; 0180 } 0181 0182 }