diff options
author | Saturneric <[email protected]> | 2021-12-16 18:18:38 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-12-16 18:18:38 +0000 |
commit | 2874ebd5e56a7da7f7e7c96da392199b296d909a (patch) | |
tree | e6b78bcbb33282e652cd47df59987fc5932725c7 /src | |
parent | Fixed Known Problem. (diff) | |
download | GpgFrontend-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.cpp | 4 | ||||
-rw-r--r-- | src/init.cpp | 128 | ||||
-rw-r--r-- | src/main.cpp | 171 | ||||
-rw-r--r-- | src/signal.cpp | 34 | ||||
-rwxr-xr-x | src/ui/FileEncryptionDialog.cpp | 60 | ||||
-rwxr-xr-x | src/ui/KeyMgmt.cpp | 4 | ||||
-rw-r--r-- | src/ui/MainWindow.cpp | 2 | ||||
-rw-r--r-- | src/ui/UserInterfaceUtils.cpp | 135 | ||||
-rw-r--r-- | src/ui/UserInterfaceUtils.h | 9 | ||||
-rw-r--r-- | src/ui/keypair_details/KeySetExpireDateDialog.cpp | 86 | ||||
-rw-r--r-- | src/ui/keypair_details/KeySetExpireDateDialog.h | 7 | ||||
-rw-r--r-- | src/ui/keypair_details/KeyUIDSignDialog.cpp | 22 | ||||
-rw-r--r-- | src/ui/settings/SettingsGeneral.cpp | 30 | ||||
-rw-r--r-- | src/ui/settings/SettingsGeneral.h | 1 | ||||
-rw-r--r-- | src/ui/smtp/SendMailDialog.cpp | 2 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.cpp | 60 | ||||
-rw-r--r-- | src/ui/widgets/KeyList.h | 11 | ||||
-rw-r--r-- | src/ui/widgets/SignersPicker.cpp | 5 |
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()) |