aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaturneric <[email protected]>2022-05-20 18:05:52 +0000
committerSaturneric <[email protected]>2022-05-20 18:05:52 +0000
commit7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527 (patch)
tree27fa99a672722c82eb6c3cc0250efb7d7a40c7bb
parentfix: connect correct signal (diff)
downloadGpgFrontend-7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527.tar.gz
GpgFrontend-7d598eb7b8f60d8d4cc9ff2b62db47eeacac4527.zip
feat: handle application's exceptions and crash
-rw-r--r--src/init.cpp29
-rw-r--r--src/main.cpp78
-rw-r--r--src/ui/GpgFrontendApplication.cpp94
-rw-r--r--src/ui/GpgFrontendApplication.h72
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