diff --git a/src/dialogs/cardinfotab.cpp b/src/dialogs/cardinfotab.cpp index 7cea5db96..d941820ab 100644 --- a/src/dialogs/cardinfotab.cpp +++ b/src/dialogs/cardinfotab.cpp @@ -1,181 +1,181 @@ // SPDX-FileCopyrightText: 2024 g10 Code GmbH // SPDX-FileContributor: Tobias Fella // SPDX-License-Identifier: GPL-2.0-or-later #include "cardinfotab.h" -#include "smartcard/openpgpcard.h" +#include "smartcard/card.h" #include "smartcard/readerstatus.h" #include "view/smartcardwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kleopatra_debug.h" using namespace Kleo; using namespace SmartCard; class CardInfoTab::Private { friend class ::Kleo::CardInfoTab; CardInfoTab *const q; void loadData(); private: GpgME::Key key; TreeWidget *subkeysTree = nullptr; QLabel *placeholderLabel = nullptr; QPushButton *reloadButton = nullptr; public: Private(CardInfoTab *qq) : q{qq} { auto vLay = new QVBoxLayout(q); vLay->setContentsMargins({}); vLay->setSpacing(0); subkeysTree = new TreeWidget{q}; subkeysTree->setAccessibleName(i18n("Subkeys")); subkeysTree->setAllColumnsShowFocus(false); subkeysTree->setSelectionMode(QAbstractItemView::SingleSelection); subkeysTree->setRootIsDecorated(false); subkeysTree->setHeaderLabels({ i18nc("@title:column", "Keygrip"), i18nc("@title:column", "Token"), i18nc("@title:column", "Type"), i18nc("@title:column", "Serial Number"), i18nc("@title:column", "Owner"), }); vLay->addWidget(subkeysTree); placeholderLabel = new QLabel(i18nc("@info", "Smartcard information is only available for your own certificates.")); placeholderLabel->setVisible(false); placeholderLabel->setAlignment(Qt::AlignHCenter); vLay->addWidget(placeholderLabel); auto separator = new KSeparator(q); vLay->addWidget(separator); auto bbox = new QHBoxLayout; reloadButton = new QPushButton(i18nc("@action:button", "Reload")); bbox->addWidget(reloadButton); bbox->addStretch(1); vLay->addLayout(bbox); } }; CardInfoTab::CardInfoTab(QWidget *parent) : QWidget{parent} , d{std::make_unique(this)} { connect(d->reloadButton, &QPushButton::clicked, this, []() { ReaderStatus::mutableInstance()->updateStatus(); }); connect(ReaderStatus::instance(), &ReaderStatus::cardAdded, this, [this]() { d->loadData(); }); connect(ReaderStatus::instance(), &ReaderStatus::cardChanged, this, [this]() { d->loadData(); }); connect(ReaderStatus::instance(), &ReaderStatus::cardRemoved, this, [this]() { d->loadData(); }); } CardInfoTab::~CardInfoTab() = default; GpgME::Key CardInfoTab::key() const { return d->key; } void CardInfoTab::Private::loadData() { subkeysTree->clear(); for (const auto &subkey : key.subkeys()) { const auto &cards = KeyCache::instance()->cardsForSubkey(subkey); for (const auto &info : cards) { auto availableCard = SmartCard::ReaderStatus::instance()->getCardWithKeyRef(info.serialNumber.toStdString(), info.keyRef.toStdString()); auto item = new QTreeWidgetItem; item->setData(0, Qt::DisplayRole, QString::fromLatin1(subkey.keyGrip())); item->setData(1, Qt::DisplayRole, info.serialNumber); if (availableCard) { const QString manufacturer = QString::fromStdString(availableCard->manufacturer()); const bool manufacturerIsUnknown = manufacturer.isEmpty() || manufacturer == QLatin1StringView("unknown"); item->setData( 2, Qt::DisplayRole, manufacturerIsUnknown ? i18nc("Unknown (card)", "Unknown %1 v%2", availableCard->displayAppName(), availableCard->displayAppVersion()) : i18nc(" ", "%1 %2 v%3", manufacturer, availableCard->displayAppName(), availableCard->displayAppVersion())); item->setData(3, Qt::DisplayRole, availableCard->displaySerialNumber()); item->setData(4, Qt::DisplayRole, availableCard->cardHolder().size() > 0 ? availableCard->cardHolder() : i18nc("unknown cardholder", "unknown")); item->setData(5, Qt::UserRole, QString::fromStdString(availableCard->appName())); } else { item->setData(2, Qt::DisplayRole, i18n("n/a")); if (!info.displaySerialNumber.isEmpty()) { item->setData(3, Qt::DisplayRole, info.displaySerialNumber); } else { item->setData(3, Qt::DisplayRole, i18n("n/a")); } item->setData(4, Qt::DisplayRole, i18n("n/a")); } subkeysTree->addTopLevelItem(item); } } for (int i = 0; i < subkeysTree->columnCount(); i++) { subkeysTree->resizeColumnToContents(i); } } void CardInfoTab::setKey(const GpgME::Key &key) { if (!key.hasSecret()) { d->subkeysTree->setVisible(false); d->placeholderLabel->setVisible(true); d->reloadButton->setEnabled(false); return; } d->key = key; d->subkeysTree->header()->resizeSections(QHeaderView::ResizeToContents); d->subkeysTree->restoreColumnLayout(QStringLiteral("CardInfoTab")); d->loadData(); for (int i = 0; i < d->subkeysTree->columnCount(); i++) { d->subkeysTree->resizeColumnToContents(i); } } #include "moc_cardinfotab.cpp"