aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2021-05-24 18:34:02 +0000
committerSaturneric <[email protected]>2021-05-24 18:34:02 +0000
commitd989b48429ff9e37316d3c5c523e3cf53bbf5907 (patch)
tree892f187bdc8e493a7278892757da778d81c2432c
parentDeclare and Define getSigners; (diff)
downloadGpgFrontend-d989b48429ff9e37316d3c5c523e3cf53bbf5907.tar.gz
GpgFrontend-d989b48429ff9e37316d3c5c523e3cf53bbf5907.zip
Streamline, expand and improve the interface of GpgContext.
Fix the wrong use of the query interface for fingerprints or identifiers at VerifyKeyDetailBox.cpp and VerifyNotification.cpp. Write the processing logic and page logic for adding a signature to the key. Signed-off-by: Saturneric <[email protected]>
Diffstat (limited to '')
-rw-r--r--include/gpg/GpgContext.h14
-rw-r--r--include/ui/keypair_details/KeyPairUIDTab.h15
-rw-r--r--include/ui/keypair_details/KeySignDialog.h44
-rw-r--r--include/ui/widgets/KeyList.h2
-rw-r--r--src/MainWindow.cpp6
-rw-r--r--src/gpg/GpgContext.cpp88
-rw-r--r--src/gpg/GpgKey.cpp7
-rwxr-xr-xsrc/ui/KeyMgmt.cpp10
-rwxr-xr-xsrc/ui/SettingsDialog.cpp5
-rw-r--r--src/ui/VerifyKeyDetailBox.cpp2
-rw-r--r--src/ui/VerifyNotification.cpp2
-rw-r--r--src/ui/keypair_details/KeyPairDetailTab.cpp3
-rw-r--r--src/ui/keypair_details/KeyPairUIDTab.cpp52
-rw-r--r--src/ui/keypair_details/KeySignDialog.cpp64
-rw-r--r--src/ui/widgets/KeyList.cpp11
15 files changed, 247 insertions, 78 deletions
diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h
index 92a8200c..5fd54618 100644
--- a/include/gpg/GpgContext.h
+++ b/include/gpg/GpgContext.h
@@ -104,11 +104,11 @@ namespace GpgME {
void exportSecretKey(const QString &uid, QByteArray *outBuffer);
- void getKeyDetails(const QString &uid, GpgKey& key);
-
void getSigners(QVector<GpgKey> &signer);
- void signKey(const QVector<GpgKey> &signer, const GpgKey &target, const QString& uid);
+ void setSigners(const QVector<GpgKey> &keys);
+
+ void signKey(const GpgKey &target, const QString& uid, const QDateTime *expires);
gpgme_signature_t verify(QByteArray *inBuffer, QByteArray *sigBuffer = nullptr);
@@ -124,7 +124,7 @@ namespace GpgME {
GpgKey getKeyByFpr(const QString &fpr);
- GpgKey getKeyById(const QString &id);
+ const GpgKey & getKeyById(const QString &id);
static QString gpgErrString(gpgme_error_t err);
@@ -146,10 +146,14 @@ namespace GpgME {
void signalKeyDBChanged();
+ void signalKeyUpdated(const QString &key_id);
+
private slots:
void slotRefreshKeyList();
+ void slotUpdateKeyList(const QString &key_id);
+
private:
gpgme_ctx_t mCtx{};
gpgme_data_t in{};
@@ -162,7 +166,7 @@ namespace GpgME {
QSettings settings;
GpgKeyList mKeyList;
- QMap<QString, GpgKey> mKeyMap;
+ QMap<QString, GpgKey *> mKeyMap;
void fetch_keys();
diff --git a/include/ui/keypair_details/KeyPairUIDTab.h b/include/ui/keypair_details/KeyPairUIDTab.h
index ae476a1f..6aca3dd8 100644
--- a/include/ui/keypair_details/KeyPairUIDTab.h
+++ b/include/ui/keypair_details/KeyPairUIDTab.h
@@ -28,12 +28,14 @@
#include "GpgFrontend.h"
#include "gpg/GpgContext.h"
+#include "KeySignDialog.h"
+
class KeyPairUIDTab : public QWidget {
Q_OBJECT
public:
- KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey& key, QWidget *parent);
+ KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent);
private:
@@ -41,15 +43,15 @@ private:
void createSignList();
- GpgME::GpgContext *mCtx;
-
- const GpgKey &key;
+ void getUIDChecked(QVector<UID> &uids);
- QTableWidget *uidList;
+ GpgME::GpgContext *mCtx;
- QTableWidget *sigList;
+ const GpgKey &mKey;
+ QTableWidget *uidList{};
+ QTableWidget *sigList{};
private slots:
@@ -57,6 +59,7 @@ private slots:
void slotRefreshSigList();
+ void slotAddSign();
};
diff --git a/include/ui/keypair_details/KeySignDialog.h b/include/ui/keypair_details/KeySignDialog.h
new file mode 100644
index 00000000..075459de
--- /dev/null
+++ b/include/ui/keypair_details/KeySignDialog.h
@@ -0,0 +1,44 @@
+//
+// Created by eric on 2021/5/24.
+//
+
+#ifndef GPGFRONTEND_KEYSIGNDIALOG_H
+#define GPGFRONTEND_KEYSIGNDIALOG_H
+
+#include "GpgFrontend.h"
+
+#include "gpg/GpgContext.h"
+#include "ui/widgets/KeyList.h"
+
+class KeySignDialog : public QDialog {
+ Q_OBJECT
+
+public:
+
+ explicit KeySignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<UID> &uid, QWidget *parent = nullptr);
+
+private:
+
+ GpgME::GpgContext *mCtx;
+
+ KeyList *mKeyList;
+
+ QPushButton *signKeyButton;
+
+ QDateTimeEdit *expiresEdit;
+
+ QCheckBox *nonExpireCheck;
+
+ const QVector<UID> &mUids;
+
+ const GpgKey &mKey;
+
+
+private slots:
+
+ void slotSignKey();
+
+};
+
+
+#endif //GPGFRONTEND_KEYSIGNDIALOG_H
diff --git a/include/ui/widgets/KeyList.h b/include/ui/widgets/KeyList.h
index 6af54518..c4169f4a 100644
--- a/include/ui/widgets/KeyList.h
+++ b/include/ui/widgets/KeyList.h
@@ -69,6 +69,8 @@ public:
QStringList *getChecked();
+ void getCheckedKeys(QVector<GpgKey> &keys);
+
QStringList *getPrivateChecked();
QStringList *getAllPrivateKeys();
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index cf100a14..f4d2badb 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -855,8 +855,7 @@ void MainWindow::slotCopyMailAddressToClipboard() {
if (mKeyList->getSelected()->isEmpty()) {
return;
}
- GpgKey key;
- mCtx->getKeyDetails(mKeyList->getSelected()->first(), key);
+ auto &key = mCtx->getKeyById(mKeyList->getSelected()->first());
QClipboard *cb = QApplication::clipboard();
QString mail = key.email;
cb->setText(mail);
@@ -866,8 +865,7 @@ void MainWindow::slotShowKeyDetails() {
if (mKeyList->getSelected()->isEmpty()) {
return;
}
- GpgKey key;
- mCtx->getKeyDetails(mKeyList->getSelected()->first(), key);
+ auto &key = mCtx->getKeyById(mKeyList->getSelected()->first());
if (key.good) {
new KeyDetailsDialog(mCtx, key, this);
}
diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp
index 91602a70..3e1f59c1 100644
--- a/src/gpg/GpgContext.cpp
+++ b/src/gpg/GpgContext.cpp
@@ -186,7 +186,7 @@ namespace GpgME {
const char *userid = userid_utf8.constData();
auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()).toUtf8();
const char *algo = algo_utf8.constData();
- unsigned long expires = params->getExpired().toTime_t();
+ unsigned long expires = QDateTime::currentDateTime().secsTo(params->getExpired());
unsigned int flags = 0;
if (!params->isSubKey()) {
@@ -253,19 +253,6 @@ namespace GpgME {
return true;
}
- void GpgContext::getKeyDetails(const QString &uid, GpgKey &key) {
- gpgme_key_t gpgme_key;
-
- // try secret
- gpgme_get_key(mCtx, uid.toUtf8().constData(), &gpgme_key, 1);
- // ok, its a public key
- if (!gpgme_key) {
- gpgme_get_key(mCtx, uid.toUtf8().constData(), &gpgme_key, 0);
- }
-
- key.parse(gpgme_key);
- }
-
/**
* List all availabe Keys (VERY much like kgpgme)
*/
@@ -297,9 +284,8 @@ namespace GpgME {
if (!key->subkeys)
continue;
- GpgKey gpg_key(key);
-
- keys_map.insert(gpg_key.id, gpg_key);
+ keys.append(GpgKey(key));
+ keys_map.insert(keys.back().id, &keys.back());
gpgme_key_unref(key);
}
@@ -343,10 +329,6 @@ namespace GpgME {
return;
}
- for(auto &gpg_key : keys_map) {
- keys.append(gpg_key);
- }
-
mKeyList = keys;
}
@@ -855,6 +837,7 @@ namespace GpgME {
}
void GpgContext::slotRefreshKeyList() {
+ qDebug() << "Refreshing Keys";
this->fetch_keys();
}
@@ -870,27 +853,41 @@ namespace GpgME {
return GpgKey(nullptr);
}
-/**
- * note: is_private_key status is not returned
- */
- GpgKey GpgContext::getKeyById(const QString &id) {
+ /**
+ * note: is_private_key status is not returned
+ */
+ const GpgKey &GpgContext::getKeyById(const QString &id) {
- //GpgKeyList list = this->fetch_keys();
- foreach (GpgKey key, mKeyList) {
- if (key.id == id) {
- return key;
- }
- }
+ auto it = mKeyMap.find(id);
- return GpgKey(nullptr);
+ if(it != mKeyMap.end()) {
+ return *it.value();
+ }
+
+ throw std::runtime_error("key not found");
}
QString GpgContext::getGpgmeVersion() {
return QString(gpgme_check_version(nullptr));
}
- void GpgContext::signKey(const QVector<GpgKey> &signer, const GpgKey &target, const QString &uid) {
+ void GpgContext::signKey(const GpgKey &target, const QString &uid, const QDateTime *expires) {
+
+ unsigned int flags = 0;
+
+ unsigned int expires_time_t = 0;
+ if (expires == nullptr) {
+ flags |= GPGME_KEYSIGN_NOEXPIRE;
+ } else {
+ expires_time_t = QDateTime::currentDateTime().secsTo(*expires);
+ }
+
+ auto gpgmeError =
+ gpgme_op_keysign(mCtx, target.key_refer, uid.toUtf8().constData(), expires_time_t, flags);
+
+ checkErr(gpgmeError);
+ emit signalKeyUpdated(target.id);
}
const GpgKeyList &GpgContext::getKeys() const {
@@ -900,17 +897,36 @@ namespace GpgME {
void GpgContext::getSigners(QVector<GpgKey> &signer) {
auto count = gpgme_signers_count(mCtx);
signer.clear();
- for(auto i = 0; i < count; i++){
+ for (auto i = 0; i < count; i++) {
auto key = gpgme_signers_enum(mCtx, i);
auto it = mKeyMap.find(key->subkeys->keyid);
- if(it == mKeyMap.end()) {
+ if (it == mKeyMap.end()) {
+ qDebug() << "Inconsistent state";
signer.push_back(GpgKey(key));
} else {
- signer.push_back(*it);
+ signer.push_back(*it.value());
}
}
}
+ void GpgContext::setSigners(const QVector<GpgKey> &keys) {
+ gpgme_signers_clear(mCtx);
+ unsigned int count = 0;
+ for (const auto &key : keys) {
+ count = gpgme_signers_add(mCtx, key.key_refer);
+ }
+ if (keys.length() != count) {
+ qDebug() << "Now All Keys Added";
+ }
+ }
+
+ void GpgContext::slotUpdateKeyList(const QString &key_id) {
+ auto it = mKeyMap.find(key_id);
+ if (it != mKeyMap.end()) {
+ it.value()->parse(it.value()->key_refer);
+ }
+ }
+
}
diff --git a/src/gpg/GpgKey.cpp b/src/gpg/GpgKey.cpp
index 51ab2158..99972eee 100644
--- a/src/gpg/GpgKey.cpp
+++ b/src/gpg/GpgKey.cpp
@@ -28,6 +28,8 @@ void GpgKey::parse(gpgme_key_t key) {
if(key == nullptr) return;
+
+
good = true;
key_refer = key;
gpgme_key_ref(key_refer);
@@ -68,6 +70,7 @@ void GpgKey::parse(gpgme_key_t key) {
break;
}
+ uids.clear();
auto uid = key->uids;
while (uid != nullptr) {
@@ -75,13 +78,13 @@ void GpgKey::parse(gpgme_key_t key) {
uid = uid->next;
}
-
if (!uids.isEmpty()) {
name = uids.first().name;
email = uids.first().email;
comment = uids.first().comment;
}
+ subKeys.clear();
auto next = key->subkeys;
while (next != nullptr) {
@@ -169,6 +172,7 @@ GpgKey &GpgKey::operator=(const GpgKey &k) {
good = k.good;
subKeys = k.subKeys;
+ uids = k.uids;
key_refer = k.key_refer;
gpgme_key_ref(key_refer);
@@ -197,6 +201,7 @@ GpgKey::GpgKey(const GpgKey &k) :
good = k.good;
subKeys = k.subKeys;
+ uids = k.uids;
key_refer = k.key_refer;
gpgme_key_ref(key_refer);
diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp
index b1699483..d40928ee 100755
--- a/src/ui/KeyMgmt.cpp
+++ b/src/ui/KeyMgmt.cpp
@@ -234,8 +234,7 @@ void KeyMgmt::deleteKeysWithWarning(QStringList *uidList)
}
QString keynames;
for (const auto &uid : *uidList) {
- GpgKey key;
- mCtx->getKeyDetails(uid, key);
+ auto &key = mCtx->getKeyById(uid);
keynames.append(key.name);
keynames.append("<i> &lt;");
keynames.append(key.email);
@@ -258,9 +257,7 @@ void KeyMgmt::slotShowKeyDetails()
return;
}
- GpgKey key;
-
- mCtx->getKeyDetails(mKeyList->getSelected()->first(), key);
+ auto &key = mCtx->getKeyById(mKeyList->getSelected()->first());
new KeyDetailsDialog(mCtx, key);
}
@@ -271,8 +268,7 @@ void KeyMgmt::slotExportKeyToFile()
if (!mCtx->exportKeys(mKeyList->getChecked(), keyArray)) {
return;
}
- GpgKey key;
- mCtx->getKeyDetails(mKeyList->getChecked()->first(), key);
+ auto &key = mCtx->getKeyById(mKeyList->getSelected()->first());
QString fileString = key.name + " " + key.email+ "(" + key.id+ ")_pub.asc";
QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString, tr("Key Files") + " (*.asc *.txt);;All Files (*)");
diff --git a/src/ui/SettingsDialog.cpp b/src/ui/SettingsDialog.cpp
index f7cd0c50..2e174b91 100755
--- a/src/ui/SettingsDialog.cpp
+++ b/src/ui/SettingsDialog.cpp
@@ -184,8 +184,9 @@ GeneralTab::GeneralTab(GpgME::GpgContext *ctx, QWidget *parent)
keyIds.insert("", tr("<none>"));
foreach (QString keyid, *mKeyList->getAllPrivateKeys()) {
- GpgKey key;
- mCtx->getKeyDetails(keyid, key);
+
+ auto &key = mCtx->getKeyById(keyid);
+
QString newKey = " (" + keyid + ")";
if (!QString(key.email).isEmpty()) {
newKey.prepend(" <" + key.email + ">");
diff --git a/src/ui/VerifyKeyDetailBox.cpp b/src/ui/VerifyKeyDetailBox.cpp
index 57f70a62..4252e10f 100644
--- a/src/ui/VerifyKeyDetailBox.cpp
+++ b/src/ui/VerifyKeyDetailBox.cpp
@@ -66,7 +66,7 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgME::GpgContext *ctx,
break;
}
default: {
- GpgKey key = mCtx->getKeyById(signature->fpr);
+ GpgKey key = mCtx->getKeyByFpr(signature->fpr);
if(!key.good) break;
diff --git a/src/ui/VerifyNotification.cpp b/src/ui/VerifyNotification.cpp
index b5b2c890..9283120f 100644
--- a/src/ui/VerifyNotification.cpp
+++ b/src/ui/VerifyNotification.cpp
@@ -130,7 +130,7 @@ bool VerifyNotification::slotRefresh() {
case GPG_ERR_BAD_SIGNATURE: {
textIsSigned = 3;
verifyStatus = VERIFY_ERROR_CRITICAL;
- GpgKey key = mCtx->getKeyById(sign->fpr);
+ GpgKey key = mCtx->getKeyByFpr(sign->fpr);
if(!key.good) break;
diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp
index 6974157f..f0819b1f 100644
--- a/src/ui/keypair_details/KeyPairDetailTab.cpp
+++ b/src/ui/keypair_details/KeyPairDetailTab.cpp
@@ -175,8 +175,7 @@ void KeyPairDetailTab::slotExportPrivateKey() {
if (ret == QMessageBox::Ok) {
auto *keyArray = new QByteArray();
mCtx->exportSecretKey(*keyid, keyArray);
- GpgKey key;
- mCtx->getKeyDetails(*keyid, key);
+ auto &key = mCtx->getKeyById(*keyid);
QString fileString = key.name + " " +key.email + "(" +
key.id + ")_pub_sec.asc";
QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString,
diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp
index 8ca68d60..f9f4d496 100644
--- a/src/ui/keypair_details/KeyPairUIDTab.cpp
+++ b/src/ui/keypair_details/KeyPairUIDTab.cpp
@@ -4,7 +4,7 @@
#include "ui/keypair_details/KeyPairUIDTab.h"
-KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent) : QWidget(parent), key(key) {
+KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget *parent) : QWidget(parent), mKey(key) {
mCtx = ctx;
@@ -39,6 +39,7 @@ KeyPairUIDTab::KeyPairUIDTab(GpgME::GpgContext *ctx, const GpgKey &key, QWidget
connect(mCtx, SIGNAL(signalKeyDBChanged()), this, SLOT(slotRefreshUIDList()));
connect(mCtx, SIGNAL(signalKeyDBChanged()), this, SLOT(slotRefreshSigList()));
+ connect(addSigButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSign()));
slotRefreshUIDList();
slotRefreshSigList();
@@ -61,7 +62,7 @@ void KeyPairUIDTab::createUIDList() {
uidList->setAlternatingRowColors(true);
QStringList labels;
- labels << tr("Name") << tr("Email") << tr("Comment");
+ labels << tr("Operate") << tr("Name") << tr("Email") << tr("Comment");
uidList->setHorizontalHeaderLabels(labels);
uidList->horizontalHeader()->setStretchLastSection(true);
}
@@ -86,32 +87,36 @@ void KeyPairUIDTab::createSignList() {
labels << tr("Type") << tr("Name") << tr("Pubkey Id") << tr("Create Time") << tr("Valid Time");
sigList->setHorizontalHeaderLabels(labels);
sigList->horizontalHeader()->setStretchLastSection(true);
+
}
void KeyPairUIDTab::slotRefreshUIDList() {
+
int row = 0;
uidList->clearContents();
- uidList->setRowCount(key.uids.size());
+ uidList->setRowCount(mKey.uids.size());
uidList->setSelectionMode(QAbstractItemView::SingleSelection);
- for(const auto& uid : key.uids) {
+ for(const auto& uid : mKey.uids) {
auto *tmp0 = new QTableWidgetItem(uid.name);
- uidList->setItem(row, 0, tmp0);
+ uidList->setItem(row, 1, tmp0);
auto *tmp1 = new QTableWidgetItem(uid.email);
- uidList->setItem(row, 1, tmp1);
+ uidList->setItem(row, 2, tmp1);
auto *tmp2 = new QTableWidgetItem(uid.comment);
- uidList->setItem(row, 2, tmp2);
+ uidList->setItem(row, 3, tmp2);
+
+ auto *tmp3 = new QTableWidgetItem(QString::number(row));
+ tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ tmp3->setCheckState(Qt::Unchecked);
+ uidList->setItem(row, 0, tmp3);
row++;
}
-
-
-
-
}
void KeyPairUIDTab::slotRefreshSigList() {
@@ -119,13 +124,13 @@ void KeyPairUIDTab::slotRefreshSigList() {
sigList->clearContents();
- for(const auto& uid : key.uids) {
+ for(const auto& uid : mKey.uids) {
row += uid.signatures.size();
}
sigList->setRowCount(row);
row = 0;
- for(const auto& uid : key.uids) {
+ for(const auto& uid : mKey.uids) {
// Only Show Selected UID's Signatures
if(!uidList->item(row, 0)->isSelected())
@@ -151,3 +156,24 @@ void KeyPairUIDTab::slotRefreshSigList() {
}
}
}
+
+void KeyPairUIDTab::slotAddSign() {
+
+ QVector<UID> selected_uids;
+
+ getUIDChecked(selected_uids);
+
+ auto keySignDialog = new KeySignDialog(mCtx, mKey, selected_uids, this);
+ keySignDialog->show();
+}
+
+void KeyPairUIDTab::getUIDChecked(QVector<UID> &selected_uids) {
+
+ auto &uids = mKey.uids;
+
+ for (int i = 0; i < uidList->rowCount(); i++) {
+ if (uidList->item(i, 0)->checkState() == Qt::Checked) {
+ selected_uids.push_back(uids[i]);
+ }
+ }
+}
diff --git a/src/ui/keypair_details/KeySignDialog.cpp b/src/ui/keypair_details/KeySignDialog.cpp
new file mode 100644
index 00000000..5a9b9118
--- /dev/null
+++ b/src/ui/keypair_details/KeySignDialog.cpp
@@ -0,0 +1,64 @@
+//
+// Created by eric on 2021/5/24.
+//
+
+#include "ui/keypair_details/KeySignDialog.h"
+
+KeySignDialog::KeySignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<UID> &uid, QWidget *parent) :
+ mCtx(ctx), mUids(uid), QDialog(parent), mKey(key) {
+
+ mKeyList = new KeyList(ctx,
+ KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress,
+ this);
+
+ signKeyButton = new QPushButton("Sign");
+
+ /**
+ * A DateTime after 5 Years is recommend.
+ */
+ expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5));
+ expiresEdit->setMinimumDateTime(QDateTime::currentDateTime());
+
+ /**
+ * Note further that the OpenPGP protocol uses 32 bit values for timestamps
+ * and thus can only encode dates up to the year 2106.
+ */
+ expiresEdit->setMaximumDate(QDate(2106, 1, 1));
+
+ nonExpireCheck = new QCheckBox("Non Expired");
+ nonExpireCheck->setTristate(false);
+
+ connect(nonExpireCheck, &QCheckBox::stateChanged, this, [this] (int state) -> void {
+ if(state == 0)
+ expiresEdit->setDisabled(false);
+ else
+ expiresEdit->setDisabled(true);
+ });
+
+ auto layout = new QGridLayout();
+
+ auto timeLayout = new QGridLayout();
+
+ layout->addWidget(mKeyList, 0, 0);
+ layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight);
+ timeLayout->addWidget(new QLabel(tr("Expired Time")), 0, 0);
+ timeLayout->addWidget(expiresEdit, 0, 1);
+ timeLayout->addWidget(nonExpireCheck, 0, 2);
+ layout->addLayout(timeLayout, 1, 0);
+
+ this->setLayout(layout);
+ this->setModal(true);
+ this->setWindowTitle(tr("Sign For Key's UID"));
+ this->adjustSize();
+}
+
+void KeySignDialog::slotSignKey() {
+ QVector<GpgKey> keys;
+ mKeyList->getCheckedKeys(keys);
+ mCtx->setSigners(keys);
+ const auto expires = expiresEdit->dateTime();
+
+ for(const auto &uid : mUids)
+ mCtx->signKey(mKey, uid.uid, &expires);
+}
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index 337c1fc5..2fdec43e 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -385,3 +385,14 @@ void KeyList::uploadFinished()
reply->deleteLater();
}
+
+void KeyList::getCheckedKeys(QVector<GpgKey> &keys) {
+
+ keys.clear();
+
+ for (int i = 0; i < mKeyList->rowCount(); i++) {
+ if (mKeyList->item(i, 0)->isSelected() == 1) {
+ keys.push_back(buffered_keys[i]);
+ }
+ }
+}