OpenCPN Partial API docs
Loading...
Searching...
No Matches
ocpn_plugin_gui.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2024 by David S. Register *
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
25#include "dychart.h" // Must be ahead due to buggy GL includes handling
26
27#include <wx/wx.h>
28#include <wx/arrstr.h>
29#include <wx/dc.h>
30#include <wx/dcmemory.h>
31#include <wx/event.h>
32#include <wx/glcanvas.h>
33#include <wx/notebook.h>
34#include <wx/string.h>
35#include <wx/window.h>
36
37#include "model/ais_decoder.h"
39#include "model/idents.h"
40#include "model/multiplexer.h"
41#include "model/own_ship.h"
42#include "model/plugin_comm.h"
43#include "model/route.h"
44#include "model/track.h"
45
46#include "ais.h"
47#include "chartdb.h"
48#include "chcanv.h"
49#include "ConfigMgr.h"
50#include "FontMgr.h"
51#include "glChartCanvas.h"
52#include "gui_lib.h"
53#include "navutil.h"
54#include "ocpn_app.h"
55#include "OCPN_AUIManager.h"
56#include "ocpn_frame.h"
57#include "OCPNPlatform.h"
58#include "ocpn_plugin.h"
59#include "options.h"
60#include "piano.h"
61#include "pluginmanager.h"
62#include "routemanagerdialog.h"
63#include "routeman_gui.h"
64#include "s52plib.h"
65#include "SoundFactory.h"
66#include "svg_utils.h"
67#include "SystemCmdSound.h"
68#include "toolbar.h"
69#include "waypointman_gui.h"
70
71extern PlugInManager* s_ppim;
72extern MyConfig* pConfig;
73extern OCPN_AUIManager* g_pauimgr;
74
75#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
76extern wxLocale* plocale_def_lang;
77#endif
78
79extern OCPNPlatform* g_Platform;
80extern ChartDB* ChartData;
81extern MyFrame* gFrame;
82extern ocpnStyle::StyleManager* g_StyleManager;
83extern options* g_pOptions;
84extern Multiplexer* g_pMUX;
85extern bool g_bShowChartBar;
86extern Routeman* g_pRouteMan;
87extern Select* pSelect;
88extern RouteManagerDialog* pRouteManagerDialog;
89extern RouteList* pRouteList;
90extern std::vector<Track*> g_TrackList;
91extern PlugInManager* g_pi_manager;
92extern s52plib* ps52plib;
93extern wxString ChartListFileName;
94extern options* g_options;
95extern ColorScheme global_color_scheme;
96extern wxArrayString g_locale_catalog_array;
97extern int g_GUIScaleFactor;
98extern int g_ChartScaleFactor;
99extern wxString g_locale;
100extern ocpnFloatingToolbarDialog* g_MainToolbar;
101
102extern int g_chart_zoom_modifier_raster;
103extern int g_chart_zoom_modifier_vector;
104extern double g_display_size_mm;
105extern bool g_bopengl;
106extern AisDecoder* g_pAIS;
107extern ChartGroupArray* g_pGroupArray;
108
109// extern ChartGroupArray* g_pGroupArray;
110extern unsigned int g_canvasConfig;
111
112extern wxString g_CmdSoundString;
113
114unsigned int gs_plib_flags;
115extern ChartCanvas* g_focusCanvas;
116extern ChartCanvas* g_overlayCanvas;
117extern bool g_bquiting;
118extern bool g_disable_main_toolbar;
119extern bool g_btenhertz;
120
121WX_DEFINE_ARRAY_PTR(ChartCanvas*, arrayofCanvasPtr);
122extern arrayofCanvasPtr g_canvasArray;
123
124void NotifySetupOptionsPlugin(const PlugInData* pic);
125
126//---------------------------------------------------------------------------
127/* Implementation of OCPN core functions callable by plugins
128 * Sorted by API version number
129 * The definitions of this API are found in ocpn_plugin.h
130 * PlugIns may call these static functions as necessary for system services
131 */
132//---------------------------------------------------------------------------
133
134//---------------------------------------------------------------------------
135// API 1.6
136//---------------------------------------------------------------------------
137/* Main Toolbar support */
138int InsertPlugInTool(wxString label, wxBitmap* bitmap, wxBitmap* bmpRollover,
139 wxItemKind kind, wxString shortHelp, wxString longHelp,
140 wxObject* clientData, int position, int tool_sel,
141 opencpn_plugin* pplugin) {
142 if (s_ppim)
143 return s_ppim->AddToolbarTool(label, bitmap, bmpRollover, kind, shortHelp,
144 longHelp, clientData, position, tool_sel,
145 pplugin);
146 else
147 return -1;
148}
149
150void RemovePlugInTool(int tool_id) {
151 if (s_ppim) s_ppim->RemoveToolbarTool(tool_id);
152}
153
154void SetToolbarToolViz(int item, bool viz) {
155 if (s_ppim) s_ppim->SetToolbarToolViz(item, viz);
156}
157
158void SetToolbarItemState(int item, bool toggle) {
159 if (s_ppim) s_ppim->SetToolbarItemState(item, toggle);
160}
161
162void SetToolbarToolBitmaps(int item, wxBitmap* bitmap, wxBitmap* bmpRollover) {
163 if (s_ppim) s_ppim->SetToolbarItemBitmaps(item, bitmap, bmpRollover);
164}
165
166int InsertPlugInToolSVG(wxString label, wxString SVGfile,
167 wxString SVGfileRollover, wxString SVGfileToggled,
168 wxItemKind kind, wxString shortHelp, wxString longHelp,
169 wxObject* clientData, int position, int tool_sel,
170 opencpn_plugin* pplugin) {
171 if (s_ppim)
172 return s_ppim->AddToolbarTool(label, SVGfile, SVGfileRollover,
173 SVGfileToggled, kind, shortHelp, longHelp,
174 clientData, position, tool_sel, pplugin);
175 else
176 return -1;
177}
178
179void SetToolbarToolBitmapsSVG(int item, wxString SVGfile,
180 wxString SVGfileRollover,
181 wxString SVGfileToggled) {
182 if (s_ppim)
183 s_ppim->SetToolbarItemBitmaps(item, SVGfile, SVGfileRollover,
184 SVGfileToggled);
185}
186
187/* Canvas Context Menu support */
188int AddCanvasMenuItem(wxMenuItem* pitem, opencpn_plugin* pplugin,
189 const char* name) {
190 if (s_ppim)
191 return s_ppim->AddCanvasContextMenuItem(pitem, pplugin, name);
192 else
193 return -1;
194}
195
196void SetCanvasMenuItemViz(int item, bool viz, const char* name) {
197 if (s_ppim) s_ppim->SetCanvasContextMenuItemViz(item, viz, name);
198}
199
200void SetCanvasMenuItemGrey(int item, bool grey, const char* name) {
201 if (s_ppim) s_ppim->SetCanvasContextMenuItemGrey(item, grey, name);
202}
203
204void RemoveCanvasMenuItem(int item, const char* name) {
205 if (s_ppim) s_ppim->RemoveCanvasContextMenuItem(item, name);
206}
207
208int AddCanvasContextMenuItem(wxMenuItem* pitem, opencpn_plugin* pplugin) {
209 /* main context popup menu */
210 return AddCanvasMenuItem(pitem, pplugin, "");
211}
212
213void SetCanvasContextMenuItemViz(int item, bool viz) {
214 SetCanvasMenuItemViz(item, viz);
215}
216
217void SetCanvasContextMenuItemGrey(int item, bool grey) {
218 SetCanvasMenuItemGrey(item, grey);
219}
220
221void RemoveCanvasContextMenuItem(int item) { RemoveCanvasMenuItem(item); }
222
223/* Utility functions */
224wxFileConfig* GetOCPNConfigObject(void) {
225 if (s_ppim)
226 return reinterpret_cast<wxFileConfig*>(
227 pConfig); // return the global application config object
228 else
229 return NULL;
230}
231
232wxWindow* GetOCPNCanvasWindow() {
233 wxWindow* pret = NULL;
234 if (s_ppim) {
235 MyFrame* pFrame = s_ppim->GetParentFrame();
236 pret = (wxWindow*)pFrame->GetPrimaryCanvas();
237 }
238 return pret;
239}
240
241void RequestRefresh(wxWindow* win) {
242 if (win) win->Refresh(true);
243}
244
245void GetCanvasPixLL(PlugIn_ViewPort* vp, wxPoint* pp, double lat, double lon) {
246 // Make enough of an application viewport to run its method....
247 ViewPort ocpn_vp;
248 ocpn_vp.clat = vp->clat;
249 ocpn_vp.clon = vp->clon;
250 ocpn_vp.m_projection_type = vp->m_projection_type;
251 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
252 ocpn_vp.skew = vp->skew;
253 ocpn_vp.rotation = vp->rotation;
254 ocpn_vp.pix_width = vp->pix_width;
255 ocpn_vp.pix_height = vp->pix_height;
256
257 wxPoint ret = ocpn_vp.GetPixFromLL(lat, lon);
258 pp->x = ret.x;
259 pp->y = ret.y;
260}
261
262void GetDoubleCanvasPixLL(PlugIn_ViewPort* vp, wxPoint2DDouble* pp, double lat,
263 double lon) {
264 // Make enough of an application viewport to run its method....
265 ViewPort ocpn_vp;
266 ocpn_vp.clat = vp->clat;
267 ocpn_vp.clon = vp->clon;
268 ocpn_vp.m_projection_type = vp->m_projection_type;
269 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
270 ocpn_vp.skew = vp->skew;
271 ocpn_vp.rotation = vp->rotation;
272 ocpn_vp.pix_width = vp->pix_width;
273 ocpn_vp.pix_height = vp->pix_height;
274
275 *pp = ocpn_vp.GetDoublePixFromLL(lat, lon);
276}
277
278void GetCanvasLLPix(PlugIn_ViewPort* vp, wxPoint p, double* plat,
279 double* plon) {
280 // Make enough of an application viewport to run its method....
281 ViewPort ocpn_vp;
282 ocpn_vp.clat = vp->clat;
283 ocpn_vp.clon = vp->clon;
284 ocpn_vp.m_projection_type = vp->m_projection_type;
285 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
286 ocpn_vp.skew = vp->skew;
287 ocpn_vp.rotation = vp->rotation;
288 ocpn_vp.pix_width = vp->pix_width;
289 ocpn_vp.pix_height = vp->pix_height;
290
291 return ocpn_vp.GetLLFromPix(p, plat, plon);
292}
293
294bool GetGlobalColor(wxString colorName, wxColour* pcolour) {
295 wxColour c = GetGlobalColor(colorName);
296 *pcolour = c;
297
298 return true;
299}
300
301wxFont* OCPNGetFont(wxString TextElement, int default_size) {
302 return FontMgr::Get().GetFont(TextElement, default_size);
303}
304
305wxFont* GetOCPNScaledFont_PlugIn(wxString TextElement, int default_size) {
306 return GetOCPNScaledFont(TextElement, default_size);
307}
308
309double GetOCPNGUIToolScaleFactor_PlugIn(int GUIScaleFactor) {
310 return g_Platform->GetToolbarScaleFactor(GUIScaleFactor);
311}
312
313double GetOCPNGUIToolScaleFactor_PlugIn() {
314 return g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
315}
316
317float GetOCPNChartScaleFactor_Plugin() {
318 return g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
319}
320
321wxFont GetOCPNGUIScaledFont_PlugIn(wxString item) {
322 return GetOCPNGUIScaledFont(item);
323}
324
325bool AddPersistentFontKey(wxString TextElement) {
326 return FontMgr::Get().AddAuxKey(TextElement);
327}
328
329wxString GetActiveStyleName() {
330 if (g_StyleManager)
331 return g_StyleManager->GetCurrentStyle()->name;
332 else
333 return _T("");
334}
335
336wxBitmap GetBitmapFromSVGFile(wxString filename, unsigned int width,
337 unsigned int height) {
338 wxBitmap bmp = LoadSVG(filename, width, height);
339
340 if (bmp.IsOk())
341 return bmp;
342 else {
343 // On error in requested width/height parameters,
344 // try to find and use dimensions embedded in the SVG file
345 unsigned int w, h;
346 SVGDocumentPixelSize(filename, w, h);
347 if (w == 0 || h == 0) {
348 // We did not succeed in deducing the size from SVG (svg element
349 // x misses width, height or both attributes), let's use some "safe"
350 // default
351 w = 32;
352 h = 32;
353 }
354 return LoadSVG(filename, w, h);
355 }
356}
357
358bool IsTouchInterface_PlugIn(void) { return g_btouch; }
359
360wxColour GetFontColour_PlugIn(wxString TextElement) {
361 return FontMgr::Get().GetFontColor(TextElement);
362}
363
364wxString* GetpSharedDataLocation(void) {
365 return g_Platform->GetSharedDataDirPtr();
366}
367
368ArrayOfPlugIn_AIS_Targets* GetAISTargetArray(void) {
369 if (!g_pAIS) return NULL;
370
371 ArrayOfPlugIn_AIS_Targets* pret = new ArrayOfPlugIn_AIS_Targets;
372
373 // Iterate over the AIS Target Hashmap
374 for (const auto& it : g_pAIS->GetTargetList()) {
375 auto td = it.second;
376 PlugIn_AIS_Target* ptarget = Create_PI_AIS_Target(td.get());
377 pret->Add(ptarget);
378 }
379
380// Test one alarm target
381#if 0
382 AisTargetData td;
383 td.n_alarm_state = AIS_ALARM_SET;
384 PlugIn_AIS_Target *ptarget = Create_PI_AIS_Target(&td);
385 pret->Add(ptarget);
386#endif
387 return pret;
388}
389
390wxAuiManager* GetFrameAuiManager(void) { return g_pauimgr; }
391
392void SendPluginMessage(wxString message_id, wxString message_body) {
393 SendMessageToAllPlugins(message_id, message_body);
394
395 // We will send an event to the main application frame (gFrame)
396 // for informational purposes.
397 // Of course, gFrame is encouraged to use any or all the
398 // data flying by if judged useful and dependable....
399
400 OCPN_MsgEvent Nevent(wxEVT_OCPN_MSG, 0);
401 Nevent.SetID(message_id);
402 Nevent.SetJSONText(message_body);
403 gFrame->GetEventHandler()->AddPendingEvent(Nevent);
404}
405
406void DimeWindow(wxWindow* win) { DimeControl(win); }
407
408void JumpToPosition(double lat, double lon, double scale) {
409 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), lat, lon, scale);
410}
411
412/* Locale (i18N) support */
413bool AddLocaleCatalog(wxString catalog) {
414#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
415
416 if (plocale_def_lang) {
417 // Add this catalog to the persistent catalog array
418 g_locale_catalog_array.Add(catalog);
419
420 return plocale_def_lang->AddCatalog(catalog);
421 } else
422#endif
423 return false;
424}
425
426wxString GetLocaleCanonicalName() { return g_locale; }
427
428/* NMEA interface support */
429void PushNMEABuffer(wxString buf) {
430 std::string full_sentence = buf.ToStdString();
431
432 if ((full_sentence[0] == '$') || (full_sentence[0] == '!')) { // Sanity check
433 std::string identifier;
434 // We notify based on full message, including the Talker ID
435 identifier = full_sentence.substr(1, 5);
436
437 // notify message listener and also "ALL" N0183 messages, to support plugin
438 // API using original talker id
439 auto address = std::make_shared<NavAddr0183>("virtual");
440 auto msg =
441 std::make_shared<const Nmea0183Msg>(identifier, full_sentence, address);
442 auto msg_all = std::make_shared<const Nmea0183Msg>(*msg, "ALL");
443
444 auto& msgbus = NavMsgBus::GetInstance();
445
446 msgbus.Notify(std::move(msg));
447 msgbus.Notify(std::move(msg_all));
448 }
449}
450
451/* Chart database access support */
452wxXmlDocument GetChartDatabaseEntryXML(int dbIndex, bool b_getGeom) {
453 wxXmlDocument doc = ChartData->GetXMLDescription(dbIndex, b_getGeom);
454
455 return doc;
456}
457
458bool UpdateChartDBInplace(wxArrayString dir_array, bool b_force_update,
459 bool b_ProgressDialog) {
460 // Make an array of CDI
461 ArrayOfCDI ChartDirArray;
462 for (unsigned int i = 0; i < dir_array.GetCount(); i++) {
463 wxString dirname = dir_array[i];
464 ChartDirInfo cdi;
465 cdi.fullpath = dirname;
466 cdi.magic_number = _T("");
467 ChartDirArray.Add(cdi);
468 }
469 bool b_ret = gFrame->UpdateChartDatabaseInplace(ChartDirArray, b_force_update,
470 b_ProgressDialog,
471 ChartData->GetDBFileName());
472 gFrame->ChartsRefresh();
473 return b_ret;
474}
475
476wxArrayString GetChartDBDirArrayString() {
477 return ChartData->GetChartDirArrayString();
478}
479
480int AddChartToDBInPlace(wxString& full_path, bool b_RefreshCanvas) {
481 // extract the path from the chart name
482 wxFileName fn(full_path);
483 wxString fdir = fn.GetPath();
484
485 bool bret = false;
486 if (ChartData) {
487 bret = ChartData->AddSingleChart(full_path);
488
489 if (bret) {
490 // Save to disk
491 pConfig->UpdateChartDirs(ChartData->GetChartDirArray());
492 ChartData->SaveBinary(ChartListFileName);
493
494 // Completely reload the chart database, for a fresh start
495 ArrayOfCDI XnewChartDirArray;
496 pConfig->LoadChartDirArray(XnewChartDirArray);
497 delete ChartData;
498 ChartData = new ChartDB();
499 ChartData->LoadBinary(ChartListFileName, XnewChartDirArray);
500
501 // Update group contents
502 if (g_pGroupArray) ChartData->ApplyGroupArray(g_pGroupArray);
503
504 if (g_options && g_options->IsShown())
505 g_options->UpdateDisplayedChartDirList(ChartData->GetChartDirArray());
506
507 if (b_RefreshCanvas || !gFrame->GetPrimaryCanvas()->GetQuiltMode()) {
508 gFrame->ChartsRefresh();
509 }
510 }
511 }
512 return bret;
513}
514
515int RemoveChartFromDBInPlace(wxString& full_path) {
516 bool bret = false;
517 if (ChartData) {
518 bret = ChartData->RemoveSingleChart(full_path);
519
520 // Save to disk
521 pConfig->UpdateChartDirs(ChartData->GetChartDirArray());
522 ChartData->SaveBinary(ChartListFileName);
523
524 // Completely reload the chart database, for a fresh start
525 ArrayOfCDI XnewChartDirArray;
526 pConfig->LoadChartDirArray(XnewChartDirArray);
527 delete ChartData;
528 ChartData = new ChartDB();
529 ChartData->LoadBinary(ChartListFileName, XnewChartDirArray);
530
531 // Update group contents
532 if (g_pGroupArray) ChartData->ApplyGroupArray(g_pGroupArray);
533
534 if (g_options && g_options->IsShown())
535 g_options->UpdateDisplayedChartDirList(ChartData->GetChartDirArray());
536
537 gFrame->ChartsRefresh();
538 }
539
540 return bret;
541}
542
543//---------------------------------------------------------------------------
544// API 1.9
545//---------------------------------------------------------------------------
546wxScrolledWindow* AddOptionsPage(OptionsParentPI parent, wxString title) {
547 if (!g_pOptions) return NULL;
548
549 size_t parentid;
550 switch (parent) {
551 case PI_OPTIONS_PARENT_DISPLAY:
552 parentid = g_pOptions->m_pageDisplay;
553 break;
554 case PI_OPTIONS_PARENT_CONNECTIONS:
555 parentid = g_pOptions->m_pageConnections;
556 break;
557 case PI_OPTIONS_PARENT_CHARTS:
558 parentid = g_pOptions->m_pageCharts;
559 break;
560 case PI_OPTIONS_PARENT_SHIPS:
561 parentid = g_pOptions->m_pageShips;
562 break;
563 case PI_OPTIONS_PARENT_UI:
564 parentid = g_pOptions->m_pageUI;
565 break;
566 case PI_OPTIONS_PARENT_PLUGINS:
567 parentid = g_pOptions->m_pagePlugins;
568 break;
569 default:
570 wxLogMessage(
571 _T("Error in PluginManager::AddOptionsPage: Unknown parent"));
572 return NULL;
573 break;
574 }
575
576 return g_pOptions->AddPage(parentid, title);
577}
578
579bool DeleteOptionsPage(wxScrolledWindow* page) {
580 if (!g_pOptions) return false;
581 return g_pOptions->DeletePluginPage(page);
582}
583
584bool DecodeSingleVDOMessage(const wxString& str, PlugIn_Position_Fix_Ex* pos,
585 wxString* accumulator) {
586 if (!pos) return false;
587
588 GenericPosDatEx gpd;
589 AisError nerr = AIS_GENERIC_ERROR;
590 if (g_pAIS) nerr = g_pAIS->DecodeSingleVDO(str, &gpd, accumulator);
591 if (nerr == AIS_NoError) {
592 pos->Lat = gpd.kLat;
593 pos->Lon = gpd.kLon;
594 pos->Cog = gpd.kCog;
595 pos->Sog = gpd.kSog;
596 pos->Hdt = gpd.kHdt;
597
598 // Fill in the dummy values
599 pos->FixTime = 0;
600 pos->Hdm = 1000;
601 pos->Var = 1000;
602 pos->nSats = 0;
603
604 return true;
605 }
606
607 return false;
608}
609
610int GetChartbarHeight(void) {
611 int val = 0;
612 if (g_bShowChartBar) {
613 ChartCanvas* cc = gFrame->GetPrimaryCanvas();
614 if (cc && cc->GetPiano()) {
615 val = cc->GetPiano()->GetHeight();
616 }
617 }
618 return val;
619}
620
621bool GetRoutepointGPX(RoutePoint* pRoutePoint, char* buffer,
622 unsigned int buffer_length) {
623 bool ret = false;
624
626 pgpx->AddGPXWaypoint(pRoutePoint);
627 wxString gpxfilename = wxFileName::CreateTempFileName(wxT("gpx"));
628 pgpx->SaveFile(gpxfilename);
629 delete pgpx;
630
631 wxFFile gpxfile(gpxfilename);
632 wxString s;
633 if (gpxfile.ReadAll(&s)) {
634 if (s.Length() < buffer_length) {
635 strncpy(buffer, (const char*)s.mb_str(wxConvUTF8), buffer_length - 1);
636 ret = true;
637 }
638 }
639
640 gpxfile.Close();
641 ::wxRemoveFile(gpxfilename);
642
643 return ret;
644}
645
646bool GetActiveRoutepointGPX(char* buffer, unsigned int buffer_length) {
647 if (g_pRouteMan->IsAnyRouteActive())
648 return GetRoutepointGPX(g_pRouteMan->GetpActivePoint(), buffer,
649 buffer_length);
650 else
651 return false;
652}
653
654void PositionBearingDistanceMercator_Plugin(double lat, double lon, double brg,
655 double dist, double* dlat,
656 double* dlon) {
657 PositionBearingDistanceMercator(lat, lon, brg, dist, dlat, dlon);
658}
659
660void DistanceBearingMercator_Plugin(double lat0, double lon0, double lat1,
661 double lon1, double* brg, double* dist) {
662 DistanceBearingMercator(lat0, lon0, lat1, lon1, brg, dist);
663}
664
665double DistGreatCircle_Plugin(double slat, double slon, double dlat,
666 double dlon) {
667 return DistGreatCircle(slat, slon, dlat, dlon);
668}
669
670void toTM_Plugin(float lat, float lon, float lat0, float lon0, double* x,
671 double* y) {
672 toTM(lat, lon, lat0, lon0, x, y);
673}
674
675void fromTM_Plugin(double x, double y, double lat0, double lon0, double* lat,
676 double* lon) {
677 fromTM(x, y, lat0, lon0, lat, lon);
678}
679
680void toSM_Plugin(double lat, double lon, double lat0, double lon0, double* x,
681 double* y) {
682 toSM(lat, lon, lat0, lon0, x, y);
683}
684
685void fromSM_Plugin(double x, double y, double lat0, double lon0, double* lat,
686 double* lon) {
687 fromSM(x, y, lat0, lon0, lat, lon);
688}
689
690void toSM_ECC_Plugin(double lat, double lon, double lat0, double lon0,
691 double* x, double* y) {
692 toSM_ECC(lat, lon, lat0, lon0, x, y);
693}
694
695void fromSM_ECC_Plugin(double x, double y, double lat0, double lon0,
696 double* lat, double* lon) {
697 fromSM_ECC(x, y, lat0, lon0, lat, lon);
698}
699
700double toUsrDistance_Plugin(double nm_distance, int unit) {
701 return toUsrDistance(nm_distance, unit);
702}
703
704double fromUsrDistance_Plugin(double usr_distance, int unit) {
705 return fromUsrDistance(usr_distance, unit);
706}
707
708double toUsrSpeed_Plugin(double kts_speed, int unit) {
709 return toUsrSpeed(kts_speed, unit);
710}
711
712double toUsrWindSpeed_Plugin(double kts_speed, int unit) {
713 return toUsrWindSpeed(kts_speed, unit);
714}
715
716double fromUsrSpeed_Plugin(double usr_speed, int unit) {
717 return fromUsrSpeed(usr_speed, unit);
718}
719
720double fromUsrWindSpeed_Plugin(double usr_wspeed, int unit) {
721 return fromUsrWindSpeed(usr_wspeed, unit);
722}
723
724double toUsrTemp_Plugin(double cel_temp, int unit) {
725 return toUsrTemp(cel_temp, unit);
726}
727
728double fromUsrTemp_Plugin(double usr_temp, int unit) {
729 return fromUsrTemp(usr_temp, unit);
730}
731
732wxString getUsrDistanceUnit_Plugin(int unit) {
733 return getUsrDistanceUnit(unit);
734}
735
736wxString getUsrSpeedUnit_Plugin(int unit) { return getUsrSpeedUnit(unit); }
737
738wxString getUsrWindSpeedUnit_Plugin(int unit) {
739 return getUsrWindSpeedUnit(unit);
740}
741
742wxString getUsrTempUnit_Plugin(int unit) { return getUsrTempUnit(unit); }
743
744bool PlugIn_GSHHS_CrossesLand(double lat1, double lon1, double lat2,
745 double lon2) {
746 static bool loaded = false;
747 if (!loaded) {
748 gshhsCrossesLandInit();
749 loaded = true;
750 }
751
752 return gshhsCrossesLand(lat1, lon1, lat2, lon2);
753}
754
755void PlugInPlaySound(wxString& sound_file) {
756 PlugInPlaySoundEx(sound_file, -1);
757}
758
759//---------------------------------------------------------------------------
760// API 1.10
761//---------------------------------------------------------------------------
762
763// API Route and Waypoint Support
764PlugIn_Waypoint::PlugIn_Waypoint() { m_HyperlinkList = NULL; }
765
766PlugIn_Waypoint::PlugIn_Waypoint(double lat, double lon,
767 const wxString& icon_ident,
768 const wxString& wp_name,
769 const wxString& GUID) {
770 wxDateTime now = wxDateTime::Now();
771 m_CreateTime = now.ToUTC();
772 m_HyperlinkList = NULL;
773
774 m_lat = lat;
775 m_lon = lon;
776 m_IconName = icon_ident;
777 m_MarkName = wp_name;
778 m_GUID = GUID;
779}
780
781PlugIn_Waypoint::~PlugIn_Waypoint() {}
782
783// PlugInRoute implementation
784PlugIn_Route::PlugIn_Route(void) { pWaypointList = new Plugin_WaypointList; }
785
786PlugIn_Route::~PlugIn_Route(void) {
787 pWaypointList->DeleteContents(false); // do not delete Waypoints
788 pWaypointList->Clear();
789
790 delete pWaypointList;
791}
792
793// PlugInTrack implementation
794PlugIn_Track::PlugIn_Track(void) { pWaypointList = new Plugin_WaypointList; }
795
796PlugIn_Track::~PlugIn_Track(void) {
797 pWaypointList->DeleteContents(false); // do not delete Waypoints
798 pWaypointList->Clear();
799
800 delete pWaypointList;
801}
802
803wxString GetNewGUID(void) { return GpxDocument::GetUUID(); }
804
805bool AddCustomWaypointIcon(wxBitmap* pimage, wxString key,
806 wxString description) {
807 wxImage image = pimage->ConvertToImage();
808 WayPointmanGui(*pWayPointMan).ProcessIcon(image, key, description);
809 return true;
810}
811
812static void cloneHyperlinkList(RoutePoint* dst, const PlugIn_Waypoint* src) {
813 // Transcribe (clone) the html HyperLink List, if present
814 if (src->m_HyperlinkList == nullptr) return;
815
816 if (src->m_HyperlinkList->GetCount() > 0) {
817 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
818 while (linknode) {
819 Plugin_Hyperlink* link = linknode->GetData();
820
821 Hyperlink* h = new Hyperlink();
822 h->DescrText = link->DescrText;
823 h->Link = link->Link;
824 h->LType = link->Type;
825
826 dst->m_HyperlinkList->Append(h);
827
828 linknode = linknode->GetNext();
829 }
830 }
831}
832
833bool AddSingleWaypoint(PlugIn_Waypoint* pwaypoint, bool b_permanent) {
834 // Validate the waypoint parameters a little bit
835
836 // GUID
837 // Make sure that this GUID is indeed unique in the Routepoint list
838 bool b_unique = true;
839 wxRoutePointListNode* prpnode = pWayPointMan->GetWaypointList()->GetFirst();
840 while (prpnode) {
841 RoutePoint* prp = prpnode->GetData();
842
843 if (prp->m_GUID == pwaypoint->m_GUID) {
844 b_unique = false;
845 break;
846 }
847 prpnode = prpnode->GetNext(); // RoutePoint
848 }
849
850 if (!b_unique) return false;
851
852 RoutePoint* pWP =
853 new RoutePoint(pwaypoint->m_lat, pwaypoint->m_lon, pwaypoint->m_IconName,
854 pwaypoint->m_MarkName, pwaypoint->m_GUID);
855
856 pWP->m_bIsolatedMark = true; // This is an isolated mark
857
858 cloneHyperlinkList(pWP, pwaypoint);
859
860 pWP->m_MarkDescription = pwaypoint->m_MarkDescription;
861
862 if (pwaypoint->m_CreateTime.IsValid())
863 pWP->SetCreateTime(pwaypoint->m_CreateTime);
864 else {
865 wxDateTime dtnow(wxDateTime::Now());
866 pWP->SetCreateTime(dtnow);
867 }
868
869 pWP->m_btemp = (b_permanent == false);
870
871 pSelect->AddSelectableRoutePoint(pwaypoint->m_lat, pwaypoint->m_lon, pWP);
872 if (b_permanent) pConfig->AddNewWayPoint(pWP, -1);
873
874 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
875 pRouteManagerDialog->UpdateWptListCtrl();
876
877 return true;
878}
879
880bool DeleteSingleWaypoint(wxString& GUID) {
881 // Find the RoutePoint
882 bool b_found = false;
883 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
884
885 if (prp) b_found = true;
886
887 if (b_found) {
888 pWayPointMan->DestroyWaypoint(prp);
889 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
890 pRouteManagerDialog->UpdateWptListCtrl();
891 }
892
893 return b_found;
894}
895
896bool UpdateSingleWaypoint(PlugIn_Waypoint* pwaypoint) {
897 // Find the RoutePoint
898 bool b_found = false;
899 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(pwaypoint->m_GUID);
900
901 if (prp) b_found = true;
902
903 if (b_found) {
904 double lat_save = prp->m_lat;
905 double lon_save = prp->m_lon;
906
907 prp->m_lat = pwaypoint->m_lat;
908 prp->m_lon = pwaypoint->m_lon;
909 prp->SetIconName(pwaypoint->m_IconName);
910 prp->SetName(pwaypoint->m_MarkName);
911 prp->m_MarkDescription = pwaypoint->m_MarkDescription;
912 prp->SetVisible(pwaypoint->m_IsVisible);
913 if (pwaypoint->m_CreateTime.IsValid())
914 prp->SetCreateTime(pwaypoint->m_CreateTime);
915
916 // Transcribe (clone) the html HyperLink List, if present
917
918 if (pwaypoint->m_HyperlinkList) {
919 prp->m_HyperlinkList->Clear();
920 if (pwaypoint->m_HyperlinkList->GetCount() > 0) {
921 wxPlugin_HyperlinkListNode* linknode =
922 pwaypoint->m_HyperlinkList->GetFirst();
923 while (linknode) {
924 Plugin_Hyperlink* link = linknode->GetData();
925
926 Hyperlink* h = new Hyperlink();
927 h->DescrText = link->DescrText;
928 h->Link = link->Link;
929 h->LType = link->Type;
930
931 prp->m_HyperlinkList->Append(h);
932
933 linknode = linknode->GetNext();
934 }
935 }
936 }
937
938 if (prp) prp->ReLoadIcon();
939
940 auto canvas = gFrame->GetPrimaryCanvas();
941 SelectCtx ctx(canvas->m_bShowNavobjects, canvas->GetCanvasTrueScale(),
942 canvas->GetScaleValue());
943 SelectItem* pFind =
944 pSelect->FindSelection(ctx, lat_save, lon_save, SELTYPE_ROUTEPOINT);
945 if (pFind) {
946 pFind->m_slat = pwaypoint->m_lat; // update the SelectList entry
947 pFind->m_slon = pwaypoint->m_lon;
948 }
949
950 if (!prp->m_btemp) pConfig->UpdateWayPoint(prp);
951
952 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
953 pRouteManagerDialog->UpdateWptListCtrl();
954 }
955
956 return b_found;
957}
958
959// translate O route class to Plugin one
960static void PlugInFromRoutePoint(PlugIn_Waypoint* dst,
961 /* const*/ RoutePoint* src) {
962 dst->m_lat = src->m_lat;
963 dst->m_lon = src->m_lon;
964 dst->m_IconName = src->GetIconName();
965 dst->m_MarkName = src->GetName();
966 dst->m_MarkDescription = src->m_MarkDescription;
967 dst->m_IsVisible = src->IsVisible();
968 dst->m_CreateTime = src->GetCreateTime(); // not const
969 dst->m_GUID = src->m_GUID;
970
971 // Transcribe (clone) the html HyperLink List, if present
972 if (src->m_HyperlinkList == nullptr) return;
973
974 delete dst->m_HyperlinkList;
975 dst->m_HyperlinkList = nullptr;
976
977 if (src->m_HyperlinkList->GetCount() > 0) {
978 dst->m_HyperlinkList = new Plugin_HyperlinkList;
979
980 wxHyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
981 while (linknode) {
982 Hyperlink* link = linknode->GetData();
983
985 h->DescrText = link->DescrText;
986 h->Link = link->Link;
987 h->Type = link->LType;
988
989 dst->m_HyperlinkList->Append(h);
990
991 linknode = linknode->GetNext();
992 }
993 }
994}
995
996bool GetSingleWaypoint(wxString GUID, PlugIn_Waypoint* pwaypoint) {
997 // Find the RoutePoint
998 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
999
1000 if (!prp) return false;
1001
1002 PlugInFromRoutePoint(pwaypoint, prp);
1003
1004 return true;
1005}
1006
1007wxArrayString GetWaypointGUIDArray(void) {
1008 wxArrayString result;
1009 const RoutePointList* list = pWayPointMan->GetWaypointList();
1010
1011 wxRoutePointListNode* prpnode = list->GetFirst();
1012 while (prpnode) {
1013 RoutePoint* prp = prpnode->GetData();
1014 result.Add(prp->m_GUID);
1015
1016 prpnode = prpnode->GetNext(); // RoutePoint
1017 }
1018
1019 return result;
1020}
1021
1022wxArrayString GetRouteGUIDArray(void) {
1023 wxArrayString result;
1024 RouteList* list = pRouteList;
1025
1026 wxRouteListNode* prpnode = list->GetFirst();
1027 while (prpnode) {
1028 Route* proute = prpnode->GetData();
1029 result.Add(proute->m_GUID);
1030
1031 prpnode = prpnode->GetNext(); // Route
1032 }
1033
1034 return result;
1035}
1036
1037wxArrayString GetTrackGUIDArray(void) {
1038 wxArrayString result;
1039 for (Track* ptrack : g_TrackList) {
1040 result.Add(ptrack->m_GUID);
1041 }
1042
1043 return result;
1044}
1045
1046wxArrayString GetWaypointGUIDArray(OBJECT_LAYER_REQ req) {
1047 wxArrayString result;
1048 const RoutePointList* list = pWayPointMan->GetWaypointList();
1049
1050 wxRoutePointListNode* prpnode = list->GetFirst();
1051 while (prpnode) {
1052 RoutePoint* prp = prpnode->GetData();
1053 switch (req) {
1054 case OBJECTS_ALL:
1055 result.Add(prp->m_GUID);
1056 break;
1057 case OBJECTS_NO_LAYERS:
1058 if (!prp->m_bIsInLayer) result.Add(prp->m_GUID);
1059 break;
1060 case OBJECTS_ONLY_LAYERS:
1061 if (prp->m_bIsInLayer) result.Add(prp->m_GUID);
1062 break;
1063 }
1064
1065 prpnode = prpnode->GetNext(); // RoutePoint
1066 }
1067
1068 return result;
1069}
1070
1071wxArrayString GetRouteGUIDArray(OBJECT_LAYER_REQ req) {
1072 wxArrayString result;
1073 RouteList* list = pRouteList;
1074
1075 wxRouteListNode* prpnode = list->GetFirst();
1076 while (prpnode) {
1077 Route* proute = prpnode->GetData();
1078 switch (req) {
1079 case OBJECTS_ALL:
1080 result.Add(proute->m_GUID);
1081 break;
1082 case OBJECTS_NO_LAYERS:
1083 if (!proute->m_bIsInLayer) result.Add(proute->m_GUID);
1084 break;
1085 case OBJECTS_ONLY_LAYERS:
1086 if (proute->m_bIsInLayer) result.Add(proute->m_GUID);
1087 break;
1088 }
1089
1090 prpnode = prpnode->GetNext(); // Route
1091 }
1092
1093 return result;
1094}
1095
1096wxArrayString GetTrackGUIDArray(OBJECT_LAYER_REQ req) {
1097 wxArrayString result;
1098 for (Track* ptrack : g_TrackList) {
1099 switch (req) {
1100 case OBJECTS_ALL:
1101 result.Add(ptrack->m_GUID);
1102 break;
1103 case OBJECTS_NO_LAYERS:
1104 if (!ptrack->m_bIsInLayer) result.Add(ptrack->m_GUID);
1105 break;
1106 case OBJECTS_ONLY_LAYERS:
1107 if (ptrack->m_bIsInLayer) result.Add(ptrack->m_GUID);
1108 break;
1109 }
1110 }
1111
1112 return result;
1113}
1114
1115wxArrayString GetIconNameArray(void) {
1116 wxArrayString result;
1117
1118 for (int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
1119 wxString* ps = pWayPointMan->GetIconKey(i);
1120 result.Add(*ps);
1121 }
1122 return result;
1123}
1124
1125bool AddPlugInRoute(PlugIn_Route* proute, bool b_permanent) {
1126 Route* route = new Route();
1127
1128 PlugIn_Waypoint* pwp;
1129 RoutePoint* pWP_src;
1130 int ip = 0;
1131 wxDateTime plannedDeparture;
1132
1133 wxPlugin_WaypointListNode* pwpnode = proute->pWaypointList->GetFirst();
1134 while (pwpnode) {
1135 pwp = pwpnode->GetData();
1136
1137 RoutePoint* pWP = new RoutePoint(pwp->m_lat, pwp->m_lon, pwp->m_IconName,
1138 pwp->m_MarkName, pwp->m_GUID);
1139
1140 // Transcribe (clone) the html HyperLink List, if present
1141 cloneHyperlinkList(pWP, pwp);
1142 pWP->m_MarkDescription = pwp->m_MarkDescription;
1143 pWP->m_bShowName = false;
1144 pWP->SetCreateTime(pwp->m_CreateTime);
1145
1146 route->AddPoint(pWP);
1147
1148 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
1149
1150 if (ip > 0)
1151 pSelect->AddSelectableRouteSegment(pWP_src->m_lat, pWP_src->m_lon,
1152 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
1153 route);
1154 else
1155 plannedDeparture = pwp->m_CreateTime;
1156 ip++;
1157 pWP_src = pWP;
1158
1159 pwpnode = pwpnode->GetNext(); // PlugInWaypoint
1160 }
1161
1162 route->m_PlannedDeparture = plannedDeparture;
1163
1164 route->m_RouteNameString = proute->m_NameString;
1165 route->m_RouteStartString = proute->m_StartString;
1166 route->m_RouteEndString = proute->m_EndString;
1167 if (!proute->m_GUID.IsEmpty()) {
1168 route->m_GUID = proute->m_GUID;
1169 }
1170 route->m_btemp = (b_permanent == false);
1171
1172 pRouteList->Append(route);
1173
1174 if (b_permanent) pConfig->AddNewRoute(route);
1175
1176 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1177 pRouteManagerDialog->UpdateRouteListCtrl();
1178
1179 return true;
1180}
1181
1182bool DeletePlugInRoute(wxString& GUID) {
1183 bool b_found = false;
1184
1185 // Find the Route
1186 Route* pRoute = g_pRouteMan->FindRouteByGUID(GUID);
1187 if (pRoute) {
1188 g_pRouteMan->DeleteRoute(pRoute, NavObjectChanges::getInstance());
1189 b_found = true;
1190 }
1191 return b_found;
1192}
1193
1194bool UpdatePlugInRoute(PlugIn_Route* proute) {
1195 bool b_found = false;
1196
1197 // Find the Route
1198 Route* pRoute = g_pRouteMan->FindRouteByGUID(proute->m_GUID);
1199 if (pRoute) b_found = true;
1200
1201 if (b_found) {
1202 bool b_permanent = (pRoute->m_btemp == false);
1203 g_pRouteMan->DeleteRoute(pRoute, NavObjectChanges::getInstance());
1204
1205 b_found = AddPlugInRoute(proute, b_permanent);
1206 }
1207
1208 return b_found;
1209}
1210
1211bool AddPlugInTrack(PlugIn_Track* ptrack, bool b_permanent) {
1212 Track* track = new Track();
1213
1214 PlugIn_Waypoint* pwp = 0;
1215 TrackPoint* pWP_src = 0;
1216 int ip = 0;
1217
1218 wxPlugin_WaypointListNode* pwpnode = ptrack->pWaypointList->GetFirst();
1219 while (pwpnode) {
1220 pwp = pwpnode->GetData();
1221
1222 TrackPoint* pWP = new TrackPoint(pwp->m_lat, pwp->m_lon);
1223 pWP->SetCreateTime(pwp->m_CreateTime);
1224
1225 track->AddPoint(pWP);
1226
1227 if (ip > 0)
1228 pSelect->AddSelectableTrackSegment(pWP_src->m_lat, pWP_src->m_lon,
1229 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
1230 track);
1231 ip++;
1232 pWP_src = pWP;
1233
1234 pwpnode = pwpnode->GetNext(); // PlugInWaypoint
1235 }
1236
1237 track->SetName(ptrack->m_NameString);
1238 track->m_TrackStartString = ptrack->m_StartString;
1239 track->m_TrackEndString = ptrack->m_EndString;
1240 track->m_GUID = ptrack->m_GUID;
1241 track->m_btemp = (b_permanent == false);
1242
1243 g_TrackList.push_back(track);
1244
1245 if (b_permanent) pConfig->AddNewTrack(track);
1246
1247 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1248 pRouteManagerDialog->UpdateTrkListCtrl();
1249
1250 return true;
1251}
1252
1253bool DeletePlugInTrack(wxString& GUID) {
1254 bool b_found = false;
1255
1256 // Find the Route
1257 Track* pTrack = g_pRouteMan->FindTrackByGUID(GUID);
1258 if (pTrack) {
1259 RoutemanGui(*g_pRouteMan).DeleteTrack(pTrack);
1260 b_found = true;
1261 }
1262
1263 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1264 pRouteManagerDialog->UpdateTrkListCtrl();
1265
1266 return b_found;
1267}
1268
1269bool UpdatePlugInTrack(PlugIn_Track* ptrack) {
1270 bool b_found = false;
1271
1272 // Find the Track
1273 Track* pTrack = g_pRouteMan->FindTrackByGUID(ptrack->m_GUID);
1274 if (pTrack) b_found = true;
1275
1276 if (b_found) {
1277 bool b_permanent = (pTrack->m_btemp == false);
1278 RoutemanGui(*g_pRouteMan).DeleteTrack(pTrack);
1279
1280 b_found = AddPlugInTrack(ptrack, b_permanent);
1281 }
1282
1283 return b_found;
1284}
1285
1286bool PlugInHasNormalizedViewPort(PlugIn_ViewPort* vp) {
1287#ifdef ocpnUSE_GL
1288 ViewPort ocpn_vp;
1289 ocpn_vp.m_projection_type = vp->m_projection_type;
1290
1291 return glChartCanvas::HasNormalizedViewPort(ocpn_vp);
1292#else
1293 return false;
1294#endif
1295}
1296
1297void PlugInMultMatrixViewport(PlugIn_ViewPort* vp, float lat, float lon) {
1298#ifdef ocpnUSE_GL
1299 ViewPort ocpn_vp;
1300 ocpn_vp.clat = vp->clat;
1301 ocpn_vp.clon = vp->clon;
1302 ocpn_vp.m_projection_type = vp->m_projection_type;
1303 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
1304 ocpn_vp.skew = vp->skew;
1305 ocpn_vp.rotation = vp->rotation;
1306 ocpn_vp.pix_width = vp->pix_width;
1307 ocpn_vp.pix_height = vp->pix_height;
1308
1309// TODO fix for multicanvas glChartCanvas::MultMatrixViewPort(ocpn_vp, lat,
1310// lon);
1311#endif
1312}
1313
1314void PlugInNormalizeViewport(PlugIn_ViewPort* vp, float lat, float lon) {
1315#ifdef ocpnUSE_GL
1316 ViewPort ocpn_vp;
1317 glChartCanvas::NormalizedViewPort(ocpn_vp, lat, lon);
1318
1319 vp->clat = ocpn_vp.clat;
1320 vp->clon = ocpn_vp.clon;
1321 vp->view_scale_ppm = ocpn_vp.view_scale_ppm;
1322 vp->rotation = ocpn_vp.rotation;
1323 vp->skew = ocpn_vp.skew;
1324#endif
1325}
1326
1327// Helper and interface classes
1328
1329//-------------------------------------------------------------------------------
1330// PlugIn_AIS_Target Implementation
1331//-------------------------------------------------------------------------------
1332
1333PlugIn_AIS_Target* Create_PI_AIS_Target(AisTargetData* ptarget) {
1335
1336 pret->MMSI = ptarget->MMSI;
1337 pret->Class = ptarget->Class;
1338 pret->NavStatus = ptarget->NavStatus;
1339 pret->SOG = ptarget->SOG;
1340 pret->COG = ptarget->COG;
1341 pret->HDG = ptarget->HDG;
1342 pret->Lon = ptarget->Lon;
1343 pret->Lat = ptarget->Lat;
1344 pret->ROTAIS = ptarget->ROTAIS;
1345 pret->ShipType = ptarget->ShipType;
1346 pret->IMO = ptarget->IMO;
1347
1348 pret->Range_NM = ptarget->Range_NM;
1349 pret->Brg = ptarget->Brg;
1350
1351 // Per target collision parameters
1352 pret->bCPA_Valid = ptarget->bCPA_Valid;
1353 pret->TCPA = ptarget->TCPA; // Minutes
1354 pret->CPA = ptarget->CPA; // Nautical Miles
1355
1356 pret->alarm_state = (plugin_ais_alarm_type)ptarget->n_alert_state;
1357
1358 memcpy(pret->CallSign, ptarget->CallSign, sizeof(ptarget->CallSign) - 1);
1359 memcpy(pret->ShipName, ptarget->ShipName, sizeof(ptarget->ShipName) - 1);
1360
1361 return pret;
1362}
1363
1364//---------------------------------------------------------------------------
1365// API 1.11
1366//---------------------------------------------------------------------------
1367
1368//---------------------------------------------------------------------------
1369// API 1.12
1370//---------------------------------------------------------------------------
1371
1372//---------------------------------------------------------------------------
1373// API 1.13
1374//---------------------------------------------------------------------------
1375double fromDMM_Plugin(wxString sdms) { return fromDMM(sdms); }
1376
1377void SetCanvasRotation(double rotation) {
1378 gFrame->GetPrimaryCanvas()->DoRotateCanvas(rotation);
1379}
1380
1381double GetCanvasTilt() { return gFrame->GetPrimaryCanvas()->GetVPTilt(); }
1382
1383void SetCanvasTilt(double tilt) {
1384 gFrame->GetPrimaryCanvas()->DoTiltCanvas(tilt);
1385}
1386
1387void SetCanvasProjection(int projection) {
1388 gFrame->GetPrimaryCanvas()->SetVPProjection(projection);
1389}
1390
1391OcpnSound* g_PluginSound = SoundFactory();
1392static void onPlugInPlaySoundExFinished(void* ptr) {}
1393
1394// Start playing a sound to a given device and return status to plugin
1395bool PlugInPlaySoundEx(wxString& sound_file, int deviceIndex) {
1396 bool ok = g_PluginSound->Load(sound_file, deviceIndex);
1397 if (!ok) {
1398 wxLogWarning("Cannot load sound file: %s", sound_file);
1399 return false;
1400 }
1401 auto cmd_sound = dynamic_cast<SystemCmdSound*>(g_PluginSound);
1402 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
1403
1404 g_PluginSound->SetFinishedCallback(onPlugInPlaySoundExFinished, NULL);
1405 ok = g_PluginSound->Play();
1406 if (!ok) {
1407 wxLogWarning("Cannot play sound file: %s", sound_file);
1408 }
1409 return ok;
1410}
1411
1412bool CheckEdgePan_PlugIn(int x, int y, bool dragging, int margin, int delta) {
1413 return gFrame->GetPrimaryCanvas()->CheckEdgePan(x, y, dragging, margin,
1414 delta);
1415}
1416
1417wxBitmap GetIcon_PlugIn(const wxString& name) {
1418 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
1419 return style->GetIcon(name);
1420}
1421
1422void SetCursor_PlugIn(wxCursor* pCursor) {
1423 gFrame->GetPrimaryCanvas()->pPlugIn_Cursor = pCursor;
1424}
1425
1426void AddChartDirectory(wxString& path) {
1427 if (g_options) {
1428 g_options->AddChartDir(path);
1429 }
1430}
1431
1432void ForceChartDBUpdate() {
1433 if (g_options) {
1434 g_options->pScanCheckBox->SetValue(true);
1435 g_options->pUpdateCheckBox->SetValue(true);
1436 }
1437}
1438
1439void ForceChartDBRebuild() {
1440 if (g_options) {
1441 g_options->pUpdateCheckBox->SetValue(true);
1442 }
1443}
1444
1445wxDialog* GetActiveOptionsDialog() { return g_options; }
1446
1447int PlatformDirSelectorDialog(wxWindow* parent, wxString* file_spec,
1448 wxString Title, wxString initDir) {
1449 return g_Platform->DoDirSelectorDialog(parent, file_spec, Title, initDir);
1450}
1451
1452int PlatformFileSelectorDialog(wxWindow* parent, wxString* file_spec,
1453 wxString Title, wxString initDir,
1454 wxString suggestedName, wxString wildcard) {
1455 return g_Platform->DoFileSelectorDialog(parent, file_spec, Title, initDir,
1456 suggestedName, wildcard);
1457}
1458
1459//---------------------------------------------------------------------------
1460// API 1.14
1461//---------------------------------------------------------------------------
1462
1463ViewPort CreateCompatibleViewportEx(const PlugIn_ViewPort& pivp) {
1464 // Create a system ViewPort
1465 ViewPort vp;
1466
1467 vp.clat = pivp.clat; // center point
1468 vp.clon = pivp.clon;
1469 vp.view_scale_ppm = pivp.view_scale_ppm;
1470 vp.skew = pivp.skew;
1471 vp.rotation = pivp.rotation;
1472 vp.chart_scale = pivp.chart_scale;
1473 vp.pix_width = pivp.pix_width;
1474 vp.pix_height = pivp.pix_height;
1475 vp.rv_rect = pivp.rv_rect;
1476 vp.b_quilt = pivp.b_quilt;
1477 vp.m_projection_type = pivp.m_projection_type;
1478
1479 if (gFrame->GetPrimaryCanvas())
1480 vp.ref_scale = gFrame->GetPrimaryCanvas()->GetVP().ref_scale;
1481 else
1482 vp.ref_scale = vp.chart_scale;
1483
1484 vp.SetBoxes();
1485 vp.Validate(); // This VP is valid
1486
1487 return vp;
1488}
1489
1490void PlugInAISDrawGL(wxGLCanvas* glcanvas, const PlugIn_ViewPort& vp) {
1491 ViewPort ocpn_vp = CreateCompatibleViewportEx(vp);
1492
1493 ocpnDC dc(*glcanvas);
1494 dc.SetVP(ocpn_vp);
1495
1496 AISDraw(dc, ocpn_vp, NULL);
1497}
1498
1499bool PlugInSetFontColor(const wxString TextElement, const wxColour color) {
1500 return FontMgr::Get().SetFontColor(TextElement, color);
1501}
1502
1503//---------------------------------------------------------------------------
1504// API 1.15
1505//---------------------------------------------------------------------------
1506
1507double PlugInGetDisplaySizeMM() { return g_Platform->GetDisplaySizeMM(); }
1508
1509wxFont* FindOrCreateFont_PlugIn(int point_size, wxFontFamily family,
1510 wxFontStyle style, wxFontWeight weight,
1511 bool underline, const wxString& facename,
1512 wxFontEncoding encoding) {
1513 return FontMgr::Get().FindOrCreateFont(point_size, family, style, weight,
1514 underline, facename, encoding);
1515}
1516
1517int PluginGetMinAvailableGshhgQuality() {
1518 return gFrame->GetPrimaryCanvas()->GetMinAvailableGshhgQuality();
1519}
1520int PluginGetMaxAvailableGshhgQuality() {
1521 return gFrame->GetPrimaryCanvas()->GetMaxAvailableGshhgQuality();
1522}
1523
1524// disable builtin console canvas, and autopilot nmea sentences
1525void PlugInHandleAutopilotRoute(bool enable) {
1526 g_bPluginHandleAutopilotRoute = enable;
1527}
1528
1529bool LaunchDefaultBrowser_Plugin(wxString url) {
1530 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
1531
1532 return true;
1533}
1534
1535//---------------------------------------------------------------------------
1536// API 1.16
1537//---------------------------------------------------------------------------
1538wxString GetSelectedWaypointGUID_Plugin() {
1539 ChartCanvas* cc = gFrame->GetFocusCanvas();
1540 if (cc && cc->GetSelectedRoutePoint()) {
1541 return cc->GetSelectedRoutePoint()->m_GUID;
1542 }
1543 return wxEmptyString;
1544}
1545
1546wxString GetSelectedRouteGUID_Plugin() {
1547 ChartCanvas* cc = gFrame->GetFocusCanvas();
1548 if (cc && cc->GetSelectedRoute()) {
1549 return cc->GetSelectedRoute()->m_GUID;
1550 }
1551 return wxEmptyString;
1552}
1553
1554wxString GetSelectedTrackGUID_Plugin() {
1555 ChartCanvas* cc = gFrame->GetFocusCanvas();
1556 if (cc && cc->GetSelectedTrack()) {
1557 return cc->GetSelectedTrack()->m_GUID;
1558 }
1559 return wxEmptyString;
1560}
1561
1562std::unique_ptr<PlugIn_Waypoint> GetWaypoint_Plugin(const wxString& GUID) {
1563 std::unique_ptr<PlugIn_Waypoint> w(new PlugIn_Waypoint);
1564 GetSingleWaypoint(GUID, w.get());
1565 return w;
1566}
1567
1568std::unique_ptr<PlugIn_Route> GetRoute_Plugin(const wxString& GUID) {
1569 std::unique_ptr<PlugIn_Route> r;
1570 Route* route = g_pRouteMan->FindRouteByGUID(GUID);
1571 if (route == nullptr) return r;
1572
1573 r = std::unique_ptr<PlugIn_Route>(new PlugIn_Route);
1574 PlugIn_Route* dst_route = r.get();
1575
1576 // PlugIn_Waypoint *pwp;
1577 RoutePoint* src_wp;
1578 wxRoutePointListNode* node = route->pRoutePointList->GetFirst();
1579
1580 while (node) {
1581 src_wp = node->GetData();
1582
1583 PlugIn_Waypoint* dst_wp = new PlugIn_Waypoint();
1584 PlugInFromRoutePoint(dst_wp, src_wp);
1585
1586 dst_route->pWaypointList->Append(dst_wp);
1587
1588 node = node->GetNext();
1589 }
1590 dst_route->m_NameString = route->m_RouteNameString;
1591 dst_route->m_StartString = route->m_RouteStartString;
1592 dst_route->m_EndString = route->m_RouteEndString;
1593 dst_route->m_GUID = route->m_GUID;
1594
1595 return r;
1596}
1597
1598std::unique_ptr<PlugIn_Track> GetTrack_Plugin(const wxString& GUID) {
1599 std::unique_ptr<PlugIn_Track> t;
1600 // Find the Track
1601 Track* pTrack = g_pRouteMan->FindTrackByGUID(GUID);
1602 if (!pTrack) return t;
1603
1604 std::unique_ptr<PlugIn_Track> tk =
1605 std::unique_ptr<PlugIn_Track>(new PlugIn_Track);
1606 PlugIn_Track* dst_track = tk.get();
1607 dst_track->m_NameString = pTrack->GetName();
1608 dst_track->m_StartString = pTrack->m_TrackStartString;
1609 dst_track->m_EndString = pTrack->m_TrackEndString;
1610 dst_track->m_GUID = pTrack->m_GUID;
1611
1612 for (int i = 0; i < pTrack->GetnPoints(); i++) {
1613 TrackPoint* ptp = pTrack->GetPoint(i);
1614
1615 PlugIn_Waypoint* dst_wp = new PlugIn_Waypoint();
1616
1617 dst_wp->m_lat = ptp->m_lat;
1618 dst_wp->m_lon = ptp->m_lon;
1619 dst_wp->m_CreateTime = ptp->GetCreateTime(); // not const
1620
1621 dst_track->pWaypointList->Append(dst_wp);
1622 }
1623
1624 return tk;
1625}
1626
1627wxWindow* PluginGetFocusCanvas() { return g_focusCanvas; }
1628
1629wxWindow* PluginGetOverlayRenderCanvas() {
1630 // if(g_overlayCanvas)
1631 return g_overlayCanvas;
1632 // else
1633}
1634
1635void CanvasJumpToPosition(wxWindow* canvas, double lat, double lon,
1636 double scale) {
1637 auto oCanvas = dynamic_cast<ChartCanvas*>(canvas);
1638 if (oCanvas) gFrame->JumpToPosition(oCanvas, lat, lon, scale);
1639}
1640
1641bool ShuttingDown(void) { return g_bquiting; }
1642
1643wxWindow* GetCanvasUnderMouse(void) { return gFrame->GetCanvasUnderMouse(); }
1644
1645int GetCanvasIndexUnderMouse(void) {
1646 ChartCanvas* l_canvas = gFrame->GetCanvasUnderMouse();
1647 if (l_canvas) {
1648 for (unsigned int i = 0; i < g_canvasArray.GetCount(); ++i) {
1649 if (l_canvas == g_canvasArray[i]) return i;
1650 }
1651 }
1652 return 0;
1653}
1654
1655// std::vector<wxWindow *> GetCanvasArray()
1656// {
1657// std::vector<wxWindow *> rv;
1658// for(unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
1659// ChartCanvas *cc = g_canvasArray.Item(i);
1660// rv.push_back(cc);
1661// }
1662//
1663// return rv;
1664// }
1665
1666wxWindow* GetCanvasByIndex(int canvasIndex) {
1667 if (g_canvasConfig == 0)
1668 return gFrame->GetPrimaryCanvas();
1669 else {
1670 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
1671 return g_canvasArray[canvasIndex];
1672 }
1673 }
1674 return NULL;
1675}
1676
1677bool CheckMUIEdgePan_PlugIn(int x, int y, bool dragging, int margin, int delta,
1678 int canvasIndex) {
1679 if (g_canvasConfig == 0)
1680 return gFrame->GetPrimaryCanvas()->CheckEdgePan(x, y, dragging, margin,
1681 delta);
1682 else {
1683 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
1684 return g_canvasArray[canvasIndex]->CheckEdgePan(x, y, dragging, margin,
1685 delta);
1686 }
1687 }
1688
1689 return false;
1690}
1691
1692void SetMUICursor_PlugIn(wxCursor* pCursor, int canvasIndex) {
1693 if (g_canvasConfig == 0)
1694 gFrame->GetPrimaryCanvas()->pPlugIn_Cursor = pCursor;
1695 else {
1696 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
1697 g_canvasArray[canvasIndex]->pPlugIn_Cursor = pCursor;
1698 }
1699 }
1700}
1701
1702int GetCanvasCount() {
1703 if (g_canvasConfig == 1) return 2;
1704 // else
1705 return 1;
1706}
1707
1708int GetLatLonFormat() { return g_iSDMMFormat; }
1709
1710wxRect GetMasterToolbarRect() {
1711 if (g_MainToolbar)
1712 return g_MainToolbar->GetToolbarRect();
1713 else
1714 return wxRect(0, 0, 1, 1);
1715}
1716
1717//---------------------------------------------------------------------------
1718// API 1.17
1719//---------------------------------------------------------------------------
1720
1721void ZeroXTE() {
1722 if (g_pRouteMan) {
1723 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1724 }
1725}
1726
1727static PlugIn_ViewPort CreatePlugInViewportEx(const ViewPort& vp) {
1728 // Create a PlugIn Viewport
1729 ViewPort tvp = vp;
1730 PlugIn_ViewPort pivp;
1731
1732 pivp.clat = tvp.clat; // center point
1733 pivp.clon = tvp.clon;
1734 pivp.view_scale_ppm = tvp.view_scale_ppm;
1735 pivp.skew = tvp.skew;
1736 pivp.rotation = tvp.rotation;
1737 pivp.chart_scale = tvp.chart_scale;
1738 pivp.pix_width = tvp.pix_width;
1739 pivp.pix_height = tvp.pix_height;
1740 pivp.rv_rect = tvp.rv_rect;
1741 pivp.b_quilt = tvp.b_quilt;
1742 pivp.m_projection_type = tvp.m_projection_type;
1743
1744 pivp.lat_min = tvp.GetBBox().GetMinLat();
1745 pivp.lat_max = tvp.GetBBox().GetMaxLat();
1746 pivp.lon_min = tvp.GetBBox().GetMinLon();
1747 pivp.lon_max = tvp.GetBBox().GetMaxLon();
1748
1749 pivp.bValid = tvp.IsValid(); // This VP is valid
1750
1751 return pivp;
1752}
1753
1754ListOfPI_S57Obj* PlugInManager::GetLightsObjRuleListVisibleAtLatLon(
1755 ChartPlugInWrapper* target, float zlat, float zlon, const ViewPort& vp) {
1756 ListOfPI_S57Obj* list = NULL;
1757 if (target) {
1758 PlugInChartBaseGLPlus2* picbgl =
1759 dynamic_cast<PlugInChartBaseGLPlus2*>(target->GetPlugInChart());
1760 if (picbgl) {
1761 PlugIn_ViewPort pi_vp = CreatePlugInViewportEx(vp);
1762 list = picbgl->GetLightsObjRuleListVisibleAtLatLon(zlat, zlon, &pi_vp);
1763
1764 return list;
1765 }
1767 dynamic_cast<PlugInChartBaseExtendedPlus2*>(target->GetPlugInChart());
1768 if (picbx) {
1769 PlugIn_ViewPort pi_vp = CreatePlugInViewportEx(vp);
1770 list = picbx->GetLightsObjRuleListVisibleAtLatLon(zlat, zlon, &pi_vp);
1771
1772 return list;
1773 } else
1774 return list;
1775 } else
1776 return list;
1777}
1778
1779// PlugInWaypointEx implementation
1780
1781#include <wx/listimpl.cpp>
1782WX_DEFINE_LIST(Plugin_WaypointExList)
1783
1784// The class implementations
1785PlugIn_Waypoint_Ex::PlugIn_Waypoint_Ex() { InitDefaults(); }
1786
1787PlugIn_Waypoint_Ex::PlugIn_Waypoint_Ex(
1788 double lat, double lon, const wxString& icon_ident, const wxString& wp_name,
1789 const wxString& GUID, const double ScaMin, const bool bNameVisible,
1790 const int nRangeRings, const double RangeDistance,
1791 const wxColor RangeColor) {
1792 InitDefaults();
1793
1794 wxDateTime now = wxDateTime::Now();
1795 m_CreateTime = now.ToUTC();
1796 m_HyperlinkList = NULL;
1797
1798 m_lat = lat;
1799 m_lon = lon;
1800 IconName = icon_ident;
1801 m_MarkName = wp_name;
1802 m_GUID = GUID;
1803 scamin = ScaMin;
1804 IsNameVisible = bNameVisible;
1805 nrange_rings = nRangeRings;
1806 RangeRingSpace = RangeDistance;
1807 RangeRingColor = RangeColor;
1808}
1809
1810void PlugIn_Waypoint_Ex::InitDefaults() {
1811 m_HyperlinkList = NULL;
1812 scamin = 1e9;
1813 b_useScamin = false;
1814 nrange_rings = 0;
1815 RangeRingSpace = 1;
1816 IsNameVisible = false;
1817 IsVisible = true;
1818 RangeRingColor = *wxBLACK;
1819 m_CreateTime = wxDateTime::Now();
1820 IsActive = false;
1821 m_lat = 0;
1822 m_lon = 0;
1823}
1824
1825bool PlugIn_Waypoint_Ex::GetFSStatus() {
1826 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(m_GUID);
1827 if (!prp) return false;
1828
1829 if (prp->m_bIsInRoute && !prp->IsShared()) return false;
1830
1831 return true;
1832}
1833
1834int PlugIn_Waypoint_Ex::GetRouteMembershipCount() {
1835 // Search all routes to count the membership of this point
1836 RoutePoint* pWP = pWayPointMan->FindRoutePointByGUID(m_GUID);
1837 if (!pWP) return 0;
1838
1839 int nCount = 0;
1840 wxRouteListNode* node = pRouteList->GetFirst();
1841 while (node) {
1842 Route* proute = node->GetData();
1843 wxRoutePointListNode* pnode = (proute->pRoutePointList)->GetFirst();
1844 while (pnode) {
1845 RoutePoint* prp = pnode->GetData();
1846 if (prp == pWP) nCount++;
1847 pnode = pnode->GetNext();
1848 }
1849
1850 node = node->GetNext();
1851 }
1852
1853 return nCount;
1854}
1855
1856PlugIn_Waypoint_Ex::~PlugIn_Waypoint_Ex() {}
1857
1858// PlugInRouteExtended implementation
1859PlugIn_Route_Ex::PlugIn_Route_Ex(void) {
1860 pWaypointList = new Plugin_WaypointExList;
1861}
1862
1863PlugIn_Route_Ex::~PlugIn_Route_Ex(void) {
1864 pWaypointList->DeleteContents(false); // do not delete Waypoints
1865 pWaypointList->Clear();
1866
1867 delete pWaypointList;
1868}
1869
1870// The utility methods implementations
1871
1872// translate O route class to PlugIn_Waypoint_Ex
1873static void PlugInExFromRoutePoint(PlugIn_Waypoint_Ex* dst,
1874 /* const*/ RoutePoint* src) {
1875 dst->m_lat = src->m_lat;
1876 dst->m_lon = src->m_lon;
1877 dst->IconName = src->GetIconName();
1878 dst->m_MarkName = src->GetName();
1879 dst->m_MarkDescription = src->GetDescription();
1880 dst->IconDescription = pWayPointMan->GetIconDescription(src->GetIconName());
1881 dst->IsVisible = src->IsVisible();
1882 dst->m_CreateTime = src->GetCreateTime(); // not const
1883 dst->m_GUID = src->m_GUID;
1884
1885 // Transcribe (clone) the html HyperLink List, if present
1886 if (src->m_HyperlinkList == nullptr) return;
1887
1888 delete dst->m_HyperlinkList;
1889 dst->m_HyperlinkList = nullptr;
1890
1891 if (src->m_HyperlinkList->GetCount() > 0) {
1892 dst->m_HyperlinkList = new Plugin_HyperlinkList;
1893
1894 wxHyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
1895 while (linknode) {
1896 Hyperlink* link = linknode->GetData();
1897
1899 h->DescrText = link->DescrText;
1900 h->Link = link->Link;
1901 h->Type = link->LType;
1902
1903 dst->m_HyperlinkList->Append(h);
1904
1905 linknode = linknode->GetNext();
1906 }
1907 }
1908
1909 // Get the range ring info
1910 dst->nrange_rings = src->m_iWaypointRangeRingsNumber;
1911 dst->RangeRingSpace = src->m_fWaypointRangeRingsStep;
1912 dst->RangeRingColor = src->m_wxcWaypointRangeRingsColour;
1913
1914 // Get other extended info
1915 dst->IsNameVisible = src->m_bShowName;
1916 dst->scamin = src->GetScaMin();
1917 dst->b_useScamin = src->GetUseSca();
1918 dst->IsActive = src->m_bIsActive;
1919}
1920
1921static void cloneHyperlinkListEx(RoutePoint* dst,
1922 const PlugIn_Waypoint_Ex* src) {
1923 // Transcribe (clone) the html HyperLink List, if present
1924 if (src->m_HyperlinkList == nullptr) return;
1925
1926 if (src->m_HyperlinkList->GetCount() > 0) {
1927 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
1928 while (linknode) {
1929 Plugin_Hyperlink* link = linknode->GetData();
1930
1931 Hyperlink* h = new Hyperlink();
1932 h->DescrText = link->DescrText;
1933 h->Link = link->Link;
1934 h->LType = link->Type;
1935
1936 dst->m_HyperlinkList->Append(h);
1937
1938 linknode = linknode->GetNext();
1939 }
1940 }
1941}
1942
1943RoutePoint* CreateNewPoint(const PlugIn_Waypoint_Ex* src, bool b_permanent) {
1944 RoutePoint* pWP = new RoutePoint(src->m_lat, src->m_lon, src->IconName,
1945 src->m_MarkName, src->m_GUID);
1946
1947 pWP->m_bIsolatedMark = true; // This is an isolated mark
1948
1949 cloneHyperlinkListEx(pWP, src);
1950
1951 pWP->m_MarkDescription = src->m_MarkDescription;
1952
1953 if (src->m_CreateTime.IsValid())
1954 pWP->SetCreateTime(src->m_CreateTime);
1955 else {
1956 wxDateTime dtnow(wxDateTime::Now());
1957 pWP->SetCreateTime(dtnow);
1958 }
1959
1960 pWP->m_btemp = (b_permanent == false);
1961
1962 // Extended fields
1963 pWP->SetIconName(src->IconName);
1964 pWP->SetWaypointRangeRingsNumber(src->nrange_rings);
1965 pWP->SetWaypointRangeRingsStep(src->RangeRingSpace);
1966 pWP->SetWaypointRangeRingsColour(src->RangeRingColor);
1967 pWP->SetScaMin(src->scamin);
1968 pWP->SetUseSca(src->b_useScamin);
1969 pWP->SetNameShown(src->IsNameVisible);
1970 pWP->SetVisible(src->IsVisible);
1971
1972 return pWP;
1973}
1974bool GetSingleWaypointEx(wxString GUID, PlugIn_Waypoint_Ex* pwaypoint) {
1975 // Find the RoutePoint
1976 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
1977
1978 if (!prp) return false;
1979
1980 PlugInExFromRoutePoint(pwaypoint, prp);
1981
1982 return true;
1983}
1984
1985bool AddSingleWaypointEx(PlugIn_Waypoint_Ex* pwaypointex, bool b_permanent) {
1986 // Validate the waypoint parameters a little bit
1987
1988 // GUID
1989 // Make sure that this GUID is indeed unique in the Routepoint list
1990 bool b_unique = true;
1991 wxRoutePointListNode* prpnode = pWayPointMan->GetWaypointList()->GetFirst();
1992 while (prpnode) {
1993 RoutePoint* prp = prpnode->GetData();
1994
1995 if (prp->m_GUID == pwaypointex->m_GUID) {
1996 b_unique = false;
1997 break;
1998 }
1999 prpnode = prpnode->GetNext(); // RoutePoint
2000 }
2001
2002 if (!b_unique) return false;
2003
2004 RoutePoint* pWP = CreateNewPoint(pwaypointex, b_permanent);
2005
2006 pWP->SetShowWaypointRangeRings(pwaypointex->nrange_rings > 0);
2007
2008 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
2009 if (b_permanent) pConfig->AddNewWayPoint(pWP, -1);
2010
2011 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
2012 pRouteManagerDialog->UpdateWptListCtrl();
2013
2014 return true;
2015}
2016
2017bool UpdateSingleWaypointEx(PlugIn_Waypoint_Ex* pwaypoint) {
2018 // Find the RoutePoint
2019 bool b_found = false;
2020 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(pwaypoint->m_GUID);
2021
2022 if (prp) b_found = true;
2023
2024 if (b_found) {
2025 double lat_save = prp->m_lat;
2026 double lon_save = prp->m_lon;
2027
2028 prp->m_lat = pwaypoint->m_lat;
2029 prp->m_lon = pwaypoint->m_lon;
2030 prp->SetIconName(pwaypoint->IconName);
2031 prp->SetName(pwaypoint->m_MarkName);
2032 prp->m_MarkDescription = pwaypoint->m_MarkDescription;
2033 prp->SetVisible(pwaypoint->IsVisible);
2034 if (pwaypoint->m_CreateTime.IsValid())
2035 prp->SetCreateTime(pwaypoint->m_CreateTime);
2036
2037 // Transcribe (clone) the html HyperLink List, if present
2038
2039 if (pwaypoint->m_HyperlinkList) {
2040 prp->m_HyperlinkList->Clear();
2041 if (pwaypoint->m_HyperlinkList->GetCount() > 0) {
2042 wxPlugin_HyperlinkListNode* linknode =
2043 pwaypoint->m_HyperlinkList->GetFirst();
2044 while (linknode) {
2045 Plugin_Hyperlink* link = linknode->GetData();
2046
2047 Hyperlink* h = new Hyperlink();
2048 h->DescrText = link->DescrText;
2049 h->Link = link->Link;
2050 h->LType = link->Type;
2051
2052 prp->m_HyperlinkList->Append(h);
2053
2054 linknode = linknode->GetNext();
2055 }
2056 }
2057 }
2058
2059 // Extended fields
2060 prp->SetWaypointRangeRingsNumber(pwaypoint->nrange_rings);
2061 prp->SetWaypointRangeRingsStep(pwaypoint->RangeRingSpace);
2062 prp->SetWaypointRangeRingsColour(pwaypoint->RangeRingColor);
2063 prp->SetScaMin(pwaypoint->scamin);
2064 prp->SetUseSca(pwaypoint->b_useScamin);
2065 prp->SetNameShown(pwaypoint->IsNameVisible);
2066
2067 prp->SetShowWaypointRangeRings(pwaypoint->nrange_rings > 0);
2068
2069 if (prp) prp->ReLoadIcon();
2070
2071 auto canvas = gFrame->GetPrimaryCanvas();
2072 SelectCtx ctx(canvas->m_bShowNavobjects, canvas->GetCanvasTrueScale(),
2073 canvas->GetScaleValue());
2074 SelectItem* pFind =
2075 pSelect->FindSelection(ctx, lat_save, lon_save, SELTYPE_ROUTEPOINT);
2076 if (pFind) {
2077 pFind->m_slat = pwaypoint->m_lat; // update the SelectList entry
2078 pFind->m_slon = pwaypoint->m_lon;
2079 }
2080
2081 if (!prp->m_btemp) pConfig->UpdateWayPoint(prp);
2082
2083 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
2084 pRouteManagerDialog->UpdateWptListCtrl();
2085 }
2086
2087 return b_found;
2088}
2089
2090bool AddPlugInRouteEx(PlugIn_Route_Ex* proute, bool b_permanent) {
2091 Route* route = new Route();
2092
2093 PlugIn_Waypoint_Ex* pwaypointex;
2094 RoutePoint *pWP, *pWP_src;
2095 int ip = 0;
2096 wxDateTime plannedDeparture;
2097
2098 wxPlugin_WaypointExListNode* pwpnode = proute->pWaypointList->GetFirst();
2099 while (pwpnode) {
2100 pwaypointex = pwpnode->GetData();
2101
2102 pWP = pWayPointMan->FindRoutePointByGUID(pwaypointex->m_GUID);
2103 if (!pWP) {
2104 pWP = CreateNewPoint(pwaypointex, b_permanent);
2105 pWP->m_bIsolatedMark = false;
2106 }
2107
2108 route->AddPoint(pWP);
2109
2110 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
2111
2112 if (ip > 0)
2113 pSelect->AddSelectableRouteSegment(pWP_src->m_lat, pWP_src->m_lon,
2114 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
2115 route);
2116
2117 plannedDeparture = pwaypointex->m_CreateTime;
2118 ip++;
2119 pWP_src = pWP;
2120
2121 pwpnode = pwpnode->GetNext(); // PlugInWaypoint
2122 }
2123
2124 route->m_PlannedDeparture = plannedDeparture;
2125
2126 route->m_RouteNameString = proute->m_NameString;
2127 route->m_RouteStartString = proute->m_StartString;
2128 route->m_RouteEndString = proute->m_EndString;
2129 if (!proute->m_GUID.IsEmpty()) {
2130 route->m_GUID = proute->m_GUID;
2131 }
2132 route->m_btemp = (b_permanent == false);
2133 route->SetVisible(proute->m_isVisible);
2134 route->m_RouteDescription = proute->m_Description;
2135
2136 pRouteList->Append(route);
2137
2138 if (b_permanent) pConfig->AddNewRoute(route);
2139
2140 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
2141 pRouteManagerDialog->UpdateRouteListCtrl();
2142
2143 return true;
2144}
2145
2146bool UpdatePlugInRouteEx(PlugIn_Route_Ex* proute) {
2147 bool b_found = false;
2148
2149 // Find the Route
2150 Route* pRoute = g_pRouteMan->FindRouteByGUID(proute->m_GUID);
2151 if (pRoute) b_found = true;
2152
2153 if (b_found) {
2154 bool b_permanent = !pRoute->m_btemp;
2155 g_pRouteMan->DeleteRoute(pRoute, NavObjectChanges::getInstance());
2156
2157 b_found = AddPlugInRouteEx(proute, b_permanent);
2158 }
2159
2160 return b_found;
2161}
2162
2163// std::unique_ptr<PlugIn_Waypoint_Ex> GetWaypointEx_Plugin(const wxString &)
2164// {
2165// }
2166
2167// std::unique_ptr<PlugIn_Route_Ex> GetRouteEx_Plugin(const wxString &)
2168// {
2169// }
2170
2171std::unique_ptr<PlugIn_Waypoint_Ex> GetWaypointEx_Plugin(const wxString& GUID) {
2172 std::unique_ptr<PlugIn_Waypoint_Ex> w(new PlugIn_Waypoint_Ex);
2173 GetSingleWaypointEx(GUID, w.get());
2174 return w;
2175}
2176
2177std::unique_ptr<PlugIn_Route_Ex> GetRouteEx_Plugin(const wxString& GUID) {
2178 std::unique_ptr<PlugIn_Route_Ex> r;
2179 Route* route = g_pRouteMan->FindRouteByGUID(GUID);
2180 if (route == nullptr) return r;
2181
2182 r = std::unique_ptr<PlugIn_Route_Ex>(new PlugIn_Route_Ex);
2183 PlugIn_Route_Ex* dst_route = r.get();
2184
2185 // PlugIn_Waypoint *pwp;
2186 RoutePoint* src_wp;
2187 wxRoutePointListNode* node = route->pRoutePointList->GetFirst();
2188
2189 while (node) {
2190 src_wp = node->GetData();
2191
2192 PlugIn_Waypoint_Ex* dst_wp = new PlugIn_Waypoint_Ex();
2193 PlugInExFromRoutePoint(dst_wp, src_wp);
2194
2195 dst_route->pWaypointList->Append(dst_wp);
2196
2197 node = node->GetNext();
2198 }
2199 dst_route->m_NameString = route->m_RouteNameString;
2200 dst_route->m_StartString = route->m_RouteStartString;
2201 dst_route->m_EndString = route->m_RouteEndString;
2202 dst_route->m_GUID = route->m_GUID;
2203 dst_route->m_isActive = g_pRouteMan->GetpActiveRoute() == route;
2204 dst_route->m_isVisible = route->IsVisible();
2205 dst_route->m_Description = route->m_RouteDescription;
2206
2207 return r;
2208}
2209
2210wxString GetActiveWaypointGUID(
2211 void) { // if no active waypoint, returns wxEmptyString
2212 RoutePoint* rp = g_pRouteMan->GetpActivePoint();
2213 if (!rp)
2214 return wxEmptyString;
2215 else
2216 return rp->m_GUID;
2217}
2218
2219wxString GetActiveRouteGUID(
2220 void) { // if no active route, returns wxEmptyString
2221 Route* rt = g_pRouteMan->GetpActiveRoute();
2222 if (!rt)
2223 return wxEmptyString;
2224 else
2225 return rt->m_GUID;
2226}
2227
2229int GetGlobalWatchdogTimoutSeconds() { return gps_watchdog_timeout_ticks; }
2230
2232std::vector<std::string> GetPriorityMaps() {
2233 MyApp& app = wxGetApp();
2234 return (app.m_comm_bridge.GetPriorityMaps());
2235}
2236
2237std::vector<std::string> GetActivePriorityIdentifiers() {
2238 std::vector<std::string> result;
2239
2240 MyApp& app = wxGetApp();
2241
2242 std::string id =
2243 app.m_comm_bridge.GetPriorityContainer("position").active_source;
2244 result.push_back(id);
2245 id = app.m_comm_bridge.GetPriorityContainer("velocity").active_source;
2246 result.push_back(id);
2247 id = app.m_comm_bridge.GetPriorityContainer("heading").active_source;
2248 result.push_back(id);
2249 id = app.m_comm_bridge.GetPriorityContainer("variation").active_source;
2250 result.push_back(id);
2251 id = app.m_comm_bridge.GetPriorityContainer("satellites").active_source;
2252 result.push_back(id);
2253
2254 return result;
2255}
2256
2257double OCPN_GetDisplayContentScaleFactor() {
2258 double rv = 1.0;
2259#if defined(__WXOSX__) || defined(__WXGTK3__)
2260 // Support scaled HDPI displays.
2261 if (gFrame) rv = gFrame->GetContentScaleFactor();
2262#endif
2263 return rv;
2264}
2265double OCPN_GetWinDIPScaleFactor() {
2266 double scaler = 1.0;
2267#ifdef __WXMSW__
2268 if (gFrame) scaler = (double)(gFrame->ToDIP(100)) / 100.;
2269#endif
2270 return scaler;
2271}
2272
2273//---------------------------------------------------------------------------
2274// API 1.18
2275//---------------------------------------------------------------------------
2276
2277//---------------------------------------------------------------------------
2278// API 1.19
2279//---------------------------------------------------------------------------
2280void ExitOCPN() {}
2281
2282bool GetFullScreen() { return gFrame->IsFullScreen(); }
2283
2284void SetFullScreen(bool set_full_screen_on) {
2285 bool state = gFrame->IsFullScreen();
2286 if (set_full_screen_on && !state)
2287 gFrame->ToggleFullScreen();
2288 else if (!set_full_screen_on && state)
2289 gFrame->ToggleFullScreen();
2290}
2291
2292extern bool g_useMUI;
2293void EnableMUIBar(bool enable, int CanvasIndex) {
2294 bool current_mui_state = g_useMUI;
2295
2296 g_useMUI = enable;
2297 if (enable && !current_mui_state) { // OFF going ON
2298 // ..For each canvas...
2299 for (unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2300 ChartCanvas* cc = g_canvasArray.Item(i);
2301 if (cc) cc->CreateMUIBar();
2302 }
2303 } else if (!enable && current_mui_state) { // ON going OFF
2304 // ..For each canvas...
2305 for (unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2306 ChartCanvas* cc = g_canvasArray.Item(i);
2307 if (cc) cc->DestroyMuiBar();
2308 }
2309 }
2310}
2311
2312bool GetEnableMUIBar(int CanvasIndex) { return g_useMUI; }
2313
2314void EnableCompassGPSIcon(bool enable, int CanvasIndex) {
2315 if (CanvasIndex < GetCanvasCount()) {
2316 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2317 if (cc) cc->SetShowGPSCompassWindow(enable);
2318 }
2319}
2320
2321bool GetEnableCompassGPSIcon(int CanvasIndex) {
2322 if (CanvasIndex < GetCanvasCount()) {
2323 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2324 if (cc)
2325 return cc->GetShowGPSCompassWindow();
2326 else
2327 return false;
2328 }
2329 return false;
2330}
2331
2332extern bool g_bShowStatusBar;
2333void EnableStatusBar(bool enable) {
2334 g_bShowStatusBar = enable;
2335 gFrame->ConfigureStatusBar();
2336}
2337
2338bool GetEnableStatusBar() { return g_bShowStatusBar; }
2339
2340void EnableChartBar(bool enable, int CanvasIndex) {
2341 bool current_chartbar_state = g_bShowChartBar;
2342 for (unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2343 ChartCanvas* cc = g_canvasArray.Item(i);
2344 if (current_chartbar_state && !enable) {
2345 gFrame->ToggleChartBar(cc);
2346 g_bShowChartBar = current_chartbar_state;
2347 } else if (!current_chartbar_state && enable) {
2348 gFrame->ToggleChartBar(cc);
2349 g_bShowChartBar = current_chartbar_state;
2350 }
2351 }
2352 g_bShowChartBar = enable;
2353}
2354
2355bool GetEnableChartBar(int CanvasIndex) { return g_bShowChartBar; }
2356
2357extern bool g_bShowMenuBar;
2358void EnableMenu(bool enable) {
2359 if (!enable) {
2360 if (g_bShowMenuBar) {
2361 g_bShowMenuBar = false;
2362 if (gFrame->m_pMenuBar) {
2363 gFrame->SetMenuBar(NULL);
2364 gFrame->m_pMenuBar->Destroy();
2365 gFrame->m_pMenuBar = NULL;
2366 }
2367 }
2368 } else {
2369 g_bShowMenuBar = true;
2370 gFrame->BuildMenuBar();
2371 }
2372}
2373
2374bool GetEnableMenu() { return g_bShowMenuBar; }
2375
2376void SetGlobalColor(std::string table, std::string name, wxColor color) {
2377 if (ps52plib) ps52plib->m_chartSymbols.UpdateTableColor(table, name, color);
2378}
2379
2380wxColor GetGlobalColorD(std::string map_name, std::string name) {
2381 wxColor ret = wxColor(*wxRED);
2382 if (ps52plib) {
2383 int i_table = ps52plib->m_chartSymbols.FindColorTable(map_name.c_str());
2384 ret = ps52plib->m_chartSymbols.GetwxColor(name.c_str(), i_table);
2385 }
2386 return ret;
2387}
2388
2389void EnableLatLonGrid(bool enable, int CanvasIndex) {
2390 if (CanvasIndex < GetCanvasCount()) {
2391 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2392 if (cc) cc->SetShowGrid(enable);
2393 }
2394}
2395
2396void EnableChartOutlines(bool enable, int CanvasIndex) {
2397 if (CanvasIndex < GetCanvasCount()) {
2398 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2399 if (cc) cc->SetShowOutlines(enable);
2400 }
2401}
2402
2403void EnableDepthUnitDisplay(bool enable, int CanvasIndex) {
2404 if (CanvasIndex < GetCanvasCount()) {
2405 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2406 if (cc) cc->SetShowDepthUnits(enable);
2407 }
2408}
2409
2410void EnableAisTargetDisplay(bool enable, int CanvasIndex) {
2411 if (CanvasIndex < GetCanvasCount()) {
2412 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2413 if (cc) cc->SetShowAIS(enable);
2414 }
2415}
2416
2417void EnableTideStationsDisplay(bool enable, int CanvasIndex) {
2418 if (CanvasIndex < GetCanvasCount()) {
2419 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2420 if (cc) cc->ShowTides(enable);
2421 }
2422}
2423
2424void EnableCurrentStationsDisplay(bool enable, int CanvasIndex) {
2425 if (CanvasIndex < GetCanvasCount()) {
2426 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2427 if (cc) cc->ShowCurrents(enable);
2428 }
2429}
2430
2431void EnableENCTextDisplay(bool enable, int CanvasIndex) {
2432 if (CanvasIndex < GetCanvasCount()) {
2433 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2434 if (cc) cc->SetShowENCText(enable);
2435 }
2436}
2437
2438void EnableENCDepthSoundingsDisplay(bool enable, int CanvasIndex) {
2439 if (CanvasIndex < GetCanvasCount()) {
2440 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2441 if (cc) cc->SetShowENCDepth(enable);
2442 }
2443}
2444
2445void EnableBuoyLightLabelsDisplay(bool enable, int CanvasIndex) {
2446 if (CanvasIndex < GetCanvasCount()) {
2447 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2448 if (cc) cc->SetShowENCBuoyLabels(enable);
2449 }
2450}
2451
2452void EnableLightsDisplay(bool enable, int CanvasIndex) {
2453 if (CanvasIndex < GetCanvasCount()) {
2454 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2455 if (cc) cc->SetShowENCLights(enable);
2456 }
2457}
2458
2459void EnableLightDescriptionsDisplay(bool enable, int CanvasIndex) {
2460 if (CanvasIndex < GetCanvasCount()) {
2461 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2462 if (cc) cc->SetShowENCLightDesc(enable);
2463 }
2464}
2465
2466void SetENCDisplayCategory(PI_DisCat cat, int CanvasIndex) {
2467 int valSet = STANDARD;
2468 switch (cat) {
2469 case PI_DISPLAYBASE:
2470 valSet = DISPLAYBASE;
2471 break;
2472 case PI_STANDARD:
2473 valSet = STANDARD;
2474 break;
2475 case PI_OTHER:
2476 valSet = OTHER;
2477 break;
2478 case PI_MARINERS_STANDARD:
2479 valSet = MARINERS_STANDARD;
2480 break;
2481 default:
2482 valSet = STANDARD;
2483 break;
2484 }
2485 if (CanvasIndex < GetCanvasCount()) {
2486 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2487 if (cc) cc->SetENCDisplayCategory(valSet);
2488 }
2489}
2490PI_DisCat GetENCDisplayCategory(int CanvasIndex) {
2491 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2492 if (cc)
2493 return ((PI_DisCat)cc->GetENCDisplayCategory());
2494 else
2495 return PI_DisCat::PI_STANDARD;
2496}
2497
2498void SetNavigationMode(PI_NavMode mode, int CanvasIndex) {
2499 int newMode = NORTH_UP_MODE;
2500 if (mode == PI_COURSE_UP_MODE)
2501 newMode = COURSE_UP_MODE;
2502 else if (mode == PI_HEAD_UP_MODE)
2503 newMode = HEAD_UP_MODE;
2504
2505 if (CanvasIndex < GetCanvasCount()) {
2506 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2507 if (cc) cc->SetUpMode(newMode);
2508 }
2509}
2510PI_NavMode GetNavigationMode(int CanvasIndex) {
2511 if (CanvasIndex < GetCanvasCount()) {
2512 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2513 if (cc) return ((PI_NavMode)cc->GetUpMode());
2514 }
2515 return PI_NavMode::PI_NORTH_UP_MODE;
2516}
2517
2518bool GetEnableLatLonGrid(int CanvasIndex) {
2519 if (CanvasIndex < GetCanvasCount()) {
2520 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2521 if (cc) return (cc->GetShowGrid());
2522 }
2523 return false;
2524}
2525
2526bool GetEnableChartOutlines(int CanvasIndex) {
2527 if (CanvasIndex < GetCanvasCount()) {
2528 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2529 if (cc) return (cc->GetShowOutlines());
2530 }
2531 return false;
2532}
2533
2534bool GetEnableDepthUnitDisplay(int CanvasIndex) {
2535 if (CanvasIndex < GetCanvasCount()) {
2536 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2537 if (cc) return (cc->GetShowDepthUnits());
2538 }
2539 return false;
2540}
2541
2542bool GetEnableAisTargetDisplay(int CanvasIndex) {
2543 if (CanvasIndex < GetCanvasCount()) {
2544 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2545 if (cc) return (cc->GetShowAIS());
2546 }
2547 return false;
2548}
2549
2550bool GetEnableTideStationsDisplay(int CanvasIndex) {
2551 if (CanvasIndex < GetCanvasCount()) {
2552 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2553 if (cc) return (cc->GetbShowTide());
2554 }
2555 return false;
2556}
2557
2558bool GetEnableCurrentStationsDisplay(int CanvasIndex) {
2559 if (CanvasIndex < GetCanvasCount()) {
2560 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2561 if (cc) return (cc->GetbShowCurrent());
2562 }
2563 return false;
2564}
2565
2566bool GetEnableENCTextDisplay(int CanvasIndex) {
2567 if (CanvasIndex < GetCanvasCount()) {
2568 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2569 if (cc) return (cc->GetShowENCText());
2570 }
2571 return false;
2572}
2573
2574bool GetEnableENCDepthSoundingsDisplay(int CanvasIndex) {
2575 if (CanvasIndex < GetCanvasCount()) {
2576 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2577 if (cc) return (cc->GetShowENCDepth());
2578 }
2579 return false;
2580}
2581
2582bool GetEnableBuoyLightLabelsDisplay(int CanvasIndex) {
2583 if (CanvasIndex < GetCanvasCount()) {
2584 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2585 if (cc) return (cc->GetShowENCBuoyLabels());
2586 }
2587 return false;
2588}
2589
2590bool GetEnableLightsDisplay(int CanvasIndex) {
2591 if (CanvasIndex < GetCanvasCount()) {
2592 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2593 if (cc) return (cc->GetShowENCLights());
2594 }
2595 return false;
2596}
2597
2598bool GetShowENCLightDesc(int CanvasIndex) {
2599 if (CanvasIndex < GetCanvasCount()) {
2600 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2601 if (cc) return (cc->GetbShowCurrent());
2602 }
2603 return false;
2604}
2605
2606void EnableTouchMode(bool enable) { g_btouch = enable; }
2607
2608bool GetTouchMode() { return g_btouch; }
2609
2610void EnableLookaheadMode(bool enable, int CanvasIndex) {
2611 if (CanvasIndex < GetCanvasCount()) {
2612 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2613 if (cc) cc->ToggleLookahead();
2614 }
2615}
2616
2617bool GetEnableLookaheadMode(int CanvasIndex) {
2618 if (CanvasIndex < GetCanvasCount()) {
2619 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2620 if (cc) return (cc->GetLookahead());
2621 }
2622 return false;
2623}
2624
2625extern bool g_bTrackActive;
2626void SetTrackingMode(bool enable) {
2627 if (!g_bTrackActive && enable)
2628 gFrame->TrackOn();
2629 else if (g_bTrackActive && !enable)
2630 gFrame->TrackOff();
2631}
2632bool GetTrackingMode() { return g_bTrackActive; }
2633
2634void SetAppColorScheme(PI_ColorScheme cs) {
2635 gFrame->SetAndApplyColorScheme((ColorScheme)cs);
2636}
2637PI_ColorScheme GetAppColorScheme() {
2638 return (PI_ColorScheme)global_color_scheme;
2639}
2640
2641void RequestWindowRefresh(wxWindow* win, bool eraseBackground) {
2642 if (win) win->Refresh(eraseBackground);
2643}
2644
2645void EnableSplitScreenLayout(bool enable) {
2646 if (g_canvasConfig == 1) {
2647 if (enable)
2648 return;
2649 else { // split to single
2650 g_canvasConfig = 0; // 0 => "single canvas"
2651 gFrame->CreateCanvasLayout();
2652 gFrame->DoChartUpdate();
2653 }
2654 } else {
2655 if (enable) { // single to split
2656 g_canvasConfig = 1; // 1 => "two canvas"
2657 gFrame->CreateCanvasLayout();
2658 gFrame->DoChartUpdate();
2659 } else {
2660 return;
2661 }
2662 }
2663}
2664
2665// ChartCanvas control utilities
2666
2667void PluginZoomCanvas(int CanvasIndex, double factor) {
2668 if (CanvasIndex < GetCanvasCount()) {
2669 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2670 if (cc) cc->ZoomCanvasSimple(factor);
2671 }
2672}
2673
2674bool GetEnableMainToolbar() { return (!g_disable_main_toolbar); }
2675void SetEnableMainToolbar(bool enable) {
2676 g_disable_main_toolbar = !enable;
2677 if (g_MainToolbar) g_MainToolbar->RefreshToolbar();
2678}
2679
2680void ShowGlobalSettingsDialog() {
2681 if (gFrame) gFrame->ScheduleSettingsDialog();
2682}
2683
2684void PluginCenterOwnship(int CanvasIndex) {
2685 if (CanvasIndex < GetCanvasCount()) {
2686 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2687 if (cc) {
2688 bool bfollow = cc->GetbFollow();
2689 cc->ResetOwnshipOffset();
2690 if (bfollow)
2691 cc->SetbFollow();
2692 else
2693 cc->JumpToPosition(gLat, gLon, cc->GetVPScale());
2694 }
2695 }
2696}
2697
2698void PluginSetFollowMode(int CanvasIndex, bool enable_follow) {
2699 if (CanvasIndex < GetCanvasCount()) {
2700 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2701 if (cc) {
2702 if (cc->GetbFollow() != enable_follow) cc->TogglebFollow();
2703 }
2704 }
2705}
2706
2707bool PluginGetFollowMode(int CanvasIndex) {
2708 if (CanvasIndex < GetCanvasCount()) {
2709 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2710 if (cc) return cc->GetbFollow();
2711 }
2712 return false;
2713}
2714
2715void EnableCanvasFocusBar(bool enable, int CanvasIndex) {
2716 if (CanvasIndex < GetCanvasCount()) {
2717 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2718 if (cc) cc->SetShowFocusBar(enable);
2719 }
2720}
2721bool GetEnableCanvasFocusBar(int CanvasIndex) {
2722 if (CanvasIndex < GetCanvasCount()) {
2723 ChartCanvas* cc = g_canvasArray.Item(CanvasIndex);
2724 if (cc) return (cc->GetShowFocusBar());
2725 }
2726 return false;
2727}
2728
2729bool GetEnableTenHertzUpdate() { return g_btenhertz; }
2730
2731void EnableTenHertzUpdate(bool enable) { g_btenhertz = enable; }
2732
2733void ConfigFlushAndReload() {
2734 if (pConfig) {
2735 pConfig->Flush();
2736 pConfig->LoadMyConfigRaw(false);
2737 pConfig->LoadCanvasConfigs(false);
2738 }
2739}
Chart display canvas.
Definition chcanv.h:135
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
Definition chcanv.h:428
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
Definition chcanv.cpp:4599
Manages the chart database and provides access to chart data.
Definition chartdb.h:95
bool LoadBinary(const wxString &filename, ArrayOfCDI &dir_array_check)
Load the chart database from a binary file.
Definition chartdb.cpp:233
Wrapper class for plugin-based charts.
Definition chartimg.h:392
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
Definition FontMgr.cpp:450
wxColour GetFontColor(const wxString &TextElement) const
Gets the text color for a UI element.
Definition FontMgr.cpp:117
bool AddAuxKey(wxString key)
Adds new plugin-defined font configuration key.
Definition FontMgr.cpp:668
bool SetFontColor(const wxString &TextElement, const wxColour color) const
Sets the text color for a UI element.
Definition FontMgr.cpp:122
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Definition FontMgr.cpp:186
Main application frame.
Definition ocpn_frame.h:136
Provides platform-specific support utilities for OpenCPN.
double GetDisplaySizeMM()
Get the width of the screen in millimeters.
Basic data for a loaded plugin, trivially copyable.
Definition route.h:75
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)
Definition routeman.cpp:747
Represents a single point in a track.
Definition track.h:52
Represents a track, which is a series of connected track points.
Definition track.h:78
Represents the view port for chart display in OpenCPN.
Definition viewport.h:84
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
Definition viewport.h:199
double ref_scale
The nominal scale of the "reference chart" for this view.
Definition viewport.h:216
int pix_height
Height of the viewport in physical pixels.
Definition viewport.h:221
double rotation
Rotation angle of the viewport in radians.
Definition viewport.h:209
int pix_width
Width of the viewport in physical pixels.
Definition viewport.h:219
wxPoint2DDouble GetDoublePixFromLL(double lat, double lon)
Convert latitude and longitude on the ViewPort to physical pixel coordinates with double precision.
Definition viewport.cpp:145
double skew
Angular distortion (shear transform) applied to the viewport in radians.
Definition viewport.h:207
void GetLLFromPix(const wxPoint &p, double *lat, double *lon)
Convert physical pixel coordinates on the ViewPort to latitude and longitude.
Definition viewport.h:104
double clon
Center longitude of the viewport in degrees.
Definition viewport.h:194
double clat
Center latitude of the viewport in degrees.
Definition viewport.h:192
wxPoint GetPixFromLL(double lat, double lon)
Convert latitude and longitude on the ViewPort to physical pixel coordinates.
Definition viewport.cpp:136
double chart_scale
Chart scale denominator (e.g., 50000 for a 1:50000 scale).
Definition viewport.h:214
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:64
Floating toolbar dialog for OpenCPN.
Definition toolbar.h:386
Raw messages layer, supports sending and recieving navmsg messages.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:54
wxFont GetOCPNGUIScaledFont(wxString item)
Retrieves a font optimized for touch and high-resolution interfaces.
Definition gui_lib.cpp:83
General purpose GUI support.
PlugIn Object Definition/API.
wxFont * OCPNGetFont(wxString TextElement, int default_size)
Gets a font for UI elements.
wxFont GetOCPNGUIScaledFont_PlugIn(wxString item)
Gets a uniquely scaled font copy for responsive UI elements.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
int GetGlobalWatchdogTimoutSeconds()
Comm Global Watchdog Query
wxColour GetFontColour_PlugIn(wxString TextElement)
Gets color configured for a UI text element.
bool PlugInPlaySoundEx(wxString &sound_file, int deviceIndex)
Start playing a sound file asynchronously.
bool PlugInSetFontColor(const wxString TextElement, const wxColour color)
Sets text color for a UI element.
std::vector< std::string > GetPriorityMaps()
Comm Priority query support methods
bool AddPersistentFontKey(wxString TextElement)
Registers a new font configuration element.
wxString g_locale
Global locale setting for OpenCPN UI.
Definition ocpn_app.cpp:596
void PlugInPlaySound(wxString &sound_file)
Start playing a sound file asynchronously.
double g_display_size_mm
The width of the physical screen in millimeters.
Definition ocpn_app.cpp:399
Tools to send data to plugins.