Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20065046
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
59 KB
Subscribers
None
View Options
diff --git a/src/crypto/decryptverifyfilescontroller.cpp b/src/crypto/decryptverifyfilescontroller.cpp
index 798f20aa9..2b9a2acc9 100644
--- a/src/crypto/decryptverifyfilescontroller.cpp
+++ b/src/crypto/decryptverifyfilescontroller.cpp
@@ -1,468 +1,468 @@
/* -*- mode: c++; c-basic-offset:4 -*-
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"
#include <crypto/gui/decryptverifyoperationwidget.h>
#include <crypto/gui/decryptverifyfileswizard.h>
#include <crypto/decryptverifytask.h>
#include <crypto/taskcollection.h>
#include <utils/gnupg-helper.h>
#include <utils/path-helper.h>
#include <utils/input.h>
#include <utils/output.h>
#include <utils/kleo_assert.h>
#include <utils/archivedefinition.h>
#include <Libkleo/Classify>
#include <KLocalizedString>
#include "kleopatra_debug.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QPointer>
#include <QTimer>
#include <memory>
#include <vector>
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
class DecryptVerifyFilesController::Private
{
DecryptVerifyFilesController *const q;
public:
static std::shared_ptr<AbstractDecryptVerifyTask> taskFromOperationWidget(const DecryptVerifyOperationWidget *w, const QString &fileName, const QDir &outDir, const std::shared_ptr<OverwritePolicy> &overwritePolicy);
explicit Private(DecryptVerifyFilesController *qq);
void slotWizardOperationPrepared();
void slotWizardCanceled();
void schedule();
void prepareWizardFromPassedFiles();
std::vector<std::shared_ptr<Task> > buildTasks(const QStringList &, const std::shared_ptr<OverwritePolicy> &);
void ensureWizardCreated();
void ensureWizardVisible();
void reportError(int err, const QString &details)
{
q->setLastError(err, details);
q->emitDoneOrError();
}
void cancelAllTasks();
QStringList m_passedFiles, m_filesAfterPreparation;
QPointer<DecryptVerifyFilesWizard> m_wizard;
std::vector<std::shared_ptr<const DecryptVerifyResult> > m_results;
std::vector<std::shared_ptr<Task> > m_runnableTasks, m_completedTasks;
std::shared_ptr<Task> m_runningTask;
bool m_errorDetected;
DecryptVerifyOperation m_operation;
};
// static
std::shared_ptr<AbstractDecryptVerifyTask> DecryptVerifyFilesController::Private::taskFromOperationWidget(const DecryptVerifyOperationWidget *w, const QString &fileName, const QDir &outDir, const std::shared_ptr<OverwritePolicy> &overwritePolicy)
{
kleo_assert(w);
std::shared_ptr<AbstractDecryptVerifyTask> task;
switch (w->mode()) {
case DecryptVerifyOperationWidget::VerifyDetachedWithSignature: {
std::shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
t->setInput(Input::createFromFile(fileName));
t->setSignedData(Input::createFromFile(w->signedDataFileName()));
task = t;
kleo_assert(fileName == w->inputFileName());
}
break;
case DecryptVerifyOperationWidget::VerifyDetachedWithSignedData: {
std::shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
t->setInput(Input::createFromFile(w->inputFileName()));
t->setSignedData(Input::createFromFile(fileName));
task = t;
kleo_assert(fileName == w->signedDataFileName());
}
break;
case DecryptVerifyOperationWidget::DecryptVerifyOpaque: {
const unsigned int classification = classify(fileName);
qCDebug(KLEOPATRA_LOG) << "classified" << fileName << "as" << printableClassification(classification);
const std::shared_ptr<ArchiveDefinition> ad = w->selectedArchiveDefinition();
const Protocol proto =
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")) :
/* else we don't care */ UnknownProtocol;
const std::shared_ptr<Input> input = Input::createFromFile(fileName);
const std::shared_ptr<Output> output =
ad ? ad->createOutputFromUnpackCommand(proto, fileName, outDir) :
/*else*/ Output::createFromFile(outDir.absoluteFilePath(outputFileName(QFileInfo(fileName).fileName())), overwritePolicy);
if (mayBeCipherText(classification)) {
qCDebug(KLEOPATRA_LOG) << "creating a DecryptVerifyTask";
std::shared_ptr<DecryptVerifyTask> t(new DecryptVerifyTask);
t->setInput(input);
t->setOutput(output);
task = t;
} else {
qCDebug(KLEOPATRA_LOG) << "creating a VerifyOpaqueTask";
std::shared_ptr<VerifyOpaqueTask> t(new VerifyOpaqueTask);
t->setInput(input);
t->setOutput(output);
task = t;
}
kleo_assert(fileName == w->inputFileName());
}
break;
}
task->autodetectProtocolFromInput();
return task;
}
DecryptVerifyFilesController::Private::Private(DecryptVerifyFilesController *qq) : q(qq), m_errorDetected(false), m_operation(DecryptVerify)
{
qRegisterMetaType<VerificationResult>();
}
void DecryptVerifyFilesController::Private::slotWizardOperationPrepared()
{
ensureWizardCreated();
std::vector<std::shared_ptr<Task> > tasks = buildTasks(m_filesAfterPreparation, std::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);
std::shared_ptr<TaskCollection> coll(new TaskCollection);
for (const auto &i: m_runnableTasks) {
q->connectTask(i);
}
coll->setTasks(m_runnableTasks);
m_wizard->setTaskCollection(coll);
QTimer::singleShot(0, q, SLOT(schedule()));
}
void DecryptVerifyFilesController::Private::slotWizardCanceled()
{
qCDebug(KLEOPATRA_LOG);
}
void DecryptVerifyFilesController::doTaskDone(const Task *task, const std::shared_ptr<const Task::Result> &result)
{
Q_ASSERT(task);
Q_UNUSED(task);
// 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
d->m_completedTasks.push_back(d->m_runningTask);
d->m_runningTask.reset();
if (const std::shared_ptr<const DecryptVerifyResult> &dvr = std::dynamic_pointer_cast<const DecryptVerifyResult>(result)) {
d->m_results.push_back(dvr);
}
QTimer::singleShot(0, this, SLOT(schedule()));
}
void DecryptVerifyFilesController::Private::schedule()
{
if (!m_runningTask && !m_runnableTasks.empty()) {
const std::shared_ptr<Task> t = m_runnableTasks.back();
m_runnableTasks.pop_back();
t->start();
m_runningTask = t;
}
if (!m_runningTask) {
kleo_assert(m_runnableTasks.empty());
for (const auto &i: m_results) {
Q_EMIT q->verificationResult(i->verificationResult());
}
q->emitDoneOrError();
}
}
void DecryptVerifyFilesController::Private::ensureWizardCreated()
{
if (m_wizard) {
return;
}
std::unique_ptr<DecryptVerifyFilesWizard> w(new DecryptVerifyFilesWizard);
w->setWindowTitle(i18n("Decrypt/Verify Files"));
w->setAttribute(Qt::WA_DeleteOnClose);
connect(w.get(), SIGNAL(operationPrepared()), q, SLOT(slotWizardOperationPrepared()), Qt::QueuedConnection);
connect(w.get(), SIGNAL(canceled()), q, SLOT(slotWizardCanceled()), Qt::QueuedConnection);
m_wizard = w.release();
}
namespace
{
struct FindExtension : std::unary_function<std::shared_ptr<ArchiveDefinition>, bool> {
const QString ext;
const Protocol proto;
FindExtension(const QString &ext, Protocol proto) : ext(ext), proto(proto) {}
bool operator()(const std::shared_ptr<ArchiveDefinition> &ad) const
{
qCDebug(KLEOPATRA_LOG) << " considering" << (ad ? ad->label() : QStringLiteral("<null>")) << "for" << ext;
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);
}
qCDebug(KLEOPATRA_LOG) << (result ? " -> matches" : " -> doesn't match");
return result;
}
};
}
std::shared_ptr<ArchiveDefinition> DecryptVerifyFilesController::pick_archive_definition(GpgME::Protocol proto, const std::vector< std::shared_ptr<ArchiveDefinition> > &ads, const QString &filename)
{
const QFileInfo fi(outputFileName(filename));
QString extension = fi.completeSuffix();
if (extension == QLatin1String("out")) { // added by outputFileName() -> useless
return std::shared_ptr<ArchiveDefinition>();
}
if (extension.endsWith(QLatin1String(".out"))) { // added by outputFileName() -> remove
extension.chop(4);
}
for (;;) {
const std::vector<std::shared_ptr<ArchiveDefinition> >::const_iterator it
= std::find_if(ads.begin(), ads.end(), FindExtension(extension, proto));
if (it != ads.end()) {
return *it;
}
const int idx = extension.indexOf(QLatin1Char('.'));
if (idx < 0) {
return std::shared_ptr<ArchiveDefinition>();
}
extension = extension.mid(idx + 1);
}
}
void DecryptVerifyFilesController::Private::prepareWizardFromPassedFiles()
{
ensureWizardCreated();
const std::vector< std::shared_ptr<ArchiveDefinition> > archiveDefinitions = ArchiveDefinition::getArchiveDefinitions();
unsigned int counter = 0;
for (const auto &fname: m_passedFiles) {
kleo_assert(!fname.isEmpty());
const unsigned int classification = classify(fname);
const Protocol proto = findProtocol(classification);
if (mayBeOpaqueSignature(classification) || mayBeCipherText(classification) || mayBeDetachedSignature(classification)) {
DecryptVerifyOperationWidget *const op = m_wizard->operationWidget(counter++);
kleo_assert(op != nullptr);
op->setArchiveDefinitions(archiveDefinitions);
const QString signedDataFileName = findSignedData(fname);
// 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
if (mayBeDetachedSignature(classification) && !signedDataFileName.isEmpty()) {
op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignature);
}
// ### end FIXME
else if (mayBeOpaqueSignature(classification) || mayBeCipherText(classification)) {
op->setMode(DecryptVerifyOperationWidget::DecryptVerifyOpaque, q->pick_archive_definition(proto, archiveDefinitions, fname));
} else {
op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignature);
}
op->setInputFileName(fname);
op->setSignedDataFileName(signedDataFileName);
m_filesAfterPreparation << fname;
} else {
// probably the signed data file was selected:
const QStringList signatures = findSignatures(fname);
if (signatures.empty()) {
// 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()
DecryptVerifyOperationWidget *const op = m_wizard->operationWidget(counter++);
kleo_assert(op != nullptr);
op->setArchiveDefinitions(archiveDefinitions);
op->setMode(DecryptVerifyOperationWidget::DecryptVerifyOpaque, q->pick_archive_definition(proto, archiveDefinitions, fname));
op->setInputFileName(fname);
m_filesAfterPreparation << fname;
} else {
for (const auto &s: signatures) {
DecryptVerifyOperationWidget *op = m_wizard->operationWidget(counter++);
kleo_assert(op != nullptr);
op->setArchiveDefinitions(archiveDefinitions);
op->setMode(DecryptVerifyOperationWidget::VerifyDetachedWithSignedData);
op->setInputFileName(s);
op->setSignedDataFileName(fname);
m_filesAfterPreparation << fname;
}
}
}
}
m_wizard->setOutputDirectory(heuristicBaseDirectory(m_passedFiles));
return;
}
std::vector< std::shared_ptr<Task> > DecryptVerifyFilesController::Private::buildTasks(const QStringList &fileNames, const std::shared_ptr<OverwritePolicy> &overwritePolicy)
{
const bool useOutDir = m_wizard->useOutputDirectory();
const QFileInfo outDirInfo(m_wizard->outputDirectory());
kleo_assert(!useOutDir || outDirInfo.isDir());
const QDir outDir(outDirInfo.absoluteFilePath());
kleo_assert(!useOutDir || outDir.exists());
std::vector<std::shared_ptr<Task> > tasks;
- for (unsigned int i = 0, end = fileNames.size(); i != end; ++i)
+ for (int i = 0, end = fileNames.size(); i != end; ++i)
try {
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));
+ tasks.push_back(taskFromOperationWidget(m_wizard->operationWidget(static_cast<unsigned int>(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]));
}
return tasks;
}
void DecryptVerifyFilesController::setFiles(const QStringList &files)
{
d->m_passedFiles = files;
}
void DecryptVerifyFilesController::Private::ensureWizardVisible()
{
ensureWizardCreated();
q->bringToForeground(m_wizard);
}
DecryptVerifyFilesController::DecryptVerifyFilesController(QObject *parent) : Controller(parent), d(new Private(this))
{
}
DecryptVerifyFilesController::DecryptVerifyFilesController(const std::shared_ptr<const ExecutionContext> &ctx, QObject *parent) : Controller(ctx, parent), d(new Private(this))
{
}
DecryptVerifyFilesController::~DecryptVerifyFilesController()
{
qCDebug(KLEOPATRA_LOG);
}
void DecryptVerifyFilesController::start()
{
d->prepareWizardFromPassedFiles();
d->ensureWizardVisible();
}
void DecryptVerifyFilesController::setOperation(DecryptVerifyOperation op)
{
d->m_operation = op;
}
DecryptVerifyOperation DecryptVerifyFilesController::operation() const
{
return d->m_operation;
}
void DecryptVerifyFilesController::Private::cancelAllTasks()
{
// we just kill all runnable tasks - this will not result in
// signal emissions.
m_runnableTasks.clear();
// a cancel() will result in a call to
if (m_runningTask) {
m_runningTask->cancel();
}
}
void DecryptVerifyFilesController::cancel()
{
qCDebug(KLEOPATRA_LOG);
try {
d->m_errorDetected = true;
if (d->m_wizard) {
d->m_wizard->close();
}
d->cancelAllTasks();
} catch (const std::exception &e) {
qCDebug(KLEOPATRA_LOG) << "Caught exception: " << e.what();
}
}
#include "moc_decryptverifyfilescontroller.cpp"
diff --git a/src/dialogs/certifycertificatedialog.cpp b/src/dialogs/certifycertificatedialog.cpp
index 11633b3d4..1c117d491 100644
--- a/src/dialogs/certifycertificatedialog.cpp
+++ b/src/dialogs/certifycertificatedialog.cpp
@@ -1,512 +1,512 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/signcertificatedialog.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 "certifycertificatedialog.h"
#include "certifycertificatedialog_p.h"
#include <utils/kleo_assert.h>
#include <Libkleo/Formatting>
#include <Libkleo/Stl_Util>
#include <KLocalizedString>
#include <QGridLayout>
#include <QStandardItem>
#include <QListView>
#include <QVBoxLayout>
#include <QWizardPage>
#include <QCheckBox>
#include <QLabel>
#include <QTextDocument> // Qt::escape
#include <gpg-error.h>
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace Kleo::Dialogs::CertifyCertificateDialogPrivate;
void UserIDModel::setCertificateToCertify(const Key &key)
{
m_key = key;
clear();
const std::vector<UserID> ids = key.userIDs();
for (unsigned int i = 0; i < ids.size(); ++i) {
QStandardItem *const item = new QStandardItem;
item->setText(Formatting::prettyUserID(key.userID(i)));
item->setData(i, UserIDIndex);
item->setCheckable(true);
item->setEditable(false);
appendRow(item);
}
}
void UserIDModel::setCheckedUserIDs(const std::vector<unsigned int> &uids)
{
std::vector<unsigned int> sorted = uids;
std::sort(sorted.begin(), sorted.end());
- for (unsigned int i = 0, end = rowCount(); i != end; ++i) {
+ for (int i = 0, end = rowCount(); i != end; ++i) {
item(i)->setCheckState(std::binary_search(sorted.begin(), sorted.end(), i) ? Qt::Checked : Qt::Unchecked);
}
}
std::vector<unsigned int> UserIDModel::checkedUserIDs() const
{
std::vector<unsigned int> ids;
for (int i = 0; i < rowCount(); ++i)
if (item(i)->checkState() == Qt::Checked) {
ids.push_back(item(i)->data(UserIDIndex).toUInt());
}
return ids;
}
void SecretKeysModel::setSecretKeys(const std::vector<Key> &keys)
{
clear();
m_secretKeys = keys;
for (unsigned int i = 0; i < m_secretKeys.size(); ++i) {
const Key key = m_secretKeys[i];
QStandardItem *const item = new QStandardItem;
item->setText(Formatting::formatForComboBox(key));
item->setData(i, IndexRole);
item->setEditable(false);
appendRow(item);
}
}
std::vector<GpgME::Key> SecretKeysModel::secretKeys() const
{
return m_secretKeys;
}
Key SecretKeysModel::keyFromItem(const QStandardItem *item) const
{
Q_ASSERT(item);
const unsigned int idx = item->data(IndexRole).toUInt();
Q_ASSERT(idx < m_secretKeys.size());
return m_secretKeys[idx];
}
Key SecretKeysModel::keyFromIndex(const QModelIndex &idx) const
{
return keyFromItem(itemFromIndex(idx));
}
SelectUserIDsPage::SelectUserIDsPage(QWidget *parent) : QWizardPage(parent), m_userIDModel()
{
QVBoxLayout *const layout = new QVBoxLayout(this);
QLabel *const label = new QLabel;
label->setText(i18n("<b>Step 1:</b> Please select the user IDs you wish to certify."));
layout->addWidget(label);
m_listView = new QListView;
m_listView->setModel(&m_userIDModel);
layout->addWidget(m_listView, 1);
m_label = new QLabel;
layout->addWidget(m_label);
m_checkbox = new QCheckBox;
m_checkbox->setChecked(false);
m_checkbox->setText(i18n("I have verified the fingerprint"));
layout->addWidget(m_checkbox);
connect(m_checkbox, &QCheckBox::toggled, this, &SelectUserIDsPage::completeChanged);
connect(&m_userIDModel, &QStandardItemModel::itemChanged, this, &QWizardPage::completeChanged);
}
bool SelectUserIDsPage::isComplete() const
{
return m_checkbox->isChecked() && !selectedUserIDs().empty();
}
void SelectUserIDsPage::setSelectedUserIDs(const std::vector<unsigned int> &uids)
{
m_userIDModel.setCheckedUserIDs(uids);
}
std::vector<unsigned int> SelectUserIDsPage::selectedUserIDs() const
{
return m_userIDModel.checkedUserIDs();
}
void SelectUserIDsPage::setCertificateToCertify(const Key &key)
{
m_label->setText(i18n("Certificate: %1\nFingerprint: %2",
Formatting::formatForComboBox(key),
QLatin1String(key.primaryFingerprint())));
m_userIDModel.setCertificateToCertify(key);
}
SelectCheckLevelPage::SelectCheckLevelPage(QWidget *parent) : QWizardPage(parent), m_ui()
{
m_ui.setupUi(this);
}
unsigned int SelectCheckLevelPage::checkLevel() const
{
if (m_ui.checkLevelNotCheckedRB->isChecked()) {
return 1;
}
if (m_ui.checkLevelCasualRB->isChecked()) {
return 2;
}
if (m_ui.checkLevelThoroughlyRB->isChecked()) {
return 3;
}
Q_ASSERT(!"No check level radiobutton checked");
return 0;
}
OptionsPage::OptionsPage(QWidget *parent) : QWizardPage(parent), m_ui()
{
m_ui.setupUi(this);
m_ui.keyListView->setModel(&m_model);
connect(m_ui.keyListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QWizardPage::completeChanged);
setCommitPage(true);
setButtonText(QWizard::CommitButton, i18n("Certify"));
}
bool OptionsPage::exportableCertificationSelected() const
{
return m_ui.exportableSignatureRB->isChecked();
}
void OptionsPage::setCertificatesWithSecretKeys(const std::vector<Key> &keys)
{
Q_ASSERT(!keys.empty());
m_model.setSecretKeys(keys);
if (keys.size() == 1) {
m_ui.stackedWidget->setCurrentWidget(m_ui.singleKeyPage);
m_ui.singleKeyLabel->setText(i18n("Certification will be performed using certificate %1.", Formatting::prettyNameAndEMail(keys[0])));
} else {
m_ui.stackedWidget->setCurrentWidget(m_ui.multipleKeysPage);
}
Q_EMIT completeChanged();
}
Key OptionsPage::selectedSecretKey() const
{
if (m_model.secretKeys().size() == 1) {
return m_model.secretKeys().at(0);
}
const QModelIndexList idxs = m_ui.keyListView->selectionModel()->selectedIndexes();
Q_ASSERT(idxs.size() <= 1);
return idxs.isEmpty() ? Key() : m_model.keyFromIndex(idxs[0]);
}
bool OptionsPage::sendToServer() const
{
return m_ui.sendToServerCB->isChecked();
}
bool OptionsPage::validatePage()
{
Q_EMIT nextClicked();
return true;
}
bool OptionsPage::isComplete() const
{
return !selectedSecretKey().isNull();
}
SummaryPage::SummaryPage(QWidget *parent) : QWizardPage(parent), m_complete(false)
{
QGridLayout *const layout = new QGridLayout(this);
QLabel *const uidLabelLabel = new QLabel(i18n("Signed user IDs:"));
uidLabelLabel->setAlignment(Qt::AlignTop);
int row = 0;
layout->addWidget(new QLabel(i18n("<b>Summary:</b>")), row, 0, 1, 2);
layout->addWidget(uidLabelLabel, ++row, 0);
layout->addWidget(m_userIDsLabel = new QLabel, row, 1);
#ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
layout->addWidget(new QLabel(i18n("Check level:")), ++row, 0);
layout->addWidget(m_checkLevelLabel = new QLabel, row, 1);
#else
m_checkLevelLabel = nullptr;
#endif
layout->addWidget(new QLabel(i18n("Selected secret key:")), ++row, 0);
layout->addWidget(m_secretKeyLabel = new QLabel, row, 1);
m_secretKeyLabel->setTextFormat(Qt::PlainText);
layout->addWidget(m_resultLabel = new QLabel, ++row, 0, 1, 2, Qt::AlignCenter);
m_resultLabel->setWordWrap(true);
layout->setRowStretch(row, 1);
m_resultLabel->setAlignment(Qt::AlignCenter);
}
bool SummaryPage::isComplete() const
{
return m_complete;
}
void SummaryPage::setSummary(const SummaryPage::Summary &sum)
{
const Key key = sum.certificateToCertify;
QStringList ids;
Q_FOREACH (const unsigned int i, sum.selectedUserIDs) {
ids += Formatting::prettyUserID(key.userID(i)).toHtmlEscaped();
}
m_userIDsLabel->setText(QLatin1String("<qt>") + ids.join(QStringLiteral("<br/>")) + QLatin1String("</qt>"));
m_secretKeyLabel->setText(sum.secretKey.isNull() ? i18n("Default certificate") : Formatting::prettyNameAndEMail(sum.secretKey));
#ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
switch (sum.checkLevel) {
case 0:
m_checkLevelLabel->setText(i18n("No statement made"));
break;
case 1:
m_checkLevelLabel->setText(i18n("Not checked"));
break;
case 2:
m_checkLevelLabel->setText(i18n("Casually checked"));
break;
case 3:
m_checkLevelLabel->setText(i18n("Thoroughly checked"));
break;
}
#endif
}
void SummaryPage::setComplete(bool complete)
{
if (complete == m_complete) {
return;
}
m_complete = complete;
Q_EMIT completeChanged();
}
void SummaryPage::setResult(const Error &err)
{
if (err && !err.isCanceled())
if (err.code() == GPG_ERR_USER_1) {
m_resultLabel->setText(i18n("The certificate was not certified because it was already certified by the same certificate."));
} else {
m_resultLabel->setText(i18n("The certificate could not be certified. <b>Error</b>: %1", QString::fromLocal8Bit(err.asString()).toHtmlEscaped()));
}
else if (err.isCanceled()) {
m_resultLabel->setText(i18n("Certification canceled."));
} else {
m_resultLabel->setText(i18n("Certification successful."));
}
}
class CertifyCertificateDialog::Private
{
friend class ::Kleo::Dialogs::CertifyCertificateDialog;
CertifyCertificateDialog *const q;
public:
explicit Private(CertifyCertificateDialog *qq)
: q(qq),
summaryPageId(0),
selectUserIDsPage(nullptr),
selectCheckLevelPage(nullptr),
optionsPage(nullptr),
summaryPage(nullptr)
{
selectUserIDsPage = new SelectUserIDsPage(q);
q->addPage(selectUserIDsPage);
//selectCheckLevelPage = new SelectCheckLevelPage( q );
//setting the cert level explicitly is not supported by the backend,
//thus we omit the page from the UI
//q->addPage( selectCheckLevelPage );
optionsPage = new OptionsPage(q);
q->addPage(optionsPage);
summaryPage = new SummaryPage(q);
summaryPageId = q->addPage(summaryPage);
connect(optionsPage, &OptionsPage::nextClicked, q, &CertifyCertificateDialog::certificationPrepared);
}
Key key() const
{
return selectUserIDsPage ? selectUserIDsPage->certificateToCertify() : Key();
}
void ensureSummaryPageVisible();
void certificationResult(const Error &error);
void setOperationCompleted()
{
summaryPage->setComplete(true);
}
SummaryPage::Summary createSummary() const
{
SummaryPage::Summary sum;
sum.selectedUserIDs = selectUserIDsPage->selectedUserIDs();
sum.secretKey = optionsPage->selectedSecretKey();
sum.certificateToCertify = selectUserIDsPage->certificateToCertify();
//PENDING
#ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
sum.checkLevel = selectCheckLevelPage->checkLevel();
#else
sum.checkLevel = 0;
#endif
sum.exportable = optionsPage->exportableCertificationSelected();
sum.sendToServer = optionsPage->sendToServer();
return sum;
}
int summaryPageId;
SelectUserIDsPage *selectUserIDsPage;
SelectCheckLevelPage *selectCheckLevelPage;
OptionsPage *optionsPage;
SummaryPage *summaryPage;
};
CertifyCertificateDialog::CertifyCertificateDialog(QWidget *p, Qt::WindowFlags f)
: QWizard(p, f), d(new Private(this))
{
}
CertifyCertificateDialog::~CertifyCertificateDialog() {}
void CertifyCertificateDialog::setCertificateToCertify(const Key &key)
{
setWindowTitle(i18nc("arg is name, email of certificate holder", "Certify Certificate: %1", Formatting::prettyName(key)));
d->selectUserIDsPage->setCertificateToCertify(key);
}
void CertifyCertificateDialog::setCertificatesWithSecretKeys(const std::vector<Key> &keys)
{
d->optionsPage->setCertificatesWithSecretKeys(keys);
}
bool CertifyCertificateDialog::exportableCertificationSelected() const
{
return d->optionsPage->exportableCertificationSelected();
}
bool CertifyCertificateDialog::trustCertificationSelected() const
{
return false;
}
bool CertifyCertificateDialog::nonRevocableCertificationSelected() const
{
return false;
}
Key CertifyCertificateDialog::selectedSecretKey() const
{
return d->optionsPage->selectedSecretKey();
}
bool CertifyCertificateDialog::sendToServer() const
{
return d->optionsPage->sendToServer();
}
unsigned int CertifyCertificateDialog::selectedCheckLevel() const
{
//PENDING
#ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
return d->selectCheckLevelPage->checkLevel();
#endif
return 0;
}
void CertifyCertificateDialog::connectJob(QGpgME::SignKeyJob *job)
{
connect(job, SIGNAL(result(GpgME::Error)), this, SLOT(certificationResult(GpgME::Error)));
d->summaryPage->setSummary(d->createSummary());
}
void CertifyCertificateDialog::setError(const Error &error)
{
d->setOperationCompleted();
d->summaryPage->setResult(error);
d->ensureSummaryPageVisible();
if (error.isCanceled()) {
close();
}
}
void CertifyCertificateDialog::Private::certificationResult(const Error &err)
{
setOperationCompleted();
summaryPage->setResult(err);
ensureSummaryPageVisible();
}
namespace
{
static bool uidEqual(const UserID &lhs, const UserID &rhs)
{
return qstrcmp(lhs.parent().primaryFingerprint(),
rhs.parent().primaryFingerprint()) == 0
&& qstrcmp(lhs.id(), rhs.id()) == 0;
}
}
void CertifyCertificateDialog::setSelectedUserIDs(const std::vector<UserID> &uids)
{
const Key key = d->key();
const char *const fpr = key.primaryFingerprint();
const std::vector<UserID> all = key.userIDs();
std::vector<unsigned int> indexes;
indexes.reserve(uids.size());
Q_FOREACH (const UserID &uid, uids) {
kleo_assert(qstrcmp(uid.parent().primaryFingerprint(), fpr) == 0);
const unsigned int idx =
std::distance(all.cbegin(), std::find_if(all.cbegin(), all.cend(),
[uid](const UserID &other) { return uidEqual(uid, other); }));
if (idx < all.size()) {
indexes.push_back(idx);
}
}
d->selectUserIDsPage->setSelectedUserIDs(indexes);
}
std::vector<unsigned int> CertifyCertificateDialog::selectedUserIDs() const
{
return d->selectUserIDsPage->selectedUserIDs();
}
void CertifyCertificateDialog::Private::ensureSummaryPageVisible()
{
while (q->currentId() != summaryPageId) {
q->next();
}
}
#include "moc_certifycertificatedialog.cpp"
#include "moc_certifycertificatedialog_p.cpp"
diff --git a/src/dialogs/expirydialog.cpp b/src/dialogs/expirydialog.cpp
index 655b4f769..421dd6227 100644
--- a/src/dialogs/expirydialog.cpp
+++ b/src/dialogs/expirydialog.cpp
@@ -1,219 +1,219 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/expirydialog.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 "expirydialog.h"
#include "ui_expirydialog.h"
#include <QDate>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Dialogs;
enum Period {
Days,
Weeks,
Months,
Years,
NumPeriods
};
static QDate date_by_amount_and_unit(int inAmount, int inUnit)
{
const QDate current = QDate::currentDate();
switch (inUnit) {
- case Days: return current.addDays(inAmount); break;
- case Weeks: return current.addDays(7 * inAmount); break;
- case Months: return current.addMonths(inAmount); break;
- case Years: return current.addYears(inAmount); break;
+ case Days: return current.addDays(inAmount);
+ case Weeks: return current.addDays(7 * inAmount);
+ case Months: return current.addMonths(inAmount);
+ case Years: return current.addYears(inAmount);
default:
Q_ASSERT(!"Should not reach here");
}
return QDate();
}
// these calculations should be precise enough for the forseeable future...
static const double DAYS_IN_GREGORIAN_YEAR = 365.2425;
static int monthsBetween(const QDate &d1, const QDate &d2)
{
const int days = d1.daysTo(d2);
return qRound(days / DAYS_IN_GREGORIAN_YEAR * 12);
}
static int yearsBetween(const QDate &d1, const QDate &d2)
{
const int days = d1.daysTo(d2);
return qRound(days / DAYS_IN_GREGORIAN_YEAR);
}
class ExpiryDialog::Private
{
friend class ::Kleo::Dialogs::ExpiryDialog;
ExpiryDialog *const q;
public:
explicit Private(ExpiryDialog *qq)
: q(qq),
inUnit(Days),
ui(q)
{
connect(ui.inSB, SIGNAL(valueChanged(int)),
q, SLOT(slotInAmountChanged()));
connect(ui.inCB, SIGNAL(currentIndexChanged(int)),
q, SLOT(slotInUnitChanged()));
connect(ui.onCW, SIGNAL(selectionChanged()),
q, SLOT(slotOnDateChanged()));
Q_ASSERT(ui.inCB->currentIndex() == inUnit);
}
private:
void slotInAmountChanged();
void slotInUnitChanged();
void slotOnDateChanged();
private:
QDate inDate() const;
int inAmountByDate(const QDate &date) const;
private:
int inUnit;
struct UI : public Ui::ExpiryDialog {
explicit UI(Dialogs::ExpiryDialog *qq)
: Ui::ExpiryDialog()
{
QWidget *mainWidget = new QWidget(qq);
setupUi(mainWidget);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, qq);
QVBoxLayout *mainLayout = new QVBoxLayout;
qq->setLayout(mainLayout);
mainLayout->addWidget(mainWidget);
QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
okButton->setDefault(true);
okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
qq->connect(buttonBox, &QDialogButtonBox::accepted, qq, &QDialog::accept);
qq->connect(buttonBox, &QDialogButtonBox::rejected, qq, &QDialog::reject);
mainLayout->addWidget(buttonBox);
Q_ASSERT(inCB->count() == NumPeriods);
onCW->setMinimumDate(QDate::currentDate().addDays(1));
}
} ui;
};
ExpiryDialog::ExpiryDialog(QWidget *p)
: QDialog(p), d(new Private(this))
{
setWindowTitle(i18n("Change Expiry"));
}
ExpiryDialog::~ExpiryDialog() {}
void ExpiryDialog::setDateOfExpiry(const QDate &date)
{
const QDate current = QDate::currentDate();
if (date.isValid()) {
d->ui.onRB->setChecked(true);
d->ui.onCW->setSelectedDate(qMax(date, current));
} else {
d->ui.neverRB->setChecked(true);
d->ui.onCW->setSelectedDate(current);
d->ui.inSB->setValue(0);
}
}
QDate ExpiryDialog::dateOfExpiry() const
{
return
d->ui.inRB->isChecked() ? d->inDate() :
d->ui.onRB->isChecked() ? d->ui.onCW->selectedDate() :
QDate();
}
void ExpiryDialog::Private::slotInUnitChanged()
{
const int oldInAmount = ui.inSB->value();
const QDate targetDate = date_by_amount_and_unit(oldInAmount, inUnit);
inUnit = ui.inCB->currentIndex();
if (targetDate.isValid()) {
ui.inSB->setValue(inAmountByDate(targetDate));
} else {
slotInAmountChanged();
}
}
void ExpiryDialog::Private::slotInAmountChanged()
{
// Only modify onCW when onCW is slave:
if (ui.inRB->isChecked()) {
ui.onCW->setSelectedDate(inDate());
}
}
void ExpiryDialog::Private::slotOnDateChanged()
{
// Only modify inSB/inCB when onCW is master:
if (ui.onRB->isChecked()) {
ui.inSB->setValue(inAmountByDate(ui.onCW->selectedDate()));
}
}
QDate ExpiryDialog::Private::inDate() const
{
return date_by_amount_and_unit(ui.inSB->value(), ui.inCB->currentIndex());
}
int ExpiryDialog::Private::inAmountByDate(const QDate &selected) const
{
const QDate current = QDate::currentDate();
switch (ui.inCB->currentIndex()) {
case Days: return current.daysTo(selected);
case Weeks: return qRound(current.daysTo(selected) / 7.0);
case Months: return monthsBetween(current, selected);
case Years: return yearsBetween(current, selected);
};
Q_ASSERT(!"Should not reach here");
return -1;
}
#include "moc_expirydialog.cpp"
diff --git a/src/dialogs/exportsecretkeydialog.cpp b/src/dialogs/exportsecretkeydialog.cpp
index 55a80a441..9bb8f5d3f 100644
--- a/src/dialogs/exportsecretkeydialog.cpp
+++ b/src/dialogs/exportsecretkeydialog.cpp
@@ -1,239 +1,239 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/exportsecretkeydialog.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 "exportsecretkeydialog.h"
#include "ui_exportsecretkeydialog.h"
#include <Libkleo/Formatting>
#include <gpgme++/key.h>
#include <KMessageBox>
#include <KLocalizedString>
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace GpgME;
// This comes from gnupg's sources, agent/minip12.c
// In fact, any charset supported by iconv would work, but we don't link to iconv directly...
static const char *charsets[] = {
"utf8",
"iso-8859-1",
"iso-8859-15",
"iso-8859-2",
"iso-8859-3",
"iso-8859-4",
"iso-8859-5",
"iso-8859-6",
"iso-8859-7",
"iso-8859-8",
"iso-8859-9",
"koi8-r",
"ibm437",
"ibm850",
"euc-jp",
"big5",
};
static const unsigned int numCharsets = sizeof charsets / sizeof * charsets;
class ExportSecretKeyDialog::Private
{
friend class ::Kleo::Dialogs::ExportSecretKeyDialog;
ExportSecretKeyDialog *const q;
public:
explicit Private(ExportSecretKeyDialog *qq)
: q(qq),
ui(q)
{
}
private:
void updateWidgets()
{
const bool x509 = key.protocol() == CMS;
ui.charsetCB->setVisible(x509);
ui.charsetLB->setVisible(x509);
}
void updateFileName()
{
const bool x509 = key.protocol() == CMS;
const bool armor = q->useArmor();
static const char *extensions[] = {
".gpg", ".asc", ".p12", ".pem"
};
const unsigned int idx = 2 * x509 + armor;
const char *const extension = extensions[idx];
const QString nf = i18n("Secret Key Files") + QStringLiteral("(*%1 *%2 *%3 *%4 *.pgp)")
.arg(QLatin1String(extensions[idx]), QLatin1String(extensions[(idx + 1) % 4]), QLatin1String(extensions[(idx + 2) % 4]), QLatin1String(extensions[(idx + 3) % 4]));
ui.outputFileFR->setNameFilter(nf);
QString fn = q->fileName();
if (fn.isEmpty()) {
return;
}
bool found = false;
for (unsigned int i = 0; i < sizeof extensions / sizeof * extensions; ++i)
if (fn.endsWith(QLatin1String(extensions[i]), Qt::CaseInsensitive)) {
fn.chop(4);
found = true;
break;
}
if (found) {
q->setFileName(fn + QLatin1String(extension));
}
}
void updateLabel()
{
ui.descriptionLB->setText(i18nc("@info",
"Please select export options for %1:",
Formatting::formatForComboBox(key)));
}
private:
Key key;
struct UI : public Ui_ExportSecretKeyDialog {
explicit UI(Dialogs::ExportSecretKeyDialog *qq)
: Ui_ExportSecretKeyDialog()
{
setupUi(qq);
outputFileFR->setExistingOnly(false);
outputFileFR->setFilter(QDir::Files);
outputFileFR->setNameFilter(i18n("Secret Key Files (*.pem *.p12 *.gpg *.asc *.pgp)"));
for (unsigned int i = 0; i < numCharsets; ++i) {
charsetCB->addItem(QString::fromLatin1(charsets[i]));
}
charsetCB->setCurrentIndex(0);
}
} ui;
};
ExportSecretKeyDialog::ExportSecretKeyDialog(QWidget *p)
: QDialog(p), d(new Private(this))
{
}
ExportSecretKeyDialog::~ExportSecretKeyDialog() {}
void ExportSecretKeyDialog::setKey(const Key &key)
{
if (qstricmp(key.primaryFingerprint(), d->key.primaryFingerprint()) == 0) {
return;
}
d->key = key;
d->updateWidgets();
d->updateLabel();
d->updateFileName();
}
Key ExportSecretKeyDialog::key() const
{
return d->key;
}
void ExportSecretKeyDialog::setFileName(const QString &fileName)
{
d->ui.outputFileFR->setFileName(fileName);
}
QString ExportSecretKeyDialog::fileName() const
{
return d->ui.outputFileFR->fileName();
}
void ExportSecretKeyDialog::setCharset(const QByteArray &charset)
{
for (unsigned int i = 0; i < sizeof charsets / sizeof * charsets; ++i)
if (charset == charsets[i]) {
- d->ui.charsetCB->setCurrentIndex(i);
+ d->ui.charsetCB->setCurrentIndex(static_cast<int>(i));
return;
}
}
QByteArray ExportSecretKeyDialog::charset() const
{
if (d->ui.charsetCB->isVisible()) {
return d->ui.charsetCB->currentText().toLatin1();
} else {
return QByteArray();
}
}
void ExportSecretKeyDialog::setUseArmor(bool on)
{
d->ui.armorCB->setChecked(on);
}
bool ExportSecretKeyDialog::useArmor() const
{
return d->ui.armorCB->isChecked();
}
void ExportSecretKeyDialog::accept()
{
d->updateFileName();
const QString fn = fileName();
if (fn.isEmpty()) {
KMessageBox::information(this, i18nc("@info",
"You have to enter an output filename."),
i18nc("@title", "Incomplete data"));
d->ui.outputFileFR->setFocus();
return;
}
const QByteArray cs = charset();
if (d->key.protocol() == CMS && cs.isEmpty()) {
KMessageBox::information(this, i18nc("@info",
"You have to choose a passphrase character set."),
i18nc("@title", "Incomplete data"));
d->ui.charsetCB->setFocus();
return;
}
QDialog::accept();
}
#include "moc_exportsecretkeydialog.cpp"
diff --git a/src/dialogs/lookupcertificatesdialog.cpp b/src/dialogs/lookupcertificatesdialog.cpp
index 3d4151a75..6989452b6 100644
--- a/src/dialogs/lookupcertificatesdialog.cpp
+++ b/src/dialogs/lookupcertificatesdialog.cpp
@@ -1,269 +1,269 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/lookupcertificatesdialog.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 "lookupcertificatesdialog.h"
#include "ui_lookupcertificatesdialog.h"
#include <utils/headerview.h>
#include <Libkleo/KeyListModel>
#include <Libkleo/KeyListSortFilterProxyModel>
#include <Libkleo/Stl_Util>
#include <KConfigGroup>
#include <gpgme++/key.h>
#include <KLocalizedString>
#include <QPushButton>
#include <QHeaderView>
#include <KSharedConfig>
using namespace Kleo;
using namespace Kleo::Dialogs;
using namespace GpgME;
static const int minimalSearchTextLength = 2; // ### TODO: make that KIOSK-able
class LookupCertificatesDialog::Private
{
friend class ::Kleo::Dialogs::LookupCertificatesDialog;
LookupCertificatesDialog *const q;
public:
explicit Private(LookupCertificatesDialog *qq);
~Private();
private:
void slotSelectionChanged()
{
enableDisableWidgets();
}
void slotSearchTextChanged()
{
enableDisableWidgets();
}
void slotSearchClicked()
{
Q_EMIT q->searchTextChanged(ui.findED->text());
}
void slotDetailsClicked()
{
Q_ASSERT(q->selectedCertificates().size() == 1);
Q_EMIT q->detailsRequested(q->selectedCertificates().front());
}
void slotSaveAsClicked()
{
Q_EMIT q->saveAsRequested(q->selectedCertificates());
}
void readConfig();
void writeConfig();
void enableDisableWidgets();
QString searchText() const
{
return ui.findED->text().trimmed();
}
QModelIndexList selectedIndexes() const
{
if (const QItemSelectionModel *const sm = ui.resultTV->selectionModel()) {
return sm->selectedRows();
} else {
return QModelIndexList();
}
}
- unsigned int numSelectedCertificates() const
+ int numSelectedCertificates() const
{
return selectedIndexes().size();
}
private:
AbstractKeyListModel *model;
KeyListSortFilterProxyModel proxy;
bool passive;
struct Ui : Ui_LookupCertificatesDialog {
explicit Ui(LookupCertificatesDialog *q)
: Ui_LookupCertificatesDialog()
{
setupUi(q);
saveAsPB->hide(); // ### not yet implemented in LookupCertificatesCommand
findED->setClearButtonEnabled(true);
importPB()->setText(i18n("Import"));
importPB()->setEnabled(false);
HeaderView *hv = new HeaderView(Qt::Horizontal);
KDAB_SET_OBJECT_NAME(hv);
resultTV->setHeader(hv);
connect(resultTV, SIGNAL(doubleClicked(QModelIndex)),
importPB(), SLOT(animateClick()));
findED->setFocus();
}
QPushButton *importPB() const
{
return buttonBox->button(QDialogButtonBox::Save);
}
QPushButton *closePB() const
{
return buttonBox->button(QDialogButtonBox::Close);
}
} ui;
};
LookupCertificatesDialog::Private::Private(LookupCertificatesDialog *qq)
: q(qq),
model(AbstractKeyListModel::createFlatKeyListModel()),
proxy(),
passive(false),
ui(q)
{
KDAB_SET_OBJECT_NAME(model);
KDAB_SET_OBJECT_NAME(proxy);
proxy.setSourceModel(model);
ui.resultTV->setModel(&proxy);
connect(ui.resultTV->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(slotSelectionChanged()));
}
LookupCertificatesDialog::Private::~Private() {}
void LookupCertificatesDialog::Private::readConfig()
{
KConfigGroup dialog(KSharedConfig::openConfig(), "LookupCertificatesDialog");
const QSize size = dialog.readEntry("Size", QSize(600, 400));
if (size.isValid()) {
q->resize(size);
}
const QByteArray headerState = dialog.readEntry("header", QByteArray());
if (!headerState.isEmpty()) {
ui.resultTV->header()->restoreState(headerState);
}
}
void LookupCertificatesDialog::Private::writeConfig()
{
KConfigGroup dialog(KSharedConfig::openConfig(), "LookupCertificatesDialog");
dialog.writeEntry("header", ui.resultTV->header()->saveState());
dialog.writeEntry("Size", q->size());
dialog.sync();
}
LookupCertificatesDialog::LookupCertificatesDialog(QWidget *p, Qt::WindowFlags f)
: QDialog(p, f), d(new Private(this))
{
d->ui.findPB->setEnabled(false);
d->readConfig();
}
LookupCertificatesDialog::~LookupCertificatesDialog()
{
d->writeConfig();
}
void LookupCertificatesDialog::setCertificates(const std::vector<Key> &certs)
{
d->model->setKeys(certs);
d->ui.resultTV->header()->resizeSections(QHeaderView::ResizeToContents);
d->ui.resultTV->setFocus();
}
std::vector<Key> LookupCertificatesDialog::selectedCertificates() const
{
return d->proxy.keys(d->selectedIndexes());
}
void LookupCertificatesDialog::setPassive(bool on)
{
if (d->passive == on) {
return;
}
d->passive = on;
d->enableDisableWidgets();
}
bool LookupCertificatesDialog::isPassive() const
{
return d->passive;
}
void LookupCertificatesDialog::setSearchText(const QString &text)
{
d->ui.findED->setText(text);
}
QString LookupCertificatesDialog::searchText() const
{
return d->ui.findED->text();
}
void LookupCertificatesDialog::accept()
{
Q_ASSERT(!d->selectedIndexes().empty());
Q_EMIT importRequested(selectedCertificates());
QDialog::accept();
}
void LookupCertificatesDialog::Private::enableDisableWidgets()
{
// enable/disable everything except 'close', based on passive:
Q_FOREACH (QObject *const o, q->children())
if (QWidget *const w = qobject_cast<QWidget *>(o)) {
w->setDisabled(passive && w != ui.closePB() && w != ui.buttonBox);
}
if (passive) {
return;
}
ui.findPB->setEnabled(searchText().length() > minimalSearchTextLength);
- const unsigned int n = numSelectedCertificates();
+ const int n = numSelectedCertificates();
ui.detailsPB->setEnabled(n == 1);
ui.saveAsPB->setEnabled(n == 1);
ui.importPB()->setEnabled(n != 0);
ui.importPB()->setDefault(false); // otherwise Import becomes default button if enabled and return triggers both a search and accept()
}
#include "moc_lookupcertificatesdialog.cpp"
diff --git a/src/utils/auditlog.cpp b/src/utils/auditlog.cpp
index 6d636cd6a..33f382330 100644
--- a/src/utils/auditlog.cpp
+++ b/src/utils/auditlog.cpp
@@ -1,80 +1,80 @@
/* -*- mode: c++; c-basic-offset:4 -*-
utils/auditlog.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 "auditlog.h"
#include <QGpgME/Job>
#include <QUrl>
#include <QUrlQuery>
#include "kleopatra_debug.h"
#include <KLocalizedString>
using namespace Kleo;
AuditLog AuditLog::fromJob(const QGpgME::Job *job)
{
if (job) {
return AuditLog(job->auditLogAsHtml(), job->auditLogError());
} else {
return AuditLog();
}
}
QString AuditLog::formatLink(const QUrl &urlTemplate) const
{
// more or less the same as
// kmail/objecttreeparser.cpp:makeShowAuditLogLink(), so any bug
// fixed here eqally applies there:
- if (const unsigned int code = m_error.code()) {
+ if (const int code = m_error.code()) {
if (code == GPG_ERR_NOT_IMPLEMENTED) {
qCDebug(KLEOPATRA_LOG) << "not showing link (not implemented)";
} else if (code == GPG_ERR_NO_DATA) {
qCDebug(KLEOPATRA_LOG) << "not showing link (not available)";
} else {
qCDebug(KLEOPATRA_LOG) << "Error Retrieving Audit Log:" << QString::fromLocal8Bit(m_error.asString());
}
return QString();
}
if (!m_text.isEmpty()) {
QUrl url = urlTemplate;
QUrlQuery urlQuery(url);
urlQuery.addQueryItem(QStringLiteral("log"), m_text);
url.setQuery(urlQuery);
return QLatin1String("<a href=\"") + url.url() + QLatin1String("\">") + i18nc("The Audit Log is a detailed error log from the gnupg backend", "Show Audit Log") + QLatin1String("</a>");
}
return QString();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:58 PM (1 h, 11 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
2e/b7/d8eb88ea2f2042872a105ce6e2a3
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment