aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/gpg/GpgContext.h6
-rw-r--r--include/gpg/Signature.h10
-rw-r--r--include/gpg/UID.h4
-rw-r--r--include/ui/keypair_details/KeyPairUIDTab.h32
-rw-r--r--include/ui/widgets/KeyList.h6
-rw-r--r--src/gpg/GpgContext.cpp43
-rw-r--r--src/gpg/Signature.cpp3
-rw-r--r--src/gpg/UID.cpp3
-rw-r--r--src/ui/keypair_details/KeyNewUIDDialog.cpp2
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.cpp28
-rw-r--r--src/ui/keypair_details/KeyPairUIDTab.cpp320
-rw-r--r--src/ui/keypair_details/KeyUIDSignDialog.cpp10
-rw-r--r--src/ui/widgets/KeyList.cpp29
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> &lt;");
+ keynames.append(uid.email);
+ keynames.append("&gt; </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> &lt;");
+ keynames.append(selected_uid.email);
+ keynames.append("&gt; </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> &lt;");
+ keynames.append(selected_uid.email);
+ keynames.append("&gt; </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> &lt;");
+ keynames.append(selected_sign.email);
+ keynames.append("&gt; </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;
+}