OpenCPN Partial API docs
Loading...
Searching...
No Matches
safe_mode_gui.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2023 Alec Leamas *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#include <cstdio>
25#include <string>
26#include <fstream>
27#include <sstream>
28
29#include <wx/button.h>
30#include <wx/dialog.h>
31#include <wx/filename.h>
32#include <wx/sizer.h>
33#include <wx/timer.h>
34#include <wx/html/htmlwin.h>
35
36#include "std_filesystem.h"
37
38#include "model/safe_mode.h"
39
40// clang-format off
41static const char* const kLastRunErrorMsg1 =
42 // clang-format off
43 _(R"( The last opencpn run seems to have failed.)");
44
45static const char* const kLastRunErrorMsg2 =
46 _(R"(Do you want to run in safe mode without plugins and other possibly problematic features?)");
47
48static const char* const kLastRunErrorMsg3 =
49 _(R"(You may consider visiting the OpenCPN-5.16 list of known issues)");
50
51static const char* const kLastRunErrorMsg4 =
52 R"( <a href="http://repo.opencpn.org/known-issues-5.16.html">)";
53
54static const char* const kLastRunErrorMsg5 =
55 _(R"(list of known issues.)"); // clang-format on
56
57namespace {
58
59class HtmlWindow : public wxHtmlWindow {
60public:
61 explicit HtmlWindow(wxWindow* parent) : wxHtmlWindow(parent, wxID_ANY) {
62 std::stringstream html;
63
64 html << "<html><body>" << kLastRunErrorMsg1 << "<br/><br/>";
65 html << kLastRunErrorMsg2 << "<br/><br/>";
66 html << kLastRunErrorMsg3 << "<br/>";
67 html << kLastRunErrorMsg4 << "<br/>";
68 html << kLastRunErrorMsg5 << "</a>";
69 html << "</body></html>";
70
71 wxHtmlWindow::SetPage(html.str());
72 wxHtmlWindow::Layout();
73 }
74};
75
76class ButtonSizer : public wxStdDialogButtonSizer {
77public:
78 explicit ButtonSizer(wxWindow* parent) : wxStdDialogButtonSizer() {
79 auto ok_btn = new wxButton(parent, wxID_OK);
80 ok_btn->SetLabel(_("Safe restart"));
81 SetAffirmativeButton(ok_btn);
82 auto cancel_btn = new wxButton(parent, wxID_CANCEL);
83 cancel_btn->SetLabel(_("Normal start"));
84 SetCancelButton(cancel_btn);
85 Realize();
86 }
87};
88
90class ModalDialogTimer : public wxTimer {
91public:
99 ModalDialogTimer(wxDialog* dialog, unsigned seconds, int exit_value)
100 : wxTimer(dialog), m_dialog(dialog), m_exit_value(exit_value) {
101 StartOnce(static_cast<int>(seconds) * 1000);
102 }
103
104 void Notify() override { m_dialog->EndModal(m_exit_value); }
105
106private:
107 wxDialog* const m_dialog;
108 const int m_exit_value;
109};
110
111class SafeModeDialog : public wxDialog {
112public:
113 SafeModeDialog(wxWindow* parent, unsigned timeout)
114 : wxDialog(parent, wxID_ANY, _("Safe Restart")),
115 m_timer(new ModalDialogTimer(this, 15, wxID_CANCEL)) {
116 auto vbox = new wxBoxSizer(wxVERTICAL);
117 vbox->Add(new HtmlWindow(this), wxSizerFlags(1).Expand());
118 vbox->Add(new ButtonSizer(this), wxSizerFlags().Expand().Border());
119 SetSizer(vbox);
120 wxDialog::Layout();
121 wxDialog::Show();
122
123 Bind(wxEVT_CHAR_HOOK, [&](wxKeyEvent& ev) { OnKeyPressed(ev); });
124 }
125
126 void StopTimer() const { m_timer->Stop(); }
127
128private:
129 wxTimer* m_timer;
130
131 void OnKeyPressed(wxKeyEvent& ev) {
132 if (ev.GetKeyCode() == WXK_RETURN) EndModal(wxID_CANCEL);
133 ev.DoAllowNextEvent();
134 ev.Skip();
135 };
136};
137
138} // namespace
139
140namespace safe_mode {
145void CheckLastStart() {
146 std::string path = CheckFilePath();
147 if (fs::exists(path)) {
148 SafeModeDialog dlg(nullptr, 15);
149 int result = dlg.ShowModal();
150 dlg.StopTimer();
151 safe_mode = result != wxID_CANCEL;
152 } else {
153 std::ofstream dest(path, std::ios::binary);
154 dest << "Internal opencpn use\n";
155 }
156}
157
158} // namespace safe_mode
Safe mode GUI handling.
Definition safe_mode.cpp:37
std::string CheckFilePath()
Return path to file created when start is commenced and removed when completed.
Definition safe_mode.cpp:47
Safe mode non-gui handling.