aboutsummaryrefslogtreecommitdiffstats
path: root/src/ui/main_window
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/main_window')
-rw-r--r--src/ui/main_window/GeneralMainWindow.cpp135
-rw-r--r--src/ui/main_window/GeneralMainWindow.h81
-rw-r--r--src/ui/main_window/KeyMgmt.cpp462
-rw-r--r--src/ui/main_window/KeyMgmt.h178
-rw-r--r--src/ui/main_window/MainWindow.cpp70
-rw-r--r--src/ui/main_window/MainWindow.h15
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp5
-rw-r--r--src/ui/main_window/MainWindowSlotFunction.cpp11
-rw-r--r--src/ui/main_window/MainWindowSlotUI.cpp10
-rw-r--r--src/ui/main_window/MainWindowUI.cpp9
10 files changed, 895 insertions, 81 deletions
diff --git a/src/ui/main_window/GeneralMainWindow.cpp b/src/ui/main_window/GeneralMainWindow.cpp
new file mode 100644
index 00000000..7df73aba
--- /dev/null
+++ b/src/ui/main_window/GeneralMainWindow.cpp
@@ -0,0 +1,135 @@
+/**
+ * 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 "GeneralMainWindow.h"
+
+#include <utility>
+
+#include "ui/struct/SettingsObject.h"
+
+GpgFrontend::UI::GeneralMainWindow::GeneralMainWindow(std::string name,
+ QWidget* parent)
+ : name_(std::move(name)), QMainWindow(parent) {
+ slot_restore_settings();
+}
+
+GpgFrontend::UI::GeneralMainWindow::~GeneralMainWindow() = default;
+
+void GpgFrontend::UI::GeneralMainWindow::closeEvent(QCloseEvent* event) {
+ slot_save_settings();
+ QMainWindow::closeEvent(event);
+}
+
+void GpgFrontend::UI::GeneralMainWindow::slot_restore_settings() noexcept {
+ try {
+ LOG(INFO) << name_ << _("Called");
+
+ SettingsObject general_windows_state(name_ + "_state");
+
+ std::string window_state = general_windows_state.Check(
+ "window_state", saveState().toBase64().toStdString());
+
+ // state sets pos & size of dock-widgets
+ this->restoreState(
+ QByteArray::fromBase64(QByteArray::fromStdString(window_state)));
+
+ bool window_save = general_windows_state.Check("window_save", true);
+
+ // Restore window size & location
+ if (window_save) {
+ int x = general_windows_state.Check("window_pos").Check("x", 100),
+ y = general_windows_state.Check("window_pos").Check("y", 100);
+
+ this->move({x, y});
+ pos_ = {x, y};
+
+ int width =
+ general_windows_state.Check("window_size").Check("width", 800),
+ height =
+ general_windows_state.Check("window_size").Check("height", 450);
+
+ this->resize({width, height});
+ size_ = {width, height};
+ }
+
+
+ // appearance
+ 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);
+ LOG(INFO) << "icon_size" << width << height;
+
+ icon_size_ = {width, height};
+ font_size_ = general_settings_state.Check("font_size", 10);
+
+ this->setIconSize(icon_size_);
+
+ // icon_style
+ int s_icon_style =
+ general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
+ this->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(s_icon_style));
+ icon_style_ = toolButtonStyle();
+
+ } catch (...) {
+ LOG(ERROR) << name_ << "error";
+ }
+}
+
+void GpgFrontend::UI::GeneralMainWindow::slot_save_settings() noexcept {
+ try {
+ LOG(INFO) << name_ << _("Called");
+
+ SettingsObject general_windows_state(name_ + "_state");
+
+ // window position and size
+ general_windows_state["window_state"] =
+ saveState().toBase64().toStdString();
+ general_windows_state["window_pos"]["x"] = pos().x();
+ general_windows_state["window_pos"]["y"] = pos().y();
+
+ general_windows_state["window_size"]["width"] = size_.width();
+ general_windows_state["window_size"]["height"] = size_.height();
+ general_windows_state["window_save"] = true;
+
+ SettingsObject general_settings_state("general_settings_state");
+
+ // icon size
+ general_settings_state["icon_size"]["width"] = icon_size_.width();
+ general_settings_state["icon_size"]["height"] = icon_size_.height();
+
+ // font size
+ general_settings_state["font_size"] = font_size_;
+
+ // tool button style
+ general_settings_state["icon_style"] = this->toolButtonStyle();
+
+ } catch (...) {
+ LOG(ERROR) << name_ << "error";
+ }
+}
diff --git a/src/ui/main_window/GeneralMainWindow.h b/src/ui/main_window/GeneralMainWindow.h
new file mode 100644
index 00000000..71327100
--- /dev/null
+++ b/src/ui/main_window/GeneralMainWindow.h
@@ -0,0 +1,81 @@
+/**
+ * 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_GENERALMAINWINDOW_H
+#define GPGFRONTEND_GENERALMAINWINDOW_H
+
+#include "ui/GpgFrontendUI.h"
+
+namespace GpgFrontend::UI {
+
+/**
+ *
+ */
+class GeneralMainWindow : public QMainWindow {
+ public:
+ /**
+ *
+ * @param name
+ */
+ explicit GeneralMainWindow(std::string name, QWidget* parent = nullptr);
+
+ /**
+ *
+ */
+ ~GeneralMainWindow() override;
+
+ protected:
+ /**
+ *
+ * @param event
+ */
+ void closeEvent(QCloseEvent* event);
+
+ QSize icon_size_{}; ///<
+ int font_size_{}; ///<
+ Qt::ToolButtonStyle icon_style_; ///<
+
+ private slots:
+ /**
+ *
+ */
+ void slot_restore_settings() noexcept;
+
+ /**
+ *
+ */
+ void slot_save_settings() noexcept;
+
+ private:
+ std::string name_; ///<
+ QPoint pos_; ///<
+ QSize size_; ///<
+};
+} // namespace GpgFrontend::UI
+
+#endif // GPGFRONTEND_GENERALMAINWINDOW_H
diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp
new file mode 100644
index 00000000..6dc2b14f
--- /dev/null
+++ b/src/ui/main_window/KeyMgmt.cpp
@@ -0,0 +1,462 @@
+/**
+ * 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 "KeyMgmt.h"
+
+#include <utility>
+
+#include "core/function/GlobalSettingStation.h"
+#include "core/function/KeyPackageOperator.h"
+#include "core/function/gpg/GpgKeyGetter.h"
+#include "core/function/gpg/GpgKeyImportExporter.h"
+#include "core/function/gpg/GpgKeyOpera.h"
+#include "ui/SignalStation.h"
+#include "ui/UserInterfaceUtils.h"
+#include "ui/dialog/import_export/ExportKeyPackageDialog.h"
+#include "ui/dialog/key_generate/SubkeyGenerateDialog.h"
+#include "ui/main_window/MainWindow.h"
+
+namespace GpgFrontend::UI {
+
+KeyMgmt::KeyMgmt(QWidget* parent)
+ : GeneralMainWindow("key_management", parent) {
+ /* the list of Keys available*/
+ key_list_ = new KeyList(KeyMenuAbility::ALL, this);
+
+ key_list_->AddListGroupTab(_("All"), KeyListRow::SECRET_OR_PUBLIC_KEY);
+
+ key_list_->AddListGroupTab(
+ _("Only Public Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ [](const GpgKey& key) -> bool {
+ return !key.IsPrivateKey() &&
+ !(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
+ });
+
+ key_list_->AddListGroupTab(
+ _("Has Private Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ [](const GpgKey& key) -> bool {
+ return key.IsPrivateKey() &&
+ !(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
+ });
+
+ key_list_->AddListGroupTab(
+ _("No Primary Key"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ [](const GpgKey& key) -> bool {
+ return !key.IsHasMasterKey() &&
+ !(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
+ });
+
+ key_list_->AddListGroupTab(
+ _("Revoked"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ [](const GpgKey& key) -> bool { return key.IsRevoked(); });
+
+ key_list_->AddListGroupTab(
+ _("Expired"), KeyListRow::SECRET_OR_PUBLIC_KEY,
+ KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
+ KeyListColumn::Usage | KeyListColumn::Validity,
+ [](const GpgKey& key) -> bool { return key.IsExpired(); });
+
+ setCentralWidget(key_list_);
+ key_list_->SetDoubleClickedAction([this](const GpgKey& key, QWidget* parent) {
+ new KeyDetailsDialog(key, parent);
+ });
+
+ key_list_->SlotRefresh();
+
+ create_actions();
+ create_menus();
+ create_tool_bars();
+
+ connect(this, &KeyMgmt::SignalStatusBarChanged,
+ qobject_cast<MainWindow*>(this->parent()),
+ &MainWindow::SlotSetStatusBarText);
+
+ auto& settings = GlobalSettingStation::GetInstance().GetUISettings();
+
+ this->statusBar()->show();
+
+ setWindowTitle(_("KeyPair Management"));
+ key_list_->AddMenuAction(delete_selected_keys_act_);
+ key_list_->AddMenuAction(show_key_details_act_);
+
+ connect(this, &KeyMgmt::SignalKeyStatusUpdated, SignalStation::GetInstance(),
+ &SignalStation::SignalKeyDatabaseRefresh);
+ connect(SignalStation::GetInstance(), &SignalStation::SignalRefreshStatusBar,
+ this, [=](const QString& message, int timeout) {
+ statusBar()->showMessage(message, timeout);
+ });
+}
+
+void KeyMgmt::create_actions() {
+ open_key_file_act_ = new QAction(_("Open"), this);
+ open_key_file_act_->setShortcut(QKeySequence(_("Ctrl+O")));
+ open_key_file_act_->setToolTip(_("Open Key File"));
+ connect(open_key_file_act_, &QAction::triggered, this,
+ [&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); });
+
+ close_act_ = new QAction(_("Close"), this);
+ close_act_->setShortcut(QKeySequence(_("Ctrl+Q")));
+ close_act_->setIcon(QIcon(":exit.png"));
+ close_act_->setToolTip(_("Close"));
+ connect(close_act_, &QAction::triggered, this, &KeyMgmt::close);
+
+ generate_key_pair_act_ = new QAction(_("New Keypair"), this);
+ generate_key_pair_act_->setShortcut(QKeySequence(_("Ctrl+N")));
+ generate_key_pair_act_->setIcon(QIcon(":key_generate.png"));
+ generate_key_pair_act_->setToolTip(_("Generate KeyPair"));
+ connect(generate_key_pair_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotGenerateKeyDialog);
+
+ generate_subkey_act_ = new QAction(_("New Subkey"), this);
+ generate_subkey_act_->setShortcut(QKeySequence(_("Ctrl+Shift+N")));
+ generate_subkey_act_->setIcon(QIcon(":key_generate.png"));
+ generate_subkey_act_->setToolTip(_("Generate Subkey For Selected KeyPair"));
+ connect(generate_subkey_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotGenerateSubKey);
+
+ import_key_from_file_act_ = new QAction(_("File"), this);
+ import_key_from_file_act_->setIcon(QIcon(":import_key_from_file.png"));
+ import_key_from_file_act_->setToolTip(_("Import New Key From File"));
+ connect(import_key_from_file_act_, &QAction::triggered, this,
+ [&]() { CommonUtils::GetInstance()->SlotImportKeyFromFile(this); });
+
+ import_key_from_clipboard_act_ = new QAction(_("Clipboard"), this);
+ import_key_from_clipboard_act_->setIcon(
+ QIcon(":import_key_from_clipboard.png"));
+ import_key_from_clipboard_act_->setToolTip(
+ _("Import New Key From Clipboard"));
+ connect(import_key_from_clipboard_act_, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->SlotImportKeyFromClipboard(this);
+ });
+
+ import_key_from_key_server_act_ = new QAction(_("Keyserver"), this);
+ import_key_from_key_server_act_->setIcon(
+ QIcon(":import_key_from_server.png"));
+ import_key_from_key_server_act_->setToolTip(
+ _("Import New Key From Keyserver"));
+ connect(import_key_from_key_server_act_, &QAction::triggered, this, [&]() {
+ CommonUtils::GetInstance()->SlotImportKeyFromKeyServer(this);
+ });
+
+ import_keys_from_key_package_act_ = new QAction(_("Key Package"), this);
+ import_keys_from_key_package_act_->setIcon(QIcon(":key_package.png"));
+ import_keys_from_key_package_act_->setToolTip(
+ _("Import Key(s) From a Key Package"));
+ connect(import_keys_from_key_package_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotImportKeyPackage);
+
+ export_key_to_clipboard_act_ = new QAction(_("Export To Clipboard"), this);
+ export_key_to_clipboard_act_->setIcon(QIcon(":export_key_to_clipboard.png"));
+ export_key_to_clipboard_act_->setToolTip(
+ _("Export Selected Key(s) To Clipboard"));
+ connect(export_key_to_clipboard_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotExportKeyToClipboard);
+
+ export_key_to_file_act_ = new QAction(_("Export To Key Package"), this);
+ export_key_to_file_act_->setIcon(QIcon(":key_package.png"));
+ export_key_to_file_act_->setToolTip(
+ _("Export Checked Key(s) To a Key Package"));
+ connect(export_key_to_file_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotExportKeyToKeyPackage);
+
+ export_key_as_open_ssh_format_ = new QAction(_("Export As OpenSSH"), this);
+ export_key_as_open_ssh_format_->setIcon(QIcon(":ssh-key.png"));
+ export_key_as_open_ssh_format_->setToolTip(
+ _("Export Selected Key(s) As OpenSSH Format to File"));
+ connect(export_key_as_open_ssh_format_, &QAction::triggered, this,
+ &KeyMgmt::SlotExportAsOpenSSHFormat);
+
+ delete_selected_keys_act_ = new QAction(_("Delete Selected Key(s)"), this);
+ delete_selected_keys_act_->setToolTip(_("Delete the Selected keys"));
+ connect(delete_selected_keys_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotDeleteSelectedKeys);
+
+ delete_checked_keys_act_ = new QAction(_("Delete Checked Key(s)"), this);
+ delete_checked_keys_act_->setToolTip(_("Delete the Checked keys"));
+ delete_checked_keys_act_->setIcon(QIcon(":button_delete.png"));
+ connect(delete_checked_keys_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotDeleteCheckedKeys);
+
+ show_key_details_act_ = new QAction(_("Show Key Details"), this);
+ show_key_details_act_->setToolTip(_("Show Details for this Key"));
+ connect(show_key_details_act_, &QAction::triggered, this,
+ &KeyMgmt::SlotShowKeyDetails);
+}
+
+void KeyMgmt::create_menus() {
+ file_menu_ = menuBar()->addMenu(_("File"));
+ file_menu_->addAction(open_key_file_act_);
+ file_menu_->addAction(close_act_);
+
+ key_menu_ = menuBar()->addMenu(_("Key"));
+ generate_key_menu_ = key_menu_->addMenu(_("Generate Key"));
+ generate_key_menu_->addAction(generate_key_pair_act_);
+ generate_key_menu_->addAction(generate_subkey_act_);
+
+ import_key_menu_ = key_menu_->addMenu(_("Import Key"));
+ import_key_menu_->addAction(import_key_from_file_act_);
+ import_key_menu_->addAction(import_key_from_clipboard_act_);
+ import_key_menu_->addAction(import_key_from_key_server_act_);
+ import_key_menu_->addAction(import_keys_from_key_package_act_);
+
+ key_menu_->addAction(export_key_to_file_act_);
+ key_menu_->addAction(export_key_to_clipboard_act_);
+ key_menu_->addAction(export_key_as_open_ssh_format_);
+ key_menu_->addSeparator();
+ key_menu_->addAction(delete_checked_keys_act_);
+}
+
+void KeyMgmt::create_tool_bars() {
+ QToolBar* keyToolBar = addToolBar(_("Key"));
+ keyToolBar->setObjectName("keytoolbar");
+
+ // add button with popup menu for import
+ auto* generateToolButton = new QToolButton(this);
+ generateToolButton->setMenu(generate_key_menu_);
+ generateToolButton->setPopupMode(QToolButton::InstantPopup);
+ generateToolButton->setIcon(QIcon(":key_generate.png"));
+ generateToolButton->setText(_("Generate"));
+ generateToolButton->setToolTip(_("Generate A New Keypair or Subkey"));
+ generateToolButton->setToolButtonStyle(icon_style_);
+ keyToolBar->addWidget(generateToolButton);
+
+ // add button with popup menu for import
+ auto* toolButton = new QToolButton(this);
+ toolButton->setMenu(import_key_menu_);
+ toolButton->setPopupMode(QToolButton::InstantPopup);
+ toolButton->setIcon(QIcon(":key_import.png"));
+ toolButton->setToolTip(_("Import key"));
+ toolButton->setText(_("Import Key"));
+ toolButton->setToolButtonStyle(icon_style_);
+ keyToolBar->addWidget(toolButton);
+
+ keyToolBar->addSeparator();
+ keyToolBar->addAction(delete_checked_keys_act_);
+ keyToolBar->addSeparator();
+ keyToolBar->addAction(export_key_to_file_act_);
+ keyToolBar->addAction(export_key_to_clipboard_act_);
+ keyToolBar->addAction(export_key_as_open_ssh_format_);
+}
+
+void KeyMgmt::SlotDeleteSelectedKeys() {
+ delete_keys_with_warning(key_list_->GetSelected());
+}
+
+void KeyMgmt::SlotDeleteCheckedKeys() {
+ delete_keys_with_warning(key_list_->GetChecked());
+}
+
+void KeyMgmt::delete_keys_with_warning(KeyIdArgsListPtr uidList) {
+ /**
+ * TODO: Different Messages for private/public key, check if
+ * more than one selected... compare to seahorse "delete-dialog"
+ */
+
+ if (uidList->empty()) return;
+ QString keynames;
+ for (const auto& key_id : *uidList) {
+ auto key = GpgKeyGetter::GetInstance().GetKey(key_id);
+ if (!key.IsGood()) continue;
+ keynames.append(QString::fromStdString(key.GetName()));
+ keynames.append("<i> &lt;");
+ keynames.append(QString::fromStdString(key.GetEmail()));
+ keynames.append("&gt; </i><br/>");
+ }
+
+ int ret = QMessageBox::warning(
+ this, _("Deleting Keys"),
+ "<b>" +
+ QString(
+ _("Are you sure that you want to delete the following keys?")) +
+ "</b><br/><br/>" + keynames + +"<br/>" +
+ _("The action can not be undone."),
+ QMessageBox::No | QMessageBox::Yes);
+
+ if (ret == QMessageBox::Yes) {
+ GpgKeyOpera::GetInstance().DeleteKeys(std::move(uidList));
+ emit SignalKeyStatusUpdated();
+ }
+}
+
+void KeyMgmt::SlotShowKeyDetails() {
+ auto keys_selected = key_list_->GetSelected();
+ if (keys_selected->empty()) return;
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
+
+ if (!key.IsGood()) {
+ QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ return;
+ }
+
+ new KeyDetailsDialog(key);
+}
+
+void KeyMgmt::SlotExportKeyToKeyPackage() {
+ auto keys_checked = key_list_->GetChecked();
+ if (keys_checked->empty()) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("Please check some keys before doing this operation."));
+ return;
+ }
+ auto dialog = new ExportKeyPackageDialog(std::move(keys_checked), this);
+ dialog->exec();
+ emit SignalStatusBarChanged(QString(_("key(s) exported")));
+}
+
+void KeyMgmt::SlotExportKeyToClipboard() {
+ auto keys_checked = key_list_->GetChecked();
+ if (keys_checked->empty()) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("Please check some keys before doing this operation."));
+ return;
+ }
+
+ ByteArrayPtr key_export_data = nullptr;
+ if (!GpgKeyImportExporter::GetInstance().ExportKeys(keys_checked,
+ key_export_data)) {
+ return;
+ }
+ QApplication::clipboard()->setText(QString::fromStdString(*key_export_data));
+}
+
+void KeyMgmt::SlotGenerateKeyDialog() {
+ auto* keyGenDialog = new KeyGenDialog(this);
+ keyGenDialog->show();
+}
+
+void KeyMgmt::SlotGenerateSubKey() {
+ auto keys_selected = key_list_->GetSelected();
+ if (keys_selected->empty()) {
+ QMessageBox::information(
+ this, _("Invalid Operation"),
+ _("Please select one KeyPair before doing this operation."));
+ return;
+ }
+ const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front());
+ if (!key.IsGood()) {
+ QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ return;
+ }
+ if (!key.IsPrivateKey()) {
+ QMessageBox::critical(this, _("Invalid Operation"),
+ _("If a key pair does not have a private key then "
+ "it will not be able to generate sub-keys."));
+ return;
+ }
+
+ auto dialog = new SubkeyGenerateDialog(key.GetId(), this);
+ dialog->show();
+}
+
+void KeyMgmt::SlotExportAsOpenSSHFormat() {
+ ByteArrayPtr key_export_data = nullptr;
+ auto keys_checked = key_list_->GetChecked();
+
+ if (keys_checked->empty()) {
+ QMessageBox::critical(
+ this, _("Forbidden"),
+ _("Please select a key before performing this operation. If you select "
+ "multiple keys, only the first key will be exported."));
+ return;
+ }
+
+ auto key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front());
+ if (!GpgKeyImportExporter::GetInstance().ExportKeyOpenSSH(key,
+ key_export_data)) {
+ QMessageBox::critical(this, _("Error"), _("An error occur in exporting."));
+ return;
+ }
+
+ if (key_export_data->empty()) {
+ QMessageBox::critical(
+ this, _("Error"),
+ _("This key may not be able to export as OpenSSH format. Please check "
+ "the key-size of the subkey(s) used to sign."));
+ return;
+ }
+
+ key = GpgKeyGetter::GetInstance().GetKey(keys_checked->front());
+ if (!key.IsGood()) {
+ QMessageBox::critical(this, _("Error"), _("Key Not Found."));
+ return;
+ }
+ QString fileString = QString::fromStdString(
+ key.GetName() + " " + key.GetEmail() + "(" + key.GetId() + ").pub");
+
+ QString file_name = QFileDialog::getSaveFileName(
+ this, _("Export OpenSSH Key To File"), fileString,
+ QString(_("OpenSSH Public Key Files")) + " (*.pub);;All Files (*)");
+
+ if (!file_name.isEmpty()) {
+ write_buffer_to_file(file_name.toStdString(), *key_export_data);
+ emit SignalStatusBarChanged(QString(_("key(s) exported")));
+ }
+}
+
+void KeyMgmt::SlotImportKeyPackage() {
+ LOG(INFO) << "Importing key package...";
+
+ auto key_package_file_name = QFileDialog::getOpenFileName(
+ this, _("Import Key Package"), {},
+ QString(_("Key Package")) + " (*.gfepack);;All Files (*)");
+
+ auto key_file_name = QFileDialog::getOpenFileName(
+ this, _("Import Key Package Passphrase File"), {},
+ QString(_("Key Package Passphrase File")) + " (*.key);;All Files (*)");
+
+ if (key_package_file_name.isEmpty() || key_file_name.isEmpty()) return;
+
+ GpgImportInformation info;
+
+ LOG(INFO) << "Importing key package: " << key_package_file_name.toStdString();
+
+ if (KeyPackageOperator::ImportKeyPackage(key_package_file_name.toStdString(),
+ key_file_name.toStdString(), info)) {
+ emit SignalStatusBarChanged(QString(_("key(s) imported")));
+ emit SignalKeyStatusUpdated();
+
+ auto dialog = new KeyImportDetailDialog(info, false, this);
+ dialog->exec();
+ } else {
+ QMessageBox::critical(this, _("Error"),
+ _("An error occur in importing key package."));
+ }
+}
+
+} // namespace GpgFrontend::UI
diff --git a/src/ui/main_window/KeyMgmt.h b/src/ui/main_window/KeyMgmt.h
new file mode 100644
index 00000000..2073113a
--- /dev/null
+++ b/src/ui/main_window/KeyMgmt.h
@@ -0,0 +1,178 @@
+/**
+ * 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 __KEYMGMT_H__
+#define __KEYMGMT_H__
+
+#include "ui/GpgFrontendUI.h"
+#include "ui/dialog/import_export/KeyImportDetailDialog.h"
+#include "ui/dialog/import_export/KeyServerImportDialog.h"
+#include "ui/dialog/key_generate/KeygenDialog.h"
+#include "ui/dialog/keypair_details/KeyDetailsDialog.h"
+#include "ui/main_window/GeneralMainWindow.h"
+#include "ui/widgets/KeyList.h"
+
+namespace GpgFrontend::UI {
+
+/**
+ * @brief
+ *
+ */
+class KeyMgmt : public GeneralMainWindow {
+ Q_OBJECT
+
+ public:
+ /**
+ * @brief Construct a new Key Mgmt object
+ *
+ * @param parent
+ */
+ explicit KeyMgmt(QWidget* parent = nullptr);
+
+ public slots:
+
+ /**
+ * @brief
+ *
+ */
+ void SlotGenerateSubKey();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotExportKeyToKeyPackage();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotExportKeyToClipboard();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotExportAsOpenSSHFormat();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotDeleteSelectedKeys();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotDeleteCheckedKeys();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotGenerateKeyDialog();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotShowKeyDetails();
+
+ /**
+ * @brief
+ *
+ */
+ void SlotImportKeyPackage();
+
+ signals:
+
+ /**
+ * @brief
+ *
+ */
+ void SignalStatusBarChanged(QString);
+
+ /**
+ * @brief
+ *
+ */
+ void SignalKeyStatusUpdated();
+
+ private:
+ /**
+ * @brief Create a menus object
+ *
+ */
+ void create_menus();
+
+ /**
+ * @brief Create a actions object
+ *
+ */
+ void create_actions();
+
+ /**
+ * @brief Create a tool bars object
+ *
+ */
+ void create_tool_bars();
+
+ /**
+ * @brief
+ *
+ * @param uidList
+ */
+ void delete_keys_with_warning(GpgFrontend::KeyIdArgsListPtr uidList);
+
+ KeyList* key_list_; ///<
+ QMenu* file_menu_{}; ///<
+ QMenu* key_menu_{}; ///<
+ QMenu* generate_key_menu_{}; ///<
+ QMenu* import_key_menu_{}; ///<
+ QAction* open_key_file_act_{}; ///<
+ QAction* export_key_to_file_act_{}; ///<
+ QAction* export_key_as_open_ssh_format_{}; ///<
+ QAction* export_key_to_clipboard_act_{}; ///<
+ QAction* delete_checked_keys_act_{}; ///<
+ QAction* delete_selected_keys_act_{}; ///<
+ QAction* generate_key_dialog_act_{}; ///<
+ QAction* generate_key_pair_act_{}; ///<
+ QAction* generate_subkey_act_{}; ///<
+ QAction* import_key_from_clipboard_act_{}; ///<
+ QAction* import_key_from_file_act_{}; ///<
+ QAction* import_key_from_key_server_act_{}; ///<
+ QAction* import_keys_from_key_package_act_{}; ///<
+ QAction* close_act_{}; ///<
+ QAction* show_key_details_act_{}; ///<
+ KeyServerImportDialog* import_dialog_{}; ///<
+};
+
+} // namespace GpgFrontend::UI
+
+#endif // __KEYMGMT_H__
diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp
index d04e3dbd..e3e4c0ab 100644
--- a/src/ui/main_window/MainWindow.cpp
+++ b/src/ui/main_window/MainWindow.cpp
@@ -36,7 +36,7 @@
namespace GpgFrontend::UI {
-MainWindow::MainWindow() {
+MainWindow::MainWindow() : GeneralMainWindow("main_window") {
this->setMinimumSize(1200, 700);
this->setWindowTitle(qApp->applicationName());
}
@@ -135,63 +135,14 @@ void MainWindow::restore_settings() {
LOG(INFO) << _("Called");
try {
- LOG(INFO) << "restore settings main_windows_state";
-
- SettingsObject main_windows_state("main_windows_state");
-
- std::string window_state = main_windows_state.Check(
- "window_state", saveState().toBase64().toStdString());
- // state sets pos & size of dock-widgets
- this->restoreState(
- QByteArray::fromBase64(QByteArray::fromStdString(window_state)));
-
- bool window_save = main_windows_state.Check("window_save", true);
-
- // Restore window size & location
- if (window_save) {
- int x = main_windows_state.Check("window_pos").Check("x", 100),
- y = main_windows_state.Check("window_pos").Check("y", 100);
-
- auto pos = QPoint(x, y);
-
- int width = main_windows_state.Check("window_size").Check("width", 800),
- height = main_windows_state.Check("window_size").Check("height", 450);
-
- auto size = QSize(width, height);
- this->resize(size);
- this->move(pos);
- } else {
- this->resize(QSize(800, 450));
- this->move(QPoint(100, 100));
- }
-
- int width = main_windows_state.Check("icon_size").Check("width", 24),
- height = main_windows_state.Check("icon_size").Check("height", 24);
- LOG(INFO) << "icon_size" << width << height;
-
- main_windows_state.Check("info_font_size", 10);
-
- // icon_style
- int s_icon_style =
- main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
- auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
- this->setToolButtonStyle(icon_style);
- import_button_->setToolButtonStyle(icon_style);
-
- // icons ize
- this->setIconSize(QSize(width, height));
- import_button_->setIconSize(QSize(width, height));
-
LOG(INFO) << "restore settings key_server";
SettingsObject key_server_json("key_server");
-
- if (!key_server_json.contains("server_list")) {
+ if (!key_server_json.contains("server_list") ||
+ key_server_json["server_list"].empty()) {
key_server_json["server_list"] = {"https://keyserver.ubuntu.com",
- "http://keys.gnupg.net",
- "http://pool.sks-keyservers.net"};
+ "https://keys.openpgp.org"};
}
-
if (!key_server_json.contains("default_server")) {
key_server_json["default_server"] = 0;
}
@@ -216,6 +167,9 @@ void MainWindow::restore_settings() {
bool save_key_checked = true;
general.lookupValue("save_key_checked", save_key_checked);
+ // set appearance
+ import_button_->setToolButtonStyle(icon_style_);
+
try {
LOG(INFO) << "restore settings default_key_checked";
@@ -255,16 +209,6 @@ void MainWindow::save_settings() {
auto &settings = GlobalSettingStation::GetInstance().GetUISettings();
try {
- SettingsObject main_windows_state("main_windows_state");
-
- // window position and size
- main_windows_state["window_state"] = saveState().toBase64().toStdString();
- main_windows_state["window_pos"]["x"] = pos().x();
- main_windows_state["window_pos"]["y"] = pos().y();
-
- main_windows_state["window_size"]["width"] = size().width();
- main_windows_state["window_size"]["height"] = size().height();
-
bool save_key_checked = settings.lookup("general.save_key_checked");
// keyid-list of private checked keys
diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h
index a0f1a5d4..b31e2fcb 100644
--- a/src/ui/main_window/MainWindow.h
+++ b/src/ui/main_window/MainWindow.h
@@ -29,17 +29,18 @@
#ifndef __GPGWIN_H__
#define __GPGWIN_H__
+#include "KeyMgmt.h"
#include "core/GpgConstants.h"
#include "core/function/result_analyse/GpgDecryptResultAnalyse.h"
#include "core/function/result_analyse/GpgEncryptResultAnalyse.h"
#include "core/function/result_analyse/GpgSignResultAnalyse.h"
#include "ui/GpgFrontendUI.h"
-#include "ui/KeyMgmt.h"
#include "ui/dialog/WaitingDialog.h"
#include "ui/dialog/Wizard.h"
-#include "ui/help/AboutDialog.h"
-#include "ui/import_export/KeyUploadDialog.h"
-#include "ui/settings/SettingsDialog.h"
+#include "ui/dialog/help/AboutDialog.h"
+#include "ui/dialog/import_export/KeyUploadDialog.h"
+#include "ui/dialog/settings/SettingsDialog.h"
+#include "ui/main_window/GeneralMainWindow.h"
#include "ui/widgets/FindWidget.h"
#include "ui/widgets/InfoBoardWidget.h"
#include "ui/widgets/TextEdit.h"
@@ -49,10 +50,13 @@ namespace GpgFrontend::UI {
* @brief
*
*/
-class MainWindow : public QMainWindow {
+class MainWindow : public GeneralMainWindow {
Q_OBJECT
public:
+ /**
+ *
+ */
struct CryptoMenu {
using OperationType = unsigned int;
@@ -383,6 +387,7 @@ class MainWindow : public QMainWindow {
QAction* about_act_{}; ///< Action to open about dialog
QAction* check_update_act_{}; ///< Action to open about dialog
QAction* translate_act_{}; ///< Action to open about dialog
+ QAction* gnupg_act_{}; ///< Action to open about dialog
QAction* open_settings_act_{}; ///< Action to open settings dialog
QAction* show_key_details_act_{}; ///< Action to open key-details dialog
QAction* start_wizard_act_{}; ///< Action to open the wizard
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index 4ab23a22..526c27c0 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -32,8 +32,8 @@
#include "core/function/gpg/GpgFileOpera.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/thread/Task.h"
+#include "dialog/SignersPicker.h"
#include "ui/UserInterfaceUtils.h"
-#include "ui/widgets/SignersPicker.h"
namespace GpgFrontend::UI {
@@ -618,6 +618,9 @@ void MainWindow::SlotFileEncryptSign() {
connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit);
loop.exec();
+ // return when canceled
+ if (!signersPicker->GetStatus()) return;
+
auto signer_key_ids = signersPicker->GetCheckedSigners();
auto p_signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp
index 0ad52248..f715046c 100644
--- a/src/ui/main_window/MainWindowSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowSlotFunction.cpp
@@ -26,7 +26,6 @@
*
*/
-#include <cstddef>
#include <memory>
#include <string>
#include <utility>
@@ -34,15 +33,12 @@
#include "MainWindow.h"
#include "core/GpgConstants.h"
#include "core/GpgModel.h"
-#include "core/function/GlobalSettingStation.h"
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/function/gpg/GpgKeyGetter.h"
#include "core/function/gpg/GpgKeyImportExporter.h"
-#include "core/model/GpgKey.h"
-#include "core/thread/TaskRunner.h"
#include "ui/UserInterfaceUtils.h"
-#include "ui/help/AboutDialog.h"
-#include "ui/widgets/SignersPicker.h"
+#include "ui/dialog/help/AboutDialog.h"
+#include "dialog/SignersPicker.h"
namespace GpgFrontend::UI {
/**
@@ -427,6 +423,9 @@ void MainWindow::slot_encrypt_sign() {
connect(signersPicker, &SignersPicker::finished, &loop, &QEventLoop::quit);
loop.exec();
+ // return when canceled
+ if (!signersPicker->GetStatus()) return;
+
auto signer_key_ids = signersPicker->GetCheckedSigners();
auto signer_keys = GpgKeyGetter::GetInstance().GetKeys(signer_key_ids);
diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp
index 9d81b11c..9061349e 100644
--- a/src/ui/main_window/MainWindowSlotUI.cpp
+++ b/src/ui/main_window/MainWindowSlotUI.cpp
@@ -105,17 +105,17 @@ void MainWindow::slot_open_settings_dialog() {
connect(dialog, &SettingsDialog::finished, this, [&]() -> void {
LOG(INFO) << "Setting Dialog Finished";
- SettingsObject main_windows_state("main_windows_state");
+ SettingsObject general_settings_state("general_settings_state");
- int width = main_windows_state.Check("icon_size").Check("width", 24),
- height = main_windows_state.Check("icon_size").Check("height", 24);
+ int width = general_settings_state.Check("icon_size").Check("width", 24),
+ height = general_settings_state.Check("icon_size").Check("height", 24);
LOG(INFO) << "icon_size" << width << height;
- main_windows_state.Check("info_font_size", 10);
+ general_settings_state.Check("info_font_size", 10);
// icon_style
int s_icon_style =
- main_windows_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
+ general_settings_state.Check("icon_style", Qt::ToolButtonTextUnderIcon);
auto icon_style = static_cast<Qt::ToolButtonStyle>(s_icon_style);
this->setToolButtonStyle(icon_style);
import_button_->setToolButtonStyle(icon_style);
diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp
index 7d798c8b..1470b731 100644
--- a/src/ui/main_window/MainWindowUI.cpp
+++ b/src/ui/main_window/MainWindowUI.cpp
@@ -251,11 +251,17 @@ void MainWindow::create_actions() {
connect(about_act_, &QAction::triggered, this,
[=]() { new AboutDialog(0, this); });
+ gnupg_act_ = new QAction(_("GnuPG"), this);
+ gnupg_act_->setIcon(QIcon(":help.png"));
+ gnupg_act_->setToolTip(_("Information about Gnupg"));
+ connect(gnupg_act_, &QAction::triggered, this,
+ [=]() { new AboutDialog(1, this); });
+
translate_act_ = new QAction(_("Translate"), this);
translate_act_->setIcon(QIcon(":help.png"));
translate_act_->setToolTip(_("Information about translation"));
connect(translate_act_, &QAction::triggered, this,
- [=]() { new AboutDialog(1, this); });
+ [=]() { new AboutDialog(2, this); });
/*
* Check Update Menu
@@ -377,6 +383,7 @@ void MainWindow::create_menus() {
help_menu_->addSeparator();
help_menu_->addAction(check_update_act_);
help_menu_->addAction(translate_act_);
+ help_menu_->addAction(gnupg_act_);
help_menu_->addAction(about_act_);
}