diff options
author | Saturneric <[email protected]> | 2022-05-20 18:05:52 +0000 |
---|---|---|
committer | Saturneric <[email protected]> | 2022-05-20 18:05:52 +0000 |
commit | 7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527 (patch) | |
tree | 27fa99a672722c82eb6c3cc0250efb7d7a40c7bb | |
parent | fix: connect correct signal (diff) | |
download | GpgFrontend-7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527.tar.gz GpgFrontend-7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527.zip |
feat: handle application's exceptions and crash
-rw-r--r-- | src/init.cpp | 29 | ||||
-rw-r--r-- | src/main.cpp | 78 | ||||
-rw-r--r-- | src/ui/GpgFrontendApplication.cpp | 94 | ||||
-rw-r--r-- | src/ui/GpgFrontendApplication.h | 72 |
4 files changed, 191 insertions, 82 deletions
diff --git a/src/init.cpp b/src/init.cpp index 775ccbd5..c872170e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -30,35 +30,6 @@ #include "GpgFrontendBuildInfo.h" #include "core/function/GlobalSettingStation.h" -QApplication* init_qapplication(int argc, char* argv[]) { - auto* app = new QApplication(argc, argv); -#ifndef MACOS - app->setWindowIcon(QIcon(":gpgfrontend.png")); -#endif - -#ifdef MACOS - // support retina screen - app->setAttribute(Qt::AA_UseHighDpiPixmaps); -#endif - - // set the extra information of the build - app->setApplicationVersion(BUILD_VERSION); - app->setApplicationName(PROJECT_NAME); - app->setQuitOnLastWindowClosed(true); - - // don't show icons in menus - app->setAttribute(Qt::AA_DontShowIconsInMenus); - - // unicode in source - QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); - return app; -} - -void destory_qapplication(QApplication* app) { - app->quit(); - delete app; -} - void init_logging_system() { el::Loggers::addFlag(el::LoggingFlag::AutoSpacing); el::Configurations defaultConf; diff --git a/src/main.cpp b/src/main.cpp index 4383bb21..b51c44ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,7 +35,7 @@ #include <cstddef> #include "core/GpgCoreInit.h" -#include "core/function/GlobalSettingStation.h" +#include "ui/GpgFrontendApplication.h" #include "ui/GpgFrontendUIInit.h" /** @@ -48,6 +48,8 @@ INITIALIZE_EASYLOGGINGPP */ jmp_buf recover_env; +constexpr int CRASH_CODE = ~0; ///< + /** * @brief handle the signal SIGSEGV * @@ -62,21 +64,6 @@ extern void handle_signal(int sig); extern void before_exit(); /** - * @brief init a new instance of QApplication. - * - * @param argc - * @param argv - */ -extern QApplication* init_qapplication(int argc, char* argv[]); - -/** - * @brief destroy the instance of QApplication. - * - * @param app - */ -extern void destory_qapplication(QApplication* app); - -/** * @brief initialize the logging system. * */ @@ -101,7 +88,8 @@ int main(int argc, char* argv[]) { Q_INIT_RESOURCE(gpgfrontend); // create qt application - auto* app = init_qapplication(argc, argv); + auto* app = + GpgFrontend::UI::GpgFrontendApplication::GetInstance(argc, argv, true); // init the logging system init_logging_system(); @@ -122,49 +110,33 @@ int main(int argc, char* argv[]) { int r = setjmp(recover_env); #endif if (!r) { -#ifdef RELEASE - try { -#endif - // renew application - if (app == nullptr) app = init_qapplication(argc, argv); - - // init ui library - GpgFrontend::UI::InitGpgFrontendUI(app); - - // create main window - return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app); -#ifdef RELEASE - } catch (...) { - // catch all unhandled exceptions and notify the user - QMessageBox::information( - nullptr, _("Unhandled Exception Thrown"), - _("Oops, an unhandled exception was thrown " - "during the running of the " - "program, and now it needs to be restarted. This is not a " - "serious problem, it may be the negligence of the programmer, " - "please report this problem if you can.")); - return_from_event_loop_code = RESTART_CODE; - } -#endif + // init ui library + GpgFrontend::UI::InitGpgFrontendUI(app); + + // create main window + return_from_event_loop_code = GpgFrontend::UI::RunGpgFrontendUI(app); } else { + LOG(ERROR) << "recover from a crash"; // when signal is caught, restart the main window - QMessageBox::information( - nullptr, _("A serious error has occurred"), - _("Oh no! GpgFrontend caught a serious error in the software, so it " - "needs to be restarted. If the problem recurs, please manually " - "terminate the program and report the problem to the developer.")); - return_from_event_loop_code = RESTART_CODE; - LOG(INFO) << "return_from_event_loop_code" << return_from_event_loop_code; + auto* message_box = new QMessageBox( + QMessageBox::Critical, _("A serious error has occurred"), + _("Oh no! GpgFrontend caught a serious error in the software, so " + "it needs to be restarted. If the problem recurs, please " + "manually terminate the program and report the problem to the " + "developer."), + QMessageBox::Ok, nullptr); + message_box->exec(); + return_from_event_loop_code = CRASH_CODE; } - // destory the application - if (app) { - destory_qapplication(app); - app = nullptr; + if (return_from_event_loop_code == CRASH_CODE) { + app = GpgFrontend::UI::GpgFrontendApplication::GetInstance(argc, argv, + true); } LOG(INFO) << "loop refresh"; - } while (return_from_event_loop_code == RESTART_CODE); + } while (return_from_event_loop_code == RESTART_CODE || + return_from_event_loop_code == CRASH_CODE); // exit the program return return_from_event_loop_code; diff --git a/src/ui/GpgFrontendApplication.cpp b/src/ui/GpgFrontendApplication.cpp new file mode 100644 index 00000000..0427f6d5 --- /dev/null +++ b/src/ui/GpgFrontendApplication.cpp @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/GpgFrontendApplication.h" + +#include "GpgFrontendBuildInfo.h" + +namespace GpgFrontend::UI { + +GpgFrontendApplication::GpgFrontendApplication(int &argc, char **argv) + : QApplication(argc, argv) { +#ifndef MACOS + this->setWindowIcon(QIcon(":gpgfrontend.png")); +#endif + +#ifdef MACOS + // support retina screen + this->setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif + + // set the extra information of the build + this->setApplicationVersion(BUILD_VERSION); + this->setApplicationName(PROJECT_NAME); + this->setQuitOnLastWindowClosed(true); + + // don't show icons in menus + this->setAttribute(Qt::AA_DontShowIconsInMenus); + + // unicode in source + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); +} + +GpgFrontendApplication *GpgFrontendApplication::GetInstance(int argc, + char *argv[], + bool new_instance) { + static GpgFrontendApplication *instance = nullptr; + if (new_instance || !instance) { + if (!instance) { + instance->quit(); + delete instance; + } + instance = new GpgFrontendApplication(argc, argv); + } + return instance; +} + +bool GpgFrontendApplication::notify(QObject *receiver, QEvent *event) { + bool app_done = true; + try { + app_done = QApplication::notify(receiver, event); + } catch (const std::exception &ex) { + LOG(INFO) << "Exception caught in notify: " << ex.what(); + QMessageBox::information(nullptr, _("Standard Exception Thrown"), + _("Oops, an standard exception was thrown " + "during the running of the " + "program. This is not a serious problem, it may " + "be the negligence of the programmer, " + "please report this problem if you can.")); + } catch (...) { + LOG(INFO) << "Unknown exception caught in notify"; + QMessageBox::information( + nullptr, _("Unhandled Exception Thrown"), + _("Oops, an unhandled exception was thrown " + "during the running of the program. This is not a " + "serious problem, it may be the negligence of the programmer, " + "please report this problem if you can.")); + } + return app_done; +} + +} // namespace GpgFrontend::UI diff --git a/src/ui/GpgFrontendApplication.h b/src/ui/GpgFrontendApplication.h new file mode 100644 index 00000000..52a0a610 --- /dev/null +++ b/src/ui/GpgFrontendApplication.h @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2021 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * The source code version of this software was modified and released + * by Saturneric<[email protected]><[email protected]> starting on May 12, 2021. + * + */ + +#include "ui/GpgFrontendUI.h" + +#ifndef GPGFRONTEND_GPGFRONTENDAPPLICATION_H +#define GPGFRONTEND_GPGFRONTENDAPPLICATION_H + +namespace GpgFrontend::UI { + +class GPGFRONTEND_UI_EXPORT GpgFrontendApplication : public QApplication { + Q_OBJECT + public: + /** + * @brief Construct a new GpgFrontend Application object + * + * @param argc + * @param argv + */ + explicit GpgFrontendApplication(int &argc, char **argv); + + /** + * @brief Destroy the GpgFrontend Application object + * + */ + ~GpgFrontendApplication() override = default; + + /** + * @brief Get the GpgFrontend Application object + * + * @return GpgFrontendApplication* + */ + static GpgFrontendApplication *GetInstance(int argc = 0, + char *argv[] = nullptr, + bool new_instance = false); + + protected: + /** + * @brief + * + * @param event + * @return bool + */ + bool notify(QObject *receiver, QEvent *event) override; +}; + +} // namespace GpgFrontend::UI + +#endif // GPGFRONTEND_GPGFRONTENDAPPLICATION_H
\ No newline at end of file |