aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2021-12-16 18:18:38 +0000
committerSaturneric <[email protected]>2021-12-16 18:18:38 +0000
commit2874ebd5e56a7da7f7e7c96da392199b296d909a (patch)
treee6b78bcbb33282e652cd47df59987fc5932725c7 /src
parentFixed Known Problem. (diff)
downloadGpgFrontend-2874ebd5e56a7da7f7e7c96da392199b296d909a.tar.gz
GpgFrontend-2874ebd5e56a7da7f7e7c96da392199b296d909a.zip
Fixed & Improve.
1. Fixed Known Issues. 2. Improve UI.
Diffstat (limited to 'src')
-rw-r--r--src/gpg/function/GpgKeyOpera.cpp4
-rw-r--r--src/init.cpp128
-rw-r--r--src/main.cpp171
-rw-r--r--src/signal.cpp34
-rwxr-xr-xsrc/ui/FileEncryptionDialog.cpp60
-rwxr-xr-xsrc/ui/KeyMgmt.cpp4
-rw-r--r--src/ui/MainWindow.cpp2
-rw-r--r--src/ui/UserInterfaceUtils.cpp135
-rw-r--r--src/ui/UserInterfaceUtils.h9
-rw-r--r--src/ui/keypair_details/KeySetExpireDateDialog.cpp86
-rw-r--r--src/ui/keypair_details/KeySetExpireDateDialog.h7
-rw-r--r--src/ui/keypair_details/KeyUIDSignDialog.cpp22
-rw-r--r--src/ui/settings/SettingsGeneral.cpp30
-rw-r--r--src/ui/settings/SettingsGeneral.h1
-rw-r--r--src/ui/smtp/SendMailDialog.cpp2
-rw-r--r--src/ui/widgets/KeyList.cpp60
-rw-r--r--src/ui/widgets/KeyList.h11
-rw-r--r--src/ui/widgets/SignersPicker.cpp5
18 files changed, 440 insertions, 331 deletions
diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp
index cdf5ab24..4bad303d 100644
--- a/src/gpg/function/GpgKeyOpera.cpp
+++ b/src/gpg/function/GpgKeyOpera.cpp
@@ -66,8 +66,6 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
std::unique_ptr<boost::posix_time::ptime>& expires) {
unsigned long expires_time = 0;
- LOG(INFO) << "expires" << *expires;
-
if (expires != nullptr) {
using namespace boost::posix_time;
using namespace std::chrono;
@@ -78,7 +76,7 @@ GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::SetExpire(
LOG(INFO) << key.id() << subkey_fpr << expires_time;
GpgError err;
- if (subkey_fpr.empty())
+ if (key.fpr() == subkey_fpr || subkey_fpr.empty())
err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, nullptr, 0);
else
err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time,
diff --git a/src/init.cpp b/src/init.cpp
new file mode 100644
index 00000000..4f441c29
--- /dev/null
+++ b/src/init.cpp
@@ -0,0 +1,128 @@
+/**
+ * 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 <boost/date_time.hpp>
+
+#include "ui/settings/GlobalSettingStation.h"
+
+void init_logging() {
+ using namespace boost::posix_time;
+ using namespace boost::gregorian;
+
+ ptime now = second_clock::local_time();
+
+ el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
+ el::Configurations defaultConf;
+ defaultConf.setToDefault();
+ el::Loggers::reconfigureLogger("default", defaultConf);
+
+ defaultConf.setGlobally(el::ConfigurationType::Format,
+ "%datetime %level %func %msg");
+
+ auto logfile_path =
+ (GpgFrontend::UI::GlobalSettingStation::GetInstance().GetLogDir() /
+ to_iso_string(now));
+ logfile_path.replace_extension(".log");
+ defaultConf.setGlobally(el::ConfigurationType::Filename,
+ logfile_path.string());
+
+ el::Loggers::reconfigureLogger("default", defaultConf);
+
+ LOG(INFO) << _("Logfile Path") << logfile_path;
+}
+
+void init_locale() {
+ auto& settings =
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("general") ||
+ settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+ settings.add("general", libconfig::Setting::TypeGroup);
+
+ // set system default at first
+ auto& general = settings["general"];
+ if (!general.exists("lang"))
+ general.add("lang", libconfig::Setting::TypeString) = "";
+
+ GpgFrontend::UI::GlobalSettingStation::GetInstance().Sync();
+
+ LOG(INFO) << "current system locale" << setlocale(LC_ALL, nullptr);
+
+ // read from settings file
+ std::string lang;
+ if (!general.lookupValue("lang", lang)) {
+ LOG(ERROR) << _("Could not read properly from configure file");
+ };
+
+ LOG(INFO) << "lang from settings" << lang;
+ LOG(INFO) << "PROJECT_NAME" << PROJECT_NAME;
+ LOG(INFO) << "locales path"
+ << GpgFrontend::UI::GlobalSettingStation::GetInstance()
+ .GetLocaleDir()
+ .c_str();
+
+#ifndef WINDOWS
+ if (!lang.empty()) {
+ std::string lc = lang.empty() ? "" : lang + ".UTF-8";
+
+ // set LC_ALL
+ auto* locale_name = setlocale(LC_ALL, lc.c_str());
+ if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
+ auto language = getenv("LANGUAGE");
+ // set LANGUAGE
+ std::string language_env = language == nullptr ? "en" : language;
+ language_env.insert(0, lang + ":");
+ LOG(INFO) << "language env" << language_env;
+ if (setenv("LANGUAGE", language_env.c_str(), 1)) {
+ LOG(WARNING) << "set LANGUAGE failed" << language_env;
+ };
+ }
+#else
+ if (!lang.empty()) {
+ std::string lc = lang.empty() ? "" : lang;
+
+ // set LC_ALL
+ auto* locale_name = setlocale(LC_ALL, lc.c_str());
+ if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
+
+ auto language = getenv("LANGUAGE");
+ // set LANGUAGE
+ std::string language_env = language == nullptr ? "en" : language;
+ language_env.insert(0, lang + ":");
+ language_env.insert(0, "LANGUAGE=");
+ LOG(INFO) << "language env" << language_env;
+ if (putenv(language_env.c_str())) {
+ LOG(WARNING) << "set LANGUAGE failed" << language_env;
+ };
+ }
+#endif
+
+ bindtextdomain(PROJECT_NAME,
+ GpgFrontend::UI::GlobalSettingStation::GetInstance()
+ .GetLocaleDir()
+ .string()
+ .c_str());
+ bind_textdomain_codeset(PROJECT_NAME, "utf-8");
+ textdomain(PROJECT_NAME);
+}
diff --git a/src/main.cpp b/src/main.cpp
index 7e46229e..d3e85c68 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,6 +22,8 @@
*
*/
+#include <csetjmp>
+#include <csignal>
#include <cstdlib>
#include "GpgFrontendBuildInfo.h"
@@ -29,15 +31,23 @@
#include "gpg/function/GpgKeyGetter.h"
#include "ui/MainWindow.h"
#include "ui/WaitingDialog.h"
-#include "ui/settings/GlobalSettingStation.h"
// Easy Logging Cpp
INITIALIZE_EASYLOGGINGPP
-void init_logging();
-void init_locale();
+// Recover buff
+jmp_buf recover_env;
+
+extern void init_logging();
+extern void init_locale();
+extern void handle_signal(int sig);
int main(int argc, char* argv[]) {
+ // Register Signals
+ signal(SIGSEGV, handle_signal);
+ signal(SIGFPE, handle_signal);
+ signal(SIGILL, handle_signal);
+
// Qt
Q_INIT_RESOURCE(gpgfrontend);
@@ -94,8 +104,6 @@ int main(int argc, char* argv[]) {
QApplication::connect(init_ctx_thread, &QThread::finished, init_ctx_thread,
&QThread::deleteLater);
- init_ctx_thread->start();
-
// Waiting Dialog
auto* waiting_dialog = new QProgressDialog();
waiting_dialog->setMaximum(0);
@@ -119,6 +127,8 @@ int main(int argc, char* argv[]) {
// Show Waiting Dialog
waiting_dialog->show();
waiting_dialog->setFocus();
+
+ init_ctx_thread->start();
while (init_ctx_thread->isRunning()) {
QApplication::processEvents();
}
@@ -132,126 +142,43 @@ int main(int argc, char* argv[]) {
int return_from_event_loop_code;
do {
- try {
- // i18n
- init_locale();
-
- QApplication::setQuitOnLastWindowClosed(true);
-
- auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>();
- main_window->init();
- main_window->show();
- return_from_event_loop_code = QApplication::exec();
-
- } catch (...) {
- QMessageBox::information(nullptr, _("Unhandled Exception Thrown"),
- _("Oops, an unhandled exception was thrown "
- "during the running of the "
- "program, and now it needs to be restarted."));
+ int r = sigsetjmp(recover_env, 1);
+ if (!r) {
+
+ try {
+ // i18n
+ init_locale();
+
+ QApplication::setQuitOnLastWindowClosed(true);
+
+ auto main_window = std::make_unique<GpgFrontend::UI::MainWindow>();
+ main_window->init();
+ main_window->show();
+ return_from_event_loop_code = QApplication::exec();
+
+ } catch (...) {
+ QMessageBox::information(
+ nullptr, _("Unhandled Exception Thrown"),
+ _("Oops, an unhandled exception was thrown "
+ "during the running of the "
+ "program, and now it needs to be restarted. This is not a "
+ "serious problem, it may be the negligence of the programmer, "
+ "please report this problem if you can."));
+ continue;
+ }
+
+ } else {
+ QMessageBox::information(
+ nullptr, _("A serious error has occurred"),
+ _("Oh no! GpgFrontend caught a serious error in the software, so it "
+ "needs to be restarted. If the problem recurs, please manually "
+ "terminate the program and report the problem to the developer."));
+ return_from_event_loop_code = RESTART_CODE;
+ LOG(INFO) << "return_from_event_loop_code" << return_from_event_loop_code;
continue;
}
+ LOG(INFO) << "loop refresh";
} while (return_from_event_loop_code == RESTART_CODE);
return return_from_event_loop_code;
}
-
-void init_logging() {
- using namespace boost::posix_time;
- using namespace boost::gregorian;
-
- ptime now = second_clock::local_time();
-
- el::Loggers::addFlag(el::LoggingFlag::AutoSpacing);
- el::Configurations defaultConf;
- defaultConf.setToDefault();
- el::Loggers::reconfigureLogger("default", defaultConf);
-
- defaultConf.setGlobally(el::ConfigurationType::Format,
- "%datetime %level %func %msg");
-
- auto logfile_path =
- (GpgFrontend::UI::GlobalSettingStation::GetInstance().GetLogDir() /
- to_iso_string(now));
- logfile_path.replace_extension(".log");
- defaultConf.setGlobally(el::ConfigurationType::Filename,
- logfile_path.string());
-
- el::Loggers::reconfigureLogger("default", defaultConf);
-
- LOG(INFO) << _("Logfile Path") << logfile_path;
-}
-
-void init_locale() {
- auto& settings =
- GpgFrontend::UI::GlobalSettingStation::GetInstance().GetUISettings();
-
- if (!settings.exists("general") ||
- settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
- settings.add("general", libconfig::Setting::TypeGroup);
-
- // set system default at first
- auto& general = settings["general"];
- if (!general.exists("lang"))
- general.add("lang", libconfig::Setting::TypeString) = "";
-
- GpgFrontend::UI::GlobalSettingStation::GetInstance().Sync();
-
- LOG(INFO) << "current system locale" << setlocale(LC_ALL, nullptr);
-
- // read from settings file
- std::string lang;
- if (!general.lookupValue("lang", lang)) {
- LOG(ERROR) << _("Could not read properly from configure file");
- };
-
- LOG(INFO) << "lang from settings" << lang;
- LOG(INFO) << "PROJECT_NAME" << PROJECT_NAME;
- LOG(INFO) << "locales path"
- << GpgFrontend::UI::GlobalSettingStation::GetInstance()
- .GetLocaleDir()
- .c_str();
-
-#ifndef WINDOWS
- if (!lang.empty()) {
- std::string lc = lang.empty() ? "" : lang + ".UTF-8";
-
- // set LC_ALL
- auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
- auto language = getenv("LANGUAGE");
- // set LANGUAGE
- std::string language_env = language == nullptr ? "en" : language;
- language_env.insert(0, lang + ":");
- LOG(INFO) << "language env" << language_env;
- if (setenv("LANGUAGE", language_env.c_str(), 1)) {
- LOG(WARNING) << "set LANGUAGE failed" << language_env;
- };
- }
-#else
- if (!lang.empty()) {
- std::string lc = lang.empty() ? "" : lang;
-
- // set LC_ALL
- auto* locale_name = setlocale(LC_ALL, lc.c_str());
- if (locale_name == nullptr) LOG(WARNING) << "set LC_ALL failed" << lc;
-
- auto language = getenv("LANGUAGE");
- // set LANGUAGE
- std::string language_env = language == nullptr ? "en" : language;
- language_env.insert(0, lang + ":");
- language_env.insert(0, "LANGUAGE=");
- LOG(INFO) << "language env" << language_env;
- if (putenv(language_env.c_str())) {
- LOG(WARNING) << "set LANGUAGE failed" << language_env;
- };
- }
-#endif
-
- bindtextdomain(PROJECT_NAME,
- GpgFrontend::UI::GlobalSettingStation::GetInstance()
- .GetLocaleDir()
- .string()
- .c_str());
- bind_textdomain_codeset(PROJECT_NAME, "utf-8");
- textdomain(PROJECT_NAME);
-}
diff --git a/src/signal.cpp b/src/signal.cpp
new file mode 100644
index 00000000..391d590b
--- /dev/null
+++ b/src/signal.cpp
@@ -0,0 +1,34 @@
+/**
+ * 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 <easyloggingpp/easylogging++.h>
+
+#include <csetjmp>
+
+extern jmp_buf recover_env;
+
+void handle_signal(int sig) {
+ LOG(INFO) << "signal caught";
+ siglongjmp(recover_env, 1);
+}
diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp
index aeba6497..6930c3c9 100755
--- a/src/ui/FileEncryptionDialog.cpp
+++ b/src/ui/FileEncryptionDialog.cpp
@@ -86,42 +86,44 @@ FileEncryptionDialog::FileEncryptionDialog(KeyIdArgsListPtr keyList,
groupBox1->setLayout(gLayout);
/*Setup KeyList*/
-
+ mKeyList = new KeyList(false, this);
if (mAction == Verify) {
- mKeyList =
- new KeyList(KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage,
- [](const GpgKey& key) -> bool {
- if (key.disabled() || key.expired() || key.revoked())
- return false;
- else
- return true;
- });
+ mKeyList->addListGroupTab(
+ _("Default"), KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage,
+ [](const GpgKey& key) -> bool {
+ if (key.disabled() || key.expired() || key.revoked())
+ return false;
+ else
+ return true;
+ });
}
if (mAction == Encrypt) {
- mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage,
- [](const GpgKey& key) -> bool {
- if (!key.CanEncrActual())
- return false;
- else
- return true;
- });
+ mKeyList->addListGroupTab(_("Default"), KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME |
+ KeyListColumn::EmailAddress |
+ KeyListColumn::Usage,
+ [](const GpgKey& key) -> bool {
+ if (!key.CanEncrActual())
+ return false;
+ else
+ return true;
+ });
}
if (mAction == Encrypt) {
- mKeyList = new KeyList(KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress |
- KeyListColumn::Usage,
- [](const GpgKey& key) -> bool {
- if (!key.CanSignActual())
- return false;
- else
- return true;
- });
+ mKeyList->addListGroupTab(_("Default"), KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME |
+ KeyListColumn::EmailAddress |
+ KeyListColumn::Usage,
+ [](const GpgKey& key) -> bool {
+ if (!key.CanSignActual())
+ return false;
+ else
+ return true;
+ });
}
if (mAction == Decrypt) mKeyList->setDisabled(true);
diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp
index 88663d67..d3759e44 100755
--- a/src/ui/KeyMgmt.cpp
+++ b/src/ui/KeyMgmt.cpp
@@ -36,7 +36,7 @@
namespace GpgFrontend::UI {
KeyMgmt::KeyMgmt(QWidget* parent) : QMainWindow(parent) {
/* the list of Keys available*/
- mKeyList = new KeyList(this);
+ mKeyList = new KeyList(true, this);
mKeyList->addListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY);
@@ -247,7 +247,7 @@ void KeyMgmt::createMenus() {
importKeyMenu->addAction(importKeyFromFileAct);
importKeyMenu->addAction(importKeyFromClipboardAct);
importKeyMenu->addAction(importKeyFromKeyServerAct);
-
+
keyMenu->addAction(exportKeyToFileAct);
keyMenu->addAction(exportKeyToClipboardAct);
keyMenu->addAction(exportKeyAsOpenSSHFormat);
diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp
index 1e58e1e1..8e6b6f81 100644
--- a/src/ui/MainWindow.cpp
+++ b/src/ui/MainWindow.cpp
@@ -50,7 +50,7 @@ void MainWindow::init() noexcept {
setCentralWidget(edit);
/* the list of Keys available*/
- mKeyList = new KeyList(this);
+ mKeyList = new KeyList(true, this);
infoBoard = new InfoBoardWidget(this);
diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp
index 4fdf4cea..0931a179 100644
--- a/src/ui/UserInterfaceUtils.cpp
+++ b/src/ui/UserInterfaceUtils.cpp
@@ -227,54 +227,10 @@ void CommonUtils::slotExecuteGpgCommand(
dialog->close();
dialog->deleteLater();
}
-void CommonUtils::slotDoImportKeyFromKeyServer(
- QNetworkReply* network_reply, const std::string& key_id,
- size_t current_index, size_t all_index,
- const ImportCallbackFunctiopn& _callback) {
- auto key_data = network_reply->readAll();
- auto key_data_ptr =
- std::make_unique<ByteArray>(key_data.data(), key_data.size());
- LOG(INFO) << "reply data size"
- << "raw" << key_data.size() << "copy" << key_data_ptr->size();
- std::string status;
- auto error = network_reply->error();
- if (error != QNetworkReply::NoError) {
- switch (error) {
- case QNetworkReply::ContentNotFoundError:
- status = _("Key Not Found");
- break;
- case QNetworkReply::TimeoutError:
- status = _("Timeout");
- break;
- case QNetworkReply::HostNotFoundError:
- status = _("Key Server Not Found");
- break;
- default:
- status = _("Connection Error");
- }
- }
- static int id = 512;
- id = ++id % 1024;
- if (!id) id = 512;
- LOG(INFO) << "id" << id;
- // fixed for multiply thread
- // switch to channel 1
- GpgImportInformation result =
- GpgKeyImportExportor::GetInstance(id).ImportKey(std::move(key_data_ptr));
- LOG(INFO) << "import key done";
- std::string new_status = status;
- if (result.imported == 1) {
- new_status = _("The key has been updated");
- } else {
- new_status = _("No need to update the key");
- }
-
- LOG(INFO) << "call callback" << key_id << current_index << all_index;
- _callback(key_id, status, current_index, all_index);
-}
void CommonUtils::slotImportKeyFromKeyServer(
- const KeyIdArgsList& key_ids, const ImportCallbackFunctiopn& callback) {
+ int ctx_channel, const KeyIdArgsList& key_ids,
+ const ImportCallbackFunctiopn& callback) {
std::string target_keyserver;
if (target_keyserver.empty()) {
try {
@@ -293,29 +249,72 @@ void CommonUtils::slotImportKeyFromKeyServer(
return;
}
}
- QUrl target_keyserver_url(target_keyserver.c_str());
-
- // LOOP
- decltype(key_ids.size()) current_index = 1, all_index = key_ids.size();
- for (const auto& key_id : key_ids) {
- QUrl req_url(target_keyserver_url.scheme() + "://" +
- target_keyserver_url.host() + "/pks/lookup?op=get&search=0x" +
- key_id.c_str() + "&options=mr");
-
- LOG(INFO) << "request url" << req_url.toString().toStdString();
-
- QNetworkReply* reply = _network_manager->get(QNetworkRequest(req_url));
- connect(reply, &QNetworkReply::finished, this,
- [this, reply, key_id, current_index, all_index, callback]() {
- this->slotDoImportKeyFromKeyServer(reply, key_id, current_index,
- all_index, callback);
- // Delete network reply
- reply->deleteLater();
- });
- current_index++;
- }
- LOG(INFO) << "request done";
+ auto thread =
+ QThread::create([target_keyserver, key_ids, callback, ctx_channel]() {
+ QUrl target_keyserver_url(target_keyserver.c_str());
+
+ auto network_manager = std::make_unique<QNetworkAccessManager>();
+ // LOOP
+ decltype(key_ids.size()) current_index = 1, all_index = key_ids.size();
+ for (const auto& key_id : key_ids) {
+ // New Req Url
+ QUrl req_url(target_keyserver_url.scheme() + "://" +
+ target_keyserver_url.host() +
+ "/pks/lookup?op=get&search=0x" + key_id.c_str() +
+ "&options=mr");
+
+ LOG(INFO) << "request url" << req_url.toString().toStdString();
+
+ // Waiting for reply
+ QNetworkReply* reply = network_manager->get(QNetworkRequest(req_url));
+ QEventLoop loop;
+ connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ // Get Data
+ auto key_data = reply->readAll();
+ auto key_data_ptr =
+ std::make_unique<ByteArray>(key_data.data(), key_data.size());
+
+ // Detect status
+ std::string status;
+ auto error = reply->error();
+ if (error != QNetworkReply::NoError) {
+ switch (error) {
+ case QNetworkReply::ContentNotFoundError:
+ status = _("Key Not Found");
+ break;
+ case QNetworkReply::TimeoutError:
+ status = _("Timeout");
+ break;
+ case QNetworkReply::HostNotFoundError:
+ status = _("Key Server Not Found");
+ break;
+ default:
+ status = _("Connection Error");
+ }
+ }
+
+ reply->deleteLater();
+
+ // Try importing
+ GpgImportInformation result =
+ GpgKeyImportExportor::GetInstance(ctx_channel)
+ .ImportKey(std::move(key_data_ptr));
+
+ if (result.imported == 1) {
+ status = _("The key has been updated");
+ } else {
+ status = _("No need to update the key");
+ }
+ callback(key_id, status, current_index, all_index);
+ current_index++;
+ }
+ });
+
+ connect(thread, &QThread::finished, thread, &QThread::deleteLater);
+ thread->start();
}
} // namespace GpgFrontend::UI \ No newline at end of file
diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h
index a08f3420..be114b0a 100644
--- a/src/ui/UserInterfaceUtils.h
+++ b/src/ui/UserInterfaceUtils.h
@@ -85,8 +85,8 @@ class CommonUtils : public QWidget {
void slotImportKeyFromClipboard(QWidget* parent);
- void slotImportKeyFromKeyServer(
- const GpgFrontend::KeyIdArgsList& key_ids,
+ static void slotImportKeyFromKeyServer(
+ int ctx_channel, const GpgFrontend::KeyIdArgsList& key_ids,
const GpgFrontend::UI::CommonUtils::ImportCallbackFunctiopn& callback);
void slotExecuteGpgCommand(
@@ -94,14 +94,9 @@ class CommonUtils : public QWidget {
const std::function<void(QProcess*)>& interact_func);
private slots:
- void slotDoImportKeyFromKeyServer(
- QNetworkReply* network_reply, const std::string& key_id,
- size_t current_index, size_t all_index,
- const GpgFrontend::UI::CommonUtils::ImportCallbackFunctiopn& _callback);
private:
static std::unique_ptr<CommonUtils> _instance;
- QNetworkAccessManager* _network_manager = new QNetworkAccessManager(this);
};
} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
index a90a4e4b..f0488105 100644
--- a/src/ui/keypair_details/KeySetExpireDateDialog.cpp
+++ b/src/ui/keypair_details/KeySetExpireDateDialog.cpp
@@ -29,12 +29,16 @@
#include "gpg/function/GpgKeyGetter.h"
#include "gpg/function/GpgKeyOpera.h"
#include "ui/SignalStation.h"
+#include "ui/settings/GlobalSettingStation.h"
+#include "ui_ModifiedExpirationDateTime.h"
namespace GpgFrontend::UI {
KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
QWidget* parent)
- : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
+ : QDialog(parent),
+ ui(std::make_shared<Ui_ModifiedExpirationDateTime>()),
+ mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) {
init();
}
@@ -42,19 +46,20 @@ KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id,
std::string subkey_fpr,
QWidget* parent)
: QDialog(parent),
+ ui(std::make_shared<Ui_ModifiedExpirationDateTime>()),
mKey(GpgKeyGetter::GetInstance().GetKey(key_id)),
mSubkey(std::move(subkey_fpr)) {
init();
}
void KeySetExpireDateDialog::slotConfirm() {
- LOG(INFO) << "Called"
- << this->dateTimeEdit->dateTime().toLocalTime().toTime_t();
+ LOG(INFO) << "Called" << ui->dateEdit->date().toString().toStdString()
+ << ui->timeEdit->time().toString().toStdString();
+ auto datetime = QDateTime(ui->dateEdit->date(), ui->timeEdit->time());
std::unique_ptr<boost::posix_time::ptime> expires = nullptr;
- if (this->nonExpiredCheck->checkState() == Qt::Unchecked) {
+ if (ui->noExpirationCheckBox->checkState() == Qt::Unchecked) {
expires = std::make_unique<boost::posix_time::ptime>(
- boost::posix_time::from_time_t(
- this->dateTimeEdit->dateTime().toLocalTime().toTime_t()));
+ boost::posix_time::from_time_t(datetime.toLocalTime().toTime_t()));
LOG(INFO) << "keyid" << mKey.id() << mSubkey << *expires;
} else {
LOG(INFO) << "keyid" << mKey.id() << mSubkey << "Non Expired";
@@ -81,44 +86,51 @@ void KeySetExpireDateDialog::slotConfirm() {
}
void KeySetExpireDateDialog::init() {
- QDateTime maxDateTime =
- QDateTime::currentDateTime().toLocalTime().addYears(2);
- dateTimeEdit = new QDateTimeEdit(maxDateTime);
- dateTimeEdit->setTimeSpec(Qt::TimeSpec::TimeZone);
- LOG(INFO) << "timespec" << Qt::TimeSpec::TimeZone;
- dateTimeEdit->setCalendarPopup(true);
- dateTimeEdit->setMinimumDateTime(QDateTime::currentDateTime().addSecs(1));
- dateTimeEdit->setMaximumDateTime(maxDateTime);
-
- nonExpiredCheck = new QCheckBox();
- nonExpiredCheck->setTristate(false);
- confirmButton = new QPushButton(_("Confirm"));
-
- auto* gridLayout = new QGridLayout();
- gridLayout->addWidget(dateTimeEdit, 0, 0, 1, 2);
- gridLayout->addWidget(nonExpiredCheck, 0, 2, 1, 1, Qt::AlignRight);
- gridLayout->addWidget(new QLabel(_("Never Expire")), 0, 3);
- gridLayout->addWidget(confirmButton, 1, 3);
-
- connect(nonExpiredCheck, SIGNAL(stateChanged(int)), this,
- SLOT(slotNonExpiredChecked(int)));
- connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm()));
+ ui->setupUi(this);
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ bool longer_expiration_date = false;
+ try {
+ longer_expiration_date = settings.lookup("general.longer_expiration_date");
+ LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ }
+
+ auto max_date_time =
+ longer_expiration_date
+ ? QDateTime::currentDateTime().toLocalTime().addYears(70)
+ : QDateTime::currentDateTime().toLocalTime().addYears(2);
- this->setLayout(gridLayout);
- this->setWindowTitle(_("Edit Expire Datetime"));
- this->setModal(true);
- this->setAttribute(Qt::WA_DeleteOnClose, true);
+ auto min_date_time = QDateTime::currentDateTime().addDays(7);
+ ui->dateEdit->setMaximumDateTime(max_date_time);
+ ui->dateEdit->setMinimumDateTime(min_date_time);
+
+ ui->dateEdit->setDateTime(max_date_time);
+ ui->timeEdit->setDateTime(max_date_time);
+
+ connect(ui->noExpirationCheckBox, SIGNAL(stateChanged(int)), this,
+ SLOT(slotNonExpiredChecked(int)));
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
+ &KeySetExpireDateDialog::slotConfirm);
connect(this, SIGNAL(signalKeyExpireDateUpdated()),
SignalStation::GetInstance(), SIGNAL(KeyDatabaseRefresh()));
+
+ ui->titleLabel->setText(_("Modified Expiration Date (Local Time)"));
+ ui->label->setText(
+ _("Tips: For the sake of security, the key is valid for up to two years. "
+ "If you are an expert user, please unlock it for a longer time in the "
+ "settings."));
+ ui->noExpirationCheckBox->setText(_("No Expiration"));
+ this->setWindowTitle(_("Modified Expiration Date"));
}
void KeySetExpireDateDialog::slotNonExpiredChecked(int state) {
- if (state == 0) {
- this->dateTimeEdit->setDisabled(false);
- } else {
- this->dateTimeEdit->setDisabled(true);
- }
+ ui->dateEdit->setDisabled(state == Qt::Checked);
+ ui->timeEdit->setDisabled(state == Qt::Checked);
}
} // namespace GpgFrontend::UI
diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.h b/src/ui/keypair_details/KeySetExpireDateDialog.h
index 37a7f7e4..d4386e43 100644
--- a/src/ui/keypair_details/KeySetExpireDateDialog.h
+++ b/src/ui/keypair_details/KeySetExpireDateDialog.h
@@ -30,6 +30,8 @@
#include "gpg/model/GpgSubKey.h"
#include "ui/GpgFrontendUI.h"
+class Ui_ModifiedExpirationDateTime;
+
namespace GpgFrontend::UI {
class KeySetExpireDateDialog : public QDialog {
@@ -47,13 +49,10 @@ class KeySetExpireDateDialog : public QDialog {
private:
void init();
+ std::shared_ptr<Ui_ModifiedExpirationDateTime> ui;
const GpgKey mKey;
const SubkeyId mSubkey;
- QDateTimeEdit* dateTimeEdit{};
- QPushButton* confirmButton{};
- QCheckBox* nonExpiredCheck{};
-
private slots:
void slotConfirm();
void slotNonExpiredChecked(int state);
diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp
index d9592c56..eb459701 100644
--- a/src/ui/keypair_details/KeyUIDSignDialog.cpp
+++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp
@@ -34,17 +34,17 @@ KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, UIDArgsListPtr uid,
QWidget* parent)
: QDialog(parent), mUids(std::move(uid)), mKey(key) {
const auto key_id = mKey.id();
- mKeyList = new KeyList(
- KeyListRow::ONLY_SECRET_KEY,
- KeyListColumn::NAME | KeyListColumn::EmailAddress,
- [key_id](const GpgKey& key) -> bool {
- if (key.disabled() || !key.can_certify() || !key.has_master_key() ||
- key.expired() || key.revoked() || key_id == key.id())
- return false;
- else
- return true;
- },
- this);
+ mKeyList = new KeyList(false, this);
+ mKeyList->addListGroupTab(_("Signers"), KeyListRow::ONLY_SECRET_KEY,
+ KeyListColumn::NAME | KeyListColumn::EmailAddress,
+ [key_id](const GpgKey& key) -> bool {
+ if (key.disabled() || !key.can_certify() ||
+ !key.has_master_key() || key.expired() ||
+ key.revoked() || key_id == key.id())
+ return false;
+ else
+ return true;
+ });
mKeyList->slotRefresh();
signKeyButton = new QPushButton("Sign");
diff --git a/src/ui/settings/SettingsGeneral.cpp b/src/ui/settings/SettingsGeneral.cpp
index 978a7b5f..3b767e3a 100644
--- a/src/ui/settings/SettingsGeneral.cpp
+++ b/src/ui/settings/SettingsGeneral.cpp
@@ -65,6 +65,17 @@ GeneralTab::GeneralTab(QWidget* parent) : QWidget(parent) {
saveCheckedKeysBox->setLayout(saveCheckedKeysBoxLayout);
/*****************************************
+ * Longer-Expire-Date-Box
+ *****************************************/
+ auto* longerKeyExpirationDateBox =
+ new QGroupBox(_("Longer Key Expiration Date"));
+ auto* longerKeyExpirationDateBoxLayout = new QHBoxLayout();
+ longerKeyExpirationDateCheckBox = new QCheckBox(
+ _("Unlock key expiration date setting up to 30 years."), this);
+ longerKeyExpirationDateBoxLayout->addWidget(longerKeyExpirationDateCheckBox);
+ longerKeyExpirationDateBox->setLayout(longerKeyExpirationDateBoxLayout);
+
+ /*****************************************
* Key-Impport-Confirmation Box
*****************************************/
auto* importConfirmationBox =
@@ -151,6 +162,7 @@ GeneralTab::GeneralTab(QWidget* parent) : QWidget(parent) {
#ifdef SERVER_SUPPORT
mainLayout->addWidget(serverBox);
#endif
+ mainLayout->addWidget(longerKeyExpirationDateBox);
mainLayout->addWidget(saveCheckedKeysBox);
mainLayout->addWidget(importConfirmationBox);
#ifdef MULTI_LANG_SUPPORT
@@ -179,6 +191,16 @@ void GeneralTab::setSettings() {
LOG(ERROR) << _("Setting Operation Error") << _("save_key_checked");
}
+ try {
+ bool longer_expiration_date =
+ settings.lookup("general.longer_expiration_date");
+ LOG(INFO) << "longer_expiration_date" << longer_expiration_date;
+ if (longer_expiration_date)
+ longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ }
+
#ifdef SERVER_SUPPORT
auto serverList =
settings.value("general/gpgfrontendServerList").toStringList();
@@ -257,6 +279,14 @@ void GeneralTab::applySettings() {
auto& general = settings["general"];
+ if (!general.exists("longer_expiration_date"))
+ general.add("longer_expiration_date", libconfig::Setting::TypeBoolean) =
+ longerKeyExpirationDateCheckBox->isChecked();
+ else {
+ general["longer_expiration_date"] =
+ longerKeyExpirationDateCheckBox->isChecked();
+ }
+
if (!general.exists("save_key_checked"))
general.add("save_key_checked", libconfig::Setting::TypeBoolean) =
saveCheckedKeysCheckBox->isChecked();
diff --git a/src/ui/settings/SettingsGeneral.h b/src/ui/settings/SettingsGeneral.h
index 7e118f98..bebe7609 100644
--- a/src/ui/settings/SettingsGeneral.h
+++ b/src/ui/settings/SettingsGeneral.h
@@ -43,6 +43,7 @@ class GeneralTab : public QWidget {
private:
QCheckBox* saveCheckedKeysCheckBox;
QCheckBox* importConfirmationCheckBox;
+ QCheckBox* longerKeyExpirationDateCheckBox;
#ifdef MULTI_LANG_SUPPORT
QComboBox* langSelectBox;
diff --git a/src/ui/smtp/SendMailDialog.cpp b/src/ui/smtp/SendMailDialog.cpp
index 28cbdf60..374b3875 100644
--- a/src/ui/smtp/SendMailDialog.cpp
+++ b/src/ui/smtp/SendMailDialog.cpp
@@ -76,7 +76,7 @@ SendMailDialog::SendMailDialog(const QString& text, QWidget* parent)
ui->bccButton->setText(_("BCC"));
ui->senderLabel->setText(_("Sender"));
ui->recipientLabel->setText(_("Recipient"));
- ui->subjectLabel->setText(_("Subject"));
+ ui->subjectLabel->setText(_("Mail Subject"));
ui->bccLabel->setText(_("BCC"));
ui->ccLabel->setText(_("CC"));
ui->tipsLabel->setText(
diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp
index b6f39fff..3933b968 100644
--- a/src/ui/widgets/KeyList.cpp
+++ b/src/ui/widgets/KeyList.cpp
@@ -37,26 +37,18 @@ namespace GpgFrontend::UI {
int KeyList::key_list_id = 2048;
-KeyList::KeyList(QWidget* parent)
+KeyList::KeyList(bool menu, QWidget* parent)
: QWidget(parent),
_m_key_list_id(key_list_id++),
- ui(std::make_shared<Ui_KeyList>()) {
+ ui(std::make_shared<Ui_KeyList>()),
+ menu_status(menu) {
init();
}
-KeyList::KeyList(KeyListRow::KeyType selectType,
- KeyListColumn::InfoType infoType,
- const std::function<bool(const GpgKey&)>& filter,
- QWidget* parent)
- : QWidget(parent),
- _m_key_list_id(key_list_id++),
- ui(std::make_shared<Ui_KeyList>()) {
- init();
- addListGroupTab(_("Default"), selectType, infoType, filter);
-}
-
void KeyList::init() {
ui->setupUi(this);
+
+ ui->menuWidget->setHidden(!menu_status);
ui->keyGroupTab->clear();
popupMenu = new QMenu(this);
@@ -74,7 +66,7 @@ void KeyList::init() {
setAcceptDrops(true);
- ui->keyListOperationsLabel->setText(_("Key List Operations: "));
+ ui->keyListOperationsLabel->setText(_("Key List Menu: "));
ui->refreshKeyListButton->setText(_("Refresh"));
ui->syncButton->setText(_("Sync Public Key"));
ui->syncButton->setToolTip(_("Sync public key with your default keyserver"));
@@ -153,6 +145,7 @@ void KeyList::slotRefresh() {
connect(thread, &QThread::finished, this, &KeyList::slotRefreshUI);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
ui->refreshKeyListButton->setDisabled(true);
+ ui->syncButton->setDisabled(true);
thread->start();
}
@@ -415,6 +408,7 @@ void KeyList::slotRefreshUI() {
}
emit signalRefreshStatusBar(_("Key List Refreshed."), 1000);
ui->refreshKeyListButton->setDisabled(false);
+ ui->syncButton->setDisabled(false);
}
void KeyList::slotSyncWithKeyServer() {
@@ -426,35 +420,31 @@ void KeyList::slotSyncWithKeyServer() {
key_ids.push_back(key.id());
}
}
- updateCallbackCalled(-1, key_ids.size());
- CommonUtils::GetInstance()->slotImportKeyFromKeyServer(
- key_ids, [=](const std::string& key_id, const std::string& status,
- size_t current_index, size_t all_index) {
+
+ ui->refreshKeyListButton->setDisabled(true);
+ ui->syncButton->setDisabled(true);
+
+ emit signalRefreshStatusBar(_("Syncing Key List..."), 3000);
+ CommonUtils::slotImportKeyFromKeyServer(
+ _m_key_list_id, key_ids,
+ [=](const std::string& key_id, const std::string& status,
+ size_t current_index, size_t all_index) {
LOG(INFO) << _("Called") << key_id << status << current_index
<< all_index;
auto key = GpgKeyGetter::GetInstance(_m_key_list_id).GetKey(key_id);
+
boost::format status_str = boost::format(_("Sync [%1%/%2%] %3% %4%")) %
current_index % all_index %
key.uids()->front().uid() % status;
emit signalRefreshStatusBar(status_str.str().c_str(), 1500);
- updateCallbackCalled(current_index, key_ids.size());
- });
-}
-
-void KeyList::updateCallbackCalled(ssize_t current_index, size_t all_index) {
- static size_t called_count = 0;
- if (current_index == -1 && all_index > 0) {
- called_count = 0;
- ui->syncButton->setDisabled(true);
- } else {
- called_count++;
- }
- if (called_count == all_index) {
- ui->syncButton->setDisabled(false);
- emit signalRefreshStatusBar(_("Key List Sync Done."), 3000);
- emit signalRefreshDatabase();
- }
+ if (current_index == all_index) {
+ ui->syncButton->setDisabled(false);
+ ui->refreshKeyListButton->setDisabled(false);
+ emit signalRefreshStatusBar(_("Key List Sync Done."), 3000);
+ emit signalRefreshDatabase();
+ }
+ });
}
KeyIdArgsListPtr KeyTable::GetChecked() {
diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h
index 254e66be..617bb274 100644
--- a/src/ui/widgets/KeyList.h
+++ b/src/ui/widgets/KeyList.h
@@ -82,14 +82,7 @@ class KeyList : public QWidget {
Q_OBJECT
public:
- explicit KeyList(
- KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY,
- KeyListColumn::InfoType infoType = KeyListColumn::ALL,
- const std::function<bool(const GpgKey&)>& filter =
- [](const GpgKey&) -> bool { return true; },
- QWidget* parent = nullptr);
-
- explicit KeyList(QWidget* parent);
+ explicit KeyList(bool menu, QWidget* parent = nullptr);
void addListGroupTab(
const QString& name,
@@ -130,7 +123,6 @@ class KeyList : public QWidget {
private:
void init();
void importKeys(const QByteArray& inBuffer);
- void updateCallbackCalled(ssize_t current_index, size_t all_index);
static int key_list_id;
int _m_key_list_id;
@@ -142,6 +134,7 @@ class KeyList : public QWidget {
QMenu* popupMenu{};
GpgFrontend::KeyLinkListPtr _buffered_keys_list;
std::function<void(const GpgKey&, QWidget*)> mAction = nullptr;
+ bool menu_status = false;
private slots:
diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp
index 6108d78e..e769d05c 100644
--- a/src/ui/widgets/SignersPicker.cpp
+++ b/src/ui/widgets/SignersPicker.cpp
@@ -31,8 +31,9 @@ SignersPicker::SignersPicker(QWidget* parent) : QDialog(parent) {
connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
/*Setup KeyList*/
- mKeyList = new KeyList(
- KeyListRow::ONLY_SECRET_KEY,
+ mKeyList = new KeyList(false, this);
+ mKeyList->addListGroupTab(
+ _("Signers"), KeyListRow::ONLY_SECRET_KEY,
KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage,
[](const GpgKey& key) -> bool {
if (!key.CanSignActual())