aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2022-01-02 23:40:04 +0000
committerSaturneric <[email protected]>2022-01-02 23:40:04 +0000
commit586b7a5211124bed6011ac71e9be51c26a542865 (patch)
tree92b9d81b6f76b2ca127221db39f9edb27e4f70cf
parent<refactor>(ui): take operations apart from key details. (diff)
downloadGpgFrontend-586b7a5211124bed6011ac71e9be51c26a542865.tar.gz
GpgFrontend-586b7a5211124bed6011ac71e9be51c26a542865.zip
<refactor>(ui): Enhanced sending email function.
-rw-r--r--src/ui/GpgFrontendUI.h6
-rw-r--r--src/ui/MainWindow.cpp2
-rw-r--r--src/ui/function/SMTPSendMailThread.cpp118
-rw-r--r--src/ui/function/SMTPSendMailThread.h21
-rw-r--r--src/ui/function/SMTPTestThread.cpp3
-rw-r--r--src/ui/function/SMTPTestThread.h7
-rw-r--r--src/ui/main_window/MainWindowUI.cpp4
-rw-r--r--src/ui/settings/SettingsKeyServer.cpp1
-rw-r--r--src/ui/smtp/EmailListEditor.cpp102
-rw-r--r--src/ui/smtp/EmailListEditor.h54
-rw-r--r--src/ui/smtp/RecipientsPicker.cpp76
-rw-r--r--src/ui/smtp/RecipientsPicker.h49
-rw-r--r--src/ui/smtp/SendMailDialog.cpp249
-rw-r--r--src/ui/smtp/SendMailDialog.h26
-rw-r--r--src/ui/smtp/SenderPicker.cpp76
-rw-r--r--src/ui/smtp/SenderPicker.h47
-rw-r--r--src/ui/widgets/KeyList.cpp55
-rw-r--r--src/ui/widgets/KeyList.h7
-rw-r--r--src/ui/widgets/SignersPicker.cpp30
-rw-r--r--src/ui/widgets/SignersPicker.h8
m---------third_party/AppImageUpdate0
-rw-r--r--ui/EmailListEditor.ui70
-rw-r--r--ui/SendMailDialog.ui208
23 files changed, 1070 insertions, 149 deletions
diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h
index 01f82822..90e15324 100644
--- a/src/ui/GpgFrontendUI.h
+++ b/src/ui/GpgFrontendUI.h
@@ -25,13 +25,15 @@
#ifndef GPGFRONTEND_GPGFRONTENDUI_H
#define GPGFRONTEND_GPGFRONTENDUI_H
-#include "GpgFrontend.h"
-
#include <QtCore>
#include <QtNetwork>
#include <QtPrintSupport>
#include <QtWidgets>
+#include "GpgFrontend.h"
+#include "gpg/GpgConstants.h"
+#include "gpg/GpgModel.h"
+
#undef LIBCONFIGXX_STATIC
#define LIBCONFIGXX_STATIC
#include <libconfig.h++>
diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp
index 0411be81..422db814 100644
--- a/src/ui/MainWindow.cpp
+++ b/src/ui/MainWindow.cpp
@@ -296,7 +296,7 @@ void MainWindow::restoreSettings() {
LOG(INFO) << "get checked key id" << key_id;
key_ids_ptr->push_back(key_id);
}
- mKeyList->setChecked(key_ids_ptr);
+ mKeyList->setChecked(std::move(key_ids_ptr));
}
auto& smtp = settings["smtp"];
diff --git a/src/ui/function/SMTPSendMailThread.cpp b/src/ui/function/SMTPSendMailThread.cpp
index 94e97749..3e5ce9bc 100644
--- a/src/ui/function/SMTPSendMailThread.cpp
+++ b/src/ui/function/SMTPSendMailThread.cpp
@@ -24,6 +24,14 @@
#include "SMTPSendMailThread.h"
+#include <boost/format.hpp>
+
+#include "gpg/function/BasicOperator.h"
+#include "gpg/function/GpgKeyGetter.h"
+#include "gpg/function/GpgKeyImportExporter.h"
+
+namespace GpgFrontend::UI {
+
void SMTPSendMailThread::run() {
SmtpClient smtp(host_.c_str(), port_, connection_type_);
@@ -32,6 +40,95 @@ void SMTPSendMailThread::run() {
smtp.setPassword(password_.c_str());
}
+ if (encrypt_content_ && public_key_ids_ != nullptr &&
+ !public_key_ids_->empty()) {
+ message.getContent().setContentType(
+ "multipart/encrypted; micalg=pgp-md5; "
+ "protocol=\"application/pgp-encrypted\"");
+ }
+
+ if (attach_signature_file_ && !private_key_id_.empty()) {
+ message.getContent().setContentType(
+ "multipart/signed; micalg=pgp-md5; "
+ "protocol=\"application/pgp-signature\"");
+ }
+
+ int index = 0;
+ for (auto& text : texts_) {
+ const auto plain_text = text->getText().toStdString();
+ // encrypt
+ if (encrypt_content_ && public_key_ids_ != nullptr &&
+ !public_key_ids_->empty()) {
+ ByteArrayPtr out_buffer = nullptr;
+ GpgEncrResult result;
+ auto in_buffer = std::make_unique<ByteArray>(plain_text);
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(public_key_ids_);
+ auto err = BasicOperator::GetInstance().Encrypt(
+ std::move(keys), *in_buffer, out_buffer, result);
+
+ if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) {
+ emit signalSMTPResult("Fail to encrypt with gpg keys");
+ return;
+ }
+ text->setText(out_buffer->c_str());
+ }
+
+ send_texts_.push_back(std::move(text));
+
+ // sign
+ if (attach_signature_file_ && !private_key_id_.empty()) {
+ ByteArrayPtr out_buffer = nullptr;
+ GpgSignResult result;
+
+ auto& plain_mime_text = send_texts_.back();
+ auto in_buffer =
+ std::make_unique<ByteArray>(plain_mime_text->getText().toStdString());
+ auto key = GpgKeyGetter::GetInstance().GetKey(private_key_id_);
+ auto keys = std::make_unique<KeyArgsList>();
+ keys->push_back(std::move(key));
+
+ auto err = BasicOperator::GetInstance().Sign(
+ std::move(keys), *in_buffer, out_buffer, GPGME_SIG_MODE_DETACH,
+ result);
+
+ if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) {
+ emit signalSMTPResult("Fail to sign with gpg keys");
+ return;
+ }
+
+ auto sign_content_name =
+ boost::format("%1%_sign_%2%.asc") % private_key_id_ % index++;
+
+ // Add MIME
+ send_texts_.push_back(std::make_unique<MimeText>(out_buffer->c_str()));
+ auto& sig_text = send_texts_.back();
+ sig_text->setContentType("application/pgp-signature");
+ sig_text->setEncoding(MimePart::_7Bit);
+ sig_text->setContentName(sign_content_name.str().c_str());
+ }
+ }
+
+ if (attach_public_key_file_ && !attached_public_key_ids_.empty()) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(attached_public_key_ids_);
+ ByteArrayPtr out_buffer = nullptr;
+ GpgKeyImportExporter::GetInstance().ExportKey(key, out_buffer);
+
+ auto public_key_file_name =
+ boost::format("%1%_pubkey.asc") % attached_public_key_ids_;
+ addFileContent(public_key_file_name.str().c_str(), out_buffer->c_str());
+ auto& key_file = files_.back();
+ key_file->setEncoding(MimePart::_7Bit);
+ key_file->setContentType("application/pgp-keys");
+ }
+
+ for (const auto& text : send_texts_) {
+ message.addPart(text.get());
+ }
+
+ for (const auto& file : files_) {
+ message.addPart(file.get());
+ }
+
// Now we can send the mail
if (!smtp.connectToHost()) {
emit signalSMTPResult("Fail to connect SMTP server");
@@ -77,12 +174,29 @@ void SMTPSendMailThread::setSender(const QString& sender) {
void SMTPSendMailThread::addTextContent(const QString& content) {
auto text = std::make_unique<MimeText>(content);
texts_.push_back(std::move(text));
- message.addPart(texts_.back().get());
}
void SMTPSendMailThread::addFileContent(const QString& file_name,
const QByteArray& content) {
auto file = std::make_unique<MimeFile>(content, file_name);
files_.push_back(std::move(file));
- message.addPart(files_.back().get());
}
+
+void SMTPSendMailThread::setEncryptContent(
+ bool encrypt_content, GpgFrontend::KeyIdArgsListPtr public_key_ids) {
+ this->encrypt_content_ = encrypt_content;
+ this->public_key_ids_ = std::move(public_key_ids);
+}
+
+void SMTPSendMailThread::setAttachSignatureFile(
+ bool attach_signature_file, GpgFrontend::KeyId private_key_id) {
+ this->attach_signature_file_ = attach_signature_file;
+ this->private_key_id_ = std::move(private_key_id);
+}
+
+void SMTPSendMailThread::setAttachPublicKey(
+ bool attach_public_key_file, GpgFrontend::KeyId attached_public_key_ids) {
+ this->attach_public_key_file_ = attach_public_key_file;
+ this->attached_public_key_ids_ = std::move(attached_public_key_ids);
+}
+} // namespace GpgFrontend::UI
diff --git a/src/ui/function/SMTPSendMailThread.h b/src/ui/function/SMTPSendMailThread.h
index ff417f5d..e5c9e27f 100644
--- a/src/ui/function/SMTPSendMailThread.h
+++ b/src/ui/function/SMTPSendMailThread.h
@@ -33,6 +33,7 @@
#include "ui/GpgFrontendUI.h"
+namespace GpgFrontend::UI {
class SMTPSendMailThread : public QThread {
Q_OBJECT
public:
@@ -62,6 +63,15 @@ class SMTPSendMailThread : public QThread {
void addFileContent(const QString& file_name, const QByteArray& content);
+ void setEncryptContent(bool encrypt_content,
+ GpgFrontend::KeyIdArgsListPtr public_key_ids);
+
+ void setAttachSignatureFile(bool attach_signature_file,
+ GpgFrontend::KeyId private_key_id);
+
+ void setAttachPublicKey(bool attach_public_key_file,
+ GpgFrontend::KeyId attached_public_key_ids);
+
signals:
void signalSMTPResult(const QString& result);
@@ -69,6 +79,7 @@ class SMTPSendMailThread : public QThread {
void run() override;
private:
+ // SMTP Options
std::string host_;
int port_;
SmtpClient::ConnectionType connection_type_;
@@ -79,7 +90,17 @@ class SMTPSendMailThread : public QThread {
MimeMessage message;
std::vector<std::unique_ptr<MimeText>> texts_;
+ std::vector<std::unique_ptr<MimeText>> send_texts_;
std::vector<std::unique_ptr<MimeFile>> files_;
+
+ // GPG Options
+ bool encrypt_content_ = false;
+ GpgFrontend::KeyIdArgsListPtr public_key_ids_;
+ bool attach_signature_file_ = false;
+ GpgFrontend::KeyId private_key_id_;
+ bool attach_public_key_file_ = false;
+ GpgFrontend::KeyId attached_public_key_ids_;
};
+} // namespace GpgFrontend::UI
#endif // GPGFRONTEND_SMTPSENDMAILTHREAD_H
diff --git a/src/ui/function/SMTPTestThread.cpp b/src/ui/function/SMTPTestThread.cpp
index 63c41a90..0eb267f2 100644
--- a/src/ui/function/SMTPTestThread.cpp
+++ b/src/ui/function/SMTPTestThread.cpp
@@ -23,6 +23,7 @@
*/
#include "SMTPTestThread.h"
+namespace GpgFrontend::UI {
void SMTPTestThread::run() {
SmtpClient smtp(host_.c_str(), port_, connection_type_);
@@ -41,3 +42,5 @@ void SMTPTestThread::run() {
smtp.quit();
emit signalSMTPTestResult("Succeed in testing connection");
}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/function/SMTPTestThread.h b/src/ui/function/SMTPTestThread.h
index e2f2048d..db61d97d 100644
--- a/src/ui/function/SMTPTestThread.h
+++ b/src/ui/function/SMTPTestThread.h
@@ -32,6 +32,7 @@
#endif
#include "ui/GpgFrontendUI.h"
+namespace GpgFrontend::UI {
class SMTPTestThread : public QThread {
Q_OBJECT
@@ -46,9 +47,7 @@ class SMTPTestThread : public QThread {
connection_type_(connection_type),
identify_(identify),
username_(std::move(username)),
- password_(std::move(password)) {
-
- }
+ password_(std::move(password)) {}
signals:
void signalSMTPTestResult(const QString& result);
@@ -66,4 +65,6 @@ class SMTPTestThread : public QThread {
std::string password_;
};
+} // namespace GpgFrontend::UI
+
#endif // GPGFRONTEND_SMTPTESTTHREAD_H
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 0c557d16..aeed1326 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -258,7 +258,7 @@ void MainWindow::createActions() {
/* Popup-Menu-Action for KeyList
*/
appendSelectedKeysAct =
- new QAction(_("Append Selected Key(s) To Text"), this);
+ new QAction(_("Append Public Key To Text Editor"), this);
appendSelectedKeysAct->setToolTip(
_("Append The Selected Keys To Text in Editor"));
connect(appendSelectedKeysAct, SIGNAL(triggered()), this,
@@ -297,7 +297,7 @@ void MainWindow::createActions() {
connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader()));
#ifdef SMTP_SUPPORT
- sendMailAct = new QAction(_("Send An Email"), this);
+ sendMailAct = new QAction(_("New Message"), this);
sendMailAct->setIcon(QIcon(":email.png"));
connect(sendMailAct, &QAction::triggered, this, [=]() {
auto* dialog = new SendMailDialog({}, this);
diff --git a/src/ui/settings/SettingsKeyServer.cpp b/src/ui/settings/SettingsKeyServer.cpp
index 1d520e35..db27e003 100644
--- a/src/ui/settings/SettingsKeyServer.cpp
+++ b/src/ui/settings/SettingsKeyServer.cpp
@@ -95,6 +95,7 @@ KeyserverTab::KeyserverTab(QWidget* parent)
const auto item = ui->keyServerListTable->item(i, 1);
if (!item->isSelected()) continue;
this->keyServerStrList.removeAt(i);
+ break;
}
this->refreshTable();
});
diff --git a/src/ui/smtp/EmailListEditor.cpp b/src/ui/smtp/EmailListEditor.cpp
new file mode 100644
index 00000000..49399f11
--- /dev/null
+++ b/src/ui/smtp/EmailListEditor.cpp
@@ -0,0 +1,102 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "EmailListEditor.h"
+
+#include "ui_EmailListEditor.h"
+
+GpgFrontend::UI::EmailListEditor::EmailListEditor(const QString& email_list,
+ QWidget* parent)
+ : QDialog(parent), ui(std::make_shared<Ui_EmailListEditorDialog>()) {
+ ui->setupUi(this);
+
+ QStringList email_string_list = email_list.split(';');
+
+ if (!email_string_list.isEmpty()) {
+ for (const auto& recipient : email_string_list) {
+ auto _recipient = recipient.trimmed();
+ if (check_email_address(_recipient)) {
+ auto item = new QListWidgetItem(_recipient);
+ ui->emaillistWidget->addItem(item);
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ }
+ }
+ }
+
+ connect(ui->addEmailAddressButton, &QPushButton::clicked, this, [=]() {
+ auto item = new QListWidgetItem("new email address");
+ ui->emaillistWidget->addItem(item);
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ });
+
+ connect(
+ ui->actionDelete_Selected_Email_Address, &QAction::triggered, this,
+ [=]() {
+ const auto row_size = ui->emaillistWidget->count();
+ for (int i = 0; i < row_size; i++) {
+ auto item = ui->emaillistWidget->item(i);
+ if (!item->isSelected()) continue;
+ delete ui->emaillistWidget->takeItem(ui->emaillistWidget->row(item));
+ break;
+ }
+ });
+
+ ui->titleLabel->setText(_("Email List:"));
+ ui->tipsLabel->setText(
+ _("Tips: You can double-click the email address in the edit list, or "
+ "click the email to pop up the option menu."));
+ ui->addEmailAddressButton->setText(_("Add An Email Address"));
+ this->setWindowTitle(_("Email List Editor"));
+ ui->actionDelete_Selected_Email_Address->setText(_("Delete"));
+
+ popupMenu = new QMenu(this);
+ popupMenu->addAction(ui->actionDelete_Selected_Email_Address);
+
+ this->exec();
+}
+
+bool GpgFrontend::UI::EmailListEditor::check_email_address(
+ const QString& email_address) {
+ return re_email.match(email_address).hasMatch();
+}
+
+QString GpgFrontend::UI::EmailListEditor::getEmailList() {
+ QString email_list;
+ for (int i = 0; i < ui->emaillistWidget->count(); ++i) {
+ QListWidgetItem* item = ui->emaillistWidget->item(i);
+ if (check_email_address(item->text())) {
+ email_list.append(item->text());
+ email_list.append("; ");
+ }
+ }
+ return email_list;
+}
+
+void GpgFrontend::UI::EmailListEditor::contextMenuEvent(
+ QContextMenuEvent* event) {
+ QWidget::contextMenuEvent(event);
+ if (ui->emaillistWidget->selectedItems().length() > 0) {
+ popupMenu->exec(event->globalPos());
+ }
+}
diff --git a/src/ui/smtp/EmailListEditor.h b/src/ui/smtp/EmailListEditor.h
new file mode 100644
index 00000000..d4e476a4
--- /dev/null
+++ b/src/ui/smtp/EmailListEditor.h
@@ -0,0 +1,54 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_EMAILLISTEDITOR_H
+#define GPGFRONTEND_EMAILLISTEDITOR_H
+
+#include "GpgFrontendUI.h"
+
+class Ui_EmailListEditorDialog;
+
+namespace GpgFrontend::UI {
+class EmailListEditor : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit EmailListEditor(const QString& email_list, QWidget* parent);
+ QString getEmailList();
+
+ private:
+ std::shared_ptr<Ui_EmailListEditorDialog> ui;
+ QMenu* popupMenu{};
+
+ QRegularExpression re_email{
+ R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"};
+
+ bool check_email_address(const QString& email_address);
+
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event) override;
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_EMAILLISTEDITOR_H
diff --git a/src/ui/smtp/RecipientsPicker.cpp b/src/ui/smtp/RecipientsPicker.cpp
new file mode 100644
index 00000000..ee6ac673
--- /dev/null
+++ b/src/ui/smtp/RecipientsPicker.cpp
@@ -0,0 +1,76 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "RecipientsPicker.h"
+
+#include "ui/widgets/KeyList.h"
+
+GpgFrontend::UI::RecipientsPicker::RecipientsPicker(
+ const GpgFrontend::KeyIdArgsListPtr& current_key_ids, QWidget* parent)
+ : QDialog(parent) {
+ auto confirm_button = new QPushButton(_("Confirm"));
+ connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept()));
+
+ // Setup KeyList
+ key_list_ = new KeyList(false, this);
+ key_list_->addListGroupTab(
+ _("Recipient(s)"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress,
+ [](const GpgKey& key) -> bool {
+ return !key.is_private_key() && key.CanEncrActual();
+ });
+ key_list_->slotRefresh();
+
+ auto key_ids = std::make_unique<GpgFrontend::KeyIdArgsList>();
+ for (const auto& key_id : *current_key_ids) {
+ key_ids->push_back(key_id);
+ }
+ key_list_->setChecked(std::move(key_ids));
+
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(new QLabel(QString(_("Select Recipient(s)")) + ": "));
+ vbox2->addWidget(key_list_);
+ vbox2->addWidget(new QLabel(
+ QString(_("We use the public key provided by the recipient to encrypt "
+ "the text.")) +
+ "\n" +
+ _("If you want to send to multiple recipients at the same time, you can "
+ "select multiple keys.")));
+ vbox2->addWidget(confirm_button);
+ vbox2->addStretch(0);
+ setLayout(vbox2);
+
+ this->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint);
+
+ this->setModal(true);
+ this->setWindowTitle("Recipient(s) Picker");
+ this->setMinimumWidth(480);
+ this->exec();
+}
+
+GpgFrontend::KeyIdArgsListPtr
+GpgFrontend::UI::RecipientsPicker::getCheckedRecipients() {
+ return key_list_->getChecked();
+}
diff --git a/src/ui/smtp/RecipientsPicker.h b/src/ui/smtp/RecipientsPicker.h
new file mode 100644
index 00000000..bf128149
--- /dev/null
+++ b/src/ui/smtp/RecipientsPicker.h
@@ -0,0 +1,49 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_RECIPENTSPICKER_H
+#define GPGFRONTEND_RECIPENTSPICKER_H
+
+#include "GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyList;
+
+class RecipientsPicker : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit RecipientsPicker(
+ const GpgFrontend::KeyIdArgsListPtr& current_key_ids,
+ QWidget* parent = nullptr);
+
+ GpgFrontend::KeyIdArgsListPtr getCheckedRecipients();
+
+ private:
+ KeyList* key_list_;
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_RECIPENTSPICKER_H
diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/smtp/SendMailDialog.cpp
index 66bfc546..3c98dab5 100644
--- a/src/ui/smtp/SendMailDialog.cpp
+++ b/src/ui/smtp/SendMailDialog.cpp
@@ -24,12 +24,15 @@
#include "SendMailDialog.h"
-#include <utility>
-
+#include "gpg/function/GpgKeyGetter.h"
+#include "ui/smtp/EmailListEditor.h"
+#include "ui/smtp/RecipientsPicker.h"
+#include "ui/smtp/SenderPicker.h"
#include "ui_SendMailDialog.h"
#ifdef SMTP_SUPPORT
#include "smtp/SmtpMime"
+#include "ui/function/SMTPSendMailThread.h"
#include "ui/settings/GlobalSettingStation.h"
#endif
@@ -40,7 +43,7 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent)
// read from settings
initSettings();
- if (smtpAddress.isEmpty()) {
+ if (smtp_address_.isEmpty()) {
QMessageBox::critical(
this, _("Incomplete configuration"),
_("The SMTP address is empty, please go to the setting interface to "
@@ -57,7 +60,7 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent)
ui->textEdit->setText(text);
ui->errorLabel->setHidden(true);
- ui->senderEdit->setText(defaultSender);
+ ui->senderEdit->setText(default_sender_);
connect(ui->ccButton, &QPushButton::clicked, [=]() {
ui->ccInputWidget->setHidden(!ui->ccInputWidget->isHidden());
ui->ccEdit->clear();
@@ -72,6 +75,23 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent)
&SendMailDialog::slotConfirm);
#endif
+ connect(ui->senderKeySelectButton, &QPushButton::clicked, this, [=]() {
+ auto picker = new SenderPicker(sender_key_id_, this);
+ sender_key_id_ = picker->getCheckedSender();
+ set_sender_value_label();
+ });
+
+ connect(ui->recipientKeySelectButton, &QPushButton::clicked, this, [=]() {
+ auto picker = new RecipientsPicker(recipients_key_ids_, this);
+ recipients_key_ids_ = picker->getCheckedRecipients();
+ set_recipients_value_label();
+ });
+
+ connect(ui->recipientsEditButton, &QPushButton::clicked, this, [=]() {
+ auto editor = new EmailListEditor(ui->recipientEdit->text(), this);
+ ui->recipientEdit->setText(editor->getEmailList());
+ });
+
ui->ccButton->setText(_("CC"));
ui->bccButton->setText(_("BCC"));
ui->senderLabel->setText(_("Sender"));
@@ -82,9 +102,15 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent)
ui->tipsLabel->setText(
_("Tips: You can fill in multiple email addresses, please separate them "
"with \";\"."));
- ui->sendMailButton->setText(_("Send Mail"));
-
- this->setWindowTitle(_("Send Mail"));
+ ui->sendMailButton->setText(_("Send Message"));
+ ui->senderKeySelectButton->setText(_("Select Sender GPG Key"));
+ ui->recipientKeySelectButton->setText(_("Select Recipient(s) GPG Key"));
+ ui->gpgOperaLabel->setText(_("GPG Operations"));
+ ui->attacSignatureCheckBox->setText(_("Attach signature"));
+ ui->attachSenderPublickeyCheckBox->setText(_("Attach sender's public key"));
+ ui->contentEncryptCheckBox->setText(_("Encrypt content"));
+
+ this->setWindowTitle(_("New Message"));
this->setAttribute(Qt::WA_DeleteOnClose);
}
@@ -155,129 +181,204 @@ void SendMailDialog::slotConfirm() {
return;
}
- SmtpClient::ConnectionType connectionType =
+ SmtpClient::ConnectionType connection_type_ =
SmtpClient::ConnectionType::TcpConnection;
- if (connectionTypeSettings == "SSL") {
- connectionType = SmtpClient::ConnectionType::SslConnection;
- } else if (connectionTypeSettings == "TLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
- } else if (connectionTypeSettings == "STARTTLS") {
- connectionType = SmtpClient::ConnectionType::TlsConnection;
+ if (connection_type_settings_ == "SSL") {
+ connection_type_ = SmtpClient::ConnectionType::SslConnection;
+ } else if (connection_type_settings_ == "TLS") {
+ connection_type_ = SmtpClient::ConnectionType::TlsConnection;
+ } else if (connection_type_settings_ == "STARTTLS") {
+ connection_type_ = SmtpClient::ConnectionType::TlsConnection;
} else {
- connectionType = SmtpClient::ConnectionType::TcpConnection;
+ connection_type_ = SmtpClient::ConnectionType::TcpConnection;
}
- SmtpClient smtp(smtpAddress, port, connectionType);
-
- // We need to set the username (your email address) and the password
- // for smtp authentification.
-
- smtp.setUser(username);
- smtp.setPassword(password);
-
- // Now we create a MimeMessage object. This will be the email.
-
- MimeMessage message;
-
- message.setSender(new EmailAddress(ui->senderEdit->text()));
- for (const auto& rcpt : rcpt_string_list) {
- if (!rcpt.isEmpty()) message.addRecipient(new EmailAddress(rcpt.trimmed()));
- }
- for (const auto& cc : cc_string_list) {
- if (!cc.isEmpty()) message.addCc(new EmailAddress(cc.trimmed()));
- }
- for (const auto& bcc : bcc_string_list) {
- if (!bcc.isEmpty()) message.addBcc(new EmailAddress(bcc.trimmed()));
+ auto host = smtp_address_.toStdString();
+ auto port = port_;
+ auto connection_type = connection_type_;
+ bool identity_needed = identity_enable_;
+ auto username = username_.toStdString();
+ auto password = password_.toStdString();
+ auto sender_address = ui->senderEdit->text().toStdString();
+
+ auto thread = new SMTPSendMailThread(
+ host, port, connection_type, identity_needed, username, password, this);
+
+ thread->setSender(ui->senderEdit->text());
+ thread->setRecipient(ui->recipientEdit->text());
+ thread->setCC(ui->ccEdit->text());
+ thread->setBCC(ui->bccEdit->text());
+ thread->setSubject(ui->subjectEdit->text());
+ thread->addTextContent(ui->textEdit->toPlainText());
+
+ if (ui->contentEncryptCheckBox->checkState() == Qt::Checked) {
+ if (recipients_key_ids_ == nullptr) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("You have checked the encrypted email content, but you have not "
+ "selected the recipient's GPG key. This is dangerous and the mail "
+ "will not be encrypted. So the send operation is forbidden"));
+ return;
+ } else {
+ auto key_ids = std::make_unique<KeyIdArgsList>();
+ for (const auto& key_id : *recipients_key_ids_)
+ key_ids->push_back(key_id);
+ thread->setEncryptContent(true, std::move(key_ids));
+ }
}
- message.setSubject(ui->subjectEdit->text());
- // Now add some text to the email.
- // First we create a MimeText object.
+ if (ui->attacSignatureCheckBox->checkState() == Qt::Checked) {
+ if (sender_key_id_.empty()) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("You checked the option to attach signature to the email, but did "
+ "not specify the sender's GPG Key. This will cause the content of "
+ "the email to be inconsistent with your expectations, so the "
+ "operation is prohibited."));
+ return;
+ } else {
+ thread->setAttachSignatureFile(true, sender_key_id_);
+ }
+ }
- MimeText text;
- text.setText(ui->textEdit->toPlainText());
+ if (ui->attachSenderPublickeyCheckBox->checkState() == Qt::Checked) {
+ if (sender_key_id_.empty()) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("You checked the option to attach your public key to the email, "
+ "but did not specify the sender's GPG Key. This will cause the "
+ "content of "
+ "the email to be inconsistent "
+ "with your expectations, so the operation is prohibited."));
+ return;
+ } else {
+ thread->setAttachPublicKey(true, sender_key_id_);
+ }
+ }
- // Now add it to the mail
- message.addPart(&text);
+ // Waiting Dialog
+ auto* waiting_dialog = new QProgressDialog(this);
+ waiting_dialog->setMaximum(0);
+ waiting_dialog->setMinimum(0);
+ auto waiting_dialog_label =
+ new QLabel(QString(_("Sending Email...")) + "<br /><br />" +
+ _("If the process does not end for a long time, please check "
+ "again whether your SMTP server configuration is correct."));
+ waiting_dialog_label->setWordWrap(true);
+ waiting_dialog->setLabel(waiting_dialog_label);
+ waiting_dialog->resize(420, 120);
+ connect(thread, &SMTPSendMailThread::signalSMTPResult, this,
+ &SendMailDialog::slotTestSMTPConnectionResult);
+ connect(thread, &QThread::finished, [=]() {
+ waiting_dialog->finished(0);
+ waiting_dialog->deleteLater();
+ });
+ connect(waiting_dialog, &QProgressDialog::canceled, [=]() {
+ LOG(INFO) << "cancel clicked";
+ if (thread->isRunning()) thread->terminate();
+ QCoreApplication::quit();
+ exit(0);
+ });
- // Now we can send the mail
- if (!smtp.connectToHost()) {
- qDebug() << "Connect to SMTP Server Failed";
- QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server"));
- return;
- }
- if (!smtp.login()) {
- qDebug() << "Login to SMTP Server Failed";
- QMessageBox::critical(this, _("Fail"), _("Fail to Login into SMTP Server"));
- return;
- }
- if (!smtp.sendMail(message)) {
- qDebug() << "Send Mail to SMTP Server Failed";
- QMessageBox::critical(this, _("Fail"),
- _("Fail to Send Mail to SMTP Server"));
- return;
- }
- smtp.quit();
+ // Show Waiting Dialog
+ waiting_dialog->show();
+ waiting_dialog->setFocus();
- // Close after sending email
- QMessageBox::information(this, _("Success"),
- _("Succeed in Sending Mail to SMTP Server"));
- deleteLater();
+ thread->start();
+ QEventLoop loop;
+ connect(thread, &QThread::finished, &loop, &QEventLoop::quit);
+ loop.exec();
}
void SendMailDialog::initSettings() {
auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
try {
- ability_enable = settings.lookup("smtp.enable");
+ ability_enable_ = settings.lookup("smtp.enable");
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked");
}
try {
- identity_enable = settings.lookup("smtp.identity_enable");
+ identity_enable_ = settings.lookup("smtp.identity_enable");
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("identity_enable");
}
try {
- smtpAddress = settings.lookup("smtp.mail_address").c_str();
+ smtp_address_ = settings.lookup("smtp.mail_address").c_str();
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("mail_address");
}
try {
- username = settings.lookup("smtp.username").c_str();
+ username_ = settings.lookup("smtp.username").c_str();
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("username");
}
try {
- password = settings.lookup("smtp.password").c_str();
+ password_ = settings.lookup("smtp.password").c_str();
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("password");
}
try {
- port = settings.lookup("smtp.port");
+ port_ = settings.lookup("smtp.port");
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("port");
}
try {
- connectionTypeSettings = settings.lookup("smtp.connection_type").c_str();
+ connection_type_settings_ = settings.lookup("smtp.connection_type").c_str();
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("connection_type");
}
try {
- defaultSender = settings.lookup("smtp.default_sender").c_str();
+ default_sender_ = settings.lookup("smtp.default_sender").c_str();
} catch (...) {
LOG(ERROR) << _("Setting Operation Error") << _("default_sender");
}
}
-
#endif
+void SendMailDialog::set_sender_value_label() {
+ auto key = GpgKeyGetter::GetInstance().GetKey(sender_key_id_);
+ if (key.good()) {
+ ui->senderKeyValueLabel->setText(key.uids()->front().uid().c_str());
+ }
+}
+
+void SendMailDialog::set_recipients_value_label() {
+ auto keys = GpgKeyGetter::GetInstance().GetKeys(recipients_key_ids_);
+ std::stringstream ss;
+ for (const auto& key : *keys) {
+ if (key.good()) {
+ ss << key.uids()->front().uid().c_str() << ";";
+ }
+ }
+ ui->recipientsKeyValueLabel->setText(ss.str().c_str());
+}
+
+void SendMailDialog::slotTestSMTPConnectionResult(const QString& result) {
+ if (result == "Fail to connect SMTP server") {
+ QMessageBox::critical(this, _("Fail"), _("Fail to Connect SMTP Server."));
+ } else if (result == "Fail to login") {
+ QMessageBox::critical(this, _("Fail"), _("Fail to Login."));
+ } else if (result == "Fail to send mail") {
+ QMessageBox::critical(this, _("Fail"), _("Fail to Login."));
+ } else if (result == "Succeed in testing connection") {
+ QMessageBox::information(this, _("Success"),
+ _("Succeed in connecting and login"));
+ } else if (result == "Succeed in sending a test email") {
+ QMessageBox::information(
+ this, _("Success"),
+ _("Succeed in sending the message to the SMTP Server"));
+ } else {
+ QMessageBox::critical(this, _("Fail"), _("Unknown error."));
+ }
+}
+
} // namespace GpgFrontend::UI
diff --git a/src/ui/smtp/SendMailDialog.h b/src/ui/smtp/SendMailDialog.h
index 979d4f88..bf082c39 100644
--- a/src/ui/smtp/SendMailDialog.h
+++ b/src/ui/smtp/SendMailDialog.h
@@ -40,24 +40,34 @@ class SendMailDialog : public QDialog {
void slotConfirm();
+ void slotTestSMTPConnectionResult(const QString& result);
+
private:
void initSettings();
std::shared_ptr<Ui_SendMailDialog> ui;
- bool ability_enable = false;
- bool identity_enable = false;
- QString smtpAddress;
- QString username;
- QString password;
- QString defaultSender;
- QString connectionTypeSettings = "None";
- int port = 25;
+ bool ability_enable_ = false;
+ bool identity_enable_ = false;
+ QString smtp_address_;
+ QString username_;
+ QString password_;
+ QString default_sender_;
+ QString connection_type_settings_ = "None";
+ int port_ = 25;
+
+ GpgFrontend::KeyId sender_key_id_;
+ GpgFrontend::KeyIdArgsListPtr recipients_key_ids_ =
+ std::make_unique<GpgFrontend::KeyIdArgsList>();
QRegularExpression re_email{
R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"};
bool check_email_address(const QString& str);
+
+ void set_sender_value_label();
+
+ void set_recipients_value_label();
};
} // namespace GpgFrontend::UI
diff --git a/src/ui/smtp/SenderPicker.cpp b/src/ui/smtp/SenderPicker.cpp
new file mode 100644
index 00000000..1cbd409f
--- /dev/null
+++ b/src/ui/smtp/SenderPicker.cpp
@@ -0,0 +1,76 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#include "SenderPicker.h"
+
+#include "ui/widgets/KeyList.h"
+
+GpgFrontend::UI::SenderPicker::SenderPicker(const KeyId& current_key_id,
+ QWidget* parent)
+ : QDialog(parent) {
+ auto confirm_button = new QPushButton(_("Confirm"));
+ connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept()));
+
+ // Setup KeyList
+ key_list_ = new KeyList(false, this);
+ key_list_->addListGroupTab(
+ _("Sender"), KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress,
+ [](const GpgKey& key) -> bool { return key.CanSignActual(); });
+ key_list_->slotRefresh();
+
+ auto key_ids = std::make_unique<GpgFrontend::KeyIdArgsList>();
+ key_ids->push_back(current_key_id);
+ key_list_->setChecked(std::move(key_ids));
+
+ auto* vbox2 = new QVBoxLayout();
+ vbox2->addWidget(new QLabel(QString(_("Select Sender")) + ": "));
+ vbox2->addWidget(key_list_);
+ vbox2->addWidget(new QLabel(
+ QString(
+ _("As the sender of the mail, the private key is generally used.")) +
+ "\n" +
+ _(" The private key is generally used as a signature for the content of "
+ "the mail.")));
+ vbox2->addWidget(confirm_button);
+ vbox2->addStretch(0);
+ setLayout(vbox2);
+
+ this->setWindowFlags(Qt::Window | Qt::WindowTitleHint |
+ Qt::CustomizeWindowHint);
+
+ this->setModal(true);
+ this->setWindowTitle("Sender Picker");
+ this->setMinimumWidth(480);
+ this->exec();
+}
+
+GpgFrontend::KeyId GpgFrontend::UI::SenderPicker::getCheckedSender() {
+ auto checked_keys = key_list_->getChecked();
+ if (!checked_keys->empty()) {
+ return key_list_->getChecked()->front();
+ } else {
+ return {};
+ }
+}
diff --git a/src/ui/smtp/SenderPicker.h b/src/ui/smtp/SenderPicker.h
new file mode 100644
index 00000000..3745bb34
--- /dev/null
+++ b/src/ui/smtp/SenderPicker.h
@@ -0,0 +1,47 @@
+/**
+ * This file is part of GpgFrontend.
+ *
+ * GpgFrontend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Foobar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from gpg4usb-team.
+ * Their source code version also complies with GNU General Public License.
+ *
+ * The source code version of this software was modified and released
+ * by Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ */
+
+#ifndef GPGFRONTEND_SENDERPICKER_H
+#define GPGFRONTEND_SENDERPICKER_H
+
+#include "GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class KeyList;
+
+class SenderPicker : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit SenderPicker(const KeyId& current_key_id, QWidget* parent = nullptr);
+
+ GpgFrontend::KeyId getCheckedSender();
+
+ private:
+ KeyList* key_list_;
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SENDERPICKER_H
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index fb715b2b..6dec19e7 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -79,7 +79,7 @@ void KeyList::init() {
&SignalStation::signalRefreshStatusBar);
setAcceptDrops(true);
-
+
ui->refreshKeyListButton->setText(_("Refresh"));
ui->syncButton->setText(_("Sync Public Key"));
ui->syncButton->setToolTip(_("Sync public key with your default keyserver"));
@@ -227,17 +227,14 @@ void KeyList::setChecked(const KeyIdArgsListPtr& keyIds,
}
}
-void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) {
- if (ui->keyGroupTab->size().isEmpty()) return;
+void KeyList::setChecked(KeyIdArgsListPtr key_ids) {
auto key_list = qobject_cast<QTableWidget*>(ui->keyGroupTab->currentWidget());
- const auto& buffered_keys =
- mKeyTables[ui->keyGroupTab->currentIndex()].buffered_keys;
-
- if (!keyIds->empty()) {
- for (int i = 0; i < key_list->rowCount(); i++) {
- if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) !=
- keyIds->end()) {
- key_list->item(i, 0)->setCheckState(Qt::Checked);
+ if (key_list == nullptr) return;
+ if (!mKeyTables.empty()) {
+ for (auto& key_table : mKeyTables) {
+ if (key_table.key_list == key_list) {
+ key_table.SetChecked(std::move(key_ids));
+ break;
}
}
}
@@ -460,31 +457,30 @@ void KeyList::slotSyncWithKeyServer() {
});
}
-KeyIdArgsListPtr KeyTable::GetChecked() {
- auto ret = std::make_unique<KeyIdArgsList>();
+KeyIdArgsListPtr& KeyTable::GetChecked() {
+ LOG(INFO) << "called";
+ if (checked_key_ids_ == nullptr)
+ checked_key_ids_ = std::make_unique<KeyIdArgsList>();
+ auto& ret = checked_key_ids_;
for (int i = 0; i < key_list->rowCount(); i++) {
- if (key_list->item(i, 0)->checkState() == Qt::Checked) {
- ret->push_back(buffered_keys[i].id());
+ auto key_id = buffered_keys[i].id();
+ if (key_list->item(i, 0)->checkState() == Qt::Checked &&
+ std::find(ret->begin(), ret->end(), key_id) == ret->end()) {
+ ret->push_back(key_id);
}
}
return ret;
}
-void KeyTable::SetChecked(const KeyIdArgsListPtr& key_ids) {
- if (!key_ids->empty()) {
- for (int i = 0; i < key_list->rowCount(); i++) {
- if (std::find(key_ids->begin(), key_ids->end(), buffered_keys[i].id()) !=
- key_ids->end()) {
- key_list->item(i, 0)->setCheckState(Qt::Checked);
- }
- }
- }
+void KeyTable::SetChecked(KeyIdArgsListPtr key_ids) {
+ LOG(INFO) << "called";
+ checked_key_ids_ = std::move(key_ids);
}
void KeyTable::Refresh(KeyLinkListPtr m_keys) {
LOG(INFO) << "Called";
- auto checked_key_list = GetChecked();
+ auto& checked_key_list = GetChecked();
// while filling the table, sort enabled causes errors
key_list->setSortingEnabled(false);
@@ -590,7 +586,14 @@ void KeyTable::Refresh(KeyLinkListPtr m_keys) {
++row_index;
}
- SetChecked(checked_key_list);
+ if (!checked_key_list->empty()) {
+ for (int i = 0; i < key_list->rowCount(); i++) {
+ if (std::find(checked_key_list->begin(), checked_key_list->end(),
+ buffered_keys[i].id()) != checked_key_list->end()) {
+ key_list->item(i, 0)->setCheckState(Qt::Checked);
+ }
+ }
+ }
LOG(INFO) << "End";
}
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index 617bb274..8d6fb600 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -59,6 +59,7 @@ struct KeyTable {
KeyListColumn::InfoType info_type;
std::vector<GpgKey> buffered_keys;
std::function<bool(const GpgKey&)> filter;
+ KeyIdArgsListPtr checked_key_ids_;
KeyTable(
QTableWidget* _key_list, KeyListRow::KeyType _select_type,
@@ -73,9 +74,9 @@ struct KeyTable {
void Refresh(KeyLinkListPtr m_keys = nullptr);
- KeyIdArgsListPtr GetChecked();
+ KeyIdArgsListPtr& GetChecked();
- void SetChecked(const KeyIdArgsListPtr& key_ids);
+ void SetChecked(KeyIdArgsListPtr key_ids);
};
class KeyList : public QWidget {
@@ -102,7 +103,7 @@ class KeyList : public QWidget {
static KeyIdArgsListPtr getChecked(const KeyTable& key_table);
KeyIdArgsListPtr getPrivateChecked();
KeyIdArgsListPtr getAllPrivateKeys();
- void setChecked(const KeyIdArgsListPtr& keyIds);
+ void setChecked(KeyIdArgsListPtr key_ids);
static void setChecked(const KeyIdArgsListPtr& keyIds,
const KeyTable& key_table);
KeyIdArgsListPtr getSelected();
diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp
index e769d05c..b035bf19 100644
--- a/src/ui/widgets/SignersPicker.cpp
+++ b/src/ui/widgets/SignersPicker.cpp
@@ -24,31 +24,31 @@
#include "ui/widgets/SignersPicker.h"
+#include "ui/widgets/KeyList.h"
+
namespace GpgFrontend::UI {
SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
- auto confirmButton = new QPushButton(_("Confirm"));
- connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
+ auto confirm_button = new QPushButton(_("Confirm"));
+ connect(confirm_button, SIGNAL(clicked(bool)), this, SLOT(accept()));
/*Setup KeyList*/
- mKeyList = new KeyList(false, this);
- mKeyList->addListGroupTab(
+ key_list_ = new KeyList(false, this);
+ key_list_->addListGroupTab(
_("Signers"), KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
- [](const GpgKey& key) -> bool {
- if (!key.CanSignActual())
- return false;
- else
- return true;
- });
- mKeyList->slotRefresh();
+ [](const GpgKey& key) -> bool { return key.CanSignActual(); });
+ key_list_->slotRefresh();
auto* vbox2 = new QVBoxLayout();
vbox2->addWidget(new QLabel(QString(_("Select Signer(s)")) + ": "));
- vbox2->addWidget(mKeyList);
+ vbox2->addWidget(key_list_);
vbox2->addWidget(new QLabel(
- _("If any key is selected, the default key will be used for signing.")));
- vbox2->addWidget(confirmButton);
+ QString(
+ _("Please select one or more private keys you use for signing.")) +
+ "\n" +
+ _("If no key is selected, the default key will be used for signing.")));
+ vbox2->addWidget(confirm_button);
vbox2->addStretch(0);
setLayout(vbox2);
@@ -62,7 +62,7 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
}
GpgFrontend::KeyIdArgsListPtr SignersPicker::getCheckedSigners() {
- return mKeyList->getPrivateChecked();
+ return key_list_->getPrivateChecked();
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/widgets/SignersPicker.h b/src/ui/widgets/SignersPicker.h
index 055b6ef6..08972a76 100644
--- a/src/ui/widgets/SignersPicker.h
+++ b/src/ui/widgets/SignersPicker.h
@@ -25,12 +25,12 @@
#ifndef GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
#define GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H
-#include "GpgFrontend.h"
-#include "gpg/GpgContext.h"
-#include "ui/widgets/KeyList.h"
+#include "GpgFrontendUI.h"
namespace GpgFrontend::UI {
+class KeyList;
+
class SignersPicker : public QDialog {
Q_OBJECT
@@ -40,7 +40,7 @@ class SignersPicker : public QDialog {
GpgFrontend::KeyIdArgsListPtr getCheckedSigners();
private:
- KeyList* mKeyList;
+ KeyList* key_list_;
};
} // namespace GpgFrontend::UI
diff --git a/third_party/AppImageUpdate b/third_party/AppImageUpdate
deleted file mode 160000
-Subproject 1b97acc55c89f742d51c3849eb62eb58464d866
diff --git a/ui/EmailListEditor.ui b/ui/EmailListEditor.ui
new file mode 100644
index 00000000..5cc0ddef
--- /dev/null
+++ b/ui/EmailListEditor.ui
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EmailListEditorDialog</class>
+ <widget class="QDialog" name="EmailListEditorDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>618</width>
+ <height>498</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Email List Editor</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="titleLabel">
+ <property name="text">
+ <string>Email List:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="emaillistWidget">
+ <property name="editTriggers">
+ <set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="isWrapping" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addEmailAddressButton">
+ <property name="text">
+ <string>Add An Email Address</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="tipsLabel">
+ <property name="text">
+ <string>Tips: You can double-click the email address in the edit list, or click the email to pop up the option menu.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ <action name="actionDelete_Selected_Email_Address">
+ <property name="text">
+ <string>Delete Selected Email Address</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/ui/SendMailDialog.ui b/ui/SendMailDialog.ui
index 8eb004f7..bb770f5b 100644
--- a/ui/SendMailDialog.ui
+++ b/ui/SendMailDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>958</width>
- <height>607</height>
+ <width>995</width>
+ <height>760</height>
</rect>
</property>
<property name="cursor">
@@ -17,7 +17,7 @@
<enum>Qt::NoContextMenu</enum>
</property>
<property name="windowTitle">
- <string>Send Mail</string>
+ <string>New Message</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
@@ -80,6 +80,9 @@
<property name="text">
<string>CC</string>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
@@ -87,6 +90,9 @@
<property name="text">
<string>BCC</string>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
@@ -96,7 +102,7 @@
<widget class="QWidget" name="horizontalWidget_4" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
- <number>0</number>
+ <number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
@@ -113,7 +119,7 @@
<item>
<widget class="QLabel" name="recipientLabel">
<property name="text">
- <string>Recipient</string>
+ <string>Recipient(s)</string>
</property>
<property name="margin">
<number>5</number>
@@ -123,6 +129,13 @@
<item>
<widget class="QLineEdit" name="recipientEdit"/>
</item>
+ <item>
+ <widget class="QPushButton" name="recipientsEditButton">
+ <property name="text">
+ <string>Edit Recipients(s)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -154,7 +167,7 @@
<item>
<widget class="QLabel" name="subjectLabel">
<property name="text">
- <string>Subject</string>
+ <string>Mail Subject</string>
</property>
<property name="margin">
<number>5</number>
@@ -168,6 +181,64 @@
</widget>
</item>
<item>
+ <widget class="QWidget" name="horizontalWidget_6" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="gpgOperaLabel">
+ <property name="text">
+ <string>GPG Operations</string>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="senderKeySelectButton">
+ <property name="text">
+ <string>Select Sender GPG Key</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="recipientKeySelectButton">
+ <property name="text">
+ <string>Select Recipient(s) GPG Key</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -178,7 +249,7 @@
<widget class="QWidget" name="ccInputWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
- <number>0</number>
+ <number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
@@ -205,6 +276,13 @@
<item>
<widget class="QLineEdit" name="ccEdit"/>
</item>
+ <item>
+ <widget class="QPushButton" name="ccEditButton">
+ <property name="text">
+ <string>Edit CC(s)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -212,7 +290,7 @@
<widget class="QWidget" name="bccInputWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
- <number>0</number>
+ <number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
@@ -239,6 +317,13 @@
<item>
<widget class="QLineEdit" name="bccEdit"/>
</item>
+ <item>
+ <widget class="QPushButton" name="bccEditButton">
+ <property name="text">
+ <string>Edit BCC(s)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -260,6 +345,57 @@
<widget class="QTextEdit" name="textEdit"/>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item alignment="Qt::AlignLeft|Qt::AlignVCenter">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Sender GPG Key: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="senderKeyValueLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item alignment="Qt::AlignLeft|Qt::AlignVCenter">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Recipient(s) GPG Key: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="recipientsKeyValueLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
<widget class="QLabel" name="errorLabel">
<property name="text">
<string/>
@@ -267,11 +403,65 @@
</widget>
</item>
<item>
+ <widget class="Line" name="line_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QCheckBox" name="contentEncryptCheckBox">
+ <property name="text">
+ <string>Encrypt content</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="attacSignatureCheckBox">
+ <property name="text">
+ <string>Attach signature</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="attachSenderPublickeyCheckBox">
+ <property name="text">
+ <string>Attach sender's public key</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="saveDraftButton">
+ <property name="text">
+ <string>Save Draft</string>
+ </property>
+ </widget>
+ </item>
<item alignment="Qt::AlignRight">
<widget class="QPushButton" name="sendMailButton">
<property name="text">
- <string>Send</string>
+ <string>Send Mail</string>
</property>
</widget>
</item>