OpenCPN Partial API docs
load_errors_dlg.cpp
1 /**************************************************************************
2  * Copyright (C) 2022 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, write to the *
16  * Free Software Foundation, Inc., *
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18  **************************************************************************/
19 
30 #include <memory>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34 
35 #include <wx/event.h>
36 #include <wx/window.h>
37 
38 #include "gui_lib.h"
39 #include "load_errors_dlg.h"
40 #include "observable_evt.h"
41 #include "model/plugin_handler.h"
42 #include "model/plugin_loader.h"
43 #ifdef __ANDROID__
44 #include "androidUTIL.h"
45 #endif
46 
47 wxDEFINE_EVENT(EVT_LOAD_COMPLETE, ObservedEvt);
48 
49 static const char* const kBadPluginsIntro = _(R"(
50 The following plugins have encountered errors during startup:
51 
52 )");
53 
54 static const char* const kBadPluginIntro = _(R"(
55 The following plugin has encountered errors during startup:
56 
57 )");
58 
59 static const char* const kBadLibsIntro = _(R"(
60 The following libraries have encountered errors during startup:
61 
62 )");
63 
64 static const char* const kBadLibIntro = _(R"(
65 The following library has encountered errors during startup:
66 
67 )");
68 static const char* const kBadPluginsFooter = _(R"(
69 
70 These plugins will be uninstalled. You might want to reinstall
71 them after updating the catalog.
72 )");
73 
74 static const char* const kBadPluginFooter = _(R"(
75 
76 This plugin will be uninstalled. You might want to reinstall
77 it after updating the catalog.
78 )");
79 
80 static const char* const kBadLibsFooter = _(R"(
81 
82 These libraries will be removed. You might want to reinstall their
83 associated plugin after updating the catalog.)");
84 
85 static const char* const kBadLibFooter = _(R"(
86 
87 The library will be removed. You might want to reinstall it's
88 associated plugin after updating the catalog.)");
89 
92 public:
93  class FormatCtx {
94  public:
95  std::vector<std::string> plugins;
96  std::vector<std::string> libs;
97 
98  FormatCtx(const std::vector<LoadError> errors) {
99  auto handler = PluginHandler::getInstance();
100  for (const auto& e : errors) {
101  auto plugin = handler->getPluginByLibrary(e.lib_path);
102  if (plugin != "")
103  plugins.push_back(plugin);
104  else
105  libs.push_back(e.lib_path);
106  }
107  }
108  };
109 
110  LoadErrorsDlg(wxWindow* parent, const FormatCtx& format_ctx)
111  : OCPNMessageDialog(parent, wxString(FormatMsg(format_ctx))) {}
112 
113  std::string FormatMsg(const FormatCtx& ctx) {
114  auto handler = PluginHandler::getInstance();
115  std::stringstream ss;
116  if (ctx.plugins.size() > 0) {
117  ss << (ctx.plugins.size() == 1 ? kBadPluginIntro : kBadPluginsIntro);
118  for (const auto& p : ctx.plugins) {
119  ss << " " << p << "\n";
120  }
121  ss << (ctx.plugins.size() == 1 ? kBadPluginFooter : kBadPluginsFooter);
122  }
123  if (ctx.libs.size() > 0) {
124  ss << (ctx.libs.size() == 1 ? kBadLibIntro : kBadLibsIntro);
125  for (const auto& lib : ctx.libs) {
126  ss << " " << lib << "\n";
127  }
128  ss << (ctx.libs.size() == 1 ? kBadLibFooter : kBadLibsFooter);
129  }
130  return ss.str();
131  }
132 };
133 
135 static void Run(wxWindow* parent, const std::vector<LoadError>& errors) {
136  LoadErrorsDlg::FormatCtx format_ctx(errors);
137  LoadErrorsDlg dlg(parent, format_ctx);
138 
139 #ifdef __ANDROID__
140  std::string ss = dlg.FormatMsg(format_ctx);
141  androidShowSimpleOKDialog("Error", ss);
142  int sts = wxID_YES;
143 #else
144  int sts = dlg.ShowModal();
145 #endif
146  if (sts == wxID_YES || sts == wxID_OK) {
147  for (const auto& plugin : format_ctx.plugins) {
148  PluginHandler::getInstance()->uninstall(plugin);
149  }
150  for (const auto& lib : format_ctx.libs) remove(lib.c_str());
151  }
152 }
153 
154 LoadErrorsDlgCtrl::LoadErrorsDlgCtrl(wxWindow* parent) : m_parent(parent) {
155  auto loader = PluginLoader::getInstance();
156 
157  load_complete_listener.Listen(loader->evt_plugin_loadall_finalize, this,
158  EVT_LOAD_COMPLETE);
159  Bind(EVT_LOAD_COMPLETE, [&](ObservedEvt& ev) {
160  auto errors = UnpackEvtPointer<std::vector<LoadError>>(ev);
161  if (errors->size() != 0) Run(m_parent, *errors);
162  });
163 }
Unloadable plugins report message box.
Adds a std::shared<void> element to wxCommandEvent.
Definition: ocpn_plugin.h:1652
bool uninstall(const std::string plugin)
Uninstall an installed and loaded plugin.
General purpose GUI support.
Handle dialog reporting plugin load errors.
wxDEFINE_EVENT(REST_IO_EVT, ObservedEvt)
Event from IO thread to main.