Libkleo

readerportselection.cpp
1/*
2 ui/readerportselection.cpp
3
4 This file is part of libkleopatra
5 SPDX-FileCopyrightText: 2022 g10 Code GmbH
6 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11#include <config-libkleo.h>
12
13#include "readerportselection.h"
14
15#include <libkleo/scdaemon.h>
16
17#include <libkleo_debug.h>
18
19#include <KLocalizedString>
20
21#if __has_include(<QGpgME/Debug>)
22#include <QGpgME/Debug>
23#endif
24
25#include <QComboBox>
26#include <QHBoxLayout>
27#include <QLineEdit>
28
29#include <gpgme++/error.h>
30
31using namespace Kleo;
32
33class ReaderPortSelection::Private
34{
35public:
36 Private(ReaderPortSelection *q);
37
38 void setValue(const QString &value);
39 QString value() const;
40
41private:
42 void onCurrentIndexChanged(int);
43 void onEditTextChanged(const QString &);
44
45private:
46 ReaderPortSelection *const q = nullptr;
47 QComboBox *const mComboBox = nullptr;
48};
49
50ReaderPortSelection::Private::Private(Kleo::ReaderPortSelection *qq)
51 : q{qq}
52 , mComboBox{new QComboBox{qq}}
53{
54 auto layout = new QHBoxLayout{q};
55 layout->setContentsMargins({});
56 layout->addWidget(mComboBox);
57
58 mComboBox->addItem(i18nc("@item:inlistbox", "Default reader"), {});
59
60 GpgME::Error err;
61 const auto readers = SCDaemon::getReaders(err);
62 if (err) {
63 qCWarning(LIBKLEO_LOG) << "Getting available smart card readers failed:" << err;
64 } else {
65 std::for_each(std::begin(readers), std::end(readers), [this](const auto &reader) {
66 const auto readerId = QString::fromStdString(reader);
67 mComboBox->addItem(readerId, readerId);
68 });
69 }
70
71 mComboBox->addItem(QString{}, {});
72 mComboBox->setToolTip(xi18nc("@info:tooltip",
73 "<para>Select the smart card reader that GnuPG shall use.<list>"
74 "<item>The first item will make GnuPG use the first reader that is found.</item>"
75 "<item>The last item allows you to enter a custom reader ID or reader port number.</item>"
76 "<item>All other items represent readers that were found by GnuPG.</item>"
77 "</list></para>"));
78
79 connect(mComboBox, &QComboBox::currentIndexChanged, q, [this](int index) {
80 onCurrentIndexChanged(index);
81 Q_EMIT q->valueChanged(q->value());
82 });
83 connect(mComboBox, &QComboBox::editTextChanged, q, [this](const QString &text) {
84 onEditTextChanged(text);
85 Q_EMIT q->valueChanged(q->value());
86 });
87}
88
89void ReaderPortSelection::Private::setValue(const QString &value)
90{
91 if (value.isEmpty()) {
92 mComboBox->setCurrentIndex(0);
93 return;
94 }
95 const int indexOfValue = mComboBox->findData(value);
96 if (indexOfValue != -1) {
97 mComboBox->setCurrentIndex(indexOfValue);
98 } else {
99 mComboBox->setCurrentIndex(mComboBox->count() - 1);
100 mComboBox->setEditText(value);
101 }
102}
103
104QString ReaderPortSelection::Private::value() const
105{
106 return mComboBox->currentData().toString();
107}
108
109void ReaderPortSelection::Private::onCurrentIndexChanged(int index)
110{
111 // the last item serves as input for a custom entry
112 mComboBox->setEditable(index == mComboBox->count() - 1);
113 if (mComboBox->lineEdit()) {
114 mComboBox->lineEdit()->setPlaceholderText(i18nc("@item:inlistbox", "Custom reader ID or port number"));
115 }
116}
117
118void ReaderPortSelection::Private::onEditTextChanged(const QString &text)
119{
120 const int lastIndex = mComboBox->count() - 1;
121 // do not overwrite the text of the custom item with the text of another item
122 if (mComboBox->currentIndex() == lastIndex) {
123 mComboBox->setItemText(lastIndex, text);
124 mComboBox->setItemData(lastIndex, text);
125 }
126}
127
128ReaderPortSelection::ReaderPortSelection(QWidget *parent)
129 : QWidget{parent}
130 , d{new Private{this}}
131{
132}
133
134ReaderPortSelection::~ReaderPortSelection() = default;
135
136void ReaderPortSelection::setValue(const QString &value)
137{
138 d->setValue(value);
139}
140
141QString ReaderPortSelection::value() const
142{
143 return d->value();
144}
145
146#include "moc_readerportselection.cpp"
QString xi18nc(const char *context, const char *text, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KLEO_EXPORT std::vector< std::string > getReaders(GpgME::Error &err)
Returns the list of available smart card readers.
void setCurrentIndex(int index)
void currentIndexChanged(int index)
void editTextChanged(const QString &text)
int findData(const QVariant &data, int role, Qt::MatchFlags flags) const const
void setEditText(const QString &text)
void setContentsMargins(const QMargins &margins)
QObject * parent() const const
QString fromStdString(const std::string &str)
bool isEmpty() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.