diff options
author | Saturneric <[email protected]> | 2021-10-02 14:08:50 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2021-10-02 14:16:27 +0000 |
commit | 3c65d087eeee687ac01af2e80f3dd538f9a2c230 (patch) | |
tree | 1e860dc6343c1897e2224a002f2ca44c574381b3 /src | |
parent | The basic functions of the core pass the test. (diff) | |
download | GpgFrontend-3c65d087eeee687ac01af2e80f3dd538f9a2c230.tar.gz GpgFrontend-3c65d087eeee687ac01af2e80f3dd538f9a2c230.zip |
UI Framework Modified.
Diffstat (limited to 'src')
104 files changed, 11267 insertions, 7863 deletions
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp deleted file mode 100644 index d2c306ef..00000000 --- a/src/MainWindow.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#include "MainWindow.h" -#include "ui/help/VersionCheckThread.h" - -MainWindow::MainWindow() - : appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - - networkAccessManager = new QNetworkAccessManager(this); - - auto waitingDialog = new WaitingDialog(tr("Loading Gnupg"), this); - - // Init Gnupg - auto ctx_thread = QThread::create([&]() { mCtx = new GpgFrontend::GpgContext(); }); - ctx_thread->start(); - while (ctx_thread->isRunning()) - QApplication::processEvents(); - waitingDialog->close(); - ctx_thread->deleteLater(); - - QString baseUrl = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; - - QNetworkRequest request; - request.setUrl(QUrl(baseUrl)); - - QNetworkReply *replay = networkAccessManager->get(request); - - auto version_thread = new VersionCheckThread(replay); - - connect(version_thread, SIGNAL(finished()), version_thread, SLOT(deleteLater())); - connect(version_thread, SIGNAL(upgradeVersion(const QString &, const QString &)), this, SLOT(slotVersionUpgrade(const QString &, const QString &))); - - version_thread->start(); - - // Check Context Status - if (!mCtx->isGood()) { - QMessageBox::critical( - nullptr, tr("ENV Loading Failed"), - tr("Gnupg is not installed correctly, please follow the ReadME " - "instructions to install gnupg and then open GPGFrontend.")); - QCoreApplication::quit(); - exit(0); - } - - /* get path were app was started */ - setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - - edit = new TextEdit(this); - setCentralWidget(edit); - - /* the list of Keys available*/ - mKeyList = new KeyList(mCtx, KeyListRow::SECRET_OR_PUBLIC_KEY, - KeyListColumn::TYPE | KeyListColumn::NAME | - KeyListColumn::EmailAddress | - KeyListColumn::Usage | KeyListColumn::Validity, - this); - mKeyList->setFilter([](const GpgKey &key) -> bool { - if (key.revoked || key.disabled || key.expired) - return false; - else - return true; - }); - mKeyList->slotRefresh(); - - infoBoard = new InfoBoardWidget(this, mCtx, mKeyList); - - /* List of binary Attachments */ - attachmentDockCreated = false; - - /* Variable containing if restart is needed */ - this->slotSetRestartNeeded(false); - - keyMgmt = new KeyMgmt(mCtx, this); - keyMgmt->hide(); - /* test attachmentdir for files alll 15s */ - auto *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(slotCheckAttachmentFolder())); - timer->start(5000); - - createActions(); - createMenus(); - createToolBars(); - createStatusBar(); - createDockWindows(); - - connect(edit->tabWidget, SIGNAL(currentChanged(int)), this, - SLOT(slotDisableTabActions(int))); - - mKeyList->addMenuAction(appendSelectedKeysAct); - mKeyList->addMenuAction(copyMailAddressToClipboardAct); - mKeyList->addMenuAction(showKeyDetailsAct); - mKeyList->addSeparator(); - mKeyList->addMenuAction(refreshKeysFromKeyserverAct); - mKeyList->addMenuAction(uploadKeyToServerAct); - - restoreSettings(); - - // open filename if provided as first command line parameter - QStringList args = qApp->arguments(); - if (args.size() > 1) { - if (!args[1].startsWith("-")) { - if (QFile::exists(args[1])) - edit->loadFile(args[1]); - } - } - edit->curTextPage()->setFocus(); - this->setMinimumSize(1200, 700); - this->setWindowTitle(qApp->applicationName()); - this->show(); - - // Show wizard, if the don't show wizard message box wasn't checked - // and keylist doesn't contain a private key - qDebug() << "wizard/showWizard" - << settings.value("wizard/showWizard", true).toBool(); - qDebug() << "wizard/nextPage" << settings.value("wizard/nextPage").isNull(); - if (settings.value("wizard/showWizard", true).toBool() || - !settings.value("wizard/nextPage").isNull()) { - slotStartWizard(); - } - -} - -void MainWindow::restoreSettings() { - // state sets pos & size of dock-widgets - this->restoreState(settings.value("window/windowState").toByteArray()); - - // Restore window size & location - if (settings.value("window/windowSave").toBool()) { - QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint(); - QSize size = settings.value("window/size", QSize(800, 450)).toSize(); - this->resize(size); - this->move(pos); - } else { - this->resize(QSize(800, 450)); - this->move(QPoint(100, 100)); - } - - // Iconsize - QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); - this->setIconSize(iconSize); - - importButton->setIconSize(iconSize); - fileEncButton->setIconSize(iconSize); - // set list of keyserver if not defined - QStringList *keyServerDefaultList; - keyServerDefaultList = new QStringList("http://keys.gnupg.net"); - keyServerDefaultList->append("https://keyserver.ubuntu.com"); - keyServerDefaultList->append("http://pool.sks-keyservers.net"); - - QStringList keyServerList = - settings.value("keyserver/keyServerList", *keyServerDefaultList) - .toStringList(); - settings.setValue("keyserver/keyServerList", keyServerList); - - // set default keyserver, if it's not set - QString defaultKeyServer = settings - .value("keyserver/defaultKeyServer", - QString("https://keyserver.ubuntu.com")) - .toString(); - settings.setValue("keyserver/defaultKeyServer", defaultKeyServer); - - // Iconstyle - Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>( - settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) - .toUInt()); - this->setToolButtonStyle(buttonStyle); - importButton->setToolButtonStyle(buttonStyle); - fileEncButton->setToolButtonStyle(buttonStyle); - - // Checked Keys - if (settings.value("keys/saveKeyChecked").toBool()) { - QStringList keyIds = - settings.value("keys/savedCheckedKeyList").toStringList(); - mKeyList->setChecked(&keyIds); - } -} - -void MainWindow::saveSettings() { - // window position and size - settings.setValue("window/windowState", saveState()); - settings.setValue("window/pos", pos()); - settings.setValue("window/size", size()); - - // keyid-list of private checked keys - if (settings.value("keys/saveKeyChecked").toBool()) { - QStringList *keyIds = mKeyList->getChecked(); - if (!keyIds->isEmpty()) { - settings.setValue("keys/savedCheckedKeyList", *keyIds); - } else { - settings.setValue("keys/savedCheckedKeyList", ""); - } - } else { - settings.remove("keys/savedCheckedKeyList"); - } -} - -void MainWindow::closeAttachmentDock() { - if (!attachmentDockCreated) { - return; - } - attachmentDock->close(); - attachmentDock->deleteLater(); - attachmentDockCreated = false; -} - -void MainWindow::closeEvent(QCloseEvent *event) { - /* - * ask to save changes, if there are - * modified documents in any tab - */ - if (edit->maybeSaveAnyTab()) { - saveSettings(); - event->accept(); - } else { - event->ignore(); - } - - // clear password from memory - mCtx->clearPasswordCache(); -} diff --git a/src/MainWindow.h b/src/MainWindow.h deleted file mode 100644 index 34a3130a..00000000 --- a/src/MainWindow.h +++ /dev/null @@ -1,415 +0,0 @@ -/** - * This file is part of GPGFrontend. - * - * GPGFrontend is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Foobar is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <https://www.gnu.org/licenses/>. - * - * The initial version of the source code is inherited from gpg4usb-team. - * Their source code version also complies with GNU General Public License. - * - * The source code version of this software was modified and released - * by Saturneric<[email protected]> starting on May 12, 2021. - * - */ - -#ifndef __GPGWIN_H__ -#define __GPGWIN_H__ - -#include "gpg/GpgConstants.h" -#include "ui/KeyMgmt.h" -#include "ui/widgets/TextEdit.h" -#include "ui/FileEncryptionDialog.h" -#include "ui/SettingsDialog.h" -#include "ui/help/AboutDialog.h" -#include "ui/widgets/InfoBoardWidget.h" -#include "ui/FindWidget.h" -#include "ui/Wizard.h" -#include "ui/KeyUploadDialog.h" -#include "ui/WaitingDialog.h" - -#include "gpg/result_analyse/SignResultAnalyse.h" -#include "gpg/result_analyse/EncryptResultAnalyse.h" -#include "gpg/result_analyse/DecryptResultAnalyse.h" - -#include "gpg/GpgFileOpera.h" - - -/** - * @brief - * - */ -class MainWindow : public QMainWindow { -Q_OBJECT - -public: - /** - * @brief - * - */ - MainWindow(); - -public slots: - - void slotSetStatusBarText(const QString& text); - -protected: - /** - * @details Close event shows a save dialog, if there are unsaved documents on exit. - * @param event - */ - void closeEvent(QCloseEvent *event) override; - -public slots: - - /** - * @details Open a new tab for path - */ - void slotOpenFile(QString &path); - - /** - * @details Open dialog for encrypting file. - */ - void slotFileEncrypt(); - - /** - * @details Open dialog for decrypting file. - */ - void slotFileDecrypt(); - - /** - * @details Open dialog for signing file. - */ - void slotFileSign(); - - /** - * @details Open dialog for verifying file. - */ - void slotFileVerify(); - - /** - * @details Open dialog for signing file. - */ - void slotFileEncryptSign(); - - /** - * @details Open dialog for verifying file. - */ - void slotFileDecryptVerify(); - - -private slots: - - /** - * @details encrypt the text of currently active textedit-page - * with the currently checked keys - */ - void slotEncrypt(); - - /** - * @details encrypt and sign the text of currently active textedit-page - * with the currently checked keys - */ - void slotEncryptSign(); - - /** - * @details Show a passphrase dialog and decrypt the text of currently active tab. - */ - void slotDecrypt(); - - /** - * @details Sign the text of currently active tab with the checked private keys - */ - void slotSign(); - - /** - * @details Verify the text of currently active tab and show verify information. - * If document is signed with a key, which is not in keylist, show import missing - * key from keyserver in Menu of verifynotification. - */ - void slotVerify(); - - /** - * @details decrypt and verify the text of currently active textedit-page - * with the currently checked keys - */ - void slotDecryptVerify(); - - /** - * @details Open dialog for encrypting file. - */ - void slotFileEncryptCustom(); - - /** - * @details Open dialog for decrypting file. - */ - void slotFileDecryptCustom(); - - /** - * @details Open dialog for signing file. - */ - void slotFileSignCustom(); - - /** - * @details Open dialog for verifying file. - */ - void slotFileVerifyCustom(); - - /** - * @details Show the details of the first of the first of selected keys - */ - void slotShowKeyDetails(); - - /** - * @details Refresh key information of selected keys from default keyserver - */ - void refreshKeysFromKeyserver(); - - /** - * @details upload the selected key to the keyserver - */ - void uploadKeyToServer(); - - /** - * @details Open find widget. - */ - void slotFind(); - - /** - * @details start the wizard - */ - void slotStartWizard(); - - /** - * @details Import keys from currently active tab to keylist if possible. - */ - void slotImportKeyFromEdit(); - - /** - * @details Append the selected keys to currently active textedit. - */ - void slotAppendSelectedKeys(); - - /** - * @details Copy the mailaddress of selected key to clipboard. - * Method for keylists contextmenu. - */ - void slotCopyMailAddressToClipboard(); - - /** - * @details Open key management dialog. - */ - void slotOpenKeyManagement(); - - /** - * @details Open about-dialog. - */ - void slotAbout(); - - /** - * @details Open check-update-tab in about-dialog. - */ - void slotCheckUpdate(); - - /** - * @details Open File Opera Tab - */ - void slotOpenFileTab(); - - /** - * @details Open settings-dialog. - */ - void slotOpenSettingsDialog(); - - /** - * @details Show a warn message in status bar, if there are files in attachment folder. - */ - void slotCheckAttachmentFolder(); - - /** - * @details Replace double linebreaks by single linebreaks in currently active tab. - */ - void slotCleanDoubleLinebreaks(); - - /** - * @details Cut the existing PGP header and footer from current tab. - */ - void slotCutPgpHeader(); - - /** - * @details Add PGP header and footer to current tab. - */ - void slotAddPgpHeader(); - - /** - * @details Disable tab related actions, if number of tabs is 0. - * @param number number of the opened tabs and -1, if no tab is opened - */ - void slotDisableTabActions(int number); - - /** - * @details get value of member restartNeeded to needed. - * @param needed true, if application has to be restarted - */ - void slotSetRestartNeeded(bool needed); - - /** - * @details called when need to upgrade. - */ - void slotVersionUpgrade(const QString ¤tVersion, const QString &latestVersion); - -private: - /** - * @details Create actions for the main-menu and the context-menu of the keylist. - */ - void createActions(); - - /** - * @details create the menu of the main-window. - */ - void createMenus(); - - /** - * @details Create edit-, crypt- and key-toolbars. - */ - void createToolBars(); - - /** - * @details Create statusbar of mainwindow. - */ - void createStatusBar(); - - /** - * @details Create keylist- and attachment-dockwindows. - */ - void createDockWindows(); - - /** - * @details Create attachment-dockwindow. - */ - void createAttachmentDock(); - - /** - * @details close attachment-dockwindow. - */ - void closeAttachmentDock(); - - /** - * @details Load settings from ini-file. - */ - void restoreSettings(); - - /** - * @details Save settings to ini-file. - */ - void saveSettings(); - - /** - * @details Get full crypto text - */ - QString getCryptText(const QString& shortenCryptoText); - - /** - * @details Shorten crypto text - */ - void shortenCryptText(); - - /** - * @brief return true, if restart is needed - */ - [[nodiscard]] bool getRestartNeeded() const; - - TextEdit *edit; /** Tabwidget holding the edit-windows */ - QMenu *fileMenu; /** Submenu for file-operations*/ - QMenu *editMenu; /** Submenu for text-operations*/ - QMenu *cryptMenu; /** Submenu for crypt-operations */ - QMenu *fileEncMenu; /** Submenu for file crypt operations */ - QMenu *helpMenu; /** Submenu for help-operations */ - QMenu *keyMenu; /** Submenu for key-operations */ - QMenu *viewMenu; /** Submenu for view operations */ - QMenu *importKeyMenu; /** Sumenu for import operations */ - QMenu *steganoMenu; /** Submenu for steganographic operations*/ - QToolBar *cryptToolBar; /** Toolbar holding crypt actions */ - QToolBar *fileToolBar; /** Toolbar holding file actions */ - QToolBar *editToolBar; /** Toolbar holding edit actions */ - QToolBar *specialEditToolBar; /** Toolbar holding special edit actions */ - QToolBar *keyToolBar; /** Toolbar holding key operations */ - QToolButton *importButton; /** Toolbutton for import dropdown menu in toolbar */ - QToolButton *fileEncButton; /** Toolbutton for file cryption dropdown menu in toolbar */ - QDockWidget *keyListDock; /** Encrypt Dock*/ - QDockWidget *attachmentDock; /** Attachment Dock */ - QDockWidget *infoBoardDock; - - QAction *newTabAct; /** Action to create new tab */ - QAction *switchTabUpAct; /** Action to switch tab up*/ - QAction *switchTabDownAct; /** Action to switch tab down */ - QAction *openAct; /** Action to open file */ - QAction *browserAct; /** Action to open file browser*/ - QAction *saveAct; /** Action to save file */ - QAction *saveAsAct; /** Action to save file as */ - QAction *printAct; /** Action to print */ - QAction *closeTabAct; /** Action to print */ - QAction *quitAct; /** Action to quit application */ - QAction *encryptAct; /** Action to encrypt text */ - QAction *encryptSignAct; /** Action to encrypt and sign text */ - QAction *decryptVerifyAct; /** Action to encrypt and sign text */ - QAction *decryptAct; /** Action to decrypt text */ - QAction *signAct; /** Action to sign text */ - QAction *verifyAct; /** Action to verify text */ - QAction *importKeyFromEditAct; /** Action to import key from edit */ - QAction *cleanDoubleLinebreaksAct; /** Action to remove double line breaks */ - - QAction *appendSelectedKeysAct; /** Action to append selected keys to edit */ - QAction *copyMailAddressToClipboardAct; /** Action to copy mail to clipboard */ - QAction *openKeyManagementAct; /** Action to open key management */ - QAction *copyAct; /** Action to copy text */ - QAction *quoteAct; /** Action to quote text */ - QAction *cutAct; /** Action to cut text */ - QAction *pasteAct; /** Action to paste text */ - QAction *selectAllAct; /** Action to select whole text */ - QAction *findAct; /** Action to find text */ - QAction *undoAct; /** Action to undo last action */ - QAction *redoAct; /** Action to redo last action */ - QAction *zoomInAct; /** Action to zoom in */ - QAction *zoomOutAct; /** Action to zoom out */ - QAction *aboutAct; /** Action to open about dialog */ - QAction *checkUpdateAct; /** Action to open about dialog */ - QAction *fileEncryptAct; /** Action to open dialog for encrypting file */ - QAction *fileDecryptAct; /** Action to open dialog for decrypting file */ - QAction *fileSignAct; /** Action to open dialog for signing file */ - QAction *fileVerifyAct; /** Action to open dialog for verifying file */ - QAction *openSettingsAct; /** Action to open settings dialog */ - QAction *showKeyDetailsAct; /** Action to open key-details dialog */ - QAction *refreshKeysFromKeyserverAct; /** Action to refresh a key from keyserver */ - QAction *uploadKeyToServerAct; /** Action to append selected keys to edit */ - QAction *startWizardAct; /** Action to open the wizard */ - QAction *cutPgpHeaderAct; /** Action for cutting the PGP header */ - QAction *addPgpHeaderAct; /** Action for adding the PGP header */ - - QLabel *statusBarIcon; /**< TODO */ - - QString appPath; - QSettings settings; - KeyList *mKeyList; - - InfoBoardWidget *infoBoard; - GpgFrontend::GpgContext *mCtx; - KeyMgmt *keyMgmt; - KeyServerImportDialog *importDialog; /**< TODO */ - - QNetworkAccessManager *networkAccessManager; - - bool attachmentDockCreated; - bool restartNeeded; -}; - -#endif // __GPGWIN_H__ diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt index e74ba86f..36a81591 100644 --- a/src/gpg/CMakeLists.txt +++ b/src/gpg/CMakeLists.txt @@ -9,10 +9,10 @@ set(UTILS_DIR ${CMAKE_SOURCE_DIR}/utils) set(GPGME_LIB_DIR ${UTILS_DIR}/gpgme/lib) -if(ESAY_LOGGING_PP) - message(STATUS "Link ESAY_LOGGING_PP") - set(THIRD_PARTY_LIBS easy_logging_pp config++) -endif() +if (ESAY_LOGGING_PP) + message(STATUS "Link ESAY_LOGGING_PP") + set(THIRD_PARTY_LIBS easy_logging_pp config++) +endif () set(BOOST_LIBS Boost::date_time Boost::filesystem) @@ -23,15 +23,15 @@ if (MINGW) target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} ${BOOST_LIBS} gpgme gpg-error assuan wsock32) -elseif(APPLE) +elseif (APPLE) message(STATUS "Link GPG Static Library For macOS") target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} ${BOOST_LIBS} libgpgme.a libgpg-error.a libassuan.a dl) -else() +else () message(STATUS "Link GPG Static Library For Unix") target_link_libraries(gpg_core ${THIRD_PARTY_LIBS} libgpgme.a libgpg-error.a libassuan.a ${BOOST_LIBS} pthread dl) -endif() +endif () diff --git a/src/gpg/GpgConstants.cpp b/src/gpg/GpgConstants.cpp index 8090a261..3d80cf90 100644 --- a/src/gpg/GpgConstants.cpp +++ b/src/gpg/GpgConstants.cpp @@ -75,11 +75,12 @@ gpgme_error_t GpgFrontend::check_gpg_error(gpgme_error_t err, } std::string GpgFrontend::beautify_fingerprint( - GpgFrontend::BypeArrayRef fingerprint) { + GpgFrontend::BypeArrayConstRef fingerprint) { + auto _fingerprint = fingerprint; uint len = fingerprint.size(); if ((len > 0) && (len % 4 == 0)) for (uint n = 0; 4 * (n + 1) < len; ++n) - fingerprint.insert(static_cast<int>(5u * n + 4u), " "); + _fingerprint.insert(static_cast<int>(5u * n + 4u), " "); return fingerprint; } @@ -123,14 +124,15 @@ std::string GpgFrontend::read_all_data_in_file(const std::string& path) { return in_buffer; } -void GpgFrontend::write_buffer_to_file(const std::string& path, +bool GpgFrontend::write_buffer_to_file(const std::string& path, const std::string& out_buffer) { std::ofstream out_file(path); out_file.open(path.c_str(), std::ios::out); if (!out_file.good()) - throw std::runtime_error("cannot open file"); + return false; out_file.write(out_buffer.c_str(), out_buffer.size()); out_file.close(); + return true; } std::string GpgFrontend::get_file_extension(const std::string& path) { @@ -142,10 +144,10 @@ std::string GpgFrontend::get_file_extension(const std::string& path) { return path_obj.extension().string(); } // In case of no extension return empty string - return std::string(); + return {}; } -std::string get_file_name_with_path(const std::string& path) { +std::string GpgFrontend::get_file_name_with_path(const std::string& path) { // Create a Path object from given string std::filesystem::path path_obj(path); // Check if file name in the path object has extension diff --git a/src/gpg/GpgConstants.h b/src/gpg/GpgConstants.h index 0c126bf7..313e49bb 100644 --- a/src/gpg/GpgConstants.h +++ b/src/gpg/GpgConstants.h @@ -29,9 +29,9 @@ #include <functional> -#include <assert.h> #include <gpg-error.h> #include <gpgme.h> +#include <cassert> #include <memory> #include <string> @@ -43,9 +43,10 @@ const int RESTART_CODE = 1000; namespace GpgFrontend { using ByteArray = std::string; -using BypeArrayPtr = std::unique_ptr<ByteArray>; +using ByteArrayPtr = std::unique_ptr<ByteArray>; using StdBypeArrayPtr = std::unique_ptr<ByteArray>; using BypeArrayRef = ByteArray&; +using BypeArrayConstRef = const ByteArray&; using StringArgsPtr = std::unique_ptr<std::vector<std::string>>; using StringArgsRef = std::vector<std::string>&; @@ -76,15 +77,14 @@ gpg_err_code_t check_gpg_error_2_err_code( gpgme_error_t predict = GPG_ERR_NO_ERROR); // Fingerprint -std::string beautify_fingerprint(BypeArrayRef fingerprint); +std::string beautify_fingerprint(BypeArrayConstRef fingerprint); // File Operation std::string read_all_data_in_file(const std::string& path); -void write_buffer_to_file(const std::string& path, +bool write_buffer_to_file(const std::string& path, const std::string& out_buffer); std::string get_file_extension(const std::string& path); -std::string get_file_extension(const std::string& path); std::string get_file_name_with_path(const std::string& path); // Check diff --git a/src/gpg/GpgModel.h b/src/gpg/GpgModel.h index fcdadb5c..7b77d678 100644 --- a/src/gpg/GpgModel.h +++ b/src/gpg/GpgModel.h @@ -29,22 +29,41 @@ #include "gpg/model/GpgKey.h" #include <list> +#include <utility> namespace GpgFrontend { -using KeyIdArgsListPtr = std::unique_ptr<std::vector<std::string>>; +using KeyId = std::string; + +using SubkeyId = std::string; + +using KeyIdArgsList = std::vector<KeyId>; + +using KeyIdArgsListPtr = std::unique_ptr<KeyIdArgsList>; + +using UIDArgsList = std::vector<std::string>; + +using UIDArgsListPtr = std::unique_ptr<UIDArgsList>; + +// KeyID/UID +using SignIdArgsList = std::vector<std::pair<std::string, std::string>>; + +using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; -using KeyArgsList = const std::vector<GpgKey>; +using KeyArgsList = std::vector<GpgKey>; using KeyListPtr = std::unique_ptr<KeyArgsList>; -using GpgKeyLinkList = const std::list<GpgFrontend::GpgKey>; +using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; + +using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; using KeyPtr = std::unique_ptr<GpgKey>; using KeyPtrArgsList = const std::initializer_list<KeyPtr>; + } // namespace GpgFrontend #endif // GPGFRONTEND_ZH_CN_TS_GPGMODEL_H diff --git a/src/gpg/function/BasicOperator.cpp b/src/gpg/function/BasicOperator.cpp index fbf9afb1..0e44c9e0 100644 --- a/src/gpg/function/BasicOperator.cpp +++ b/src/gpg/function/BasicOperator.cpp @@ -29,7 +29,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt( GpgFrontend::KeyArgsList&& keys, GpgFrontend::BypeArrayRef in_buffer, - GpgFrontend::BypeArrayPtr& out_buffer, + GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgEncrResult& result) { // gpgme_encrypt_result_t e_result; gpgme_key_t recipients[keys.size() + 1]; @@ -57,7 +57,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Encrypt( GpgFrontend::GpgError GpgFrontend::BasicOperator::Decrypt( BypeArrayRef in_buffer, - GpgFrontend::BypeArrayPtr& out_buffer, + GpgFrontend::ByteArrayPtr& out_buffer, GpgFrontend::GpgDecrResult& result) { gpgme_error_t err; @@ -75,7 +75,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Decrypt( GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify( BypeArrayRef& in_buffer, - BypeArrayPtr& sig_buffer, + ByteArrayPtr& sig_buffer, GpgVerifyResult& result) const { gpgme_error_t err; @@ -95,7 +95,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Verify( GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyArgsList&& keys, BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, GpgSignResult& result) { gpgme_error_t err; @@ -132,7 +132,7 @@ GpgFrontend::GpgError GpgFrontend::BasicOperator::Sign(KeyArgsList&& keys, gpgme_error_t GpgFrontend::BasicOperator::DecryptVerify( BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result) { gpgme_error_t err; @@ -157,7 +157,7 @@ gpgme_error_t GpgFrontend::BasicOperator::EncryptSign( KeyArgsList&& keys, KeyArgsList&& signers, BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgEncrResult& encr_result, GpgSignResult& sign_result) { gpgme_error_t err; diff --git a/src/gpg/function/BasicOperator.h b/src/gpg/function/BasicOperator.h index 2e5da307..e8fa943d 100644 --- a/src/gpg/function/BasicOperator.h +++ b/src/gpg/function/BasicOperator.h @@ -36,32 +36,32 @@ class BasicOperator : public SingletonFunctionObject<BasicOperator> { public: gpg_error_t Encrypt(KeyArgsList&& keys, BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgEncrResult& result); gpgme_error_t EncryptSign(KeyArgsList&& keys, KeyArgsList&& signers, BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgEncrResult& encr_result, GpgSignResult& sign_result); gpgme_error_t Decrypt(BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgDecrResult& result); gpgme_error_t DecryptVerify(BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, GpgDecrResult& decrypt_result, GpgVerifyResult& verify_result); gpgme_error_t Verify(BypeArrayRef in_buffer, - BypeArrayPtr& sig_buffer, + ByteArrayPtr& sig_buffer, GpgVerifyResult& result) const; gpg_error_t Sign(KeyArgsList&& key_fprs, BypeArrayRef in_buffer, - BypeArrayPtr& out_buffer, + ByteArrayPtr& out_buffer, gpgme_sig_mode_t mode, GpgSignResult& result); diff --git a/src/gpg/function/GpgFileOpera.h b/src/gpg/function/GpgFileOpera.h index 2eac251b..dece2e52 100644 --- a/src/gpg/function/GpgFileOpera.h +++ b/src/gpg/function/GpgFileOpera.h @@ -31,7 +31,7 @@ namespace GpgFrontend { -class GpgFileOpera { +class GpgFileOpera : public SingletonFunctionObject<GpgFileOpera> { public: GpgError EncryptFile(KeyArgsList&& keys, const std::string& path, diff --git a/src/gpg/function/GpgKeyGetter.cpp b/src/gpg/function/GpgKeyGetter.cpp index f2413706..ce4c9899 100644 --- a/src/gpg/function/GpgKeyGetter.cpp +++ b/src/gpg/function/GpgKeyGetter.cpp @@ -44,10 +44,10 @@ GpgFrontend::GpgKey GpgFrontend::GpgKeyGetter::GetPubkey( return GpgKey(std::move(_p_key)); } -GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::FetchKey() { +GpgFrontend::KeyLinkListPtr GpgFrontend::GpgKeyGetter::FetchKey() { gpgme_error_t err; - auto keys_list = std::make_unique<std::vector<GpgKey>>(); + auto keys_list = std::make_unique<GpgKeyLinkList>(); err = gpgme_op_keylist_start(ctx, nullptr, 0); assert(check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR); @@ -63,3 +63,10 @@ GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::FetchKey() { return keys_list; } +GpgFrontend::KeyListPtr GpgFrontend::GpgKeyGetter::GetKeys( + const KeyIdArgsListPtr& ids) { + auto keys = std::make_unique<KeyArgsList>(); + for (const auto& id : *ids) + keys->push_back(GetKey(id)); + return keys; +} diff --git a/src/gpg/function/GpgKeyGetter.h b/src/gpg/function/GpgKeyGetter.h index af22e2f2..8eab4e10 100644 --- a/src/gpg/function/GpgKeyGetter.h +++ b/src/gpg/function/GpgKeyGetter.h @@ -37,9 +37,11 @@ class GpgKeyGetter : public SingletonFunctionObject<GpgKeyGetter> { GpgKey GetKey(const std::string& fpr); + KeyListPtr GetKeys(const KeyIdArgsListPtr& ids); + GpgKey GetPubkey(const std::string& fpr); - KeyListPtr FetchKey(); + KeyLinkListPtr FetchKey(); private: GpgContext& ctx = diff --git a/src/gpg/function/GpgKeyImportExportor.cpp b/src/gpg/function/GpgKeyImportExportor.cpp index 98ffc328..bdfc25bd 100644 --- a/src/gpg/function/GpgKeyImportExportor.cpp +++ b/src/gpg/function/GpgKeyImportExportor.cpp @@ -61,7 +61,7 @@ GpgFrontend::GpgImportInformation GpgFrontend::GpgKeyImportExportor::ImportKey( */ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( KeyIdArgsListPtr& uid_list, - BypeArrayPtr& out_buffer) const { + ByteArrayPtr& out_buffer) const { if (uid_list->empty()) return false; @@ -89,8 +89,8 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( * @return if success */ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( - KeyArgsList& keys, - BypeArrayPtr& out_buffer) const { + const KeyArgsList& keys, + ByteArrayPtr& out_buffer) const { KeyIdArgsListPtr key_ids = std::make_unique<std::vector<std::string>>(); for (const auto& key : keys) key_ids->push_back(key.id()); @@ -105,7 +105,7 @@ bool GpgFrontend::GpgKeyImportExportor::ExportKeys( */ bool GpgFrontend::GpgKeyImportExportor::ExportSecretKey( const GpgKey& key, - BypeArrayPtr out_buffer) const { + ByteArrayPtr& out_buffer) const { DLOG(INFO) << "Export Secret Key" << key.id().c_str(); gpgme_key_t target_key[2] = {gpgme_key_t(key), nullptr}; diff --git a/src/gpg/function/GpgKeyImportExportor.h b/src/gpg/function/GpgKeyImportExportor.h index 2cdb4e80..d71daddb 100644 --- a/src/gpg/function/GpgKeyImportExportor.h +++ b/src/gpg/function/GpgKeyImportExportor.h @@ -97,11 +97,11 @@ class GpgKeyImportExportor public: GpgImportInformation ImportKey(StdBypeArrayPtr inBuffer); - bool ExportKeys(KeyIdArgsListPtr& uid_list, BypeArrayPtr& out_buffer) const; + bool ExportKeys(KeyIdArgsListPtr& uid_list, ByteArrayPtr& out_buffer) const; - bool ExportKeys(KeyArgsList& keys, BypeArrayPtr& outBuffer) const; + bool ExportKeys(const KeyArgsList& keys, ByteArrayPtr& outBuffer) const; - bool ExportSecretKey(const GpgKey& key, BypeArrayPtr outBuffer) const; + bool ExportSecretKey(const GpgKey& key, ByteArrayPtr& outBuffer) const; private: GpgContext& ctx = diff --git a/src/gpg/function/GpgKeyManager.cpp b/src/gpg/function/GpgKeyManager.cpp index a6697bc4..361c00bd 100644 --- a/src/gpg/function/GpgKeyManager.cpp +++ b/src/gpg/function/GpgKeyManager.cpp @@ -23,14 +23,16 @@ */ #include "gpg/function/GpgKeyManager.h" -#include "gpg/function/BasicOperator.h" -#include "gpg/function/GpgKeyGetter.h" #include <boost/date_time/posix_time/conversion.hpp> #include <string> +#include "gpg/function/BasicOperator.h" +#include "gpg/function/GpgKeyGetter.h" bool GpgFrontend::GpgKeyManager::signKey( - const GpgFrontend::GpgKey &target, GpgFrontend::KeyArgsList &keys, - const std::string &uid, std::unique_ptr<boost::gregorian::date> &expires) { + const GpgFrontend::GpgKey& target, + GpgFrontend::KeyArgsList& keys, + const std::string& uid, + const std::unique_ptr<boost::gregorian::date>& expires) { using namespace boost::posix_time; BasicOperator::GetInstance().SetSigners(keys); @@ -50,21 +52,26 @@ bool GpgFrontend::GpgKeyManager::signKey( } bool GpgFrontend::GpgKeyManager::revSign( - const GpgFrontend::GpgKey &key, - const GpgFrontend::GpgKeySignature &signature) { - - auto &key_getter = GpgKeyGetter::GetInstance(); - auto signing_key = key_getter.GetKey(signature.keyid()); - - auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key), - gpgme_key_t(signing_key), - signature.uid().data(), 0)); - return check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR; + const GpgFrontend::GpgKey& key, + const GpgFrontend::SignIdArgsListPtr& signature_id) { + auto& key_getter = GpgKeyGetter::GetInstance(); + + for (const auto& sign_id : *signature_id) { + auto signing_key = key_getter.GetKey(sign_id.first); + assert(signing_key.good()); + auto err = check_gpg_error(gpgme_op_revsig(ctx, gpgme_key_t(key), + gpgme_key_t(signing_key), + sign_id.second.c_str(), 0)); + if (check_gpg_error_2_err_code(err) != GPG_ERR_NO_ERROR) + return false; + } + return true; } bool GpgFrontend::GpgKeyManager::setExpire( - const GpgFrontend::GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, - std::unique_ptr<boost::gregorian::date> &expires) { + const GpgFrontend::GpgKey& key, + std::unique_ptr<GpgSubKey>& subkey, + std::unique_ptr<boost::gregorian::date>& expires) { using namespace boost::posix_time; unsigned long expires_time = 0; @@ -72,7 +79,7 @@ bool GpgFrontend::GpgKeyManager::setExpire( if (expires != nullptr) expires_time = to_time_t(ptime(*expires)); - const char *sub_fprs = nullptr; + const char* sub_fprs = nullptr; if (subkey != nullptr) sub_fprs = subkey->fpr().c_str(); diff --git a/src/gpg/function/GpgKeyManager.h b/src/gpg/function/GpgKeyManager.h index 6d57c7d7..f50c8dcc 100644 --- a/src/gpg/function/GpgKeyManager.h +++ b/src/gpg/function/GpgKeyManager.h @@ -32,7 +32,7 @@ namespace GpgFrontend { class GpgKeyManager : public SingletonFunctionObject<GpgKeyManager> { -public: + public: /** * Sign a key pair(actually a certain uid) * @param target target key pair @@ -40,18 +40,22 @@ public: * @param expires expire date and time of the signature * @return if successful */ - bool signKey(const GpgKey &target, KeyArgsList &keys, const std::string &uid, - std::unique_ptr<boost::gregorian::date> &expires); + bool signKey(const GpgKey& target, + KeyArgsList& keys, + const std::string& uid, + const std::unique_ptr<boost::gregorian::date>& expires); - bool revSign(const GpgKey &key, const GpgKeySignature &signature); + bool revSign(const GpgFrontend::GpgKey& key, + const GpgFrontend::SignIdArgsListPtr& signature_id); - bool setExpire(const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, - std::unique_ptr<boost::gregorian::date> &expires); + bool setExpire(const GpgKey& key, + std::unique_ptr<GpgSubKey>& subkey, + std::unique_ptr<boost::gregorian::date>& expires); -private: - GpgContext &ctx = GpgContext::GetInstance(); + private: + GpgContext& ctx = GpgContext::GetInstance(); }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H +#endif // GPGFRONTEND_ZH_CN_TS_GPGKEYMANAGER_H diff --git a/src/gpg/function/GpgKeyOpera.cpp b/src/gpg/function/GpgKeyOpera.cpp index f79fb2c3..f61534c5 100644 --- a/src/gpg/function/GpgKeyOpera.cpp +++ b/src/gpg/function/GpgKeyOpera.cpp @@ -41,9 +41,9 @@ * @param uidList key ids */ void GpgFrontend::GpgKeyOpera::DeleteKeys( - GpgFrontend::KeyIdArgsListPtr uid_list) { + GpgFrontend::KeyIdArgsListPtr key_ids) { GpgError err; - for (const auto &tmp : *uid_list) { + for (const auto& tmp : *key_ids) { auto key = GpgKeyGetter::GetInstance().GetKey(tmp); if (key.good()) { LOG(INFO) << "GpgKeyOpera DeleteKeys Get Key Good"; @@ -62,21 +62,21 @@ void GpgFrontend::GpgKeyOpera::DeleteKeys( * @return if successful */ void GpgFrontend::GpgKeyOpera::SetExpire( - const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, - std::unique_ptr<boost::gregorian::date> &expires) { + const GpgKey& key, + const SubkeyId& subkey_id, + std::unique_ptr<boost::gregorian::date>& expires) { unsigned long expires_time = 0; if (expires != nullptr) { using namespace boost::posix_time; expires_time = to_time_t(ptime(*expires)); } - const char *sub_fprs = nullptr; - - if (subkey != nullptr) - sub_fprs = subkey->fpr().c_str(); - - auto err = - gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, sub_fprs, 0); + GpgError err; + if (subkey_id.empty()) + err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, nullptr, 0); + else + err = gpgme_op_setexpire(ctx, gpgme_key_t(key), expires_time, + subkey_id.c_str(), 0); assert(gpg_err_code(err) != GPG_ERR_NO_ERROR); } @@ -88,7 +88,8 @@ void GpgFrontend::GpgKeyOpera::SetExpire( * @return the process doing this job */ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( - const GpgKey &key, const std::string &output_file_name) { + const GpgKey& key, + const std::string& output_file_name) { auto args = std::vector<std::string>{"--command-fd", "0", "--status-fd", "1", "-o", output_file_name.c_str(), @@ -96,7 +97,7 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( using boost::process::async_pipe; GpgCommandExecutor::GetInstance().Execute( - args, [](async_pipe &in, async_pipe &out) -> void { + args, [](async_pipe& in, async_pipe& out) -> void { boost::asio::streambuf buff; boost::asio::read_until(in, buff, '\n'); @@ -112,13 +113,12 @@ void GpgFrontend::GpgKeyOpera::GenerateRevokeCert( * @param params key generation args * @return error information */ -GpgFrontend::GpgError -GpgFrontend::GpgKeyOpera::GenerateKey(std::unique_ptr<GenKeyInfo> params) { - +GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateKey( + const std::unique_ptr<GenKeyInfo>& params) { auto userid_utf8 = params->getUserid(); - const char *userid = userid_utf8.c_str(); + const char* userid = userid_utf8.c_str(); auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()); - const char *algo = algo_utf8.c_str(); + const char* algo = algo_utf8.c_str(); unsigned long expires = 0; { using namespace boost::posix_time; @@ -150,15 +150,14 @@ GpgFrontend::GpgKeyOpera::GenerateKey(std::unique_ptr<GenKeyInfo> params) { * @param params opera args * @return error info */ -GpgFrontend::GpgError -GpgFrontend::GpgKeyOpera::GenerateSubkey(const GpgKey &key, - std::unique_ptr<GenKeyInfo> params) { - +GpgFrontend::GpgError GpgFrontend::GpgKeyOpera::GenerateSubkey( + const GpgKey& key, + const std::unique_ptr<GenKeyInfo>& params) { if (!params->isSubKey()) return GPG_ERR_CANCELED; auto algo_utf8 = (params->getAlgo() + params->getKeySizeStr()); - const char *algo = algo_utf8.c_str(); + const char* algo = algo_utf8.c_str(); unsigned long expires = 0; { using namespace boost::posix_time; diff --git a/src/gpg/function/GpgKeyOpera.h b/src/gpg/function/GpgKeyOpera.h index a635084d..36864cc7 100644 --- a/src/gpg/function/GpgKeyOpera.h +++ b/src/gpg/function/GpgKeyOpera.h @@ -32,23 +32,25 @@ namespace GpgFrontend { class GenKeyInfo; class GpgKeyOpera : public SingletonFunctionObject<GpgKeyOpera> { -public: - void DeleteKeys(KeyIdArgsListPtr uid_list); + public: + void DeleteKeys(KeyIdArgsListPtr key_ids); - void SetExpire(const GpgKey &key, std::unique_ptr<GpgSubKey> &subkey, - std::unique_ptr<boost::gregorian::date> &expires); + void SetExpire(const GpgKey& key, + const SubkeyId& subkey_id, + std::unique_ptr<boost::gregorian::date>& expires); - void GenerateRevokeCert(const GpgKey &key, - const std::string &output_file_name); + void GenerateRevokeCert(const GpgKey& key, + const std::string& output_file_name); - GpgFrontend::GpgError GenerateKey(std::unique_ptr<GenKeyInfo> params); + GpgFrontend::GpgError GenerateKey(const std::unique_ptr<GenKeyInfo>& params); - GpgFrontend::GpgError GenerateSubkey(const GpgKey &key, - std::unique_ptr<GenKeyInfo> params); + GpgFrontend::GpgError GenerateSubkey( + const GpgKey& key, + const std::unique_ptr<GenKeyInfo>& params); -private: - GpgContext &ctx = GpgContext::GetInstance(); + private: + GpgContext& ctx = GpgContext::GetInstance(); }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // _GPGKEYOPERA_H
\ No newline at end of file +#endif // _GPGKEYOPERA_H
\ No newline at end of file diff --git a/src/gpg/function/UidOperator.cpp b/src/gpg/function/UidOperator.cpp index d0058540..5b02855b 100644 --- a/src/gpg/function/UidOperator.cpp +++ b/src/gpg/function/UidOperator.cpp @@ -26,34 +26,38 @@ #include "boost/format.hpp" -bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey &key, - const GpgFrontend::GpgUID &uid) { - auto userid = (boost::format("%1% (%2%) <%3%>") % uid.name() % uid.comment() % - uid.email()) - .str(); - auto err = gpgme_op_adduid(ctx, gpgme_key_t(key), userid.c_str(), 0); +bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key, + const std::string& uid) { + auto err = gpgme_op_adduid(ctx, gpgme_key_t(key), uid.c_str(), 0); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } -bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey &key, - const GpgFrontend::GpgUID &uid) { - auto err = check_gpg_error( - gpgme_op_revuid(ctx, gpgme_key_t(key), uid.uid().c_str(), 0)); +bool GpgFrontend::UidOperator::revUID(const GpgFrontend::GpgKey& key, + const std::string& uid) { + auto err = + check_gpg_error(gpgme_op_revuid(ctx, gpgme_key_t(key), uid.c_str(), 0)); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } -bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey &key, - const GpgFrontend::GpgUID &uid) { +bool GpgFrontend::UidOperator::setPrimaryUID(const GpgFrontend::GpgKey& key, + const std::string& uid) { auto err = check_gpg_error(gpgme_op_set_uid_flag( - ctx, gpgme_key_t(key), uid.uid().c_str(), "primary", nullptr)); + ctx, gpgme_key_t(key), uid.c_str(), "primary", nullptr)); if (check_gpg_error_2_err_code(err) == GPG_ERR_NO_ERROR) return true; else return false; } +bool GpgFrontend::UidOperator::addUID(const GpgFrontend::GpgKey& key, + const std::string& name, + const std::string& comment, + const std::string& email) { + auto uid = boost::format("%1 (%2) <%3>") % name % comment % email; + return addUID(key, uid.str()); +} diff --git a/src/gpg/function/UidOperator.h b/src/gpg/function/UidOperator.h index d5bbcb3b..e3068b1f 100644 --- a/src/gpg/function/UidOperator.h +++ b/src/gpg/function/UidOperator.h @@ -30,15 +30,28 @@ namespace GpgFrontend { -class UidOperator { -public: +class UidOperator : public SingletonFunctionObject<UidOperator> { + public: /** * create a new uid in certain key pair * @param key target key pair - * @param uid uid args + * @param uid uid args(combine name&comment&email) * @return if successful */ - bool addUID(const GpgKey &key, const GpgUID &uid); + bool addUID(const GpgKey& key, const std::string& uid); + + /** + * create a new uid in certain key pair + * @param key target key pair + * @param name + * @param comment + * @param email + * @return + */ + bool addUID(const GpgKey& key, + const std::string& name, + const std::string& comment, + const std::string& email); /** * Revoke(Delete) UID from certain key pair @@ -46,7 +59,7 @@ public: * @param uid target uid * @return if successful */ - bool revUID(const GpgKey &key, const GpgUID &uid); + bool revUID(const GpgKey& key, const std::string& uid); /** * Set one of a uid of a key pair as primary @@ -54,12 +67,12 @@ public: * @param uid target uid * @return if successful */ - bool setPrimaryUID(const GpgKey &key, const GpgUID &uid); + bool setPrimaryUID(const GpgKey& key, const std::string& uid); -private: - GpgContext &ctx = GpgContext::GetInstance(); + private: + GpgContext& ctx = GpgContext::GetInstance(); }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H +#endif // GPGFRONTEND_ZH_CN_TS_UIDOPERATOR_H diff --git a/src/gpg/model/GpgData.cpp b/src/gpg/model/GpgData.cpp index 44e5ae44..1ffff0c5 100644 --- a/src/gpg/model/GpgData.cpp +++ b/src/gpg/model/GpgData.cpp @@ -27,18 +27,17 @@ GpgFrontend::GpgData::GpgData() { gpgme_data_t data; - gpgme_error_t err = gpgme_data_new(&data); + auto err = gpgme_data_new(&data); assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); data_ = std::unique_ptr<struct gpgme_data, __data_ref_deletor>(std::move(data)); } -GpgFrontend::GpgData::GpgData(void *buffer, size_t size, bool copy) { +GpgFrontend::GpgData::GpgData(void* buffer, size_t size, bool copy) { gpgme_data_t data; - gpgme_error_t err = - gpgme_data_new_from_mem(&data, (const char *)buffer, size, copy); + auto err = gpgme_data_new_from_mem(&data, (const char*)buffer, size, copy); assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR); data_ = @@ -51,11 +50,11 @@ GpgFrontend::GpgData::GpgData(void *buffer, size_t size, bool copy) { */ #define BUF_SIZE (32 * 1024) -GpgFrontend::BypeArrayPtr GpgFrontend::GpgData::Read2Buffer() { +GpgFrontend::ByteArrayPtr GpgFrontend::GpgData::Read2Buffer() { gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET); gpgme_error_t err = gpg_error(GPG_ERR_NO_ERROR); - BypeArrayPtr out_buffer = std::make_unique<std::string>(); + ByteArrayPtr out_buffer = std::make_unique<std::string>(); if (ret) { err = gpgme_err_code_from_errno(errno); diff --git a/src/gpg/model/GpgData.h b/src/gpg/model/GpgData.h index 0c4615ad..30a1c496 100644 --- a/src/gpg/model/GpgData.h +++ b/src/gpg/model/GpgData.h @@ -30,16 +30,16 @@ namespace GpgFrontend { class GpgData { -public: + public: GpgData(); - GpgData(void *buffer, size_t size, bool copy = true); + GpgData(void* buffer, size_t size, bool copy = true); operator gpgme_data_t() { return data_.get(); } - BypeArrayPtr Read2Buffer(); + ByteArrayPtr Read2Buffer(); -private: + private: struct __data_ref_deletor { void operator()(gpgme_data_t _data) { if (_data != nullptr) @@ -50,6 +50,6 @@ private: std::unique_ptr<struct gpgme_data, __data_ref_deletor> data_ = nullptr; }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // _GPGDATA_H
\ No newline at end of file +#endif // _GPGDATA_H
\ No newline at end of file diff --git a/src/gpg/model/GpgSubKey.h b/src/gpg/model/GpgSubKey.h index c251141b..edb52f44 100644 --- a/src/gpg/model/GpgSubKey.h +++ b/src/gpg/model/GpgSubKey.h @@ -32,7 +32,7 @@ namespace GpgFrontend { class GpgSubKey { -public: + public: [[nodiscard]] std::string id() const { return _subkey_ref->keyid; } [[nodiscard]] std::string fpr() const { return _subkey_ref->fpr; } @@ -77,24 +77,26 @@ public: explicit GpgSubKey(gpgme_subkey_t subkey); - GpgSubKey(GpgSubKey &&o) noexcept { swap(_subkey_ref, o._subkey_ref); } + GpgSubKey(GpgSubKey&& o) noexcept { swap(_subkey_ref, o._subkey_ref); } - GpgSubKey(const GpgSubKey &) = delete; + GpgSubKey(const GpgSubKey&) = delete; - GpgSubKey &operator=(GpgSubKey &&o) noexcept { + GpgSubKey& operator=(GpgSubKey&& o) noexcept { swap(_subkey_ref, o._subkey_ref); return *this; }; - GpgSubKey &operator=(const GpgSubKey &) = delete; + GpgSubKey& operator=(const GpgSubKey&) = delete; -private: + bool operator==(const GpgSubKey& o) const { return fpr() == o.fpr(); } + + private: using SubkeyRefHandler = std::unique_ptr<struct _gpgme_subkey, std::function<void(gpgme_subkey_t)>>; SubkeyRefHandler _subkey_ref = nullptr; }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // GPGFRONTEND_GPGSUBKEY_H +#endif // GPGFRONTEND_GPGSUBKEY_H diff --git a/src/gpg/result_analyse/ResultAnalyse.cpp b/src/gpg/result_analyse/ResultAnalyse.cpp index 44e32e7b..3005ea1f 100644 --- a/src/gpg/result_analyse/ResultAnalyse.cpp +++ b/src/gpg/result_analyse/ResultAnalyse.cpp @@ -24,15 +24,11 @@ #include "gpg/result_analyse/ResultAnalyse.h" -const std::string GpgFrontend::ResultAnalyse::getResultReport() { - if (!analysed_) - do_analyse(); +const std::string GpgFrontend::ResultAnalyse::getResultReport() const { return stream.str(); } -int GpgFrontend::ResultAnalyse::getStatus() { - if (!analysed_) - do_analyse(); +int GpgFrontend::ResultAnalyse::getStatus() const { return status; } diff --git a/src/gpg/result_analyse/ResultAnalyse.h b/src/gpg/result_analyse/ResultAnalyse.h index d2cf0037..d187cd8a 100644 --- a/src/gpg/result_analyse/ResultAnalyse.h +++ b/src/gpg/result_analyse/ResultAnalyse.h @@ -31,16 +31,16 @@ namespace GpgFrontend { class ResultAnalyse { -public: + public: ResultAnalyse() = default; - [[nodiscard]] const std::string getResultReport(); + [[nodiscard]] const std::string getResultReport() const; - [[nodiscard]] int getStatus(); + [[nodiscard]] int getStatus() const; void analyse(); -protected: + protected: virtual void do_analyse() = 0; std::stringstream stream; @@ -52,6 +52,6 @@ protected: void setStatus(int mStatus); }; -} // namespace GpgFrontend +} // namespace GpgFrontend -#endif // GPGFRONTEND_RESULTANALYSE_H +#endif // GPGFRONTEND_RESULTANALYSE_H diff --git a/src/main.cpp b/src/main.cpp index 831a6121..1222adf3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,95 +22,96 @@ * */ -#include "MainWindow.h" #include "GpgFrontendBuildInfo.h" +#include "ui/MainWindow.h" -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { + Q_INIT_RESOURCE(gpgfrontend); - Q_INIT_RESOURCE(gpgfrontend); + QApplication app(argc, argv); - QApplication app(argc, argv); + // get application path + QString appPath = qApp->applicationDirPath(); - // get application path - QString appPath = qApp->applicationDirPath(); + QApplication::setApplicationVersion(BUILD_VERSION); + QApplication::setApplicationName(PROJECT_NAME); - QApplication::setApplicationVersion(BUILD_VERSION); - QApplication::setApplicationName(PROJECT_NAME); + // dont show icons in menus + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); - // dont show icons in menus - QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); - - // unicode in source - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); + // unicode in source + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); #ifdef WINDOWS - // css - QFile file(RESOURCE_DIR(qApp->applicationDirPath()) + "/css/default.qss"); - file.open(QFile::ReadOnly); - QString styleSheet = QLatin1String(file.readAll()); - qApp->setStyleSheet(styleSheet); - file.close(); + // css + QFile file(RESOURCE_DIR(qApp->applicationDirPath()) + "/css/default.qss"); + file.open(QFile::ReadOnly); + QString styleSheet = QLatin1String(file.readAll()); + qApp->setStyleSheet(styleSheet); + file.close(); #endif - /** - * internationalisation. loop to restart mainwindow - * with changed translation when settings change. - */ - if(!QDir(RESOURCE_DIR(appPath) + "/conf").exists()) { - QDir().mkdir(RESOURCE_DIR(appPath) + "/conf"); + /** + * internationalisation. loop to restart mainwindow + * with changed translation when settings change. + */ + if (!QDir(RESOURCE_DIR(appPath) + "/conf").exists()) { + QDir().mkdir(RESOURCE_DIR(appPath) + "/conf"); + } + QSettings::setDefaultFormat(QSettings::IniFormat); + QSettings settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat); + QTranslator translator, translator2; + int return_from_event_loop_code; + + qDebug() << "Resource Directory" << RESOURCE_DIR(appPath); + + do { + QApplication::removeTranslator(&translator); + QApplication::removeTranslator(&translator2); + + QString lang = + settings.value("int/lang", QLocale::system().name()).toString(); + if (lang.isEmpty()) { + lang = QLocale::system().name(); } - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat); - QTranslator translator, translator2; - int return_from_event_loop_code; - - qDebug() << "Resource Directory" << RESOURCE_DIR(appPath); - - do { - QApplication::removeTranslator(&translator); - QApplication::removeTranslator(&translator2); - - QString lang = settings.value("int/lang", QLocale::system().name()).toString(); - if (lang.isEmpty()) { - lang = QLocale::system().name(); - } - qDebug() << "Language set" << lang; - translator.load(RESOURCE_DIR(appPath) + "/ts/" + "gpgfrontend_" + lang); - qDebug() << "Translator" << translator.filePath(); - QApplication::installTranslator(&translator); - - // set qt translations - translator2.load(RESOURCE_DIR(appPath) + "/ts/qt_" + lang); - qDebug() << "Translator2" << translator2.filePath(); - QApplication::installTranslator(&translator2); - - QApplication::setQuitOnLastWindowClosed(true); + qDebug() << "Language set" << lang; + translator.load(RESOURCE_DIR(appPath) + "/ts/" + "gpgfrontend_" + lang); + qDebug() << "Translator" << translator.filePath(); + QApplication::installTranslator(&translator); + // set qt translations + translator2.load(RESOURCE_DIR(appPath) + "/ts/qt_" + lang); + qDebug() << "Translator2" << translator2.filePath(); + QApplication::installTranslator(&translator2); - /** - * The function `gpgme_check_version' must be called before any other - * function in the library, because it initializes the thread support - * subsystem in GPGME. (from the info page) */ - gpgme_check_version(nullptr); + QApplication::setQuitOnLastWindowClosed(true); - // the locale set here is used for the other setlocale calls which have nullptr - // -> nullptr means use default, which is configured here - setlocale(LC_ALL, settings.value("int/lang").toLocale().name().toUtf8().constData()); - - /** set locale, because tests do also */ - gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr)); - //qDebug() << "Locale set to" << LC_CTYPE << " - " << setlocale(LC_CTYPE, nullptr); - #ifndef _WIN32 - gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr)); - #endif + /** + * The function `gpgme_check_version' must be called before any other + * function in the library, because it initializes the thread support + * subsystem in GPGME. (from the info page) */ + gpgme_check_version(nullptr); + + // the locale set here is used for the other setlocale calls which have + // nullptr + // -> nullptr means use default, which is configured here + setlocale( + LC_ALL, + settings.value("int/lang").toLocale().name().toUtf8().constData()); + + /** set locale, because tests do also */ + gpgme_set_locale(nullptr, LC_CTYPE, setlocale(LC_CTYPE, nullptr)); +// qDebug() << "Locale set to" << LC_CTYPE << " - " << setlocale(LC_CTYPE, +// nullptr); +#ifndef _WIN32 + gpgme_set_locale(nullptr, LC_MESSAGES, setlocale(LC_MESSAGES, nullptr)); +#endif - MainWindow window; - return_from_event_loop_code = QApplication::exec(); + MainWindow window; + return_from_event_loop_code = QApplication::exec(); - } while (return_from_event_loop_code == RESTART_CODE); + } while (return_from_event_loop_code == RESTART_CODE); - return return_from_event_loop_code; + return return_from_event_loop_code; } - - - diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 170e7454..ecf998d6 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -6,7 +6,7 @@ aux_source_directory(./main_window UI_SOURCE) aux_source_directory(./help UI_SOURCE) aux_source_directory(./settings UI_SOURCE) -add_library(gpgfrontend-ui STATIC ${UI_SOURCE}) +add_library(gpgfrontend-ui STATIC ${UI_SOURCE} GpgFrontendUI.h) target_link_libraries(gpgfrontend-ui Qt5::Network Qt5::PrintSupport Qt5::Widgets Qt5::Test Qt5::Core)
\ No newline at end of file diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp index 55c8e5f0..d141df1e 100755 --- a/src/ui/FileEncryptionDialog.cpp +++ b/src/ui/FileEncryptionDialog.cpp @@ -24,266 +24,258 @@ #include "ui/FileEncryptionDialog.h" -FileEncryptionDialog::FileEncryptionDialog(GpgFrontend::GpgContext *ctx, QStringList keyList, DialogAction action, - QWidget *parent) - : QDialog(parent), mAction(action), mCtx(ctx){ - - if (mAction == Decrypt) { - setWindowTitle(tr("Decrypt File")); - } else if (mAction == Encrypt) { - setWindowTitle(tr("Encrypt File")); - } else if (mAction == Sign) { - setWindowTitle(tr("Sign File")); - } else if (mAction == Verify) { - setWindowTitle(tr("Verify File")); - } - - setModal(true); - - auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExecuteAction())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - auto *groupBox1 = new QGroupBox(tr("Input Parameters")); - - /* Setup input & Outputfileselection*/ - inputFileEdit = new QLineEdit(); - auto *fb1 = new QPushButton("Select"); - connect(fb1, SIGNAL(clicked()), this, SLOT(slotSelectInputFile())); - auto *fl1 = new QLabel(tr("Target File")); - fl1->setBuddy(inputFileEdit); - - outputFileEdit = new QLineEdit(); - auto *fb2 = new QPushButton("Select"); - connect(fb2, SIGNAL(clicked()), this, SLOT(slotSelectOutputFile())); - auto *fl2 = new QLabel(tr("Output File")); - fl2->setBuddy(outputFileEdit); - - auto *gLayout = new QGridLayout(); - gLayout->addWidget(fl1, 0, 0); - gLayout->addWidget(inputFileEdit, 0, 1); - gLayout->addWidget(fb1, 0, 2); - signFileEdit = new QLineEdit(); - // verify does not need outfile, but signature file - if (mAction != Verify) { - gLayout->addWidget(fl2, 1, 0); - gLayout->addWidget(outputFileEdit, 1, 1); - gLayout->addWidget(fb2, 1, 2); - } else { - auto *sfb1 = new QPushButton("Select"); - connect(sfb1, SIGNAL(clicked()), this, SLOT(slotSelectSignFile())); - auto *sfl1 = new QLabel(tr("Signature File(.sig) Path")); - sfl1->setBuddy(signFileEdit); - - gLayout->addWidget(sfl1, 1, 0); - gLayout->addWidget(signFileEdit, 1, 1); - gLayout->addWidget(sfb1, 1, 2); - } - groupBox1->setLayout(gLayout); - - /*Setup KeyList*/ - mKeyList = new KeyList(mCtx, KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); - if(mAction == Verify) - mKeyList->setFilter([](const GpgKey &key) -> bool { - if(key.disabled || key.expired || key.revoked) return false; - else return true; - }); - - if(mAction == Encrypt) - mKeyList->setFilter([](const GpgKey &key) -> bool { - if(!GpgFrontend::GpgContext::checkIfKeyCanEncr(key)) return false; - else return true; - }); - - if(mAction == Sign) - mKeyList->setFilter([](const GpgKey &key) -> bool { - if(!GpgFrontend::GpgContext::checkIfKeyCanSign(key)) return false; - else return true; - }); - - if(mAction == Decrypt) - mKeyList->setDisabled(true); - - mKeyList->slotRefresh(); - mKeyList->setChecked(&keyList); - - statusLabel = new QLabel(); - statusLabel->setStyleSheet("QLabel {color: red;}"); - - auto *vbox2 = new QVBoxLayout(); - vbox2->addWidget(groupBox1); - vbox2->addWidget(mKeyList); - vbox2->addWidget(statusLabel); - vbox2->addWidget(buttonBox); - vbox2->addStretch(0); - setLayout(vbox2); - - this->setMinimumWidth(480); - this->show(); - +#include "gpg/function/BasicOperator.h" +#include "gpg/function/GpgKeyGetter.h" + +namespace GpgFrontend::UI { +FileEncryptionDialog::FileEncryptionDialog(KeyIdArgsListPtr keyList, + DialogAction action, + QWidget* parent) + : QDialog(parent), mAction(action) { + if (mAction == Decrypt) { + setWindowTitle(tr("Decrypt File")); + } else if (mAction == Encrypt) { + setWindowTitle(tr("Encrypt File")); + } else if (mAction == Sign) { + setWindowTitle(tr("Sign File")); + } else if (mAction == Verify) { + setWindowTitle(tr("Verify File")); + } + + setModal(true); + + auto* buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExecuteAction())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + auto* groupBox1 = new QGroupBox(tr("Input Parameters")); + + /* Setup input & Outputfileselection*/ + inputFileEdit = new QLineEdit(); + auto* fb1 = new QPushButton("Select"); + connect(fb1, SIGNAL(clicked()), this, SLOT(slotSelectInputFile())); + auto* fl1 = new QLabel(tr("Target File")); + fl1->setBuddy(inputFileEdit); + + outputFileEdit = new QLineEdit(); + auto* fb2 = new QPushButton("Select"); + connect(fb2, SIGNAL(clicked()), this, SLOT(slotSelectOutputFile())); + auto* fl2 = new QLabel(tr("Output File")); + fl2->setBuddy(outputFileEdit); + + auto* gLayout = new QGridLayout(); + gLayout->addWidget(fl1, 0, 0); + gLayout->addWidget(inputFileEdit, 0, 1); + gLayout->addWidget(fb1, 0, 2); + signFileEdit = new QLineEdit(); + // verify does not need outfile, but signature file + if (mAction != Verify) { + gLayout->addWidget(fl2, 1, 0); + gLayout->addWidget(outputFileEdit, 1, 1); + gLayout->addWidget(fb2, 1, 2); + } else { + auto* sfb1 = new QPushButton("Select"); + connect(sfb1, SIGNAL(clicked()), this, SLOT(slotSelectSignFile())); + auto* sfl1 = new QLabel(tr("Signature File(.sig) Path")); + sfl1->setBuddy(signFileEdit); + + gLayout->addWidget(sfl1, 1, 0); + gLayout->addWidget(signFileEdit, 1, 1); + gLayout->addWidget(sfb1, 1, 2); + } + groupBox1->setLayout(gLayout); + + /*Setup KeyList*/ + mKeyList = new KeyList( + KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); + if (mAction == Verify) + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (key.disabled() || key.expired() || key.revoked()) + return false; + else + return true; + }); + + if (mAction == Encrypt) + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (!key.CanEncrActual()) + return false; + else + return true; + }); + + if (mAction == Sign) + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (!key.CanSignActual()) + return false; + else + return true; + }); + + if (mAction == Decrypt) + mKeyList->setDisabled(true); + + mKeyList->slotRefresh(); + mKeyList->setChecked(keyList); + + statusLabel = new QLabel(); + statusLabel->setStyleSheet("QLabel {color: red;}"); + + auto* vbox2 = new QVBoxLayout(); + vbox2->addWidget(groupBox1); + vbox2->addWidget(mKeyList); + vbox2->addWidget(statusLabel); + vbox2->addWidget(buttonBox); + vbox2->addStretch(0); + setLayout(vbox2); + + this->setMinimumWidth(480); + this->show(); } void FileEncryptionDialog::slotSelectInputFile() { - QString path = ""; - if (inputFileEdit->text().size() > 0) { - path = QFileInfo(inputFileEdit->text()).absolutePath(); - } - -// QString infileName = QFileDialog::getOpenFileName(this, tr("Open File"), path, tr("Files") + tr("All Files (*)")); - QString infileName = QFileDialog::getOpenFileName(this, tr("Open File"), path); - inputFileEdit->setText(infileName); - - // try to find a matching output-filename, if not yet done - if (!infileName.isEmpty() - && outputFileEdit->text().size() == 0 - && signFileEdit->text().size() == 0) { - if (mAction == Encrypt) { - outputFileEdit->setText(infileName + ".asc"); - } else if (mAction == Sign) { - outputFileEdit->setText(infileName + ".sig"); - } else if (mAction == Verify) { - signFileEdit->setText(infileName + ".sig"); - } else { - if (infileName.endsWith(".asc", Qt::CaseInsensitive)) { - QString ofn = infileName; - ofn.chop(4); - outputFileEdit->setText(ofn); - } else { - outputFileEdit->setText(infileName + ".out"); - } - } + QString path = ""; + if (inputFileEdit->text().size() > 0) { + path = QFileInfo(inputFileEdit->text()).absolutePath(); + } + + // QString infileName = QFileDialog::getOpenFileName(this, tr("Open File"), + // path, tr("Files") + tr("All Files (*)")); + QString infileName = + QFileDialog::getOpenFileName(this, tr("Open File"), path); + inputFileEdit->setText(infileName); + + // try to find a matching output-filename, if not yet done + if (!infileName.isEmpty() && outputFileEdit->text().size() == 0 && + signFileEdit->text().size() == 0) { + if (mAction == Encrypt) { + outputFileEdit->setText(infileName + ".asc"); + } else if (mAction == Sign) { + outputFileEdit->setText(infileName + ".sig"); + } else if (mAction == Verify) { + signFileEdit->setText(infileName + ".sig"); + } else { + if (infileName.endsWith(".asc", Qt::CaseInsensitive)) { + QString ofn = infileName; + ofn.chop(4); + outputFileEdit->setText(ofn); + } else { + outputFileEdit->setText(infileName + ".out"); + } } + } } void FileEncryptionDialog::slotSelectOutputFile() { - QString path = ""; - if (outputFileEdit->text().size() > 0) { - path = QFileInfo(outputFileEdit->text()).absolutePath(); - } - - QString outfileName = QFileDialog::getSaveFileName(this, tr("Save File"), path, nullptr, nullptr, - QFileDialog::DontConfirmOverwrite); - outputFileEdit->setText(outfileName); - + QString path = ""; + if (outputFileEdit->text().size() > 0) { + path = QFileInfo(outputFileEdit->text()).absolutePath(); + } + + QString outfileName = + QFileDialog::getSaveFileName(this, tr("Save File"), path, nullptr, + nullptr, QFileDialog::DontConfirmOverwrite); + outputFileEdit->setText(outfileName); } void FileEncryptionDialog::slotSelectSignFile() { - QString path = ""; - if (signFileEdit->text().size() > 0) { - path = QFileInfo(signFileEdit->text()).absolutePath(); - } - - QString signfileName = QFileDialog::getSaveFileName(this, tr("Open File"), path, nullptr, nullptr, - QFileDialog::DontConfirmOverwrite); - signFileEdit->setText(signfileName); - - if (inputFileEdit->text().size() == 0 && signfileName.endsWith(".sig", Qt::CaseInsensitive)) { - QString sfn = signfileName; - sfn.chop(4); - inputFileEdit->setText(sfn); - } - + QString path = ""; + if (signFileEdit->text().size() > 0) { + path = QFileInfo(signFileEdit->text()).absolutePath(); + } + + QString signfileName = + QFileDialog::getSaveFileName(this, tr("Open File"), path, nullptr, + nullptr, QFileDialog::DontConfirmOverwrite); + signFileEdit->setText(signfileName); + + if (inputFileEdit->text().size() == 0 && + signfileName.endsWith(".sig", Qt::CaseInsensitive)) { + QString sfn = signfileName; + sfn.chop(4); + inputFileEdit->setText(sfn); + } } void FileEncryptionDialog::slotExecuteAction() { - - QFile infile; - infile.setFileName(inputFileEdit->text()); - if (!infile.open(QIODevice::ReadOnly)) { - statusLabel->setText(tr("Couldn't open file")); - inputFileEdit->setStyleSheet("QLineEdit { background: yellow }"); - return; - } - - QByteArray inBuffer = infile.readAll(); - auto *outBuffer = new QByteArray(); - infile.close(); - - QVector<GpgKey> keys; - mKeyList->getCheckedKeys(keys); - - qDebug() << "slotExecuteAction" << mAction; - - if (mAction == Encrypt) { - qDebug() << "Action Encrypt"; - gpgme_error_t err = mCtx->encrypt(keys, inBuffer, outBuffer, nullptr); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { - qDebug() << "Error" << gpgme_strerror(err); - QMessageBox::warning(this, tr("Error"), - tr("Error Occurred During Encryption")); - return; - } + QFile infile; + infile.setFileName(inputFileEdit->text()); + if (!infile.open(QIODevice::ReadOnly)) { + statusLabel->setText(tr("Couldn't open file")); + inputFileEdit->setStyleSheet("QLineEdit { background: yellow }"); + return; + } + auto in_data = read_all_data_in_file(inputFileEdit->text().toStdString()); + auto out_data = std::make_unique<ByteArray>(); + + auto key_ids = mKeyList->getChecked(); + auto keys = std::vector<GpgKey>(); + for (const auto& key_id : *key_ids) + keys.push_back(GpgKeyGetter::GetInstance().GetKey(key_id)); + + if (mAction == Encrypt) { + qDebug() << "Action Encrypt"; + GpgEncrResult result = nullptr; + gpgme_error_t err = BasicOperator::GetInstance().Encrypt( + std::move(keys), in_data, out_data, result); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { + qDebug() << "Error" << gpgme_strerror(err); + + QMessageBox::warning(this, tr("Error"), + tr("Error Occurred During Encryption")); + return; } - - if (mAction == Decrypt) { - qDebug() << "Action Decrypt"; - gpgme_error_t err = mCtx->decrypt(inBuffer, outBuffer, nullptr); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { - qDebug() << "Error" << gpgme_strerror(err); - QMessageBox::warning(this, tr("Error"), - tr("Error Occurred During Decryption")); - return; - } + } + + else if (mAction == Decrypt) { + qDebug() << "Action Decrypt"; + GpgDecrResult result = nullptr; + gpgme_error_t err = + BasicOperator::GetInstance().Decrypt(in_data, out_data, result); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { + qDebug() << "Error" << gpgme_strerror(err); + QMessageBox::warning(this, tr("Error"), + tr("Error Occurred During Decryption")); + return; } - - if (mAction == Sign) { - qDebug() << "Action Sign"; - gpgme_error_t err = mCtx->sign(keys, inBuffer, outBuffer, GPGME_SIG_MODE_DETACH, nullptr); - if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { - qDebug() << "Error" << gpgme_strerror(err); - QMessageBox::warning(this, tr("Error"), - tr("Error Occurred During Signature")); - return; - } + } + + else if (mAction == Sign) { + qDebug() << "Action Sign"; + GpgSignResult result = nullptr; + gpgme_error_t err = BasicOperator::GetInstance().Sign( + std::move(keys), in_data, out_data, GPGME_SIG_MODE_DETACH, result); + if (gpgme_err_code(err) != GPG_ERR_NO_ERROR) { + qDebug() << "Error" << gpgme_strerror(err); + QMessageBox::warning(this, tr("Error"), + tr("Error Occurred During Signature")); + return; } + } - if (mAction == Verify) { - QFile sign_file; - sign_file.setFileName(signFileEdit->text()); - if (!sign_file.open(QIODevice::ReadOnly)) { - statusLabel->setText(tr("Couldn't open file")); - signFileEdit->setStyleSheet("QLineEdit { background: yellow }"); - return; - } - auto signBuffer = sign_file.readAll(); - gpgme_verify_result_t result; - auto error = mCtx->verify(&inBuffer, &signBuffer, &result); - new VerifyDetailsDialog(this, mCtx, mKeyList, error, result); - return; - } + if (mAction == Verify) { + auto sign_data = std::make_unique<ByteArray>( + read_all_data_in_file(signFileEdit->text().toStdString())); + GpgVerifyResult result = nullptr; + auto error = + BasicOperator::GetInstance().Verify(in_data, sign_data, result); + new VerifyDetailsDialog(this, mKeyList, error, std::move(result)); + return; + } - QFile outfile(outputFileEdit->text()); - if (outfile.exists()) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("File"), - tr("File exists! Do you want to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - if (ret == QMessageBox::Cancel) { - return; - } - } + write_buffer_to_file(outputFileEdit->text().toStdString(), *out_data); - if (!outfile.open(QFile::WriteOnly)) { - QMessageBox::warning(this, tr("File"), - tr("Cannot write file %1:\n%2.") - .arg(outputFileEdit->text()) - .arg(outfile.errorString())); - return; - } - - QDataStream out(&outfile); - out.writeRawData(outBuffer->data(), outBuffer->length()); - outfile.close(); - QMessageBox::information(nullptr, "Done", "Output saved to " + outputFileEdit->text()); - - accept(); + accept(); } void FileEncryptionDialog::slotShowKeyList() { - mKeyList->show(); + mKeyList->show(); } void FileEncryptionDialog::slotHideKeyList() { - mKeyList->hide(); + mKeyList->hide(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/FileEncryptionDialog.h b/src/ui/FileEncryptionDialog.h new file mode 100755 index 00000000..a3e56564 --- /dev/null +++ b/src/ui/FileEncryptionDialog.h @@ -0,0 +1,115 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __FILEENCRYPTIONDIALOG_H__ +#define __FILEENCRYPTIONDIALOG_H__ + +#include "VerifyDetailsDialog.h" +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +/** + * @brief + * + * @class FileEncryptionDialog fileencryptiondialog.h "fileencryptiondialog.h" + */ +class FileEncryptionDialog : public QDialog { + Q_OBJECT + + public: + enum DialogAction { Encrypt, Decrypt, Sign, Verify }; + + /** + * @brief + * + * @fn FileEncryptionDialog + * @param ctx + * @param keyList + * @param parent + */ + FileEncryptionDialog(KeyIdArgsListPtr keyList, + DialogAction action, + QWidget* parent = nullptr); + + public slots: + + /** + * @details + * + * @fn selectInputFile + */ + void slotSelectInputFile(); + + /** + * @brief + * + * @fn selectOutputFile + */ + void slotSelectOutputFile(); + + /** + * @brief + * + * @fn selectSignFile + */ + void slotSelectSignFile(); + + /** + * @brief + * + * @fn executeAction + */ + void slotExecuteAction(); + + /** + * @brief + * + * @fn hideKeyList + */ + void slotHideKeyList(); + + /** + * @brief + * + * @fn showKeyList + */ + void slotShowKeyList(); + + private: + QLineEdit* outputFileEdit; + QLineEdit* inputFileEdit; + QLineEdit* signFileEdit; + DialogAction mAction; + QLabel* statusLabel; + + protected: + KeyList* mKeyList; +}; + +} // namespace GpgFrontend::UI + +#endif // __FILEENCRYPTIONDIALOG_H__ diff --git a/src/ui/FindWidget.cpp b/src/ui/FindWidget.cpp index fce62223..f9b92685 100644 --- a/src/ui/FindWidget.cpp +++ b/src/ui/FindWidget.cpp @@ -24,135 +24,139 @@ #include "ui/FindWidget.h" -FindWidget::FindWidget(QWidget *parent, QTextEdit *edit) : - QWidget(parent) -{ - mTextpage = edit; - findEdit = new QLineEdit(this); - auto *closeButton= new QPushButton(this->style()->standardIcon(QStyle::SP_TitleBarCloseButton),"",this); - auto *nextButton= new QPushButton(QIcon(":button_next.png"), ""); - auto *previousButton= new QPushButton(QIcon(":button_previous.png"), ""); - - auto *notificationWidgetLayout = new QHBoxLayout(this); - notificationWidgetLayout->setContentsMargins(10,0,0,0); - notificationWidgetLayout->addWidget(new QLabel(tr("Find:"))); - notificationWidgetLayout->addWidget(findEdit,2); - notificationWidgetLayout->addWidget(nextButton); - notificationWidgetLayout->addWidget(previousButton); - notificationWidgetLayout->addWidget(closeButton); - - this->setLayout(notificationWidgetLayout); - connect(findEdit,SIGNAL(textEdited(QString)),this,SLOT(slotFind())); - connect(findEdit,SIGNAL(returnPressed()),this,SLOT(slotFindNext())); - connect(nextButton,SIGNAL(clicked()),this,SLOT(slotFindNext())); - connect(previousButton,SIGNAL(clicked()),this,SLOT(slotFindPrevious())); - connect(closeButton,SIGNAL(clicked()),this,SLOT(slotClose())); - - // The timer is necessary for setting the focus - QTimer::singleShot(0, findEdit, SLOT(setFocus())); +namespace GpgFrontend::UI { + +FindWidget::FindWidget(QWidget* parent, QTextEdit* edit) : QWidget(parent) { + mTextpage = edit; + findEdit = new QLineEdit(this); + auto* closeButton = new QPushButton( + this->style()->standardIcon(QStyle::SP_TitleBarCloseButton), "", this); + auto* nextButton = new QPushButton(QIcon(":button_next.png"), ""); + auto* previousButton = new QPushButton(QIcon(":button_previous.png"), ""); + + auto* notificationWidgetLayout = new QHBoxLayout(this); + notificationWidgetLayout->setContentsMargins(10, 0, 0, 0); + notificationWidgetLayout->addWidget(new QLabel(tr("Find:"))); + notificationWidgetLayout->addWidget(findEdit, 2); + notificationWidgetLayout->addWidget(nextButton); + notificationWidgetLayout->addWidget(previousButton); + notificationWidgetLayout->addWidget(closeButton); + + this->setLayout(notificationWidgetLayout); + connect(findEdit, SIGNAL(textEdited(QString)), this, SLOT(slotFind())); + connect(findEdit, SIGNAL(returnPressed()), this, SLOT(slotFindNext())); + connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFindNext())); + connect(previousButton, SIGNAL(clicked()), this, SLOT(slotFindPrevious())); + connect(closeButton, SIGNAL(clicked()), this, SLOT(slotClose())); + + // The timer is necessary for setting the focus + QTimer::singleShot(0, findEdit, SLOT(setFocus())); } -void FindWidget::setBackground() -{ - QTextCursor cursor = mTextpage->textCursor(); - // if match is found set background of QLineEdit to white, otherwise to red - QPalette bgPalette( findEdit->palette() ); - - if (!findEdit->text().isEmpty() && mTextpage->document()->find(findEdit->text()).position() < 0 ) { - bgPalette.setColor( QPalette::Base, "#ececba"); - } else { - bgPalette.setColor( QPalette::Base, Qt::white); - } - findEdit->setPalette(bgPalette); +void FindWidget::setBackground() { + QTextCursor cursor = mTextpage->textCursor(); + // if match is found set background of QLineEdit to white, otherwise to red + QPalette bgPalette(findEdit->palette()); + + if (!findEdit->text().isEmpty() && + mTextpage->document()->find(findEdit->text()).position() < 0) { + bgPalette.setColor(QPalette::Base, "#ececba"); + } else { + bgPalette.setColor(QPalette::Base, Qt::white); + } + findEdit->setPalette(bgPalette); } -void FindWidget::slotFindNext() -{ - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively); - - // if end of document is reached, restart search from beginning - if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if(cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); +void FindWidget::slotFindNext() { + QTextCursor cursor = mTextpage->textCursor(); + cursor = mTextpage->document()->find(findEdit->text(), cursor, + QTextDocument::FindCaseSensitively); + + // if end of document is reached, restart search from beginning + if (cursor.position() == -1) { + cursor = mTextpage->document()->find(findEdit->text(), cursor, + QTextDocument::FindCaseSensitively); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + mTextpage->setTextCursor(cursor); + } + this->setBackground(); } -void FindWidget::slotFind() -{ - QTextCursor cursor = mTextpage->textCursor(); - - if (cursor.anchor() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively); - } else { - cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(), QTextDocument::FindCaseSensitively); - } - - // if end of document is reached, restart search from beginning - if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), cursor, QTextDocument::FindCaseSensitively); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if(cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); +void FindWidget::slotFind() { + QTextCursor cursor = mTextpage->textCursor(); + + if (cursor.anchor() == -1) { + cursor = mTextpage->document()->find(findEdit->text(), cursor, + QTextDocument::FindCaseSensitively); + } else { + cursor = mTextpage->document()->find(findEdit->text(), cursor.anchor(), + QTextDocument::FindCaseSensitively); + } + + // if end of document is reached, restart search from beginning + if (cursor.position() == -1) { + cursor = mTextpage->document()->find(findEdit->text(), cursor, + QTextDocument::FindCaseSensitively); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + mTextpage->setTextCursor(cursor); + } + this->setBackground(); } -void FindWidget::slotFindPrevious() -{ - QTextDocument::FindFlags flags; - flags |= QTextDocument::FindBackward; - flags |= QTextDocument::FindCaseSensitively; - - QTextCursor cursor = mTextpage->textCursor(); - cursor = mTextpage->document()->find(findEdit->text(), cursor, flags); - - // if begin of document is reached, restart search from end - if (cursor.position() == -1) { - cursor = mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags); - } - - // cursor should not stay at -1, otherwise text is not editable - // todo: check how gedit handles this - if(cursor.position() != -1) { - mTextpage->setTextCursor(cursor); - } - this->setBackground(); +void FindWidget::slotFindPrevious() { + QTextDocument::FindFlags flags; + flags |= QTextDocument::FindBackward; + flags |= QTextDocument::FindCaseSensitively; + + QTextCursor cursor = mTextpage->textCursor(); + cursor = mTextpage->document()->find(findEdit->text(), cursor, flags); + + // if begin of document is reached, restart search from end + if (cursor.position() == -1) { + cursor = + mTextpage->document()->find(findEdit->text(), QTextCursor::End, flags); + } + + // cursor should not stay at -1, otherwise text is not editable + // todo: check how gedit handles this + if (cursor.position() != -1) { + mTextpage->setTextCursor(cursor); + } + this->setBackground(); } -void FindWidget::keyPressEvent( QKeyEvent* e ) -{ - switch ( e->key() ) - { +void FindWidget::keyPressEvent(QKeyEvent* e) { + switch (e->key()) { case Qt::Key_Escape: - this->slotClose(); - break; + this->slotClose(); + break; case Qt::Key_F3: - if (e->modifiers() & Qt::ShiftModifier) { - this->slotFindPrevious(); - } else { - this->slotFindNext(); - } - break; - } + if (e->modifiers() & Qt::ShiftModifier) { + this->slotFindPrevious(); + } else { + this->slotFindNext(); + } + break; + } } void FindWidget::slotClose() { - QTextCursor cursor = mTextpage->textCursor(); - - if ( cursor.position() == -1) { - cursor.setPosition(0); - mTextpage->setTextCursor(cursor); - } - mTextpage->setFocus(); - close(); + QTextCursor cursor = mTextpage->textCursor(); + + if (cursor.position() == -1) { + cursor.setPosition(0); + mTextpage->setTextCursor(cursor); + } + mTextpage->setFocus(); + close(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/FindWidget.h b/src/ui/FindWidget.h new file mode 100644 index 00000000..f57f95a6 --- /dev/null +++ b/src/ui/FindWidget.h @@ -0,0 +1,72 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef FINDWIDGET_H +#define FINDWIDGET_H + +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/EditorPage.h" + +namespace GpgFrontend::UI { + +/** + * @brief Class for handling the find widget shown at buttom of a textedit-page + */ +class FindWidget : public QWidget { + Q_OBJECT + + public: + /** + * @brief + * + * @param parent The parent widget + */ + explicit FindWidget(QWidget* parent, QTextEdit* edit); + + private: + void keyPressEvent(QKeyEvent* e) override; + + /** + * @details Set background of findEdit to red, if no match is found (Documents + * textcursor position equals -1), otherwise set it to white. + */ + void setBackground(); + + QTextEdit* mTextpage; /** Textedit associated to the notification */ + QLineEdit* findEdit; /** Label holding the text shown in infoBoard */ + + private slots: + + void slotFindNext(); + + void slotFindPrevious(); + + void slotFind(); + + void slotClose(); +}; + +} // namespace GpgFrontend::UI + +#endif // FINDWIDGET_H diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h new file mode 100644 index 00000000..42d125d6 --- /dev/null +++ b/src/ui/GpgFrontendUI.h @@ -0,0 +1,35 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_GPGFRONTENDUI_H +#define GPGFRONTEND_GPGFRONTENDUI_H + +#include <GpgFrontend.h> + +#include <QtCore> +#include <QtNetwork> +#include <QtPrintSupport> +#include <QtWidgets> + +#endif // GPGFRONTEND_GPGFRONTENDUI_H diff --git a/src/ui/KeyImportDetailDialog.cpp b/src/ui/KeyImportDetailDialog.cpp index 8614051b..d2f33a2e 100644 --- a/src/ui/KeyImportDetailDialog.cpp +++ b/src/ui/KeyImportDetailDialog.cpp @@ -22,145 +22,168 @@ * */ -#include <ui/KeyImportDetailDialog.h> - -KeyImportDetailDialog::KeyImportDetailDialog(GpgFrontend::GpgContext *ctx, GpgImportInformation result, bool automatic, - QWidget *parent) - : QDialog(parent), mCtx(ctx), mResult(std::move(result)) { - - // If no key for import found, just show a message - if (mResult.considered == 0) { - if(automatic) - QMessageBox::information(nullptr, tr("Key Update Details"), tr("No keys found")); - else - QMessageBox::information(nullptr, tr("Key Import Details"), tr("No keys found to import")); - return; - } +#include "ui/KeyImportDetailDialog.h" + +#include "gpg/function/GpgKeyGetter.h" + +namespace GpgFrontend::UI { +KeyImportDetailDialog::KeyImportDetailDialog(GpgImportInformation result, + bool automatic, + QWidget* parent) + : QDialog(parent), mResult(std::move(result)) { + // If no key for import found, just show a message + if (mResult.considered == 0) { + if (automatic) + QMessageBox::information(nullptr, tr("Key Update Details"), + tr("No keys found")); + else + QMessageBox::information(nullptr, tr("Key Import Details"), + tr("No keys found to import")); + return; + } - auto *mvbox = new QVBoxLayout(); + auto* mvbox = new QVBoxLayout(); - this->createGeneralInfoBox(); - mvbox->addWidget(generalInfoBox); + this->createGeneralInfoBox(); + mvbox->addWidget(generalInfoBox); - this->createKeysTable(); - mvbox->addWidget(keysTable); + this->createKeysTable(); + mvbox->addWidget(keysTable); - this->createButtonBox(); - mvbox->addWidget(buttonBox); + this->createButtonBox(); + mvbox->addWidget(buttonBox); - this->setLayout(mvbox); - if(automatic) - this->setWindowTitle(tr("Key Update Details")); - else - this->setWindowTitle(tr("Key Import Details")); + this->setLayout(mvbox); + if (automatic) + this->setWindowTitle(tr("Key Update Details")); + else + this->setWindowTitle(tr("Key Import Details")); - this->resize(QSize(600, 300)); - this->setModal(true); - this->exec(); + this->resize(QSize(600, 300)); + this->setModal(true); + this->exec(); } void KeyImportDetailDialog::createGeneralInfoBox() { - // GridBox for general import information - generalInfoBox = new QGroupBox(tr("General key info")); - auto *generalInfoBoxLayout = new QGridLayout(generalInfoBox); - - generalInfoBoxLayout->addWidget(new QLabel(tr("Considered:")), 1, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.considered)), 1, 1); - int row = 2; - if (mResult.unchanged != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Public unchanged:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.unchanged)), row, 1); - row++; - } - if (mResult.imported != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Imported:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.imported)), row, 1); - row++; - } - if (mResult.not_imported != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Not imported:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.not_imported)), row, 1); - row++; - } - if (mResult.secret_read != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Private read:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_read)), row, 1); - row++; - } - if (mResult.secret_imported != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Private imported:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_imported)), row, 1); - row++; - } - if (mResult.secret_unchanged != 0) { - generalInfoBoxLayout->addWidget(new QLabel(tr("Private unchanged:")), row, 0); - generalInfoBoxLayout->addWidget(new QLabel(QString::number(mResult.secret_unchanged)), row, 1); - row++; - } + // GridBox for general import information + generalInfoBox = new QGroupBox(tr("General key info")); + auto* generalInfoBoxLayout = new QGridLayout(generalInfoBox); + + generalInfoBoxLayout->addWidget(new QLabel(tr("Considered:")), 1, 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.considered)), 1, 1); + int row = 2; + if (mResult.unchanged != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Public unchanged:")), row, + 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.unchanged)), row, 1); + row++; + } + if (mResult.imported != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Imported:")), row, 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.imported)), row, 1); + row++; + } + if (mResult.not_imported != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Not imported:")), row, 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.not_imported)), row, 1); + row++; + } + if (mResult.secret_read != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Private read:")), row, 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.secret_read)), row, 1); + row++; + } + if (mResult.secret_imported != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Private imported:")), row, + 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.secret_imported)), row, 1); + row++; + } + if (mResult.secret_unchanged != 0) { + generalInfoBoxLayout->addWidget(new QLabel(tr("Private unchanged:")), row, + 0); + generalInfoBoxLayout->addWidget( + new QLabel(QString::number(mResult.secret_unchanged)), row, 1); + row++; + } } void KeyImportDetailDialog::createKeysTable() { - keysTable = new QTableWidget(this); - keysTable->setRowCount(0); - keysTable->setColumnCount(4); - keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - // Nothing is selectable - keysTable->setSelectionMode(QAbstractItemView::NoSelection); - - QStringList headerLabels; - headerLabels << tr("Name") << tr("Email") << tr("Status") << tr("Fingerprint"); - keysTable->verticalHeader()->hide(); - - keysTable->setHorizontalHeaderLabels(headerLabels); - int row = 0; - for (const auto &impKey : mResult.importedKeys) { - keysTable->setRowCount(row + 1); - GpgKey key = mCtx->getKeyRefByFpr(impKey.fpr); - if(!key.good) continue; - keysTable->setItem(row, 0, new QTableWidgetItem(key.name)); - keysTable->setItem(row, 1, new QTableWidgetItem(key.email)); - keysTable->setItem(row, 2, new QTableWidgetItem(getStatusString(impKey.importStatus))); - keysTable->setItem(row, 3, new QTableWidgetItem(impKey.fpr)); - row++; - } - keysTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); - keysTable->horizontalHeader()->setStretchLastSection(true); - keysTable->resizeColumnsToContents(); + keysTable = new QTableWidget(this); + keysTable->setRowCount(0); + keysTable->setColumnCount(4); + keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + // Nothing is selectable + keysTable->setSelectionMode(QAbstractItemView::NoSelection); + + QStringList headerLabels; + headerLabels << tr("Name") << tr("Email") << tr("Status") + << tr("Fingerprint"); + keysTable->verticalHeader()->hide(); + + keysTable->setHorizontalHeaderLabels(headerLabels); + int row = 0; + for (const auto& imp_key : mResult.importedKeys) { + keysTable->setRowCount(row + 1); + GpgKey key = GpgKeyGetter::GetInstance().GetKey(imp_key.fpr); + if (!key.good()) + continue; + keysTable->setItem( + row, 0, new QTableWidgetItem(QString::fromStdString(key.name()))); + keysTable->setItem( + row, 1, new QTableWidgetItem(QString::fromStdString(key.email()))); + keysTable->setItem( + row, 2, new QTableWidgetItem(getStatusString(imp_key.import_status))); + keysTable->setItem( + row, 3, new QTableWidgetItem(QString::fromStdString(imp_key.fpr))); + row++; + } + keysTable->horizontalHeader()->setSectionResizeMode( + 0, QHeaderView::ResizeToContents); + keysTable->horizontalHeader()->setStretchLastSection(true); + keysTable->resizeColumnsToContents(); } QString KeyImportDetailDialog::getStatusString(int keyStatus) { - QString statusString; - // keystatus is greater than 15, if key is private - if (keyStatus > 15) { - statusString.append(tr("private")); - keyStatus = keyStatus - 16; - } else { - statusString.append(tr("public")); - } - if (keyStatus == 0) { - statusString.append(", " + tr("unchanged")); + QString statusString; + // keystatus is greater than 15, if key is private + if (keyStatus > 15) { + statusString.append(tr("private")); + keyStatus = keyStatus - 16; + } else { + statusString.append(tr("public")); + } + if (keyStatus == 0) { + statusString.append(", " + tr("unchanged")); + } else { + if (keyStatus == 1) { + statusString.append(", " + tr("new key")); } else { - if (keyStatus == 1) { - statusString.append(", " + tr("new key")); - } else { - if (keyStatus > 7) { - statusString.append(", " + tr("new subkey")); - keyStatus = keyStatus - 8; - } - if (keyStatus > 3) { - statusString.append(", " + tr("new signature")); - keyStatus = keyStatus - 4; - } - if (keyStatus > 1) { - statusString.append(", " + tr("new uid")); - keyStatus = keyStatus - 2; - } - } + if (keyStatus > 7) { + statusString.append(", " + tr("new subkey")); + keyStatus = keyStatus - 8; + } + if (keyStatus > 3) { + statusString.append(", " + tr("new signature")); + keyStatus = keyStatus - 4; + } + if (keyStatus > 1) { + statusString.append(", " + tr("new uid")); + keyStatus = keyStatus - 2; + } } - return statusString; + } + return statusString; } void KeyImportDetailDialog::createButtonBox() { - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); + buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); } +} // namespace GpgFrontend::UI diff --git a/src/ui/KeyImportDetailDialog.h b/src/ui/KeyImportDetailDialog.h new file mode 100644 index 00000000..e3137503 --- /dev/null +++ b/src/ui/KeyImportDetailDialog.h @@ -0,0 +1,56 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYIMPORTDETAILSDIALOG_H__ +#define __KEYIMPORTDETAILSDIALOG_H__ + +#include <gpg/function/GpgKeyImportExportor.h> +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { +class KeyImportDetailDialog : public QDialog { + Q_OBJECT + + public: + KeyImportDetailDialog(GpgImportInformation result, + bool automatic, + QWidget* parent = nullptr); + + private: + void createGeneralInfoBox(); + void createKeysTable(); + void createButtonBox(); + static QString getStatusString(int keyStatus); + + QTableWidget* keysTable{}; + GpgFrontend::GpgContext* mCtx; + QGroupBox* generalInfoBox{}; + QGroupBox* keyInfoBox{}; + QDialogButtonBox* buttonBox{}; + GpgImportInformation mResult; +}; +} // namespace GpgFrontend::UI + +#endif // __KEYIMPORTDETAILSDIALOG_H__ diff --git a/src/ui/KeyMgmt.cpp b/src/ui/KeyMgmt.cpp index 9f3665d3..6d15a1eb 100755 --- a/src/ui/KeyMgmt.cpp +++ b/src/ui/KeyMgmt.cpp @@ -26,331 +26,345 @@ #include <utility> -KeyMgmt::KeyMgmt(GpgFrontend::GpgContext *ctx, QWidget *parent) : - QMainWindow(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) { - mCtx = ctx; - - /* the list of Keys available*/ - mKeyList = new KeyList(mCtx); - mKeyList->setColumnWidth(2, 250); - mKeyList->setColumnWidth(3, 250); - setCentralWidget(mKeyList); - mKeyList->setDoubleClickedAction([this](const GpgKey &key, QWidget *parent) { - new KeyDetailsDialog(mCtx, key, parent); - }); - - createActions(); - createMenus(); - createToolBars(); - connect(this, SIGNAL(signalStatusBarChanged(QString)), this->parent(), SLOT(slotSetStatusBarText(QString))); - - /* Restore the iconstyle */ - this->settings.sync(); - - QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); - settings.setValue("toolbar/iconsize", iconSize); - - Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>(settings.value("toolbar/iconstyle", - Qt::ToolButtonTextUnderIcon).toUInt()); - this->setIconSize(iconSize); - this->setToolButtonStyle(buttonStyle); - - // state sets pos & size of dock-widgets - this->restoreState(this->settings.value("keymgmt/windowState").toByteArray()); - - qDebug() << "windows/windowSave" << this->settings.value("window/windowSave").toBool(); - - // Restore window size & location - if (this->settings.value("keymgmt/setWindowSize").toBool()) { - QPoint pos = settings.value("keymgmt/pos", QPoint(100, 100)).toPoint(); - QSize size = settings.value("keymgmt/size", QSize(900, 600)).toSize(); - qDebug() << "Settings size" << size << "pos" << pos; - this->setMinimumSize(size); - this->move(pos); - } else { - qDebug() << "Use default min windows size and pos"; - QPoint defaultPoint(100, 100); - QSize defaultMinSize(900, 600); - this->setMinimumSize(defaultMinSize); - this->move(defaultPoint); - this->settings.setValue("keymgmt/pos", defaultPoint); - this->settings.setValue("keymgmt/size", defaultMinSize); - this->settings.setValue("keymgmt/setWindowSize", true); - } - - setWindowTitle(tr("Key Pair Management")); - mKeyList->addMenuAction(deleteSelectedKeysAct); - mKeyList->addMenuAction(showKeyDetailsAct); +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyImportExportor.h" +#include "gpg/function/GpgKeyOpera.h" + +namespace GpgFrontend::UI { +KeyMgmt::KeyMgmt(QWidget* parent) + : QMainWindow(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + /* the list of Keys available*/ + mKeyList = new KeyList(); + mKeyList->setColumnWidth(2, 250); + mKeyList->setColumnWidth(3, 250); + setCentralWidget(mKeyList); + mKeyList->setDoubleClickedAction([this](const GpgKey& key, QWidget* parent) { + new KeyDetailsDialog(key, parent); + }); + + createActions(); + createMenus(); + createToolBars(); + connect(this, SIGNAL(signalStatusBarChanged(QString)), this->parent(), + SLOT(slotSetStatusBarText(QString))); + + /* Restore the iconstyle */ + this->settings.sync(); + + QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); + settings.setValue("toolbar/iconsize", iconSize); + + Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>( + settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) + .toUInt()); + this->setIconSize(iconSize); + this->setToolButtonStyle(buttonStyle); + + // state sets pos & size of dock-widgets + this->restoreState(this->settings.value("keymgmt/windowState").toByteArray()); + + qDebug() << "windows/windowSave" + << this->settings.value("window/windowSave").toBool(); + + // Restore window size & location + if (this->settings.value("keymgmt/setWindowSize").toBool()) { + QPoint pos = settings.value("keymgmt/pos", QPoint(100, 100)).toPoint(); + QSize size = settings.value("keymgmt/size", QSize(900, 600)).toSize(); + qDebug() << "Settings size" << size << "pos" << pos; + this->setMinimumSize(size); + this->move(pos); + } else { + qDebug() << "Use default min windows size and pos"; + QPoint defaultPoint(100, 100); + QSize defaultMinSize(900, 600); + this->setMinimumSize(defaultMinSize); + this->move(defaultPoint); + this->settings.setValue("keymgmt/pos", defaultPoint); + this->settings.setValue("keymgmt/size", defaultMinSize); + this->settings.setValue("keymgmt/setWindowSize", true); + } + + setWindowTitle(tr("Key Pair Management")); + mKeyList->addMenuAction(deleteSelectedKeysAct); + mKeyList->addMenuAction(showKeyDetailsAct); } void KeyMgmt::createActions() { - openKeyFileAct = new QAction(tr("&Open"), this); - openKeyFileAct->setShortcut(tr("Ctrl+O")); - openKeyFileAct->setToolTip(tr("Open Key File")); - connect(openKeyFileAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromFile())); - - closeAct = new QAction(tr("&Close"), this); - closeAct->setShortcut(tr("Ctrl+Q")); - closeAct->setIcon(QIcon(":exit.png")); - closeAct->setToolTip(tr("Close")); - connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); - - generateKeyPairAct = new QAction(tr("New Keypair"), this); - generateKeyPairAct->setShortcut(tr("Ctrl+N")); - generateKeyPairAct->setIcon(QIcon(":key_generate.png")); - generateKeyPairAct->setToolTip(tr("Generate KeyPair")); - connect(generateKeyPairAct, SIGNAL(triggered()), this, SLOT(slotGenerateKeyDialog())); - - generateSubKeyAct = new QAction(tr("New Subkey"), this); - generateSubKeyAct->setShortcut(tr("Ctrl+Shift+N")); - generateSubKeyAct->setIcon(QIcon(":key_generate.png")); - generateSubKeyAct->setToolTip(tr("Generate Subkey For Selected KeyPair")); - connect(generateSubKeyAct, SIGNAL(triggered()), this, SLOT(slotGenerateSubKey())); - - importKeyFromFileAct = new QAction(tr("&File"), this); - importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png")); - importKeyFromFileAct->setToolTip(tr("Import New Key From File")); - connect(importKeyFromFileAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromFile())); - - importKeyFromClipboardAct = new QAction(tr("&Clipboard"), this); - importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png")); - importKeyFromClipboardAct->setToolTip(tr("Import New Key From Clipboard")); - connect(importKeyFromClipboardAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromClipboard())); - - importKeyFromKeyServerAct = new QAction(tr("&Keyserver"), this); - importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png")); - importKeyFromKeyServerAct->setToolTip(tr("Import New Key From Keyserver")); - connect(importKeyFromKeyServerAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromKeyServer())); - - exportKeyToClipboardAct = new QAction(tr("Export To &Clipboard"), this); - exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png")); - exportKeyToClipboardAct->setToolTip(tr("Export Selected Key(s) To Clipboard")); - connect(exportKeyToClipboardAct, SIGNAL(triggered()), this, SLOT(slotExportKeyToClipboard())); - - exportKeyToFileAct = new QAction(tr("Export To &File"), this); - exportKeyToFileAct->setIcon(QIcon(":export_key_to_file.png")); - exportKeyToFileAct->setToolTip(tr("Export Selected Key(s) To File")); - connect(exportKeyToFileAct, SIGNAL(triggered()), this, SLOT(slotExportKeyToFile())); - - deleteSelectedKeysAct = new QAction(tr("Delete Selected Key(s)"), this); - deleteSelectedKeysAct->setToolTip(tr("Delete the Selected keys")); - connect(deleteSelectedKeysAct, SIGNAL(triggered()), this, SLOT(slotDeleteSelectedKeys())); - - deleteCheckedKeysAct = new QAction(tr("Delete Checked Key(s)"), this); - deleteCheckedKeysAct->setToolTip(tr("Delete the Checked keys")); - deleteCheckedKeysAct->setIcon(QIcon(":button_delete.png")); - connect(deleteCheckedKeysAct, SIGNAL(triggered()), this, SLOT(slotDeleteCheckedKeys())); - - showKeyDetailsAct = new QAction(tr("Show Key Details"), this); - showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); - connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(slotShowKeyDetails())); + openKeyFileAct = new QAction(tr("&Open"), this); + openKeyFileAct->setShortcut(tr("Ctrl+O")); + openKeyFileAct->setToolTip(tr("Open Key File")); + connect(openKeyFileAct, SIGNAL(triggered()), this, + SLOT(slotImportKeyFromFile())); + + closeAct = new QAction(tr("&Close"), this); + closeAct->setShortcut(tr("Ctrl+Q")); + closeAct->setIcon(QIcon(":exit.png")); + closeAct->setToolTip(tr("Close")); + connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); + + generateKeyPairAct = new QAction(tr("New Keypair"), this); + generateKeyPairAct->setShortcut(tr("Ctrl+N")); + generateKeyPairAct->setIcon(QIcon(":key_generate.png")); + generateKeyPairAct->setToolTip(tr("Generate KeyPair")); + connect(generateKeyPairAct, SIGNAL(triggered()), this, + SLOT(slotGenerateKeyDialog())); + + generateSubKeyAct = new QAction(tr("New Subkey"), this); + generateSubKeyAct->setShortcut(tr("Ctrl+Shift+N")); + generateSubKeyAct->setIcon(QIcon(":key_generate.png")); + generateSubKeyAct->setToolTip(tr("Generate Subkey For Selected KeyPair")); + connect(generateSubKeyAct, SIGNAL(triggered()), this, + SLOT(slotGenerateSubKey())); + + importKeyFromFileAct = new QAction(tr("&File"), this); + importKeyFromFileAct->setIcon(QIcon(":import_key_from_file.png")); + importKeyFromFileAct->setToolTip(tr("Import New Key From File")); + connect(importKeyFromFileAct, SIGNAL(triggered()), this, + SLOT(slotImportKeyFromFile())); + + importKeyFromClipboardAct = new QAction(tr("&Clipboard"), this); + importKeyFromClipboardAct->setIcon(QIcon(":import_key_from_clipboard.png")); + importKeyFromClipboardAct->setToolTip(tr("Import New Key From Clipboard")); + connect(importKeyFromClipboardAct, SIGNAL(triggered()), this, + SLOT(slotImportKeyFromClipboard())); + + importKeyFromKeyServerAct = new QAction(tr("&Keyserver"), this); + importKeyFromKeyServerAct->setIcon(QIcon(":import_key_from_server.png")); + importKeyFromKeyServerAct->setToolTip(tr("Import New Key From Keyserver")); + connect(importKeyFromKeyServerAct, SIGNAL(triggered()), this, + SLOT(slotImportKeyFromKeyServer())); + + exportKeyToClipboardAct = new QAction(tr("Export To &Clipboard"), this); + exportKeyToClipboardAct->setIcon(QIcon(":export_key_to_clipboard.png")); + exportKeyToClipboardAct->setToolTip( + tr("Export Selected Key(s) To Clipboard")); + connect(exportKeyToClipboardAct, SIGNAL(triggered()), this, + SLOT(slotExportKeyToClipboard())); + + exportKeyToFileAct = new QAction(tr("Export To &File"), this); + exportKeyToFileAct->setIcon(QIcon(":export_key_to_file.png")); + exportKeyToFileAct->setToolTip(tr("Export Selected Key(s) To File")); + connect(exportKeyToFileAct, SIGNAL(triggered()), this, + SLOT(slotExportKeyToFile())); + + deleteSelectedKeysAct = new QAction(tr("Delete Selected Key(s)"), this); + deleteSelectedKeysAct->setToolTip(tr("Delete the Selected keys")); + connect(deleteSelectedKeysAct, SIGNAL(triggered()), this, + SLOT(slotDeleteSelectedKeys())); + + deleteCheckedKeysAct = new QAction(tr("Delete Checked Key(s)"), this); + deleteCheckedKeysAct->setToolTip(tr("Delete the Checked keys")); + deleteCheckedKeysAct->setIcon(QIcon(":button_delete.png")); + connect(deleteCheckedKeysAct, SIGNAL(triggered()), this, + SLOT(slotDeleteCheckedKeys())); + + showKeyDetailsAct = new QAction(tr("Show Key Details"), this); + showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); + connect(showKeyDetailsAct, SIGNAL(triggered()), this, + SLOT(slotShowKeyDetails())); } void KeyMgmt::createMenus() { - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(openKeyFileAct); - fileMenu->addAction(closeAct); - - keyMenu = menuBar()->addMenu(tr("&Key")); - generateKeyMenu = keyMenu->addMenu(tr("&Generate Key")); - generateKeyMenu->addAction(generateKeyPairAct); - generateKeyMenu->addAction(generateSubKeyAct); - - importKeyMenu = keyMenu->addMenu(tr("&Import Key")); - importKeyMenu->addAction(importKeyFromFileAct); - importKeyMenu->addAction(importKeyFromClipboardAct); - importKeyMenu->addAction(importKeyFromKeyServerAct); - keyMenu->addAction(exportKeyToFileAct); - keyMenu->addAction(exportKeyToClipboardAct); - keyMenu->addSeparator(); - keyMenu->addAction(deleteCheckedKeysAct); + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(openKeyFileAct); + fileMenu->addAction(closeAct); + + keyMenu = menuBar()->addMenu(tr("&Key")); + generateKeyMenu = keyMenu->addMenu(tr("&Generate Key")); + generateKeyMenu->addAction(generateKeyPairAct); + generateKeyMenu->addAction(generateSubKeyAct); + + importKeyMenu = keyMenu->addMenu(tr("&Import Key")); + importKeyMenu->addAction(importKeyFromFileAct); + importKeyMenu->addAction(importKeyFromClipboardAct); + importKeyMenu->addAction(importKeyFromKeyServerAct); + keyMenu->addAction(exportKeyToFileAct); + keyMenu->addAction(exportKeyToClipboardAct); + keyMenu->addSeparator(); + keyMenu->addAction(deleteCheckedKeysAct); } void KeyMgmt::createToolBars() { - QToolBar *keyToolBar = addToolBar(tr("Key")); - keyToolBar->setObjectName("keytoolbar"); - - // add button with popup menu for import - auto *generateToolButton = new QToolButton(this); - generateToolButton->setMenu(generateKeyMenu); - generateToolButton->setPopupMode(QToolButton::InstantPopup); - generateToolButton->setIcon(QIcon(":key_generate.png")); - generateToolButton->setText(tr("Generate")); - generateToolButton->setToolTip(tr("Generate A New Keypair or Subkey")); - generateToolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - keyToolBar->addWidget(generateToolButton); - - // add button with popup menu for import - auto *toolButton = new QToolButton(this); - toolButton->setMenu(importKeyMenu); - toolButton->setPopupMode(QToolButton::InstantPopup); - toolButton->setIcon(QIcon(":key_import.png")); - toolButton->setToolTip(tr("Import key")); - toolButton->setText(tr("Import Key")); - toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - keyToolBar->addWidget(toolButton); - - keyToolBar->addSeparator(); - keyToolBar->addAction(deleteCheckedKeysAct); - keyToolBar->addSeparator(); - keyToolBar->addAction(exportKeyToFileAct); - keyToolBar->addAction(exportKeyToClipboardAct); - + QToolBar* keyToolBar = addToolBar(tr("Key")); + keyToolBar->setObjectName("keytoolbar"); + + // add button with popup menu for import + auto* generateToolButton = new QToolButton(this); + generateToolButton->setMenu(generateKeyMenu); + generateToolButton->setPopupMode(QToolButton::InstantPopup); + generateToolButton->setIcon(QIcon(":key_generate.png")); + generateToolButton->setText(tr("Generate")); + generateToolButton->setToolTip(tr("Generate A New Keypair or Subkey")); + generateToolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + keyToolBar->addWidget(generateToolButton); + + // add button with popup menu for import + auto* toolButton = new QToolButton(this); + toolButton->setMenu(importKeyMenu); + toolButton->setPopupMode(QToolButton::InstantPopup); + toolButton->setIcon(QIcon(":key_import.png")); + toolButton->setToolTip(tr("Import key")); + toolButton->setText(tr("Import Key")); + toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + keyToolBar->addWidget(toolButton); + + keyToolBar->addSeparator(); + keyToolBar->addAction(deleteCheckedKeysAct); + keyToolBar->addSeparator(); + keyToolBar->addAction(exportKeyToFileAct); + keyToolBar->addAction(exportKeyToClipboardAct); } -void KeyMgmt::slotImportKeys(QByteArray inBuffer) { - GpgImportInformation result = mCtx->importKey(std::move(inBuffer)); - new KeyImportDetailDialog(mCtx, result, false, this); - +void KeyMgmt::slotImportKeys(ByteArrayPtr in_buffer) { + GpgImportInformation result = + GpgKeyImportExportor::GetInstance().ImportKey(std::move(in_buffer)); + new KeyImportDetailDialog(result, false, this); } void KeyMgmt::slotImportKeyFromFile() { - QString fileName = QFileDialog::getOpenFileName(this, tr("Open Key"), "", - tr("Key Files") + " (*.asc *.txt);;" + tr("Keyring files") + - " (*.gpg);;All Files (*)"); - if (!fileName.isNull()) { - QFile file; - file.setFileName(fileName); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << tr("Couldn't Open File: ") + fileName; - return; - } - QByteArray inBuffer = file.readAll(); - slotImportKeys(inBuffer); - file.close(); - } + QString file_name = QFileDialog::getOpenFileName( + this, tr("Open Key"), "", + tr("Key Files") + " (*.asc *.txt);;" + tr("Keyring files") + + " (*.gpg);;All Files (*)"); + if (!file_name.isNull()) { + slotImportKeys(std::make_unique<ByteArray>( + read_all_data_in_file(file_name.toStdString()))); + } } void KeyMgmt::slotImportKeyFromKeyServer() { - importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this); - importDialog->show(); + importDialog = new KeyServerImportDialog(mKeyList, false, this); + importDialog->show(); } void KeyMgmt::slotImportKeyFromClipboard() { - QClipboard *cb = QApplication::clipboard(); - slotImportKeys(cb->text(QClipboard::Clipboard).toUtf8()); + QClipboard* cb = QApplication::clipboard(); + slotImportKeys(std::make_unique<ByteArray>( + cb->text(QClipboard::Clipboard).toUtf8().toStdString())); } void KeyMgmt::slotDeleteSelectedKeys() { - deleteKeysWithWarning(mKeyList->getSelected()); + deleteKeysWithWarning(mKeyList->getSelected()); } void KeyMgmt::slotDeleteCheckedKeys() { - deleteKeysWithWarning(mKeyList->getChecked()); + deleteKeysWithWarning(mKeyList->getChecked()); } -void KeyMgmt::deleteKeysWithWarning(QStringList *uidList) { - /** - * TODO: Different Messages for private/public key, check if - * more than one selected... compare to seahorse "delete-dialog" - */ - - if (uidList->isEmpty()) { - return; - } - QString keynames; - for (const auto &uid : *uidList) { - auto key = mCtx->getKeyRefById(uid); - if (!key.good) continue; - keynames.append(key.name); - keynames.append("<i> <"); - keynames.append(key.email); - keynames.append("> </i><br/>"); - } - - int ret = QMessageBox::warning(this, tr("Deleting Keys"), - "<b>" + tr("Are you sure that you want to delete the following keys?") + - "</b><br/><br/>" + keynames + - +"<br/>" + tr("The action can not be undone."), - QMessageBox::No | QMessageBox::Yes); - - if (ret == QMessageBox::Yes) { - mCtx->deleteKeys(uidList); - } +void KeyMgmt::deleteKeysWithWarning(KeyIdArgsListPtr key_ids) { + /** + * TODO: Different Messages for private/public key, check if + * more than one selected... compare to seahorse "delete-dialog" + */ + + if (key_ids->empty()) + return; + QString keynames; + for (const auto& key_id : *key_ids) { + auto key = GpgKeyGetter::GetInstance().GetKey(key_id); + if (!key.good()) + continue; + keynames.append(QString::fromStdString(key.name())); + keynames.append("<i> <"); + keynames.append(QString::fromStdString(key.email())); + keynames.append("> </i><br/>"); + } + + int ret = QMessageBox::warning( + this, tr("Deleting Keys"), + "<b>" + tr("Are you sure that you want to delete the following keys?") + + "</b><br/><br/>" + keynames + +"<br/>" + + tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) + GpgKeyOpera::GetInstance().DeleteKeys(std::move(key_ids)); } void KeyMgmt::slotShowKeyDetails() { - if (mKeyList->getSelected()->isEmpty()) { - return; - } + auto keys_selected = mKeyList->getSelected(); + if (keys_selected->empty()) + return; - auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); + auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); - if (!key.good) { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - return; - } + if (!key.good()) { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + return; + } - new KeyDetailsDialog(mCtx, key); + new KeyDetailsDialog(key); } void KeyMgmt::slotExportKeyToFile() { - auto *keyArray = new QByteArray(); - if (!mCtx->exportKeys(mKeyList->getChecked(), keyArray)) { - delete keyArray; - return; - } - auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); - if (!key.good) { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - return; - } - QString fileString = key.name + " " + key.email + "(" + key.id + ")_pub.asc"; - - QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString, - tr("Key Files") + " (*.asc *.txt);;All Files (*)"); - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - delete keyArray; - return; - } - QTextStream stream(&file); - stream << *keyArray; - file.close(); - delete keyArray; - emit signalStatusBarChanged(QString(tr("key(s) exported"))); + ByteArrayPtr key_export_data = nullptr; + auto keys_checked = mKeyList->getChecked(); + if (!GpgKeyImportExportor::GetInstance().ExportKeys(keys_checked, + key_export_data)) { + return; + } + auto key = + GpgKeyGetter::GetInstance().GetKey(mKeyList->getSelected()->front()); + if (!key.good()) { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + return; + } + QString fileString = QString::fromStdString(key.name() + " " + key.email() + + "(" + key.id() + ")_pub.asc"); + + QString file_name = QFileDialog::getSaveFileName( + this, tr("Export Key To File"), fileString, + tr("Key Files") + " (*.asc *.txt);;All Files (*)"); + + write_buffer_to_file(file_name.toStdString(), *key_export_data); + + emit signalStatusBarChanged(QString(tr("key(s) exported"))); } void KeyMgmt::slotExportKeyToClipboard() { - auto *keyArray = new QByteArray(); - QClipboard *cb = QApplication::clipboard(); - if (!mCtx->exportKeys(mKeyList->getChecked(), keyArray)) { - return; - } - cb->setText(*keyArray); - delete keyArray; + ByteArrayPtr key_export_data = nullptr; + auto keys_checked = mKeyList->getChecked(); + if (!GpgKeyImportExportor::GetInstance().ExportKeys(keys_checked, + key_export_data)) { + return; + } + QApplication::clipboard()->setText(QString::fromStdString(*key_export_data)); } void KeyMgmt::slotGenerateKeyDialog() { - auto *keyGenDialog = new KeyGenDialog(mCtx, this); - keyGenDialog->show(); + auto* keyGenDialog = new KeyGenDialog(this); + keyGenDialog->show(); } -void KeyMgmt::closeEvent(QCloseEvent *event) { - QMainWindow::closeEvent(event); +void KeyMgmt::closeEvent(QCloseEvent* event) { + QMainWindow::closeEvent(event); } void KeyMgmt::slotGenerateSubKey() { - auto selectedList = mKeyList->getSelected(); - if (selectedList->empty()) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one KeyPair before doing this operation.")); - return; - } - const auto key = mCtx->getKeyRefById(selectedList->first()); - if (!key.good) { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - return; - } - if (!key.is_private_key) { - QMessageBox::critical(nullptr, - tr("Invalid Operation"), - tr("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(mCtx, key, this); - dialog->show(); + auto keys_selected = mKeyList->getSelected(); + if (keys_selected->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one KeyPair before doing this operation.")); + return; + } + const auto key = GpgKeyGetter::GetInstance().GetKey(keys_selected->front()); + if (!key.good()) { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + return; + } + if (!key.is_private_key()) { + QMessageBox::critical(nullptr, tr("Invalid Operation"), + tr("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.id(), this); + dialog->show(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/KeyMgmt.h b/src/ui/KeyMgmt.h new file mode 100755 index 00000000..deddb4f7 --- /dev/null +++ b/src/ui/KeyMgmt.h @@ -0,0 +1,111 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYMGMT_H__ +#define __KEYMGMT_H__ + +#include "KeyImportDetailDialog.h" +#include "KeyServerImportDialog.h" +#include "ui/GpgFrontendUI.h" +#include "ui/keygen/KeygenDialog.h" +#include "ui/keypair_details/KeyDetailsDialog.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class KeyMgmt : public QMainWindow { + Q_OBJECT + + public: + explicit KeyMgmt(QWidget* parent = nullptr); + + QAction* importKeyFromClipboardAct{}; + QAction* importKeyFromFileAct{}; + QAction* importKeyFromKeyServerAct{}; + + QAction* generateKeyPairAct{}; + QAction* generateSubKeyAct{}; + + public slots: + + void slotGenerateSubKey(); + + void slotImportKeyFromFile(); + + void slotImportKeyFromClipboard(); + + void slotImportKeyFromKeyServer(); + + void slotImportKeys(GpgFrontend::ByteArrayPtr in_buffer); + + void slotExportKeyToFile(); + + void slotExportKeyToClipboard(); + + void slotDeleteSelectedKeys(); + + void slotDeleteCheckedKeys(); + + void slotGenerateKeyDialog(); + + void slotShowKeyDetails(); + + signals: + + void signalStatusBarChanged(QString); + + private: + void createMenus(); + + void createActions(); + + void createToolBars(); + + void deleteKeysWithWarning(GpgFrontend::KeyIdArgsListPtr uidList); + + QString appPath; + QSettings settings; + + KeyList* mKeyList; + QMenu* fileMenu{}; + QMenu* keyMenu{}; + QMenu* generateKeyMenu{}; + QMenu* importKeyMenu{}; + QAction* openKeyFileAct{}; + QAction* exportKeyToFileAct{}; + QAction* exportKeyToClipboardAct{}; + QAction* deleteCheckedKeysAct{}; + QAction* deleteSelectedKeysAct{}; + QAction* generateKeyDialogAct{}; + QAction* closeAct{}; + QAction* showKeyDetailsAct{}; + KeyServerImportDialog* importDialog{}; + + protected: + void closeEvent(QCloseEvent* event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYMGMT_H__ diff --git a/src/ui/KeyServerImportDialog.cpp b/src/ui/KeyServerImportDialog.cpp index 4343eb79..dae8f723 100644 --- a/src/ui/KeyServerImportDialog.cpp +++ b/src/ui/KeyServerImportDialog.cpp @@ -26,451 +26,479 @@ #include <utility> -KeyServerImportDialog::KeyServerImportDialog(GpgFrontend::GpgContext *ctx, KeyList *keyList, bool automatic, - QWidget *parent) - : QDialog(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat), - mCtx(ctx), mKeyList(keyList), mAutomatic(automatic) { - - if(automatic) { - setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); - } - - // Buttons - closeButton = createButton(tr("&Close"), SLOT(close())); - importButton = createButton(tr("&Import ALL"), SLOT(slotImport())); - searchButton = createButton(tr("&Search"), SLOT(slotSearch())); - - // Line edit for search string - searchLabel = new QLabel(tr("Search String:")); - searchLineEdit = new QLineEdit(); - - // combobox for keyserverlist - keyServerLabel = new QLabel(tr("Key Server:")); - keyServerComboBox = createComboBox(); - - // table containing the keys found - createKeysTable(); - message = new QLabel; - message->setFixedHeight(24); - icon = new QLabel; - icon->setFixedHeight(24); - - // Network Waiting - waitingBar = new QProgressBar(); - waitingBar->setVisible(false); - waitingBar->setRange(0, 0); - waitingBar->setFixedWidth(200); - - // Layout for messagebox - auto *messageLayout = new QHBoxLayout; - messageLayout->addWidget(icon); - messageLayout->addWidget(message); - messageLayout->addWidget(waitingBar); - messageLayout->addStretch(); - - // Layout for import and close button - auto *buttonsLayout = new QHBoxLayout; - buttonsLayout->addStretch(); - if(!automatic) - buttonsLayout->addWidget(importButton); - buttonsLayout->addWidget(closeButton); - - auto *mainLayout = new QGridLayout; - - // 自动化调用界面布局 - if(automatic) { - mainLayout->addLayout(messageLayout, 0, 0, 1, 3); - } else { - mainLayout->addWidget(searchLabel, 1, 0); - mainLayout->addWidget(searchLineEdit, 1, 1); - mainLayout->addWidget(searchButton, 1, 2); - mainLayout->addWidget(keyServerLabel, 2, 0); - mainLayout->addWidget(keyServerComboBox, 2, 1); - mainLayout->addWidget(keysTable, 3, 0, 1, 3); - mainLayout->addLayout(messageLayout, 4, 0, 1, 3); - mainLayout->addLayout(buttonsLayout, 6, 0, 1, 3); - } - - this->setLayout(mainLayout); - if(automatic) - this->setWindowTitle(tr("Update Keys from Keyserver")); - else - this->setWindowTitle(tr("Import Keys from Keyserver")); - - if(automatic) { - this->setFixedSize(240, 42); +#include "gpg/function/GpgKeyImportExportor.h" + +namespace GpgFrontend::UI { + +KeyServerImportDialog::KeyServerImportDialog(KeyList* keyList, + bool automatic, + QWidget* parent) + : QDialog(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mKeyList(keyList), + mAutomatic(automatic) { + if (automatic) { + setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); + } + + // Buttons + closeButton = createButton(tr("&Close"), SLOT(close())); + importButton = createButton(tr("&Import ALL"), SLOT(slotImport())); + searchButton = createButton(tr("&Search"), SLOT(slotSearch())); + + // Line edit for search string + searchLabel = new QLabel(tr("Search String:")); + searchLineEdit = new QLineEdit(); + + // combobox for keyserverlist + keyServerLabel = new QLabel(tr("Key Server:")); + keyServerComboBox = createComboBox(); + + // table containing the keys found + createKeysTable(); + message = new QLabel; + message->setFixedHeight(24); + icon = new QLabel; + icon->setFixedHeight(24); + + // Network Waiting + waitingBar = new QProgressBar(); + waitingBar->setVisible(false); + waitingBar->setRange(0, 0); + waitingBar->setFixedWidth(200); + + // Layout for messagebox + auto* messageLayout = new QHBoxLayout; + messageLayout->addWidget(icon); + messageLayout->addWidget(message); + messageLayout->addWidget(waitingBar); + messageLayout->addStretch(); + + // Layout for import and close button + auto* buttonsLayout = new QHBoxLayout; + buttonsLayout->addStretch(); + if (!automatic) + buttonsLayout->addWidget(importButton); + buttonsLayout->addWidget(closeButton); + + auto* mainLayout = new QGridLayout; + + // 自动化调用界面布局 + if (automatic) { + mainLayout->addLayout(messageLayout, 0, 0, 1, 3); + } else { + mainLayout->addWidget(searchLabel, 1, 0); + mainLayout->addWidget(searchLineEdit, 1, 1); + mainLayout->addWidget(searchButton, 1, 2); + mainLayout->addWidget(keyServerLabel, 2, 0); + mainLayout->addWidget(keyServerComboBox, 2, 1); + mainLayout->addWidget(keysTable, 3, 0, 1, 3); + mainLayout->addLayout(messageLayout, 4, 0, 1, 3); + mainLayout->addLayout(buttonsLayout, 6, 0, 1, 3); + } + + this->setLayout(mainLayout); + if (automatic) + this->setWindowTitle(tr("Update Keys from Keyserver")); + else + this->setWindowTitle(tr("Import Keys from Keyserver")); + + if (automatic) { + this->setFixedSize(240, 42); + } else { + // Restore window size & location + if (this->settings.value("ImportKeyFromServer/setWindowSize").toBool()) { + QPoint pos = + settings.value("ImportKeyFromServer/pos", QPoint(150, 150)).toPoint(); + QSize size = + settings.value("ImportKeyFromServer/size", QSize(500, 300)).toSize(); + qDebug() << "Settings size" << size << "pos" << pos; + this->setMinimumSize(size); + this->move(pos); } else { - // Restore window size & location - if (this->settings.value("ImportKeyFromServer/setWindowSize").toBool()) { - QPoint pos = settings.value("ImportKeyFromServer/pos", QPoint(150, 150)).toPoint(); - QSize size = settings.value("ImportKeyFromServer/size", QSize(500, 300)).toSize(); - qDebug() << "Settings size" << size << "pos" << pos; - this->setMinimumSize(size); - this->move(pos); - } else { - qDebug() << "Use default min windows size and pos"; - QPoint defaultPoint(150, 150); - QSize defaultMinSize(500, 300); - this->setMinimumSize(defaultMinSize); - this->move(defaultPoint); - this->settings.setValue("ImportKeyFromServer/pos", defaultPoint); - this->settings.setValue("ImportKeyFromServer/size", defaultMinSize); - this->settings.setValue("ImportKeyFromServer/setWindowSize", true); - } + qDebug() << "Use default min windows size and pos"; + QPoint defaultPoint(150, 150); + QSize defaultMinSize(500, 300); + this->setMinimumSize(defaultMinSize); + this->move(defaultPoint); + this->settings.setValue("ImportKeyFromServer/pos", defaultPoint); + this->settings.setValue("ImportKeyFromServer/size", defaultMinSize); + this->settings.setValue("ImportKeyFromServer/setWindowSize", true); } + } - this->setModal(true); + this->setModal(true); } -QPushButton *KeyServerImportDialog::createButton(const QString &text, const char *member) { - auto *button = new QPushButton(text); - connect(button, SIGNAL(clicked()), this, member); - return button; +QPushButton* KeyServerImportDialog::createButton(const QString& text, + const char* member) { + auto* button = new QPushButton(text); + connect(button, SIGNAL(clicked()), this, member); + return button; } -QComboBox *KeyServerImportDialog::createComboBox() { - auto *comboBox = new QComboBox; - comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); +QComboBox* KeyServerImportDialog::createComboBox() { + auto* comboBox = new QComboBox; + comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - // Read keylist from ini-file and fill it into combobox - comboBox->addItems(settings.value("keyserver/keyServerList").toStringList()); + // Read keylist from ini-file and fill it into combobox + comboBox->addItems(settings.value("keyserver/keyServerList").toStringList()); - // set default keyserver in combobox - QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); - comboBox->setCurrentIndex(comboBox->findText(keyserver)); + // set default keyserver in combobox + QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); + comboBox->setCurrentIndex(comboBox->findText(keyserver)); - return comboBox; + return comboBox; } void KeyServerImportDialog::createKeysTable() { - keysTable = new QTableWidget(); - keysTable->setColumnCount(4); + keysTable = new QTableWidget(); + keysTable->setColumnCount(4); - // always a whole row is marked - keysTable->setSelectionBehavior(QAbstractItemView::SelectRows); - keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + // always a whole row is marked + keysTable->setSelectionBehavior(QAbstractItemView::SelectRows); + keysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - // Make just one row selectable - keysTable->setSelectionMode(QAbstractItemView::SingleSelection); + // Make just one row selectable + keysTable->setSelectionMode(QAbstractItemView::SingleSelection); - QStringList labels; - labels << tr("UID") << tr("Creation date") << tr("KeyID") << tr("Tag"); - keysTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); - keysTable->setHorizontalHeaderLabels(labels); - keysTable->verticalHeader()->hide(); + QStringList labels; + labels << tr("UID") << tr("Creation date") << tr("KeyID") << tr("Tag"); + keysTable->horizontalHeader()->setSectionResizeMode( + 0, QHeaderView::ResizeToContents); + keysTable->setHorizontalHeaderLabels(labels); + keysTable->verticalHeader()->hide(); - connect(keysTable, SIGNAL(cellActivated(int, int)), - this, SLOT(slotImport())); + connect(keysTable, SIGNAL(cellActivated(int, int)), this, SLOT(slotImport())); } -void KeyServerImportDialog::setMessage(const QString &text, bool error) { - message->setText(text); - if (error) { - icon->setPixmap(QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); - } else { - icon->setPixmap(QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); - } +void KeyServerImportDialog::setMessage(const QString& text, bool error) { + message->setText(text); + if (error) { + icon->setPixmap( + QPixmap(":error.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); + } else { + icon->setPixmap( + QPixmap(":info.png").scaled(QSize(24, 24), Qt::KeepAspectRatio)); + } } void KeyServerImportDialog::slotSearch() { + if (searchLineEdit->text().isEmpty()) { + setMessage("<h4>" + tr("Text is empty.") + "</h4>", false); + return; + } - if (searchLineEdit->text().isEmpty()) { - setMessage("<h4>" + tr("Text is empty.") + "</h4>", false); - return; - } - - QUrl urlFromRemote = keyServerComboBox->currentText() + "/pks/lookup?search=" + searchLineEdit->text() + - "&op=index&options=mr"; - qnam = new QNetworkAccessManager(this); - QNetworkReply *reply = qnam->get(QNetworkRequest(urlFromRemote)); + QUrl urlFromRemote = keyServerComboBox->currentText() + + "/pks/lookup?search=" + searchLineEdit->text() + + "&op=index&options=mr"; + qnam = new QNetworkAccessManager(this); + QNetworkReply* reply = qnam->get(QNetworkRequest(urlFromRemote)); - connect(reply, SIGNAL(finished()), - this, SLOT(slotSearchFinished())); + connect(reply, SIGNAL(finished()), this, SLOT(slotSearchFinished())); - setLoading(true); + setLoading(true); - while (reply->isRunning()) { - QApplication::processEvents(); - } - - setLoading(false); + while (reply->isRunning()) { + QApplication::processEvents(); + } + setLoading(false); } void KeyServerImportDialog::slotSearchFinished() { - auto *reply = qobject_cast<QNetworkReply *>(sender()); - - keysTable->clearContents(); - keysTable->setRowCount(0); - QString firstLine = QString(reply->readLine(1024)); - - auto error = reply->error(); - if (error != QNetworkReply::NoError) { - qDebug() << "Error From Reply" << reply->errorString(); - switch (error) { - case QNetworkReply::ContentNotFoundError : - setMessage(tr("Not Key Found"), true); - break; - case QNetworkReply::TimeoutError : - setMessage(tr("Timeout"), true); - break; - case QNetworkReply::HostNotFoundError : - setMessage(tr("Key Server Not Found"), true); - break; - default: - setMessage(tr("Connection Error"), true); - } + auto* reply = qobject_cast<QNetworkReply*>(sender()); + + keysTable->clearContents(); + keysTable->setRowCount(0); + QString firstLine = QString(reply->readLine(1024)); + + auto error = reply->error(); + if (error != QNetworkReply::NoError) { + qDebug() << "Error From Reply" << reply->errorString(); + switch (error) { + case QNetworkReply::ContentNotFoundError: + setMessage(tr("Not Key Found"), true); + break; + case QNetworkReply::TimeoutError: + setMessage(tr("Timeout"), true); + break; + case QNetworkReply::HostNotFoundError: + setMessage(tr("Key Server Not Found"), true); + break; + default: + setMessage(tr("Connection Error"), true); + } + return; + } + + if (firstLine.contains("Error")) { + QString text = QString(reply->readLine(1024)); + if (text.contains("Too many responses")) { + setMessage("<h4>" + tr("Too many responses from keyserver!") + "</h4>", + true); + return; + } else if (text.contains("No keys found")) { + // if string looks like hex string, search again with 0x prepended + QRegExp rx("[0-9A-Fa-f]*"); + QString query = searchLineEdit->text(); + if (rx.exactMatch(query)) { + setMessage("<h4>" + + tr("No keys found, input may be kexId, retrying search " + "with 0x.") + + "</h4>", + true); + searchLineEdit->setText(query.prepend("0x")); + this->slotSearch(); return; + } else { + setMessage("<h4>" + tr("No keys found containing the search string!") + + "</h4>", + true); + return; + } + } else if (text.contains("Insufficiently specific words")) { + setMessage( + "<h4>" + tr("Insufficiently specific search string!") + "</h4>", + true); + return; + } else { + setMessage(text, true); + return; } + } else { + int row = 0; + bool strikeout = false; + while (reply->canReadLine()) { + auto line_buff = reply->readLine().trimmed(); + QString decoded = + QString::fromUtf8(line_buff.constData(), line_buff.size()); + QStringList line = decoded.split(":"); + // TODO: have a look at two following pub lines + if (line[0] == "pub") { + strikeout = false; + + QString flags = line[line.size() - 1]; + keysTable->setRowCount(row + 1); + + // flags can be "d" for disabled, "r" for revoked + // or "e" for expired + if (flags.contains("r") or flags.contains("d") or flags.contains("e")) { + strikeout = true; + if (flags.contains("e")) { + keysTable->setItem(row, 3, + new QTableWidgetItem(QString("expired"))); + } + if (flags.contains("r")) { + keysTable->setItem(row, 3, + new QTableWidgetItem(QString(tr("revoked")))); + } + if (flags.contains("d")) { + keysTable->setItem(row, 3, + new QTableWidgetItem(QString(tr("disabled")))); + } + } + + QStringList line2 = QString(reply->readLine()).split(":"); - if (firstLine.contains("Error")) { - QString text = QString(reply->readLine(1024)); - if (text.contains("Too many responses")) { - setMessage("<h4>" +tr("Too many responses from keyserver!") + "</h4>", true); - return; - } else if (text.contains("No keys found")) { - // if string looks like hex string, search again with 0x prepended - QRegExp rx("[0-9A-Fa-f]*"); - QString query = searchLineEdit->text(); - if (rx.exactMatch(query)) { - setMessage("<h4>" + tr("No keys found, input may be kexId, retrying search with 0x.") + "</h4>", true); - searchLineEdit->setText(query.prepend("0x")); - this->slotSearch(); - return; - } else { - setMessage("<h4>" +tr("No keys found containing the search string!") + "</h4>", true); - return; - } - } else if (text.contains("Insufficiently specific words")) { - setMessage("<h4>" + tr("Insufficiently specific search string!") + "</h4>", true); - return; - } else { - setMessage(text, true); - return; + auto* uid = new QTableWidgetItem(); + if (line2.size() > 1) { + uid->setText(line2[1]); + keysTable->setItem(row, 0, uid); } - } else { - int row = 0; - bool strikeout = false; - while (reply->canReadLine()) { - auto line_buff = reply->readLine().trimmed(); - QString decoded = QString::fromUtf8(line_buff.constData(), line_buff.size()); - QStringList line = decoded.split(":"); - //TODO: have a look at two following pub lines - if (line[0] == "pub") { - strikeout = false; - - QString flags = line[line.size() - 1]; - keysTable->setRowCount(row + 1); - - // flags can be "d" for disabled, "r" for revoked - // or "e" for expired - if (flags.contains("r") or flags.contains("d") or flags.contains("e")) { - strikeout = true; - if (flags.contains("e")) { - keysTable->setItem(row, 3, new QTableWidgetItem(QString("expired"))); - } - if (flags.contains("r")) { - keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("revoked")))); - } - if (flags.contains("d")) { - keysTable->setItem(row, 3, new QTableWidgetItem(QString(tr("disabled")))); - } - } - - QStringList line2 = QString(reply->readLine()).split(":"); - - auto *uid = new QTableWidgetItem(); - if (line2.size() > 1) { - uid->setText(line2[1]); - keysTable->setItem(row, 0, uid); - } - auto *creation_date = new QTableWidgetItem( - QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy")); - keysTable->setItem(row, 1, creation_date); - auto *keyid = new QTableWidgetItem(line[1]); - keysTable->setItem(row, 2, keyid); - if (strikeout) { - QFont strike = uid->font(); - strike.setStrikeOut(true); - uid->setFont(strike); - creation_date->setFont(strike); - keyid->setFont(strike); - } - row++; - } else { - if (line[0] == "uid") { - QStringList l; - int height = keysTable->rowHeight(row - 1); - keysTable->setRowHeight(row - 1, height + 16); - QString tmp = keysTable->item(row - 1, 0)->text(); - tmp.append(QString("\n") + line[1]); - auto *tmp1 = new QTableWidgetItem(tmp); - keysTable->setItem(row - 1, 0, tmp1); - if (strikeout) { - QFont strike = tmp1->font(); - strike.setStrikeOut(true); - tmp1->setFont(strike); - } - } - } - setMessage(tr("<h4>%1 keys found. Double click a key to import it.</h4>").arg(row), false); + auto* creation_date = new QTableWidgetItem( + QDateTime::fromTime_t(line[4].toInt()).toString("dd. MMM. yyyy")); + keysTable->setItem(row, 1, creation_date); + auto* keyid = new QTableWidgetItem(line[1]); + keysTable->setItem(row, 2, keyid); + if (strikeout) { + QFont strike = uid->font(); + strike.setStrikeOut(true); + uid->setFont(strike); + creation_date->setFont(strike); + keyid->setFont(strike); + } + row++; + } else { + if (line[0] == "uid") { + QStringList l; + int height = keysTable->rowHeight(row - 1); + keysTable->setRowHeight(row - 1, height + 16); + QString tmp = keysTable->item(row - 1, 0)->text(); + tmp.append(QString("\n") + line[1]); + auto* tmp1 = new QTableWidgetItem(tmp); + keysTable->setItem(row - 1, 0, tmp1); + if (strikeout) { + QFont strike = tmp1->font(); + strike.setStrikeOut(true); + tmp1->setFont(strike); + } } - keysTable->resizeColumnsToContents(); + } + setMessage(tr("<h4>%1 keys found. Double click a key to import it.</h4>") + .arg(row), + false); } - reply->deleteLater(); + keysTable->resizeColumnsToContents(); + } + reply->deleteLater(); } void KeyServerImportDialog::slotImport() { - if (keysTable->currentRow() > -1) { - QString keyid = keysTable->item(keysTable->currentRow(), 2)->text(); - slotImport(QStringList(keyid), keyServerComboBox->currentText()); - } + if (keysTable->currentRow() > -1) { + QString keyid = keysTable->item(keysTable->currentRow(), 2)->text(); + slotImport(QStringList(keyid), keyServerComboBox->currentText()); + } } void KeyServerImportDialog::slotImport(const QStringList& keyIds) { - QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); - qDebug() << "Select Key Server" << keyserver; - slotImport(keyIds, QUrl(keyserver)); + QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); + qDebug() << "Select Key Server" << keyserver; + slotImport(keyIds, QUrl(keyserver)); } -void KeyServerImportDialog::slotImportKey(const QVector<GpgKey>& keys) { - QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); - qDebug() << "Select Key Server" << keyserver; - auto keyIds = QStringList(); - for(const auto &key : keys) { - keyIds.append(key.id); - } - slotImport(keyIds, QUrl(keyserver)); +void KeyServerImportDialog::slotImportKey(const KeyIdArgsListPtr& keys) { + QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); + qDebug() << "Select Key Server" << keyserver; + auto key_ids = QStringList(); + for (const auto& key_id : *keys) { + key_ids.append(QString::fromStdString(key_id)); + } + slotImport(key_ids, QUrl(keyserver)); } +void KeyServerImportDialog::slotImport(const QStringList& keyIds, + const QUrl& keyServerUrl) { + for (const auto& keyId : keyIds) { + QUrl reqUrl(keyServerUrl.scheme() + "://" + keyServerUrl.host() + + "/pks/lookup?op=get&search=0x" + keyId + "&options=mr"); + qDebug() << "slotImport reqUrl" << reqUrl; + auto pManager = new QNetworkAccessManager(this); -void KeyServerImportDialog::slotImport(const QStringList& keyIds, const QUrl &keyServerUrl) { - for (const auto &keyId : keyIds) { - QUrl reqUrl( - keyServerUrl.scheme() + "://" + keyServerUrl.host() + "/pks/lookup?op=get&search=0x" + keyId + - "&options=mr"); - qDebug() << "slotImport reqUrl" << reqUrl; - auto pManager = new QNetworkAccessManager(this); + QNetworkReply* reply = pManager->get(QNetworkRequest(reqUrl)); - QNetworkReply *reply = pManager->get(QNetworkRequest(reqUrl)); + connect(reply, SIGNAL(finished()), this, SLOT(slotImportFinished())); - connect(reply, SIGNAL(finished()), - this, SLOT(slotImportFinished())); - - setLoading(true); - - while(reply->isRunning()) { - QApplication::processEvents(); - } + setLoading(true); - setLoading(false); + while (reply->isRunning()) { + QApplication::processEvents(); } + + setLoading(false); + } } void KeyServerImportDialog::slotImportFinished() { - auto *reply = qobject_cast<QNetworkReply *>(sender()); - - QByteArray key = reply->readAll(); - - QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); - - auto error = reply->error(); - if (error != QNetworkReply::NoError) { - qDebug() << "Error From Reply" << reply->errorString(); - switch (error) { - case QNetworkReply::ContentNotFoundError : - setMessage(tr("Key Not Found"), true); - break; - case QNetworkReply::TimeoutError : - setMessage(tr("Timeout"), true); - break; - case QNetworkReply::HostNotFoundError : - setMessage(tr("Key Server Not Found"), true); - break; - default: - setMessage(tr("Connection Error"), true); - } - if(mAutomatic) { - setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); - } - return; - } - - // Add keyserver to list in config-file, if it isn't contained - QStringList keyServerList = settings.value("keyserver/keyServerList").toStringList(); - if (!keyServerList.contains(keyServerComboBox->currentText())) { - keyServerList.append(keyServerComboBox->currentText()); - settings.setValue("keyserver/keyServerList", keyServerList); + auto* reply = qobject_cast<QNetworkReply*>(sender()); + + QByteArray key = reply->readAll(); + + QVariant redirectionTarget = + reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + + auto error = reply->error(); + if (error != QNetworkReply::NoError) { + qDebug() << "Error From Reply" << reply->errorString(); + switch (error) { + case QNetworkReply::ContentNotFoundError: + setMessage(tr("Key Not Found"), true); + break; + case QNetworkReply::TimeoutError: + setMessage(tr("Timeout"), true); + break; + case QNetworkReply::HostNotFoundError: + setMessage(tr("Key Server Not Found"), true); + break; + default: + setMessage(tr("Connection Error"), true); } - reply->deleteLater(); - - this->importKeys(key.constData()); - if(mAutomatic) { - setMessage(tr("<h4>Key Updated</h4>"), false); - } else { - setMessage(tr("<h4>Key Imported</h4>"), false); + if (mAutomatic) { + setWindowFlags(Qt::Window | Qt::WindowTitleHint | + Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint); } - - + return; + } + + // Add keyserver to list in config-file, if it isn't contained + QStringList keyServerList = + settings.value("keyserver/keyServerList").toStringList(); + if (!keyServerList.contains(keyServerComboBox->currentText())) { + keyServerList.append(keyServerComboBox->currentText()); + settings.setValue("keyserver/keyServerList", keyServerList); + } + reply->deleteLater(); + + this->importKeys(std::make_unique<ByteArray>(key.constData(), key.length())); + if (mAutomatic) { + setMessage(tr("<h4>Key Updated</h4>"), false); + } else { + setMessage(tr("<h4>Key Imported</h4>"), false); + } } -void KeyServerImportDialog::importKeys(QByteArray inBuffer) { - GpgImportInformation result = mCtx->importKey(std::move(inBuffer)); - if(mAutomatic) { - new KeyImportDetailDialog(mCtx, result, false, this); - this->accept(); - } else { - new KeyImportDetailDialog(mCtx, result, false, this); - } +void KeyServerImportDialog::importKeys(ByteArrayPtr in_data) { + GpgImportInformation result = + GpgKeyImportExportor::GetInstance().ImportKey(std::move(in_data)); + if (mAutomatic) { + new KeyImportDetailDialog(result, true, this); + this->accept(); + } else { + new KeyImportDetailDialog(result, false, this); + } } void KeyServerImportDialog::setLoading(bool status) { - if (status) { - waitingBar->setVisible(true); - icon->setVisible(false); - message->setVisible(false); - } else { - waitingBar->setVisible(false); - icon->setVisible(true); - message->setVisible(true); - } -} - -KeyServerImportDialog::KeyServerImportDialog(GpgFrontend::GpgContext *ctx, QWidget *parent) - : QDialog(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat), - mCtx(ctx), mAutomatic(true) { - - setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); - - message = new QLabel; - message->setFixedHeight(24); - icon = new QLabel; - icon->setFixedHeight(24); - - // Network Waiting - waitingBar = new QProgressBar(); + if (status) { + waitingBar->setVisible(true); + icon->setVisible(false); + message->setVisible(false); + } else { waitingBar->setVisible(false); - waitingBar->setRange(0, 0); - waitingBar->setFixedHeight(24); - waitingBar->setFixedWidth(200); - - // Layout for messagebox - auto *messageLayout = new QHBoxLayout; - messageLayout->addWidget(icon); - messageLayout->addWidget(message); - messageLayout->addWidget(waitingBar); - messageLayout->addStretch(); - - keyServerComboBox = createComboBox(); - - auto *mainLayout = new QGridLayout; - - mainLayout->addLayout(messageLayout, 0, 0, 1, 3); + icon->setVisible(true); + message->setVisible(true); + } +} - this->setLayout(mainLayout); - this->setWindowTitle(tr("Upload Keys from Keyserver")); - this->setFixedSize(200, 42); - this->setModal(true); +KeyServerImportDialog::KeyServerImportDialog(QWidget* parent) + : QDialog(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mAutomatic(true) { + setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); + + message = new QLabel; + message->setFixedHeight(24); + icon = new QLabel; + icon->setFixedHeight(24); + + // Network Waiting + waitingBar = new QProgressBar(); + waitingBar->setVisible(false); + waitingBar->setRange(0, 0); + waitingBar->setFixedHeight(24); + waitingBar->setFixedWidth(200); + + // Layout for messagebox + auto* messageLayout = new QHBoxLayout; + messageLayout->addWidget(icon); + messageLayout->addWidget(message); + messageLayout->addWidget(waitingBar); + messageLayout->addStretch(); + + keyServerComboBox = createComboBox(); + + auto* mainLayout = new QGridLayout; + + mainLayout->addLayout(messageLayout, 0, 0, 1, 3); + + this->setLayout(mainLayout); + this->setWindowTitle(tr("Upload Keys from Keyserver")); + this->setFixedSize(200, 42); + this->setModal(true); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/KeyServerImportDialog.h b/src/ui/KeyServerImportDialog.h new file mode 100644 index 00000000..615a77c6 --- /dev/null +++ b/src/ui/KeyServerImportDialog.h @@ -0,0 +1,94 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYSERVERIMPORTDIALOG_H__ +#define __KEYSERVERIMPORTDIALOG_H__ + +#include "KeyImportDetailDialog.h" +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class KeyServerImportDialog : public QDialog { + Q_OBJECT + + public: + KeyServerImportDialog(KeyList* keyList, bool automatic, QWidget* parent); + + KeyServerImportDialog(QWidget* parent); + + void slotImport(const QStringList& keyIds); + + void slotImport(const QStringList& keyIds, const QUrl& keyserverUrl); + + void slotImportKey(const KeyIdArgsListPtr& keys); + + private slots: + + void slotImport(); + + void slotSearchFinished(); + + void slotImportFinished(); + + void slotSearch(); + + private: + void createKeysTable(); + + void setMessage(const QString& text, bool error); + + void importKeys(ByteArrayPtr in_data); + + void setLoading(bool status); + + QPushButton* createButton(const QString& text, const char* member); + + QComboBox* createComboBox(); + + bool mAutomatic; + + QString appPath; + QSettings settings; + + KeyList* mKeyList{}; + QLineEdit* searchLineEdit{}; + QComboBox* keyServerComboBox{}; + QProgressBar* waitingBar; + QLabel* searchLabel{}; + QLabel* keyServerLabel{}; + QLabel* message{}; + QLabel* icon{}; + QPushButton* closeButton{}; + QPushButton* importButton{}; + QPushButton* searchButton{}; + QTableWidget* keysTable{}; + QNetworkAccessManager* qnam{}; +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYSERVERIMPORTDIALOG_H__ diff --git a/src/ui/KeyUploadDialog.cpp b/src/ui/KeyUploadDialog.cpp index 321441b7..06b1d074 100644 --- a/src/ui/KeyUploadDialog.cpp +++ b/src/ui/KeyUploadDialog.cpp @@ -24,105 +24,116 @@ #include "ui/KeyUploadDialog.h" -KeyUploadDialog::KeyUploadDialog(GpgFrontend::GpgContext *ctx, const QVector<GpgKey> &keys, QWidget *parent) +#include <algorithm> + +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyImportExportor.h" + +namespace GpgFrontend::UI { + +KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, + QWidget* parent) : appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat), - mCtx(ctx), - mKeys(keys), - QDialog(parent) { - - - auto *pb = new QProgressBar(); - pb->setRange(0, 0); - pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - pb->setTextVisible(false); - - auto *layout = new QVBoxLayout(); - layout->addWidget(pb); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - this->setLayout(layout); - - this->setModal(true); - this->setWindowTitle(tr("Uploading Public Key")); - this->setFixedSize(240, 42); + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mKeys(GpgKeyGetter::GetInstance().GetKeys(keys_ids)), + QDialog(parent) { + auto* pb = new QProgressBar(); + pb->setRange(0, 0); + pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + pb->setTextVisible(false); + + auto* layout = new QVBoxLayout(); + layout->addWidget(pb); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + this->setLayout(layout); + + this->setModal(true); + this->setWindowTitle(tr("Uploading Public Key")); + this->setFixedSize(240, 42); } void KeyUploadDialog::slotUpload() { - mCtx->exportKeys(mKeys, mKeyData); - uploadKeyToServer(mKeyData); + auto out_data = std::make_unique<ByteArray>(); + GpgKeyImportExportor::GetInstance().ExportKeys(*mKeys, out_data); + uploadKeyToServer(std::move(out_data)); } -void KeyUploadDialog::uploadKeyToServer(QByteArray &keys) { +void KeyUploadDialog::uploadKeyToServer(ByteArrayPtr keys_data) { + // set default keyserver + QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); - // set default keyserver - QString keyserver = settings.value("keyserver/defaultKeyServer").toString(); + QUrl reqUrl(keyserver + "/pks/add"); + auto qnam = new QNetworkAccessManager(this); - QUrl reqUrl(keyserver + "/pks/add"); - auto qnam = new QNetworkAccessManager(this); + // Building Post Data + QByteArray postData; - // Building Post Data - QByteArray postData; + auto& data = *keys_data; - keys.replace("\n", "%0A") - .replace("\r", "%0D") - .replace("(", "%28") - .replace(")", "%29") - .replace("/", "%2F") - .replace(":", "%3A") - .replace("+", "%2B") - .replace('=', "%3D") - .replace(' ', '+'); + boost::algorithm::replace_all(data, "\n", "%0A"); + boost::algorithm::replace_all(data, "\r", "%0D"); + boost::algorithm::replace_all(data, "(", "%28"); + boost::algorithm::replace_all(data, ")", "%29"); + boost::algorithm::replace_all(data, "/", "%2F"); + boost::algorithm::replace_all(data, ":", "%3A"); + boost::algorithm::replace_all(data, "+", "%2B"); + boost::algorithm::replace_all(data, '=', "%3D"); + boost::algorithm::replace_all(data, ' ', '+'); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + QNetworkRequest request(reqUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, + "application/x-www-form-urlencoded"); - postData.append("keytext").append("=").append(keys); + postData.append("keytext").append("=").append( + QString::fromStdString(data).toUtf8()); - // Send Post Data - QNetworkReply *reply = qnam->post(request, postData); - connect(reply, SIGNAL(finished()), - this, SLOT(slotUploadFinished())); + // Send Post Data + QNetworkReply* reply = qnam->post(request, postData); + connect(reply, SIGNAL(finished()), this, SLOT(slotUploadFinished())); + // Keep Waiting + while (reply->isRunning()) { + QApplication::processEvents(); + } - // Keep Waiting - while(reply->isRunning()) { - QApplication::processEvents(); - } - - // Done - this->hide(); - this->close(); + // Done + this->hide(); + this->close(); } void KeyUploadDialog::slotUploadFinished() { - auto *reply = qobject_cast<QNetworkReply *>(sender()); - - QByteArray response = reply->readAll(); - qDebug() << "Response: " << response.data(); - - auto error = reply->error(); - if (error != QNetworkReply::NoError) { - qDebug() << "Error From Reply" << reply->errorString(); - QString message; - switch (error) { - case QNetworkReply::ContentNotFoundError : - message = tr("Key Not Found"); - break; - case QNetworkReply::TimeoutError : - message = tr("Timeout"); - break; - case QNetworkReply::HostNotFoundError : - message = tr("Key Server Not Found"); - break; - default: - message = tr("Connection Error"); - } - QMessageBox::critical(this, "Upload Failed", message); - return; - } else { - QMessageBox::information(this, "Upload Success", "Upload Public Key Successfully"); - qDebug() << "Success while contacting keyserver!"; + auto* reply = qobject_cast<QNetworkReply*>(sender()); + + QByteArray response = reply->readAll(); + qDebug() << "Response: " << response.data(); + + auto error = reply->error(); + if (error != QNetworkReply::NoError) { + qDebug() << "Error From Reply" << reply->errorString(); + QString message; + switch (error) { + case QNetworkReply::ContentNotFoundError: + message = tr("Key Not Found"); + break; + case QNetworkReply::TimeoutError: + message = tr("Timeout"); + break; + case QNetworkReply::HostNotFoundError: + message = tr("Key Server Not Found"); + break; + default: + message = tr("Connection Error"); } - reply->deleteLater(); + QMessageBox::critical(this, "Upload Failed", message); + return; + } else { + QMessageBox::information(this, "Upload Success", + "Upload Public Key Successfully"); + qDebug() << "Success while contacting keyserver!"; + } + reply->deleteLater(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/KeyUploadDialog.h b/src/ui/KeyUploadDialog.h new file mode 100644 index 00000000..b57440d4 --- /dev/null +++ b/src/ui/KeyUploadDialog.h @@ -0,0 +1,57 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYUPLOADWIDGET_H +#define GPGFRONTEND_KEYUPLOADWIDGET_H + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class KeyUploadDialog : public QDialog { + Q_OBJECT + public: + explicit KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, QWidget* parent); + + public slots: + + void slotUpload(); + + private slots: + + void uploadKeyToServer(GpgFrontend::ByteArrayPtr keys_data); + + void slotUploadFinished(); + + private: + QString appPath; + QSettings settings; + KeyListPtr mKeys; + QByteArray mKeyData; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYUPLOADWIDGET_H diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp new file mode 100644 index 00000000..33478b8a --- /dev/null +++ b/src/ui/MainWindow.cpp @@ -0,0 +1,249 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "MainWindow.h" +#include "ui/help/VersionCheckThread.h" + +namespace GpgFrontend::UI { + +MainWindow::MainWindow() + : appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + networkAccessManager = new QNetworkAccessManager(this); + + auto waitingDialog = new WaitingDialog(tr("Loading Gnupg"), this); + + QString baseUrl = + "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; + + QNetworkRequest request; + request.setUrl(QUrl(baseUrl)); + + QNetworkReply* replay = networkAccessManager->get(request); + + auto version_thread = new VersionCheckThread(replay); + + connect(version_thread, SIGNAL(finished()), version_thread, + SLOT(deleteLater())); + connect(version_thread, + SIGNAL(upgradeVersion(const QString&, const QString&)), this, + SLOT(slotVersionUpgrade(const QString&, const QString&))); + + version_thread->start(); + + // Check Context Status + if (!GpgContext::GetInstance().good()) { + QMessageBox::critical( + nullptr, tr("ENV Loading Failed"), + tr("Gnupg is not installed correctly, please follow the ReadME " + "instructions to install gnupg and then open GPGFrontend.")); + QCoreApplication::quit(); + exit(0); + } + + /* get path were app was started */ + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + + edit = new TextEdit(this); + setCentralWidget(edit); + + /* the list of Keys available*/ + mKeyList = new KeyList(KeyListRow::SECRET_OR_PUBLIC_KEY, + KeyListColumn::TYPE | KeyListColumn::NAME | + KeyListColumn::EmailAddress | + KeyListColumn::Usage | KeyListColumn::Validity, + this); + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (key.revoked() || key.disabled() || key.expired()) + return false; + else + return true; + }); + mKeyList->slotRefresh(); + + infoBoard = new InfoBoardWidget(this, mKeyList); + + /* List of binary Attachments */ + attachmentDockCreated = false; + + /* Variable containing if restart is needed */ + this->slotSetRestartNeeded(false); + + keyMgmt = new KeyMgmt(this); + keyMgmt->hide(); + /* test attachmentdir for files alll 15s */ + auto* timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(slotCheckAttachmentFolder())); + timer->start(5000); + + createActions(); + createMenus(); + createToolBars(); + createStatusBar(); + createDockWindows(); + + connect(edit->tabWidget, SIGNAL(currentChanged(int)), this, + SLOT(slotDisableTabActions(int))); + + mKeyList->addMenuAction(appendSelectedKeysAct); + mKeyList->addMenuAction(copyMailAddressToClipboardAct); + mKeyList->addMenuAction(showKeyDetailsAct); + mKeyList->addSeparator(); + mKeyList->addMenuAction(refreshKeysFromKeyserverAct); + mKeyList->addMenuAction(uploadKeyToServerAct); + + restoreSettings(); + + // open filename if provided as first command line parameter + QStringList args = qApp->arguments(); + if (args.size() > 1) { + if (!args[1].startsWith("-")) { + if (QFile::exists(args[1])) + edit->loadFile(args[1]); + } + } + edit->curTextPage()->setFocus(); + this->setMinimumSize(1200, 700); + this->setWindowTitle(qApp->applicationName()); + this->show(); + + // Show wizard, if the don't show wizard message box wasn't checked + // and keylist doesn't contain a private key + qDebug() << "wizard/showWizard" + << settings.value("wizard/showWizard", true).toBool(); + qDebug() << "wizard/nextPage" << settings.value("wizard/nextPage").isNull(); + if (settings.value("wizard/showWizard", true).toBool() || + !settings.value("wizard/nextPage").isNull()) { + slotStartWizard(); + } +} + +void MainWindow::restoreSettings() { + // state sets pos & size of dock-widgets + this->restoreState(settings.value("window/windowState").toByteArray()); + + // Restore window size & location + if (settings.value("window/windowSave").toBool()) { + QPoint pos = settings.value("window/pos", QPoint(100, 100)).toPoint(); + QSize size = settings.value("window/size", QSize(800, 450)).toSize(); + this->resize(size); + this->move(pos); + } else { + this->resize(QSize(800, 450)); + this->move(QPoint(100, 100)); + } + + // Iconsize + QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); + this->setIconSize(iconSize); + + importButton->setIconSize(iconSize); + fileEncButton->setIconSize(iconSize); + // set list of keyserver if not defined + QStringList* keyServerDefaultList; + keyServerDefaultList = new QStringList("http://keys.gnupg.net"); + keyServerDefaultList->append("https://keyserver.ubuntu.com"); + keyServerDefaultList->append("http://pool.sks-keyservers.net"); + + QStringList keyServerList = + settings.value("keyserver/keyServerList", *keyServerDefaultList) + .toStringList(); + settings.setValue("keyserver/keyServerList", keyServerList); + + // set default keyserver, if it's not set + QString defaultKeyServer = settings + .value("keyserver/defaultKeyServer", + QString("https://keyserver.ubuntu.com")) + .toString(); + settings.setValue("keyserver/defaultKeyServer", defaultKeyServer); + + // Iconstyle + Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>( + settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) + .toUInt()); + this->setToolButtonStyle(buttonStyle); + importButton->setToolButtonStyle(buttonStyle); + fileEncButton->setToolButtonStyle(buttonStyle); + + // Checked Keys + if (settings.value("keys/saveKeyChecked").toBool()) { + QStringList keyIds = + settings.value("keys/savedCheckedKeyList").toStringList(); + auto key_ids_ptr = std::make_unique<KeyIdArgsList>(); + for (auto& key_id : keyIds) + key_ids_ptr->push_back(key_id.toStdString()); + mKeyList->setChecked(key_ids_ptr); + } +} + +void MainWindow::saveSettings() { + // window position and size + settings.setValue("window/windowState", saveState()); + settings.setValue("window/pos", pos()); + settings.setValue("window/size", size()); + + // keyid-list of private checked keys + if (settings.value("keys/saveKeyChecked").toBool()) { + auto keyIds = mKeyList->getChecked(); + if (!keyIds->empty()) { + QStringList key_ids_str_list; + for (const auto& key_id : keyIds) + key_ids_str_list << QString::fromStdString(key_id); + settings.setValue("keys/savedCheckedKeyList", key_ids_str_list); + } else { + settings.setValue("keys/savedCheckedKeyList", ""); + } + } else { + settings.remove("keys/savedCheckedKeyList"); + } +} + +void MainWindow::closeAttachmentDock() { + if (!attachmentDockCreated) { + return; + } + attachmentDock->close(); + attachmentDock->deleteLater(); + attachmentDockCreated = false; +} + +void MainWindow::closeEvent(QCloseEvent* event) { + /* + * ask to save changes, if there are + * modified documents in any tab + */ + if (edit->maybeSaveAnyTab()) { + saveSettings(); + event->accept(); + } else { + event->ignore(); + } + + // clear password from memory + // GpgContext::GetInstance().clearPasswordCache(); +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h new file mode 100644 index 00000000..333ee971 --- /dev/null +++ b/src/ui/MainWindow.h @@ -0,0 +1,425 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __GPGWIN_H__ +#define __GPGWIN_H__ + +#include "gpg/GpgConstants.h" +#include "ui/FileEncryptionDialog.h" +#include "ui/FindWidget.h" +#include "ui/GpgFrontendUI.h" +#include "ui/KeyMgmt.h" +#include "ui/KeyUploadDialog.h" +#include "ui/SettingsDialog.h" +#include "ui/WaitingDialog.h" +#include "ui/Wizard.h" +#include "ui/help/AboutDialog.h" +#include "ui/widgets/InfoBoardWidget.h" +#include "ui/widgets/TextEdit.h" + +#include "gpg/result_analyse/DecryptResultAnalyse.h" +#include "gpg/result_analyse/EncryptResultAnalyse.h" +#include "gpg/result_analyse/SignResultAnalyse.h" + +namespace GpgFrontend::UI { +/** + * @brief + * + */ +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + /** + * @brief + * + */ + MainWindow(); + + public slots: + + void slotSetStatusBarText(const QString& text); + + protected: + /** + * @details Close event shows a save dialog, if there are unsaved documents on + * exit. + * @param event + */ + void closeEvent(QCloseEvent* event) override; + + public slots: + + /** + * @details Open a new tab for path + */ + void slotOpenFile(QString& path); + + /** + * @details Open dialog for encrypting file. + */ + void slotFileEncrypt(); + + /** + * @details Open dialog for decrypting file. + */ + void slotFileDecrypt(); + + /** + * @details Open dialog for signing file. + */ + void slotFileSign(); + + /** + * @details Open dialog for verifying file. + */ + void slotFileVerify(); + + /** + * @details Open dialog for signing file. + */ + void slotFileEncryptSign(); + + /** + * @details Open dialog for verifying file. + */ + void slotFileDecryptVerify(); + + private slots: + + /** + * @details encrypt the text of currently active textedit-page + * with the currently checked keys + */ + void slotEncrypt(); + + /** + * @details encrypt and sign the text of currently active textedit-page + * with the currently checked keys + */ + void slotEncryptSign(); + + /** + * @details Show a passphrase dialog and decrypt the text of currently active + * tab. + */ + void slotDecrypt(); + + /** + * @details Sign the text of currently active tab with the checked private + * keys + */ + void slotSign(); + + /** + * @details Verify the text of currently active tab and show verify + * information. If document is signed with a key, which is not in keylist, + * show import missing key from keyserver in Menu of verifynotification. + */ + void slotVerify(); + + /** + * @details decrypt and verify the text of currently active textedit-page + * with the currently checked keys + */ + void slotDecryptVerify(); + + /** + * @details Open dialog for encrypting file. + */ + void slotFileEncryptCustom(); + + /** + * @details Open dialog for decrypting file. + */ + void slotFileDecryptCustom(); + + /** + * @details Open dialog for signing file. + */ + void slotFileSignCustom(); + + /** + * @details Open dialog for verifying file. + */ + void slotFileVerifyCustom(); + + /** + * @details Show the details of the first of the first of selected keys + */ + void slotShowKeyDetails(); + + /** + * @details Refresh key information of selected keys from default keyserver + */ + void refreshKeysFromKeyserver(); + + /** + * @details upload the selected key to the keyserver + */ + void uploadKeyToServer(); + + /** + * @details Open find widget. + */ + void slotFind(); + + /** + * @details start the wizard + */ + void slotStartWizard(); + + /** + * @details Import keys from currently active tab to keylist if possible. + */ + void slotImportKeyFromEdit(); + + /** + * @details Append the selected keys to currently active textedit. + */ + void slotAppendSelectedKeys(); + + /** + * @details Copy the mailaddress of selected key to clipboard. + * Method for keylists contextmenu. + */ + void slotCopyMailAddressToClipboard(); + + /** + * @details Open key management dialog. + */ + void slotOpenKeyManagement(); + + /** + * @details Open about-dialog. + */ + void slotAbout(); + + /** + * @details Open check-update-tab in about-dialog. + */ + void slotCheckUpdate(); + + /** + * @details Open File Opera Tab + */ + void slotOpenFileTab(); + + /** + * @details Open settings-dialog. + */ + void slotOpenSettingsDialog(); + + /** + * @details Show a warn message in status bar, if there are files in + * attachment folder. + */ + void slotCheckAttachmentFolder(); + + /** + * @details Replace double linebreaks by single linebreaks in currently active + * tab. + */ + void slotCleanDoubleLinebreaks(); + + /** + * @details Cut the existing PGP header and footer from current tab. + */ + void slotCutPgpHeader(); + + /** + * @details Add PGP header and footer to current tab. + */ + void slotAddPgpHeader(); + + /** + * @details Disable tab related actions, if number of tabs is 0. + * @param number number of the opened tabs and -1, if no tab is opened + */ + void slotDisableTabActions(int number); + + /** + * @details get value of member restartNeeded to needed. + * @param needed true, if application has to be restarted + */ + void slotSetRestartNeeded(bool needed); + + /** + * @details called when need to upgrade. + */ + void slotVersionUpgrade(const QString& currentVersion, + const QString& latestVersion); + + private: + /** + * @details Create actions for the main-menu and the context-menu of the + * keylist. + */ + void createActions(); + + /** + * @details create the menu of the main-window. + */ + void createMenus(); + + /** + * @details Create edit-, crypt- and key-toolbars. + */ + void createToolBars(); + + /** + * @details Create statusbar of mainwindow. + */ + void createStatusBar(); + + /** + * @details Create keylist- and attachment-dockwindows. + */ + void createDockWindows(); + + /** + * @details Create attachment-dockwindow. + */ + void createAttachmentDock(); + + /** + * @details close attachment-dockwindow. + */ + void closeAttachmentDock(); + + /** + * @details Load settings from ini-file. + */ + void restoreSettings(); + + /** + * @details Save settings to ini-file. + */ + void saveSettings(); + + /** + * @details Get full crypto text + */ + QString getCryptText(const QString& shortenCryptoText); + + /** + * @details Shorten crypto text + */ + void shortenCryptText(); + + /** + * @brief return true, if restart is needed + */ + [[nodiscard]] bool getRestartNeeded() const; + + TextEdit* edit; /** Tabwidget holding the edit-windows */ + QMenu* fileMenu; /** Submenu for file-operations*/ + QMenu* editMenu; /** Submenu for text-operations*/ + QMenu* cryptMenu; /** Submenu for crypt-operations */ + QMenu* fileEncMenu; /** Submenu for file crypt operations */ + QMenu* helpMenu; /** Submenu for help-operations */ + QMenu* keyMenu; /** Submenu for key-operations */ + QMenu* viewMenu; /** Submenu for view operations */ + QMenu* importKeyMenu; /** Sumenu for import operations */ + QMenu* steganoMenu; /** Submenu for steganographic operations*/ + QToolBar* cryptToolBar; /** Toolbar holding crypt actions */ + QToolBar* fileToolBar; /** Toolbar holding file actions */ + QToolBar* editToolBar; /** Toolbar holding edit actions */ + QToolBar* specialEditToolBar; /** Toolbar holding special edit actions */ + QToolBar* keyToolBar; /** Toolbar holding key operations */ + QToolButton* + importButton; /** Toolbutton for import dropdown menu in toolbar */ + QToolButton* fileEncButton; /** Toolbutton for file cryption dropdown menu in + toolbar */ + QDockWidget* keyListDock; /** Encrypt Dock*/ + QDockWidget* attachmentDock; /** Attachment Dock */ + QDockWidget* infoBoardDock; + + QAction* newTabAct; /** Action to create new tab */ + QAction* switchTabUpAct; /** Action to switch tab up*/ + QAction* switchTabDownAct; /** Action to switch tab down */ + QAction* openAct; /** Action to open file */ + QAction* browserAct; /** Action to open file browser*/ + QAction* saveAct; /** Action to save file */ + QAction* saveAsAct; /** Action to save file as */ + QAction* printAct; /** Action to print */ + QAction* closeTabAct; /** Action to print */ + QAction* quitAct; /** Action to quit application */ + QAction* encryptAct; /** Action to encrypt text */ + QAction* encryptSignAct; /** Action to encrypt and sign text */ + QAction* decryptVerifyAct; /** Action to encrypt and sign text */ + QAction* decryptAct; /** Action to decrypt text */ + QAction* signAct; /** Action to sign text */ + QAction* verifyAct; /** Action to verify text */ + QAction* importKeyFromEditAct; /** Action to import key from edit */ + QAction* cleanDoubleLinebreaksAct; /** Action to remove double line breaks */ + + QAction* appendSelectedKeysAct; /** Action to append selected keys to edit */ + QAction* + copyMailAddressToClipboardAct; /** Action to copy mail to clipboard */ + QAction* openKeyManagementAct; /** Action to open key management */ + QAction* copyAct; /** Action to copy text */ + QAction* quoteAct; /** Action to quote text */ + QAction* cutAct; /** Action to cut text */ + QAction* pasteAct; /** Action to paste text */ + QAction* selectAllAct; /** Action to select whole text */ + QAction* findAct; /** Action to find text */ + QAction* undoAct; /** Action to undo last action */ + QAction* redoAct; /** Action to redo last action */ + QAction* zoomInAct; /** Action to zoom in */ + QAction* zoomOutAct; /** Action to zoom out */ + QAction* aboutAct; /** Action to open about dialog */ + QAction* checkUpdateAct; /** Action to open about dialog */ + QAction* fileEncryptAct; /** Action to open dialog for encrypting file */ + QAction* fileDecryptAct; /** Action to open dialog for decrypting file */ + QAction* fileSignAct; /** Action to open dialog for signing file */ + QAction* fileVerifyAct; /** Action to open dialog for verifying file */ + QAction* openSettingsAct; /** Action to open settings dialog */ + QAction* showKeyDetailsAct; /** Action to open key-details dialog */ + QAction* + refreshKeysFromKeyserverAct; /** Action to refresh a key from keyserver */ + QAction* uploadKeyToServerAct; /** Action to append selected keys to edit */ + QAction* startWizardAct; /** Action to open the wizard */ + QAction* cutPgpHeaderAct; /** Action for cutting the PGP header */ + QAction* addPgpHeaderAct; /** Action for adding the PGP header */ + + QLabel* statusBarIcon; /**< TODO */ + + QString appPath; + QSettings settings; + KeyList* mKeyList; + + InfoBoardWidget* infoBoard; + KeyMgmt* keyMgmt; + KeyServerImportDialog* importDialog; /**< TODO */ + + QNetworkAccessManager* networkAccessManager; + + bool attachmentDockCreated; + bool restartNeeded; +}; + +} // namespace GpgFrontend::UI + +#endif // __GPGWIN_H__ diff --git a/src/ui/QuitDialog.cpp b/src/ui/QuitDialog.cpp index 783a8a61..f6b3f196 100755 --- a/src/ui/QuitDialog.cpp +++ b/src/ui/QuitDialog.cpp @@ -24,109 +24,116 @@ #include "ui/QuitDialog.h" -QuitDialog::QuitDialog(QWidget *parent, const QHash<int, QString>& unsavedDocs) - : QDialog(parent) { - setWindowTitle(tr("Unsaved Files")); - setModal(true); - discarded = false; +namespace GpgFrontend::UI { - /* - * Table of unsaved documents - */ - QHashIterator<int, QString> i(unsavedDocs); - int row = 0; - mFileList = new QTableWidget(this); - mFileList->horizontalHeader()->hide(); - mFileList->setColumnCount(3); - mFileList->setColumnWidth(0, 20); - mFileList->setColumnHidden(2, true); - mFileList->verticalHeader()->hide(); - mFileList->setShowGrid(false); - mFileList->setEditTriggers(QAbstractItemView::NoEditTriggers); - mFileList->setFocusPolicy(Qt::NoFocus); - mFileList->horizontalHeader()->setStretchLastSection(true); - // fill the table - i.toFront(); //jump to the end of list to fill the table backwards - while (i.hasNext()) { - i.next(); - mFileList->setRowCount(mFileList->rowCount() + 1); +QuitDialog::QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs) + : QDialog(parent) { + setWindowTitle(tr("Unsaved Files")); + setModal(true); + discarded = false; - // checkbox in front of filename - auto *tmp0 = new QTableWidgetItem(); - tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - tmp0->setCheckState(Qt::Checked); - mFileList->setItem(row, 0, tmp0); + /* + * Table of unsaved documents + */ + QHashIterator<int, QString> i(unsavedDocs); + int row = 0; + mFileList = new QTableWidget(this); + mFileList->horizontalHeader()->hide(); + mFileList->setColumnCount(3); + mFileList->setColumnWidth(0, 20); + mFileList->setColumnHidden(2, true); + mFileList->verticalHeader()->hide(); + mFileList->setShowGrid(false); + mFileList->setEditTriggers(QAbstractItemView::NoEditTriggers); + mFileList->setFocusPolicy(Qt::NoFocus); + mFileList->horizontalHeader()->setStretchLastSection(true); + // fill the table + i.toFront(); // jump to the end of list to fill the table backwards + while (i.hasNext()) { + i.next(); + mFileList->setRowCount(mFileList->rowCount() + 1); - // filename - auto *tmp1 = new QTableWidgetItem(i.value()); - mFileList->setItem(row, 1, tmp1); + // checkbox in front of filename + auto* tmp0 = new QTableWidgetItem(); + tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + tmp0->setCheckState(Qt::Checked); + mFileList->setItem(row, 0, tmp0); - // tab-index in hidden column - auto *tmp2 = new QTableWidgetItem(QString::number(i.key())); - mFileList->setItem(row, 2, tmp2); - ++row; - } - /* - * Warnbox with icon and text - */ - auto pixmap = QPixmap(":error.png"); - pixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); - auto *warn_icon = new QLabel(); - warn_icon->setPixmap(pixmap); - auto *warn_label = new QLabel( - tr("%1 files contain unsaved information.<br/>Save the changes before closing?").arg(row)); - auto *warnBoxLayout = new QHBoxLayout(); - warnBoxLayout->addWidget(warn_icon); - warnBoxLayout->addWidget(warn_label); - warnBoxLayout->setAlignment(Qt::AlignLeft); - auto *warnBox = new QWidget(this); - warnBox->setLayout(warnBoxLayout); + // filename + auto* tmp1 = new QTableWidgetItem(i.value()); + mFileList->setItem(row, 1, tmp1); - /* - * Two labels on top and under the filelist - */ - auto *checkLabel = new QLabel(tr("Check the files you want to save:")); - auto *note_label = new QLabel(tr("<b>Note:</b> If you don't save these files, all changes are lost.<br/>")); + // tab-index in hidden column + auto* tmp2 = new QTableWidgetItem(QString::number(i.key())); + mFileList->setItem(row, 2, tmp2); + ++row; + } + /* + * Warnbox with icon and text + */ + auto pixmap = QPixmap(":error.png"); + pixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); + auto* warn_icon = new QLabel(); + warn_icon->setPixmap(pixmap); + auto* warn_label = + new QLabel(tr("%1 files contain unsaved information.<br/>Save the " + "changes before closing?") + .arg(row)); + auto* warnBoxLayout = new QHBoxLayout(); + warnBoxLayout->addWidget(warn_icon); + warnBoxLayout->addWidget(warn_label); + warnBoxLayout->setAlignment(Qt::AlignLeft); + auto* warnBox = new QWidget(this); + warnBox->setLayout(warnBoxLayout); - /* - * Buttonbox - */ - auto *buttonBox = new QDialogButtonBox( - QDialogButtonBox::Discard | QDialogButtonBox::Save | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - QPushButton *btnNoKey = buttonBox->button(QDialogButtonBox::Discard); - connect(btnNoKey, SIGNAL(clicked()), SLOT(slotMyDiscard())); + /* + * Two labels on top and under the filelist + */ + auto* checkLabel = new QLabel(tr("Check the files you want to save:")); + auto* note_label = + new QLabel(tr("<b>Note:</b> If you don't save these files, all changes " + "are lost.<br/>")); - /* - * Set the layout - */ - auto *vbox = new QVBoxLayout(); - vbox->addWidget(warnBox); - vbox->addWidget(checkLabel); - vbox->addWidget(mFileList); - vbox->addWidget(note_label); - vbox->addWidget(buttonBox); - this->setLayout(vbox); -} + /* + * Buttonbox + */ + auto* buttonBox = + new QDialogButtonBox(QDialogButtonBox::Discard | QDialogButtonBox::Save | + QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + QPushButton* btnNoKey = buttonBox->button(QDialogButtonBox::Discard); + connect(btnNoKey, SIGNAL(clicked()), SLOT(slotMyDiscard())); + /* + * Set the layout + */ + auto* vbox = new QVBoxLayout(); + vbox->addWidget(warnBox); + vbox->addWidget(checkLabel); + vbox->addWidget(mFileList); + vbox->addWidget(note_label); + vbox->addWidget(buttonBox); + this->setLayout(vbox); +} void QuitDialog::slotMyDiscard() { - discarded = true; - reject(); + discarded = true; + reject(); } bool QuitDialog::isDiscarded() const { - return discarded; + return discarded; } QList<int> QuitDialog::getTabIdsToSave() { - QList<int> tabIdsToSave; - for (int i = 0; i < mFileList->rowCount(); i++) { - if (mFileList->item(i, 0)->checkState() == Qt::Checked) { - tabIdsToSave << mFileList->item(i, 2)->text().toInt(); - } + QList<int> tabIdsToSave; + for (int i = 0; i < mFileList->rowCount(); i++) { + if (mFileList->item(i, 0)->checkState() == Qt::Checked) { + tabIdsToSave << mFileList->item(i, 2)->text().toInt(); } - return tabIdsToSave; + } + return tabIdsToSave; } +} // namespace GpgFrontend::UI diff --git a/src/ui/QuitDialog.h b/src/ui/QuitDialog.h new file mode 100755 index 00000000..86616667 --- /dev/null +++ b/src/ui/QuitDialog.h @@ -0,0 +1,53 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __QUITDIALOG_H__ +#define __QUITDIALOG_H__ + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class QuitDialog : public QDialog { + Q_OBJECT + + public: + QuitDialog(QWidget* parent, const QHash<int, QString>& unsavedDocs); + + [[nodiscard]] bool isDiscarded() const; + + QList<int> getTabIdsToSave(); + + private slots: + + void slotMyDiscard(); + + private: + bool discarded; + QTableWidget* mFileList; +}; + +} // namespace GpgFrontend::UI + +#endif // __QUITDIALOG_H__ diff --git a/src/ui/SendMailDialog.cpp b/src/ui/SendMailDialog.cpp index 5bea7cb2..e140ca87 100644 --- a/src/ui/SendMailDialog.cpp +++ b/src/ui/SendMailDialog.cpp @@ -25,149 +25,171 @@ #include "ui/SendMailDialog.h" #include <utility> -#include "smtp/SmtpMime" - -SendMailDialog::SendMailDialog(QString text, QWidget *parent) - : QDialog(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat), mText(std::move(text)) { - - if (smtpAddress.isEmpty()) { - QMessageBox::critical(this, tr("Incomplete configuration"), - tr("The SMTP address is empty, please go to the setting interface to complete the configuration.")); - - deleteLater(); - return; - - } - - senderEdit = new QLineEdit(); - senderEdit->setText(defaultSender); - recipientEdit = new QTextEdit(); - recipientEdit->setPlaceholderText("One or more email addresses. Please use ; to separate."); - subjectEdit = new QLineEdit(); - - errorLabel = new QLabel(); - - qDebug() << "Send Mail Settings" << smtpAddress << username << password << defaultSender << connectionTypeSettings; - - confirmButton = new QPushButton("Confirm"); - auto layout = new QGridLayout(); - layout->addWidget(new QLabel("Sender"), 0, 0); - layout->addWidget(senderEdit, 0, 1); - layout->addWidget(new QLabel("Recipient"), 1, 0); - layout->addWidget(recipientEdit, 1, 1); - layout->addWidget(new QLabel("Subject"), 2, 0); - layout->addWidget(subjectEdit, 2, 1); - layout->addWidget(confirmButton, 3, 1); - layout->addWidget(errorLabel, 4, 0, 1, 2); - - connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm())); +#ifdef STMP_ENABLED +#include "smtp/SmtpMime" +#endif + +namespace GpgFrontend::UI { + +SendMailDialog::SendMailDialog(QString text, QWidget* parent) + : QDialog(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mText(std::move(text)) { + if (smtpAddress.isEmpty()) { + QMessageBox::critical( + this, tr("Incomplete configuration"), + tr("The SMTP address is empty, please go to the setting interface to " + "complete the configuration.")); - this->setLayout(layout); - this->setWindowTitle("Send Mail"); - this->setModal(true); - this->setFixedWidth(320); - this->show(); + deleteLater(); + return; + } + + senderEdit = new QLineEdit(); + senderEdit->setText(defaultSender); + recipientEdit = new QTextEdit(); + recipientEdit->setPlaceholderText( + "One or more email addresses. Please use ; to separate."); + subjectEdit = new QLineEdit(); + + errorLabel = new QLabel(); + + qDebug() << "Send Mail Settings" << smtpAddress << username << password + << defaultSender << connectionTypeSettings; + + confirmButton = new QPushButton("Confirm"); + + auto layout = new QGridLayout(); + layout->addWidget(new QLabel("Sender"), 0, 0); + layout->addWidget(senderEdit, 0, 1); + layout->addWidget(new QLabel("Recipient"), 1, 0); + layout->addWidget(recipientEdit, 1, 1); + layout->addWidget(new QLabel("Subject"), 2, 0); + layout->addWidget(subjectEdit, 2, 1); + layout->addWidget(confirmButton, 3, 1); + layout->addWidget(errorLabel, 4, 0, 1, 2); + +#ifdef STMP_ENABLED + connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm())); +#endif + + this->setLayout(layout); + this->setWindowTitle("Send Mail"); + this->setModal(true); + this->setFixedWidth(320); + this->show(); } -bool SendMailDialog::check_email_address(const QString &str) { - return re_email.match(str).hasMatch(); +bool SendMailDialog::check_email_address(const QString& str) { + return re_email.match(str).hasMatch(); } -void SendMailDialog::slotConfirm() { - - QString errString; - errorLabel->clear(); - - QStringList rcptStringList = recipientEdit->toPlainText().split(';'); - - if (rcptStringList.isEmpty()) { - errString.append(tr(" Recipient cannot be empty \n")); - } else { - for (const auto& reci : rcptStringList) { - qDebug() << "Receiver" << reci.trimmed(); - if (!check_email_address(reci.trimmed())) { - errString.append(tr(" One or more Recipient's Email Address is invalid \n")); - break; - } - } - } - if (senderEdit->text().isEmpty()) { - errString.append(tr(" Sender cannot be empty \n")); - } else if (!check_email_address(senderEdit->text())) { - errString.append(tr(" Sender's Email Address is invalid \n")); - } - - if (!errString.isEmpty()) { - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); - error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(errString); - return; - } - - SmtpClient::ConnectionType connectionType = SmtpClient::ConnectionType::TcpConnection; - - if (connectionTypeSettings == "SSL") { - connectionType = SmtpClient::ConnectionType::SslConnection; - } else if (connectionTypeSettings == "TLS") { - connectionType = SmtpClient::ConnectionType::TlsConnection; - } else if (connectionTypeSettings == "STARTTLS") { - connectionType = SmtpClient::ConnectionType::TlsConnection; - } else { - connectionType = SmtpClient::ConnectionType::TcpConnection; - } - - SmtpClient smtp(smtpAddress, port, connectionType); - - // We need to set the username (your email address) and the password - // for smtp authentification. +#ifdef STMP_ENABLED - smtp.setUser(username); - smtp.setPassword(password); - - // Now we create a MimeMessage object. This will be the email. - - MimeMessage message; - - message.setSender(new EmailAddress(senderEdit->text())); - for (const auto &reci : rcptStringList) { - if(!reci.isEmpty()) - message.addRecipient(new EmailAddress(reci.trimmed())); +void SendMailDialog::slotConfirm() { + QString errString; + errorLabel->clear(); + + QStringList rcptStringList = recipientEdit->toPlainText().split(';'); + + if (rcptStringList.isEmpty()) { + errString.append(tr(" Recipient cannot be empty \n")); + } else { + for (const auto& reci : rcptStringList) { + qDebug() << "Receiver" << reci.trimmed(); + if (!check_email_address(reci.trimmed())) { + errString.append( + tr(" One or more Recipient's Email Address is invalid \n")); + break; + } } - message.setSubject(subjectEdit->text()); - - // Now add some text to the email. - // First we create a MimeText object. - - MimeText text; - - text.setText(mText); + } + if (senderEdit->text().isEmpty()) { + errString.append(tr(" Sender cannot be empty \n")); + } else if (!check_email_address(senderEdit->text())) { + errString.append(tr(" Sender's Email Address is invalid \n")); + } + + if (!errString.isEmpty()) { + errorLabel->setAutoFillBackground(true); + QPalette error = errorLabel->palette(); + error.setColor(QPalette::Window, "#ff8080"); + errorLabel->setPalette(error); + errorLabel->setText(errString); + return; + } + + SmtpClient::ConnectionType connectionType = + SmtpClient::ConnectionType::TcpConnection; + + if (connectionTypeSettings == "SSL") { + connectionType = SmtpClient::ConnectionType::SslConnection; + } else if (connectionTypeSettings == "TLS") { + connectionType = SmtpClient::ConnectionType::TlsConnection; + } else if (connectionTypeSettings == "STARTTLS") { + connectionType = SmtpClient::ConnectionType::TlsConnection; + } else { + connectionType = SmtpClient::ConnectionType::TcpConnection; + } + + SmtpClient smtp(smtpAddress, port, connectionType); + + // We need to set the username (your email address) and the password + // for smtp authentification. + + smtp.setUser(username); + smtp.setPassword(password); + + // Now we create a MimeMessage object. This will be the email. + + MimeMessage message; + + message.setSender(new EmailAddress(senderEdit->text())); + for (const auto& reci : rcptStringList) { + if (!reci.isEmpty()) + message.addRecipient(new EmailAddress(reci.trimmed())); + } + message.setSubject(subjectEdit->text()); + + // Now add some text to the email. + // First we create a MimeText object. + + MimeText text; + + text.setText(mText); + + // Now add it to the mail + message.addPart(&text); + + // Now we can send the mail + if (!smtp.connectToHost()) { + qDebug() << "Connect to SMTP Server Failed"; + QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server")); + return; + } + if (!smtp.login()) { + qDebug() << "Login to SMTP Server Failed"; + QMessageBox::critical(this, tr("Fail"), + tr("Fail to Login into SMTP Server")); + return; + } + if (!smtp.sendMail(message)) { + qDebug() << "Send Mail to SMTP Server Failed"; + QMessageBox::critical(this, tr("Fail"), + tr("Fail to Send Mail to SMTP Server")); + return; + } + smtp.quit(); + + // Close after sending email + QMessageBox::information(this, tr("Success"), + tr("Succeed in Sending Mail to SMTP Server")); + deleteLater(); +} - // Now add it to the mail - message.addPart(&text); +#endif - // Now we can send the mail - if (!smtp.connectToHost()) { - qDebug() << "Connect to SMTP Server Failed"; - QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server")); - return; - } - if (!smtp.login()) { - qDebug() << "Login to SMTP Server Failed"; - QMessageBox::critical(this, tr("Fail"), tr("Fail to Login into SMTP Server")); - return; - } - if (!smtp.sendMail(message)) { - qDebug() << "Send Mail to SMTP Server Failed"; - QMessageBox::critical(this, tr("Fail"), tr("Fail to Send Mail to SMTP Server")); - return; - } - smtp.quit(); - - // Close after sending email - QMessageBox::information(this, tr("Success"), tr("Succeed in Sending Mail to SMTP Server")); - deleteLater(); -} +} // namespace GpgFrontend::UI diff --git a/src/ui/SendMailDialog.h b/src/ui/SendMailDialog.h new file mode 100644 index 00000000..6afdfe79 --- /dev/null +++ b/src/ui/SendMailDialog.h @@ -0,0 +1,71 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SENDMAILDIALOG_H +#define GPGFRONTEND_SENDMAILDIALOG_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class SendMailDialog : public QDialog { + Q_OBJECT + public: + explicit SendMailDialog(QString text, QWidget* parent = nullptr); + + private slots: + + void slotConfirm(); + + private: + QString appPath; + QSettings settings; + + QLineEdit* senderEdit; + QTextEdit* recipientEdit; + QLineEdit* subjectEdit; + QPushButton* confirmButton; + + QLabel* errorLabel; + QString mText; + + QString smtpAddress = + settings.value("sendMail/smtpAddress", QString()).toString(); + QString username = settings.value("sendMail/username", QString()).toString(); + QString password = settings.value("sendMail/password", QString()).toString(); + QString defaultSender = + settings.value("sendMail/defaultSender", QString()).toString(); + QString connectionTypeSettings = + settings.value("sendMail/connectionType", QString()).toString(); + int port = settings.value("sendMail/port", QString()).toInt(); + + QRegularExpression re_email{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + bool check_email_address(const QString& str); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SENDMAILDIALOG_H diff --git a/src/ui/SettingsDialog.h b/src/ui/SettingsDialog.h new file mode 100755 index 00000000..d205f8fe --- /dev/null +++ b/src/ui/SettingsDialog.h @@ -0,0 +1,255 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __SETTINGSDIALOG_H__ +#define __SETTINGSDIALOG_H__ + +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class GeneralTab : public QWidget { + Q_OBJECT + + public: + explicit GeneralTab(QWidget* parent = nullptr); + + void setSettings(); + + void applySettings(); + + private: + QString appPath; + QSettings settings; + + QComboBox* serverSelectBox; + QCheckBox* saveCheckedKeysCheckBox; + QCheckBox* importConfirmationCheckBox; + QComboBox* langSelectBox; + QComboBox* ownKeySelectBox; + QPushButton* getServiceTokenButton; + QLabel* serviceTokenLabel; + QHash<QString, QString> lang; + + std::unordered_map<std::string, std::string> keyIds; + std::vector<std::string> keyIdsList; + std::string serviceToken; + KeyList* mKeyList; + + private slots: + + void slotOwnKeyIdChanged(); + + void slotLanguageChanged(); + + void slotGetServiceToken(); + + signals: + + void signalRestartNeeded(bool needed); +}; + +class SendMailTab : public QWidget { + Q_OBJECT + + public: + explicit SendMailTab(QWidget* parent = nullptr); + + void setSettings(); + + void applySettings(); + + private slots: + + void slotCheckConnection(); + + void slotCheckBoxSetEnableDisable(int state); + + private: + QString appPath; + QSettings settings; + + QCheckBox* enableCheckBox; + + QLineEdit* smtpAddress; + QLineEdit* username; + QLineEdit* password; + QSpinBox* portSpin; + QComboBox* connectionTypeComboBox; + QLineEdit* defaultSender; + + QPushButton* checkConnectionButton; + + signals: + + void signalRestartNeeded(bool needed); +}; + +class AppearanceTab : public QWidget { + Q_OBJECT + + public: + // void setSettings(); + explicit AppearanceTab(QWidget* parent = nullptr); + + void setSettings(); + + void applySettings(); + + private: + QString appPath; + QSettings settings; + + QButtonGroup* iconStyleGroup; + QRadioButton* iconSizeSmall; + QRadioButton* iconSizeMedium; + QRadioButton* iconSizeLarge; + QButtonGroup* iconSizeGroup; + QRadioButton* iconTextButton; + QRadioButton* iconIconsButton; + QRadioButton* iconAllButton; + QSpinBox* infoBoardFontSizeSpin; + QCheckBox* windowSizeCheckBox; + + signals: + + void signalRestartNeeded(bool needed); +}; + +class KeyserverTab : public QWidget { + Q_OBJECT + + public: + explicit KeyserverTab(QWidget* parent = nullptr); + + void setSettings(); + + void applySettings(); + + private: + QString appPath; + QSettings settings; + QComboBox* comboBox; + QLineEdit* newKeyServerEdit; + QTableWidget* keyServerTable; + QStringList keyServerStrList; + + private slots: + + void addKeyServer(); + + void refreshTable(); + + signals: + + void signalRestartNeeded(bool needed); +}; + +class AdvancedTab : public QWidget { + Q_OBJECT + + public: + explicit AdvancedTab(QWidget* parent = nullptr); + + void setSettings(); + + void applySettings(); + + private: + QString appPath; + QSettings settings; + + QCheckBox* steganoCheckBox; + QCheckBox* autoPubkeyExchangeCheckBox; + + signals: + + void signalRestartNeeded(bool needed); +}; + +class GpgPathsTab : public QWidget { + Q_OBJECT + public: + explicit GpgPathsTab(QWidget* parent = nullptr); + + void applySettings(); + + private: + static QString getRelativePath(const QString& dir1, const QString& dir2); + + QString appPath; + QSettings settings; + + QString defKeydbPath; /** The default keydb path used by gpg4usb */ + QString accKeydbPath; /** The currently used keydb path */ + QLabel* keydbLabel; + + void setSettings(); + + private slots: + + QString chooseKeydbDir(); + + void setKeydbPathToDefault(); +}; + +class SettingsDialog : public QDialog { + Q_OBJECT + + public: + explicit SettingsDialog(QWidget* parent = nullptr); + + GeneralTab* generalTab; + SendMailTab* sendMailTab; + AppearanceTab* appearanceTab; + KeyserverTab* keyserverTab; + AdvancedTab* advancedTab; + GpgPathsTab* gpgPathsTab; + + static QHash<QString, QString> listLanguages(); + + public slots: + + void slotAccept(); + + signals: + + void signalRestartNeeded(bool needed); + + private: + QTabWidget* tabWidget; + QDialogButtonBox* buttonBox; + bool restartNeeded{}; + + bool getRestartNeeded() const; + + private slots: + + void slotSetRestartNeeded(bool needed); +}; + +} // namespace GpgFrontend::UI + +#endif // __SETTINGSDIALOG_H__ diff --git a/src/ui/ShowCopyDialog.cpp b/src/ui/ShowCopyDialog.cpp index 3286f6c4..98a1df3c 100644 --- a/src/ui/ShowCopyDialog.cpp +++ b/src/ui/ShowCopyDialog.cpp @@ -24,30 +24,37 @@ #include "ui/ShowCopyDialog.h" -ShowCopyDialog::ShowCopyDialog(const QString &text, const QString &info, QWidget *parent) : QDialog(parent) { - textEdit = new QTextEdit(); - textEdit->setReadOnly(true); - textEdit->setLineWrapMode(QTextEdit::WidgetWidth); - textEdit->setText(text); - copyButton = new QPushButton("Copy"); - connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText())); - - infoLabel = new QLabel(); - infoLabel->setText(info); - infoLabel->setWordWrap(true); - - auto *layout = new QVBoxLayout(); - layout->addWidget(textEdit); - layout->addWidget(copyButton); - layout->addWidget(infoLabel); - - this->setWindowTitle("Short Ciphertext"); - this->resize(320, 120); - this->setModal(true); - this->setLayout(layout); +namespace GpgFrontend::UI { + +ShowCopyDialog::ShowCopyDialog(const QString& text, + const QString& info, + QWidget* parent) + : QDialog(parent) { + textEdit = new QTextEdit(); + textEdit->setReadOnly(true); + textEdit->setLineWrapMode(QTextEdit::WidgetWidth); + textEdit->setText(text); + copyButton = new QPushButton("Copy"); + connect(copyButton, SIGNAL(clicked(bool)), this, SLOT(slotCopyText())); + + infoLabel = new QLabel(); + infoLabel->setText(info); + infoLabel->setWordWrap(true); + + auto* layout = new QVBoxLayout(); + layout->addWidget(textEdit); + layout->addWidget(copyButton); + layout->addWidget(infoLabel); + + this->setWindowTitle("Short Ciphertext"); + this->resize(320, 120); + this->setModal(true); + this->setLayout(layout); } void ShowCopyDialog::slotCopyText() { - QClipboard *cb = QApplication::clipboard(); - cb->setText(textEdit->toPlainText()); + QClipboard* cb = QApplication::clipboard(); + cb->setText(textEdit->toPlainText()); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/ShowCopyDialog.h b/src/ui/ShowCopyDialog.h new file mode 100644 index 00000000..82deedee --- /dev/null +++ b/src/ui/ShowCopyDialog.h @@ -0,0 +1,51 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H +#define GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class ShowCopyDialog : public QDialog { + Q_OBJECT + public: + explicit ShowCopyDialog(const QString& text, + const QString& info = "", + QWidget* parent = nullptr); + + private slots: + + void slotCopyText(); + + private: + QLabel* infoLabel; + QTextEdit* textEdit; + QPushButton* copyButton; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_ZH_CN_TS_SHOWCOPYDIALOG_H diff --git a/src/ui/VerifyDetailsDialog.cpp b/src/ui/VerifyDetailsDialog.cpp index 3462ad69..f06c31a4 100644 --- a/src/ui/VerifyDetailsDialog.cpp +++ b/src/ui/VerifyDetailsDialog.cpp @@ -24,60 +24,69 @@ #include "ui/VerifyDetailsDialog.h" -VerifyDetailsDialog::VerifyDetailsDialog(QWidget *parent, GpgFrontend::GpgContext *ctx, KeyList *keyList, gpg_error_t error, - gpgme_verify_result_t result) : - QDialog(parent), mCtx(ctx), mKeyList(keyList), sign(result->signatures), error(error) { +namespace GpgFrontend::UI { +VerifyDetailsDialog::VerifyDetailsDialog(QWidget* parent, + KeyList* keyList, + GpgError error, + GpgVerifyResult result) + : QDialog(parent), + mKeyList(keyList), + mResult(std::move(result)), + error(error) { + this->setWindowTitle(tr("Signature Details")); - this->setWindowTitle(tr("Signature Details")); + mainLayout = new QHBoxLayout(); + this->setLayout(mainLayout); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh())); - mainLayout = new QHBoxLayout(); - this->setLayout(mainLayout); + slotRefresh(); - slotRefresh(); - - this->exec(); + this->exec(); } void VerifyDetailsDialog::slotRefresh() { + mVbox = new QWidget(); + auto* mVboxLayout = new QVBoxLayout(mVbox); + mainLayout->addWidget(mVbox); - mVbox = new QWidget(); - auto *mVboxLayout = new QVBoxLayout(mVbox); - mainLayout->addWidget(mVbox); + // Button Box for close button + buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); - // Button Box for close button - buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); + mVboxLayout->addWidget(new QLabel(tr("Status: ") + gpgme_strerror(error))); - mVboxLayout->addWidget(new QLabel(tr("Status: ") + gpgme_strerror(error))); + auto sign = mResult->signatures; - if (sign == nullptr) { - mVboxLayout->addWidget(new QLabel(tr("No valid input found"))); - mVboxLayout->addWidget(buttonBox); - return; - } + if (sign == nullptr) { + mVboxLayout->addWidget(new QLabel(tr("No valid input found"))); + mVboxLayout->addWidget(buttonBox); + return; + } - // Get timestamp of signature of current text - QDateTime timestamp; - timestamp.setTime_t(sign->timestamp); + // Get timestamp of signature of current text + QDateTime timestamp; + timestamp.setTime_t(sign->timestamp); - // Set the title widget depending on sign status - if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) { - mVboxLayout->addWidget(new QLabel(tr("Error Validating signature"))); - } else if (mInputSignature != nullptr) { - mVboxLayout->addWidget(new QLabel( - tr("File was signed on %1 <br/> It Contains:<br/><br/>").arg(QLocale::system().toString(timestamp)))); - } else { - mVboxLayout->addWidget(new QLabel(tr("Signed on %1 <br/> It Contains:<br /><br/>").arg( - QLocale::system().toString(timestamp)))); - } - // Add informationbox for every single key - while (sign) { - auto *sbox = new VerifyKeyDetailBox(this, mCtx, mKeyList, sign); - sign = sign->next; - mVboxLayout->addWidget(sbox); - } + // Set the title widget depending on sign status + if (gpg_err_code(sign->status) == GPG_ERR_BAD_SIGNATURE) { + mVboxLayout->addWidget(new QLabel(tr("Error Validating signature"))); + } else if (mInputSignature != nullptr) { + mVboxLayout->addWidget( + new QLabel(tr("File was signed on %1 <br/> It Contains:<br/><br/>") + .arg(QLocale::system().toString(timestamp)))); + } else { + mVboxLayout->addWidget( + new QLabel(tr("Signed on %1 <br/> It Contains:<br /><br/>") + .arg(QLocale::system().toString(timestamp)))); + } + // Add information box for every single key + while (sign) { + auto* sign_box = new VerifyKeyDetailBox(this, mKeyList, sign); + sign = sign->next; + mVboxLayout->addWidget(sign_box); + } - mVboxLayout->addWidget(buttonBox); + mVboxLayout->addWidget(buttonBox); } + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/VerifyDetailsDialog.h b/src/ui/VerifyDetailsDialog.h new file mode 100644 index 00000000..3d201194 --- /dev/null +++ b/src/ui/VerifyDetailsDialog.h @@ -0,0 +1,59 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __VERIFYDETAILSDIALOG_H__ +#define __VERIFYDETAILSDIALOG_H__ + +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/EditorPage.h" +#include "ui/widgets/VerifyKeyDetailBox.h" + +namespace GpgFrontend::UI { + +class VerifyDetailsDialog : public QDialog { + Q_OBJECT + public: + explicit VerifyDetailsDialog(QWidget* parent, + KeyList* keyList, + GpgError error, + GpgVerifyResult result); + + private slots: + + void slotRefresh(); + + private: + KeyList* mKeyList; + QHBoxLayout* mainLayout; + QWidget* mVbox{}; + QByteArray* mInputData{}; /** Data to be verified */ + QByteArray* mInputSignature{}; /** Data to be verified */ + QDialogButtonBox* buttonBox{}; + GpgVerifyResult mResult; + gpgme_error_t error; +}; + +} // namespace GpgFrontend::UI + +#endif // __VERIFYDETAILSDIALOG_H__ diff --git a/src/ui/WaitingDialog.cpp b/src/ui/WaitingDialog.cpp index daccc3ca..44727193 100644 --- a/src/ui/WaitingDialog.cpp +++ b/src/ui/WaitingDialog.cpp @@ -1,20 +1,50 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + #include "ui/WaitingDialog.h" -WaitingDialog::WaitingDialog(const QString &title, QWidget *parent) : QDialog(parent) { - auto *pb = new QProgressBar(); - pb->setRange(0, 0); - pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - pb->setTextVisible(false); +namespace GpgFrontend::UI { + +WaitingDialog::WaitingDialog(const QString& title, QWidget* parent) + : QDialog(parent) { + auto* pb = new QProgressBar(); + pb->setRange(0, 0); + pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + pb->setTextVisible(false); - auto *layout = new QVBoxLayout(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - layout->addWidget(pb); - this->setLayout(layout); + auto* layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addWidget(pb); + this->setLayout(layout); - this->setModal(true); - this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); - this->setWindowTitle(title); - this->setFixedSize(240, 42); - this->show(); + this->setModal(true); + this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | + Qt::CustomizeWindowHint); + this->setWindowTitle(title); + this->setFixedSize(240, 42); + this->show(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/WaitingDialog.h b/src/ui/WaitingDialog.h new file mode 100644 index 00000000..a81ab9ce --- /dev/null +++ b/src/ui/WaitingDialog.h @@ -0,0 +1,41 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class WaitingDialog : public QDialog { + Q_OBJECT + public: + WaitingDialog(const QString& title, QWidget* parent); + + public slots: + + private slots: + + private: +}; + +} // namespace GpgFrontend::UI diff --git a/src/ui/Wizard.cpp b/src/ui/Wizard.cpp index 4c7b8d7c..2f050e80 100644 --- a/src/ui/Wizard.cpp +++ b/src/ui/Wizard.cpp @@ -24,234 +24,256 @@ #include "ui/Wizard.h" -Wizard::Wizard(GpgFrontend::GpgContext *ctx, KeyMgmt *keyMgmt, QWidget *parent) - : QWizard(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) { - mCtx = ctx; - mKeyMgmt = keyMgmt; - - setPage(Page_Intro, new IntroPage(this)); - setPage(Page_Choose, new ChoosePage(this)); - setPage(Page_GenKey, new KeyGenPage(mCtx, this)); - setPage(Page_Conclusion, new ConclusionPage(this)); +namespace GpgFrontend::UI { + +Wizard::Wizard(KeyMgmt* keyMgmt, QWidget* parent) + : QWizard(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + mKeyMgmt = keyMgmt; + + setPage(Page_Intro, new IntroPage(this)); + setPage(Page_Choose, new ChoosePage(this)); + setPage(Page_GenKey, new KeyGenPage(this)); + setPage(Page_Conclusion, new ConclusionPage(this)); #ifndef Q_WS_MAC - setWizardStyle(ModernStyle); + setWizardStyle(ModernStyle); #endif - setWindowTitle(tr("First Start Wizard")); + setWindowTitle(tr("First Start Wizard")); - // http://www.flickr.com/photos/laureenp/6141822934/ - setPixmap(QWizard::WatermarkPixmap, QPixmap(":/keys2.jpg")); - setPixmap(QWizard::LogoPixmap, QPixmap(":/logo_small.png")); - setPixmap(QWizard::BannerPixmap, QPixmap(":/banner.png")); + // http://www.flickr.com/photos/laureenp/6141822934/ + setPixmap(QWizard::WatermarkPixmap, QPixmap(":/keys2.jpg")); + setPixmap(QWizard::LogoPixmap, QPixmap(":/logo_small.png")); + setPixmap(QWizard::BannerPixmap, QPixmap(":/banner.png")); - setStartId(settings.value("wizard/nextPage", -1).toInt()); - settings.remove("wizard/nextPage"); - - connect(this, SIGNAL(accepted()), this, SLOT(slotWizardAccepted())); + setStartId(settings.value("wizard/nextPage", -1).toInt()); + settings.remove("wizard/nextPage"); + connect(this, SIGNAL(accepted()), this, SLOT(slotWizardAccepted())); } void Wizard::slotWizardAccepted() { - // Don't show is mapped to show -> negation - settings.setValue("wizard/showWizard", !field("showWizard").toBool()); + // Don't show is mapped to show -> negation + settings.setValue("wizard/showWizard", !field("showWizard").toBool()); - if (field("openHelp").toBool()) { - emit signalOpenHelp("docu.html#content"); - } + if (field("openHelp").toBool()) { + emit signalOpenHelp("docu.html#content"); + } } -IntroPage::IntroPage(QWidget *parent) - : QWizardPage(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) { - setTitle(tr("Getting Started...")); - setSubTitle(tr("... with GPGFrontend")); - - auto *topLabel = new QLabel(tr("Welcome to use GPGFrontend for decrypting and signing text or file!") + - " <br><br><a href='https://gpgfrontend.pub'>GpgFrontend</a> " + - tr("is a Powerful, Easy-to-Use, Compact, Cross-Platform, and Installation-Free OpenPGP Crypto Tool.") + - tr("For brief information have a look at the") + - " <a href='https://gpgfrontend.pub/index.html#/overview'>" + - tr("Overview") + "</a> (" + - tr("by clicking the link, the page will open in the web browser") + - "). <br>"); - topLabel->setTextFormat(Qt::RichText); - topLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - topLabel->setOpenExternalLinks(true); - topLabel->setWordWrap(true); - - // QComboBox for language selection - auto *langLabel = new QLabel(tr("Choose a Language")); - langLabel->setWordWrap(true); - - languages = SettingsDialog::listLanguages(); - auto *langSelectBox = new QComboBox(); - - for (const auto &l : languages) { - langSelectBox->addItem(l); - } - // selected entry from config - QString langKey = settings.value("int/lang").toString(); - QString langValue = languages.value(langKey); - if (langKey != "") { - langSelectBox->setCurrentIndex(langSelectBox->findText(langValue)); - } - - connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotLangChange(QString))); - - // set layout and add widgets - auto *layout = new QVBoxLayout; - layout->addWidget(topLabel); - layout->addWidget(langLabel); - layout->addWidget(langSelectBox); - setLayout(layout); +IntroPage::IntroPage(QWidget* parent) + : QWizardPage(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + setTitle(tr("Getting Started...")); + setSubTitle(tr("... with GPGFrontend")); + + auto* topLabel = new QLabel( + tr("Welcome to use GPGFrontend for decrypting and signing text or " + "file!") + + " <br><br><a href='https://gpgfrontend.pub'>GpgFrontend</a> " + + tr("is a Powerful, Easy-to-Use, Compact, Cross-Platform, and " + "Installation-Free OpenPGP Crypto Tool.") + + tr("For brief information have a look at the") + + " <a href='https://gpgfrontend.pub/index.html#/overview'>" + + tr("Overview") + "</a> (" + + tr("by clicking the link, the page will open in the web browser") + + "). <br>"); + topLabel->setTextFormat(Qt::RichText); + topLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + topLabel->setOpenExternalLinks(true); + topLabel->setWordWrap(true); + + // QComboBox for language selection + auto* langLabel = new QLabel(tr("Choose a Language")); + langLabel->setWordWrap(true); + + languages = SettingsDialog::listLanguages(); + auto* langSelectBox = new QComboBox(); + + for (const auto& l : languages) { + langSelectBox->addItem(l); + } + // selected entry from config + QString langKey = settings.value("int/lang").toString(); + QString langValue = languages.value(langKey); + if (langKey != "") { + langSelectBox->setCurrentIndex(langSelectBox->findText(langValue)); + } + + connect(langSelectBox, SIGNAL(currentIndexChanged(QString)), this, + SLOT(slotLangChange(QString))); + + // set layout and add widgets + auto* layout = new QVBoxLayout; + layout->addWidget(topLabel); + layout->addWidget(langLabel); + layout->addWidget(langSelectBox); + setLayout(layout); } -void IntroPage::slotLangChange(const QString &lang) { - settings.setValue("int/lang", languages.key(lang)); - settings.setValue("wizard/nextPage", this->wizard()->currentId()); - qApp->exit(RESTART_CODE); +void IntroPage::slotLangChange(const QString& lang) { + settings.setValue("int/lang", languages.key(lang)); + settings.setValue("wizard/nextPage", this->wizard()->currentId()); + qApp->exit(RESTART_CODE); } int IntroPage::nextId() const { - return Wizard::Page_Choose; + return Wizard::Page_Choose; } -ChoosePage::ChoosePage(QWidget *parent) - : QWizardPage(parent) { - setTitle(tr("Choose your action...")); - setSubTitle(tr("...by clicking on the appropriate link.")); - - auto *keygenLabel = new QLabel(tr("If you have never used GPGFrontend before and also don't own a gpg key yet you " - "may possibly want to read how to") + - " <a href=\"https://gpgfrontend.pub/index.html#/manual/generate-key\">" - + tr("Generate Key") + "</a><hr>"); - keygenLabel->setTextFormat(Qt::RichText); - keygenLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - keygenLabel->setOpenExternalLinks(true); - keygenLabel->setWordWrap(true); - - auto *encrDecyTextLabel = new QLabel( - tr("If you want to learn how to encrypt, decrypt, sign and verify text, you can read ") - + "<a href=\"https://gpgfrontend.pub/index.html#/manual/encrypt-decrypt-text\">" - + tr("Encrypt & Decrypt Text") + "</a> " + tr("or") - + " <a href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-text\">" - + tr("Sign & Verify Text") - + "</a><hr>"); - - encrDecyTextLabel->setTextFormat(Qt::RichText); - encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - encrDecyTextLabel->setOpenExternalLinks(true); - encrDecyTextLabel->setWordWrap(true); - - auto *signVerifyTextLabel = new QLabel(tr("If you want to operate file, you can read ") - + - "<a href=\"https://gpgfrontend.pub/index.html#/manual/encrypt-decrypt-file\">" - + tr("Encrypt & Sign File") + "</a> " + tr("or") - + - " <a href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-file\">" - + tr("Sign & Verify File") - + "</a><hr>"); - signVerifyTextLabel->setTextFormat(Qt::RichText); - signVerifyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - signVerifyTextLabel->setOpenExternalLinks(true); - signVerifyTextLabel->setWordWrap(true); - - auto *layout = new QVBoxLayout(); - layout->addWidget(keygenLabel); - layout->addWidget(encrDecyTextLabel); - layout->addWidget(signVerifyTextLabel); - setLayout(layout); - nextPage = Wizard::Page_Conclusion; +ChoosePage::ChoosePage(QWidget* parent) : QWizardPage(parent) { + setTitle(tr("Choose your action...")); + setSubTitle(tr("...by clicking on the appropriate link.")); + + auto* keygenLabel = new QLabel( + tr("If you have never used GPGFrontend before and also don't own a gpg " + "key yet you " + "may possibly want to read how to") + + " <a href=\"https://gpgfrontend.pub/index.html#/manual/generate-key\">" + + tr("Generate Key") + "</a><hr>"); + keygenLabel->setTextFormat(Qt::RichText); + keygenLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + keygenLabel->setOpenExternalLinks(true); + keygenLabel->setWordWrap(true); + + auto* encrDecyTextLabel = new QLabel( + tr("If you want to learn how to encrypt, decrypt, sign and verify text, " + "you can read ") + + "<a " + "href=\"https://gpgfrontend.pub/index.html#/manual/" + "encrypt-decrypt-text\">" + + tr("Encrypt & Decrypt Text") + "</a> " + tr("or") + + " <a " + "href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-text\">" + + tr("Sign & Verify Text") + "</a><hr>"); + + encrDecyTextLabel->setTextFormat(Qt::RichText); + encrDecyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + encrDecyTextLabel->setOpenExternalLinks(true); + encrDecyTextLabel->setWordWrap(true); + + auto* signVerifyTextLabel = new QLabel( + tr("If you want to operate file, you can read ") + + "<a " + "href=\"https://gpgfrontend.pub/index.html#/manual/" + "encrypt-decrypt-file\">" + + tr("Encrypt & Sign File") + "</a> " + tr("or") + + " <a " + "href=\"https://gpgfrontend.pub/index.html#/manual/sign-verify-file\">" + + tr("Sign & Verify File") + "</a><hr>"); + signVerifyTextLabel->setTextFormat(Qt::RichText); + signVerifyTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + signVerifyTextLabel->setOpenExternalLinks(true); + signVerifyTextLabel->setWordWrap(true); + + auto* layout = new QVBoxLayout(); + layout->addWidget(keygenLabel); + layout->addWidget(encrDecyTextLabel); + layout->addWidget(signVerifyTextLabel); + setLayout(layout); + nextPage = Wizard::Page_Conclusion; } int ChoosePage::nextId() const { - return nextPage; + return nextPage; } -void ChoosePage::slotJumpPage(const QString &page) { - QMetaObject qmo = Wizard::staticMetaObject; - int index = qmo.indexOfEnumerator("WizardPages"); - QMetaEnum m = qmo.enumerator(index); +void ChoosePage::slotJumpPage(const QString& page) { + QMetaObject qmo = Wizard::staticMetaObject; + int index = qmo.indexOfEnumerator("WizardPages"); + QMetaEnum m = qmo.enumerator(index); - nextPage = m.keyToValue(page.toUtf8().data()); - wizard()->next(); + nextPage = m.keyToValue(page.toUtf8().data()); + wizard()->next(); } -KeyGenPage::KeyGenPage(GpgFrontend::GpgContext *ctx, QWidget *parent) - : QWizardPage(parent) { - mCtx = ctx; - setTitle(tr("Create a keypair...")); - setSubTitle(tr("...for decrypting and signing messages")); - auto *topLabel = new QLabel(tr("You should create a new keypair." - "The pair consists of a public and a private key.<br>" - "Other users can use the public key to encrypt messages for you " - "and verify messages signed by you." - "You can use the private key to decrypt and sign messages.<br>" - "For more information have a look at the offline tutorial (which then is shown in the main window):")); - topLabel->setWordWrap(true); - auto *linkLabel = new QLabel("<a href=""docu_keygen.html#content"">" + tr("Offline tutorial") + "</a>"); - //linkLabel->setOpenExternalLinks(true); - - // connect(linkLabel, SIGNAL(linkActivated(QString)), parentWidget()->parentWidget(), SLOT(openHelp(QString))); - - auto *createKeyButtonBox = new QWidget(this); - auto *createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox); - auto *createKeyButton = new QPushButton(tr("Create New Key")); - createKeyButtonBoxLayout->addWidget(createKeyButton); - createKeyButtonBoxLayout->addStretch(1); - auto *layout = new QVBoxLayout(); - layout->addWidget(topLabel); - layout->addWidget(linkLabel); - layout->addWidget(createKeyButtonBox); - connect(createKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotGenerateKeyDialog())); - - setLayout(layout); +KeyGenPage::KeyGenPage(QWidget* parent) : QWizardPage(parent) { + setTitle(tr("Create a keypair...")); + setSubTitle(tr("...for decrypting and signing messages")); + auto* topLabel = new QLabel( + tr("You should create a new keypair." + "The pair consists of a public and a private key.<br>" + "Other users can use the public key to encrypt messages for you " + "and verify messages signed by you." + "You can use the private key to decrypt and sign messages.<br>" + "For more information have a look at the offline tutorial (which then " + "is shown in the main window):")); + topLabel->setWordWrap(true); + auto* linkLabel = new QLabel( + "<a href=" + "docu_keygen.html#content" + ">" + + tr("Offline tutorial") + "</a>"); + // linkLabel->setOpenExternalLinks(true); + + // connect(linkLabel, SIGNAL(linkActivated(QString)), + // parentWidget()->parentWidget(), SLOT(openHelp(QString))); + + auto* createKeyButtonBox = new QWidget(this); + auto* createKeyButtonBoxLayout = new QHBoxLayout(createKeyButtonBox); + auto* createKeyButton = new QPushButton(tr("Create New Key")); + createKeyButtonBoxLayout->addWidget(createKeyButton); + createKeyButtonBoxLayout->addStretch(1); + auto* layout = new QVBoxLayout(); + layout->addWidget(topLabel); + layout->addWidget(linkLabel); + layout->addWidget(createKeyButtonBox); + connect(createKeyButton, SIGNAL(clicked(bool)), this, + SLOT(slotGenerateKeyDialog())); + + setLayout(layout); } int KeyGenPage::nextId() const { - return Wizard::Page_Conclusion; + return Wizard::Page_Conclusion; } void KeyGenPage::slotGenerateKeyDialog() { - qDebug() << "Try Opening KeyGenDialog"; - auto *keyGenDialog = new KeyGenDialog(mCtx, this); - keyGenDialog->show(); - wizard()->next(); + qDebug() << "Try Opening KeyGenDialog"; + (new KeyGenDialog(this))->show(); + wizard()->next(); } -ConclusionPage::ConclusionPage(QWidget *parent) - : QWizardPage(parent) { - setTitle(tr("Ready.")); - setSubTitle(tr("Have fun with GPGFrontend!")); - - auto *bottomLabel = new QLabel(tr("You are ready to use GPGFrontend now.<br><br>") + - "<a href=\"https://saturneric.github.io/GpgFrontend/index.html#/overview\">" - + tr("The Online Document") + "</a>" - + - tr(" will get you started with GPGFrontend. It will open in the main window.<br>")); - - bottomLabel->setTextFormat(Qt::RichText); - bottomLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - bottomLabel->setOpenExternalLinks(true); - bottomLabel->setWordWrap(true); - - openHelpCheckBox = new QCheckBox(tr("Open offline help.")); - openHelpCheckBox->setChecked(Qt::Checked); - - dontShowWizardCheckBox = new QCheckBox(tr("Dont show the wizard again.")); - dontShowWizardCheckBox->setChecked(Qt::Checked); - - registerField("showWizard", dontShowWizardCheckBox); - // registerField("openHelp", openHelpCheckBox); - - auto *layout = new QVBoxLayout; - layout->addWidget(bottomLabel); - // layout->addWidget(openHelpCheckBox); - layout->addWidget(dontShowWizardCheckBox); - setLayout(layout); - setVisible(true); +ConclusionPage::ConclusionPage(QWidget* parent) : QWizardPage(parent) { + setTitle(tr("Ready.")); + setSubTitle(tr("Have fun with GPGFrontend!")); + + auto* bottomLabel = + new QLabel(tr("You are ready to use GPGFrontend now.<br><br>") + + "<a " + "href=\"https://saturneric.github.io/GpgFrontend/index.html#/" + "overview\">" + + tr("The Online Document") + "</a>" + + tr(" will get you started with GPGFrontend. It will open in " + "the main window.<br>")); + + bottomLabel->setTextFormat(Qt::RichText); + bottomLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + bottomLabel->setOpenExternalLinks(true); + bottomLabel->setWordWrap(true); + + openHelpCheckBox = new QCheckBox(tr("Open offline help.")); + openHelpCheckBox->setChecked(Qt::Checked); + + dontShowWizardCheckBox = new QCheckBox(tr("Dont show the wizard again.")); + dontShowWizardCheckBox->setChecked(Qt::Checked); + + registerField("showWizard", dontShowWizardCheckBox); + // registerField("openHelp", openHelpCheckBox); + + auto* layout = new QVBoxLayout; + layout->addWidget(bottomLabel); + // layout->addWidget(openHelpCheckBox); + layout->addWidget(dontShowWizardCheckBox); + setLayout(layout); + setVisible(true); } int ConclusionPage::nextId() const { - return -1; + return -1; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/Wizard.h b/src/ui/Wizard.h new file mode 100644 index 00000000..cb6cd13e --- /dev/null +++ b/src/ui/Wizard.h @@ -0,0 +1,129 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef WIZARD_H +#define WIZARD_H + +#include "SettingsDialog.h" +#include "gpg/GpgConstants.h" +#include "ui/GpgFrontendUI.h" +#include "ui/KeyMgmt.h" +#include "ui/keygen/KeygenDialog.h" + +namespace GpgFrontend::UI { + +class Wizard : public QWizard { + Q_OBJECT + Q_ENUMS(WizardPages) + + public: + enum WizardPages { + Page_Intro, + Page_Choose, + Page_ImportFromGpg4usb, + Page_ImportFromGnupg, + Page_GenKey, + Page_Conclusion + }; + + Wizard(KeyMgmt* keyMgmt, QWidget* parent = nullptr); + + private: + KeyMgmt* mKeyMgmt; + QString appPath; + QSettings settings; + + private slots: + + void slotWizardAccepted(); + + signals: + + void signalOpenHelp(QString page); +}; + +class IntroPage : public QWizardPage { + Q_OBJECT + + public: + explicit IntroPage(QWidget* parent = nullptr); + + QHash<QString, QString> languages; + + [[nodiscard]] int nextId() const override; + + private: + QString appPath; + QSettings settings; + + private slots: + + void slotLangChange(const QString& lang); +}; + +class ChoosePage : public QWizardPage { + Q_OBJECT + + public: + explicit ChoosePage(QWidget* parent = nullptr); + + private slots: + + void slotJumpPage(const QString& page); + + private: + [[nodiscard]] int nextId() const override; + + int nextPage; +}; + +class KeyGenPage : public QWizardPage { + Q_OBJECT + + public: + explicit KeyGenPage(QWidget* parent = nullptr); + + [[nodiscard]] int nextId() const override; + + private slots: + + void slotGenerateKeyDialog(); +}; + +class ConclusionPage : public QWizardPage { + Q_OBJECT + + public: + explicit ConclusionPage(QWidget* parent = nullptr); + + [[nodiscard]] int nextId() const override; + + private: + QCheckBox* dontShowWizardCheckBox; + QCheckBox* openHelpCheckBox; +}; + +} // namespace GpgFrontend::UI + +#endif diff --git a/src/ui/help/AboutDialog.cpp b/src/ui/help/AboutDialog.cpp index deb6a3bc..4c6c2348 100644 --- a/src/ui/help/AboutDialog.cpp +++ b/src/ui/help/AboutDialog.cpp @@ -30,188 +30,209 @@ using namespace rapidjson; -AboutDialog::AboutDialog(int defaultIndex, QWidget *parent) - : QDialog(parent) { - this->setWindowTitle(tr("About ") + qApp->applicationName()); +namespace GpgFrontend::UI { - auto *tabWidget = new QTabWidget; - auto *infoTab = new InfoTab(); - auto *translatorsTab = new TranslatorsTab(); - updateTab = new UpdateTab(); +AboutDialog::AboutDialog(int defaultIndex, QWidget* parent) : QDialog(parent) { + this->setWindowTitle(tr("About ") + qApp->applicationName()); - tabWidget->addTab(infoTab, tr("General")); - tabWidget->addTab(translatorsTab, tr("Translators")); - tabWidget->addTab(updateTab, tr("Update")); + auto* tabWidget = new QTabWidget; + auto* infoTab = new InfoTab(); + auto* translatorsTab = new TranslatorsTab(); + updateTab = new UpdateTab(); - connect(tabWidget, &QTabWidget::currentChanged, this, [&](int index) { - qDebug() << "Current Index" << index; - }); + tabWidget->addTab(infoTab, tr("General")); + tabWidget->addTab(translatorsTab, tr("Translators")); + tabWidget->addTab(updateTab, tr("Update")); - if(defaultIndex < tabWidget->count() && defaultIndex >= 0) { - tabWidget->setCurrentIndex(defaultIndex); - } + connect(tabWidget, &QTabWidget::currentChanged, this, + [&](int index) { qDebug() << "Current Index" << index; }); - auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); + if (defaultIndex < tabWidget->count() && defaultIndex >= 0) { + tabWidget->setCurrentIndex(defaultIndex); + } - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(tabWidget); - mainLayout->addWidget(buttonBox); - setLayout(mainLayout); + auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(close())); - this->show(); + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(tabWidget); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + + this->show(); } -void AboutDialog::showEvent(QShowEvent *ev) { - QDialog::showEvent(ev); - updateTab->getLatestVersion(); +void AboutDialog::showEvent(QShowEvent* ev) { + QDialog::showEvent(ev); + updateTab->getLatestVersion(); } -InfoTab::InfoTab(QWidget *parent) - : QWidget(parent) { - auto *pixmap = new QPixmap(":gpgfrontend-logo.png"); - auto *text = new QString("<center><h2>" + qApp->applicationName() + "</h2></center>" - + "<center><b>" + qApp->applicationVersion() + "</b></center>" - + "<center>" + GIT_VERSION + "</center>" - + tr("<br><center>GPGFrontend is an easy-to-use, compact, cross-platform, <br>" - "and installation-free gpg front-end tool.<br>" - "It visualizes most of the common operations of gpg commands.<br>" - "It's licensed under the GPL v3<br><br>" - "<b>Developer:</b><br>" - "Saturneric<br><br>" - "If you have any questions or suggestions, raise an issue<br/>" - "at <a href=\"https://github.com/saturneric/GpgFrontend\">GitHub</a> or send a mail to my mailing list at <a href=\"mailto:[email protected]\">[email protected]</a>.") + - tr("<br><br> Built with Qt ") + qVersion() - + tr(" and GPGME ") + GpgFrontend::GpgContext::getGpgmeVersion() + - tr("<br>Built at ") + BUILD_TIMESTAMP + "</center>"); - - auto *layout = new QGridLayout(); - auto *pixmapLabel = new QLabel(); - pixmapLabel->setPixmap(*pixmap); - layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); - auto *aboutLabel = new QLabel(); - aboutLabel->setText(*text); - aboutLabel->setOpenExternalLinks(true); - layout->addWidget(aboutLabel, 1, 0, 1, -1); - layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, - QSizePolicy::Fixed), 2, 1, 1, 1); - - setLayout(layout); +InfoTab::InfoTab(QWidget* parent) : QWidget(parent) { + auto* pixmap = new QPixmap(":gpgfrontend-logo.png"); + auto* text = new QString( + "<center><h2>" + qApp->applicationName() + "</h2></center>" + + "<center><b>" + qApp->applicationVersion() + "</b></center>" + + "<center>" + GIT_VERSION + "</center>" + + tr("<br><center>GPGFrontend is an easy-to-use, compact, cross-platform, " + "<br>" + "and installation-free gpg front-end tool.<br>" + "It visualizes most of the common operations of gpg commands.<br>" + "It's licensed under the GPL v3<br><br>" + "<b>Developer:</b><br>" + "Saturneric<br><br>" + "If you have any questions or suggestions, raise an issue<br/>" + "at <a href=\"https://github.com/saturneric/GpgFrontend\">GitHub</a> " + "or send a mail to my mailing list at <a " + "href=\"mailto:[email protected]\">[email protected]</a>.") + + tr("<br><br> Built with Qt ") + qVersion() + tr(" and GPGME ") + + GpgFrontend::GpgContext::getGpgmeVersion().c_str() + tr("<br>Built at ") + + BUILD_TIMESTAMP + "</center>"); + + auto* layout = new QGridLayout(); + auto* pixmapLabel = new QLabel(); + pixmapLabel->setPixmap(*pixmap); + layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); + auto* aboutLabel = new QLabel(); + aboutLabel->setText(*text); + aboutLabel->setOpenExternalLinks(true); + layout->addWidget(aboutLabel, 1, 0, 1, -1); + layout->addItem( + new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1, + 1, 1); + + setLayout(layout); } -TranslatorsTab::TranslatorsTab(QWidget *parent) - : QWidget(parent) { - QFile translatorsFile; - translatorsFile.setFileName(qApp->applicationDirPath() + "/About"); - translatorsFile.open(QIODevice::ReadOnly); - QByteArray inBuffer = translatorsFile.readAll(); +TranslatorsTab::TranslatorsTab(QWidget* parent) : QWidget(parent) { + QFile translatorsFile; + translatorsFile.setFileName(qApp->applicationDirPath() + "/About"); + translatorsFile.open(QIODevice::ReadOnly); + QByteArray inBuffer = translatorsFile.readAll(); - auto *label = new QLabel(inBuffer); - auto *mainLayout = new QVBoxLayout(this); - mainLayout->addWidget(label); + auto* label = new QLabel(inBuffer); + auto* mainLayout = new QVBoxLayout(this); + mainLayout->addWidget(label); - setLayout(mainLayout); + setLayout(mainLayout); } -UpdateTab::UpdateTab(QWidget *parent) { - auto *pixmap = new QPixmap(":gpgfrontend-logo.png"); - auto *layout = new QGridLayout(); - auto *pixmapLabel = new QLabel(); - pixmapLabel->setPixmap(*pixmap); - layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); - - currentVersion = "v" + QString::number(VERSION_MAJOR) + "." - + QString::number(VERSION_MINOR) + "." - + QString::number(VERSION_PATCH); - - auto tipsLabel = new QLabel(); - tipsLabel->setText("<center>" + - tr("It is recommended that you always check the version of GpgFrontend and upgrade to the latest version.") + - "</center><br><center>" + - tr("New versions not only represent new features, but also often represent functional and security fixes.") + "</center>"); - tipsLabel->setWordWrap(true); - - currentVersionLabel = new QLabel(); - currentVersionLabel->setText("<center>" + tr("Current Version: ") + "<b>" + currentVersion + "</b></center>"); - currentVersionLabel->setWordWrap(true); - - latestVersionLabel = new QLabel(); - latestVersionLabel->setWordWrap(true); - - upgradeLabel = new QLabel(); - upgradeLabel->setText("<center>" + - tr("The current version is inconsistent with the latest version on github.") + - "</center><br><center>" + - tr("Please click <a href=\"https://github.com/saturneric/GpgFrontend/releases\">here</a> to download the latest version.") + "</center>"); - upgradeLabel->setWordWrap(true); - upgradeLabel->setOpenExternalLinks(true); - upgradeLabel->setHidden(true); - - pb = new QProgressBar(); - pb->setRange(0, 0); - pb->setTextVisible(false); - - layout->addWidget(tipsLabel, 1, 0, 1, -1); - layout->addWidget(currentVersionLabel, 2, 0, 1, -1); - layout->addWidget(latestVersionLabel, 3, 0, 1, -1); - layout->addWidget(upgradeLabel, 4, 0, 1, -1); - layout->addWidget(pb, 5, 0, 1, -1); - layout->addItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, - QSizePolicy::Fixed), 2, 1, 1, 1); - - connect(this, SIGNAL(replyFromUpdateServer(QByteArray)), this, SLOT(processReplyDataFromUpdateServer(QByteArray))); - - setLayout(layout); +UpdateTab::UpdateTab(QWidget* parent) { + auto* pixmap = new QPixmap(":gpgfrontend-logo.png"); + auto* layout = new QGridLayout(); + auto* pixmapLabel = new QLabel(); + pixmapLabel->setPixmap(*pixmap); + layout->addWidget(pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter); + + currentVersion = "v" + QString::number(VERSION_MAJOR) + "." + + QString::number(VERSION_MINOR) + "." + + QString::number(VERSION_PATCH); + + auto tipsLabel = new QLabel(); + tipsLabel->setText("<center>" + + tr("It is recommended that you always check the version " + "of GpgFrontend and upgrade to the latest version.") + + "</center><br><center>" + + tr("New versions not only represent new features, but " + "also often represent functional and security fixes.") + + "</center>"); + tipsLabel->setWordWrap(true); + + currentVersionLabel = new QLabel(); + currentVersionLabel->setText("<center>" + tr("Current Version: ") + "<b>" + + currentVersion + "</b></center>"); + currentVersionLabel->setWordWrap(true); + + latestVersionLabel = new QLabel(); + latestVersionLabel->setWordWrap(true); + + upgradeLabel = new QLabel(); + upgradeLabel->setText( + "<center>" + + tr("The current version is inconsistent with the latest version on " + "github.") + + "</center><br><center>" + + tr("Please click <a " + "href=\"https://github.com/saturneric/GpgFrontend/releases\">here</a> " + "to download the latest version.") + + "</center>"); + upgradeLabel->setWordWrap(true); + upgradeLabel->setOpenExternalLinks(true); + upgradeLabel->setHidden(true); + + pb = new QProgressBar(); + pb->setRange(0, 0); + pb->setTextVisible(false); + + layout->addWidget(tipsLabel, 1, 0, 1, -1); + layout->addWidget(currentVersionLabel, 2, 0, 1, -1); + layout->addWidget(latestVersionLabel, 3, 0, 1, -1); + layout->addWidget(upgradeLabel, 4, 0, 1, -1); + layout->addWidget(pb, 5, 0, 1, -1); + layout->addItem( + new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed), 2, 1, + 1, 1); + + connect(this, SIGNAL(replyFromUpdateServer(QByteArray)), this, + SLOT(processReplyDataFromUpdateServer(QByteArray))); + + setLayout(layout); } void UpdateTab::getLatestVersion() { + this->pb->setHidden(false); - this->pb->setHidden(false); - - qDebug() << "Try to get latest version"; - - QString baseUrl = "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; + qDebug() << "Try to get latest version"; - auto manager = new QNetworkAccessManager(this); + QString baseUrl = + "https://api.github.com/repos/saturneric/gpgfrontend/releases/latest"; - QNetworkRequest request; - request.setUrl(QUrl(baseUrl)); - QNetworkReply *replay = manager->get(request); - auto thread = QThread::create([replay, this]() { - while(replay->isRunning()) QApplication::processEvents(); - emit replyFromUpdateServer(replay->readAll()); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); + auto manager = new QNetworkAccessManager(this); + QNetworkRequest request; + request.setUrl(QUrl(baseUrl)); + QNetworkReply* replay = manager->get(request); + auto thread = QThread::create([replay, this]() { + while (replay->isRunning()) + QApplication::processEvents(); + emit replyFromUpdateServer(replay->readAll()); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); } void UpdateTab::processReplyDataFromUpdateServer(const QByteArray& data) { - - qDebug() << "Try to Process Reply Data From Update Server"; - - this->pb->setHidden(true); - - Document d; - if (d.Parse(data.constData()).HasParseError() || !d.IsObject()) { - qDebug() << "VersionCheckThread Found Network Error"; - auto latestVersion = "Unknown"; - latestVersionLabel->setText("<center><b>" + tr("Latest Version From Github: ") + latestVersion + "</b></center>"); - return; - } - - QString latestVersion = d["tag_name"].GetString(); - - qDebug() << "Latest Version From Github" << latestVersion; - - QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))"); - QRegularExpressionMatch match = re.match(latestVersion); - if (match.hasMatch()) { - latestVersion = match.captured(0); - qDebug() << "Latest Version Matched" << latestVersion; - } else latestVersion = "Unknown"; - - latestVersionLabel->setText("<center><b>" + tr("Latest Version From Github: ") + latestVersion + "</b></center>"); - - if(latestVersion > currentVersion) upgradeLabel->setHidden(false); + qDebug() << "Try to Process Reply Data From Update Server"; + + this->pb->setHidden(true); + + Document d; + if (d.Parse(data.constData()).HasParseError() || !d.IsObject()) { + qDebug() << "VersionCheckThread Found Network Error"; + auto latestVersion = "Unknown"; + latestVersionLabel->setText("<center><b>" + + tr("Latest Version From Github: ") + + latestVersion + "</b></center>"); + return; + } + + QString latestVersion = d["tag_name"].GetString(); + + qDebug() << "Latest Version From Github" << latestVersion; + + QRegularExpression re(R"(^[vV](\d+\.)?(\d+\.)?(\*|\d+))"); + QRegularExpressionMatch match = re.match(latestVersion); + if (match.hasMatch()) { + latestVersion = match.captured(0); + qDebug() << "Latest Version Matched" << latestVersion; + } else + latestVersion = "Unknown"; + + latestVersionLabel->setText("<center><b>" + + tr("Latest Version From Github: ") + + latestVersion + "</b></center>"); + + if (latestVersion > currentVersion) + upgradeLabel->setHidden(false); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/help/AboutDialog.h b/src/ui/help/AboutDialog.h new file mode 100644 index 00000000..3b7d42c8 --- /dev/null +++ b/src/ui/help/AboutDialog.h @@ -0,0 +1,103 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __ABOUTDIALOG_H__ +#define __ABOUTDIALOG_H__ + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" +namespace GpgFrontend::UI { + +/** + * @brief Class containing the main tab of about dialog + * + */ +class InfoTab : public QWidget { + Q_OBJECT + + public: + explicit InfoTab(QWidget* parent = nullptr); +}; + +/** + * @brief Class containing the translator tab of about dialog + * + */ +class TranslatorsTab : public QWidget { + Q_OBJECT + + public: + explicit TranslatorsTab(QWidget* parent = nullptr); +}; + +/** + * @brief Class containing the main tab of about dialog + * + */ +class UpdateTab : public QWidget { + Q_OBJECT + + QLabel* currentVersionLabel; + + QLabel* latestVersionLabel; + + QLabel* upgradeLabel; + + QProgressBar* pb; + + QString currentVersion; + + public: + explicit UpdateTab(QWidget* parent = nullptr); + + void getLatestVersion(); + + private slots: + void processReplyDataFromUpdateServer(const QByteArray& data); + ; + + signals: + void replyFromUpdateServer(QByteArray data); +}; + +/** + * @brief Class for handling the about dialog + * + */ +class AboutDialog : public QDialog { + Q_OBJECT + + public: + explicit AboutDialog(int defaultIndex, QWidget* parent); + + protected: + void showEvent(QShowEvent* ev) override; + + private: + UpdateTab* updateTab; +}; + +} // namespace GpgFrontend::UI + +#endif // __ABOUTDIALOG_H__ diff --git a/src/ui/help/VersionCheckThread.cpp b/src/ui/help/VersionCheckThread.cpp index bf1bbeda..3204dadf 100644 --- a/src/ui/help/VersionCheckThread.cpp +++ b/src/ui/help/VersionCheckThread.cpp @@ -25,51 +25,52 @@ #include "ui/help/VersionCheckThread.h" #include "GpgFrontendBuildInfo.h" #include "rapidjson/document.h" -#include "rapidjson/writer.h" using namespace rapidjson; -void VersionCheckThread::run() { - qDebug() << "Start Version Thread to get latest version from Github"; +namespace GpgFrontend::UI { - auto currentVersion = "v" + QString::number(VERSION_MAJOR) + "." - + QString::number(VERSION_MINOR) + "." - + QString::number(VERSION_PATCH); +void VersionCheckThread::run() { + qDebug() << "Start Version Thread to get latest version from Github"; - while(mNetworkReply->isRunning()) { - QApplication::processEvents(); - } + auto currentVersion = "v" + QString::number(VERSION_MAJOR) + "." + + QString::number(VERSION_MINOR) + "." + + QString::number(VERSION_PATCH); - if(mNetworkReply->error() != QNetworkReply::NoError) { - qDebug() << "VersionCheckThread Found Network Error"; - return; - } + while (mNetworkReply->isRunning()) { + QApplication::processEvents(); + } - QByteArray bytes = mNetworkReply->readAll(); + if (mNetworkReply->error() != QNetworkReply::NoError) { + qDebug() << "VersionCheckThread Found Network Error"; + return; + } - Document d; - d.Parse(bytes.constData()); + QByteArray bytes = mNetworkReply->readAll(); - QString latestVersion = d["tag_name"].GetString(); + Document d; + d.Parse(bytes.constData()); - qDebug() << "Latest Version From Github" << latestVersion; + QString latestVersion = d["tag_name"].GetString(); - QRegularExpression re("^[vV](\\d+\\.)?(\\d+\\.)?(\\*|\\d+)"); - QRegularExpressionMatch match = re.match(latestVersion); - if (match.hasMatch()) { - latestVersion = match.captured(0); // matched == "23 def" - qDebug() << "Latest Version Matched" << latestVersion; - } else { - latestVersion = currentVersion; - qDebug() << "Latest Version Unknown" << latestVersion; - } + qDebug() << "Latest Version From Github" << latestVersion; - if(latestVersion != currentVersion) { - emit upgradeVersion(currentVersion, latestVersion); - } + QRegularExpression re("^[vV](\\d+\\.)?(\\d+\\.)?(\\*|\\d+)"); + QRegularExpressionMatch match = re.match(latestVersion); + if (match.hasMatch()) { + latestVersion = match.captured(0); // matched == "23 def" + qDebug() << "Latest Version Matched" << latestVersion; + } else { + latestVersion = currentVersion; + qDebug() << "Latest Version Unknown" << latestVersion; + } + if (latestVersion != currentVersion) { + emit upgradeVersion(currentVersion, latestVersion); + } } -VersionCheckThread::VersionCheckThread(QNetworkReply *networkReply):mNetworkReply(networkReply) { +VersionCheckThread::VersionCheckThread(QNetworkReply* networkReply) + : mNetworkReply(networkReply) {} -} +} // namespace GpgFrontend::UI diff --git a/src/ui/help/VersionCheckThread.h b/src/ui/help/VersionCheckThread.h new file mode 100644 index 00000000..eedbfa5b --- /dev/null +++ b/src/ui/help/VersionCheckThread.h @@ -0,0 +1,52 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_VERSIONCHECKTHREAD_H +#define GPGFRONTEND_VERSIONCHECKTHREAD_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class VersionCheckThread : public QThread { + Q_OBJECT + + public: + explicit VersionCheckThread(QNetworkReply* networkReply); + + signals: + + void upgradeVersion(const QString& currentVersion, + const QString& latestVersion); + + protected: + void run() override; + + private: + QNetworkReply* mNetworkReply; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_VERSIONCHECKTHREAD_H diff --git a/src/ui/keygen/KeygenDialog.cpp b/src/ui/keygen/KeygenDialog.cpp index 958f9ecc..0786d644 100644 --- a/src/ui/keygen/KeygenDialog.cpp +++ b/src/ui/keygen/KeygenDialog.cpp @@ -23,339 +23,340 @@ */ #include "ui/keygen/KeygenDialog.h" +#include "gpg/function/GpgKeyOpera.h" #include "ui/WaitingDialog.h" -KeyGenDialog::KeyGenDialog(GpgFrontend::GpgContext *ctx, QWidget *parent) - : QDialog(parent), mCtx(ctx) { +namespace GpgFrontend::UI { - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); +KeyGenDialog::KeyGenDialog(QWidget* parent) : QDialog(parent) { + buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - this->setWindowTitle(tr("Generate Key")); - this->setModal(true); - generateKeyDialog(); + this->setWindowTitle(tr("Generate Key")); + this->setModal(true); + generateKeyDialog(); } void KeyGenDialog::generateKeyDialog() { + keyUsageGroupBox = create_key_usage_group_box(); - keyUsageGroupBox = create_key_usage_group_box(); + auto* groupGrid = new QGridLayout(this); + groupGrid->addWidget(create_basic_info_group_box(), 0, 0); + groupGrid->addWidget(keyUsageGroupBox, 1, 0); - auto *groupGrid = new QGridLayout(this); - groupGrid->addWidget(create_basic_info_group_box(), 0, 0); - groupGrid->addWidget(keyUsageGroupBox, 1, 0); + auto* nameList = new QWidget(this); + nameList->setLayout(groupGrid); - auto *nameList = new QWidget(this); - nameList->setLayout(groupGrid); + auto* vbox2 = new QVBoxLayout(); + vbox2->addWidget(nameList); + vbox2->addWidget(errorLabel); + vbox2->addWidget(buttonBox); - auto *vbox2 = new QVBoxLayout(); - vbox2->addWidget(nameList); - vbox2->addWidget(errorLabel); - vbox2->addWidget(buttonBox); + this->setLayout(vbox2); - this->setLayout(vbox2); - - set_signal_slot(); - - refresh_widgets_state(); + set_signal_slot(); + refresh_widgets_state(); } void KeyGenDialog::slotKeyGenAccept() { - QString errorString = ""; - + QString errorString = ""; + + /** + * check for errors in keygen dialog input + */ + if ((nameEdit->text()).size() < 5) { + errorString.append(tr(" Name must contain at least five characters. \n")); + } + if (emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) { + errorString.append(tr(" Please give a email address. \n")); + } + + /** + * primary keys should have a reasonable expiration date (no more than 2 years + * in the future) + */ + if (dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { + errorString.append(tr(" Expiration time no more than 2 years. \n")); + } + + if (errorString.isEmpty()) { /** - * check for errors in keygen dialog input + * create the string for key generation */ - if ((nameEdit->text()).size() < 5) { - errorString.append(tr(" Name must contain at least five characters. \n")); - } if(emailEdit->text().isEmpty() || !check_email_address(emailEdit->text())) { - errorString.append(tr(" Please give a email address. \n")); - } - - /** - * primary keys should have a reasonable expiration date (no more than 2 years in the future) - */ - if(dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { - errorString.append(tr(" Expiration time no more than 2 years. \n")); - } - - if (errorString.isEmpty()) { - /** - * create the string for key generation - */ - genKeyInfo.setUserid(QString("%1 (%3) <%2>").arg(nameEdit->text(), emailEdit->text(), commentEdit->text())); + genKeyInfo->setUserid( + QString("%1 (%3) <%2>") + .arg(nameEdit->text(), emailEdit->text(), commentEdit->text()) + .toStdString()); - genKeyInfo.setKeySize(keySizeSpinBox->value()); + genKeyInfo->setKeySize(keySizeSpinBox->value()); - if (expireCheckBox->checkState()) { - genKeyInfo.setNonExpired(true); - } else { - genKeyInfo.setExpired(dateEdit->dateTime()); - } + if (expireCheckBox->checkState()) { + genKeyInfo->setNonExpired(true); + } else { + genKeyInfo->setExpired( + boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t()) + .date()); + } - gpgme_error_t error = false; - auto thread = QThread::create([&]() { - error = mCtx->generateKey(&genKeyInfo); - }); - thread->start(); + gpgme_error_t error = false; + auto thread = QThread::create( + [&]() { error = GpgKeyOpera::GetInstance().GenerateKey(genKeyInfo); }); + thread->start(); - auto *dialog = new WaitingDialog("Generating", this); - dialog->show(); + auto* dialog = new WaitingDialog("Generating", this); + dialog->show(); - while (thread->isRunning()) { - QCoreApplication::processEvents(); - } + while (thread->isRunning()) { + QCoreApplication::processEvents(); + } - dialog->close(); + dialog->close(); - if(gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - QMessageBox::information(this, tr("Success"), tr("The new key pair has been generated.")); - this->close(); - } - else - QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error))); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { + QMessageBox::information(this, tr("Success"), + tr("The new key pair has been generated.")); + this->close(); + } else + QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error))); - } else { - /** - * create error message - */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); - error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(errorString); - - this->show(); - } + } else { + /** + * create error message + */ + errorLabel->setAutoFillBackground(true); + QPalette error = errorLabel->palette(); + error.setColor(QPalette::Window, "#ff8080"); + errorLabel->setPalette(error); + errorLabel->setText(errorString); + + this->show(); + } } void KeyGenDialog::slotExpireBoxChanged() { - if (expireCheckBox->checkState()) { - dateEdit->setEnabled(false); - } else { - dateEdit->setEnabled(true); - } + if (expireCheckBox->checkState()) { + dateEdit->setEnabled(false); + } else { + dateEdit->setEnabled(true); + } } -QGroupBox *KeyGenDialog::create_key_usage_group_box() { +QGroupBox* KeyGenDialog::create_key_usage_group_box() { + auto* groupBox = new QGroupBox(this); + auto* grid = new QGridLayout(this); - auto *groupBox = new QGroupBox(this); - auto *grid = new QGridLayout(this); + groupBox->setTitle(tr("Key Usage")); - groupBox->setTitle(tr("Key Usage")); + auto* encrypt = new QCheckBox(tr("Encryption"), groupBox); + encrypt->setTristate(false); - auto* encrypt = new QCheckBox(tr("Encryption"), groupBox); - encrypt->setTristate(false); + auto* sign = new QCheckBox(tr("Signing"), groupBox); + sign->setTristate(false); - auto* sign = new QCheckBox(tr("Signing"),groupBox); - sign->setTristate(false); + auto* cert = new QCheckBox(tr("Certification"), groupBox); + cert->setTristate(false); - auto* cert = new QCheckBox(tr("Certification"),groupBox); - cert->setTristate(false); + auto* auth = new QCheckBox(tr("Authentication"), groupBox); + auth->setTristate(false); - auto* auth = new QCheckBox(tr("Authentication"), groupBox); - auth->setTristate(false); + keyUsageCheckBoxes.push_back(encrypt); + keyUsageCheckBoxes.push_back(sign); + keyUsageCheckBoxes.push_back(cert); + keyUsageCheckBoxes.push_back(auth); - keyUsageCheckBoxes.push_back(encrypt); - keyUsageCheckBoxes.push_back(sign); - keyUsageCheckBoxes.push_back(cert); - keyUsageCheckBoxes.push_back(auth); + grid->addWidget(encrypt, 0, 0); + grid->addWidget(sign, 0, 1); + grid->addWidget(cert, 1, 0); + grid->addWidget(auth, 1, 1); - grid->addWidget(encrypt, 0, 0); - grid->addWidget(sign, 0, 1); - grid->addWidget(cert, 1, 0); - grid->addWidget(auth, 1, 1); + groupBox->setLayout(grid); - groupBox->setLayout(grid); - - return groupBox; + return groupBox; } void KeyGenDialog::slotEncryptionBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowEncryption(false); - } else { - genKeyInfo.setAllowEncryption(true); - } + if (state == 0) { + genKeyInfo->setAllowEncryption(false); + } else { + genKeyInfo->setAllowEncryption(true); + } } void KeyGenDialog::slotSigningBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowSigning(false); - } else { - genKeyInfo.setAllowSigning(true); - } + if (state == 0) { + genKeyInfo->setAllowSigning(false); + } else { + genKeyInfo->setAllowSigning(true); + } } void KeyGenDialog::slotCertificationBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowCertification(false); - } else { - genKeyInfo.setAllowCertification(true); - } + if (state == 0) { + genKeyInfo->setAllowCertification(false); + } else { + genKeyInfo->setAllowCertification(true); + } } void KeyGenDialog::slotAuthenticationBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowAuthentication(false); - } else { - genKeyInfo.setAllowAuthentication(true); - } + if (state == 0) { + genKeyInfo->setAllowAuthentication(false); + } else { + genKeyInfo->setAllowAuthentication(true); + } } void KeyGenDialog::slotActivatedKeyType(int index) { + qDebug() << "key type index changed " << index; - qDebug() << "key type index changed " << index; - - genKeyInfo.setAlgo(this->keyTypeComboBox->itemText(index)); - refresh_widgets_state(); + genKeyInfo->setAlgo(this->keyTypeComboBox->itemText(index).toStdString()); + refresh_widgets_state(); } void KeyGenDialog::refresh_widgets_state() { - - qDebug() << "refresh_widgets_state called"; - - if(genKeyInfo.isAllowEncryption()) - keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeEncryption()) - keyUsageCheckBoxes[0]->setDisabled(false); - else - keyUsageCheckBoxes[0]->setDisabled(true); - - - if(genKeyInfo.isAllowSigning()) - keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeSigning()) - keyUsageCheckBoxes[1]->setDisabled(false); - else - keyUsageCheckBoxes[1]->setDisabled(true); - - - if(genKeyInfo.isAllowCertification()) - keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeCertification()) - keyUsageCheckBoxes[2]->setDisabled(false); - else - keyUsageCheckBoxes[2]->setDisabled(true); - - - if(genKeyInfo.isAllowAuthentication()) - keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeAuthentication()) - keyUsageCheckBoxes[3]->setDisabled(false); - else - keyUsageCheckBoxes[3]->setDisabled(true); - - - - if(genKeyInfo.isAllowNoPassPhrase()) - noPassPhraseCheckBox->setDisabled(false); - else - noPassPhraseCheckBox->setDisabled(true); - - - keySizeSpinBox->setRange(genKeyInfo.getSuggestMinKeySize(), genKeyInfo.getSuggestMaxKeySize()); - keySizeSpinBox->setValue(genKeyInfo.getKeySize()); - keySizeSpinBox->setSingleStep(genKeyInfo.getSizeChangeStep()); - - + qDebug() << "refresh_widgets_state called"; + + if (genKeyInfo->isAllowEncryption()) + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeEncryption()) + keyUsageCheckBoxes[0]->setDisabled(false); + else + keyUsageCheckBoxes[0]->setDisabled(true); + + if (genKeyInfo->isAllowSigning()) + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeSigning()) + keyUsageCheckBoxes[1]->setDisabled(false); + else + keyUsageCheckBoxes[1]->setDisabled(true); + + if (genKeyInfo->isAllowCertification()) + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeCertification()) + keyUsageCheckBoxes[2]->setDisabled(false); + else + keyUsageCheckBoxes[2]->setDisabled(true); + + if (genKeyInfo->isAllowAuthentication()) + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeAuthentication()) + keyUsageCheckBoxes[3]->setDisabled(false); + else + keyUsageCheckBoxes[3]->setDisabled(true); + + if (genKeyInfo->isAllowNoPassPhrase()) + noPassPhraseCheckBox->setDisabled(false); + else + noPassPhraseCheckBox->setDisabled(true); + + keySizeSpinBox->setRange(genKeyInfo->getSuggestMinKeySize(), + genKeyInfo->getSuggestMaxKeySize()); + keySizeSpinBox->setValue(genKeyInfo->getKeySize()); + keySizeSpinBox->setSingleStep(genKeyInfo->getSizeChangeStep()); } void KeyGenDialog::set_signal_slot() { - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged())); - - connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionBoxChanged(int))); - connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, SLOT(slotSigningBoxChanged(int))); - connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, SLOT(slotCertificationBoxChanged(int))); - connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, SLOT(slotAuthenticationBoxChanged(int))); - - connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotActivatedKeyType(int))); - - connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this, [this](int state) -> void { - if(state == 0) { - genKeyInfo.setNonPassPhrase(false); - } else { - genKeyInfo.setNonPassPhrase(true); - } - - }); - + connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(expireCheckBox, SIGNAL(stateChanged(int)), this, + SLOT(slotExpireBoxChanged())); + + connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, + SLOT(slotEncryptionBoxChanged(int))); + connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, + SLOT(slotSigningBoxChanged(int))); + connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, + SLOT(slotCertificationBoxChanged(int))); + connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, + SLOT(slotAuthenticationBoxChanged(int))); + + connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(slotActivatedKeyType(int))); + + connect(noPassPhraseCheckBox, &QCheckBox::stateChanged, this, + [this](int state) -> void { + if (state == 0) { + genKeyInfo->setNonPassPhrase(false); + } else { + genKeyInfo->setNonPassPhrase(true); + } + }); } -bool KeyGenDialog::check_email_address(const QString &str) { - return re_email.match(str).hasMatch(); +bool KeyGenDialog::check_email_address(const QString& str) { + return re_email.match(str).hasMatch(); } -QGroupBox *KeyGenDialog::create_basic_info_group_box() { - - errorLabel = new QLabel(tr("")); - nameEdit = new QLineEdit(this); - emailEdit = new QLineEdit(this); - commentEdit = new QLineEdit(this); - keySizeSpinBox = new QSpinBox(this); - keyTypeComboBox = new QComboBox(this); - - for(auto &algo : GenKeyInfo::SupportedKeyAlgo) { - keyTypeComboBox->addItem(algo); - } - if(!GenKeyInfo::SupportedKeyAlgo.isEmpty()) { - keyTypeComboBox->setCurrentIndex(0); - } - - QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); - - dateEdit = new QDateTimeEdit(maxDateTime, this); - dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); - dateEdit->setMaximumDateTime(maxDateTime); - dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); - dateEdit->setCalendarPopup(true); - dateEdit->setEnabled(true); - - expireCheckBox = new QCheckBox(this); - expireCheckBox->setCheckState(Qt::Unchecked); - - noPassPhraseCheckBox = new QCheckBox(this); - noPassPhraseCheckBox->setCheckState(Qt::Unchecked); - - auto *vbox1 = new QGridLayout; - - vbox1->addWidget(new QLabel(tr("Name:")), 0, 0); - vbox1->addWidget(new QLabel(tr("Email Address:")), 1, 0); - vbox1->addWidget(new QLabel(tr("Comment:")), 2, 0); - vbox1->addWidget(new QLabel(tr("Expiration Date:")), 3, 0); - vbox1->addWidget(new QLabel(tr("Never Expire")), 3, 3); - vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 4, 0); - vbox1->addWidget(new QLabel(tr("Key Type:")), 5, 0); - vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 6, 0); - - vbox1->addWidget(nameEdit, 0, 1, 1, 3); - vbox1->addWidget(emailEdit, 1, 1, 1, 3); - vbox1->addWidget(commentEdit, 2, 1, 1, 3); - vbox1->addWidget(dateEdit, 3, 1); - vbox1->addWidget(expireCheckBox, 3, 2); - vbox1->addWidget(keySizeSpinBox, 4, 1); - vbox1->addWidget(keyTypeComboBox, 5, 1); - vbox1->addWidget(noPassPhraseCheckBox, 6, 1); - - auto basicInfoGroupBox = new QGroupBox(); - basicInfoGroupBox->setLayout(vbox1); - basicInfoGroupBox->setTitle(tr("Basic Information")); - - return basicInfoGroupBox; +QGroupBox* KeyGenDialog::create_basic_info_group_box() { + errorLabel = new QLabel(tr("")); + nameEdit = new QLineEdit(this); + emailEdit = new QLineEdit(this); + commentEdit = new QLineEdit(this); + keySizeSpinBox = new QSpinBox(this); + keyTypeComboBox = new QComboBox(this); + + for (auto& algo : GenKeyInfo::SupportedKeyAlgo) { + keyTypeComboBox->addItem(QString::fromStdString(algo)); + } + if (!GenKeyInfo::SupportedKeyAlgo.empty()) { + keyTypeComboBox->setCurrentIndex(0); + } + + QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); + + dateEdit = new QDateTimeEdit(maxDateTime, this); + dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); + dateEdit->setMaximumDateTime(maxDateTime); + dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + dateEdit->setCalendarPopup(true); + dateEdit->setEnabled(true); + + expireCheckBox = new QCheckBox(this); + expireCheckBox->setCheckState(Qt::Unchecked); + + noPassPhraseCheckBox = new QCheckBox(this); + noPassPhraseCheckBox->setCheckState(Qt::Unchecked); + + auto* vbox1 = new QGridLayout; + + vbox1->addWidget(new QLabel(tr("Name:")), 0, 0); + vbox1->addWidget(new QLabel(tr("Email Address:")), 1, 0); + vbox1->addWidget(new QLabel(tr("Comment:")), 2, 0); + vbox1->addWidget(new QLabel(tr("Expiration Date:")), 3, 0); + vbox1->addWidget(new QLabel(tr("Never Expire")), 3, 3); + vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 4, 0); + vbox1->addWidget(new QLabel(tr("Key Type:")), 5, 0); + vbox1->addWidget(new QLabel(tr("Non Pass Phrase")), 6, 0); + + vbox1->addWidget(nameEdit, 0, 1, 1, 3); + vbox1->addWidget(emailEdit, 1, 1, 1, 3); + vbox1->addWidget(commentEdit, 2, 1, 1, 3); + vbox1->addWidget(dateEdit, 3, 1); + vbox1->addWidget(expireCheckBox, 3, 2); + vbox1->addWidget(keySizeSpinBox, 4, 1); + vbox1->addWidget(keyTypeComboBox, 5, 1); + vbox1->addWidget(noPassPhraseCheckBox, 6, 1); + + auto basicInfoGroupBox = new QGroupBox(); + basicInfoGroupBox->setLayout(vbox1); + basicInfoGroupBox->setTitle(tr("Basic Information")); + + return basicInfoGroupBox; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keygen/KeygenDialog.h b/src/ui/keygen/KeygenDialog.h new file mode 100644 index 00000000..97846eb5 --- /dev/null +++ b/src/ui/keygen/KeygenDialog.h @@ -0,0 +1,114 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYGENDIALOG_H__ +#define __KEYGENDIALOG_H__ + +#include "gpg/GpgContext.h" +#include "gpg/GpgGenKeyInfo.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class KeyGenDialog : public QDialog { + Q_OBJECT + + public: + /** + * @details Constructor of this class + * + * @param ctx The current GpgME context + * @param key The key to show details of + * @param parent The parent of this widget + */ + explicit KeyGenDialog(QWidget* parent = nullptr); + + private: + QGroupBox* create_key_usage_group_box(); + + QGroupBox* create_basic_info_group_box(); + + QRegularExpression re_email{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + QStringList errorMessages; /** List of errors occuring when checking entries + of lineedits */ + std::unique_ptr<GenKeyInfo> genKeyInfo = std::make_unique<GenKeyInfo>(); + + QDialogButtonBox* buttonBox; /** Box for standard buttons */ + QLabel* errorLabel{}; /** Label containing error message */ + QLineEdit* nameEdit{}; /** Line edit for the keys name */ + QLineEdit* emailEdit{}; /** Line edit for the keys email */ + QLineEdit* commentEdit{}; /** Line edit for the keys comment */ + QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */ + QComboBox* keyTypeComboBox{}; /** Combobox for Key type */ + QDateTimeEdit* dateEdit{}; /** Date edit for expiration date */ + QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */ + QCheckBox* noPassPhraseCheckBox{}; + + QGroupBox* keyUsageGroupBox{}; /** Group of Widgets detecting the usage of the + Key **/ + + // ENCR, SIGN, CERT, AUTH + std::vector<QCheckBox*> keyUsageCheckBoxes; + + void generateKeyDialog(); + + /** + * @details Refresh widgets state by GenKeyInfo + */ + void refresh_widgets_state(); + + void set_signal_slot(); + + bool check_email_address(const QString& str); + + private slots: + + /** + * @details when expirebox was checked/unchecked, enable/disable the + * expiration date box + */ + void slotExpireBoxChanged(); + + /** + * @details check all lineedits for false entries. Show error, when there is + * one, otherwise generate the key + */ + void slotKeyGenAccept(); + + void slotEncryptionBoxChanged(int state); + + void slotSigningBoxChanged(int state); + + void slotCertificationBoxChanged(int state); + + void slotAuthenticationBoxChanged(int state); + + void slotActivatedKeyType(int index); +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYGENDIALOG_H__ diff --git a/src/ui/keygen/SubkeyGenerateDialog.cpp b/src/ui/keygen/SubkeyGenerateDialog.cpp index 8e5d01a3..1da37393 100644 --- a/src/ui/keygen/SubkeyGenerateDialog.cpp +++ b/src/ui/keygen/SubkeyGenerateDialog.cpp @@ -23,277 +23,288 @@ */ #include "ui/keygen/SubkeyGenerateDialog.h" + +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyOpera.h" #include "ui/WaitingDialog.h" -SubkeyGenerateDialog::SubkeyGenerateDialog(GpgFrontend::GpgContext *ctx, const GpgKey &key, QWidget *parent) - : genKeyInfo(true), mCtx(ctx), mKey(key), QDialog(parent) { +namespace GpgFrontend::UI { - buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); +SubkeyGenerateDialog::SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent) + : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { + buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - keyUsageGroupBox = create_key_usage_group_box(); + keyUsageGroupBox = create_key_usage_group_box(); - auto *groupGrid = new QGridLayout(this); - groupGrid->addWidget(create_basic_info_group_box(), 0, 0); - groupGrid->addWidget(keyUsageGroupBox, 1, 0); + auto* groupGrid = new QGridLayout(this); + groupGrid->addWidget(create_basic_info_group_box(), 0, 0); + groupGrid->addWidget(keyUsageGroupBox, 1, 0); - auto *nameList = new QWidget(this); - nameList->setLayout(groupGrid); + auto* nameList = new QWidget(this); + nameList->setLayout(groupGrid); - auto *vbox2 = new QVBoxLayout(); - vbox2->addWidget(nameList); - vbox2->addWidget(errorLabel); - vbox2->addWidget(buttonBox); + auto* vbox2 = new QVBoxLayout(); + vbox2->addWidget(nameList); + vbox2->addWidget(errorLabel); + vbox2->addWidget(buttonBox); - this->setWindowTitle(tr("Generate New Subkey")); + this->setWindowTitle(tr("Generate New Subkey")); - this->setLayout(vbox2); - this->setModal(true); + this->setLayout(vbox2); + this->setModal(true); - set_signal_slot(); - refresh_widgets_state(); + set_signal_slot(); + refresh_widgets_state(); } -QGroupBox *SubkeyGenerateDialog::create_key_usage_group_box() { - auto *groupBox = new QGroupBox(this); - auto *grid = new QGridLayout(this); +QGroupBox* SubkeyGenerateDialog::create_key_usage_group_box() { + auto* groupBox = new QGroupBox(this); + auto* grid = new QGridLayout(this); - groupBox->setTitle("Key Usage"); + groupBox->setTitle("Key Usage"); - auto* encrypt = new QCheckBox(tr("Encryption"), groupBox); - encrypt->setTristate(false); + auto* encrypt = new QCheckBox(tr("Encryption"), groupBox); + encrypt->setTristate(false); - auto* sign = new QCheckBox(tr("Signing"),groupBox); - sign->setTristate(false); + auto* sign = new QCheckBox(tr("Signing"), groupBox); + sign->setTristate(false); - auto* cert = new QCheckBox(tr("Certification"),groupBox); - cert->setTristate(false); + auto* cert = new QCheckBox(tr("Certification"), groupBox); + cert->setTristate(false); - auto* auth = new QCheckBox(tr("Authentication"), groupBox); - auth->setTristate(false); + auto* auth = new QCheckBox(tr("Authentication"), groupBox); + auth->setTristate(false); - keyUsageCheckBoxes.push_back(encrypt); - keyUsageCheckBoxes.push_back(sign); - keyUsageCheckBoxes.push_back(cert); - keyUsageCheckBoxes.push_back(auth); + keyUsageCheckBoxes.push_back(encrypt); + keyUsageCheckBoxes.push_back(sign); + keyUsageCheckBoxes.push_back(cert); + keyUsageCheckBoxes.push_back(auth); - grid->addWidget(encrypt, 0, 0); - grid->addWidget(sign, 0, 1); - grid->addWidget(cert, 1, 0); - grid->addWidget(auth, 1, 1); + grid->addWidget(encrypt, 0, 0); + grid->addWidget(sign, 0, 1); + grid->addWidget(cert, 1, 0); + grid->addWidget(auth, 1, 1); - groupBox->setLayout(grid); + groupBox->setLayout(grid); - return groupBox; + return groupBox; } -QGroupBox *SubkeyGenerateDialog::create_basic_info_group_box() { - errorLabel = new QLabel(tr("")); - keySizeSpinBox = new QSpinBox(this); - keyTypeComboBox = new QComboBox(this); +QGroupBox* SubkeyGenerateDialog::create_basic_info_group_box() { + errorLabel = new QLabel(tr("")); + keySizeSpinBox = new QSpinBox(this); + keyTypeComboBox = new QComboBox(this); - for(auto &algo : GenKeyInfo::SupportedSubkeyAlgo) { - keyTypeComboBox->addItem(algo); - } - if(!GenKeyInfo::SupportedKeyAlgo.isEmpty()) { - keyTypeComboBox->setCurrentIndex(0); - } + for (auto& algo : GenKeyInfo::SupportedSubkeyAlgo) { + keyTypeComboBox->addItem(QString::fromStdString(algo)); + } + if (!GenKeyInfo::SupportedKeyAlgo.empty()) { + keyTypeComboBox->setCurrentIndex(0); + } - QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); + QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); - dateEdit = new QDateTimeEdit(maxDateTime, this); - dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); - dateEdit->setMaximumDateTime(maxDateTime); - dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); - dateEdit->setCalendarPopup(true); - dateEdit->setEnabled(true); + dateEdit = new QDateTimeEdit(maxDateTime, this); + dateEdit->setMinimumDateTime(QDateTime::currentDateTime()); + dateEdit->setMaximumDateTime(maxDateTime); + dateEdit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + dateEdit->setCalendarPopup(true); + dateEdit->setEnabled(true); - expireCheckBox = new QCheckBox(this); - expireCheckBox->setCheckState(Qt::Unchecked); + expireCheckBox = new QCheckBox(this); + expireCheckBox->setCheckState(Qt::Unchecked); - auto *vbox1 = new QGridLayout; + auto* vbox1 = new QGridLayout; - vbox1->addWidget(new QLabel(tr("Expiration Date:")), 2, 0); - vbox1->addWidget(new QLabel(tr("Never Expire")), 2, 3); - vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 1, 0); - vbox1->addWidget(new QLabel(tr("Key Type:")), 0, 0); + vbox1->addWidget(new QLabel(tr("Expiration Date:")), 2, 0); + vbox1->addWidget(new QLabel(tr("Never Expire")), 2, 3); + vbox1->addWidget(new QLabel(tr("KeySize (in Bit):")), 1, 0); + vbox1->addWidget(new QLabel(tr("Key Type:")), 0, 0); - vbox1->addWidget(dateEdit, 2, 1); - vbox1->addWidget(expireCheckBox, 2, 2); - vbox1->addWidget(keySizeSpinBox, 1, 1); - vbox1->addWidget(keyTypeComboBox, 0, 1); + vbox1->addWidget(dateEdit, 2, 1); + vbox1->addWidget(expireCheckBox, 2, 2); + vbox1->addWidget(keySizeSpinBox, 1, 1); + vbox1->addWidget(keyTypeComboBox, 0, 1); - auto basicInfoGroupBox = new QGroupBox(); - basicInfoGroupBox->setLayout(vbox1); - basicInfoGroupBox->setTitle(tr("Basic Information")); + auto basicInfoGroupBox = new QGroupBox(); + basicInfoGroupBox->setLayout(vbox1); + basicInfoGroupBox->setTitle(tr("Basic Information")); - return basicInfoGroupBox; + return basicInfoGroupBox; } void SubkeyGenerateDialog::set_signal_slot() { - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(expireCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotExpireBoxChanged())); - - connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionBoxChanged(int))); - connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, SLOT(slotSigningBoxChanged(int))); - connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, SLOT(slotCertificationBoxChanged(int))); - connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, SLOT(slotAuthenticationBoxChanged(int))); - - connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotActivatedKeyType(int))); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotKeyGenAccept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(expireCheckBox, SIGNAL(stateChanged(int)), this, + SLOT(slotExpireBoxChanged())); + + connect(keyUsageCheckBoxes[0], SIGNAL(stateChanged(int)), this, + SLOT(slotEncryptionBoxChanged(int))); + connect(keyUsageCheckBoxes[1], SIGNAL(stateChanged(int)), this, + SLOT(slotSigningBoxChanged(int))); + connect(keyUsageCheckBoxes[2], SIGNAL(stateChanged(int)), this, + SLOT(slotCertificationBoxChanged(int))); + connect(keyUsageCheckBoxes[3], SIGNAL(stateChanged(int)), this, + SLOT(slotAuthenticationBoxChanged(int))); + + connect(keyTypeComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(slotActivatedKeyType(int))); } void SubkeyGenerateDialog::slotExpireBoxChanged() { - if (expireCheckBox->checkState()) { - dateEdit->setEnabled(false); - } else { - dateEdit->setEnabled(true); - } + if (expireCheckBox->checkState()) { + dateEdit->setEnabled(false); + } else { + dateEdit->setEnabled(true); + } } void SubkeyGenerateDialog::refresh_widgets_state() { - qDebug() << "refresh_widgets_state called"; - - if(genKeyInfo.isAllowEncryption()) - keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeEncryption()) - keyUsageCheckBoxes[0]->setDisabled(false); - else - keyUsageCheckBoxes[0]->setDisabled(true); - - - if(genKeyInfo.isAllowSigning()) - keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeSigning()) - keyUsageCheckBoxes[1]->setDisabled(false); - else - keyUsageCheckBoxes[1]->setDisabled(true); - - - if(genKeyInfo.isAllowCertification()) - keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeCertification()) - keyUsageCheckBoxes[2]->setDisabled(false); - else - keyUsageCheckBoxes[2]->setDisabled(true); - - - if(genKeyInfo.isAllowAuthentication()) - keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked); - else - keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked); - - if(genKeyInfo.isAllowChangeAuthentication()) - keyUsageCheckBoxes[3]->setDisabled(false); - else - keyUsageCheckBoxes[3]->setDisabled(true); - - - keySizeSpinBox->setRange(genKeyInfo.getSuggestMinKeySize(), genKeyInfo.getSuggestMaxKeySize()); - keySizeSpinBox->setValue(genKeyInfo.getKeySize()); - keySizeSpinBox->setSingleStep(genKeyInfo.getSizeChangeStep()); - + qDebug() << "refresh_widgets_state called"; + + if (genKeyInfo->isAllowEncryption()) + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[0]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeEncryption()) + keyUsageCheckBoxes[0]->setDisabled(false); + else + keyUsageCheckBoxes[0]->setDisabled(true); + + if (genKeyInfo->isAllowSigning()) + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[1]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeSigning()) + keyUsageCheckBoxes[1]->setDisabled(false); + else + keyUsageCheckBoxes[1]->setDisabled(true); + + if (genKeyInfo->isAllowCertification()) + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[2]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeCertification()) + keyUsageCheckBoxes[2]->setDisabled(false); + else + keyUsageCheckBoxes[2]->setDisabled(true); + + if (genKeyInfo->isAllowAuthentication()) + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Checked); + else + keyUsageCheckBoxes[3]->setCheckState(Qt::CheckState::Unchecked); + + if (genKeyInfo->isAllowChangeAuthentication()) + keyUsageCheckBoxes[3]->setDisabled(false); + else + keyUsageCheckBoxes[3]->setDisabled(true); + + keySizeSpinBox->setRange(genKeyInfo->getSuggestMinKeySize(), + genKeyInfo->getSuggestMaxKeySize()); + keySizeSpinBox->setValue(genKeyInfo->getKeySize()); + keySizeSpinBox->setSingleStep(genKeyInfo->getSizeChangeStep()); } void SubkeyGenerateDialog::slotKeyGenAccept() { - QString errorString = ""; - - /** - * primary keys should have a reasonable expiration date (no more than 2 years in the future) - */ - if(dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { - - errorString.append(tr(" Expiration time no more than 2 years. ")); - } + QString errorString = ""; - if (errorString.isEmpty()) { + /** + * primary keys should have a reasonable expiration date (no more than 2 years + * in the future) + */ + if (dateEdit->dateTime() > QDateTime::currentDateTime().addYears(2)) { + errorString.append(tr(" Expiration time no more than 2 years. ")); + } - genKeyInfo.setKeySize(keySizeSpinBox->value()); + if (errorString.isEmpty()) { + genKeyInfo->setKeySize(keySizeSpinBox->value()); - if (expireCheckBox->checkState()) { - genKeyInfo.setNonExpired(true); - } else { - genKeyInfo.setExpired(dateEdit->dateTime()); - } + if (expireCheckBox->checkState()) { + genKeyInfo->setNonExpired(true); + } else { + genKeyInfo->setExpired( + boost::posix_time::from_time_t(dateEdit->dateTime().toTime_t()) + .date()); + } - gpgme_error_t error = false; - auto thread = QThread::create([&]() { - error = mCtx->generateSubkey(mKey, &genKeyInfo); - }); - thread->start(); + gpgme_error_t error = false; + auto thread = QThread::create([&]() { + error = GpgKeyOpera::GetInstance().GenerateSubkey(mKey, genKeyInfo); + }); + thread->start(); - auto *dialog = new WaitingDialog("Generating", this); - dialog->show(); + auto* dialog = new WaitingDialog("Generating", this); + dialog->show(); - while (thread->isRunning()) { - QCoreApplication::processEvents(); - } + while (thread->isRunning()) { + QCoreApplication::processEvents(); + } - dialog->close(); + dialog->close(); - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - QMessageBox::information(nullptr, tr("Success"), tr("The new subkey has been generated.")); - this->close(); - } else - QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error))); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { + QMessageBox::information(nullptr, tr("Success"), + tr("The new subkey has been generated.")); + this->close(); + } else + QMessageBox::critical(this, tr("Failure"), tr(gpgme_strerror(error))); - } else { - /** - * create error message - */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); - error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(errorString); - - this->show(); - } + } else { + /** + * create error message + */ + errorLabel->setAutoFillBackground(true); + QPalette error = errorLabel->palette(); + error.setColor(QPalette::Window, "#ff8080"); + errorLabel->setPalette(error); + errorLabel->setText(errorString); + + this->show(); + } } void SubkeyGenerateDialog::slotEncryptionBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowEncryption(false); - } else { - genKeyInfo.setAllowEncryption(true); - } + if (state == 0) { + genKeyInfo->setAllowEncryption(false); + } else { + genKeyInfo->setAllowEncryption(true); + } } void SubkeyGenerateDialog::slotSigningBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowSigning(false); - } else { - genKeyInfo.setAllowSigning(true); - } + if (state == 0) { + genKeyInfo->setAllowSigning(false); + } else { + genKeyInfo->setAllowSigning(true); + } } void SubkeyGenerateDialog::slotCertificationBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowCertification(false); - } else { - genKeyInfo.setAllowCertification(true); - } + if (state == 0) { + genKeyInfo->setAllowCertification(false); + } else { + genKeyInfo->setAllowCertification(true); + } } void SubkeyGenerateDialog::slotAuthenticationBoxChanged(int state) { - if(state == 0) { - genKeyInfo.setAllowAuthentication(false); - } else { - genKeyInfo.setAllowAuthentication(true); - } + if (state == 0) { + genKeyInfo->setAllowAuthentication(false); + } else { + genKeyInfo->setAllowAuthentication(true); + } } void SubkeyGenerateDialog::slotActivatedKeyType(int index) { - qDebug() << "key type index changed " << index; - genKeyInfo.setAlgo(this->keyTypeComboBox->itemText(index)); - refresh_widgets_state(); + qDebug() << "key type index changed " << index; + genKeyInfo->setAlgo(this->keyTypeComboBox->itemText(index).toStdString()); + refresh_widgets_state(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keygen/SubkeyGenerateDialog.h b/src/ui/keygen/SubkeyGenerateDialog.h new file mode 100644 index 00000000..1b4249b4 --- /dev/null +++ b/src/ui/keygen/SubkeyGenerateDialog.h @@ -0,0 +1,94 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_SUBKEYGENERATEDIALOG_H +#define GPGFRONTEND_SUBKEYGENERATEDIALOG_H + +#include <gpg/GpgGenKeyInfo.h> +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class SubkeyGenerateDialog : public QDialog { + Q_OBJECT + + public: + explicit SubkeyGenerateDialog(const KeyId& key_id, QWidget* parent); + + private: + GpgKey mKey; + + std::unique_ptr<GenKeyInfo> genKeyInfo = std::make_unique<GenKeyInfo>(); + + QGroupBox* keyUsageGroupBox{}; + QDialogButtonBox* buttonBox; /** Box for standardbuttons */ + QLabel* errorLabel{}; /** Label containing error message */ + QSpinBox* keySizeSpinBox{}; /** Spinbox for the keys size (in bit) */ + QComboBox* keyTypeComboBox{}; /** Combobox for Keytpe */ + QDateTimeEdit* dateEdit{}; /** Dateedit for expiration date */ + QCheckBox* expireCheckBox{}; /** Checkbox, if key should expire */ + + // ENCR, SIGN, CERT, AUTH + std::vector<QCheckBox*> keyUsageCheckBoxes; + + QGroupBox* create_key_usage_group_box(); + + QGroupBox* create_basic_info_group_box(); + + void set_signal_slot(); + + /** + * @details Refresh widgets state by GenKeyInfo + */ + void refresh_widgets_state(); + + private slots: + + /** + * @details when expirebox was checked/unchecked, enable/disable the + * expiration date box + */ + void slotExpireBoxChanged(); + + /** + * @details check all lineedits for false entries. Show error, when there is + * one, otherwise generate the key + */ + void slotKeyGenAccept(); + + void slotEncryptionBoxChanged(int state); + + void slotSigningBoxChanged(int state); + + void slotCertificationBoxChanged(int state); + + void slotAuthenticationBoxChanged(int state); + + void slotActivatedKeyType(int index); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_SUBKEYGENERATEDIALOG_H diff --git a/src/ui/keypair_details/EditSubKeyDialog.h b/src/ui/keypair_details/EditSubKeyDialog.h new file mode 100644 index 00000000..6577d382 --- /dev/null +++ b/src/ui/keypair_details/EditSubKeyDialog.h @@ -0,0 +1,34 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_EDITSUBKEY_H +#define GPGFRONTEND_EDITSUBKEY_H + + +class EditSubKeyDialog { + +}; + + +#endif //GPGFRONTEND_EDITSUBKEY_H diff --git a/src/ui/keypair_details/KeyDetailsDialog.cpp b/src/ui/keypair_details/KeyDetailsDialog.cpp index 0d94e584..54bc6286 100644 --- a/src/ui/keypair_details/KeyDetailsDialog.cpp +++ b/src/ui/keypair_details/KeyDetailsDialog.cpp @@ -24,21 +24,22 @@ #include "ui/keypair_details/KeyDetailsDialog.h" -KeyDetailsDialog::KeyDetailsDialog(GpgFrontend::GpgContext *ctx, const GpgKey& key, QWidget *parent) - : QDialog(parent) { +namespace GpgFrontend::UI { +KeyDetailsDialog::KeyDetailsDialog(const GpgKey& key, QWidget* parent) + : QDialog(parent) { + tabWidget = new QTabWidget(); + tabWidget->addTab(new KeyPairDetailTab(key.id(), tabWidget), tr("KeyPair")); + tabWidget->addTab(new KeyPairUIDTab(key.id(), tabWidget), tr("UIDs")); + tabWidget->addTab(new KeyPairSubkeyTab(key.id(), tabWidget), tr("Subkeys")); - tabWidget = new QTabWidget(); - tabWidget->addTab(new KeyPairDetailTab(ctx, key, tabWidget), tr("KeyPair")); - tabWidget->addTab(new KeyPairUIDTab(ctx, key, tabWidget), tr("UIDs")); - tabWidget->addTab(new KeyPairSubkeyTab(ctx, key, tabWidget), tr("Subkeys")); + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(tabWidget); - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(tabWidget); - - this->setAttribute(Qt::WA_DeleteOnClose, true); - this->setLayout(mainLayout); - this->setWindowTitle(tr("Key Details")); - this->setModal(true); - this->setMinimumSize(380, 620); - this->show(); -}
\ No newline at end of file + this->setAttribute(Qt::WA_DeleteOnClose, true); + this->setLayout(mainLayout); + this->setWindowTitle(tr("Key Details")); + this->setModal(true); + this->setMinimumSize(380, 620); + this->show(); +} +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyDetailsDialog.h b/src/ui/keypair_details/KeyDetailsDialog.h new file mode 100644 index 00000000..0f7342aa --- /dev/null +++ b/src/ui/keypair_details/KeyDetailsDialog.h @@ -0,0 +1,47 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYDETAILSDIALOG_H__ +#define __KEYDETAILSDIALOG_H__ + +#include "KeyPairDetailTab.h" +#include "KeyPairSubkeyTab.h" +#include "KeyPairUIDTab.h" +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class KeyDetailsDialog : public QDialog { + Q_OBJECT + + public: + explicit KeyDetailsDialog(const GpgKey& key, QWidget* parent = nullptr); + + private: + QTabWidget* tabWidget{}; +}; +} // namespace GpgFrontend::UI + +#endif // __KEYDETAILSDIALOG_H__ diff --git a/src/ui/keypair_details/KeyNewUIDDialog.cpp b/src/ui/keypair_details/KeyNewUIDDialog.cpp index 7c6e1ca5..a22250c1 100644 --- a/src/ui/keypair_details/KeyNewUIDDialog.cpp +++ b/src/ui/keypair_details/KeyNewUIDDialog.cpp @@ -24,79 +24,77 @@ #include "ui/keypair_details/KeyNewUIDDialog.h" -KeyNewUIDDialog::KeyNewUIDDialog(GpgFrontend::GpgContext *ctx, const GpgKey &key, QWidget *parent) : - mCtx(ctx), mKey(key), QDialog(parent) { - - name = new QLineEdit(); - name->setMinimumWidth(240); - email = new QLineEdit(); - email->setMinimumWidth(240); - comment = new QLineEdit(); - comment->setMinimumWidth(240); - createButton = new QPushButton("Create"); - errorLabel = new QLabel(); - - auto gridLayout = new QGridLayout(); - gridLayout->addWidget(new QLabel(tr("Name")), 0, 0); - gridLayout->addWidget(new QLabel(tr("Email")), 1, 0); - gridLayout->addWidget(new QLabel(tr("Comment")), 2, 0); - - - gridLayout->addWidget(name, 0 ,1); - gridLayout->addWidget(email, 1 ,1); - gridLayout->addWidget(comment, 2 ,1); - - gridLayout->addWidget(createButton, 3, 0, 1, 2); - gridLayout->addWidget(errorLabel, 4, 0, 1, 2); - - connect(createButton, SIGNAL(clicked(bool)), this, SLOT(slotCreateNewUID())); - - this->setLayout(gridLayout); - this->setWindowTitle(tr("Create New UID")); - this->setAttribute(Qt::WA_DeleteOnClose, true); - this->setModal(true); +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/UidOperator.h" + +namespace GpgFrontend::UI { +KeyNewUIDDialog::KeyNewUIDDialog(const KeyId& key_id, QWidget* parent) + : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { + name = new QLineEdit(); + name->setMinimumWidth(240); + email = new QLineEdit(); + email->setMinimumWidth(240); + comment = new QLineEdit(); + comment->setMinimumWidth(240); + createButton = new QPushButton("Create"); + errorLabel = new QLabel(); + + auto gridLayout = new QGridLayout(); + gridLayout->addWidget(new QLabel(tr("Name")), 0, 0); + gridLayout->addWidget(new QLabel(tr("Email")), 1, 0); + gridLayout->addWidget(new QLabel(tr("Comment")), 2, 0); + + gridLayout->addWidget(name, 0, 1); + gridLayout->addWidget(email, 1, 1); + gridLayout->addWidget(comment, 2, 1); + + gridLayout->addWidget(createButton, 3, 0, 1, 2); + gridLayout->addWidget(errorLabel, 4, 0, 1, 2); + + connect(createButton, SIGNAL(clicked(bool)), this, SLOT(slotCreateNewUID())); + + this->setLayout(gridLayout); + this->setWindowTitle(tr("Create New UID")); + this->setAttribute(Qt::WA_DeleteOnClose, true); + this->setModal(true); } void KeyNewUIDDialog::slotCreateNewUID() { - - QString errorString = ""; - + QString errorString = ""; + + /** + * check for errors in keygen dialog input + */ + if ((name->text()).size() < 5) { + errorString.append(tr(" Name must contain at least five characters. \n")); + } + if (email->text().isEmpty() || !check_email_address(email->text())) { + errorString.append(tr(" Please give a email address. \n")); + } + + if (errorString.isEmpty()) { + if (UidOperator::GetInstance().addUID(mKey, name->text().toStdString(), + comment->text().toStdString(), + email->text().toStdString())) + emit finished(1); + else + emit finished(-1); + + } else { /** - * check for errors in keygen dialog input + * create error message */ - if ((name->text()).size() < 5) { - errorString.append(tr(" Name must contain at least five characters. \n")); - } if(email->text().isEmpty() || !check_email_address(email->text())) { - errorString.append(tr(" Please give a email address. \n")); - } - - if (errorString.isEmpty()) { - GpgUID uid; - uid.name = name->text(); - uid.email = email->text(); - uid.comment = comment->text(); - - if(mCtx->addUID(mKey, uid)) { - emit finished(1); - - } else { - emit finished(-1); - } - - } else { - /** - * create error message - */ - errorLabel->setAutoFillBackground(true); - QPalette error = errorLabel->palette(); - error.setColor(QPalette::Window, "#ff8080"); - errorLabel->setPalette(error); - errorLabel->setText(errorString); - - this->show(); - } + errorLabel->setAutoFillBackground(true); + QPalette error = errorLabel->palette(); + error.setColor(QPalette::Window, "#ff8080"); + errorLabel->setPalette(error); + errorLabel->setText(errorString); + + this->show(); + } } -bool KeyNewUIDDialog::check_email_address(const QString &str) { - return re_email.match(str).hasMatch(); +bool KeyNewUIDDialog::check_email_address(const QString& str) { + return re_email.match(str).hasMatch(); } +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyNewUIDDialog.h b/src/ui/keypair_details/KeyNewUIDDialog.h new file mode 100644 index 00000000..076a69ed --- /dev/null +++ b/src/ui/keypair_details/KeyNewUIDDialog.h @@ -0,0 +1,61 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYNEWUIDDIALOG_H +#define GPGFRONTEND_KEYNEWUIDDIALOG_H + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { +class KeyNewUIDDialog : public QDialog { + Q_OBJECT + + public: + KeyNewUIDDialog(const KeyId& key, QWidget* parent = nullptr); + + private slots: + + void slotCreateNewUID(); + + private: + GpgKey mKey; + + QLineEdit* name{}; + QLineEdit* email{}; + QLineEdit* comment{}; + + QPushButton* createButton{}; + + QStringList errorMessages; + QLabel* errorLabel{}; + + QRegularExpression re_email{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + bool check_email_address(const QString& str); +}; +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYNEWUIDDIALOG_H diff --git a/src/ui/keypair_details/KeyPairDetailTab.cpp b/src/ui/keypair_details/KeyPairDetailTab.cpp index 1f5d4095..fe95a10e 100644 --- a/src/ui/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/keypair_details/KeyPairDetailTab.cpp @@ -23,330 +23,346 @@ */ #include "ui/keypair_details/KeyPairDetailTab.h" +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyImportExportor.h" #include "ui/WaitingDialog.h" -KeyPairDetailTab::KeyPairDetailTab(GpgFrontend::GpgContext *ctx, const GpgKey &mKey, QWidget *parent) : mKey(mKey), - QWidget(parent) { - - mCtx = ctx; - keyid = new QString(mKey.id); - - ownerBox = new QGroupBox(tr("Owner")); - keyBox = new QGroupBox(tr("Master Key")); - fingerprintBox = new QGroupBox(tr("Fingerprint")); - additionalUidBox = new QGroupBox(tr("Additional UIDs")); - - nameVarLabel = new QLabel(); - nameVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - emailVarLabel = new QLabel(); - emailVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - - commentVarLabel = new QLabel(); - commentVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - keyidVarLabel = new QLabel(); - keyidVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - - usageVarLabel = new QLabel(); - actualUsageVarLabel = new QLabel(); - - keySizeVarLabel = new QLabel(); - expireVarLabel = new QLabel(); - createdVarLabel = new QLabel(); - algorithmVarLabel = new QLabel(); - - // Show the situation that master key not exists. - masterKeyExistVarLabel = new QLabel(mKey.has_master_key ? tr("Exists") : tr("Not Exists")); - if (!mKey.has_master_key) { - auto paletteExpired = masterKeyExistVarLabel->palette(); - paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); - masterKeyExistVarLabel->setPalette(paletteExpired); - } else { - auto paletteValid = masterKeyExistVarLabel->palette(); - paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::darkGreen); - masterKeyExistVarLabel->setPalette(paletteValid); +namespace GpgFrontend::UI { +KeyPairDetailTab::KeyPairDetailTab(const std::string& key_id, QWidget* parent) + : QWidget(parent), + mKey(std::move(GpgKeyGetter::GetInstance().GetKey(key_id))) { + keyid = mKey.id(); + + ownerBox = new QGroupBox(tr("Owner")); + keyBox = new QGroupBox(tr("Master Key")); + fingerprintBox = new QGroupBox(tr("Fingerprint")); + additionalUidBox = new QGroupBox(tr("Additional UIDs")); + + nameVarLabel = new QLabel(); + nameVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + emailVarLabel = new QLabel(); + emailVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + + commentVarLabel = new QLabel(); + commentVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + keyidVarLabel = new QLabel(); + keyidVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + + usageVarLabel = new QLabel(); + actualUsageVarLabel = new QLabel(); + + keySizeVarLabel = new QLabel(); + expireVarLabel = new QLabel(); + createdVarLabel = new QLabel(); + algorithmVarLabel = new QLabel(); + + // Show the situation that master key not exists. + masterKeyExistVarLabel = + new QLabel(mKey.has_master_key() ? tr("Exists") : tr("Not Exists")); + if (!mKey.has_master_key()) { + auto paletteExpired = masterKeyExistVarLabel->palette(); + paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); + masterKeyExistVarLabel->setPalette(paletteExpired); + } else { + auto paletteValid = masterKeyExistVarLabel->palette(); + paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), + Qt::darkGreen); + masterKeyExistVarLabel->setPalette(paletteValid); + } + + if (mKey.expired()) { + auto paletteExpired = expireVarLabel->palette(); + paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); + expireVarLabel->setPalette(paletteExpired); + } else { + auto paletteValid = expireVarLabel->palette(); + paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); + expireVarLabel->setPalette(paletteValid); + } + + auto* mvbox = new QVBoxLayout(); + auto* vboxKD = new QGridLayout(); + auto* vboxOD = new QGridLayout(); + + vboxOD->addWidget(new QLabel(tr("Name:")), 0, 0); + vboxOD->addWidget(new QLabel(tr("Email Address:")), 1, 0); + vboxOD->addWidget(new QLabel(tr("Comment:")), 2, 0); + vboxOD->addWidget(nameVarLabel, 0, 1); + vboxOD->addWidget(emailVarLabel, 1, 1); + vboxOD->addWidget(commentVarLabel, 2, 1); + + vboxKD->addWidget(new QLabel(tr("Key ID: ")), 0, 0); + vboxKD->addWidget(new QLabel(tr("Algorithm: ")), 1, 0); + vboxKD->addWidget(new QLabel(tr("Key Size:")), 2, 0); + vboxKD->addWidget(new QLabel(tr("Nominal Usage: ")), 3, 0); + vboxKD->addWidget(new QLabel(tr("Actual Usage: ")), 4, 0); + vboxKD->addWidget(new QLabel(tr("Expires on: ")), 5, 0); + vboxKD->addWidget(new QLabel(tr("Last Update: ")), 6, 0); + vboxKD->addWidget(new QLabel(tr("Secret Key Existence: ")), 7, 0); + + vboxKD->addWidget(keySizeVarLabel, 2, 1); + vboxKD->addWidget(expireVarLabel, 5, 1); + vboxKD->addWidget(algorithmVarLabel, 1, 1); + vboxKD->addWidget(createdVarLabel, 6, 1); + vboxKD->addWidget(keyidVarLabel, 0, 1); + vboxKD->addWidget(usageVarLabel, 3, 1); + vboxKD->addWidget(actualUsageVarLabel, 4, 1); + vboxKD->addWidget(masterKeyExistVarLabel, 7, 1); + + ownerBox->setLayout(vboxOD); + mvbox->addWidget(ownerBox); + keyBox->setLayout(vboxKD); + mvbox->addWidget(keyBox); + + fingerPrintVarLabel = + new QLabel(beautifyFingerprint(QString::fromStdString(mKey.fpr()))); + fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;"); + auto* hboxFP = new QHBoxLayout(); + + hboxFP->addWidget(fingerPrintVarLabel); + + auto* copyFingerprintButton = new QPushButton(tr("Copy")); + copyFingerprintButton->setFlat(true); + copyFingerprintButton->setToolTip(tr("copy fingerprint to clipboard")); + connect(copyFingerprintButton, SIGNAL(clicked()), this, + SLOT(slotCopyFingerprint())); + + hboxFP->addWidget(copyFingerprintButton); + + fingerprintBox->setLayout(hboxFP); + mvbox->addWidget(fingerprintBox); + mvbox->addStretch(); + + if (mKey.is_private_key()) { + auto* privKeyBox = new QGroupBox(tr("Operations")); + auto* vboxPK = new QVBoxLayout(); + + auto* exportButton = + new QPushButton(tr("Export Private Key (Include Subkey)")); + vboxPK->addWidget(exportButton); + connect(exportButton, SIGNAL(clicked()), this, + SLOT(slotExportPrivateKey())); + + if (mKey.has_master_key()) { + auto* editExpiresButton = + new QPushButton(tr("Modify Expiration Datetime (Master Key)")); + vboxPK->addWidget(editExpiresButton); + connect(editExpiresButton, SIGNAL(clicked()), this, + SLOT(slotModifyEditDatetime())); + + auto hBoxLayout = new QHBoxLayout(); + auto* keyServerOperaButton = + new QPushButton(tr("Key Server Operation (Pubkey)")); + keyServerOperaButton->setStyleSheet("text-align:center;"); + + auto* revokeCertGenButton = + new QPushButton(tr("Generate Revoke Certificate")); + connect(revokeCertGenButton, SIGNAL(clicked()), this, + SLOT(slotGenRevokeCert())); + + hBoxLayout->addWidget(keyServerOperaButton); + hBoxLayout->addWidget(revokeCertGenButton); + + vboxPK->addLayout(hBoxLayout); + connect(keyServerOperaButton, SIGNAL(clicked()), this, + SLOT(slotModifyEditDatetime())); + + // Set Menu + createKeyServerOperaMenu(); + keyServerOperaButton->setMenu(keyServerOperaMenu); } - if (mKey.expired) { - auto paletteExpired = expireVarLabel->palette(); - paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); - expireVarLabel->setPalette(paletteExpired); - } else { - auto paletteValid = expireVarLabel->palette(); - paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); - expireVarLabel->setPalette(paletteValid); - } + privKeyBox->setLayout(vboxPK); + mvbox->addWidget(privKeyBox); + } - auto *mvbox = new QVBoxLayout(); - auto *vboxKD = new QGridLayout(); - auto *vboxOD = new QGridLayout(); - - vboxOD->addWidget(new QLabel(tr("Name:")), 0, 0); - vboxOD->addWidget(new QLabel(tr("Email Address:")), 1, 0); - vboxOD->addWidget(new QLabel(tr("Comment:")), 2, 0); - vboxOD->addWidget(nameVarLabel, 0, 1); - vboxOD->addWidget(emailVarLabel, 1, 1); - vboxOD->addWidget(commentVarLabel, 2, 1); - - vboxKD->addWidget(new QLabel(tr("Key ID: ")), 0, 0); - vboxKD->addWidget(new QLabel(tr("Algorithm: ")), 1, 0); - vboxKD->addWidget(new QLabel(tr("Key Size:")), 2, 0); - vboxKD->addWidget(new QLabel(tr("Nominal Usage: ")), 3, 0); - vboxKD->addWidget(new QLabel(tr("Actual Usage: ")), 4, 0); - vboxKD->addWidget(new QLabel(tr("Expires on: ")), 5, 0); - vboxKD->addWidget(new QLabel(tr("Last Update: ")), 6, 0); - vboxKD->addWidget(new QLabel(tr("Secret Key Existence: ")), 7, 0); - - - vboxKD->addWidget(keySizeVarLabel, 2, 1); - vboxKD->addWidget(expireVarLabel, 5, 1); - vboxKD->addWidget(algorithmVarLabel, 1, 1); - vboxKD->addWidget(createdVarLabel, 6, 1); - vboxKD->addWidget(keyidVarLabel, 0, 1); - vboxKD->addWidget(usageVarLabel, 3, 1); - vboxKD->addWidget(actualUsageVarLabel, 4, 1); - vboxKD->addWidget(masterKeyExistVarLabel, 7, 1); - - ownerBox->setLayout(vboxOD); - mvbox->addWidget(ownerBox); - keyBox->setLayout(vboxKD); - mvbox->addWidget(keyBox); - - fingerPrintVarLabel = new QLabel(beautifyFingerprint(mKey.fpr)); - fingerPrintVarLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); - fingerPrintVarLabel->setStyleSheet("margin-left: 0; margin-right: 5;"); - auto *hboxFP = new QHBoxLayout(); - - hboxFP->addWidget(fingerPrintVarLabel); - - auto *copyFingerprintButton = new QPushButton(tr("Copy")); - copyFingerprintButton->setFlat(true); - copyFingerprintButton->setToolTip(tr("copy fingerprint to clipboard")); - connect(copyFingerprintButton, SIGNAL(clicked()), this, SLOT(slotCopyFingerprint())); - - hboxFP->addWidget(copyFingerprintButton); - - fingerprintBox->setLayout(hboxFP); - mvbox->addWidget(fingerprintBox); - mvbox->addStretch(); - - if (mKey.is_private_key) { - auto *privKeyBox = new QGroupBox(tr("Operations")); - auto *vboxPK = new QVBoxLayout(); - - auto *exportButton = new QPushButton(tr("Export Private Key (Include Subkey)")); - vboxPK->addWidget(exportButton); - connect(exportButton, SIGNAL(clicked()), this, SLOT(slotExportPrivateKey())); - - if (mKey.has_master_key) { - auto *editExpiresButton = new QPushButton(tr("Modify Expiration Datetime (Master Key)")); - vboxPK->addWidget(editExpiresButton); - connect(editExpiresButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime())); - - auto hBoxLayout = new QHBoxLayout(); - auto *keyServerOperaButton = new QPushButton(tr("Key Server Operation (Pubkey)")); - keyServerOperaButton->setStyleSheet("text-align:center;"); - - auto *revokeCertGenButton = new QPushButton(tr("Generate Revoke Certificate")); - connect(revokeCertGenButton, SIGNAL(clicked()), this, SLOT(slotGenRevokeCert())); - - hBoxLayout->addWidget(keyServerOperaButton); - hBoxLayout->addWidget(revokeCertGenButton); - - vboxPK->addLayout(hBoxLayout); - connect(keyServerOperaButton, SIGNAL(clicked()), this, SLOT(slotModifyEditDatetime())); - - // Set Menu - createKeyServerOperaMenu(); - keyServerOperaButton->setMenu(keyServerOperaMenu); - } - - privKeyBox->setLayout(vboxPK); - mvbox->addWidget(privKeyBox); - } + if ((mKey.expired()) || (mKey.revoked())) { + auto* expBox = new QHBoxLayout(); + QPixmap pixmap(":warning.png"); - if ((mKey.expired) || (mKey.revoked)) { - auto *expBox = new QHBoxLayout(); - QPixmap pixmap(":warning.png"); - - auto *expLabel = new QLabel(); - auto *iconLabel = new QLabel(); - if (mKey.expired) { - expLabel->setText(tr("Warning: The Master Key has expired.")); - } - if (mKey.revoked) { - expLabel->setText(tr("Warning: The Master Key has been revoked")); - } - - iconLabel->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio)); - QFont font = expLabel->font(); - font.setBold(true); - expLabel->setFont(font); - expLabel->setAlignment(Qt::AlignCenter); - expBox->addWidget(iconLabel); - expBox->addWidget(expLabel); - mvbox->addLayout(expBox); + auto* expLabel = new QLabel(); + auto* iconLabel = new QLabel(); + if (mKey.expired()) { + expLabel->setText(tr("Warning: The Master Key has expired.")); + } + if (mKey.revoked()) { + expLabel->setText(tr("Warning: The Master Key has been revoked")); } - mvbox->setContentsMargins(0, 0, 0, 0); - - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshKeyInfo())); - - slotRefreshKeyInfo(); - setAttribute(Qt::WA_DeleteOnClose, true); - setLayout(mvbox); + iconLabel->setPixmap(pixmap.scaled(24, 24, Qt::KeepAspectRatio)); + QFont font = expLabel->font(); + font.setBold(true); + expLabel->setFont(font); + expLabel->setAlignment(Qt::AlignCenter); + expBox->addWidget(iconLabel); + expBox->addWidget(expLabel); + mvbox->addLayout(expBox); + } + + mvbox->setContentsMargins(0, 0, 0, 0); + + slotRefreshKeyInfo(); + setAttribute(Qt::WA_DeleteOnClose, true); + setLayout(mvbox); } void KeyPairDetailTab::slotExportPrivateKey() { - // Show a information box with explanation about private key - int ret = QMessageBox::information(this, tr("Exporting private Key"), - "<h3>" + tr("You are about to export your") + "<font color=\"red\">" + - tr("PRIVATE KEY") + "</font>!</h3>\n" + - tr("This is NOT your Public Key, so DON'T give it away.") + "<br />" + - tr("Do you REALLY want to export your PRIVATE KEY?"), - QMessageBox::Cancel | QMessageBox::Ok); - - // export key, if ok was clicked - if (ret == QMessageBox::Ok) { - auto *keyArray = new QByteArray(); - - if (!mCtx->exportSecretKey(mKey, keyArray)) { - QMessageBox::critical(this, "Error", "An error occurred during the export operation."); - return; - } - - auto key = mCtx->getKeyRefById(*keyid); - if (!key.good) { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - return; - } - QString fileString = key.name + " " + key.email + "(" + - key.id + ")_secret.asc"; - QString fileName = QFileDialog::getSaveFileName(this, tr("Export Key To File"), fileString, - tr("Key Files") + " (*.asc *.txt);;All Files (*)"); - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QMessageBox::critical(nullptr, tr("Export Error"), tr("Couldn't open %1 for writing").arg(fileName)); - return; - } - QTextStream stream(&file); - stream << *keyArray; - file.close(); - delete keyArray; + // Show a information box with explanation about private key + int ret = QMessageBox::information( + this, tr("Exporting private Key"), + "<h3>" + tr("You are about to export your") + "<font color=\"red\">" + + tr("PRIVATE KEY") + "</font>!</h3>\n" + + tr("This is NOT your Public Key, so DON'T give it away.") + "<br />" + + tr("Do you REALLY want to export your PRIVATE KEY?"), + QMessageBox::Cancel | QMessageBox::Ok); + + // export key, if ok was clicked + if (ret == QMessageBox::Ok) { + ByteArrayPtr keyArray = nullptr; + + if (!GpgKeyImportExportor::GetInstance().ExportSecretKey(mKey, keyArray)) { + QMessageBox::critical(this, "Error", + "An error occurred during the export operation."); + return; + } + + auto key = GpgKeyGetter::GetInstance().GetKey(keyid); + if (!key.good()) { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + return; } + auto fileString = + key.name() + " " + key.email() + "(" + key.id() + ")_secret.asc"; + auto fileName = + QFileDialog::getSaveFileName( + this, tr("Export Key To File"), QString::fromStdString(fileString), + tr("Key Files") + " (*.asc *.txt);;All Files (*)") + .toStdString(); + + if (!write_buffer_to_file(fileName, *keyArray)) { + QMessageBox::critical(nullptr, tr("Export Error"), + tr("Couldn't open %1 for writing") + .arg(QString::fromStdString(fileName))); + return; + } + } } QString KeyPairDetailTab::beautifyFingerprint(QString fingerprint) { - uint len = fingerprint.length(); - if ((len > 0) && (len % 4 == 0)) - for (uint n = 0; 4 * (n + 1) < len; ++n) - fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); - return fingerprint; + uint len = fingerprint.length(); + if ((len > 0) && (len % 4 == 0)) + for (uint n = 0; 4 * (n + 1) < len; ++n) + fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); + return fingerprint; } void KeyPairDetailTab::slotCopyFingerprint() { - QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", ""); - QClipboard *cb = QApplication::clipboard(); - cb->setText(fpr); + QString fpr = fingerPrintVarLabel->text().trimmed().replace(" ", ""); + QClipboard* cb = QApplication::clipboard(); + cb->setText(fpr); } void KeyPairDetailTab::slotModifyEditDatetime() { - auto dialog = new KeySetExpireDateDialog(mCtx, mKey, nullptr, this); - dialog->show(); + auto dialog = new KeySetExpireDateDialog(mKey, this); + dialog->show(); } void KeyPairDetailTab::slotRefreshKeyInfo() { - - nameVarLabel->setText(mKey.name); - emailVarLabel->setText(mKey.email); - - commentVarLabel->setText(mKey.comment); - keyidVarLabel->setText(mKey.id); - - QString usage; - QTextStream usage_steam(&usage); - - if (mKey.can_certify) - usage_steam << "Cert "; - if (mKey.can_encrypt) - usage_steam << "Encr "; - if (mKey.can_sign) - usage_steam << "Sign "; - if (mKey.can_authenticate) - usage_steam << "Auth "; - - usageVarLabel->setText(usage); - - QString actualUsage; - QTextStream actual_usage_steam(&actualUsage); - - if (GpgFrontend::GpgContext::checkIfKeyCanCert(mKey)) - actual_usage_steam << "Cert "; - if (GpgFrontend::GpgContext::checkIfKeyCanEncr(mKey)) - actual_usage_steam << "Encr "; - if (GpgFrontend::GpgContext::checkIfKeyCanSign(mKey)) - actual_usage_steam << "Sign "; - if (GpgFrontend::GpgContext::checkIfKeyCanAuth(mKey)) - actual_usage_steam << "Auth "; - - actualUsageVarLabel->setText(actualUsage); - - QString keySizeVal, keyExpireVal, keyCreateTimeVal, keyAlgoVal; - - keySizeVal = QString::number(mKey.length); - - if (mKey.expires.toTime_t() == 0) { - keyExpireVal = tr("Never Expire"); - } else { - keyExpireVal = mKey.expires.toString(); - } - - keyAlgoVal = mKey.pubkey_algo; - keyCreateTimeVal = mKey.create_time.toString(); - - keySizeVarLabel->setText(keySizeVal); - expireVarLabel->setText(keyExpireVal); - createdVarLabel->setText(keyCreateTimeVal); - algorithmVarLabel->setText(keyAlgoVal); - - fingerPrintVarLabel->setText(beautifyFingerprint(mKey.fpr)); - + nameVarLabel->setText(QString::fromStdString(mKey.name())); + emailVarLabel->setText(QString::fromStdString(mKey.email())); + + commentVarLabel->setText(QString::fromStdString(mKey.comment())); + keyidVarLabel->setText(QString::fromStdString(mKey.id())); + + QString usage; + QTextStream usage_steam(&usage); + + if (mKey.can_certify()) + usage_steam << "Cert "; + if (mKey.can_encrypt()) + usage_steam << "Encr "; + if (mKey.can_sign()) + usage_steam << "Sign "; + if (mKey.can_authenticate()) + usage_steam << "Auth "; + + usageVarLabel->setText(usage); + + QString actualUsage; + QTextStream actual_usage_steam(&actualUsage); + + if (mKey.CanCertActual()) + actual_usage_steam << "Cert "; + if (mKey.CanEncrActual()) + actual_usage_steam << "Encr "; + if (mKey.CanSignActual()) + actual_usage_steam << "Sign "; + if (mKey.CanAuthActual()) + actual_usage_steam << "Auth "; + + actualUsageVarLabel->setText(actualUsage); + + QString keySizeVal, keyExpireVal, keyCreateTimeVal, keyAlgoVal; + + keySizeVal = QString::number(mKey.length()); + + if (to_time_t(boost::posix_time::ptime(mKey.expires())) == 0) { + keyExpireVal = tr("Never Expire"); + } else { + keyExpireVal = + QString::fromStdString(boost::gregorian::to_iso_string(mKey.expires())); + } + + keyAlgoVal = QString::fromStdString(mKey.pubkey_algo()); + keyCreateTimeVal = QString::fromStdString(to_iso_string(mKey.create_time())); + + keySizeVarLabel->setText(keySizeVal); + expireVarLabel->setText(keyExpireVal); + createdVarLabel->setText(keyCreateTimeVal); + algorithmVarLabel->setText(keyAlgoVal); + + auto key_fpr = mKey.fpr(); + fingerPrintVarLabel->setText( + QString::fromStdString(beautify_fingerprint(key_fpr))); } void KeyPairDetailTab::createKeyServerOperaMenu() { - keyServerOperaMenu = new QMenu(this); - - auto *uploadKeyPair = new QAction(tr("Upload Key Pair to Key Server"), this); - connect(uploadKeyPair, SIGNAL(triggered()), this, SLOT(slotUploadKeyToServer())); - auto *updateKeyPair = new QAction(tr("Update Key Pair"), this); - connect(updateKeyPair, SIGNAL(triggered()), this, SLOT(slotUpdateKeyToServer())); - - keyServerOperaMenu->addAction(uploadKeyPair); - // TODO Solve Refresh Problem -// keyServerOperaMenu->addAction(updateKeyPair); + keyServerOperaMenu = new QMenu(this); + + auto* uploadKeyPair = new QAction(tr("Upload Key Pair to Key Server"), this); + connect(uploadKeyPair, SIGNAL(triggered()), this, + SLOT(slotUploadKeyToServer())); + auto* updateKeyPair = new QAction(tr("Update Key Pair"), this); + connect(updateKeyPair, SIGNAL(triggered()), this, + SLOT(slotUpdateKeyToServer())); + + keyServerOperaMenu->addAction(uploadKeyPair); + // TODO Solve Refresh Problem + // keyServerOperaMenu->addAction(updateKeyPair); } void KeyPairDetailTab::slotUploadKeyToServer() { - QVector<GpgKey> keys; - keys.append(mKey); - auto *dialog = new KeyUploadDialog(mCtx, keys); + auto keys = std::make_unique<KeyIdArgsList>(); + keys->push_back(mKey.id()); + auto* dialog = new KeyUploadDialog(keys, this); } void KeyPairDetailTab::slotUpdateKeyToServer() { - QVector<GpgKey> keys; - keys.append(mKey); - auto *dialog = new KeyServerImportDialog(mCtx, this); - dialog->show(); - dialog->slotImportKey(keys); + auto keys = std::make_unique<KeyIdArgsList>(); + keys->push_back(mKey.id()); + auto* dialog = new KeyServerImportDialog(this); + dialog->show(); + dialog->slotImportKey(keys); } void KeyPairDetailTab::slotGenRevokeCert() { - auto mOutputFileName = QFileDialog::getSaveFileName(this, tr("Generate revocation certificate"), - QString(), - QStringLiteral("%1 (*.rev)").arg( - tr("Revocation Certificates"))); - - if (!mOutputFileName.isEmpty()) - mCtx->generateRevokeCert(mKey, mOutputFileName); + auto mOutputFileName = QFileDialog::getSaveFileName( + this, tr("Generate revocation certificate"), QString(), + QStringLiteral("%1 (*.rev)").arg(tr("Revocation Certificates"))); + // if (!mOutputFileName.isEmpty()) + // mCtx->generateRevokeCert(mKey, mOutputFileName); } +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairDetailTab.h b/src/ui/keypair_details/KeyPairDetailTab.h new file mode 100644 index 00000000..a4978568 --- /dev/null +++ b/src/ui/keypair_details/KeyPairDetailTab.h @@ -0,0 +1,104 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYPAIRDETAILTAB_H +#define GPGFRONTEND_KEYPAIRDETAILTAB_H + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +#include "KeySetExpireDateDialog.h" +#include "ui/KeyServerImportDialog.h" +#include "ui/KeyUploadDialog.h" + +namespace GpgFrontend::UI { + +class KeyPairDetailTab : public QWidget { + Q_OBJECT + + /** + * @details Return QString with a space inserted at every fourth character + * + * @param fingerprint The fingerprint to be beautified + */ + static QString beautifyFingerprint(QString fingerprint); + + void createKeyServerOperaMenu(); + + private slots: + + /** + * @details Export the key to a file, which is choosen in a file dialog + */ + void slotExportPrivateKey(); + + /** + * @details Copy the fingerprint to clipboard + */ + void slotCopyFingerprint(); + + void slotModifyEditDatetime(); + + void slotRefreshKeyInfo(); + + void slotUploadKeyToServer(); + + void slotUpdateKeyToServer(); + + void slotGenRevokeCert(); + + private: + std::string keyid; /** The id of the key the details should be shown for */ + + GpgKey mKey; + + QGroupBox* ownerBox; /** Groupbox containing owner information */ + QGroupBox* keyBox; /** Groupbox containing key information */ + QGroupBox* fingerprintBox; /** Groupbox containing fingerprint information */ + QGroupBox* additionalUidBox; /** Groupbox containing information about + additional uids */ + + QLabel* nameVarLabel; /** Label containng the keys name */ + QLabel* emailVarLabel; /** Label containng the keys email */ + QLabel* commentVarLabel; /** Label containng the keys commment */ + QLabel* keySizeVarLabel; /** Label containng the keys keysize */ + QLabel* expireVarLabel; /** Label containng the keys expiration date */ + QLabel* createdVarLabel; /** Label containng the keys creation date */ + QLabel* algorithmVarLabel; /** Label containng the keys algorithm */ + QLabel* keyidVarLabel; /** Label containng the keys keyid */ + QLabel* fingerPrintVarLabel; /** Label containng the keys fingerprint */ + QLabel* usageVarLabel; + QLabel* actualUsageVarLabel; + QLabel* masterKeyExistVarLabel; + + QMenu* keyServerOperaMenu; + + public: + explicit KeyPairDetailTab(const std::string& key_id, + QWidget* parent = nullptr); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYPAIRDETAILTAB_H diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/keypair_details/KeyPairSubkeyTab.cpp index e2714303..84d9f558 100644 --- a/src/ui/keypair_details/KeyPairSubkeyTab.cpp +++ b/src/ui/keypair_details/KeyPairSubkeyTab.cpp @@ -23,244 +23,262 @@ */ #include "ui/keypair_details/KeyPairSubkeyTab.h" - -KeyPairSubkeyTab::KeyPairSubkeyTab(GpgFrontend::GpgContext *ctx, const GpgKey &key, QWidget *parent) : mCtx(ctx), mKey(key), QWidget(parent) { - - createSubkeyList(); - createSubkeyOperaMenu(); - - listBox = new QGroupBox("Subkey List"); - detailBox = new QGroupBox("Detail of Selected Subkey"); - - auto uidButtonsLayout = new QGridLayout(); - - auto addSubkeyButton = new QPushButton(tr("Generate A New Subkey")); - if(!mKey.is_private_key || !mKey.has_master_key) { - addSubkeyButton->setDisabled(true); - setHidden(addSubkeyButton); - } - - uidButtonsLayout->addWidget(addSubkeyButton, 0, 1); - - auto *baseLayout = new QVBoxLayout(); - - auto subkeyListLayout = new QGridLayout(); - subkeyListLayout->addWidget(subkeyList, 0, 0); - subkeyListLayout->addLayout(uidButtonsLayout, 1, 0); - subkeyListLayout->setContentsMargins(0, 10, 0, 0); - - auto *subkeyDetailLayout = new QGridLayout(); - - subkeyDetailLayout->addWidget(new QLabel(tr("Key ID: ")), 0, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Algorithm: ")), 1, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Key Size:")), 2, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Usage: ")), 3, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Expires On ")), 4, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Last Update: ")), 5, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Existence: ")), 6, 0); - subkeyDetailLayout->addWidget(new QLabel(tr("Fingerprint: ")), 7, 0); - - - keyidVarLabel = new QLabel(); - keySizeVarLabel = new QLabel(); - expireVarLabel = new QLabel(); - algorithmVarLabel = new QLabel(); - createdVarLabel = new QLabel(); - usageVarLabel = new QLabel(); - masterKeyExistVarLabel = new QLabel(); - fingerPrintVarLabel = new QLabel(); - - subkeyDetailLayout->addWidget(keyidVarLabel, 0, 1); - subkeyDetailLayout->addWidget(keySizeVarLabel, 2, 1); - subkeyDetailLayout->addWidget(expireVarLabel, 4, 1); - subkeyDetailLayout->addWidget(algorithmVarLabel, 1, 1); - subkeyDetailLayout->addWidget(createdVarLabel, 5, 1); - subkeyDetailLayout->addWidget(usageVarLabel, 3, 1); - subkeyDetailLayout->addWidget(masterKeyExistVarLabel, 6, 1); - subkeyDetailLayout->addWidget(fingerPrintVarLabel, 7, 1); - - listBox->setLayout(subkeyListLayout); - listBox->setContentsMargins(0, 5, 0, 0); - detailBox->setLayout(subkeyDetailLayout); - - baseLayout->addWidget(listBox); - baseLayout->addWidget(detailBox); - baseLayout->addStretch(); - - connect(addSubkeyButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSubkey())); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshSubkeyList())); - connect(subkeyList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSubkeyDetail())); - - baseLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(baseLayout); - setAttribute(Qt::WA_DeleteOnClose, true); - - slotRefreshSubkeyList(); - +#include "gpg/function/GpgKeyGetter.h" + +namespace GpgFrontend::UI { + +KeyPairSubkeyTab::KeyPairSubkeyTab(const std::string& key_id, QWidget* parent) + : mKey(std::move(GpgKeyGetter::GetInstance().GetKey(key_id))), + QWidget(parent) { + createSubkeyList(); + createSubkeyOperaMenu(); + + listBox = new QGroupBox("Subkey List"); + detailBox = new QGroupBox("Detail of Selected Subkey"); + + auto uidButtonsLayout = new QGridLayout(); + + auto addSubkeyButton = new QPushButton(tr("Generate A New Subkey")); + if (!mKey.is_private_key() || !mKey.has_master_key()) { + addSubkeyButton->setDisabled(true); + setHidden(addSubkeyButton); + } + + uidButtonsLayout->addWidget(addSubkeyButton, 0, 1); + + auto* baseLayout = new QVBoxLayout(); + + auto subkeyListLayout = new QGridLayout(); + subkeyListLayout->addWidget(subkeyList, 0, 0); + subkeyListLayout->addLayout(uidButtonsLayout, 1, 0); + subkeyListLayout->setContentsMargins(0, 10, 0, 0); + + auto* subkeyDetailLayout = new QGridLayout(); + + subkeyDetailLayout->addWidget(new QLabel(tr("Key ID: ")), 0, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Algorithm: ")), 1, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Key Size:")), 2, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Usage: ")), 3, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Expires On ")), 4, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Last Update: ")), 5, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Existence: ")), 6, 0); + subkeyDetailLayout->addWidget(new QLabel(tr("Fingerprint: ")), 7, 0); + + keyidVarLabel = new QLabel(); + keySizeVarLabel = new QLabel(); + expireVarLabel = new QLabel(); + algorithmVarLabel = new QLabel(); + createdVarLabel = new QLabel(); + usageVarLabel = new QLabel(); + masterKeyExistVarLabel = new QLabel(); + fingerPrintVarLabel = new QLabel(); + + subkeyDetailLayout->addWidget(keyidVarLabel, 0, 1); + subkeyDetailLayout->addWidget(keySizeVarLabel, 2, 1); + subkeyDetailLayout->addWidget(expireVarLabel, 4, 1); + subkeyDetailLayout->addWidget(algorithmVarLabel, 1, 1); + subkeyDetailLayout->addWidget(createdVarLabel, 5, 1); + subkeyDetailLayout->addWidget(usageVarLabel, 3, 1); + subkeyDetailLayout->addWidget(masterKeyExistVarLabel, 6, 1); + subkeyDetailLayout->addWidget(fingerPrintVarLabel, 7, 1); + + listBox->setLayout(subkeyListLayout); + listBox->setContentsMargins(0, 5, 0, 0); + detailBox->setLayout(subkeyDetailLayout); + + baseLayout->addWidget(listBox); + baseLayout->addWidget(detailBox); + baseLayout->addStretch(); + + connect(addSubkeyButton, SIGNAL(clicked(bool)), this, SLOT(slotAddSubkey())); + connect(subkeyList, SIGNAL(itemSelectionChanged()), this, + SLOT(slotRefreshSubkeyDetail())); + + baseLayout->setContentsMargins(0, 0, 0, 0); + + setLayout(baseLayout); + setAttribute(Qt::WA_DeleteOnClose, true); + + slotRefreshSubkeyList(); } void KeyPairSubkeyTab::createSubkeyList() { - subkeyList = new QTableWidget(this); + subkeyList = new QTableWidget(this); - subkeyList->setColumnCount(5); - subkeyList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - subkeyList->verticalHeader()->hide(); - subkeyList->setShowGrid(false); - subkeyList->setSelectionBehavior(QAbstractItemView::SelectRows); + subkeyList->setColumnCount(5); + subkeyList->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + subkeyList->verticalHeader()->hide(); + subkeyList->setShowGrid(false); + subkeyList->setSelectionBehavior(QAbstractItemView::SelectRows); - // tableitems not editable - subkeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); + // tableitems not editable + subkeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); - // no focus (rectangle around tableitems) - // may be it should focus on whole row - subkeyList->setFocusPolicy(Qt::NoFocus); - subkeyList->setAlternatingRowColors(true); + // no focus (rectangle around tableitems) + // may be it should focus on whole row + subkeyList->setFocusPolicy(Qt::NoFocus); + subkeyList->setAlternatingRowColors(true); - QStringList labels; - labels << tr("Subkey ID") << tr("Key Size") << tr("Algo") << tr("Create Date") << tr("Expire Date"); + QStringList labels; + labels << tr("Subkey ID") << tr("Key Size") << tr("Algo") << tr("Create Date") + << tr("Expire Date"); - subkeyList->setHorizontalHeaderLabels(labels); - subkeyList->horizontalHeader()->setStretchLastSection(false); + subkeyList->setHorizontalHeaderLabels(labels); + subkeyList->horizontalHeader()->setStretchLastSection(false); } void KeyPairSubkeyTab::slotRefreshSubkeyList() { - int row = 0; - - subkeyList->setSelectionMode(QAbstractItemView::SingleSelection); - - this->buffered_subkeys.clear(); - - for(const auto &subkeys : mKey.subKeys) { - if(subkeys.disabled || subkeys.revoked) - continue; - this->buffered_subkeys.push_back(&subkeys); - } - - subkeyList->setRowCount(buffered_subkeys.size()); - - for(const auto& subkeys : buffered_subkeys) { - - auto *tmp0 = new QTableWidgetItem(subkeys->id); - tmp0->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 0, tmp0); - - auto *tmp1 = new QTableWidgetItem(QString::number(subkeys->length)); - tmp1->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 1, tmp1); - - auto *tmp2 = new QTableWidgetItem(subkeys->pubkey_algo); - tmp2->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 2, tmp2); - - auto *tmp3= new QTableWidgetItem(subkeys->timestamp.toString()); - tmp3->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 3, tmp3); - - auto *tmp4= new QTableWidgetItem(subkeys->expires.toTime_t() == 0 ? tr("Never Expire") : subkeys->expires.toString()); - tmp4->setTextAlignment(Qt::AlignCenter); - subkeyList->setItem(row, 4, tmp4); - - row++; - } - - if(subkeyList->rowCount() > 0) { - subkeyList->selectRow(0); - } + int row = 0; + + subkeyList->setSelectionMode(QAbstractItemView::SingleSelection); + + this->buffered_subkeys.clear(); + auto sub_keys = mKey.subKeys(); + for (auto& sub_key : *sub_keys) { + if (sub_key.disabled() || sub_key.revoked()) + continue; + this->buffered_subkeys.push_back(std::move(sub_key)); + } + + subkeyList->setRowCount(buffered_subkeys.size()); + + for (const auto& subkeys : buffered_subkeys) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(subkeys.id())); + tmp0->setTextAlignment(Qt::AlignCenter); + subkeyList->setItem(row, 0, tmp0); + + auto* tmp1 = new QTableWidgetItem(QString::number(subkeys.length())); + tmp1->setTextAlignment(Qt::AlignCenter); + subkeyList->setItem(row, 1, tmp1); + + auto* tmp2 = + new QTableWidgetItem(QString::fromStdString(subkeys.pubkey_algo())); + tmp2->setTextAlignment(Qt::AlignCenter); + subkeyList->setItem(row, 2, tmp2); + + auto* tmp3 = new QTableWidgetItem( + QString::fromStdString(to_iso_string(subkeys.timestamp()))); + tmp3->setTextAlignment(Qt::AlignCenter); + subkeyList->setItem(row, 3, tmp3); + + auto* tmp4 = new QTableWidgetItem( + boost::posix_time::to_time_t( + boost::posix_time::ptime(subkeys.expires())) == 0 + ? tr("Never Expire") + : QString::fromStdString(to_iso_string(subkeys.expires()))); + tmp4->setTextAlignment(Qt::AlignCenter); + subkeyList->setItem(row, 4, tmp4); + + row++; + } + + if (subkeyList->rowCount() > 0) { + subkeyList->selectRow(0); + } } void KeyPairSubkeyTab::slotAddSubkey() { - auto dialog = new SubkeyGenerateDialog(mCtx, mKey, this); - dialog->show(); + auto dialog = new SubkeyGenerateDialog(mKey, this); + dialog->show(); } void KeyPairSubkeyTab::slotRefreshSubkeyDetail() { - - auto key = getSelectedSubkey(); - - keyidVarLabel->setText(key->id); - keySizeVarLabel->setText(QString::number(key->length)); - - expireVarLabel->setText(key->expires.toTime_t() == 0 ? tr("Never Expires") : key->expires.toString()); - if(key->expires.toTime_t() != 0 && key->expires < QDateTime::currentDateTime()) { - auto paletteExpired = expireVarLabel->palette(); - paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); - expireVarLabel->setPalette(paletteExpired); - } else { - auto paletteValid = expireVarLabel->palette(); - paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); - expireVarLabel->setPalette(paletteValid); - } - - algorithmVarLabel->setText(key->pubkey_algo); - createdVarLabel->setText(key->timestamp.toString()); - - QString usage; - QTextStream usage_steam(&usage); - - if(key->can_certify) - usage_steam << "Cert "; - if(key->can_encrypt) - usage_steam << "Encr "; - if(key->can_sign) - usage_steam << "Sign "; - if(key->can_authenticate) - usage_steam << "Auth "; - - usageVarLabel->setText(usage); - - // Show the situation that master key not exists. - masterKeyExistVarLabel->setText(key->secret ? "Exists" : "Not Exists"); - if(!key->secret){ - auto paletteExpired = masterKeyExistVarLabel->palette(); - paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); - masterKeyExistVarLabel->setPalette(paletteExpired); - } else { - auto paletteValid = masterKeyExistVarLabel->palette(); - paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::darkGreen); - masterKeyExistVarLabel->setPalette(paletteValid); - } - - fingerPrintVarLabel->setText(key->fpr); + auto& subkey = getSelectedSubkey(); + + keyidVarLabel->setText(QString::fromStdString(subkey.id())); + keySizeVarLabel->setText(QString::number(subkey.length())); + + time_t subkey_time_t = + boost::posix_time::to_time_t(boost::posix_time::ptime(subkey.expires())); + + expireVarLabel->setText( + subkey_time_t == 0 + ? tr("Never Expires") + : QString::fromStdString(to_iso_string(subkey.expires()))); + if (subkey_time_t != 0 && + subkey.expires() < boost::posix_time::second_clock::local_time().date()) { + auto paletteExpired = expireVarLabel->palette(); + paletteExpired.setColor(expireVarLabel->foregroundRole(), Qt::red); + expireVarLabel->setPalette(paletteExpired); + } else { + auto paletteValid = expireVarLabel->palette(); + paletteValid.setColor(expireVarLabel->foregroundRole(), Qt::darkGreen); + expireVarLabel->setPalette(paletteValid); + } + + algorithmVarLabel->setText(QString::fromStdString(subkey.pubkey_algo())); + createdVarLabel->setText( + QString::fromStdString(to_iso_string(subkey.timestamp()))); + + QString usage; + QTextStream usage_steam(&usage); + + if (subkey.can_certify()) + usage_steam << "Cert "; + if (subkey.can_encrypt()) + usage_steam << "Encr "; + if (subkey.can_sign()) + usage_steam << "Sign "; + if (subkey.can_authenticate()) + usage_steam << "Auth "; + + usageVarLabel->setText(usage); + + // Show the situation that master key not exists. + masterKeyExistVarLabel->setText(subkey.secret() ? "Exists" : "Not Exists"); + if (!subkey.secret()) { + auto paletteExpired = masterKeyExistVarLabel->palette(); + paletteExpired.setColor(masterKeyExistVarLabel->foregroundRole(), Qt::red); + masterKeyExistVarLabel->setPalette(paletteExpired); + } else { + auto paletteValid = masterKeyExistVarLabel->palette(); + paletteValid.setColor(masterKeyExistVarLabel->foregroundRole(), + Qt::darkGreen); + masterKeyExistVarLabel->setPalette(paletteValid); + } + + fingerPrintVarLabel->setText(QString::fromStdString(subkey.fpr())); } void KeyPairSubkeyTab::createSubkeyOperaMenu() { - subkeyOperaMenu = new QMenu(this); - // auto *revokeSubkeyAct = new QAction(tr("Revoke Subkey")); - auto *editSubkeyAct = new QAction(tr("Edit Expire Date")); - connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey())); + subkeyOperaMenu = new QMenu(this); + // auto *revokeSubkeyAct = new QAction(tr("Revoke Subkey")); + auto* editSubkeyAct = new QAction(tr("Edit Expire Date")); + connect(editSubkeyAct, SIGNAL(triggered(bool)), this, SLOT(slotEditSubkey())); - // subkeyOperaMenu->addAction(revokeSubkeyAct); - subkeyOperaMenu->addAction(editSubkeyAct); + // subkeyOperaMenu->addAction(revokeSubkeyAct); + subkeyOperaMenu->addAction(editSubkeyAct); } void KeyPairSubkeyTab::slotEditSubkey() { - qDebug() << "Slot Edit Subkry"; - auto *subkey = getSelectedSubkey(); - if(subkey == buffered_subkeys[0]) { - subkey = nullptr; - } - auto dialog = new KeySetExpireDateDialog(mCtx, mKey, subkey, this); - dialog->show(); + qDebug() << "Slot Edit Subkry"; + auto subkey_id = std::make_unique<std::string>(getSelectedSubkey().id()); + if (*subkey_id == buffered_subkeys[0].id()) { + subkey_id = nullptr; + } + auto dialog = new KeySetExpireDateDialog(mKey, subkey_id, this); + dialog->show(); } -void KeyPairSubkeyTab::slotRevokeSubkey() { - -} +void KeyPairSubkeyTab::slotRevokeSubkey() {} -void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent *event) { - if (!subkeyList->selectedItems().isEmpty()) { - subkeyOperaMenu->exec(event->globalPos()); - } +void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent* event) { + if (!subkeyList->selectedItems().isEmpty()) { + subkeyOperaMenu->exec(event->globalPos()); + } } -const GpgSubKey *KeyPairSubkeyTab::getSelectedSubkey() { - int row = 0; +const GpgSubKey& KeyPairSubkeyTab::getSelectedSubkey() { + int row = 0; - for(int i = 0 ; i < subkeyList->rowCount(); i++) { - if(subkeyList->item(row, 0)->isSelected()) break; - row++; - } + for (int i = 0; i < subkeyList->rowCount(); i++) { + if (subkeyList->item(row, 0)->isSelected()) + break; + row++; + } - return buffered_subkeys[row]; + return buffered_subkeys[row]; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairSubkeyTab.h b/src/ui/keypair_details/KeyPairSubkeyTab.h new file mode 100644 index 00000000..642d0cf4 --- /dev/null +++ b/src/ui/keypair_details/KeyPairSubkeyTab.h @@ -0,0 +1,85 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYPAIRSUBKEYTAB_H +#define GPGFRONTEND_KEYPAIRSUBKEYTAB_H + +#include "ui/GpgFrontendUI.h" + +#include "KeySetExpireDateDialog.h" +#include "gpg/GpgContext.h" +#include "ui/keygen/SubkeyGenerateDialog.h" + +namespace GpgFrontend::UI { + +class KeyPairSubkeyTab : public QWidget { + Q_OBJECT + + public: + KeyPairSubkeyTab(const std::string& key, QWidget* parent); + + private: + void createSubkeyList(); + + void createSubkeyOperaMenu(); + + const GpgSubKey& getSelectedSubkey(); + + GpgKey mKey; + QTableWidget* subkeyList{}; + std::vector<GpgSubKey> buffered_subkeys; + + QGroupBox* listBox; + QGroupBox* detailBox; + + QMenu* subkeyOperaMenu{}; + + QLabel* keySizeVarLabel; /** Label containng the keys keysize */ + QLabel* expireVarLabel; /** Label containng the keys expiration date */ + QLabel* createdVarLabel; /** Label containng the keys creation date */ + QLabel* algorithmVarLabel; /** Label containng the keys algorithm */ + QLabel* keyidVarLabel; /** Label containng the keys keyid */ + QLabel* fingerPrintVarLabel; /** Label containng the keys fingerprint */ + QLabel* usageVarLabel; + QLabel* masterKeyExistVarLabel; + + private slots: + + void slotAddSubkey(); + + void slotRefreshSubkeyList(); + + void slotRefreshSubkeyDetail(); + + void slotEditSubkey(); + + void slotRevokeSubkey(); + + protected: + void contextMenuEvent(QContextMenuEvent* event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYPAIRSUBKEYTAB_H diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp index fed500a4..075db08e 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/keypair_details/KeyPairUIDTab.cpp @@ -23,489 +23,483 @@ */ #include "ui/keypair_details/KeyPairUIDTab.h" +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyManager.h" +#include "gpg/function/UidOperator.h" -KeyPairUIDTab::KeyPairUIDTab(GpgFrontend::GpgContext *ctx, const GpgKey &key, QWidget *parent) : QWidget(parent), mKey(key) { +namespace GpgFrontend::UI { - mCtx = ctx; +KeyPairUIDTab::KeyPairUIDTab(const std::string& key_id, QWidget* parent) + : QWidget(parent), + mKey(std::move(GpgKeyGetter::GetInstance().GetKey(key_id))) { + createUIDList(); + createSignList(); + createManageUIDMenu(); + createUIDPopupMenu(); + createSignPopupMenu(); - createUIDList(); - createSignList(); - createManageUIDMenu(); - createUIDPopupMenu(); - createSignPopupMenu(); + auto uidButtonsLayout = new QGridLayout(); - auto uidButtonsLayout = new QGridLayout(); + auto addUIDButton = new QPushButton(tr("New UID")); + auto manageUIDButton = new QPushButton(tr("UID Management")); - auto addUIDButton = new QPushButton(tr("New UID")); - auto manageUIDButton = new QPushButton(tr("UID Management")); + if (mKey.has_master_key()) { + manageUIDButton->setMenu(manageSelectedUIDMenu); + } else { + manageUIDButton->setDisabled(true); + } - if(mKey.has_master_key) { - manageUIDButton->setMenu(manageSelectedUIDMenu); - } else { - manageUIDButton->setDisabled(true); - } - - uidButtonsLayout->addWidget(addUIDButton, 0, 1); - uidButtonsLayout->addWidget(manageUIDButton, 0, 2); + uidButtonsLayout->addWidget(addUIDButton, 0, 1); + uidButtonsLayout->addWidget(manageUIDButton, 0, 2); - auto gridLayout = new QGridLayout(); + auto gridLayout = new QGridLayout(); - gridLayout->addWidget(uidList, 0, 0); - gridLayout->addLayout(uidButtonsLayout, 1, 0); - gridLayout->setContentsMargins(0, 10, 0, 0); + gridLayout->addWidget(uidList, 0, 0); + gridLayout->addLayout(uidButtonsLayout, 1, 0); + gridLayout->setContentsMargins(0, 10, 0, 0); - auto uidGroupBox = new QGroupBox(); - uidGroupBox->setLayout(gridLayout); - uidGroupBox->setTitle(tr("UIDs")); + auto uidGroupBox = new QGroupBox(); + uidGroupBox->setLayout(gridLayout); + uidGroupBox->setTitle(tr("UIDs")); - auto signGridLayout = new QGridLayout(); - signGridLayout->addWidget(sigList, 0, 0); - signGridLayout->setContentsMargins(0, 10, 0, 0); + auto signGridLayout = new QGridLayout(); + signGridLayout->addWidget(sigList, 0, 0); + signGridLayout->setContentsMargins(0, 10, 0, 0); - auto signGroupBox = new QGroupBox(); - signGroupBox->setLayout(signGridLayout); - signGroupBox->setTitle(tr("Signature of Selected UID")); + auto signGroupBox = new QGroupBox(); + signGroupBox->setLayout(signGridLayout); + signGroupBox->setTitle(tr("Signature of Selected UID")); - auto vboxLayout = new QVBoxLayout(); - vboxLayout->addWidget(uidGroupBox); - vboxLayout->addWidget(signGroupBox); - vboxLayout->setContentsMargins(0, 0, 0, 0); + auto vboxLayout = new QVBoxLayout(); + vboxLayout->addWidget(uidGroupBox); + vboxLayout->addWidget(signGroupBox); + vboxLayout->setContentsMargins(0, 0, 0, 0); - connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID())); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefreshUIDList())); - connect(uidList, SIGNAL(itemSelectionChanged()), this, SLOT(slotRefreshSigList())); + connect(addUIDButton, SIGNAL(clicked(bool)), this, SLOT(slotAddUID())); + connect(uidList, SIGNAL(itemSelectionChanged()), this, + SLOT(slotRefreshSigList())); - setLayout(vboxLayout); - setAttribute(Qt::WA_DeleteOnClose, true); + setLayout(vboxLayout); + setAttribute(Qt::WA_DeleteOnClose, true); - slotRefreshUIDList(); + slotRefreshUIDList(); } void KeyPairUIDTab::createUIDList() { - - uidList = new QTableWidget(this); - uidList->setColumnCount(4); - uidList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - uidList->verticalHeader()->hide(); - uidList->setShowGrid(false); - uidList->setSelectionBehavior(QAbstractItemView::SelectRows); - uidList->setSelectionMode( QAbstractItemView::SingleSelection ); - - // tableitems not editable - uidList->setEditTriggers(QAbstractItemView::NoEditTriggers); - - // no focus (rectangle around tableitems) - // may be it should focus on whole row - uidList->setFocusPolicy(Qt::NoFocus); - uidList->setAlternatingRowColors(true); - - QStringList labels; - labels << tr("Select") << tr("Name") << tr("Email") << tr("Comment"); - uidList->setHorizontalHeaderLabels(labels); - uidList->horizontalHeader()->setStretchLastSection(true); + uidList = new QTableWidget(this); + uidList->setColumnCount(4); + uidList->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + uidList->verticalHeader()->hide(); + uidList->setShowGrid(false); + uidList->setSelectionBehavior(QAbstractItemView::SelectRows); + uidList->setSelectionMode(QAbstractItemView::SingleSelection); + + // tableitems not editable + uidList->setEditTriggers(QAbstractItemView::NoEditTriggers); + + // no focus (rectangle around tableitems) + // may be it should focus on whole row + uidList->setFocusPolicy(Qt::NoFocus); + uidList->setAlternatingRowColors(true); + + QStringList labels; + labels << tr("Select") << tr("Name") << tr("Email") << tr("Comment"); + uidList->setHorizontalHeaderLabels(labels); + uidList->horizontalHeader()->setStretchLastSection(true); } void KeyPairUIDTab::createSignList() { - - sigList = new QTableWidget(this); - sigList->setColumnCount(5); - sigList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - sigList->verticalHeader()->hide(); - sigList->setShowGrid(false); - sigList->setSelectionBehavior(QAbstractItemView::SelectRows); - - // table items not editable - sigList->setEditTriggers(QAbstractItemView::NoEditTriggers); - - // no focus (rectangle around table items) - // may be it should focus on whole row - sigList->setFocusPolicy(Qt::NoFocus); - sigList->setAlternatingRowColors(true); - - QStringList labels; - labels << tr("Key ID") << tr("Name") << tr("Email") << tr("Create Date") << tr("Expired Date"); - sigList->setHorizontalHeaderLabels(labels); - sigList->horizontalHeader()->setStretchLastSection(false); - + sigList = new QTableWidget(this); + sigList->setColumnCount(5); + sigList->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + sigList->verticalHeader()->hide(); + sigList->setShowGrid(false); + sigList->setSelectionBehavior(QAbstractItemView::SelectRows); + + // table items not editable + sigList->setEditTriggers(QAbstractItemView::NoEditTriggers); + + // no focus (rectangle around table items) + // may be it should focus on whole row + sigList->setFocusPolicy(Qt::NoFocus); + sigList->setAlternatingRowColors(true); + + QStringList labels; + labels << tr("Key ID") << tr("Name") << tr("Email") << tr("Create Date") + << tr("Expired Date"); + sigList->setHorizontalHeaderLabels(labels); + sigList->horizontalHeader()->setStretchLastSection(false); } void KeyPairUIDTab::slotRefreshUIDList() { + int row = 0; - int row = 0; - - uidList->setSelectionMode(QAbstractItemView::SingleSelection); + uidList->setSelectionMode(QAbstractItemView::SingleSelection); - this->buffered_uids.clear(); + this->buffered_uids.clear(); - for(const auto &uid : mKey.uids) { - if(uid.invalid || uid.revoked) { - continue; - } - this->buffered_uids.push_back(&uid); + auto uids = mKey.uids(); + for (auto& uid : *uids) { + if (uid.invalid() || uid.revoked()) { + continue; } + this->buffered_uids.push_back(std::move(uid)); + } - uidList->setRowCount(buffered_uids.size()); + uidList->setRowCount(buffered_uids.size()); - for(const auto& uid : buffered_uids) { + for (const auto& uid : buffered_uids) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(uid.name())); + uidList->setItem(row, 1, tmp0); - auto *tmp0 = new QTableWidgetItem(uid->name); - uidList->setItem(row, 1, tmp0); + auto* tmp1 = new QTableWidgetItem(QString::fromStdString(uid.email())); + uidList->setItem(row, 2, tmp1); - auto *tmp1 = new QTableWidgetItem(uid->email); - uidList->setItem(row, 2, tmp1); + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(uid.comment())); + uidList->setItem(row, 3, tmp2); - auto *tmp2 = new QTableWidgetItem(uid->comment); - uidList->setItem(row, 3, tmp2); + auto* tmp3 = new QTableWidgetItem(QString::number(row)); + tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | + Qt::ItemIsSelectable); + tmp3->setTextAlignment(Qt::AlignCenter); + tmp3->setCheckState(Qt::Unchecked); + uidList->setItem(row, 0, tmp3); - auto *tmp3 = new QTableWidgetItem(QString::number(row)); - tmp3->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - tmp3->setTextAlignment(Qt::AlignCenter); - tmp3->setCheckState(Qt::Unchecked); - uidList->setItem(row, 0, tmp3); + row++; + } - row++; - } - - if(uidList->rowCount() > 0) { - uidList->selectRow(0); - } + if (uidList->rowCount() > 0) { + uidList->selectRow(0); + } - slotRefreshSigList(); + slotRefreshSigList(); } void KeyPairUIDTab::slotRefreshSigList() { + int uidRow = 0, sigRow = 0; + for (const auto& uid : buffered_uids) { + // Only Show Selected UID Signatures + if (!uidList->item(uidRow++, 0)->isSelected()) { + continue; + } - int uidRow = 0, sigRow = 0; - for(const auto& uid : buffered_uids) { - - // Only Show Selected UID Signatures - if(!uidList->item(uidRow++, 0)->isSelected()) { - continue; - } - - buffered_signatures.clear(); - - for(const auto &sig : uid->signatures) { - if(sig.invalid || sig.revoked) { - continue; - } - buffered_signatures.push_back(&sig); - } - - sigList->setRowCount(buffered_signatures.size()); - - for(const auto &sig : buffered_signatures) { + buffered_signatures.clear(); + auto signatures = uid.signatures(); + for (auto& sig : *signatures) { + if (sig.invalid() || sig.revoked()) { + continue; + } + buffered_signatures.push_back(std::move(sig)); + } - auto *tmp0 = new QTableWidgetItem(sig->keyid); - sigList->setItem(sigRow, 0, tmp0); + sigList->setRowCount(buffered_signatures.size()); - if(gpgme_err_code(sig->status) == GPG_ERR_NO_PUBKEY) { - auto *tmp2 = new QTableWidgetItem("<Unknown>"); - sigList->setItem(sigRow, 1, tmp2); + for (const auto& sig : buffered_signatures) { + auto* tmp0 = new QTableWidgetItem(QString::fromStdString(sig.keyid())); + sigList->setItem(sigRow, 0, tmp0); - auto *tmp3 = new QTableWidgetItem("<Unknown>"); - sigList->setItem(sigRow, 2, tmp3); - } else { - auto *tmp2 = new QTableWidgetItem(sig->name); - sigList->setItem(sigRow, 1, tmp2); + if (gpgme_err_code(sig.status()) == GPG_ERR_NO_PUBKEY) { + auto* tmp2 = new QTableWidgetItem("<Unknown>"); + sigList->setItem(sigRow, 1, tmp2); - auto *tmp3 = new QTableWidgetItem(sig->email); - sigList->setItem(sigRow, 2, tmp3); - } + auto* tmp3 = new QTableWidgetItem("<Unknown>"); + sigList->setItem(sigRow, 2, tmp3); + } else { + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(sig.name())); + sigList->setItem(sigRow, 1, tmp2); - auto *tmp4 = new QTableWidgetItem(sig->create_time.toString()); - sigList->setItem(sigRow, 3, tmp4); + auto* tmp3 = new QTableWidgetItem(QString::fromStdString(sig.email())); + sigList->setItem(sigRow, 2, tmp3); + } - auto *tmp5 = new QTableWidgetItem(sig->expire_time.toTime_t() == 0 ? tr("Never Expires") : sig->expire_time.toString()); - tmp5->setTextAlignment(Qt::AlignCenter); - sigList->setItem(sigRow, 4, tmp5); + auto* tmp4 = new QTableWidgetItem(QString::fromStdString( + boost::gregorian::to_iso_string(sig.create_time()))); + sigList->setItem(sigRow, 3, tmp4); - sigRow++; - } + auto* tmp5 = new QTableWidgetItem( + boost::posix_time::to_time_t( + boost::posix_time::ptime(sig.expire_time())) == 0 + ? tr("Never Expires") + : QString::fromStdString( + boost::gregorian::to_iso_string(sig.expire_time()))); + tmp5->setTextAlignment(Qt::AlignCenter); + sigList->setItem(sigRow, 4, tmp5); - break; + sigRow++; } + + break; + } } void KeyPairUIDTab::slotAddSign() { + auto selected_uids = getUIDChecked(); - QVector<GpgUID> selected_uids; - getUIDChecked(selected_uids); + if (selected_uids->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one or more UIDs before doing this operation.")); + return; + } - if(selected_uids.isEmpty()) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one or more UIDs before doing this operation.")); - return; - } - - auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this); - keySignDialog->show(); + auto keySignDialog = new KeyUIDSignDialog(mKey, selected_uids, this); + keySignDialog->show(); } - - -void KeyPairUIDTab::getUIDChecked(QVector<GpgUID> &selected_uids) { - - auto &uids = buffered_uids; - - for (int i = 0; i < uidList->rowCount(); i++) { - if (uidList->item(i, 0)->checkState() == Qt::Checked) { - selected_uids.push_back(*uids[i]); - } - } +UIDArgsListPtr KeyPairUIDTab::getUIDChecked() { + auto selected_uids = std::make_unique<UIDArgsList>(); + for (int i = 0; i < uidList->rowCount(); i++) { + if (uidList->item(i, 0)->checkState() == Qt::Checked) + selected_uids->push_back(buffered_uids[i].uid()); + } + return selected_uids; } void KeyPairUIDTab::createManageUIDMenu() { + manageSelectedUIDMenu = new QMenu(this); - manageSelectedUIDMenu = new QMenu(this); + auto* signUIDAct = new QAction(tr("Sign Selected UID(s)"), this); + connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign())); + auto* delUIDAct = new QAction(tr("Delete Selected UID(s)"), this); + connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID())); - auto *signUIDAct = new QAction(tr("Sign Selected UID(s)"), this); - connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSign())); - auto *delUIDAct = new QAction(tr("Delete Selected UID(s)"), this); - connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUID())); - - if(mKey.has_master_key) { - manageSelectedUIDMenu->addAction(signUIDAct); - manageSelectedUIDMenu->addAction(delUIDAct); - } + if (mKey.has_master_key()) { + manageSelectedUIDMenu->addAction(signUIDAct); + manageSelectedUIDMenu->addAction(delUIDAct); + } } void KeyPairUIDTab::slotAddUID() { - auto keyNewUIDDialog = new KeyNewUIDDialog(mCtx, mKey, this); - connect(keyNewUIDDialog, SIGNAL(finished(int)), this, SLOT(slotAddUIDResult(int))); - connect(keyNewUIDDialog, SIGNAL(finished(int)), keyNewUIDDialog, SLOT(deleteLater())); - keyNewUIDDialog->show(); + auto keyNewUIDDialog = new KeyNewUIDDialog(mKey.id(), this); + connect(keyNewUIDDialog, SIGNAL(finished(int)), this, + SLOT(slotAddUIDResult(int))); + connect(keyNewUIDDialog, SIGNAL(finished(int)), keyNewUIDDialog, + SLOT(deleteLater())); + keyNewUIDDialog->show(); } void KeyPairUIDTab::slotAddUIDResult(int result) { - if(result == 1) { - QMessageBox::information(nullptr, - tr("Successful Operation"), - tr("Successfully added a new UID.")); - } else if (result == -1) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } + if (result == 1) { + QMessageBox::information(nullptr, tr("Successful Operation"), + tr("Successfully added a new UID.")); + } else if (result == -1) { + QMessageBox::critical(nullptr, tr("Operation Failed"), + tr("An error occurred during the operation.")); + } } void KeyPairUIDTab::slotDelUID() { - - QVector<GpgUID> selected_uids; - getUIDChecked(selected_uids); - - if(selected_uids.isEmpty()) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one or more UIDs before doing this operation.")); - return; + auto selected_uids = getUIDChecked(); + + if (selected_uids->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one or more UIDs before doing this operation.")); + return; + } + + QString keynames; + for (auto& uid : *selected_uids) { + keynames.append(QString::fromStdString(uid)); + keynames.append("<br/>"); + } + + int ret = QMessageBox::warning( + this, tr("Deleting UIDs"), + "<b>" + tr("Are you sure that you want to delete the following uids?") + + "</b><br/><br/>" + keynames + +"<br/>" + + tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + bool if_success = true; + + if (ret == QMessageBox::Yes) { + for (const auto& uid : *selected_uids) { + if (UidOperator::GetInstance().revUID(mKey, uid)) { + if_success = false; + } } - QString keynames; - for (const auto &uid : selected_uids) { - keynames.append(uid.name); - keynames.append("<i> <"); - keynames.append(uid.email); - keynames.append("> </i><br/>"); - } - - int ret = QMessageBox::warning(this, tr("Deleting UIDs"), - "<b>"+tr("Are you sure that you want to delete the following uids?")+"</b><br/><br/>"+keynames+ - +"<br/>"+tr("The action can not be undone."), - QMessageBox::No | QMessageBox::Yes); - - - bool if_success = true; - - if (ret == QMessageBox::Yes) { - for(const auto &uid : selected_uids) { - if(!mCtx->revUID(mKey, uid)) { - if_success = false; - } - } - - if(!if_success) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } - + if (!if_success) { + QMessageBox::critical(nullptr, tr("Operation Failed"), + tr("An error occurred during the operation.")); } + } } void KeyPairUIDTab::slotSetPrimaryUID() { - - GpgUID selected_uid; - - if(!getUIDSelected(selected_uid)) { - auto emptyUIDMsg = new QMessageBox(); - emptyUIDMsg->setText("Please select one UID before doing this operation."); - emptyUIDMsg->exec(); - return; - } - - QString keynames; - - keynames.append(selected_uid.name); - keynames.append("<i> <"); - keynames.append(selected_uid.email); - keynames.append("> </i><br/>"); - - int ret = QMessageBox::warning(this, tr("Set Primary UID"), - "<b>"+tr("Are you sure that you want to set the Primary UID to?")+"</b><br/><br/>"+keynames+ - +"<br/>"+tr("The action can not be undone."), - QMessageBox::No | QMessageBox::Yes); - - if (ret == QMessageBox::Yes) { - if(!mCtx->setPrimaryUID(mKey, selected_uid)) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } + auto selected_uids = getUIDSelected(); + + if (selected_uids->empty()) { + auto emptyUIDMsg = new QMessageBox(); + emptyUIDMsg->setText("Please select one UID before doing this operation."); + emptyUIDMsg->exec(); + return; + } + + QString keynames; + + keynames.append(QString::fromStdString(selected_uids->front())); + keynames.append("<br/>"); + + int ret = QMessageBox::warning( + this, tr("Set Primary UID"), + "<b>" + tr("Are you sure that you want to set the Primary UID to?") + + "</b><br/><br/>" + keynames + +"<br/>" + + tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if (!UidOperator::GetInstance().setPrimaryUID(mKey, + selected_uids->front())) { + QMessageBox::critical(nullptr, tr("Operation Failed"), + tr("An error occurred during the operation.")); } + } } -bool KeyPairUIDTab::getUIDSelected(GpgUID &uid) { - auto &uids = buffered_uids; - for (int i = 0; i < uidList->rowCount(); i++) { - if (uidList->item(i, 0)->isSelected()) { - uid = *uids[i]; - return true; - } +UIDArgsListPtr KeyPairUIDTab::getUIDSelected() { + auto uids = std::make_unique<UIDArgsList>(); + for (int i = 0; i < uidList->rowCount(); i++) { + if (uidList->item(i, 0)->isSelected()) { + uids->push_back(buffered_uids[i].uid()); } - return false; + } + return std::move(uids); } -bool KeyPairUIDTab::getSignSelected(GpgKeySignature &signature) { - auto &signatures = buffered_signatures; - for (int i = 0; i < sigList->rowCount(); i++) { - if (sigList->item(i, 0)->isSelected()) { - signature = *signatures[i]; - return true; - } +SignIdArgsListPtr KeyPairUIDTab::getSignSelected() { + auto signatures = std::make_unique<SignIdArgsList>(); + for (int i = 0; i < sigList->rowCount(); i++) { + if (sigList->item(i, 0)->isSelected()) { + auto& sign = buffered_signatures[i]; + signatures->push_back({sign.keyid(), sign.uid()}); } - return false; + } + return signatures; } void KeyPairUIDTab::createUIDPopupMenu() { - - uidPopupMenu = new QMenu(this); - - auto *serPrimaryUIDAct = new QAction(tr("Set As Primary"), this); - connect(serPrimaryUIDAct, SIGNAL(triggered()), this, SLOT(slotSetPrimaryUID())); - auto *signUIDAct = new QAction(tr("Sign UID"), this); - connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle())); - auto *delUIDAct = new QAction(tr("Delete UID"), this); - connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle())); - - if(mKey.has_master_key) { - uidPopupMenu->addAction(serPrimaryUIDAct); - uidPopupMenu->addAction(signUIDAct); - uidPopupMenu->addAction(delUIDAct); - } + uidPopupMenu = new QMenu(this); + + auto* serPrimaryUIDAct = new QAction(tr("Set As Primary"), this); + connect(serPrimaryUIDAct, SIGNAL(triggered()), this, + SLOT(slotSetPrimaryUID())); + auto* signUIDAct = new QAction(tr("Sign UID"), this); + connect(signUIDAct, SIGNAL(triggered()), this, SLOT(slotAddSignSingle())); + auto* delUIDAct = new QAction(tr("Delete UID"), this); + connect(delUIDAct, SIGNAL(triggered()), this, SLOT(slotDelUIDSingle())); + + if (mKey.has_master_key()) { + uidPopupMenu->addAction(serPrimaryUIDAct); + uidPopupMenu->addAction(signUIDAct); + uidPopupMenu->addAction(delUIDAct); + } } -void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent *event) { - if (uidList->selectedItems().length() > 0 && sigList->selectedItems().isEmpty()) { - uidPopupMenu->exec(event->globalPos()); - } +void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent* event) { + if (uidList->selectedItems().length() > 0 && + sigList->selectedItems().isEmpty()) { + uidPopupMenu->exec(event->globalPos()); + } - if (!sigList->selectedItems().isEmpty()) { - signPopupMenu->exec(event->globalPos()); - } + if (!sigList->selectedItems().isEmpty()) { + signPopupMenu->exec(event->globalPos()); + } } void KeyPairUIDTab::slotAddSignSingle() { + auto selected_uids = getUIDSelected(); - GpgUID selected_uid; + if (selected_uids->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one UID before doing this operation.")); + return; + } - if(!getUIDSelected(selected_uid)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one UID before doing this operation.")); - return; - } - - auto selected_uids = QVector<GpgUID>({selected_uid }); - auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this); - keySignDialog->show(); + auto keySignDialog = new KeyUIDSignDialog(mKey, selected_uids, this); + keySignDialog->show(); } void KeyPairUIDTab::slotDelUIDSingle() { - GpgUID selected_uid; - - if(!getUIDSelected(selected_uid)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one UID before doing this operation.")); - return; - } - - QString keynames; - - keynames.append(selected_uid.name); - keynames.append("<i> <"); - keynames.append(selected_uid.email); - keynames.append("> </i><br/>"); - - int ret = QMessageBox::warning(this, tr("Deleting UID"), - "<b>"+tr("Are you sure that you want to delete the following uid?")+"</b><br/><br/>"+keynames+ - +"<br/>"+tr("The action can not be undone."), - QMessageBox::No | QMessageBox::Yes); - - if (ret == QMessageBox::Yes) { - if(!mCtx->revUID(mKey, selected_uid)) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } + auto selected_uids = getUIDSelected(); + if (selected_uids->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one UID before doing this operation.")); + return; + } + + QString keynames; + + keynames.append(QString::fromStdString(selected_uids->front())); + keynames.append("<br/>"); + + int ret = QMessageBox::warning( + this, tr("Deleting UID"), + "<b>" + tr("Are you sure that you want to delete the following uid?") + + "</b><br/><br/>" + keynames + +"<br/>" + + tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if (!UidOperator::GetInstance().revUID(mKey, selected_uids->front())) { + QMessageBox::critical(nullptr, tr("Operation Failed"), + tr("An error occurred during the operation.")); } + } } void KeyPairUIDTab::createSignPopupMenu() { - signPopupMenu = new QMenu(this); + signPopupMenu = new QMenu(this); - auto *delSignAct = new QAction(tr("Delete(Revoke) Key Signature"), this); - connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign())); + auto* delSignAct = new QAction(tr("Delete(Revoke) Key Signature"), this); + connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign())); - signPopupMenu->addAction(delSignAct); + signPopupMenu->addAction(delSignAct); } void KeyPairUIDTab::slotDelSign() { - GpgKeySignature selected_sign; - - if(!getSignSelected(selected_sign)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("Please select one Key Signature before doing this operation.")); - return; - } - - if(gpgme_err_code(selected_sign.status) == GPG_ERR_NO_PUBKEY) { - QMessageBox::critical(nullptr, - tr("Invalid Operation"), - tr("To delete the signature, you need to have its corresponding public key in the local database.")); - return; - } - - QString keynames; - - keynames.append(selected_sign.name); - keynames.append("<i> <"); - keynames.append(selected_sign.email); - keynames.append("> </i><br/>"); - - int ret = QMessageBox::warning(this, tr("Deleting Key Signature"), - "<b>"+tr("Are you sure that you want to delete the following signature?")+"</b><br/><br/>"+keynames+ - +"<br/>"+tr("The action can not be undone."), - QMessageBox::No | QMessageBox::Yes); - - if (ret == QMessageBox::Yes) { - if(!mCtx->revSign(mKey, selected_sign)) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } + auto selected_signs = getSignSelected(); + if (selected_signs->empty()) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("Please select one Key Signature before doing this operation.")); + return; + } + + if (!GpgKeyGetter::GetInstance() + .GetKey(selected_signs->front().first) + .good()) { + QMessageBox::critical( + nullptr, tr("Invalid Operation"), + tr("To delete the signature, you need to have its corresponding public " + "key in the local database.")); + return; + } + + QString keynames; + + keynames.append(QString::fromStdString(selected_signs->front().second)); + keynames.append("<br/>"); + + int ret = QMessageBox::warning( + this, tr("Deleting Key Signature"), + "<b>" + + tr("Are you sure that you want to delete the following signature?") + + "</b><br/><br/>" + keynames + +"<br/>" + + tr("The action can not be undone."), + QMessageBox::No | QMessageBox::Yes); + + if (ret == QMessageBox::Yes) { + if (!GpgKeyManager::GetInstance().revSign(mKey, selected_signs)) { + QMessageBox::critical(nullptr, tr("Operation Failed"), + tr("An error occurred during the operation.")); } + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyPairUIDTab.h b/src/ui/keypair_details/KeyPairUIDTab.h new file mode 100644 index 00000000..0246ead2 --- /dev/null +++ b/src/ui/keypair_details/KeyPairUIDTab.h @@ -0,0 +1,96 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYPAIRUIDTAB_H +#define GPGFRONTEND_KEYPAIRUIDTAB_H + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" + +#include "KeyNewUIDDialog.h" +#include "KeyUIDSignDialog.h" + +namespace GpgFrontend::UI { + +class KeyPairUIDTab : public QWidget { + Q_OBJECT + + public: + KeyPairUIDTab(const std::string& key_id, QWidget* parent); + + private: + GpgKey mKey; + QTableWidget* uidList{}; + QTableWidget* sigList{}; + QMenu* manageSelectedUIDMenu{}; + QMenu* uidPopupMenu{}; + QMenu* signPopupMenu{}; + std::vector<GpgUID> buffered_uids; + std::vector<GpgKeySignature> buffered_signatures; + + void createUIDList(); + + void createSignList(); + + void createManageUIDMenu(); + + void createUIDPopupMenu(); + + void createSignPopupMenu(); + + UIDArgsListPtr getUIDChecked(); + + UIDArgsListPtr getUIDSelected(); + + SignIdArgsListPtr getSignSelected(); + + private slots: + + void slotRefreshUIDList(); + + void slotRefreshSigList(); + + void slotAddSign(); + + void slotAddSignSingle(); + + void slotAddUID(); + + void slotDelUID(); + + void slotDelUIDSingle(); + + void slotSetPrimaryUID(); + + void slotDelSign(); + + static void slotAddUIDResult(int result); + + protected: + void contextMenuEvent(QContextMenuEvent* event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYPAIRUIDTAB_H diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/keypair_details/KeySetExpireDateDialog.cpp index da4f63cf..788adf44 100644 --- a/src/ui/keypair_details/KeySetExpireDateDialog.cpp +++ b/src/ui/keypair_details/KeySetExpireDateDialog.cpp @@ -24,51 +24,69 @@ #include "ui/keypair_details/KeySetExpireDateDialog.h" -KeySetExpireDateDialog::KeySetExpireDateDialog(GpgFrontend::GpgContext *ctx, const GpgKey &key, const GpgSubKey *subkey, QWidget *parent) : -QDialog(parent), mKey(key), mSubkey(subkey), mCtx(ctx) { +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyOpera.h" - QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); - dateTimeEdit = new QDateTimeEdit(maxDateTime); - dateTimeEdit->setMinimumDateTime(QDateTime::currentDateTime().addSecs(1)); - dateTimeEdit->setMaximumDateTime(maxDateTime); - nonExpiredCheck = new QCheckBox(); - nonExpiredCheck->setTristate(false); - confirmButton = new QPushButton(tr("Confirm")); +namespace GpgFrontend::UI { - auto *gridLayout = new QGridLayout(); - gridLayout->addWidget(dateTimeEdit, 0, 0, 1, 2); - gridLayout->addWidget(nonExpiredCheck, 0, 2, 1, 1, Qt::AlignRight); - gridLayout->addWidget(new QLabel(tr("Never Expire")), 0, 3); - gridLayout->addWidget(confirmButton, 1, 3); - - connect(nonExpiredCheck, SIGNAL(stateChanged(int)), this, SLOT(slotNonExpiredChecked(int))); - connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm())); +KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, + QWidget* parent) + : QDialog(parent), mKey(GpgKeyGetter::GetInstance().GetKey(key_id)) { + init(); +} - this->setLayout(gridLayout); - this->setWindowTitle("Edit Expire Datetime"); - this->setModal(true); - this->setAttribute(Qt::WA_DeleteOnClose, true); +KeySetExpireDateDialog::KeySetExpireDateDialog(const KeyId& key_id, + const std::string& subkey_id, + QWidget* parent) + : QDialog(parent), + mKey(GpgKeyGetter::GetInstance().GetKey(key_id)), + mSubkey(subkey_id) { + init(); } void KeySetExpireDateDialog::slotConfirm() { - QDateTime *expires = nullptr; - if(this->nonExpiredCheck->checkState() == Qt::Unchecked) { - expires = new QDateTime(this->dateTimeEdit->dateTime()); - } + std::unique_ptr<boost::gregorian::date> expires = nullptr; + if (this->nonExpiredCheck->checkState() == Qt::Unchecked) { + expires = std::make_unique<boost::gregorian::date>( + boost::posix_time::from_time_t( + this->dateTimeEdit->dateTime().toTime_t()) + .date()); + } + GpgKeyOpera::GetInstance().SetExpire(mKey, mSubkey, expires); + this->close(); +} + +void KeySetExpireDateDialog::init() { + QDateTime maxDateTime = QDateTime::currentDateTime().addYears(2); + dateTimeEdit = new QDateTimeEdit(maxDateTime); + dateTimeEdit->setMinimumDateTime(QDateTime::currentDateTime().addSecs(1)); + dateTimeEdit->setMaximumDateTime(maxDateTime); + nonExpiredCheck = new QCheckBox(); + nonExpiredCheck->setTristate(false); + confirmButton = new QPushButton(tr("Confirm")); - if(!mCtx->setExpire(mKey, mSubkey, expires)) { - QMessageBox::critical(nullptr, - tr("Operation Failed"), - tr("An error occurred during the operation.")); - } - delete expires; - this->close(); + auto* gridLayout = new QGridLayout(); + gridLayout->addWidget(dateTimeEdit, 0, 0, 1, 2); + gridLayout->addWidget(nonExpiredCheck, 0, 2, 1, 1, Qt::AlignRight); + gridLayout->addWidget(new QLabel(tr("Never Expire")), 0, 3); + gridLayout->addWidget(confirmButton, 1, 3); + + connect(nonExpiredCheck, SIGNAL(stateChanged(int)), this, + SLOT(slotNonExpiredChecked(int))); + connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(slotConfirm())); + + this->setLayout(gridLayout); + this->setWindowTitle("Edit Expire Datetime"); + this->setModal(true); + this->setAttribute(Qt::WA_DeleteOnClose, true); } void KeySetExpireDateDialog::slotNonExpiredChecked(int state) { - if(state == 0) { - this->dateTimeEdit->setDisabled(false); - } else { - this->dateTimeEdit->setDisabled(true); - } + if (state == 0) { + this->dateTimeEdit->setDisabled(false); + } else { + this->dateTimeEdit->setDisabled(true); + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeySetExpireDateDialog.h b/src/ui/keypair_details/KeySetExpireDateDialog.h new file mode 100644 index 00000000..d7c19eaa --- /dev/null +++ b/src/ui/keypair_details/KeySetExpireDateDialog.h @@ -0,0 +1,63 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H +#define GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H + +#include "gpg/GpgContext.h" +#include "gpg/model/GpgKey.h" +#include "gpg/model/GpgSubKey.h" +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class KeySetExpireDateDialog : public QDialog { + Q_OBJECT + public: + explicit KeySetExpireDateDialog(const KeyId& key_id, + QWidget* parent = nullptr); + + explicit KeySetExpireDateDialog(const KeyId& key_id, + const std::string& subkey_id, + QWidget* parent = nullptr); + + private: + + void init(); + + const GpgKey mKey; + const SubkeyId mSubkey; + + QDateTimeEdit* dateTimeEdit{}; + QPushButton* confirmButton{}; + QCheckBox* nonExpiredCheck{}; + + private slots: + void slotConfirm(); + void slotNonExpiredChecked(int state); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYSETEXPIREDATEDIALOG_H diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp index 90b2033c..f49a16bc 100644 --- a/src/ui/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp @@ -23,89 +23,99 @@ */ #include "ui/keypair_details/KeyUIDSignDialog.h" - -KeyUIDSignDialog::KeyUIDSignDialog(GpgFrontend::GpgContext *ctx, const GpgKey &key, const QVector<GpgUID> &uid, QWidget *parent) : - mKey(key), mCtx(ctx), mUids(uid), QDialog(parent) { - - mKeyList = new KeyList(ctx, - KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress, - this); - - mKeyList->setFilter([](const GpgKey &key) -> bool { - if(key.disabled || !key.can_certify || !key.has_master_key || key.expired || key.revoked) return false; - else return true; - }); - mKeyList->setExcludeKeys({key.id}); - mKeyList->slotRefresh(); - - signKeyButton = new QPushButton("Sign"); - - /** - * A DateTime after 5 Years is recommend. - */ - expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5)); - expiresEdit->setMinimumDateTime(QDateTime::currentDateTime()); - - /** - * Note further that the OpenPGP protocol uses 32 bit values for timestamps - * and thus can only encode dates up to the year 2106. - */ - expiresEdit->setMaximumDate(QDate(2106, 1, 1)); - - nonExpireCheck = new QCheckBox("Non Expired"); - nonExpireCheck->setTristate(false); - - connect(nonExpireCheck, &QCheckBox::stateChanged, this, [this] (int state) -> void { - if(state == 0) - expiresEdit->setDisabled(false); - else - expiresEdit->setDisabled(true); - }); - - auto layout = new QGridLayout(); - - auto timeLayout = new QGridLayout(); - - layout->addWidget(mKeyList, 0, 0); - layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight); - timeLayout->addWidget(new QLabel(tr("Expire Date")), 0, 0); - timeLayout->addWidget(expiresEdit, 0, 1); - timeLayout->addWidget(nonExpireCheck, 0, 2); - layout->addLayout(timeLayout, 1, 0); - - connect(signKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotSignKey(bool))); - - this->setLayout(layout); - this->setModal(true); - this->setWindowTitle(tr("Sign For Key's UID(s)")); - this->adjustSize(); - - setAttribute(Qt::WA_DeleteOnClose, true); +#include "gpg/function/GpgKeyGetter.h" +#include "gpg/function/GpgKeyManager.h" + +namespace GpgFrontend::UI { + +KeyUIDSignDialog::KeyUIDSignDialog(const GpgKey& key, + const UIDArgsListPtr& uid, + QWidget* parent) + : mKey(key), mUids(uid), QDialog(parent) { + mKeyList = + new KeyList(KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress, this); + + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (key.disabled() || !key.can_certify() || !key.has_master_key() || + key.expired() || key.revoked()) + return false; + else + return true; + }); + mKeyList->setExcludeKeys({key.id()}); + mKeyList->slotRefresh(); + + signKeyButton = new QPushButton("Sign"); + + /** + * A DateTime after 5 Years is recommend. + */ + expiresEdit = new QDateTimeEdit(QDateTime::currentDateTime().addYears(5)); + expiresEdit->setMinimumDateTime(QDateTime::currentDateTime()); + + /** + * Note further that the OpenPGP protocol uses 32 bit values for timestamps + * and thus can only encode dates up to the year 2106. + */ + expiresEdit->setMaximumDate(QDate(2106, 1, 1)); + + nonExpireCheck = new QCheckBox("Non Expired"); + nonExpireCheck->setTristate(false); + + connect(nonExpireCheck, &QCheckBox::stateChanged, this, + [this](int state) -> void { + if (state == 0) + expiresEdit->setDisabled(false); + else + expiresEdit->setDisabled(true); + }); + + auto layout = new QGridLayout(); + + auto timeLayout = new QGridLayout(); + + layout->addWidget(mKeyList, 0, 0); + layout->addWidget(signKeyButton, 2, 0, Qt::AlignRight); + timeLayout->addWidget(new QLabel(tr("Expire Date")), 0, 0); + timeLayout->addWidget(expiresEdit, 0, 1); + timeLayout->addWidget(nonExpireCheck, 0, 2); + layout->addLayout(timeLayout, 1, 0); + + connect(signKeyButton, SIGNAL(clicked(bool)), this, SLOT(slotSignKey(bool))); + + this->setLayout(layout); + this->setModal(true); + this->setWindowTitle(tr("Sign For Key's UID(s)")); + this->adjustSize(); + + setAttribute(Qt::WA_DeleteOnClose, true); } void KeyUIDSignDialog::slotSignKey(bool clicked) { - - // Set Signers - QVector<GpgKey> keys; - mKeyList->getCheckedKeys(keys); - - const auto expires = expiresEdit->dateTime(); - - for(const auto &uid : mUids) { - // Sign For mKey - if (!mCtx->signKey(mKey, keys, uid.uid, &expires)) { - QMessageBox::critical(nullptr, - tr("Unsuccessful Operation"), - QString(tr("Signature operation failed for UID ") + "%1") - .arg(uid.uid)); - } - + // Set Signers + auto key_ids = mKeyList->getChecked(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(std::move(key_ids)); + + auto expires = std::make_unique<boost::gregorian::date>( + boost::posix_time::from_time_t(expiresEdit->dateTime().toTime_t()) + .date()); + + for (const auto& uid : *mUids) { + // Sign For mKey + if (!GpgKeyManager::GetInstance().signKey(mKey, *keys, uid, expires)) { + QMessageBox::critical( + nullptr, tr("Unsuccessful Operation"), + QString(tr("Signature operation failed for UID ") + "%1") + .arg(uid.c_str())); } + } - QMessageBox::information(nullptr, - tr("Operation Complete"), - tr("The signature operation of the UID is complete")); + QMessageBox::information( + nullptr, tr("Operation Complete"), + tr("The signature operation of the UID is complete")); - this->close(); + this->close(); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/keypair_details/KeyUIDSignDialog.h b/src/ui/keypair_details/KeyUIDSignDialog.h new file mode 100644 index 00000000..cd35c4e6 --- /dev/null +++ b/src/ui/keypair_details/KeyUIDSignDialog.h @@ -0,0 +1,62 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_KEYUIDSIGNDIALOG_H +#define GPGFRONTEND_KEYUIDSIGNDIALOG_H + +#include "gpg/GpgContext.h" +#include "ui/GpgFrontendUI.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class KeyUIDSignDialog : public QDialog { + Q_OBJECT + + public: + explicit KeyUIDSignDialog(const GpgKey& key, + const UIDArgsListPtr& uid, + QWidget* parent = nullptr); + + private: + KeyList* mKeyList; + + QPushButton* signKeyButton; + + QDateTimeEdit* expiresEdit; + + QCheckBox* nonExpireCheck; + + const UIDArgsListPtr& mUids; + + const GpgKey& mKey; + + private slots: + + void slotSignKey(bool clicked); +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_KEYUIDSIGNDIALOG_H diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index eff84fcf..2719b103 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -24,587 +24,503 @@ #include "MainWindow.h" -void MainWindow::slotFileEncrypt() { - - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - QFileInfo pathInfo(fileInfo.absolutePath()); - - if (!fileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); - return; - } - if (!pathInfo.isWritable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); - return; - } - if (QFile::exists(path + ".asc")) { - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - return; - } - - QVector<GpgKey> keys; - - mKeyList->getCheckedKeys(keys); +#include "gpg/function/GpgFileOpera.h" +#include "gpg/function/GpgKeyGetter.h" + +namespace GpgFrontend::UI { + +void refresh_info_board(InfoBoardWidget* info_board, + int status, + const std::string& report_text) { + if (status < 0) + info_board->slotRefresh(QString::fromStdString(report_text), + INFO_ERROR_CRITICAL); + else if (status > 0) + info_board->slotRefresh(QString::fromStdString(report_text), INFO_ERROR_OK); + else + info_board->slotRefresh(QString::fromStdString(report_text), + INFO_ERROR_WARN); +} - if (keys.empty()) { - QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); - return; - } +void process_result_analyse(TextEdit* edit, + InfoBoardWidget* info_board, + const ResultAnalyse& result_analyse) { + info_board->associateTabWidget(edit->tabWidget); + info_board->associateFileTreeView(edit->curFilePage()); + refresh_info_board(info_board, result_analyse.getStatus(), + result_analyse.getResultReport()); +} - for (const auto &key : keys) { - if (!GpgFrontend::GpgContext::checkIfKeyCanEncr(key)) { - QMessageBox::information(this, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; +void process_result_analyse(TextEdit* edit, + InfoBoardWidget* info_board, + const ResultAnalyse& result_analyse_a, + const ResultAnalyse& result_analyse_b) { + info_board->associateTabWidget(edit->tabWidget); + info_board->associateFileTreeView(edit->curFilePage()); + + refresh_info_board( + info_board, + std::min(result_analyse_a.getStatus(), result_analyse_a.getStatus()), + result_analyse_a.getResultReport() + result_analyse_a.getResultReport()); +} - } - } +bool file_pre_check(QWidget* parent, const QString& path) { + QFileInfo file_info(path); + QFileInfo path_info(file_info.absolutePath()); + if (!file_info.isFile()) { + QMessageBox::critical(parent, QApplication::tr("Error"), + QApplication::tr("Select a file before doing it.")); + return false; + } + if (!file_info.isReadable()) { + QMessageBox::critical(parent, QApplication::tr("Error"), + QApplication::tr("No permission to read this file.")); + return false; + } + if (!path_info.isWritable()) { + QMessageBox::critical(parent, QApplication::tr("Error"), + QApplication::tr("No permission to create file.")); + return false; + } + return true; +} - gpgme_encrypt_result_t result; - - gpgme_error_t error; - bool if_error = false; - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::encryptFile(mCtx, keys, path, &result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog(tr("Encrypting"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } +void process_operation(QWidget* parent, + std::string waiting_title, + std::function<void()> func) { + GpgEncrResult result = nullptr; + + gpgme_error_t error; + bool if_error = false; + auto thread = QThread::create(func); + QApplication::connect(thread, SIGNAL(finished()), thread, + SLOT(deleteLater())); + thread->start(); + + auto* dialog = + new WaitingDialog(QString::fromStdString(waiting_title), parent); + while (thread->isRunning()) { + QApplication::processEvents(); + } + dialog->close(); +} - dialog->close(); - if (!if_error) { - auto resultAnalyse = new EncryptResultAnalyse(error, result); - auto &reportText = resultAnalyse->getResultReport(); - infoBoard->associateTabWidget(edit->tabWidget); - infoBoard->associateFileTreeView(edit->curFilePage()); - - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - delete resultAnalyse; - - fileTreeView->update(); - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } +void MainWindow::slotFileEncrypt() { + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + if (!file_pre_check(this, path)) + return; + + if (QFile::exists(path + ".asc")) { + auto ret = QMessageBox::warning( + this, tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + return; + } + + auto key_ids = mKeyList->getChecked(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); + if (keys->empty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + for (const auto& key : *keys) { + if (!key.CanEncrActual()) { + QMessageBox::information( + this, tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a " + "encrypt usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + QString::fromStdString(key.uids()->front().uid())); + return; + } + } + + GpgEncrResult result = nullptr; + GpgError error; + bool if_error = false; + process_operation(this, tr("Encrypting").toStdString(), [&]() { + try { + error = GpgFileOpera::GetInstance().EncryptFile( + std::move(*keys), path.toStdString(), result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + auto resultAnalyse = EncryptResultAnalyse(error, std::move(result)); + resultAnalyse.analyse(); + process_result_analyse(edit, infoBoard, resultAnalyse); + fileTreeView->update(); + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } } void MainWindow::slotFileDecrypt() { + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + if (!file_pre_check(this, path)) + return; + + QString outFileName, fileExtension = QFileInfo(path).suffix(); + + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = path.lastIndexOf(QChar('.')); + outFileName = path.left(pos); + } else { + outFileName = path + ".out"; + } + + if (QFile::exists(outFileName)) { + auto ret = QMessageBox::warning( + this, tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + return; + } + + GpgDecrResult result = nullptr; + gpgme_error_t error; + bool if_error = false; + process_operation(this, tr("Decrypting").toStdString(), [&]() { + try { + error = + GpgFileOpera::GetInstance().DecryptFile(path.toStdString(), result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + auto resultAnalyse = DecryptResultAnalyse(error, std::move(result)); + resultAnalyse.analyse(); + process_result_analyse(edit, infoBoard, resultAnalyse); - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - QFileInfo pathInfo(fileInfo.absolutePath()); - if (!fileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); - return; - } - if (!pathInfo.isWritable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); - return; - } - - QString outFileName, fileExtension = fileInfo.suffix(); - - if (fileExtension == "asc" || fileExtension == "gpg") { - int pos = path.lastIndexOf(QChar('.')); - outFileName = path.left(pos); - } else { - outFileName = path + ".out"; - } - - if (QFile::exists(outFileName)) { - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - return; - } - - gpgme_decrypt_result_t result; - gpgme_error_t error; - bool if_error = false; - - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::decryptFile(mCtx, path, &result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog("Decrypting", this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - - dialog->close(); - - if (!if_error) { - auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); - auto &reportText = resultAnalyse->getResultReport(); - infoBoard->associateTabWidget(edit->tabWidget); - infoBoard->associateFileTreeView(edit->curFilePage()); - - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - delete resultAnalyse; - - fileTreeView->update(); - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } - - + fileTreeView->update(); + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } } void MainWindow::slotFileSign() { - - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - QFileInfo pathInfo(fileInfo.absolutePath()); - - if (!fileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); - return; - } - if (!pathInfo.isWritable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); - return; - } - - if (QFile::exists(path + ".sig")) { - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - return; - } - - QVector<GpgKey> keys; - - mKeyList->getCheckedKeys(keys); - - if (keys.empty()) { - QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); - return; - } - - for (const auto &key : keys) { - if (!GpgFrontend::GpgContext::checkIfKeyCanEncr(key)) { - QMessageBox::information(this, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; - - } - } - - gpgme_sign_result_t result; - gpgme_error_t error; - bool if_error = false; - - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::signFile(mCtx, keys, path, &result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog(tr("Signing"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - - dialog->close(); - - if (!if_error) { - - auto resultAnalyse = new SignResultAnalyse(mCtx, error, result); - auto &reportText = resultAnalyse->getResultReport(); - infoBoard->associateTabWidget(edit->tabWidget); - infoBoard->associateFileTreeView(edit->curFilePage()); - - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - delete resultAnalyse; - - fileTreeView->update(); - - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + if (!file_pre_check(this, path)) + return; + + if (QFile::exists(path + ".sig")) { + auto ret = QMessageBox::warning( + this, tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + return; + } + + auto key_ids = mKeyList->getChecked(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); + + if (keys->empty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + for (const auto& key : *keys) { + if (!key.CanSignActual()) { + QMessageBox::information( + this, tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a " + "sign usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + QString::fromStdString(key.uids()->front().uid())); + return; + } + } + + GpgSignResult result = nullptr; + gpgme_error_t error; + bool if_error = false; + + process_operation(this, tr("Signing").toStdString(), [&]() { + try { + error = GpgFileOpera::GetInstance().SignFile(std::move(*keys), + path.toStdString(), result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + auto resultAnalyse = SignResultAnalyse(error, std::move(result)); + resultAnalyse.analyse(); + process_result_analyse(edit, infoBoard, resultAnalyse); fileTreeView->update(); + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } + + fileTreeView->update(); } void MainWindow::slotFileVerify() { + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + QFileInfo fileInfo(path); + + QString signFilePath, dataFilePath; + + if (fileInfo.suffix() == "gpg") { + dataFilePath = path; + signFilePath = path; + } else if (fileInfo.suffix() == "sig") { + int pos = path.lastIndexOf(QChar('.')); + dataFilePath = path.left(pos); + signFilePath = path; + } else { + dataFilePath = path; + signFilePath = path + ".sig"; + } + + QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath); + + if (!dataFileInfo.isFile() || !signFileInfo.isFile()) { + QMessageBox::critical( + this, tr("Error"), + tr("Please select the appropriate target file or signature file. " + "Ensure that both are in this directory.")); + return; + } + if (!dataFileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), + tr("No permission to read target file.")); + return; + } + if (!fileInfo.isReadable()) { + QMessageBox::critical(this, tr("Error"), + tr("No permission to read signature file.")); + return; + } + + GpgVerifyResult result = nullptr; + gpgme_error_t error; + bool if_error = false; + process_operation(this, tr("Verifying").toStdString(), [&]() { + try { + error = GpgFileOpera::GetInstance().VerifyFile(dataFilePath.toStdString(), + result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + auto resultAnalyse = VerifyResultAnalyse(error, std::move(result)); + resultAnalyse.analyse(); + process_result_analyse(edit, infoBoard, resultAnalyse); + + // if (resultAnalyse->getStatus() >= 0) { + // infoBoard->resetOptionActionsMenu(); + // infoBoard->addOptionalAction( + // "Show Verify Details", [this, error, result]() { + // VerifyDetailsDialog(this, mCtx, mKeyList, error, result); + // }); + // } - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - - QString signFilePath, dataFilePath; - - if (fileInfo.suffix() == "gpg") { - dataFilePath = path; - signFilePath = path; - } else if (fileInfo.suffix() == "sig") { - int pos = path.lastIndexOf(QChar('.')); - dataFilePath = path.left(pos); - signFilePath = path; - } else { - dataFilePath = path; - signFilePath = path + ".sig"; - } - - QFileInfo dataFileInfo(dataFilePath), signFileInfo(signFilePath); - - if (!dataFileInfo.isFile() || !signFileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), - tr("Please select the appropriate target file or signature file. Ensure that both are in this directory.")); - return; - } - if (!dataFileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read target file.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read signature file.")); - return; - } - - gpgme_verify_result_t result; - - gpgme_error_t error; - bool if_error = false; - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::verifyFile(mCtx, dataFilePath, &result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog(tr("Verifying"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - dialog->close(); - - if (!if_error) { - auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); - auto &reportText = resultAnalyse->getResultReport(); - infoBoard->associateTabWidget(edit->tabWidget); - infoBoard->associateFileTreeView(edit->curFilePage()); - - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - if (resultAnalyse->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, result); - }); - } - - delete resultAnalyse; - - fileTreeView->update(); - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } + fileTreeView->update(); + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } } void MainWindow::slotFileEncryptSign() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - QFileInfo pathInfo(fileInfo.absolutePath()); - - if (!fileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), tr("Select a file before doing it.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); - return; - } - if (!pathInfo.isWritable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); - return; - } - if (QFile::exists(path + ".gpg")) { - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("The target file already exists, do you need to overwrite it?"), - QMessageBox::Ok | QMessageBox::Cancel); - - if (ret == QMessageBox::Cancel) - return; - } - - QVector<GpgKey> keys; - - mKeyList->getCheckedKeys(keys); - - if (keys.empty()) { - QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); - return; - } - - bool can_sign = false, can_encr = false; + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + if (!file_pre_check(this, path)) + return; + + if (QFile::exists(path + ".gpg")) { + auto ret = QMessageBox::warning( + this, tr("Warning"), + tr("The target file already exists, do you need to overwrite it?"), + QMessageBox::Ok | QMessageBox::Cancel); + + if (ret == QMessageBox::Cancel) + return; + } + + auto key_ids = mKeyList->getChecked(); + auto keys = GpgKeyGetter::GetInstance().GetKeys(key_ids); + + if (keys->empty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } + + bool can_sign = false, can_encr = false; + + for (const auto& key : *keys) { + bool key_can_sign = key.CanSignActual(); + bool key_can_encr = key.CanEncrActual(); + + if (!key_can_sign && !key_can_encr) { + QMessageBox::critical( + nullptr, tr("Invalid KeyPair"), + tr("The selected keypair cannot be used for signing and encryption " + "at the same time.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + QString::fromStdString(key.uids()->front().uid())); + return; + } + + if (key_can_sign) + can_sign = true; + if (key_can_encr) + can_encr = true; + } + + if (!can_encr) { + QMessageBox::critical(nullptr, tr("Incomplete Operation"), + tr("None of the selected key pairs can provide the " + "encryption function.")); + return; + } + + if (!can_sign) { + QMessageBox::warning(nullptr, tr("Incomplete Operation"), + tr("None of the selected key pairs can provide the " + "signature function.")); + } + + GpgEncrResult encr_result = nullptr; + GpgSignResult sign_result = nullptr; + + gpgme_error_t error; + bool if_error = false; + + process_operation(this, tr("Encrypting and Signing").toStdString(), [&]() { + try { + error = GpgFileOpera::GetInstance().EncryptSignFile( + std::move(*keys), path.toStdString(), encr_result, sign_result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + auto encrypt_res = EncryptResultAnalyse(error, std::move(encr_result)); + auto sign_res = SignResultAnalyse(error, std::move(sign_result)); + encrypt_res.analyse(); + sign_res.analyse(); + process_result_analyse(edit, infoBoard, encrypt_res, sign_res); - for (const auto &key : keys) { - bool key_can_sign = GpgFrontend::GpgContext::checkIfKeyCanSign(key); - bool key_can_encr = GpgFrontend::GpgContext::checkIfKeyCanEncr(key); - - if (!key_can_sign && !key_can_encr) { - QMessageBox::critical(nullptr, - tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for signing and encryption at the same time.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; - } - - if (key_can_sign) can_sign = true; - if (key_can_encr) can_encr = true; - } - - if (!can_encr) { - QMessageBox::critical(nullptr, - tr("Incomplete Operation"), - tr("None of the selected key pairs can provide the encryption function.")); - return; - } - - if (!can_sign) { - QMessageBox::warning(nullptr, - tr("Incomplete Operation"), - tr("None of the selected key pairs can provide the signature function.")); - } - - gpgme_encrypt_result_t encr_result = nullptr; - gpgme_sign_result_t sign_result = nullptr; - - gpgme_error_t error; - bool if_error = false; - - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::encryptSignFile(mCtx, keys, path, &encr_result, &sign_result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog(tr("Encrypting and Signing"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - dialog->close(); - - if (!if_error) { - - auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); - auto resultAnalyseSign = new SignResultAnalyse(mCtx, error, sign_result); - int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus()); - auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport(); - - infoBoard->associateFileTreeView(edit->curFilePage()); - - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - delete resultAnalyseEncr; - delete resultAnalyseSign; - - fileTreeView->update(); + fileTreeView->update(); - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } } void MainWindow::slotFileDecryptVerify() { - auto fileTreeView = edit->slotCurPageFileTreeView(); - auto path = fileTreeView->getSelected(); - - QFileInfo fileInfo(path); - QFileInfo pathInfo(fileInfo.absolutePath()); - if (!fileInfo.isFile()) { - QMessageBox::critical(this, tr("Error"), tr("Select a file(.gpg/.asc) before doing it.")); - return; - } - if (!fileInfo.isReadable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to read this file.")); - return; - } - if (!pathInfo.isWritable()) { - QMessageBox::critical(this, tr("Error"), tr("No permission to create file.")); - return; - } - - QString outFileName, fileExtension = fileInfo.suffix(); - - if (fileExtension == "asc" || fileExtension == "gpg") { - int pos = path.lastIndexOf(QChar('.')); - outFileName = path.left(pos); - } else { - outFileName = path + ".out"; - } - - gpgme_decrypt_result_t d_result = nullptr; - gpgme_verify_result_t v_result = nullptr; + auto fileTreeView = edit->slotCurPageFileTreeView(); + auto path = fileTreeView->getSelected(); + + if (!file_pre_check(this, path)) + return; + + QString outFileName, fileExtension = QFileInfo(path).suffix(); + + if (fileExtension == "asc" || fileExtension == "gpg") { + int pos = path.lastIndexOf(QChar('.')); + outFileName = path.left(pos); + } else { + outFileName = path + ".out"; + } + + GpgDecrResult d_result = nullptr; + GpgVerifyResult v_result = nullptr; + gpgme_error_t error; + bool if_error = false; + process_operation(this, tr("Decrypting and Verifying").toStdString(), [&]() { + try { + error = GpgFileOpera::GetInstance().DecryptVerifyFile(path.toStdString(), + d_result, v_result); + } catch (const std::runtime_error& e) { + if_error = true; + } + }); + + if (!if_error) { + infoBoard->associateFileTreeView(edit->curFilePage()); + + auto decrypt_res = DecryptResultAnalyse(error, std::move(d_result)); + auto verify_res = VerifyResultAnalyse(error, std::move(v_result)); + decrypt_res.analyse(); + verify_res.analyse(); + process_result_analyse(edit, infoBoard, decrypt_res, verify_res); + + // if (verify_res.getStatus() >= 0) { + // infoBoard->resetOptionActionsMenu(); + // infoBoard->addOptionalAction( + // "Show Verify Details", [this, error, v_result]() { + // VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); + // }); + // } - gpgme_error_t error; - bool if_error = false; - - auto thread = QThread::create([&]() { - try { - error = GpgFileOpera::decryptVerifyFile(mCtx, path, &d_result, &v_result); - } catch (const std::runtime_error &e) { - if_error = true; - } - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - - auto *dialog = new WaitingDialog(tr("Decrypting and Verifying"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - dialog->close(); - - if (!if_error) { - infoBoard->associateFileTreeView(edit->curFilePage()); - - auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); - auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); - - int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus()); - auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport(); - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - if (resultAnalyseVerify->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); - }); - } - delete resultAnalyseDecrypt; - delete resultAnalyseVerify; - - fileTreeView->update(); - } else { - QMessageBox::critical(this, tr("Error"), tr("An error occurred during operation.")); - return; - } + fileTreeView->update(); + } else { + QMessageBox::critical(this, tr("Error"), + tr("An error occurred during operation.")); + return; + } } void MainWindow::slotFileEncryptCustom() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Encrypt, this); + new FileEncryptionDialog(mKeyList->getChecked(), + FileEncryptionDialog::Encrypt, this); } void MainWindow::slotFileDecryptCustom() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Decrypt, this); + auto key_ids = mKeyList->getChecked(); + new FileEncryptionDialog(mKeyList->getChecked(), + FileEncryptionDialog::Decrypt, this); } void MainWindow::slotFileSignCustom() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Sign, this); + auto key_ids = mKeyList->getChecked(); + new FileEncryptionDialog(mKeyList->getChecked(), FileEncryptionDialog::Sign, + this); } void MainWindow::slotFileVerifyCustom() { - QStringList *keyList; - keyList = mKeyList->getChecked(); - new FileEncryptionDialog(mCtx, *keyList, FileEncryptionDialog::Verify, this); + auto key_ids = mKeyList->getChecked(); + new FileEncryptionDialog(mKeyList->getChecked(), FileEncryptionDialog::Verify, + this); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowServerSlotFunction.cpp b/src/ui/main_window/MainWindowServerSlotFunction.cpp index dbbf178a..6266efda 100644 --- a/src/ui/main_window/MainWindowServerSlotFunction.cpp +++ b/src/ui/main_window/MainWindowServerSlotFunction.cpp @@ -23,216 +23,242 @@ */ #include "MainWindow.h" -#include "server/ComUtils.h" -#include "ui/ShowCopyDialog.h" +#ifdef SERVER_SUPPORT #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" +#include "server/ComUtils.h" +#endif +#include "ui/ShowCopyDialog.h" + +namespace GpgFrontend::UI { + +#ifdef SERVER_SUPPORT /** * get full size crypt text from server using short crypto text * @param shortenCryptoText short crypto text([GpgFrontend_ShortCrypto]://) * @return */ -QString MainWindow::getCryptText(const QString &shortenCryptoText) { - - QString ownKeyId = settings.value("general/ownKeyId").toString(); - - GpgKey key = mCtx->getKeyRefById(ownKeyId); - if (!key.good) { - QMessageBox::critical(this, tr("Invalid Own Key"), - tr("Own Key can not be use to do any operation. " - "Please go to the setting interface to select an OwnKey and get a ServiceToken.")); - return {}; - } - - auto utils = new ComUtils(this); +QString MainWindow::getCryptText(const QString& shortenCryptoText) { + QString ownKeyId = settings.value("general/ownKeyId").toString(); + + GpgKey key = mCtx->getKeyRefById(ownKeyId); + if (!key.good) { + QMessageBox::critical(this, tr("Invalid Own Key"), + tr("Own Key can not be use to do any operation. " + "Please go to the setting interface to select an " + "OwnKey and get a ServiceToken.")); + return {}; + } - QString serviceToken = settings.value("general/serviceToken").toString(); - if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { - QMessageBox::critical(this, tr("Error"), - tr("Please obtain a Service Token from the server in the settings.")); - return {}; - } + auto utils = new ComUtils(this); - QUrl reqUrl(utils->getUrl(ComUtils::GetFullCryptText)); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QString serviceToken = settings.value("general/serviceToken").toString(); + if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { + QMessageBox::critical( + this, tr("Error"), + tr("Please obtain a Service Token from the server in the settings.")); + return {}; + } - // Sign Shorten Text - auto outSignTextBase64 = ComUtils::getSignStringBase64(mCtx, shortenCryptoText, key); + QUrl reqUrl(utils->getUrl(ComUtils::GetFullCryptText)); + QNetworkRequest request(reqUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - rapidjson::Document doc; - doc.SetObject(); + // Sign Shorten Text + auto outSignTextBase64 = + ComUtils::getSignStringBase64(mCtx, shortenCryptoText, key); - rapidjson::Value s, t; + rapidjson::Document doc; + doc.SetObject(); - // Signature - s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); - // Service Token - const auto t_byte_array = serviceToken.toUtf8(); - t.SetString(t_byte_array.constData(), t_byte_array.count()); + rapidjson::Value s, t; - rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); + // Signature + s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); + // Service Token + const auto t_byte_array = serviceToken.toUtf8(); + t.SetString(t_byte_array.constData(), t_byte_array.count()); - doc.AddMember("signature", s, allocator); - doc.AddMember("serviceToken", t, allocator); + rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); - rapidjson::StringBuffer sb; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); - doc.Accept(writer); + doc.AddMember("signature", s, allocator); + doc.AddMember("serviceToken", t, allocator); - QByteArray postData(sb.GetString()); - qDebug() << "postData" << QString::fromUtf8(postData); + rapidjson::StringBuffer sb; + rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); + doc.Accept(writer); - QNetworkReply *reply = utils->getNetworkManager().post(request, postData); + QByteArray postData(sb.GetString()); + qDebug() << "postData" << QString::fromUtf8(postData); - auto dialog = new WaitingDialog(tr("Getting Cpt From Server"), this); - dialog->show(); + QNetworkReply* reply = utils->getNetworkManager().post(request, postData); - while (reply->isRunning()) QApplication::processEvents(); + auto dialog = new WaitingDialog(tr("Getting Cpt From Server"), this); + dialog->show(); - dialog->close(); + while (reply->isRunning()) + QApplication::processEvents(); - QByteArray replyData = reply->readAll().constData(); - if (utils->checkServerReply(replyData)) { - /** - * { - * "cryptoText" : ... - * "sha": ... - * "serviceToken": ... - * "date": ... - * } - */ + dialog->close(); - if (!utils->checkDataValueStr("cryptoText") - || !utils->checkDataValueStr("sha") - || !utils->checkDataValueStr("serviceToken")) { - QMessageBox::critical(this, tr("Error"), - tr("The communication content with the server does not meet the requirements")); - return {}; - } + QByteArray replyData = reply->readAll().constData(); + if (utils->checkServerReply(replyData)) { + /** + * { + * "cryptoText" : ... + * "sha": ... + * "serviceToken": ... + * "date": ... + * } + */ - auto cryptoText = utils->getDataValueStr("cryptoText"); - auto sha = utils->getDataValueStr("sha"); - auto serviceTokenFromServer = utils->getDataValueStr("serviceToken"); + if (!utils->checkDataValueStr("cryptoText") || + !utils->checkDataValueStr("sha") || + !utils->checkDataValueStr("serviceToken")) { + QMessageBox::critical(this, tr("Error"), + tr("The communication content with the server does " + "not meet the requirements")); + return {}; + } - QCryptographicHash sha_generator(QCryptographicHash::Sha256); - sha_generator.addData(cryptoText.toUtf8()); + auto cryptoText = utils->getDataValueStr("cryptoText"); + auto sha = utils->getDataValueStr("sha"); + auto serviceTokenFromServer = utils->getDataValueStr("serviceToken"); - if (sha_generator.result().toHex() == sha && serviceToken == serviceTokenFromServer) { - return cryptoText; - } else QMessageBox::critical(this, tr("Error"), tr("Invalid short ciphertext")); + QCryptographicHash sha_generator(QCryptographicHash::Sha256); + sha_generator.addData(cryptoText.toUtf8()); - return {}; - } + if (sha_generator.result().toHex() == sha && + serviceToken == serviceTokenFromServer) { + return cryptoText; + } else + QMessageBox::critical(this, tr("Error"), tr("Invalid short ciphertext")); return {}; -} + } -void MainWindow::shortenCryptText() { + return {}; +} - // gather information - QString serviceToken = settings.value("general/serviceToken").toString(); - QString ownKeyId = settings.value("general/ownKeyId").toString(); - QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8(); +#endif - auto utils = new ComUtils(this); +#ifdef SERVER_SUPPORT - if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { - QMessageBox::critical(this, tr("Invalid Service Token"), - tr("Please go to the setting interface to get a ServiceToken.")); - return; +void MainWindow::shortenCryptText() { + // gather information + QString serviceToken = settings.value("general/serviceToken").toString(); + QString ownKeyId = settings.value("general/ownKeyId").toString(); + QByteArray cryptoText = edit->curTextPage()->toPlainText().toUtf8(); + + auto utils = new ComUtils(this); + + if (serviceToken.isEmpty() || !utils->checkServiceTokenFormat(serviceToken)) { + QMessageBox::critical( + this, tr("Invalid Service Token"), + tr("Please go to the setting interface to get a ServiceToken.")); + return; + } + + QUrl reqUrl(utils->getUrl(ComUtils::ShortenCryptText)); + QNetworkRequest request(reqUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + GpgKey key = mCtx->getKeyRefById(ownKeyId); + if (!key.good) { + QMessageBox::critical(this, tr("Invalid Own Key"), + tr("Own Key can not be use to do any operation.")); + return; + } + + QCryptographicHash ch(QCryptographicHash::Md5); + ch.addData(cryptoText); + QString md5 = ch.result().toHex(); + + qDebug() << "md5" << md5; + + QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8(); + + QCryptographicHash sha(QCryptographicHash::Sha256); + sha.addData(signText); + QString shaText = sha.result().toHex(); + + qDebug() << "shaText" << shaText; + + QByteArray outSignTextBase64 = + ComUtils::getSignStringBase64(mCtx, signText, key); + + rapidjson::Value c, s, m, t; + + rapidjson::Document doc; + doc.SetObject(); + + c.SetString(cryptoText.constData(), cryptoText.count()); + auto m_byte_array = shaText.toUtf8(); + m.SetString(m_byte_array.constData(), m_byte_array.count()); + s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); + auto t_byte_array = serviceToken.toUtf8(); + t.SetString(t_byte_array.constData(), t_byte_array.count()); + + rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); + + doc.AddMember("cryptoText", c, allocator); + doc.AddMember("sha", m, allocator); + doc.AddMember("sign", s, allocator); + doc.AddMember("serviceToken", t, allocator); + + rapidjson::StringBuffer sb; + rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); + doc.Accept(writer); + + QByteArray postData(sb.GetString()); + qDebug() << "postData" << QString::fromUtf8(postData); + + QNetworkReply* reply = networkAccessManager->post(request, postData); + + auto* dialog = new WaitingDialog(tr("Getting Scpt From Server"), this); + dialog->show(); + while (reply->isRunning()) + QApplication::processEvents(); + dialog->close(); + + if (utils->checkServerReply(reply->readAll().constData())) { + /** + * { + * "shortenText" : ... + * "md5": ... + * } + */ + + if (!utils->checkDataValueStr("shortenText") || + !utils->checkDataValueStr("md5")) { + QMessageBox::critical(this, tr("Error"), + tr("The communication content with the server does " + "not meet the requirements")); + return; } - QUrl reqUrl(utils->getUrl(ComUtils::ShortenCryptText)); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - - GpgKey key = mCtx->getKeyRefById(ownKeyId); - if (!key.good) { - QMessageBox::critical(this, tr("Invalid Own Key"), tr("Own Key can not be use to do any operation.")); - return; + QString shortenText = utils->getDataValueStr("shortenText"); + + QCryptographicHash md5_generator(QCryptographicHash::Md5); + md5_generator.addData(shortenText.toUtf8()); + if (md5_generator.result().toHex() == utils->getDataValueStr("md5")) { + auto* dialog = + new ShowCopyDialog(shortenText, + tr("Notice: Use Decrypt & Verify operation to " + "decrypt this short crypto text."), + this); + dialog->show(); + } else { + QMessageBox::critical( + this, tr("Error"), + tr("There is a problem with the communication with the server")); + return; } - - QCryptographicHash ch(QCryptographicHash::Md5); - ch.addData(cryptoText); - QString md5 = ch.result().toHex(); - - qDebug() << "md5" << md5; - - QByteArray signText = QString("[%1][%2]").arg(serviceToken, md5).toUtf8(); - - QCryptographicHash sha(QCryptographicHash::Sha256); - sha.addData(signText); - QString shaText = sha.result().toHex(); - - qDebug() << "shaText" << shaText; - - QByteArray outSignTextBase64 = ComUtils::getSignStringBase64(mCtx, signText, key); - - rapidjson::Value c, s, m, t; - - rapidjson::Document doc; - doc.SetObject(); - - c.SetString(cryptoText.constData(), cryptoText.count()); - auto m_byte_array = shaText.toUtf8(); - m.SetString(m_byte_array.constData(), m_byte_array.count()); - s.SetString(outSignTextBase64.constData(), outSignTextBase64.count()); - auto t_byte_array = serviceToken.toUtf8(); - t.SetString(t_byte_array.constData(), t_byte_array.count()); - - rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); - - doc.AddMember("cryptoText", c, allocator); - doc.AddMember("sha", m, allocator); - doc.AddMember("sign", s, allocator); - doc.AddMember("serviceToken", t, allocator); - - rapidjson::StringBuffer sb; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); - doc.Accept(writer); - - QByteArray postData(sb.GetString()); - qDebug() << "postData" << QString::fromUtf8(postData); - - QNetworkReply *reply = networkAccessManager->post(request, postData); - - auto *dialog = new WaitingDialog(tr("Getting Scpt From Server"), this); - dialog->show(); - while (reply->isRunning()) QApplication::processEvents(); - dialog->close(); - - if (utils->checkServerReply(reply->readAll().constData())) { - - /** - * { - * "shortenText" : ... - * "md5": ... - * } - */ - - if (!utils->checkDataValueStr("shortenText") || !utils->checkDataValueStr("md5")) { - QMessageBox::critical(this, tr("Error"), - tr("The communication content with the server does not meet the requirements")); - return; - } - - QString shortenText = utils->getDataValueStr("shortenText"); - - QCryptographicHash md5_generator(QCryptographicHash::Md5); - md5_generator.addData(shortenText.toUtf8()); - if (md5_generator.result().toHex() == utils->getDataValueStr("md5")) { - auto *dialog = new ShowCopyDialog(shortenText, - tr("Notice: Use Decrypt & Verify operation to decrypt this short crypto text."), - this); - dialog->show(); - } else { - QMessageBox::critical(this, tr("Error"), tr("There is a problem with the communication with the server")); - return; - } - } - + } } +#endif + +} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 347cf412..0dcbd506 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -23,559 +23,576 @@ */ #include "MainWindow.h" -#include "ui/SendMailDialog.h" -#include "ui/widgets/SignersPicker.h" -#include "server/api/PubkeyUploader.h" + +#ifdef ADVANCE_SUPPORT #include "advance/UnknownSignersChecker.h" +#endif +#ifdef SERVER_SUPPORT +#include "server/api/PubkeyUploader.h" +#endif +#include "ui/SendMailDialog.h" +#include "ui/widgets/SignersPicker.h" +namespace GpgFrontend::UI { /** * Encrypt Entry(Text & File) */ void MainWindow::slotEncrypt() { + if (edit->tabCount() == 0) + return; - if (edit->tabCount() == 0) return; + if (edit->slotCurPageTextEdit() != nullptr) { + auto keys = mKeyList->getChecked(keys); - if (edit->slotCurPageTextEdit() != nullptr) { - - QVector<GpgKey> keys; - mKeyList->getCheckedKeys(keys); - - if (keys.count() == 0) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); - return; - } - - for (const auto &key : keys) { - if (!GpgFrontend::GpgContext::checkIfKeyCanEncr(key)) { - QMessageBox::information(nullptr, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a encrypt usage.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; + if (keys.count() == 0) { + QMessageBox::critical(nullptr, tr("No Key Selected"), + tr("No Key Selected")); + return; + } - } - } + for (const auto& key : keys) { + if (!GpgFrontend::GpgContext::checkIfKeyCanEncr(key)) { + QMessageBox::information( + nullptr, tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a " + "encrypt usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + key.uids.first().uid); + return; + } + } - auto tmp = QByteArray(); + auto tmp = QByteArray(); - gpgme_encrypt_result_t result = nullptr; + gpgme_encrypt_result_t result = nullptr; - gpgme_error_t error; + gpgme_error_t error; - auto thread = QThread::create([&]() { - error = mCtx->encrypt(keys, edit->curTextPage()->toPlainText().toUtf8(), &tmp, &result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); + auto thread = QThread::create([&]() { + error = mCtx->encrypt(keys, edit->curTextPage()->toPlainText().toUtf8(), + &tmp, &result); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); - auto *dialog = new WaitingDialog(tr("Encrypting"), this); + auto* dialog = new WaitingDialog(tr("Encrypting"), this); - while (thread->isRunning()) - QApplication::processEvents(); + while (thread->isRunning()) + QApplication::processEvents(); - dialog->close(); + dialog->close(); - auto resultAnalyse = new EncryptResultAnalyse(error, result); - auto &reportText = resultAnalyse->getResultReport(); + auto resultAnalyse = new EncryptResultAnalyse(error, result); + auto& reportText = resultAnalyse->getResultReport(); - auto tmp2 = QString(tmp); - edit->slotFillTextEditWithText(tmp2); - infoBoard->associateTextEdit(edit->curTextPage()); + auto tmp2 = QString(tmp); + edit->slotFillTextEditWithText(tmp2); + infoBoard->associateTextEdit(edit->curTextPage()); - // check result analyse status - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + // check result analyse status + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - // set optional actions - if (resultAnalyse->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Send Mail", [this]() { - if (settings.value("sendMail/enable", false).toBool()) - new SendMailDialog(edit->curTextPage()->toPlainText(), this); - else { - QMessageBox::warning(nullptr, - tr("Function Disabled"), - tr("Please go to the settings interface to enable and configure this function.")); - } - }); + // set optional actions + if (resultAnalyse->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Send Mail", [this]() { + if (settings.value("sendMail/enable", false).toBool()) + new SendMailDialog(edit->curTextPage()->toPlainText(), this); + else { + QMessageBox::warning(nullptr, tr("Function Disabled"), + tr("Please go to the settings interface to " + "enable and configure this function.")); } - - delete resultAnalyse; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileEncrypt(); + }); } + + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileEncrypt(); + } } void MainWindow::slotSign() { + if (edit->tabCount() == 0) + return; - if (edit->tabCount() == 0) return; - - if (edit->slotCurPageTextEdit() != nullptr) { - - QVector<GpgKey> keys; + if (edit->slotCurPageTextEdit() != nullptr) { + QVector<GpgKey> keys; - mKeyList->getPrivateCheckedKeys(keys); + mKeyList->getPrivateCheckedKeys(keys); - if (keys.isEmpty()) { - QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); - return; - } + if (keys.isEmpty()) { + QMessageBox::critical(this, tr("No Key Selected"), tr("No Key Selected")); + return; + } - for (const auto &key : keys) { - if (!GpgFrontend::GpgContext::checkIfKeyCanSign(key)) { - QMessageBox::information(this, - tr("Invalid Operation"), - tr("The selected key contains a key that does not actually have a signature usage.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; - } - } + for (const auto& key : keys) { + if (!GpgFrontend::GpgContext::checkIfKeyCanSign(key)) { + QMessageBox::information( + this, tr("Invalid Operation"), + tr("The selected key contains a key that does not actually have a " + "signature usage.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + key.uids.first().uid); + return; + } + } - auto tmp = QByteArray(); + auto tmp = QByteArray(); - gpgme_sign_result_t result = nullptr; + gpgme_sign_result_t result = nullptr; - gpgme_error_t error; - auto thread = QThread::create([&]() { - error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), &tmp, GPGME_SIG_MODE_CLEAR, &result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); + gpgme_error_t error; + auto thread = QThread::create([&]() { + error = mCtx->sign(keys, edit->curTextPage()->toPlainText().toUtf8(), + &tmp, GPGME_SIG_MODE_CLEAR, &result); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); - auto *dialog = new WaitingDialog(tr("Signing"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } - dialog->close(); + auto* dialog = new WaitingDialog(tr("Signing"), this); + while (thread->isRunning()) { + QApplication::processEvents(); + } + dialog->close(); - infoBoard->associateTextEdit(edit->curTextPage()); - edit->slotFillTextEditWithText(QString::fromUtf8(tmp)); + infoBoard->associateTextEdit(edit->curTextPage()); + edit->slotFillTextEditWithText(QString::fromUtf8(tmp)); - auto resultAnalyse = new SignResultAnalyse(mCtx, error, result); + auto resultAnalyse = new SignResultAnalyse(mCtx, error, result); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + auto& reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - delete resultAnalyse; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileSign(); - } + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileSign(); + } } void MainWindow::slotDecrypt() { - if (edit->tabCount() == 0) return; - - if (edit->slotCurPageTextEdit() != nullptr) { - - auto decrypted = QByteArray(); - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); - GpgFrontend::GpgContext::preventNoDataErr(&text); - - if (text.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { - QMessageBox::critical(this, tr("Notice"), tr("Short Crypto Text only supports Decrypt & Verify.")); - return; - } + if (edit->tabCount() == 0) + return; + + if (edit->slotCurPageTextEdit() != nullptr) { + auto decrypted = QByteArray(); + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgFrontend::GpgContext::preventNoDataErr(&text); + + if (text.trimmed().startsWith( + GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { + QMessageBox::critical( + this, tr("Notice"), + tr("Short Crypto Text only supports Decrypt & Verify.")); + return; + } - gpgme_decrypt_result_t result = nullptr; + gpgme_decrypt_result_t result = nullptr; - gpgme_error_t error; - auto thread = QThread::create([&]() { - // try decrypt, if fail do nothing, especially don't replace text - error = mCtx->decrypt(text, &decrypted, &result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); + gpgme_error_t error; + auto thread = QThread::create([&]() { + // try decrypt, if fail do nothing, especially don't replace text + error = mCtx->decrypt(text, &decrypted, &result); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); - auto *dialog = new WaitingDialog(tr("Decrypting"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } + auto* dialog = new WaitingDialog(tr("Decrypting"), this); + while (thread->isRunning()) { + QApplication::processEvents(); + } - dialog->close(); + dialog->close(); - infoBoard->associateTextEdit(edit->curTextPage()); + infoBoard->associateTextEdit(edit->curTextPage()); - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromUtf8(decrypted)); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromUtf8(decrypted)); - auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); + auto resultAnalyse = new DecryptResultAnalyse(mCtx, error, result); - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + auto& reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - delete resultAnalyse; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileDecrypt(); - } + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileDecrypt(); + } } void MainWindow::slotFind() { - if (edit->tabCount() == 0 || edit->curTextPage() == nullptr) { - return; - } - - // At first close verifynotification, if existing - edit->slotCurPageTextEdit()->closeNoteByClass("findwidget"); + if (edit->tabCount() == 0 || edit->curTextPage() == nullptr) { + return; + } - auto *fw = new FindWidget(this, edit->curTextPage()); - edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget"); + // At first close verifynotification, if existing + edit->slotCurPageTextEdit()->closeNoteByClass("findwidget"); + auto* fw = new FindWidget(this, edit->curTextPage()); + edit->slotCurPageTextEdit()->showNotificationWidget(fw, "findWidget"); } void MainWindow::slotVerify() { - - if (edit->tabCount() == 0) return; - - if (edit->slotCurPageTextEdit() != nullptr) { - - QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); - GpgFrontend::GpgContext::preventNoDataErr(&text); - - gpgme_verify_result_t result; - - gpgme_error_t error; - auto thread = QThread::create([&]() { - error = mCtx->verify(&text, nullptr, &result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - auto *dialog = new WaitingDialog(tr("Verifying"), this); - while (thread->isRunning()) - QApplication::processEvents(); - dialog->close(); - - auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); - infoBoard->associateTextEdit(edit->curTextPage()); - - auto &reportText = resultAnalyse->getResultReport(); - if (resultAnalyse->getStatus() < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (resultAnalyse->getStatus() > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - if (resultAnalyse->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, result); - }); - } - delete resultAnalyse; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileVerify(); + if (edit->tabCount() == 0) + return; + + if (edit->slotCurPageTextEdit() != nullptr) { + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgFrontend::GpgContext::preventNoDataErr(&text); + + gpgme_verify_result_t result; + + gpgme_error_t error; + auto thread = QThread::create( + [&]() { error = mCtx->verify(&text, nullptr, &result); }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); + + auto* dialog = new WaitingDialog(tr("Verifying"), this); + while (thread->isRunning()) + QApplication::processEvents(); + dialog->close(); + + auto resultAnalyse = new VerifyResultAnalyse(mCtx, error, result); + infoBoard->associateTextEdit(edit->curTextPage()); + + auto& reportText = resultAnalyse->getResultReport(); + if (resultAnalyse->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (resultAnalyse->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if (resultAnalyse->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction( + "Show Verify Details", [this, error, result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, result); + }); } + delete resultAnalyse; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileVerify(); + } } void MainWindow::slotEncryptSign() { + if (edit->tabCount() == 0) + return; - if (edit->tabCount() == 0) return; - - if (edit->slotCurPageTextEdit() != nullptr) { - - QVector<GpgKey> keys; - mKeyList->getCheckedKeys(keys); - - if (keys.empty()) { - QMessageBox::critical(nullptr, tr("No Key Selected"), tr("No Key Selected")); - return; - } - - for (const auto &key : keys) { - bool key_can_encr = GpgFrontend::GpgContext::checkIfKeyCanEncr(key); - - if (!key_can_encr) { - QMessageBox::critical(nullptr, - tr("Invalid KeyPair"), - tr("The selected keypair cannot be used for encryption.<br/>") - + tr("<br/>For example the Following Key: <br/>") + key.uids.first().uid); - return; - } + if (edit->slotCurPageTextEdit() != nullptr) { + QVector<GpgKey> keys; + mKeyList->getCheckedKeys(keys); - } + if (keys.empty()) { + QMessageBox::critical(nullptr, tr("No Key Selected"), + tr("No Key Selected")); + return; + } - QVector<GpgKey> signerKeys; + for (const auto& key : keys) { + bool key_can_encr = GpgFrontend::GpgContext::checkIfKeyCanEncr(key); - auto signersPicker = new SignersPicker(mCtx, this); + if (!key_can_encr) { + QMessageBox::critical( + nullptr, tr("Invalid KeyPair"), + tr("The selected keypair cannot be used for encryption.<br/>") + + tr("<br/>For example the Following Key: <br/>") + + key.uids.first().uid); + return; + } + } - QEventLoop loop; - connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit())); - loop.exec(); + QVector<GpgKey> signerKeys; - signersPicker->getCheckedSigners(signerKeys); + auto signersPicker = new SignersPicker(mCtx, this); - for (const auto &key : keys) { - qDebug() << "Keys " << key.email; - } + QEventLoop loop; + connect(signersPicker, SIGNAL(finished(int)), &loop, SLOT(quit())); + loop.exec(); - for (const auto &signer : signerKeys) { - qDebug() << "Signers " << signer.email; - } + signersPicker->getCheckedSigners(signerKeys); + for (const auto& key : keys) { + qDebug() << "Keys " << key.email; + } - auto tmp = QByteArray(); - gpgme_encrypt_result_t encr_result = nullptr; - gpgme_sign_result_t sign_result = nullptr; + for (const auto& signer : signerKeys) { + qDebug() << "Signers " << signer.email; + } - gpgme_error_t error; - auto thread = QThread::create([&]() { - error = mCtx->encryptSign(keys, signerKeys, edit->curTextPage()->toPlainText().toUtf8(), &tmp, - &encr_result, - &sign_result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); + auto tmp = QByteArray(); + gpgme_encrypt_result_t encr_result = nullptr; + gpgme_sign_result_t sign_result = nullptr; + + gpgme_error_t error; + auto thread = QThread::create([&]() { + error = mCtx->encryptSign(keys, signerKeys, + edit->curTextPage()->toPlainText().toUtf8(), + &tmp, &encr_result, &sign_result); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); + + auto* dialog = new WaitingDialog(tr("Encrypting and Signing"), this); + while (thread->isRunning()) { + QApplication::processEvents(); + } - auto *dialog = new WaitingDialog(tr("Encrypting and Signing"), this); - while (thread->isRunning()) { - QApplication::processEvents(); - } + if (settings.value("advanced/autoPubkeyExchange").toBool()) { + PubkeyUploader pubkeyUploader(mCtx, signerKeys); + pubkeyUploader.start(); + if (!pubkeyUploader.result()) { + QMessageBox::warning(nullptr, tr("Automatic Key Exchange Warning"), + tr("Part of the automatic key exchange failed, " + "which may be related to your key.") + + tr("If possible, try to use the RSA algorithm " + "compatible with the server for signing.")); + } + } - if (settings.value("advanced/autoPubkeyExchange").toBool()) { - PubkeyUploader pubkeyUploader(mCtx, signerKeys); - pubkeyUploader.start(); - if (!pubkeyUploader.result()) { - QMessageBox::warning(nullptr, - tr("Automatic Key Exchange Warning"), - tr("Part of the automatic key exchange failed, which may be related to your key.") - + - tr("If possible, try to use the RSA algorithm compatible with the server for signing.")); - } - } + dialog->close(); - dialog->close(); + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { + auto tmp2 = QString(tmp); + edit->slotFillTextEditWithText(tmp2); + } - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) { - auto tmp2 = QString(tmp); - edit->slotFillTextEditWithText(tmp2); + qDebug() << "Start Analyse Result"; + + auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); + auto resultAnalyseSign = new SignResultAnalyse(mCtx, error, sign_result); + int status = std::min(resultAnalyseEncr->getStatus(), + resultAnalyseSign->getStatus()); + auto reportText = resultAnalyseEncr->getResultReport() + + resultAnalyseSign->getResultReport(); + + infoBoard->associateTextEdit(edit->curTextPage()); + + if (status < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (status > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + qDebug() << "End Analyse Result"; + + if (status >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Send Mail", [this]() { + if (settings.value("sendMail/enable", false).toBool()) + new SendMailDialog(edit->curTextPage()->toPlainText(), this); + else { + QMessageBox::warning(nullptr, tr("Function Disabled"), + tr("Please go to the settings interface to " + "enable and configure this function.")); } - - qDebug() << "Start Analyse Result"; - - auto resultAnalyseEncr = new EncryptResultAnalyse(error, encr_result); - auto resultAnalyseSign = new SignResultAnalyse(mCtx, error, sign_result); - int status = std::min(resultAnalyseEncr->getStatus(), resultAnalyseSign->getStatus()); - auto reportText = resultAnalyseEncr->getResultReport() + resultAnalyseSign->getResultReport(); - - infoBoard->associateTextEdit(edit->curTextPage()); - - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); - - qDebug() << "End Analyse Result"; - - if (status >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Send Mail", [this]() { - if (settings.value("sendMail/enable", false).toBool()) - new SendMailDialog(edit->curTextPage()->toPlainText(), this); - else { - QMessageBox::warning(nullptr, - tr("Function Disabled"), - tr("Please go to the settings interface to enable and configure this function.")); - } - }); - infoBoard->addOptionalAction("Shorten Ciphertext", [this]() { - if (settings.value("general/serviceToken").toString().isEmpty()) - QMessageBox::warning(nullptr, - tr("Service Token Empty"), - tr("Please go to the settings interface to set Own Key and get Service Token.")); - else { - shortenCryptText(); - } - }); + }); + infoBoard->addOptionalAction("Shorten Ciphertext", [this]() { + if (settings.value("general/serviceToken").toString().isEmpty()) + QMessageBox::warning(nullptr, tr("Service Token Empty"), + tr("Please go to the settings interface to set " + "Own Key and get Service Token.")); + else { + shortenCryptText(); } - - delete resultAnalyseEncr; - delete resultAnalyseSign; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileEncryptSign(); + }); } + + delete resultAnalyseEncr; + delete resultAnalyseSign; + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileEncryptSign(); + } } void MainWindow::slotDecryptVerify() { + if (edit->tabCount() == 0) + return; + + if (edit->slotCurPageTextEdit() != nullptr) { + auto decrypted = QByteArray(); + QString plainText = edit->curTextPage()->toPlainText(); + + if (plainText.trimmed().startsWith( + GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { + auto cryptoText = getCryptText(plainText); + if (!cryptoText.isEmpty()) { + plainText = cryptoText; + } + } - if (edit->tabCount() == 0) return; - - if (edit->slotCurPageTextEdit() != nullptr) { - - auto decrypted = QByteArray(); - QString plainText = edit->curTextPage()->toPlainText(); - - - if (plainText.trimmed().startsWith(GpgConstants::GPG_FRONTEND_SHORT_CRYPTO_HEAD)) { - auto cryptoText = getCryptText(plainText); - if (!cryptoText.isEmpty()) { - plainText = cryptoText; - } - } - - QByteArray text = plainText.toUtf8(); - - GpgFrontend::GpgContext::preventNoDataErr(&text); - - gpgme_decrypt_result_t d_result = nullptr; - gpgme_verify_result_t v_result = nullptr; - - auto *dialog = new WaitingDialog(tr("Decrypting and Verifying"), this); - - // Automatically import public keys that are not stored locally - if (settings.value("advanced/autoPubkeyExchange").toBool()) { - gpgme_verify_result_t tmp_v_result = nullptr; - auto thread = QThread::create([&]() { - mCtx->verify(&text, nullptr, &tmp_v_result); - }); - thread->start(); - while (thread->isRunning()) QApplication::processEvents(); - auto *checker = new UnknownSignersChecker(mCtx, tmp_v_result); - checker->start(); - checker->deleteLater(); - } - - gpgme_error_t error; - auto thread = QThread::create([&]() { - error = mCtx->decryptVerify(text, &decrypted, &d_result, &v_result); - }); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); - - while (thread->isRunning()) QApplication::processEvents(); - - dialog->close(); - - qDebug() << "Start Analyse Result"; + QByteArray text = plainText.toUtf8(); - infoBoard->associateTextEdit(edit->curTextPage()); + GpgFrontend::GpgContext::preventNoDataErr(&text); - if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) - edit->slotFillTextEditWithText(QString::fromUtf8(decrypted)); + gpgme_decrypt_result_t d_result = nullptr; + gpgme_verify_result_t v_result = nullptr; - auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); - auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); + auto* dialog = new WaitingDialog(tr("Decrypting and Verifying"), this); - int status = std::min(resultAnalyseDecrypt->getStatus(), resultAnalyseVerify->getStatus()); - auto &reportText = resultAnalyseDecrypt->getResultReport() + resultAnalyseVerify->getResultReport(); - if (status < 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); - else if (status > 0) - infoBoard->slotRefresh(reportText, INFO_ERROR_OK); - else - infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + // Automatically import public keys that are not stored locally + if (settings.value("advanced/autoPubkeyExchange").toBool()) { + gpgme_verify_result_t tmp_v_result = nullptr; + auto thread = QThread::create( + [&]() { mCtx->verify(&text, nullptr, &tmp_v_result); }); + thread->start(); + while (thread->isRunning()) + QApplication::processEvents(); + auto* checker = new UnknownSignersChecker(mCtx, tmp_v_result); + checker->start(); + checker->deleteLater(); + } - if (resultAnalyseVerify->getStatus() >= 0) { - infoBoard->resetOptionActionsMenu(); - infoBoard->addOptionalAction("Show Verify Details", [this, error, v_result]() { - VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); - }); - } - delete resultAnalyseDecrypt; - delete resultAnalyseVerify; + gpgme_error_t error; + auto thread = QThread::create([&]() { + error = mCtx->decryptVerify(text, &decrypted, &d_result, &v_result); + }); + connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); + + while (thread->isRunning()) + QApplication::processEvents(); + + dialog->close(); + + qDebug() << "Start Analyse Result"; + + infoBoard->associateTextEdit(edit->curTextPage()); + + if (gpgme_err_code(error) == GPG_ERR_NO_ERROR) + edit->slotFillTextEditWithText(QString::fromUtf8(decrypted)); + + auto resultAnalyseDecrypt = new DecryptResultAnalyse(mCtx, error, d_result); + auto resultAnalyseVerify = new VerifyResultAnalyse(mCtx, error, v_result); + + int status = std::min(resultAnalyseDecrypt->getStatus(), + resultAnalyseVerify->getStatus()); + auto& reportText = resultAnalyseDecrypt->getResultReport() + + resultAnalyseVerify->getResultReport(); + if (status < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if (status > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if (resultAnalyseVerify->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction( + "Show Verify Details", [this, error, v_result]() { + VerifyDetailsDialog(this, mCtx, mKeyList, error, v_result); + }); + } + delete resultAnalyseDecrypt; + delete resultAnalyseVerify; - qDebug() << "End Analyse Result"; + qDebug() << "End Analyse Result"; - } else if (edit->slotCurPageFileTreeView() != nullptr) { - this->slotFileDecryptVerify(); - } + } else if (edit->slotCurPageFileTreeView() != nullptr) { + this->slotFileDecryptVerify(); + } } - /* * Append the selected (not checked!) Key(s) To Textedit */ void MainWindow::slotAppendSelectedKeys() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { - return; - } + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { + return; + } - auto *keyArray = new QByteArray(); - mCtx->exportKeys(mKeyList->getSelected(), keyArray); - edit->curTextPage()->append(*keyArray); + auto* keyArray = new QByteArray(); + mCtx->exportKeys(mKeyList->getSelected(), keyArray); + edit->curTextPage()->append(*keyArray); } void MainWindow::slotCopyMailAddressToClipboard() { - if (mKeyList->getSelected()->isEmpty()) { - return; - } - auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); - if (!key.good) { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - return; - } - QClipboard *cb = QApplication::clipboard(); - QString mail = key.email; - cb->setText(mail); + if (mKeyList->getSelected()->isEmpty()) { + return; + } + auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); + if (!key.good) { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + return; + } + QClipboard* cb = QApplication::clipboard(); + QString mail = key.email; + cb->setText(mail); } void MainWindow::slotShowKeyDetails() { - if (mKeyList->getSelected()->isEmpty()) { - return; - } - auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); - if (key.good) { - new KeyDetailsDialog(mCtx, key, this); - } else { - QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); - } + if (mKeyList->getSelected()->isEmpty()) { + return; + } + auto key = mCtx->getKeyRefById(mKeyList->getSelected()->first()); + if (key.good) { + new KeyDetailsDialog(mCtx, key, this); + } else { + QMessageBox::critical(nullptr, tr("Error"), tr("Key Not Found.")); + } } void MainWindow::refreshKeysFromKeyserver() { - if (mKeyList->getSelected()->isEmpty()) { - return; - } - - auto *dialog = new KeyServerImportDialog(mCtx, mKeyList, true, this); - dialog->show(); - dialog->slotImport(*mKeyList->getSelected()); + if (mKeyList->getSelected()->isEmpty()) { + return; + } + auto* dialog = new KeyServerImportDialog(mCtx, mKeyList, true, this); + dialog->show(); + dialog->slotImport(*mKeyList->getSelected()); } void MainWindow::uploadKeyToServer() { - QVector<GpgKey> keys; - keys.append(mKeyList->getSelectedKey()); - auto *dialog = new KeyUploadDialog(mCtx, keys, this); - dialog->show(); - dialog->slotUpload(); + QVector<GpgKey> keys; + keys.append(mKeyList->getSelectedKey()); + auto* dialog = new KeyUploadDialog(mCtx, keys, this); + dialog->show(); + dialog->slotUpload(); } - -void MainWindow::slotOpenFile(QString &path) { - edit->slotOpenFile(path); +void MainWindow::slotOpenFile(QString& path) { + edit->slotOpenFile(path); } -void MainWindow::slotVersionUpgrade(const QString ¤tVersion, const QString &latestVersion) { - if (currentVersion < latestVersion) { - QMessageBox::warning(this, - tr("Outdated Version"), - tr("This version(%1) is out of date, please update the latest version in time. ").arg( - currentVersion) - + tr("You can download the latest version(%1) on Github Releases Page.<br/>").arg( - latestVersion)); - } else if (currentVersion > latestVersion) { - QMessageBox::warning(this, - tr("Unreleased Version"), - tr("This version(%1) has not been officially released and is not recommended for use in a production environment. <br/>").arg( - currentVersion) - + tr("You can download the latest version(%1) on Github Releases Page.<br/>").arg( - latestVersion)); - } +void MainWindow::slotVersionUpgrade(const QString& currentVersion, + const QString& latestVersion) { + if (currentVersion < latestVersion) { + QMessageBox::warning(this, tr("Outdated Version"), + tr("This version(%1) is out of date, please update " + "the latest version in time. ") + .arg(currentVersion) + + tr("You can download the latest version(%1) on " + "Github Releases Page.<br/>") + .arg(latestVersion)); + } else if (currentVersion > latestVersion) { + QMessageBox::warning( + this, tr("Unreleased Version"), + tr("This version(%1) has not been officially released and is not " + "recommended for use in a production environment. <br/>") + .arg(currentVersion) + + tr("You can download the latest version(%1) on Github Releases " + "Page.<br/>") + .arg(latestVersion)); + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 7065e41c..982c9efb 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -24,197 +24,200 @@ #include "MainWindow.h" +namespace GpgFrontend::UI { + void MainWindow::slotAbout() { - new AboutDialog(0, this); + new AboutDialog(0, this); } void MainWindow::slotCheckUpdate() { - new AboutDialog(2, this); + new AboutDialog(2, this); } -void MainWindow::slotSetStatusBarText(const QString &text) { - statusBar()->showMessage(text, 20000); +void MainWindow::slotSetStatusBarText(const QString& text) { + statusBar()->showMessage(text, 20000); } void MainWindow::slotStartWizard() { - auto *wizard = new Wizard(mCtx, keyMgmt, this); - wizard->show(); - wizard->setModal(true); + auto* wizard = new Wizard(keyMgmt, this); + wizard->show(); + wizard->setModal(true); } - void MainWindow::slotCheckAttachmentFolder() { - // TODO: always check? - if (!settings.value("mime/parseMime").toBool()) { - return; - } - - QString attachmentDir = qApp->applicationDirPath() + "/attachments/"; - // filenum minus . and .. - uint filenum = QDir(attachmentDir).count() - 2; - if (filenum > 0) { - QString statusText; - if (filenum == 1) { - statusText = tr("There is one unencrypted file in attachment folder"); - } else { - statusText = tr("There are ") + QString::number(filenum) + tr(" unencrypted files in attachment folder"); - } - statusBarIcon->setStatusTip(statusText); - statusBarIcon->show(); + // TODO: always check? + if (!settings.value("mime/parseMime").toBool()) { + return; + } + + QString attachmentDir = qApp->applicationDirPath() + "/attachments/"; + // filenum minus . and .. + uint filenum = QDir(attachmentDir).count() - 2; + if (filenum > 0) { + QString statusText; + if (filenum == 1) { + statusText = tr("There is one unencrypted file in attachment folder"); } else { - statusBarIcon->hide(); + statusText = tr("There are ") + QString::number(filenum) + + tr(" unencrypted files in attachment folder"); } + statusBarIcon->setStatusTip(statusText); + statusBarIcon->show(); + } else { + statusBarIcon->hide(); + } } void MainWindow::slotImportKeyFromEdit() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) - return; - keyMgmt->slotImportKeys(edit->curTextPage()->toPlainText().toUtf8()); + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) + return; + keyMgmt->slotImportKeys(std::make_unique<ByteArray>( + edit->curTextPage()->toPlainText().toStdString())); } void MainWindow::slotOpenKeyManagement() { - keyMgmt->show(); - keyMgmt->raise(); - keyMgmt->activateWindow(); + keyMgmt->show(); + keyMgmt->raise(); + keyMgmt->activateWindow(); } void MainWindow::slotOpenFileTab() { - edit->slotNewFileTab(); + edit->slotNewFileTab(); } void MainWindow::slotDisableTabActions(int number) { - bool disable; - - if (number == -1) - disable = true; - else - disable = false; - - if(edit->curFilePage() != nullptr) { - disable = true; - } - - printAct->setDisabled(disable); - saveAct->setDisabled(disable); - saveAsAct->setDisabled(disable); - quoteAct->setDisabled(disable); - cutAct->setDisabled(disable); - copyAct->setDisabled(disable); - pasteAct->setDisabled(disable); - closeTabAct->setDisabled(disable); - selectAllAct->setDisabled(disable); - findAct->setDisabled(disable); - verifyAct->setDisabled(disable); - signAct->setDisabled(disable); - encryptAct->setDisabled(disable); - encryptSignAct->setDisabled(disable); - decryptAct->setDisabled(disable); - decryptVerifyAct->setDisabled(disable); - - redoAct->setDisabled(disable); - undoAct->setDisabled(disable); - zoomOutAct->setDisabled(disable); - zoomInAct->setDisabled(disable); - cleanDoubleLinebreaksAct->setDisabled(disable); - quoteAct->setDisabled(disable); - appendSelectedKeysAct->setDisabled(disable); - importKeyFromEditAct->setDisabled(disable); - - cutPgpHeaderAct->setDisabled(disable); - addPgpHeaderAct->setDisabled(disable); + bool disable; + + if (number == -1) + disable = true; + else + disable = false; + + if (edit->curFilePage() != nullptr) { + disable = true; + } + + printAct->setDisabled(disable); + saveAct->setDisabled(disable); + saveAsAct->setDisabled(disable); + quoteAct->setDisabled(disable); + cutAct->setDisabled(disable); + copyAct->setDisabled(disable); + pasteAct->setDisabled(disable); + closeTabAct->setDisabled(disable); + selectAllAct->setDisabled(disable); + findAct->setDisabled(disable); + verifyAct->setDisabled(disable); + signAct->setDisabled(disable); + encryptAct->setDisabled(disable); + encryptSignAct->setDisabled(disable); + decryptAct->setDisabled(disable); + decryptVerifyAct->setDisabled(disable); + + redoAct->setDisabled(disable); + undoAct->setDisabled(disable); + zoomOutAct->setDisabled(disable); + zoomInAct->setDisabled(disable); + cleanDoubleLinebreaksAct->setDisabled(disable); + quoteAct->setDisabled(disable); + appendSelectedKeysAct->setDisabled(disable); + importKeyFromEditAct->setDisabled(disable); + + cutPgpHeaderAct->setDisabled(disable); + addPgpHeaderAct->setDisabled(disable); } void MainWindow::slotOpenSettingsDialog() { + auto dialog = new SettingsDialog(this); + + connect(dialog, &SettingsDialog::finished, this, [&]() -> void { + qDebug() << "Setting Dialog Finished"; + + // Iconsize + QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); + this->setIconSize(iconSize); + importButton->setIconSize(iconSize); + fileEncButton->setIconSize(iconSize); + + // Iconstyle + Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>( + settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) + .toUInt()); + this->setToolButtonStyle(buttonStyle); + importButton->setToolButtonStyle(buttonStyle); + fileEncButton->setToolButtonStyle(buttonStyle); + + // restart mainwindow if necessary + if (getRestartNeeded()) { + if (edit->maybeSaveAnyTab()) { + saveSettings(); + qApp->exit(RESTART_CODE); + } + } - auto dialog = new SettingsDialog(mCtx, this); - - connect(dialog, &SettingsDialog::finished, this, [&] () -> void { - - qDebug() << "Setting Dialog Finished"; - - // Iconsize - QSize iconSize = settings.value("toolbar/iconsize", QSize(32, 32)).toSize(); - this->setIconSize(iconSize); - importButton->setIconSize(iconSize); - fileEncButton->setIconSize(iconSize); - - // Iconstyle - Qt::ToolButtonStyle buttonStyle = static_cast<Qt::ToolButtonStyle>(settings.value("toolbar/iconstyle", - Qt::ToolButtonTextUnderIcon).toUInt()); - this->setToolButtonStyle(buttonStyle); - importButton->setToolButtonStyle(buttonStyle); - fileEncButton->setToolButtonStyle(buttonStyle); - - // restart mainwindow if necessary - if (getRestartNeeded()) { - if (edit->maybeSaveAnyTab()) { - saveSettings(); - qApp->exit(RESTART_CODE); - } - } - - // steganography hide/show - if (!settings.value("advanced/steganography").toBool()) { - this->menuBar()->removeAction(steganoMenu->menuAction()); - } else { - this->menuBar()->insertAction(viewMenu->menuAction(), steganoMenu->menuAction()); - } - }); - + // steganography hide/show + if (!settings.value("advanced/steganography").toBool()) { + this->menuBar()->removeAction(steganoMenu->menuAction()); + } else { + this->menuBar()->insertAction(viewMenu->menuAction(), + steganoMenu->menuAction()); + } + }); } void MainWindow::slotCleanDoubleLinebreaks() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { - return; - } + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { + return; + } - QString content = edit->curTextPage()->toPlainText(); - content.replace("\n\n", "\n"); - edit->slotFillTextEditWithText(content); + QString content = edit->curTextPage()->toPlainText(); + content.replace("\n\n", "\n"); + edit->slotFillTextEditWithText(content); } void MainWindow::slotAddPgpHeader() { - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { - return; - } + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { + return; + } - QString content = edit->curTextPage()->toPlainText().trimmed(); + QString content = edit->curTextPage()->toPlainText().trimmed(); - content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN); - content.append("\n").append(GpgConstants::PGP_CRYPT_END); + content.prepend("\n\n").prepend(GpgConstants::PGP_CRYPT_BEGIN); + content.append("\n").append(GpgConstants::PGP_CRYPT_END); - edit->slotFillTextEditWithText(content); + edit->slotFillTextEditWithText(content); } void MainWindow::slotCutPgpHeader() { + if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { + return; + } - if (edit->tabCount() == 0 || edit->slotCurPageTextEdit() == nullptr) { - return; - } - - QString content = edit->curTextPage()->toPlainText(); - int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN); - int end = content.indexOf(GpgConstants::PGP_CRYPT_END); + QString content = edit->curTextPage()->toPlainText(); + int start = content.indexOf(GpgConstants::PGP_CRYPT_BEGIN); + int end = content.indexOf(GpgConstants::PGP_CRYPT_END); - if (start < 0 || end < 0) { - return; - } + if (start < 0 || end < 0) { + return; + } - // remove head - int headEnd = content.indexOf("\n\n", start) + 2; - content.remove(start, headEnd - start); + // remove head + int headEnd = content.indexOf("\n\n", start) + 2; + content.remove(start, headEnd - start); - // remove tail - end = content.indexOf(GpgConstants::PGP_CRYPT_END); - content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size()); + // remove tail + end = content.indexOf(GpgConstants::PGP_CRYPT_END); + content.remove(end, QString(GpgConstants::PGP_CRYPT_END).size()); - edit->slotFillTextEditWithText(content.trimmed()); + edit->slotFillTextEditWithText(content.trimmed()); } void MainWindow::slotSetRestartNeeded(bool needed) { - this->restartNeeded = needed; + this->restartNeeded = needed; } bool MainWindow::getRestartNeeded() const { - return this->restartNeeded; + return this->restartNeeded; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index 21f6e3b7..44fed8dc 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -24,427 +24,454 @@ #include "MainWindow.h" +namespace GpgFrontend::UI { + void MainWindow::createActions() { - /* Main Menu - */ - newTabAct = new QAction(tr("&New"), this); - newTabAct->setIcon(QIcon(":misc_doc.png")); - QList<QKeySequence> newTabActShortcutList; - newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N)); - newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T)); - newTabAct->setShortcuts(newTabActShortcutList); - newTabAct->setToolTip(tr("Open a new file")); - connect(newTabAct, SIGNAL(triggered()), edit, SLOT(slotNewTab())); - - openAct = new QAction(tr("&Open..."), this); - openAct->setIcon(QIcon(":fileopen.png")); - openAct->setShortcut(QKeySequence::Open); - openAct->setToolTip(tr("Open an existing file")); - connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen())); - - browserAct = new QAction(tr("&Browser"), this); - browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); - browserAct->setToolTip(tr("Open a file browser")); - connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab())); - - saveAct = new QAction(tr("&Save"), this); - saveAct->setIcon(QIcon(":filesave.png")); - saveAct->setShortcut(QKeySequence::Save); - saveAct->setToolTip(tr("Save the current File")); - connect(saveAct, SIGNAL(triggered()), edit, SLOT(slotSave())); - - saveAsAct = new QAction(tr("Save &As") + "...", this); - saveAsAct->setIcon(QIcon(":filesaveas.png")); - saveAsAct->setShortcut(QKeySequence::SaveAs); - saveAsAct->setToolTip(tr("Save the current File as...")); - connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(slotSaveAs())); - - printAct = new QAction(tr("&Print"), this); - printAct->setIcon(QIcon(":fileprint.png")); - printAct->setShortcut(QKeySequence::Print); - printAct->setToolTip(tr("Print Document")); - connect(printAct, SIGNAL(triggered()), edit, SLOT(slotPrint())); - - closeTabAct = new QAction(tr("&Close"), this); - closeTabAct->setShortcut(QKeySequence::Close); - closeTabAct->setToolTip(tr("Close file")); - connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(slotCloseTab())); - - quitAct = new QAction(tr("&Quit"), this); - quitAct->setShortcut(QKeySequence::Quit); - quitAct->setIcon(QIcon(":exit.png")); - quitAct->setToolTip(tr("Quit Program")); - connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); - - /* Edit Menu - */ - undoAct = new QAction(tr("&Undo"), this); - undoAct->setShortcut(QKeySequence::Undo); - undoAct->setToolTip(tr("Undo Last Edit Action")); - connect(undoAct, SIGNAL(triggered()), edit, SLOT(slotUndo())); - - redoAct = new QAction(tr("&Redo"), this); - redoAct->setShortcut(QKeySequence::Redo); - redoAct->setToolTip(tr("Redo Last Edit Action")); - connect(redoAct, SIGNAL(triggered()), edit, SLOT(slotRedo())); - - zoomInAct = new QAction(tr("Zoom In"), this); - zoomInAct->setShortcut(QKeySequence::ZoomIn); - connect(zoomInAct, SIGNAL(triggered()), edit, SLOT(slotZoomIn())); - - zoomOutAct = new QAction(tr("Zoom Out"), this); - zoomOutAct->setShortcut(QKeySequence::ZoomOut); - connect(zoomOutAct, SIGNAL(triggered()), edit, SLOT(slotZoomOut())); - - pasteAct = new QAction(tr("&Paste"), this); - pasteAct->setIcon(QIcon(":button_paste.png")); - pasteAct->setShortcut(QKeySequence::Paste); - pasteAct->setToolTip(tr("Paste Text From Clipboard")); - connect(pasteAct, SIGNAL(triggered()), edit, SLOT(slotPaste())); - - cutAct = new QAction(tr("Cu&t"), this); - cutAct->setIcon(QIcon(":button_cut.png")); - cutAct->setShortcut(QKeySequence::Cut); - cutAct->setToolTip(tr("Cut the current selection's contents to the " - "clipboard")); - connect(cutAct, SIGNAL(triggered()), edit, SLOT(slotCut())); - - copyAct = new QAction(tr("&Copy"), this); - copyAct->setIcon(QIcon(":button_copy.png")); - copyAct->setShortcut(QKeySequence::Copy); - copyAct->setToolTip(tr("Copy the current selection's contents to the " - "clipboard")); - connect(copyAct, SIGNAL(triggered()), edit, SLOT(slotCopy())); - - quoteAct = new QAction(tr("&Quote"), this); - quoteAct->setIcon(QIcon(":quote.png")); - quoteAct->setToolTip(tr("Quote whole text")); - connect(quoteAct, SIGNAL(triggered()), edit, SLOT(slotQuote())); - - selectAllAct = new QAction(tr("Select &All"), this); - selectAllAct->setIcon(QIcon(":edit.png")); - selectAllAct->setShortcut(QKeySequence::SelectAll); - selectAllAct->setToolTip(tr("Select the whole text")); - connect(selectAllAct, SIGNAL(triggered()), edit, SLOT(slotSelectAll())); - - findAct = new QAction(tr("&Find"), this); - findAct->setShortcut(QKeySequence::Find); - findAct->setToolTip(tr("Find a word")); - connect(findAct, SIGNAL(triggered()), this, SLOT(slotFind())); - - cleanDoubleLinebreaksAct = new QAction(tr("Remove &spacing"), this); - cleanDoubleLinebreaksAct->setIcon(QIcon(":format-line-spacing-triple.png")); - //cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll); - cleanDoubleLinebreaksAct->setToolTip(tr("Remove double linebreaks, e.g. in pasted text from webmailer")); - connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, SLOT(slotCleanDoubleLinebreaks())); - - openSettingsAct = new QAction(tr("Se&ttings"), this); - openSettingsAct->setToolTip(tr("Open settings dialog")); - openSettingsAct->setShortcut(QKeySequence::Preferences); - connect(openSettingsAct, SIGNAL(triggered()), this, SLOT(slotOpenSettingsDialog())); - - /* Crypt Menu - */ - encryptAct = new QAction(tr("&Encrypt"), this); - encryptAct->setIcon(QIcon(":encrypted.png")); - encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); - encryptAct->setToolTip(tr("Encrypt Message")); - connect(encryptAct, SIGNAL(triggered()), this, SLOT(slotEncrypt())); - - encryptSignAct = new QAction(tr("&Encrypt &Sign"), this); - encryptSignAct->setIcon(QIcon(":encrypted_signed.png")); - encryptSignAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E)); - encryptSignAct->setToolTip(tr("Encrypt and Sign Message")); - connect(encryptSignAct, SIGNAL(triggered()), this, SLOT(slotEncryptSign())); - - decryptAct = new QAction(tr("&Decrypt"), this); - decryptAct->setIcon(QIcon(":decrypted.png")); - decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); - decryptAct->setToolTip(tr("Decrypt Message")); - connect(decryptAct, SIGNAL(triggered()), this, SLOT(slotDecrypt())); - - decryptVerifyAct = new QAction(tr("&Decrypt &Verify"), this); - decryptVerifyAct->setIcon(QIcon(":decrypted_verified.png")); - decryptVerifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D)); - decryptVerifyAct->setToolTip(tr("Decrypt and Verify Message")); - connect(decryptVerifyAct, SIGNAL(triggered()), this, SLOT(slotDecryptVerify())); - - /* - * File encryption submenu - */ - fileEncryptAct = new QAction(tr("&Encrypt File"), this); - fileEncryptAct->setToolTip(tr("Encrypt File")); - connect(fileEncryptAct, SIGNAL(triggered()), this, SLOT(slotFileEncryptCustom())); - - fileDecryptAct = new QAction(tr("&Decrypt File"), this); - fileDecryptAct->setToolTip(tr("Decrypt File")); - connect(fileDecryptAct, SIGNAL(triggered()), this, SLOT(slotFileDecryptCustom())); - - fileSignAct = new QAction(tr("&Sign File"), this); - fileSignAct->setToolTip(tr("Sign File")); - connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSignCustom())); - - fileVerifyAct = new QAction(tr("&Verify File"), this); - fileVerifyAct->setToolTip(tr("Verify File")); - connect(fileVerifyAct, SIGNAL(triggered()), this, SLOT(slotFileVerifyCustom())); - - - signAct = new QAction(tr("&Sign"), this); - signAct->setIcon(QIcon(":signature.png")); - signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); - signAct->setToolTip(tr("Sign Message")); - connect(signAct, SIGNAL(triggered()), this, SLOT(slotSign())); - - verifyAct = new QAction(tr("&Verify"), this); - verifyAct->setIcon(QIcon(":verify.png")); - verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); - verifyAct->setToolTip(tr("Verify Message")); - connect(verifyAct, SIGNAL(triggered()), this, SLOT(slotVerify())); - - /* Key Menu - */ - - importKeyFromEditAct = new QAction(tr("&Editor"), this); - importKeyFromEditAct->setIcon(QIcon(":txt.png")); - importKeyFromEditAct->setToolTip(tr("Import New Key From Editor")); - connect(importKeyFromEditAct, SIGNAL(triggered()), this, SLOT(slotImportKeyFromEdit())); - - openKeyManagementAct = new QAction(tr("Manage &Keys"), this); - openKeyManagementAct->setIcon(QIcon(":keymgmt.png")); - openKeyManagementAct->setToolTip(tr("Open Keymanagement")); - connect(openKeyManagementAct, SIGNAL(triggered()), this, SLOT(slotOpenKeyManagement())); - - /* - * About Menu - */ - aboutAct = new QAction(tr("&About"), this); - aboutAct->setIcon(QIcon(":help.png")); - aboutAct->setToolTip(tr("Show the application's About box")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(slotAbout())); - - /* - * Check Update Menu - */ - checkUpdateAct = new QAction(tr("&Check for Updates"), this); - checkUpdateAct->setIcon(QIcon(":help.png")); - checkUpdateAct->setToolTip(tr("Check for updates")); - connect(checkUpdateAct, SIGNAL(triggered()), this, SLOT(slotCheckUpdate())); - - startWizardAct = new QAction(tr("Open &Wizard"), this); - startWizardAct->setToolTip(tr("Open the wizard")); - connect(startWizardAct, SIGNAL(triggered()), this, SLOT(slotStartWizard())); - - /* Popup-Menu-Action for KeyList - */ - appendSelectedKeysAct = new QAction(tr("Append Selected Key(s) To Text"), this); - appendSelectedKeysAct->setToolTip(tr("Append The Selected Keys To Text in Editor")); - connect(appendSelectedKeysAct, SIGNAL(triggered()), this, SLOT(slotAppendSelectedKeys())); - - copyMailAddressToClipboardAct = new QAction(tr("Copy Email"), this); - copyMailAddressToClipboardAct->setToolTip(tr("Copy selected Email to clipboard")); - connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, SLOT(slotCopyMailAddressToClipboard())); - - // TODO: find central place for shared actions, to avoid code-duplication with keymgmt.cpp - showKeyDetailsAct = new QAction(tr("Show Key Details"), this); - showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); - connect(showKeyDetailsAct, SIGNAL(triggered()), this, SLOT(slotShowKeyDetails())); - - refreshKeysFromKeyserverAct = new QAction(tr("Refresh Key From Key Server"), this); - refreshKeysFromKeyserverAct->setToolTip(tr("Refresh key from default key server")); - connect(refreshKeysFromKeyserverAct, SIGNAL(triggered()), this, SLOT(refreshKeysFromKeyserver())); - - uploadKeyToServerAct = new QAction(tr("Upload Public Key(s) To Server"), this); - uploadKeyToServerAct->setToolTip(tr("Upload The Selected Public Keys To Server")); - connect(uploadKeyToServerAct, SIGNAL(triggered()), this, SLOT(uploadKeyToServer())); - - /* Key-Shortcuts for Tab-Switchung-Action - */ - switchTabUpAct = new QAction(this); - switchTabUpAct->setShortcut(QKeySequence::NextChild); - connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabUp())); - this->addAction(switchTabUpAct); - - switchTabDownAct = new QAction(this); - switchTabDownAct->setShortcut(QKeySequence::PreviousChild); - connect(switchTabDownAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabDown())); - this->addAction(switchTabDownAct); - - cutPgpHeaderAct = new QAction(tr("Remove PGP Header"), this); - connect(cutPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotCutPgpHeader())); - - addPgpHeaderAct = new QAction(tr("Add PGP Header"), this); - connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader())); + /* Main Menu + */ + newTabAct = new QAction(tr("&New"), this); + newTabAct->setIcon(QIcon(":misc_doc.png")); + QList<QKeySequence> newTabActShortcutList; + newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_N)); + newTabActShortcutList.append(QKeySequence(Qt::CTRL + Qt::Key_T)); + newTabAct->setShortcuts(newTabActShortcutList); + newTabAct->setToolTip(tr("Open a new file")); + connect(newTabAct, SIGNAL(triggered()), edit, SLOT(slotNewTab())); + + openAct = new QAction(tr("&Open..."), this); + openAct->setIcon(QIcon(":fileopen.png")); + openAct->setShortcut(QKeySequence::Open); + openAct->setToolTip(tr("Open an existing file")); + connect(openAct, SIGNAL(triggered()), edit, SLOT(slotOpen())); + + browserAct = new QAction(tr("&Browser"), this); + browserAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); + browserAct->setToolTip(tr("Open a file browser")); + connect(browserAct, SIGNAL(triggered()), this, SLOT(slotOpenFileTab())); + + saveAct = new QAction(tr("&Save"), this); + saveAct->setIcon(QIcon(":filesave.png")); + saveAct->setShortcut(QKeySequence::Save); + saveAct->setToolTip(tr("Save the current File")); + connect(saveAct, SIGNAL(triggered()), edit, SLOT(slotSave())); + + saveAsAct = new QAction(tr("Save &As") + "...", this); + saveAsAct->setIcon(QIcon(":filesaveas.png")); + saveAsAct->setShortcut(QKeySequence::SaveAs); + saveAsAct->setToolTip(tr("Save the current File as...")); + connect(saveAsAct, SIGNAL(triggered()), edit, SLOT(slotSaveAs())); + + printAct = new QAction(tr("&Print"), this); + printAct->setIcon(QIcon(":fileprint.png")); + printAct->setShortcut(QKeySequence::Print); + printAct->setToolTip(tr("Print Document")); + connect(printAct, SIGNAL(triggered()), edit, SLOT(slotPrint())); + + closeTabAct = new QAction(tr("&Close"), this); + closeTabAct->setShortcut(QKeySequence::Close); + closeTabAct->setToolTip(tr("Close file")); + connect(closeTabAct, SIGNAL(triggered()), edit, SLOT(slotCloseTab())); + + quitAct = new QAction(tr("&Quit"), this); + quitAct->setShortcut(QKeySequence::Quit); + quitAct->setIcon(QIcon(":exit.png")); + quitAct->setToolTip(tr("Quit Program")); + connect(quitAct, SIGNAL(triggered()), this, SLOT(close())); + + /* Edit Menu + */ + undoAct = new QAction(tr("&Undo"), this); + undoAct->setShortcut(QKeySequence::Undo); + undoAct->setToolTip(tr("Undo Last Edit Action")); + connect(undoAct, SIGNAL(triggered()), edit, SLOT(slotUndo())); + + redoAct = new QAction(tr("&Redo"), this); + redoAct->setShortcut(QKeySequence::Redo); + redoAct->setToolTip(tr("Redo Last Edit Action")); + connect(redoAct, SIGNAL(triggered()), edit, SLOT(slotRedo())); + + zoomInAct = new QAction(tr("Zoom In"), this); + zoomInAct->setShortcut(QKeySequence::ZoomIn); + connect(zoomInAct, SIGNAL(triggered()), edit, SLOT(slotZoomIn())); + + zoomOutAct = new QAction(tr("Zoom Out"), this); + zoomOutAct->setShortcut(QKeySequence::ZoomOut); + connect(zoomOutAct, SIGNAL(triggered()), edit, SLOT(slotZoomOut())); + + pasteAct = new QAction(tr("&Paste"), this); + pasteAct->setIcon(QIcon(":button_paste.png")); + pasteAct->setShortcut(QKeySequence::Paste); + pasteAct->setToolTip(tr("Paste Text From Clipboard")); + connect(pasteAct, SIGNAL(triggered()), edit, SLOT(slotPaste())); + + cutAct = new QAction(tr("Cu&t"), this); + cutAct->setIcon(QIcon(":button_cut.png")); + cutAct->setShortcut(QKeySequence::Cut); + cutAct->setToolTip( + tr("Cut the current selection's contents to the " + "clipboard")); + connect(cutAct, SIGNAL(triggered()), edit, SLOT(slotCut())); + + copyAct = new QAction(tr("&Copy"), this); + copyAct->setIcon(QIcon(":button_copy.png")); + copyAct->setShortcut(QKeySequence::Copy); + copyAct->setToolTip( + tr("Copy the current selection's contents to the " + "clipboard")); + connect(copyAct, SIGNAL(triggered()), edit, SLOT(slotCopy())); + + quoteAct = new QAction(tr("&Quote"), this); + quoteAct->setIcon(QIcon(":quote.png")); + quoteAct->setToolTip(tr("Quote whole text")); + connect(quoteAct, SIGNAL(triggered()), edit, SLOT(slotQuote())); + + selectAllAct = new QAction(tr("Select &All"), this); + selectAllAct->setIcon(QIcon(":edit.png")); + selectAllAct->setShortcut(QKeySequence::SelectAll); + selectAllAct->setToolTip(tr("Select the whole text")); + connect(selectAllAct, SIGNAL(triggered()), edit, SLOT(slotSelectAll())); + + findAct = new QAction(tr("&Find"), this); + findAct->setShortcut(QKeySequence::Find); + findAct->setToolTip(tr("Find a word")); + connect(findAct, SIGNAL(triggered()), this, SLOT(slotFind())); + + cleanDoubleLinebreaksAct = new QAction(tr("Remove &spacing"), this); + cleanDoubleLinebreaksAct->setIcon(QIcon(":format-line-spacing-triple.png")); + // cleanDoubleLineBreaksAct->setShortcut(QKeySequence::SelectAll); + cleanDoubleLinebreaksAct->setToolTip( + tr("Remove double linebreaks, e.g. in pasted text from webmailer")); + connect(cleanDoubleLinebreaksAct, SIGNAL(triggered()), this, + SLOT(slotCleanDoubleLinebreaks())); + + openSettingsAct = new QAction(tr("Se&ttings"), this); + openSettingsAct->setToolTip(tr("Open settings dialog")); + openSettingsAct->setShortcut(QKeySequence::Preferences); + connect(openSettingsAct, SIGNAL(triggered()), this, + SLOT(slotOpenSettingsDialog())); + + /* Crypt Menu + */ + encryptAct = new QAction(tr("&Encrypt"), this); + encryptAct->setIcon(QIcon(":encrypted.png")); + encryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); + encryptAct->setToolTip(tr("Encrypt Message")); + connect(encryptAct, SIGNAL(triggered()), this, SLOT(slotEncrypt())); + + encryptSignAct = new QAction(tr("&Encrypt &Sign"), this); + encryptSignAct->setIcon(QIcon(":encrypted_signed.png")); + encryptSignAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_E)); + encryptSignAct->setToolTip(tr("Encrypt and Sign Message")); + connect(encryptSignAct, SIGNAL(triggered()), this, SLOT(slotEncryptSign())); + + decryptAct = new QAction(tr("&Decrypt"), this); + decryptAct->setIcon(QIcon(":decrypted.png")); + decryptAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); + decryptAct->setToolTip(tr("Decrypt Message")); + connect(decryptAct, SIGNAL(triggered()), this, SLOT(slotDecrypt())); + + decryptVerifyAct = new QAction(tr("&Decrypt &Verify"), this); + decryptVerifyAct->setIcon(QIcon(":decrypted_verified.png")); + decryptVerifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D)); + decryptVerifyAct->setToolTip(tr("Decrypt and Verify Message")); + connect(decryptVerifyAct, SIGNAL(triggered()), this, + SLOT(slotDecryptVerify())); + + /* + * File encryption submenu + */ + fileEncryptAct = new QAction(tr("&Encrypt File"), this); + fileEncryptAct->setToolTip(tr("Encrypt File")); + connect(fileEncryptAct, SIGNAL(triggered()), this, + SLOT(slotFileEncryptCustom())); + + fileDecryptAct = new QAction(tr("&Decrypt File"), this); + fileDecryptAct->setToolTip(tr("Decrypt File")); + connect(fileDecryptAct, SIGNAL(triggered()), this, + SLOT(slotFileDecryptCustom())); + + fileSignAct = new QAction(tr("&Sign File"), this); + fileSignAct->setToolTip(tr("Sign File")); + connect(fileSignAct, SIGNAL(triggered()), this, SLOT(slotFileSignCustom())); + + fileVerifyAct = new QAction(tr("&Verify File"), this); + fileVerifyAct->setToolTip(tr("Verify File")); + connect(fileVerifyAct, SIGNAL(triggered()), this, + SLOT(slotFileVerifyCustom())); + + signAct = new QAction(tr("&Sign"), this); + signAct->setIcon(QIcon(":signature.png")); + signAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I)); + signAct->setToolTip(tr("Sign Message")); + connect(signAct, SIGNAL(triggered()), this, SLOT(slotSign())); + + verifyAct = new QAction(tr("&Verify"), this); + verifyAct->setIcon(QIcon(":verify.png")); + verifyAct->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); + verifyAct->setToolTip(tr("Verify Message")); + connect(verifyAct, SIGNAL(triggered()), this, SLOT(slotVerify())); + + /* Key Menu + */ + + importKeyFromEditAct = new QAction(tr("&Editor"), this); + importKeyFromEditAct->setIcon(QIcon(":txt.png")); + importKeyFromEditAct->setToolTip(tr("Import New Key From Editor")); + connect(importKeyFromEditAct, SIGNAL(triggered()), this, + SLOT(slotImportKeyFromEdit())); + + openKeyManagementAct = new QAction(tr("Manage &Keys"), this); + openKeyManagementAct->setIcon(QIcon(":keymgmt.png")); + openKeyManagementAct->setToolTip(tr("Open Keymanagement")); + connect(openKeyManagementAct, SIGNAL(triggered()), this, + SLOT(slotOpenKeyManagement())); + + /* + * About Menu + */ + aboutAct = new QAction(tr("&About"), this); + aboutAct->setIcon(QIcon(":help.png")); + aboutAct->setToolTip(tr("Show the application's About box")); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(slotAbout())); + + /* + * Check Update Menu + */ + checkUpdateAct = new QAction(tr("&Check for Updates"), this); + checkUpdateAct->setIcon(QIcon(":help.png")); + checkUpdateAct->setToolTip(tr("Check for updates")); + connect(checkUpdateAct, SIGNAL(triggered()), this, SLOT(slotCheckUpdate())); + + startWizardAct = new QAction(tr("Open &Wizard"), this); + startWizardAct->setToolTip(tr("Open the wizard")); + connect(startWizardAct, SIGNAL(triggered()), this, SLOT(slotStartWizard())); + + /* Popup-Menu-Action for KeyList + */ + appendSelectedKeysAct = + new QAction(tr("Append Selected Key(s) To Text"), this); + appendSelectedKeysAct->setToolTip( + tr("Append The Selected Keys To Text in Editor")); + connect(appendSelectedKeysAct, SIGNAL(triggered()), this, + SLOT(slotAppendSelectedKeys())); + + copyMailAddressToClipboardAct = new QAction(tr("Copy Email"), this); + copyMailAddressToClipboardAct->setToolTip( + tr("Copy selected Email to clipboard")); + connect(copyMailAddressToClipboardAct, SIGNAL(triggered()), this, + SLOT(slotCopyMailAddressToClipboard())); + + // TODO: find central place for shared actions, to avoid code-duplication with + // keymgmt.cpp + showKeyDetailsAct = new QAction(tr("Show Key Details"), this); + showKeyDetailsAct->setToolTip(tr("Show Details for this Key")); + connect(showKeyDetailsAct, SIGNAL(triggered()), this, + SLOT(slotShowKeyDetails())); + + refreshKeysFromKeyserverAct = + new QAction(tr("Refresh Key From Key Server"), this); + refreshKeysFromKeyserverAct->setToolTip( + tr("Refresh key from default key server")); + connect(refreshKeysFromKeyserverAct, SIGNAL(triggered()), this, + SLOT(refreshKeysFromKeyserver())); + + uploadKeyToServerAct = + new QAction(tr("Upload Public Key(s) To Server"), this); + uploadKeyToServerAct->setToolTip( + tr("Upload The Selected Public Keys To Server")); + connect(uploadKeyToServerAct, SIGNAL(triggered()), this, + SLOT(uploadKeyToServer())); + + /* Key-Shortcuts for Tab-Switchung-Action + */ + switchTabUpAct = new QAction(this); + switchTabUpAct->setShortcut(QKeySequence::NextChild); + connect(switchTabUpAct, SIGNAL(triggered()), edit, SLOT(slotSwitchTabUp())); + this->addAction(switchTabUpAct); + + switchTabDownAct = new QAction(this); + switchTabDownAct->setShortcut(QKeySequence::PreviousChild); + connect(switchTabDownAct, SIGNAL(triggered()), edit, + SLOT(slotSwitchTabDown())); + this->addAction(switchTabDownAct); + + cutPgpHeaderAct = new QAction(tr("Remove PGP Header"), this); + connect(cutPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotCutPgpHeader())); + + addPgpHeaderAct = new QAction(tr("Add PGP Header"), this); + connect(addPgpHeaderAct, SIGNAL(triggered()), this, SLOT(slotAddPgpHeader())); } void MainWindow::createMenus() { - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newTabAct); - fileMenu->addAction(browserAct); - fileMenu->addAction(openAct); - fileMenu->addSeparator(); - fileMenu->addAction(saveAct); - fileMenu->addAction(saveAsAct); - fileMenu->addSeparator(); - fileMenu->addAction(printAct); - fileMenu->addSeparator(); - fileMenu->addAction(closeTabAct); - fileMenu->addAction(quitAct); - - editMenu = menuBar()->addMenu(tr("&Edit")); - editMenu->addAction(undoAct); - editMenu->addAction(redoAct); - editMenu->addSeparator(); - editMenu->addAction(zoomInAct); - editMenu->addAction(zoomOutAct); - editMenu->addSeparator(); - editMenu->addAction(copyAct); - editMenu->addAction(cutAct); - editMenu->addAction(pasteAct); - editMenu->addAction(selectAllAct); - editMenu->addAction(findAct); - editMenu->addSeparator(); - editMenu->addAction(quoteAct); - editMenu->addAction(cleanDoubleLinebreaksAct); - editMenu->addSeparator(); - editMenu->addAction(openSettingsAct); - - fileEncMenu = new QMenu(tr("&File...")); - fileEncMenu->addAction(fileEncryptAct); - fileEncMenu->addAction(fileDecryptAct); - fileEncMenu->addAction(fileSignAct); - fileEncMenu->addAction(fileVerifyAct); - - cryptMenu = menuBar()->addMenu(tr("&Crypt")); - cryptMenu->addAction(encryptAct); - cryptMenu->addAction(encryptSignAct); - cryptMenu->addAction(decryptAct); - cryptMenu->addAction(decryptVerifyAct); - cryptMenu->addSeparator(); - cryptMenu->addAction(signAct); - cryptMenu->addAction(verifyAct); - cryptMenu->addSeparator(); - cryptMenu->addMenu(fileEncMenu); - - keyMenu = menuBar()->addMenu(tr("&Keys")); - importKeyMenu = keyMenu->addMenu(tr("&Import Key")); - importKeyMenu->setIcon(QIcon(":key_import.png")); - importKeyMenu->addAction(keyMgmt->importKeyFromFileAct); - importKeyMenu->addAction(importKeyFromEditAct); - importKeyMenu->addAction(keyMgmt->importKeyFromClipboardAct); - importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); - importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); - keyMenu->addAction(openKeyManagementAct); - - steganoMenu = menuBar()->addMenu(tr("&Steganography")); - steganoMenu->addAction(cutPgpHeaderAct); - steganoMenu->addAction(addPgpHeaderAct); - - // Hide menu, when steganography menu is disabled in settings - if (!settings.value("advanced/steganography").toBool()) { - this->menuBar()->removeAction(steganoMenu->menuAction()); - } - - viewMenu = menuBar()->addMenu(tr("&View")); - - helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(startWizardAct); - helpMenu->addSeparator(); - helpMenu->addAction(checkUpdateAct); - helpMenu->addAction(aboutAct); - + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(newTabAct); + fileMenu->addAction(browserAct); + fileMenu->addAction(openAct); + fileMenu->addSeparator(); + fileMenu->addAction(saveAct); + fileMenu->addAction(saveAsAct); + fileMenu->addSeparator(); + fileMenu->addAction(printAct); + fileMenu->addSeparator(); + fileMenu->addAction(closeTabAct); + fileMenu->addAction(quitAct); + + editMenu = menuBar()->addMenu(tr("&Edit")); + editMenu->addAction(undoAct); + editMenu->addAction(redoAct); + editMenu->addSeparator(); + editMenu->addAction(zoomInAct); + editMenu->addAction(zoomOutAct); + editMenu->addSeparator(); + editMenu->addAction(copyAct); + editMenu->addAction(cutAct); + editMenu->addAction(pasteAct); + editMenu->addAction(selectAllAct); + editMenu->addAction(findAct); + editMenu->addSeparator(); + editMenu->addAction(quoteAct); + editMenu->addAction(cleanDoubleLinebreaksAct); + editMenu->addSeparator(); + editMenu->addAction(openSettingsAct); + + fileEncMenu = new QMenu(tr("&File...")); + fileEncMenu->addAction(fileEncryptAct); + fileEncMenu->addAction(fileDecryptAct); + fileEncMenu->addAction(fileSignAct); + fileEncMenu->addAction(fileVerifyAct); + + cryptMenu = menuBar()->addMenu(tr("&Crypt")); + cryptMenu->addAction(encryptAct); + cryptMenu->addAction(encryptSignAct); + cryptMenu->addAction(decryptAct); + cryptMenu->addAction(decryptVerifyAct); + cryptMenu->addSeparator(); + cryptMenu->addAction(signAct); + cryptMenu->addAction(verifyAct); + cryptMenu->addSeparator(); + cryptMenu->addMenu(fileEncMenu); + + keyMenu = menuBar()->addMenu(tr("&Keys")); + importKeyMenu = keyMenu->addMenu(tr("&Import Key")); + importKeyMenu->setIcon(QIcon(":key_import.png")); + importKeyMenu->addAction(keyMgmt->importKeyFromFileAct); + importKeyMenu->addAction(importKeyFromEditAct); + importKeyMenu->addAction(keyMgmt->importKeyFromClipboardAct); + importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); + importKeyMenu->addAction(keyMgmt->importKeyFromKeyServerAct); + keyMenu->addAction(openKeyManagementAct); + + steganoMenu = menuBar()->addMenu(tr("&Steganography")); + steganoMenu->addAction(cutPgpHeaderAct); + steganoMenu->addAction(addPgpHeaderAct); + + // Hide menu, when steganography menu is disabled in settings + if (!settings.value("advanced/steganography").toBool()) { + this->menuBar()->removeAction(steganoMenu->menuAction()); + } + + viewMenu = menuBar()->addMenu(tr("&View")); + + helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(startWizardAct); + helpMenu->addSeparator(); + helpMenu->addAction(checkUpdateAct); + helpMenu->addAction(aboutAct); } void MainWindow::createToolBars() { - fileToolBar = addToolBar(tr("File")); - fileToolBar->setObjectName("fileToolBar"); - fileToolBar->addAction(newTabAct); - fileToolBar->addAction(openAct); - fileToolBar->addAction(saveAct); - fileToolBar->hide(); - viewMenu->addAction(fileToolBar->toggleViewAction()); - - cryptToolBar = addToolBar(tr("Crypt")); - cryptToolBar->setObjectName("cryptToolBar"); - cryptToolBar->addAction(encryptAct); - cryptToolBar->addAction(encryptSignAct); - cryptToolBar->addAction(decryptAct); - cryptToolBar->addAction(decryptVerifyAct); - cryptToolBar->addAction(signAct); - cryptToolBar->addAction(verifyAct); - viewMenu->addAction(cryptToolBar->toggleViewAction()); - - keyToolBar = addToolBar(tr("Key")); - keyToolBar->setObjectName("keyToolBar"); - keyToolBar->addAction(openKeyManagementAct); - viewMenu->addAction(keyToolBar->toggleViewAction()); - - editToolBar = addToolBar(tr("Edit")); - editToolBar->setObjectName("editToolBar"); - editToolBar->addAction(copyAct); - editToolBar->addAction(pasteAct); - editToolBar->addAction(selectAllAct); - viewMenu->addAction(editToolBar->toggleViewAction()); - - specialEditToolBar = addToolBar(tr("Special Edit")); - specialEditToolBar->setObjectName("specialEditToolBar"); - specialEditToolBar->addAction(quoteAct); - specialEditToolBar->addAction(cleanDoubleLinebreaksAct); - specialEditToolBar->hide(); - viewMenu->addAction(specialEditToolBar->toggleViewAction()); - - // Add dropdown menu for key import to keytoolbar - importButton = new QToolButton(); - importButton->setMenu(importKeyMenu); - importButton->setPopupMode(QToolButton::InstantPopup); - importButton->setIcon(QIcon(":key_import.png")); - importButton->setToolTip(tr("Import key from...")); - importButton->setText(tr("Import key")); - keyToolBar->addWidget(importButton); - - // Add dropdown menu for file encryption/decryption to crypttoolbar - fileEncButton = new QToolButton(); - connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab())); - fileEncButton->setPopupMode(QToolButton::InstantPopup); - fileEncButton->setIcon(QIcon(":fileencryption.png")); - fileEncButton->setToolTip(tr("Browser to view and operate file")); - fileEncButton->setText(tr("Browser")); - fileToolBar->addWidget(fileEncButton); - + fileToolBar = addToolBar(tr("File")); + fileToolBar->setObjectName("fileToolBar"); + fileToolBar->addAction(newTabAct); + fileToolBar->addAction(openAct); + fileToolBar->addAction(saveAct); + fileToolBar->hide(); + viewMenu->addAction(fileToolBar->toggleViewAction()); + + cryptToolBar = addToolBar(tr("Crypt")); + cryptToolBar->setObjectName("cryptToolBar"); + cryptToolBar->addAction(encryptAct); + cryptToolBar->addAction(encryptSignAct); + cryptToolBar->addAction(decryptAct); + cryptToolBar->addAction(decryptVerifyAct); + cryptToolBar->addAction(signAct); + cryptToolBar->addAction(verifyAct); + viewMenu->addAction(cryptToolBar->toggleViewAction()); + + keyToolBar = addToolBar(tr("Key")); + keyToolBar->setObjectName("keyToolBar"); + keyToolBar->addAction(openKeyManagementAct); + viewMenu->addAction(keyToolBar->toggleViewAction()); + + editToolBar = addToolBar(tr("Edit")); + editToolBar->setObjectName("editToolBar"); + editToolBar->addAction(copyAct); + editToolBar->addAction(pasteAct); + editToolBar->addAction(selectAllAct); + viewMenu->addAction(editToolBar->toggleViewAction()); + + specialEditToolBar = addToolBar(tr("Special Edit")); + specialEditToolBar->setObjectName("specialEditToolBar"); + specialEditToolBar->addAction(quoteAct); + specialEditToolBar->addAction(cleanDoubleLinebreaksAct); + specialEditToolBar->hide(); + viewMenu->addAction(specialEditToolBar->toggleViewAction()); + + // Add dropdown menu for key import to keytoolbar + importButton = new QToolButton(); + importButton->setMenu(importKeyMenu); + importButton->setPopupMode(QToolButton::InstantPopup); + importButton->setIcon(QIcon(":key_import.png")); + importButton->setToolTip(tr("Import key from...")); + importButton->setText(tr("Import key")); + keyToolBar->addWidget(importButton); + + // Add dropdown menu for file encryption/decryption to crypttoolbar + fileEncButton = new QToolButton(); + connect(fileEncButton, SIGNAL(clicked(bool)), this, SLOT(slotOpenFileTab())); + fileEncButton->setPopupMode(QToolButton::InstantPopup); + fileEncButton->setIcon(QIcon(":fileencryption.png")); + fileEncButton->setToolTip(tr("Browser to view and operate file")); + fileEncButton->setText(tr("Browser")); + fileToolBar->addWidget(fileEncButton); } void MainWindow::createStatusBar() { - 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); - statusBarIcon->hide(); - statusBar()->showMessage(tr("Ready"), 2000); - statusBarBox->setLayout(statusBarBoxLayout); + 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); + statusBarIcon->hide(); + statusBar()->showMessage(tr("Ready"), 2000); + statusBarBox->setLayout(statusBarBoxLayout); } void MainWindow::createDockWindows() { - /* KeyList-Dockwindow - */ - keyListDock = new QDockWidget(tr("Key ToolBox"), this); - keyListDock->setObjectName("EncryptDock"); - keyListDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - keyListDock->setMinimumWidth(460); - addDockWidget(Qt::RightDockWidgetArea, keyListDock); - keyListDock->setWidget(mKeyList); - viewMenu->addAction(keyListDock->toggleViewAction()); - - infoBoardDock = new QDockWidget(tr("Information Board"), this); - infoBoardDock->setObjectName("Information Board"); - infoBoardDock->setAllowedAreas(Qt::BottomDockWidgetArea); - addDockWidget(Qt::BottomDockWidgetArea, infoBoardDock); - infoBoardDock->setWidget(infoBoard); - infoBoardDock->widget()->layout()->setContentsMargins(0, 0, 0, 0); - viewMenu->addAction(infoBoardDock->toggleViewAction()); + /* KeyList-Dockwindow + */ + keyListDock = new QDockWidget(tr("Key ToolBox"), this); + keyListDock->setObjectName("EncryptDock"); + keyListDock->setAllowedAreas(Qt::LeftDockWidgetArea | + Qt::RightDockWidgetArea); + keyListDock->setMinimumWidth(460); + addDockWidget(Qt::RightDockWidgetArea, keyListDock); + keyListDock->setWidget(mKeyList); + viewMenu->addAction(keyListDock->toggleViewAction()); + + infoBoardDock = new QDockWidget(tr("Information Board"), this); + infoBoardDock->setObjectName("Information Board"); + infoBoardDock->setAllowedAreas(Qt::BottomDockWidgetArea); + addDockWidget(Qt::BottomDockWidgetArea, infoBoardDock); + infoBoardDock->setWidget(infoBoard); + infoBoardDock->widget()->layout()->setContentsMargins(0, 0, 0, 0); + viewMenu->addAction(infoBoardDock->toggleViewAction()); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsAdvanced.cpp b/src/ui/settings/SettingsAdvanced.cpp index 30414250..90e588e9 100644 --- a/src/ui/settings/SettingsAdvanced.cpp +++ b/src/ui/settings/SettingsAdvanced.cpp @@ -24,44 +24,49 @@ #include "ui/SettingsDialog.h" -AdvancedTab::AdvancedTab(QWidget *parent) -: QWidget(parent), appPath(qApp->applicationDirPath()), -settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - /***************************************** - * Steganography Box - *****************************************/ - auto *steganoBox = new QGroupBox(tr("Show Steganography Options")); - auto *steganoBoxLayout = new QHBoxLayout(); - steganoCheckBox = new QCheckBox(tr("Show Steganographic Options."), this); - steganoBoxLayout->addWidget(steganoCheckBox); - steganoBox->setLayout(steganoBoxLayout); +namespace GpgFrontend::UI { - auto *pubkeyExchangeBox = new QGroupBox(tr("Pubkey Exchange")); - auto *pubkeyExchangeBoxLayout = new QHBoxLayout(); - autoPubkeyExchangeCheckBox = new QCheckBox(tr("Auto Pubkey Exchange"), this); - pubkeyExchangeBoxLayout->addWidget(autoPubkeyExchangeCheckBox); - pubkeyExchangeBox->setLayout(pubkeyExchangeBoxLayout); +AdvancedTab::AdvancedTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + /***************************************** + * Steganography Box + *****************************************/ + auto* steganoBox = new QGroupBox(tr("Show Steganography Options")); + auto* steganoBoxLayout = new QHBoxLayout(); + steganoCheckBox = new QCheckBox(tr("Show Steganographic Options."), this); + steganoBoxLayout->addWidget(steganoCheckBox); + steganoBox->setLayout(steganoBoxLayout); - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(steganoBox); - mainLayout->addWidget(pubkeyExchangeBox); - setSettings(); - mainLayout->addStretch(1); - setLayout(mainLayout); + auto* pubkeyExchangeBox = new QGroupBox(tr("Pubkey Exchange")); + auto* pubkeyExchangeBoxLayout = new QHBoxLayout(); + autoPubkeyExchangeCheckBox = new QCheckBox(tr("Auto Pubkey Exchange"), this); + pubkeyExchangeBoxLayout->addWidget(autoPubkeyExchangeCheckBox); + pubkeyExchangeBox->setLayout(pubkeyExchangeBoxLayout); + + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(steganoBox); + mainLayout->addWidget(pubkeyExchangeBox); + setSettings(); + mainLayout->addStretch(1); + setLayout(mainLayout); } void AdvancedTab::setSettings() { - if (settings.value("advanced/steganography").toBool()) { - steganoCheckBox->setCheckState(Qt::Checked); - } - if (settings.value("advanced/autoPubkeyExchange").toBool()) { - autoPubkeyExchangeCheckBox->setCheckState(Qt::Checked); - } + if (settings.value("advanced/steganography").toBool()) { + steganoCheckBox->setCheckState(Qt::Checked); + } + if (settings.value("advanced/autoPubkeyExchange").toBool()) { + autoPubkeyExchangeCheckBox->setCheckState(Qt::Checked); + } } void AdvancedTab::applySettings() { - settings.setValue("advanced/steganography", steganoCheckBox->isChecked()); - settings.setValue("advanced/autoPubkeyExchange", autoPubkeyExchangeCheckBox->isChecked()); + settings.setValue("advanced/steganography", steganoCheckBox->isChecked()); + settings.setValue("advanced/autoPubkeyExchange", + autoPubkeyExchangeCheckBox->isChecked()); } +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsAppearance.cpp b/src/ui/settings/SettingsAppearance.cpp index aeb7ed70..79bfe5d8 100644 --- a/src/ui/settings/SettingsAppearance.cpp +++ b/src/ui/settings/SettingsAppearance.cpp @@ -24,82 +24,85 @@ #include "ui/SettingsDialog.h" -AppearanceTab::AppearanceTab(QWidget *parent) -: QWidget(parent), appPath(qApp->applicationDirPath()), -settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - /***************************************** - * Icon-Size-Box - *****************************************/ - auto *iconSizeBox = new QGroupBox(tr("Iconsize")); - iconSizeGroup = new QButtonGroup(); - iconSizeSmall = new QRadioButton(tr("small")); - iconSizeMedium = new QRadioButton(tr("medium")); - iconSizeLarge = new QRadioButton(tr("large")); - - iconSizeGroup->addButton(iconSizeSmall, 1); - iconSizeGroup->addButton(iconSizeMedium, 2); - iconSizeGroup->addButton(iconSizeLarge, 3); - - auto *iconSizeBoxLayout = new QHBoxLayout(); - iconSizeBoxLayout->addWidget(iconSizeSmall); - iconSizeBoxLayout->addWidget(iconSizeMedium); - iconSizeBoxLayout->addWidget(iconSizeLarge); - - iconSizeBox->setLayout(iconSizeBoxLayout); - - /***************************************** - * Icon-Style-Box - *****************************************/ - auto *iconStyleBox = new QGroupBox(tr("Iconstyle")); - iconStyleGroup = new QButtonGroup(); - iconTextButton = new QRadioButton(tr("just text")); - iconIconsButton = new QRadioButton(tr("just icons")); - iconAllButton = new QRadioButton(tr("text and icons")); - - iconStyleGroup->addButton(iconTextButton, 1); - iconStyleGroup->addButton(iconIconsButton, 2); - iconStyleGroup->addButton(iconAllButton, 3); - - auto *iconStyleBoxLayout = new QHBoxLayout(); - iconStyleBoxLayout->addWidget(iconTextButton); - iconStyleBoxLayout->addWidget(iconIconsButton); - iconStyleBoxLayout->addWidget(iconAllButton); - - iconStyleBox->setLayout(iconStyleBoxLayout); - - /***************************************** - * Window-Size-Box - *****************************************/ - auto *windowSizeBox = new QGroupBox(tr("Windowstate")); - auto *windowSizeBoxLayout = new QHBoxLayout(); - windowSizeCheckBox = - new QCheckBox(tr("Save window size and position on exit."), this); - windowSizeBoxLayout->addWidget(windowSizeCheckBox); - windowSizeBox->setLayout(windowSizeBoxLayout); - - /***************************************** - * Info-Board-Font-Size-Box - *****************************************/ - - auto *infoBoardBox = new QGroupBox(tr("Information Board")); - auto *infoBoardLayout = new QHBoxLayout(); - infoBoardFontSizeSpin = new QSpinBox(); - infoBoardFontSizeSpin->setRange(9, 18); - infoBoardFontSizeSpin->setValue(10); - infoBoardFontSizeSpin->setSingleStep(1); - infoBoardLayout->addWidget(new QLabel(tr(" Front Size"))); - infoBoardLayout->addWidget(infoBoardFontSizeSpin); - 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); +namespace GpgFrontend::UI { + +AppearanceTab::AppearanceTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + /***************************************** + * Icon-Size-Box + *****************************************/ + auto* iconSizeBox = new QGroupBox(tr("Iconsize")); + iconSizeGroup = new QButtonGroup(); + iconSizeSmall = new QRadioButton(tr("small")); + iconSizeMedium = new QRadioButton(tr("medium")); + iconSizeLarge = new QRadioButton(tr("large")); + + iconSizeGroup->addButton(iconSizeSmall, 1); + iconSizeGroup->addButton(iconSizeMedium, 2); + iconSizeGroup->addButton(iconSizeLarge, 3); + + auto* iconSizeBoxLayout = new QHBoxLayout(); + iconSizeBoxLayout->addWidget(iconSizeSmall); + iconSizeBoxLayout->addWidget(iconSizeMedium); + iconSizeBoxLayout->addWidget(iconSizeLarge); + + iconSizeBox->setLayout(iconSizeBoxLayout); + + /***************************************** + * Icon-Style-Box + *****************************************/ + auto* iconStyleBox = new QGroupBox(tr("Iconstyle")); + iconStyleGroup = new QButtonGroup(); + iconTextButton = new QRadioButton(tr("just text")); + iconIconsButton = new QRadioButton(tr("just icons")); + iconAllButton = new QRadioButton(tr("text and icons")); + + iconStyleGroup->addButton(iconTextButton, 1); + iconStyleGroup->addButton(iconIconsButton, 2); + iconStyleGroup->addButton(iconAllButton, 3); + + auto* iconStyleBoxLayout = new QHBoxLayout(); + iconStyleBoxLayout->addWidget(iconTextButton); + iconStyleBoxLayout->addWidget(iconIconsButton); + iconStyleBoxLayout->addWidget(iconAllButton); + + iconStyleBox->setLayout(iconStyleBoxLayout); + + /***************************************** + * Window-Size-Box + *****************************************/ + auto* windowSizeBox = new QGroupBox(tr("Windowstate")); + auto* windowSizeBoxLayout = new QHBoxLayout(); + windowSizeCheckBox = + new QCheckBox(tr("Save window size and position on exit."), this); + windowSizeBoxLayout->addWidget(windowSizeCheckBox); + windowSizeBox->setLayout(windowSizeBoxLayout); + + /***************************************** + * Info-Board-Font-Size-Box + *****************************************/ + + auto* infoBoardBox = new QGroupBox(tr("Information Board")); + auto* infoBoardLayout = new QHBoxLayout(); + infoBoardFontSizeSpin = new QSpinBox(); + infoBoardFontSizeSpin->setRange(9, 18); + infoBoardFontSizeSpin->setValue(10); + infoBoardFontSizeSpin->setSingleStep(1); + infoBoardLayout->addWidget(new QLabel(tr(" Front Size"))); + infoBoardLayout->addWidget(infoBoardFontSizeSpin); + 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); } /********************************** @@ -108,47 +111,47 @@ settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", * appropriately **********************************/ void AppearanceTab::setSettings() { - - // Iconsize - QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); - switch (iconSize.height()) { - case 12: - iconSizeSmall->setChecked(true); - break; - case 24: - iconSizeMedium->setChecked(true); - break; - case 32: - iconSizeLarge->setChecked(true); - break; - } - // Iconstyle - Qt::ToolButtonStyle iconStyle = static_cast<Qt::ToolButtonStyle>( - settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) - .toUInt()); - switch (iconStyle) { - case Qt::ToolButtonTextOnly: - iconTextButton->setChecked(true); - break; - case Qt::ToolButtonIconOnly: - iconIconsButton->setChecked(true); - break; - case Qt::ToolButtonTextUnderIcon: - iconAllButton->setChecked(true); - break; - default: - break; - } - - // Window Save and Position - if (settings.value("window/windowSave").toBool()) - windowSizeCheckBox->setCheckState(Qt::Checked); - - // infoBoardFontSize - auto infoBoardFontSize = settings.value("informationBoard/fontSize", 10).toInt(); - if (infoBoardFontSize < 9 || infoBoardFontSize > 18) - infoBoardFontSize = 10; - infoBoardFontSizeSpin->setValue(infoBoardFontSize); + // Iconsize + QSize iconSize = settings.value("toolbar/iconsize", QSize(24, 24)).toSize(); + switch (iconSize.height()) { + case 12: + iconSizeSmall->setChecked(true); + break; + case 24: + iconSizeMedium->setChecked(true); + break; + case 32: + iconSizeLarge->setChecked(true); + break; + } + // Iconstyle + Qt::ToolButtonStyle iconStyle = static_cast<Qt::ToolButtonStyle>( + settings.value("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon) + .toUInt()); + switch (iconStyle) { + case Qt::ToolButtonTextOnly: + iconTextButton->setChecked(true); + break; + case Qt::ToolButtonIconOnly: + iconIconsButton->setChecked(true); + break; + case Qt::ToolButtonTextUnderIcon: + iconAllButton->setChecked(true); + break; + default: + break; + } + + // Window Save and Position + if (settings.value("window/windowSave").toBool()) + windowSizeCheckBox->setCheckState(Qt::Checked); + + // infoBoardFontSize + auto infoBoardFontSize = + settings.value("informationBoard/fontSize", 10).toInt(); + if (infoBoardFontSize < 9 || infoBoardFontSize > 18) + infoBoardFontSize = 10; + infoBoardFontSizeSpin->setValue(infoBoardFontSize); } /*********************************** @@ -156,32 +159,34 @@ void AppearanceTab::setSettings() { * write them to settings-file *************************************/ void AppearanceTab::applySettings() { - switch (iconSizeGroup->checkedId()) { - case 1: - settings.setValue("toolbar/iconsize", QSize(12, 12)); - break; - case 2: - settings.setValue("toolbar/iconsize", QSize(24, 24)); - break; - case 3: - settings.setValue("toolbar/iconsize", QSize(32, 32)); - break; - } - - switch (iconStyleGroup->checkedId()) { - case 1: - settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextOnly); - break; - case 2: - settings.setValue("toolbar/iconstyle", Qt::ToolButtonIconOnly); - break; - case 3: - settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon); - break; - } - - settings.setValue("window/windowSave", windowSizeCheckBox->isChecked()); - - settings.setValue("informationBoard/fontSize", infoBoardFontSizeSpin->value()); + switch (iconSizeGroup->checkedId()) { + case 1: + settings.setValue("toolbar/iconsize", QSize(12, 12)); + break; + case 2: + settings.setValue("toolbar/iconsize", QSize(24, 24)); + break; + case 3: + settings.setValue("toolbar/iconsize", QSize(32, 32)); + break; + } + + switch (iconStyleGroup->checkedId()) { + case 1: + settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextOnly); + break; + case 2: + settings.setValue("toolbar/iconstyle", Qt::ToolButtonIconOnly); + break; + case 3: + settings.setValue("toolbar/iconstyle", Qt::ToolButtonTextUnderIcon); + break; + } + + settings.setValue("window/windowSave", windowSizeCheckBox->isChecked()); + + settings.setValue("informationBoard/fontSize", + infoBoardFontSizeSpin->value()); } +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsDialog.cpp b/src/ui/settings/SettingsDialog.cpp index 33595b25..9a423dfd 100644 --- a/src/ui/settings/SettingsDialog.cpp +++ b/src/ui/settings/SettingsDialog.cpp @@ -25,181 +25,186 @@ #include "ui/SettingsDialog.h" #include "ui/WaitingDialog.h" -SettingsDialog::SettingsDialog(GpgFrontend::GpgContext *ctx, QWidget *parent) - : QDialog(parent) { - mCtx = ctx; - tabWidget = new QTabWidget; - generalTab = new GeneralTab(mCtx); - appearanceTab = new AppearanceTab; - sendMailTab = new SendMailTab; - keyserverTab = new KeyserverTab; - advancedTab = new AdvancedTab; - gpgPathsTab = new GpgPathsTab; - - tabWidget->addTab(generalTab, tr("General")); - tabWidget->addTab(appearanceTab, tr("Appearance")); - tabWidget->addTab(sendMailTab, tr("Send Mail")); - tabWidget->addTab(keyserverTab, tr("Key Server")); - // tabWidget->addTab(gpgPathsTab, tr("Gpg paths")); - tabWidget->addTab(advancedTab, tr("Advanced")); - - buttonBox = - new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(tabWidget); - mainLayout->stretch(0); - mainLayout->addWidget(buttonBox); - mainLayout->stretch(0); - setLayout(mainLayout); - - setWindowTitle(tr("Settings")); - - // slots for handling the restartneeded member - this->slotSetRestartNeeded(false); - connect(generalTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - connect(appearanceTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - connect(sendMailTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - connect(keyserverTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - connect(advancedTab, SIGNAL(signalRestartNeeded(bool)), this, - SLOT(slotSetRestartNeeded(bool))); - - connect(this, SIGNAL(signalRestartNeeded(bool)), parent, - SLOT(slotSetRestartNeeded(bool))); - - this->resize(480, 640); - this->show(); +namespace GpgFrontend::UI { + +SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent) { + tabWidget = new QTabWidget; + generalTab = new GeneralTab(); + appearanceTab = new AppearanceTab; + sendMailTab = new SendMailTab; + keyserverTab = new KeyserverTab; + advancedTab = new AdvancedTab; + gpgPathsTab = new GpgPathsTab; + + tabWidget->addTab(generalTab, tr("General")); + tabWidget->addTab(appearanceTab, tr("Appearance")); + tabWidget->addTab(sendMailTab, tr("Send Mail")); + tabWidget->addTab(keyserverTab, tr("Key Server")); + // tabWidget->addTab(gpgPathsTab, tr("Gpg paths")); + tabWidget->addTab(advancedTab, tr("Advanced")); + + buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotAccept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(tabWidget); + mainLayout->stretch(0); + mainLayout->addWidget(buttonBox); + mainLayout->stretch(0); + setLayout(mainLayout); + + setWindowTitle(tr("Settings")); + + // slots for handling the restartneeded member + this->slotSetRestartNeeded(false); + connect(generalTab, SIGNAL(signalRestartNeeded(bool)), this, + SLOT(slotSetRestartNeeded(bool))); + connect(appearanceTab, SIGNAL(signalRestartNeeded(bool)), this, + SLOT(slotSetRestartNeeded(bool))); + connect(sendMailTab, SIGNAL(signalRestartNeeded(bool)), this, + SLOT(slotSetRestartNeeded(bool))); + connect(keyserverTab, SIGNAL(signalRestartNeeded(bool)), this, + SLOT(slotSetRestartNeeded(bool))); + connect(advancedTab, SIGNAL(signalRestartNeeded(bool)), this, + SLOT(slotSetRestartNeeded(bool))); + + connect(this, SIGNAL(signalRestartNeeded(bool)), parent, + SLOT(slotSetRestartNeeded(bool))); + + this->resize(480, 640); + this->show(); } -bool SettingsDialog::getRestartNeeded() const { return this->restartNeeded; } +bool SettingsDialog::getRestartNeeded() const { + return this->restartNeeded; +} void SettingsDialog::slotSetRestartNeeded(bool needed) { - this->restartNeeded = needed; + this->restartNeeded = needed; } void SettingsDialog::slotAccept() { - generalTab->applySettings(); - sendMailTab->applySettings(); - appearanceTab->applySettings(); - keyserverTab->applySettings(); - advancedTab->applySettings(); - gpgPathsTab->applySettings(); - if (getRestartNeeded()) { - emit signalRestartNeeded(true); - } - close(); + generalTab->applySettings(); + sendMailTab->applySettings(); + appearanceTab->applySettings(); + keyserverTab->applySettings(); + advancedTab->applySettings(); + gpgPathsTab->applySettings(); + if (getRestartNeeded()) { + emit signalRestartNeeded(true); + } + close(); } // http://www.informit.com/articles/article.aspx?p=1405555&seqNum=3 // http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application QHash<QString, QString> SettingsDialog::listLanguages() { - QHash<QString, QString> languages; + QHash<QString, QString> languages; - languages.insert("", tr("System Default")); + languages.insert("", tr("System Default")); - QString appPath = qApp->applicationDirPath(); - QDir qmDir = QDir(RESOURCE_DIR(appPath) + "/ts/"); - QStringList fileNames = qmDir.entryList(QStringList("gpgfrontend_*.qm")); + QString appPath = qApp->applicationDirPath(); + QDir qmDir = QDir(RESOURCE_DIR(appPath) + "/ts/"); + QStringList fileNames = qmDir.entryList(QStringList("gpgfrontend_*.qm")); - for (int i = 0; i < fileNames.size(); ++i) { - QString locale = fileNames[i]; - locale.truncate(locale.lastIndexOf('.')); - locale.remove(0, locale.indexOf('_') + 1); + for (int i = 0; i < fileNames.size(); ++i) { + QString locale = fileNames[i]; + locale.truncate(locale.lastIndexOf('.')); + locale.remove(0, locale.indexOf('_') + 1); - // this works in qt 4.8 - QLocale qloc(locale); + // this works in qt 4.8 + QLocale qloc(locale); #if QT_VERSION < 0x040800 - QString language = - QLocale::languageToString(qloc.language()) + " (" + locale + - ")"; //+ " (" + QLocale::languageToString(qloc.language()) + ")"; + QString language = + QLocale::languageToString(qloc.language()) + " (" + locale + + ")"; //+ " (" + QLocale::languageToString(qloc.language()) + ")"; #else - QString language = qloc.nativeLanguageName() + " (" + locale + ")"; + QString language = qloc.nativeLanguageName() + " (" + locale + ")"; #endif - languages.insert(locale, language); - } - return languages; + languages.insert(locale, language); + } + return languages; } -GpgPathsTab::GpgPathsTab(QWidget *parent) - : QWidget(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - setSettings(); - - /***************************************** - * Keydb Box - *****************************************/ - auto *keydbBox = new QGroupBox(tr("Relative path to keydb")); - auto *keydbBoxLayout = new QGridLayout(); - - // Label containing the current keydbpath relative to default keydb path - keydbLabel = new QLabel(accKeydbPath, this); - - auto *keydbButton = new QPushButton("Change keydb path", this); - connect(keydbButton, SIGNAL(clicked()), this, SLOT(chooseKeydbDir())); - auto *keydbDefaultButton = new QPushButton("Set keydb to default path", this); - connect(keydbDefaultButton, SIGNAL(clicked()), this, - SLOT(setKeydbPathToDefault())); - - keydbBox->setLayout(keydbBoxLayout); - keydbBoxLayout->addWidget(new QLabel(tr("Current keydb path: ")), 1, 1); - keydbBoxLayout->addWidget(keydbLabel, 1, 2); - keydbBoxLayout->addWidget(keydbButton, 1, 3); - keydbBoxLayout->addWidget(keydbDefaultButton, 2, 3); - keydbBoxLayout->addWidget( - new QLabel(tr("<b>NOTE: </b> Gpg4usb will restart automatically if you " - "change the keydb path!")), - 3, 1, 1, 3); - - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(keydbBox); - mainLayout->addStretch(1); - setLayout(mainLayout); +GpgPathsTab::GpgPathsTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + setSettings(); + + /***************************************** + * Keydb Box + *****************************************/ + auto* keydbBox = new QGroupBox(tr("Relative path to keydb")); + auto* keydbBoxLayout = new QGridLayout(); + + // Label containing the current keydbpath relative to default keydb path + keydbLabel = new QLabel(accKeydbPath, this); + + auto* keydbButton = new QPushButton("Change keydb path", this); + connect(keydbButton, SIGNAL(clicked()), this, SLOT(chooseKeydbDir())); + auto* keydbDefaultButton = new QPushButton("Set keydb to default path", this); + connect(keydbDefaultButton, SIGNAL(clicked()), this, + SLOT(setKeydbPathToDefault())); + + keydbBox->setLayout(keydbBoxLayout); + keydbBoxLayout->addWidget(new QLabel(tr("Current keydb path: ")), 1, 1); + keydbBoxLayout->addWidget(keydbLabel, 1, 2); + keydbBoxLayout->addWidget(keydbButton, 1, 3); + keydbBoxLayout->addWidget(keydbDefaultButton, 2, 3); + keydbBoxLayout->addWidget( + new QLabel(tr("<b>NOTE: </b> Gpg4usb will restart automatically if you " + "change the keydb path!")), + 3, 1, 1, 3); + + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(keydbBox); + mainLayout->addStretch(1); + setLayout(mainLayout); } -QString GpgPathsTab::getRelativePath(const QString &dir1, const QString &dir2) { - QDir dir(dir1); - QString s; +QString GpgPathsTab::getRelativePath(const QString& dir1, const QString& dir2) { + QDir dir(dir1); + QString s; - s = dir.relativeFilePath(dir2); - qDebug() << "relative path: " << s; - if (s.isEmpty()) { - s = "."; - } - return s; + s = dir.relativeFilePath(dir2); + qDebug() << "relative path: " << s; + if (s.isEmpty()) { + s = "."; + } + return s; } void GpgPathsTab::setKeydbPathToDefault() { - accKeydbPath = "."; - keydbLabel->setText("."); + accKeydbPath = "."; + keydbLabel->setText("."); } QString GpgPathsTab::chooseKeydbDir() { - QString dir = QFileDialog::getExistingDirectory( - this, tr("Choose keydb directory"), accKeydbPath, - QFileDialog::ShowDirsOnly); + QString dir = QFileDialog::getExistingDirectory( + this, tr("Choose keydb directory"), accKeydbPath, + QFileDialog::ShowDirsOnly); - accKeydbPath = getRelativePath(defKeydbPath, dir); - keydbLabel->setText(accKeydbPath); - return ""; + accKeydbPath = getRelativePath(defKeydbPath, dir); + keydbLabel->setText(accKeydbPath); + return ""; } void GpgPathsTab::setSettings() { - defKeydbPath = qApp->applicationDirPath() + "/keydb"; + defKeydbPath = qApp->applicationDirPath() + "/keydb"; - accKeydbPath = settings.value("gpgpaths/keydbpath").toString(); - if (accKeydbPath.isEmpty()) { - accKeydbPath = "."; - } + accKeydbPath = settings.value("gpgpaths/keydbpath").toString(); + if (accKeydbPath.isEmpty()) { + accKeydbPath = "."; + } } void GpgPathsTab::applySettings() { - settings.setValue("gpgpaths/keydbpath", accKeydbPath); + settings.setValue("gpgpaths/keydbpath", accKeydbPath); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsGeneral.cpp b/src/ui/settings/SettingsGeneral.cpp index 666556a0..dab0bb5d 100644 --- a/src/ui/settings/SettingsGeneral.cpp +++ b/src/ui/settings/SettingsGeneral.cpp @@ -23,121 +23,131 @@ */ #include "ui/SettingsDialog.h" -#include "ui/WaitingDialog.h" -#include "server/ComUtils.h" #include "rapidjson/prettywriter.h" -GeneralTab::GeneralTab(GpgFrontend::GpgContext *ctx, QWidget *parent) - : QWidget(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - mCtx = ctx; - - /***************************************** - * GpgFrontend Server - *****************************************/ - auto *serverBox = new QGroupBox(tr("GpgFrontend Server")); - auto *serverBoxLayout = new QVBoxLayout(); - serverSelectBox = new QComboBox(); - serverBoxLayout->addWidget(serverSelectBox); - serverBoxLayout->addWidget(new QLabel( - tr("Server that provides short key and key exchange services"))); - - serverBox->setLayout(serverBoxLayout); - - /***************************************** - * Save-Checked-Keys-Box - *****************************************/ - auto *saveCheckedKeysBox = new QGroupBox(tr("Save Checked Keys")); - auto *saveCheckedKeysBoxLayout = new QHBoxLayout(); - saveCheckedKeysCheckBox = new QCheckBox( - tr("Save checked private keys on exit and restore them on next start."), - this); - saveCheckedKeysBoxLayout->addWidget(saveCheckedKeysCheckBox); - saveCheckedKeysBox->setLayout(saveCheckedKeysBoxLayout); - - /***************************************** - * Key-Impport-Confirmation Box - *****************************************/ - auto *importConfirmationBox = - new QGroupBox(tr("Confirm drag'n'drop key import")); - auto *importConfirmationBoxLayout = new QHBoxLayout(); - importConfirmationCheckBox = new QCheckBox( - tr("Import files dropped on the keylist without confirmation."), this); - importConfirmationBoxLayout->addWidget(importConfirmationCheckBox); - importConfirmationBox->setLayout(importConfirmationBoxLayout); - - /***************************************** - * Language Select Box - *****************************************/ - auto *langBox = new QGroupBox(tr("Language")); - auto *langBoxLayout = new QVBoxLayout(); - langSelectBox = new QComboBox; - lang = SettingsDialog::listLanguages(); - - for (const auto &l: lang) { langSelectBox->addItem(l); } - - langBoxLayout->addWidget(langSelectBox); - langBoxLayout->addWidget( - new QLabel(tr("<b>NOTE: </b> GpgFrontend will restart automatically if " - "you change the language!"))); - langBox->setLayout(langBoxLayout); - connect(langSelectBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotLanguageChanged())); - - /***************************************** - * Own Key Select Box - *****************************************/ - auto *ownKeyBox = new QGroupBox(tr("Own key")); - auto *ownKeyBoxLayout = new QVBoxLayout(); - auto *ownKeyServiceTokenLayout = new QHBoxLayout(); - ownKeySelectBox = new QComboBox; - getServiceTokenButton = new QPushButton(tr("Get Service Token")); - serviceTokenLabel = new QLabel(tr("No Service Token Found")); - serviceTokenLabel->setAlignment(Qt::AlignCenter); - - ownKeyBox->setLayout(ownKeyBoxLayout); - mKeyList = new KeyList(mCtx); - - // Fill the keyid hashmap - keyIds.insert("", tr("<none>")); - - for (const auto &keyid : *mKeyList->getAllPrivateKeys()) { - auto key = mCtx->getKeyRefById(keyid); - if (!key.good) continue; - keyIds.insert(key.id, key.uids.first().uid); - } - for (const auto &k : keyIds.keys()) { - ownKeySelectBox->addItem(keyIds.find(k).value()); - keyIdsList.append(k); - } - connect(ownKeySelectBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(slotOwnKeyIdChanged())); - connect(getServiceTokenButton, SIGNAL(clicked(bool)), this, - SLOT(slotGetServiceToken())); - - ownKeyBoxLayout->addWidget(new QLabel( - tr("Key pair for synchronization and identity authentication"))); - ownKeyBoxLayout->addWidget(ownKeySelectBox); - ownKeyBoxLayout->addLayout(ownKeyServiceTokenLayout); - ownKeyServiceTokenLayout->addWidget(getServiceTokenButton); - ownKeyServiceTokenLayout->addWidget(serviceTokenLabel); - ownKeyServiceTokenLayout->stretch(0); - - /***************************************** - * Mainlayout - *****************************************/ - auto *mainLayout = new QVBoxLayout; - mainLayout->addWidget(serverBox); - mainLayout->addWidget(saveCheckedKeysBox); - mainLayout->addWidget(importConfirmationBox); - mainLayout->addWidget(langBox); - mainLayout->addWidget(ownKeyBox); - - setSettings(); - mainLayout->addStretch(1); - setLayout(mainLayout); +#ifdef SERVER_SUPPORT +#include "server/ComUtils.h" +#endif +#include "gpg/function/GpgKeyGetter.h" +#include "ui/WaitingDialog.h" + +namespace GpgFrontend::UI { + +GeneralTab::GeneralTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + /***************************************** + * GpgFrontend Server + *****************************************/ + auto* serverBox = new QGroupBox(tr("GpgFrontend Server")); + auto* serverBoxLayout = new QVBoxLayout(); + serverSelectBox = new QComboBox(); + serverBoxLayout->addWidget(serverSelectBox); + serverBoxLayout->addWidget(new QLabel( + tr("Server that provides short key and key exchange services"))); + + serverBox->setLayout(serverBoxLayout); + + /***************************************** + * Save-Checked-Keys-Box + *****************************************/ + auto* saveCheckedKeysBox = new QGroupBox(tr("Save Checked Keys")); + auto* saveCheckedKeysBoxLayout = new QHBoxLayout(); + saveCheckedKeysCheckBox = new QCheckBox( + tr("Save checked private keys on exit and restore them on next start."), + this); + saveCheckedKeysBoxLayout->addWidget(saveCheckedKeysCheckBox); + saveCheckedKeysBox->setLayout(saveCheckedKeysBoxLayout); + + /***************************************** + * Key-Impport-Confirmation Box + *****************************************/ + auto* importConfirmationBox = + new QGroupBox(tr("Confirm drag'n'drop key import")); + auto* importConfirmationBoxLayout = new QHBoxLayout(); + importConfirmationCheckBox = new QCheckBox( + tr("Import files dropped on the keylist without confirmation."), this); + importConfirmationBoxLayout->addWidget(importConfirmationCheckBox); + importConfirmationBox->setLayout(importConfirmationBoxLayout); + + /***************************************** + * Language Select Box + *****************************************/ + auto* langBox = new QGroupBox(tr("Language")); + auto* langBoxLayout = new QVBoxLayout(); + langSelectBox = new QComboBox; + lang = SettingsDialog::listLanguages(); + + for (const auto& l : lang) { + langSelectBox->addItem(l); + } + + langBoxLayout->addWidget(langSelectBox); + langBoxLayout->addWidget( + new QLabel(tr("<b>NOTE: </b> GpgFrontend will restart automatically if " + "you change the language!"))); + langBox->setLayout(langBoxLayout); + connect(langSelectBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(slotLanguageChanged())); + + /***************************************** + * Own Key Select Box + *****************************************/ + auto* ownKeyBox = new QGroupBox(tr("Own key")); + auto* ownKeyBoxLayout = new QVBoxLayout(); + auto* ownKeyServiceTokenLayout = new QHBoxLayout(); + ownKeySelectBox = new QComboBox; + getServiceTokenButton = new QPushButton(tr("Get Service Token")); + serviceTokenLabel = new QLabel(tr("No Service Token Found")); + serviceTokenLabel->setAlignment(Qt::AlignCenter); + + ownKeyBox->setLayout(ownKeyBoxLayout); + mKeyList = new KeyList(); + + // Fill the keyid hashmap + keyIds.insert({"", "<none>"}); + + auto private_keys = mKeyList->getAllPrivateKeys(); + + for (const auto& keyid : *private_keys) { + auto key = GpgKeyGetter::GetInstance().GetKey(keyid); + if (!key.good()) + continue; + keyIds.insert({key.id(), key.uids()->front().uid()}); + } + for (const auto& k : keyIds) { + ownKeySelectBox->addItem(QString::fromStdString(k.second)); + keyIdsList.push_back(k.first); + } + connect(ownKeySelectBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(slotOwnKeyIdChanged())); + connect(getServiceTokenButton, SIGNAL(clicked(bool)), this, + SLOT(slotGetServiceToken())); + + ownKeyBoxLayout->addWidget(new QLabel( + tr("Key pair for synchronization and identity authentication"))); + ownKeyBoxLayout->addWidget(ownKeySelectBox); + ownKeyBoxLayout->addLayout(ownKeyServiceTokenLayout); + ownKeyServiceTokenLayout->addWidget(getServiceTokenButton); + ownKeyServiceTokenLayout->addWidget(serviceTokenLabel); + ownKeyServiceTokenLayout->stretch(0); + + /***************************************** + * Mainlayout + *****************************************/ + auto* mainLayout = new QVBoxLayout; + mainLayout->addWidget(serverBox); + mainLayout->addWidget(saveCheckedKeysBox); + mainLayout->addWidget(importConfirmationBox); + mainLayout->addWidget(langBox); + mainLayout->addWidget(ownKeyBox); + + setSettings(); + mainLayout->addStretch(1); + setLayout(mainLayout); } /********************************** @@ -146,55 +156,58 @@ GeneralTab::GeneralTab(GpgFrontend::GpgContext *ctx, QWidget *parent) * appropriately **********************************/ void GeneralTab::setSettings() { - // Keysaving - if (settings.value("keys/saveKeyChecked").toBool()) { - saveCheckedKeysCheckBox->setCheckState(Qt::Checked); - } - - auto serverList = settings.value("general/gpgfrontendServerList").toStringList(); - if (serverList.empty()) { - serverList.append("service.gpgfrontend.pub"); - serverList.append("localhost"); - } - for (const auto &s : serverList) - serverSelectBox->addItem(s); - - qDebug() << "Current Gpgfrontend Server" << settings.value("general/currentGpgfrontendServer").toString(); - serverSelectBox->setCurrentText(settings.value("general/currentGpgfrontendServer", - "service.gpgfrontend.pub").toString()); - - connect(serverSelectBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged), - this, [&](const QString ¤t) -> void { - settings.setValue("general/currentGpgfrontendServer", current); - }); - - // Language setting - QString langKey = settings.value("int/lang").toString(); - QString langValue = lang.value(langKey); - if (langKey != "") { - langSelectBox->setCurrentIndex(langSelectBox->findText(langValue)); - } - - QString own_key_id = settings.value("general/ownKeyId").toString(); - qDebug() << "OwnKeyId" << own_key_id; - if (own_key_id.isEmpty()) { - ownKeySelectBox->setCurrentText("<none>"); - } else { - const auto text = keyIds.find(own_key_id).value(); - qDebug() << "OwnKey" << own_key_id << text; - ownKeySelectBox->setCurrentText(text); - } - - serviceToken = settings.value("general/serviceToken").toString(); - qDebug() << "Load Service Token" << serviceToken; - if (!serviceToken.isEmpty()) { - serviceTokenLabel->setText(serviceToken); - } - - // Get own key information from keydb/gpg.conf (if contained) - if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { - importConfirmationCheckBox->setCheckState(Qt::Checked); - } + // Keysaving + if (settings.value("keys/saveKeyChecked").toBool()) { + saveCheckedKeysCheckBox->setCheckState(Qt::Checked); + } + + auto serverList = + settings.value("general/gpgfrontendServerList").toStringList(); + if (serverList.empty()) { + serverList.append("service.gpgfrontend.pub"); + serverList.append("localhost"); + } + for (const auto& s : serverList) + serverSelectBox->addItem(s); + + qDebug() << "Current Gpgfrontend Server" + << settings.value("general/currentGpgfrontendServer").toString(); + serverSelectBox->setCurrentText( + settings + .value("general/currentGpgfrontendServer", "service.gpgfrontend.pub") + .toString()); + + connect(serverSelectBox, + QOverload<const QString&>::of(&QComboBox::currentTextChanged), this, + [&](const QString& current) -> void { + settings.setValue("general/currentGpgfrontendServer", current); + }); + + // Language setting + QString langKey = settings.value("int/lang").toString(); + QString langValue = lang.value(langKey); + if (langKey != "") { + langSelectBox->setCurrentIndex(langSelectBox->findText(langValue)); + } + + auto own_key_id = settings.value("general/ownKeyId").toString().toStdString(); + if (own_key_id.empty()) { + ownKeySelectBox->setCurrentText("<none>"); + } else { + const auto uid = keyIds.find(own_key_id)->second; + ownKeySelectBox->setCurrentText(QString::fromStdString(uid)); + } + + serviceToken = + settings.value("general/serviceToken").toString().toStdString(); + if (!serviceToken.empty()) { + serviceTokenLabel->setText(QString::fromStdString(serviceToken)); + } + + // Get own key information from keydb/gpg.conf (if contained) + if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { + importConfirmationCheckBox->setCheckState(Qt::Checked); + } } /*********************************** @@ -202,157 +215,164 @@ void GeneralTab::setSettings() { * write them to settings-file *************************************/ void GeneralTab::applySettings() { - settings.setValue("keys/saveKeyChecked", - saveCheckedKeysCheckBox->isChecked()); + settings.setValue("keys/saveKeyChecked", + saveCheckedKeysCheckBox->isChecked()); - qDebug() << "serverSelectBox currentText" << serverSelectBox->currentText(); - settings.setValue("general/currentGpgfrontendServer", - serverSelectBox->currentText()); + qDebug() << "serverSelectBox currentText" << serverSelectBox->currentText(); + settings.setValue("general/currentGpgfrontendServer", + serverSelectBox->currentText()); - auto *serverList = new QStringList(); - for (int i = 0; i < serverSelectBox->count(); i++) - serverList->append(serverSelectBox->itemText(i)); - settings.setValue("general/gpgfrontendServerList", - *serverList); - delete serverList; + auto* serverList = new QStringList(); + for (int i = 0; i < serverSelectBox->count(); i++) + serverList->append(serverSelectBox->itemText(i)); + settings.setValue("general/gpgfrontendServerList", *serverList); + delete serverList; - settings.setValue("int/lang", lang.key(langSelectBox->currentText())); + settings.setValue("int/lang", lang.key(langSelectBox->currentText())); - settings.setValue("general/ownKeyId", - keyIdsList[ownKeySelectBox->currentIndex()]); + settings.setValue( + "general/ownKeyId", + QString::fromStdString(keyIdsList[ownKeySelectBox->currentIndex()])); - settings.setValue("general/serviceToken", - serviceToken); + settings.setValue("general/serviceToken", + QString::fromStdString(serviceToken)); - settings.setValue("general/confirmImportKeys", - importConfirmationCheckBox->isChecked()); + settings.setValue("general/confirmImportKeys", + importConfirmationCheckBox->isChecked()); } -void GeneralTab::slotLanguageChanged() { emit signalRestartNeeded(true); } +void GeneralTab::slotLanguageChanged() { + emit signalRestartNeeded(true); +} void GeneralTab::slotOwnKeyIdChanged() { - // Set ownKeyId to currently selected - this->serviceTokenLabel->setText(tr("No Service Token Found")); - serviceToken.clear(); + // Set ownKeyId to currently selected + this->serviceTokenLabel->setText(tr("No Service Token Found")); + serviceToken.clear(); } +#ifdef SERVER_SUPPORT void GeneralTab::slotGetServiceToken() { + auto utils = new ComUtils(this); - auto utils = new ComUtils(this); + QUrl reqUrl(utils->getUrl(ComUtils::GetServiceToken)); + QNetworkRequest request(reqUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl reqUrl(utils->getUrl(ComUtils::GetServiceToken)); - QNetworkRequest request(reqUrl); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + const auto keyId = keyIdsList[ownKeySelectBox->currentIndex()]; + qDebug() << "KeyId" << keyIdsList[ownKeySelectBox->currentIndex()]; - const auto keyId = keyIdsList[ownKeySelectBox->currentIndex()]; + if (keyId.isEmpty()) { + QMessageBox::critical( + this, tr("Invalid Operation"), + tr("Own Key can not be None while getting service token.")); + return; + } - qDebug() << "KeyId" << keyIdsList[ownKeySelectBox->currentIndex()]; + QStringList selectedKeyIds(keyIdsList[ownKeySelectBox->currentIndex()]); - if (keyId.isEmpty()) { - QMessageBox::critical(this, tr("Invalid Operation"), - tr("Own Key can not be None while getting service token.")); - return; - } + QByteArray keyDataBuf; + mCtx->exportKeys(&selectedKeyIds, &keyDataBuf); - QStringList selectedKeyIds(keyIdsList[ownKeySelectBox->currentIndex()]); + GpgKey key = mCtx->getKeyRefById(keyId); - QByteArray keyDataBuf; - mCtx->exportKeys(&selectedKeyIds, &keyDataBuf); + if (!key.good) { + QMessageBox::critical(this, tr("Error"), tr("Key Not Exists")); + return; + } - GpgKey key = mCtx->getKeyRefById(keyId); + qDebug() << "keyDataBuf" << keyDataBuf; - if (!key.good) { - QMessageBox::critical(this, tr("Error"), - tr("Key Not Exists")); - return; - } + /** + * { + * "publicKey" : ... + * "sha": ... + * "signedFpr": ... + * "version": ... + * } + */ - qDebug() << "keyDataBuf" << keyDataBuf; + QCryptographicHash shaGen(QCryptographicHash::Sha256); + shaGen.addData(keyDataBuf); - /** - * { - * "publicKey" : ... - * "sha": ... - * "signedFpr": ... - * "version": ... - * } - */ + auto shaStr = shaGen.result().toHex(); - QCryptographicHash shaGen(QCryptographicHash::Sha256); - shaGen.addData(keyDataBuf); + auto signFprStr = ComUtils::getSignStringBase64(mCtx, key.fpr, key); - auto shaStr = shaGen.result().toHex(); + rapidjson::Value pubkey, ver, sha, signFpr; - auto signFprStr = ComUtils::getSignStringBase64(mCtx, key.fpr, key); + rapidjson::Document doc; + doc.SetObject(); - rapidjson::Value pubkey, ver, sha, signFpr; + pubkey.SetString(keyDataBuf.constData(), keyDataBuf.count()); - rapidjson::Document doc; - doc.SetObject(); + auto version = qApp->applicationVersion(); + ver.SetString(version.toUtf8().constData(), + qApp->applicationVersion().count()); - pubkey.SetString(keyDataBuf.constData(), keyDataBuf.count()); + sha.SetString(shaStr.constData(), shaStr.count()); + signFpr.SetString(signFprStr.constData(), signFprStr.count()); - auto version = qApp->applicationVersion(); - ver.SetString(version.toUtf8().constData(), qApp->applicationVersion().count()); + rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); - sha.SetString(shaStr.constData(), shaStr.count()); - signFpr.SetString(signFprStr.constData(), signFprStr.count()); + doc.AddMember("publicKey", pubkey, allocator); + doc.AddMember("sha", sha, allocator); + doc.AddMember("signedFpr", signFpr, allocator); + doc.AddMember("version", ver, allocator); - rapidjson::Document::AllocatorType &allocator = doc.GetAllocator(); + rapidjson::StringBuffer sb; + rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); + doc.Accept(writer); - doc.AddMember("publicKey", pubkey, allocator); - doc.AddMember("sha", sha, allocator); - doc.AddMember("signedFpr", signFpr, allocator); - doc.AddMember("version", ver, allocator); + QByteArray postData(sb.GetString()); - rapidjson::StringBuffer sb; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); - doc.Accept(writer); + QNetworkReply* reply = utils->getNetworkManager().post(request, postData); - QByteArray postData(sb.GetString()); + // Show Waiting Dailog + auto dialog = new WaitingDialog("Getting Token From Server", this); + dialog->show(); - QNetworkReply *reply = utils->getNetworkManager().post(request, postData); + while (reply->isRunning()) { + QApplication::processEvents(); + } - // Show Waiting Dailog - auto dialog = new WaitingDialog("Getting Token From Server", this); - dialog->show(); + dialog->close(); - while (reply->isRunning()) { - QApplication::processEvents(); - } + if (utils->checkServerReply(reply->readAll().constData())) { + /** + * { + * "serviceToken" : ... + * "fpr": ... + * } + */ - dialog->close(); - - if (utils->checkServerReply(reply->readAll().constData())) { - - /** - * { - * "serviceToken" : ... - * "fpr": ... - * } - */ - - if (!utils->checkDataValueStr("serviceToken") || !utils->checkDataValueStr("fpr")) { - QMessageBox::critical(this, tr("Error"), - tr("The communication content with the server does not meet the requirements")); - return; - } - - QString serviceTokenTemp = utils->getDataValueStr("serviceToken"); - QString fpr = utils->getDataValueStr("fpr"); - auto key = mCtx->getKeyRefByFpr(fpr); - if (utils->checkServiceTokenFormat(serviceTokenTemp) && key.good) { - serviceToken = serviceTokenTemp; - qDebug() << "Get Service Token" << serviceToken; - // Auto update settings - settings.setValue("general/serviceToken", serviceToken); - serviceTokenLabel->setText(serviceToken); - QMessageBox::information(this, tr("Notice"), - tr("Succeed in getting service token")); - } else { - QMessageBox::critical(this, tr("Error"), tr("There is a problem with the communication with the server")); - } + if (!utils->checkDataValueStr("serviceToken") || + !utils->checkDataValueStr("fpr")) { + QMessageBox::critical(this, tr("Error"), + tr("The communication content with the server does " + "not meet the requirements")); + return; } + QString serviceTokenTemp = utils->getDataValueStr("serviceToken"); + QString fpr = utils->getDataValueStr("fpr"); + auto key = mCtx->getKeyRefByFpr(fpr); + if (utils->checkServiceTokenFormat(serviceTokenTemp) && key.good) { + serviceToken = serviceTokenTemp; + qDebug() << "Get Service Token" << serviceToken; + // Auto update settings + settings.setValue("general/serviceToken", serviceToken); + serviceTokenLabel->setText(serviceToken); + QMessageBox::information(this, tr("Notice"), + tr("Succeed in getting service token")); + } else { + QMessageBox::critical( + this, tr("Error"), + tr("There is a problem with the communication with the server")); + } + } } +#endif + +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsKeyServer.cpp b/src/ui/settings/SettingsKeyServer.cpp index b49eb9e0..e11115c1 100644 --- a/src/ui/settings/SettingsKeyServer.cpp +++ b/src/ui/settings/SettingsKeyServer.cpp @@ -24,66 +24,69 @@ #include "ui/SettingsDialog.h" -KeyserverTab::KeyserverTab(QWidget *parent) - : QWidget(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - - auto generalGroupBox = new QGroupBox(tr("General")); - auto generalLayout = new QVBoxLayout(); - - keyServerTable = new QTableWidget(); - keyServerTable->setColumnCount(3); - keyServerTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - keyServerTable->horizontalHeader()->setStretchLastSection(false); - keyServerTable->verticalHeader()->hide(); - keyServerTable->setShowGrid(false); - keyServerTable->sortByColumn(0, Qt::AscendingOrder); - keyServerTable->setSelectionBehavior(QAbstractItemView::SelectRows); - keyServerTable->setSelectionMode(QAbstractItemView::SingleSelection); - - // tableitems not editable - keyServerTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - // no focus (rectangle around tableitems) - // may be it should focus on whole row - keyServerTable->setFocusPolicy(Qt::NoFocus); - keyServerTable->setAlternatingRowColors(true); - - QStringList labels; - labels << tr("No.") << tr("Address") << tr("Available"); - keyServerTable->setHorizontalHeaderLabels(labels); - - auto *mainLayout = new QVBoxLayout(this); - auto *label = new QLabel(tr("Default Key Server for Import:")); - - comboBox = new QComboBox; - comboBox->setEditable(false); - comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - - auto *addKeyServerBox = new QWidget(this); - auto *addKeyServerLayout = new QHBoxLayout(addKeyServerBox); - auto *http = new QLabel("URL: "); - newKeyServerEdit = new QLineEdit(this); - auto *newKeyServerButton = new QPushButton(tr("Add"), this); - connect(newKeyServerButton, SIGNAL(clicked()), this, SLOT(addKeyServer())); - addKeyServerLayout->addWidget(http); - addKeyServerLayout->addWidget(newKeyServerEdit); - addKeyServerLayout->addWidget(newKeyServerButton); - - generalLayout->addWidget(label); - generalLayout->addWidget(comboBox); - generalLayout->addWidget(keyServerTable); - generalLayout->addWidget(addKeyServerBox); - generalLayout->addStretch(0); - - generalGroupBox->setLayout(generalLayout); - mainLayout->addWidget(generalGroupBox); - mainLayout->addStretch(0); - - setLayout(mainLayout); - // Read keylist from ini-file and fill it into combobox - setSettings(); - refreshTable(); +namespace GpgFrontend::UI { + +KeyserverTab::KeyserverTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + auto generalGroupBox = new QGroupBox(tr("General")); + auto generalLayout = new QVBoxLayout(); + + keyServerTable = new QTableWidget(); + keyServerTable->setColumnCount(3); + keyServerTable->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + keyServerTable->horizontalHeader()->setStretchLastSection(false); + keyServerTable->verticalHeader()->hide(); + keyServerTable->setShowGrid(false); + keyServerTable->sortByColumn(0, Qt::AscendingOrder); + keyServerTable->setSelectionBehavior(QAbstractItemView::SelectRows); + keyServerTable->setSelectionMode(QAbstractItemView::SingleSelection); + + // tableitems not editable + keyServerTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + // no focus (rectangle around tableitems) + // may be it should focus on whole row + keyServerTable->setFocusPolicy(Qt::NoFocus); + keyServerTable->setAlternatingRowColors(true); + + QStringList labels; + labels << tr("No.") << tr("Address") << tr("Available"); + keyServerTable->setHorizontalHeaderLabels(labels); + + auto* mainLayout = new QVBoxLayout(this); + auto* label = new QLabel(tr("Default Key Server for Import:")); + + comboBox = new QComboBox; + comboBox->setEditable(false); + comboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + auto* addKeyServerBox = new QWidget(this); + auto* addKeyServerLayout = new QHBoxLayout(addKeyServerBox); + auto* http = new QLabel("URL: "); + newKeyServerEdit = new QLineEdit(this); + auto* newKeyServerButton = new QPushButton(tr("Add"), this); + connect(newKeyServerButton, SIGNAL(clicked()), this, SLOT(addKeyServer())); + addKeyServerLayout->addWidget(http); + addKeyServerLayout->addWidget(newKeyServerEdit); + addKeyServerLayout->addWidget(newKeyServerButton); + + generalLayout->addWidget(label); + generalLayout->addWidget(comboBox); + generalLayout->addWidget(keyServerTable); + generalLayout->addWidget(addKeyServerBox); + generalLayout->addStretch(0); + + generalGroupBox->setLayout(generalLayout); + mainLayout->addWidget(generalGroupBox); + mainLayout->addStretch(0); + + setLayout(mainLayout); + // Read keylist from ini-file and fill it into combobox + setSettings(); + refreshTable(); } /********************************** @@ -92,29 +95,27 @@ KeyserverTab::KeyserverTab(QWidget *parent) * appropriately **********************************/ void KeyserverTab::setSettings() { + keyServerStrList = settings.value("keyserver/keyServerList").toStringList(); - keyServerStrList = settings.value("keyserver/keyServerList").toStringList(); - - for (const auto &keyServer : keyServerStrList) { - comboBox->addItem(keyServer); - qDebug() << "KeyserverTab Get ListItemText" << keyServer; - } - - comboBox->setCurrentText( - settings.value("keyserver/defaultKeyServer").toString()); + for (const auto& keyServer : keyServerStrList) { + comboBox->addItem(keyServer); + qDebug() << "KeyserverTab Get ListItemText" << keyServer; + } + comboBox->setCurrentText( + settings.value("keyserver/defaultKeyServer").toString()); } void KeyserverTab::addKeyServer() { - QString targetUrl; - if (newKeyServerEdit->text().startsWith("http://") || - newKeyServerEdit->text().startsWith("https://")) - targetUrl = newKeyServerEdit->text(); - else - targetUrl = "http://" + newKeyServerEdit->text(); - keyServerStrList.append(targetUrl); - comboBox->addItem(targetUrl); - refreshTable(); + QString targetUrl; + if (newKeyServerEdit->text().startsWith("http://") || + newKeyServerEdit->text().startsWith("https://")) + targetUrl = newKeyServerEdit->text(); + else + targetUrl = "http://" + newKeyServerEdit->text(); + keyServerStrList.append(targetUrl); + comboBox->addItem(targetUrl); + refreshTable(); } /*********************************** @@ -122,27 +123,28 @@ void KeyserverTab::addKeyServer() { * write them to settings-file *************************************/ void KeyserverTab::applySettings() { - settings.setValue("keyserver/keyServerList", keyServerStrList); - settings.setValue("keyserver/defaultKeyServer", comboBox->currentText()); + settings.setValue("keyserver/keyServerList", keyServerStrList); + settings.setValue("keyserver/defaultKeyServer", comboBox->currentText()); } void KeyserverTab::refreshTable() { - - qDebug() << "Start Refreshing Key Server Table"; - - keyServerTable->setRowCount(keyServerStrList.size()); - - int index = 0; - for (const auto &server : keyServerStrList) { - auto *tmp1 = new QTableWidgetItem(QString::number(index)); - tmp1->setTextAlignment(Qt::AlignCenter); - keyServerTable->setItem(index, 0, tmp1); - auto *tmp2 = new QTableWidgetItem(server); - tmp2->setTextAlignment(Qt::AlignCenter); - keyServerTable->setItem(index, 1, tmp2); - auto *tmp3 = new QTableWidgetItem(""); - tmp3->setTextAlignment(Qt::AlignCenter); - keyServerTable->setItem(index, 2, tmp3); - index++; - } + qDebug() << "Start Refreshing Key Server Table"; + + keyServerTable->setRowCount(keyServerStrList.size()); + + int index = 0; + for (const auto& server : keyServerStrList) { + auto* tmp1 = new QTableWidgetItem(QString::number(index)); + tmp1->setTextAlignment(Qt::AlignCenter); + keyServerTable->setItem(index, 0, tmp1); + auto* tmp2 = new QTableWidgetItem(server); + tmp2->setTextAlignment(Qt::AlignCenter); + keyServerTable->setItem(index, 1, tmp2); + auto* tmp3 = new QTableWidgetItem(""); + tmp3->setTextAlignment(Qt::AlignCenter); + keyServerTable->setItem(index, 2, tmp3); + index++; + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/settings/SettingsSendMail.cpp b/src/ui/settings/SettingsSendMail.cpp index a5e3274f..8db3cd0a 100644 --- a/src/ui/settings/SettingsSendMail.cpp +++ b/src/ui/settings/SettingsSendMail.cpp @@ -22,75 +22,81 @@ * */ -#include "ui/SettingsDialog.h" +#ifdef SMTP_SUPPORT #include "smtp/SmtpMime" +#endif +#include "ui/SettingsDialog.h" -SendMailTab::SendMailTab(QWidget *parent) - : QWidget(parent), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - - enableCheckBox = new QCheckBox(tr("Enable")); - enableCheckBox->setTristate(false); - - smtpAddress = new QLineEdit(); - username = new QLineEdit(); - password = new QLineEdit(); - password->setEchoMode(QLineEdit::Password); - - portSpin = new QSpinBox(); - portSpin->setMinimum(1); - portSpin->setMaximum(65535); - connectionTypeComboBox = new QComboBox(); - connectionTypeComboBox->addItem("None"); - connectionTypeComboBox->addItem("SSL"); - connectionTypeComboBox->addItem("TLS"); - connectionTypeComboBox->addItem("STARTTLS"); - - defaultSender = new QLineEdit();; - checkConnectionButton = new QPushButton(tr("Check Connection")); - - auto generalGroupBox = new QGroupBox(tr("General")); - auto connectGroupBox = new QGroupBox(tr("Connection")); - auto preferenceGroupBox = new QGroupBox(tr("Preference")); - - auto generalLayout = new QGridLayout(); - generalLayout->addWidget(enableCheckBox); - - auto connectLayout = new QGridLayout(); - connectLayout->addWidget(new QLabel(tr("SMTP Address")), 1, 0); - connectLayout->addWidget(smtpAddress, 1, 1, 1, 4); - connectLayout->addWidget(new QLabel(tr("Username")), 2, 0); - connectLayout->addWidget(username, 2, 1, 1, 4); - connectLayout->addWidget(new QLabel(tr("Password")), 3, 0); - connectLayout->addWidget(password, 3, 1, 1, 4); - connectLayout->addWidget(new QLabel(tr("Port")), 4, 0); - connectLayout->addWidget(portSpin, 4, 1, 1, 1); - connectLayout->addWidget(new QLabel(tr("Connection Security")), 5, 0); - connectLayout->addWidget(connectionTypeComboBox, 5, 1, 1, 1); - connectLayout->addWidget(checkConnectionButton, 6, 0); - - auto preferenceLayout = new QGridLayout(); - - preferenceLayout->addWidget(new QLabel(tr("Default Sender")), 0, 0); - preferenceLayout->addWidget(defaultSender, 0, 1, 1, 4); - - generalGroupBox->setLayout(generalLayout); - connectGroupBox->setLayout(connectLayout); - preferenceGroupBox->setLayout(preferenceLayout); - - auto vBox = new QVBoxLayout(); - vBox->addWidget(generalGroupBox); - vBox->addWidget(connectGroupBox); - vBox->addWidget(preferenceGroupBox); - vBox->addStretch(0); - - connect(enableCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotCheckBoxSetEnableDisable(int))); - connect(checkConnectionButton, SIGNAL(clicked(bool)), this, SLOT(slotCheckConnection())); - - - this->setLayout(vBox); - setSettings(); +namespace GpgFrontend::UI { + +SendMailTab::SendMailTab(QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + enableCheckBox = new QCheckBox(tr("Enable")); + enableCheckBox->setTristate(false); + + smtpAddress = new QLineEdit(); + username = new QLineEdit(); + password = new QLineEdit(); + password->setEchoMode(QLineEdit::Password); + + portSpin = new QSpinBox(); + portSpin->setMinimum(1); + portSpin->setMaximum(65535); + connectionTypeComboBox = new QComboBox(); + connectionTypeComboBox->addItem("None"); + connectionTypeComboBox->addItem("SSL"); + connectionTypeComboBox->addItem("TLS"); + connectionTypeComboBox->addItem("STARTTLS"); + + defaultSender = new QLineEdit(); + ; + checkConnectionButton = new QPushButton(tr("Check Connection")); + + auto generalGroupBox = new QGroupBox(tr("General")); + auto connectGroupBox = new QGroupBox(tr("Connection")); + auto preferenceGroupBox = new QGroupBox(tr("Preference")); + + auto generalLayout = new QGridLayout(); + generalLayout->addWidget(enableCheckBox); + + auto connectLayout = new QGridLayout(); + connectLayout->addWidget(new QLabel(tr("SMTP Address")), 1, 0); + connectLayout->addWidget(smtpAddress, 1, 1, 1, 4); + connectLayout->addWidget(new QLabel(tr("Username")), 2, 0); + connectLayout->addWidget(username, 2, 1, 1, 4); + connectLayout->addWidget(new QLabel(tr("Password")), 3, 0); + connectLayout->addWidget(password, 3, 1, 1, 4); + connectLayout->addWidget(new QLabel(tr("Port")), 4, 0); + connectLayout->addWidget(portSpin, 4, 1, 1, 1); + connectLayout->addWidget(new QLabel(tr("Connection Security")), 5, 0); + connectLayout->addWidget(connectionTypeComboBox, 5, 1, 1, 1); + connectLayout->addWidget(checkConnectionButton, 6, 0); + + auto preferenceLayout = new QGridLayout(); + + preferenceLayout->addWidget(new QLabel(tr("Default Sender")), 0, 0); + preferenceLayout->addWidget(defaultSender, 0, 1, 1, 4); + + generalGroupBox->setLayout(generalLayout); + connectGroupBox->setLayout(connectLayout); + preferenceGroupBox->setLayout(preferenceLayout); + + auto vBox = new QVBoxLayout(); + vBox->addWidget(generalGroupBox); + vBox->addWidget(connectGroupBox); + vBox->addWidget(preferenceGroupBox); + vBox->addStretch(0); + + connect(enableCheckBox, SIGNAL(stateChanged(int)), this, + SLOT(slotCheckBoxSetEnableDisable(int))); + connect(checkConnectionButton, SIGNAL(clicked(bool)), this, + SLOT(slotCheckConnection())); + + this->setLayout(vBox); + setSettings(); } /********************************** @@ -99,27 +105,28 @@ SendMailTab::SendMailTab(QWidget *parent) * appropriately **********************************/ void SendMailTab::setSettings() { - - if (settings.value("sendMail/enable", false).toBool()) - enableCheckBox->setCheckState(Qt::Checked); - else { - enableCheckBox->setCheckState(Qt::Unchecked); - smtpAddress->setDisabled(true); - username->setDisabled(true); - password->setDisabled(true); - portSpin->setDisabled(true); - connectionTypeComboBox->setDisabled(true); - defaultSender->setDisabled(true); - checkConnectionButton->setDisabled(true); - } - - smtpAddress->setText(settings.value("sendMail/smtpAddress", QString()).toString()); - username->setText(settings.value("sendMail/username", QString()).toString()); - password->setText(settings.value("sendMail/password", QString()).toString()); - portSpin->setValue(settings.value("sendMail/port", 25).toInt()); - connectionTypeComboBox->setCurrentText(settings.value("sendMail/connectionType", "None").toString()); - defaultSender->setText(settings.value("sendMail/defaultSender", QString()).toString()); - + if (settings.value("sendMail/enable", false).toBool()) + enableCheckBox->setCheckState(Qt::Checked); + else { + enableCheckBox->setCheckState(Qt::Unchecked); + smtpAddress->setDisabled(true); + username->setDisabled(true); + password->setDisabled(true); + portSpin->setDisabled(true); + connectionTypeComboBox->setDisabled(true); + defaultSender->setDisabled(true); + checkConnectionButton->setDisabled(true); + } + + smtpAddress->setText( + settings.value("sendMail/smtpAddress", QString()).toString()); + username->setText(settings.value("sendMail/username", QString()).toString()); + password->setText(settings.value("sendMail/password", QString()).toString()); + portSpin->setValue(settings.value("sendMail/port", 25).toInt()); + connectionTypeComboBox->setCurrentText( + settings.value("sendMail/connectionType", "None").toString()); + defaultSender->setText( + settings.value("sendMail/defaultSender", QString()).toString()); } /*********************************** @@ -127,67 +134,69 @@ void SendMailTab::setSettings() { * write them to settings-file *************************************/ void SendMailTab::applySettings() { - - settings.setValue("sendMail/smtpAddress", smtpAddress->text()); - settings.setValue("sendMail/username", username->text()); - settings.setValue("sendMail/password", password->text()); - settings.setValue("sendMail/port", portSpin->value()); - settings.setValue("sendMail/connectionType", connectionTypeComboBox->currentText()); - settings.setValue("sendMail/defaultSender", defaultSender->text()); - - settings.setValue("sendMail/enable", enableCheckBox->isChecked()); + settings.setValue("sendMail/smtpAddress", smtpAddress->text()); + settings.setValue("sendMail/username", username->text()); + settings.setValue("sendMail/password", password->text()); + settings.setValue("sendMail/port", portSpin->value()); + settings.setValue("sendMail/connectionType", + connectionTypeComboBox->currentText()); + settings.setValue("sendMail/defaultSender", defaultSender->text()); + + settings.setValue("sendMail/enable", enableCheckBox->isChecked()); } +#ifdef SMTP_SUPPORT void SendMailTab::slotCheckConnection() { - - SmtpClient::ConnectionType connectionType; - const auto selectedConnType = connectionTypeComboBox->currentText(); - if (selectedConnType == "SSL") { - connectionType = SmtpClient::ConnectionType::SslConnection; - } else if (selectedConnType == "TLS" || selectedConnType == "STARTTLS") { - connectionType = SmtpClient::ConnectionType::TlsConnection; - } else { - connectionType = SmtpClient::ConnectionType::TcpConnection; - } - - SmtpClient smtp(smtpAddress->text(), portSpin->value(), connectionType); - - smtp.setUser(username->text()); - smtp.setPassword(password->text()); - - bool if_success = true; - - if (!smtp.connectToHost()) { - QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server")); - if_success = false; - } - if (if_success && !smtp.login()) { - QMessageBox::critical(this, tr("Fail"), tr("Fail to Login")); - if_success = false; - } - - if (if_success) - QMessageBox::information(this, tr("Success"), tr("Succeed in connecting and login")); - + SmtpClient::ConnectionType connectionType; + const auto selectedConnType = connectionTypeComboBox->currentText(); + if (selectedConnType == "SSL") { + connectionType = SmtpClient::ConnectionType::SslConnection; + } else if (selectedConnType == "TLS" || selectedConnType == "STARTTLS") { + connectionType = SmtpClient::ConnectionType::TlsConnection; + } else { + connectionType = SmtpClient::ConnectionType::TcpConnection; + } + + SmtpClient smtp(smtpAddress->text(), portSpin->value(), connectionType); + + smtp.setUser(username->text()); + smtp.setPassword(password->text()); + + bool if_success = true; + + if (!smtp.connectToHost()) { + QMessageBox::critical(this, tr("Fail"), tr("Fail to Connect SMTP Server")); + if_success = false; + } + if (if_success && !smtp.login()) { + QMessageBox::critical(this, tr("Fail"), tr("Fail to Login")); + if_success = false; + } + + if (if_success) + QMessageBox::information(this, tr("Success"), + tr("Succeed in connecting and login")); } +#endif void SendMailTab::slotCheckBoxSetEnableDisable(int state) { - if (state == Qt::Checked) { - smtpAddress->setEnabled(true); - username->setEnabled(true); - password->setEnabled(true); - portSpin->setEnabled(true); - connectionTypeComboBox->setEnabled(true); - defaultSender->setEnabled(true); - checkConnectionButton->setEnabled(true); - } else { - smtpAddress->setDisabled(true); - username->setDisabled(true); - password->setDisabled(true); - portSpin->setDisabled(true); - connectionTypeComboBox->setDisabled(true); - defaultSender->setDisabled(true); - checkConnectionButton->setDisabled(true); - } + if (state == Qt::Checked) { + smtpAddress->setEnabled(true); + username->setEnabled(true); + password->setEnabled(true); + portSpin->setEnabled(true); + connectionTypeComboBox->setEnabled(true); + defaultSender->setEnabled(true); + checkConnectionButton->setEnabled(true); + } else { + smtpAddress->setDisabled(true); + username->setDisabled(true); + password->setDisabled(true); + portSpin->setDisabled(true); + connectionTypeComboBox->setDisabled(true); + defaultSender->setDisabled(true); + checkConnectionButton->setDisabled(true); + } } +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.cpp b/src/ui/widgets/EditorPage.cpp index beb37b96..76db1b0b 100644 --- a/src/ui/widgets/EditorPage.cpp +++ b/src/ui/widgets/EditorPage.cpp @@ -26,82 +26,86 @@ #include <utility> -EditorPage::EditorPage(QString filePath, QWidget *parent) : QWidget(parent), - fullFilePath(std::move(filePath)) { - // Set the Textedit properties - textPage = new QTextEdit(); - textPage->setAcceptRichText(false); - - // Set the layout style - mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(textPage); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); - - setAttribute(Qt::WA_DeleteOnClose); - textPage->setFocus(); - - // Front in same width - this->setFont({"Courier"}); +namespace GpgFrontend::UI { + +EditorPage::EditorPage(QString filePath, QWidget* parent) + : QWidget(parent), fullFilePath(std::move(filePath)) { + // Set the Textedit properties + textPage = new QTextEdit(); + textPage->setAcceptRichText(false); + + // Set the layout style + mainLayout = new QVBoxLayout(); + mainLayout->setSpacing(0); + mainLayout->addWidget(textPage); + mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); + + setAttribute(Qt::WA_DeleteOnClose); + textPage->setFocus(); + + // Front in same width + this->setFont({"Courier"}); } -const QString &EditorPage::getFilePath() const { - return fullFilePath; +const QString& EditorPage::getFilePath() const { + return fullFilePath; } -QTextEdit *EditorPage::getTextPage() { - return textPage; +QTextEdit* EditorPage::getTextPage() { + return textPage; } -void EditorPage::setFilePath(const QString &filePath) { - fullFilePath = filePath; +void EditorPage::setFilePath(const QString& filePath) { + fullFilePath = filePath; } -void EditorPage::showNotificationWidget(QWidget *widget, const char *className) { - widget->setProperty(className, true); - mainLayout->addWidget(widget); +void EditorPage::showNotificationWidget(QWidget* widget, + const char* className) { + widget->setProperty(className, true); + mainLayout->addWidget(widget); } -void EditorPage::closeNoteByClass(const char *className) { - QList<QWidget *> widgets = findChildren<QWidget *>(); - for (QWidget *widget: widgets) { - if (widget->property(className) == true) { - widget->close(); - } +void EditorPage::closeNoteByClass(const char* className) { + QList<QWidget*> widgets = findChildren<QWidget*>(); + for (QWidget* widget : widgets) { + if (widget->property(className) == true) { + widget->close(); } + } } void EditorPage::slotFormatGpgHeader() { - - QString content = textPage->toPlainText(); - - // Get positions of the gpg-headers, if they exist - int start = content.indexOf(GpgConstants::PGP_SIGNED_BEGIN); - int startSig = content.indexOf(GpgConstants::PGP_SIGNATURE_BEGIN); - int endSig = content.indexOf(GpgConstants::PGP_SIGNATURE_END); - - if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { - return; - } - - signMarked = true; - - // Set the fontstyle for the header - QTextCharFormat signFormat; - signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); - signFormat.setFontPointSize(9); - - // set font style for the signature - QTextCursor cursor(textPage->document()); - cursor.setPosition(startSig, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); - cursor.setCharFormat(signFormat); - - // set the font style for the header - int headEnd = content.indexOf("\n\n", start); - cursor.setPosition(start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); - cursor.setCharFormat(signFormat); - + QString content = textPage->toPlainText(); + + // Get positions of the gpg-headers, if they exist + int start = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNED_BEGIN); + int startSig = + content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_BEGIN); + int endSig = content.indexOf(GpgFrontend::GpgConstants::PGP_SIGNATURE_END); + + if (start < 0 || startSig < 0 || endSig < 0 || signMarked) { + return; + } + + signMarked = true; + + // Set the fontstyle for the header + QTextCharFormat signFormat; + signFormat.setForeground(QBrush(QColor::fromRgb(80, 80, 80))); + signFormat.setFontPointSize(9); + + // set font style for the signature + QTextCursor cursor(textPage->document()); + cursor.setPosition(startSig, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, endSig); + cursor.setCharFormat(signFormat); + + // set the font style for the header + int headEnd = content.indexOf("\n\n", start); + cursor.setPosition(start, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, headEnd); + cursor.setCharFormat(signFormat); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/EditorPage.h b/src/ui/widgets/EditorPage.h new file mode 100644 index 00000000..4d7d7ab6 --- /dev/null +++ b/src/ui/widgets/EditorPage.h @@ -0,0 +1,108 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __EDITORPAGE_H__ +#define __EDITORPAGE_H__ + +#include "gpg/GpgConstants.h" +#include "ui/GpgFrontendUI.h" + +QT_BEGIN_NAMESPACE +class QVBoxLayout; + +class QHBoxLayout; + +class QString; + +class QLabel; +QT_END_NAMESPACE + +namespace GpgFrontend::UI { + +/** + * @brief Class for handling a single tab of the tabwidget + * + */ +class EditorPage : public QWidget { + Q_OBJECT + public: + /** + * @details Add layout and add plaintextedit + * + * @param filePath Path of the file handled in this tab + * @param parent Pointer to the parent widget + */ + explicit EditorPage(QString filePath = "", QWidget* parent = nullptr); + + /** + * @details Get the filepath of the currently activated tab. + */ + const QString& getFilePath() const; + + /** + * @details Set filepath of currently activated tab. + * + * @param filePath The path to be set + */ + void setFilePath(const QString& filePath); + + /** + * @details Return pointer tp the textedit of the currently activated tab. + */ + QTextEdit* getTextPage(); + + /** + * @details Show additional widget at buttom of currently active tab + * + * @param widget The widget to be added + * @param className The name to handle the added widget + */ + void showNotificationWidget(QWidget* widget, const char* className); + + /** + * @details Hide all widgets with the given className + * + * @param className The classname of the widgets to hide + */ + void closeNoteByClass(const char* className); + + const QString uuid = QUuid::createUuid().toString(); + + private: + QTextEdit* textPage; /** The textedit of the tab */ + QVBoxLayout* mainLayout; /** The layout for the tab */ + QString fullFilePath; /** The path to the file handled in the tab */ + bool signMarked{}; /** true, if the signed header is marked, false if not */ + + private slots: + + /** + * @details Format the gpg header in another font-style + */ + void slotFormatGpgHeader(); +}; + +} // namespace GpgFrontend::UI + +#endif // __EDITORPAGE_H__ diff --git a/src/ui/widgets/FilePage.cpp b/src/ui/widgets/FilePage.cpp index b9602d58..07d3b762 100644 --- a/src/ui/widgets/FilePage.cpp +++ b/src/ui/widgets/FilePage.cpp @@ -26,242 +26,251 @@ #include "MainWindow.h" -FilePage::FilePage(QWidget *parent) : QWidget(parent) { - - qDebug() << "First Parent" << parent; - firstParent = parent; - - qDebug() << "New File Page"; - - dirModel = new QFileSystemModel(); - dirModel->setRootPath(QDir::currentPath()); - - dirTreeView = new QTreeView(); - dirTreeView->setModel(dirModel); - dirTreeView->setAnimated(true); - dirTreeView->setIndentation(20); - dirTreeView->setRootIndex(dirModel->index(QDir::currentPath())); - dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu); - mPath = dirModel->rootPath(); - - createPopupMenu(); - - - upLevelButton = new QPushButton(); - connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel())); - - QString buttonStyle = "QPushButton{border:none;background-color:rgba(255, 255, 255,100);}"; - - - auto upPixmap = QPixmap(":up.png"); - upPixmap = upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QIcon upButtonIcon(upPixmap); - upLevelButton->setIcon(upButtonIcon); - upLevelButton->setIconSize(upPixmap.rect().size()); - upLevelButton->setStyleSheet(buttonStyle); - - refreshButton = new QPushButton("Refresh"); - connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); - - goPathButton = new QPushButton(); - connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); - - auto updatePixmap = QPixmap(":refresh.png"); - updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QIcon updateButtonIcon(updatePixmap); - goPathButton->setIcon(updateButtonIcon); - goPathButton->setIconSize(updatePixmap.rect().size()); - goPathButton->setStyleSheet(buttonStyle); - - pathEdit = new QLineEdit(); - pathEdit->setText(dirModel->rootPath()); - - auto *menuLayout = new QHBoxLayout(); - menuLayout->addWidget(upLevelButton); - menuLayout->setStretchFactor(upLevelButton, 1); - menuLayout->addWidget(pathEdit); - menuLayout->setStretchFactor(pathEdit, 10); - menuLayout->addWidget(goPathButton); - menuLayout->setStretchFactor(goPathButton, 1); - // menuLayout->addWidget(refreshButton); - // menuLayout->setStretchFactor(refreshButton, 1); - - auto *layout = new QVBoxLayout(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - layout->addLayout(menuLayout); - layout->setStretchFactor(menuLayout, 1); - layout->addWidget(dirTreeView); - layout->setStretchFactor(dirTreeView, 8); - - this->setLayout(layout); - - connect(dirTreeView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(fileTreeViewItemClicked(const QModelIndex &))); - connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(fileTreeViewItemDoubleClicked(const QModelIndex &))); - connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &))); - - emit pathChanged(mPath); - +namespace GpgFrontend::UI { + +FilePage::FilePage(QWidget* parent) : QWidget(parent) { + qDebug() << "First Parent" << parent; + firstParent = parent; + + qDebug() << "New File Page"; + + dirModel = new QFileSystemModel(); + dirModel->setRootPath(QDir::currentPath()); + + dirTreeView = new QTreeView(); + dirTreeView->setModel(dirModel); + dirTreeView->setAnimated(true); + dirTreeView->setIndentation(20); + dirTreeView->setRootIndex(dirModel->index(QDir::currentPath())); + dirTreeView->setContextMenuPolicy(Qt::CustomContextMenu); + mPath = dirModel->rootPath(); + + createPopupMenu(); + + upLevelButton = new QPushButton(); + connect(upLevelButton, SIGNAL(clicked(bool)), this, SLOT(slotUpLevel())); + + QString buttonStyle = + "QPushButton{border:none;background-color:rgba(255, 255, 255,100);}"; + + auto upPixmap = QPixmap(":up.png"); + upPixmap = + upPixmap.scaled(18, 18, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QIcon upButtonIcon(upPixmap); + upLevelButton->setIcon(upButtonIcon); + upLevelButton->setIconSize(upPixmap.rect().size()); + upLevelButton->setStyleSheet(buttonStyle); + + refreshButton = new QPushButton("Refresh"); + connect(refreshButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); + + goPathButton = new QPushButton(); + connect(goPathButton, SIGNAL(clicked(bool)), this, SLOT(slotGoPath())); + + auto updatePixmap = QPixmap(":refresh.png"); + updatePixmap = updatePixmap.scaled(18, 18, Qt::KeepAspectRatio, + Qt::SmoothTransformation); + QIcon updateButtonIcon(updatePixmap); + goPathButton->setIcon(updateButtonIcon); + goPathButton->setIconSize(updatePixmap.rect().size()); + goPathButton->setStyleSheet(buttonStyle); + + pathEdit = new QLineEdit(); + pathEdit->setText(dirModel->rootPath()); + + auto* menuLayout = new QHBoxLayout(); + menuLayout->addWidget(upLevelButton); + menuLayout->setStretchFactor(upLevelButton, 1); + menuLayout->addWidget(pathEdit); + menuLayout->setStretchFactor(pathEdit, 10); + menuLayout->addWidget(goPathButton); + menuLayout->setStretchFactor(goPathButton, 1); + // menuLayout->addWidget(refreshButton); + // menuLayout->setStretchFactor(refreshButton, 1); + + auto* layout = new QVBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + layout->addLayout(menuLayout); + layout->setStretchFactor(menuLayout, 1); + layout->addWidget(dirTreeView); + layout->setStretchFactor(dirTreeView, 8); + + this->setLayout(layout); + + connect(dirTreeView, SIGNAL(clicked(const QModelIndex&)), this, + SLOT(fileTreeViewItemClicked(const QModelIndex&))); + connect(dirTreeView, SIGNAL(doubleClicked(const QModelIndex&)), this, + SLOT(fileTreeViewItemDoubleClicked(const QModelIndex&))); + connect(dirTreeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, + SLOT(onCustomContextMenu(const QPoint&))); + + emit pathChanged(mPath); } -void FilePage::fileTreeViewItemClicked(const QModelIndex &index) { - selectedPath = dirModel->fileInfo(index).absoluteFilePath(); - qDebug() << "selectedPath" << selectedPath; +void FilePage::fileTreeViewItemClicked(const QModelIndex& index) { + selectedPath = dirModel->fileInfo(index).absoluteFilePath(); + qDebug() << "selectedPath" << selectedPath; } void FilePage::slotUpLevel() { - QModelIndex currentRoot = dirTreeView->rootIndex(); - - mPath = dirModel->fileInfo(currentRoot).absoluteFilePath(); - QDir dir(mPath); - dir.makeAbsolute(); - dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral("..")))); - mPath = dir.absolutePath(); - auto fileInfo = QFileInfo(dir.absolutePath()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - pathEdit->setText(mPath); - slotGoPath(); - } - qDebug() << "Current Root mPath" << mPath; - emit pathChanged(mPath); + QModelIndex currentRoot = dirTreeView->rootIndex(); + + mPath = dirModel->fileInfo(currentRoot).absoluteFilePath(); + QDir dir(mPath); + dir.makeAbsolute(); + dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral("..")))); + mPath = dir.absolutePath(); + auto fileInfo = QFileInfo(dir.absolutePath()); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + pathEdit->setText(mPath); + slotGoPath(); + } + qDebug() << "Current Root mPath" << mPath; + emit pathChanged(mPath); } -void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex &index) { - mPath = dirModel->fileInfo(index).absoluteFilePath(); - auto fileInfo = QFileInfo(mPath); - auto targetModelIndex = dirTreeView->model()->index(index.row(), 0, index.parent()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - dirTreeView->setRootIndex(targetModelIndex); - pathEdit->setText(mPath); - } - qDebug() << "Index mPath" << mPath; - emit pathChanged(mPath); +void FilePage::fileTreeViewItemDoubleClicked(const QModelIndex& index) { + mPath = dirModel->fileInfo(index).absoluteFilePath(); + auto fileInfo = QFileInfo(mPath); + auto targetModelIndex = + dirTreeView->model()->index(index.row(), 0, index.parent()); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + dirTreeView->setRootIndex(targetModelIndex); + pathEdit->setText(mPath); + } + qDebug() << "Index mPath" << mPath; + emit pathChanged(mPath); } QString FilePage::getSelected() const { - return selectedPath; + return selectedPath; } void FilePage::slotGoPath() { - qDebug() << "getSelected" << pathEdit->text(); - auto fileInfo = QFileInfo(pathEdit->text()); - if(fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { - mPath = fileInfo.filePath(); - qDebug() << "Set Path" << mPath; - dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); - } else { - QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable."); - } - emit pathChanged(mPath); + qDebug() << "getSelected" << pathEdit->text(); + auto fileInfo = QFileInfo(pathEdit->text()); + if (fileInfo.isDir() && fileInfo.isReadable() && fileInfo.isExecutable()) { + mPath = fileInfo.filePath(); + qDebug() << "Set Path" << mPath; + dirTreeView->setRootIndex(dirModel->index(fileInfo.filePath())); + } else { + QMessageBox::critical(this, "Error", + "The path is unprivileged or unreachable."); + } + emit pathChanged(mPath); } void FilePage::createPopupMenu() { - popUpMenu = new QMenu(); - - auto openItemAct = new QAction(tr("Open"), this); - connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem())); - auto deleteItemAct = new QAction(tr("Delete"), this); - connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); - encryptItemAct = new QAction(tr("Encrypt and Sign"), this); - connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); - decryptItemAct = new QAction(tr("Decrypt and Verify"), this); - connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); - signItemAct = new QAction(tr("Only Sign"), this); - connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); - verifyItemAct = new QAction(tr("Only Verify"), this); - connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem())); - - popUpMenu->addAction(openItemAct); - popUpMenu->addAction(deleteItemAct); - popUpMenu->addSeparator(); - popUpMenu->addAction(encryptItemAct); - popUpMenu->addAction(decryptItemAct); - popUpMenu->addAction(signItemAct); - popUpMenu->addAction(verifyItemAct); - + popUpMenu = new QMenu(); + + auto openItemAct = new QAction(tr("Open"), this); + connect(openItemAct, SIGNAL(triggered()), this, SLOT(slotOpenItem())); + auto deleteItemAct = new QAction(tr("Delete"), this); + connect(deleteItemAct, SIGNAL(triggered()), this, SLOT(slotDeleteItem())); + encryptItemAct = new QAction(tr("Encrypt and Sign"), this); + connect(encryptItemAct, SIGNAL(triggered()), this, SLOT(slotEncryptItem())); + decryptItemAct = new QAction(tr("Decrypt and Verify"), this); + connect(decryptItemAct, SIGNAL(triggered()), this, SLOT(slotDecryptItem())); + signItemAct = new QAction(tr("Only Sign"), this); + connect(signItemAct, SIGNAL(triggered()), this, SLOT(slotSignItem())); + verifyItemAct = new QAction(tr("Only Verify"), this); + connect(verifyItemAct, SIGNAL(triggered()), this, SLOT(slotVerifyItem())); + + popUpMenu->addAction(openItemAct); + popUpMenu->addAction(deleteItemAct); + popUpMenu->addSeparator(); + popUpMenu->addAction(encryptItemAct); + popUpMenu->addAction(decryptItemAct); + popUpMenu->addAction(signItemAct); + popUpMenu->addAction(verifyItemAct); } -void FilePage::onCustomContextMenu(const QPoint &point) { - QModelIndex index = dirTreeView->indexAt(point); - selectedPath = dirModel->fileInfo(index).absoluteFilePath(); - qDebug() << "Right Click" << selectedPath; - if (index.isValid()) { - QFileInfo info(selectedPath); - encryptItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); - decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg"); - signItemAct->setEnabled(info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); - verifyItemAct->setEnabled(info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg")); - - popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point)); - } +void FilePage::onCustomContextMenu(const QPoint& point) { + QModelIndex index = dirTreeView->indexAt(point); + selectedPath = dirModel->fileInfo(index).absoluteFilePath(); + qDebug() << "Right Click" << selectedPath; + if (index.isValid()) { + QFileInfo info(selectedPath); + encryptItemAct->setEnabled( + info.isFile() && (info.suffix() != "gpg" && info.suffix() != "sig")); + decryptItemAct->setEnabled(info.isFile() && info.suffix() == "gpg"); + signItemAct->setEnabled(info.isFile() && + (info.suffix() != "gpg" && info.suffix() != "sig")); + verifyItemAct->setEnabled( + info.isFile() && (info.suffix() == "sig" || info.suffix() == "gpg")); + + popUpMenu->exec(dirTreeView->viewport()->mapToGlobal(point)); + } } void FilePage::slotOpenItem() { - QFileInfo info(mPath); - if(info.isDir()) { - qDebug() << "getSelected" << pathEdit->text(); - if(info.isReadable() && info.isExecutable()) { - qDebug() << "Set Path" << info.filePath(); - dirTreeView->setRootIndex(dirModel->index(info.filePath())); - } else { - QMessageBox::critical(this, "Error", "The path is unprivileged or unreachable."); - } + QFileInfo info(mPath); + if (info.isDir()) { + qDebug() << "getSelected" << pathEdit->text(); + if (info.isReadable() && info.isExecutable()) { + qDebug() << "Set Path" << info.filePath(); + dirTreeView->setRootIndex(dirModel->index(info.filePath())); } else { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - qDebug() << "Open Item" << mPath; - if (mainWindow != nullptr) - mainWindow->slotOpenFile(mPath); + QMessageBox::critical(this, "Error", + "The path is unprivileged or unreachable."); } + } else { + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + qDebug() << "Open Item" << mPath; + if (mainWindow != nullptr) + mainWindow->slotOpenFile(mPath); + } } void FilePage::slotDeleteItem() { - QModelIndex index = dirTreeView->currentIndex(); - QVariant data = dirTreeView->model()->data(index); + QModelIndex index = dirTreeView->currentIndex(); + QVariant data = dirTreeView->model()->data(index); - auto ret = QMessageBox::warning(this, - tr("Warning"), - tr("Are you sure you want to delete it?"), - QMessageBox::Ok | QMessageBox::Cancel); + auto ret = QMessageBox::warning(this, tr("Warning"), + tr("Are you sure you want to delete it?"), + QMessageBox::Ok | QMessageBox::Cancel); - if(ret == QMessageBox::Cancel) - return; + if (ret == QMessageBox::Cancel) + return; - qDebug() << "Delete Item" << data.toString(); + qDebug() << "Delete Item" << data.toString(); - if(!dirModel->remove(index)){ - QMessageBox::critical(this, - tr("Error"), - tr("Unable to delete the file or folder.")); - } + if (!dirModel->remove(index)) { + QMessageBox::critical(this, tr("Error"), + tr("Unable to delete the file or folder.")); + } } void FilePage::slotEncryptItem() { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - if(mainWindow != nullptr) - mainWindow->slotFileEncryptSign(); + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + if (mainWindow != nullptr) + mainWindow->slotFileEncryptSign(); } void FilePage::slotDecryptItem() { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - if(mainWindow != nullptr) - mainWindow->slotFileDecryptVerify(); + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + if (mainWindow != nullptr) + mainWindow->slotFileDecryptVerify(); } void FilePage::slotSignItem() { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - if(mainWindow != nullptr) - mainWindow->slotFileSign(); + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + if (mainWindow != nullptr) + mainWindow->slotFileSign(); } void FilePage::slotVerifyItem() { - auto mainWindow = qobject_cast<MainWindow *>(firstParent); - if(mainWindow != nullptr) - mainWindow->slotFileVerify(); + auto mainWindow = qobject_cast<MainWindow*>(firstParent); + if (mainWindow != nullptr) + mainWindow->slotFileVerify(); } -void FilePage::keyPressEvent(QKeyEvent *event) { - qDebug() << "Key Press" << event->key(); - if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - slotGoPath(); - } +void FilePage::keyPressEvent(QKeyEvent* event) { + qDebug() << "Key Press" << event->key(); + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + slotGoPath(); + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/FilePage.h b/src/ui/widgets/FilePage.h new file mode 100644 index 00000000..be7ceea7 --- /dev/null +++ b/src/ui/widgets/FilePage.h @@ -0,0 +1,86 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_FILEPAGE_H +#define GPGFRONTEND_FILEPAGE_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class FilePage : public QWidget { + Q_OBJECT + public: + explicit FilePage(QWidget* parent = nullptr); + + [[nodiscard]] QString getSelected() const; + + void createPopupMenu(); + + signals: + void pathChanged(const QString& path); + + private slots: + + void fileTreeViewItemClicked(const QModelIndex& index); + void fileTreeViewItemDoubleClicked(const QModelIndex& index); + + void slotUpLevel(); + void slotGoPath(); + + void slotOpenItem(); + void slotDeleteItem(); + void slotEncryptItem(); + void slotDecryptItem(); + void slotSignItem(); + void slotVerifyItem(); + + void onCustomContextMenu(const QPoint& point); + + protected: + void keyPressEvent(QKeyEvent* event) override; + + private: + QFileSystemModel* dirModel; + QTreeView* dirTreeView; + QLineEdit* pathEdit; + QString mPath; + QString selectedPath; + + QPushButton* upLevelButton; + QPushButton* goPathButton; + QPushButton* refreshButton; + + QMenu* popUpMenu{}; + QAction* encryptItemAct{}; + QAction* decryptItemAct{}; + QAction* signItemAct{}; + QAction* verifyItemAct{}; + + QWidget* firstParent; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_FILEPAGE_H diff --git a/src/ui/widgets/HelpPage.cpp b/src/ui/widgets/HelpPage.cpp index e018da81..dfc24929 100644 --- a/src/ui/widgets/HelpPage.cpp +++ b/src/ui/widgets/HelpPage.cpp @@ -26,25 +26,24 @@ #include <utility> -HelpPage::HelpPage(const QString &path, QWidget *parent) : - QWidget(parent) { +namespace GpgFrontend::UI { - browser = new QTextBrowser(); - auto *mainLayout = new QVBoxLayout(); - mainLayout->setSpacing(0); - mainLayout->addWidget(browser); - mainLayout->setContentsMargins(0, 0, 0, 0); - setLayout(mainLayout); - - connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl))); - browser->setOpenLinks(false); - browser->setSource(localizedHelp(QUrl(path))); - browser->setFocus(); +HelpPage::HelpPage(const QString& path, QWidget* parent) : QWidget(parent) { + browser = new QTextBrowser(); + auto* mainLayout = new QVBoxLayout(); + mainLayout->setSpacing(0); + mainLayout->addWidget(browser); + mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); + connect(browser, SIGNAL(anchorClicked(QUrl)), this, SLOT(slotOpenUrl(QUrl))); + browser->setOpenLinks(false); + browser->setSource(localizedHelp(QUrl(path))); + browser->setFocus(); } -void HelpPage::slotOpenUrl(const QUrl &url) { - browser->setSource(localizedHelp(url)); +void HelpPage::slotOpenUrl(const QUrl& url) { + browser->setSource(localizedHelp(url)); }; /** @@ -55,29 +54,31 @@ void HelpPage::slotOpenUrl(const QUrl &url) { * @param url * @return */ -QUrl HelpPage::localizedHelp(const QUrl &url) { - QString path = url.toLocalFile(); - QString filename = path.mid(path.lastIndexOf("/") + 1); - QString filepath = path.left(path.lastIndexOf("/") + 1); - QStringList fileparts = filename.split("."); - - //QSettings settings; - QString lang = QSettings().value("int/lang", QLocale::system().name()).toString(); - if (lang.isEmpty()) { - lang = QLocale::system().name(); - } +QUrl HelpPage::localizedHelp(const QUrl& url) { + QString path = url.toLocalFile(); + QString filename = path.mid(path.lastIndexOf("/") + 1); + QString filepath = path.left(path.lastIndexOf("/") + 1); + QStringList fileparts = filename.split("."); - fileparts.insert(1, lang); - QString langfile = filepath + fileparts.join("."); + // QSettings settings; + QString lang = + QSettings().value("int/lang", QLocale::system().name()).toString(); + if (lang.isEmpty()) { + lang = QLocale::system().name(); + } - if (QFile(QUrl(langfile).toLocalFile()).exists()) { - return langfile; - } else { - return path; - } + fileparts.insert(1, lang); + QString langfile = filepath + fileparts.join("."); + if (QFile(QUrl(langfile).toLocalFile()).exists()) { + return langfile; + } else { + return path; + } } -QTextBrowser *HelpPage::getBrowser() { - return browser; +QTextBrowser* HelpPage::getBrowser() { + return browser; } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/HelpPage.h b/src/ui/widgets/HelpPage.h new file mode 100644 index 00000000..25490557 --- /dev/null +++ b/src/ui/widgets/HelpPage.h @@ -0,0 +1,49 @@ +/* + * helppage.h + * + * Copyright 2008 gpg4usb-team <[email protected]> + * + * This file is part of gpg4usb. + * + * Gpg4usb 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. + * + * Gpg4usb 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 gpg4usb. If not, see <http://www.gnu.org/licenses/> + */ + +#ifndef HELPPAGE_H +#define HELPPAGE_H + +#include "ui/GpgFrontendUI.h" + +namespace GpgFrontend::UI { + +class HelpPage : public QWidget { + Q_OBJECT + public: + explicit HelpPage(const QString& path, QWidget* parent = nullptr); + + QTextBrowser* getBrowser(); + + signals: + + public slots: + + void slotOpenUrl(const QUrl& url); + + private: + QTextBrowser* browser; /** The textbrowser of the tab */ + QUrl localizedHelp(const QUrl& path); +}; + +} // namespace GpgFrontend::UI + +#endif // HELPPAGE_H diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp index 0c0b6bcd..a77ed73c 100644 --- a/src/ui/widgets/InfoBoardWidget.cpp +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -24,170 +24,178 @@ #include "ui/widgets/InfoBoardWidget.h" -InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgFrontend::GpgContext *ctx, KeyList *keyList) : - QWidget(parent), mCtx(ctx), mKeyList(keyList), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", - QSettings::IniFormat) { - - infoBoard = new QTextEdit(this); - infoBoard->setReadOnly(true); - infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - infoBoard->setMinimumWidth(480); - infoBoard->setContentsMargins(0, 0, 0, 0); - - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotReset())); - - importFromKeyserverAct = new QAction(tr("Import missing key from Keyserver"), this); - connect(importFromKeyserverAct, SIGNAL(triggered()), this, SLOT(slotImportFromKeyserver())); - - detailMenu = new QMenu(this); - detailMenu->addAction(importFromKeyserverAct); - importFromKeyserverAct->setVisible(false); - - auto *actionButtonMenu = new QWidget(); - actionButtonMenu->setContentsMargins(0, 0, 0, 0); - actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - actionButtonMenu->setFixedHeight(36); - - actionButtonLayout = new QHBoxLayout(); - actionButtonLayout->setContentsMargins(5, 5, 5, 5); - actionButtonLayout->setSpacing(0); - actionButtonMenu->setLayout(actionButtonLayout); - - auto label = new QLabel(tr("Optional Actions")); - label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - label->setContentsMargins(0, 0, 0, 0); - - actionButtonLayout->addWidget(label); - actionButtonLayout->addStretch(); - - - QFrame *line; - line = new QFrame(this); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - line->setContentsMargins(0, 0, 0, 0); - - auto *notificationWidgetLayout = new QVBoxLayout(this); - notificationWidgetLayout->setContentsMargins(0, 0, 0, 0); - notificationWidgetLayout->setSpacing(0); - - notificationWidgetLayout->addWidget(infoBoard); - notificationWidgetLayout->setStretchFactor(infoBoard, 10); - notificationWidgetLayout->addWidget(actionButtonMenu); - notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1); - notificationWidgetLayout->addWidget(line); - notificationWidgetLayout->setStretchFactor(line, 1); - notificationWidgetLayout->addStretch(0); - this->setLayout(notificationWidgetLayout); +namespace GpgFrontend::UI { + +InfoBoardWidget::InfoBoardWidget(QWidget* parent, KeyList* keyList) + : QWidget(parent), + mKeyList(keyList), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat) { + infoBoard = new QTextEdit(this); + infoBoard->setReadOnly(true); + infoBoard->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + infoBoard->setMinimumWidth(480); + infoBoard->setContentsMargins(0, 0, 0, 0); + + importFromKeyserverAct = + new QAction(tr("Import missing key from Keyserver"), this); + connect(importFromKeyserverAct, SIGNAL(triggered()), this, + SLOT(slotImportFromKeyserver())); + + detailMenu = new QMenu(this); + detailMenu->addAction(importFromKeyserverAct); + importFromKeyserverAct->setVisible(false); + + auto* actionButtonMenu = new QWidget(); + actionButtonMenu->setContentsMargins(0, 0, 0, 0); + actionButtonMenu->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + actionButtonMenu->setFixedHeight(36); + + actionButtonLayout = new QHBoxLayout(); + actionButtonLayout->setContentsMargins(5, 5, 5, 5); + actionButtonLayout->setSpacing(0); + actionButtonMenu->setLayout(actionButtonLayout); + + auto label = new QLabel(tr("Optional Actions")); + label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + label->setContentsMargins(0, 0, 0, 0); + + actionButtonLayout->addWidget(label); + actionButtonLayout->addStretch(); + + QFrame* line; + line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setContentsMargins(0, 0, 0, 0); + + auto* notificationWidgetLayout = new QVBoxLayout(this); + notificationWidgetLayout->setContentsMargins(0, 0, 0, 0); + notificationWidgetLayout->setSpacing(0); + + notificationWidgetLayout->addWidget(infoBoard); + notificationWidgetLayout->setStretchFactor(infoBoard, 10); + notificationWidgetLayout->addWidget(actionButtonMenu); + notificationWidgetLayout->setStretchFactor(actionButtonMenu, 1); + notificationWidgetLayout->addWidget(line); + notificationWidgetLayout->setStretchFactor(line, 1); + notificationWidgetLayout->addStretch(0); + this->setLayout(notificationWidgetLayout); } void InfoBoardWidget::slotImportFromKeyserver() { - auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this); - importDialog->slotImport(*keysNotInList); + auto* importDialog = new KeyServerImportDialog(mKeyList, false, this); + importDialog->slotImport(*keysNotInList); } -void InfoBoardWidget::setInfoBoard(const QString &text, InfoBoardStatus verifyLabelStatus) { - QString color; - infoBoard->clear(); - switch (verifyLabelStatus) { - case INFO_ERROR_OK: - color = "#008000"; - break; - case INFO_ERROR_WARN: - color = "#FF8C00"; - break; - case INFO_ERROR_CRITICAL: - color = "#DC143C"; - break; - default: - break; - } - infoBoard->append(text); - - infoBoard->setAutoFillBackground(true); - QPalette status = infoBoard->palette(); - status.setColor(QPalette::Text, color); - infoBoard->setPalette(status); - auto infoBoardFontSize = settings.value("informationBoard/fontSize", 10).toInt(); - infoBoard->setFont(QFont("Times", infoBoardFontSize)); +void InfoBoardWidget::setInfoBoard(const QString& text, + InfoBoardStatus verifyLabelStatus) { + QString color; + infoBoard->clear(); + switch (verifyLabelStatus) { + case INFO_ERROR_OK: + color = "#008000"; + break; + case INFO_ERROR_WARN: + color = "#FF8C00"; + break; + case INFO_ERROR_CRITICAL: + color = "#DC143C"; + break; + default: + break; + } + infoBoard->append(text); + + infoBoard->setAutoFillBackground(true); + QPalette status = infoBoard->palette(); + status.setColor(QPalette::Text, color); + infoBoard->setPalette(status); + auto infoBoardFontSize = + settings.value("informationBoard/fontSize", 10).toInt(); + infoBoard->setFont(QFont("Times", infoBoardFontSize)); } -void InfoBoardWidget::slotRefresh(const QString &text, InfoBoardStatus status) { - infoBoard->clear(); - setInfoBoard(text, status); - infoBoard->verticalScrollBar()->setValue(0); +void InfoBoardWidget::slotRefresh(const QString& text, InfoBoardStatus status) { + infoBoard->clear(); + setInfoBoard(text, status); + infoBoard->verticalScrollBar()->setValue(0); } -void InfoBoardWidget::associateTextEdit(QTextEdit *edit) { - if (mTextPage != nullptr) - disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); - this->mTextPage = edit; - connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); +void InfoBoardWidget::associateTextEdit(QTextEdit* edit) { + if (mTextPage != nullptr) + disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); + this->mTextPage = edit; + connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); } -void InfoBoardWidget::associateFileTreeView(FilePage *treeView) { -// if (mFileTreeView != nullptr) -// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); -// this->mFileTreeView = treeView; -// connect(treeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); +void InfoBoardWidget::associateFileTreeView(FilePage* treeView) { + // if (mFileTreeView != nullptr) + // disconnect(mFileTreeView, &FilePage::pathChanged, this, + // &InfoBoardWidget::slotReset); + // this->mFileTreeView = treeView; + // connect(treeView, &FilePage::pathChanged, this, + // &InfoBoardWidget::slotReset); } -void InfoBoardWidget::associateTabWidget(QTabWidget *tab) { - if (mTextPage != nullptr) - disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); -// if (mFileTreeView != nullptr) -// disconnect(mFileTreeView, &FilePage::pathChanged, this, &InfoBoardWidget::slotReset); - if (mTabWidget != nullptr) { - disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); - connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); - } - - mTextPage = nullptr; - mFileTreeView = nullptr; - mTabWidget = tab; - connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); - connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); +void InfoBoardWidget::associateTabWidget(QTabWidget* tab) { + if (mTextPage != nullptr) + disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); + // if (mFileTreeView != nullptr) + // disconnect(mFileTreeView, &FilePage::pathChanged, this, + // &InfoBoardWidget::slotReset); + if (mTabWidget != nullptr) { + disconnect(mTabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); + connect(mTabWidget, SIGNAL(tabCloseRequested(int)), this, + SLOT(slotReset())); + } + + mTextPage = nullptr; + mFileTreeView = nullptr; + mTabWidget = tab; + connect(tab, SIGNAL(tabBarClicked(int)), this, SLOT(slotReset())); + connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(slotReset())); } - -void InfoBoardWidget::addOptionalAction(const QString &name, const std::function<void()> &action) { - auto actionButton = new QPushButton(name); - auto layout = new QHBoxLayout(); - layout->setContentsMargins(5, 0, 5, 0); - infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - // set margin from surroundings - layout->addWidget(actionButton); - actionButtonLayout->addLayout(layout); - connect(actionButton, &QPushButton::clicked, this, [=]() { - action(); - }); +void InfoBoardWidget::addOptionalAction(const QString& name, + const std::function<void()>& action) { + auto actionButton = new QPushButton(name); + auto layout = new QHBoxLayout(); + layout->setContentsMargins(5, 0, 5, 0); + infoBoard->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + // set margin from surroundings + layout->addWidget(actionButton); + actionButtonLayout->addLayout(layout); + connect(actionButton, &QPushButton::clicked, this, [=]() { action(); }); } /** * Delete All item in actionButtonLayout */ void InfoBoardWidget::resetOptionActionsMenu() { - deleteWidgetsInLayout(actionButtonLayout, 2); + deleteWidgetsInLayout(actionButtonLayout, 2); } void InfoBoardWidget::slotReset() { - this->infoBoard->clear(); - resetOptionActionsMenu(); + this->infoBoard->clear(); + resetOptionActionsMenu(); } /** * Try Delete all widget from target layout * @param layout target layout */ -void InfoBoardWidget::deleteWidgetsInLayout(QLayout *layout, int start_index) { - QLayoutItem *item; - while ((item = layout->layout()->takeAt(start_index)) != nullptr) { - layout->removeItem(item); - if (item->layout() != nullptr) - deleteWidgetsInLayout(item->layout()); - else if (item->widget() != nullptr) - delete item->widget(); - delete item; - } +void InfoBoardWidget::deleteWidgetsInLayout(QLayout* layout, int start_index) { + QLayoutItem* item; + while ((item = layout->layout()->takeAt(start_index)) != nullptr) { + layout->removeItem(item); + if (item->layout() != nullptr) + deleteWidgetsInLayout(item->layout()); + else if (item->widget() != nullptr) + delete item->widget(); + delete item; + } } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/InfoBoardWidget.h b/src/ui/widgets/InfoBoardWidget.h new file mode 100644 index 00000000..5512a78a --- /dev/null +++ b/src/ui/widgets/InfoBoardWidget.h @@ -0,0 +1,118 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __VERIFYNOTIFICATION_H__ +#define __VERIFYNOTIFICATION_H__ + +#include "EditorPage.h" +#include "FilePage.h" +#include "gpg/result_analyse/VerifyResultAnalyse.h" +#include "ui/VerifyDetailsDialog.h" + +namespace GpgFrontend::UI { +/** + * @details Enumeration for the status of Verifylabel + */ +typedef enum { + INFO_ERROR_OK = 0, + INFO_ERROR_WARN = 1, + INFO_ERROR_CRITICAL = 2, + INFO_ERROR_NEUTRAL = 3, +} InfoBoardStatus; + +/** + * @brief Class for handling the verifylabel shown at buttom of a textedit-page + */ +class InfoBoardWidget : public QWidget { + Q_OBJECT + public: + /** + * @brief + * + * @param ctx The GPGme-Context + * @param parent The parent widget + */ + explicit InfoBoardWidget(QWidget* parent, KeyList* keyList); + + void associateTextEdit(QTextEdit* edit); + + void associateFileTreeView(FilePage* treeView); + + void associateTabWidget(QTabWidget* tab); + + void addOptionalAction(const QString& name, + const std::function<void()>& action); + + void resetOptionActionsMenu(); + + /** + * @details Set the text and background-color of verify notification. + * + * @param text The text to be set. + * @param verifyLabelStatus The status of label to set the specified color. + */ + void setInfoBoard(const QString& text, InfoBoardStatus verifyLabelStatus); + + QStringList* keysNotInList; /** List with keys, which are in signature but not + in keylist */ + + public slots: + + /** + * @details Import the keys contained in keysNotInList from keyserver + * + */ + void slotImportFromKeyserver(); + + void slotReset(); + + /** + * @details Refresh the contents of dialog. + */ + void slotRefresh(const QString& text, InfoBoardStatus status); + + private: + QString appPath; + QSettings settings; + + QMenu* detailMenu; /** Menu for te Button in verfiyNotification */ + QAction* importFromKeyserverAct; /** Action for importing keys from keyserver + which are notin keylist */ + QTextEdit* infoBoard; + KeyList* mKeyList; /** Table holding the keys */ + + QTextEdit* mTextPage{nullptr}; /** TextEdit associated to the notification */ + FilePage* mFileTreeView{ + nullptr}; /** TreeView associated to the notification */ + QTabWidget* mTabWidget{ + nullptr}; /** TreeView associated to the notification */ + + QHBoxLayout* actionButtonLayout; + + void deleteWidgetsInLayout(QLayout* layout, int start_index = 0); +}; + +} // namespace GpgFrontend::UI + +#endif // __VERIFYNOTIFICATION_H__
\ No newline at end of file diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index 8a334e3e..f340cafc 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -23,397 +23,387 @@ */ #include "ui/widgets/KeyList.h" +#include "gpg/function/GpgKeyGetter.h" #include <utility> -KeyList::KeyList(GpgFrontend::GpgContext *ctx, - KeyListRow::KeyType selectType, - KeyListColumn::InfoType infoType, - QWidget *parent) - : QWidget(parent), mSelectType(selectType), mInfoType(infoType), appPath(qApp->applicationDirPath()), - settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", QSettings::IniFormat) { - mCtx = ctx; - - - mKeyList = new QTableWidget(this); - mKeyList->setColumnCount(7); - mKeyList->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - mKeyList->verticalHeader()->hide(); - mKeyList->setShowGrid(false); - mKeyList->sortByColumn(2, Qt::AscendingOrder); - mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows); - mKeyList->setSelectionMode(QAbstractItemView::SingleSelection); - - // tableitems not editable - mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); - // no focus (rectangle around tableitems) - // may be it should focus on whole row - mKeyList->setFocusPolicy(Qt::NoFocus); - - mKeyList->setAlternatingRowColors(true); - - // Hidden Column For Purpose - if (!(mInfoType & KeyListColumn::TYPE)) { - mKeyList->setColumnHidden(1, true); - } - if (!(mInfoType & KeyListColumn::NAME)) { - mKeyList->setColumnHidden(2, true); - } - if (!(mInfoType & KeyListColumn::EmailAddress)) { - mKeyList->setColumnHidden(3, true); - } - if (!(mInfoType & KeyListColumn::Usage)) { - mKeyList->setColumnHidden(4, true); - } - if (!(mInfoType & KeyListColumn::Validity)) { - mKeyList->setColumnHidden(5, true); - } - if (!(mInfoType & KeyListColumn::FingerPrint)) { - mKeyList->setColumnHidden(6, true); - } +namespace GpgFrontend::UI { - QStringList labels; - labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address") - << tr("Usage") << tr("Validity") << tr("Finger Print"); +KeyList::KeyList(KeyListRow::KeyType selectType, + KeyListColumn::InfoType infoType, + QWidget* parent) + : QWidget(parent), + appPath(qApp->applicationDirPath()), + settings(RESOURCE_DIR(appPath) + "/conf/gpgfrontend.ini", + QSettings::IniFormat), + mSelectType(selectType), + mInfoType(infoType) { + mKeyList = new QTableWidget(this); + mKeyList->setColumnCount(7); + mKeyList->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeToContents); + mKeyList->verticalHeader()->hide(); + mKeyList->setShowGrid(false); + mKeyList->sortByColumn(2, Qt::AscendingOrder); + mKeyList->setSelectionBehavior(QAbstractItemView::SelectRows); + mKeyList->setSelectionMode(QAbstractItemView::SingleSelection); + + // tableitems not editable + mKeyList->setEditTriggers(QAbstractItemView::NoEditTriggers); + // no focus (rectangle around tableitems) + // may be it should focus on whole row + mKeyList->setFocusPolicy(Qt::NoFocus); + + mKeyList->setAlternatingRowColors(true); + + // Hidden Column For Purpose + if (!(mInfoType & KeyListColumn::TYPE)) { + mKeyList->setColumnHidden(1, true); + } + if (!(mInfoType & KeyListColumn::NAME)) { + mKeyList->setColumnHidden(2, true); + } + if (!(mInfoType & KeyListColumn::EmailAddress)) { + mKeyList->setColumnHidden(3, true); + } + if (!(mInfoType & KeyListColumn::Usage)) { + mKeyList->setColumnHidden(4, true); + } + if (!(mInfoType & KeyListColumn::Validity)) { + mKeyList->setColumnHidden(5, true); + } + if (!(mInfoType & KeyListColumn::FingerPrint)) { + mKeyList->setColumnHidden(6, true); + } + + QStringList labels; + labels << tr("Select") << tr("Type") << tr("Name") << tr("Email Address") + << tr("Usage") << tr("Validity") << tr("Finger Print"); + + mKeyList->setHorizontalHeaderLabels(labels); + mKeyList->horizontalHeader()->setStretchLastSection(false); + + auto* layout = new QVBoxLayout; + layout->addWidget(mKeyList); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(3); + setLayout(layout); + + popupMenu = new QMenu(this); + + connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex&)), this, + SLOT(slotDoubleClicked(const QModelIndex&))); + setAcceptDrops(true); + slotRefresh(); +} - mKeyList->setHorizontalHeaderLabels(labels); - mKeyList->horizontalHeader()->setStretchLastSection(false); +void KeyList::slotRefresh() { + auto keyList = getChecked(); + // while filling the table, sort enabled causes errors + mKeyList->setSortingEnabled(false); + mKeyList->clearContents(); - auto *layout = new QVBoxLayout; - layout->addWidget(mKeyList); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(3); - setLayout(layout); + auto keys = GpgKeyGetter::GetInstance().FetchKey(); - popupMenu = new QMenu(this); + auto it = keys->begin(); - connect(mKeyList, SIGNAL(doubleClicked(const QModelIndex &)), - this, SLOT(slotDoubleClicked(const QModelIndex &))); - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh())); - setAcceptDrops(true); - slotRefresh(); -} + int row_count = 0; -void KeyList::slotRefresh() { - QStringList *keyList; - keyList = getChecked(); - // while filling the table, sort enabled causes errors - mKeyList->setSortingEnabled(false); - mKeyList->clearContents(); - - GpgKeyList keys = mCtx->getKeys(); - - auto it = keys.begin(); - - int row_count = 0; - - while (it != keys.end()) { - if (mFilter != nullptr) { - if (!mFilter(*it)) { - it = keys.erase(it); - continue; - } - } - if (!excluded_key_ids.isEmpty()) { - - auto iterator = std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(), - [it](const auto &key_id) -> bool { - if (it->id == key_id) return true; - else return false; - }); - - if (iterator != excluded_key_ids.end()) { - it = keys.erase(it); - continue; - } - } - if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key) { - it = keys.erase(it); - continue; - } - row_count++; - it++; + while (it != keys->end()) { + if (mFilter != nullptr) { + if (!mFilter(*it)) { + it = keys->erase(it); + continue; + } + } + if (!excluded_key_ids.empty()) { + auto iterator = + std::find_if(excluded_key_ids.begin(), excluded_key_ids.end(), + [it](const auto& key_id) -> bool { + if (it->id() == key_id) + return true; + else + return false; + }); + + if (iterator != excluded_key_ids.end()) { + it = keys->erase(it); + continue; + } + } + if (mSelectType == KeyListRow::ONLY_SECRET_KEY && !it->is_private_key()) { + it = keys->erase(it); + continue; + } + row_count++; + it++; + } + + mKeyList->setRowCount(row_count); + + int row_index = 0; + it = keys->begin(); + buffered_keys.clear(); + + while (it != keys->end()) { + buffered_keys.push_back( + std::move(GpgKeyGetter::GetInstance().GetKey(it->id()))); + + auto* tmp0 = new QTableWidgetItem(QString::number(row_index)); + tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | + Qt::ItemIsSelectable); + tmp0->setTextAlignment(Qt::AlignCenter); + tmp0->setCheckState(Qt::Unchecked); + mKeyList->setItem(row_index, 0, tmp0); + + QString type_str; + QTextStream type_steam(&type_str); + if (it->is_private_key()) { + type_steam << "pub/sec"; + } else { + type_steam << "pub"; } - mKeyList->setRowCount(row_count); - - int row_index = 0; - it = keys.begin(); - buffered_keys.clear(); - - while (it != keys.end()) { - - buffered_keys.push_back(*it); - - auto *tmp0 = new QTableWidgetItem(QString::number(row_index)); - tmp0->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - tmp0->setTextAlignment(Qt::AlignCenter); - tmp0->setCheckState(Qt::Unchecked); - mKeyList->setItem(row_index, 0, tmp0); - - QString type_str; - QTextStream type_steam(&type_str); - if (it->is_private_key) { - type_steam << "pub/sec"; - } else { - type_steam << "pub"; - } - - if (it->is_private_key && !it->has_master_key) { - type_steam << "#"; - } - auto *tmp1 = new QTableWidgetItem(type_str); - mKeyList->setItem(row_index, 1, tmp1); - - auto *tmp2 = new QTableWidgetItem(it->name); - tmp2->setToolTip(it->name); - mKeyList->setItem(row_index, 2, tmp2); - auto *tmp3 = new QTableWidgetItem(it->email); - tmp3->setToolTip(it->email); - mKeyList->setItem(row_index, 3, tmp3); - - QString usage; - QTextStream usage_steam(&usage); - - if (GpgFrontend::GpgContext::checkIfKeyCanCert(*it)) - usage_steam << "C"; - if (GpgFrontend::GpgContext::checkIfKeyCanEncr(*it)) - usage_steam << "E"; - if (GpgFrontend::GpgContext::checkIfKeyCanSign(*it)) - usage_steam << "S"; - if (GpgFrontend::GpgContext::checkIfKeyCanAuth(*it)) - usage_steam << "A"; - - auto *temp_usage = new QTableWidgetItem(usage); - temp_usage->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 4, temp_usage); - - auto *temp_validity = new QTableWidgetItem(it->owner_trust); - temp_validity->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 5, temp_validity); - - auto *temp_fpr = new QTableWidgetItem(it->fpr); - temp_fpr->setTextAlignment(Qt::AlignCenter); - mKeyList->setItem(row_index, 6, temp_fpr); - - // strike out expired keys - if (it->expired || it->revoked) { - QFont strike = tmp2->font(); - strike.setStrikeOut(true); - tmp0->setFont(strike); - temp_usage->setFont(strike); - temp_fpr->setFont(strike); - temp_validity->setFont(strike); - tmp1->setFont(strike); - tmp2->setFont(strike); - tmp3->setFont(strike); - } - - it++; - ++row_index; + if (it->is_private_key() && !it->has_master_key()) { + type_steam << "#"; + } + auto* tmp1 = new QTableWidgetItem(type_str); + mKeyList->setItem(row_index, 1, tmp1); + + auto* tmp2 = new QTableWidgetItem(QString::fromStdString(it->name())); + mKeyList->setItem(row_index, 2, tmp2); + auto* tmp3 = new QTableWidgetItem(QString::fromStdString(it->email())); + mKeyList->setItem(row_index, 3, tmp3); + + QString usage; + QTextStream usage_steam(&usage); + + if (it->CanCertActual()) + usage_steam << "C"; + if (it->CanEncrActual()) + usage_steam << "E"; + if (it->CanSignActual()) + usage_steam << "S"; + if (it->CanAuthActual()) + usage_steam << "A"; + + auto* temp_usage = new QTableWidgetItem(usage); + temp_usage->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 4, temp_usage); + + auto* temp_validity = + new QTableWidgetItem(QString::fromStdString(it->owner_trust())); + temp_validity->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 5, temp_validity); + + auto* temp_fpr = new QTableWidgetItem(QString::fromStdString(it->fpr())); + temp_fpr->setTextAlignment(Qt::AlignCenter); + mKeyList->setItem(row_index, 6, temp_fpr); + + // strike out expired keys + if (it->expired() || it->revoked()) { + QFont strike = tmp2->font(); + strike.setStrikeOut(true); + tmp0->setFont(strike); + temp_usage->setFont(strike); + temp_fpr->setFont(strike); + temp_validity->setFont(strike); + tmp1->setFont(strike); + tmp2->setFont(strike); + tmp3->setFont(strike); } + it++; + ++row_index; + } - setChecked(keyList); + setChecked(std::move(keyList)); } -QStringList *KeyList::getChecked() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getChecked() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return std::move(ret); } -QStringList *KeyList::getAllPrivateKeys() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getAllPrivateKeys() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 1) && buffered_keys[i].is_private_key()) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return std::move(ret); } -QStringList *KeyList::getPrivateChecked() { - auto *ret = new QStringList(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && (mKeyList->item(i, 1))) { - *ret << buffered_keys[i].id; - } +KeyIdArgsListPtr KeyList::getPrivateChecked() { + auto ret = std::make_unique<KeyIdArgsList>(); + for (int i = 0; i < mKeyList->rowCount(); i++) { + if ((mKeyList->item(i, 0)->checkState() == Qt::Checked) && + (mKeyList->item(i, 1))) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return std::move(ret); } -void KeyList::setChecked(QStringList *keyIds) { - if (!keyIds->isEmpty()) { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (keyIds->contains(buffered_keys[i].id)) { - mKeyList->item(i, 0)->setCheckState(Qt::Checked); - } - } +void KeyList::setChecked(const KeyIdArgsListPtr& keyIds) { + if (!keyIds->empty()) { + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (std::find(keyIds->begin(), keyIds->end(), buffered_keys[i].id()) != + keyIds->end()) { + mKeyList->item(i, 0)->setCheckState(Qt::Checked); + } } + } } -QStringList *KeyList::getSelected() { - auto *ret = new QStringList(); +KeyIdArgsListPtr KeyList::getSelected() { + auto ret = std::make_unique<KeyIdArgsList>(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->isSelected() == 1) { - *ret << buffered_keys[i].id; - } + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->isSelected() == 1) { + ret->push_back(buffered_keys[i].id()); } - return ret; + } + return std::move(ret); } [[maybe_unused]] bool KeyList::containsPrivateKeys() { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 1)) { - return true; - } + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 1)) { + return true; } - return false; + } + return false; } void KeyList::setColumnWidth(int row, int size) { - mKeyList->setColumnWidth(row, size); + mKeyList->setColumnWidth(row, size); } -void KeyList::contextMenuEvent(QContextMenuEvent *event) { - if (mKeyList->selectedItems().length() > 0) { - popupMenu->exec(event->globalPos()); - } - +void KeyList::contextMenuEvent(QContextMenuEvent* event) { + if (mKeyList->selectedItems().length() > 0) { + popupMenu->exec(event->globalPos()); + } } void KeyList::addSeparator() { - popupMenu->addSeparator(); + popupMenu->addSeparator(); } -void KeyList::addMenuAction(QAction *act) { - popupMenu->addAction(act); +void KeyList::addMenuAction(QAction* act) { + popupMenu->addAction(act); } -void KeyList::dropEvent(QDropEvent *event) { - - auto *dialog = new QDialog(); - - dialog->setWindowTitle(tr("Import Keys")); - QLabel *label; - label = new QLabel( - tr("You've dropped something on the table.\n GpgFrontend will now try to import key(s).") + "\n"); - - // "always import keys"-CheckBox - auto *checkBox = new QCheckBox(tr("Always import without bothering.")); - if (settings.value("general/confirmImportKeys").toBool()) checkBox->setCheckState(Qt::Unchecked); - - // Buttons for ok and cancel - auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); - - auto *vbox = new QVBoxLayout(); - vbox->addWidget(label); - vbox->addWidget(checkBox); - vbox->addWidget(buttonBox); - - dialog->setLayout(vbox); - - if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { - dialog->exec(); - if (dialog->result() == QDialog::Rejected) { - return; - } - if (checkBox->isChecked()) { - settings.setValue("general/confirmImportKeys", false); - } else { - settings.setValue("general/confirmImportKeys", true); - - } +void KeyList::dropEvent(QDropEvent* event) { + auto* dialog = new QDialog(); + + dialog->setWindowTitle(tr("Import Keys")); + QLabel* label; + label = new QLabel(tr("You've dropped something on the table.\n GpgFrontend " + "will now try to import key(s).") + + "\n"); + + // "always import keys"-CheckBox + auto* checkBox = new QCheckBox(tr("Always import without bothering.")); + if (settings.value("general/confirmImportKeys").toBool()) + checkBox->setCheckState(Qt::Unchecked); + + // Buttons for ok and cancel + auto* buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + + auto* vbox = new QVBoxLayout(); + vbox->addWidget(label); + vbox->addWidget(checkBox); + vbox->addWidget(buttonBox); + + dialog->setLayout(vbox); + + if (settings.value("general/confirmImportKeys", Qt::Checked).toBool()) { + dialog->exec(); + if (dialog->result() == QDialog::Rejected) { + return; } - - if (event->mimeData()->hasUrls()) { - for (const QUrl &tmp : event->mimeData()->urls()) { - QFile file; - file.setFileName(tmp.toLocalFile()); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << tr("Couldn't Open File: ") + tmp.toString(); - } - QByteArray inBuffer = file.readAll(); - this->importKeys(inBuffer); - file.close(); - } + if (checkBox->isChecked()) { + settings.setValue("general/confirmImportKeys", false); } else { - QByteArray inBuffer(event->mimeData()->text().toUtf8()); - this->importKeys(inBuffer); + settings.setValue("general/confirmImportKeys", true); + } + } + + if (event->mimeData()->hasUrls()) { + for (const QUrl& tmp : event->mimeData()->urls()) { + QFile file; + file.setFileName(tmp.toLocalFile()); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << tr("Couldn't Open File: ") + tmp.toString(); + } + QByteArray inBuffer = file.readAll(); + this->importKeys(inBuffer); + file.close(); } + } else { + QByteArray inBuffer(event->mimeData()->text().toUtf8()); + this->importKeys(inBuffer); + } } -void KeyList::dragEnterEvent(QDragEnterEvent *event) { - event->acceptProposedAction(); +void KeyList::dragEnterEvent(QDragEnterEvent* event) { + event->acceptProposedAction(); } /** set background color for Keys and put them to top * */ -[[maybe_unused]] void KeyList::markKeys(QStringList *keyIds) { - foreach(QString id, *keyIds) { - qDebug() << "marked: " << id; - } +[[maybe_unused]] void KeyList::markKeys(QStringList* keyIds) { + foreach (QString id, *keyIds) { qDebug() << "marked: " << id; } } -void KeyList::importKeys(QByteArray inBuffer) { - GpgImportInformation result = mCtx->importKey(std::move(inBuffer)); - new KeyImportDetailDialog(mCtx, result, false, this); +void KeyList::importKeys(const QByteArray& inBuffer) { + auto std_buffer = std::make_unique<ByteArray>(inBuffer.toStdString()); + GpgImportInformation result = + GpgKeyImportExportor::GetInstance().ImportKey(std::move(std_buffer)); + new KeyImportDetailDialog(result, false, this); } -void KeyList::getCheckedKeys(QVector<GpgKey> &keys) { - keys.clear(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked) { - keys.push_back(buffered_keys[i]); - } - } +void KeyList::setExcludeKeys(std::initializer_list<std::string> key_ids) { + excluded_key_ids.clear(); + for (auto& key_id : key_ids) { + excluded_key_ids.push_back(key_id); + } } -void KeyList::setExcludeKeys(std::initializer_list<QString> key_ids) { - excluded_key_ids.clear(); - for (auto &key_id : key_ids) { - excluded_key_ids.push_back(key_id); - } +void KeyList::setFilter(std::function<bool(const GpgKey&)> filter) { + this->mFilter = std::move(filter); } -void KeyList::setFilter(std::function<bool(const GpgKey &)> filter) { - this->mFilter = std::move(filter); +void KeyList::slotDoubleClicked(const QModelIndex& index) { + if (mAction != nullptr) { + const auto key = + GpgKeyGetter::GetInstance().GetKey(buffered_keys[index.row()].id()); + mAction(key, this); + } } -void KeyList::slotDoubleClicked(const QModelIndex &index) { - if (mAction != nullptr) { - const auto key = mCtx->getKeyRefById(buffered_keys[index.row()].id); - mAction(key, this); - } - +void KeyList::setDoubleClickedAction( + std::function<void(const GpgKey&, QWidget*)> action) { + this->mAction = std::move(action); } -void KeyList::setDoubleClickedAction(std::function<void(const GpgKey &, QWidget *)> action) { - this->mAction = std::move(action); -} - -void KeyList::getPrivateCheckedKeys(QVector<GpgKey> &keys) { - keys.clear(); - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->checkState() == Qt::Checked && buffered_keys[i].is_private_key) { - keys.push_back(buffered_keys[i]); - } +std::string KeyList::getSelectedKey() { + for (int i = 0; i < mKeyList->rowCount(); i++) { + if (mKeyList->item(i, 0)->isSelected() == 1) { + return buffered_keys[i].id(); } + } + return {}; } -GpgKey KeyList::getSelectedKey() { - for (int i = 0; i < mKeyList->rowCount(); i++) { - if (mKeyList->item(i, 0)->isSelected() == 1) { - return buffered_keys[i]; - } - } - return GpgKey(); -} +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h new file mode 100644 index 00000000..c1c49c5c --- /dev/null +++ b/src/ui/widgets/KeyList.h @@ -0,0 +1,124 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __KEYLIST_H__ +#define __KEYLIST_H__ + +#include "gpg/GpgContext.h" +#include "ui/KeyImportDetailDialog.h" +namespace GpgFrontend::UI { + +struct KeyListRow { + using KeyType = unsigned int; + + static const KeyType SECRET_OR_PUBLIC_KEY = 0; + static const KeyType ONLY_SECRET_KEY = 1; +}; + +struct KeyListColumn { + using InfoType = unsigned int; + + static constexpr InfoType ALL = ~0; + static constexpr InfoType TYPE = 1 << 0; + static constexpr InfoType NAME = 1 << 1; + static constexpr InfoType EmailAddress = 1 << 2; + static constexpr InfoType Usage = 1 << 3; + static constexpr InfoType Validity = 1 << 4; + static constexpr InfoType FingerPrint = 1 << 5; +}; + +class KeyList : public QWidget { + Q_OBJECT + + public: + explicit KeyList( + KeyListRow::KeyType selectType = KeyListRow::SECRET_OR_PUBLIC_KEY, + KeyListColumn::InfoType infoType = KeyListColumn::ALL, + QWidget* parent = nullptr); + + void setExcludeKeys(std::initializer_list<std::string> key_ids); + + void setFilter(std::function<bool(const GpgKey&)> filter); + + void setDoubleClickedAction( + std::function<void(const GpgKey&, QWidget*)> action); + + void setColumnWidth(int row, int size); + + void addMenuAction(QAction* act); + + void addSeparator(); + + KeyIdArgsListPtr getChecked(); + + KeyIdArgsListPtr getPrivateChecked(); + + KeyIdArgsListPtr getAllPrivateKeys(); + + void setChecked(const KeyIdArgsListPtr& keyIds); + + KeyIdArgsListPtr getSelected(); + + std::string getSelectedKey(); + + [[maybe_unused]] static void markKeys(QStringList* keyIds); + + [[maybe_unused]] bool containsPrivateKeys(); + + public slots: + + void slotRefresh(); + + private: + void importKeys(const QByteArray& inBuffer); + + QString appPath; + QSettings settings; + + QTableWidget* mKeyList; + QMenu* popupMenu; + QNetworkAccessManager* qnam{}; + std::vector<GpgKey> buffered_keys; + KeyListRow::KeyType mSelectType; + KeyListColumn::InfoType mInfoType; + std::vector<std::string> excluded_key_ids; + + std::function<bool(const GpgKey&)> mFilter = nullptr; + std::function<void(const GpgKey&, QWidget*)> mAction = nullptr; + + private slots: + + void slotDoubleClicked(const QModelIndex& index); + + protected: + void contextMenuEvent(QContextMenuEvent* event) override; + + void dragEnterEvent(QDragEnterEvent* event) override; + + void dropEvent(QDropEvent* event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // __KEYLIST_H__ diff --git a/src/ui/widgets/SignersPicker.cpp b/src/ui/widgets/SignersPicker.cpp index b48752c7..58dc8dbc 100644 --- a/src/ui/widgets/SignersPicker.cpp +++ b/src/ui/widgets/SignersPicker.cpp @@ -24,36 +24,42 @@ #include "ui/widgets/SignersPicker.h" -SignersPicker::SignersPicker(GpgFrontend::GpgContext *ctx, QWidget *parent) : mCtx(ctx), QDialog(parent) { - auto confirmButton = new QPushButton(tr("Confirm")); - connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept())); +namespace GpgFrontend::UI { - /*Setup KeyList*/ - mKeyList = new KeyList(mCtx, KeyListRow::ONLY_SECRET_KEY, - KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); +SignersPicker::SignersPicker(GpgFrontend::GpgContext* ctx, QWidget* parent) + : mCtx(ctx), QDialog(parent) { + auto confirmButton = new QPushButton(tr("Confirm")); + connect(confirmButton, SIGNAL(clicked(bool)), this, SLOT(accept())); - mKeyList->setFilter([](const GpgKey &key) -> bool { - if (!GpgFrontend::GpgContext::checkIfKeyCanSign(key)) return false; - else return true; - }); + /*Setup KeyList*/ + mKeyList = new KeyList( + mCtx, KeyListRow::ONLY_SECRET_KEY, + KeyListColumn::NAME | KeyListColumn::EmailAddress | KeyListColumn::Usage); - mKeyList->slotRefresh(); + mKeyList->setFilter([](const GpgKey& key) -> bool { + if (!GpgFrontend::GpgContext::checkIfKeyCanSign(key)) + return false; + else + return true; + }); - auto *vbox2 = new QVBoxLayout(); - vbox2->addWidget(new QLabel("Select Signer(s): ")); - vbox2->addWidget(mKeyList); - vbox2->addWidget(confirmButton); - vbox2->addStretch(0); - setLayout(vbox2); - - this->setModal(true); - this->setWindowTitle("Signers Picker"); - this->setMinimumWidth(480); - this->show(); + mKeyList->slotRefresh(); + auto* vbox2 = new QVBoxLayout(); + vbox2->addWidget(new QLabel("Select Signer(s): ")); + vbox2->addWidget(mKeyList); + vbox2->addWidget(confirmButton); + vbox2->addStretch(0); + setLayout(vbox2); + this->setModal(true); + this->setWindowTitle("Signers Picker"); + this->setMinimumWidth(480); + this->show(); } -void SignersPicker::getCheckedSigners(QVector<GpgKey> &keys) { - mKeyList->getPrivateCheckedKeys(keys); +void SignersPicker::getCheckedSigners(QVector<GpgKey>& keys) { + mKeyList->getPrivateCheckedKeys(keys); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/SignersPicker.h b/src/ui/widgets/SignersPicker.h new file mode 100644 index 00000000..17c57e62 --- /dev/null +++ b/src/ui/widgets/SignersPicker.h @@ -0,0 +1,51 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H +#define GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H + +#include "GpgFrontend.h" +#include "gpg/GpgContext.h" + +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class SignersPicker : public QDialog { + Q_OBJECT + + public: + explicit SignersPicker(GpgFrontend::GpgContext* ctx, + QWidget* parent = nullptr); + + void getCheckedSigners(QVector<GpgKey>& keys); + + private: + GpgFrontend::GpgContext* mCtx; + KeyList* mKeyList; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_ZH_CN_TS_SIGNERSPIRCKER_H diff --git a/src/ui/widgets/TextEdit.cpp b/src/ui/widgets/TextEdit.cpp index eab0f799..db60cca7 100644 --- a/src/ui/widgets/TextEdit.cpp +++ b/src/ui/widgets/TextEdit.cpp @@ -24,14 +24,16 @@ #include "ui/widgets/TextEdit.h" -TextEdit::TextEdit(QWidget *parent) : QWidget(parent) { +namespace GpgFrontend::UI { + +TextEdit::TextEdit(QWidget* parent) : QWidget(parent) { countPage = 0; tabWidget = new QTabWidget(this); tabWidget->setMovable(true); tabWidget->setTabsClosable(true); tabWidget->setDocumentMode(true); - auto *layout = new QVBoxLayout; + auto* layout = new QVBoxLayout; layout->addWidget(tabWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -52,7 +54,7 @@ TextEdit::TextEdit(QWidget *parent) : QWidget(parent) { void TextEdit::slotNewTab() { QString header = tr("untitled") + QString::number(++countPage) + ".txt"; - auto *page = new EditorPage(); + auto* page = new EditorPage(); tabWidget->addTab(page, header); tabWidget->setCurrentIndex(tabWidget->count() - 1); page->getTextPage()->setFocus(); @@ -60,28 +62,25 @@ void TextEdit::slotNewTab() { this, SLOT(slotShowModified())); } -void TextEdit::slotNewHelpTab(const QString &title, const QString &path) const { - - auto *page = new HelpPage(path); +void TextEdit::slotNewHelpTab(const QString& title, const QString& path) const { + auto* page = new HelpPage(path); tabWidget->addTab(page, title); tabWidget->setCurrentIndex(tabWidget->count() - 1); } void TextEdit::slotNewFileTab() const { - - auto *page = new FilePage(qobject_cast<QWidget *>(parent())); + auto* page = new FilePage(qobject_cast<QWidget*>(parent())); tabWidget->addTab(page, "[Browser]"); tabWidget->setCurrentIndex(tabWidget->count() - 1); - connect(page, SIGNAL(pathChanged(const QString &)), this, - SLOT(slotFilePagePathChanged(const QString &))); + connect(page, SIGNAL(pathChanged(const QString&)), this, + SLOT(slotFilePagePathChanged(const QString&))); } -void TextEdit::slotOpenFile(QString &path) { - +void TextEdit::slotOpenFile(QString& path) { QFile file(path); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto *page = new EditorPage(path); + auto* page = new EditorPage(path); pagesHashMap.insert(page->uuid, page); QApplication::setOverrideCursor(Qt::WaitCursor); @@ -104,7 +103,7 @@ void TextEdit::slotOpenFile(QString &path) { }); page->setFilePath(path); - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); document->setModified(false); tabWidget->addTab(page, strippedName(path)); @@ -122,11 +121,11 @@ void TextEdit::slotOpenFile(QString &path) { } } -void TextEdit::slotInsertTargetTextPage(const QString &pagePtr, - const QString &text) { +void TextEdit::slotInsertTargetTextPage(const QString& pagePtr, + const QString& text) { auto it = pagesHashMap.find(pagePtr); if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); + auto* taregtTextPage = qobject_cast<EditorPage*>(it.value()); if (taregtTextPage != nullptr) { taregtTextPage->getTextPage()->insertPlainText(text); taregtTextPage->getTextPage()->document()->setModified(false); @@ -134,10 +133,10 @@ void TextEdit::slotInsertTargetTextPage(const QString &pagePtr, } } -void TextEdit::slotReadTargetTextPageStart(const QString &pagePtr) { +void TextEdit::slotReadTargetTextPageStart(const QString& pagePtr) { auto it = pagesHashMap.find(pagePtr); if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); + auto* taregtTextPage = qobject_cast<EditorPage*>(it.value()); if (taregtTextPage != nullptr) { qDebug() << "Setting TextEdit At Start" << pagePtr; taregtTextPage->getTextPage()->setReadOnly(true); @@ -150,10 +149,10 @@ void TextEdit::slotReadTargetTextPageStart(const QString &pagePtr) { } } -void TextEdit::slotReadTargetTextPageDone(const QString &pagePtr) { +void TextEdit::slotReadTargetTextPageDone(const QString& pagePtr) { auto it = pagesHashMap.find(pagePtr); if (it != pagesHashMap.end()) { - auto *taregtTextPage = qobject_cast<EditorPage *>(it.value()); + auto* taregtTextPage = qobject_cast<EditorPage*>(it.value()); if (taregtTextPage != nullptr) { qDebug() << "Setting TextEdit At End" << pagePtr; taregtTextPage->getTextPage()->setReadOnly(false); @@ -173,18 +172,18 @@ void TextEdit::slotReadTargetTextPageDone(const QString &pagePtr) { void TextEdit::slotOpen() { QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath()); - for (const auto &fileName : fileNames) { + for (const auto& fileName : fileNames) { if (!fileName.isEmpty()) { QFile file(fileName); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - auto *page = new EditorPage(fileName); + auto* page = new EditorPage(fileName); QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); page->getTextPage()->setPlainText(in.readAll()); page->setFilePath(fileName); - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); document->setModified(false); tabWidget->addTab(page, strippedName(fileName)); @@ -222,7 +221,7 @@ void TextEdit::slotSave() { } } -bool TextEdit::saveFile(const QString &fileName) { +bool TextEdit::saveFile(const QString& fileName) { if (fileName.isEmpty()) { return false; } @@ -230,13 +229,13 @@ bool TextEdit::saveFile(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); QTextStream outputStream(&file); QApplication::setOverrideCursor(Qt::WaitCursor); outputStream << page->getTextPage()->toPlainText(); QApplication::restoreOverrideCursor(); - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); document->setModified(false); @@ -259,7 +258,7 @@ bool TextEdit::slotSaveAs() { return true; } - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); QString path; if (page->getFilePath() != "") { path = page->getFilePath(); @@ -312,13 +311,12 @@ void TextEdit::removeTab(int index) { * If it returns false, the close event should be aborted. */ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { - - EditorPage *page = slotCurPageTextEdit(); + EditorPage* page = slotCurPageTextEdit(); // if this page is no textedit, there should be nothing to save if (page == nullptr) { return true; } - QTextDocument *document = page->getTextPage()->document(); + QTextDocument* document = page->getTextPage()->document(); if (document->isModified()) { QMessageBox::StandardButton result = QMessageBox::Cancel; @@ -327,7 +325,7 @@ bool TextEdit::maybeSaveCurrentTab(bool askToSave) { QString docname = tabWidget->tabText(tabWidget->currentIndex()); docname.remove(0, 2); - const QString &filePath = page->getFilePath(); + const QString& filePath = page->getFilePath(); if (askToSave) { result = QMessageBox::warning( this, tr("Unsaved document"), @@ -381,7 +379,7 @@ bool TextEdit::maybeSaveAnyTab() { if (unsavedDocs.size() > 1) { QHashIterator<int, QString> i(unsavedDocs); - QuitDialog *dialog; + QuitDialog* dialog; dialog = new QuitDialog(this, unsavedDocs); int result = dialog->exec(); @@ -414,8 +412,8 @@ bool TextEdit::maybeSaveAnyTab() { return false; } -QTextEdit *TextEdit::curTextPage() const { - auto *curTextPage = qobject_cast<EditorPage *>(tabWidget->currentWidget()); +QTextEdit* TextEdit::curTextPage() const { + auto* curTextPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); if (curTextPage != nullptr) { return curTextPage->getTextPage(); } else { @@ -423,8 +421,8 @@ QTextEdit *TextEdit::curTextPage() const { } } -FilePage *TextEdit::curFilePage() const { - auto *curFilePage = qobject_cast<FilePage *>(tabWidget->currentWidget()); +FilePage* TextEdit::curFilePage() const { + auto* curFilePage = qobject_cast<FilePage*>(tabWidget->currentWidget()); if (curFilePage != nullptr) { return curFilePage; } else { @@ -432,15 +430,17 @@ FilePage *TextEdit::curFilePage() const { } } -int TextEdit::tabCount() const { return tabWidget->count(); } +int TextEdit::tabCount() const { + return tabWidget->count(); +} -EditorPage *TextEdit::slotCurPageTextEdit() const { - auto *curPage = qobject_cast<EditorPage *>(tabWidget->currentWidget()); +EditorPage* TextEdit::slotCurPageTextEdit() const { + auto* curPage = qobject_cast<EditorPage*>(tabWidget->currentWidget()); return curPage; } -FilePage *TextEdit::slotCurPageFileTreeView() const { - auto *curPage = qobject_cast<FilePage *>(tabWidget->currentWidget()); +FilePage* TextEdit::slotCurPageFileTreeView() const { + auto* curPage = qobject_cast<FilePage*>(tabWidget->currentWidget()); return curPage; } @@ -466,7 +466,7 @@ void TextEdit::slotQuote() const { cursor.endEditBlock(); } -void TextEdit::slotFillTextEditWithText(const QString &text) const { +void TextEdit::slotFillTextEditWithText(const QString& text) const { QTextCursor cursor(curTextPage()->document()); cursor.beginEditBlock(); this->curTextPage()->selectAll(); @@ -474,7 +474,7 @@ void TextEdit::slotFillTextEditWithText(const QString &text) const { cursor.endEditBlock(); } -void TextEdit::loadFile(const QString &fileName) { +void TextEdit::loadFile(const QString& fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning( @@ -492,7 +492,7 @@ void TextEdit::loadFile(const QString &fileName) { // statusBar()->showMessage(tr("File loaded"), 2000); } -QString TextEdit::strippedName(const QString &fullFileName) { +QString TextEdit::strippedName(const QString& fullFileName) { return QFileInfo(fullFileName).fileName(); } @@ -502,13 +502,13 @@ void TextEdit::slotPrint() { } #ifndef QT_NO_PRINTER - QTextDocument *document; + QTextDocument* document; if (curTextPage() != nullptr) { document = curTextPage()->document(); } QPrinter printer; - auto *dlg = new QPrintDialog(&printer, this); + auto* dlg = new QPrintDialog(&printer, this); if (dlg->exec() != QDialog::Accepted) { return; } @@ -549,11 +549,11 @@ void TextEdit::slotSwitchTabDown() const { * return a hash of tabindexes and title of unsaved tabs */ QHash<int, QString> TextEdit::unsavedDocuments() const { - QHash<int, QString> unsavedDocs; // this list could be used to implement gedit - // like "unsaved changed"-dialog + QHash<int, QString> unsavedDocs; // this list could be used to implement + // gedit like "unsaved changed"-dialog for (int i = 0; i < tabWidget->count(); i++) { - auto *ep = qobject_cast<EditorPage *>(tabWidget->widget(i)); + auto* ep = qobject_cast<EditorPage*>(tabWidget->widget(i)); if (ep != nullptr && ep->getTextPage()->document()->isModified()) { QString docname = tabWidget->tabText(i); // remove * before name of modified doc @@ -633,7 +633,7 @@ void TextEdit::slotSelectAll() const { curTextPage()->selectAll(); } -void TextEdit::slotFilePagePathChanged(const QString &path) { +void TextEdit::slotFilePagePathChanged(const QString& path) { int index = tabWidget->currentIndex(); QString mPath; QFileInfo fileInfo(path); @@ -647,3 +647,5 @@ void TextEdit::slotFilePagePathChanged(const QString &path) { mPath.append("/"); tabWidget->setTabText(index, mPath); } + +} // namespace GpgFrontend::UI diff --git a/src/ui/widgets/TextEdit.h b/src/ui/widgets/TextEdit.h new file mode 100644 index 00000000..6af70345 --- /dev/null +++ b/src/ui/widgets/TextEdit.h @@ -0,0 +1,301 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __TEXTEDIT_H__ +#define __TEXTEDIT_H__ + +#include "ui/QuitDialog.h" +#include "ui/widgets/EditorPage.h" +#include "ui/widgets/FilePage.h" +#include "ui/widgets/HelpPage.h" + +namespace GpgFrontend::UI { +/** + * @brief TextEdit class + */ +class TextEdit : public QWidget { + Q_OBJECT + public: + /** + * @brief + */ + TextEdit(QWidget* parent); + + /** + * @details Load the content of file into the current textpage + * + * @param fileName QString containing the filename to load + * @return nothing + */ + void loadFile(const QString& fileName); + + /** + * @details Checks if there are unsaved documents in any tab, + * which may need to be saved. Call this function before + * closing the programme or all tabs. + * @return \li false, if the close event should be aborted. + * \li true, otherwise + */ + bool maybeSaveAnyTab(); + + [[nodiscard]] int tabCount() const; + + /** + * @details textpage of the currently activated tab + * @return \li reference to QTextEdit if tab has one + * \li 0 otherwise (e.g. if helppage) + */ + [[nodiscard]] QTextEdit* curTextPage() const; + + [[nodiscard]] FilePage* curFilePage() const; + + /** + * @details List of currently unsaved tabs. + * @returns QHash<int, QString> Hash of tabindexes and title of unsaved tabs. + */ + [[nodiscard]] QHash<int, QString> unsavedDocuments() const; + + QTabWidget* tabWidget; /** Widget containing the tabs of the editor */ + + public slots: + + /** + * @details Return pointer to the currently activated text edit tab page. + * + */ + [[nodiscard]] EditorPage* slotCurPageTextEdit() const; + + /** + * @details Return pointer to the currently activated file treeview tab page. + * + */ + [[nodiscard]] FilePage* slotCurPageFileTreeView() const; + + /** + * @details Insert a ">" at the begining of every line of current textedit. + */ + void slotQuote() const; + + /** + * @details replace the text of currently active textedit with given text. + * @param text to fill on. + */ + void slotFillTextEditWithText(const QString& text) const; + + /** + * @details Saves the content of the current tab, if it has a filepath + * otherwise it calls saveAs for the current tab + */ + void slotSave(); + + /** + * @details Opens a savefiledialog and calls saveFile with the choosen + * filename. + * + * @return Return the return value of the savefile method + */ + bool slotSaveAs(); + + /** + * @details Show an OpenFileDoalog and open the file in a new tab. + * Shows an error dialog, if the open fails. + * Set the focus to the tab of the opened file. + */ + void slotOpen(); + + /** + * @details Open a print-dialog for the current tab + */ + void slotPrint(); + + /** + * @details Adds a new tab with the title "untitled"+countpage+".txt" + * Sets the focus to the new tab. Increase Tab-Count by + * one + */ + void slotNewTab(); + + /** + * @details Adds a new tab with opening file by path + */ + void slotOpenFile(QString& path); + + /** + * @details Adds a new tab with the given title and opens given html file. + * Increase Tab-Count by one + * @param title title for the tab + * @param path path for html file to show + */ + void slotNewHelpTab(const QString& title, const QString& path) const; + + /** + * New File Tab to do file operation + */ + void slotNewFileTab() const; + + /** + * @details put a * in front of current tabs title, if current textedit is + * modified + */ + void slotShowModified() const; + + /** + * @details close the current tab and decrease TabWidget->count by \a 1 + * + */ + void slotCloseTab(); + + /** + * @details Switch to the next tab. + * + */ + void slotSwitchTabUp() const; + + /** + * @details Switch to the previous tab. + * + */ + void slotSwitchTabDown() const; + + /** + * @details Insert text in target Text Edit + */ + void slotInsertTargetTextPage(const QString& pagePtr, const QString& text); + + void slotReadTargetTextPageStart(const QString& pageStr); + + void slotReadTargetTextPageDone(const QString& pagePtr); + + signals: + + void readTargetTextPageStart(const QString& pagePtr); + + void insertTargetTextPage(const QString& pagePtr, const QString& text); + + void readTargetTextPageDone(const QString& pagePtr); + + private: + /** + * @details return just a filename stripped of a whole path + * + * @param a filename path + * @return QString containing the filename + */ + static QString strippedName(const QString& fullFileName); + + /** + * @brief + * + * @param askToSave + */ + bool maybeSaveCurrentTab(bool askToSave); + + /**************************************************************************************** + * Name: countPage + * Description: int cotaining the number of added tabs + */ + int countPage; /* TODO */ + + QHash<const QString, QWidget*> pagesHashMap; + + private slots: + + void slotFilePagePathChanged(const QString& path); + + /** + * @details Remove the tab with given index + * + * @param index Tab-number to remove + */ + void removeTab(int index); + + /** + * @details Cut selected text in current textpage. + */ + void slotCut() const; + + /** + * @details Copy selected text of current textpage to clipboard. + */ + void slotCopy() const; + + /** + * @details Paste text from clipboard to current textpage. + */ + void slotPaste() const; + + /** + * @details Undo last change in current textpage. + * + */ + void slotUndo() const; + /**************************************************************************************** + * Name: redo + * Description: redo last change in current textpage + * Parameters: none + * Return Values: none + * Change on members: none + */ + /** + * @brief + * + */ + void slotRedo() const; + + void slotZoomIn() const; + + void slotZoomOut() const; + /**************************************************************************************** + * Name: selectAll + * Description: select all in current textpage + * Parameters: none + * Return Values: none + * Change on members: none + */ + /** + * @brief + * + */ + void slotSelectAll() const; + + protected: + /**************************************************************************************** + * Name: saveFile + * Description: Saves the content of currentTab to the file filename + * Parameters: QString filename contains the full path of the file to + * save Return Values: true, if the file was saved succesfully false, if + * parameter filename is empty or the saving failed Change on members: sets + * isModified of the current tab to false + */ + /** + * @brief + * + * @param fileName + */ + bool saveFile(const QString& fileName); +}; + +} // namespace GpgFrontend::UI + +#endif // __TEXTEDIT_H__ diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp index 4d88389c..76af201d 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.cpp +++ b/src/ui/widgets/VerifyKeyDetailBox.cpp @@ -24,180 +24,193 @@ #include "ui/widgets/VerifyKeyDetailBox.h" -VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget *parent, GpgFrontend::GpgContext *ctx, KeyList *keyList, - gpgme_signature_t signature) : - QGroupBox(parent), mCtx(ctx), mKeyList(keyList), fpr(signature->fpr) { +#include "gpg/function/GpgKeyGetter.h" - auto *vbox = new QVBoxLayout(); +namespace GpgFrontend::UI { - switch (gpg_err_code(signature->status)) { - case GPG_ERR_NO_PUBKEY: { - this->setTitle("A Error Signature"); - auto *importButton = new QPushButton(tr("Import from keyserver")); - connect(importButton, SIGNAL(clicked()), this, SLOT(slotImportFormKeyserver())); +VerifyKeyDetailBox::VerifyKeyDetailBox(QWidget* parent, + KeyList* keyList, + gpgme_signature_t signature) + : QGroupBox(parent), mKeyList(keyList), fpr(signature->fpr) { + auto* vbox = new QVBoxLayout(); - this->setTitle(tr("Key not present with id 0x") + signature->fpr); + switch (gpg_err_code(signature->status)) { + case GPG_ERR_NO_PUBKEY: { + this->setTitle("A Error Signature"); + auto* importButton = new QPushButton(tr("Import from keyserver")); + connect(importButton, SIGNAL(clicked()), this, + SLOT(slotImportFormKeyserver())); - auto grid = new QGridLayout(); + this->setTitle(tr("Key not present with id 0x") + signature->fpr); - grid->addWidget(new QLabel(tr("Status:")), 0, 0); - //grid->addWidget(new QLabel(tr("Fingerprint:")), 1, 0); - grid->addWidget(new QLabel(tr("Key not present in keylist")), 0, 1); - //grid->addWidget(new QLabel(signature->fpr), 1, 1); - grid->addWidget(importButton, 2, 0, 2, 1); + auto grid = new QGridLayout(); - vbox->addLayout(grid); - break; - } - case GPG_ERR_NO_ERROR: { - this->setTitle("A Signature:"); - auto gird = createKeyInfoGrid(signature); - if(gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + grid->addWidget(new QLabel(tr("Status:")), 0, 0); + // grid->addWidget(new QLabel(tr("Fingerprint:")), 1, 0); + grid->addWidget(new QLabel(tr("Key not present in keylist")), 0, 1); + // grid->addWidget(new QLabel(signature->fpr), 1, 1); + grid->addWidget(importButton, 2, 0, 2, 1); + + vbox->addLayout(grid); + break; + } + case GPG_ERR_NO_ERROR: { + this->setTitle("A Signature:"); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } - case GPG_ERR_CERT_REVOKED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Cert Revoked"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_CERT_REVOKED: { + this->setTitle("An Error Signature"); + vbox->addWidget(new QLabel(tr("Status: Cert Revoked"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } - case GPG_ERR_SIG_EXPIRED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_SIG_EXPIRED: { + this->setTitle("An Error Signature"); + vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } - case GPG_ERR_KEY_EXPIRED: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); - vbox->addWidget(new QLabel(tr("Status: Key Expired"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_KEY_EXPIRED: { + this->setTitle("An Error Signature"); + vbox->addWidget(new QLabel(tr("Status: Signature Expired"))); + vbox->addWidget(new QLabel(tr("Status: Key Expired"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } - case GPG_ERR_GENERAL: { - this->setTitle("An Error Signature"); - vbox->addWidget(new QLabel(tr("Status: General Error"))); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + case GPG_ERR_GENERAL: { + this->setTitle("An Error Signature"); + vbox->addWidget(new QLabel(tr("Status: General Error"))); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } - default: { - this->setTitle("An Error Signature"); - this->setTitle(tr("Status: Unknown Error")); - auto gird = createKeyInfoGrid(signature); - if (gird != nullptr) { - vbox->addLayout(gird); - } else { - vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); - if(signature->fpr != nullptr) { - vbox->addWidget(new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); - } - } - break; + } + break; + } + default: { + this->setTitle("An Error Signature"); + this->setTitle(tr("Status: Unknown Error")); + auto gird = createKeyInfoGrid(signature); + if (gird != nullptr) { + vbox->addLayout(gird); + } else { + vbox->addWidget(new QLabel(tr("Key Information is NOT Available"))); + if (signature->fpr != nullptr) { + vbox->addWidget( + new QLabel(tr("Fingerprint: ") + QString(signature->fpr))); } + } + break; } - this->setLayout(vbox); + } + this->setLayout(vbox); } void VerifyKeyDetailBox::slotImportFormKeyserver() { - auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, false, this); - importDialog->slotImport(QStringList(fpr)); + auto* importDialog = new KeyServerImportDialog(mKeyList, false, this); + importDialog->slotImport(QStringList(fpr)); } QString VerifyKeyDetailBox::beautifyFingerprint(QString fingerprint) { - uint len = fingerprint.length(); - if ((len > 0) && (len % 4 == 0)) - for (uint n = 0; 4 * (n + 1) < len; ++n) - fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); - return fingerprint; + uint len = fingerprint.length(); + if ((len > 0) && (len % 4 == 0)) + for (uint n = 0; 4 * (n + 1) < len; ++n) + fingerprint.insert(static_cast<int>(5u * n + 4u), ' '); + return fingerprint; } -QGridLayout *VerifyKeyDetailBox::createKeyInfoGrid(gpgme_signature_t &signature) { - - auto grid = new QGridLayout(); - GpgKey key = mCtx->getKeyRefByFpr(signature->fpr); - - if(!key.good) return nullptr; - grid->addWidget(new QLabel(tr("Signer Name:")), 0, 0); - grid->addWidget(new QLabel(tr("Signer Email:")), 1, 0); - grid->addWidget(new QLabel(tr("Key's Fingerprint:")), 2, 0); - grid->addWidget(new QLabel(tr("Valid:")), 3, 0); - grid->addWidget(new QLabel(tr("Flags:")), 4, 0); - - grid->addWidget(new QLabel(key.name), 0, 1); - grid->addWidget(new QLabel(key.email), 1, 1); - grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1); - - - if(signature->summary & GPGME_SIGSUM_VALID) { - grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1); - } else { - grid->addWidget(new QLabel(tr("NOT Fully Valid")), 3, 1); - } - - QString flags; - QTextStream textStream(&flags); - - if(signature->summary & GPGME_SIGSUM_GREEN) { - textStream << tr("Good "); - } - if(signature->summary & GPGME_SIGSUM_RED) { - textStream << tr("Bad "); - } - if(signature->summary & GPGME_SIGSUM_SIG_EXPIRED) { - textStream << tr("Expired "); - } - if(signature->summary & GPGME_SIGSUM_KEY_MISSING) { - textStream << tr("Missing Key "); - } - if(signature->summary & GPGME_SIGSUM_KEY_REVOKED) { - textStream << tr("Revoked Key "); - } - if(signature->summary & GPGME_SIGSUM_KEY_EXPIRED) { - textStream << tr("Expired Key "); - } - if(signature->summary & GPGME_SIGSUM_CRL_MISSING) { - textStream << tr("Missing CRL "); - } - - grid->addWidget(new QLabel(tr(flags.toUtf8().constData())), 4, 1); - return grid; +QGridLayout* VerifyKeyDetailBox::createKeyInfoGrid( + gpgme_signature_t& signature) { + auto grid = new QGridLayout(); + GpgKey key = GpgKeyGetter::GetInstance().GetKey(signature->fpr); + + if (!key.good()) + return nullptr; + grid->addWidget(new QLabel(tr("Signer Name:")), 0, 0); + grid->addWidget(new QLabel(tr("Signer Email:")), 1, 0); + grid->addWidget(new QLabel(tr("Key's Fingerprint:")), 2, 0); + grid->addWidget(new QLabel(tr("Valid:")), 3, 0); + grid->addWidget(new QLabel(tr("Flags:")), 4, 0); + + grid->addWidget(new QLabel(QString::fromStdString(key.name())), 0, 1); + grid->addWidget(new QLabel(QString::fromStdString(key.email())), 1, 1); + grid->addWidget(new QLabel(beautifyFingerprint(signature->fpr)), 2, 1); + + if (signature->summary & GPGME_SIGSUM_VALID) { + grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1); + } else { + grid->addWidget(new QLabel(tr("NOT Fully Valid")), 3, 1); + } + + QString flags; + QTextStream textStream(&flags); + + if (signature->summary & GPGME_SIGSUM_GREEN) { + textStream << tr("Good "); + } + if (signature->summary & GPGME_SIGSUM_RED) { + textStream << tr("Bad "); + } + if (signature->summary & GPGME_SIGSUM_SIG_EXPIRED) { + textStream << tr("Expired "); + } + if (signature->summary & GPGME_SIGSUM_KEY_MISSING) { + textStream << tr("Missing Key "); + } + if (signature->summary & GPGME_SIGSUM_KEY_REVOKED) { + textStream << tr("Revoked Key "); + } + if (signature->summary & GPGME_SIGSUM_KEY_EXPIRED) { + textStream << tr("Expired Key "); + } + if (signature->summary & GPGME_SIGSUM_CRL_MISSING) { + textStream << tr("Missing CRL "); + } + + grid->addWidget(new QLabel(tr(flags.toUtf8().constData())), 4, 1); + return grid; } + +} // namespace GpgFrontend::UI
\ No newline at end of file diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h new file mode 100644 index 00000000..7a6ded4e --- /dev/null +++ b/src/ui/widgets/VerifyKeyDetailBox.h @@ -0,0 +1,56 @@ +/** + * This file is part of GPGFrontend. + * + * GPGFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Foobar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from gpg4usb-team. + * Their source code version also complies with GNU General Public License. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]> starting on May 12, 2021. + * + */ + +#ifndef __VERIFYKEYDETAILBOX_H__ +#define __VERIFYKEYDETAILBOX_H__ + +#include "ui/KeyServerImportDialog.h" +#include "ui/widgets/KeyList.h" + +namespace GpgFrontend::UI { + +class VerifyKeyDetailBox : public QGroupBox { + Q_OBJECT + public: + explicit VerifyKeyDetailBox(QWidget* parent, + KeyList* mKeyList, + gpgme_signature_t signature); + + private slots: + + void slotImportFormKeyserver(); + + private: + KeyList* mKeyList; + + static QString beautifyFingerprint(QString fingerprint); + + static QGridLayout* createKeyInfoGrid(gpgme_signature_t& signature); + + QString fpr; +}; + +} // namespace GpgFrontend::UI + +#endif // __VERIFYKEYDETAILBOX_H__ |