/**
* 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 .
*
* 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 starting on May 12, 2021.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "MainWindow.h"
#include "ui/UserInterfaceUtils.h"
namespace GpgFrontend::UI {
void MainWindow::create_actions() {
/* Main Menu
*/
new_tab_act_ = new QAction(_("New"), this);
new_tab_act_->setIcon(QIcon(":misc_doc.png"));
QList newTabActShortcutList;
newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N));
newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T));
new_tab_act_->setShortcuts(newTabActShortcutList);
new_tab_act_->setToolTip(_("Open a new file"));
connect(new_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotNewTab);
open_act_ = new QAction(_("Open..."), this);
open_act_->setIcon(QIcon(":fileopen.png"));
open_act_->setShortcut(QKeySequence::Open);
open_act_->setToolTip(_("Open an existing file"));
connect(open_act_, &QAction::triggered, edit_, &TextEdit::SlotOpen);
browser_act_ = new QAction(_("File Browser"), this);
browser_act_->setIcon(QIcon(":file-browser.png"));
browser_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
browser_act_->setToolTip(_("Open a file browser"));
connect(browser_act_, &QAction::triggered, this,
&MainWindow::slot_open_file_tab);
save_act_ = new QAction(_("Save File"), this);
save_act_->setIcon(QIcon(":filesave.png"));
save_act_->setShortcut(QKeySequence::Save);
save_act_->setToolTip(_("Save the current File"));
connect(save_act_, &QAction::triggered, edit_, &TextEdit::SlotSave);
save_as_act_ = new QAction(QString(_("Save As")) + "...", this);
save_as_act_->setIcon(QIcon(":filesaveas.png"));
save_as_act_->setShortcut(QKeySequence::SaveAs);
save_as_act_->setToolTip(_("Save the current File as..."));
connect(save_as_act_, &QAction::triggered, edit_, &TextEdit::SlotSaveAs);
print_act_ = new QAction(_("Print"), this);
print_act_->setIcon(QIcon(":fileprint.png"));
print_act_->setShortcut(QKeySequence::Print);
print_act_->setToolTip(_("Print Document"));
connect(print_act_, &QAction::triggered, edit_, &TextEdit::SlotPrint);
close_tab_act_ = new QAction(_("Close"), this);
close_tab_act_->setShortcut(QKeySequence::Close);
close_tab_act_->setToolTip(_("Close file"));
connect(close_tab_act_, &QAction::triggered, edit_, &TextEdit::SlotCloseTab);
quit_act_ = new QAction(_("Quit"), this);
quit_act_->setShortcut(QKeySequence::Quit);
quit_act_->setIcon(QIcon(":exit.png"));
quit_act_->setToolTip(_("Quit Program"));
connect(quit_act_, &QAction::triggered, this, &MainWindow::close);
/* Edit Menu
*/
undo_act_ = new QAction(_("Undo"), this);
undo_act_->setShortcut(QKeySequence::Undo);
undo_act_->setToolTip(_("Undo Last Edit Action"));
connect(undo_act_, &QAction::triggered, edit_, &TextEdit::SlotUndo);
redo_act_ = new QAction(_("Redo"), this);
redo_act_->setShortcut(QKeySequence::Redo);
redo_act_->setToolTip(_("Redo Last Edit Action"));
connect(redo_act_, &QAction::triggered, edit_, &TextEdit::SlotRedo);
zoom_in_act_ = new QAction(_("Zoom In"), this);
zoom_in_act_->setShortcut(QKeySequence::ZoomIn);
connect(zoom_in_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomIn);
zoom_out_act_ = new QAction(_("Zoom Out"), this);
zoom_out_act_->setShortcut(QKeySequence::ZoomOut);
connect(zoom_out_act_, &QAction::triggered, edit_, &TextEdit::SlotZoomOut);
paste_act_ = new QAction(_("Paste"), this);
paste_act_->setIcon(QIcon(":button_paste.png"));
paste_act_->setShortcut(QKeySequence::Paste);
paste_act_->setToolTip(_("Paste Text From Clipboard"));
connect(paste_act_, &QAction::triggered, edit_, &TextEdit::SlotPaste);
cut_act_ = new QAction(_("Cut"), this);
cut_act_->setIcon(QIcon(":button_cut.png"));
cut_act_->setShortcut(QKeySequence::Cut);
cut_act_->setToolTip(
_("Cut the current selection's contents to the "
"clipboard"));
connect(cut_act_, &QAction::triggered, edit_, &TextEdit::SlotCut);
copy_act_ = new QAction(_("Copy"), this);
copy_act_->setIcon(QIcon(":button_copy.png"));
copy_act_->setShortcut(QKeySequence::Copy);
copy_act_->setToolTip(
_("Copy the current selection's contents to the "
"clipboard"));
connect(copy_act_, &QAction::triggered, edit_, &TextEdit::SlotCopy);
quote_act_ = new QAction(_("Quote"), this);
quote_act_->setIcon(QIcon(":quote.png"));
quote_act_->setToolTip(_("Quote whole text"));
connect(quote_act_, &QAction::triggered, edit_, &TextEdit::SlotQuote);
select_all_act_ = new QAction(_("Select All"), this);
select_all_act_->setIcon(QIcon(":edit.png"));
select_all_act_->setShortcut(QKeySequence::SelectAll);
select_all_act_->setToolTip(_("Select the whole text"));
connect(select_all_act_, &QAction::triggered, edit_,
&TextEdit::SlotSelectAll);
find_act_ = new QAction(_("Find"), this);
find_act_->setShortcut(QKeySequence::Find);
find_act_->setToolTip(_("Find a word"));
connect(find_act_, &QAction::triggered, this, &MainWindow::slot_find);
clean_double_line_breaks_act_ = new QAction(_("Remove spacing"), this);
clean_double_line_breaks_act_->setIcon(
QIcon(":format-line-spacing-triple.png"));
// cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll);
clean_double_line_breaks_act_->setToolTip(
_("Remove double linebreaks, e.g. in pasted text from Web Mailer"));
connect(clean_double_line_breaks_act_, &QAction::triggered, this,
&MainWindow::slot_clean_double_line_breaks);
open_settings_act_ = new QAction(_("Settings"), this);
open_settings_act_->setToolTip(_("Open settings dialog"));
open_settings_act_->setMenuRole(QAction::PreferencesRole);
open_settings_act_->setShortcut(QKeySequence::Preferences);
connect(open_settings_act_, &QAction::triggered, this,
&MainWindow::slot_open_settings_dialog);
/* Crypt Menu
*/
encrypt_act_ = new QAction(_("Encrypt"), this);
encrypt_act_->setIcon(QIcon(":encrypted.png"));
encrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
encrypt_act_->setToolTip(_("Encrypt Message"));
connect(encrypt_act_, &QAction::triggered, this, &MainWindow::slot_encrypt);
encrypt_sign_act_ = new QAction(_("Encrypt Sign"), this);
encrypt_sign_act_->setIcon(QIcon(":encrypted_signed.png"));
encrypt_sign_act_->setShortcut(
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E));
encrypt_sign_act_->setToolTip(_("Encrypt and Sign Message"));
connect(encrypt_sign_act_, &QAction::triggered, this,
&MainWindow::slot_encrypt_sign);
decrypt_act_ = new QAction(_("Decrypt"), this);
decrypt_act_->setIcon(QIcon(":decrypted.png"));
decrypt_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
decrypt_act_->setToolTip(_("Decrypt Message"));
connect(decrypt_act_, &QAction::triggered, this, &MainWindow::slot_decrypt);
decrypt_verify_act_ = new QAction(_("Decrypt Verify"), this);
decrypt_verify_act_->setIcon(QIcon(":decrypted_verified.png"));
decrypt_verify_act_->setShortcut(
QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D));
decrypt_verify_act_->setToolTip(_("Decrypt and Verify Message"));
connect(decrypt_verify_act_, &QAction::triggered, this,
&MainWindow::slot_decrypt_verify);
sign_act_ = new QAction(_("Sign"), this);
sign_act_->setIcon(QIcon(":signature.png"));
sign_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
sign_act_->setToolTip(_("Sign Message"));
connect(sign_act_, &QAction::triggered, this, &MainWindow::slot_sign);
verify_act_ = new QAction(_("Verify"), this);
verify_act_->setIcon(QIcon(":verify.png"));
verify_act_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
verify_act_->setToolTip(_("Verify Message"));
connect(verify_act_, &QAction::triggered, this, &MainWindow::slot_verify);
/* Key Menu
*/
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_key_from_edit_act_ = new QAction(_("Editor"), this);
import_key_from_edit_act_->setIcon(QIcon(":txt.png"));
import_key_from_edit_act_->setToolTip(_("Import New Key From Editor"));
connect(import_key_from_edit_act_, &QAction::triggered, this,
&MainWindow::slot_import_key_from_edit);
open_key_management_act_ = new QAction(_("Manage Keys"), this);
open_key_management_act_->setIcon(QIcon(":keymgmt.png"));
open_key_management_act_->setToolTip(_("Open Key Management"));
connect(open_key_management_act_, &QAction::triggered, this,
&MainWindow::slot_open_key_management);
/*
* About Menu
*/
about_act_ = new QAction(_("About"), this);
about_act_->setIcon(QIcon(":help.png"));
about_act_->setToolTip(_("Show the application's About box"));
about_act_->setMenuRole(QAction::AboutRole);
connect(about_act_, &QAction::triggered, this,
[=]() { new AboutDialog(0, 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); });
/*
* Check Update Menu
*/
check_update_act_ = new QAction(_("Check for Updates"), this);
check_update_act_->setIcon(QIcon(":help.png"));
check_update_act_->setToolTip(_("Check for updates"));
connect(check_update_act_, &QAction::triggered, this,
[=]() { new AboutDialog(2, this); });
start_wizard_act_ = new QAction(_("Open Wizard"), this);
start_wizard_act_->setToolTip(_("Open the wizard"));
connect(start_wizard_act_, &QAction::triggered, this,
&MainWindow::slot_start_wizard);
/* Popup-Menu-Action for KeyList
*/
append_selected_keys_act_ = new QAction(_("Append To Text Editor"), this);
append_selected_keys_act_->setToolTip(
_("Append The Selected Public Key To Text in Editor"));
connect(append_selected_keys_act_, &QAction::triggered, this,
&MainWindow::slot_append_selected_keys);
copy_mail_address_to_clipboard_act_ = new QAction(_("Copy Email"), this);
copy_mail_address_to_clipboard_act_->setToolTip(
_("Copy selected Email to clipboard"));
connect(copy_mail_address_to_clipboard_act_, &QAction::triggered, this,
&MainWindow::slot_copy_mail_address_to_clipboard);
// TODO: find central place for shared actions, to avoid code-duplication with
// keymgmt.cpp
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,
&MainWindow::slot_show_key_details);
/* Key-Shortcuts for Tab-Switchung-Action
*/
switch_tab_up_act_ = new QAction(this);
switch_tab_up_act_->setShortcut(QKeySequence::NextChild);
connect(switch_tab_up_act_, &QAction::triggered, edit_,
&TextEdit::SlotSwitchTabUp);
this->addAction(switch_tab_up_act_);
switch_tab_down_act_ = new QAction(this);
switch_tab_down_act_->setShortcut(QKeySequence::PreviousChild);
connect(switch_tab_down_act_, &QAction::triggered, edit_,
&TextEdit::SlotSwitchTabDown);
this->addAction(switch_tab_down_act_);
cut_pgp_header_act_ = new QAction(_("Remove PGP Header"), this);
connect(cut_pgp_header_act_, &QAction::triggered, this,
&MainWindow::slot_cut_pgp_header);
add_pgp_header_act_ = new QAction(_("Add PGP Header"), this);
connect(add_pgp_header_act_, &QAction::triggered, this,
&MainWindow::slot_add_pgp_header);
}
void MainWindow::create_menus() {
file_menu_ = menuBar()->addMenu(_("File"));
file_menu_->addAction(new_tab_act_);
file_menu_->addAction(browser_act_);
file_menu_->addAction(open_act_);
file_menu_->addSeparator();
file_menu_->addAction(save_act_);
file_menu_->addAction(save_as_act_);
file_menu_->addSeparator();
file_menu_->addAction(print_act_);
file_menu_->addSeparator();
file_menu_->addAction(close_tab_act_);
file_menu_->addAction(quit_act_);
edit_menu_ = menuBar()->addMenu(_("Edit"));
edit_menu_->addAction(undo_act_);
edit_menu_->addAction(redo_act_);
edit_menu_->addSeparator();
edit_menu_->addAction(zoom_in_act_);
edit_menu_->addAction(zoom_out_act_);
edit_menu_->addSeparator();
edit_menu_->addAction(copy_act_);
edit_menu_->addAction(cut_act_);
edit_menu_->addAction(paste_act_);
edit_menu_->addAction(select_all_act_);
edit_menu_->addAction(find_act_);
edit_menu_->addSeparator();
edit_menu_->addAction(quote_act_);
edit_menu_->addAction(clean_double_line_breaks_act_);
edit_menu_->addSeparator();
edit_menu_->addAction(open_settings_act_);
crypt_menu_ = menuBar()->addMenu(_("Crypt"));
crypt_menu_->addAction(encrypt_act_);
crypt_menu_->addAction(encrypt_sign_act_);
crypt_menu_->addAction(decrypt_act_);
crypt_menu_->addAction(decrypt_verify_act_);
crypt_menu_->addSeparator();
crypt_menu_->addAction(sign_act_);
crypt_menu_->addAction(verify_act_);
crypt_menu_->addSeparator();
key_menu_ = menuBar()->addMenu(_("Keys"));
import_key_menu_ = key_menu_->addMenu(_("Import Key"));
import_key_menu_->setIcon(QIcon(":key_import.png"));
import_key_menu_->addAction(import_key_from_file_act_);
import_key_menu_->addAction(import_key_from_edit_act_);
import_key_menu_->addAction(import_key_from_clipboard_act_);
import_key_menu_->addAction(import_key_from_key_server_act_);
key_menu_->addAction(open_key_management_act_);
steganography_menu_ = menuBar()->addMenu(_("Steganography"));
steganography_menu_->addAction(cut_pgp_header_act_);
steganography_menu_->addAction(add_pgp_header_act_);
view_menu_ = menuBar()->addMenu(_("View"));
help_menu_ = menuBar()->addMenu(_("Help"));
help_menu_->addAction(start_wizard_act_);
help_menu_->addSeparator();
help_menu_->addAction(check_update_act_);
help_menu_->addAction(translate_act_);
help_menu_->addAction(about_act_);
}
void MainWindow::create_tool_bars() {
file_tool_bar_ = addToolBar(_("File"));
file_tool_bar_->setObjectName("fileToolBar");
file_tool_bar_->addAction(new_tab_act_);
file_tool_bar_->addAction(open_act_);
file_tool_bar_->addAction(save_act_);
file_tool_bar_->addAction(browser_act_);
view_menu_->addAction(file_tool_bar_->toggleViewAction());
crypt_tool_bar_ = addToolBar(_("Operations"));
crypt_tool_bar_->setObjectName("cryptToolBar");
crypt_tool_bar_->addAction(encrypt_act_);
crypt_tool_bar_->addAction(encrypt_sign_act_);
crypt_tool_bar_->addAction(decrypt_act_);
crypt_tool_bar_->addAction(decrypt_verify_act_);
crypt_tool_bar_->addAction(sign_act_);
crypt_tool_bar_->addAction(verify_act_);
view_menu_->addAction(crypt_tool_bar_->toggleViewAction());
key_tool_bar_ = addToolBar(_("Key"));
key_tool_bar_->setObjectName("keyToolBar");
key_tool_bar_->addAction(open_key_management_act_);
view_menu_->addAction(key_tool_bar_->toggleViewAction());
edit_tool_bar_ = addToolBar(_("Edit"));
edit_tool_bar_->setObjectName("editToolBar");
edit_tool_bar_->addAction(copy_act_);
edit_tool_bar_->addAction(paste_act_);
edit_tool_bar_->addAction(select_all_act_);
edit_tool_bar_->hide();
view_menu_->addAction(edit_tool_bar_->toggleViewAction());
special_edit_tool_bar_ = addToolBar(_("Special Edit"));
special_edit_tool_bar_->setObjectName("specialEditToolBar");
special_edit_tool_bar_->addAction(quote_act_);
special_edit_tool_bar_->addAction(clean_double_line_breaks_act_);
special_edit_tool_bar_->hide();
view_menu_->addAction(special_edit_tool_bar_->toggleViewAction());
// Add dropdown menu for key import to keytoolbar
import_button_ = new QToolButton();
import_button_->setMenu(import_key_menu_);
import_button_->setPopupMode(QToolButton::InstantPopup);
import_button_->setIcon(QIcon(":key_import.png"));
import_button_->setToolTip(_("Import key from..."));
import_button_->setText(_("Import key"));
key_tool_bar_->addWidget(import_button_);
}
void MainWindow::create_status_bar() {
auto* statusBarBox = new QWidget();
auto* statusBarBoxLayout = new QHBoxLayout();
// QPixmap* pixmap;
// icon which should be shown if there are files in attachments-folder
// pixmap = new QPixmap(":statusbar_icon.png");
// statusBarIcon = new QLabel();
// statusBar()->addWidget(statusBarIcon);
//
// statusBarIcon->setPixmap(*pixmap);
// statusBar()->insertPermanentWidget(0, statusBarIcon, 0);
statusBar()->showMessage(_("Ready"), 2000);
statusBarBox->setLayout(statusBarBoxLayout);
}
void MainWindow::create_dock_windows() {
/* KeyList-Dock window
*/
key_list_dock_ = new QDockWidget(_("Key ToolBox"), this);
key_list_dock_->setObjectName("EncryptDock");
key_list_dock_->setAllowedAreas(Qt::LeftDockWidgetArea |
Qt::RightDockWidgetArea);
key_list_dock_->setMinimumWidth(460);
addDockWidget(Qt::RightDockWidgetArea, key_list_dock_);
m_key_list_->AddListGroupTab(
_("Default"), KeyListRow::SECRET_OR_PUBLIC_KEY,
KeyListColumn::TYPE | KeyListColumn::NAME | KeyListColumn::EmailAddress |
KeyListColumn::Usage | KeyListColumn::Validity,
[](const GpgKey& key) -> bool {
return !(key.IsRevoked() || key.IsDisabled() || key.IsExpired());
});
m_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());
});
m_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());
});
m_key_list_->SlotRefresh();
key_list_dock_->setWidget(m_key_list_);
view_menu_->addAction(key_list_dock_->toggleViewAction());
info_board_dock_ = new QDockWidget(_("Information Board"), this);
info_board_dock_->setObjectName("Information Board");
info_board_dock_->setAllowedAreas(Qt::BottomDockWidgetArea);
addDockWidget(Qt::BottomDockWidgetArea, info_board_dock_);
info_board_dock_->setWidget(info_board_);
info_board_dock_->widget()->layout()->setContentsMargins(0, 0, 0, 0);
view_menu_->addAction(info_board_dock_->toggleViewAction());
}
} // namespace GpgFrontend::UI