31#include <wx/filename.h>
34#include <wx/html/htmlwin.h>
36#include "std_filesystem.h"
41static const char*
const kLastRunErrorMsg1 =
43 _(R
"( The last opencpn run seems to have failed.)");
45static const char*
const kLastRunErrorMsg2 =
46 _(R
"(Do you want to run in safe mode without plugins and other possibly problematic features?)");
48static const char*
const kLastRunErrorMsg3 =
49 _(R
"(You may consider visiting the OpenCPN-5.16 list of known issues)");
51static const char*
const kLastRunErrorMsg4 =
52 R
"( <a href="http://repo.opencpn.org/known-issues-5.16.html">)";
54static const char*
const kLastRunErrorMsg5 =
55 _(R
"(list of known issues.)");
59class HtmlWindow :
public wxHtmlWindow {
61 explicit HtmlWindow(wxWindow* parent) : wxHtmlWindow(parent, wxID_ANY) {
62 std::stringstream html;
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>";
71 wxHtmlWindow::SetPage(html.str());
72 wxHtmlWindow::Layout();
76class ButtonSizer :
public wxStdDialogButtonSizer {
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);
90class ModalDialogTimer :
public wxTimer {
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);
104 void Notify()
override { m_dialog->EndModal(m_exit_value); }
107 wxDialog*
const m_dialog;
108 const int m_exit_value;
111class SafeModeDialog :
public wxDialog {
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());
123 Bind(wxEVT_CHAR_HOOK, [&](wxKeyEvent& ev) { OnKeyPressed(ev); });
126 void StopTimer()
const { m_timer->Stop(); }
131 void OnKeyPressed(wxKeyEvent& ev) {
132 if (ev.GetKeyCode() == WXK_RETURN) EndModal(wxID_CANCEL);
133 ev.DoAllowNextEvent();
147 if (fs::exists(path)) {
148 SafeModeDialog dlg(
nullptr, 15);
149 int result = dlg.ShowModal();
153 std::ofstream dest(path, std::ios::binary);
154 dest <<
"Internal opencpn use\n";
std::string CheckFilePath()
Return path to file created when start is commenced and removed when completed.
void CheckLastStart()
Check if the last start failed, possibly invoke user dialog and set global safe mode state.
Safe mode non-gui handling.