From 2d0980d4f6b8277447bc9646c27e1d38c5a98373 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Fri, 3 Apr 2020 23:52:44 +0200 Subject: [PATCH] Use pkcs11_lib_list as model for Options:pkcs11list Change pkcs11List from QListWidget to QListView The pkcs11_lib_list holds the data of the loaded libraries. For the model a QList "model_data" is used to hold indexes into QList dirs to allow duplicates, moves and removes. On windows it now displays the paths with \ separators. --- lib/pkcs11.cpp | 48 +-------- lib/pkcs11.h | 32 +----- lib/pkcs11_lib.cpp | 216 ++++++++++++++++++++++++++++++++++----- lib/pkcs11_lib.h | 62 +++++++++-- lib/pki_scard.cpp | 2 +- lib/pki_x509.cpp | 4 +- ui/Options.ui | 5 +- widgets/CertTreeView.cpp | 2 +- widgets/KeyTreeView.cpp | 4 +- widgets/MW_database.cpp | 6 +- widgets/MW_menu.cpp | 3 +- widgets/MainWindow.cpp | 15 ++- widgets/NewKey.cpp | 2 +- widgets/Options.cpp | 105 +++---------------- widgets/Options.h | 9 +- widgets/SearchPkcs11.cpp | 1 + 16 files changed, 284 insertions(+), 232 deletions(-) diff --git a/lib/pkcs11.cpp b/lib/pkcs11.cpp index b9b4ce57..8b15cd91 100644 --- a/lib/pkcs11.cpp +++ b/lib/pkcs11.cpp @@ -27,7 +27,7 @@ #include "openssl_compat.h" -pkcs11_lib_list pkcs11::libs; +pkcs11_lib_list pkcs11::libraries; pkcs11::pkcs11() { @@ -44,52 +44,6 @@ pkcs11::~pkcs11() } } -pkcs11_lib *pkcs11::load_lib(const QString &fname) -{ - if (fname.isEmpty()) - return NULL; - return libs.add_lib(fname); -} - -void pkcs11::reload_libs(const QString &libnames) -{ - QMap store; - - if (libnames.isEmpty()) { - remove_libs(); - return; - } - - for (pkcs11_lib_list::iterator i = libs.begin(); i != libs.end(); ++i) - store[(*i)->filename()] = *i; - libs.clear(); - - foreach(QString name, libnames.split('\n')) { - bool enable; - QString n = pkcs11_lib::name2File(name, &enable); - pkcs11_lib *l = store.take(n); - if (l) { - if (enable == l->isEnabled()) { - libs.append(l); - } else { - delete l; - l = NULL; - } - } - // NOT else - if (!l) - l = load_lib(name); - - qDebug() << "REORDER:" << n << name - << "Enabled:" << l->isEnabled() - << "Loaded:" << l->isLoaded() - << "Should:" << enable; - } - qDebug() << "Delete remainig Libs start"; - qDeleteAll(store); - qDebug() << "Delete remainig Libs done"; -} - void pkcs11::startSession(slotid slot, bool rw) { CK_RV rv; diff --git a/lib/pkcs11.h b/lib/pkcs11.h index d978694d..fa35bbcd 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -102,43 +102,15 @@ class pkcs11 friend class pk11_attr_data; private: - static pkcs11_lib_list libs; slotid p11slot; CK_SESSION_HANDLE session; CK_OBJECT_HANDLE p11obj; public: + static pkcs11_lib_list libraries; pkcs11(); ~pkcs11(); - static bool loaded() - { - foreach(pkcs11_lib *l, libs) { - if (l->isLoaded()) - return true; - } - return false; - } - static pkcs11_lib *load_lib(const QString &fname); - static pkcs11_lib *get_lib(const QString &fname) - { - return libs.get_lib(fname); - } - static bool remove_lib(QString fname) - { - return libs.remove_lib(fname); - } - static void remove_libs() - { - qDeleteAll(libs); - libs.clear(); - } - static void reload_libs(const QString &libnames); - static pkcs11_lib_list get_libs() - { - return libs; - } - tkInfo tokenInfo(slotid slot); tkInfo tokenInfo() { @@ -150,7 +122,7 @@ class pkcs11 } slotidList getSlotList() { - return libs.getSlotList(); + return libraries.getSlotList(); } bool selectToken(slotid *slot, QWidget *w); diff --git a/lib/pkcs11_lib.cpp b/lib/pkcs11_lib.cpp index 8d588c64..6e034427 100644 --- a/lib/pkcs11_lib.cpp +++ b/lib/pkcs11_lib.cpp @@ -114,7 +114,7 @@ QList pkcs11_lib::getSlotList() return sl; } -QString pkcs11_lib::driverInfo() +QString pkcs11_lib::driverInfo() const { CK_INFO info; CK_RV rv; @@ -154,48 +154,75 @@ QString pkcs11_lib::name2File(const QString &name, bool *enabled) if (enabled) *enabled = ena[0] != '0'; } - return libname; + return relativePath(libname); } pkcs11_lib *pkcs11_lib_list::add_lib(const QString &fname) { - foreach(pkcs11_lib *l, *this) { - if (l->isLib(fname)) + int idx = -1; + pkcs11_lib *l = NULL; + + if (fname.isEmpty()) + return NULL; + + for (int i = 0; i < libs.size(); i++) { + l = libs[i]; + if (!l->isLib(fname)) + continue; + if (model_data.contains(i)) return l; + idx = i; + break; } - pkcs11_lib *l = new pkcs11_lib(fname); - append(l); + if (idx == -1) { + pkcs11_lib *l = new pkcs11_lib(fname); + idx = libs.size(); + libs << l; + } + beginInsertRows(QModelIndex(), model_data.size(), model_data.size()); + model_data << idx; + endInsertRows(); return l; } -pkcs11_lib *pkcs11_lib_list::get_lib(const QString &fname) +void pkcs11_lib_list::load(const QString &list) { - foreach(pkcs11_lib *l, *this) { - if (l->isLib(fname)) - return l; - } - return NULL; -} - -bool pkcs11_lib_list::remove_lib(const QString &fname) -{ - for(int i=0; iisLib(fname)) { - delete takeAt(i); - return true; + beginResetModel(); + QString orig = getPkcs11Provider(); + QList newlist; + foreach(QString name, list.split('\n')) { + pkcs11_lib *newitem = NULL; + name = name.trimmed(); + if (name.isEmpty()) + continue; + for (int i = 0; i < libs.size(); i++) { + if (name == libs[i]->toData()) { + newitem = libs.takeAt(i); + break; + } } + if (!newitem) { + newitem = new pkcs11_lib(name); + } + newlist << newitem; } - return false; + qDeleteAll(libs); + libs = newlist; + model_data.clear(); + for (int i = 0; i < libs.size(); i++) + model_data << i; + + endResetModel(); + qDebug() << "Libs reloaded from" << orig << "to" << getPkcs11Provider(); } -slotidList pkcs11_lib_list::getSlotList() +slotidList pkcs11_lib_list::getSlotList() const { slotidList list; QString ex; bool success = false; - for (int i=0; iisLoaded()) continue; try { @@ -213,6 +240,147 @@ slotidList pkcs11_lib_list::getSlotList() throw errorEx(ex); } +QString pkcs11_lib_list::getPkcs11Provider() const +{ + QStringList prov; + foreach(int i, model_data) + prov << libs[i]->toData(); + return prov.size() == 0 ? QString() : prov.join("\n"); +} + +void pkcs11_lib_list::remove_libs() +{ + beginRemoveRows(QModelIndex(), 0, libs.size() -1); + qDeleteAll(libs); + libs.clear(); + model_data.clear(); + endRemoveRows(); +} + +bool pkcs11_lib_list::loaded() const +{ + foreach(pkcs11_lib *l, libs) + if (l->isLoaded()) + return true; + return false; +} + +int pkcs11_lib_list::rowCount(const QModelIndex &) const +{ + return model_data.size(); +} + +pkcs11_lib *pkcs11_lib_list::libByModelIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return NULL; + int idx = model_data[index.row()]; + return (idx >= 0 && idx < libs.size()) ? libs[idx] : NULL; +} + +QVariant pkcs11_lib_list::data(const QModelIndex &index, int role) const +{ + pkcs11_lib *l = libByModelIndex(index); + if (!l) + return QVariant(); + + QString pixmap; + + switch (role) { + case Qt::DisplayRole: + return QVariant(nativeSeparator(l->filename())); + case Qt::DecorationRole: + pixmap = l->pixmap(); + if (pixmap.isEmpty()) { + QPixmap p(QSize(20, 20)); + p.fill(Qt::transparent); + return QVariant(p); + } + return QVariant(QPixmap(pixmap)); + case Qt::ToolTipRole: + return QVariant(l->driverInfo().trimmed()); + case Qt::CheckStateRole: + return l->checked(); + } + return QVariant(); +} + +QMap pkcs11_lib_list::itemData(const QModelIndex &index) const +{ + QMap map; + if (index.isValid()) + map[Qt::UserRole] = QVariant(model_data[index.row()]); + return map; +} + +bool pkcs11_lib_list::setItemData(const QModelIndex &index, + const QMap &roles) +{ + if (index.isValid() && roles[Qt::UserRole].isValid()) { + model_data[index.row()] = roles[Qt::UserRole].toInt(); + return true; + } + return false; +} + +bool pkcs11_lib_list::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + pkcs11_lib *l = libByModelIndex(index); + if (!l || role != Qt::CheckStateRole) + return false; + + if (value == l->checked()) { + /* No changes */ + return true; + } + QString file = l->toData(value == Qt::Checked); + + delete l; + int idx = model_data[index.row()]; + libs[idx] = new pkcs11_lib(file); + + emit dataChanged(index, index); + return true; +} + +Qt::ItemFlags pkcs11_lib_list::flags(const QModelIndex & index) const +{ + if (index.isValid()) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | + Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable; + return QAbstractListModel::flags(index) | Qt::ItemIsDropEnabled; +} + +Qt::DropActions pkcs11_lib_list::supportedDropActions() const +{ + return Qt::MoveAction; +} + +bool pkcs11_lib_list::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid() || row < 0 || row + count > model_data.size()) + return false; + + beginRemoveRows(parent, row, row + count - 1); + while (count-- > 0 && row < model_data.size()) + model_data.removeAt(row); + endRemoveRows(); + return true; +} + +bool pkcs11_lib_list::insertRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid()) + return false; + + beginInsertRows(parent, row, row +count -1); + for (int i = 0; i < count; i++) + model_data.insert(row +i, 0); + endInsertRows(); + return true; +} + const char *pk11errorString(unsigned long rv) { #define PK11_ERR(x) case x : return #x; diff --git a/lib/pkcs11_lib.h b/lib/pkcs11_lib.h index ef13afb0..025816a7 100644 --- a/lib/pkcs11_lib.h +++ b/lib/pkcs11_lib.h @@ -10,8 +10,11 @@ #include "lib/exception.h" #include "opensc-pkcs11.h" +#include #include +#include #include +#include #include @@ -30,12 +33,12 @@ class pkcs11_lib ~pkcs11_lib(); QList getSlotList(); - QString driverInfo(); - QString filename() + QString driverInfo() const; + QString filename() const { return file; } - CK_FUNCTION_LIST *ptr() + CK_FUNCTION_LIST *ptr() const { return p11; } @@ -43,14 +46,28 @@ class pkcs11_lib { return p11 != NULL; } - bool isEnabled() const + enum Qt::CheckState checked() const { - return enabled; + return enabled ? Qt::Checked : Qt::Unchecked; } - bool isLib(const QString &name) + bool isLib(const QString &name) const { return name2File(name) == file; } + QString toData(int enabled) const + { + return QString("%1:%2").arg(enabled).arg(file); + } + QString toData() const + { + return toData(enabled); + } + QString pixmap() const + { + if (!enabled) + return QString(); + return isLoaded() ? ":doneIco" : ":warnIco"; + } }; class slotid @@ -84,7 +101,7 @@ class slotid if (!lib) throw errorEx("InternalError: slotid is invalid"); } - CK_FUNCTION_LIST *p11() + CK_FUNCTION_LIST *p11() const { return lib->ptr(); } @@ -92,13 +109,36 @@ class slotid typedef QList slotidList; -class pkcs11_lib_list: public QList +class pkcs11_lib_list: public QAbstractListModel { + QList libs; + QList model_data; + public: pkcs11_lib *add_lib(const QString &fname); - pkcs11_lib *get_lib(const QString &fname); - bool remove_lib(const QString &fname); - slotidList getSlotList(); + void load(const QString &list); + slotidList getSlotList() const; + QString getPkcs11Provider() const; + void remove_libs(); + bool loaded() const; + + /* Helper for QAbstractListModel */ + pkcs11_lib *libByModelIndex(const QModelIndex &index) const; + + /* Reimplementation from QAbstractListModel */ + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, + int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + + QMap itemData(const QModelIndex &index) const; + bool setItemData(const QModelIndex &index, const QMap &roles); + + Qt::ItemFlags flags(const QModelIndex& index) const; + Qt::DropActions supportedDropActions() const; + + bool removeRows(int row, int count, const QModelIndex &p = QModelIndex()); + bool insertRows(int row, int count, const QModelIndex &p = QModelIndex()); }; void pk11error(const QString &fmt, int r); diff --git a/lib/pki_scard.cpp b/lib/pki_scard.cpp index f9d44150..5df75f43 100644 --- a/lib/pki_scard.cpp +++ b/lib/pki_scard.cpp @@ -615,7 +615,7 @@ bool pki_scard::find_key_on_card(slotid *slot) const * returns the slot ID in slot true on success */ bool pki_scard::prepare_card(slotid *slot) const { - if (!pkcs11::loaded()) + if (!pkcs11::libraries.loaded()) return false; QString msg = tr("Please insert card: %1 %2 [%3] with Serial: %4"). diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index f202529b..bf917e7e 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -385,7 +385,7 @@ void pki_x509::deleteFromToken() pki_scard *card = dynamic_cast(privkey); slotidList p11_slots; - if (!card || !pkcs11::loaded()) + if (!card || !pkcs11::libraries.loaded()) return; if (privkey && privkey->isToken()) { @@ -542,7 +542,7 @@ bool pki_x509::canSign() const pki_key *privkey = getRefKey(); if (!privkey || privkey->isPubKey()) return false; - if (privkey->isToken() && !pkcs11::loaded()) + if (privkey->isToken() && !pkcs11::libraries.loaded()) return false; return isCA(); } diff --git a/ui/Options.ui b/ui/Options.ui index 0efad93a..71044b73 100644 --- a/ui/Options.ui +++ b/ui/Options.ui @@ -325,10 +325,13 @@ Especially EC and DSA are only defined with SHA1 in the PKCS#11 specification. - + true + + true + false diff --git a/widgets/CertTreeView.cpp b/widgets/CertTreeView.cpp index 73cc4a98..390e221f 100644 --- a/widgets/CertTreeView.cpp +++ b/widgets/CertTreeView.cpp @@ -34,7 +34,7 @@ void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport, privkey = cert->getRefKey(); parent = cert->getSigner(); parentCanSign = parent && parent->canSign() && (parent != cert); - hasScard = pkcs11::loaded(); + hasScard = pkcs11::libraries.loaded(); multi = indexes.size() > 1; diff --git a/widgets/KeyTreeView.cpp b/widgets/KeyTreeView.cpp index ef27305c..a1b929b7 100644 --- a/widgets/KeyTreeView.cpp +++ b/widgets/KeyTreeView.cpp @@ -37,7 +37,7 @@ void KeyTreeView::fillContextMenu(QMenu *menu, QMenu *subExport, } } - if (!pkcs11::loaded() || multi) + if (!pkcs11::libraries.loaded() || multi) return; if (key->isToken()) { @@ -133,7 +133,7 @@ void KeyTreeView::toToken() return; pki_key *key = static_cast(currentIdx.internalPointer()); - if (!key || !pkcs11::loaded() || key->isToken()) + if (!key || !pkcs11::libraries.loaded() || key->isToken()) return; pki_scard *card = NULL; diff --git a/widgets/MW_database.cpp b/widgets/MW_database.cpp index 57b00d0e..bb01a40b 100644 --- a/widgets/MW_database.cpp +++ b/widgets/MW_database.cpp @@ -356,8 +356,6 @@ void MainWindow::timerEvent(QTimerEvent *event) return; stamp = q.value(0).toULongLong(); q.finish(); - qDebug() << "Stamp" << stamp - << "DatabaseStamp" << DbTransaction::DatabaseStamp; if (stamp > DbTransaction::DatabaseStamp) { SQL_PREPARE(q, "SELECT DISTINCT type FROM items WHERE stamp=?"); @@ -544,8 +542,8 @@ void MainWindow::close_database() update_history(currentDB); - pkcs11::remove_libs(); - enableTokenMenu(pkcs11::loaded()); + pkcs11::libraries.remove_libs(); + enableTokenMenu(pkcs11::libraries.loaded()); QSqlDatabase::removeDatabase(connName); currentDB.clear(); Settings.clear(); diff --git a/widgets/MW_menu.cpp b/widgets/MW_menu.cpp index bb1ca9e9..23c6a426 100644 --- a/widgets/MW_menu.cpp +++ b/widgets/MW_menu.cpp @@ -240,6 +240,5 @@ void MainWindow::setOptions() } delete opt; - pkcs11::reload_libs(Settings["pkcs11path"]); - enableTokenMenu(pkcs11::loaded()); + load_engine(); } diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 5314a22d..b593b19c 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -61,9 +61,8 @@ void MainWindow::enableTokenMenu(bool enable) void MainWindow::load_engine() { - pkcs11::reload_libs(Settings["pkcs11path"]); - // Error(err); - enableTokenMenu(pkcs11::loaded()); + pkcs11::libraries.load(Settings["pkcs11path"]); + enableTokenMenu(pkcs11::libraries.loaded()); } void MainWindow::initResolver() @@ -218,7 +217,7 @@ void MainWindow::setItemEnabled(bool enable) foreach(QAction *a, acList) { a->setEnabled(enable); } - enableTokenMenu(pkcs11::loaded()); + enableTokenMenu(pkcs11::libraries.loaded()); } void MainWindow::init_images() @@ -377,7 +376,7 @@ void MainWindow::pastePem() void MainWindow::initToken() { bool ok; - if (!pkcs11::loaded()) + if (!pkcs11::libraries.loaded()) return; try { pkcs11 p11; @@ -418,7 +417,7 @@ void MainWindow::initToken() void MainWindow::changePin(bool so) { - if (!pkcs11::loaded()) + if (!pkcs11::libraries.loaded()) return; try { pkcs11 p11; @@ -439,7 +438,7 @@ void MainWindow::changeSoPin() void MainWindow::initPin() { - if (!pkcs11::loaded()) + if (!pkcs11::libraries.loaded()) return; try { pkcs11 p11; @@ -462,7 +461,7 @@ void MainWindow::manageToken() pki_x509 *cert = NULL; ImportMulti *dlgi = NULL; - if (!pkcs11::loaded()) + if (!pkcs11::libraries.loaded()) return; try { diff --git a/widgets/NewKey.cpp b/widgets/NewKey.cpp index f16bc8a1..b7750f35 100644 --- a/widgets/NewKey.cpp +++ b/widgets/NewKey.cpp @@ -147,7 +147,7 @@ NewKey::NewKey(QWidget *parent, QString name) updateCurves(); keyLength->setEditText(QString::number(defaultSize) + " bit"); keyDesc->setFocus(); - if (pkcs11::loaded()) try { + if (pkcs11::libraries.loaded()) try { pkcs11 p11; p11_slots = p11.getSlotList(); diff --git a/widgets/Options.cpp b/widgets/Options.cpp index 514cc9ef..9a3ee377 100644 --- a/widgets/Options.cpp +++ b/widgets/Options.cpp @@ -14,11 +14,9 @@ #include #include -Options::Options(MainWindow *parent) +Options::Options(QWidget *parent) :QDialog(parent) { - mw = parent; - setWindowTitle(XCA_TITLE); setupUi(this); @@ -45,7 +43,6 @@ Options::Options(MainWindow *parent) setDnString(Settings["mandatory_dn"], extDNlist); setDnString(Settings["explicit_dn"], expDNlist); - setupPkcs11Provider(Settings["pkcs11path"]); suppress->setCheckState(Settings["suppress_messages"]); noColorize->setCheckState(Settings["no_expire_colors"]); @@ -69,8 +66,10 @@ Options::Options(MainWindow *parent) cert_expiry_num->setText(x); serial_len->setValue(Settings["serial_len"]); - connect(pkcs11List, SIGNAL(itemClicked(QListWidgetItem *)), - this, SLOT(Pkcs11ItemChanged(QListWidgetItem *))); + + pkcs11List->setModel(&pkcs11::libraries); + pkcs11List->showDropIndicator(); + pkcs11List->setSelectionMode(QAbstractItemView::ExtendedSelection); } Options::~Options() @@ -147,7 +146,7 @@ int Options::exec() Settings["mandatory_dn"] = getDnString(extDNlist); Settings["explicit_dn"] = getDnString(expDNlist); Settings["string_opt"] = string_opts[mbstring->currentIndex()]; - Settings["pkcs11path"] = getPkcs11Provider(); + Settings["pkcs11path"] = pkcs11::libraries.getPkcs11Provider(); Settings["cert_expiry"] = cert_expiry_num->text() + cert_expiry_unit->currentItemData().toString(); @@ -172,15 +171,8 @@ void Options::on_addButton_clicked(void) void Options::addLib(QString fname) { - QString status; - fname = QFileInfo(fname).canonicalFilePath(); - - if (fname.isEmpty() || pkcs11::get_lib(fname)) - return; - - pkcs11_lib *l = pkcs11::load_lib(fname); - addLibItem(fname); + pkcs11_lib *l = pkcs11::libraries.add_lib(fname); if (searchP11 && l) QToolTip::showText(searchP11->mapToGlobal( @@ -189,14 +181,14 @@ void Options::addLib(QString fname) void Options::on_removeButton_clicked(void) { - QListWidgetItem *item = pkcs11List->takeItem(pkcs11List->currentRow()); - if (!item) - return; - try { - pkcs11::remove_lib(item->text()); - } catch (errorEx &err) { - mw->Error(err); - } + QList indexes; + foreach(QModelIndex i, pkcs11List->selectionModel()->selectedIndexes()) + indexes << i.row(); + + /* Delete from highest to lowest index */ + qSort(indexes.begin(), indexes.end(), qGreater()); + foreach(int i, indexes) + pkcs11List->model()->removeRow(i); } void Options::on_searchPkcs11_clicked(void) @@ -208,70 +200,3 @@ void Options::on_searchPkcs11_clicked(void) } searchP11->show(); } - -void Options::Pkcs11ItemChanged(QListWidgetItem *item) -{ - pkcs11List->blockSignals(true); - pkcs11_lib *l = pkcs11::get_libs().get_lib(item->text()); - qDebug() << item->text() << item->checkState() << l->isEnabled() << l->isLoaded(); - if ((item->checkState() == Qt::Checked) != l->isEnabled()) { - QString file = listItem2Name(item); - pkcs11::remove_lib(file); - pkcs11::load_lib(file); - updatePkcs11Item(item); - } - pkcs11List->blockSignals(false); -} - -void Options::updatePkcs11Item(QListWidgetItem *item) const -{ - pkcs11_lib *l = pkcs11::get_libs().get_lib(item->text()); - if (!l) - return; - if (l->isEnabled()) { - item->setIcon(QPixmap(l->isLoaded() ? ":doneIco" : ":warnIco")); - } else { - QPixmap m(QSize(20,20)); - m.fill(Qt::transparent); - item->setIcon(QIcon(m)); - } - item->setToolTip(l->driverInfo().trimmed()); -} - -QListWidgetItem *Options::addLibItem(const QString &lib) const -{ - pkcs11_lib *l = pkcs11::get_libs().get_lib(lib); - if (!l) - return NULL; - QListWidgetItem *item = new QListWidgetItem(lib); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - updatePkcs11Item(item); - item->setText(l->filename()); - item->setCheckState(l->isEnabled() ? Qt::Checked : Qt::Unchecked); - pkcs11List->addItem(item); - return item; -} - -void Options::setupPkcs11Provider(QString list) -{ - foreach(QString libname, list.split('\n')) { - addLibItem(libname); - } -} - -QString Options::listItem2Name(const QListWidgetItem *item) const -{ - return QString("%1:%2").arg(item->checkState() == Qt::Checked) - .arg(item->text()); -} - -QString Options::getPkcs11Provider() -{ - QStringList prov; - for (int j=0; jcount(); j++) { - prov << listItem2Name(pkcs11List->item(j)); - } - if (prov.count() == 0) - return QString(""); - return prov.join("\n"); -} diff --git a/widgets/Options.h b/widgets/Options.h index 4613912e..950fc7b3 100644 --- a/widgets/Options.h +++ b/widgets/Options.h @@ -22,17 +22,11 @@ class Options: public QDialog, public Ui::Options QStringList string_opts; QString getDnString(QListWidget *w); void setDnString(QString dn, QListWidget *w); - void setupPkcs11Provider(QString list); - QString getPkcs11Provider(); - MainWindow *mw; - QString listItem2Name(const QListWidgetItem *item) const; - void updatePkcs11Item(QListWidgetItem *item) const; public: - Options(MainWindow *parent); + Options(QWidget *parent); ~Options(); int exec(); - QListWidgetItem *addLibItem(const QString &) const; public slots: void on_extDNadd_clicked(); @@ -44,7 +38,6 @@ class Options: public QDialog, public Ui::Options void on_removeButton_clicked(void); void on_searchPkcs11_clicked(void); void addLib(QString); - void Pkcs11ItemChanged(QListWidgetItem *); }; #endif diff --git a/widgets/SearchPkcs11.cpp b/widgets/SearchPkcs11.cpp index da12c2ac..f48c37a7 100644 --- a/widgets/SearchPkcs11.cpp +++ b/widgets/SearchPkcs11.cpp @@ -26,6 +26,7 @@ SearchPkcs11::SearchPkcs11(QWidget *parent, const QString &fname) filename->setText(nativeSeparator(fname)); setWindowTitle(XCA_TITLE); + liblist->setSelectionMode(QAbstractItemView::ExtendedSelection); searching = NULL; }