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 
31 using namespace Kleo;
32 
33 class ReaderPortSelection::Private
34 {
35 public:
36  Private(ReaderPortSelection *q);
37 
38  void setValue(const QString &value);
39  QString value() const;
40 
41 private:
42  void onCurrentIndexChanged(int);
43  void onEditTextChanged(const QString &);
44 
45 private:
46  ReaderPortSelection *const q = nullptr;
47  QComboBox *const mComboBox = nullptr;
48 };
49 
50 ReaderPortSelection::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 
89 void 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 
104 QString ReaderPortSelection::Private::value() const
105 {
106  return mComboBox->currentData().toString();
107 }
108 
109 void 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 
118 void 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 
128 ReaderPortSelection::ReaderPortSelection(QWidget *parent)
129  : QWidget{parent}
130  , d{new Private{this}}
131 {
132 }
133 
134 ReaderPortSelection::~ReaderPortSelection() = default;
135 
136 void ReaderPortSelection::setValue(const QString &value)
137 {
138  d->setValue(value);
139 }
140 
141 QString 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 fromStdString(const std::string &str)
bool isEmpty() const const
int count() const const
void currentIndexChanged(int index)
void setContentsMargins(int left, int top, int right, int bottom)
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 editTextChanged(const QString &text)
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.