diff options
Diffstat (limited to '')
-rw-r--r-- | include/gpg/GpgContext.h | 6 | ||||
-rw-r--r-- | include/gpg/Signature.h | 10 | ||||
-rw-r--r-- | include/gpg/UID.h | 4 | ||||
-rw-r--r-- | include/ui/keypair_details/KeyPairUIDTab.h | 32 | ||||
-rw-r--r-- | include/ui/widgets/KeyList.h | 6 | ||||
-rw-r--r-- | src/gpg/GpgContext.cpp | 43 | ||||
-rw-r--r-- | src/gpg/Signature.cpp | 3 | ||||
-rw-r--r-- | src/gpg/UID.cpp | 3 | ||||
-rw-r--r-- | src/ui/keypair_details/KeyNewUIDDialog.cpp | 2 | ||||
-rw-r--r-- | src/ui/keypair_details/KeyPairDetailTab.cpp | 28 | ||||
-rw-r--r-- | src/ui/keypair_details/KeyPairUIDTab.cpp | 320 | ||||
-rw-r--r-- | src/ui/keypair_details/KeyUIDSignDialog.cpp | 10 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.cpp | 29 |
13 files changed, 422 insertions, 74 deletions
diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h index ff4a9d20..a68c6490 100644 --- a/include/gpg/GpgContext.h +++ b/include/gpg/GpgContext.h @@ -110,12 +110,18 @@ namespace GpgME { bool signKey(const GpgKey &target, const QString& uid, const QDateTime *expires); + bool revSign(const GpgKey &key, const Signature &signature); + gpgme_signature_t verify(QByteArray *inBuffer, QByteArray *sigBuffer = nullptr); bool sign(QStringList *uidList, const QByteArray &inBuffer, QByteArray *outBuffer, bool detached = false); bool addUID(const GpgKey &key, const UID &uid); + bool revUID(const GpgKey &key, const UID &uid); + + bool setPrimaryUID(const GpgKey &key, const UID &uid); + /** * @details If text contains PGP-message, put a linebreak before the message, * so that gpgme can decrypt correctly diff --git a/include/gpg/Signature.h b/include/gpg/Signature.h index 3fa4414b..4d69c90b 100644 --- a/include/gpg/Signature.h +++ b/include/gpg/Signature.h @@ -30,25 +30,21 @@ struct Signature { bool revoked{}; - bool expired{}; - bool invalid{}; - bool exportable{}; + gpgme_error_t status{}; + + QString keyid; QString pubkey_algo; QDateTime create_time; - QDateTime expire_time; QString uid; - QString name; - QString email; - QString comment; Signature() = default; diff --git a/include/gpg/UID.h b/include/gpg/UID.h index d7a0f3bd..c048c7ad 100644 --- a/include/gpg/UID.h +++ b/include/gpg/UID.h @@ -41,6 +41,10 @@ struct UID { QString uid{}; + bool revoked; + + bool invalid; + QVector<Signature> signatures; UID() = default; diff --git a/include/ui/keypair_details/KeyPairUIDTab.h b/include/ui/keypair_details/KeyPairUIDTab.h index 70e657cd..0dd73f7b 100644 --- a/include/ui/keypair_details/KeyPairUIDTab.h +++ b/include/ui/keypair_details/KeyPairUIDTab.h @@ -46,17 +46,25 @@ private: void createManageUIDMenu(); + void createUIDPopupMenu(); + + void createSignPopupMenu(); + void getUIDChecked(QVector<UID> &uids); - GpgME::GpgContext *mCtx; + bool getUIDSelected(UID &uid); - const GpgKey &mKey; + bool getSignSelected(Signature &signature); + GpgME::GpgContext *mCtx; + const GpgKey &mKey; QTableWidget *uidList{}; - QTableWidget *sigList{}; - - QMenu *manageUIDMenu; + QMenu *manageSelectedUIDMenu; + QMenu *uidPopupMenu; + QMenu *signPopupMenu; + QVector<const UID *> buffered_uids; + QVector<const Signature *> buffered_signatures; private slots: @@ -66,10 +74,24 @@ private slots: void slotAddSign(); + void slotAddSignSingle(); + void slotAddUID(); + void slotDelUID(); + + void slotDelUIDSingle(); + + void slotSetPrimaryUID(); + + void slotDelSign(); + static void slotAddUIDResult(int result); +protected: + + void contextMenuEvent(QContextMenuEvent *event) override; + }; diff --git a/include/ui/widgets/KeyList.h b/include/ui/widgets/KeyList.h index 4bdafc17..0d9b07dc 100644 --- a/include/ui/widgets/KeyList.h +++ b/include/ui/widgets/KeyList.h @@ -65,6 +65,8 @@ public: void setExcludeKeys(std::initializer_list<QString> key_ids); + void setFilter(std::function<bool(const GpgKey&)> filter); + void setColumnWidth(int row, int size); void addMenuAction(QAction *act); @@ -93,6 +95,7 @@ public slots: void uploadKeyToServer(QByteArray *keys); private: + void importKeys(QByteArray inBuffer); GpgME::GpgContext *mCtx; @@ -104,6 +107,8 @@ private: KeyListColumn::InfoType mInfoType; QVector<QString> excluded_key_ids; + std::function<bool(const GpgKey &)> mFilter = nullptr; + private slots: @@ -111,6 +116,7 @@ private slots: protected: + void contextMenuEvent(QContextMenuEvent *event) override; void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp index b72eda73..51ee07b5 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/gpg/GpgContext.cpp @@ -982,6 +982,49 @@ namespace GpgME { } + bool GpgContext::revUID(const GpgKey &key, const UID &uid) { + auto gpgmeError = gpgme_op_revuid(mCtx, key.key_refer, uid.uid.toUtf8().constData(), 0); + if(gpgmeError == GPG_ERR_NO_ERROR) { + emit signalKeyUpdated(key.id); + return true; + } + else { + checkErr(gpgmeError); + return false; + } + } + + bool GpgContext::setPrimaryUID(const GpgKey &key, const UID &uid) { + auto gpgmeError = gpgme_op_set_uid_flag(mCtx, key.key_refer, + uid.uid.toUtf8().constData(), "primary", nullptr); + if(gpgmeError == GPG_ERR_NO_ERROR) { + emit signalKeyUpdated(key.id); + return true; + } + else { + checkErr(gpgmeError); + return false; + } + } + + bool GpgContext::revSign(const GpgKey &key, const Signature &signature) { + + auto signing_key = getKeyById(signature.keyid); + + auto gpgmeError = gpgme_op_revsig(mCtx, key.key_refer, + signing_key.key_refer, + signature.uid.toUtf8().constData(), 0); + if(gpgmeError == GPG_ERR_NO_ERROR) { + emit signalKeyUpdated(key.id); + return true; + } + else { + checkErr(gpgmeError); + return false; + } + return false; + } + } diff --git a/src/gpg/Signature.cpp b/src/gpg/Signature.cpp index 8e82c507..079f8a05 100644 --- a/src/gpg/Signature.cpp +++ b/src/gpg/Signature.cpp @@ -26,7 +26,8 @@ Signature::Signature(gpgme_key_sig_t key_sig) : revoked(key_sig->revoked), expired(key_sig->expired), invalid(key_sig->invalid), - exportable(key_sig->exportable), pubkey_algo(gpgme_pubkey_algo_name(key_sig->pubkey_algo)), + exportable(key_sig->exportable), status(key_sig->status), + keyid(key_sig->keyid), pubkey_algo(gpgme_pubkey_algo_name(key_sig->pubkey_algo)), uid(key_sig->uid), name(key_sig->name), email(key_sig->email), comment(key_sig->comment), create_time(QDateTime::fromTime_t(key_sig->timestamp)), expire_time(QDateTime::fromTime_t(key_sig->expires)){ diff --git a/src/gpg/UID.cpp b/src/gpg/UID.cpp index 62632e8f..a4e6f342 100644 --- a/src/gpg/UID.cpp +++ b/src/gpg/UID.cpp @@ -5,7 +5,8 @@ #include "gpg/UID.h" UID::UID(gpgme_user_id_t user_id) : - uid(user_id->uid), name(user_id->name), email(user_id->email), comment(user_id->comment) { + uid(user_id->uid), name(user_id->name), email(user_id->email), comment(user_id->comment), + revoked(user_id->revoked), invalid(user_id->invalid) { auto sig = user_id->signatures; diff --git a/src/ui/keypair_details/KeyNewUIDDialog.cpp b/src/ui/keypair_details/KeyNewUIDDialog.cpp index 9a70b102..a132bdf9 100644 --- a/src/ui/keypair_details/KeyNewUIDDialog.cpp +++ b/src/ui/keypair_details/KeyNewUIDDialog.cpp @@ -60,7 +60,7 @@ void KeyNewUIDDialog::slotCreateNewUID() { emit finished(1); } else { - emit finished(0); + emit finished(-1); } } else { diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index 873b478c..441fae77 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -67,18 +67,20 @@ KeyPairDetailTab::KeyPairDetailTab(GpgME::GpgContext *ctx, const GpgKey &key, QW vboxOD->addWidget(emailVarLabel, 1, 1); vboxOD->addWidget(commentVarLabel, 2, 1); - vboxKD->addWidget(new QLabel(tr("Key size:")), 0, 0); - vboxKD->addWidget(new QLabel(tr("Expires on: ")), 1, 0); - vboxKD->addWidget(new QLabel(tr("Algorithm: ")), 3, 0); - vboxKD->addWidget(new QLabel(tr("Last Update: ")), 4, 0); - vboxKD->addWidget(new QLabel(tr("Key ID: ")), 5, 0); - vboxKD->addWidget(new QLabel(tr("Usage: ")), 6, 0); - vboxKD->addWidget(keySizeVarLabel, 0, 1); - vboxKD->addWidget(expireVarLabel, 1, 1); - vboxKD->addWidget(algorithmVarLabel, 3, 1); - vboxKD->addWidget(createdVarLabel, 4, 1); - vboxKD->addWidget(keyidVarLabel, 5, 1); - vboxKD->addWidget(usageVarLabel, 6, 1); + vboxKD->addWidget(new QLabel(tr("Key ID: ")), 0, 0); + vboxKD->addWidget(new QLabel(tr("Algorithm: ")), 1, 0); + vboxKD->addWidget(new QLabel(tr("Key size:")), 2, 0); + vboxKD->addWidget(new QLabel(tr("Usage: ")), 3, 0); + vboxKD->addWidget(new QLabel(tr("Expires on: ")), 4, 0); + vboxKD->addWidget(new QLabel(tr("Last Update: ")), 5, 0); + + + vboxKD->addWidget(keySizeVarLabel, 2, 1); + vboxKD->addWidget(expireVarLabel, 4, 1); + vboxKD->addWidget(algorithmVarLabel, 1, 1); + vboxKD->addWidget(createdVarLabel, 5, 1); + vboxKD->addWidget(keyidVarLabel, 0, 1); + vboxKD->addWidget(usageVarLabel, 3, 1); ownerBox->setLayout(vboxOD); mvbox->addWidget(ownerBox); @@ -88,7 +90,7 @@ KeyPairDetailTab::KeyPairDetailTab(GpgME::GpgContext *ctx, const GpgKey &key, QW fingerPrintVarLabel = new QLabel(beautifyFingerprint(key.fpr)); fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - fingerPrintVarLabel->setStyleSheet("margin-left: 5; margin-right: 5;"); + fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;"); auto *hboxFP = new QHBoxLayout(); hboxFP->addWidget(fingerPrintVarLabel); diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp index 82d27262..40316163 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/keypair_details/KeyPairUIDTab.cpp @@ -11,13 +11,15 @@ KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget createUIDList(); createSignList(); createManageUIDMenu(); + createUIDPopupMenu(); + createSignPopupMenu(); auto uidButtonsLayout = new QGridLayout(); auto addUIDButton = new QPushButton(tr("New UID")); auto manageUIDButton = new QPushButton(tr("UID Management")); - manageUIDButton->setMenu(manageUIDMenu); + manageUIDButton->setMenu(manageSelectedUIDMenu); uidButtonsLayout->addWidget(addUIDButton, 0, 1); uidButtonsLayout->addWidget(manageUIDButton, 0, 2); @@ -28,16 +30,14 @@ KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget gridLayout->addWidget(sigList, 2, 0); - setLayout(gridLayout); - connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID())); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshUIDList())); - connect(uidList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSigList())); - slotRefreshUIDList(); + setLayout(gridLayout); setAttribute(Qt::WA_DeleteOnClose, true); + + slotRefreshUIDList(); } void KeyPairUIDTab::createUIDList() { @@ -73,16 +73,16 @@ void KeyPairUIDTab::createSignList() { sigList->setShowGrid(false); sigList->setSelectionBehavior(QAbstractItemView::SelectRows); - // tableitems not editable + // table items not editable sigList->setEditTriggers(QAbstractItemView::NoEditTriggers); - // no focus (rectangle around tableitems) + // no focus (rectangle around table items) // may be it should focus on whole row sigList->setFocusPolicy(Qt::NoFocus); sigList->setAlternatingRowColors(true); QStringList labels; - labels << tr("Type") << tr("Name") << tr("Email") << tr("Create Time") << tr("Valid Time"); + labels << tr("Key ID") << tr("Name") << tr("Email") << tr("Create Time") << tr("Valid Time"); sigList->setHorizontalHeaderLabels(labels); sigList->horizontalHeader()->setStretchLastSection(true); @@ -92,18 +92,28 @@ void KeyPairUIDTab::slotRefreshUIDList() { int row = 0; - uidList->setRowCount(mKey.uids.size()); uidList->setSelectionMode(QAbstractItemView::SingleSelection); - for(const auto& uid : mKey.uids) { + this->buffered_uids.clear(); + + for(const auto &uid : mKey.uids) { + if(uid.invalid || uid.revoked) { + continue; + } + this->buffered_uids.push_back(&uid); + } + + uidList->setRowCount(buffered_uids.size()); + + for(const auto& uid : buffered_uids) { - auto *tmp0 = new QTableWidgetItem(uid.name); + auto *tmp0 = new QTableWidgetItem(uid->name); uidList->setItem(row, 1, tmp0); - auto *tmp1 = new QTableWidgetItem(uid.email); + auto *tmp1 = new QTableWidgetItem(uid->email); uidList->setItem(row, 2, tmp1); - auto *tmp2 = new QTableWidgetItem(uid.comment); + auto *tmp2 = new QTableWidgetItem(uid->comment); uidList->setItem(row, 3, tmp2); auto *tmp3 = new QTableWidgetItem(QString::number(row)); @@ -120,29 +130,47 @@ void KeyPairUIDTab::slotRefreshUIDList() { void KeyPairUIDTab::slotRefreshSigList() { int uidRow = 0, sigRow = 0; - for(const auto& uid : mKey.uids) { + for(const auto& uid : buffered_uids) { - // Only Show Selected UID's Signatures + // Only Show Selected UID Signatures if(!uidList->item(uidRow++, 0)->isSelected()) { continue; } - sigList->setRowCount(uid.signatures.size()); + buffered_signatures.clear(); - for(const auto &sig : uid.signatures) { - auto *tmp0 = new QTableWidgetItem(sig.pubkey_algo); + for(const auto &sig : uid->signatures) { + if(sig.invalid || sig.revoked) { + continue; + } + buffered_signatures.push_back(&sig); + } + + sigList->setRowCount(buffered_signatures.size()); + + for(const auto &sig : buffered_signatures) { + + auto *tmp0 = new QTableWidgetItem(sig->keyid); sigList->setItem(sigRow, 0, tmp0); - auto *tmp2 = new QTableWidgetItem(sig.name); - sigList->setItem(sigRow, 1, tmp2); + if(gpgme_err_code(sig->status) == GPG_ERR_NO_PUBKEY) { + auto *tmp2 = new QTableWidgetItem("<Unknown>"); + sigList->setItem(sigRow, 1, tmp2); - auto *tmp3 = new QTableWidgetItem(sig.email); - sigList->setItem(sigRow, 2, tmp3); + auto *tmp3 = new QTableWidgetItem("<Unknown>"); + sigList->setItem(sigRow, 2, tmp3); + } else { + auto *tmp2 = new QTableWidgetItem(sig->name); + sigList->setItem(sigRow, 1, tmp2); - auto *tmp4 = new QTableWidgetItem(sig.create_time.toString()); + auto *tmp3 = new QTableWidgetItem(sig->email); + sigList->setItem(sigRow, 2, tmp3); + } + + auto *tmp4 = new QTableWidgetItem(sig->create_time.toString()); sigList->setItem(sigRow, 3, tmp4); - auto *tmp5 = new QTableWidgetItem(sig.expire_time.toString()); + auto *tmp5 = new QTableWidgetItem(sig->expire_time.toString()); sigList->setItem(sigRow, 4, tmp5); sigRow++; @@ -155,13 +183,12 @@ void KeyPairUIDTab::slotRefreshSigList() { void KeyPairUIDTab::slotAddSign() { QVector<UID> selected_uids; - getUIDChecked(selected_uids); if(selected_uids.isEmpty()) { - auto emptyUIDMsg = new QMessageBox(); - emptyUIDMsg->setText("Please select one or more UIDs before doing this operation."); - emptyUIDMsg->exec(); + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("Please select one or more UIDs before doing this operation.")); return; } @@ -169,25 +196,30 @@ void KeyPairUIDTab::slotAddSign() { keySignDialog->show(); } + + void KeyPairUIDTab::getUIDChecked(QVector<UID> &selected_uids) { - auto &uids = mKey.uids; + auto &uids = buffered_uids; for (int i = 0; i < uidList->rowCount(); i++) { if (uidList->item(i, 0)->checkState() == Qt::Checked) { - selected_uids.push_back(uids[i]); + selected_uids.push_back(*uids[i]); } } } void KeyPairUIDTab::createManageUIDMenu() { - manageUIDMenu = new QMenu(this); + manageSelectedUIDMenu = new QMenu(this); auto *signUIDAct = new QAction(tr("Sign Selected UID(s)"), this); connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign())); + auto *delUIDAct = new QAction(tr("Delete Selected UID(s)"), this); + connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID())); - manageUIDMenu->addAction(signUIDAct); + manageSelectedUIDMenu->addAction(signUIDAct); + manageSelectedUIDMenu->addAction(delUIDAct); } void KeyPairUIDTab::slotAddUID() { @@ -198,13 +230,231 @@ void KeyPairUIDTab::slotAddUID() { } void KeyPairUIDTab::slotAddUIDResult(int result) { - if(result) { + if(result == 1) { QMessageBox::information(nullptr, tr("Successful Operation"), tr("Successfully added a new UID.")); - } else { + } else if (result == -1) { QMessageBox::critical(nullptr, tr("Operation Failed"), tr("An error occurred during the operation.")); } } + +void KeyPairUIDTab::slotDelUID() { + + QVector<UID> selected_uids; + getUIDChecked(selected_uids); + + if(selected_uids.isEmpty()) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("Please select one or more UIDs before doing this operation.")); + return; + } + + QString keynames; + for (const auto &uid : selected_uids) { + keynames.append(uid.name); + keynames.append("<i> <"); + keynames.append(uid.email); + keynames.append("> </i><br/>"); + } + + int ret = QMessageBox::warning(this, tr("Deleting UIDs"), + "<b>"+tr("Are you sure that you want to delete the following uids?")+"</b><br/><br/>"+keynames+ + +"<br/>"+tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + + bool if_success = true; + + if (ret == QMessageBox::Yes) { + for(const auto &uid : selected_uids) { + if(!mCtx->revUID(mKey, uid)) { + if_success = false; + } + } + + if(!if_success) { + QMessageBox::critical(nullptr, + tr("Operation Failed"), + tr("An error occurred during the operation.")); + } + + } +} + +void KeyPairUIDTab::slotSetPrimaryUID() { + + UID selected_uid; + + if(!getUIDSelected(selected_uid)) { + auto emptyUIDMsg = new QMessageBox(); + emptyUIDMsg->setText("Please select one UID before doing this operation."); + emptyUIDMsg->exec(); + return; + } + + QString keynames; + + keynames.append(selected_uid.name); + keynames.append("<i> <"); + keynames.append(selected_uid.email); + keynames.append("> </i><br/>"); + + int ret = QMessageBox::warning(this, tr("Set Primary UID"), + "<b>"+tr("Are you sure that you want to set the Primary UID to?")+"</b><br/><br/>"+keynames+ + +"<br/>"+tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if(!mCtx->setPrimaryUID(mKey, selected_uid)) { + QMessageBox::critical(nullptr, + tr("Operation Failed"), + tr("An error occurred during the operation.")); + } + } +} + +bool KeyPairUIDTab::getUIDSelected(UID &uid) { + auto &uids = buffered_uids; + for (int i = 0; i < uidList->rowCount(); i++) { + if (uidList->item(i, 0)->isSelected()) { + uid = *uids[i]; + return true; + } + } + return false; +} + +bool KeyPairUIDTab::getSignSelected(Signature &signature) { + auto &signatures = buffered_signatures; + for (int i = 0; i < sigList->rowCount(); i++) { + if (sigList->item(i, 0)->isSelected()) { + signature = *signatures[i]; + return true; + } + } + return false; +} + +void KeyPairUIDTab::createUIDPopupMenu() { + + uidPopupMenu = new QMenu(this); + + auto *serPrimaryUIDAct = new QAction(tr("Set As Primary"), this); + connect(serPrimaryUIDAct, SIGNAL(triggered()), this, SLOT(slotSetPrimaryUID())); + auto *signUIDAct = new QAction(tr("Sign UID"), this); + connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle())); + auto *delUIDAct = new QAction(tr("Delete UID"), this); + connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle())); + + uidPopupMenu->addAction(serPrimaryUIDAct); + uidPopupMenu->addAction(signUIDAct); + uidPopupMenu->addAction(delUIDAct); +} + +void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent *event) { + if (uidList->selectedItems().length() > 0 && sigList->selectedItems().isEmpty()) { + uidPopupMenu->exec(event->globalPos()); + } + + if (!sigList->selectedItems().isEmpty()) { + signPopupMenu->exec(event->globalPos()); + } +} + +void KeyPairUIDTab::slotAddSignSingle() { + + UID selected_uid; + + if(!getUIDSelected(selected_uid)) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("Please select one UID before doing this operation.")); + return; + } + + auto selected_uids = QVector<UID>({ selected_uid }); + auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this); + keySignDialog->show(); +} + +void KeyPairUIDTab::slotDelUIDSingle() { + UID selected_uid; + + if(!getUIDSelected(selected_uid)) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("Please select one UID before doing this operation.")); + return; + } + + QString keynames; + + keynames.append(selected_uid.name); + keynames.append("<i> <"); + keynames.append(selected_uid.email); + keynames.append("> </i><br/>"); + + int ret = QMessageBox::warning(this, tr("Deleting UID"), + "<b>"+tr("Are you sure that you want to delete the following uid?")+"</b><br/><br/>"+keynames+ + +"<br/>"+tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if(!mCtx->revUID(mKey, selected_uid)) { + QMessageBox::critical(nullptr, + tr("Operation Failed"), + tr("An error occurred during the operation.")); + } + } +} + +void KeyPairUIDTab::createSignPopupMenu() { + signPopupMenu = new QMenu(this); + + auto *delSignAct = new QAction(tr("Delete Signature"), this); + connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign())); + + signPopupMenu->addAction(delSignAct); +} + +void KeyPairUIDTab::slotDelSign() { + Signature selected_sign; + + if(!getSignSelected(selected_sign)) { + QMessageBox::information(nullptr, + tr("Invalid Operation"), + tr("Please select one Signature before doing this operation.")); + return; + } + + if(gpgme_err_code(selected_sign.status) == GPG_ERR_NO_PUBKEY) { + QMessageBox::critical(nullptr, + tr("Invalid Operation"), + tr("To delete the signature, you need to have its corresponding public key in the local database.")); + return; + } + + QString keynames; + + keynames.append(selected_sign.name); + keynames.append("<i> <"); + keynames.append(selected_sign.email); + keynames.append("> </i><br/>"); + + int ret = QMessageBox::warning(this, tr("Deleting Signature"), + "<b>"+tr("Are you sure that you want to delete the following signature?")+"</b><br/><br/>"+keynames+ + +"<br/>"+tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if(!mCtx->revSign(mKey, selected_sign)) { + QMessageBox::critical(nullptr, + tr("Operation Failed"), + tr("An error occurred during the operation.")); + } + } +} diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp index 64a15865..cb4056b3 100644 --- a/src/ui/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp @@ -12,6 +12,10 @@ KeyUIDSignDialog::KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, co KeyListColumn::NAME | KeyListColumn::EmailAddress, this); + mKeyList->setFilter([](const GpgKey &key) -> bool { + if(key.disabled || !key.can_sign) return false; + else return true; + }); mKeyList->setExcludeKeys({key.id}); mKeyList->slotRefresh(); @@ -73,9 +77,9 @@ void KeyUIDSignDialog::slotSignKey(bool clicked) { // Sign For mKey if (!mCtx->signKey(mKey, uid.uid, &expires)) { QMessageBox::critical(nullptr, - tr("Operation Unsuccessful"), - QString("%1 <%2>"+tr(" signature operation failed for UID ") + "%3") - .arg(mKey.name, mKey.email, uid.uid)); + tr("Unsuccessful Operation"), + QString(tr("Signature operation failed for UID ") + "%1") + .arg(uid.uid)); } } diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index d8e4a094..2082bbc9 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -42,6 +42,7 @@ KeyList::KeyList(GpgME::GpgContext *ctx, mKeyList->setShowGrid(false); mKeyList->sortByColumn(2, Qt::AscendingOrder); mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows); + mKeyList->setSelectionMode( QAbstractItemView::SingleSelection ); // tableitems not editable mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -105,16 +106,24 @@ void KeyList::slotRefresh() int row_count = 0; while (it != keys.end()) { + if(mFilter != nullptr) { + if(!mFilter(*it)) { + it = keys.erase(it); + continue; + } + } if(!excluded_key_ids.isEmpty()){ - bool if_find = false; - for(const auto &key_id : excluded_key_ids) { - if(it->id == key_id) { - it = keys.erase(it); - if_find = true; - break; - } + + auto iterator = std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(), + [it] (const auto &key_id) -> bool { + if(it->id == key_id) return true; + else return false; + }); + + if(iterator != excluded_key_ids.end()) { + it = keys.erase(it); + continue; } - if(if_find) continue; } if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key) { it = keys.erase(it); @@ -423,3 +432,7 @@ void KeyList::setExcludeKeys(std::initializer_list<QString> key_ids) { excluded_key_ids.push_back(key_id); } } + +void KeyList::setFilter(std::function<bool(const GpgKey &)> filter) { + this->mFilter = filter; +} |