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();
145void CheckLastStart() {
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.
Safe mode non-gui handling.