56#include <wx/stdpaths.h>
57#include <wx/tokenzr.h>
58#include <wx/display.h>
59#include <wx/jsonreader.h>
61#include "o_sound/o_sound.h"
86#include "model/nav_object_database.h"
100#include "ais_info_gui.h"
101#include "dialog_alert.h"
105#include "ais_info_gui.h"
129#include "load_errors_dlg.h"
132#include "N2KParser.h"
155#include "user_colors.h"
161#include "androidUTIL.h"
165static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
176GLenum g_texture_rectangle_format;
179#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
180extern wxLocale *plocale_def_lang;
184extern bool g_b_EnableVBO;
185extern GLenum g_texture_rectangle_format;
189static int g_last_ChartScaleFactor;
190static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
191static int options_subpage = 0;
192static bool b_reloadForPlugins;
194static wxSize options_lastWindowSize(0, 0);
195static wxPoint options_lastWindowPos(0, 0);
199static double gQueryVar = 361.0;
201static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
202static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
204static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
210typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
211typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
213static SetSysColors_t pSetSysColors;
214static GetSysColor_t pGetSysColor;
216void SaveSystemColors();
217void RestoreSystemColors();
222DWORD color_3ddkshadow;
224DWORD color_activecaption;
225DWORD color_gradientactivecaption;
226DWORD color_captiontext;
227DWORD color_windowframe;
228DWORD color_inactiveborder;
233#include <wx/msw/msvcrt.h>
237static const long long lNaN = 0xfff8000000000000;
238#define NAN (*(double *)&lNaN)
242static double gLat_gt, gLon_gt;
243static double gLat_gt_m1, gLon_gt_m1;
244static uint64_t fix_time_gt;
245static uint64_t fix_time_gt_last;
247static double gSog_gt, gHdt_gt;
248static double gCog_gt_m1, gHdt_gt_m1;
249static uint64_t hdt_time_gt;
250static double cog_rate_gt, hdt_rate_gt;
252void InitializeUserColors();
253void DeInitializeUserColors();
254void SetSystemColors(ColorScheme cs);
256static bool LoadAllPlugIns(
bool load_enabled) {
257 AbstractPlatform::ShowBusySpinner();
258 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
259 AbstractPlatform::HideBusySpinner();
263static void LaunchLocalHelp() {
265 androidLaunchHelpView();
267 wxString def_lang_canonical =
"en_US";
270 if (plocale_def_lang)
271 def_lang_canonical = plocale_def_lang->GetCanonicalName();
274 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
276 wxString help_try = help_locn + def_lang_canonical +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"en_US" +
".html";
281 if (!::wxFileExists(help_try)) {
282 help_try = help_locn +
"web" +
".html";
285 if (!::wxFileExists(help_try))
return;
288 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
293static wxString _menuText(wxString name, wxString shortcut) {
297 menutext <<
"\t" << shortcut;
302static void DoHelpDialog() {
314 [] { LaunchLocalHelp(); });
326#if defined(__WXGTK__) || defined(__WXQT__)
327#include "bitmaps/opencpn.xpm"
342 if (g_bInlandEcdis) {
346 wxPoint tbp_incanvas =
349 g_iENCToolbarPosY = tbp_incanvas.y;
350 g_iENCToolbarPosX = tbp_incanvas.x;
358 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
362 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
365 g_iENCToolbarPosY = -1;
368 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
374 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
378 double tool_scale_factor =
379 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
381 tool_scale_factor, callbacks);
391#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
394static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
395 const char *prop_name) {
399 unsigned long ret_nitems;
400 unsigned long ret_bytes_after;
401 unsigned char *ret_prop;
403 xa_prop_name = XInternAtom(disp, prop_name, False);
411 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
412 &xa_ret_type, &ret_format, &ret_nitems,
413 &ret_bytes_after, &ret_prop) != Success)
416 if (xa_ret_type != xa_prop_type) {
420 return (
char *)ret_prop;
425static bool isTransparentToolbarInOpenGLOK() {
432 if (!g_bdisable_opengl) {
433 Display *disp = XOpenDisplay(NULL);
435 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_NET_SUPPORTING_WM_CHECK")) ||
438 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
440 "_WIN_SUPPORTING_WM_CHECK"))) {
443 if ((wm_name = get_X11_property(disp, *sup_window,
444 XInternAtom(disp,
"UTF8_STRING", False),
446 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
449 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
464wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
466 font->GetFamily(), font->GetStyle(),
467 font->GetWeight(),
false, font->GetFaceName());
469wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
470 wxFontStyle style, wxFontWeight weight,
471 const wxString faceName,
double scale) {
475wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
476 return GetOCPNScaledFont_PlugIn(label, Ptsize);
485wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
487BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
488EVT_CLOSE(MyFrame::OnCloseWindow)
489EVT_MENU(wxID_EXIT, MyFrame::OnExit)
490EVT_SIZE(MyFrame::OnSize)
491EVT_MOVE(MyFrame::OnMove)
492EVT_ICONIZE(MyFrame::OnIconize)
493EVT_MENU(-1, MyFrame::OnToolLeftClick)
494EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
496EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
497EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
498EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
500EVT_MAXIMIZE(MyFrame::OnMaximize)
501EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
502 MyFrame::RequestNewToolbarArgEvent)
503EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
505EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
506EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
507EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
509#ifdef wxHAS_POWER_EVENTS
510EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
511EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
512EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
513EVT_POWER_RESUME(MyFrame::OnResume)
524static
void onBellsFinishedCB(
void *ptr) {
525 auto framePtr =
static_cast<MyFrame *
>(ptr);
527 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
528 wxPostEvent(framePtr, ev);
533 auto msg = ev.GetString().ToStdString();
534 auto ¬eman = NotificationManager::GetInstance();
535 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
538static NmeaLog *GetDataMonitor() {
539 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
540 return dynamic_cast<NmeaLog *
>(w);
543MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
544 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
545 OpenFileFunc open_gpx_file)
547 m_connections_dlg(nullptr),
549 m_pauidockart(pauidockart),
550 m_rest_server(rest_server),
551 m_open_gpx_file(open_gpx_file) {
563 m_ulLastNMEATicktime = 0;
564 m_data_monitor->Hide();
566 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
570 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
573 InitTimer.SetOwner(
this, INIT_TIMER);
575 m_initializing =
false;
576 m_toolbar_callbacks.render_gl_textures =
578 [&](
ocpnDC &dc,
float *coords,
float *uv) {
579 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
580 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
583 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
587 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
590 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
593 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
596 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
599 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
601 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
610 m_bTimeIsSet =
false;
611 m_bdefer_resize =
false;
614 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
615 COGFilterTable[i] = NAN;
616 SOGFilterTable[i] = NAN;
618 m_last_bGPSValid =
false;
619 m_last_bVelocityValid =
false;
629 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
634 double process_noise_std = 1.0;
635 double measurement_noise_std = 0.5;
639 m_ChartUpdatePeriod = 1;
644 log_callbacks.log_is_active = [&]() {
645 auto log = GetDataMonitor();
646 return log && log->IsVisible();
648 log_callbacks.log_message = [&](
Logline ll) {
649 NmeaLog *monitor = GetDataMonitor();
652 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
655 ais_callbacks.confirm_stop_track = []() {
656 int r = OCPNMessageBox(
658 _(
"This AIS target has Persistent tracking selected by MMSI "
660 "A Persistent track recording will therefore be restarted for this "
662 "Do you instead want to stop Persistent tracking for this target?"),
663 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
664 return r == wxID_YES;
666 ais_callbacks.get_target_mmsi = []() {
667 auto alert_dlg_active =
669 assert(alert_dlg_active);
670 return alert_dlg_active->Get_Dialog_MMSI();
678 wxLogMessage(
" **** Connect stuff");
684 Connect(wxEVT_OCPN_MSG,
685 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
693 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
701#if defined(__WXGTK__) || defined(__WXQT__)
702 wxIcon app_icon(opencpn);
710 wxDynamicLibrary dllUser32(
"user32.dll");
712 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
713 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
718 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
723 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
724 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
726 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
727 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
728 [&](wxCommandEvent) { Refresh(); });
729 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
731 m_update_statusbar_listener.Init(
732 GuiEvents::GetInstance().gframe_update_status_bar,
734 m_center_aistarget_listener.Init(
735 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
736 auto ais_target = obs::UnpackEvtPointer<AisTargetData>(ev);
737 CenterAisTarget(ais_target);
739 m_reload_charts_listener.Init(
740 GuiEvents::GetInstance().on_finalize_chartdbs,
741 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
745 EnableFullScreenView();
747 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
753 FrameTenHzTimer.Stop();
768 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
774void MyFrame::FreezeCharts() {
777 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
779 if (cc && !cc->IsFrozen()) cc->Freeze();
783void MyFrame::CenterAisTarget(
784 const std::shared_ptr<const AisTargetData> &ais_target) {
792 double factor = cc->GetScaleValue() / 5000.0;
793 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
799void MyFrame::ThawCharts() {
802 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
804 if (cc && cc->IsFrozen()) cc->Thaw();
811 switch (event.type) {
812 case SENC_BUILD_STARTED:
815 case SENC_BUILD_DONE_NOERROR:
817 chart =
event.m_ticket->m_chart;
819 chart->PostInit(FULL_INIT, global_color_scheme);
821 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
823 if (cc) cc->ClearS52PLIBStateHash();
830 delete event.m_ticket;
832 case SENC_BUILD_DONE_ERROR:
833 wxLogDebug(
"SENC build done: SENC_BUILD_DONE_ERROR");
836 delete event.m_ticket;
843bool MyFrame::StartRebuildChartDatabase() {
844 bool b_SetInitialPoint =
false;
847 ArrayOfCDI ChartDirArray;
848 pConfig->LoadChartDirArray(ChartDirArray);
850 if (ChartDirArray.GetCount()) {
855 _(
"OpenCPN needs to update the chart database from config file "
859 wxICON_INFORMATION | wxOK);
867 _(
"Rebuilding chart database from configuration file entries..."));
871 wxString dummy1 = _(
"Elapsed time : ");
872 wxString dummy2 = _(
"Estimated time : ");
873 wxString dummy3 = _(
"Remaining time : ");
874 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
875 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
885void MyFrame::OnBellsFinished(wxCommandEvent &event) {
886 int bells = wxMin(m_BellsToPlay, 2);
887 if (bells <= 0)
return;
889 wxString soundfile =
"sounds";
890 appendOSDirSlash(&soundfile);
891 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
892 soundfile.Prepend(g_Platform->GetSharedDataDir());
893 wxLogMessage(
"Using bells sound file: " + soundfile);
895 o_sound::Sound *sound = bells_sound[bells - 1];
896 sound->SetFinishedCallback(onBellsFinishedCB,
this);
897 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
898 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
899 sound->Load(soundfile);
900 if (!sound->IsOk()) {
901 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
905 m_BellsToPlay -= bells;
908void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
910void MyFrame::OnMaximize(wxMaximizeEvent &event) {
917void MyFrame::ReloadAllVP() {
918 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
920 if (cc) cc->ReloadVP();
924void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
925 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
928 global_color_scheme = cs;
931 case GLOBAL_COLOR_SCHEME_DAY:
934 case GLOBAL_COLOR_SCHEME_DUSK:
937 case GLOBAL_COLOR_SCHEME_NIGHT:
938 SchemeName =
"NIGHT";
945 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
947 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
948 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
949 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
950 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
951 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
953 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
982 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
983 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
987 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
989 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
993 user_colors::GetMapByScheme(SchemeName.ToStdString());
998 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1001 cc->SetColorScheme(cs);
1002 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1003 cc->HideChartInfoWindow();
1004 cc->SetQuiltChartHiLiteIndex(-1);
1010 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1022 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1035 if (g_pais_query_dialog_active) {
1036 bool b_isshown = g_pais_query_dialog_active->IsShown();
1037 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1038 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1040 g_pais_query_dialog_active->Close();
1043 g_pais_query_dialog_active->
Create(
1044 this, -1, _(
"AIS Target Query"),
1045 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1046 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1047 g_pais_query_dialog_active->UpdateText();
1048 if (b_isshown) g_pais_query_dialog_active->Show();
1053 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1057 ApplyGlobalColorSchemetoStatusBar();
1059 UpdateAllToolbars(cs);
1064 bool btoolbarFull = g_bmasterToolbarFull;
1070 if (!btoolbarFull) {
1072 RequestNewMasterToolbar();
1074 CollapseGlobalToolbar();
1077 RequestNewMasterToolbar();
1086void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1087 if (m_pStatusBar != NULL) {
1088 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1089 m_pStatusBar->ClearBackground();
1100void MyFrame::CancelAllMouseRoute() {
1102 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1104 if (cc) cc->CancelMouseRoute();
1108void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1116 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1124 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1133 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1136 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1137 config_array.Item(i)->canvas = NULL;
1143 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1148 switch (g_canvasConfig) {
1162 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1163 cc->GetglCanvas()->Show();
1166 config_array.Item(0)->canvas = cc;
1170 cc->ApplyCanvasConfig(config_array.Item(0));
1174 cc->ConfigureChartBar();
1175 cc->SetColorScheme(global_color_scheme);
1176 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1177 cc->SetShowGPS(
true);
1180 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1182 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1198 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1201 config_array.Item(0)->canvas = cc;
1203 cc->ApplyCanvasConfig(config_array.Item(0));
1206 cc->ConfigureChartBar();
1207 cc->SetColorScheme(global_color_scheme);
1208 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1209 cc->SetShowGPS(
false);
1212 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1214 .CaptionVisible(
false)
1216 .CloseButton(
false);
1225 if (config_array.GetCount() < 2) {
1227 pcc->configIndex = 1;
1231 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1232 config_array.Add(pcc);
1235 config_array.Item(1)->canvas = cc;
1237 cc->ApplyCanvasConfig(config_array.Item(1));
1240 cc->ConfigureChartBar();
1241 cc->SetColorScheme(global_color_scheme);
1242 cc->SetShowGPS(
true);
1244 cc->SetShowGPSCompassWindow(
true);
1247 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1249 .CaptionVisible(
false)
1251 .CloseButton(
false);
1252 g_pauimgr->GetPane(cc).RightDockable(
true);
1256 config_array.Item(1)->canvasSize =
1257 wxSize(GetClientSize().x / 2, GetClientSize().y);
1258 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1263 if (b_useStoredSize) {
1264 int ccw = config_array.Item(1)->canvasSize.x;
1265 int cch = config_array.Item(1)->canvasSize.y;
1268 if (ccw < GetClientSize().x / 10) {
1269 ccw = GetClientSize().x / 2;
1270 cch = GetClientSize().y;
1273 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1274 cc->SetSize(ccw, cch);
1292 console->SetColorScheme(global_color_scheme);
1297 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1303void MyFrame::RequestNewToolbars(
bool bforcenew) {
1304 if (b_inCloseWindow) {
1308 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1309 PositionIENCToolbar();
1318void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1324void MyFrame::SetAllToolbarScale() {
1325 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1328void MyFrame::SetGPSCompassScale() {
1329 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1333 wxPoint screenPoint = ::wxGetMousePosition();
1336 switch (g_canvasConfig) {
1338 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1341 if (canvas->GetScreenRect().Contains(
1345 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1348 if (canvas->GetScreenRect().Contains(
1355 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1358 if (canvas->GetScreenRect().Contains(
1359 canvas->ScreenToClient(screenPoint)))
1367int MyFrame::GetCanvasIndexUnderMouse() {
1368 wxPoint screenPoint = ::wxGetMousePosition();
1371 switch (g_canvasConfig) {
1373 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1376 if (canvas->GetScreenRect().Contains(
1380 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1383 if (canvas->GetScreenRect().Contains(
1390 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1393 if (canvas->GetScreenRect().Contains(
1394 canvas->ScreenToClient(screenPoint)))
1402bool MyFrame::DropMarker(
bool atOwnShip) {
1409 if (!canvas)
return false;
1416 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1418 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1420 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1431 RefreshAllCanvas(
false);
1436void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1437 if (g_canvasConfig != 0) {
1440 int nTargetGTK = -1;
1442 wxWindow *source = FindFocus();
1448 switch (g_canvasConfig) {
1450 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1453 if (canvas && (canvas == test)) {
1458 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1461 if (canvas && (canvas == test)) {
1469 int nfinalTarget = nTarget;
1471 nfinalTarget = nTargetGTK;
1473 target = ConfigMgr::Get()
1474 .GetCanvasConfigArray()
1479 target->Refresh(
true);
1490void MyFrame::FastClose() {
1492 FrameTenHzTimer.Stop();
1494 FrameTimer1.Start(1);
1498void MyFrame::OnExit(wxCommandEvent &event) {
1502void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1505 if (b_inCloseWindow) {
1515 if (!g_bDeferredInitDone)
return;
1532 if (bDBUpdateInProgress)
return;
1534 b_inCloseWindow =
true;
1536 ::wxSetCursor(wxCURSOR_WAIT);
1540 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1542 if (cc && cc->IsMeasureActive()) {
1543 cc->CancelMeasureRoute();
1548 SendPreShutdownHookToPlugins();
1552 if (g_pAISTargetList) {
1553 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1554 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1555 g_pauimgr->DetachPane(g_pAISTargetList);
1582 SetCursor(wxCURSOR_WAIT);
1584 RefreshAllCanvas(
true);
1590 RestoreScreenBrightness();
1601 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1602 g_iENCToolbarPosY = tbp_incanvas.y;
1603 g_iENCToolbarPosX = tbp_incanvas.x;
1607 g_bframemax = IsMaximized();
1610 FrameTenHzTimer.Stop();
1612 FrameCOGTimer.Stop();
1626 if (g_bAutoAnchorMark) {
1627 bool watching_anchor =
false;
1635 wxDateTime now = wxDateTime::Now();
1636 wxTimeSpan uptime = now.Subtract(g_start_time);
1638 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1639 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1644 if (g_declutter_anchorage) {
1645 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1646 if (pr->GetName().StartsWith(
"Anchorage")) {
1647 double a =
gLat - pr->m_lat;
1648 double b =
gLon - pr->m_lon;
1649 double l = sqrt((a * a) + (b * b));
1652 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1654 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1655 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1663 wxString name = now.Format();
1664 name.Prepend(_(
"Anchorage created "));
1670 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1679 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1683 NavObj_dB::GetInstance().Close();
1687 pConfig->DeleteGroup(
"/Routes");
1688 pConfig->DeleteGroup(
"/Marks");
1707 if (g_pAISTargetList) {
1708 g_pAISTargetList->Disconnect_decoder();
1709 g_pAISTargetList->Destroy();
1712 if (RouteManagerDialog::getInstanceFlag()) {
1729 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1731 if (cc) cc->Destroy();
1755 CommBridge::GetInstance().SaveConfig();
1775 auto ®istry = CommDriverRegistry::GetInstance();
1776 registry.CloseAllDrivers();
1779 for (
auto *cp : TheConnectionParams()) {
1784 while (pLayerList->size())
delete *pLayerList->begin();
1788 ReleaseApiListeners();
1791 g_bTempShowMenuBar =
false;
1793#define THREAD_WAIT_SECONDS 5
1803 wxLogMessage(
"Starting compressor pool drain");
1804 wxDateTime now = wxDateTime::Now();
1805 time_t stall = now.GetTicks();
1806 time_t end = stall + THREAD_WAIT_SECONDS;
1809 while (stall < end) {
1810 wxDateTime later = wxDateTime::Now();
1811 stall = later.GetTicks();
1814 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1823 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1829 uninitIXNetSystem();
1837 wxLogMessage(
"gFrame destroyed.");
1840#ifndef USE_ANDROID_GLES2
1841 qDebug() <<
"Calling OnExit()";
1845 wxTheApp->ExitMainLoop();
1848void MyFrame::OnMove(wxMoveEvent &event) {
1849 auto idx = wxDisplay::GetFromWindow(
this);
1862 DEBUG_LOG <<
"Moved to " << idx
1863#if wxCHECK_VERSION(3, 1, 6)
1864 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1865 << wxDisplay(idx).GetPPI().GetY()
1866 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1868 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1869 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1870 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1871 << wxGetDisplaySizeMM().GetY()
1872 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1881 if (g_config_display_size_manual) {
1890 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1893 cc->SetMUIBarPosition();
1902 UpdateGPSCompassStatusBoxes();
1912 PositionIENCToolbar();
1918 g_nframewin_posx = GetPosition().x;
1919 g_nframewin_posy = GetPosition().y;
1922void MyFrame::ProcessCanvasResize() {
1923 UpdateGPSCompassStatusBoxes(
true);
1927 PositionIENCToolbar();
1930 TriggerRecaptureTimer();
1934void MyFrame::TriggerRecaptureTimer() {
1935 m_recaptureTimer.Start(
1936 1000, wxTIMER_ONE_SHOT);
1939void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1941void MyFrame::SetCanvasSizes(wxSize frameSize) {
1945 int cccw = frameSize.x;
1946 int ccch = frameSize.y;
1950 switch (g_canvasConfig) {
1956 cc->GetSize( &cur_width, &cur_height );
1957 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1959 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1961 cc->SetSize( 0, 0, cccw, ccch );
1971 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1972 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1974 ccw = wxMin(ccw, cccw * 8 / 10);
1975 ccw = wxMax(ccw, cccw * 2 / 10);
1979 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1986 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2003void MyFrame::OnIconize(wxIconizeEvent &event) {
2013 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2015 if (cc && cc->GetMUIBar()) {
2016 if (cc->GetMUIBar()->GetCanvasOptions()) {
2017 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2018 cc->GetMUIBar()->PushCanvasOptions();
2027void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2029void MyFrame::ODoSetSize() {
2031 GetClientSize(&x, &y);
2034 if (m_pStatusBar != NULL) {
2035 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2036 int currentCount = m_pStatusBar->GetFieldsCount();
2037 if (currentCount != m_StatusBarFieldCount) {
2038 if ((currentCount > 0) && (currentCount < 7)) {
2041 int widths[] = {2, 2, 2, 2, 2, 2};
2042 m_pStatusBar->SetStatusWidths(currentCount, widths);
2045 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2048 if (m_StatusBarFieldCount) {
2053 if (m_StatusBarFieldCount > 2) {
2054 int widths[] = {-6, -5, -5, -6, -4};
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2056 }
else if (m_StatusBarFieldCount == 2) {
2057 int cwidth = x * 90 / 100;
2058 int widths[] = {100, 100};
2059 widths[0] = cwidth * 6.4 / 10.0;
2060 widths[1] = cwidth * 3.6 / 10.0;
2061 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2063 int widths[] = {100, 100};
2064 widths[0] = x * 90 / 100;
2065 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2068 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2069 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2070 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2072 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2074 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2082 m_pStatusBar->GetFieldRect(0, stat_box);
2085 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2087 wxFont sys_font = *wxNORMAL_FONT;
2088 int try_font_size = sys_font.GetPointSize();
2091 int min_font_size = 10;
2101 wxFont *statusBarFont =
2102 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2103 int font_size = statusBarFont->GetPointSize();
2105 font_size = wxMin(font_size,
2108 wxMax(font_size, min_font_size);
2111 font_size = statusBarFont->GetPointSize();
2118 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2119 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2121 int min_height = stat_box.height;
2123 m_pStatusBar->SetFont(*pstat_font);
2124 m_pStatusBar->SetForegroundColour(
2125 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2127 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2129 (min_height >> 1) * 2;
2130 m_pStatusBar->SetMinHeight(min_height);
2139 SetCanvasSizes(GetClientSize());
2141 UpdateGPSCompassStatusBoxes(
true);
2143 if (
console) PositionConsole();
2146 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2148 if (cc) cc->FormatPianoKeys();
2154 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2155 GetPrimaryCanvas()->GetCompass()->GetRect());
2181 options_lastWindowSize = wxSize(0, 0);
2182 options_lastWindowPos = wxPoint(0, 0);
2189 if (!b_inCloseWindow) {
2192 resizeAndroidPersistents();
2196 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2197 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2203void MyFrame::PositionConsole() {
2204#if defined(__WXMSW__) || defined(__WXMAC__)
2205 if (NULL == GetPrimaryCanvas())
return;
2207 int ccx, ccy, ccsx, ccsy, consx, consy;
2212 consoleHost->GetSize(&ccsx, &ccsy);
2213 consoleHost->GetPosition(&ccx, &ccy);
2215 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2216 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2217 consoleHost = GetPrimaryCanvas();
2222 if (consoleHost->GetCompass()) {
2223 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2225 if (compass_rect.y < 100)
2226 yOffset = compass_rect.y + compass_rect.height + 45;
2230 wxSize csz =
console->GetSize();
2234 wxPoint screen_pos =
2235 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2238 if (NULL == GetPrimaryCanvas())
return;
2240 int ccx, ccy, ccsx, ccsy, consx, consy;
2245 consoleHost->GetSize(&ccsx, &ccsy);
2246 consoleHost->GetPosition(&ccx, &ccy);
2248 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2249 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2250 consoleHost = GetPrimaryCanvas();
2253 int yTopOffset = 60;
2254 int yBottomOffset = 0;
2256 if (consoleHost->GetCompass()) {
2257 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2259 if (compass_rect.y < 100)
2260 yTopOffset = compass_rect.y + compass_rect.height;
2262 if (consoleHost->GetMUIBar()) {
2263 wxRect mui_rect = consoleHost->GetMUIBarRect();
2264 yBottomOffset = ccsy - mui_rect.y;
2268 wxSize csz =
console->GetSize();
2271 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2273 if (consy < yAvail) {
2274 yFinal = (yAvail - consy) / 2;
2275 yFinal += yTopOffset;
2276 }
else if (
console->GetCDI()->IsShown()) {
2277 int cdi_height =
console->GetCDI()->GetSize().y;
2278 int consy_no_cdi = consy - cdi_height;
2279 yFinal = (yAvail - consy_no_cdi) / 2;
2280 yFinal += yTopOffset;
2284 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2289void MyFrame::UpdateAllFonts() {
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;
2337void MyFrame::RefreshGroupIndices() {
2339 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2341 if (cc) cc->canvasRefreshGroupIndex();
2345bool MyFrame::DisableTbarTooltips() {
2350 wxLogWarning(
"Global g_MainToolbar has not been created.");
2354void MyFrame::EnableTbarTooltips() {
2360void MyFrame::HideTbarTooltip() {
2366void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2368 switch (event.GetId()) {
2369 case ID_MENU_SCALE_OUT:
2370 DoStackDelta(GetPrimaryCanvas(), 1);
2374 case ID_MENU_SCALE_IN:
2375 DoStackDelta(GetPrimaryCanvas(), -1);
2379 case ID_MENU_ZOOM_IN: {
2380 if (GetFocusCanvas()) {
2381 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2386 case ID_MENU_ZOOM_OUT: {
2387 if (GetFocusCanvas()) {
2388 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2393 case ID_MENU_ROUTE_NEW: {
2394 if (GetFocusCanvas()) {
2395 if (0 == GetFocusCanvas()->m_routeState) {
2396 GetFocusCanvas()->StartRoute();
2398 GetFocusCanvas()->FinishRoute();
2404 case ID_MENU_TOOL_MEASURE: {
2405 GetPrimaryCanvas()->StartMeasureRoute();
2409 case ID_MENU_TOOL_NMEA_DBG_LOG:
2410 m_data_monitor->Show();
2411 m_data_monitor->Raise();
2414 case ID_MENU_TOOL_IO_MONITOR:
2415 m_data_monitor->Show();
2418 case ID_MENU_MARK_BOAT: {
2423 case ID_MENU_MARK_CURSOR: {
2428 case ID_MENU_NAV_FOLLOW: {
2429 if (
gFrame->GetPrimaryCanvas())
2430 gFrame->GetPrimaryCanvas()->TogglebFollow();
2434 case ID_MENU_CHART_OUTLINES: {
2435 ToggleChartOutlines(GetFocusCanvas());
2439 case ID_MENU_CHART_QUILTING: {
2440 ToggleQuiltMode(GetFocusCanvas());
2444 case ID_MENU_UI_CHARTBAR: {
2445 ToggleChartBar(GetFocusCanvas());
2449 case ID_MENU_ENC_TEXT:
2451 ToggleENCText(GetFocusCanvas());
2454 case ID_MENU_ENC_LIGHTS: {
2455 ToggleLights(GetFocusCanvas());
2458 case ID_MENU_ENC_SOUNDINGS: {
2459 ToggleSoundings(GetFocusCanvas());
2462 case ID_MENU_ENC_ANCHOR: {
2463 ToggleAnchor(GetFocusCanvas());
2466 case ID_MENU_ENC_DATA_QUALITY: {
2467 ToggleDataQuality(GetFocusCanvas());
2470 case ID_MENU_SHOW_NAVOBJECTS: {
2471 ToggleNavobjects(GetFocusCanvas());
2475 case ID_MENU_AIS_TARGETS: {
2476 ToggleAISDisplay(GetFocusCanvas());
2479 case ID_MENU_AIS_MOORED_TARGETS: {
2480 g_bHideMoored = !g_bHideMoored;
2483 case ID_MENU_AIS_SCALED_TARGETS: {
2484 ToggleAISMinimizeTargets(GetFocusCanvas());
2488 case ID_MENU_AIS_TARGETLIST: {
2489 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2493 case ID_MENU_AIS_TRACKS: {
2494 g_bAISShowTracks = !g_bAISShowTracks;
2495 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2499 case ID_MENU_AIS_CPADIALOG: {
2500 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2501 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2502 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2503 if (g_bAIS_CPA_Alert) {
2504 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2509 case ID_MENU_AIS_CPASOUND: {
2510 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2511 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2515 case ID_MENU_AIS_CPAWARNING: {
2516 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2517 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2521 case wxID_PREFERENCES:
2528 case ID_SETTINGS_NEW: {
2533 case ID_SETTINGS_DELETE: {
2536 g_pOptions =
nullptr;
2540 case ID_RELOAD_CHARTS: {
2545 case ID_MENU_SETTINGS_BASIC: {
2547 androidDisableFullScreen();
2549 DoAndroidPreferences();
2556 case ID_MENU_UI_FULLSCREEN: {
2561 case ID_MENU_SHOW_CURRENTS: {
2562 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2563 GetFocusCanvas()->ReloadVP();
2564 GetFocusCanvas()->Refresh(
false);
2568 case ID_MENU_SHOW_TIDES: {
2569 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2570 GetFocusCanvas()->ReloadVP();
2571 GetFocusCanvas()->Refresh(
false);
2591 case ID_MENU_UI_COLSCHEME:
2592 case ID_COLSCHEME: {
2593 ToggleColorScheme();
2602 case ID_MENU_OQUIT: {
2607 case ID_MENU_ROUTE_MANAGER:
2608 case ID_ROUTEMANAGER: {
2631 case ID_MENU_NAV_TRACK:
2633 if (!g_bTrackActive) {
2635 g_bTrackCarryOver =
true;
2638 g_bTrackCarryOver =
false;
2639 RefreshAllCanvas(
true);
2644 case ID_MENU_CHART_NORTHUP: {
2645 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2648 case ID_MENU_CHART_COGUP: {
2649 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2652 case ID_MENU_CHART_HEADUP: {
2653 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2657 case ID_MENU_MARK_MOB:
2663 case ID_MASTERTOGGLE: {
2665 wxString tip = _(
"Show Toolbar");
2666 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2668 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2670 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2673 if (g_bmasterToolbarFull)
2674 m_nMasterToolCountShown =
2678 m_nMasterToolCountShown = 2;
2680 m_nMasterToolCountShown =
2683 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2691 case ID_CMD_SELECT_CHART_TYPE: {
2692 selectChartDisplay(event.GetExtraLong(), -1);
2696 case ID_CMD_SELECT_CHART_FAMILY: {
2697 selectChartDisplay(-1, event.GetExtraLong());
2701 case ID_CMD_APPLY_SETTINGS: {
2702 applySettingsString(event.GetString());
2704 androidRestoreFullScreen();
2710 case ID_CMD_NULL_REFRESH: {
2715 case ID_CMD_SETVP: {
2716 setStringVP(event.GetString());
2720 case ID_CMD_INVALIDATE: {
2726 case ID_CMD_POST_JSON_TO_PLUGINS: {
2729 nlohmann::json root;
2731 root = nlohmann::json::parse(event.GetString().ToStdString());
2732 if (root[
"MessageID"].is_string()) {
2733 std::string msg_id = root[
"MessageID"].get<std::string>();
2736 }
catch (nlohmann::json::exception &) {
2758 ArrayOfPlugInToolbarTools tool_array =
2760 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2762 if (event.GetId() == pttc->id) {
2763 if (pttc->m_pplugin)
2785bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2786 bool viz_now = g_bmasterToolbarFull;
2789 wxString tip = _(
"Show Toolbar");
2791 tip = _(
"Hide Toolbar");
2793 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2796 bool toggle =
false;
2797 if (viz && !g_bmasterToolbarFull)
2800 else if (!viz && g_bmasterToolbarFull)
2804 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2807 if (g_bmasterToolbarFull)
2808 m_nMasterToolCountShown =
2812 m_nMasterToolCountShown = 2;
2814 m_nMasterToolCountShown =
2817 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2823void MyFrame::ScheduleReloadCharts() {
2824 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2825 evt.SetId(ID_RELOAD_CHARTS);
2826 GetEventHandler()->AddPendingEvent(evt);
2829void MyFrame::ScheduleDeleteSettingsDialog() {
2830 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2831 evt.SetId(ID_SETTINGS_DELETE);
2832 GetEventHandler()->AddPendingEvent(evt);
2835void MyFrame::ScheduleSettingsDialog() {
2836 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2837 evt.SetId(ID_SETTINGS);
2838 GetEventHandler()->AddPendingEvent(evt);
2841void MyFrame::ScheduleSettingsDialogNew() {
2842 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2843 evt.SetId(ID_SETTINGS_NEW);
2844 GetEventHandler()->AddPendingEvent(evt);
2847void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2848 UpdateCanvasConfigDescriptors();
2850 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2851 CreateCanvasLayout(
true);
2853 CreateCanvasLayout();
2857 ConfigureStatusBar();
2858 wxSize lastOptSize = options_lastWindowSize;
2863 options_lastWindowSize = lastOptSize;
2867 ScheduleSettingsDialogNew();
2869 ScheduleSettingsDialog();
2874 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2877 int index_hint = -1;
2878 if (i < pathArray.GetCount())
2879 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2880 cc->canvasChartsRefresh(index_hint);
2881 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2890 return GetPrimaryCanvas();
2893void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2895 if (g_bmasterToolbarFull) {
2896#ifndef OCPN_TOOLBAR_ANIMATE
2897 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2900 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2901 m_nMasterToolCountShown++;
2906 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2914#ifndef OCPN_TOOLBAR_ANIMATE
2915 m_nMasterToolCountShown = 1;
2917 if (m_nMasterToolCountShown > 1) {
2918 m_nMasterToolCountShown--;
2922 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2932void MyFrame::InvalidateAllGL() {
2935 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2945void MyFrame::RefreshAllCanvas(
bool bErase) {
2947 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2950 cc->Refresh(bErase);
2955void MyFrame::setStringVP(wxString VPS) {
2960 wxStringTokenizer tkz(VPS,
";");
2962 wxString token = tkz.GetNextToken();
2964 token.ToDouble(&lat);
2966 token = tkz.GetNextToken();
2968 token.ToDouble(&lon);
2970 token = tkz.GetNextToken();
2972 token.ToDouble(&scale_ppm);
2974 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2977void MyFrame::DoSettingsNew() {
2984void MyFrame::DoSettings() {
2985 if (!g_bDeferredInitDone) {
2986 wxLogWarning(
"Ignoring settings request while OpenCPN is initializing.");
2994 ApplyGlobalSettings(
true);
2997 bool b_loadHarmonics =
false;
2998 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3001 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3004 if (b_loadHarmonics) LoadHarmonics();
3012 g_bShowChartBar = !g_bShowChartBar;
3014 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3019 if (g_bShowChartBar) {
3021 UpdateControlBar(cc);
3024 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3027void MyFrame::ToggleColorScheme() {
3028 static bool lastIsNight;
3029 ColorScheme s = user_colors::GetColorScheme();
3032 if (lastIsNight && is == 3)
3035 lastIsNight =
false;
3037 if (lastIsNight) is = 2;
3038 if (is == 3) lastIsNight =
true;
3039 s = (ColorScheme)is;
3040 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3042 SetAndApplyColorScheme(s);
3045void MyFrame::ToggleFullScreen() {
3046 bool to = !IsFullScreen();
3051 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3053 ShowFullScreen(to, style);
3056 UpdateAllToolbars(global_color_scheme);
3058 UpdateControlBar(GetPrimaryCanvas());
3060 TriggerRecaptureTimer();
3063void MyFrame::ActivateMOB() {
3065 wxDateTime mob_time = wxDateTime::Now();
3066 wxString mob_label(_(
"MAN OVERBOARD"));
3067 mob_label += _(
" on ");
3068 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3072 pWP_MOB->SetShared(
true);
3074 pWP_MOB->SetWaypointArrivalRadius(
3076 pWP_MOB->SetUseSca(
false);
3078 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3086 new RoutePoint(zlat, zlon, g_default_wp_icon,
3087 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3088 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3093 temp_route->AddPoint(pWP_src);
3094 temp_route->AddPoint(pWP_MOB);
3096 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3106 temp_route->SetRouteArrivalRadius(-1.0);
3112 v[
"GUID"] = temp_route->
m_GUID;
3113 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
3116 if (RouteManagerDialog::getInstanceFlag()) {
3124 RefreshAllCanvas(
false);
3126 wxString mob_message(_(
"MAN OVERBOARD"));
3127 mob_message += _(
" Time: ");
3128 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3129 mob_message += _(
" Position: ");
3130 mob_message += toSDMM(1,
gLat);
3132 mob_message += toSDMM(2,
gLon);
3133 wxLogMessage(mob_message);
3135void MyFrame::TrackOn() {
3136 g_bTrackActive =
true;
3144 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3146 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3148 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3151 androidSetTrackTool(
true);
3154 if (RouteManagerDialog::getInstanceFlag()) {
3163 if (name.IsEmpty()) {
3169 name = _(
"(Unnamed Track)");
3173 SendJsonMessageToAllPlugins(
"OCPN_TRK_ACTIVATED", v);
3175 g_FlushNavobjChangesTimeout = 30;
3178Track *MyFrame::TrackOff(
bool do_add_point) {
3184 SendJsonMessageToAllPlugins(
"OCPN_TRK_DEACTIVATED", v);
3193 if (g_bTrackDaily) {
3198 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3199 return_val = pExtendTrack;
3206 g_bTrackActive =
false;
3208 if (RouteManagerDialog::getInstanceFlag()) {
3215 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3217 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3218 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3221 androidSetTrackTool(
false);
3225 m_target_rotate_time = wxInvalidDateTime;
3230void MyFrame::InitializeTrackRestart() {
3231 if (!g_bTrackDaily)
return;
3232 if (m_target_rotate_time.IsValid())
return;
3235 switch (g_track_rotate_time_type) {
3237 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3239 case TIME_TYPE_COMPUTER:
3240 rotate_at = g_track_rotate_time;
3244 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3245 rotate_at = g_track_rotate_time + utc_offset;
3248 if (rotate_at > 86400)
3250 else if (rotate_at < 0)
3253 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3254 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3257 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3258 m_target_rotate_time += wxTimeSpan(24);
3262bool MyFrame::ShouldRestartTrack() {
3264 InitializeTrackRestart();
3266 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3267 m_target_rotate_time += wxTimeSpan(24);
3273void MyFrame::TrackDailyRestart() {
3275 Track *pPreviousTrack = TrackOff(
true);
3282 if (pPreviousTrack) {
3283 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3287 if (RouteManagerDialog::getInstanceFlag()) {
3295void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3297 cc->SetUpMode(mode);
3299 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3300 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3301 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3304 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3309 cc->SetShowENCText(!cc->GetShowENCText());
3311 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3319void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3322 cc->SetENCDisplayCategory(nset);
3324 UpdateGlobalMenuItems();
3335 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3337 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3346 cc->SetShowENCLights(!cc->GetShowENCLights());
3348 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3358void MyFrame::ToggleRocks(
void )
3364 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3365 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3366 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3367 pOLE->nViz = !pOLE->nViz;
3371 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3372 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3373 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3376 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3380 ps52plib->GenerateStateHash();
3387 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3389 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3397 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3399 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3414 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3415 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3420 cc->SetShowAIS(!cc->GetShowAIS());
3421 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3425void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3426 cc->SetAttenAIS(!cc->GetAttenAIS());
3427 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3433 cc->m_bFollow =
true;
3436 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3440 SetChartUpdatePeriod();
3448 cc->m_bFollow =
false;
3450 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3454 SetChartUpdatePeriod();
3457void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3458 cc->SetShowOutlines(!cc->GetShowOutlines());
3460 RefreshAllCanvas(
false);
3464 if (g_bopengl) InvalidateAllGL();
3467 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3470void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3472void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3474 bool enabled = m_pMenuBar->IsEnabled(item_id);
3475 m_pMenuBar->Enable(item_id,
false);
3476 m_pMenuBar->Check(item_id, state);
3477 m_pMenuBar->Enable(item_id, enabled);
3481void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3488void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3489 wxBitmap *bmpRollover) {
3491 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3496void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3497 wxString rolloverSVGfile,
3498 wxString toggledSVGfile) {
3501 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3505void MyFrame::ConfigureStatusBar() {
3507 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3510 UseNativeStatusBar(
false);
3513 if (g_bShowStatusBar) {
3514 if (!m_pStatusBar) {
3516 CreateStatusBar(m_StatusBarFieldCount, 0);
3517 ApplyGlobalColorSchemetoStatusBar();
3522 m_pStatusBar->Destroy();
3523 m_pStatusBar = NULL;
3529void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3530 ConfigureStatusBar();
3532 wxSize lastOptSize = options_lastWindowSize;
3538 options_lastWindowSize = lastOptSize;
3540 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3543void MyFrame::BuildMenuBar() {
3549 bool showMenuBar =
true;
3551 bool showMenuBar = g_bShowMenuBar;
3563 m_pMenuBar =
new wxMenuBar();
3564 RegisterGlobalMenuItems();
3565 SetMenuBar(m_pMenuBar);
3569 UpdateGlobalMenuItems();
3574 m_pMenuBar->Destroy();
3580void MyFrame::RegisterGlobalMenuItems() {
3581 if (!m_pMenuBar)
return;
3583 wxMenu *nav_menu =
new wxMenu();
3584 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3585 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3586 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3587 nav_menu->AppendSeparator();
3588 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3589 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3590 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3591 nav_menu->AppendSeparator();
3593 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3594 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3596 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3597 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3599 nav_menu->AppendSeparator();
3600 nav_menu->Append(ID_MENU_SCALE_IN,
3601 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3602 nav_menu->Append(ID_MENU_SCALE_OUT,
3603 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3605 nav_menu->AppendSeparator();
3606 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3608 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3610 wxMenu *view_menu =
new wxMenu();
3612 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3613 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3614 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3615 _menuText(_(
"Show Chart Outlines"),
"O"));
3617 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3618 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3619 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3620 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3622 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3623 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3625 view_menu->AppendSeparator();
3627 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3628 _menuText(_(
"Show ENC text"),
"T"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3630 _menuText(_(
"Show ENC Lights"),
"L"));
3631 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3632 _menuText(_(
"Show ENC Soundings"),
"S"));
3633 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3634 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3635 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3636 _menuText(_(
"Show ENC Data Quality"),
"U"));
3637 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3638 _menuText(_(
"Show Navobjects"),
"V"));
3640 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3641 _menuText(_(
"Show ENC text"),
"Alt-T"));
3642 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3643 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3644 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3645 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3646 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3647 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3648 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3649 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3650 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3651 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3653 view_menu->AppendSeparator();
3654 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3655 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3656 view_menu->AppendSeparator();
3658 view_menu->Append(ID_MENU_UI_COLSCHEME,
3659 _menuText(_(
"Change Color Scheme"),
"C"));
3661 view_menu->Append(ID_MENU_UI_COLSCHEME,
3662 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3665 view_menu->AppendSeparator();
3667 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3668 _menuText(_(
"Toggle Full Screen"),
"F11"));
3670 m_pMenuBar->Append(view_menu, _(
"&View"));
3672 wxMenu *ais_menu =
new wxMenu();
3673 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3674 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3675 _(
"Attenuate less critical AIS targets"));
3676 ais_menu->AppendSeparator();
3677 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3678 _(
"Hide Moored AIS Targets"));
3679 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3680 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3681 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3684 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3685 _menuText(_(
"Show CPA Warnings"),
"W"));
3687 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3688 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3691 ais_menu->AppendSeparator();
3692 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3693 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3695 wxMenu *tools_menu =
new wxMenu();
3697 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3698 _menuText(_(
"Data Monitor"),
"E"));
3699 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3700 _menuText(_(
"Measure Distance"),
"M"));
3702 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3703 _menuText(_(
"Data Monitor"),
"Alt-E"));
3704 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3705 _menuText(_(
"Measure Distance"),
"Alt-M"));
3708 tools_menu->AppendSeparator();
3709 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3710 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3711 tools_menu->AppendSeparator();
3712 tools_menu->Append(ID_MENU_MARK_BOAT,
3713 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3714 tools_menu->Append(ID_MENU_MARK_CURSOR,
3715 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3716 tools_menu->AppendSeparator();
3720 _menuText(_(
"Drop MOB Marker"),
3722 tools_menu->AppendSeparator();
3723 tools_menu->Append(wxID_PREFERENCES,
3724 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3726 tools_menu->Append(ID_MENU_MARK_MOB,
3727 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3728 tools_menu->AppendSeparator();
3729 tools_menu->Append(wxID_PREFERENCES,
3730 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3732 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3735 wxMenu *window_menu =
new wxMenu();
3736 m_pMenuBar->Append(window_menu, _(
"&Window"));
3739 wxMenu *help_menu =
new wxMenu();
3740 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3741 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3742 m_pMenuBar->Append(help_menu, _(
"&Help"));
3745 UpdateGlobalMenuItems();
3746 EnableSettingsTool(g_bDeferredInitDone);
3749void MyFrame::UpdateGlobalMenuItems() {
3750 if (!m_pMenuBar)
return;
3752 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3753 ->Check(GetPrimaryCanvas()->m_bFollow);
3754 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3755 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3756 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3757 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3758 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3759 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3760 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3761 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3762 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3763 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3764 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3765 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3766 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3767 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3768 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3769 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3770 if (g_bAIS_CPA_Alert) {
3771 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3772 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3774 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3775 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3778 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3779 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3780 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3783 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3784 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3785 ->Check(ps52plib->GetShowSoundings());
3787 bool light_state =
false;
3789 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3791 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3792 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3793 light_state = (pOLE->nViz == 1);
3798 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3799 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3803 DisCat nset = ps52plib->GetDisplayCategory();
3804 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3805 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3806 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3807 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3808 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3809 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3810 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3812 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3813 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3814 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3819void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3820 if (!m_pMenuBar)
return;
3822 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3824 if (cc->GetUpMode() == NORTH_UP_MODE)
3825 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3826 else if (cc->GetUpMode() == COURSE_UP_MODE)
3827 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3829 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3831 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3832 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3833 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3834 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3835 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3836 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3837 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3838 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3839 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3840 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3841 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3842 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3843 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3844 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3845 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3848 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3849 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3852 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3854 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3855 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3860 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3864 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3865 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3866 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3867 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3868 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3869 ->Check(cc->GetShowENCDataQual());
3870 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3872 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3873 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3874 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3879void MyFrame::InvalidateAllCanvasUndo() {
3881 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3883 if (cc) cc->undo->InvalidateUndo();
3887void MyFrame::SubmergeAllCanvasToolbars() {
3889 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3891 if (cc) cc->SubmergeToolbar();
3895void MyFrame::SurfaceAllCanvasToolbars() {
3896 if (g_bshowToolbar) {
3898 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3900 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3907void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3909 if (lon > 180.0) lon -= 360.0;
3914 cc->JumpToPosition(lat, lon,
scale);
3917 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3921void MyFrame::UpdateCanvasConfigDescriptors() {
3923 for (
unsigned int i = 0;
3924 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3925 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3933 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3934 cc->GroupID = chart->m_groupIndex;
3937 cc->
bQuilt = chart->GetQuiltMode();
3943 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3945 cc->
bFollow = chart->m_bFollow;
3950 int upmode = chart->GetUpMode();
3951 if (upmode == COURSE_UP_MODE)
3953 else if (upmode == HEAD_UP_MODE)
3960void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3961 if (!RBBox.GetValid())
return;
3963 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3964 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3967 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3968 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3976 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3977 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3979 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3980 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3982 cc->GetSize(&ww, &wh);
3984 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3986 ppm = wxMin(ppm, 1.0);
3992void MyFrame::PrepareOptionsClose(
options *settings,
3993 int settings_return_value) {
3995 options_lastPage = settings->lastPage;
4000 if (options_lastPage == 1) options_lastPage = 0;
4002 options_subpage = settings->lastSubPage;
4003 options_lastWindowPos = settings->lastWindowPos;
4004 options_lastWindowSize = settings->lastWindowSize;
4007 androidEnableBackButton(
true);
4008 androidEnableOptionsMenu(
true);
4009 androidRestoreFullScreen();
4010 androidEnableRotation();
4013 EnableSettingsTool(
true);
4016void MyFrame::DoOptionsDialog() {
4017 EnableSettingsTool(
false);
4020 AbstractPlatform::ShowBusySpinner();
4023 pConfig->SetPath(
"/Settings");
4024 pConfig->Read(
"OptionsSizeX", &sx, -1);
4025 pConfig->Read(
"OptionsSizeY", &sy, -1);
4027 wxWindow *optionsParent =
this;
4029 optionsParent = GetPrimaryCanvas();
4032 callbacks.prepare_close = [&](
options *me,
int changes) {
4033 PrepareOptionsClose(me, changes);
4035 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4036 ProcessOptionsDialog(changes, workdir_list);
4039 wxPoint(-1, -1), wxSize(sx, sy));
4041 AbstractPlatform::HideBusySpinner();
4045 g_options->SetInitChartDir(*pInit_Chart_Dir);
4049 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4050 g_options->SetWorkDirListPtr(pWorkDirArray);
4056 prev_locale = g_locale;
4057 g_options->SetInitialPage(options_lastPage, options_subpage);
4060 g_options->lastWindowPos = options_lastWindowPos;
4061 if (options_lastWindowPos != wxPoint(0, 0)) {
4063 g_options->SetSize(options_lastWindowSize);
4067 if (options_lastWindowSize != wxSize(0, 0)) {
4068 g_options->SetSize(options_lastWindowSize);
4073 androidEnableBackButton(
false);
4074 androidEnableOptionsMenu(
false);
4075 androidDisableFullScreen();
4083 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4086 wxString chart_file_name;
4087 if (cc->GetQuiltMode()) {
4088 int dbi = cc->GetQuiltRefChartdbIndex();
4089 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4091 if (cc->m_singleChart)
4092 chart_file_name = cc->m_singleChart->GetFullPath();
4095 pathArray.Add(chart_file_name);
4101 last_canvasConfig = g_canvasConfig;
4104 g_last_ChartScaleFactor = g_ChartScaleFactor;
4110void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4111 bool b_need_refresh =
false;
4114 if ((rr & VISIT_CHARTS) &&
4115 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4117 UpdateChartDatabaseInplace(*pNewDirArray,
4118 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4121 b_need_refresh =
true;
4126 if (rr & STYLE_CHANGED) {
4129 _(
"Please restart OpenCPN to activate language or style changes."),
4130 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4133 bool charts_updating =
4134 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4135 if (!charts_updating) RefreshGroupIndices();
4137 if (rr & TIDES_CHANGED) {
4143 if (rr & S52_CHANGED) {
4144 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4155 g_Platform->GetDisplayDPmm());
4158 double stuffcog = NAN;
4159 double stuffsog = NAN;
4160 if (!std::isnan(
gCog)) stuffcog =
gCog;
4161 if (!std::isnan(
gSog)) stuffsog =
gSog;
4163 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4164 COGFilterTable[i] = stuffcog;
4165 SOGFilterTable[i] = stuffsog;
4168 SetChartUpdatePeriod();
4170 if (rr & GL_CHANGED) {
4174 b_need_refresh =
true;
4177 if (rr & S52_CHANGED) {
4178 b_need_refresh =
true;
4182 if (rr & REBUILD_RASTER_CACHE) {
4184 GetPrimaryCanvas()->Disable();
4186 GetPrimaryCanvas()->Enable();
4191 if (g_config_display_size_manual &&
4199 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4206 int rrt = rr & S52_CHANGED;
4208 (rrt == S52_CHANGED) ||
4209 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4219 ps52plib->SetScaleFactorExp(
4220 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4221 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4225 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4227 if (cc) cc->ApplyGlobalSettings();
4235 if (!charts_updating) {
4236 bool ztc = g_bEnableZoomToCursor;
4237 g_bEnableZoomToCursor =
false;
4239 if (!GetPrimaryCanvas()->IsFrozen())
4241 g_bEnableZoomToCursor = ztc;
4246 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4255 SetGPSCompassScale();
4257 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4260 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4261 if (!charts_updating) cc->UpdateCanvasControlBar();
4264 UpdateGPSCompassStatusBoxes();
4266 SetAllToolbarScale();
4267 RequestNewToolbars();
4269 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4272 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4275 cc->RebuildCursors();
4280 bool b_masterScaleChange =
false;
4282 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4283 b_masterScaleChange =
true;
4285 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4286 RequestNewMasterToolbar(
true);
4288 bool bMuiChange =
false;
4294 if (b_masterScaleChange || bMuiChange) {
4296 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4299 cc->ProcessNewGUIScale();
4305 if (rr & LOCALE_CHANGED) {
4306 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4308 rr |= NEED_NEW_OPTIONS;
4317 g_last_ChartScaleFactor = g_ChartScaleFactor;
4322bool MyFrame::CheckGroup(
int igroup) {
4323 if (igroup == 0)
return true;
4327 if (!pGroup->m_element_array.size())
4330 for (
const auto &elem : pGroup->m_element_array) {
4331 for (
unsigned int ic = 0;
4332 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4333 auto &cte =
ChartData->GetChartTableEntry(ic);
4334 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4336 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4343bool MyFrame::ScrubGroupArray() {
4348 bool b_change =
false;
4349 unsigned int igroup = 0;
4350 while (igroup < g_pGroupArray->GetCount()) {
4351 bool b_chart_in_element =
false;
4354 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4355 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4357 for (
unsigned int ic = 0;
4358 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4359 auto &cte =
ChartData->GetChartTableEntry(ic);
4360 wxString chart_full_path = cte.GetFullSystemPath();
4362 if (chart_full_path.StartsWith(element_root)) {
4363 b_chart_in_element =
true;
4369 if (!b_chart_in_element) {
4370 wxString test_string =
"GSHH";
4371 if (element_root.Upper().Contains(test_string))
4372 b_chart_in_element =
true;
4375 if (!b_chart_in_element)
4377 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4389void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4391 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4393 if (cc && (cc != ccThis)) cc->Refresh();
4398void MyFrame::ChartsRefresh() {
4401 AbstractPlatform::ShowBusySpinner();
4403 bool b_run = FrameTimer1.IsRunning();
4406 FrameTenHzTimer.Stop();
4409 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4412 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4413 if (cc->GetQuiltMode()) {
4414 currentIndex = cc->GetQuiltReferenceChartIndex();
4416 cc->canvasChartsRefresh(currentIndex);
4420 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4421 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4423 AbstractPlatform::HideBusySpinner();
4426void MyFrame::InvalidateAllQuilts() {
4427 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4430 cc->InvalidateQuilt();
4431 cc->SetQuiltRefChart(-1);
4432 cc->m_singleChart = NULL;
4437bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4439 const wxString &ChartListFileName) {
4440 bool b_run = FrameTimer1.IsRunning();
4442 FrameTenHzTimer.Stop();
4444 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4445 FrameCOGTimer.Stop();
4448 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4451 cc->InvalidateQuilt();
4452 cc->SetQuiltRefChart(-1);
4453 cc->m_singleChart = NULL;
4463 AbstractPlatform::ShowBusySpinner();
4466 wxString longmsg = _(
"OpenCPN Chart Update");
4468 ".................................................................."
4471 Updateprog =
new wxGenericProgressDialog();
4474 Updateprog->SetFont(*qFont);
4476 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4477 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4478 wxPD_REMAINING_TIME);
4480 DimeControl(Updateprog);
4485 wxLogMessage(
"Starting chart database Update...");
4489 m_gshhg_chart_loc = gWorldMapLocation;
4490 gWorldMapLocation = wxEmptyString;
4494 AbstractPlatform::HideBusySpinner();
4498void MyFrame::FinalizeChartDBUpdate() {
4500 if (!g_bDeferredInitDone) {
4502 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4505 bool b_groupchange = ScrubGroupArray();
4507 RefreshGroupIndices();
4509 if (b_groupchange) {
4510 pConfig->DestroyConfigGroups();
4515 if (g_bDeferredInitDone) ScheduleReloadCharts();
4520 cc->ToggleCanvasQuiltMode();
4522 bool cur_mode = cc->GetQuiltMode();
4524 if( !cc->GetQuiltMode() )
4525 cc->SetQuiltMode(
true );
4527 if( cc->GetQuiltMode() ) {
4528 cc->SetQuiltMode(
false );
4529 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4533 if( cur_mode != cc->GetQuiltMode() ){
4539 g_bQuiltEnable = cc->GetQuiltMode();
4543 ps52plib->GenerateStateHash();
4551 DoStackDelta(cc, -1);
4557 DoStackDelta(cc, 1);
4560void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4562void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4564void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4566 cc->DoCanvasStackDelta(direction);
4570void MyFrame::PositionIENCToolbar() {
4574 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4576 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4584void MyFrame::OnInitTimer(wxTimerEvent &event) {
4587 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4591 wxLog::FlushActive();
4593 switch (m_iInitCount++) {
4595 EnableSettingsTool(
false);
4600 if (g_bInlandEcdis) {
4601 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4602 double range_set = 500.;
4604 range = wxRound(range * 10) / 10.;
4608 else if (range > 2000.)
4610 else if (range > 1600.)
4612 else if (range > 1200.)
4614 else if (range > 800.)
4619 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4623 g_Platform->SetFullscreen(g_bFullscreen);
4627 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4630 cc->SetGroupIndex(0,
false);
4636 const bool update_started = StartRebuildChartDatabase();
4638 if (update_started) {
4650 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4664 3 * GetCharHeight());
4666 m_data_monitor->Center();
4674 pConfig->SetPath(
"/Settings");
4675 pConfig->Read(
"OptionsSizeX", &sx, -1);
4676 pConfig->Read(
"OptionsSizeY", &sy, -1);
4678 wxWindow *optionsParent =
this;
4680 optionsParent = GetPrimaryCanvas();
4682 BuildiENCToolbar(
true, m_toolbar_callbacks);
4689 if (!g_params.empty()) {
4690 for (
size_t n = 0; n < g_params.size(); n++) {
4691 wxString path = g_params[n];
4692 if (::wxFileExists(path)) {
4694 pSet->load_file(path.fn_str());
4697 pSet->LoadAllGPXObjects(
4698 !pSet->IsOpenCPN(), wpt_dups,
4700 LLBBox box = pSet->GetBBox();
4701 if (box.GetValid()) {
4702 CenterView(GetPrimaryCanvas(), box);
4711 InitAppMsgBusListener();
4716 auto loader = PluginLoader::GetInstance();
4717 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4718 if (!b_haveWMM)
gVar = g_UserVar;
4726 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4729 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4731 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4734 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4738 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4739 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4740 NavObj_dB::GetInstance().LoadNavObjects();
4743 if (!g_AW1GUID.IsEmpty()) {
4746 if (!g_AW2GUID.IsEmpty()) {
4752 appendOSDirSlash(&layerdir);
4753 layerdir.Append(
"layers");
4755 if (wxDir::Exists(layerdir)) {
4757 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4758 wxLogMessage(laymsg);
4759 pConfig->LoadLayers(layerdir);
4764 if (!g_kiosk_startup) {
4765 AbstractPlatform::ShowBusySpinner();
4768 pConfig->SetPath(
"/Settings");
4769 pConfig->Read(
"OptionsSizeX", &sx, -1);
4770 pConfig->Read(
"OptionsSizeY", &sy, -1);
4772 wxWindow *optionsParent =
this;
4774 optionsParent = GetPrimaryCanvas();
4777 callbacks.prepare_close = [&](
options *me,
int changes) {
4778 PrepareOptionsClose(me, changes);
4780 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4781 ProcessOptionsDialog(changes, workdir_list);
4784 wxPoint(-1, -1), wxSize(sx, sy));
4785 AbstractPlatform::HideBusySpinner();
4792 wxLogMessage(
"OnInitTimer...Last Call");
4796 RequestNewMasterToolbar();
4798 PositionIENCToolbar();
4800 g_bDeferredInitDone =
true;
4810 GetPrimaryCanvas()->SetFocus();
4811 GetPrimaryCanvas()->Enable();
4814 if (b_reloadForPlugins) {
4820 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4822 if (cc) cc->SetFirstAuto(
true);
4830 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4832 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4836 cc->CheckGroupValid();
4837 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4838 cc->SetShowGPSCompassWindow(
true);
4843 androidEnableBackButton(
true);
4844 androidEnableRotation();
4845 androidEnableOptionItems(
true);
4849 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4855 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4857 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4859 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4865 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4867 wxLog::FlushActive();
4869 RefreshAllCanvas(
true);
4870 UsbWatchDaemon::GetInstance().Start();
4871 EnableSettingsTool(g_bDeferredInitDone);
4877void MyFrame::InitAppMsgBusListener() {
4878 auto &msgbus = AppMsgBus::GetInstance();
4881 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4882 listener_basic_navdata.Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4886 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4887 HandleBasicNavMsg(basicnav_msg);
4891 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4892 listener_gps_watchdog.Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4896 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4897 HandleGPSWatchdogMsg(msg);
4904void MyFrame::ReleaseApiListeners() {}
4909 m_on_raise_listener.Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4910 m_on_quit_listener.Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4911 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4912 server.open_file_cb = [&](
const std::string &path) {
4913 return m_open_gpx_file(path);
4920void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4921 if (msg->gps_watchdog <= 0) {
4922 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4926 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4931 if (m_fix_start_time.IsValid()) {
4932 wxDateTime now = wxDateTime::Now();
4933 wxTimeSpan span = now - m_fix_start_time;
4934 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4935 auto ¬eman = NotificationManager::GetInstance();
4936 wxString msg = _(
"GNSS Position fix lost");
4937 noteman.AddNotification(NotificationSeverity::kCritical,
4939 m_fix_start_time = wxInvalidDateTime;
4943 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4944 bool last_bVelocityValid = bVelocityValid;
4945 bVelocityValid =
false;
4952void MyFrame::CalculateCOGAverage() {
4954 if (!std::isnan(
gCog)) {
4957 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4960 double sum = 0., count = 0;
4962 double adder = COGTable[i];
4963 if (std::isnan(adder))
continue;
4965 if (fabs(adder -
g_COGAvg) > 180.) {
4979 else if (sum >= 360.)
4988void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4989 m_fixtime = msg->time;
4990 double hdt_data_interval = 0;
4991 double fix_time_interval = 0;
4993 double msgtime = msg->set_time.tv_sec;
4994 double m1 = msg->set_time.tv_nsec / 1e9;
4997 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4998 ((msg->vflag & POS_VALID) == POS_VALID)) {
5000 if (!m_fix_start_time.IsValid()) {
5001 m_fix_start_time = wxDateTime::Now();
5006 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5009 fix_time_gt_last = fix_time_gt;
5010 uint64_t fix_time_gt_now =
5011 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5012 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5016 double implied_sog = dist / (fix_time_interval / 3600);
5021 gLat_gt_m1 = gLat_gt;
5022 gLon_gt_m1 = gLon_gt;
5026 fix_time_gt = fix_time_gt_now;
5030 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5031 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5032 gCog_gt_m1 = gCog_gt;
5042 if (!std::isnan(gCog_gt_m1)) {
5044 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5051 if ((fix_time_gt - fix_time_gt_last) > .08) {
5056 if (gCog_gt > gCog_gt_m1) {
5057 if ((gCog_gt - gCog_gt_m1) > 180.)
5062 if ((gCog_gt_m1 - gCog_gt) > 180.)
5067 difft = fabs(gCog_gt - gCog_gt_m1);
5068 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5076 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5077 tentative_cog_rate_gt *= 1e9;
5078 cog_rate_gt = tentative_cog_rate_gt;
5086 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5089static double hdt_avg;
5090 double hdt_norm =
gHdt;
5091 if(
gHdt > 180) hdt_norm -= 360;
5094 hdt_avg += hdt_norm * 0.1;
5099 if (!std::isnan(
gHdt)) {
5101 uint64_t hdt_time_gt_last = hdt_time_gt;
5102 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5103 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5106 if (hdt_data_interval > .09) {
5108 gHdt_gt_m1 = gHdt_gt;
5111 if (!std::isnan(gHdt_gt_m1)) {
5113 double tentative_hdt_rate_gt =
5114 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5115 tentative_hdt_rate_gt *= 1e9;
5117 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5118 hdt_rate_gt = tentative_hdt_rate_gt;
5126 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5129 CalculateCOGAverage();
5137 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5138 if ((msg->vflag & POS_VALID) == POS_VALID)
5143 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5145 bVelocityValid =
true;
5149void MyFrame::UpdateStatusBar() {
5152 unsigned long uiCurrentTickCount;
5153 m_MMEAeventTime.SetToCurrent();
5154 uiCurrentTickCount =
5155 m_MMEAeventTime.GetMillisecond() / 100;
5156 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5157 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5158 m_ulLastNMEATicktime = uiCurrentTickCount;
5160 if (m_tick_idx++ > 6) m_tick_idx = 0;
5165 if (NULL != GetStatusBar()) {
5168 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5171 wxString s1(tick_buf, wxConvUTF8);
5173 s1 += toSDMM(1,
gLat);
5175 s1 += toSDMM(2,
gLon);
5177 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5181 if (!std::isnan(
gSog))
5182 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5184 sogcog.Printf(
"SOG --- ");
5188 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5190 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5192 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5193 (
int)toMagnetic(
gCog), 0x00B0);
5195 cogs.Printf((
"COG ---%c"), 0x00B0);
5197 sogcog.Append(cogs);
5198 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5203void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5204 MemFootTimer.Stop();
5206 int memsize = GetApplicationMemoryUse();
5209 printf(
"Memsize: %d \n", memsize);
5212 if (memsize > (g_MemFootMB * 1000)) {
5216 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5217 unsigned int nCache = pCache->GetCount();
5220 for (
unsigned int i = 0; i < nCache; i++) {
5230 for (
unsigned int i = 0; i < nCache - 1; i++) {
5231 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5233 pcea[i] = pcea[i + 1];
5244 unsigned int idelete = 0;
5245 unsigned int idelete_max = pCache->GetCount();
5248 unsigned int minimum_cache = 1;
5249 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5251 while ((memsize > (g_MemFootMB * 1000)) &&
5252 (pCache->GetCount() > minimum_cache) &&
5253 (idelete < idelete_max)) {
5254 int memsizeb = memsize;
5258 memsize = GetApplicationMemoryUse();
5259 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5267 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5272void MyFrame::CheckToolbarPosition() {
5275 static bool bMaximized;
5277 if (IsMaximized() && !bMaximized) {
5284 PositionIENCToolbar();
5285 }
else if (!IsMaximized() && bMaximized) {
5293 PositionIENCToolbar();
5298void MyFrame::ProcessUnitTest() {
5299 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5306 cc->m_bFollow =
false;
5308 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5309 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5312 if (cc->m_groupIndex > 0) {
5313 while (ut_index < ChartData->GetChartTableEntries() &&
5314 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5318 if (ut_index < ChartData->GetChartTableEntries()) {
5322 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5323 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5330 if (cc->GetQuiltMode()) {
5331 if (cc->IsChartQuiltableRef(ut_index))
5332 cc->SelectQuiltRefdbChart(ut_index);
5334 cc->SelectdbChart(ut_index);
5337 if (g_unit_test_1) {
5345 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5346 cte->GetLatMin(), cte->GetLonMax(), NULL,
5350 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5351 cte->GetLatMax(), cte->GetLonMin(), NULL,
5354 cc->GetSize(&ww, &wh);
5355 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5357 ppm = wxMin(ppm, 1.0);
5364 if (ut_index > ut_index_max) exit(0);
5375 bool b_rotate =
false;
5377 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5380 if (!b_rotate && !g_btenhertz)
return;
5382 bool b_update =
false;
5384 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5387 struct timespec now;
5388 clock_gettime(CLOCK_MONOTONIC, &now);
5389 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5390 double diffc = diff / 1e9;
5393 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5394 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5395 if (gCog_tentative < 0.) gCog_tentative += 360.;
5396 gCog = gCog_tentative;
5400 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5401 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5402 double diffc = diff / 1e9;
5403 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5407 if (gSog_gt && !std::isnan(gCog_gt)) {
5408 double delta_t = diffc / 3600;
5409 double distance = gSog_gt * delta_t;
5412 double angr = gCog_gt / 180 * M_PI;
5413 double latr = gLat_gt * M_PI / 180;
5414 double D = distance / 3443;
5415 double sD = sin(D), cD = cos(D);
5416 double sy = sin(latr), cy = cos(latr);
5417 double sa = sin(angr), ca = cos(angr);
5419 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5420 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5430 if (cc) cc->DoCanvasCOGSet();
5439 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5440 bool bnew = cc->DoCanvasUpdate();
5441 if (!bnew) cc->UpdateShips();
5450 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5453bool MyFrame::ProcessQuitFlag() {
5457 FrameTenHzTimer.Stop();
5459 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5460 if (top) top->Close(
true);
5467void MyFrame::ProcessDeferredTrackOn() {
5470 if (g_bDeferredStartTrack) {
5471 if (!g_bTrackActive) {
5474 g_bDeferredStartTrack =
false;
5477 g_bDeferredStartTrack =
false;
5482void MyFrame::ProcessAnchorWatch() {
5490 double d = g_nAWMax;
5493 bool toofar =
false;
5494 bool tooclose =
false;
5495 if (d >= 0.0) toofar = (dist * 1852. > d);
5496 if (d < 0.0) tooclose = (dist * 1852 < -d);
5498 if (tooclose || toofar)
5499 AnchorAlertOn1 =
true;
5501 AnchorAlertOn1 =
false;
5503 AnchorAlertOn1 =
false;
5511 double d = g_nAWMax;
5514 bool toofar =
false;
5515 bool tooclose =
false;
5516 if (d >= 0) toofar = (dist * 1852. > d);
5517 if (d < 0) tooclose = (dist * 1852 < -d);
5519 if (tooclose || toofar)
5520 AnchorAlertOn2 =
true;
5522 AnchorAlertOn2 =
false;
5524 AnchorAlertOn2 =
false;
5527 AnchorAlertOn1 =
true;
5530void MyFrame::SendFixToPlugins() {
5541 GPSData.
nSats = g_SatsInView;
5543 wxDateTime tCheck((time_t)m_fixtime);
5544 if (tCheck.IsValid()) {
5553 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5556 SendPositionFixToAllPlugIns(&GPSData);
5560void MyFrame::ProcessLogAndBells() {
5563 wxDateTime lognow = wxDateTime::Now();
5564 int hourLOC = lognow.GetHour();
5565 int minuteLOC = lognow.GetMinute();
5567 int minuteUTC = lognow.GetMinute();
5568 int second = lognow.GetSecond();
5570 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5571 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5572 (minuteUTC == 30)) {
5573 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5574 wxString day = lognow.FormatISODate();
5575 wxString utc = lognow.FormatISOTime();
5576 wxString navmsg =
"LOGBOOK: ";
5584 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5588 if (std::isnan(
gCog))
5589 cog.Printf(
"COG ----- ");
5591 cog.Printf(
"COG %10.5f ",
gCog);
5594 if (std::isnan(
gSog))
5595 sog.Printf(
"SOG ----- ");
5597 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5603 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5606 wxLogMessage(navmsg);
5607 g_loglast_time = lognow;
5609 int bells = (hourLOC % 4) * 2;
5610 if (minuteLOC != 0) bells++;
5611 if (!bells) bells = 8;
5613 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5614 m_BellsToPlay = bells;
5615 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5616 wxPostEvent(
this, ev);
5623 CheckToolbarPosition();
5627 if (ProcessQuitFlag())
return;
5629 if (bDBUpdateInProgress)
return;
5632 FrameTenHzTimer.Stop();
5634 ProcessDeferredTrackOn();
5636 ProcessAnchorWatch();
5637 ProcessLogAndBells();
5639 if (ShouldRestartTrack()) TrackDailyRestart();
5642 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5643 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5644 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5650 if (
gSog > 3.0) g_bCruising =
true;
5656 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5658 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5664 bool bnew_view =
false;
5665 if (!g_btenhertz) bnew_view = DoChartUpdate();
5672 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5675 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5678 cc->DrawBlinkObjects();
5681 if (bactiveRouteUpdate) {
5688 cc->SetOwnShipState(SHIP_NORMAL);
5690 if (cc->GetQuiltMode()) {
5691 double erf = cc->GetQuiltMaxErrorFactor();
5692 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5694 if (cc->m_singleChart) {
5695 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5696 cc->SetOwnShipState(SHIP_LOWACCURACY);
5700 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5703 (bVelocityValid != m_last_bVelocityValid) ||
5704 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5705 if (!g_bopengl) cc->UpdateShips();
5713 m_last_bVelocityValid = bVelocityValid;
5718 bool brq_dynamic =
false;
5720 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5721 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5723 if (pic->m_enabled && pic->m_init_state) {
5724 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5731 if (brq_dynamic) bnew_view =
true;
5735 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5738 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5743 if (cc->GetglCanvas()) {
5745 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5747 if ((!g_btenhertz)) {
5748 if (cc->m_bFollow) {
5749 cc->DoCanvasUpdate();
5766 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5780 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5781 g_pais_query_dialog_active->UpdateText();
5784 if (g_pAISTargetList && (0 == (g_tick % (5))))
5785 g_pAISTargetList->UpdateAISTargetList();
5788 UpdateGPSCompassStatusBoxes();
5793 console->RefreshConsoleData();
5800 if (m_bdefer_resize) {
5801 if (0 == (g_tick % (5))) {
5802 printf(
"___RESIZE\n");
5803 SetSize(m_defer_size);
5805 m_bdefer_resize =
false;
5812 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5814 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5815 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5819double MyFrame::GetMag(
double a,
double lat,
double lon) {
5820 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5821 auto loader = PluginLoader::GetInstance();
5822 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5829 wxDateTime now = wxDateTime::Now();
5830 SendJSON_WMM_Var_Request(lat, lon, now);
5831 if (fabs(gQueryVar) < 360.0)
5832 Variance = gQueryVar;
5834 return toMagnetic(a, Variance);
5837bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5843 v[
"Year"] = date.GetYear();
5844 v[
"Month"] = date.GetMonth();
5845 v[
"Day"] = date.GetDay();
5847 SendJsonMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5853void MyFrame::TouchAISActive() {
5855 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5857 if (cc) cc->TouchAISToolActive();
5861void MyFrame::UpdateAISTool() {
5865 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5867 if (cc) cc->UpdateAISTBTool();
5872void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5874 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5876 if (cc) cc->SetbTCUpdate(
true);
5879 RefreshAllCanvas(
false);
5884void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5888 bool b_rotate =
false;
5889 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5891 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5895 FrameCOGTimer.Stop();
5902 int period_ms = 100;
5904 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5907void MyFrame::DoCOGSet() {
5909 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5911 if (cc) cc->DoCanvasCOGSet();
5915void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5921 wxFont oldfont = pdc->GetFont();
5923 pdc->SetFont(*pFont);
5924 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5925 pdc->SetBackgroundMode(wxTRANSPARENT);
5927 pdc->DrawText(str, x, y + 1);
5928 pdc->DrawText(str, x, y - 1);
5929 pdc->DrawText(str, x + 1, y);
5930 pdc->DrawText(str, x - 1, y);
5932 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5934 pdc->DrawText(str, x, y);
5936 pdc->SetFont(oldfont);
5940void MyFrame::UpdateRotationState(
double rotation) {
5942 g_bCourseUp =
false;
5944 if (fabs(rotation) > .001) {
5945 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5946 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5948 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5951 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5952 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5954 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5958 UpdateGPSCompassStatusBoxes(
true);
5962void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5964 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5966 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5972int MyFrame::GetApplicationMemoryUse() {
5978 wxWindow *fWin = wxWindow::FindFocus();
5980 wxArrayString outputArray;
5981 wxString cmd(
"ps --no-headers -o vsize ");
5982 unsigned long pid = wxGetProcessId();
5984 cmd1.Printf(
"%ld", pid);
5986 wxExecute(cmd, outputArray);
5988 if (outputArray.GetCount()) {
5989 wxString s = outputArray.Item(0);
5991 if (s.ToLong(&vtmp)) memsize = vtmp;
5994 if (fWin) fWin->SetFocus();
6000 PROCESS_MEMORY_COUNTERS pmc;
6002 unsigned long processID = wxGetProcessId();
6004 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6006 if (NULL == hProcess)
return 0;
6008 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6026 memsize = pmc.WorkingSetSize / 1024;
6029 CloseHandle(hProcess);
6036double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6037 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6040void MyFrame::SetChartUpdatePeriod() {
6043 g_ChartUpdatePeriod = 0;
6048 bool bskewdc =
false;
6049 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6052 if (!g_bopengl && !cc->GetVP().b_quilt) {
6053 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6055 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6059 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6061 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6066 cc->UpdateCanvasControlBar();
6069void MyFrame::selectChartDisplay(
int type,
int family) {
6071 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6073 if (cc) cc->selectCanvasChartDisplay(type, family);
6076 UpdateGlobalMenuItems();
6085bool MyFrame::DoChartUpdate() {
6086 bool return_val =
false;
6089 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6091 if (cc) return_val |= cc->DoCanvasUpdate();
6097void MyFrame::MouseEvent(wxMouseEvent &event) {
6099 event.GetPosition(&x, &y);
6104#include <mach/mach.h>
6105#include <mach/message.h>
6106#include <mach/kern_return.h>
6107#include <mach/task_info.h>
6109#include <malloc/malloc.h>
6116#if defined(__linux__)
6117#include "sys/types.h"
6118#include "sys/sysinfo.h"
6121void MyFrame::DoPrint(
void) {
6123 g_PrintingInProgress =
true;
6126 GetPrimaryCanvas()->GetglCanvas()->Render();
6127 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6137 printer.Initialize(wxLANDSCAPE);
6138 printer.EnablePageNumbers(
false);
6141 bool tooltips_were_enabled = DisableTbarTooltips();
6142 printer.Print(
this, &printout);
6143 if (tooltips_were_enabled) {
6144 EnableTbarTooltips();
6163 g_PrintingInProgress =
false;
6166 GetPrimaryCanvas()->SetFocus();
6172 wxString message_ID =
event.GetID();
6173 wxString message_JSONText =
event.GetJSONText();
6181 if (message_ID ==
"WMM_VARIATION_BOAT") {
6182 nlohmann::json root;
6184 root = nlohmann::json::parse(message_JSONText);
6185 }
catch (nlohmann::json::exception &) {
6190 gVar = root[
"Decl"].get<
double>();
6191 }
catch (nlohmann::json::exception &) {
6197 if (message_ID ==
"WMM_VARIATION") {
6198 nlohmann::json root;
6200 root = nlohmann::json::parse(message_JSONText);
6201 }
catch (nlohmann::json::exception &) {
6204 wxString decl = root[
"Decl"].get<std::string>();
6206 decl.ToDouble(&decl_val);
6208 gQueryVar = decl_val;
6211 if (message_ID ==
"GRIB_TIMELINE") {
6214 v = nlohmann::json::parse(message_JSONText);
6215 }
catch (nlohmann::json::exception &) {
6216 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6219 wxDateTime oldTimeSource = gTimeSource;
6221 if (v[
"Day"].get<int>() == -1) {
6222 gTimeSource = wxInvalidDateTime;
6223 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6225 gTimeSource.Set(v[
"Day"].get<int>(),
6226 (wxDateTime::Month)v[
"Month"].get<int>(),
6227 v[
"Year"].get<int>(), v[
"Hour"].get<int>(),
6228 v[
"Minute"].get<int>(), v[
"Second"].get<int>());
6232 if (oldTimeSource != gTimeSource) {
6234 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6236 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6241 cc->pCwin->Refresh(
false);
6247 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6248 nlohmann::json root;
6249 wxString trk_id =
"";
6252 root = nlohmann::json::parse(message_JSONText);
6253 }
catch (nlohmann::json::exception &) {
6256 if (root.contains(
"Track_ID")) trk_id = root[
"Track_ID"].get<std::string>();
6259 v[
"Track_ID"] = trk_id;
6261 wxString name = wxEmptyString;
6262 if (ptrack->m_GUID == trk_id) {
6263 name = ptrack->GetName();
6264 if (name.IsEmpty()) {
6270 name = _(
"(Unnamed Track)");
6277 v[
"TotalNodes"] = ptrack->GetnPoints();
6278 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6280 v[
"lat"] = tp->m_lat;
6281 v[
"lon"] = tp->m_lon;
6284 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6289 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6291 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6292 nlohmann::json root;
6295 root = nlohmann::json::parse(message_JSONText);
6296 }
catch (nlohmann::json::exception &) {
6300 if (root.contains(
"GUID")) guid = root[
"GUID"].get<std::string>();
6305 wxString name = wxEmptyString;
6307 if ((*it)->m_GUID == guid) {
6308 name = (*it)->m_RouteNameString;
6309 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6315 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6316 itp != (*it)->pRoutePointList->end(); itp++) {
6317 w[i][
"lat"] = (*itp)->m_lat;
6318 w[i][
"lon"] = (*itp)->m_lon;
6319 w[i][
"Name"] = (*itp)->GetName();
6320 w[i][
"Description"] = (*itp)->GetDescription();
6321 w[i][
"GUID"] = (*itp)->m_GUID;
6322 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6324 auto node = (*itp)->m_HyperlinkList->begin();
6325 if (node != (*itp)->m_HyperlinkList->end()) {
6327 while (node != (*itp)->m_HyperlinkList->end()) {
6329 v[i][
"WPLink" + std::to_string(n)] = httpLink->Link;
6330 v[i][
"WPLinkDesciption" + std::to_string(n++)] =
6331 httpLink->DescrText;
6338 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6344 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6345 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6346 nlohmann::json root;
6349 root = nlohmann::json::parse(message_JSONText);
6350 }
catch (nlohmann::json::exception &) {
6353 if (root.contains(
"mode")) {
6354 if (root[
"mode"].get<std::string>() ==
"Track") route =
false;
6359 for (RouteList::iterator it =
pRouteList->begin();
6361 wxString name = (*it)->m_RouteNameString;
6362 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6364 v[i][
"error"] =
false;
6365 v[i][
"name"] = name;
6366 v[i][
"GUID"] = (*it)->m_GUID;
6367 v[i][
"active"] = (*it)->IsActive();
6372 wxString name = ptrack->GetName();
6373 if (name.IsEmpty()) {
6379 name = _(
"(Unnamed Track)");
6381 v[i][
"error"] =
false;
6382 v[i][
"name"] = name;
6383 v[i][
"GUID"] = ptrack->m_GUID;
6388 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6391 v[0][
"error"] =
true;
6392 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6394 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6396 v[0][
"error"] =
true;
6399 v[0][
"error"] =
false;
6400 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6401 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6402 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6403 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6404 v[0][
"active_waypoint_lat"] =
6406 v[0][
"active_waypoint_lon"] =
6410 SendJsonMessageToAllPlugins(
"OCPN_ACTIVE_ROUTELEG_RESPONSE", v);
6414void MyFrame::FilterCogSog() {
6415 if (g_bfilter_cogsog) {
6417 double cog_last =
gCog;
6420 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6421 COGFilterTable[i] = COGFilterTable[i - 1];
6422 COGFilterTable[0] = cog_last;
6425 if (!std::isnan(cog_last)) {
6427 double sum = 0., count = 0;
6428 for (
int i = 0; i < g_COGFilterSec; i++) {
6429 double adder = COGFilterTable[i];
6430 if (std::isnan(adder))
continue;
6432 if (fabs(adder - cog_last) > 180.) {
6433 if ((adder - cog_last) > 0.)
6446 else if (sum >= 360.)
6453 double sog_last =
gSog;
6456 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6457 SOGFilterTable[i] = SOGFilterTable[i - 1];
6458 SOGFilterTable[0] = sog_last;
6461 if (!std::isnan(
gSog)) {
6462 double sum = 0., count = 0;
6463 for (
int i = 0; i < g_SOGFilterSec; i++) {
6464 if (std::isnan(SOGFilterTable[i]))
continue;
6466 sum += SOGFilterTable[i];
6476void MyFrame::LoadHarmonics() {
6479 ptcmgr->LoadDataSources(TideCurrentDataSet);
6481 bool b_newdataset =
false;
6484 for (
auto a :
ptcmgr->GetDataSet()) {
6485 bool b_foundi =
false;
6486 for (
auto b : TideCurrentDataSet) {
6493 b_newdataset =
true;
6498 for (
auto a : TideCurrentDataSet) {
6499 bool b_foundi =
false;
6500 for (
auto b :
ptcmgr->GetDataSet()) {
6507 b_newdataset =
true;
6512 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6516void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6517 if (!ptarget)
return;
6520 wxDateTime mob_time = wxDateTime::Now();
6521 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6522 mob_label += _(
" on ");
6523 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6526 mob_label, wxEmptyString);
6527 pWP_MOB->SetShared(
true);
6529 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6531 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6533 pWP_MOB->SetUseSca(
false);
6541 wxString(_(
"Own ship")), wxEmptyString);
6543 pWP_MOB->SetUseSca(
false);
6550 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6566 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
6569 if (RouteManagerDialog::getInstanceFlag()) {
6576 RefreshAllCanvas(
false);
6578 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6579 mob_message += _(
" Time: ");
6580 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6581 mob_message += _(
" Ownship Position: ");
6582 mob_message += toSDMM(1,
gLat);
6584 mob_message += toSDMM(2,
gLon);
6585 mob_message += _(
" MOB Position: ");
6586 mob_message += toSDMM(1, ptarget->Lat);
6588 mob_message += toSDMM(2, ptarget->Lon);
6589 wxLogMessage(mob_message);
6592void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6596 OwnPoint->m_lat =
gLat;
6597 OwnPoint->m_lon =
gLon;
6599 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6604 MOB_Point->m_lat = ptarget->Lat;
6605 MOB_Point->m_lon = ptarget->Lon;
6607 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6608 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6610 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6611 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6614 RefreshAllCanvas(
false);
6617 wxDateTime mob_time = wxDateTime::Now();
6619 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6620 mob_message += _(
" Time: ");
6621 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6622 mob_message += _(
" Ownship Position: ");
6623 mob_message += toSDMM(1,
gLat);
6625 mob_message += toSDMM(2,
gLon);
6626 mob_message += _(
" MOB Position: ");
6627 mob_message += toSDMM(1, ptarget->Lat);
6629 mob_message += toSDMM(2, ptarget->Lon);
6631 wxLogMessage(mob_message);
6635void MyFrame::applySettingsString(wxString settings) {
6637 int last_UIScaleFactor = g_GUIScaleFactor;
6638 bool previous_expert = g_bUIexpert;
6639 g_last_ChartScaleFactor = g_ChartScaleFactor;
6640 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6643 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6649 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6651 if (rr & S52_CHANGED) {
6653 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6655 ->ClearCNSYLUPArray();
6656 ps52plib->GenerateStateHash();
6660 ProcessOptionsDialog(rr, pNewDirArray);
6665 bool b_newToolbar =
false;
6667 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6669 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6671 if (rr & TOOLBAR_CHANGED) {
6672 b_newToolbar =
true;
6677 if (previous_expert && !g_bUIexpert) {
6678 androidForceFullRepaint();
6682 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6686 SetGPSCompassScale();
6688 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6690 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6692 UpdateGPSCompassStatusBoxes(
true);
6695 AbstractPlatform::ShowBusySpinner();
6697 SetAllToolbarScale();
6701 AbstractPlatform::HideBusySpinner();
6703 RequestNewMasterToolbar(
true);
6710 UpdateControlBar(GetPrimaryCanvas());
6716 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6719#ifdef wxHAS_POWER_EVENTS
6720void MyFrame::OnSuspending(wxPowerEvent &event) {
6724 wxLogMessage(
"System suspend starting...");
6727void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6730 wxLogMessage(
"System is going to suspend.");
6733void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6736 wxLogMessage(
"System suspend was cancelled.");
6739int g_last_resume_ticks;
6740void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6741 wxDateTime now = wxDateTime::Now();
6742 wxLogMessage(
"System resumed from suspend.");
6744 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6745 SystemEvents::GetInstance().
evt_resume.Notify();
6747 wxLogMessage(
"Restarting streams.");
6748 g_last_resume_ticks = now.GetTicks();
6752 g_pMUX->ClearStreams();
6754 g_pMUX->StartAllStreams();
6763 if (IsMaximized()) {
6768 wxSize sz = GetSize();
6769 SetSize(wxSize(sz.x - 1, sz.y));
6781void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6782 bool btbRebuild =
false;
6784 bool b_reshow =
true;
6787 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6788 if ((ff > 0.01f) || bforcenew) {
6798 long orient = g_Platform->GetDefaultToolbarOrientation();
6799 wxWindow *toolbarParent =
this;
6801 toolbarParent = GetPrimaryCanvas();
6804 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6805 m_toolbar_callbacks);
6807 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6814 g_bmasterToolbarFull =
true;
6818 CreateMasterToolbar();
6833bool MyFrame::CollapseGlobalToolbar() {
6835 m_nMasterToolCountShown = 1;
6839 g_bmasterToolbarFull =
false;
6855 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6856 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6857 tic->m_bRequired =
true;
6862 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6863 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6867 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6868 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6869 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6874 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6875 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6879 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6880 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6881 _(
"Enable Tracking"),
"MUI_track");
6885 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6886 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6898 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6899 _(
"Print Chart"),
"MUI_print");
6903 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6904 _(
"About OpenCPN"),
"MUI_help");
6908 AddDefaultPositionPlugInTools();
6912 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6913 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6924 ArrayOfPlugInToolbarTools tool_array =
6926 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6928 if (!pttc->b_viz)
continue;
6930 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6933 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6934 if (g_bTrackActive) {
6935 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6942bool MyFrame::CheckAndAddPlugInTool() {
6950 if (!tb)
return false;
6952 int n_tools = tb->GetToolsCount();
6956 ArrayOfPlugInToolbarTools tool_array =
6959 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6961 if (pttc->position == n_tools) {
6962 wxBitmap *ptool_bmp;
6964 switch (global_color_scheme) {
6965 case GLOBAL_COLOR_SCHEME_DAY:
6966 ptool_bmp = pttc->bitmap_day;
6969 case GLOBAL_COLOR_SCHEME_DUSK:
6970 ptool_bmp = pttc->bitmap_dusk;
6972 case GLOBAL_COLOR_SCHEME_NIGHT:
6973 ptool_bmp = pttc->bitmap_night;
6976 ptool_bmp = pttc->bitmap_day;
6981 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6983 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6984 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6985 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6986 tic->m_bPlugin =
true;
6995 while (CheckAndAddPlugInTool()) {
7001bool MyFrame::AddDefaultPositionPlugInTools() {
7008 ArrayOfPlugInToolbarTools tool_array =
7011 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7015 if (!pttc->b_viz)
continue;
7017 if (pttc->position == -1)
7019 wxBitmap *ptool_bmp;
7021 switch (global_color_scheme) {
7022 case GLOBAL_COLOR_SCHEME_DAY:
7023 ptool_bmp = pttc->bitmap_day;
7025 case GLOBAL_COLOR_SCHEME_DUSK:
7026 ptool_bmp = pttc->bitmap_dusk;
7028 case GLOBAL_COLOR_SCHEME_NIGHT:
7029 ptool_bmp = pttc->bitmap_night;
7032 ptool_bmp = pttc->bitmap_day;
7037 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7039 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7040 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7041 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7042 tic->m_bPlugin =
true;
7061typedef struct _MSW_COLOR_SPEC {
7063 wxString S52_RGB_COLOR;
7067MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7068 {COLOR_MENUTEXT,
"UITX1", 0},
7069 {COLOR_BTNSHADOW,
"UIBCK", 0},
7072void SaveSystemColors() {
7086 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7087 while (pcspec->COLOR_NAME != -1) {
7088 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7093void RestoreSystemColors() {
7094 int element[NCOLORS];
7095 int rgbcolor[NCOLORS];
7098 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7099 while (pcspec->COLOR_NAME != -1) {
7100 element[i] = pcspec->COLOR_NAME;
7101 rgbcolor[i] = pcspec->SysRGB_COLOR;
7106 if (pSetSysColors) {
7107 pSetSysColors(i, (
unsigned long *)&element[0],
7108 (
unsigned long *)&rgbcolor[0]);
7114void SetSystemColors(ColorScheme cs) {
7116 int element[NCOLORS];
7117 int rgbcolor[NCOLORS];
7119 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7120 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7121 while (pcspec->COLOR_NAME != -1) {
7122 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7123 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7124 element[i] = pcspec->COLOR_NAME;
7130 pSetSysColors(i, (
unsigned long *)&element[0],
7131 (
unsigned long *)&rgbcolor[0]);
7135 RestoreSystemColors();
7142static const WORD MAX_CONSOLE_LINES =
7147void RedirectIOToConsole()
7152 wxIntPtr lStdHandle;
7154 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7164 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7165 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7166 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7170 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7171 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7172 fp = _fdopen(hConHandle,
"w");
7174 setvbuf(stdout, NULL, _IONBF, 0);
7178 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7179 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7180 fp = _fdopen(hConHandle,
"r");
7182 setvbuf(stdin, NULL, _IONBF, 0);
7186 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7187 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7188 fp = _fdopen(hConHandle,
"w");
7190 setvbuf(stderr, NULL, _IONBF, 0);
7201 FontMgr::Get().SetLocale(g_locale);
7222 if (g_pais_query_dialog_active) {
7223 g_pais_query_dialog_active->Destroy();
7224 g_pais_query_dialog_active = NULL;
7227 auto alert_dlg_active =
7229 if (alert_dlg_active) {
7230 alert_dlg_active->Destroy();
7231 g_pais_alert_dialog_active =
nullptr;
7234 if (g_pAISTargetList) {
7236 g_pAISTargetList->Disconnect_decoder();
7237 g_pAISTargetList->Destroy();
7238 g_pAISTargetList = NULL;
7242 if (gFrame->m_pMenuBar) {
7243 gFrame->SetMenuBar(NULL);
7244 gFrame->m_pMenuBar->Destroy();
7245 gFrame->m_pMenuBar = NULL;
7247 gFrame->BuildMenuBar();
7250 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7252 if (cc) cc->CanvasApplyLocale();
7257 wxString perspective;
7259 pConfig->Read(
"AUIPerspective", &perspective);
7273 bool bno_load =
false;
7274 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7276 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7277 wxAuiPaneInfo pane = pane_array_val[i];
7278 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7284 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7289 gFrame->RequestNewToolbars(
true);
7290 gFrame->RequestNewMasterToolbar(
true);
7297 : wxThread(wxTHREAD_JOINABLE) {
7298 m_filename = filename;
7309 newChart->SetNativeScale(m_scale);
7310 newChart->SetFullExtent(m_ext);
7312 newChart->FindOrCreateSenc(m_filename);
7317 wxString m_filename;
7323static double chart_dist(
int index) {
7329 if (cte.GetBBox().Contains(
gLat,
gLon))
7334 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7335 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7336 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7339 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7340 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7342 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7348WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7349static int CompareInts(
int n1,
int n2) {
7350 double d1 = chart_dist(n1);
7351 double d2 = chart_dist(n2);
7352 return (
int)(d1 - d2);
7357 wxString chart_path;
7362WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7364#include <wx/arrimpl.cpp>
7367void ParseAllENC(wxWindow *parent) {
7368 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7376 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7379 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7381 idx_sorted_by_distance.Add(i);
7385 if (count == 0)
return;
7387 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7393 ArrayOfCompressTargets ct_array;
7394 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7395 int i = idx_sorted_by_distance[j];
7398 double distance = chart_dist(i);
7400 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7403 pct->distance = distance;
7404 pct->chart_path = filename;
7406 ct_array.push_back(pct);
7409 int thread_count = 0;
7412 if (g_nCPUCount > 0)
7413 thread_count = g_nCPUCount;
7415 thread_count = wxThread::GetCPUCount();
7417 if (thread_count < 1) {
7426 for(
int t = 0; t < thread_count; t++)
7430 wxGenericProgressDialog *prog =
nullptr;
7434 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7435 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7437 prog =
new wxGenericProgressDialog();
7439 prog->SetFont(*qFont);
7441 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7442 count + 1, parent, style);
7451 prog->ShowWindowModal();
7460 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7461 wxString filename = ct_array[j].chart_path;
7462 double distance = ct_array[j].distance;
7463 int index =
ChartData->FinddbIndex(filename);
7464 if (index < 0)
continue;
7467 ext.NLAT = cte.GetLatMax();
7468 ext.SLAT = cte.GetLatMin();
7469 ext.WLON = cte.GetLonMin();
7470 ext.ELON = cte.GetLonMax();
7472 int scale = cte.GetScale();
7475 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7478 if (wxThread::IsMain()) {
7480 wxSize sz = prog->GetSize();
7485 prog->Update(count, msg, &skip);
7497 newChart->SetNativeScale(
scale);
7498 newChart->SetFullExtent(ext);
7499 newChart->DisableBackgroundSENC();
7501 newChart->FindOrCreateSenc(filename,
7505 if (wxThread::IsMain()) {
7506 msg.Printf(_(
"ENC Completed."));
7508 prog->Update(count, msg, &skip);
7518 for (
int t = 0;; t = (t + 1) % thread_count) {
7525 if (!workers[t]->IsAlive()) {
7538#if defined(__WXMSW__) || defined(__WXOSX__)
7545 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
AisInfoGui * g_pAISGUI
Global instance.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
arrayofCanvasPtr g_canvasArray
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
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.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Minimal ChartCAnvas interface with very little dependencies.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
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.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
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)
Centers the view on a specific lat/lon position.
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.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
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)
Get a font object for a UI element.
obs::EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
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.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
AbstractRestServer implementation and interface to underlying IO thread.
std::string GetEndpoint() override
Return HTTPS url to local rest server.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
obs::EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
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.
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.
Device context class that can use either wxDC or OpenGL for drawing.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
CommBridge class and helpers.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
double AnchorDistFix(double const d, double const AnchorPointMinDist, double const AnchorPointMaxDist)
Return constrained value of d so that AnchorPointMinDist < abs(d) < AnchorPointMaxDist.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
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()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Miscellaneous utilities, many of which string related.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
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.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
Generic hardware events interface.
WaypointMan drawing stuff.