Page MenuHome GnuPG

No OneTemporary

diff --git a/src/view/netkeywidget.cpp b/src/view/netkeywidget.cpp
index 79e8c088a..23bf7d31c 100644
--- a/src/view/netkeywidget.cpp
+++ b/src/view/netkeywidget.cpp
@@ -1,61 +1,61 @@
/* view/netkeywidget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2017 Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "netkeywidget.h"
#include "cardkeysview.h"
#include "nullpinwidget.h"
#include "kleopatra_debug.h"
#include "smartcard/netkeycard.h"
#include <KLocalizedString>
#include <QLabel>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::SmartCard;
NetKeyWidget::NetKeyWidget(QWidget *parent)
- : SmartCardWidget(parent)
+ : SmartCardWidget(AppType::NetKeyApp, parent)
{
mNullPinWidget = new NullPinWidget{this};
mContentLayout->addWidget(mNullPinWidget);
mErrorLabel = new QLabel{this};
mErrorLabel->setVisible(false);
mContentLayout->addWidget(mErrorLabel);
// do not show Created column by default; creation time is not reported by scdaemon for NetKey cards
mCardKeysView = new CardKeysView{this, CardKeysView::NoOptions};
mContentLayout->addWidget(mCardKeysView, 1);
}
NetKeyWidget::~NetKeyWidget() = default;
void NetKeyWidget::setCard(const NetKeyCard *card)
{
SmartCardWidget::setCard(card);
mNullPinWidget->setSerialNumber(serialNumber());
/* According to users of NetKey Cards it is fairly uncommon
* to use SigG Certificates at all. So it should be optional to set the pins. */
mNullPinWidget->setVisible(card->hasNKSNullPin() /*|| card->hasSigGNullPin()*/);
mNullPinWidget->setSigGVisible(false /*card->hasSigGNullPin()*/);
mNullPinWidget->setNKSVisible(card->hasNKSNullPin());
const auto errMsg = card->errorMsg();
if (!errMsg.isEmpty()) {
mErrorLabel->setText(QStringLiteral("<b>%1:</b> %2").arg(i18n("Error"), errMsg));
mErrorLabel->setVisible(true);
} else {
mErrorLabel->setVisible(false);
}
}
diff --git a/src/view/p15cardwidget.cpp b/src/view/p15cardwidget.cpp
index 745847c86..bc37ab0a7 100644
--- a/src/view/p15cardwidget.cpp
+++ b/src/view/p15cardwidget.cpp
@@ -1,115 +1,115 @@
/* view/p15cardwiget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "p15cardwidget.h"
#include "cardkeysview.h"
#include "settings.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/p15card.h"
#include "smartcard/readerstatus.h"
#include <QLabel>
#include <QPushButton>
#include <QStringList>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <KSeparator>
#include <Libkleo/Compat>
#include <Libkleo/Formatting>
#include <Libkleo/GnuPG>
#include <Libkleo/KeyCache>
#include <QGpgME/CryptoConfig>
#include <QGpgME/ImportFromKeyserverJob>
#include <QGpgME/KeyListJob>
#include <QGpgME/Protocol>
#include <gpgme++/importresult.h>
#include <gpgme++/keylistresult.h>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::SmartCard;
P15CardWidget::P15CardWidget(QWidget *parent)
- : SmartCardWidget{parent}
+ : SmartCardWidget{AppType::P15App, parent}
{
mStatusLabel = new QLabel{this};
mStatusLabel->setVisible(false);
mContentLayout->addWidget(mStatusLabel);
mCardKeysView = new CardKeysView{this};
mContentLayout->addWidget(mCardKeysView, 1);
}
P15CardWidget::~P15CardWidget() = default;
void P15CardWidget::searchPGPFpr(const std::string &fpr)
{
/* Only do auto import from LDAP */
auto conf = QGpgME::cryptoConfig();
Q_ASSERT(conf);
if (!Settings().alwaysSearchCardOnKeyserver() && !Kleo::keyserver().startsWith(QLatin1String{"ldap"})) {
return;
}
mStatusLabel->setText(i18n("Searching in directory service..."));
mStatusLabel->setVisible(true);
qCDebug(KLEOPATRA_LOG) << "Looking for:" << fpr.c_str() << "on ldap server";
QGpgME::KeyListJob *job = QGpgME::openpgp()->keyListJob(true);
connect(job, &QGpgME::KeyListJob::result, job, [this](GpgME::KeyListResult, std::vector<GpgME::Key> keys, QString, GpgME::Error) {
if (keys.size() == 1) {
auto importJob = QGpgME::openpgp()->importFromKeyserverJob();
qCDebug(KLEOPATRA_LOG) << "Importing: " << keys[0].primaryFingerprint();
connect(importJob, &QGpgME::ImportFromKeyserverJob::result, importJob, [this](GpgME::ImportResult, QString, GpgME::Error) {
qCDebug(KLEOPATRA_LOG) << "import job done";
mStatusLabel->setText(i18n("Automatic import finished."));
});
importJob->start(keys);
} else if (keys.size() > 1) {
qCDebug(KLEOPATRA_LOG) << "Multiple keys found on server";
mStatusLabel->setText(i18n("Error multiple keys found on server."));
} else {
qCDebug(KLEOPATRA_LOG) << "No key found";
mStatusLabel->setText(i18n("Key not found in directory service."));
}
});
job->start(QStringList() << QString::fromStdString(fpr));
}
void P15CardWidget::setCard(const P15Card *card)
{
SmartCardWidget::setCard(card);
const auto sigInfo = card->keyInfo(card->signingKeyRef());
if (!sigInfo.grip.empty()) {
const auto key = KeyCache::instance()->findSubkeyByKeyGrip(sigInfo.grip, GpgME::OpenPGP).parent();
if (key.isNull()) {
qCDebug(KLEOPATRA_LOG) << "Failed to find key for grip:" << sigInfo.grip.c_str();
const auto pgpSigFpr = card->keyFingerprint(OpenPGPCard::pgpSigKeyRef());
if (!pgpSigFpr.empty()) {
qCDebug(KLEOPATRA_LOG) << "Should be pgp key:" << pgpSigFpr.c_str();
searchPGPFpr(pgpSigFpr);
}
} else {
mStatusLabel->setVisible(false);
}
}
/* Check if additional keys could be available */
if (!Settings().autoLoadP15Certs()) {
return;
}
}
diff --git a/src/view/pgpcardwidget.cpp b/src/view/pgpcardwidget.cpp
index dd05f8f51..934268c29 100644
--- a/src/view/pgpcardwidget.cpp
+++ b/src/view/pgpcardwidget.cpp
@@ -1,195 +1,195 @@
/* view/pgpcardwiget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-FileCopyrightText: 2020, 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "pgpcardwidget.h"
#include "kleopatra_debug.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/readerstatus.h"
#include <view/cardkeysview.h>
#include <utils/qt-cxx20-compat.h>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <KLocalizedString>
#include <KMessageBox>
#include <Libkleo/Formatting>
using namespace Kleo;
using namespace Kleo::SmartCard;
PGPCardWidget::PGPCardWidget(QWidget *parent)
- : SmartCardWidget(parent)
+ : SmartCardWidget(AppType::OpenPGPApp, parent)
{
{
mInfoGridLayout->setColumnStretch(mInfoGridLayout->columnCount() - 1, 0); // undo stretch set by base widget
int row = mInfoGridLayout->rowCount();
// Cardholder Row
mInfoGridLayout->addWidget(new QLabel(i18nc("The owner of a smartcard. GnuPG refers to this as cardholder.", "Cardholder:")), row, 0);
mCardHolderLabel = new QLabel{this};
mCardHolderLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
mInfoGridLayout->addWidget(mCardHolderLabel, row, 1);
{
auto button = new QPushButton{this};
button->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
button->setAccessibleName(i18nc("@action:button", "Edit"));
button->setToolTip(i18n("Change"));
mInfoGridLayout->addWidget(button, row, 2);
connect(button, &QPushButton::clicked, this, &PGPCardWidget::changeNameRequested);
}
row++;
// URL Row
mInfoGridLayout->addWidget(new QLabel(i18nc("The URL under which a public key that "
"corresponds to a smartcard can be downloaded",
"Pubkey URL:")),
row,
0);
mUrlLabel = new QLabel{this};
mUrlLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
mInfoGridLayout->addWidget(mUrlLabel, row, 1);
{
auto button = new QPushButton{this};
button->setIcon(QIcon::fromTheme(QStringLiteral("cell_edit")));
button->setAccessibleName(i18nc("@action:button", "Edit"));
button->setToolTip(i18n("Change"));
mInfoGridLayout->addWidget(button, row, 2);
connect(button, &QPushButton::clicked, this, &PGPCardWidget::changeUrlRequested);
}
mInfoGridLayout->setColumnStretch(mInfoGridLayout->columnCount(), 1);
}
mCardKeysView = new CardKeysView{this};
mContentLayout->addWidget(mCardKeysView, 1);
}
void PGPCardWidget::setCard(const OpenPGPCard *card)
{
SmartCardWidget::setCard(card);
const auto holder = card->cardHolder();
const auto url = QString::fromStdString(card->pubkeyUrl());
mCardHolderLabel->setText(holder.isEmpty() ? i18n("not set") : holder);
mUrl = url;
mUrlLabel->setText(url.isEmpty() ? i18n("not set") : QStringLiteral("<a href=\"%1\">%1</a>").arg(url.toHtmlEscaped()));
mUrlLabel->setOpenExternalLinks(true);
}
void PGPCardWidget::changeNameRequested()
{
QString text = mCardHolderLabel->text();
while (true) {
bool ok = false;
text = QInputDialog::getText(this, i18n("Change cardholder"), i18n("New name:"), QLineEdit::Normal, text, &ok, Qt::WindowFlags(), Qt::ImhLatinOnly);
if (!ok) {
return;
}
// Some additional restrictions imposed by gnupg
if (text.contains(QLatin1Char('<'))) {
KMessageBox::error(this, i18nc("@info", "The \"<\" character may not be used."));
continue;
}
if (text.contains(QLatin1String(" "))) {
KMessageBox::error(this, i18nc("@info", "Double spaces are not allowed"));
continue;
}
if (text.size() > 38) {
KMessageBox::error(this, i18nc("@info", "The size of the name may not exceed 38 characters."));
}
break;
}
auto parts = text.split(QLatin1Char(' '));
const auto lastName = parts.takeLast();
const QString formatted = lastName + QStringLiteral("<<") + parts.join(QLatin1Char('<'));
const auto pgpCard = ReaderStatus::instance()->getCard<OpenPGPCard>(serialNumber());
if (!pgpCard) {
KMessageBox::error(this, i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(serialNumber())));
return;
}
const QByteArray command = QByteArrayLiteral("SCD SETATTR DISP-NAME ") + formatted.toUtf8();
ReaderStatus::mutableInstance()->startSimpleTransaction(pgpCard, command, this, [this](const GpgME::Error &err) {
changeNameResult(err);
});
}
void PGPCardWidget::changeNameResult(const GpgME::Error &err)
{
if (err) {
KMessageBox::error(this, i18nc("@info", "Name change failed: %1", Formatting::errorAsString(err)));
return;
}
if (!err.isCanceled()) {
KMessageBox::information(this, i18nc("@info", "Name successfully changed."), i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
}
void PGPCardWidget::changeUrlRequested()
{
QString text = mUrl;
while (true) {
bool ok = false;
text = QInputDialog::getText(this,
i18n("Change the URL where the pubkey can be found"),
i18n("New pubkey URL:"),
QLineEdit::Normal,
text,
&ok,
Qt::WindowFlags(),
Qt::ImhLatinOnly);
if (!ok) {
return;
}
// Some additional restrictions imposed by gnupg
if (text.size() > 254) {
KMessageBox::error(this, i18nc("@info", "The size of the URL may not exceed 254 characters."));
}
break;
}
const auto pgpCard = ReaderStatus::instance()->getCard<OpenPGPCard>(serialNumber());
if (!pgpCard) {
KMessageBox::error(this, i18n("Failed to find the OpenPGP card with the serial number: %1", QString::fromStdString(serialNumber())));
return;
}
const QByteArray command = QByteArrayLiteral("SCD SETATTR PUBKEY-URL ") + text.toUtf8();
ReaderStatus::mutableInstance()->startSimpleTransaction(pgpCard, command, this, [this](const GpgME::Error &err) {
changeUrlResult(err);
});
}
void PGPCardWidget::changeUrlResult(const GpgME::Error &err)
{
if (err) {
KMessageBox::error(this, i18nc("@info", "URL change failed: %1", Formatting::errorAsString(err)));
return;
}
if (!err.isCanceled()) {
KMessageBox::information(this, i18nc("@info", "URL successfully changed."), i18nc("@title", "Success"));
ReaderStatus::mutableInstance()->updateStatus();
}
}
diff --git a/src/view/pivcardwidget.cpp b/src/view/pivcardwidget.cpp
index f83e466e6..78d8e1d92 100644
--- a/src/view/pivcardwidget.cpp
+++ b/src/view/pivcardwidget.cpp
@@ -1,26 +1,29 @@
/* view/pivcardwiget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "pivcardwidget.h"
#include "cardkeysview.h"
+#include <smartcard/card.h>
+
#include <QVBoxLayout>
using namespace Kleo;
+using namespace Kleo::SmartCard;
PIVCardWidget::PIVCardWidget(QWidget *parent)
- : SmartCardWidget(parent)
+ : SmartCardWidget(AppType::PIVApp, parent)
{
// do not show Created column by default; creation time is not reported by scdaemon for PIV cards
mCardKeysView = new CardKeysView{this, CardKeysView::NoOptions};
mContentLayout->addWidget(mCardKeysView, 1);
}
PIVCardWidget::~PIVCardWidget() = default;
diff --git a/src/view/smartcardwidget.cpp b/src/view/smartcardwidget.cpp
index b974e0d3d..150ca8f27 100644
--- a/src/view/smartcardwidget.cpp
+++ b/src/view/smartcardwidget.cpp
@@ -1,253 +1,255 @@
/* view/smartcardwidget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2024 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "smartcardwidget.h"
#include "infofield.h"
#include "smartcardactions.h"
#include <smartcard/card.h>
#include <smartcard/netkeycard.h>
#include <smartcard/pivcard.h>
#include <utils/qt6compat.h>
#include <view/cardkeysview.h>
#include <Libkleo/Compliance>
#include <KLocalizedString>
#include <QGridLayout>
#include <QLabel>
#include <QMenu>
#include <QScrollArea>
#include <QToolButton>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::SmartCard;
using namespace Qt::Literals::StringLiterals;
static QString cardTypeForDisplay(const Card *card)
{
switch (card->appType()) {
case AppType::NetKeyApp:
return i18nc("1 is a Version number", "NetKey v%1 Card", card->appVersion());
case AppType::OpenPGPApp: {
const std::string manufacturer = card->manufacturer();
const bool manufacturerIsUnknown = manufacturer.empty() || manufacturer == "unknown";
return (manufacturerIsUnknown //
? i18nc("Placeholder is a version number", "Unknown OpenPGP v%1 card", card->displayAppVersion())
: i18nc("First placeholder is manufacturer, second placeholder is a version number",
"%1 OpenPGP v%2 card",
QString::fromStdString(manufacturer),
card->displayAppVersion()));
}
case AppType::P15App:
return i18nc("%1 is a smartcard manufacturer", "%1 PKCS#15 card", QString::fromStdString(card->manufacturer()));
case AppType::PIVApp:
return i18nc("%1 version number", "PIV v%1 card", card->displayAppVersion());
default:
return {};
};
}
static std::vector<QAction *> actionsForCard(SmartCard::AppType appType)
{
std::vector<QString> actions;
switch (appType) {
case AppType::NetKeyApp:
actions = {
u"card_all_create_openpgp_certificate"_s,
u"card_netkey_set_nks_pin"_s,
u"card_netkey_set_sigg_pin"_s,
};
break;
case AppType::OpenPGPApp:
actions = {
u"card_pgp_generate_keys_and_certificate"_s,
u"card_pgp_change_pin"_s,
u"card_pgp_unblock_card"_s,
u"card_pgp_change_admin_pin"_s,
u"card_pgp_change_puk"_s,
};
break;
case AppType::P15App:
// there are no card actions for generic PKCS#15 cards
break;
case AppType::PIVApp:
actions = {
u"card_all_create_openpgp_certificate"_s,
u"card_piv_change_pin"_s,
u"card_piv_change_puk"_s,
u"card_piv_change_admin_key"_s,
};
break;
case AppType::NoApp:
break;
};
return SmartCardActions::instance()->actions(actions);
}
static void updateCardAction(QAction *action, const Card *card)
{
switch (card->appType()) {
case AppType::NetKeyApp: {
auto netKeyCard = static_cast<const NetKeyCard *>(card);
if (action->objectName() == "card_all_create_openpgp_certificate"_L1) {
action->setEnabled(!netKeyCard->hasNKSNullPin() && card->hasSigningKey() && card->hasEncryptionKey()
&& DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->signingKeyRef()).algorithm)
&& DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->encryptionKeyRef()).algorithm));
} else if (action->objectName() == "card_netkey_set_nks_pin"_L1) {
if (!netKeyCard->hasNKSNullPin()) {
action->setText(i18nc("@action NKS is an identifier for a type of keys on a NetKey card", "Change NKS PIN"));
}
} else if (action->objectName() == "card_netkey_set_sigg_pin"_L1) {
if (!netKeyCard->hasSigGNullPin()) {
action->setText(i18nc("@action SigG is an identifier for a type of keys on a NetKey card", "Change SigG PIN"));
}
}
break;
}
case AppType::OpenPGPApp:
break;
case AppType::P15App:
break;
case AppType::PIVApp: {
if (action->objectName() == "card_all_create_openpgp_certificate"_L1) {
action->setEnabled(card->hasSigningKey() && card->hasEncryptionKey()
&& DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->signingKeyRef()).algorithm)
&& DeVSCompliance::algorithmIsCompliant(card->keyInfo(card->encryptionKeyRef()).algorithm));
}
break;
}
case AppType::NoApp:
break;
};
}
static void updateCardActions(QToolButton *actionsButton, const Card *card)
{
if (!actionsButton->menu()) {
const auto actions = actionsForCard(card->appType());
if (actions.empty()) {
// there are no card actions for this card app
return;
} else {
actionsButton->setVisible(true);
}
auto menu = new QMenu{actionsButton};
for (auto action : actions) {
menu->addAction(SmartCardActions::createProxyAction(action, menu));
}
actionsButton->setMenu(menu);
}
for (auto action : actionsButton->menu()->actions()) {
updateCardAction(action, card);
}
}
-SmartCardWidget::SmartCardWidget(QWidget *parent)
+SmartCardWidget::SmartCardWidget(Kleo::SmartCard::AppType appType, QWidget *parent)
: QWidget{parent}
+ , mAppType{appType}
{
auto mainLayout = new QVBoxLayout{this};
mainLayout->setContentsMargins({});
auto area = new QScrollArea{this};
area->setFocusPolicy(Qt::NoFocus);
area->setFrameShape(QFrame::NoFrame);
area->setWidgetResizable(true);
mainLayout->addWidget(area);
auto areaWidget = new QWidget{this};
area->setWidget(areaWidget);
mContentLayout = new QVBoxLayout{areaWidget};
auto contentLayout = mContentLayout;
auto upperLayout = new QHBoxLayout;
{
// auto gridLayout = new QGridLayout;
mInfoGridLayout = new QGridLayout;
auto gridLayout = mInfoGridLayout;
// gridLayout->setColumnStretch(1, 1);
int row = -1;
row++;
mCardTypeField = std::make_unique<InfoField>(i18nc("@label", "Card type:"), parent);
gridLayout->addWidget(mCardTypeField->label(), row, 0);
gridLayout->addLayout(mCardTypeField->layout(), row, 1);
row++;
mSerialNumberField = std::make_unique<InfoField>(i18nc("@label", "Serial number:"), parent);
gridLayout->addWidget(mSerialNumberField->label(), row, 0);
gridLayout->addLayout(mSerialNumberField->layout(), row, 1);
gridLayout->setColumnStretch(gridLayout->columnCount(), 1);
upperLayout->addLayout(gridLayout, 1);
}
{
auto layout = new QVBoxLayout;
mCardActionsButton = new QToolButton{this};
mCardActionsButton->setPopupMode(QToolButton::InstantPopup);
mCardActionsButton->setText(i18nc("@action:button", "Card Actions"));
mCardActionsButton->setToolTip(i18nc("@info", "Show actions available for this smart card"));
mCardActionsButton->setVisible(false);
layout->addWidget(mCardActionsButton);
layout->addStretch(1);
upperLayout->addLayout(layout);
}
contentLayout->addLayout(upperLayout);
}
SmartCardWidget::~SmartCardWidget() = default;
void SmartCardWidget::setCard(const Card *card)
{
+ Q_ASSERT(mAppType == card->appType());
mCard.reset(card->clone());
mCardTypeField->setValue(cardTypeForDisplay(card));
mSerialNumberField->setValue(card->displaySerialNumber());
updateCardActions(mCardActionsButton, card);
mCardKeysView->setCard(mCard);
}
const Kleo::SmartCard::Card *SmartCardWidget::card() const
{
return mCard.get();
}
Kleo::SmartCard::AppType SmartCardWidget::cardType() const
{
return mCard ? mCard->appType() : AppType::NoApp;
}
std::string SmartCardWidget::serialNumber() const
{
return mCard ? mCard->serialNumber() : std::string{};
}
std::string SmartCardWidget::currentCardSlot() const
{
if (mCardKeysView) {
return mCardKeysView->currentCardSlot();
}
return {};
}
GpgME::Key SmartCardWidget::currentCertificate() const
{
if (mCardKeysView) {
return mCardKeysView->currentCertificate();
}
return {};
}
diff --git a/src/view/smartcardwidget.h b/src/view/smartcardwidget.h
index f767f5a11..45c12702c 100644
--- a/src/view/smartcardwidget.h
+++ b/src/view/smartcardwidget.h
@@ -1,64 +1,67 @@
/* view/smartcardwidget.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2024 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QWidget>
#include <memory>
#include <string>
class QGridLayout;
class QToolButton;
class QVBoxLayout;
namespace GpgME
{
class Key;
}
namespace Kleo
{
class CardKeysView;
class InfoField;
}
namespace Kleo::SmartCard
{
enum class AppType;
class Card;
}
class SmartCardWidget : public QWidget
{
Q_OBJECT
+protected:
+ SmartCardWidget(Kleo::SmartCard::AppType appType, QWidget *parent = nullptr);
+
public:
- SmartCardWidget(QWidget *parent = nullptr);
~SmartCardWidget() override;
void setCard(const Kleo::SmartCard::Card *card);
const Kleo::SmartCard::Card *card() const;
Kleo::SmartCard::AppType cardType() const;
std::string serialNumber() const;
std::string currentCardSlot() const;
GpgME::Key currentCertificate() const;
protected:
QVBoxLayout *mContentLayout = nullptr;
QGridLayout *mInfoGridLayout = nullptr;
private:
+ Kleo::SmartCard::AppType mAppType;
std::shared_ptr<const Kleo::SmartCard::Card> mCard;
std::unique_ptr<Kleo::InfoField> mCardTypeField;
std::unique_ptr<Kleo::InfoField> mSerialNumberField;
QToolButton *mCardActionsButton = nullptr;
protected:
Kleo::CardKeysView *mCardKeysView = nullptr;
};

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 4:10 AM (1 d, 6 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
bb/c0/a6ba1bc0f2b9f6c1303f3e80efd6

Event Timeline