54#include <wx/stdpaths.h>
55#include <wx/tokenzr.h>
56#include <wx/display.h>
57#include <wx/jsonreader.h>
59#include "model/ais_decoder.h"
61#include "model/ais_target_data.h"
63#include "model/comm_drv_factory.h"
65#include "model/comm_n0183_output.h"
67#include "model/comm_vars.h"
68#include "model/config_vars.h"
69#include "model/cutil.h"
70#include "model/georef.h"
72#include "model/idents.h"
75#include "model/multiplexer.h"
76#include "model/nav_object_database.h"
77#include "model/navutil_base.h"
78#include "model/own_ship.h"
80#include "model/plugin_loader.h"
81#include "model/routeman.h"
82#include "model/select.h"
84#include "model/track.h"
86#include "dialog_alert.h"
87#include "AboutFrameImpl.h"
90#include "ais_info_gui.h"
91#include "AISTargetAlertDialog.h"
92#include "AISTargetListDialog.h"
93#include "AISTargetQueryDialog.h"
94#include "CanvasConfig.h"
96#include "chart_ctx_factory.h"
100#include "color_handler.h"
103#include "connections_dlg.h"
104#include "ConfigMgr.h"
108#include "glChartCanvas.h"
109#include "GoToPositionDialog.h"
111#include "iENCToolbar.h"
113#include "load_errors_dlg.h"
116#include "N2KParser.h"
118#include "NMEALogWindow.h"
121#include "OCPN_AUIManager.h"
122#include "ocpn_frame.h"
123#include "OCPNPlatform.h"
124#include "OCPN_Sound.h"
126#include "pluginmanager.h"
127#include "print_dialog.h"
128#include "printout_chart.h"
129#include "routemanagerdialog.h"
130#include "routeman_gui.h"
131#include "route_point_gui.h"
132#include "RoutePropDlgImpl.h"
135#include "S57QueryDialog.h"
136#include "SystemCmdSound.h"
140#include "TrackPropDlg.h"
141#include "waypointman_gui.h"
142#include "CanvasOptions.h"
146#include "androidUTIL.h"
152WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
160extern arrayofCanvasPtr g_canvasArray;
173extern about *g_pAboutDlgLegacy;
176extern double vLat, vLon;
177extern wxString g_locale;
178extern ColorScheme global_color_scheme;
183GLenum g_texture_rectangle_format;
186#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
187extern wxLocale *plocale_def_lang;
194extern s52plib *ps52plib;
198extern bool g_b_legacy_input_filter_behaviour;
199extern bool g_bTrackActive;
201extern bool g_bmasterToolbarFull;
202extern int g_nAutoHideToolbar;
203extern bool g_bAutoHideToolbar;
204extern bool g_bshowToolbar;
205extern int g_maintoolbar_x;
206extern int g_maintoolbar_y;
207extern wxString g_toolbarConfig;
208extern float g_toolbar_scalefactor;
209extern float g_compass_scalefactor;
210extern bool g_bShowMenuBar;
211extern bool g_bShowCompassWin;
213extern bool g_benable_rotate;
214extern int g_GUIScaleFactor;
215extern int g_ChartScaleFactor;
216extern int g_last_ChartScaleFactor;
217extern int g_ShipScaleFactor;
218extern float g_ShipScaleFactorExp;
219extern int g_ENCTextScaleFactor;
221extern bool g_bShowTide;
222extern bool g_bShowCurrent;
223extern bool g_bUIexpert;
224extern RouteList *pRouteList;
225extern wxString g_default_wp_icon;
226extern std::vector<std::string> TideCurrentDataSet;
227extern wxString g_TCData_Dir;
229extern char nmea_tick_chars[];
230extern double AnchorPointMinDist;
231extern bool AnchorAlertOn1, AnchorAlertOn2;
232extern wxString g_AW1GUID;
233extern wxString g_AW2GUID;
234extern bool g_bCruising;
235extern double g_COGAvg;
236extern int g_COGAvgSec;
238extern std::vector<Track *> g_TrackList;
239extern double gQueryVar;
240extern int g_ChartUpdatePeriod;
241extern int g_SkewCompUpdatePeriod;
242extern bool g_bCourseUp;
243extern bool g_bLookAhead;
244extern bool g_bskew_comp;
245extern bool g_bPauseTest;
247extern bool g_bPlayShipsBells;
248extern wxDateTime g_loglast_time;
249extern int g_nAWDefault;
251extern bool g_bDeferredStartTrack;
252extern bool bDBUpdateInProgress;
256extern bool g_bDeferredInitDone;
257extern int options_lastPage;
258extern int options_subpage;
259extern bool b_reloadForPlugins;
261extern int g_NeedDBUpdate;
262extern bool g_bFullscreen;
263extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
264extern ChartGroupArray *g_pGroupArray;
265extern bool g_bEnableZoomToCursor;
266extern double g_display_size_mm;
267extern std::vector<size_t> g_config_display_size_mm;
268extern wxString ChartListFileName;
269extern bool g_bFullscreenToolbar;
270extern arrayofCanvasPtr g_canvasArray;
271extern wxString g_lastAppliedTemplateGUID;
272extern wxPoint options_lastWindowPos;
273extern wxSize options_lastWindowSize;
274extern unsigned int g_canvasConfig;
275extern bool g_bFullScreenQuilt;
276extern bool g_bQuiltEnable;
277extern wxString *pInit_Chart_Dir;
278extern bool g_bShowOutlines;
279extern bool g_bTempShowMenuBar;
280extern bool g_bShowStatusBar;
281extern bool g_FlushNavobjChanges;
282extern int g_FlushNavobjChangesTimeout;
283extern bool g_bShowChartBar;
284extern double g_plus_minus_zoom_factor;
285extern int g_nframewin_x;
286extern int g_nframewin_y;
287extern int g_nframewin_posx;
288extern int g_nframewin_posy;
289extern bool g_bframemax;
290extern LayerList *pLayerList;
291extern bool g_bAutoAnchorMark;
292extern wxDateTime g_start_time;
293extern bool g_bcompression_wait;
294extern bool g_bquiting;
295extern bool b_inCloseWindow;
296extern bool b_inCompressAllCharts;
297extern long g_maintoolbar_orient;
298extern wxAuiDefaultDockArt *g_pauidockart;
299extern int g_click_stop;
300extern wxString g_CmdSoundString;
301extern std::vector<OcpnSound *> bells_sound;
302extern char bells_sound_file_name[2][12];
303extern int g_sticky_chart;
304extern int g_sticky_projection;
305extern wxArrayPtrVoid *UserColourHashTableArray;
306extern wxColorHashMap *pcurrent_user_color_hash;
309extern bool g_own_ship_sog_cog_calc;
310extern int g_own_ship_sog_cog_calc_damp_sec;
311extern bool g_bHasHwClock;
312extern bool s_bSetSystemTime;
313extern bool bVelocityValid;
314extern int gHDx_Watchdog;
317extern bool g_bUseGLL;
318extern int g_MemFootMB;
321extern int g_chart_zoom_modifier_vector;
322extern bool g_config_display_size_manual;
323extern bool g_PrintingInProgress;
324extern bool g_disable_main_toolbar;
325extern bool g_btenhertz;
330typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
331typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
333SetSysColors_t pSetSysColors;
334GetSysColor_t pGetSysColor;
336void SaveSystemColors(
void);
337void RestoreSystemColors(
void);
342DWORD color_3ddkshadow;
344DWORD color_activecaption;
345DWORD color_gradientactivecaption;
346DWORD color_captiontext;
347DWORD color_windowframe;
348DWORD color_inactiveborder;
353#include <wx/msw/msvcrt.h>
357static const long long lNaN = 0xfff8000000000000;
358#define NAN (*(double *)&lNaN)
361static wxArrayPtrVoid *UserColorTableArray = 0;
364double gLat_gt, gLon_gt;
365double gLat_gt_m1, gLon_gt_m1;
367uint64_t fix_time_gt_last;
369double gSog_gt, gCog_gt, gHdt_gt;
370double gCog_gt_m1, gHdt_gt_m1;
372double cog_rate_gt, hdt_rate_gt;
375void appendOSDirSlash(wxString *pString);
377void InitializeUserColors(
void);
378void DeInitializeUserColors(
void);
379void SetSystemColors(ColorScheme cs);
381static bool LoadAllPlugIns(
bool load_enabled) {
382 AbstractPlatform::ShowBusySpinner();
383 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled);
384 AbstractPlatform::HideBusySpinner();
392#if defined(__WXGTK__) || defined(__WXQT__)
393#include "bitmaps/opencpn.xpm"
408int g_iENCToolbarPosX;
409int g_iENCToolbarPosY;
411void BuildiENCToolbar(
bool bnew) {
412 if (g_bInlandEcdis) {
415 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
416 wxPoint tbp_incanvas =
419 g_iENCToolbarPosY = tbp_incanvas.y;
420 g_iENCToolbarPosX = tbp_incanvas.x;
422 delete g_iENCToolbar;
427 if (!g_iENCToolbar) {
428 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
432 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
434 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
435 g_iENCToolbarPosY = -1;
438 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
444 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
448 double tool_scale_factor =
449 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
452 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
453 g_iENCToolbar->SetColorScheme(global_color_scheme);
454 g_iENCToolbar->EnableSubmerge(
false);
457 delete g_iENCToolbar;
458 g_iENCToolbar = NULL;
462bool ShowNavWarning() {
465OpenCPN is distributed in the hope that it will be useful, \
466but WITHOUT ANY WARRANTY; without even the implied \
467warranty of MERCHANTABILITY or FITNESS FOR A \
468PARTICULAR PURPOSE.\n\n\
469See the GNU General Public License for more details.\n\n\
470OpenCPN must only be used in conjunction with approved \
471paper charts and traditional methods of navigation.\n\n\
472DO NOT rely upon OpenCPN for safety of life or property.\n\n\
473Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
475 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
478 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
481 msg.Replace(
"\n",
"<br>");
483 std::stringstream html;
484 html <<
"<html><body><p>";
485 html << msg.ToStdString();
486 html <<
"</p></body></html>";
488 std::string title = _(
"Welcome to OpenCPN").ToStdString();
489 std::string action = _(
"Agree").ToStdString();
491 info_dlg.SetInitialSize();
492 info_dlg.AddHtmlContent(html);
493 int agreed = info_dlg.ShowModal();
494 return agreed == wxID_OK;
499 if (chart ==
nullptr)
return false;
502 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
504 if (cc && cc->m_singleChart == chart) {
511#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
514static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
515 const char *prop_name) {
519 unsigned long ret_nitems;
520 unsigned long ret_bytes_after;
521 unsigned char *ret_prop;
523 xa_prop_name = XInternAtom(disp, prop_name, False);
531 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
532 &xa_ret_type, &ret_format, &ret_nitems,
533 &ret_bytes_after, &ret_prop) != Success)
536 if (xa_ret_type != xa_prop_type) {
540 return (
char *)ret_prop;
545static bool isTransparentToolbarInOpenGLOK(
void) {
552 if (!g_bdisable_opengl) {
553 Display *disp = XOpenDisplay(NULL);
555 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
557 "_NET_SUPPORTING_WM_CHECK")) ||
558 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
560 "_WIN_SUPPORTING_WM_CHECK"))) {
563 if ((wm_name = get_X11_property(disp, *sup_window,
564 XInternAtom(disp,
"UTF8_STRING", False),
566 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
569 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
590wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
592BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
593EVT_CLOSE(MyFrame::OnCloseWindow)
594EVT_MENU(wxID_EXIT, MyFrame::OnExit)
595EVT_SIZE(MyFrame::OnSize)
596EVT_MOVE(MyFrame::OnMove)
597EVT_ICONIZE(MyFrame::OnIconize)
598EVT_MENU(-1, MyFrame::OnToolLeftClick)
599EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
600EVT_TIMER(FRAME_TIMER_1, MyFrame::OnFrameTimer1)
601EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
602EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
603EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
604EVT_TIMER(FRANE_TENHZ_TIMER, MyFrame::OnFrameTenHzTimer)
605EVT_MAXIMIZE(MyFrame::OnMaximize)
606EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
607 MyFrame::RequestNewToolbarArgEvent)
608EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
610EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
611EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
612EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
614#ifdef wxHAS_POWER_EVENTS
615EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
616EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
617EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
618EVT_POWER_RESUME(MyFrame::OnResume)
629static
void onBellsFinishedCB(
void *ptr) {
630 auto framePtr =
static_cast<MyFrame *
>(ptr);
632 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
633 wxPostEvent(framePtr, ev);
638 auto msg = ev.GetString().ToStdString();
639 OCPNMessageBox(
GetTopWindow(), msg, _(
"Communication Error"));
643MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
644 const wxSize &size,
long style)
645 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
646 comm_overflow_dlg(this),
647 m_connections_dlg(nullptr) {
648 g_current_monitor = wxDisplay::GetFromWindow(
this);
654 g_current_monitor_dip_px_ratio =
655 g_monitor_info[g_current_monitor].width_px /
656 g_monitor_info[g_current_monitor].width;
659 m_last_track_rotation_ts = 0;
660 m_ulLastNMEATicktime = 0;
663 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
667 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
670 InitTimer.SetOwner(
this, INIT_TIMER);
672 m_initializing =
false;
675 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
678 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
681 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
684 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
687 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
689 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
698 m_bTimeIsSet =
false;
701 m_bdefer_resize =
false;
704 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
705 COGFilterTable[i] = NAN;
706 SOGFilterTable[i] = NAN;
708 m_last_bGPSValid =
false;
709 m_last_bVelocityValid =
false;
719 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
724 double process_noise_std = 1.0;
725 double measurement_noise_std = 0.5;
727 m_ChartUpdatePeriod = 1;
732 log_callbacks.log_is_active = []() {
733 return NMEALogWindow::GetInstance().
Active();
735 log_callbacks.log_message = [](
const wxString &s) {
736 NMEALogWindow::GetInstance().
Add(s);
738 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
741 ais_callbacks.confirm_stop_track = []() {
742 int r = OCPNMessageBox(
744 _(
"This AIS target has Persistent tracking selected by MMSI "
746 "A Persistent track recording will therefore be restarted for this "
748 "Do you instead want to stop Persistent tracking for this target?"),
749 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
750 return r == wxID_YES;
752 ais_callbacks.get_target_mmsi = []() {
753 auto alert_dlg_active =
755 assert(alert_dlg_active);
756 return alert_dlg_active->Get_Dialog_MMSI();
764 wxLogMessage(
" **** Connect stuff");
770 Connect(wxEVT_OCPN_MSG,
771 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
778 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
779 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
787#if defined(__WXGTK__) || defined(__WXQT__)
788 wxIcon app_icon(opencpn);
796 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
798 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
799 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
804 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
807 g_sticky_projection = -1;
810 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
811 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
813 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
815 [&](wxCommandEvent) { Refresh(); });
816 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
821 EnableFullScreenView();
827 FrameTenHzTimer.Stop();
834 wxRouteListNode *node = pRouteList->GetFirst();
837 Route *pRouteDelete = node->GetData();
840 node = node->GetNext();
847 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
855 switch (event.type) {
856 case SENC_BUILD_STARTED:
859 case SENC_BUILD_DONE_NOERROR:
861 chart =
event.m_ticket->m_chart;
863 chart->PostInit(FULL_INIT, global_color_scheme);
865 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
867 if (cc) cc->ClearS52PLIBStateHash();
872 delete event.m_ticket;
874 case SENC_BUILD_DONE_ERROR:
882void MyFrame::RebuildChartDatabase() {
883 bool b_SetInitialPoint =
false;
886 ArrayOfCDI ChartDirArray;
887 pConfig->LoadChartDirArray(ChartDirArray);
889 if (ChartDirArray.GetCount()) {
892 if (g_NeedDBUpdate == 1) {
894 _(
"OpenCPN needs to update the chart database from config file "
898 wxICON_INFORMATION | wxOK);
906 _(
"Rebuilding chart database from configuration file entries..."));
910 wxString dummy1 = _(
"Elapsed time : ");
911 wxString dummy2 = _(
"Estimated time : ");
912 wxString dummy3 = _(
"Remaining time : ");
913 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
914 _(
"OpenCPN Chart Update"), line, 100, NULL,
915 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
916 wxPD_REMAINING_TIME);
918 ChartData->
Create(ChartDirArray, pprog);
919 ChartData->SaveBinary(ChartListFileName);
924 ChartData->ApplyGroupArray(g_pGroupArray);
929void MyFrame::OnBellsFinished(wxCommandEvent &event) {
930 int bells = wxMin(m_BellsToPlay, 2);
931 if (bells <= 0)
return;
933 wxString soundfile = _T(
"sounds");
934 appendOSDirSlash(&soundfile);
935 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
936 soundfile.Prepend(g_Platform->GetSharedDataDir());
937 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
939 OcpnSound *sound = bells_sound[bells - 1];
940 sound->SetFinishedCallback(onBellsFinishedCB,
this);
941 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
942 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
943 sound->Load(soundfile);
944 if (!sound->IsOk()) {
945 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
949 m_BellsToPlay -= bells;
952void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
954void MyFrame::OnMaximize(wxMaximizeEvent &event) {
961ColorScheme GetColorScheme() {
return global_color_scheme; }
963ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
965void MyFrame::ReloadAllVP() {
966 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
968 if (cc) cc->ReloadVP();
972void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
973 global_color_scheme = cs;
977 case GLOBAL_COLOR_SCHEME_DAY:
978 SchemeName = _T(
"DAY");
980 case GLOBAL_COLOR_SCHEME_DUSK:
981 SchemeName = _T(
"DUSK");
983 case GLOBAL_COLOR_SCHEME_NIGHT:
984 SchemeName = _T(
"NIGHT");
987 SchemeName = _T(
"DAY");
991 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
993 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
994 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
995 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
996 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
997 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
999 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1028 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1029 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1031 g_pauimgr->Update();
1033 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1036 unsigned Usercolortable_index = 0;
1037 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1038 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1039 if (SchemeName.IsSameAs(*ct->tableName)) {
1040 Usercolortable_index = i;
1045 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1048 pcurrent_user_color_hash =
1049 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1051 SetSystemColors(cs);
1054 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1057 cc->SetColorScheme(cs);
1058 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1059 cc->HideChartInfoWindow();
1060 cc->SetQuiltChartHiLiteIndex(-1);
1066 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1067 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1070 g_options->SetColorScheme(cs);
1074 console->SetColorScheme(cs);
1078 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1081 if (g_pMarkInfoDialog) {
1082 g_pMarkInfoDialog->SetColorScheme(cs);
1085 if (pRoutePropDialog) {
1086 pRoutePropDialog->SetColorScheme(cs);
1091 if (g_pais_query_dialog_active) {
1092 bool b_isshown = g_pais_query_dialog_active->IsShown();
1093 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1094 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1096 g_pais_query_dialog_active->Close();
1099 g_pais_query_dialog_active->
Create(
1100 this, -1, _(
"AIS Target Query"),
1101 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1102 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1103 g_pais_query_dialog_active->UpdateText();
1104 if (b_isshown) g_pais_query_dialog_active->Show();
1107 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1109 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1111 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1113 ApplyGlobalColorSchemetoStatusBar();
1115 UpdateAllToolbars(cs);
1117 if (g_MainToolbar) {
1118 if (g_MainToolbar->GetColorScheme() != cs) {
1120 bool btoolbarFull = g_bmasterToolbarFull;
1122 g_MainToolbar->SetColorScheme(cs);
1126 if (!btoolbarFull) {
1128 RequestNewMasterToolbar();
1129 g_MainToolbar->SetColorScheme(cs);
1130 CollapseGlobalToolbar();
1133 RequestNewMasterToolbar();
1134 g_MainToolbar->SetColorScheme(cs);
1139 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1142void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1143 if (m_pStatusBar != NULL) {
1144 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1145 m_pStatusBar->ClearBackground();
1150 if (g_canvasArray.GetCount() > 0)
1151 return g_canvasArray.Item(0);
1155void MyFrame::CancelAllMouseRoute() {
1157 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1159 if (cc) cc->CancelMouseRoute();
1163void MyFrame::NotifyChildrenResize() {}
1165void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1167 if (ChartData) ChartData->PurgeCache();
1170 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1173 g_pauimgr->DetachPane(cc);
1178 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1187 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1190 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1191 config_array.Item(i)->canvas = NULL;
1197 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1198 g_canvasArray.RemoveAt(i);
1202 switch (g_canvasConfig) {
1205 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1207 g_canvasArray.Add(cc);
1209 cc = g_canvasArray[0];
1215 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1216 cc->GetglCanvas()->Show();
1219 config_array.Item(0)->canvas = cc;
1223 cc->ApplyCanvasConfig(config_array.Item(0));
1227 cc->ConfigureChartBar();
1228 cc->SetColorScheme(global_color_scheme);
1229 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1230 cc->SetShowGPS(
true);
1232 g_pauimgr->AddPane(cc);
1233 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1234 g_pauimgr->GetPane(cc).Fixed();
1235 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1236 g_pauimgr->GetPane(cc).CenterPane();
1241 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1243 g_canvasArray.Add(cc);
1245 cc = g_canvasArray[0];
1251 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1254 config_array.Item(0)->canvas = cc;
1256 cc->ApplyCanvasConfig(config_array.Item(0));
1259 cc->ConfigureChartBar();
1260 cc->SetColorScheme(global_color_scheme);
1261 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1262 cc->SetShowGPS(
false);
1264 g_pauimgr->AddPane(cc);
1265 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1266 g_pauimgr->GetPane(cc)
1267 .CaptionVisible(
false)
1269 .CloseButton(
false);
1271 g_pauimgr->GetPane(cc).CenterPane();
1274 g_canvasArray.Add(cc);
1278 if (config_array.GetCount() < 2) {
1280 pcc->configIndex = 1;
1284 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1285 config_array.Add(pcc);
1288 config_array.Item(1)->canvas = cc;
1290 cc->ApplyCanvasConfig(config_array.Item(1));
1293 cc->ConfigureChartBar();
1294 cc->SetColorScheme(global_color_scheme);
1295 cc->SetShowGPS(
true);
1298 g_pauimgr->AddPane(cc);
1299 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1300 g_pauimgr->GetPane(cc)
1301 .CaptionVisible(
false)
1303 .CloseButton(
false);
1304 g_pauimgr->GetPane(cc).RightDockable(
true);
1305 g_pauimgr->GetPane(cc).Right();
1308 config_array.Item(1)->canvasSize =
1309 wxSize(GetClientSize().x / 2, GetClientSize().y);
1310 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1315 if (b_useStoredSize) {
1316 int ccw = config_array.Item(1)->canvasSize.x;
1317 int cch = config_array.Item(1)->canvasSize.y;
1320 if (ccw < GetClientSize().x / 10) {
1321 ccw = GetClientSize().x / 2;
1322 cch = GetClientSize().y;
1325 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1326 cc->SetSize(ccw, cch);
1337 g_focusCanvas = GetPrimaryCanvas();
1340void MyFrame::RequestNewToolbars(
bool bforcenew) {
1341 if (b_inCloseWindow) {
1345 BuildiENCToolbar(bforcenew);
1346 PositionIENCToolbar();
1355void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1356 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1361void MyFrame::SetAllToolbarScale() {
1362 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1365void MyFrame::SetGPSCompassScale() {
1366 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1370 wxPoint screenPoint = ::wxGetMousePosition();
1373 switch (g_canvasConfig) {
1375 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1378 if (canvas->GetScreenRect().Contains(
1382 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1385 if (canvas->GetScreenRect().Contains(
1392 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1395 if (canvas->GetScreenRect().Contains(
1396 canvas->ScreenToClient(screenPoint)))
1404int MyFrame::GetCanvasIndexUnderMouse() {
1405 wxPoint screenPoint = ::wxGetMousePosition();
1408 switch (g_canvasConfig) {
1410 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1413 if (canvas->GetScreenRect().Contains(
1417 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1420 if (canvas->GetScreenRect().Contains(
1427 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1430 if (canvas->GetScreenRect().Contains(
1431 canvas->ScreenToClient(screenPoint)))
1439bool MyFrame::DropMarker(
bool atOwnShip) {
1446 if (!canvas)
return false;
1453 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1455 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1456 pConfig->AddNewWayPoint(pWP, -1);
1460 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1461 pRouteManagerDialog->UpdateWptListCtrl();
1466 RefreshAllCanvas(
false);
1471void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1472 if (g_canvasConfig != 0) {
1475 int nTargetGTK = -1;
1477 wxWindow *source = FindFocus();
1483 switch (g_canvasConfig) {
1485 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1488 if (canvas && (canvas == test)) {
1493 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1496 if (canvas && (canvas == test)) {
1504 int nfinalTarget = nTarget;
1506 nfinalTarget = nTargetGTK;
1508 target = ConfigMgr::Get()
1509 .GetCanvasConfigArray()
1514 target->Refresh(
true);
1525void MyFrame::FastClose() {
1527 FrameTenHzTimer.Stop();
1529 FrameTimer1.Start(1);
1533void MyFrame::OnExit(wxCommandEvent &event) {
1537void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1540 if (b_inCloseWindow) {
1550 if (!g_bDeferredInitDone)
return;
1563 if (b_inCompressAllCharts) {
1567 if (bDBUpdateInProgress)
return;
1569 b_inCloseWindow =
true;
1571 ::wxSetCursor(wxCURSOR_WAIT);
1575 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1577 if (cc && cc->IsMeasureActive()) {
1578 cc->CancelMeasureRoute();
1583 SendPreShutdownHookToPlugins();
1587 if (g_pAISTargetList) {
1588 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1589 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1590 g_pauimgr->DetachPane(g_pAISTargetList);
1601 pConfig->SetPath(_T (
"/AUI" ));
1602 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1609 if (g_glTextureManager) {
1610 g_glTextureManager->PurgeJobList();
1612 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1617 SetCursor(wxCURSOR_WAIT);
1619 RefreshAllCanvas(
true);
1625 RestoreScreenBrightness();
1634 if (g_iENCToolbar) {
1635 wxPoint locn = g_iENCToolbar->GetPosition();
1636 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1637 g_iENCToolbarPosY = tbp_incanvas.y;
1638 g_iENCToolbarPosX = tbp_incanvas.x;
1642 g_bframemax = IsMaximized();
1645 FrameTenHzTimer.Stop();
1647 FrameCOGTimer.Stop();
1661 if (g_bAutoAnchorMark) {
1662 bool watching_anchor =
false;
1663 if (pAnchorWatchPoint1)
1664 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1666 if (pAnchorWatchPoint2)
1667 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1670 wxDateTime now = wxDateTime::Now();
1671 wxTimeSpan uptime = now.Subtract(g_start_time);
1673 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1674 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1679 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1682 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1683 double a = gLat - pr->m_lat;
1684 double b = gLon - pr->m_lon;
1685 double l = sqrt((a * a) + (b * b));
1688 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1689 pConfig->DeleteWayPoint(pr);
1690 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1696 node = node->GetNext();
1699 wxString name = now.Format();
1700 name.Prepend(_(
"Anchorage created "));
1702 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1703 pWP->m_bShowName =
false;
1706 pConfig->AddNewWayPoint(pWP, -1);
1711 pConfig->UpdateSettings();
1714 auto plugin_loader = PluginLoader::getInstance();
1715 if (plugin_loader) {
1716 plugin_loader->DeactivateAllPlugIns();
1719 wxLogMessage(_T(
"opencpn::MyFrame exiting cleanly."));
1723 pConfig->UpdateNavObj();
1725 pConfig->m_pNavObjectChangesSet->reset();
1729 pConfig->DeleteGroup(_T (
"/Routes" ));
1730 pConfig->DeleteGroup(_T (
"/Marks" ));
1733 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1734 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1739 if (g_pCM93OffsetDialog) {
1740 g_pCM93OffsetDialog->Destroy();
1741 g_pCM93OffsetDialog = NULL;
1749 if (g_iENCToolbar) {
1756 if (g_pAISTargetList) {
1757 g_pAISTargetList->Disconnect_decoder();
1758 g_pAISTargetList->Destroy();
1765 if (RouteManagerDialog::getInstanceFlag()) {
1766 if (pRouteManagerDialog) {
1767 pRouteManagerDialog->Destroy();
1768 pRouteManagerDialog = NULL;
1773 if (ChartData) ChartData->PurgeCache();
1779 g_focusCanvas = NULL;
1782 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1784 if (cc) cc->Destroy();
1787 g_canvasArray.Clear();
1789 g_pauimgr->UnInit();
1799 if (ChartData) ChartData->PurgeCachePlugins();
1801 if (PluginLoader::getInstance())
1802 PluginLoader::getInstance()->UnLoadAllPlugIns();
1805 delete g_pi_manager;
1806 g_pi_manager = NULL;
1809 MyApp &app = wxGetApp();
1810 app.m_comm_bridge.SaveConfig();
1830 auto ®istry = CommDriverRegistry::GetInstance();
1831 registry.CloseAllDrivers();
1834 for (
auto *cp : TheConnectionParams()) {
1839 LayerList::iterator it;
1840 while (pLayerList->GetCount()) {
1841 Layer *lay = pLayerList->GetFirst()->GetData();
1846 NMEALogWindow::Shutdown();
1848 ReleaseApiListeners();
1850 g_MainToolbar = NULL;
1851 g_bTempShowMenuBar =
false;
1853#define THREAD_WAIT_SECONDS 5
1859 if (g_bopengl && g_glTextureManager &&
1860 g_glTextureManager->GetRunningJobCount()) {
1861 g_glTextureManager->ClearAllRasterTextures();
1863 wxLogMessage(_T(
"Starting compressor pool drain"));
1864 wxDateTime now = wxDateTime::Now();
1865 time_t stall = now.GetTicks();
1866 time_t end = stall + THREAD_WAIT_SECONDS;
1869 while (stall < end) {
1870 wxDateTime later = wxDateTime::Now();
1871 stall = later.GetTicks();
1874 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1875 g_glTextureManager->GetRunningJobCount());
1877 if (!g_glTextureManager->GetRunningJobCount())
break;
1883 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1884 n_comploop, g_glTextureManager->GetRunningJobCount());
1887 delete g_glTextureManager;
1889 uninitIXNetSystem();
1893 wxLogMessage(_T(
"gFrame destroyed."));
1896#ifndef USE_ANDROID_GLES2
1897 qDebug() <<
"Calling OnExit()";
1901 wxTheApp->ExitMainLoop();
1904void MyFrame::OnMove(wxMoveEvent &event) {
1905 auto idx = wxDisplay::GetFromWindow(
this);
1906 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
1907 static_cast<size_t>(idx) < g_monitor_info.size()) {
1908 g_current_monitor = idx;
1914 g_current_monitor_dip_px_ratio =
1915 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
1918 DEBUG_LOG <<
"Moved to " << idx
1919#if wxCHECK_VERSION(3, 1, 6)
1920 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1921 << wxDisplay(idx).GetPPI().GetY()
1922 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1924 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1925 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1926 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1927 << wxGetDisplaySizeMM().GetY()
1928 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1929 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
1930 << g_monitor_info[idx].height_mm <<
"mm "
1931 << g_monitor_info[idx].width_mm <<
"x"
1932 << g_monitor_info[idx].height_mm <<
"mm "
1933 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
1934 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
1935 << g_monitor_info[idx].height_px <<
"px"
1936 << g_monitor_info[idx].scale <<
"%";
1937 if (g_config_display_size_manual) {
1938 if (g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
1939 g_display_size_mm = g_config_display_size_mm[idx];
1942 g_display_size_mm = g_monitor_info[idx].width_mm;
1946 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1949 cc->SetMUIBarPosition();
1958 UpdateGPSCompassStatusBoxes();
1960 if (console && console->IsShown()) PositionConsole();
1968 PositionIENCToolbar();
1974 g_nframewin_posx = GetPosition().x;
1975 g_nframewin_posy = GetPosition().y;
1978void MyFrame::ProcessCanvasResize(
void) {
1979 UpdateGPSCompassStatusBoxes(
true);
1981 if (console && console->IsShown()) PositionConsole();
1983 PositionIENCToolbar();
1986 TriggerRecaptureTimer();
1990void MyFrame::TriggerRecaptureTimer() {
1991 m_recaptureTimer.Start(
1992 1000, wxTIMER_ONE_SHOT);
1995void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
1997void MyFrame::SetCanvasSizes(wxSize frameSize) {
1998 if (!g_canvasArray.GetCount())
return;
2001 int cccw = frameSize.x;
2002 int ccch = frameSize.y;
2006 switch (g_canvasConfig) {
2010 cc = g_canvasArray.Item(0);
2012 cc->GetSize( &cur_width, &cur_height );
2013 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2014 if( g_pauimgr->GetPane( cc ).IsOk() )
2015 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2017 cc->SetSize( 0, 0, cccw, ccch );
2025 cc = g_canvasArray.Item(1);
2027 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2028 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2030 ccw = wxMin(ccw, cccw * 8 / 10);
2031 ccw = wxMax(ccw, cccw * 2 / 10);
2035 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2042 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2043 g_pauimgr->GetPane(cc).Fixed();
2044 g_pauimgr->Update();
2047 g_pauimgr->GetPane(cc).Resizable();
2059void MyFrame::OnIconize(wxIconizeEvent &event) {
2061 if (g_MainToolbar) {
2062 g_MainToolbar->Show(!event.IsIconized());
2064 if (g_iENCToolbar) {
2065 g_iENCToolbar->Show(!event.IsIconized());
2069 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2071 if (cc && cc->GetMUIBar()) {
2072 if (cc->GetMUIBar()->GetCanvasOptions()) {
2073 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2074 cc->GetMUIBar()->PushCanvasOptions();
2083void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2085void MyFrame::ODoSetSize(
void) {
2087 GetClientSize(&x, &y);
2090 if (m_pStatusBar != NULL) {
2091 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2092 int currentCount = m_pStatusBar->GetFieldsCount();
2093 if (currentCount != m_StatusBarFieldCount) {
2094 if ((currentCount > 0) && (currentCount < 7)) {
2097 int widths[] = {2, 2, 2, 2, 2, 2};
2098 m_pStatusBar->SetStatusWidths(currentCount, widths);
2101 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2104 if (m_StatusBarFieldCount) {
2109 if (m_StatusBarFieldCount > 2) {
2110 int widths[] = {-6, -5, -5, -6, -4};
2111 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2112 }
else if (m_StatusBarFieldCount == 2) {
2113 int cwidth = x * 90 / 100;
2114 int widths[] = {100, 100};
2115 widths[0] = cwidth * 6.4 / 10.0;
2116 widths[1] = cwidth * 3.6 / 10.0;
2117 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2119 int widths[] = {100, 100};
2120 widths[0] = x * 90 / 100;
2121 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2124 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2125 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2126 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2128 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2129 _T(
" COG ---\u00B0"));
2130 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2138 m_pStatusBar->GetFieldRect(0, stat_box);
2141 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2143 wxFont sys_font = *wxNORMAL_FONT;
2144 int try_font_size = sys_font.GetPointSize();
2147 int min_font_size = 10;
2157 wxFont *statusBarFont =
2158 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2159 int font_size = statusBarFont->GetPointSize();
2161 font_size = wxMin(font_size,
2164 wxMax(font_size, min_font_size);
2167 font_size = statusBarFont->GetPointSize();
2174 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2175 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2177 int min_height = stat_box.height;
2179 m_pStatusBar->SetFont(*pstat_font);
2180 m_pStatusBar->SetForegroundColour(
2181 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2183 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2185 (min_height >> 1) * 2;
2186 m_pStatusBar->SetMinHeight(min_height);
2195 SetCanvasSizes(GetClientSize());
2197 UpdateGPSCompassStatusBoxes(
true);
2199 if (console) PositionConsole();
2202 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2204 if (cc) cc->FormatPianoKeys();
2208 if (g_MainToolbar) {
2209 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2210 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2211 GetPrimaryCanvas()->GetCompass()->GetRect());
2212 g_MainToolbar->Realize();
2214 if (szBefore != g_MainToolbar->GetToolbarSize())
2215 g_MainToolbar->RefreshToolbar();
2224 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2237 options_lastWindowSize = wxSize(0, 0);
2238 options_lastWindowPos = wxPoint(0, 0);
2245 if (!b_inCloseWindow) {
2246 if (g_options) g_options->Raise();
2248 resizeAndroidPersistents();
2253 if (g_pauimgr) g_pauimgr->Update();
2256void MyFrame::PositionConsole(
void) {
2257 if (NULL == GetPrimaryCanvas())
return;
2259 int ccx, ccy, ccsx, ccsy, consx, consy;
2261 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2264 consoleHost->GetSize(&ccsx, &ccsy);
2265 consoleHost->GetPosition(&ccx, &ccy);
2267 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2268 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2269 consoleHost = GetPrimaryCanvas();
2274 if (consoleHost->GetCompass()) {
2275 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2277 if (compass_rect.y < 100)
2278 yOffset = compass_rect.y + compass_rect.height + 45;
2282 console->GetSize(&consx, &consy);
2284 wxPoint screen_pos =
2285 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2286 console->Move(screen_pos);
2289void MyFrame::UpdateAllFonts() {
2291 console->UpdateFonts();
2298 DestroyPersistentDialogs();
2300 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2305void MyFrame::DestroyPersistentDialogs() {
2306 if (g_pais_query_dialog_active) {
2307 g_pais_query_dialog_active->Hide();
2308 g_pais_query_dialog_active->Destroy();
2309 g_pais_query_dialog_active = NULL;
2312 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2313 pRoutePropDialog->Hide();
2314 pRoutePropDialog->Destroy();
2315 pRoutePropDialog = NULL;
2318 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2319 pTrackPropDialog->Hide();
2320 pTrackPropDialog->Destroy();
2321 pTrackPropDialog = NULL;
2324 if (g_pMarkInfoDialog) {
2325 g_pMarkInfoDialog->Hide();
2326 g_pMarkInfoDialog->Destroy();
2327 g_pMarkInfoDialog = NULL;
2330 if (g_pObjectQueryDialog) {
2331 g_pObjectQueryDialog->Hide();
2332 g_pObjectQueryDialog->Destroy();
2333 g_pObjectQueryDialog = NULL;
2337void MyFrame::RefreshGroupIndices(
void) {
2339 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2341 if (cc) cc->canvasRefreshGroupIndex();
2345void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2346 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2348 switch (event.GetId()) {
2349 case ID_MENU_SCALE_OUT:
2350 DoStackDelta(GetPrimaryCanvas(), 1);
2354 case ID_MENU_SCALE_IN:
2355 DoStackDelta(GetPrimaryCanvas(), -1);
2359 case ID_MENU_ZOOM_IN: {
2360 if (GetFocusCanvas()) {
2361 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2366 case ID_MENU_ZOOM_OUT: {
2367 if (GetFocusCanvas()) {
2368 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2373 case ID_MENU_ROUTE_NEW: {
2374 if (GetFocusCanvas()) {
2375 if (0 == GetFocusCanvas()->m_routeState) {
2376 GetFocusCanvas()->StartRoute();
2378 GetFocusCanvas()->FinishRoute();
2384 case ID_MENU_TOOL_MEASURE: {
2385 GetPrimaryCanvas()->StartMeasureRoute();
2389 case ID_MENU_TOOL_NMEA_DBG_LOG:
2390 if (!wxWindow::FindWindowByName(
"NmeaDebugWindow")) {
2391 auto top_window = wxWindow::FindWindowByName(kTopLevelWindowName);
2392 NMEALogWindow::GetInstance().Create(top_window, 35);
2394 wxWindow::FindWindowByName(
"NmeaDebugWindow")->Show();
2397 case ID_MENU_MARK_BOAT: {
2402 case ID_MENU_MARK_CURSOR: {
2407 case ID_MENU_NAV_FOLLOW: {
2408 if (gFrame->GetPrimaryCanvas())
2409 gFrame->GetPrimaryCanvas()->TogglebFollow();
2413 case ID_MENU_CHART_OUTLINES: {
2414 ToggleChartOutlines(GetFocusCanvas());
2418 case ID_MENU_CHART_QUILTING: {
2419 ToggleQuiltMode(GetFocusCanvas());
2423 case ID_MENU_UI_CHARTBAR: {
2424 ToggleChartBar(GetFocusCanvas());
2428 case ID_MENU_ENC_TEXT:
2430 ToggleENCText(GetFocusCanvas());
2433 case ID_MENU_ENC_LIGHTS: {
2434 ToggleLights(GetFocusCanvas());
2437 case ID_MENU_ENC_SOUNDINGS: {
2438 ToggleSoundings(GetFocusCanvas());
2441 case ID_MENU_ENC_ANCHOR: {
2442 ToggleAnchor(GetFocusCanvas());
2445 case ID_MENU_ENC_DATA_QUALITY: {
2446 ToggleDataQuality(GetFocusCanvas());
2449 case ID_MENU_SHOW_NAVOBJECTS: {
2450 ToggleNavobjects(GetFocusCanvas());
2454 case ID_MENU_AIS_TARGETS: {
2455 ToggleAISDisplay(GetFocusCanvas());
2458 case ID_MENU_AIS_MOORED_TARGETS: {
2459 g_bHideMoored = !g_bHideMoored;
2462 case ID_MENU_AIS_SCALED_TARGETS: {
2463 ToggleAISMinimizeTargets(GetFocusCanvas());
2467 case ID_MENU_AIS_TARGETLIST: {
2468 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2472 case ID_MENU_AIS_TRACKS: {
2473 g_bAISShowTracks = !g_bAISShowTracks;
2474 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2478 case ID_MENU_AIS_CPADIALOG: {
2479 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2480 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2481 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2482 if (g_bAIS_CPA_Alert) {
2483 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2488 case ID_MENU_AIS_CPASOUND: {
2489 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2490 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2494 case ID_MENU_AIS_CPAWARNING: {
2495 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2496 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2500 case wxID_PREFERENCES:
2502 g_MainToolbar->HideTooltip();
2507 case ID_SETTINGS_NEW: {
2512 case ID_SETTINGS_DELETE: {
2514 g_options =
nullptr;
2518 case ID_MENU_SETTINGS_BASIC: {
2521 androidDisableFullScreen();
2522 g_MainToolbar->HideTooltip();
2523 DoAndroidPreferences();
2530 case ID_MENU_UI_FULLSCREEN: {
2535 case ID_MENU_SHOW_CURRENTS: {
2536 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2537 GetFocusCanvas()->ReloadVP();
2538 GetFocusCanvas()->Refresh(
false);
2542 case ID_MENU_SHOW_TIDES: {
2543 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2544 GetFocusCanvas()->ReloadVP();
2545 GetFocusCanvas()->Refresh(
false);
2551 g_Platform->DoHelpDialog();
2556 g_Platform->LaunchLocalHelp();
2565 case ID_MENU_UI_COLSCHEME:
2566 case ID_COLSCHEME: {
2567 ToggleColorScheme();
2576 case ID_MENU_OQUIT: {
2581 case ID_MENU_ROUTE_MANAGER:
2582 case ID_ROUTEMANAGER: {
2583 pRouteManagerDialog = RouteManagerDialog::getInstance(
2586 if (pRouteManagerDialog->IsShown())
2587 pRouteManagerDialog->Hide();
2589 pRouteManagerDialog->UpdateRouteListCtrl();
2590 pRouteManagerDialog->UpdateTrkListCtrl();
2591 pRouteManagerDialog->UpdateWptListCtrl();
2592 pRouteManagerDialog->UpdateLayListCtrl();
2594 pRouteManagerDialog->Show();
2598 pRouteManagerDialog->Centre();
2599 pRouteManagerDialog->Raise();
2605 case ID_MENU_NAV_TRACK:
2607 if (!g_bTrackActive) {
2609 g_bTrackCarryOver =
true;
2612 if (pConfig && pConfig->IsChangesFileDirty()) {
2613 pConfig->UpdateNavObj(
true);
2615 g_bTrackCarryOver =
false;
2616 RefreshAllCanvas(
true);
2621 case ID_MENU_CHART_NORTHUP: {
2622 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2625 case ID_MENU_CHART_COGUP: {
2626 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2629 case ID_MENU_CHART_HEADUP: {
2630 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2634 case ID_MENU_MARK_MOB:
2640 case ID_MASTERTOGGLE: {
2641 if (g_MainToolbar) {
2642 wxString tip = _(
"Show Toolbar");
2643 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2644 if (g_MainToolbar->GetToolbar())
2645 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2647 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2650 if (g_bmasterToolbarFull)
2651 m_nMasterToolCountShown =
2652 g_MainToolbar->GetToolCount() -
2655 m_nMasterToolCountShown = 2;
2657 m_nMasterToolCountShown =
2658 g_MainToolbar->GetToolShowCount();
2660 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2668 case ID_CMD_SELECT_CHART_TYPE: {
2669 selectChartDisplay(event.GetExtraLong(), -1);
2673 case ID_CMD_SELECT_CHART_FAMILY: {
2674 selectChartDisplay(-1, event.GetExtraLong());
2678 case ID_CMD_APPLY_SETTINGS: {
2679 applySettingsString(event.GetString());
2681 androidRestoreFullScreen();
2687 case ID_CMD_NULL_REFRESH: {
2692 case ID_CMD_SETVP: {
2693 setStringVP(event.GetString());
2697 case ID_CMD_INVALIDATE: {
2703 case ID_CMD_POST_JSON_TO_PLUGINS: {
2709 int numErrors = reader.
Parse(event.GetString(), &root);
2710 if (numErrors == 0) {
2711 if (root[_T(
"MessageID")].IsString()) {
2712 wxString MsgID = root[_T(
"MessageID")].
AsString();
2723 if (g_iENCToolbar) {
2724 g_iENCToolbar->OnToolLeftClick(event);
2734 g_MainToolbar->HideTooltip();
2736 ArrayOfPlugInToolbarTools tool_array =
2737 g_pi_manager->GetPluginToolbarToolArray();
2738 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2740 if (event.GetId() == pttc->id) {
2741 if (pttc->m_pplugin)
2760 if (g_MainToolbar) g_MainToolbar->Realize();
2763bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2764 bool viz_now = g_bmasterToolbarFull;
2766 g_MainToolbar->HideTooltip();
2767 wxString tip = _(
"Show Toolbar");
2769 tip = _(
"Hide Toolbar");
2770 if (g_MainToolbar->GetToolbar())
2771 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2774 bool toggle =
false;
2775 if (viz && !g_bmasterToolbarFull)
2778 else if (!viz && g_bmasterToolbarFull)
2782 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2785 if (g_bmasterToolbarFull)
2786 m_nMasterToolCountShown =
2787 g_MainToolbar->GetToolCount() -
2790 m_nMasterToolCountShown = 2;
2792 m_nMasterToolCountShown =
2793 g_MainToolbar->GetToolShowCount();
2795 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2801void MyFrame::ScheduleDeleteSettingsDialog() {
2802 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2803 evt.SetId(ID_SETTINGS_DELETE);
2804 GetEventHandler()->AddPendingEvent(evt);
2807void MyFrame::ScheduleSettingsDialog() {
2808 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2809 evt.SetId(ID_SETTINGS);
2810 GetEventHandler()->AddPendingEvent(evt);
2813void MyFrame::ScheduleSettingsDialogNew() {
2814 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2815 evt.SetId(ID_SETTINGS_NEW);
2816 GetEventHandler()->AddPendingEvent(evt);
2819void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2820 UpdateCanvasConfigDescriptors();
2822 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2823 CreateCanvasLayout(
true);
2825 CreateCanvasLayout();
2827 g_pauimgr->Update();
2829 ConfigureStatusBar();
2830 wxSize lastOptSize = options_lastWindowSize;
2835 options_lastWindowSize = lastOptSize;
2839 ScheduleSettingsDialogNew();
2841 ScheduleSettingsDialog();
2846 if ((g_canvasConfig != 0) && g_focusCanvas)
2847 return g_focusCanvas;
2849 return GetPrimaryCanvas();
2852void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2853 if (g_bmasterToolbarFull) {
2854#ifndef OCPN_TOOLBAR_ANIMATE
2855 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
2858 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
2859 m_nMasterToolCountShown++;
2860 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2861 g_MainToolbar->Realize();
2862 g_MainToolbar->RefreshToolbar();
2864 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2866 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2867 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2868 g_MainToolbar->Realize();
2869 g_MainToolbar->RefreshToolbar();
2872#ifndef OCPN_TOOLBAR_ANIMATE
2873 m_nMasterToolCountShown = 1;
2875 if (m_nMasterToolCountShown > 1) {
2876 m_nMasterToolCountShown--;
2877 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2878 g_MainToolbar->Realize();
2879 g_MainToolbar->RefreshToolbar();
2880 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2882 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2883 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2884 g_MainToolbar->Realize();
2885 g_MainToolbar->RefreshToolbar();
2890void MyFrame::InvalidateAllGL() {
2893 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2903void MyFrame::RefreshAllCanvas(
bool bErase) {
2905 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2908 cc->Refresh(bErase);
2913void MyFrame::setStringVP(wxString VPS) {
2918 wxStringTokenizer tkz(VPS, _T(
";"));
2920 wxString token = tkz.GetNextToken();
2922 token.ToDouble(&lat);
2924 token = tkz.GetNextToken();
2926 token.ToDouble(&lon);
2928 token = tkz.GetNextToken();
2930 token.ToDouble(&scale_ppm);
2932 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2935void MyFrame::DoSettingsNew() {
2937 g_options =
nullptr;
2942void MyFrame::DoSettings() {
2946 ApplyGlobalSettings(
true);
2949 bool b_loadHarmonics =
false;
2950 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2953 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2956 if (b_loadHarmonics) LoadHarmonics();
2964 g_bShowChartBar = !g_bShowChartBar;
2966 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2971 if (g_bShowChartBar) {
2973 UpdateControlBar(cc);
2976 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2979void MyFrame::ToggleColorScheme() {
2980 static bool lastIsNight;
2981 ColorScheme s = GetColorScheme();
2984 if (lastIsNight && is == 3)
2987 lastIsNight =
false;
2989 if (lastIsNight) is = 2;
2990 if (is == 3) lastIsNight =
true;
2991 s = (ColorScheme)is;
2992 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
2994 SetAndApplyColorScheme(s);
2997void MyFrame::ToggleFullScreen() {
2998 bool to = !IsFullScreen();
3003 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3005 ShowFullScreen(to, style);
3008 UpdateAllToolbars(global_color_scheme);
3010 UpdateControlBar(GetPrimaryCanvas());
3012 TriggerRecaptureTimer();
3015void MyFrame::ActivateMOB(
void) {
3017 wxDateTime mob_time = wxDateTime::Now();
3018 wxString mob_label(_(
"MAN OVERBOARD"));
3019 mob_label += _(
" on ");
3020 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3023 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3024 pWP_MOB->SetShared(
true);
3026 pWP_MOB->SetWaypointArrivalRadius(
3028 pWP_MOB->SetUseSca(
false);
3029 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3030 pConfig->AddNewWayPoint(pWP_MOB, -1);
3032 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3035 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3038 new RoutePoint(zlat, zlon, g_default_wp_icon,
3039 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3040 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3043 pRouteList->Append(temp_route);
3045 temp_route->AddPoint(pWP_src);
3046 temp_route->AddPoint(pWP_MOB);
3048 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3051 temp_route->m_RouteNameString = _(
"Temporary MOB Route");
3052 temp_route->m_RouteStartString = _(
"Assumed 1 Mile Point");
3054 temp_route->m_RouteEndString = mob_label;
3056 temp_route->m_bDeleteOnArrival =
false;
3058 temp_route->SetRouteArrivalRadius(-1.0);
3060 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3061 g_pRouteMan->ActivateRoute(temp_route, pWP_MOB);
3064 v[_T(
"GUID")] = temp_route->m_GUID;
3065 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
3066 SendJSONMessageToAllPlugins(msg_id, v);
3069 if (RouteManagerDialog::getInstanceFlag()) {
3070 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3071 pRouteManagerDialog->UpdateRouteListCtrl();
3072 pRouteManagerDialog->UpdateWptListCtrl();
3077 RefreshAllCanvas(
false);
3079 wxString mob_message(_(
"MAN OVERBOARD"));
3080 mob_message += _(
" Time: ");
3081 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3082 mob_message += _(
" Position: ");
3083 mob_message += toSDMM(1, gLat);
3084 mob_message += _T(
" ");
3085 mob_message += toSDMM(2, gLon);
3086 wxLogMessage(mob_message);
3088void MyFrame::TrackOn(
void) {
3089 g_bTrackActive =
true;
3092 g_TrackList.push_back(g_pActiveTrack);
3093 if (pConfig) pConfig->AddNewTrack(g_pActiveTrack);
3095 g_pActiveTrack->Start();
3098 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3100 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3102 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3105 androidSetTrackTool(
true);
3108 if (RouteManagerDialog::getInstanceFlag()) {
3109 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3110 pRouteManagerDialog->UpdateTrkListCtrl();
3111 pRouteManagerDialog->UpdateRouteListCtrl();
3117 now = now.Now().ToUTC();
3118 wxString name = g_pActiveTrack->GetName();
3119 if (name.IsEmpty()) {
3120 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3121 if (tp->GetCreateTime().IsValid())
3122 name = tp->GetCreateTime().FormatISODate() + _T(
" ") +
3123 tp->GetCreateTime().FormatISOTime();
3125 name = _(
"(Unnamed Track)");
3127 v[_T(
"Name")] = name;
3128 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3129 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3130 SendJSONMessageToAllPlugins(msg_id, v);
3131 g_FlushNavobjChangesTimeout =
3135Track *MyFrame::TrackOff(
bool do_add_point) {
3136 Track *return_val = g_pActiveTrack;
3138 if (g_pActiveTrack) {
3140 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3141 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3142 SendJSONMessageToAllPlugins(msg_id, v);
3144 g_pActiveTrack->Stop(do_add_point);
3146 if (g_pActiveTrack->GetnPoints() < 2) {
3147 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3150 if (g_bTrackDaily) {
3151 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3153 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3154 return_val = pExtendTrack;
3158 g_pActiveTrack = NULL;
3161 g_bTrackActive =
false;
3163 if (RouteManagerDialog::getInstanceFlag()) {
3164 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3165 pRouteManagerDialog->UpdateTrkListCtrl();
3166 pRouteManagerDialog->UpdateRouteListCtrl();
3170 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3172 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3173 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3176 androidSetTrackTool(
false);
3179 g_FlushNavobjChangesTimeout =
3185bool MyFrame::ShouldRestartTrack(
void) {
3186 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3187 time_t now = wxDateTime::Now().GetTicks();
3188 time_t today = wxDateTime::Today().GetTicks();
3190 switch (g_track_rotate_time_type) {
3192 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3194 case TIME_TYPE_COMPUTER:
3195 rotate_at = g_track_rotate_time;
3199 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3200 rotate_at = g_track_rotate_time + utc_offset;
3203 if (rotate_at > 86400)
3205 else if (rotate_at < 0)
3207 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3208 now - today >= rotate_at) {
3209 if (m_last_track_rotation_ts == 0) {
3210 if (now - today > rotate_at)
3211 m_last_track_rotation_ts = today + rotate_at;
3213 m_last_track_rotation_ts = today + rotate_at - 86400;
3216 m_last_track_rotation_ts = now;
3222void MyFrame::TrackDailyRestart(
void) {
3223 if (!g_pActiveTrack)
return;
3225 Track *pPreviousTrack = TrackOff(
true);
3226 if (pConfig && pConfig->IsChangesFileDirty()) {
3227 pConfig->UpdateNavObj(
true);
3236 if (pPreviousTrack) {
3237 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3238 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3241 if (RouteManagerDialog::getInstanceFlag()) {
3242 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3243 pRouteManagerDialog->UpdateTrkListCtrl();
3244 pRouteManagerDialog->UpdateRouteListCtrl();
3249void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3251 cc->SetUpMode(mode);
3253 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3254 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3255 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3258 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3263 cc->SetShowENCText(!cc->GetShowENCText());
3265 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3273void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3276 cc->SetENCDisplayCategory(nset);
3278 UpdateGlobalMenuItems();
3289 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3291 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3300 cc->SetShowENCLights(!cc->GetShowENCLights());
3302 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3304 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3312void MyFrame::ToggleRocks(
void )
3318 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3319 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3320 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3321 pOLE->nViz = !pOLE->nViz;
3325 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3326 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3327 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3330 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3334 ps52plib->GenerateStateHash();
3341 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3343 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3345 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3351 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3353 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3355 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3368 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3369 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3374 cc->SetShowAIS(!cc->GetShowAIS());
3375 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3379void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3380 cc->SetAttenAIS(!cc->GetAttenAIS());
3381 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3387 cc->m_bFollow =
true;
3390 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3394 SetChartUpdatePeriod();
3402 cc->m_bFollow =
false;
3404 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3408 SetChartUpdatePeriod();
3411void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3412 cc->SetShowOutlines(!cc->GetShowOutlines());
3414 RefreshAllCanvas(
false);
3418 if (g_bopengl) InvalidateAllGL();
3421 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3424void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3426void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3428 bool enabled = m_pMenuBar->IsEnabled(item_id);
3429 m_pMenuBar->Enable(item_id,
false);
3430 m_pMenuBar->Check(item_id, state);
3431 m_pMenuBar->Enable(item_id, enabled);
3435void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3436 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3437 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3438 g_MainToolbar->Realize();
3442void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3443 wxBitmap *bmpRollover) {
3444 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3445 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3446 g_MainToolbar->Realize();
3450void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3451 wxString rolloverSVGfile,
3452 wxString toggledSVGfile) {
3453 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3454 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3455 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3459void MyFrame::ConfigureStatusBar() {
3461 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3464 UseNativeStatusBar(
false);
3467 if (g_bShowStatusBar) {
3468 if (!m_pStatusBar) {
3470 CreateStatusBar(m_StatusBarFieldCount, 0);
3471 ApplyGlobalColorSchemetoStatusBar();
3476 m_pStatusBar->Destroy();
3477 m_pStatusBar = NULL;
3483void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3484 ConfigureStatusBar();
3486 wxSize lastOptSize = options_lastWindowSize;
3492 options_lastWindowSize = lastOptSize;
3494 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3497wxString _menuText(wxString name, wxString shortcut) {
3501 menutext << _T(
"\t") << shortcut;
3506void MyFrame::BuildMenuBar(
void) {
3512 bool showMenuBar =
true;
3514 bool showMenuBar = g_bShowMenuBar;
3526 m_pMenuBar =
new wxMenuBar();
3527 RegisterGlobalMenuItems();
3528 SetMenuBar(m_pMenuBar);
3532 UpdateGlobalMenuItems();
3537 m_pMenuBar->Destroy();
3543void MyFrame::RegisterGlobalMenuItems() {
3544 if (!m_pMenuBar)
return;
3546 wxMenu *nav_menu =
new wxMenu();
3547 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3548 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3549 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3550 nav_menu->AppendSeparator();
3551 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3552 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3553 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3554 nav_menu->AppendSeparator();
3556 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3557 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3559 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3560 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3562 nav_menu->AppendSeparator();
3563 nav_menu->Append(ID_MENU_SCALE_IN,
3564 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3565 nav_menu->Append(ID_MENU_SCALE_OUT,
3566 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3568 nav_menu->AppendSeparator();
3569 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3571 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3573 wxMenu *view_menu =
new wxMenu();
3575 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3576 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3577 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3578 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3580 view_menu->AppendCheckItem(
3581 ID_MENU_CHART_QUILTING,
3582 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3583 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3584 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3586 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3587 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3589 view_menu->AppendSeparator();
3591 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3592 _menuText(_(
"Show ENC text"), _T(
"T")));
3593 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3594 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3595 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3596 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3597 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3598 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3599 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3600 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3601 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3602 _menuText(_(
"Show Navobjects"), _T(
"V")));
3604 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3605 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3606 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3607 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3608 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3609 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3610 view_menu->AppendCheckItem(
3611 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3612 view_menu->AppendCheckItem(
3613 ID_MENU_ENC_DATA_QUALITY,
3614 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3615 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3616 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3618 view_menu->AppendSeparator();
3619 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3620 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3621 view_menu->AppendSeparator();
3623 view_menu->Append(ID_MENU_UI_COLSCHEME,
3624 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3626 view_menu->Append(ID_MENU_UI_COLSCHEME,
3627 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3630 view_menu->AppendSeparator();
3632 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3633 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3635 m_pMenuBar->Append(view_menu, _(
"&View"));
3637 wxMenu *ais_menu =
new wxMenu();
3638 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3639 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3640 _(
"Attenuate less critical AIS targets"));
3641 ais_menu->AppendSeparator();
3642 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3643 _(
"Hide Moored AIS Targets"));
3644 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3645 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3646 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3650 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3652 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3653 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3656 ais_menu->AppendSeparator();
3657 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3658 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3660 wxMenu *tools_menu =
new wxMenu();
3661 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3662 _menuText(_(
"NMEA Debugger"),
"Alt-C"));
3664 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3665 _menuText(_(
"Measure Distance"), _T(
"M")));
3667 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3668 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3671 tools_menu->AppendSeparator();
3672 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3673 tools_menu->Append(ID_MENU_ROUTE_NEW,
3674 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3675 tools_menu->AppendSeparator();
3676 tools_menu->Append(ID_MENU_MARK_BOAT,
3677 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3678 tools_menu->Append(ID_MENU_MARK_CURSOR,
3679 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3680 tools_menu->AppendSeparator();
3685 _(
"Drop MOB Marker"),
3686 _T(
"RawCtrl-Space")));
3687 tools_menu->AppendSeparator();
3688 tools_menu->Append(wxID_PREFERENCES,
3689 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3691 tools_menu->Append(ID_MENU_MARK_MOB,
3692 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3693 tools_menu->AppendSeparator();
3694 tools_menu->Append(wxID_PREFERENCES,
3695 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3697 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3700 wxMenu *window_menu =
new wxMenu();
3701 m_pMenuBar->Append(window_menu, _(
"&Window"));
3704 wxMenu *help_menu =
new wxMenu();
3705 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3706 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3707 m_pMenuBar->Append(help_menu, _(
"&Help"));
3710 UpdateGlobalMenuItems();
3713void MyFrame::UpdateGlobalMenuItems() {
3714 if (!m_pMenuBar)
return;
3716 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3717 ->Check(GetPrimaryCanvas()->m_bFollow);
3718 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3719 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3720 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3721 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3722 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3723 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3724 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3725 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3726 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3727 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3728 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3729 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3730 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3731 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3732 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3733 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3734 if (g_bAIS_CPA_Alert) {
3735 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3736 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3739 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3743 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3744 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3747 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3748 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3749 ->Check(ps52plib->GetShowSoundings());
3751 bool light_state =
false;
3753 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3755 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3756 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3757 light_state = (pOLE->nViz == 1);
3762 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3763 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3767 DisCat nset = ps52plib->GetDisplayCategory();
3768 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3769 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3770 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3771 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3772 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3773 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3774 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3777 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3778 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3783void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3784 if (!m_pMenuBar)
return;
3786 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3788 if (cc->GetUpMode() == NORTH_UP_MODE)
3789 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3790 else if (cc->GetUpMode() == COURSE_UP_MODE)
3791 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3793 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3795 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3796 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3797 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3798 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3799 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3800 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3801 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3802 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3803 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3804 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3805 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3806 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3807 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3808 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3809 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3812 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3813 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3816 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3818 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3819 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3824 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3828 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3829 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3830 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3831 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3832 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3833 ->Check(cc->GetShowENCDataQual());
3834 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3836 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3837 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3838 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3843void MyFrame::InvalidateAllCanvasUndo() {
3845 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3847 if (cc) cc->undo->InvalidateUndo();
3851void MyFrame::SubmergeAllCanvasToolbars(
void) {
3853 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3855 if (cc) cc->SubmergeToolbar();
3859void MyFrame::SurfaceAllCanvasToolbars(
void) {
3860 if (g_bshowToolbar) {
3862 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3864 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3871void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3873 if (lon > 180.0) lon -= 360.0;
3878 cc->JumpToPosition(lat, lon,
scale);
3881 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3885void MyFrame::UpdateCanvasConfigDescriptors() {
3887 for (
unsigned int i = 0;
3888 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3889 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3897 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3898 cc->GroupID = chart->m_groupIndex;
3901 cc->
bQuilt = chart->GetQuiltMode();
3908 cc->
bFollow = chart->m_bFollow;
3913 int upmode = chart->GetUpMode();
3914 if (upmode == COURSE_UP_MODE)
3916 else if (upmode == HEAD_UP_MODE)
3923void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3924 if (!RBBox.GetValid())
return;
3926 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3927 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3930 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3931 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3939 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3940 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3942 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3943 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3945 cc->GetSize(&ww, &wh);
3947 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3949 ppm = wxMin(ppm, 1.0);
3955void MyFrame::PrepareOptionsClose(
options *settings,
3956 int settings_return_value) {
3958 options_lastPage = settings->lastPage;
3963 if (options_lastPage == 1) options_lastPage = 0;
3965 options_subpage = settings->lastSubPage;
3966 options_lastWindowPos = settings->lastWindowPos;
3967 options_lastWindowSize = settings->lastWindowSize;
3970 androidEnableBackButton(
true);
3971 androidEnableOptionsMenu(
true);
3972 androidRestoreFullScreen();
3973 androidEnableRotation();
3982 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3985 int index_hint = -1;
3986 if (i < pathArray.GetCount())
3987 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
3988 cc->canvasChartsRefresh(index_hint);
3989 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
3996void MyFrame::DoOptionsDialog() {
3997 if (NULL == g_options) {
3998 AbstractPlatform::ShowBusySpinner();
4001 pConfig->SetPath(
"/Settings");
4002 pConfig->Read(
"OptionsSizeX", &sx, -1);
4003 pConfig->Read(
"OptionsSizeY", &sy, -1);
4005 wxWindow *optionsParent =
this;
4007 optionsParent = GetPrimaryCanvas();
4009 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4012 AbstractPlatform::HideBusySpinner();
4016 g_options->SetInitChartDir(*pInit_Chart_Dir);
4019 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
4020 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4021 g_options->SetWorkDirListPtr(pWorkDirArray);
4024 g_options->SetConfigPtr(pConfig);
4025 g_options->SetInitialSettings();
4027 prev_locale = g_locale;
4028 g_options->SetInitialPage(options_lastPage, options_subpage);
4031 g_options->lastWindowPos = options_lastWindowPos;
4032 if (options_lastWindowPos != wxPoint(0, 0)) {
4033 g_options->Move(options_lastWindowPos);
4034 g_options->SetSize(options_lastWindowSize);
4036 g_options->CenterOnScreen();
4038 if (options_lastWindowSize != wxSize(0, 0)) {
4039 g_options->SetSize(options_lastWindowSize);
4044 androidEnableBackButton(
false);
4045 androidEnableOptionsMenu(
false);
4046 androidDisableFullScreen();
4053 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4056 wxString chart_file_name;
4057 if (cc->GetQuiltMode()) {
4058 int dbi = cc->GetQuiltRefChartdbIndex();
4059 chart_file_name = ChartData->GetDBChartFileName(dbi);
4061 if (cc->m_singleChart)
4062 chart_file_name = cc->m_singleChart->GetFullPath();
4065 pathArray.Add(chart_file_name);
4071 last_canvasConfig = g_canvasConfig;
4074 g_last_ChartScaleFactor = g_ChartScaleFactor;
4080void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4081 bool b_need_refresh =
false;
4083 if ((rr & VISIT_CHARTS) &&
4084 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4086 UpdateChartDatabaseInplace(*pNewDirArray,
4087 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4090 b_need_refresh =
true;
4094 if (rr & STYLE_CHANGED) {
4097 _(
"Please restart OpenCPN to activate language or style changes."),
4098 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4101 bool b_groupchange =
false;
4102 if (((rr & VISIT_CHARTS) &&
4103 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4104 (rr & GROUPS_CHANGED)) {
4105 b_groupchange = ScrubGroupArray();
4106 ChartData->ApplyGroupArray(g_pGroupArray);
4107 RefreshGroupIndices();
4110 if (rr & GROUPS_CHANGED || b_groupchange) {
4111 pConfig->DestroyConfigGroups();
4112 pConfig->CreateConfigGroups(g_pGroupArray);
4115 if (rr & TIDES_CHANGED) {
4121 if (rr & S52_CHANGED) {
4122 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4125 pConfig->UpdateSettings();
4127 if (g_pActiveTrack) {
4128 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4132 g_pRouteMan->SetColorScheme(global_color_scheme,
4133 g_Platform->GetDisplayDPmm());
4136 double stuffcog = NAN;
4137 double stuffsog = NAN;
4138 if (!std::isnan(gCog)) stuffcog = gCog;
4139 if (!std::isnan(gSog)) stuffsog = gSog;
4141 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4142 COGFilterTable[i] = stuffcog;
4143 SOGFilterTable[i] = stuffsog;
4146 SetChartUpdatePeriod();
4148 if (rr & GL_CHANGED) {
4152 b_need_refresh =
true;
4155 if (rr & S52_CHANGED) {
4156 b_need_refresh =
true;
4160 if (rr & REBUILD_RASTER_CACHE) {
4161 if (g_glTextureManager) {
4162 GetPrimaryCanvas()->Disable();
4163 g_glTextureManager->BuildCompressedCache();
4164 GetPrimaryCanvas()->Enable();
4169 if (g_config_display_size_manual &&
4170 g_config_display_size_mm.size() > g_current_monitor &&
4171 g_config_display_size_mm[g_current_monitor] > 0) {
4172 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4177 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4183 g_pi_manager->SendBaseConfigToAllPlugIns();
4184 int rrt = rr & S52_CHANGED;
4185 g_pi_manager->SendS52ConfigToAllPlugIns(
4186 (rrt == S52_CHANGED) ||
4187 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4190 if (g_MainToolbar) {
4191 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4192 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4197 ps52plib->SetScaleFactorExp(
4198 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4199 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4203 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4205 if (cc) cc->ApplyGlobalSettings();
4212 int index_hint = ChartData->FinddbIndex( chart_file_name );
4213 if( -1 == index_hint )
4221 bool ztc = g_bEnableZoomToCursor;
4222 g_bEnableZoomToCursor =
4227 g_bEnableZoomToCursor = ztc;
4230 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4231 if (g_pMarkInfoDialog) {
4232 g_pMarkInfoDialog->Hide();
4233 g_pMarkInfoDialog->Destroy();
4234 g_pMarkInfoDialog = NULL;
4239 SetGPSCompassScale();
4241 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4244 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4245 cc->UpdateCanvasControlBar();
4248 UpdateGPSCompassStatusBoxes();
4250 SetAllToolbarScale();
4251 RequestNewToolbars();
4254 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4257 cc->RebuildCursors();
4262 bool b_masterScaleChange =
false;
4263 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4264 b_masterScaleChange =
true;
4266 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4267 RequestNewMasterToolbar(
true);
4269 bool bMuiChange =
false;
4275 if (b_masterScaleChange || bMuiChange) {
4277 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4280 cc->ProcessNewGUIScale();
4286 if (rr & LOCALE_CHANGED) {
4287 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4289 rr |= NEED_NEW_OPTIONS;
4294 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4298 g_last_ChartScaleFactor = g_ChartScaleFactor;
4303bool MyFrame::CheckGroup(
int igroup) {
4304 if (igroup == 0)
return true;
4306 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4308 if (!pGroup->m_element_array.size())
4311 for (
const auto &elem : pGroup->m_element_array) {
4312 for (
unsigned int ic = 0;
4313 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4315 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4317 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4324bool MyFrame::ScrubGroupArray() {
4329 bool b_change =
false;
4330 unsigned int igroup = 0;
4331 while (igroup < g_pGroupArray->GetCount()) {
4332 bool b_chart_in_element =
false;
4333 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4335 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4336 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4338 for (
unsigned int ic = 0;
4339 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4341 wxString chart_full_path = pcte->GetFullSystemPath();
4343 if (chart_full_path.StartsWith(element_root)) {
4344 b_chart_in_element =
true;
4350 if (!b_chart_in_element) {
4351 wxString test_string = _T(
"GSHH");
4352 if (element_root.Upper().Contains(test_string))
4353 b_chart_in_element =
true;
4356 if (!b_chart_in_element)
4358 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4370void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4372 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4374 if (cc && (cc != ccThis)) cc->Refresh();
4379void MyFrame::ChartsRefresh() {
4380 if (!ChartData)
return;
4382 AbstractPlatform::ShowBusySpinner();
4384 bool b_run = FrameTimer1.IsRunning();
4387 FrameTenHzTimer.Stop();
4390 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4393 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4394 if (cc->GetQuiltMode()) {
4395 currentIndex = cc->GetQuiltReferenceChartIndex();
4397 cc->canvasChartsRefresh(currentIndex);
4401 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4402 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4404 AbstractPlatform::HideBusySpinner();
4407void MyFrame::InvalidateAllQuilts() {
4408 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4411 cc->InvalidateQuilt();
4412 cc->SetQuiltRefChart(-1);
4413 cc->m_singleChart = NULL;
4418bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4420 const wxString &ChartListFileName) {
4421 bool b_run = FrameTimer1.IsRunning();
4423 FrameTenHzTimer.Stop();
4425 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4426 FrameCOGTimer.Stop();
4429 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4432 cc->InvalidateQuilt();
4433 cc->SetQuiltRefChart(-1);
4434 cc->m_singleChart = NULL;
4438 ChartData->PurgeCache();
4444 AbstractPlatform::ShowBusySpinner();
4446 wxGenericProgressDialog *pprog =
nullptr;
4448 wxString longmsg = _(
"OpenCPN Chart Update");
4450 _T(
"..................................................................")
4453 pprog = new wxGenericProgressDialog();
4456 pprog->SetFont(*qFont);
4458 pprog->Create(_("OpenCPN
Chart Update"), longmsg, 100, gFrame,
4459 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4460 wxPD_REMAINING_TIME);
4466 wxLogMessage(_T(" "));
4467 wxLogMessage(_T("Starting chart database Update..."));
4468 wxString gshhg_chart_loc = gWorldMapLocation;
4469 gWorldMapLocation = wxEmptyString;
4472 ChartData->Update(DirArray, b_force, pprog);
4473 ChartData->SaveBinary(ChartListFileName);
4474 wxLogMessage(_T("Finished chart database Update"));
4475 wxLogMessage(_T(" "));
4476 if (gWorldMapLocation.empty()) {
4480 gWorldMapLocation = gDefaultWorldMapLocation;
4481 gshhg_chart_loc = wxEmptyString;
4484 if (gWorldMapLocation != gshhg_chart_loc) {
4486 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4488 if (cc) cc->ResetWorldBackgroundChart();
4491 gshhsCrossesLandReset();
4496 AbstractPlatform::HideBusySpinner();
4498 pConfig->UpdateChartDirs(DirArray);
4501 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4502 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4504 if (b_runCOGTimer) {
4506 int period_ms = 100;
4507 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4508 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4515 cc->ToggleCanvasQuiltMode();
4517 bool cur_mode = cc->GetQuiltMode();
4519 if( !cc->GetQuiltMode() )
4520 cc->SetQuiltMode(
true );
4522 if( cc->GetQuiltMode() ) {
4523 cc->SetQuiltMode(
false );
4524 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4528 if( cur_mode != cc->GetQuiltMode() ){
4534 g_bQuiltEnable = cc->GetQuiltMode();
4538 ps52plib->GenerateStateHash();
4543void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4545void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4547void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4549 cc->DoCanvasStackDelta(direction);
4553void MyFrame::PositionIENCToolbar() {
4555 if (g_iENCToolbar) {
4557 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4559 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4567void MyFrame::OnInitTimer(wxTimerEvent &event) {
4570 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4573 wxLog::FlushActive();
4575 switch (m_iInitCount++) {
4577 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4579 if (g_bInlandEcdis) {
4580 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4581 double range_set = 500.;
4583 range = wxRound(range * 10) / 10.;
4587 else if (range > 2000.)
4589 else if (range > 1600.)
4591 else if (range > 1200.)
4593 else if (range > 800.)
4598 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4602 g_Platform->SetFullscreen(g_bFullscreen);
4605 if (g_NeedDBUpdate > 0) {
4606 RebuildChartDatabase();
4607 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4610 cc->SetGroupIndex(0,
false);
4618 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4619 CHART_FAMILY_RASTER)) {
4622 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4624 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4625 CHART_FAMILY_VECTOR)) {
4628 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4637 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4640 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4642 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4645 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4649 pConfig->LoadNavObjects();
4651 if (!g_AW1GUID.IsEmpty()) {
4652 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4654 if (!g_AW2GUID.IsEmpty()) {
4655 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4660 appendOSDirSlash(&layerdir);
4661 layerdir.Append(_T(
"layers"));
4663 if (wxDir::Exists(layerdir)) {
4665 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4667 wxLogMessage(laymsg);
4668 pConfig->LoadLayers(layerdir);
4676 for (
auto *cp : TheConnectionParams()) {
4679 cp->b_IsSetup = TRUE;
4684 console->SetColorScheme(global_color_scheme);
4688 if (g_pRouteMan->IsAnyRouteActive()) {
4689 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
4696 if (m_initializing)
break;
4697 m_initializing =
true;
4698 AbstractPlatform::ShowBusySpinner();
4700 AbstractPlatform::HideBusySpinner();
4702 RequestNewMasterToolbar();
4705 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4707 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4709 wxString perspective;
4710 pConfig->SetPath(_T (
"/AUI" ));
4711 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4718 bool bno_load =
false;
4720 wxArrayString name_array;
4721 wxStringTokenizer st(perspective, _T(
"|;"));
4722 while (st.HasMoreTokens()) {
4723 wxString s1 = st.GetNextToken();
4724 if (s1.StartsWith(_T(
"name="))) {
4725 wxString sc = s1.AfterFirst(
'=');
4730 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4731 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4732 wxAuiPaneInfo pane = pane_array_val.Item(i);
4736 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4742 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4746 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4749 g_pauimgr->GetPane(cc).MinSize(10,10);
4756 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4759 wxSize frameSize = GetClientSize();
4760 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4761 int width = wxMax(minSize.x, frameSize.x / 10);
4762 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4765 g_pauimgr->Update();
4769 g_pi_manager->NotifyAuiPlugIns();
4772 g_pi_manager->ShowDeferredBlacklistMessages();
4774 g_pi_manager->CallLateInit();
4779 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4780 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4782 if (cc) cc->SetFirstAuto(
true);
4785 b_reloadForPlugins =
true;
4792 if (g_MainToolbar) {
4793 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4794 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4800 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4802 cc->RequestNewCanvasToolbar(
true );
4804 if(cc && cc->GetToolbarEnable()){
4805 cc->GetToolbar()->SetAutoHide(g_bAutoHideToolbar);
4806 cc->GetToolbar()->SetAutoHideTimer(g_nAutoHideToolbar);
4816 pConfig->SetPath(
"/Settings");
4817 pConfig->Read(
"OptionsSizeX", &sx, -1);
4818 pConfig->Read(
"OptionsSizeY", &sy, -1);
4820 wxWindow *optionsParent =
this;
4822 optionsParent = GetPrimaryCanvas();
4824 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4827 BuildiENCToolbar(
true);
4834 if (!g_params.empty()) {
4835 for (
size_t n = 0; n < g_params.size(); n++) {
4836 wxString path = g_params[n];
4837 if (::wxFileExists(path)) {
4839 pSet->load_file(path.fn_str());
4842 pSet->LoadAllGPXObjects(
4843 !pSet->IsOpenCPN(), wpt_dups,
4845 LLBBox box = pSet->GetBBox();
4846 if (box.GetValid()) {
4847 CenterView(GetPrimaryCanvas(), box);
4856 InitAppMsgBusListener();
4864 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4866 PositionIENCToolbar();
4868 g_bDeferredInitDone =
true;
4870 GetPrimaryCanvas()->SetFocus();
4871 g_focusCanvas = GetPrimaryCanvas();
4877 if (b_reloadForPlugins) {
4882 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4884 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4888 cc->CheckGroupValid();
4893 androidEnableBackButton(
true);
4894 androidEnableRotation();
4895 androidEnableOptionItems(
true);
4899 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
4908 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
4910 wxLog::FlushActive();
4912 RefreshAllCanvas(
true);
4913 wxGetApp().m_usb_watcher.Start();
4919void MyFrame::InitAppMsgBusListener() {
4920 auto &msgbus = AppMsgBus::GetInstance();
4923 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4924 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4928 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4929 HandleBasicNavMsg(basicnav_msg);
4933 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4934 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4938 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4939 HandleGPSWatchdogMsg(msg);
4946void MyFrame::ReleaseApiListeners() {}
4951 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4952 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4953 server.SetGetRestApiEndpointCb(
4954 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4955 server.open_file_cb = [](
const std::string &path) {
4956 return wxGetApp().OpenFile(path);
4963void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4964 if (msg->gps_watchdog <= 0) {
4965 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4966 bool last_bGPSValid = bGPSValid;
4969 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4970 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4971 bool last_bVelocityValid = bVelocityValid;
4972 bVelocityValid =
false;
4979void MyFrame::CalculateCOGAverage() {
4981 if (!std::isnan(gCog)) {
4982 if (g_COGAvgSec > 0) {
4984 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4987 double sum = 0., count = 0;
4988 for (
int i = 0; i < g_COGAvgSec; i++) {
4989 double adder = COGTable[i];
4990 if (std::isnan(adder))
continue;
4992 if (fabs(adder - g_COGAvg) > 180.) {
4993 if ((adder - g_COGAvg) > 0.)
5006 else if (sum >= 360.)
5015void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5016 m_fixtime = msg->time;
5017 double hdt_data_interval = 0;
5018 double fix_time_interval = 0;
5020 double msgtime = msg->set_time.tv_sec;
5021 double m1 = msg->set_time.tv_nsec / 1e9;
5024 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5025 ((msg->vflag & POS_VALID) == POS_VALID)) {
5028 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5031 fix_time_gt_last = fix_time_gt;
5032 uint64_t fix_time_gt_now =
5033 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5034 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5038 double implied_sog = dist / (fix_time_interval / 3600);
5043 gLat_gt_m1 = gLat_gt;
5044 gLon_gt_m1 = gLon_gt;
5048 fix_time_gt = fix_time_gt_now;
5052 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5053 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5054 gCog_gt_m1 = gCog_gt;
5064 if (!std::isnan(gCog_gt_m1)) {
5066 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5073 if ((fix_time_gt - fix_time_gt_last) > .08) {
5078 if (gCog_gt > gCog_gt_m1) {
5079 if ((gCog_gt - gCog_gt_m1) > 180.)
5084 if ((gCog_gt_m1 - gCog_gt) > 180.)
5089 difft = fabs(gCog_gt - gCog_gt_m1);
5090 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5098 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5099 tentative_cog_rate_gt *= 1e9;
5100 cog_rate_gt = tentative_cog_rate_gt;
5108 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5111static double hdt_avg;
5112 double hdt_norm = gHdt;
5113 if(gHdt > 180) hdt_norm -= 360;
5116 hdt_avg += hdt_norm * 0.1;
5118 if( gHdt < 0) gHdt += 360.;
5121 if (!std::isnan(gHdt)) {
5123 uint64_t hdt_time_gt_last = hdt_time_gt;
5124 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5125 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5128 if (hdt_data_interval > .09) {
5130 gHdt_gt_m1 = gHdt_gt;
5133 if (!std::isnan(gHdt_gt_m1)) {
5135 double tentative_hdt_rate_gt =
5136 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5137 tentative_hdt_rate_gt *= 1e9;
5139 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5140 hdt_rate_gt = tentative_hdt_rate_gt;
5148 if (std::isnan(gHdt)) gHdt_gt = NAN;
5151 CalculateCOGAverage();
5158 bool last_bGPSValid = bGPSValid;
5159 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5160 if ((msg->vflag & POS_VALID) == POS_VALID)
5165 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5167 bVelocityValid =
true;
5171void MyFrame::UpdateStatusBar() {
5174 unsigned long uiCurrentTickCount;
5175 m_MMEAeventTime.SetToCurrent();
5176 uiCurrentTickCount =
5177 m_MMEAeventTime.GetMillisecond() / 100;
5178 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5179 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5180 m_ulLastNMEATicktime = uiCurrentTickCount;
5182 if (m_tick_idx++ > 6) m_tick_idx = 0;
5187 if (NULL != GetStatusBar()) {
5190 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5193 wxString s1(tick_buf, wxConvUTF8);
5195 s1 += toSDMM(1, gLat);
5197 s1 += toSDMM(2, gLon);
5199 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5203 if (!std::isnan(gSog))
5204 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5207 sogcog.Printf(_T(
"SOG --- "));
5211 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5213 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5215 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5216 (
int)toMagnetic(gCog), 0x00B0);
5218 cogs.Printf((
"COG ---%c"), 0x00B0);
5220 sogcog.Append(cogs);
5221 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5226void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5227 MemFootTimer.Stop();
5229 int memsize = GetApplicationMemoryUse();
5232 printf(
"Memsize: %d \n", memsize);
5235 if (memsize > (g_MemFootMB * 1000)) {
5237 if (ChartData && cc) {
5239 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5240 unsigned int nCache = pCache->GetCount();
5243 for (
unsigned int i = 0; i < nCache; i++) {
5253 for (
unsigned int i = 0; i < nCache - 1; i++) {
5254 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5256 pcea[i] = pcea[i + 1];
5267 unsigned int idelete = 0;
5268 unsigned int idelete_max = pCache->GetCount();
5271 unsigned int minimum_cache = 1;
5272 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5274 while ((memsize > (g_MemFootMB * 1000)) &&
5275 (pCache->GetCount() > minimum_cache) &&
5276 (idelete < idelete_max)) {
5277 int memsizeb = memsize;
5279 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5281 memsize = GetApplicationMemoryUse();
5282 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5290 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5295void MyFrame::CheckToolbarPosition() {
5298 static bool bMaximized;
5300 if (IsMaximized() && !bMaximized) {
5302 if (g_MainToolbar) {
5303 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5304 g_MainToolbar->SetDefaultPosition();
5305 g_MainToolbar->Realize();
5307 PositionIENCToolbar();
5308 }
else if (!IsMaximized() && bMaximized) {
5310 if (g_MainToolbar) {
5311 g_MainToolbar->SetYAuxOffset(0);
5312 g_MainToolbar->SetDockY(-1);
5313 g_MainToolbar->SetDefaultPosition();
5314 g_MainToolbar->Realize();
5316 PositionIENCToolbar();
5321void MyFrame::ProcessUnitTest() {
5322 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5329 cc->m_bFollow =
false;
5330 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5331 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5332 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5335 if (cc->m_groupIndex > 0) {
5336 while (ut_index < ChartData->GetChartTableEntries() &&
5337 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5341 if (ut_index < ChartData->GetChartTableEntries()) {
5343 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5345 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5346 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5353 if (cc->GetQuiltMode()) {
5354 if (cc->IsChartQuiltableRef(ut_index))
5355 cc->SelectQuiltRefdbChart(ut_index);
5357 cc->SelectdbChart(ut_index);
5360 if (g_unit_test_1) {
5368 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5369 cte->GetLatMin(), cte->GetLonMax(), NULL,
5373 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5374 cte->GetLatMax(), cte->GetLonMin(), NULL,
5377 cc->GetSize(&ww, &wh);
5378 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5380 ppm = wxMin(ppm, 1.0);
5387 if (ut_index > ut_index_max) exit(0);
5396void MyFrame::OnFrameTenHzTimer(wxTimerEvent &event) {
5398 bool b_rotate =
false;
5400 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5403 if (!b_rotate && !g_btenhertz)
return;
5405 bool b_update =
false;
5407 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5410 struct timespec now;
5411 clock_gettime(CLOCK_MONOTONIC, &now);
5412 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5413 double diffc = diff / 1e9;
5416 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5417 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5418 if (gCog_tentative < 0.) gCog_tentative += 360.;
5419 gCog = gCog_tentative;
5423 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5424 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5425 double diffc = diff / 1e9;
5426 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5430 if (gSog_gt && !std::isnan(gCog_gt)) {
5431 double delta_t = diffc / 3600;
5432 double distance = gSog_gt * delta_t;
5435 double angr = gCog_gt / 180 * M_PI;
5436 double latr = gLat_gt * M_PI / 180;
5437 double D = distance / 3443;
5438 double sD = sin(D), cD = cos(D);
5439 double sy = sin(latr), cy = cos(latr);
5440 double sa = sin(angr), ca = cos(angr);
5442 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5443 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5453 if (cc) cc->DoCanvasCOGSet();
5464 if (b_rotate || cc->m_bFollow) {
5465 cc->DoCanvasUpdate();
5474 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5477void MyFrame::ProcessQuitFlag() {
5480 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5482 FrameTenHzTimer.Stop();
5489void MyFrame::ProcessDeferredTrackOn() {
5492 if (g_bDeferredStartTrack) {
5493 if (!g_bTrackActive) {
5496 g_bDeferredStartTrack =
false;
5499 g_bDeferredStartTrack =
false;
5504void MyFrame::ProcessAnchorWatch() {
5507 if (pAnchorWatchPoint1) {
5510 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5511 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5512 double d = g_nAWMax;
5513 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5514 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5515 bool toofar =
false;
5516 bool tooclose =
false;
5517 if (d >= 0.0) toofar = (dist * 1852. > d);
5518 if (d < 0.0) tooclose = (dist * 1852 < -d);
5520 if (tooclose || toofar)
5521 AnchorAlertOn1 =
true;
5523 AnchorAlertOn1 =
false;
5525 AnchorAlertOn1 =
false;
5527 if (pAnchorWatchPoint2) {
5530 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5531 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5533 double d = g_nAWMax;
5534 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5535 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5536 bool toofar =
false;
5537 bool tooclose =
false;
5538 if (d >= 0) toofar = (dist * 1852. > d);
5539 if (d < 0) tooclose = (dist * 1852 < -d);
5541 if (tooclose || toofar)
5542 AnchorAlertOn2 =
true;
5544 AnchorAlertOn2 =
false;
5546 AnchorAlertOn2 =
false;
5548 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5549 AnchorAlertOn1 =
true;
5552void MyFrame::SendFixToPlugins() {
5556 GPSData.
kLat = gLat;
5557 GPSData.
kLon = gLon;
5558 GPSData.
kCog = gCog;
5559 GPSData.
kSog = gSog;
5560 GPSData.
kVar = gVar;
5561 GPSData.
kHdm = gHdm;
5562 GPSData.
kHdt = gHdt;
5563 GPSData.
nSats = g_SatsInView;
5565 wxDateTime tCheck((time_t)m_fixtime);
5566 if (tCheck.IsValid()) {
5575 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5578 SendPositionFixToAllPlugIns(&GPSData);
5582void MyFrame::ProcessLogAndBells() {
5585 wxDateTime lognow = wxDateTime::Now();
5586 int hourLOC = lognow.GetHour();
5587 int minuteLOC = lognow.GetMinute();
5589 int minuteUTC = lognow.GetMinute();
5590 int second = lognow.GetSecond();
5592 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5593 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5594 (minuteUTC == 30)) {
5595 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5596 wxString day = lognow.FormatISODate();
5597 wxString utc = lognow.FormatISOTime();
5598 wxString navmsg = _T(
"LOGBOOK: ");
5602 navmsg += _T(
" UTC ");
5606 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5610 if (std::isnan(gCog))
5611 cog.Printf(_T(
"COG ----- "));
5613 cog.Printf(_T(
"COG %10.5f "), gCog);
5616 if (std::isnan(gSog))
5617 sog.Printf(_T(
"SOG ----- "));
5619 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5625 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5628 wxLogMessage(navmsg);
5629 g_loglast_time = lognow;
5631 int bells = (hourLOC % 4) * 2;
5632 if (minuteLOC != 0) bells++;
5633 if (!bells) bells = 8;
5635 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5636 m_BellsToPlay = bells;
5637 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5638 wxPostEvent(
this, ev);
5644void MyFrame::OnFrameTimer1(wxTimerEvent &event) {
5645 CheckToolbarPosition();
5651 if (bDBUpdateInProgress)
return;
5654 FrameTenHzTimer.Stop();
5656 ProcessDeferredTrackOn();
5658 ProcessAnchorWatch();
5659 ProcessLogAndBells();
5661 if (ShouldRestartTrack()) TrackDailyRestart();
5664 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5665 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5666 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5672 if (gSog > 3.0) g_bCruising =
true;
5678 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5679 _T(
" COG ---\u00B0"));
5680 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5686 bool bnew_view =
false;
5687 if (!g_btenhertz) bnew_view = DoChartUpdate();
5692 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5695 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5698 cc->DrawBlinkObjects();
5701 if (bactiveRouteUpdate) {
5703 if (g_pRouteMan->GetpActiveRoute())
5704 cc->RefreshRect(g_blink_rect,
false);
5708 cc->SetOwnShipState(SHIP_NORMAL);
5710 if (cc->GetQuiltMode()) {
5711 double erf = cc->GetQuiltMaxErrorFactor();
5712 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5714 if (cc->m_singleChart) {
5715 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5716 cc->SetOwnShipState(SHIP_LOWACCURACY);
5720 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5722 if ((bGPSValid != m_last_bGPSValid) ||
5723 (bVelocityValid != m_last_bVelocityValid) ||
5724 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5725 if (!g_bopengl) cc->UpdateShips();
5732 m_last_bGPSValid = bGPSValid;
5733 m_last_bVelocityValid = bVelocityValid;
5738 bool brq_dynamic =
false;
5740 auto *pplugin_array = PluginLoader::getInstance()->GetPlugInArray();
5741 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5743 if (pic->m_enabled && pic->m_init_state) {
5744 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5751 if (brq_dynamic) bnew_view =
true;
5755 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5758 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5763 if (cc->GetglCanvas()) {
5765 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5768 if (cc->m_bFollow) {
5769 cc->DoCanvasUpdate();
5776 if (std::isnan(gCog)) cc->Refresh(
false);
5789 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5803 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5804 g_pais_query_dialog_active->UpdateText();
5807 if (g_pAISTargetList && (0 == (g_tick % (5))))
5808 g_pAISTargetList->UpdateAISTargetList();
5811 UpdateGPSCompassStatusBoxes();
5814 if (console && console->IsShown()) {
5816 console->RefreshConsoleData();
5823 if (m_bdefer_resize) {
5824 if (0 == (g_tick % (5))) {
5825 printf(
"___RESIZE\n");
5826 SetSize(m_defer_size);
5827 g_pauimgr->Update();
5828 m_bdefer_resize =
false;
5836 if (((g_tick % g_FlushNavobjChangesTimeout) == 0) || g_FlushNavobjChanges) {
5837 if (pConfig && pConfig->IsChangesFileDirty()) {
5838 androidShowBusyIcon();
5839 wxStopWatch update_sw;
5840 pConfig->UpdateNavObj(
true);
5841 wxString msg = wxString::Format(
5842 _T(
"OpenCPN periodic navobj update took %ld ms."), update_sw.Time());
5844 qDebug() << msg.mb_str();
5845 g_FlushNavobjChanges =
false;
5846 androidHideBusyIcon();
5855 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5857 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5858 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5862double MyFrame::GetMag(
double a,
double lat,
double lon) {
5863 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5864 auto loader = PluginLoader::getInstance();
5865 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5872 wxDateTime now = wxDateTime::Now();
5873 SendJSON_WMM_Var_Request(lat, lon, now);
5874 if (fabs(gQueryVar) < 360.0)
5875 Variance = gQueryVar;
5877 return toMagnetic(a, Variance);
5880bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5886 v[_T(
"Year")] = date.GetYear();
5887 v[_T(
"Month")] = date.GetMonth();
5888 v[_T(
"Day")] = date.GetDay();
5890 SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
5896void MyFrame::TouchAISActive(
void) {
5898 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5900 if (cc) cc->TouchAISToolActive();
5904void MyFrame::UpdateAISTool(
void) {
5905 if (!g_pAIS)
return;
5908 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5910 if (cc) cc->UpdateAISTBTool();
5915void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5917 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5919 if (cc) cc->SetbTCUpdate(
true);
5922 RefreshAllCanvas(
false);
5927void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5931 bool b_rotate =
false;
5932 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5934 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5938 FrameCOGTimer.Stop();
5945 int period_ms = 100;
5947 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5950void MyFrame::DoCOGSet(
void) {
5952 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5954 if (cc) cc->DoCanvasCOGSet();
5958void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5964 wxFont oldfont = pdc->GetFont();
5966 pdc->SetFont(*pFont);
5967 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
5968 pdc->SetBackgroundMode(wxTRANSPARENT);
5970 pdc->DrawText(str, x, y + 1);
5971 pdc->DrawText(str, x, y - 1);
5972 pdc->DrawText(str, x + 1, y);
5973 pdc->DrawText(str, x - 1, y);
5975 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
5977 pdc->DrawText(str, x, y);
5979 pdc->SetFont(oldfont);
5983void MyFrame::UpdateRotationState(
double rotation) {
5985 g_bCourseUp =
false;
5987 if (fabs(rotation) > .001) {
5988 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5989 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5991 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5994 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5995 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5997 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6001 UpdateGPSCompassStatusBoxes(
true);
6005void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6007 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6009 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6015int MyFrame::GetApplicationMemoryUse(
void) {
6021 wxWindow *fWin = wxWindow::FindFocus();
6023 wxArrayString outputArray;
6024 wxString cmd(_T(
"ps --no-headers -o vsize "));
6025 unsigned long pid = wxGetProcessId();
6027 cmd1.Printf(_T(
"%ld"), pid);
6029 wxExecute(cmd, outputArray);
6031 if (outputArray.GetCount()) {
6032 wxString s = outputArray.Item(0);
6034 if (s.ToLong(&vtmp)) memsize = vtmp;
6037 if (fWin) fWin->SetFocus();
6043 PROCESS_MEMORY_COUNTERS pmc;
6045 unsigned long processID = wxGetProcessId();
6047 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6049 if (NULL == hProcess)
return 0;
6051 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6069 memsize = pmc.WorkingSetSize / 1024;
6072 CloseHandle(hProcess);
6079double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6080 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6083void MyFrame::SetChartUpdatePeriod() {
6086 g_ChartUpdatePeriod = 0;
6091 bool bskewdc =
false;
6092 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6095 if (!g_bopengl && !cc->GetVP().b_quilt) {
6096 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6098 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6102 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6104 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6109 cc->UpdateCanvasControlBar();
6112void MyFrame::selectChartDisplay(
int type,
int family) {
6114 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6116 if (cc) cc->selectCanvasChartDisplay(type, family);
6119 UpdateGlobalMenuItems();
6128bool MyFrame::DoChartUpdate(
void) {
6129 bool return_val =
false;
6132 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6134 if (cc) return_val |= cc->DoCanvasUpdate();
6140void MyFrame::MouseEvent(wxMouseEvent &event) {
6142 event.GetPosition(&x, &y);
6147#include <mach/mach.h>
6148#include <mach/message.h>
6149#include <mach/kern_return.h>
6150#include <mach/task_info.h>
6152#include <malloc/malloc.h>
6159#if defined(__linux__)
6160#include "sys/types.h"
6161#include "sys/sysinfo.h"
6164int g_lastMemTick = -1;
6168bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6170 return androidGetMemoryStatus(mem_total, mem_used);
6173#if defined(__linux__)
6177 struct sysinfo sys_info;
6178 if (sysinfo(&sys_info) != -1)
6179 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6193 FILE *file = fopen(
"/proc/self/statm",
"r");
6195 if (fscanf(file,
"%d", mem_used) != 1) {
6196 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6209 PROCESS_MEMORY_COUNTERS pmc;
6211 unsigned long processID = wxGetProcessId();
6214 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6217 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6235 *mem_used = pmc.WorkingSetSize / 1024;
6238 CloseHandle(hProcess);
6242 MEMORYSTATUSEX statex;
6244 statex.dwLength =
sizeof(statex);
6246 GlobalMemoryStatusEx(&statex);
6264 *mem_total = statex.ullTotalPhys / 1024;
6271 if (g_tick != g_lastMemTick) {
6272 malloc_zone_pressure_relief(NULL, 0);
6275 int blocksInUse = 0;
6276 int sizeAllocated = 0;
6278 malloc_statistics_t stats;
6279 stats.blocks_in_use = 0;
6280 stats.size_in_use = 0;
6281 stats.max_size_in_use = 0;
6282 stats.size_allocated = 0;
6283 malloc_zone_statistics(NULL, &stats);
6284 bytesInUse += stats.size_in_use;
6285 blocksInUse += stats.blocks_in_use;
6286 sizeAllocated += stats.size_allocated;
6288 g_memUsed = sizeAllocated >> 10;
6291 g_lastMemTick = g_tick;
6294 if (mem_used) *mem_used = g_memUsed;
6297 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6299 double pagesUsed = 0.0, totalPages = 0.0;
6301 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6302 *mem_total = atol(buf) >> 10;
6310 if (mem_used) *mem_used = 0;
6311 if (mem_total) *mem_total = 0;
6315void MyFrame::DoPrint(
void) {
6317 g_PrintingInProgress =
true;
6320 GetPrimaryCanvas()->GetglCanvas()->Render();
6321 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6331 printer.Initialize(wxLANDSCAPE);
6332 printer.EnablePageNumbers(
false);
6333 printer.Print(
this, &printout);
6351 g_PrintingInProgress =
false;
6354 GetPrimaryCanvas()->SetFocus();
6359wxDateTime gTimeSource;
6362 wxString message_ID =
event.GetID();
6363 wxString message_JSONText =
event.GetJSONText();
6371 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6379 int numErrors = reader.
Parse(message_JSONText, &root);
6380 if (numErrors > 0) {
6386 wxString decl = root[_T(
"Decl")].
AsString();
6388 decl.ToDouble(&decl_val);
6394 if (message_ID == _T(
"WMM_VARIATION")) {
6402 int numErrors = reader.
Parse(message_JSONText, &root);
6403 if (numErrors > 0) {
6409 wxString decl = root[_T(
"Decl")].
AsString();
6411 decl.ToDouble(&decl_val);
6413 gQueryVar = decl_val;
6416 if (message_ID == _T(
"GRIB_TIMELINE")) {
6419 r.
Parse(message_JSONText, &v);
6420 if (v[_T(
"Day")].AsInt() == -1)
6421 gTimeSource = wxInvalidDateTime;
6423 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6424 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6425 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6426 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6428 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6431 wxString trk_id = wxEmptyString;
6433 int numErrors = reader.
Parse(message_JSONText, &root);
6434 if (numErrors > 0)
return;
6437 trk_id = root[_T(
"Track_ID")].
AsString();
6440 v[_T(
"Track_ID")] = trk_id;
6441 for (
Track *ptrack : g_TrackList) {
6442 wxString name = wxEmptyString;
6443 if (ptrack->m_GUID == trk_id) {
6444 name = ptrack->GetName();
6445 if (name.IsEmpty()) {
6447 if (rp && rp->GetCreateTime().IsValid())
6448 name = rp->GetCreateTime().FormatISODate() + _T(
" ") +
6449 rp->GetCreateTime().FormatISOTime();
6451 name = _(
"(Unnamed Track)");
6457 v[_T(
"error")] =
false;
6458 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6459 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6461 v[_T(
"lat")] = tp->m_lat;
6462 v[_T(
"lon")] = tp->m_lon;
6463 v[_T(
"NodeNr")] = i;
6465 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6466 SendJSONMessageToAllPlugins(msg_id, v);
6470 v[_T(
"error")] =
true;
6472 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6473 SendJSONMessageToAllPlugins(msg_id, v);
6475 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6478 wxString guid = wxEmptyString;
6480 int numErrors = reader.
Parse(message_JSONText, &root);
6481 if (numErrors > 0) {
6488 v[_T(
"GUID")] = guid;
6489 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6491 wxString name = wxEmptyString;
6493 if ((*it)->m_GUID == guid) {
6494 name = (*it)->m_RouteNameString;
6495 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6497 v[_T(
"Name")] = name;
6498 v[_T(
"error")] =
false;
6501 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6502 itp != (*it)->pRoutePointList->end(); itp++) {
6503 w[i][_T(
"lat")] = (*itp)->m_lat;
6504 w[i][_T(
"lon")] = (*itp)->m_lon;
6505 w[i][_T(
"Name")] = (*itp)->GetName();
6506 w[i][_T(
"Description")] = (*itp)->GetDescription();
6507 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6508 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6509 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6514 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6516 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6517 httpLink->DescrText;
6518 node = node->GetNext();
6523 v[_T(
"waypoints")] = w;
6524 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6525 SendJSONMessageToAllPlugins(msg_id, v);
6530 v[_T(
"error")] =
true;
6532 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6533 SendJSONMessageToAllPlugins(msg_id, v);
6534 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6539 int numErrors = reader.
Parse(message_JSONText, &root);
6540 if (numErrors > 0)
return;
6543 wxString str = root[_T(
"mode")].
AsString();
6544 if (str == _T(
"Track")) route =
false;
6549 for (RouteList::iterator it = pRouteList->begin();
6550 it != pRouteList->end(); it++) {
6551 wxString name = (*it)->m_RouteNameString;
6552 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6554 v[i][_T(
"error")] =
false;
6555 v[i][_T(
"name")] = name;
6556 v[i][_T(
"GUID")] = (*it)->m_GUID;
6557 v[i][_T(
"active")] = (*it)->IsActive();
6561 for (
Track *ptrack : g_TrackList) {
6562 wxString name = ptrack->GetName();
6563 if (name.IsEmpty()) {
6565 if (tp && tp->GetCreateTime().IsValid())
6566 name = tp->GetCreateTime().FormatISODate() + _T(
" ") +
6567 tp->GetCreateTime().FormatISOTime();
6569 name = _(
"(Unnamed Track)");
6571 v[i][_T(
"error")] =
false;
6572 v[i][_T(
"name")] = name;
6573 v[i][_T(
"GUID")] = ptrack->m_GUID;
6574 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6578 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6579 SendJSONMessageToAllPlugins(msg_id, v);
6582 v[0][_T(
"error")] =
true;
6583 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6584 SendJSONMessageToAllPlugins(msg_id, v);
6586 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6588 v[0][_T(
"error")] =
true;
6589 if (g_pRouteMan->GetpActiveRoute()) {
6590 if (g_pRouteMan->m_bDataValid) {
6591 v[0][_T(
"error")] =
false;
6592 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6593 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6594 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6595 v[0][_T(
"active_route_GUID")] =
6596 g_pRouteMan->GetpActiveRoute()->GetGUID();
6597 v[0][_T(
"active_waypoint_lat")] =
6598 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLatitude();
6599 v[0][_T(
"active_waypoint_lon")] =
6600 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLongitude();
6603 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6604 SendJSONMessageToAllPlugins(msg_id, v);
6608void MyFrame::FilterCogSog(
void) {
6609 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6611 double cog_last = gCog;
6614 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6615 COGFilterTable[i] = COGFilterTable[i - 1];
6616 COGFilterTable[0] = cog_last;
6619 if (!std::isnan(cog_last)) {
6621 double sum = 0., count = 0;
6622 for (
int i = 0; i < g_COGFilterSec; i++) {
6623 double adder = COGFilterTable[i];
6624 if (std::isnan(adder))
continue;
6626 if (fabs(adder - cog_last) > 180.) {
6627 if ((adder - cog_last) > 0.)
6640 else if (sum >= 360.)
6647 double sog_last = gSog;
6650 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6651 SOGFilterTable[i] = SOGFilterTable[i - 1];
6652 SOGFilterTable[0] = sog_last;
6655 if (!std::isnan(gSog)) {
6656 double sum = 0., count = 0;
6657 for (
int i = 0; i < g_SOGFilterSec; i++) {
6658 if (std::isnan(SOGFilterTable[i]))
continue;
6660 sum += SOGFilterTable[i];
6670void MyFrame::LoadHarmonics() {
6673 ptcmgr->LoadDataSources(TideCurrentDataSet);
6675 bool b_newdataset =
false;
6678 for (
auto a : ptcmgr->GetDataSet()) {
6679 bool b_foundi =
false;
6680 for (
auto b : TideCurrentDataSet) {
6687 b_newdataset =
true;
6692 for (
auto a : TideCurrentDataSet) {
6693 bool b_foundi =
false;
6694 for (
auto b : ptcmgr->GetDataSet()) {
6701 b_newdataset =
true;
6706 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6710void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6711 if (!ptarget)
return;
6714 wxDateTime mob_time = wxDateTime::Now();
6715 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6716 mob_label += _(
" on ");
6717 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6720 mob_label, wxEmptyString);
6721 pWP_MOB->SetShared(
true);
6723 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6724 pConfig->AddNewWayPoint(pWP_MOB, -1);
6725 pWP_MOB->SetUseSca(
false);
6733 wxString(_(
"Own ship")), wxEmptyString);
6734 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6735 pWP_MOB->SetUseSca(
false);
6736 pAISMOBRoute =
new Route();
6737 pRouteList->Append(pAISMOBRoute);
6739 pAISMOBRoute->AddPoint(pWP_src);
6740 pAISMOBRoute->AddPoint(pWP_MOB);
6742 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6743 pWP_src, pWP_MOB, pAISMOBRoute);
6745 pAISMOBRoute->m_RouteNameString = _(
"Temporary AISMOB Route");
6746 pAISMOBRoute->m_RouteStartString = _(
"Present own ship");
6747 pAISMOBRoute->m_RouteEndString = mob_label;
6749 pAISMOBRoute->m_bDeleteOnArrival =
false;
6751 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6753 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6757 v[_T(
"GUID")] = pAISMOBRoute->m_GUID;
6758 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6759 SendJSONMessageToAllPlugins(msg_id, v);
6762 if (RouteManagerDialog::getInstanceFlag()) {
6763 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6764 pRouteManagerDialog->UpdateRouteListCtrl();
6765 pRouteManagerDialog->UpdateWptListCtrl();
6769 RefreshAllCanvas(
false);
6771 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6772 mob_message += _(
" Time: ");
6773 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6774 mob_message += _(
" Ownship Position: ");
6775 mob_message += toSDMM(1, gLat);
6776 mob_message += _T(
" ");
6777 mob_message += toSDMM(2, gLon);
6778 mob_message += _(
" MOB Position: ");
6779 mob_message += toSDMM(1, ptarget->Lat);
6780 mob_message += _T(
" ");
6781 mob_message += toSDMM(2, ptarget->Lon);
6782 wxLogMessage(mob_message);
6785void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6786 if (pAISMOBRoute && ptarget) {
6788 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6789 OwnPoint->m_lat = gLat;
6790 OwnPoint->m_lon = gLon;
6792 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6793 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6796 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6797 MOB_Point->m_lat = ptarget->Lat;
6798 MOB_Point->m_lon = ptarget->Lon;
6800 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6801 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6803 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6804 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6807 RefreshAllCanvas(
false);
6810 wxDateTime mob_time = wxDateTime::Now();
6812 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6813 mob_message += _(
" Time: ");
6814 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6815 mob_message += _(
" Ownship Position: ");
6816 mob_message += toSDMM(1, gLat);
6817 mob_message += _T(
" ");
6818 mob_message += toSDMM(2, gLon);
6819 mob_message += _(
" MOB Position: ");
6820 mob_message += toSDMM(1, ptarget->Lat);
6821 mob_message += _T(
" ");
6822 mob_message += toSDMM(2, ptarget->Lon);
6824 wxLogMessage(mob_message);
6828void MyFrame::applySettingsString(wxString settings) {
6830 int last_UIScaleFactor = g_GUIScaleFactor;
6831 bool previous_expert = g_bUIexpert;
6832 g_last_ChartScaleFactor = g_ChartScaleFactor;
6833 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6836 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6839 pConfig->UpdateSettings();
6842 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6844 if (rr & S52_CHANGED) {
6846 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6848 ->ClearCNSYLUPArray();
6849 ps52plib->GenerateStateHash();
6853 ProcessOptionsDialog(rr, pNewDirArray);
6858 bool b_newToolbar =
false;
6860 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6862 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6864 if (rr & TOOLBAR_CHANGED) {
6865 b_newToolbar =
true;
6870 if (previous_expert && !g_bUIexpert) {
6871 androidForceFullRepaint();
6875 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6879 SetGPSCompassScale();
6881 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6883 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6885 UpdateGPSCompassStatusBoxes(
true);
6888 AbstractPlatform::ShowBusySpinner();
6890 SetAllToolbarScale();
6894 AbstractPlatform::HideBusySpinner();
6896 RequestNewMasterToolbar(
true);
6903 UpdateControlBar(GetPrimaryCanvas());
6906 if (console) console->Raise();
6910 if (NMEALogWindow::GetInstance().Active())
6911 NMEALogWindow::GetInstance().GetTTYWindow()->Raise();
6914#ifdef wxHAS_POWER_EVENTS
6915void MyFrame::OnSuspending(wxPowerEvent &event) {
6919 wxLogMessage(_T(
"System suspend starting..."));
6922void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6925 wxLogMessage(_T(
"System is going to suspend."));
6928void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6931 wxLogMessage(_T(
"System suspend was cancelled."));
6934int g_last_resume_ticks;
6935void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6936 wxDateTime now = wxDateTime::Now();
6937 wxLogMessage(_T(
"System resumed from suspend."));
6939 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6942 wxLogMessage(
"Restarting streams.");
6943 g_last_resume_ticks = now.GetTicks();
6947 g_pMUX->ClearStreams();
6949 g_pMUX->StartAllStreams();
6958 if (IsMaximized()) {
6963 wxSize sz = GetSize();
6964 SetSize(wxSize(sz.x - 1, sz.y));
6976void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6977 bool btbRebuild =
false;
6979 bool b_reshow =
true;
6980 if (g_MainToolbar) {
6982 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6983 if ((ff > 0.01f) || bforcenew) {
6984 g_MainToolbar->DestroyToolBar();
6985 delete g_MainToolbar;
6986 g_MainToolbar = NULL;
6992 if (!g_MainToolbar) {
6993 long orient = g_Platform->GetDefaultToolbarOrientation();
6994 wxWindow *toolbarParent =
this;
6996 toolbarParent = GetPrimaryCanvas();
6999 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7000 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
7001 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7002 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7003 g_MainToolbar->EnableRolloverBitmaps(
false);
7005 g_MainToolbar->CreateConfigMenu();
7006 g_MainToolbar->SetDefaultPosition();
7008 g_bmasterToolbarFull =
true;
7011 if (g_MainToolbar) {
7012 CreateMasterToolbar();
7016 g_MainToolbar->SetColorScheme(global_color_scheme);
7022 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7023 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7027bool MyFrame::CollapseGlobalToolbar() {
7028 if (g_MainToolbar) {
7029 m_nMasterToolCountShown = 1;
7030 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7031 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7032 g_MainToolbar->Realize();
7033 g_bmasterToolbarFull =
false;
7042 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7049 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7050 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7051 tic->m_bRequired =
true;
7053 g_MainToolbar->AddToolItem(tic);
7056 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7057 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7058 g_MainToolbar->AddToolItem(tic);
7061 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7062 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7063 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7065 g_MainToolbar->AddToolItem(tic);
7068 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7069 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7070 g_MainToolbar->AddToolItem(tic);
7073 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7074 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7075 _(
"Enable Tracking"), _T(
"MUI_track"));
7076 g_MainToolbar->AddToolItem(tic);
7079 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7080 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7081 g_MainToolbar->AddToolItem(tic);
7092 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7093 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7094 g_MainToolbar->AddToolItem(tic);
7097 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7098 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7099 g_MainToolbar->AddToolItem(tic);
7102 AddDefaultPositionPlugInTools();
7106 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7107 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7108 g_MainToolbar->AddToolItem(tic);
7111 g_MainToolbar->RebuildToolbar();
7115 g_MainToolbar->Realize();
7118 ArrayOfPlugInToolbarTools tool_array =
7119 g_pi_manager->GetPluginToolbarToolArray();
7120 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7122 if (!pttc->b_viz)
continue;
7124 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7127 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7128 if (g_bTrackActive) {
7129 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7131 g_MainToolbar->Realize();
7136bool MyFrame::CheckAndAddPlugInTool() {
7137 if (!g_pi_manager)
return false;
7142 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7144 if (!tb)
return false;
7146 int n_tools = tb->GetToolsCount();
7150 ArrayOfPlugInToolbarTools tool_array =
7151 g_pi_manager->GetPluginToolbarToolArray();
7153 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7155 if (pttc->position == n_tools) {
7156 wxBitmap *ptool_bmp;
7158 switch (global_color_scheme) {
7159 case GLOBAL_COLOR_SCHEME_DAY:
7160 ptool_bmp = pttc->bitmap_day;
7163 case GLOBAL_COLOR_SCHEME_DUSK:
7164 ptool_bmp = pttc->bitmap_dusk;
7166 case GLOBAL_COLOR_SCHEME_NIGHT:
7167 ptool_bmp = pttc->bitmap_night;
7170 ptool_bmp = pttc->bitmap_day;
7175 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7177 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7178 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7179 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7180 tic->m_bPlugin =
true;
7189 while (CheckAndAddPlugInTool()) {
7195bool MyFrame::AddDefaultPositionPlugInTools() {
7196 if (!g_pi_manager)
return false;
7202 ArrayOfPlugInToolbarTools tool_array =
7203 g_pi_manager->GetPluginToolbarToolArray();
7205 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7209 if (!pttc->b_viz)
continue;
7211 if (pttc->position == -1)
7213 wxBitmap *ptool_bmp;
7215 switch (global_color_scheme) {
7216 case GLOBAL_COLOR_SCHEME_DAY:
7217 ptool_bmp = pttc->bitmap_day;
7219 case GLOBAL_COLOR_SCHEME_DUSK:
7220 ptool_bmp = pttc->bitmap_dusk;
7222 case GLOBAL_COLOR_SCHEME_NIGHT:
7223 ptool_bmp = pttc->bitmap_night;
7226 ptool_bmp = pttc->bitmap_day;
7231 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7233 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7234 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7235 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7236 tic->m_bPlugin =
true;
7238 g_MainToolbar->AddToolItem(tic);
7251wxColour GetGlobalColor(wxString colorName);
7253static const char *usercolors[] = {
7254 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7255 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7256 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7257 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7258 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7259 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7260 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7262 "DILG0; 255;255;255;",
7264 "DILG0; 238;239;242;",
7266 "DILG1; 212;208;200;",
7267 "DILG2; 255;255;255;",
7271 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7272 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7273 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7275 "UDKRD; 124; 16; 0;",
7276 "UARTE; 200; 0; 0;",
7278 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7279 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7280 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7281 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7283 "DASHB; 255;255;255;",
7284 "DASHL; 175;175;175;",
7285 "DASHF; 50; 50; 50;",
7286 "DASHR; 200; 0; 0;",
7288 "DASHN; 200;120; 0;",
7289 "DASH1; 204;204;255;",
7290 "DASH2; 122;131;172;",
7291 "COMP1; 211;211;211;",
7293 "GREY3; 40; 40; 40;",
7294 "BLUE4; 100;100;200;",
7295 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7296 "BLUEBACK; 212;234;238;",
7297 "LANDBACK; 201;185;122;",
7300 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7301 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7302 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7303 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7304 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7305 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7306 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7308 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7309 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7310 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7312 "DILG0; 110;110;110;",
7313 "DILG1; 110;110;110;",
7315 "DILG3; 130;130;130;",
7316 "UITX1; 41; 46; 46;",
7318 "UARTE; 64; 64; 64;",
7320 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7321 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7322 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7323 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7325 "DASHB; 77; 77; 77;",
7326 "DASHL; 54; 54; 54;",
7328 "DASHR; 58; 21; 21;",
7329 "DASHG; 21; 58; 21;",
7330 "DASHN; 100; 50; 0;",
7331 "DASH1; 76; 76;113;",
7332 "DASH2; 48; 52; 72;",
7333 "COMP1; 107;107;107;",
7335 "GREY3; 20; 20; 20;",
7336 "BLUE4; 80; 80;160;",
7337 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7338 "LANDBACK; 201;185;122;",
7340 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7341 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7342 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7343 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7344 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7345 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7346 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7347 "DILG0; 80; 80; 80;",
7348 "DILG1; 80; 80; 80;",
7350 "DILG3; 65; 65; 65;",
7351 "UITX1; 31; 34; 35;",
7353 "UARTE; 64; 64; 64;",
7355 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7356 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7357 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7359 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7360 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7361 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7362 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7365 "DASHL; 20; 20; 20;",
7366 "DASHF; 64; 64; 64;",
7367 "DASHR; 70; 15; 15;",
7368 "DASHG; 15; 70; 15;",
7369 "DASHN; 17; 80; 56;",
7370 "DASH1; 48; 52; 72;",
7371 "DASH2; 36; 36; 53;",
7372 "COMP1; 24; 24; 24;",
7374 "GREY3; 10; 10; 10;",
7375 "BLUE4; 70; 70;140;",
7376 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7377 "LANDBACK; 201;185;122;",
7381int get_static_line(
char *d,
const char **p,
int index,
int n) {
7382 if (!strcmp(p[index],
"*****"))
return 0;
7384 strncpy(d, p[index], n);
7388void InitializeUserColors(
void) {
7389 const char **p = usercolors;
7397 UserColorTableArray =
new wxArrayPtrVoid;
7398 UserColourHashTableArray =
new wxArrayPtrVoid;
7402 ct->tableName =
new wxString(_T(
"DAY"));
7403 ct->color =
new wxArrayPtrVoid;
7404 UserColorTableArray->Add((
void *)ct);
7407 ct->tableName =
new wxString(_T(
"DUSK"));
7408 ct->color =
new wxArrayPtrVoid;
7409 UserColorTableArray->Add((
void *)ct);
7412 ct->tableName =
new wxString(_T(
"NIGHT"));
7413 ct->color =
new wxArrayPtrVoid;
7414 UserColorTableArray->Add((
void *)ct);
7416 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7417 if (!strncmp(buf,
"Table", 5)) {
7418 sscanf(buf,
"Table:%s", TableName);
7420 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7421 ctp = (colTable *)(UserColorTableArray->Item(it));
7422 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7431 while (buf[j] !=
';' && j < 20) {
7437 S52color *c =
new S52color;
7438 strcpy(c->colName, name);
7440 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7453 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7454 wxColorHashMap *phash =
new wxColorHashMap;
7455 UserColourHashTableArray->Add((
void *)phash);
7457 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7459 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7460 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7462 wxColour c(c2->R, c2->G, c2->B);
7463 wxString key(c2->colName, wxConvUTF8);
7470 pcurrent_user_color_hash =
7471 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7474void DeInitializeUserColors(
void) {
7475 if (!UserColorTableArray)
return;
7476 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7477 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7479 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7480 S52color *c = (S52color *)ct->color->Item(j);
7484 delete ct->tableName;
7490 delete UserColorTableArray;
7492 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7493 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7497 delete UserColourHashTableArray;
7504typedef struct _MSW_COLOR_SPEC {
7506 wxString S52_RGB_COLOR;
7510MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7511 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7512 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7515void SaveSystemColors() {
7529 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7530 while (pcspec->COLOR_NAME != -1) {
7531 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7536void RestoreSystemColors() {
7537 int element[NCOLORS];
7538 int rgbcolor[NCOLORS];
7541 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7542 while (pcspec->COLOR_NAME != -1) {
7543 element[i] = pcspec->COLOR_NAME;
7544 rgbcolor[i] = pcspec->SysRGB_COLOR;
7550 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7555void SetSystemColors(ColorScheme cs) {
7557 int element[NCOLORS];
7558 int rgbcolor[NCOLORS];
7560 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7561 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7562 while (pcspec->COLOR_NAME != -1) {
7563 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7564 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7565 element[i] = pcspec->COLOR_NAME;
7571 pSetSysColors(i, (
unsigned long *)&element[0],
7572 (
unsigned long *)&rgbcolor[0]);
7576 RestoreSystemColors();
7581wxColor GetDimColor(wxColor c) {
7582 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7583 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7587 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7588 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7590 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7591 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7592 hsv.value = hsv.value * factor;
7593 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7595 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7601double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7602 double const AnchorPointMaxDist)
7605 if (d < AnchorPointMinDist)
7606 return AnchorPointMinDist;
7607 else if (d > AnchorPointMaxDist)
7608 return AnchorPointMaxDist;
7614 if (d > -AnchorPointMinDist)
7615 return -AnchorPointMinDist;
7616 else if (d < -AnchorPointMaxDist)
7617 return -AnchorPointMaxDist;
7624static const WORD MAX_CONSOLE_LINES =
7629void RedirectIOToConsole()
7634 wxIntPtr lStdHandle;
7636 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7646 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7647 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7648 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7652 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7653 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7654 fp = _fdopen(hConHandle,
"w");
7656 setvbuf(stdout, NULL, _IONBF, 0);
7660 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7661 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7662 fp = _fdopen(hConHandle,
"r");
7664 setvbuf(stdin, NULL, _IONBF, 0);
7668 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7669 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7670 fp = _fdopen(hConHandle,
"w");
7672 setvbuf(stderr, NULL, _IONBF, 0);
7684bool TestGLCanvas(wxString prog_dir) {
7686 wxString test_app = prog_dir;
7687 test_app += _T(
"ocpn_gltest1.exe");
7689 if (::wxFileExists(test_app)) {
7690 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7691 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7692 if (proc_return == 0)
7693 printf(
"GLCanvas OK\n");
7695 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7697 return (proc_return == 0);
7707bool ReloadLocale() {
7712 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7719 FontMgr::Get().SetLocale(g_locale);
7727 if (pRoutePropDialog) {
7728 pRoutePropDialog->Hide();
7729 pRoutePropDialog->Destroy();
7730 pRoutePropDialog = NULL;
7733 if (pRouteManagerDialog) {
7734 pRouteManagerDialog->Hide();
7735 pRouteManagerDialog->Destroy();
7736 pRouteManagerDialog = NULL;
7739 if (console) console->SetColorScheme(global_color_scheme);
7740 if (g_pais_query_dialog_active) {
7741 g_pais_query_dialog_active->Destroy();
7742 g_pais_query_dialog_active = NULL;
7745 auto alert_dlg_active =
7747 if (alert_dlg_active) {
7748 alert_dlg_active->Destroy();
7749 g_pais_alert_dialog_active =
nullptr;
7752 if (g_pAISTargetList) {
7753 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7754 g_pAISTargetList->Disconnect_decoder();
7755 g_pAISTargetList->Destroy();
7756 g_pAISTargetList = NULL;
7760 if (gFrame->m_pMenuBar) {
7761 gFrame->SetMenuBar(NULL);
7762 gFrame->m_pMenuBar->Destroy();
7763 gFrame->m_pMenuBar = NULL;
7765 gFrame->BuildMenuBar();
7768 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7770 if (cc) cc->CanvasApplyLocale();
7775 wxString perspective;
7776 pConfig->SetPath(_T (
"/AUI" ));
7777 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7782 PluginLoader::getInstance()->DeactivateAllPlugIns();
7783 PluginLoader::getInstance()->UpdatePlugIns();
7791 bool bno_load =
false;
7792 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7794 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7795 wxAuiPaneInfo pane = pane_array_val[i];
7796 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7802 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7804 g_pauimgr->Update();
7807 gFrame->RequestNewToolbars(
true);
7808 gFrame->RequestNewMasterToolbar(
true);
7812extern s57RegistrarMgr *m_pRegistrarMan;
7813extern wxString g_UserPresLibData;
7814extern wxString g_SENCPrefix;
7815extern wxString g_csv_locn;
7831 g_csv_locn = g_Platform->GetSharedDataDir();
7832 g_csv_locn.Append(_T(
"s57data"));
7835 g_csv_locn = _T(
".");
7836 appendOSDirSlash(&g_csv_locn);
7837 g_csv_locn.Append(_T(
"s57data"));
7842 if (g_SENCPrefix.IsEmpty()) {
7844 appendOSDirSlash(&g_SENCPrefix);
7845 g_SENCPrefix.Append(_T(
"SENC"));
7849 wxFileName f(g_SENCPrefix);
7851 g_SENCPrefix = f.GetFullPath();
7853 g_SENCPrefix = _T(
"SENC");
7859 bool b_force_legacy =
false;
7861 if (g_UserPresLibData.IsEmpty()) {
7862 plib_data = g_csv_locn;
7863 appendOSDirSlash(&plib_data);
7864 plib_data.Append(_T(
"S52RAZDS.RLE"));
7866 plib_data = g_UserPresLibData;
7867 b_force_legacy =
true;
7870 ps52plib =
new s52plib(plib_data, b_force_legacy);
7885 if (!ps52plib->m_bOK) {
7888 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7890 wxString look_data_dir;
7891 look_data_dir.Append(std_path.GetUserDataDir());
7892 appendOSDirSlash(&look_data_dir);
7893 wxString tentative_SData_Locn = look_data_dir;
7894 look_data_dir.Append(_T(
"s57data"));
7896 plib_data = look_data_dir;
7897 appendOSDirSlash(&plib_data);
7898 plib_data.Append(_T(
"S52RAZDS.RLE"));
7900 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7901 ps52plib =
new s52plib(plib_data);
7903 if (ps52plib->m_bOK) {
7904 g_csv_locn = look_data_dir;
7913 if (!ps52plib->m_bOK) {
7916 wxString look_data_dir;
7917 look_data_dir = g_Platform->GetSharedDataDir();
7918 look_data_dir.Append(_T(
"s57data"));
7920 plib_data = look_data_dir;
7921 appendOSDirSlash(&plib_data);
7922 plib_data.Append(_T(
"S52RAZDS.RLE"));
7924 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7925 ps52plib =
new s52plib(plib_data);
7927 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7930 if (ps52plib->m_bOK) {
7931 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
7933 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7938 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7940 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7941 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7942 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7943 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7946 pConfig->LoadS57Config();
7947 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7950 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
7951 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
7953 ps52plib->SetDIPFactor(dip_factor);
7958 ps52plib->SetScaleFactorExp(
7959 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7960 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7965 extern bool g_b_EnableVBO;
7966 extern GLenum g_texture_rectangle_format;
7971 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7972 ps52plib->SetGLRendererString(renderer);
7975 ps52plib->SetGLOptions(
7976 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7977 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7978 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7984 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
7993 : wxThread(wxTHREAD_JOINABLE) {
7994 m_filename = filename;
8005 newChart->SetNativeScale(m_scale);
8006 newChart->SetFullExtent(m_ext);
8008 newChart->FindOrCreateSenc(m_filename);
8013 wxString m_filename;
8019static double chart_dist(
int index) {
8025 if (cte.GetBBox().Contains(gLat, gLon))
8030 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8031 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8032 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8035 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8036 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8038 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8044WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8045static int CompareInts(
int n1,
int n2) {
8046 double d1 = chart_dist(n1);
8047 double d2 = chart_dist(n2);
8048 return (
int)(d1 - d2);
8053 wxString chart_path;
8058WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8060#include <wx/arrimpl.cpp>
8063void ParseAllENC(wxWindow *parent) {
8064 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8072 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8075 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8077 idx_sorted_by_distance.Add(i);
8081 if (count == 0)
return;
8083 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8089 ArrayOfCompressTargets ct_array;
8090 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8091 int i = idx_sorted_by_distance[j];
8094 double distance = chart_dist(i);
8096 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8099 pct->distance = distance;
8100 pct->chart_path = filename;
8102 ct_array.push_back(pct);
8105 int thread_count = 0;
8108 extern int g_nCPUCount;
8109 if (g_nCPUCount > 0)
8110 thread_count = g_nCPUCount;
8112 thread_count = wxThread::GetCPUCount();
8114 if (thread_count < 1) {
8123 for(
int t = 0; t < thread_count; t++)
8127 wxGenericProgressDialog *prog =
nullptr;
8131 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8132 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8134 prog =
new wxGenericProgressDialog();
8136 prog->SetFont(*qFont);
8138 prog->Create(_(
"OpenCPN ENC Prepare"),
8139 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8149 prog->ShowWindowModal();
8158 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8159 wxString filename = ct_array[j].chart_path;
8160 double distance = ct_array[j].distance;
8161 int index = ChartData->FinddbIndex(filename);
8162 if (index < 0)
continue;
8165 ext.NLAT = cte.GetLatMax();
8166 ext.SLAT = cte.GetLatMin();
8167 ext.WLON = cte.GetLonMin();
8168 ext.ELON = cte.GetLonMax();
8170 int scale = cte.GetScale();
8173 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8176 if (wxThread::IsMain()) {
8178 wxSize sz = prog->GetSize();
8180 msg += _T(
" Chart:");
8183 prog->Update(count, msg, &skip);
8195 newChart->SetNativeScale(
scale);
8196 newChart->SetFullExtent(ext);
8197 newChart->DisableBackgroundSENC();
8199 newChart->FindOrCreateSenc(filename,
8203 if (wxThread::IsMain()) {
8204 msg.Printf(_(
"ENC Completed."));
8206 prog->Update(count, msg, &skip);
8216 for (
int t = 0;; t = (t + 1) % thread_count) {
8223 if (!workers[t]->IsAlive()) {
8236#if defined(__WXMSW__) || defined(__WXOSX__)
8243 for(
int t = 0; t<thread_count; t++) {
Global state for AIS decoder.
Dialog for displaying AIS target alerts.
Dialog for displaying a list of AIS targets.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Implements the AboutFrame class with additional functionality.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
A modal message dialog with a cancel and confirmation button.
Dialog for managing CM93 chart offsets.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void DoZoomCanvas(double factor, bool can_zoom_to_cursor=true)
Internal function that implements the actual zoom operation.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Set the viewport center point.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OperGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Primary navigation console display for route and vessel tracking.
const void Notify()
Notify all listeners, no data supplied.
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.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Represents a layer of chart objects in OpenCPN.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
bool Active() const
Return true if log is visible i.
void Add(const wxString &s)
Add an formatted string to log output.
void Init(const KeyProvider &kp, std::function< void(ObservedEvt &ev)> action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
Represents a navigational route in the navigation system.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Represents the About dialog for OpenCPN.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
Global variables reflecting command line options and arguments.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
wxWindow * GetTopWindow()
Return the top level window a k a gFrame.
Hooks into gui available in model.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse(void)
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Tools to send data to plugins.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.