Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20320582
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
25 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment