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 #ifdef ocpnUSE_GL 35 #include <wx/glcanvas.h> 36 #endif 37 38 #include "config.h" 39 40 #include "ocpn_plugin.h" 41 #include "chart1.h" // for MyFrame 42 //#include "chcanv.h" // for ViewPort 43 #include "OCPN_Sound.h" 44 #include "chartimg.h" 45 #include "catalog_parser.h" 46 47 #include "s57chart.h" // for Object list 48 #include "semantic_vers.h" 49 50 //For widgets... 51 #include "wx/hyperlink.h" 52 #include <wx/choice.h> 53 #include <wx/tglbtn.h> 54 #include <wx/bmpcbox.h> 55 56 #ifndef __OCPN__ANDROID__ 57 #ifdef OCPN_USE_CURL 58 #include "wx/curl/http.h" 59 #include "wx/curl/dialog.h" 60 #endif 61 #endif 62 63 // Include wxJSON headers 64 // We undefine MIN/MAX so avoid warning of redefinition coming from 65 // json_defs.h 66 // Definitions checked manually, and are identical 67 #ifdef MIN 68 #undef MIN 69 #endif 70 71 #ifdef MAX 72 #undef MAX 73 #endif 74 75 #include <wx/json_defs.h> 76 #include <wx/jsonwriter.h> 77 78 // Assorted static helper routines 79 80 PlugIn_AIS_Target *Create_PI_AIS_Target(AIS_Target_Data *ptarget); 81 82 class PluginListPanel; 83 class PluginPanel; 84 class pluginUtilHandler; 85 86 typedef struct { 87 wxString name; // name of the plugin 88 int version_major; // major version 89 int version_minor; // minor version 90 bool hard; // hard blacklist - if true, don't load it at all, if false, load it and just warn the user 91 bool all_lower; // if true, blacklist also all the lower versions of the plugin 92 } BlackListedPlugin; 93 94 const BlackListedPlugin PluginBlacklist[] = { 95 { _T("aisradar_pi"), 0, 95, true, true }, 96 { _T("radar_pi"), 0, 95, true, true }, // GCC alias for aisradar_pi 97 { _T("watchdog_pi"), 1, 00, true, true }, 98 { _T("squiddio_pi"), 0, 2, true, true }, 99 { _T("objsearch_pi"), 0, 3, true, true }, 100 #ifdef __WXOSX__ 101 { _T("s63_pi"), 0, 6, true, true }, 102 #endif 103 }; 104 105 //---------------------------------------------------------------------------- 106 // PlugIn Messaging scheme Event 107 //---------------------------------------------------------------------------- 108 109 class OCPN_MsgEvent: public wxEvent 110 { 111 public: 112 OCPN_MsgEvent( wxEventType commandType = wxEVT_NULL, int id = 0 ); 113 OCPN_MsgEvent(const OCPN_MsgEvent & event)114 OCPN_MsgEvent(const OCPN_MsgEvent & event) 115 : wxEvent(event), 116 m_MessageID(event.m_MessageID), 117 m_MessageText(event.m_MessageText) 118 { } 119 120 ~OCPN_MsgEvent( ); 121 122 // accessors GetID()123 wxString GetID() { return m_MessageID; } GetJSONText()124 wxString GetJSONText() { return m_MessageText; } 125 SetID(const wxString & string)126 void SetID(const wxString &string) { m_MessageID = string; } SetJSONText(const wxString & string)127 void SetJSONText(const wxString &string) { m_MessageText = string; } 128 129 130 // required for sending with wxPostEvent() 131 wxEvent *Clone() const; 132 133 private: 134 wxString m_MessageID; 135 wxString m_MessageText; 136 137 138 }; 139 140 extern const wxEventType wxEVT_OCPN_MSG; 141 142 enum class PluginStatus { 143 System, // One of the four system plugins, unmanaged. 144 Managed, // Managed by installer. 145 Unmanaged, // Unmanaged, probably a package. 146 Ghost, // Managed, shadowing another (packaged?) plugin. 147 Unknown, 148 LegacyUpdateAvailable, 149 ManagedInstallAvailable, 150 ManagedInstalledUpdateAvailable, 151 ManagedInstalledCurrentVersion, 152 ManagedInstalledDowngradeAvailable, 153 PendingListRemoval 154 }; 155 156 enum ActionVerb { 157 NOP = 0, 158 UPGRADE_TO_MANAGED_VERSION, 159 UPGRADE_INSTALLED_MANAGED_VERSION, 160 REINSTALL_MANAGED_VERSION, 161 DOWNGRADE_INSTALLED_MANAGED_VERSION, 162 UNINSTALL_MANAGED_VERSION, 163 INSTALL_MANAGED_VERSION 164 }; 165 166 // Fwd definitions 167 class StatusIconPanel; 168 169 //----------------------------------------------------------------------------------------------------- 170 // 171 // The PlugIn Container Specification 172 // 173 //----------------------------------------------------------------------------------------------------- 174 class PlugInContainer 175 { 176 public: 177 PlugInContainer(); 178 179 opencpn_plugin *m_pplugin; 180 bool m_bEnabled; 181 bool m_bInitState; 182 bool m_bToolboxPanel; 183 int m_cap_flag; // PlugIn Capabilities descriptor 184 wxString m_plugin_file; // The full file path 185 wxString m_plugin_filename; // The short file path 186 wxDateTime m_plugin_modification; // used to detect upgraded plugins 187 destroy_t *m_destroy_fn; 188 wxDynamicLibrary m_library; 189 wxString m_common_name; // A common name string for the plugin 190 wxString m_short_description; 191 wxString m_long_description; 192 int m_api_version; 193 int m_version_major; 194 int m_version_minor; 195 wxBitmap *m_bitmap; 196 /** 197 * Return version from plugin API. Older pre-117 plugins just 198 * support major and minor version, newer plugins have 199 * complete semantic version data. 200 */ 201 SemanticVersion GetVersion(); 202 wxString m_version_str; // Complete version as of 203 // semantic_vers 204 PluginStatus m_pluginStatus; 205 std::string m_InstalledManagedVersion; // As detected from manifest 206 PluginMetadata m_ManagedMetadata; 207 }; 208 209 // Declare an array of PlugIn Containers 210 WX_DEFINE_ARRAY_PTR(PlugInContainer *, ArrayOfPlugIns); 211 212 class PlugInMenuItemContainer 213 { 214 public: 215 wxMenuItem *pmenu_item; 216 opencpn_plugin *m_pplugin; 217 bool b_viz; 218 bool b_grey; 219 int id; 220 wxString m_in_menu; 221 }; 222 223 // Define an array of PlugIn MenuItem Containers 224 WX_DEFINE_ARRAY_PTR(PlugInMenuItemContainer *, ArrayOfPlugInMenuItems); 225 226 227 class PlugInToolbarToolContainer 228 { 229 public: 230 PlugInToolbarToolContainer(); 231 ~PlugInToolbarToolContainer(); 232 233 opencpn_plugin *m_pplugin; 234 int id; 235 wxString label; 236 wxBitmap *bitmap_day; 237 wxBitmap *bitmap_dusk; 238 wxBitmap *bitmap_night; 239 wxBitmap *bitmap_Rollover_day; 240 wxBitmap *bitmap_Rollover_dusk; 241 wxBitmap *bitmap_Rollover_night; 242 243 wxItemKind kind; 244 wxString shortHelp; 245 wxString longHelp; 246 wxObject *clientData; 247 int position; 248 bool b_viz; 249 bool b_toggle; 250 int tool_sel; 251 wxString pluginNormalIconSVG; 252 wxString pluginRolloverIconSVG; 253 wxString pluginToggledIconSVG; 254 255 }; 256 257 // Define an array of PlugIn ToolbarTool Containers 258 WX_DEFINE_ARRAY_PTR(PlugInToolbarToolContainer *, ArrayOfPlugInToolbarTools); 259 260 261 262 //----------------------------------------------------------------------------------------------------- 263 // 264 // The PlugIn Manager Specification 265 // 266 //----------------------------------------------------------------------------------------------------- 267 268 class PlugInManager: public wxEvtHandler 269 { 270 271 public: 272 PlugInManager(MyFrame *parent); 273 virtual ~PlugInManager(); 274 275 bool LoadAllPlugIns(bool enabled_plugins, bool b_enable_blackdialog = true); 276 277 /** Unload, delete and remove item ix in GetPlugInArray(). */ 278 bool UnLoadPlugIn(size_t ix); 279 280 bool UnLoadAllPlugIns(); 281 bool DeactivateAllPlugIns(); 282 bool DeactivatePlugIn(PlugInContainer *pic); 283 bool UpdatePlugIns(); 284 285 bool UpdateConfig(); 286 287 PlugInContainer *LoadPlugIn(wxString plugin_file); GetPlugInArray()288 ArrayOfPlugIns *GetPlugInArray(){ return &plugin_array; } 289 290 bool RenderAllCanvasOverlayPlugIns( ocpnDC &dc, const ViewPort &vp, int canvasIndex); 291 bool RenderAllGLCanvasOverlayPlugIns( wxGLContext *pcontext, const ViewPort &vp, int canvasIndex); 292 void SendCursorLatLonToAllPlugIns( double lat, double lon); 293 void SendViewPortToRequestingPlugIns( ViewPort &vp ); 294 void PrepareAllPluginContextMenus(); 295 296 void NotifySetupOptions(); 297 void ClosePlugInPanel(PlugInContainer* pic, int ix); 298 void CloseAllPlugInPanels( int ); 299 GetPluginToolbarToolArray()300 ArrayOfPlugInToolbarTools &GetPluginToolbarToolArray(){ return m_PlugInToolbarTools; } 301 int AddToolbarTool(wxString label, wxBitmap *bitmap, wxBitmap *bmpRollover, 302 wxItemKind kind, wxString shortHelp, wxString longHelp, 303 wxObject *clientData, int position, 304 int tool_sel, opencpn_plugin *pplugin ); 305 306 void RemoveToolbarTool(int tool_id); 307 void SetToolbarToolViz(int tool_id, bool viz); 308 void SetToolbarItemState(int tool_id, bool toggle); 309 void SetToolbarItemBitmaps(int item, wxBitmap *bitmap, wxBitmap *bmpDisabled); 310 311 int AddToolbarTool(wxString label, wxString SVGfile, wxString SVGRolloverfile, wxString SVGToggledfile, 312 wxItemKind kind, wxString shortHelp, wxString longHelp, 313 wxObject *clientData, int position, 314 int tool_sel, opencpn_plugin *pplugin ); 315 316 void SetToolbarItemBitmaps(int item, wxString SVGfile, 317 wxString SVGfileRollover, 318 wxString SVGfileToggled); 319 320 opencpn_plugin *FindToolOwner(const int id); 321 wxString GetToolOwnerCommonName(const int id); 322 void ShowDeferredBlacklistMessages(); 323 GetPluginContextMenuItemArray()324 ArrayOfPlugInMenuItems &GetPluginContextMenuItemArray(){ return m_PlugInMenuItems; } 325 int AddCanvasContextMenuItem(wxMenuItem *pitem, opencpn_plugin *pplugin, const char *name = "" ); 326 void RemoveCanvasContextMenuItem(int item, const char *name = "" ); 327 void SetCanvasContextMenuItemViz(int item, bool viz, const char *name = "" ); 328 void SetCanvasContextMenuItemGrey(int item, bool grey, const char *name = "" ); 329 330 void SendNMEASentenceToAllPlugIns(const wxString &sentence); 331 void SendPositionFixToAllPlugIns(GenericPosDatEx *ppos); 332 void SendActiveLegInfoToAllPlugIns(ActiveLegDat *infos); 333 void SendAISSentenceToAllPlugIns(const wxString &sentence); 334 void SendJSONMessageToAllPlugins(const wxString &message_id, wxJSONValue v); 335 void SendMessageToAllPlugins(const wxString &message_id, const wxString &message_body); 336 int GetJSONMessageTargetCount(); 337 338 void SendResizeEventToAllPlugIns(int x, int y); 339 void SetColorSchemeForAllPlugIns(ColorScheme cs); 340 void NotifyAuiPlugIns(void); 341 bool CallLateInit(void); 342 343 bool IsPlugInAvailable(wxString commonName); 344 bool IsAnyPlugInChartEnabled(); 345 346 void SendVectorChartObjectInfo(const wxString &chart, const wxString &feature, const wxString &objname, double &lat, double &lon, double &scale, int &nativescale); 347 348 bool SendMouseEventToPlugins( wxMouseEvent &event); 349 bool SendKeyEventToPlugins( wxKeyEvent &event); 350 351 void SendBaseConfigToAllPlugIns(); 352 void SendS52ConfigToAllPlugIns( bool bReconfig = false ); 353 void SendSKConfigToAllPlugIns(); 354 355 void UpdateManagedPlugins(); 356 357 wxArrayString GetPlugInChartClassNameArray(void); 358 359 ListOfPI_S57Obj *GetPlugInObjRuleListAtLatLon( ChartPlugInWrapper *target, float zlat, float zlon, 360 float SelectRadius, const ViewPort& vp ); 361 wxString CreateObjDescriptions( ChartPlugInWrapper *target, ListOfPI_S57Obj *rule_list ); 362 363 wxString GetLastError(); GetParentFrame()364 MyFrame *GetParentFrame(){ return pParent; } 365 366 void DimeWindow(wxWindow *win); GetUtilHandler()367 pluginUtilHandler *GetUtilHandler(){ return m_utilHandler; } SetListPanelPtr(PluginListPanel * ptr)368 void SetListPanelPtr( PluginListPanel *ptr ) { m_listPanel = ptr; } 369 bool CheckPluginCompatibility(wxString plugin_file); 370 371 private: 372 bool CheckBlacklistedPlugin(opencpn_plugin* plugin); 373 wxBitmap *BuildDimmedToolBitmap(wxBitmap *pbmp_normal, unsigned char dim_ratio); 374 bool UpDateChartDataTypes(void); 375 bool LoadPlugInDirectory(const wxString &plugin_dir, bool enabled_plugins, bool b_enable_blackdialog); 376 void ProcessLateInit(PlugInContainer *pic); 377 378 MyFrame *pParent; 379 380 ArrayOfPlugIns plugin_array; 381 wxString m_last_error_string; 382 383 ArrayOfPlugInMenuItems m_PlugInMenuItems; 384 ArrayOfPlugInToolbarTools m_PlugInToolbarTools; 385 386 wxString m_plugin_location; 387 388 int m_plugin_tool_id_next; 389 int m_plugin_menu_item_id_next; 390 wxBitmap m_cached_overlay_bm; 391 392 bool m_benable_blackdialog; 393 bool m_benable_blackdialog_done; 394 wxArrayString m_deferred_blacklist_messages; 395 396 wxArrayString m_plugin_order; 397 void SetPluginOrder( wxString serialized_names ); 398 wxString GetPluginOrder(); 399 400 pluginUtilHandler *m_utilHandler; 401 PluginListPanel *m_listPanel; 402 403 404 #ifndef __OCPN__ANDROID__ 405 #ifdef OCPN_USE_CURL 406 407 public: 408 wxCurlDownloadThread *m_pCurlThread; 409 // The libcurl handle being re used for the transfer. 410 std::shared_ptr<wxCurlBase> m_pCurl; 411 412 // returns true if the error can be ignored 413 bool HandleCurlThreadError(wxCurlThreadError err, wxCurlBaseThread *p, 414 const wxString &url = wxEmptyString); 415 void OnEndPerformCurlDownload(wxCurlEndPerformEvent &ev); 416 void OnCurlDownload(wxCurlDownloadEvent &ev); 417 418 wxEvtHandler *m_download_evHandler; 419 long *m_downloadHandle; 420 bool m_last_online; 421 long m_last_online_chk; 422 #endif 423 #endif 424 425 DECLARE_EVENT_TABLE() 426 }; 427 428 WX_DEFINE_ARRAY_PTR(PluginPanel *, ArrayOfPluginPanel); 429 430 class PluginDownloadDialog; 431 432 /* 433 * Panel with a single + sign which opens the "Add/download plugins" dialog. 434 */ 435 class AddPluginPanel: public wxPanel 436 { 437 public: 438 AddPluginPanel(wxWindow* parent); 439 void OnClick(wxMouseEvent& event); 440 ~AddPluginPanel(); 441 442 protected: 443 wxBitmap m_bitmap; 444 wxStaticBitmap* m_staticBitmap; 445 wxWindow* m_parent; 446 }; 447 448 449 /* 450 * Panel with buttons to control plugin catalog management. 451 */ 452 class CatalogMgrPanel: public wxPanel 453 { 454 public: 455 CatalogMgrPanel(wxWindow* parent); 456 ~CatalogMgrPanel(); 457 void OnUpdateButton(wxCommandEvent &event); 458 void OnChannelSelected(wxCommandEvent &event); SetListPanelPtr(PluginListPanel * listPanel)459 void SetListPanelPtr(PluginListPanel *listPanel){ m_PluginListPanel = listPanel; } 460 void OnTarballButton(wxCommandEvent &event); 461 protected: 462 wxString GetCatalogText(bool); 463 unsigned int GetChannelIndex(const wxArrayString* channels); 464 void SetUpdateButtonLabel(); 465 466 wxButton *m_updateButton, *m_advancedButton, *m_tarballButton; 467 wxStaticText *m_catalogText, *m_customText; 468 wxChoice *m_choiceChannel; 469 wxTextCtrl *m_tcCustomURL; 470 wxWindow* m_parent; 471 PluginListPanel *m_PluginListPanel; 472 }; 473 474 475 #define ID_CMD_BUTTON_PERFORM_ACTION 27663 476 477 class PluginListPanel: public wxScrolledWindow 478 { 479 DECLARE_EVENT_TABLE() 480 481 public: 482 PluginListPanel( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, ArrayOfPlugIns *pPluginArray ); 483 ~PluginListPanel(); 484 485 void SelectPlugin( PluginPanel *pi ); 486 void MoveUp( PluginPanel *pi ); 487 void MoveDown( PluginPanel *pi ); 488 void UpdateSelections(); 489 void UpdatePluginsOrder(); 490 491 /** Complete reload from plugins array. */ 492 void ReloadPluginPanels(ArrayOfPlugIns* plugins); 493 void SelectByName(wxString &name); 494 495 wxBoxSizer *m_pitemBoxSizer01; 496 private: 497 void AddPlugin(PlugInContainer* pic); 498 int ComputePluginSpace(ArrayOfPluginPanel plugins, wxBoxSizer* sizer); 499 //void Clear(); 500 501 wxPanel *m_panel; 502 ArrayOfPlugIns *m_pPluginArray; 503 ArrayOfPluginPanel m_PluginItems; 504 PluginPanel *m_PluginSelected; 505 wxString m_selectedName; 506 int m_pluginSpacer; 507 }; 508 509 /** Invokes client browser on plugin info_url when clicked. */ 510 class WebsiteButton: public wxPanel 511 { 512 public: 513 WebsiteButton(wxWindow* parent, const char* url); ~WebsiteButton()514 ~WebsiteButton(){}; SetURL(std::string url)515 void SetURL( std::string url){ m_url = url; } 516 protected: 517 std::string m_url; 518 }; 519 520 class PluginPanel: public wxPanel 521 { 522 DECLARE_EVENT_TABLE() 523 524 public: 525 PluginPanel( wxPanel *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, PlugInContainer *p_plugin ); 526 ~PluginPanel(); 527 528 void OnPluginSelected( wxMouseEvent &event ); 529 void OnPluginSelectedUp( wxMouseEvent &event ); 530 void DoPluginSelect(); 531 532 void SetSelected( bool selected ); 533 void OnPluginPreferences( wxCommandEvent& event ); 534 void OnPluginEnableToggle( wxCommandEvent& event ); 535 void OnPluginAction( wxCommandEvent& event ); 536 void OnPluginUninstall( wxCommandEvent& event ); 537 void OnPluginUp( wxCommandEvent& event ); 538 void OnPluginDown( wxCommandEvent& event ); 539 void SetEnabled( bool enabled ); GetSelected()540 bool GetSelected(){ return m_bSelected; } GetPluginPtr()541 PlugInContainer* GetPluginPtr() { return m_pPlugin; }; 542 void SetActionLabel( wxString &label); GetAction()543 ActionVerb GetAction() { return m_action; } GetPlugin()544 PlugInContainer* GetPlugin() { return m_pPlugin; } 545 void OnPaint(wxPaintEvent &event); 546 547 private: 548 PluginListPanel *m_PluginListPanel; 549 bool m_bSelected; 550 PlugInContainer *m_pPlugin; 551 StatusIconPanel *m_status_icon; 552 wxStaticText *m_pName; 553 wxStaticText *m_pVersion; 554 wxStaticText *m_pDescription; 555 wxBoxSizer *m_pButtons; 556 wxStaticBitmap *m_itemStaticBitmap; 557 wxButton *m_pButtonPreferences; 558 wxButton *m_pButtonAction, *m_pButtonUninstall; 559 560 wxCheckBox *m_cbEnable; 561 WebsiteButton *m_info_btn; 562 ActionVerb m_action; 563 int m_penWidthUnselected, m_penWidthSelected; 564 565 }; 566 567 568 // API 1.11 adds access to S52 Presentation library 569 // These are some wrapper conversion utilities 570 571 class S52PLIB_Context 572 { 573 public: S52PLIB_Context()574 S52PLIB_Context(){ 575 bBBObj_valid = false; 576 bCS_Added = false; 577 bFText_Added = false; 578 CSrules = NULL; 579 FText = NULL; 580 ChildRazRules = NULL; 581 MPSRulesList = NULL; 582 LUP = NULL; 583 }; 584 ~S52PLIB_Context()585 ~S52PLIB_Context(){}; 586 587 wxBoundingBox BBObj; // lat/lon BBox of the rendered object 588 bool bBBObj_valid; // set after the BBObj has been calculated once. 589 590 Rules *CSrules; // per object conditional symbology 591 int bCS_Added; 592 593 S52_TextC *FText; 594 int bFText_Added; 595 wxRect rText; 596 597 LUPrec *LUP; 598 ObjRazRules *ChildRazRules; 599 mps_container *MPSRulesList; 600 }; 601 602 603 void CreateCompatibleS57Object( PI_S57Obj *pObj, S57Obj *cobj, chart_context *pctx ); 604 void UpdatePIObjectPlibContext( PI_S57Obj *pObj, S57Obj *cobj ); 605 606 #endif // _PLUGINMGR_H_ 607 608