OpenCPN Partial API docs
pluginmanager.h
1 /***************************************************************************
2  *
3  *
4  * Project: OpenCPN
5  * Purpose: PlugIn Manager Object
6  * Author: David Register
7  *
8  ***************************************************************************
9  * Copyright (C) 2010 by David S. Register *
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  * This program is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19  * GNU General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU General Public License *
22  * along with this program; if not, write to the *
23  * Free Software Foundation, Inc., *
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
25  **************************************************************************/
26 
27 #ifndef _PLUGINMGR_H_
28 #define _PLUGINMGR_H_
29 
30 #include <wx/wx.h>
31 #include <wx/dynarray.h>
32 #include <wx/dynlib.h>
33 
34 #include <memory>
35 #include <atomic>
36 #include "config.h"
37 
38 #include "ocpn_plugin.h"
39 #include "OCPN_Sound.h"
40 #include "chartimg.h"
41 #include "model/catalog_parser.h"
42 #include "model/plugin_blacklist.h"
43 #include "observable.h"
44 #include "model/ais_target_data.h"
45 #include "model/comm_navmsg.h"
46 #include "s57chart.h" // for Object list
47 #include "model/semantic_vers.h"
48 
49 // For widgets...
50 #include <wx/hyperlink.h>
51 #include <wx/choice.h>
52 #include <wx/tglbtn.h>
53 #include <wx/bmpcbox.h>
54 
55 #ifndef __OCPN__ANDROID__
56 #ifdef OCPN_USE_CURL
57 #include <wx/curl/http.h>
58 #include <wx/curl/dialog.h>
59 #endif
60 #endif
61 
62 // Include wxJSON headers
63 // We undefine MIN/MAX so avoid warning of redefinition coming from
64 // json_defs.h
65 // Definitions checked manually, and are identical
66 #ifdef MIN
67 #undef MIN
68 #endif
69 
70 #ifdef MAX
71 #undef MAX
72 #endif
73 
74 #include <wx/json_defs.h>
75 #include <wx/jsonwriter.h>
76 #include "model/plugin_loader.h"
77 
78 // Assorted static helper routines
79 
80 PlugIn_AIS_Target* Create_PI_AIS_Target(AisTargetData* ptarget);
81 
82 class PluginListPanel;
83 class PluginPanel;
84 class pluginUtilHandler;
85 class MyFrame;
86 
87 //----------------------------------------------------------------------------
88 // PlugIn Messaging scheme Event
89 //----------------------------------------------------------------------------
90 
91 class OCPN_MsgEvent : public wxEvent {
92 public:
93  OCPN_MsgEvent(wxEventType commandType = wxEVT_NULL, int id = 0);
94 
95  OCPN_MsgEvent(const OCPN_MsgEvent& event)
96  : wxEvent(event),
97  m_MessageID(event.m_MessageID),
98  m_MessageText(event.m_MessageText) {}
99 
100  ~OCPN_MsgEvent();
101 
102  // accessors
103  wxString GetID() { return m_MessageID; }
104  wxString GetJSONText() { return m_MessageText; }
105 
106  void SetID(const wxString& string) { m_MessageID = string; }
107  void SetJSONText(const wxString& string) { m_MessageText = string; }
108 
109  // required for sending with wxPostEvent()
110  wxEvent* Clone() const;
111 
112 private:
113  wxString m_MessageID;
114  wxString m_MessageText;
115 };
116 
117 extern const wxEventType wxEVT_OCPN_MSG;
118 
119 enum ActionVerb {
120  NOP = 0,
121  UPGRADE_TO_MANAGED_VERSION,
122  UPGRADE_INSTALLED_MANAGED_VERSION,
123  REINSTALL_MANAGED_VERSION,
124  DOWNGRADE_INSTALLED_MANAGED_VERSION,
125  UNINSTALL_MANAGED_VERSION,
126  INSTALL_MANAGED_VERSION
127 };
128 
130 public:
131  wxMenuItem* pmenu_item;
132  opencpn_plugin* m_pplugin;
133  bool b_viz;
134  bool b_grey;
135  int id;
136  wxString m_in_menu;
137 };
138 
139 // Define an array of PlugIn MenuItem Containers
140 WX_DEFINE_ARRAY_PTR(PlugInMenuItemContainer*, ArrayOfPlugInMenuItems);
141 
143 public:
146 
147  opencpn_plugin* m_pplugin;
148  int id;
149  wxString label;
150  wxBitmap* bitmap_day;
151  wxBitmap* bitmap_dusk;
152  wxBitmap* bitmap_night;
153  wxBitmap* bitmap_Rollover_day;
154  wxBitmap* bitmap_Rollover_dusk;
155  wxBitmap* bitmap_Rollover_night;
156 
157  wxItemKind kind;
158  wxString shortHelp;
159  wxString longHelp;
160  wxObject* clientData;
161  int position;
162  bool b_viz;
163  bool b_toggle;
164  int tool_sel;
165  wxString pluginNormalIconSVG;
166  wxString pluginRolloverIconSVG;
167  wxString pluginToggledIconSVG;
168 };
169 
170 // Define an array of PlugIn ToolbarTool Containers
171 WX_DEFINE_ARRAY_PTR(PlugInToolbarToolContainer*, ArrayOfPlugInToolbarTools);
172 
173 //-----------------------------------------------------------------------------------------------------
174 //
175 // The PlugIn Manager Specification
176 //
177 //-----------------------------------------------------------------------------------------------------
178 
179 class BlacklistUI;
180 
181 class PlugInManager : public wxEvtHandler {
182 public:
183  PlugInManager(MyFrame* parent);
184  virtual ~PlugInManager();
185 
186  bool RenderAllCanvasOverlayPlugIns(ocpnDC& dc, const ViewPort& vp,
187  int canvasIndex, int priority);
188  bool RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
189  const ViewPort& vp, int canvasIndex,
190  int priority);
191  void SendCursorLatLonToAllPlugIns(double lat, double lon);
192  void SendViewPortToRequestingPlugIns(ViewPort& vp);
193  void PrepareAllPluginContextMenus();
194 
195  void NotifySetupOptions();
196  void ClosePlugInPanel(const PlugInContainer* pic, int ix);
197  void CloseAllPlugInPanels(int);
198 
199  ArrayOfPlugInToolbarTools& GetPluginToolbarToolArray() {
200  return m_PlugInToolbarTools;
201  }
202  int AddToolbarTool(wxString label, wxBitmap* bitmap, wxBitmap* bmpRollover,
203  wxItemKind kind, wxString shortHelp, wxString longHelp,
204  wxObject* clientData, int position, int tool_sel,
205  opencpn_plugin* pplugin);
206 
207  void RemoveToolbarTool(int tool_id);
208  void SetToolbarToolViz(int tool_id, bool viz);
209  void SetToolbarItemState(int tool_id, bool toggle);
210  void SetToolbarItemBitmaps(int item, wxBitmap* bitmap, wxBitmap* bmpDisabled);
211 
212  int AddToolbarTool(wxString label, wxString SVGfile, wxString SVGRolloverfile,
213  wxString SVGToggledfile, wxItemKind kind,
214  wxString shortHelp, wxString longHelp,
215  wxObject* clientData, int position, int tool_sel,
216  opencpn_plugin* pplugin);
217 
218  void SetToolbarItemBitmaps(int item, wxString SVGfile,
219  wxString SVGfileRollover, wxString SVGfileToggled);
220 
221  opencpn_plugin* FindToolOwner(const int id);
222  wxString GetToolOwnerCommonName(const int id);
223  void ShowDeferredBlacklistMessages();
224 
225  ArrayOfPlugInMenuItems& GetPluginContextMenuItemArray() {
226  return m_PlugInMenuItems;
227  }
228  int AddCanvasContextMenuItem(wxMenuItem* pitem, opencpn_plugin* pplugin,
229  const char* name = "");
230  void RemoveCanvasContextMenuItem(int item, const char* name = "");
231  void SetCanvasContextMenuItemViz(int item, bool viz, const char* name = "");
232  void SetCanvasContextMenuItemGrey(int item, bool grey, const char* name = "");
233 
234  static void SendNMEASentenceToAllPlugIns(const wxString& sentence);
235  void SendPositionFixToAllPlugIns(GenericPosDatEx* ppos);
236  void SendActiveLegInfoToAllPlugIns(const ActiveLegDat* infos);
237  void SendAISSentenceToAllPlugIns(const wxString& sentence);
238  void SendJSONMessageToAllPlugins(const wxString& message_id, wxJSONValue v);
239  void SendMessageToAllPlugins(const wxString& message_id,
240  const wxString& message_body);
241  bool UpDateChartDataTypes();
242  void FinalizePluginLoadall();
243 
244  int GetJSONMessageTargetCount();
245  bool UpdateConfig();
246  void SendResizeEventToAllPlugIns(int x, int y);
247  void SetColorSchemeForAllPlugIns(ColorScheme cs);
248  void NotifyAuiPlugIns(void);
249  bool CallLateInit(void);
250 
251  bool IsAnyPlugInChartEnabled();
252 
253  void SendVectorChartObjectInfo(const wxString& chart, const wxString& feature,
254  const wxString& objname, double& lat,
255  double& lon, double& scale, int& nativescale);
256 
257  bool SendMouseEventToPlugins(wxMouseEvent& event);
258  bool SendKeyEventToPlugins(wxKeyEvent& event);
259 
260  void SendBaseConfigToAllPlugIns();
261  void SendS52ConfigToAllPlugIns(bool bReconfig = false);
262  void SendSKConfigToAllPlugIns();
263 
264  void UpdateManagedPlugins();
265  bool CheckBlacklistedPlugin(const PluginMetadata plugin);
266 
267  void InitCommListeners(void);
268  void HandleN0183(std::shared_ptr<const Nmea0183Msg> n0183_msg);
269  void HandleSignalK(std::shared_ptr<const SignalkMsg> sK_msg);
270 
271  wxArrayString GetPlugInChartClassNameArray(void);
272 
273  ListOfPI_S57Obj* GetPlugInObjRuleListAtLatLon(ChartPlugInWrapper* target,
274  float zlat, float zlon,
275  float SelectRadius,
276  const ViewPort& vp);
277  wxString CreateObjDescriptions(ChartPlugInWrapper* target,
278  ListOfPI_S57Obj* rule_list);
279 
280  wxString GetLastError();
281  MyFrame* GetParentFrame() { return pParent; }
282 
283  void DimeWindow(wxWindow* win);
284  pluginUtilHandler* GetUtilHandler() { return m_utilHandler; }
285  void SetListPanelPtr(PluginListPanel* ptr) { m_listPanel = ptr; }
286 
287  ListOfPI_S57Obj* GetLightsObjRuleListVisibleAtLatLon(
288  ChartPlugInWrapper* target, float zlat, float zlon, const ViewPort& vp);
289 
290 private:
291  bool CheckBlacklistedPlugin(wxString name, int major, int minor);
292  bool CheckBlacklistedPlugin(opencpn_plugin* plugin);
293 
294  ObservableListener evt_ais_json_listener;
295  ObservableListener evt_blacklisted_plugin_listener;
296  ObservableListener evt_download_failed_listener;
297  ObservableListener evt_download_ok_listener;
298  ObservableListener evt_load_directory_listener;
299  ObservableListener evt_load_plugin_listener;
300  ObservableListener evt_plugin_loadall_finalize_listener;
301  ObservableListener evt_pluglist_change_listener;
302  ObservableListener evt_update_chart_types_listener;
303  ObservableListener evt_json_to_all_plugins_listener;
304  ObservableListener evt_routeman_json_listener;
305  ObservableListener evt_routeman_leginfo_listener;
306 
307  ObservableListener m_listener_N0183_all;
308  ObservableListener m_listener_SignalK;
309 
310  ObsListener m_on_msg_sent_listener;
311 
312  wxBitmap* BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
313  unsigned char dim_ratio);
314 
315  void ProcessLateInit(const PlugInContainer* pic);
316  void OnPluginDeactivate(const PlugInContainer* pic);
317  void HandlePluginLoaderEvents();
318  void HandlePluginHandlerEvents();
319 
320  MyFrame* pParent;
321  std::unique_ptr<BlacklistUI> m_blacklist_ui;
322 
323  wxString m_last_error_string;
324 
325  ArrayOfPlugInMenuItems m_PlugInMenuItems;
326  ArrayOfPlugInToolbarTools m_PlugInToolbarTools;
327 
328  wxString m_plugin_location;
329 
330  int m_plugin_tool_id_next;
331  int m_plugin_menu_item_id_next;
332  wxBitmap m_cached_overlay_bm;
333 
334  wxArrayString m_plugin_order;
335  void SetPluginOrder(wxString serialized_names);
336  wxString GetPluginOrder();
337 
338  pluginUtilHandler* m_utilHandler;
339  PluginListPanel* m_listPanel;
340  std::unique_ptr<AbstractBlacklist> m_blacklist;
341 
342 #ifndef __OCPN__ANDROID__
343 #ifdef OCPN_USE_CURL
344 
345 public:
346  wxCurlDownloadThread* m_pCurlThread;
347  // The libcurl handle being re used for the transfer.
348  std::shared_ptr<wxCurlBase> m_pCurl;
349 
350  // returns true if the error can be ignored
351  bool HandleCurlThreadError(wxCurlThreadError err, wxCurlBaseThread* p,
352  const wxString& url = wxEmptyString);
353  void OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev);
354  void OnCurlDownload(wxCurlDownloadEvent& ev);
355 
356  wxEvtHandler* m_download_evHandler;
357  long* m_downloadHandle;
358  bool m_last_online;
359  long m_last_online_chk;
360 #endif
361 #endif
362 
363  DECLARE_EVENT_TABLE()
364 };
365 
366 WX_DEFINE_ARRAY_PTR(PluginPanel*, ArrayOfPluginPanel);
367 
369 
370 /*
371  * Panel with a single + sign which opens the "Add/download plugins" dialog.
372  */
373 class AddPluginPanel : public wxPanel {
374 public:
375  AddPluginPanel(wxWindow* parent);
376  void OnClick(wxMouseEvent& event);
377  ~AddPluginPanel();
378 
379 protected:
380  wxBitmap m_bitmap;
381  wxStaticBitmap* m_staticBitmap;
382  wxWindow* m_parent;
383 };
384 
385 /*
386  * Panel with buttons to control plugin catalog management.
387  */
388 class CatalogMgrPanel : public wxPanel {
389 public:
390  CatalogMgrPanel(wxWindow* parent);
391  ~CatalogMgrPanel();
392  void OnUpdateButton(wxCommandEvent& event);
393  void SetListPanelPtr(PluginListPanel* listPanel) {
394  m_PluginListPanel = listPanel;
395  }
396  void OnTarballButton(wxCommandEvent& event);
397  void OnPluginSettingsButton(wxCommandEvent& event);
398 
399 protected:
400  wxString GetCatalogText(bool);
401  void SetUpdateButtonLabel();
402  wxString GetImportInitDir();
403 
404  wxButton *m_updateButton, *m_advancedButton, *m_tarballButton;
405  wxButton* m_adv_button;
406  wxStaticText* m_catalogText;
407  wxWindow* m_parent;
408  PluginListPanel* m_PluginListPanel;
409  ObservableListener catalog_listener;
410 };
411 
412 #define ID_CMD_BUTTON_PERFORM_ACTION 27663
413 
414 class PluginListPanel : public wxScrolledWindow {
415  DECLARE_EVENT_TABLE()
416 
417 public:
418  PluginListPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos,
419  const wxSize& size);
420  ~PluginListPanel();
421 
422  void SelectPlugin(PluginPanel* pi);
423  void MoveUp(PluginPanel* pi);
424  void MoveDown(PluginPanel* pi);
425  void UpdateSelections();
426  void UpdatePluginsOrder();
427 
429  void ReloadPluginPanels();
430  void SelectByName(wxString& name);
431 
432 private:
433  void AddPlugin(const PlugInData& pd);
434  void AddPlugin(const std::string& name);
435  int ComputePluginSpace(ArrayOfPluginPanel plugins, wxBoxSizer* sizer);
436  // void Clear();
437 
438  ArrayOfPluginPanel m_PluginItems;
439  PluginPanel* m_PluginSelected;
440  wxString m_selectedName;
441  int m_pluginSpacer;
442  std::atomic_flag m_is_loading;
443 };
444 
446 class WebsiteButton : public wxPanel {
447 public:
448  WebsiteButton(wxWindow* parent, const char* url);
449  ~WebsiteButton(){};
450  void SetURL(std::string url) { m_url = url; }
451 
452 protected:
453  std::string m_url;
454 };
455 
456 class PluginPanel : public wxPanel {
457  DECLARE_EVENT_TABLE()
458 
459 
460 public:
462  PluginPanel(wxPanel* parent, wxWindowID id, const wxPoint& pos,
463  const wxSize& size, const PlugInData plugin);
464 
466  PluginPanel(wxPanel* parent, wxWindowID id, const wxPoint& pos,
467  const wxSize& size, PluginMetadata plugin);
468 
470  PluginPanel(wxPanel* parent, const std::string& name);
471 
472  ~PluginPanel();
473 
474  void OnPluginSelected(wxMouseEvent& event);
475  void OnPluginSelectedUp(wxMouseEvent& event);
476  void DoPluginSelect();
477 
478  void SetSelected(bool selected);
479  void OnPluginPreferences(wxCommandEvent& event);
480  void OnPluginEnableToggle(wxCommandEvent& event);
481  void OnPluginAction(wxCommandEvent& event);
482  void OnPluginUninstall(wxCommandEvent& event);
483  void OnPluginUp(wxCommandEvent& event);
484  void OnPluginDown(wxCommandEvent& event);
485  void SetEnabled(bool enabled);
486  bool GetSelected() { return m_bSelected; }
487  const PlugInData* GetPluginPtr() { return &m_plugin; };
488  void SetActionLabel(wxString& label);
489  ActionVerb GetAction() { return m_action; }
490  const PlugInData* GetPlugin() { return &m_plugin; }
491  void OnPaint(wxPaintEvent& event);
492 
493 private:
494  PluginListPanel* m_PluginListPanel;
495  bool m_bSelected;
496  const PlugInData m_plugin;
497  wxStaticText* m_pName;
498  wxStaticText* m_pVersion;
499  wxStaticText* m_pDescription;
500  wxBoxSizer* m_pButtons;
501  wxStaticBitmap* m_itemStaticBitmap;
502  wxStaticBitmap* m_itemStatusIconBitmap;
503  wxButton* m_pButtonPreferences;
504  wxButton *m_pButtonAction, *m_pButtonUninstall;
505 
506  wxCheckBox* m_cbEnable;
507  WebsiteButton* m_info_btn;
508  ActionVerb m_action;
509  int m_penWidthUnselected, m_penWidthSelected;
510  bool m_is_safe_panel;
511 };
512 
513 // API 1.11 adds access to S52 Presentation library
514 // These are some wrapper conversion utilities
515 
517 public:
518  S52PLIB_Context() {
519  bBBObj_valid = false;
520  bCS_Added = false;
521  bFText_Added = false;
522  CSrules = NULL;
523  FText = NULL;
524  ChildRazRules = NULL;
525  MPSRulesList = NULL;
526  LUP = NULL;
527  };
528 
529  ~S52PLIB_Context(){};
530 
531  BoundingBox BBObj; // lat/lon BBox of the rendered object
532  bool bBBObj_valid; // set after the BBObj has been calculated once.
533 
534  Rules* CSrules; // per object conditional symbology
535  int bCS_Added;
536 
537  S52_TextC* FText;
538  int bFText_Added;
539  wxRect rText;
540 
541  LUPrec* LUP;
542  ObjRazRules* ChildRazRules;
543  mps_container* MPSRulesList;
544 };
545 
546 void CreateCompatibleS57Object(PI_S57Obj* pObj, S57Obj* cobj,
547  chart_context* pctx);
548 void UpdatePIObjectPlibContext(PI_S57Obj* pObj, S57Obj* cobj);
549 
550 #endif // _PLUGINMGR_H_
Handle messages for blacklisted plugins.
Define an action to be performed when a KeyProvider is notified.
Definition: observable.h:210
Keeps listening over it's lifespan, removes itself on destruction.
Definition: observable.h:133
Data for a loaded plugin, including dl-loaded library.
Definition: plugin_loader.h:99
Basic data for a loaded plugin, trivially copyable.
Definition: plugin_loader.h:64
void ReloadPluginPanels()
Complete reload from plugins array.
PluginPanel(wxPanel *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, const PlugInData plugin)
An entry in the list of plugins presented by Options | Plugins.
Invokes client browser on plugin info_url when clicked.
WebsiteButton(wxWindow *parent, const char *url)
Invokes client browser on plugin info_url when clicked.
Definition: ocpndc.h:58
Plugin metadata, reflects the xml format directly.
Definition: Quilt.cpp:867