diff options
Diffstat (limited to '')
25 files changed, 444 insertions, 368 deletions
diff --git a/include/MainWindow.h b/include/MainWindow.h index c8efd63c..b4dc9b44 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -32,7 +32,7 @@ #include "ui/FileEncryptionDialog.h" #include "ui/SettingsDialog.h" #include "ui/AboutDialog.h" -#include "ui/VerifyNotification.h" +#include "ui/widgets/InfoBoardWidget.h" #include "ui/FindWidget.h" #include "ui/Wizard.h" @@ -300,6 +300,7 @@ private: QToolButton *fileEncButton; /** Toolbutton for file cryption dropdown menu in toolbar */ QDockWidget *keylistDock; /** Encrypt Dock*/ QDockWidget *attachmentDock; /** Attachment Dock */ + QDockWidget *infoBoardDock; [[maybe_unused]] QDialog *genkeyDialog; /** Dialog for key generation */ QAction *newTabAct; /** Action to create new tab */ @@ -351,6 +352,7 @@ private: QLabel *statusBarIcon; /**< TODO */ QSettings settings; /**< TODO */ KeyList *mKeyList; /**< TODO */ + InfoBoardWidget *infoBoard; Attachments *mAttachments; /**< TODO */ GpgME::GpgContext *mCtx; /**< TODO */ KeyMgmt *keyMgmt; /**< TODO */ diff --git a/include/gpg/GpgContext.h b/include/gpg/GpgContext.h index 41fdca55..600d7c57 100644 --- a/include/gpg/GpgContext.h +++ b/include/gpg/GpgContext.h @@ -101,17 +101,17 @@ namespace GpgME { bool signKey(const GpgKey &target, const QString& uid, const QDateTime *expires); - bool revSign(const GpgKey &key, const Signature &signature); + bool revSign(const GpgKey &key, const GpgKeySignature &signature); gpgme_signature_t verify(QByteArray *inBuffer, QByteArray *sigBuffer = nullptr); bool sign(QVector<GpgKey> keys, const QByteArray &inBuffer, QByteArray *outBuffer, bool detached = false); - bool addUID(const GpgKey &key, const UID &uid); + bool addUID(const GpgKey &key, const GpgUID &uid); - bool revUID(const GpgKey &key, const UID &uid); + bool revUID(const GpgKey &key, const GpgUID &uid); - bool setPrimaryUID(const GpgKey &key, const UID &uid); + bool setPrimaryUID(const GpgKey &key, const GpgUID &uid); bool setExpire(const GpgKey &key, const GpgSubKey *subkey, QDateTime *expires); diff --git a/include/gpg/GpgKey.h b/include/gpg/GpgKey.h index f83a2a1e..9bf33111 100644 --- a/include/gpg/GpgKey.h +++ b/include/gpg/GpgKey.h @@ -25,7 +25,7 @@ #ifndef GPGFRONTEND_GPGKEY_H #define GPGFRONTEND_GPGKEY_H -#include "UID.h" +#include "GpgUID.h" #include "GpgSubKey.h" class GpgKey { @@ -62,7 +62,7 @@ public: QVector<GpgSubKey> subKeys; - QVector<UID> uids; + QVector<GpgUID> uids; gpgme_key_t key_refer = nullptr; diff --git a/include/gpg/Signature.h b/include/gpg/GpgKeySignature.h index 4d69c90b..05a212a7 100644 --- a/include/gpg/Signature.h +++ b/include/gpg/GpgKeySignature.h @@ -22,12 +22,12 @@ * */ -#ifndef GPGFRONTEND_SIGNATURE_H -#define GPGFRONTEND_SIGNATURE_H +#ifndef GPGFRONTEND_GPGKEYSIGNATURE_H +#define GPGFRONTEND_GPGKEYSIGNATURE_H #include "GpgFrontend.h" -struct Signature { +struct GpgKeySignature { bool revoked{}; bool expired{}; @@ -47,16 +47,18 @@ struct Signature { QString email; QString comment; - Signature() = default; + gpgme_sigsum_t summary; - explicit Signature(gpgme_key_sig_t key_sig); + GpgKeySignature() = default; - Signature(Signature &&) noexcept = default; - Signature(const Signature &) = default; - Signature& operator=(Signature &&) noexcept = default; - Signature& operator=(const Signature &) = default; + explicit GpgKeySignature(gpgme_key_sig_t key_sig); + + GpgKeySignature(GpgKeySignature &&) noexcept = default; + GpgKeySignature(const GpgKeySignature &) = default; + GpgKeySignature& operator=(GpgKeySignature &&) noexcept = default; + GpgKeySignature& operator=(const GpgKeySignature &) = default; }; -#endif //GPGFRONTEND_SIGNATURE_H +#endif //GPGFRONTEND_GPGKEYSIGNATURE_H diff --git a/include/gpg/UID.h b/include/gpg/GpgUID.h index c048c7ad..99fe828f 100644 --- a/include/gpg/UID.h +++ b/include/gpg/GpgUID.h @@ -22,16 +22,16 @@ * */ -#ifndef GPGFRONTEND_UID_H -#define GPGFRONTEND_UID_H +#ifndef GPGFRONTEND_GPGUID_H +#define GPGFRONTEND_GPGUID_H #include <utility> #include "GpgFrontend.h" -#include "Signature.h" +#include "GpgKeySignature.h" -struct UID { +struct GpgUID { QString name{}; @@ -45,17 +45,17 @@ struct UID { bool invalid; - QVector<Signature> signatures; + QVector<GpgKeySignature> signatures; - UID() = default; + GpgUID() = default; - explicit UID(gpgme_user_id_t user_id); + explicit GpgUID(gpgme_user_id_t user_id); - UID(UID &&) noexcept = default; - UID(const UID &) = default; - UID& operator=(UID &&) noexcept = default; - UID& operator=(const UID &) = default; + GpgUID(GpgUID &&) noexcept = default; + GpgUID(const GpgUID &) = default; + GpgUID& operator=(GpgUID &&) noexcept = default; + GpgUID& operator=(const GpgUID &) = default; }; -#endif //GPGFRONTEND_UID_H
\ No newline at end of file +#endif //GPGFRONTEND_GPGUID_H
\ No newline at end of file diff --git a/include/gpg/result_analyse/VerifyResultAnalyse.h b/include/gpg/result_analyse/VerifyResultAnalyse.h new file mode 100644 index 00000000..7c4faf3c --- /dev/null +++ b/include/gpg/result_analyse/VerifyResultAnalyse.h @@ -0,0 +1,35 @@ +// +// Created by eric on 2021/6/7. +// + +#ifndef GPGFRONTEND_VERIFYRESULTANALYSE_H +#define GPGFRONTEND_VERIFYRESULTANALYSE_H + +#include "gpg/GpgContext.h" +#include "gpg/GpgKeySignature.h" + +class VerifyResultAnalyse { +public: + + explicit VerifyResultAnalyse(GpgME::GpgContext *ctx, gpgme_signature_t signature); + + [[nodiscard]] const QString &getResultReport() const; + + [[nodiscard]] int getStatus() const; + +private: + + GpgME::GpgContext *mCtx; + QString verifyLabelText; + QTextStream textSteam{&verifyLabelText}; + + int status = 1; + + bool printSigner(QTextStream &stream, gpgme_signature_t sign); + + void setStatus(int mStatus); + +}; + + +#endif //GPGFRONTEND_VERIFYRESULTANALYSE_H diff --git a/include/ui/FindWidget.h b/include/ui/FindWidget.h index 7994583b..ad98682c 100644 --- a/include/ui/FindWidget.h +++ b/include/ui/FindWidget.h @@ -51,7 +51,7 @@ private: void setBackground(); QTextEdit *mTextpage; /** Textedit associated to the notification */ - QLineEdit *findEdit; /** Label holding the text shown in verifyNotification */ + QLineEdit *findEdit; /** Label holding the text shown in infoBoard */ [[maybe_unused]] QTextCharFormat cursorFormat; private slots: diff --git a/include/ui/VerifyDetailsDialog.h b/include/ui/VerifyDetailsDialog.h index 74e059a7..571f7ba1 100644 --- a/include/ui/VerifyDetailsDialog.h +++ b/include/ui/VerifyDetailsDialog.h @@ -31,8 +31,8 @@ class VerifyDetailsDialog : public QDialog { Q_OBJECT public: - explicit VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext *ctx, KeyList *mKeyList, QByteArray *inputData, - QByteArray *inputSignature = nullptr); + explicit VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, + gpgme_signature_t signature); private slots: @@ -42,10 +42,11 @@ private: GpgME::GpgContext *mCtx; KeyList *mKeyList; QHBoxLayout *mainLayout; - QWidget *mVbox; - QByteArray *mInputData; /** Data to be verified */ - QByteArray *mInputSignature; /** Data to be verified */ + QWidget *mVbox{}; + QByteArray *mInputData{}; /** Data to be verified */ + QByteArray *mInputSignature{}; /** Data to be verified */ QDialogButtonBox *buttonBox{}; + gpgme_signature_t sign; }; #endif // __VERIFYDETAILSDIALOG_H__ diff --git a/include/ui/keypair_details/KeyPairUIDTab.h b/include/ui/keypair_details/KeyPairUIDTab.h index 0dd73f7b..6042ec29 100644 --- a/include/ui/keypair_details/KeyPairUIDTab.h +++ b/include/ui/keypair_details/KeyPairUIDTab.h @@ -50,11 +50,11 @@ private: void createSignPopupMenu(); - void getUIDChecked(QVector<UID> &uids); + void getUIDChecked(QVector<GpgUID> &uids); - bool getUIDSelected(UID &uid); + bool getUIDSelected(GpgUID &uid); - bool getSignSelected(Signature &signature); + bool getSignSelected(GpgKeySignature &signature); GpgME::GpgContext *mCtx; const GpgKey &mKey; @@ -63,8 +63,8 @@ private: QMenu *manageSelectedUIDMenu; QMenu *uidPopupMenu; QMenu *signPopupMenu; - QVector<const UID *> buffered_uids; - QVector<const Signature *> buffered_signatures; + QVector<const GpgUID *> buffered_uids; + QVector<const GpgKeySignature *> buffered_signatures; private slots: diff --git a/include/ui/keypair_details/KeyUIDSignDialog.h b/include/ui/keypair_details/KeyUIDSignDialog.h index b4582228..88549e95 100644 --- a/include/ui/keypair_details/KeyUIDSignDialog.h +++ b/include/ui/keypair_details/KeyUIDSignDialog.h @@ -35,7 +35,7 @@ class KeyUIDSignDialog : public QDialog { public: - explicit KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<UID> &uid, QWidget *parent = nullptr); + explicit KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<GpgUID> &uid, QWidget *parent = nullptr); private: @@ -49,7 +49,7 @@ private: QCheckBox *nonExpireCheck; - const QVector<UID> mUids; + const QVector<GpgUID> mUids; const GpgKey &mKey; diff --git a/include/ui/VerifyNotification.h b/include/ui/widgets/InfoBoardWidget.h index a42a6b22..4fdbdf9f 100644 --- a/include/ui/VerifyNotification.h +++ b/include/ui/widgets/InfoBoardWidget.h @@ -26,33 +26,23 @@ #define __VERIFYNOTIFICATION_H__ #include "ui/EditorPage.h" -#include "VerifyDetailsDialog.h" - -QT_BEGIN_NAMESPACE -class QLabel; - -class QHBoxLayout; - -class QMenu; - -class QPushButton; - -QT_END_NAMESPACE +#include "ui/VerifyDetailsDialog.h" +#include "gpg/result_analyse/VerifyResultAnalyse.h" /** * @details Enumeration for the status of Verifylabel */ typedef enum { - VERIFY_ERROR_OK = 0, - VERIFY_ERROR_WARN = 1, - VERIFY_ERROR_CRITICAL = 2, - VERIFY_ERROR_NEUTRAL = 3, -} verify_label_status; + 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 VerifyNotification : public QWidget { +class InfoBoardWidget : public QWidget { Q_OBJECT public: /** @@ -61,7 +51,16 @@ public: * @param ctx The GPGme-Context * @param parent The parent widget */ - explicit VerifyNotification(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, QTextEdit *edit); + explicit InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList); + + + void associateTextEdit(QTextEdit *edit); + + void addOptionalAction(const QString& name, const std::function<void()>& action); + + void resetOptionActionsMenu(); + + /** * @details Set the text and background-color of verify notification. @@ -69,13 +68,8 @@ public: * @param text The text to be set. * @param verifyLabelStatus The status of label to set the specified color. */ - void setInfoBoard(const QString& text, verify_label_status verifyLabelStatus); + void setInfoBoard(const QString& text, InfoBoardStatus verifyLabelStatus); - /** - * @details Show the import from keyserver-action in detailsmenu. - * @param visible show the action, if visible is true, otherwise hide it. - */ - void showImportAction(bool visible); QStringList *keysNotInList; /** List with keys, which are in signature but not in keylist */ @@ -88,31 +82,25 @@ public slots: */ void slotImportFromKeyserver(); - /** - * @details Show a dialog with signing details. - */ - void slotShowVerifyDetails(); + void slotReset(); /** * @details Refresh the contents of dialog. */ - bool slotRefresh(); + void slotRefresh(const QString &text, InfoBoardStatus status); private: QMenu *detailMenu; /** Menu for te Button in verfiyNotification */ QAction *importFromKeyserverAct; /** Action for importing keys from keyserver which are notin keylist */ - QAction *showVerifyDetailsAct; /** Action for showing verify detail dialog */ - QPushButton *detailsButton; /** Button shown in verifynotification */ - QLabel *verifyLabel; /** Label holding the text shown in verifyNotification */ QTextEdit *infoBoard; GpgME::GpgContext *mCtx; /** GpgME Context */ KeyList *mKeyList; /** Table holding the keys */ - QTextEdit *mTextpage; /** Textedit associated to the notification */ + QTextEdit *mTextPage{ nullptr }; /** Textedit associated to the notification */ + QHBoxLayout *actionButtonLayout; [[maybe_unused]] QVector<QString> verifyDetailStringVector; /** Vector containing the text for labels in verifydetaildialog */ - [[maybe_unused]] QVector<verify_label_status> verifyDetailStatusVector; /** Vector containing the status for labels in verifydetaildialog */ + [[maybe_unused]] QVector<InfoBoardStatus> verifyDetailStatusVector; /** Vector containing the status for labels in verifydetaildialog */ - bool printSigner(QTextStream &stream, gpgme_signature_t sign); }; -#endif // __VERIFYNOTIFICATION_H__ +#endif // __VERIFYNOTIFICATION_H__
\ No newline at end of file diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index cd65c18f..f173fa81 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -45,6 +45,8 @@ MainWindow::MainWindow() { }); mKeyList->slotRefresh(); + infoBoard = new InfoBoardWidget(this, mCtx, mKeyList); + /* List of binary Attachments */ attachmentDockCreated = false; @@ -606,6 +608,14 @@ void MainWindow::createDockWindows() { 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()); + /* Attachments-Dockwindow */ if (settings.value("mime/parseMime").toBool()) { @@ -621,7 +631,7 @@ void MainWindow::createAttachmentDock() { attachmentDock = new QDockWidget(tr("Attached files:"), this); attachmentDock->setObjectName("AttachmentDock"); attachmentDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea); - addDockWidget(Qt::BottomDockWidgetArea, attachmentDock); + addDockWidget(Qt::LeftDockWidgetArea, attachmentDock); attachmentDock->setWidget(mAttachments); // hide till attachment is decrypted viewMenu->addAction(attachmentDock->toggleViewAction()); @@ -857,25 +867,40 @@ void MainWindow::slotVerify() { } // At first close verifynotification, if existing - edit->slotCurPage()->closeNoteByClass("verifyNotification"); + // edit->slotCurPage()->closeNoteByClass("infoBoard"); - // create new verfiy notification - auto *vn = new VerifyNotification(this, mCtx, mKeyList, edit->curTextPage()); + // If an unknown key is found, enable the importfromkeyserveraction - // if signing information is found, show the notification, otherwise close it - if (vn->slotRefresh()) { - edit->slotCurPage()->showNotificationWidget(vn, "verifyNotification"); - } else { - QMessageBox::warning(nullptr, "Signature NOT Found", "The signature was not found in the target text"); - vn->close(); + QByteArray text = edit->curTextPage()->toPlainText().toUtf8(); + GpgME::GpgContext::preventNoDataErr(&text); + + gpgme_signature_t sign = mCtx->verify(&text); + + auto verify = new VerifyResultAnalyse(mCtx, sign); + infoBoard->associateTextEdit(edit->curTextPage()); + + auto &reportText = verify->getResultReport(); + if(verify->getStatus() < 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_CRITICAL); + else if(verify->getStatus() > 0) + infoBoard->slotRefresh(reportText, INFO_ERROR_OK); + else + infoBoard->slotRefresh(reportText, INFO_ERROR_WARN); + + if(verify->getStatus() >= 0) { + infoBoard->resetOptionActionsMenu(); + infoBoard->addOptionalAction("Show Verify Details", [this, sign]() { + VerifyDetailsDialog(this, mCtx, mKeyList, sign); + }); } + } /* * Append the selected (not checked!) Key(s) To Textedit */ void MainWindow::slotAppendSelectedKeys() { - if (edit->tabCount() == 0 || edit->slotCurPage() == 0) { + if (edit->tabCount() == 0 || edit->slotCurPage() == nullptr) { return; } diff --git a/src/gpg/CMakeLists.txt b/src/gpg/CMakeLists.txt index 0c164844..3359f662 100644 --- a/src/gpg/CMakeLists.txt +++ b/src/gpg/CMakeLists.txt @@ -1,3 +1,4 @@ +aux_source_directory(./result_analyse GPG_SOURCE) aux_source_directory(. GPG_SOURCE) add_library(gpg STATIC ${GPG_SOURCE}) diff --git a/src/gpg/GpgContext.cpp b/src/gpg/GpgContext.cpp index 492aef83..be6e19d4 100644 --- a/src/gpg/GpgContext.cpp +++ b/src/gpg/GpgContext.cpp @@ -938,7 +938,7 @@ namespace GpgME { } } - bool GpgContext::addUID(const GpgKey &key, const UID &uid) { + bool GpgContext::addUID(const GpgKey &key, const GpgUID &uid) { QString userid = QString("%1 (%3) <%2>").arg(uid.name, uid.email, uid.comment); auto gpgmeError = gpgme_op_adduid(mCtx, key.key_refer, userid.toUtf8().constData(), 0); if(gpgmeError == GPG_ERR_NO_ERROR) { @@ -952,7 +952,7 @@ namespace GpgME { } - bool GpgContext::revUID(const GpgKey &key, const UID &uid) { + bool GpgContext::revUID(const GpgKey &key, const GpgUID &uid) { auto gpgmeError = gpgme_op_revuid(mCtx, key.key_refer, uid.uid.toUtf8().constData(), 0); if(gpgmeError == GPG_ERR_NO_ERROR) { emit signalKeyUpdated(key.id); @@ -964,7 +964,7 @@ namespace GpgME { } } - bool GpgContext::setPrimaryUID(const GpgKey &key, const UID &uid) { + bool GpgContext::setPrimaryUID(const GpgKey &key, const GpgUID &uid) { auto gpgmeError = gpgme_op_set_uid_flag(mCtx, key.key_refer, uid.uid.toUtf8().constData(), "primary", nullptr); if(gpgmeError == GPG_ERR_NO_ERROR) { @@ -977,7 +977,7 @@ namespace GpgME { } } - bool GpgContext::revSign(const GpgKey &key, const Signature &signature) { + bool GpgContext::revSign(const GpgKey &key, const GpgKeySignature &signature) { auto signing_key = getKeyById(signature.keyid); diff --git a/src/gpg/GpgKey.cpp b/src/gpg/GpgKey.cpp index df4b05ca..cd62fc5d 100644 --- a/src/gpg/GpgKey.cpp +++ b/src/gpg/GpgKey.cpp @@ -72,7 +72,7 @@ void GpgKey::parse(gpgme_key_t key) { auto uid = key->uids; while (uid != nullptr) { - uids.push_back(UID(uid)); + uids.push_back(GpgUID(uid)); uid = uid->next; } diff --git a/src/gpg/Signature.cpp b/src/gpg/GpgKeySignature.cpp index 079f8a05..142d1550 100644 --- a/src/gpg/Signature.cpp +++ b/src/gpg/GpgKeySignature.cpp @@ -22,9 +22,9 @@ * */ -#include "gpg/Signature.h" +#include "gpg/GpgKeySignature.h" -Signature::Signature(gpgme_key_sig_t key_sig) : +GpgKeySignature::GpgKeySignature(gpgme_key_sig_t key_sig) : revoked(key_sig->revoked), expired(key_sig->expired), invalid(key_sig->invalid), exportable(key_sig->exportable), status(key_sig->status), keyid(key_sig->keyid), pubkey_algo(gpgme_pubkey_algo_name(key_sig->pubkey_algo)), diff --git a/src/gpg/UID.cpp b/src/gpg/GpgUID.cpp index a4e6f342..f8f7e8fa 100644 --- a/src/gpg/UID.cpp +++ b/src/gpg/GpgUID.cpp @@ -2,16 +2,16 @@ // Created by eric on 2021/5/22. // -#include "gpg/UID.h" +#include "gpg/GpgUID.h" -UID::UID(gpgme_user_id_t user_id) : +GpgUID::GpgUID(gpgme_user_id_t user_id) : uid(user_id->uid), name(user_id->name), email(user_id->email), comment(user_id->comment), revoked(user_id->revoked), invalid(user_id->invalid) { auto sig = user_id->signatures; while (sig != nullptr) { - signatures.push_back(Signature(sig)); + signatures.push_back(GpgKeySignature(sig)); sig = sig->next; } diff --git a/src/gpg/result_analyse/VerifyResultAnalyse.cpp b/src/gpg/result_analyse/VerifyResultAnalyse.cpp new file mode 100644 index 00000000..44f4a3af --- /dev/null +++ b/src/gpg/result_analyse/VerifyResultAnalyse.cpp @@ -0,0 +1,142 @@ +// +// Created by eric on 2021/6/7. +// + +#include "GpgFrontend.h" +#include "gpg/result_analyse/VerifyResultAnalyse.h" + +VerifyResultAnalyse::VerifyResultAnalyse(GpgME::GpgContext *ctx, gpgme_signature_t sign) : mCtx(ctx) { + + textSteam << "Verify Report: " << endl; + + if (sign == nullptr){ + textSteam << "> Not Signature Found" << endl; + status = -1; + return; + } + + + textSteam << "> It was Signed ON " << QDateTime::fromTime_t(sign->timestamp).toString() << endl; + + textSteam << endl << "> It Contains:" << endl; + + bool canContinue = true; + + while (sign && canContinue) { + + switch (gpg_err_code(sign->status)) { + case GPG_ERR_BAD_SIGNATURE: + textSteam << QApplication::tr("One or More Bad Signatures.") << endl; + canContinue = false; + setStatus(-1); + break; + case GPG_ERR_NO_ERROR: + textSteam << QApplication::tr("A "); + if(sign->summary & GPGME_SIGSUM_GREEN) { + textSteam << QApplication::tr("Good "); + } + if(sign->summary & GPGME_SIGSUM_RED) { + textSteam << QApplication::tr("Bad "); + } + if(sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { + textSteam << QApplication::tr("Expired "); + } + if(sign->summary & GPGME_SIGSUM_KEY_MISSING) { + textSteam << QApplication::tr("Missing Key's "); + } + if(sign->summary & GPGME_SIGSUM_KEY_REVOKED) { + textSteam << QApplication::tr("Revoked Key's "); + } + if(sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { + textSteam << QApplication::tr("Expired Key's "); + } + if(sign->summary & GPGME_SIGSUM_CRL_MISSING) { + textSteam << QApplication::tr("Missing CRL's "); + } + + if(sign->summary & GPGME_SIGSUM_VALID) { + textSteam << QApplication::tr("Signature Fully Valid.") << endl; + } else { + textSteam << QApplication::tr("Signature NOT Fully Valid.") << endl; + } + + if(!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { + if(!printSigner(textSteam, sign)) { + setStatus(0); + } + } else { + textSteam << QApplication::tr("Key is NOT present with ID 0x") << QString(sign->fpr) << endl; + } + + setStatus(1); + + break; + case GPG_ERR_NO_PUBKEY: + textSteam << QApplication::tr("A signature could NOT be verified due to a Missing Key\n"); + setStatus(-1); + break; + case GPG_ERR_CERT_REVOKED: + textSteam << QApplication::tr("A signature is valid but the key used to verify the signature has been revoked\n"); + if(!printSigner(textSteam, sign)) { + setStatus(0); + } + setStatus(-1); + break; + case GPG_ERR_SIG_EXPIRED: + textSteam << QApplication::tr("A signature is valid but expired\n"); + if(!printSigner(textSteam, sign)) { + setStatus(0); + } + setStatus(-1); + break; + case GPG_ERR_KEY_EXPIRED: + textSteam << QApplication::tr("A signature is valid but the key used to verify the signature has expired.\n"); + if(!printSigner(textSteam, sign)) { + setStatus(0); + } + break; + case GPG_ERR_GENERAL: + textSteam << QApplication::tr("There was some other error which prevented the signature verification.\n"); + status = -1; + canContinue = false; + break; + default: + textSteam << QApplication::tr("Error for key with fingerprint ") << + GpgME::GpgContext::beautifyFingerprint(QString(sign->fpr)); + setStatus(-1); + } + textSteam << endl; + sign = sign->next; + } +} + +bool VerifyResultAnalyse::printSigner(QTextStream &stream, gpgme_signature_t sign) { + bool keyFound = true; + stream << QApplication::tr("Signed By: "); + auto key = mCtx->getKeyByFpr(sign->fpr); + if(!key.good) { + stream << "<Unknown>"; + setStatus(0); + keyFound = false; + } + stream << key.name; + if (!key.email.isEmpty()) { + stream << "<" << key.email << ">"; + } + stream << endl; + return keyFound; + +} + +const QString &VerifyResultAnalyse::getResultReport() const{ + return verifyLabelText; +} + +int VerifyResultAnalyse::getStatus() const { + return status; +} + +void VerifyResultAnalyse::setStatus(int mStatus) { + if(mStatus < status) + status = mStatus; +} diff --git a/src/ui/FileEncryptionDialog.cpp b/src/ui/FileEncryptionDialog.cpp index d4c0d6d1..813b9278 100755 --- a/src/ui/FileEncryptionDialog.cpp +++ b/src/ui/FileEncryptionDialog.cpp @@ -222,8 +222,9 @@ void FileEncryptionDialog::slotExecuteAction() { signFileEdit->setStyleSheet("QLineEdit { background: yellow }"); return; } - QByteArray signBuffer = signfile.readAll(); - new VerifyDetailsDialog(this, mCtx, mKeyList, &inBuffer, &signBuffer); + auto signBuffer = signfile.readAll(); + gpgme_signature_t sign = mCtx->verify(&inBuffer, &signBuffer); + new VerifyDetailsDialog(this, mCtx, mKeyList, sign); return; } diff --git a/src/ui/VerifyDetailsDialog.cpp b/src/ui/VerifyDetailsDialog.cpp index 27306280..fe193aa0 100644 --- a/src/ui/VerifyDetailsDialog.cpp +++ b/src/ui/VerifyDetailsDialog.cpp @@ -25,28 +25,22 @@ #include "ui/VerifyDetailsDialog.h" VerifyDetailsDialog::VerifyDetailsDialog(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, - QByteArray *inputData, QByteArray *inputSignature) : - QDialog(parent) { - mCtx = ctx; - mKeyList = keyList; - //mTextpage = edit; - mInputData = inputData; - mInputSignature = inputSignature; + gpgme_signature_t signature) : + QDialog(parent), mCtx(ctx), mKeyList(keyList), sign(signature) { + this->setWindowTitle(tr("Signature Details")); - connect(mCtx, SIGNAL(keyDBChanged()), this, SLOT(slotRefresh())); + connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh())); mainLayout = new QHBoxLayout(); this->setLayout(mainLayout); - mVbox = new QWidget(); slotRefresh(); this->exec(); } void VerifyDetailsDialog::slotRefresh() { - mVbox->close(); mVbox = new QWidget(); auto *mVboxLayout = new QVBoxLayout(mVbox); @@ -56,16 +50,6 @@ void VerifyDetailsDialog::slotRefresh() { buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); - // Get signature information of current text - //QByteArray text = mTextpage->toPlainText().toUtf8(); - //mCtx->preventNoDataErr(&text); - gpgme_signature_t sign; - if (mInputSignature != nullptr) { - sign = mCtx->verify(mInputData, mInputSignature); - } else { - sign = mCtx->verify(mInputData); - } - if (sign == nullptr) { mVboxLayout->addWidget(new QLabel(tr("No valid input found"))); mVboxLayout->addWidget(buttonBox); diff --git a/src/ui/VerifyNotification.cpp b/src/ui/VerifyNotification.cpp deleted file mode 100644 index 8b79f16b..00000000 --- a/src/ui/VerifyNotification.cpp +++ /dev/null @@ -1,231 +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 "ui/VerifyNotification.h" - -VerifyNotification::VerifyNotification(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList, QTextEdit *edit) : - QWidget(parent), mCtx(ctx), mKeyList(keyList), mTextpage(edit) { - - verifyLabel = new QLabel(this); - infoBoard = new QTextEdit(this); - infoBoard->setReadOnly(true); - infoBoard->setFixedHeight(160); - - this->setFixedHeight(170); - - connect(mCtx, SIGNAL(signalKeyInfoChanged()), this, SLOT(slotRefresh())); - connect(edit, SIGNAL(textChanged()), this, SLOT(close())); - - importFromKeyserverAct = new QAction(tr("Import missing key from Keyserver"), this); - connect(importFromKeyserverAct, SIGNAL(triggered()), this, SLOT(slotImportFromKeyserver())); - - showVerifyDetailsAct = new QAction(tr("Show detailed verify information"), this); - connect(showVerifyDetailsAct, SIGNAL(triggered()), this, SLOT(slotShowVerifyDetails())); - - detailMenu = new QMenu(this); - detailMenu->addAction(showVerifyDetailsAct); - detailMenu->addAction(importFromKeyserverAct); - importFromKeyserverAct->setVisible(false); - - keysNotInList = new QStringList(); - detailsButton = new QPushButton(tr("Details"), this); - detailsButton->setMenu(detailMenu); - auto *notificationWidgetLayout = new QHBoxLayout(this); - notificationWidgetLayout->addWidget(infoBoard); - notificationWidgetLayout->addWidget(detailsButton); - this->setLayout(notificationWidgetLayout); -} - -void VerifyNotification::slotImportFromKeyserver() { - auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, this); - importDialog->slotImport(*keysNotInList); -} - -void VerifyNotification::setInfoBoard(const QString &text, verify_label_status verifyLabelStatus) { - QString color; - infoBoard->setText(text); - switch (verifyLabelStatus) { - case VERIFY_ERROR_OK: - color = "#ccffcc"; - break; - case VERIFY_ERROR_WARN: - color = "#ececba"; - break; - case VERIFY_ERROR_CRITICAL: - color = "#ff8080"; - break; - default: - break; - } - - infoBoard->setAutoFillBackground(true); - QPalette status = infoBoard->palette(); - status.setColor(QPalette::Text, color); - infoBoard->setPalette(status); - infoBoard->setFont(QFont("Times", 10, QFont::Bold)); -} - -void VerifyNotification::showImportAction(bool visible) { - importFromKeyserverAct->setVisible(visible); -} - -void VerifyNotification::slotShowVerifyDetails() { - QByteArray text = mTextpage->toPlainText().toUtf8(); - GpgME::GpgContext::preventNoDataErr(&text); - new VerifyDetailsDialog(this, mCtx, mKeyList, &text); -} - -bool VerifyNotification::slotRefresh() { - verify_label_status verifyStatus = VERIFY_ERROR_OK; - - QByteArray text = mTextpage->toPlainText().toUtf8(); - GpgME::GpgContext::preventNoDataErr(&text); - int textIsSigned = GpgME::GpgContext::textIsSigned(text); - - gpgme_signature_t sign = mCtx->verify(&text); - - if (sign == nullptr) { - return false; - } - - QString verifyLabelText; - QTextStream textSteam(&verifyLabelText); - bool unknownKeyFound = false; - bool canContinue = true; - - - textSteam << "Signed At " << QDateTime::fromTime_t(sign->timestamp).toString() << endl; - - textSteam << endl << "It Contains:" << endl; - - while (sign && canContinue) { - - switch (gpg_err_code(sign->status)) { - case GPG_ERR_BAD_SIGNATURE: - textIsSigned = 3; - verifyStatus = VERIFY_ERROR_CRITICAL; - textSteam << tr("One or More Bad Signatures.") << endl; - canContinue = false; - break; - case GPG_ERR_NO_ERROR: - textSteam << tr("A "); - if(sign->summary & GPGME_SIGSUM_GREEN) { - textSteam << tr("Good "); - } - if(sign->summary & GPGME_SIGSUM_RED) { - textSteam << tr("Bad "); - } - if(sign->summary & GPGME_SIGSUM_SIG_EXPIRED) { - textSteam << tr("Expired "); - } - if(sign->summary & GPGME_SIGSUM_KEY_MISSING) { - textSteam << tr("Missing Key's "); - } - if(sign->summary & GPGME_SIGSUM_KEY_REVOKED) { - textSteam << tr("Revoked Key's "); - } - if(sign->summary & GPGME_SIGSUM_KEY_EXPIRED) { - textSteam << tr("Expired Key's "); - } - if(sign->summary & GPGME_SIGSUM_CRL_MISSING) { - textSteam << tr("Missing CRL's "); - } - - if(sign->summary & GPGME_SIGSUM_VALID) { - textSteam << tr("Signature Fully Valid.") << endl; - } else { - textSteam << tr("Signature NOT Fully Valid.") << endl; - } - - if(!(sign->status & GPGME_SIGSUM_KEY_MISSING)) { - unknownKeyFound = printSigner(textSteam, sign); - } else { - textSteam << tr("Key is NOT present with ID 0x") << QString(sign->fpr) << endl; - } - - break; - case GPG_ERR_NO_PUBKEY: - verifyStatus = VERIFY_ERROR_WARN; - textSteam << tr("A signature could NOT be verified due to a Missing Key\n"); - unknownKeyFound = true; - break; - case GPG_ERR_CERT_REVOKED: - verifyStatus = VERIFY_ERROR_WARN; - textSteam << tr("A signature is valid but the key used to verify the signature has been revoked\n"); - unknownKeyFound = printSigner(textSteam, sign); - break; - case GPG_ERR_SIG_EXPIRED: - verifyStatus = VERIFY_ERROR_WARN; - textSteam << tr("A signature is valid but expired\n"); - unknownKeyFound = printSigner(textSteam, sign); - break; - case GPG_ERR_KEY_EXPIRED: - verifyStatus = VERIFY_ERROR_WARN; - textSteam << tr("A signature is valid but the key used to verify the signature has expired.\n"); - unknownKeyFound = printSigner(textSteam, sign); - break; - case GPG_ERR_GENERAL: - verifyStatus = VERIFY_ERROR_CRITICAL; - textSteam << tr("There was some other error which prevented the signature verification.\n"); - canContinue = false; - break; - default: - verifyStatus = VERIFY_ERROR_WARN; - textSteam << tr("Error for key with fingerprint ") << - GpgME::GpgContext::beautifyFingerprint(QString(sign->fpr)); - } - textSteam << endl; - sign = sign->next; - } - - - // If an unknown key is found, enable the importfromkeyserveraction - this->showImportAction(unknownKeyFound); - - // Remove the last linebreak - verifyLabelText.remove(verifyLabelText.length() - 1, 1); - - setInfoBoard(verifyLabelText, verifyStatus); - - return true; -} - -bool VerifyNotification::printSigner(QTextStream &stream, gpgme_signature_t sign) { - bool keyFound = true; - stream << tr("Signed By: "); - auto key = mCtx->getKeyByFpr(sign->fpr); - if(!key.good) { - stream << "<Unknown>"; - keyFound = false; - } - stream << key.name; - if (!key.email.isEmpty()) { - stream << "<" << key.email << ">"; - } - - stream << endl; - - return keyFound; - -}
\ No newline at end of file diff --git a/src/ui/keypair_details/KeyNewUIDDialog.cpp b/src/ui/keypair_details/KeyNewUIDDialog.cpp index 1e6df250..7605bfae 100644 --- a/src/ui/keypair_details/KeyNewUIDDialog.cpp +++ b/src/ui/keypair_details/KeyNewUIDDialog.cpp @@ -71,7 +71,7 @@ void KeyNewUIDDialog::slotCreateNewUID() { } if (errorString.isEmpty()) { - UID uid; + GpgUID uid; uid.name = name->text(); uid.email = email->text(); uid.comment = comment->text(); diff --git a/src/ui/keypair_details/KeyPairUIDTab.cpp b/src/ui/keypair_details/KeyPairUIDTab.cpp index 729fb1d2..1a6c769d 100644 --- a/src/ui/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/keypair_details/KeyPairUIDTab.cpp @@ -222,7 +222,7 @@ void KeyPairUIDTab::slotRefreshSigList() { void KeyPairUIDTab::slotAddSign() { - QVector<UID> selected_uids; + QVector<GpgUID> selected_uids; getUIDChecked(selected_uids); if(selected_uids.isEmpty()) { @@ -238,7 +238,7 @@ void KeyPairUIDTab::slotAddSign() { -void KeyPairUIDTab::getUIDChecked(QVector<UID> &selected_uids) { +void KeyPairUIDTab::getUIDChecked(QVector<GpgUID> &selected_uids) { auto &uids = buffered_uids; @@ -283,7 +283,7 @@ void KeyPairUIDTab::slotAddUIDResult(int result) { void KeyPairUIDTab::slotDelUID() { - QVector<UID> selected_uids; + QVector<GpgUID> selected_uids; getUIDChecked(selected_uids); if(selected_uids.isEmpty()) { @@ -327,7 +327,7 @@ void KeyPairUIDTab::slotDelUID() { void KeyPairUIDTab::slotSetPrimaryUID() { - UID selected_uid; + GpgUID selected_uid; if(!getUIDSelected(selected_uid)) { auto emptyUIDMsg = new QMessageBox(); @@ -357,7 +357,7 @@ void KeyPairUIDTab::slotSetPrimaryUID() { } } -bool KeyPairUIDTab::getUIDSelected(UID &uid) { +bool KeyPairUIDTab::getUIDSelected(GpgUID &uid) { auto &uids = buffered_uids; for (int i = 0; i < uidList->rowCount(); i++) { if (uidList->item(i, 0)->isSelected()) { @@ -368,7 +368,7 @@ bool KeyPairUIDTab::getUIDSelected(UID &uid) { return false; } -bool KeyPairUIDTab::getSignSelected(Signature &signature) { +bool KeyPairUIDTab::getSignSelected(GpgKeySignature &signature) { auto &signatures = buffered_signatures; for (int i = 0; i < sigList->rowCount(); i++) { if (sigList->item(i, 0)->isSelected()) { @@ -407,7 +407,7 @@ void KeyPairUIDTab::contextMenuEvent(QContextMenuEvent *event) { void KeyPairUIDTab::slotAddSignSingle() { - UID selected_uid; + GpgUID selected_uid; if(!getUIDSelected(selected_uid)) { QMessageBox::information(nullptr, @@ -416,13 +416,13 @@ void KeyPairUIDTab::slotAddSignSingle() { return; } - auto selected_uids = QVector<UID>({ selected_uid }); + auto selected_uids = QVector<GpgUID>({selected_uid }); auto keySignDialog = new KeyUIDSignDialog(mCtx, mKey, selected_uids, this); keySignDialog->show(); } void KeyPairUIDTab::slotDelUIDSingle() { - UID selected_uid; + GpgUID selected_uid; if(!getUIDSelected(selected_uid)) { QMessageBox::information(nullptr, @@ -455,19 +455,19 @@ void KeyPairUIDTab::slotDelUIDSingle() { void KeyPairUIDTab::createSignPopupMenu() { signPopupMenu = new QMenu(this); - auto *delSignAct = new QAction(tr("Delete(Revoke) Signature"), this); + auto *delSignAct = new QAction(tr("Delete(Revoke) Key Signature"), this); connect(delSignAct, SIGNAL(triggered()), this, SLOT(slotDelSign())); signPopupMenu->addAction(delSignAct); } void KeyPairUIDTab::slotDelSign() { - Signature selected_sign; + GpgKeySignature selected_sign; if(!getSignSelected(selected_sign)) { QMessageBox::information(nullptr, tr("Invalid Operation"), - tr("Please select one Signature before doing this operation.")); + tr("Please select one Key Signature before doing this operation.")); return; } @@ -485,7 +485,7 @@ void KeyPairUIDTab::slotDelSign() { keynames.append(selected_sign.email); keynames.append("> </i><br/>"); - int ret = QMessageBox::warning(this, tr("Deleting Signature"), + 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); diff --git a/src/ui/keypair_details/KeyUIDSignDialog.cpp b/src/ui/keypair_details/KeyUIDSignDialog.cpp index 4ccf51a1..f112ea25 100644 --- a/src/ui/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/keypair_details/KeyUIDSignDialog.cpp @@ -24,7 +24,7 @@ #include "ui/keypair_details/KeyUIDSignDialog.h" -KeyUIDSignDialog::KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<UID> &uid, QWidget *parent) : +KeyUIDSignDialog::KeyUIDSignDialog(GpgME::GpgContext *ctx, const GpgKey &key, const QVector<GpgUID> &uid, QWidget *parent) : mKey(key), mCtx(ctx), mUids(uid), QDialog(parent) { mKeyList = new KeyList(ctx, diff --git a/src/ui/widgets/InfoBoardWidget.cpp b/src/ui/widgets/InfoBoardWidget.cpp new file mode 100644 index 00000000..daa52d85 --- /dev/null +++ b/src/ui/widgets/InfoBoardWidget.cpp @@ -0,0 +1,126 @@ +/** + * 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/widgets/InfoBoardWidget.h" + +InfoBoardWidget::InfoBoardWidget(QWidget *parent, GpgME::GpgContext *ctx, KeyList *keyList) : + QWidget(parent), mCtx(ctx), mKeyList(keyList){ + + infoBoard = new QTextEdit(this); + infoBoard->setReadOnly(true); + infoBoard->setMinimumHeight(140); + infoBoard->setMinimumWidth(480); + + 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); + + actionButtonLayout = new QHBoxLayout(); + auto label = new QLabel("Optional Actions Menu"); + label->setMinimumHeight(25); + actionButtonLayout->addWidget(label); + actionButtonLayout->addStretch(); + + QFrame *line; + line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + + auto *notificationWidgetLayout = new QVBoxLayout(this); + notificationWidgetLayout->addWidget(infoBoard); + notificationWidgetLayout->addLayout(actionButtonLayout); + notificationWidgetLayout->addWidget(line); + this->setLayout(notificationWidgetLayout); +} + +void InfoBoardWidget::slotImportFromKeyserver() { + auto *importDialog = new KeyServerImportDialog(mCtx, mKeyList, 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); + infoBoard->setFont(QFont("Times", 10, QFont::Bold)); +} + +void InfoBoardWidget::slotRefresh(const QString &text, InfoBoardStatus status) { + infoBoard->clear(); + setInfoBoard(text, status); + infoBoard->verticalScrollBar()->setValue(0); +} + +void InfoBoardWidget::associateTextEdit(QTextEdit *edit) { + this->mTextPage = edit; + if(mTextPage != nullptr) { + disconnect(mTextPage, SIGNAL(textChanged()), this, SLOT(slotReset())); + } + connect(edit, SIGNAL(textChanged()), this, SLOT(slotReset())); +} + +void InfoBoardWidget::addOptionalAction(const QString& name, const std::function<void()>& action) { + auto actionButton = new QPushButton(name); + actionButtonLayout->addWidget(actionButton); + connect(actionButton, &QPushButton::clicked, this, [=]() { + action(); + }); +} + +void InfoBoardWidget::resetOptionActionsMenu() { + QLayoutItem *item; + while ((item = actionButtonLayout->layout()->takeAt( 2)) != nullptr ) { + actionButtonLayout->removeItem(item); + delete item->widget(); + delete item; + } +} + +void InfoBoardWidget::slotReset() { + this->infoBoard->clear(); + resetOptionActionsMenu(); +} |