aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/dialog/settings
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/dialog/settings')
-rw-r--r--src/ui/dialog/settings/SettingsAdvanced.cpp104
-rw-r--r--src/ui/dialog/settings/SettingsAdvanced.h55
-rw-r--r--src/ui/dialog/settings/SettingsAppearance.cpp207
-rw-r--r--src/ui/dialog/settings/SettingsAppearance.h83
-rw-r--r--src/ui/dialog/settings/SettingsDialog.cpp146
-rw-r--r--src/ui/dialog/settings/SettingsDialog.h112
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.cpp196
-rw-r--r--src/ui/dialog/settings/SettingsGeneral.h99
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.cpp301
-rw-r--r--src/ui/dialog/settings/SettingsKeyServer.h111
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.cpp338
-rw-r--r--src/ui/dialog/settings/SettingsNetwork.h94
12 files changed, 1846 insertions, 0 deletions
diff --git a/src/ui/dialog/settings/SettingsAdvanced.cpp b/src/ui/dialog/settings/SettingsAdvanced.cpp
new file mode 100644
index 00000000..516d4d02
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsAdvanced.cpp
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsAdvanced.h"
+
+#include "core/function/GlobalSettingStation.h"
+
+namespace GpgFrontend::UI {
+
+AdvancedTab::AdvancedTab(QWidget* parent) : QWidget(parent) {
+ auto* stegano_box = new QGroupBox(_("Show Steganography Options"));
+ auto* stegano_box_layout = new QHBoxLayout();
+ stegano_check_box_ = new QCheckBox(_("Show Steganography Options."), this);
+ stegano_box_layout->addWidget(stegano_check_box_);
+ stegano_box->setLayout(stegano_box_layout);
+
+ auto* pubkey_exchange_box = new QGroupBox(_("Pubkey Exchange"));
+ auto* pubkey_exchange_box_layout = new QHBoxLayout();
+ auto_pubkey_exchange_check_box_ =
+ new QCheckBox(_("Auto Pubkey Exchange"), this);
+ pubkey_exchange_box_layout->addWidget(auto_pubkey_exchange_check_box_);
+ pubkey_exchange_box->setLayout(pubkey_exchange_box_layout);
+
+ auto* main_layout = new QVBoxLayout;
+ main_layout->addWidget(stegano_box);
+ main_layout->addWidget(pubkey_exchange_box);
+ SetSettings();
+ main_layout->addStretch(1);
+ setLayout(main_layout);
+}
+
+void AdvancedTab::SetSettings() {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ try {
+ bool stegano_checked = settings.lookup("advanced.stegano_checked");
+ if (stegano_checked) stegano_check_box_->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("stegano_checked");
+ }
+
+ try {
+ bool auto_pubkey_exchange_checked =
+ settings.lookup("advanced.auto_pubkey_exchange_checked");
+ if (auto_pubkey_exchange_checked)
+ auto_pubkey_exchange_check_box_->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error")
+ << _("auto_pubkey_exchange_checked");
+ }
+}
+
+void AdvancedTab::ApplySettings() {
+ auto& settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("advanced") ||
+ settings.lookup("advanced").getType() != libconfig::Setting::TypeGroup)
+ settings.add("advanced", libconfig::Setting::TypeGroup);
+
+ auto& advanced = settings["advanced"];
+
+ if (!advanced.exists("stegano_checked"))
+ advanced.add("stegano_checked", libconfig::Setting::TypeBoolean) =
+ stegano_check_box_->isChecked();
+ else {
+ advanced["stegano_checked"] = stegano_check_box_->isChecked();
+ }
+
+ if (!advanced.exists("auto_pubkey_exchange_checked"))
+ advanced.add("auto_pubkey_exchange_checked",
+ libconfig::Setting::TypeBoolean) =
+ auto_pubkey_exchange_check_box_->isChecked();
+ else {
+ advanced["auto_pubkey_exchange_checked"] =
+ auto_pubkey_exchange_check_box_->isChecked();
+ }
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsAdvanced.h b/src/ui/dialog/settings/SettingsAdvanced.h
new file mode 100644
index 00000000..c1a3d5a6
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsAdvanced.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSADVANCED_H
+#define GPGFRONTEND_SETTINGSADVANCED_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+class AdvancedTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ explicit AdvancedTab(QWidget* parent = nullptr);
+
+ void SetSettings();
+
+ void ApplySettings();
+
+ private:
+ QCheckBox* stegano_check_box_;
+ QCheckBox* auto_pubkey_exchange_check_box_;
+
+ signals:
+
+ void SignalRestartNeeded(bool needed);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSADVANCED_H
diff --git a/src/ui/dialog/settings/SettingsAppearance.cpp b/src/ui/dialog/settings/SettingsAppearance.cpp
new file mode 100644
index 00000000..17471a0d
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsAppearance.cpp
@@ -0,0 +1,207 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsAppearance.h"
+
+#include "core/function/GlobalSettingStation.h"
+#include "ui/struct/SettingsObject.h"
+
+namespace GpgFrontend::UI {
+
+AppearanceTab::AppearanceTab(QWidget* parent) : QWidget(parent) {
+ /*****************************************
+ * Icon-Size-Box
+ *****************************************/
+ auto* iconSizeBox = new QGroupBox(_("Icon Size"));
+ icon_size_group_ = new QButtonGroup();
+ icon_size_small_ = new QRadioButton(_("small"));
+ icon_size_medium_ = new QRadioButton(_("medium"));
+ icon_size_large_ = new QRadioButton(_("large"));
+
+ icon_size_group_->addButton(icon_size_small_, 1);
+ icon_size_group_->addButton(icon_size_medium_, 2);
+ icon_size_group_->addButton(icon_size_large_, 3);
+
+ auto* iconSizeBoxLayout = new QHBoxLayout();
+ iconSizeBoxLayout->addWidget(icon_size_small_);
+ iconSizeBoxLayout->addWidget(icon_size_medium_);
+ iconSizeBoxLayout->addWidget(icon_size_large_);
+
+ iconSizeBox->setLayout(iconSizeBoxLayout);
+
+ /*****************************************
+ * Icon-Style-Box
+ *****************************************/
+ auto* iconStyleBox = new QGroupBox(_("Icon Style"));
+ icon_style_group_ = new QButtonGroup();
+ icon_text_button_ = new QRadioButton(_("just text"));
+ icon_icons_button_ = new QRadioButton(_("just icons"));
+ icon_all_button_ = new QRadioButton(_("text and icons"));
+
+ icon_style_group_->addButton(icon_text_button_, 1);
+ icon_style_group_->addButton(icon_icons_button_, 2);
+ icon_style_group_->addButton(icon_all_button_, 3);
+
+ auto* iconStyleBoxLayout = new QHBoxLayout();
+ iconStyleBoxLayout->addWidget(icon_text_button_);
+ iconStyleBoxLayout->addWidget(icon_icons_button_);
+ iconStyleBoxLayout->addWidget(icon_all_button_);
+
+ iconStyleBox->setLayout(iconStyleBoxLayout);
+
+ /*****************************************
+ * Window-Size-Box
+ *****************************************/
+ auto* windowSizeBox = new QGroupBox(_("Window State"));
+ auto* windowSizeBoxLayout = new QHBoxLayout();
+ window_size_check_box_ =
+ new QCheckBox(_("Save window size and position on exit."), this);
+ windowSizeBoxLayout->addWidget(window_size_check_box_);
+ windowSizeBox->setLayout(windowSizeBoxLayout);
+
+ /*****************************************
+ * Info-Board-Font-Size-Box
+ *****************************************/
+
+ auto* infoBoardBox = new QGroupBox(_("Information Board"));
+ auto* infoBoardLayout = new QHBoxLayout();
+ info_board_font_size_spin_ = new QSpinBox();
+ info_board_font_size_spin_->setRange(9, 18);
+ info_board_font_size_spin_->setValue(10);
+ info_board_font_size_spin_->setSingleStep(1);
+ infoBoardLayout->addWidget(new QLabel(_("Font Size in Information Board")));
+ infoBoardLayout->addWidget(info_board_font_size_spin_);
+ infoBoardBox->setLayout(infoBoardLayout);
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(iconSizeBox);
+ mainLayout->addWidget(iconStyleBox);
+ mainLayout->addWidget(windowSizeBox);
+ mainLayout->addWidget(infoBoardBox);
+ mainLayout->addStretch(1);
+ SetSettings();
+ setLayout(mainLayout);
+}
+
+/**********************************
+ * Read the settings from config
+ * and set the buttons and checkboxes
+ * appropriately
+ **********************************/
+void AppearanceTab::SetSettings() {
+ SettingsObject general_settings_state("general_settings_state");
+
+ int width = general_settings_state.Check("icon_size").Check("width", 24),
+ height = general_settings_state.Check("icon_size").Check("height", 24);
+
+ auto icon_size = QSize(width, height);
+
+ switch (icon_size.width()) {
+ case 12:
+ icon_size_small_->setChecked(true);
+ break;
+ case 24:
+ icon_size_medium_->setChecked(true);
+ break;
+ case 32:
+ icon_size_large_->setChecked(true);
+ break;
+ }
+
+ // icon_style
+ int s_icon_style =
+ general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
+ auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
+
+ switch (icon_style) {
+ case Qt::ToolButtonTextOnly:
+ icon_text_button_->setChecked(true);
+ break;
+ case Qt::ToolButtonIconOnly:
+ icon_icons_button_->setChecked(true);
+ break;
+ case Qt::ToolButtonTextUnderIcon:
+ icon_all_button_->setChecked(true);
+ break;
+ default:
+ break;
+ }
+
+ bool window_save = general_settings_state.Check("window_save", true);
+ if (window_save) window_size_check_box_->setCheckState(Qt::Checked);
+
+ auto info_font_size = general_settings_state.Check("font_size", 10);
+ if (info_font_size < 9 || info_font_size > 18) info_font_size = 10;
+ info_board_font_size_spin_->setValue(info_font_size);
+}
+
+/***********************************
+ * get the values of the buttons and
+ * write them to settings-file
+ *************************************/
+void AppearanceTab::ApplySettings() {
+
+ SettingsObject general_settings_state("general_settings_state");
+
+ int icon_size = 24;
+ switch (icon_size_group_->checkedId()) {
+ case 1:
+ icon_size = 12;
+ break;
+ case 2:
+ icon_size = 24;
+ break;
+ case 3:
+ icon_size = 32;
+ break;
+ }
+
+ general_settings_state["icon_size"]["width"] = icon_size;
+ general_settings_state["icon_size"]["height"] = icon_size;
+
+ auto icon_style = Qt::ToolButtonTextUnderIcon;
+ switch (icon_style_group_->checkedId()) {
+ case 1:
+ icon_style = Qt::ToolButtonTextOnly;
+ break;
+ case 2:
+ icon_style = Qt::ToolButtonIconOnly;
+ break;
+ case 3:
+ icon_style = Qt::ToolButtonTextUnderIcon;
+ break;
+ }
+
+ general_settings_state["icon_style"] = icon_style;
+
+ general_settings_state["window_save"] = window_size_check_box_->isChecked();
+
+ general_settings_state["info_font_size"] = info_board_font_size_spin_->value();
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsAppearance.h b/src/ui/dialog/settings/SettingsAppearance.h
new file mode 100644
index 00000000..7110d992
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsAppearance.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSAPPEARANCE_H
+#define GPGFRONTEND_SETTINGSAPPEARANCE_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+class AppearanceTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new Appearance Tab object
+ *
+ * @param parent
+ */
+ explicit AppearanceTab(QWidget* parent = nullptr);
+
+ /**
+ * @brief Set the Settings object
+ *
+ */
+ void SetSettings();
+
+ /**
+ * @brief
+ *
+ */
+ void ApplySettings();
+
+ private:
+ QButtonGroup* icon_style_group_; ///<
+ QRadioButton* icon_size_small_; ///<
+ QRadioButton* icon_size_medium_; ///<
+ QRadioButton* icon_size_large_; ///<
+ QButtonGroup* icon_size_group_; ///<
+ QRadioButton* icon_text_button_; ///<
+ QRadioButton* icon_icons_button_; ///<
+ QRadioButton* icon_all_button_; ///<
+ QSpinBox* info_board_font_size_spin_; ///<
+ QCheckBox* window_size_check_box_; ///<
+
+ signals:
+
+ /**
+ * @brief
+ *
+ * @param needed
+ */
+ void signalRestartNeeded(bool needed);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSAPPEARANCE_H
diff --git a/src/ui/dialog/settings/SettingsDialog.cpp b/src/ui/dialog/settings/SettingsDialog.cpp
new file mode 100644
index 00000000..e2677a0f
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsDialog.cpp
@@ -0,0 +1,146 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsDialog.h"
+
+#include "SettingsAdvanced.h"
+#include "SettingsAppearance.h"
+#include "SettingsGeneral.h"
+#include "SettingsKeyServer.h"
+#include "SettingsNetwork.h"
+#include "core/function/GlobalSettingStation.h"
+#include "ui/main_window/MainWindow.h"
+
+namespace GpgFrontend::UI {
+
+SettingsDialog::SettingsDialog(QWidget* parent)
+ : GeneralDialog(typeid(SettingsDialog).name(), parent) {
+ tab_widget_ = new QTabWidget();
+ general_tab_ = new GeneralTab();
+ appearance_tab_ = new AppearanceTab();
+ key_server_tab_ = new KeyserverTab();
+ network_tab_ = new NetworkTab();
+
+ auto* mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(tab_widget_);
+ mainLayout->stretch(0);
+
+ tab_widget_->addTab(general_tab_, _("General"));
+ tab_widget_->addTab(appearance_tab_, _("Appearance"));
+ tab_widget_->addTab(key_server_tab_, _("Key Server"));
+ tab_widget_->addTab(network_tab_, _("Network"));
+
+#ifndef MACOS
+ button_box_ =
+ new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ connect(button_box_, &QDialogButtonBox::accepted, this,
+ &SettingsDialog::SlotAccept);
+ connect(button_box_, &QDialogButtonBox::rejected, this,
+ &SettingsDialog::reject);
+ mainLayout->addWidget(button_box_);
+ mainLayout->stretch(0);
+ setWindowTitle(_("Settings"));
+#else
+ connect(this, &QDialog::finished, this, &SettingsDialog::SlotAccept);
+ connect(this, &QDialog::finished, this, &SettingsDialog::deleteLater);
+ setWindowTitle(_("Preference"));
+#endif
+
+ setLayout(mainLayout);
+
+ // slots for handling the restart needed member
+ this->slot_set_restart_needed(false);
+ connect(general_tab_, &GeneralTab::SignalRestartNeeded, this,
+ &SettingsDialog::slot_set_restart_needed);
+ connect(this, &SettingsDialog::SignalRestartNeeded,
+ qobject_cast<MainWindow*>(parent), &MainWindow::SlotSetRestartNeeded);
+
+ this->setMinimumSize(480, 680);
+ this->adjustSize();
+ this->show();
+}
+
+bool SettingsDialog::get_restart_needed() const {
+ return this->restart_needed_;
+}
+
+void SettingsDialog::slot_set_restart_needed(bool needed) {
+ this->restart_needed_ = needed;
+}
+
+void SettingsDialog::SlotAccept() {
+ LOG(INFO) << "Called";
+
+ general_tab_->ApplySettings();
+ appearance_tab_->ApplySettings();
+ key_server_tab_->ApplySettings();
+ network_tab_->ApplySettings();
+
+ LOG(INFO) << "apply done";
+
+ // write settings to filesystem
+ GlobalSettingStation::GetInstance().SyncSettings();
+
+ LOG(INFO) << "restart needed" << get_restart_needed();
+ if (get_restart_needed()) {
+ emit SignalRestartNeeded(true);
+ }
+ close();
+}
+
+QHash<QString, QString> SettingsDialog::ListLanguages() {
+ QHash<QString, QString> languages;
+
+ languages.insert(QString(), _("System Default"));
+
+ auto locale_path = GlobalSettingStation::GetInstance().GetLocaleDir();
+
+ auto locale_dir = QDir(QString::fromStdString(locale_path.string()));
+ QStringList file_names = locale_dir.entryList(QStringList("*"));
+
+ for (int i = 0; i < file_names.size(); ++i) {
+ QString locale = file_names[i];
+ LOG(INFO) << "locale" << locale.toStdString();
+ if (locale == "." || locale == "..") continue;
+
+ // this works in qt 4.8
+ QLocale q_locale(locale);
+ if (q_locale.nativeCountryName().isEmpty()) continue;
+#if QT_VERSION < 0x040800
+ QString language =
+ QLocale::languageToString(q_locale.language()) + " (" + locale +
+ ")"; //+ " (" + QLocale::languageToString(q_locale.language()) + ")";
+#else
+ auto language = q_locale.nativeLanguageName() + " (" + locale + ")";
+#endif
+ languages.insert(locale, language);
+ }
+ return languages;
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsDialog.h b/src/ui/dialog/settings/SettingsDialog.h
new file mode 100644
index 00000000..172370d0
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsDialog.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef __SETTINGSDIALOG_H__
+#define __SETTINGSDIALOG_H__
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/dialog/GeneralDialog.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+class GeneralTab;
+class AppearanceTab;
+class KeyserverTab;
+class NetworkTab;
+
+/**
+ * @brief
+ *
+ */
+class SettingsDialog : public GeneralDialog {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new Settings Dialog object
+ *
+ * @param parent
+ */
+ explicit SettingsDialog(QWidget* parent = nullptr);
+
+ GeneralTab* general_tab_; ///<
+ AppearanceTab* appearance_tab_; ///<
+ KeyserverTab* key_server_tab_; ///<
+ NetworkTab* network_tab_; ///<
+
+ /**
+ * @brief
+ *
+ * @return QHash<QString, QString>
+ */
+ static QHash<QString, QString> ListLanguages();
+
+ public slots:
+
+ /**
+ * @brief
+ *
+ */
+ void SlotAccept();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ * @param needed
+ */
+ void SignalRestartNeeded(bool needed);
+
+ private:
+ QTabWidget* tab_widget_; ///<
+ QDialogButtonBox* button_box_; ///<
+ bool restart_needed_{}; ///<
+
+ /**
+ * @brief Get the Restart Needed object
+ *
+ * @return true
+ * @return false
+ */
+ bool get_restart_needed() const;
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ * @param needed
+ */
+ void slot_set_restart_needed(bool needed);
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __SETTINGSDIALOG_H__
diff --git a/src/ui/dialog/settings/SettingsGeneral.cpp b/src/ui/dialog/settings/SettingsGeneral.cpp
new file mode 100644
index 00000000..3c7bca32
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsGeneral.cpp
@@ -0,0 +1,196 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsGeneral.h"
+
+#ifdef MULTI_LANG_SUPPORT
+#include "SettingsDialog.h"
+#endif
+
+#include "core/function/GlobalSettingStation.h"
+#include "ui_GeneralSettings.h"
+
+namespace GpgFrontend::UI {
+
+GeneralTab::GeneralTab(QWidget* parent)
+ : QWidget(parent), ui_(std::make_shared<Ui_GeneralSettings>()) {
+ ui_->setupUi(this);
+
+ ui_->saveCheckedKeysBox->setTitle(_("Save Checked Keys"));
+ ui_->saveCheckedKeysCheckBox->setText(
+ _("Save checked private keys on exit and restore them on next start."));
+ ui_->longerKeyExpirationDateBox->setTitle(_("Longer Key Expiration Date"));
+ ui_->longerKeyExpirationDateCheckBox->setText(
+ _("Unlock key expiration date setting up to 30 years."));
+ ui_->importConfirmationBox->setTitle(_("Confirm drag'n'drop key import"));
+ ui_->importConfirmationCheckBox->setText(
+ _("Import files dropped on the Key List without confirmation."));
+
+ ui_->asciiModeBox->setTitle(_("ASCII Mode"));
+ ui_->asciiModeCheckBox->setText(
+ _("ASCII encoding is not used when file encrypting and "
+ "signing."));
+
+ ui_->langBox->setTitle(_("Language"));
+ ui_->langNoteLabel->setText(
+ "<b>" + QString(_("NOTE")) + _(": ") + "</b>" +
+ _("GpgFrontend will restart automatically if you change the language!"));
+
+#ifdef MULTI_LANG_SUPPORT
+ lang_ = SettingsDialog::ListLanguages();
+ for (const auto& l : lang_) {
+ ui_->langSelectBox->addItem(l);
+ }
+ connect(ui_->langSelectBox, qOverload<int>(&QComboBox::currentIndexChanged),
+ this, &GeneralTab::slot_language_changed);
+#endif
+
+ SetSettings();
+}
+
+/**********************************
+ * Read the settings from config
+ * and set the buttons and checkboxes
+ * appropriately
+ **********************************/
+void GeneralTab::SetSettings() {
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+ try {
+ bool save_key_checked = settings.lookup("general.save_key_checked");
+ if (save_key_checked)
+ ui_->saveCheckedKeysCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ 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)
+ ui_->longerKeyExpirationDateCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("longer_expiration_date");
+ }
+
+#ifdef MULTI_LANG_SUPPORT
+ try {
+ std::string lang_key = settings.lookup("general.lang");
+ QString lang_value = lang_.value(lang_key.c_str());
+ LOG(INFO) << "lang settings current" << lang_value.toStdString();
+ if (!lang_.empty()) {
+ ui_->langSelectBox->setCurrentIndex(
+ ui_->langSelectBox->findText(lang_value));
+ } else {
+ ui_->langSelectBox->setCurrentIndex(0);
+ }
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("lang");
+ }
+#endif
+
+ try {
+ bool confirm_import_keys = settings.lookup("general.confirm_import_keys");
+ LOG(INFO) << "confirm_import_keys" << confirm_import_keys;
+ if (confirm_import_keys)
+ ui_->importConfirmationCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("confirm_import_keys");
+ }
+
+ try {
+ bool non_ascii_when_export =
+ settings.lookup("general.non_ascii_when_export");
+ LOG(INFO) << "non_ascii_when_export" << non_ascii_when_export;
+ if (non_ascii_when_export)
+ ui_->asciiModeCheckBox->setCheckState(Qt::Checked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("non_ascii_when_export");
+ }
+}
+
+/***********************************
+ * get the values of the buttons and
+ * write them to settings-file
+ *************************************/
+void GeneralTab::ApplySettings() {
+ auto& settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("general") ||
+ settings.lookup("general").getType() != libconfig::Setting::TypeGroup)
+ settings.add("general", libconfig::Setting::TypeGroup);
+
+ auto& general = settings["general"];
+
+ if (!general.exists("longer_expiration_date"))
+ general.add("longer_expiration_date", libconfig::Setting::TypeBoolean) =
+ ui_->longerKeyExpirationDateCheckBox->isChecked();
+ else {
+ general["longer_expiration_date"] =
+ ui_->longerKeyExpirationDateCheckBox->isChecked();
+ }
+
+ if (!general.exists("save_key_checked"))
+ general.add("save_key_checked", libconfig::Setting::TypeBoolean) =
+ ui_->saveCheckedKeysCheckBox->isChecked();
+ else {
+ general["save_key_checked"] = ui_->saveCheckedKeysCheckBox->isChecked();
+ }
+
+ if (!general.exists("non_ascii_when_export"))
+ general.add("non_ascii_when_export", libconfig::Setting::TypeBoolean) =
+ ui_->asciiModeCheckBox->isChecked();
+ else {
+ general["non_ascii_when_export"] = ui_->asciiModeCheckBox->isChecked();
+ }
+
+#ifdef MULTI_LANG_SUPPORT
+ if (!general.exists("lang"))
+ general.add("lang", libconfig::Setting::TypeBoolean) =
+ lang_.key(ui_->langSelectBox->currentText()).toStdString();
+ else {
+ general["lang"] =
+ lang_.key(ui_->langSelectBox->currentText()).toStdString();
+ }
+#endif
+
+ if (!general.exists("confirm_import_keys"))
+ general.add("confirm_import_keys", libconfig::Setting::TypeBoolean) =
+ ui_->importConfirmationCheckBox->isChecked();
+ else {
+ general["confirm_import_keys"] =
+ ui_->importConfirmationCheckBox->isChecked();
+ }
+}
+
+#ifdef MULTI_LANG_SUPPORT
+void GeneralTab::slot_language_changed() { emit SignalRestartNeeded(true); }
+#endif
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsGeneral.h b/src/ui/dialog/settings/SettingsGeneral.h
new file mode 100644
index 00000000..b3e7d904
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsGeneral.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSGENERAL_H
+#define GPGFRONTEND_SETTINGSGENERAL_H
+
+#include "ui/GpgFrontendUI.h"
+
+class Ui_GeneralSettings;
+
+namespace GpgFrontend::UI {
+class KeyList;
+
+/**
+ * @brief
+ *
+ */
+class GeneralTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new General Tab object
+ *
+ * @param parent
+ */
+ explicit GeneralTab(QWidget* parent = nullptr);
+
+ /**
+ * @brief Set the Settings object
+ *
+ */
+ void SetSettings();
+
+ /**
+ * @brief
+ *
+ */
+ void ApplySettings();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ * @param needed
+ */
+ void SignalRestartNeeded(bool needed);
+
+ private:
+ std::shared_ptr<Ui_GeneralSettings> ui_; ///<
+
+#ifdef MULTI_LANG_SUPPORT
+ QHash<QString, QString> lang_; ///<
+#endif
+
+ std::vector<std::string> key_ids_list_; ///<
+
+ KeyList* m_key_list_{}; ///<
+
+ private slots:
+
+#ifdef MULTI_LANG_SUPPORT
+ /**
+ * @brief
+ *
+ */
+ void slot_language_changed();
+
+#endif
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSGENERAL_H
diff --git a/src/ui/dialog/settings/SettingsKeyServer.cpp b/src/ui/dialog/settings/SettingsKeyServer.cpp
new file mode 100644
index 00000000..2c09b66c
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsKeyServer.cpp
@@ -0,0 +1,301 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsKeyServer.h"
+
+#include "core/function/GlobalSettingStation.h"
+#include "core/thread/Task.h"
+#include "core/thread/TaskRunnerGetter.h"
+#include "ui/struct/SettingsObject.h"
+#include "ui/thread/ListedKeyServerTestTask.h"
+#include "ui_KeyServerSettings.h"
+
+namespace GpgFrontend::UI {
+
+KeyserverTab::KeyserverTab(QWidget* parent)
+ : QWidget(parent), ui_(std::make_shared<Ui_KeyServerSettings>()) {
+ ui_->setupUi(this);
+ ui_->keyServerListTable->setSizeAdjustPolicy(
+ QAbstractScrollArea::AdjustToContents);
+
+ connect(ui_->addKeyServerPushButton, &QPushButton::clicked, this,
+ &KeyserverTab::slot_add_key_server);
+ connect(ui_->testKeyServerButton, &QPushButton::clicked, this,
+ &KeyserverTab::slot_test_listed_key_server);
+
+ ui_->keyServerListGroupBox->setTitle(_("Keyserver List"));
+ ui_->operationsGroupBox->setTitle(_("Operations"));
+
+ ui_->keyServerListTable->horizontalHeaderItem(0)->setText(_("Default"));
+ ui_->keyServerListTable->horizontalHeaderItem(1)->setText(
+ _("Keyserver Address"));
+ ui_->keyServerListTable->horizontalHeaderItem(2)->setText(_("Security"));
+ ui_->keyServerListTable->horizontalHeaderItem(3)->setText(_("Available"));
+
+ ui_->addKeyServerPushButton->setText(_("Add"));
+ ui_->testKeyServerButton->setText(_("Test Listed Keyserver"));
+
+ ui_->tipsLabel->setText(
+ _("Tips: Please Double-click table item to edit it."));
+ ui_->actionDelete_Selected_Key_Server->setText(_("Delete Selected"));
+ ui_->actionDelete_Selected_Key_Server->setToolTip(
+ _("Delete Selected Key Server"));
+ ui_->actionSet_As_Default->setText(_("Set As Default"));
+ ui_->actionSet_As_Default->setToolTip(_("Set As Default"));
+
+ popup_menu_ = new QMenu(this);
+ popup_menu_->addAction(ui_->actionSet_As_Default);
+ popup_menu_->addAction(ui_->actionDelete_Selected_Key_Server);
+
+ connect(ui_->keyServerListTable, &QTableWidget::itemChanged,
+ [=](QTableWidgetItem* item) {
+ LOG(INFO) << "item edited" << item->column();
+ if (item->column() != 1) return;
+ const auto row_size = ui_->keyServerListTable->rowCount();
+ // Update Actions
+ if (row_size > 0) {
+ key_server_str_list_.clear();
+ for (int i = 0; i < row_size; i++) {
+ const auto key_server =
+ ui_->keyServerListTable->item(i, 1)->text();
+ key_server_str_list_.append(key_server);
+ }
+ }
+ });
+
+ connect(ui_->actionSet_As_Default, &QAction::triggered, [=]() {
+ const auto row_size = ui_->keyServerListTable->rowCount();
+ for (int i = 0; i < row_size; i++) {
+ const auto item = ui_->keyServerListTable->item(i, 1);
+ if (!item->isSelected()) continue;
+ this->default_key_server_ = item->text();
+ }
+ this->slot_refresh_table();
+ });
+
+ connect(ui_->actionDelete_Selected_Key_Server, &QAction::triggered, [=]() {
+ const auto row_size = ui_->keyServerListTable->rowCount();
+ for (int i = 0; i < row_size; i++) {
+ const auto item = ui_->keyServerListTable->item(i, 1);
+ if (!item->isSelected()) continue;
+ this->key_server_str_list_.removeAt(i);
+ break;
+ }
+ this->slot_refresh_table();
+ });
+
+ // Read key-list from ini-file and fill it into combobox
+ SetSettings();
+ slot_refresh_table();
+}
+
+/**********************************
+ * Read the settings from config
+ * and set the buttons and checkboxes
+ * appropriately
+ **********************************/
+void KeyserverTab::SetSettings() {
+ try {
+ SettingsObject key_server_json("key_server");
+
+ const auto key_server_list =
+ key_server_json.Check("server_list", nlohmann::json::array());
+
+ for (const auto& key_server : key_server_list) {
+ const auto key_server_str = key_server.get<std::string>();
+ this->key_server_str_list_.append(key_server_str.c_str());
+ }
+
+ int default_key_server_index = key_server_json.Check("default_server", 0);
+ if (default_key_server_index >= key_server_list.size()) {
+ throw std::runtime_error("default_server index out of range");
+ }
+ std::string default_key_server =
+ key_server_list[default_key_server_index].get<std::string>();
+
+ if (!key_server_str_list_.contains(default_key_server.c_str()))
+ key_server_str_list_.append(default_key_server.c_str());
+ default_key_server_ = QString::fromStdString(default_key_server);
+ } catch (const std::exception& e) {
+ LOG(ERROR) << "Error reading key-server settings: " << e.what();
+ }
+}
+
+void KeyserverTab::slot_add_key_server() {
+ auto target_url = ui_->addKeyServerEdit->text();
+ if (url_reg_.match(target_url).hasMatch()) {
+ if (target_url.startsWith("https://")) {
+ ;
+ } else if (target_url.startsWith("http://")) {
+ QMessageBox::warning(
+ this, _("Insecure keyserver address"),
+ _("For security reasons, using HTTP as the communication protocol "
+ "with "
+ "the key server is not recommended. It is recommended to use "
+ "HTTPS."));
+ }
+ key_server_str_list_.append(ui_->addKeyServerEdit->text());
+ } else {
+ auto ret = QMessageBox::warning(
+ this, _("Warning"),
+ _("You may not use HTTPS or HTTP as the protocol for communicating "
+ "with the key server, which may not be wrong. But please check the "
+ "address you entered again to make sure it is correct. Are you "
+ "sure "
+ "that want to add it into the keyserver list?"),
+ QMessageBox::Ok | QMessageBox::Cancel);
+
+ if (ret == QMessageBox::Cancel)
+ return;
+ else
+ key_server_str_list_.append(ui_->addKeyServerEdit->text());
+ }
+ slot_refresh_table();
+}
+
+void KeyserverTab::ApplySettings() {
+ SettingsObject key_server_json("key_server");
+ key_server_json["server_list"] = nlohmann::json::array();
+ auto& key_server_list = key_server_json["server_list"];
+
+ const auto list_size = key_server_str_list_.size();
+ for (int i = 0; i < list_size; i++) {
+ const auto key_server = key_server_str_list_[i];
+ if (default_key_server_ == key_server)
+ key_server_json["default_server"] = i;
+ key_server_list.insert(key_server_list.end(), key_server.toStdString());
+ }
+}
+
+void KeyserverTab::slot_refresh_table() {
+ LOG(INFO) << "Start Refreshing Key Server Table";
+
+ ui_->keyServerListTable->blockSignals(true);
+ ui_->keyServerListTable->setRowCount(key_server_str_list_.size());
+
+ int index = 0;
+ for (const auto& server : key_server_str_list_) {
+ auto* tmp1 =
+ new QTableWidgetItem(server == default_key_server_ ? "*" : QString{});
+ tmp1->setTextAlignment(Qt::AlignCenter);
+ ui_->keyServerListTable->setItem(index, 0, tmp1);
+ tmp1->setFlags(tmp1->flags() ^ Qt::ItemIsEditable);
+
+ auto* tmp2 = new QTableWidgetItem(server);
+ tmp2->setTextAlignment(Qt::AlignCenter);
+ ui_->keyServerListTable->setItem(index, 1, tmp2);
+
+ auto* tmp3 = new QTableWidgetItem(server.startsWith("https") ? _("true")
+ : _("false"));
+ tmp3->setTextAlignment(Qt::AlignCenter);
+ ui_->keyServerListTable->setItem(index, 2, tmp3);
+ tmp3->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
+
+ auto* tmp4 = new QTableWidgetItem(_("unknown"));
+ tmp4->setTextAlignment(Qt::AlignCenter);
+ ui_->keyServerListTable->setItem(index, 3, tmp4);
+ tmp4->setFlags(tmp3->flags() ^ Qt::ItemIsEditable);
+ index++;
+ }
+ const auto column_count = ui_->keyServerListTable->columnCount();
+ for (int i = 0; i < column_count; i++) {
+ ui_->keyServerListTable->resizeColumnToContents(i);
+ }
+ ui_->keyServerListTable->blockSignals(false);
+}
+
+void KeyserverTab::slot_test_listed_key_server() {
+ auto timeout = QInputDialog::getInt(this, _("Set TCP Timeout"),
+ tr("timeout(ms): "), 2500, 200, 16000);
+
+ QStringList urls;
+ const auto row_size = ui_->keyServerListTable->rowCount();
+ for (int i = 0; i < row_size; i++) {
+ const auto keyserver_url = ui_->keyServerListTable->item(i, 1)->text();
+ urls.push_back(keyserver_url);
+ }
+
+ auto* task = new ListedKeyServerTestTask(urls, timeout, this);
+
+ connect(
+ task,
+ &GpgFrontend::UI::ListedKeyServerTestTask::SignalKeyServerListTestResult,
+ this,
+ [=](std::vector<ListedKeyServerTestTask::KeyServerTestResultType>
+ result) {
+ const auto row_size = ui_->keyServerListTable->rowCount();
+ if (result.size() != row_size) return;
+ ui_->keyServerListTable->blockSignals(true);
+ for (int i = 0; i < row_size; i++) {
+ const auto status = result[i];
+ auto status_iem = ui_->keyServerListTable->item(i, 3);
+ if (status == ListedKeyServerTestTask::kTestResultType_Success) {
+ status_iem->setText(_("Reachable"));
+ status_iem->setForeground(QBrush(QColor::fromRgb(0, 255, 0)));
+ } else {
+ status_iem->setText(_("Not Reachable"));
+ status_iem->setForeground(QBrush(QColor::fromRgb(255, 0, 0)));
+ }
+ }
+ ui_->keyServerListTable->blockSignals(false);
+ });
+
+ // Waiting Dialog
+ auto* waiting_dialog = new QProgressDialog(this);
+ waiting_dialog->setMaximum(0);
+ waiting_dialog->setMinimum(0);
+ auto waiting_dialog_label =
+ new QLabel(QString(_("Test Key Server Connection...")) + "<br /><br />" +
+ _("This test only tests the network connectivity of the key "
+ "server. Passing the test does not mean that the key server "
+ "is functionally available."));
+ waiting_dialog_label->setWordWrap(true);
+ waiting_dialog->setLabel(waiting_dialog_label);
+ waiting_dialog->resize(420, 120);
+ waiting_dialog->setModal(true);
+ connect(task, &Thread::Task::SignalTaskFinished, [=]() {
+ waiting_dialog->close();
+ waiting_dialog->deleteLater();
+ });
+ // Show Waiting Dialog
+ waiting_dialog->show();
+ waiting_dialog->setFocus();
+
+ Thread::TaskRunnerGetter::GetInstance()
+ .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_Network)
+ ->PostTask(task);
+}
+
+void KeyserverTab::contextMenuEvent(QContextMenuEvent* event) {
+ QWidget::contextMenuEvent(event);
+ if (ui_->keyServerListTable->selectedItems().length() > 0) {
+ popup_menu_->exec(event->globalPos());
+ }
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/dialog/settings/SettingsKeyServer.h b/src/ui/dialog/settings/SettingsKeyServer.h
new file mode 100644
index 00000000..f983e69b
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsKeyServer.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSKEYSERVER_H
+#define GPGFRONTEND_SETTINGSKEYSERVER_H
+
+#include "ui/GpgFrontendUI.h"
+
+class Ui_KeyServerSettings;
+
+namespace GpgFrontend::UI {
+/**
+ * @brief
+ *
+ */
+class KeyserverTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new Keyserver Tab object
+ *
+ * @param parent
+ */
+ explicit KeyserverTab(QWidget* parent = nullptr);
+
+ /**
+ * @brief Set the Settings object
+ *
+ */
+ void SetSettings();
+
+ /**
+ * @brief
+ *
+ */
+ void ApplySettings();
+
+ private:
+ std::shared_ptr<Ui_KeyServerSettings> ui_;
+ QString default_key_server_;
+ QStringList key_server_str_list_;
+ QMenu* popup_menu_{};
+
+ QRegularExpression url_reg_{
+ R"(^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$)"};
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_add_key_server();
+
+ /**
+ * @brief
+ *
+ */
+ void slot_refresh_table();
+
+ /**
+ * @brief
+ *
+ */
+ void slot_test_listed_key_server();
+
+ signals:
+ /**
+ * @brief
+ *
+ * @param needed
+ */
+ void SignalRestartNeeded(bool needed);
+
+ protected:
+ /**
+ * @brief
+ *
+ * @param event
+ */
+ void contextMenuEvent(QContextMenuEvent* event) override;
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSKEYSERVER_H
diff --git a/src/ui/dialog/settings/SettingsNetwork.cpp b/src/ui/dialog/settings/SettingsNetwork.cpp
new file mode 100644
index 00000000..d4edae42
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsNetwork.cpp
@@ -0,0 +1,338 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include "SettingsNetwork.h"
+
+#include "core/function/GlobalSettingStation.h"
+#include "ui/thread/ProxyConnectionTestThread.h"
+#include "ui_NetworkSettings.h"
+
+GpgFrontend::UI::NetworkTab::NetworkTab(QWidget *parent)
+ : QWidget(parent), ui_(std::make_shared<Ui_NetworkSettings>()) {
+ ui_->setupUi(this);
+
+ connect(ui_->enableProxyCheckBox, &QCheckBox::stateChanged, this,
+ [=](int state) { switch_ui_enabled(state == Qt::Checked); });
+
+ connect(
+ ui_->proxyTypeComboBox, &QComboBox::currentTextChanged, this,
+ [=](const QString &current_text) { switch_ui_proxy_type(current_text); });
+
+ connect(ui_->checkProxyConnectionButton, &QPushButton::clicked, this,
+ &NetworkTab::slot_test_proxy_connection_result);
+
+ ui_->proxyGroupBox->setTitle(_("Proxy"));
+ ui_->capabilityGroupBox->setTitle(_("Network Capability"));
+ ui_->operationsGroupBox->setTitle(_("Operations"));
+
+ ui_->enableProxyCheckBox->setText(_("Enable Proxy"));
+ ui_->proxyServerPortLabel->setText(_("Port"));
+
+ ui_->proxyServerAddressLabel->setText(_("Host Address"));
+ ui_->proxyServerPortLabel->setText(_("Port"));
+ ui_->proxyTypeLabel->setText(_("Proxy Type"));
+ ui_->usernameLabel->setText(_("Username"));
+ ui_->passwordLabel->setText(_("Password"));
+
+ ui_->forbidALLCheckBox->setText(_("Forbid all network connection."));
+ ui_->forbidALLCheckBox->setDisabled(true);
+
+ ui_->prohibitUpdateCheck->setText(
+ _("Prohibit checking for version updates when the program starts."));
+ ui_->checkProxyConnectionButton->setText(_("Check Proxy Connection"));
+
+ SetSettings();
+}
+
+void GpgFrontend::UI::NetworkTab::SetSettings() {
+ auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ try {
+ std::string proxy_host = settings.lookup("proxy.proxy_host");
+ ui_->proxyServerAddressEdit->setText(proxy_host.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("proxy_host");
+ }
+
+ try {
+ std::string std_username = settings.lookup("proxy.username");
+ ui_->usernameEdit->setText(std_username.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("username");
+ }
+
+ try {
+ std::string std_password = settings.lookup("proxy.password");
+ ui_->passwordEdit->setText(std_password.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("password");
+ }
+
+ try {
+ int port = settings.lookup("proxy.port");
+ ui_->portSpin->setValue(port);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("port");
+ }
+
+ ui_->proxyTypeComboBox->setCurrentText("HTTP");
+ try {
+ std::string proxy_type = settings.lookup("proxy.proxy_type");
+ ui_->proxyTypeComboBox->setCurrentText(proxy_type.c_str());
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("proxy_type");
+ }
+ switch_ui_proxy_type(ui_->proxyTypeComboBox->currentText());
+
+ ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked);
+ try {
+ bool proxy_enable = settings.lookup("proxy.enable");
+ if (proxy_enable)
+ ui_->enableProxyCheckBox->setCheckState(Qt::Checked);
+ else
+ ui_->enableProxyCheckBox->setCheckState(Qt::Unchecked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("proxy_enable");
+ }
+
+ {
+ auto state = ui_->enableProxyCheckBox->checkState();
+ switch_ui_enabled(state == Qt::Checked);
+ }
+
+ ui_->forbidALLCheckBox->setCheckState(Qt::Unchecked);
+ try {
+ bool forbid_all_connection =
+ settings.lookup("network.forbid_all_connection");
+ if (forbid_all_connection)
+ ui_->forbidALLCheckBox->setCheckState(Qt::Checked);
+ else
+ ui_->forbidALLCheckBox->setCheckState(Qt::Unchecked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("forbid_all_connection");
+ }
+
+ ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
+ try {
+ bool prohibit_update_checking =
+ settings.lookup("network.prohibit_update_checking");
+ if (prohibit_update_checking)
+ ui_->prohibitUpdateCheck->setCheckState(Qt::Checked);
+ else
+ ui_->prohibitUpdateCheck->setCheckState(Qt::Unchecked);
+ } catch (...) {
+ LOG(ERROR) << _("Setting Operation Error") << _("prohibit_update_checking");
+ }
+}
+
+void GpgFrontend::UI::NetworkTab::ApplySettings() {
+ LOG(INFO) << "called";
+
+ auto &settings =
+ GpgFrontend::GlobalSettingStation::GetInstance().GetUISettings();
+
+ if (!settings.exists("proxy") ||
+ settings.lookup("proxy").getType() != libconfig::Setting::TypeGroup)
+ settings.add("proxy", libconfig::Setting::TypeGroup);
+
+ auto &proxy = settings["proxy"];
+
+ if (!proxy.exists("proxy_host"))
+ proxy.add("proxy_host", libconfig::Setting::TypeString) =
+ ui_->proxyServerAddressEdit->text().toStdString();
+ else {
+ proxy["proxy_host"] = ui_->proxyServerAddressEdit->text().toStdString();
+ }
+
+ if (!proxy.exists("username"))
+ proxy.add("username", libconfig::Setting::TypeString) =
+ ui_->usernameEdit->text().toStdString();
+ else {
+ proxy["username"] = ui_->usernameEdit->text().toStdString();
+ }
+
+ if (!proxy.exists("password"))
+ proxy.add("password", libconfig::Setting::TypeString) =
+ ui_->passwordEdit->text().toStdString();
+ else {
+ proxy["password"] = ui_->passwordEdit->text().toStdString();
+ }
+
+ if (!proxy.exists("port"))
+ proxy.add("port", libconfig::Setting::TypeInt) = ui_->portSpin->value();
+ else {
+ proxy["port"] = ui_->portSpin->value();
+ }
+
+ if (!proxy.exists("proxy_type"))
+ proxy.add("proxy_type", libconfig::Setting::TypeString) =
+ ui_->proxyTypeComboBox->currentText().toStdString();
+ else {
+ proxy["proxy_type"] = ui_->proxyTypeComboBox->currentText().toStdString();
+ }
+
+ if (!proxy.exists("enable"))
+ proxy.add("enable", libconfig::Setting::TypeBoolean) =
+ ui_->enableProxyCheckBox->isChecked();
+ else {
+ proxy["enable"] = ui_->enableProxyCheckBox->isChecked();
+ }
+
+ if (!settings.exists("network") ||
+ settings.lookup("network").getType() != libconfig::Setting::TypeGroup)
+ settings.add("network", libconfig::Setting::TypeGroup);
+
+ auto &network = settings["network"];
+
+ if (!network.exists("forbid_all_connection"))
+ network.add("forbid_all_connection", libconfig::Setting::TypeBoolean) =
+ ui_->forbidALLCheckBox->isChecked();
+ else {
+ network["forbid_all_connection"] = ui_->forbidALLCheckBox->isChecked();
+ }
+
+ if (!network.exists("prohibit_update_checking"))
+ network.add("prohibit_update_checking", libconfig::Setting::TypeBoolean) =
+ ui_->prohibitUpdateCheck->isChecked();
+ else {
+ network["prohibit_update_checking"] = ui_->prohibitUpdateCheck->isChecked();
+ }
+
+ apply_proxy_settings();
+
+ LOG(INFO) << "done";
+}
+
+void GpgFrontend::UI::NetworkTab::slot_test_proxy_connection_result() {
+ apply_proxy_settings();
+
+ bool ok;
+ auto url = QInputDialog::getText(this, _("Test Server Url Accessibility"),
+ tr("Server Url"), QLineEdit::Normal,
+ "https://", &ok);
+ if (ok && !url.isEmpty()) {
+ auto thread = new ProxyConnectionTestThread(url, 800, this);
+ connect(thread,
+ &GpgFrontend::UI::ProxyConnectionTestThread::
+ SignalProxyConnectionTestResult,
+ this, [=](const QString &result) {
+ if (result == "Reachable") {
+ QMessageBox::information(this, _("Success"),
+ _("Successfully connect to the target "
+ "server through the proxy server."));
+ } else {
+ QMessageBox::critical(
+ this, _("Failed"),
+ _("Unable to connect to the target server through the "
+ "proxy server. Proxy settings may be invalid."));
+ }
+ });
+ connect(thread, &QThread::finished, thread, &QThread::deleteLater);
+
+ // Waiting Dialog
+ auto *waiting_dialog = new QProgressDialog(this);
+ waiting_dialog->setMaximum(0);
+ waiting_dialog->setMinimum(0);
+ auto waiting_dialog_label = new QLabel(
+ QString(_("Test Proxy Server Connection...")) + "<br /><br />" +
+ _("Is using your proxy settings to access the url. Note that this test "
+ "operation will apply your proxy settings to the entire software."));
+ waiting_dialog_label->setWordWrap(true);
+ waiting_dialog->setLabel(waiting_dialog_label);
+ waiting_dialog->resize(420, 120);
+ 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();
+ });
+
+ // Show Waiting Dialog
+ waiting_dialog->show();
+ waiting_dialog->setFocus();
+
+ thread->start();
+ QEventLoop loop;
+ connect(thread, &QThread::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+ }
+}
+
+void GpgFrontend::UI::NetworkTab::apply_proxy_settings() {
+ // apply settings
+ QNetworkProxy _proxy;
+ if (ui_->enableProxyCheckBox->isChecked() &&
+ proxy_type_ != QNetworkProxy::DefaultProxy) {
+ _proxy.setType(proxy_type_);
+ _proxy.setHostName(ui_->proxyServerAddressEdit->text());
+ _proxy.setPort(ui_->portSpin->value());
+ if (!ui_->usernameEdit->text().isEmpty()) {
+ _proxy.setUser(ui_->usernameEdit->text());
+ _proxy.setPassword(ui_->passwordEdit->text());
+ }
+ } else {
+ _proxy.setType(proxy_type_);
+ }
+
+ QNetworkProxy::setApplicationProxy(_proxy);
+}
+
+void GpgFrontend::UI::NetworkTab::switch_ui_enabled(bool enabled) {
+ ui_->proxyServerAddressEdit->setDisabled(!enabled);
+ ui_->portSpin->setDisabled(!enabled);
+ ui_->proxyTypeComboBox->setDisabled(!enabled);
+ ui_->usernameEdit->setDisabled(!enabled);
+ ui_->passwordEdit->setDisabled(!enabled);
+ ui_->checkProxyConnectionButton->setDisabled(!enabled);
+ if (!enabled) proxy_type_ = QNetworkProxy::NoProxy;
+}
+
+void GpgFrontend::UI::NetworkTab::switch_ui_proxy_type(
+ const QString &type_text) {
+ if (type_text == "HTTP") {
+ ui_->proxyServerAddressEdit->setDisabled(false);
+ ui_->portSpin->setDisabled(false);
+ ui_->usernameEdit->setDisabled(false);
+ ui_->passwordEdit->setDisabled(false);
+ proxy_type_ = QNetworkProxy::HttpProxy;
+ } else if (type_text == "Socks5") {
+ ui_->proxyServerAddressEdit->setDisabled(false);
+ ui_->portSpin->setDisabled(false);
+ ui_->usernameEdit->setDisabled(false);
+ ui_->passwordEdit->setDisabled(false);
+ proxy_type_ = QNetworkProxy::Socks5Proxy;
+ } else {
+ ui_->proxyServerAddressEdit->setDisabled(true);
+ ui_->portSpin->setDisabled(true);
+ ui_->usernameEdit->setDisabled(true);
+ ui_->passwordEdit->setDisabled(true);
+ proxy_type_ = QNetworkProxy::DefaultProxy;
+ }
+}
diff --git a/src/ui/dialog/settings/SettingsNetwork.h b/src/ui/dialog/settings/SettingsNetwork.h
new file mode 100644
index 00000000..d4c0d00d
--- /dev/null
+++ b/src/ui/dialog/settings/SettingsNetwork.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (C) 2021 Saturneric
+ *
+ * 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.
+ *
+ * GpgFrontend 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 GpgFrontend. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * The initial version of the source code is inherited from
+ * the gpg4usb project, which is under GPL-3.0-or-later.
+ *
+ * All the source code of GpgFrontend was modified and released by
+ * Saturneric<[email protected]> starting on May 12, 2021.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef GPGFRONTEND_SETTINGSNETWORK_H
+#define GPGFRONTEND_SETTINGSNETWORK_H
+
+#include "ui/GpgFrontendUI.h"
+
+class Ui_NetworkSettings;
+
+namespace GpgFrontend::UI {
+class NetworkTab : public QWidget {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new Network Tab object
+ *
+ * @param parent
+ */
+ explicit NetworkTab(QWidget* parent = nullptr);
+
+ /**
+ * @brief Set the Settings object
+ *
+ */
+ void SetSettings();
+
+ /**
+ * @brief
+ *
+ */
+ void ApplySettings();
+
+ private slots:
+
+ /**
+ * @brief
+ *
+ */
+ void slot_test_proxy_connection_result();
+
+ private:
+ std::shared_ptr<Ui_NetworkSettings> ui_; ///<
+ QNetworkProxy::ProxyType proxy_type_ = QNetworkProxy::HttpProxy; ///<
+
+ /**
+ * @brief
+ *
+ */
+ void apply_proxy_settings();
+
+ /**
+ * @brief
+ *
+ * @param enabled
+ */
+ void switch_ui_enabled(bool enabled);
+
+ /**
+ * @brief
+ *
+ * @param type_text
+ */
+ void switch_ui_proxy_type(const QString& type_text);
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_SETTINGSNETWORK_H