Skip to content

Commit f23ad56

Browse files
committed
feat(ui): enhance loading dialog during environment check
* Replace progress dialog with a custom modal dialog * Provide user feedback while checking OpenPGP environment * Allow cancellation of the initialization process
1 parent ec11010 commit f23ad56

1 file changed

Lines changed: 88 additions & 44 deletions

File tree

src/ui/GpgFrontendUIInit.cpp

Lines changed: 88 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -48,76 +48,120 @@ namespace {
4848
QContainer<QTranslator*> registered_translators;
4949
QContainer<QByteArray> loaded_qm_datum;
5050

51-
}; // namespace
51+
[[noreturn]] void TerminateSelfImmediately() {
52+
qWarning() << "Application startup was canceled. Terminating process.";
53+
std::_Exit(0);
54+
}
55+
56+
} // namespace
5257

5358
extern void InitUITranslations();
5459

5560
void WaitEnvCheckingProcess() {
5661
FLOG_D() << "we need to wait for env checking process";
5762

58-
// create and show loading window before starting the main window
59-
auto* progress_dialog = new QProgressDialog();
60-
progress_dialog->setMaximum(0);
61-
progress_dialog->setMinimum(0);
63+
auto env_state =
64+
Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.all", 0);
65+
FLOG_D("ui is ready to wait for env initialized, env_state: %d", env_state);
66+
67+
if (env_state == 1) {
68+
FLOG_D("env state turned initialized before the looper start");
69+
return;
70+
}
71+
72+
auto* dialog = new QDialog(nullptr);
73+
dialog->setAttribute(Qt::WA_DeleteOnClose);
74+
dialog->setWindowTitle(QCoreApplication::tr("Starting GpgFrontend"));
75+
dialog->setModal(true);
76+
dialog->setWindowFlag(Qt::WindowContextHelpButtonHint, false);
77+
dialog->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, true);
78+
79+
auto* title_label =
80+
new QLabel(QCoreApplication::tr("Loading essential information"));
81+
auto title_font = title_label->font();
82+
title_font.setBold(true);
83+
title_font.setPointSize(title_font.pointSize() + 1);
84+
title_label->setFont(title_font);
85+
86+
auto* message_label = new QLabel(QCoreApplication::tr(
87+
"GpgFrontend is checking your OpenPGP environment and preparing the "
88+
"default engine. This may take a few seconds."));
89+
message_label->setWordWrap(true);
90+
91+
auto* hint_label = new QLabel(QCoreApplication::tr(
92+
"Please keep this window open while the initialization is running."));
93+
hint_label->setWordWrap(true);
94+
95+
auto* progress_bar = new QProgressBar;
96+
progress_bar->setRange(0, 0);
97+
progress_bar->setTextVisible(false);
98+
99+
auto* cancel_button = new QPushButton(QCoreApplication::tr("Cancel"));
100+
101+
auto* button_layout = new QHBoxLayout;
102+
button_layout->addStretch();
103+
button_layout->addWidget(cancel_button);
104+
105+
auto* layout = new QVBoxLayout(dialog);
106+
layout->setContentsMargins(24, 20, 24, 20);
107+
layout->setSpacing(12);
108+
layout->addWidget(title_label);
109+
layout->addWidget(message_label);
110+
layout->addSpacing(4);
111+
layout->addWidget(progress_bar);
112+
layout->addWidget(hint_label);
113+
layout->addSpacing(4);
114+
layout->addLayout(button_layout);
115+
116+
dialog->resize(460, dialog->sizeHint().height());
62117

63-
auto* waiting_dialog_label = new QLabel(
64-
QCoreApplication::tr("Loading Essential Info...") + "<br /><br />" +
65-
QCoreApplication::tr(
66-
"This may take a few seconds or minutes according to your default "
67-
"openpgp engine, please wait patiently."));
118+
QEventLoop looper;
119+
120+
const auto close_dialog = [dialog]() {
121+
LOG_D() << "closing env checking dialog";
68122

69-
waiting_dialog_label->setWordWrap(true);
70-
progress_dialog->setLabel(waiting_dialog_label);
71-
progress_dialog->resize(420, 120);
123+
if (dialog != nullptr) {
124+
dialog->accept();
125+
dialog->deleteLater();
126+
}
127+
};
72128

73129
QApplication::connect(CoreSignalStation::GetInstance(),
74-
&CoreSignalStation::SignalCoreFullyLoaded,
75-
progress_dialog, [=]() {
130+
&CoreSignalStation::SignalCoreFullyLoaded, dialog,
131+
[close_dialog]() {
76132
LOG_D() << "ui caught signal: core fully loaded";
77-
progress_dialog->finished(0);
78-
progress_dialog->deleteLater();
133+
close_dialog();
79134
});
80135

81136
QApplication::connect(CoreSignalStation::GetInstance(),
82-
&CoreSignalStation::SignalBadOpenPGPEnv,
83-
progress_dialog, [=]() {
137+
&CoreSignalStation::SignalBadOpenPGPEnv, dialog,
138+
[close_dialog]() {
84139
LOG_D() << "ui caught signal: core loading failed";
85-
progress_dialog->finished(0);
86-
progress_dialog->deleteLater();
140+
close_dialog();
87141
});
88142

89-
// new local event looper
90-
QEventLoop looper;
91143
QApplication::connect(CoreSignalStation::GetInstance(),
92144
&CoreSignalStation::SignalCoreFullyLoaded, &looper,
93145
&QEventLoop::quit);
94146

95-
QApplication::connect(progress_dialog, &QProgressDialog::canceled, [=]() {
147+
QApplication::connect(CoreSignalStation::GetInstance(),
148+
&CoreSignalStation::SignalBadOpenPGPEnv, &looper,
149+
&QEventLoop::quit);
150+
151+
QApplication::connect(cancel_button, &QPushButton::clicked, dialog, []() {
96152
FLOG_D("cancel clicked on waiting dialog");
97-
QApplication::quit();
98-
exit(0);
153+
TerminateSelfImmediately();
99154
});
100155

101-
auto env_state =
102-
Module::RetrieveRTValueTypedOrDefault<>("core", "env.state.all", 0);
103-
FLOG_D("ui is ready to wait for env initialized, env_state: %d", env_state);
104-
105-
// check twice to avoid some unlucky sitations
106-
if (env_state == 1) {
107-
FLOG_D("env state turned initialized before the looper start");
108-
progress_dialog->finished(0);
109-
progress_dialog->deleteLater();
110-
return;
111-
}
156+
QApplication::connect(dialog, &QDialog::rejected, dialog, []() {
157+
FLOG_D("waiting dialog rejected");
158+
TerminateSelfImmediately();
159+
});
112160

113-
// show the loading window
114-
progress_dialog->setModal(true);
115-
progress_dialog->raise();
116-
progress_dialog->activateWindow();
117-
progress_dialog->setFocus();
118-
progress_dialog->show();
161+
dialog->show();
162+
dialog->raise();
163+
dialog->activateWindow();
119164

120-
// block the main thread until the gpg context is loaded
121165
looper.exec();
122166
}
123167

0 commit comments

Comments
 (0)