Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F36623268
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
12 KB
Subscribers
None
View Options
diff --git a/src/crypto/gui/resultitemwidget.cpp b/src/crypto/gui/resultitemwidget.cpp
index a4e2c575b..57dcb5f93 100644
--- a/src/crypto/gui/resultitemwidget.cpp
+++ b/src/crypto/gui/resultitemwidget.cpp
@@ -1,351 +1,342 @@
/*
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "resultitemwidget.h"
#include "commands/command.h"
#include "commands/lookupcertificatescommand.h"
#include "crypto/decryptverifytask.h"
#include "view/htmllabel.h"
#include "view/urllabel.h"
#include <Libkleo/ApplicationPaletteWatcher>
#include <Libkleo/AuditLogEntry>
#include <Libkleo/AuditLogViewer>
#include <Libkleo/Classify>
#include <Libkleo/SystemInfo>
#include <gpgme++/decryptionresult.h>
#include <gpgme++/key.h>
#include "kleopatra_debug.h"
#include <KColorScheme>
#include <KGuiItem>
#include <KLocalizedString>
#include <KStandardGuiItem>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
namespace
{
// TODO move out of here
static KColorScheme::BackgroundRole colorForVisualCode(Task::Result::VisualCode code)
{
switch (code) {
case Task::Result::AllGood:
return KColorScheme::PositiveBackground;
case Task::Result::Warning:
return KColorScheme::NormalBackground;
case Task::Result::Danger:
return KColorScheme::NegativeBackground;
default:
return KColorScheme::NormalBackground;
}
}
struct ResultItemData {
QPointer<QWidget> widget;
KColorScheme::BackgroundRole backgroundRole;
};
}
class ResultItemWidget::Private
{
ResultItemWidget *const q;
public:
Private(const std::shared_ptr<const Task::Result> &result, ResultItemWidget *qq);
void slotLinkActivated(const QString &);
void updateShowDetailsLabel();
void updateStyleSheets();
void addIgnoreMDCButton(QBoxLayout *lay);
void oneImportFinished();
ApplicationPaletteWatcher m_appPaletteWatcher;
QList<QPointer<QWidget>> m_mainStylesheetWidgets;
QList<ResultItemData> m_itemStylesheetWidgets;
const std::shared_ptr<const Task::Result> m_result;
UrlLabel *m_auditLogLabel = nullptr;
QPushButton *m_closeButton = nullptr;
QPushButton *m_showButton = nullptr;
bool m_importCanceled = false;
};
void ResultItemWidget::Private::oneImportFinished()
{
if (m_importCanceled) {
return;
}
if (m_result->parentTask()) {
m_result->parentTask()->start();
}
q->setVisible(false);
}
void ResultItemWidget::Private::addIgnoreMDCButton(QBoxLayout *lay)
{
if (!m_result || !lay) {
return;
}
const auto dvResult = dynamic_cast<const DecryptVerifyResult *>(m_result.get());
if (!dvResult) {
return;
}
const auto decResult = dvResult->decryptionResult();
if (decResult.isNull() || !decResult.error() || !decResult.isLegacyCipherNoMDC()) {
return;
}
auto btn = new QPushButton(i18nc("@action:button", "Force decryption"));
btn->setFixedSize(btn->sizeHint());
connect(btn, &QPushButton::clicked, q, [this]() {
if (m_result->parentTask()) {
const auto dvTask = dynamic_cast<DecryptVerifyTask *>(m_result->parentTask().data());
dvTask->setIgnoreMDCError(true);
dvTask->start();
q->setVisible(false);
} else {
qCWarning(KLEOPATRA_LOG) << "Failed to get parent task";
}
});
lay->addWidget(btn);
}
static QUrl auditlog_url_template()
{
QUrl url(QStringLiteral("kleoresultitem://showauditlog"));
return url;
}
void ResultItemWidget::Private::updateShowDetailsLabel()
{
const auto auditLogUrl = m_result->auditLog().asUrl(auditlog_url_template());
const auto auditLogLinkText = m_result->hasError() ? i18n("Diagnostics") //
: i18nc("The Audit Log is a detailed error log from the gnupg backend", "Show Audit Log");
m_auditLogLabel->setUrl(auditLogUrl, auditLogLinkText);
m_auditLogLabel->setVisible(!auditLogUrl.isEmpty());
}
void ResultItemWidget::Private::updateStyleSheets()
{
const QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background(KColorScheme::NormalBackground).color();
const QColor borderColor = (color.lightnessF() > 0.5) ? color.darker(150) : color.lighter(150);
- const QString styleSheet = SystemInfo::isHighContrastColorSchemeInUse()
- ? QStringLiteral(
- "QFrame,QLabel { margin: 0px; }"
- "QFrame#resultFrame{ border-style: solid; border-radius: 3px; border-width: 1px }"
- "QLabel { padding: 5px; border-radius: 3px }")
- : QStringLiteral(
- "QFrame,QLabel { background-color: %1; margin: 0px; }"
- "QFrame#resultFrame{ border-color: %2; border-style: solid; border-radius: 3px; border-width: 1px }"
- "QLabel { padding: 5px; border-radius: 3px }")
- .arg(color.name())
- .arg(borderColor.name());
+ const QString styleSheet = QStringLiteral(
+ "QFrame,QLabel { background-color: %1; margin: 0px; }"
+ "QFrame#resultFrame{ border-color: %2; border-style: solid; border-radius: 3px; border-width: 1px }"
+ "QLabel { padding: 5px; border-radius: 3px }")
+ .arg(color.name())
+ .arg(borderColor.name());
for (auto &w : m_mainStylesheetWidgets) {
w->setStyleSheet(styleSheet);
}
for (auto &item : m_itemStylesheetWidgets) {
const QColor color = KColorScheme(QPalette::Active, KColorScheme::View).background(item.backgroundRole).color();
const QColor borderColor = (color.lightnessF() > 0.5) ? color.darker(150) : color.lighter(150);
- const QString styleSheet = SystemInfo::isHighContrastColorSchemeInUse()
- ? QStringLiteral(
- "QFrame { margin: 0px; }"
- "QFrame { padding: 5px; border-radius: 3px }")
- : QStringLiteral(
- "QFrame { background-color: %1; margin: 0px; }"
- "QFrame { padding: 5px; border-radius: 3px; border-style: solid; border-width: 1px; border-color: %2; }")
- .arg(color.name())
- .arg(borderColor.name());
+ const QString styleSheet = QStringLiteral(
+ "QFrame { background-color: %1; margin: 0px; }"
+ "QFrame { padding: 5px; border-radius: 3px; border-style: solid; border-width: 1px; border-color: %2; }")
+ .arg(color.name())
+ .arg(borderColor.name());
item.widget->setStyleSheet(styleSheet);
}
}
ResultItemWidget::Private::Private(const std::shared_ptr<const Task::Result> &result, ResultItemWidget *qq)
: q(qq)
, m_result(result)
{
Q_ASSERT(m_result);
auto topLayout = new QVBoxLayout(q);
auto frame = new QFrame;
frame->setObjectName(QLatin1StringView("resultFrame"));
m_mainStylesheetWidgets.push_back(frame);
topLayout->addWidget(frame);
auto vlay = new QVBoxLayout(frame);
auto layout = new QHBoxLayout();
auto overview = new HtmlLabel;
overview->setWordWrap(true);
overview->setHtml(m_result->overview());
m_mainStylesheetWidgets.push_back(overview);
q->setFocusPolicy(overview->focusPolicy());
q->setFocusProxy(overview);
connect(overview, &QLabel::linkActivated, q, [this](const auto &link) {
slotLinkActivated(link);
});
layout->addWidget(overview);
vlay->addLayout(layout);
auto actionLayout = new QVBoxLayout;
layout->addLayout(actionLayout);
addIgnoreMDCButton(actionLayout);
m_auditLogLabel = new UrlLabel;
connect(m_auditLogLabel, &QLabel::linkActivated, q, [this](const auto &link) {
slotLinkActivated(link);
});
actionLayout->addWidget(m_auditLogLabel);
m_mainStylesheetWidgets.push_back(m_auditLogLabel);
for (const auto &detail : m_result.get()->detailsList()) {
auto frame = new QFrame;
auto row = new QHBoxLayout(frame);
auto iconLabel = new QLabel;
QString icon;
if (detail.code == Task::Result::AllGood) {
icon = QStringLiteral("data-success");
} else if (detail.code == Task::Result::Warning) {
icon = QStringLiteral("data-warning");
} else {
icon = QStringLiteral("data-error");
}
iconLabel->setPixmap(QIcon::fromTheme(icon).pixmap(32, 32));
row->addWidget(iconLabel, 0);
auto detailsLabel = new HtmlLabel;
detailsLabel->setWordWrap(true);
detailsLabel->setHtml(detail.details);
iconLabel->setStyleSheet(QStringLiteral("QLabel {border-width: 0; }"));
m_itemStylesheetWidgets.push_back({frame, colorForVisualCode(detail.code)});
detailsLabel->setStyleSheet(QStringLiteral("QLabel {border-width: 0; }"));
connect(detailsLabel, &QLabel::linkActivated, q, [this](const auto &link) {
slotLinkActivated(link);
});
row->addWidget(detailsLabel, 1);
vlay->addWidget(frame);
}
m_showButton = new QPushButton;
m_showButton->setVisible(false);
connect(m_showButton, &QAbstractButton::clicked, q, &ResultItemWidget::showButtonClicked);
actionLayout->addWidget(m_showButton);
m_closeButton = new QPushButton;
KGuiItem::assign(m_closeButton, KStandardGuiItem::close());
m_closeButton->setFixedSize(m_closeButton->sizeHint());
connect(m_closeButton, &QAbstractButton::clicked, q, &ResultItemWidget::closeButtonClicked);
actionLayout->addWidget(m_closeButton);
m_closeButton->setVisible(false);
layout->setStretch(0, 1);
actionLayout->addStretch(-1);
vlay->addStretch(-1);
updateShowDetailsLabel();
updateStyleSheets();
connect(&m_appPaletteWatcher, &ApplicationPaletteWatcher::paletteChanged, q, [this]() {
updateStyleSheets();
});
}
ResultItemWidget::ResultItemWidget(const std::shared_ptr<const Task::Result> &result, QWidget *parent, Qt::WindowFlags flags)
: QWidget(parent, flags)
, d(new Private(result, this))
{
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum);
}
ResultItemWidget::~ResultItemWidget()
{
}
void ResultItemWidget::showCloseButton(bool show)
{
d->m_closeButton->setVisible(show);
}
void ResultItemWidget::setShowButton(const QString &text, bool show)
{
d->m_showButton->setText(text);
d->m_showButton->setVisible(show);
}
bool ResultItemWidget::hasErrorResult() const
{
return d->m_result->hasError();
}
void ResultItemWidget::Private::slotLinkActivated(const QString &link)
{
Q_ASSERT(m_result);
qCDebug(KLEOPATRA_LOG) << "Link activated: " << link;
if (link.startsWith(QLatin1StringView("key:"))) {
auto split = link.split(QLatin1Char(':'));
auto fpr = split.value(1);
if (split.size() == 2 && isFingerprint(fpr)) {
/* There might be a security consideration here if somehow
* a short keyid is used in a link and it collides with another.
* So we additionally check that it really is a fingerprint. */
auto cmd = Command::commandForQuery(fpr);
cmd->setParentWId(q->effectiveWinId());
cmd->start();
} else {
qCWarning(KLEOPATRA_LOG) << "key link invalid " << link;
}
return;
}
const QUrl url(link);
if (url.host() == QLatin1StringView("showauditlog")) {
q->showAuditLog();
return;
}
if (url.scheme() == QStringLiteral("certificate")) {
auto cmd = new Kleo::Commands::LookupCertificatesCommand(url.path(), nullptr);
connect(cmd, &Kleo::Commands::LookupCertificatesCommand::canceled, q, [this]() {
m_importCanceled = true;
});
connect(cmd, &Kleo::Commands::LookupCertificatesCommand::finished, q, [this]() {
oneImportFinished();
});
cmd->setParentWidget(q);
cmd->start();
return;
}
qCWarning(KLEOPATRA_LOG) << "Unexpected link scheme: " << link;
}
void ResultItemWidget::showAuditLog()
{
AuditLogViewer::showAuditLog(parentWidget(), d->m_result->auditLog());
}
#include "moc_resultitemwidget.cpp"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:43 PM (8 h, 33 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
6c/00/4e37bbc3c336c124937e235bf547
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment