Page MenuHome GnuPG

No OneTemporary

diff --git a/src/view/smartcardwidget.cpp b/src/view/smartcardwidget.cpp
index e471ee93e..6f3c4859b 100644
--- a/src/view/smartcardwidget.cpp
+++ b/src/view/smartcardwidget.cpp
@@ -1,226 +1,242 @@
/* view/smartcardwidget.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 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "smartcardwidget.h"
#include "smartcard/readerstatus.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/netkeycard.h"
#include "smartcard/p15card.h"
#include "smartcard/pivcard.h"
#include "smartcard/utils.h"
#include "view/pgpcardwidget.h"
#include "view/netkeywidget.h"
#include "view/pivcardwidget.h"
#include "view/p15cardwidget.h"
#include "kleopatra_debug.h"
#include <KLocalizedString>
#include <QHBoxLayout>
#include <QLabel>
#include <QPointer>
#include <QPushButton>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QStackedWidget>
using namespace Kleo;
using namespace Kleo::SmartCard;
namespace {
class PlaceHolderWidget: public QWidget
{
Q_OBJECT
public:
explicit PlaceHolderWidget(QWidget *parent = nullptr)
: QWidget{parent}
{
auto lay = new QVBoxLayout;
lay->addStretch(-1);
const QStringList supported = QStringList() << i18nc("OpenPGP refers to a smartcard protocol", "OpenPGP v2.0 - v3.3")
<< i18nc("Gnuk is a cryptographic token for GnuPG", "Gnuk")
<< i18nc("NetKey refers to a smartcard protocol", "NetKey v3")
<< i18nc("PIV refers to a smartcard protocol", "PIV (requires GnuPG 2.3 or later)")
<< i18nc("CardOS is a smartcard operating system", "CardOS 5 (various apps)");
lay->addWidget(new QLabel(QStringLiteral("\t\t<h3>") +
i18n("Please insert a compatible smartcard.") + QStringLiteral("</h3>"), this));
lay->addSpacing(10);
lay->addWidget(new QLabel(QStringLiteral("\t\t") +
i18n("Kleopatra currently supports the following card types:") +
QStringLiteral("<ul><li>") + supported.join(QLatin1String("</li><li>")) +
QStringLiteral("</li></ul>"), this));
lay->addSpacing(10);
- lay->addWidget(new QLabel(i18n("Refresh the view (F5) to update the smartcard status."), this));
+ {
+ auto hbox = new QHBoxLayout;
+ hbox->addStretch(1);
+ mReloadButton = new QPushButton{i18n("Reload"), this};
+ hbox->addWidget(mReloadButton);
+ hbox->addStretch(1);
+ lay->addLayout(hbox);
+ }
lay->addStretch(-1);
auto hLay = new QHBoxLayout(this);
hLay->addStretch(-1);
hLay->addLayout(lay);
hLay->addStretch(-1);
lay->addStretch(-1);
+
+ connect(mReloadButton, &QPushButton::clicked, this, &PlaceHolderWidget::reload);
}
+
+Q_SIGNALS:
+ void reload();
+
+private:
+ QPushButton *mReloadButton = nullptr;
};
} // namespace
class SmartCardWidget::Private
{
friend class ::Kleo::SmartCardWidget;
public:
Private(SmartCardWidget *qq);
void cardAddedOrChanged(const std::string &serialNumber, const std::string &appName);
void cardRemoved(const std::string &serialNumber, const std::string &appName);
private:
template <typename C, typename W>
void cardAddedOrChanged(const std::string &serialNumber);
private:
SmartCardWidget *const q;
QMap<std::pair<std::string, std::string>, QPointer<QWidget>> mCardWidgets;
PlaceHolderWidget *mPlaceHolderWidget;
QStackedWidget *mStack;
QTabWidget *mTabWidget;
};
SmartCardWidget::Private::Private(SmartCardWidget *qq)
: q{qq}
{
auto vLay = new QVBoxLayout(q);
vLay->addWidget(new QLabel(QStringLiteral("<h2>") + i18n("Smartcard Management") +
QStringLiteral("</h2>")));
mStack = new QStackedWidget;
vLay->addWidget(mStack);
mPlaceHolderWidget = new PlaceHolderWidget;
mStack->addWidget(mPlaceHolderWidget);
mTabWidget = new QTabWidget;
mStack->addWidget(mTabWidget);
mStack->setCurrentWidget(mPlaceHolderWidget);
+ connect(mPlaceHolderWidget, &PlaceHolderWidget::reload, q, &SmartCardWidget::reload);
connect(ReaderStatus::instance(), &ReaderStatus::cardAdded,
q, [this] (const std::string &serialNumber, const std::string &appName) { cardAddedOrChanged(serialNumber, appName); });
connect(ReaderStatus::instance(), &ReaderStatus::cardChanged,
q, [this] (const std::string &serialNumber, const std::string &appName) { cardAddedOrChanged(serialNumber, appName); });
connect(ReaderStatus::instance(), &ReaderStatus::cardRemoved,
q, [this] (const std::string &serialNumber, const std::string &appName) { cardRemoved(serialNumber, appName); });
}
void SmartCardWidget::Private::cardAddedOrChanged(const std::string &serialNumber, const std::string &appName)
{
if (appName == SmartCard::NetKeyCard::AppName) {
cardAddedOrChanged<NetKeyCard, NetKeyWidget>(serialNumber);
} else if (appName == SmartCard::OpenPGPCard::AppName) {
cardAddedOrChanged<OpenPGPCard, PGPCardWidget>(serialNumber);
} else if (appName == SmartCard::PIVCard::AppName) {
cardAddedOrChanged<PIVCard, PIVCardWidget>(serialNumber);
} else if (appName == SmartCard::P15Card::AppName) {
cardAddedOrChanged<P15Card, P15CardWidget>(serialNumber);
} else {
qCWarning(KLEOPATRA_LOG) << "SmartCardWidget::Private::cardAddedOrChanged:"
<< "App" << appName.c_str() << "is not supported";
}
}
namespace {
static QString getCardLabel(const std::shared_ptr<Card> &card) {
if (!card->cardHolder().isEmpty()) {
return i18nc("@title:tab smartcard application - name of card holder - serial number of smartcard", "%1 - %2 - %3",
displayAppName(card->appName()), card->cardHolder(), card->displaySerialNumber());
} else {
return i18nc("@title:tab smartcard application - serial number of smartcard", "%1 - %2",
displayAppName(card->appName()), card->displaySerialNumber());
}
}
}
template <typename C, typename W>
void SmartCardWidget::Private::cardAddedOrChanged(const std::string &serialNumber)
{
const auto card = ReaderStatus::instance()->getCard<C>(serialNumber);
if (!card) {
qCWarning(KLEOPATRA_LOG) << "SmartCardWidget::Private::cardAddedOrChanged:"
<< "New or changed card" << serialNumber.c_str() << "with app" << C::AppName.c_str() << "not found";
return;
}
W *cardWidget = dynamic_cast<W *>(mCardWidgets.value({serialNumber, C::AppName}).data());
if (!cardWidget) {
cardWidget = new W;
mCardWidgets.insert({serialNumber, C::AppName}, cardWidget);
mTabWidget->addTab(cardWidget, getCardLabel(card));
if (mCardWidgets.size() == 1) {
mStack->setCurrentWidget(mTabWidget);
}
}
cardWidget->setCard(card.get());
}
void SmartCardWidget::Private::cardRemoved(const std::string &serialNumber, const std::string &appName)
{
QWidget * cardWidget = mCardWidgets.take({serialNumber, appName});
if (cardWidget) {
const int index = mTabWidget->indexOf(cardWidget);
if (index != -1) {
mTabWidget->removeTab(index);
}
delete cardWidget;
}
if (mCardWidgets.empty()) {
mStack->setCurrentWidget(mPlaceHolderWidget);
}
}
SmartCardWidget::SmartCardWidget(QWidget *parent)
: QWidget{parent}
, d{std::make_unique<Private>(this)}
{
}
Kleo::SmartCardWidget::~SmartCardWidget() = default;
QWidget *getFirstEnabledFocusWidget(QWidget *parent)
{
for (auto w = parent->nextInFocusChain(); w != parent; w = w->nextInFocusChain()) {
if (w->isEnabled() && (w->focusPolicy() != Qt::NoFocus)) {
return w;
}
}
return nullptr;
}
void SmartCardWidget::focusFirstChild(Qt::FocusReason reason)
{
if (d->mStack->currentWidget() == d->mPlaceHolderWidget) {
if (auto w = getFirstEnabledFocusWidget(d->mPlaceHolderWidget)) {
w->setFocus(reason);
}
} else if (auto cardWidget = d->mTabWidget->currentWidget()) {
if (auto w = getFirstEnabledFocusWidget(cardWidget)) {
w->setFocus(reason);
}
}
}
void SmartCardWidget::reload()
{
ReaderStatus::mutableInstance()->updateStatus();
}
#include "smartcardwidget.moc"

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:44 PM (16 h, 1 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
62/82/a9e5c16ae781c7f5e8bb07e00416

Event Timeline