53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
83#include "model/nav_object_database.h"
97#include "ais_info_gui.h"
98#include "dialog_alert.h"
102#include "ais_info_gui.h"
126#include "load_errors_dlg.h"
129#include "N2KParser.h"
152#include "user_colors.h"
158#include "androidUTIL.h"
162static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
173GLenum g_texture_rectangle_format;
176#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
177extern wxLocale *plocale_def_lang;
181extern bool g_b_EnableVBO;
182extern GLenum g_texture_rectangle_format;
186static int g_last_ChartScaleFactor;
187static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
188static int options_subpage = 0;
189static bool b_reloadForPlugins;
191static wxSize options_lastWindowSize(0, 0);
192static wxPoint options_lastWindowPos(0, 0);
196static double gQueryVar = 361.0;
198static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
199static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
201static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
207typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
208typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
210static SetSysColors_t pSetSysColors;
211static GetSysColor_t pGetSysColor;
213void SaveSystemColors();
214void RestoreSystemColors();
219DWORD color_3ddkshadow;
221DWORD color_activecaption;
222DWORD color_gradientactivecaption;
223DWORD color_captiontext;
224DWORD color_windowframe;
225DWORD color_inactiveborder;
230#include <wx/msw/msvcrt.h>
234static const long long lNaN = 0xfff8000000000000;
235#define NAN (*(double *)&lNaN)
239static double gLat_gt, gLon_gt;
240static double gLat_gt_m1, gLon_gt_m1;
241static uint64_t fix_time_gt;
242static uint64_t fix_time_gt_last;
244static double gSog_gt, gHdt_gt;
245static double gCog_gt_m1, gHdt_gt_m1;
246static uint64_t hdt_time_gt;
247static double cog_rate_gt, hdt_rate_gt;
249void InitializeUserColors();
250void DeInitializeUserColors();
251void SetSystemColors(ColorScheme cs);
253static bool LoadAllPlugIns(
bool load_enabled) {
254 AbstractPlatform::ShowBusySpinner();
255 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
256 AbstractPlatform::HideBusySpinner();
260static void LaunchLocalHelp() {
262 androidLaunchHelpView();
264 wxString def_lang_canonical =
"en_US";
267 if (plocale_def_lang)
268 def_lang_canonical = plocale_def_lang->GetCanonicalName();
271 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
273 wxString help_try = help_locn + def_lang_canonical +
".html";
275 if (!::wxFileExists(help_try)) {
276 help_try = help_locn +
"en_US" +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"web" +
".html";
282 if (!::wxFileExists(help_try))
return;
285 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
290static wxString _menuText(wxString name, wxString shortcut) {
294 menutext <<
"\t" << shortcut;
299static void DoHelpDialog() {
311 [] { LaunchLocalHelp(); });
323#if defined(__WXGTK__) || defined(__WXQT__)
324#include "bitmaps/opencpn.xpm"
339 if (g_bInlandEcdis) {
343 wxPoint tbp_incanvas =
346 g_iENCToolbarPosY = tbp_incanvas.y;
347 g_iENCToolbarPosX = tbp_incanvas.x;
355 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
359 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
362 g_iENCToolbarPosY = -1;
365 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
371 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
375 double tool_scale_factor =
376 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
378 tool_scale_factor, callbacks);
388#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
391static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
392 const char *prop_name) {
396 unsigned long ret_nitems;
397 unsigned long ret_bytes_after;
398 unsigned char *ret_prop;
400 xa_prop_name = XInternAtom(disp, prop_name, False);
408 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
409 &xa_ret_type, &ret_format, &ret_nitems,
410 &ret_bytes_after, &ret_prop) != Success)
413 if (xa_ret_type != xa_prop_type) {
417 return (
char *)ret_prop;
422static bool isTransparentToolbarInOpenGLOK() {
429 if (!g_bdisable_opengl) {
430 Display *disp = XOpenDisplay(NULL);
432 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
434 "_NET_SUPPORTING_WM_CHECK")) ||
435 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_WIN_SUPPORTING_WM_CHECK"))) {
440 if ((wm_name = get_X11_property(disp, *sup_window,
441 XInternAtom(disp,
"UTF8_STRING", False),
443 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
446 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
461wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
463 font->GetFamily(), font->GetStyle(),
464 font->GetWeight(),
false, font->GetFaceName());
466wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
467 wxFontStyle style, wxFontWeight weight,
468 const wxString faceName,
double scale) {
472wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
473 return GetOCPNScaledFont_PlugIn(label, Ptsize);
482wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
484BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
485EVT_CLOSE(MyFrame::OnCloseWindow)
486EVT_MENU(wxID_EXIT, MyFrame::OnExit)
487EVT_SIZE(MyFrame::OnSize)
488EVT_MOVE(MyFrame::OnMove)
489EVT_ICONIZE(MyFrame::OnIconize)
490EVT_MENU(-1, MyFrame::OnToolLeftClick)
491EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
493EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
494EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
495EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
497EVT_MAXIMIZE(MyFrame::OnMaximize)
498EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
499 MyFrame::RequestNewToolbarArgEvent)
500EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
502EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
503EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
504EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
506#ifdef wxHAS_POWER_EVENTS
507EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
508EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
509EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
510EVT_POWER_RESUME(MyFrame::OnResume)
521static
void onBellsFinishedCB(
void *ptr) {
522 auto framePtr =
static_cast<MyFrame *
>(ptr);
524 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
525 wxPostEvent(framePtr, ev);
530 auto msg = ev.GetString().ToStdString();
531 auto ¬eman = NotificationManager::GetInstance();
532 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
535static NmeaLog *GetDataMonitor() {
536 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
537 return dynamic_cast<NmeaLog *
>(w);
540MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
541 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
542 OpenFileFunc open_gpx_file)
544 m_connections_dlg(nullptr),
546 m_pauidockart(pauidockart),
547 m_rest_server(rest_server),
548 m_open_gpx_file(open_gpx_file) {
560 m_ulLastNMEATicktime = 0;
561 m_data_monitor->Hide();
563 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
567 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
570 InitTimer.SetOwner(
this, INIT_TIMER);
572 m_initializing =
false;
573 m_toolbar_callbacks.render_gl_textures =
575 [&](
ocpnDC &dc,
float *coords,
float *uv) {
576 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
577 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
580 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
584 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
587 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
590 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
593 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
596 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
598 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
607 m_bTimeIsSet =
false;
608 m_bdefer_resize =
false;
611 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
612 COGFilterTable[i] = NAN;
613 SOGFilterTable[i] = NAN;
615 m_last_bGPSValid =
false;
616 m_last_bVelocityValid =
false;
626 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
631 double process_noise_std = 1.0;
632 double measurement_noise_std = 0.5;
636 m_ChartUpdatePeriod = 1;
641 log_callbacks.log_is_active = [&]() {
642 auto log = GetDataMonitor();
643 return log && log->IsVisible();
645 log_callbacks.log_message = [&](
Logline ll) {
646 NmeaLog *monitor = GetDataMonitor();
649 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
652 ais_callbacks.confirm_stop_track = []() {
653 int r = OCPNMessageBox(
655 _(
"This AIS target has Persistent tracking selected by MMSI "
657 "A Persistent track recording will therefore be restarted for this "
659 "Do you instead want to stop Persistent tracking for this target?"),
660 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
661 return r == wxID_YES;
663 ais_callbacks.get_target_mmsi = []() {
664 auto alert_dlg_active =
666 assert(alert_dlg_active);
667 return alert_dlg_active->Get_Dialog_MMSI();
675 wxLogMessage(
" **** Connect stuff");
681 Connect(wxEVT_OCPN_MSG,
682 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
690 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
698#if defined(__WXGTK__) || defined(__WXQT__)
699 wxIcon app_icon(opencpn);
707 wxDynamicLibrary dllUser32(
"user32.dll");
709 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
710 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
715 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
720 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
721 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
723 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
724 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
725 [&](wxCommandEvent) { Refresh(); });
726 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
728 m_update_statusbar_listener.Init(
729 GuiEvents::GetInstance().gframe_update_status_bar,
731 m_center_aistarget_listener.Init(
732 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
733 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
734 CenterAisTarget(ais_target);
736 m_reload_charts_listener.Init(
737 GuiEvents::GetInstance().on_finalize_chartdbs,
738 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
742 EnableFullScreenView();
744 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
750 FrameTenHzTimer.Stop();
765 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
771void MyFrame::FreezeCharts() {
774 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
776 if (cc && !cc->IsFrozen()) cc->Freeze();
780void MyFrame::CenterAisTarget(
781 const std::shared_ptr<const AisTargetData> &ais_target) {
789 double factor = cc->GetScaleValue() / 5000.0;
790 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
796void MyFrame::ThawCharts() {
799 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
801 if (cc && cc->IsFrozen()) cc->Thaw();
808 switch (event.type) {
809 case SENC_BUILD_STARTED:
812 case SENC_BUILD_DONE_NOERROR:
814 chart =
event.m_ticket->m_chart;
816 chart->PostInit(FULL_INIT, global_color_scheme);
818 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
820 if (cc) cc->ClearS52PLIBStateHash();
825 delete event.m_ticket;
827 case SENC_BUILD_DONE_ERROR:
835void MyFrame::StartRebuildChartDatabase() {
836 bool b_SetInitialPoint =
false;
839 ArrayOfCDI ChartDirArray;
840 pConfig->LoadChartDirArray(ChartDirArray);
842 if (ChartDirArray.GetCount()) {
847 _(
"OpenCPN needs to update the chart database from config file "
851 wxICON_INFORMATION | wxOK);
859 _(
"Rebuilding chart database from configuration file entries..."));
863 wxString dummy1 = _(
"Elapsed time : ");
864 wxString dummy2 = _(
"Estimated time : ");
865 wxString dummy3 = _(
"Remaining time : ");
866 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
867 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
875void MyFrame::OnBellsFinished(wxCommandEvent &event) {
876 int bells = wxMin(m_BellsToPlay, 2);
877 if (bells <= 0)
return;
879 wxString soundfile =
"sounds";
880 appendOSDirSlash(&soundfile);
881 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
882 soundfile.Prepend(g_Platform->GetSharedDataDir());
883 wxLogMessage(
"Using bells sound file: " + soundfile);
885 o_sound::Sound *sound = bells_sound[bells - 1];
886 sound->SetFinishedCallback(onBellsFinishedCB,
this);
887 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
888 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
889 sound->Load(soundfile);
890 if (!sound->IsOk()) {
891 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
895 m_BellsToPlay -= bells;
898void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
900void MyFrame::OnMaximize(wxMaximizeEvent &event) {
907void MyFrame::ReloadAllVP() {
908 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
910 if (cc) cc->ReloadVP();
914void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
915 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
918 global_color_scheme = cs;
921 case GLOBAL_COLOR_SCHEME_DAY:
924 case GLOBAL_COLOR_SCHEME_DUSK:
927 case GLOBAL_COLOR_SCHEME_NIGHT:
928 SchemeName =
"NIGHT";
935 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
937 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
938 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
939 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
940 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
941 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
943 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
972 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
973 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
977 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
979 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
983 user_colors::GetMapByScheme(SchemeName.ToStdString());
988 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
991 cc->SetColorScheme(cs);
992 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
993 cc->HideChartInfoWindow();
994 cc->SetQuiltChartHiLiteIndex(-1);
1000 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1012 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1025 if (g_pais_query_dialog_active) {
1026 bool b_isshown = g_pais_query_dialog_active->IsShown();
1027 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1028 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1030 g_pais_query_dialog_active->Close();
1033 g_pais_query_dialog_active->
Create(
1034 this, -1, _(
"AIS Target Query"),
1035 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1036 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1037 g_pais_query_dialog_active->UpdateText();
1038 if (b_isshown) g_pais_query_dialog_active->Show();
1043 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1047 ApplyGlobalColorSchemetoStatusBar();
1049 UpdateAllToolbars(cs);
1054 bool btoolbarFull = g_bmasterToolbarFull;
1060 if (!btoolbarFull) {
1062 RequestNewMasterToolbar();
1064 CollapseGlobalToolbar();
1067 RequestNewMasterToolbar();
1076void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1077 if (m_pStatusBar != NULL) {
1078 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1079 m_pStatusBar->ClearBackground();
1090void MyFrame::CancelAllMouseRoute() {
1092 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1094 if (cc) cc->CancelMouseRoute();
1098void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1106 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1114 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1123 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1126 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1127 config_array.Item(i)->canvas = NULL;
1133 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1138 switch (g_canvasConfig) {
1152 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1153 cc->GetglCanvas()->Show();
1156 config_array.Item(0)->canvas = cc;
1160 cc->ApplyCanvasConfig(config_array.Item(0));
1164 cc->ConfigureChartBar();
1165 cc->SetColorScheme(global_color_scheme);
1166 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1167 cc->SetShowGPS(
true);
1170 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1172 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1188 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1191 config_array.Item(0)->canvas = cc;
1193 cc->ApplyCanvasConfig(config_array.Item(0));
1196 cc->ConfigureChartBar();
1197 cc->SetColorScheme(global_color_scheme);
1198 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1199 cc->SetShowGPS(
false);
1202 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1204 .CaptionVisible(
false)
1206 .CloseButton(
false);
1215 if (config_array.GetCount() < 2) {
1217 pcc->configIndex = 1;
1221 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1222 config_array.Add(pcc);
1225 config_array.Item(1)->canvas = cc;
1227 cc->ApplyCanvasConfig(config_array.Item(1));
1230 cc->ConfigureChartBar();
1231 cc->SetColorScheme(global_color_scheme);
1232 cc->SetShowGPS(
true);
1234 cc->SetShowGPSCompassWindow(
true);
1237 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1239 .CaptionVisible(
false)
1241 .CloseButton(
false);
1242 g_pauimgr->GetPane(cc).RightDockable(
true);
1246 config_array.Item(1)->canvasSize =
1247 wxSize(GetClientSize().x / 2, GetClientSize().y);
1248 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1253 if (b_useStoredSize) {
1254 int ccw = config_array.Item(1)->canvasSize.x;
1255 int cch = config_array.Item(1)->canvasSize.y;
1258 if (ccw < GetClientSize().x / 10) {
1259 ccw = GetClientSize().x / 2;
1260 cch = GetClientSize().y;
1263 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1264 cc->SetSize(ccw, cch);
1282 console->SetColorScheme(global_color_scheme);
1287 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1293void MyFrame::RequestNewToolbars(
bool bforcenew) {
1294 if (b_inCloseWindow) {
1298 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1299 PositionIENCToolbar();
1308void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1314void MyFrame::SetAllToolbarScale() {
1315 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1318void MyFrame::SetGPSCompassScale() {
1319 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1323 wxPoint screenPoint = ::wxGetMousePosition();
1326 switch (g_canvasConfig) {
1328 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1331 if (canvas->GetScreenRect().Contains(
1335 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1338 if (canvas->GetScreenRect().Contains(
1345 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1348 if (canvas->GetScreenRect().Contains(
1349 canvas->ScreenToClient(screenPoint)))
1357int MyFrame::GetCanvasIndexUnderMouse() {
1358 wxPoint screenPoint = ::wxGetMousePosition();
1361 switch (g_canvasConfig) {
1363 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1366 if (canvas->GetScreenRect().Contains(
1370 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1373 if (canvas->GetScreenRect().Contains(
1380 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1383 if (canvas->GetScreenRect().Contains(
1384 canvas->ScreenToClient(screenPoint)))
1392bool MyFrame::DropMarker(
bool atOwnShip) {
1399 if (!canvas)
return false;
1406 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1408 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1410 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1421 RefreshAllCanvas(
false);
1426void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1427 if (g_canvasConfig != 0) {
1430 int nTargetGTK = -1;
1432 wxWindow *source = FindFocus();
1438 switch (g_canvasConfig) {
1440 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1443 if (canvas && (canvas == test)) {
1448 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1451 if (canvas && (canvas == test)) {
1459 int nfinalTarget = nTarget;
1461 nfinalTarget = nTargetGTK;
1463 target = ConfigMgr::Get()
1464 .GetCanvasConfigArray()
1469 target->Refresh(
true);
1480void MyFrame::FastClose() {
1482 FrameTenHzTimer.Stop();
1484 FrameTimer1.Start(1);
1488void MyFrame::OnExit(wxCommandEvent &event) {
1492void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1495 if (b_inCloseWindow) {
1505 if (!g_bDeferredInitDone)
return;
1522 if (bDBUpdateInProgress)
return;
1524 b_inCloseWindow =
true;
1526 ::wxSetCursor(wxCURSOR_WAIT);
1530 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1532 if (cc && cc->IsMeasureActive()) {
1533 cc->CancelMeasureRoute();
1538 SendPreShutdownHookToPlugins();
1542 if (g_pAISTargetList) {
1543 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1544 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1545 g_pauimgr->DetachPane(g_pAISTargetList);
1572 SetCursor(wxCURSOR_WAIT);
1574 RefreshAllCanvas(
true);
1580 RestoreScreenBrightness();
1591 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1592 g_iENCToolbarPosY = tbp_incanvas.y;
1593 g_iENCToolbarPosX = tbp_incanvas.x;
1597 g_bframemax = IsMaximized();
1600 FrameTenHzTimer.Stop();
1602 FrameCOGTimer.Stop();
1616 if (g_bAutoAnchorMark) {
1617 bool watching_anchor =
false;
1625 wxDateTime now = wxDateTime::Now();
1626 wxTimeSpan uptime = now.Subtract(g_start_time);
1628 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1629 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1634 if (g_declutter_anchorage) {
1635 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1636 if (pr->GetName().StartsWith(
"Anchorage")) {
1637 double a =
gLat - pr->m_lat;
1638 double b =
gLon - pr->m_lon;
1639 double l = sqrt((a * a) + (b * b));
1642 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1644 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1645 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1653 wxString name = now.Format();
1654 name.Prepend(_(
"Anchorage created "));
1660 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1669 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1673 NavObj_dB::GetInstance().Close();
1677 pConfig->DeleteGroup(
"/Routes");
1678 pConfig->DeleteGroup(
"/Marks");
1697 if (g_pAISTargetList) {
1698 g_pAISTargetList->Disconnect_decoder();
1699 g_pAISTargetList->Destroy();
1702 if (RouteManagerDialog::getInstanceFlag()) {
1719 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1721 if (cc) cc->Destroy();
1745 CommBridge::GetInstance().SaveConfig();
1765 auto ®istry = CommDriverRegistry::GetInstance();
1766 registry.CloseAllDrivers();
1769 for (
auto *cp : TheConnectionParams()) {
1774 while (pLayerList->size())
delete *pLayerList->begin();
1778 ReleaseApiListeners();
1781 g_bTempShowMenuBar =
false;
1783#define THREAD_WAIT_SECONDS 5
1793 wxLogMessage(
"Starting compressor pool drain");
1794 wxDateTime now = wxDateTime::Now();
1795 time_t stall = now.GetTicks();
1796 time_t end = stall + THREAD_WAIT_SECONDS;
1799 while (stall < end) {
1800 wxDateTime later = wxDateTime::Now();
1801 stall = later.GetTicks();
1804 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1813 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1819 uninitIXNetSystem();
1827 wxLogMessage(
"gFrame destroyed.");
1830#ifndef USE_ANDROID_GLES2
1831 qDebug() <<
"Calling OnExit()";
1835 wxTheApp->ExitMainLoop();
1838void MyFrame::OnMove(wxMoveEvent &event) {
1839 auto idx = wxDisplay::GetFromWindow(
this);
1852 DEBUG_LOG <<
"Moved to " << idx
1853#if wxCHECK_VERSION(3, 1, 6)
1854 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1855 << wxDisplay(idx).GetPPI().GetY()
1856 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1858 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1859 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1860 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1861 << wxGetDisplaySizeMM().GetY()
1862 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1871 if (g_config_display_size_manual) {
1880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1883 cc->SetMUIBarPosition();
1892 UpdateGPSCompassStatusBoxes();
1902 PositionIENCToolbar();
1908 g_nframewin_posx = GetPosition().x;
1909 g_nframewin_posy = GetPosition().y;
1912void MyFrame::ProcessCanvasResize() {
1913 UpdateGPSCompassStatusBoxes(
true);
1917 PositionIENCToolbar();
1920 TriggerRecaptureTimer();
1924void MyFrame::TriggerRecaptureTimer() {
1925 m_recaptureTimer.Start(
1926 1000, wxTIMER_ONE_SHOT);
1929void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1931void MyFrame::SetCanvasSizes(wxSize frameSize) {
1935 int cccw = frameSize.x;
1936 int ccch = frameSize.y;
1940 switch (g_canvasConfig) {
1946 cc->GetSize( &cur_width, &cur_height );
1947 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1949 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1951 cc->SetSize( 0, 0, cccw, ccch );
1961 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1962 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1964 ccw = wxMin(ccw, cccw * 8 / 10);
1965 ccw = wxMax(ccw, cccw * 2 / 10);
1969 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1976 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1993void MyFrame::OnIconize(wxIconizeEvent &event) {
2003 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2005 if (cc && cc->GetMUIBar()) {
2006 if (cc->GetMUIBar()->GetCanvasOptions()) {
2007 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2008 cc->GetMUIBar()->PushCanvasOptions();
2017void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2019void MyFrame::ODoSetSize() {
2021 GetClientSize(&x, &y);
2024 if (m_pStatusBar != NULL) {
2025 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2026 int currentCount = m_pStatusBar->GetFieldsCount();
2027 if (currentCount != m_StatusBarFieldCount) {
2028 if ((currentCount > 0) && (currentCount < 7)) {
2031 int widths[] = {2, 2, 2, 2, 2, 2};
2032 m_pStatusBar->SetStatusWidths(currentCount, widths);
2035 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2038 if (m_StatusBarFieldCount) {
2043 if (m_StatusBarFieldCount > 2) {
2044 int widths[] = {-6, -5, -5, -6, -4};
2045 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2046 }
else if (m_StatusBarFieldCount == 2) {
2047 int cwidth = x * 90 / 100;
2048 int widths[] = {100, 100};
2049 widths[0] = cwidth * 6.4 / 10.0;
2050 widths[1] = cwidth * 3.6 / 10.0;
2051 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2053 int widths[] = {100, 100};
2054 widths[0] = x * 90 / 100;
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2058 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2059 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2060 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2062 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2064 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2072 m_pStatusBar->GetFieldRect(0, stat_box);
2075 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2077 wxFont sys_font = *wxNORMAL_FONT;
2078 int try_font_size = sys_font.GetPointSize();
2081 int min_font_size = 10;
2091 wxFont *statusBarFont =
2092 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2093 int font_size = statusBarFont->GetPointSize();
2095 font_size = wxMin(font_size,
2098 wxMax(font_size, min_font_size);
2101 font_size = statusBarFont->GetPointSize();
2108 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2109 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2111 int min_height = stat_box.height;
2113 m_pStatusBar->SetFont(*pstat_font);
2114 m_pStatusBar->SetForegroundColour(
2115 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2117 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2119 (min_height >> 1) * 2;
2120 m_pStatusBar->SetMinHeight(min_height);
2129 SetCanvasSizes(GetClientSize());
2131 UpdateGPSCompassStatusBoxes(
true);
2133 if (
console) PositionConsole();
2136 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2138 if (cc) cc->FormatPianoKeys();
2144 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2145 GetPrimaryCanvas()->GetCompass()->GetRect());
2171 options_lastWindowSize = wxSize(0, 0);
2172 options_lastWindowPos = wxPoint(0, 0);
2179 if (!b_inCloseWindow) {
2182 resizeAndroidPersistents();
2186 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2187 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2193void MyFrame::PositionConsole() {
2194#if defined(__WXMSW__) || defined(__WXMAC__)
2195 if (NULL == GetPrimaryCanvas())
return;
2197 int ccx, ccy, ccsx, ccsy, consx, consy;
2202 consoleHost->GetSize(&ccsx, &ccsy);
2203 consoleHost->GetPosition(&ccx, &ccy);
2205 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2206 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2207 consoleHost = GetPrimaryCanvas();
2212 if (consoleHost->GetCompass()) {
2213 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2215 if (compass_rect.y < 100)
2216 yOffset = compass_rect.y + compass_rect.height + 45;
2220 wxSize csz =
console->GetSize();
2224 wxPoint screen_pos =
2225 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2228 if (NULL == GetPrimaryCanvas())
return;
2230 int ccx, ccy, ccsx, ccsy, consx, consy;
2235 consoleHost->GetSize(&ccsx, &ccsy);
2236 consoleHost->GetPosition(&ccx, &ccy);
2238 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2239 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2240 consoleHost = GetPrimaryCanvas();
2243 int yTopOffset = 60;
2244 int yBottomOffset = 0;
2246 if (consoleHost->GetCompass()) {
2247 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2249 if (compass_rect.y < 100)
2250 yTopOffset = compass_rect.y + compass_rect.height;
2252 if (consoleHost->GetMUIBar()) {
2253 wxRect mui_rect = consoleHost->GetMUIBarRect();
2254 yBottomOffset = ccsy - mui_rect.y;
2258 wxSize csz =
console->GetSize();
2261 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2263 if (consy < yAvail) {
2264 yFinal = (yAvail - consy) / 2;
2265 yFinal += yTopOffset;
2266 }
else if (
console->GetCDI()->IsShown()) {
2267 int cdi_height =
console->GetCDI()->GetSize().y;
2268 int consy_no_cdi = consy - cdi_height;
2269 yFinal = (yAvail - consy_no_cdi) / 2;
2270 yFinal += yTopOffset;
2274 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2279void MyFrame::UpdateAllFonts() {
2288 DestroyPersistentDialogs();
2290 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2295void MyFrame::DestroyPersistentDialogs() {
2296 if (g_pais_query_dialog_active) {
2297 g_pais_query_dialog_active->Hide();
2298 g_pais_query_dialog_active->Destroy();
2299 g_pais_query_dialog_active = NULL;
2327void MyFrame::RefreshGroupIndices() {
2329 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2331 if (cc) cc->canvasRefreshGroupIndex();
2335void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2338 switch (event.GetId()) {
2339 case ID_MENU_SCALE_OUT:
2340 DoStackDelta(GetPrimaryCanvas(), 1);
2344 case ID_MENU_SCALE_IN:
2345 DoStackDelta(GetPrimaryCanvas(), -1);
2349 case ID_MENU_ZOOM_IN: {
2350 if (GetFocusCanvas()) {
2351 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2356 case ID_MENU_ZOOM_OUT: {
2357 if (GetFocusCanvas()) {
2358 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2363 case ID_MENU_ROUTE_NEW: {
2364 if (GetFocusCanvas()) {
2365 if (0 == GetFocusCanvas()->m_routeState) {
2366 GetFocusCanvas()->StartRoute();
2368 GetFocusCanvas()->FinishRoute();
2374 case ID_MENU_TOOL_MEASURE: {
2375 GetPrimaryCanvas()->StartMeasureRoute();
2379 case ID_MENU_TOOL_NMEA_DBG_LOG:
2380 m_data_monitor->Show();
2381 m_data_monitor->Raise();
2384 case ID_MENU_TOOL_IO_MONITOR:
2385 m_data_monitor->Show();
2388 case ID_MENU_MARK_BOAT: {
2393 case ID_MENU_MARK_CURSOR: {
2398 case ID_MENU_NAV_FOLLOW: {
2399 if (
gFrame->GetPrimaryCanvas())
2400 gFrame->GetPrimaryCanvas()->TogglebFollow();
2404 case ID_MENU_CHART_OUTLINES: {
2405 ToggleChartOutlines(GetFocusCanvas());
2409 case ID_MENU_CHART_QUILTING: {
2410 ToggleQuiltMode(GetFocusCanvas());
2414 case ID_MENU_UI_CHARTBAR: {
2415 ToggleChartBar(GetFocusCanvas());
2419 case ID_MENU_ENC_TEXT:
2421 ToggleENCText(GetFocusCanvas());
2424 case ID_MENU_ENC_LIGHTS: {
2425 ToggleLights(GetFocusCanvas());
2428 case ID_MENU_ENC_SOUNDINGS: {
2429 ToggleSoundings(GetFocusCanvas());
2432 case ID_MENU_ENC_ANCHOR: {
2433 ToggleAnchor(GetFocusCanvas());
2436 case ID_MENU_ENC_DATA_QUALITY: {
2437 ToggleDataQuality(GetFocusCanvas());
2440 case ID_MENU_SHOW_NAVOBJECTS: {
2441 ToggleNavobjects(GetFocusCanvas());
2445 case ID_MENU_AIS_TARGETS: {
2446 ToggleAISDisplay(GetFocusCanvas());
2449 case ID_MENU_AIS_MOORED_TARGETS: {
2450 g_bHideMoored = !g_bHideMoored;
2453 case ID_MENU_AIS_SCALED_TARGETS: {
2454 ToggleAISMinimizeTargets(GetFocusCanvas());
2458 case ID_MENU_AIS_TARGETLIST: {
2459 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2463 case ID_MENU_AIS_TRACKS: {
2464 g_bAISShowTracks = !g_bAISShowTracks;
2465 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2469 case ID_MENU_AIS_CPADIALOG: {
2470 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2471 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2472 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2473 if (g_bAIS_CPA_Alert) {
2474 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2479 case ID_MENU_AIS_CPASOUND: {
2480 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2481 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2485 case ID_MENU_AIS_CPAWARNING: {
2486 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2487 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2491 case wxID_PREFERENCES:
2498 case ID_SETTINGS_NEW: {
2503 case ID_SETTINGS_DELETE: {
2506 g_pOptions =
nullptr;
2510 case ID_RELOAD_CHARTS: {
2515 case ID_MENU_SETTINGS_BASIC: {
2517 androidDisableFullScreen();
2519 DoAndroidPreferences();
2526 case ID_MENU_UI_FULLSCREEN: {
2531 case ID_MENU_SHOW_CURRENTS: {
2532 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2533 GetFocusCanvas()->ReloadVP();
2534 GetFocusCanvas()->Refresh(
false);
2538 case ID_MENU_SHOW_TIDES: {
2539 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2540 GetFocusCanvas()->ReloadVP();
2541 GetFocusCanvas()->Refresh(
false);
2561 case ID_MENU_UI_COLSCHEME:
2562 case ID_COLSCHEME: {
2563 ToggleColorScheme();
2572 case ID_MENU_OQUIT: {
2577 case ID_MENU_ROUTE_MANAGER:
2578 case ID_ROUTEMANAGER: {
2601 case ID_MENU_NAV_TRACK:
2603 if (!g_bTrackActive) {
2605 g_bTrackCarryOver =
true;
2608 g_bTrackCarryOver =
false;
2609 RefreshAllCanvas(
true);
2614 case ID_MENU_CHART_NORTHUP: {
2615 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2618 case ID_MENU_CHART_COGUP: {
2619 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2622 case ID_MENU_CHART_HEADUP: {
2623 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2627 case ID_MENU_MARK_MOB:
2633 case ID_MASTERTOGGLE: {
2635 wxString tip = _(
"Show Toolbar");
2636 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2638 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2640 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2643 if (g_bmasterToolbarFull)
2644 m_nMasterToolCountShown =
2648 m_nMasterToolCountShown = 2;
2650 m_nMasterToolCountShown =
2653 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2661 case ID_CMD_SELECT_CHART_TYPE: {
2662 selectChartDisplay(event.GetExtraLong(), -1);
2666 case ID_CMD_SELECT_CHART_FAMILY: {
2667 selectChartDisplay(-1, event.GetExtraLong());
2671 case ID_CMD_APPLY_SETTINGS: {
2672 applySettingsString(event.GetString());
2674 androidRestoreFullScreen();
2680 case ID_CMD_NULL_REFRESH: {
2685 case ID_CMD_SETVP: {
2686 setStringVP(event.GetString());
2690 case ID_CMD_INVALIDATE: {
2696 case ID_CMD_POST_JSON_TO_PLUGINS: {
2702 int numErrors = reader.
Parse(event.GetString(), &root);
2703 if (numErrors == 0) {
2704 if (root[
"MessageID"].IsString()) {
2705 wxString MsgID = root[
"MessageID"].
AsString();
2729 ArrayOfPlugInToolbarTools tool_array =
2731 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2733 if (event.GetId() == pttc->id) {
2734 if (pttc->m_pplugin)
2756bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2757 bool viz_now = g_bmasterToolbarFull;
2760 wxString tip = _(
"Show Toolbar");
2762 tip = _(
"Hide Toolbar");
2764 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2767 bool toggle =
false;
2768 if (viz && !g_bmasterToolbarFull)
2771 else if (!viz && g_bmasterToolbarFull)
2775 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2778 if (g_bmasterToolbarFull)
2779 m_nMasterToolCountShown =
2783 m_nMasterToolCountShown = 2;
2785 m_nMasterToolCountShown =
2788 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2794void MyFrame::ScheduleReloadCharts() {
2795 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2796 evt.SetId(ID_RELOAD_CHARTS);
2797 GetEventHandler()->AddPendingEvent(evt);
2800void MyFrame::ScheduleDeleteSettingsDialog() {
2801 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2802 evt.SetId(ID_SETTINGS_DELETE);
2803 GetEventHandler()->AddPendingEvent(evt);
2806void MyFrame::ScheduleSettingsDialog() {
2807 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2808 evt.SetId(ID_SETTINGS);
2809 GetEventHandler()->AddPendingEvent(evt);
2812void MyFrame::ScheduleSettingsDialogNew() {
2813 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2814 evt.SetId(ID_SETTINGS_NEW);
2815 GetEventHandler()->AddPendingEvent(evt);
2818void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2819 UpdateCanvasConfigDescriptors();
2821 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2822 CreateCanvasLayout(
true);
2824 CreateCanvasLayout();
2828 ConfigureStatusBar();
2829 wxSize lastOptSize = options_lastWindowSize;
2834 options_lastWindowSize = lastOptSize;
2838 ScheduleSettingsDialogNew();
2840 ScheduleSettingsDialog();
2845 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2848 int index_hint = -1;
2849 if (i < pathArray.GetCount())
2850 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2851 cc->canvasChartsRefresh(index_hint);
2852 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2861 return GetPrimaryCanvas();
2864void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2866 if (g_bmasterToolbarFull) {
2867#ifndef OCPN_TOOLBAR_ANIMATE
2868 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2871 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2872 m_nMasterToolCountShown++;
2877 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2885#ifndef OCPN_TOOLBAR_ANIMATE
2886 m_nMasterToolCountShown = 1;
2888 if (m_nMasterToolCountShown > 1) {
2889 m_nMasterToolCountShown--;
2893 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2903void MyFrame::InvalidateAllGL() {
2906 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2916void MyFrame::RefreshAllCanvas(
bool bErase) {
2918 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2921 cc->Refresh(bErase);
2926void MyFrame::setStringVP(wxString VPS) {
2931 wxStringTokenizer tkz(VPS,
";");
2933 wxString token = tkz.GetNextToken();
2935 token.ToDouble(&lat);
2937 token = tkz.GetNextToken();
2939 token.ToDouble(&lon);
2941 token = tkz.GetNextToken();
2943 token.ToDouble(&scale_ppm);
2945 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2948void MyFrame::DoSettingsNew() {
2955void MyFrame::DoSettings() {
2960 ApplyGlobalSettings(
true);
2963 bool b_loadHarmonics =
false;
2964 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2967 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2970 if (b_loadHarmonics) LoadHarmonics();
2978 g_bShowChartBar = !g_bShowChartBar;
2980 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2985 if (g_bShowChartBar) {
2987 UpdateControlBar(cc);
2990 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2993void MyFrame::ToggleColorScheme() {
2994 static bool lastIsNight;
2995 ColorScheme s = user_colors::GetColorScheme();
2998 if (lastIsNight && is == 3)
3001 lastIsNight =
false;
3003 if (lastIsNight) is = 2;
3004 if (is == 3) lastIsNight =
true;
3005 s = (ColorScheme)is;
3006 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3008 SetAndApplyColorScheme(s);
3011void MyFrame::ToggleFullScreen() {
3012 bool to = !IsFullScreen();
3017 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3019 ShowFullScreen(to, style);
3022 UpdateAllToolbars(global_color_scheme);
3024 UpdateControlBar(GetPrimaryCanvas());
3026 TriggerRecaptureTimer();
3029void MyFrame::ActivateMOB() {
3031 wxDateTime mob_time = wxDateTime::Now();
3032 wxString mob_label(_(
"MAN OVERBOARD"));
3033 mob_label += _(
" on ");
3034 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3038 pWP_MOB->SetShared(
true);
3040 pWP_MOB->SetWaypointArrivalRadius(
3042 pWP_MOB->SetUseSca(
false);
3044 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3052 new RoutePoint(zlat, zlon, g_default_wp_icon,
3053 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3054 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3059 temp_route->AddPoint(pWP_src);
3060 temp_route->AddPoint(pWP_MOB);
3062 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3072 temp_route->SetRouteArrivalRadius(-1.0);
3078 v[
"GUID"] = temp_route->
m_GUID;
3079 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3080 SendJSONMessageToAllPlugins(msg_id, v);
3083 if (RouteManagerDialog::getInstanceFlag()) {
3091 RefreshAllCanvas(
false);
3093 wxString mob_message(_(
"MAN OVERBOARD"));
3094 mob_message += _(
" Time: ");
3095 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3096 mob_message += _(
" Position: ");
3097 mob_message += toSDMM(1,
gLat);
3099 mob_message += toSDMM(2,
gLon);
3100 wxLogMessage(mob_message);
3102void MyFrame::TrackOn() {
3103 g_bTrackActive =
true;
3111 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3113 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3115 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3118 androidSetTrackTool(
true);
3121 if (RouteManagerDialog::getInstanceFlag()) {
3130 if (name.IsEmpty()) {
3136 name = _(
"(Unnamed Track)");
3140 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3141 SendJSONMessageToAllPlugins(msg_id, v);
3142 g_FlushNavobjChangesTimeout =
3146Track *MyFrame::TrackOff(
bool do_add_point) {
3151 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3153 SendJSONMessageToAllPlugins(msg_id, v);
3162 if (g_bTrackDaily) {
3167 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3168 return_val = pExtendTrack;
3175 g_bTrackActive =
false;
3177 if (RouteManagerDialog::getInstanceFlag()) {
3184 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3186 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3187 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3190 androidSetTrackTool(
false);
3194 m_target_rotate_time = wxInvalidDateTime;
3199void MyFrame::InitializeTrackRestart() {
3200 if (!g_bTrackDaily)
return;
3201 if (m_target_rotate_time.IsValid())
return;
3204 switch (g_track_rotate_time_type) {
3206 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3208 case TIME_TYPE_COMPUTER:
3209 rotate_at = g_track_rotate_time;
3213 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3214 rotate_at = g_track_rotate_time + utc_offset;
3217 if (rotate_at > 86400)
3219 else if (rotate_at < 0)
3222 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3223 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3226 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3227 m_target_rotate_time += wxTimeSpan(24);
3231bool MyFrame::ShouldRestartTrack() {
3233 InitializeTrackRestart();
3235 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3236 m_target_rotate_time += wxTimeSpan(24);
3242void MyFrame::TrackDailyRestart() {
3244 Track *pPreviousTrack = TrackOff(
true);
3251 if (pPreviousTrack) {
3252 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3256 if (RouteManagerDialog::getInstanceFlag()) {
3264void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3266 cc->SetUpMode(mode);
3268 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3269 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3270 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3273 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3278 cc->SetShowENCText(!cc->GetShowENCText());
3280 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3288void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3291 cc->SetENCDisplayCategory(nset);
3293 UpdateGlobalMenuItems();
3304 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3306 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3315 cc->SetShowENCLights(!cc->GetShowENCLights());
3317 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3327void MyFrame::ToggleRocks(
void )
3333 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3334 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3335 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3336 pOLE->nViz = !pOLE->nViz;
3340 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3341 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3342 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3345 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3349 ps52plib->GenerateStateHash();
3356 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3358 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3366 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3368 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3383 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3384 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3389 cc->SetShowAIS(!cc->GetShowAIS());
3390 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3394void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3395 cc->SetAttenAIS(!cc->GetAttenAIS());
3396 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3402 cc->m_bFollow =
true;
3405 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3409 SetChartUpdatePeriod();
3417 cc->m_bFollow =
false;
3419 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3423 SetChartUpdatePeriod();
3426void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3427 cc->SetShowOutlines(!cc->GetShowOutlines());
3429 RefreshAllCanvas(
false);
3433 if (g_bopengl) InvalidateAllGL();
3436 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3439void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3441void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3443 bool enabled = m_pMenuBar->IsEnabled(item_id);
3444 m_pMenuBar->Enable(item_id,
false);
3445 m_pMenuBar->Check(item_id, state);
3446 m_pMenuBar->Enable(item_id, enabled);
3450void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3457void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3458 wxBitmap *bmpRollover) {
3460 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3465void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3466 wxString rolloverSVGfile,
3467 wxString toggledSVGfile) {
3470 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3474void MyFrame::ConfigureStatusBar() {
3476 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3479 UseNativeStatusBar(
false);
3482 if (g_bShowStatusBar) {
3483 if (!m_pStatusBar) {
3485 CreateStatusBar(m_StatusBarFieldCount, 0);
3486 ApplyGlobalColorSchemetoStatusBar();
3491 m_pStatusBar->Destroy();
3492 m_pStatusBar = NULL;
3498void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3499 ConfigureStatusBar();
3501 wxSize lastOptSize = options_lastWindowSize;
3507 options_lastWindowSize = lastOptSize;
3509 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3512void MyFrame::BuildMenuBar() {
3518 bool showMenuBar =
true;
3520 bool showMenuBar = g_bShowMenuBar;
3532 m_pMenuBar =
new wxMenuBar();
3533 RegisterGlobalMenuItems();
3534 SetMenuBar(m_pMenuBar);
3538 UpdateGlobalMenuItems();
3543 m_pMenuBar->Destroy();
3549void MyFrame::RegisterGlobalMenuItems() {
3550 if (!m_pMenuBar)
return;
3552 wxMenu *nav_menu =
new wxMenu();
3553 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3554 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3555 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3556 nav_menu->AppendSeparator();
3557 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3558 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3559 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3560 nav_menu->AppendSeparator();
3562 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3563 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3565 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3566 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3568 nav_menu->AppendSeparator();
3569 nav_menu->Append(ID_MENU_SCALE_IN,
3570 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3571 nav_menu->Append(ID_MENU_SCALE_OUT,
3572 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3574 nav_menu->AppendSeparator();
3575 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3577 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3579 wxMenu *view_menu =
new wxMenu();
3581 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3582 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3583 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3584 _menuText(_(
"Show Chart Outlines"),
"O"));
3586 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3587 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3588 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3589 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3591 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3592 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3594 view_menu->AppendSeparator();
3596 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3597 _menuText(_(
"Show ENC text"),
"T"));
3598 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3599 _menuText(_(
"Show ENC Lights"),
"L"));
3600 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3601 _menuText(_(
"Show ENC Soundings"),
"S"));
3602 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3603 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3604 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3605 _menuText(_(
"Show ENC Data Quality"),
"U"));
3606 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3607 _menuText(_(
"Show Navobjects"),
"V"));
3609 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3610 _menuText(_(
"Show ENC text"),
"Alt-T"));
3611 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3612 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3613 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3614 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3615 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3616 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3617 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3618 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3619 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3620 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3622 view_menu->AppendSeparator();
3623 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3624 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3625 view_menu->AppendSeparator();
3627 view_menu->Append(ID_MENU_UI_COLSCHEME,
3628 _menuText(_(
"Change Color Scheme"),
"C"));
3630 view_menu->Append(ID_MENU_UI_COLSCHEME,
3631 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3634 view_menu->AppendSeparator();
3636 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3637 _menuText(_(
"Toggle Full Screen"),
"F11"));
3639 m_pMenuBar->Append(view_menu, _(
"&View"));
3641 wxMenu *ais_menu =
new wxMenu();
3642 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3643 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3644 _(
"Attenuate less critical AIS targets"));
3645 ais_menu->AppendSeparator();
3646 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3647 _(
"Hide Moored AIS Targets"));
3648 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3650 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3653 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3654 _menuText(_(
"Show CPA Warnings"),
"W"));
3656 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3657 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3660 ais_menu->AppendSeparator();
3661 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3662 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3664 wxMenu *tools_menu =
new wxMenu();
3666 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3667 _menuText(_(
"Data Monitor"),
"E"));
3668 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3669 _menuText(_(
"Measure Distance"),
"M"));
3671 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3672 _menuText(_(
"Data Monitor"),
"Alt-E"));
3673 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3674 _menuText(_(
"Measure Distance"),
"Alt-M"));
3677 tools_menu->AppendSeparator();
3678 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3679 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3680 tools_menu->AppendSeparator();
3681 tools_menu->Append(ID_MENU_MARK_BOAT,
3682 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3683 tools_menu->Append(ID_MENU_MARK_CURSOR,
3684 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3685 tools_menu->AppendSeparator();
3689 _menuText(_(
"Drop MOB Marker"),
3691 tools_menu->AppendSeparator();
3692 tools_menu->Append(wxID_PREFERENCES,
3693 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3695 tools_menu->Append(ID_MENU_MARK_MOB,
3696 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3697 tools_menu->AppendSeparator();
3698 tools_menu->Append(wxID_PREFERENCES,
3699 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3701 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3704 wxMenu *window_menu =
new wxMenu();
3705 m_pMenuBar->Append(window_menu, _(
"&Window"));
3708 wxMenu *help_menu =
new wxMenu();
3709 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3710 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3711 m_pMenuBar->Append(help_menu, _(
"&Help"));
3714 UpdateGlobalMenuItems();
3717void MyFrame::UpdateGlobalMenuItems() {
3718 if (!m_pMenuBar)
return;
3720 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3721 ->Check(GetPrimaryCanvas()->m_bFollow);
3722 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3723 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3724 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3725 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3726 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3727 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3728 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3729 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3730 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3731 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3732 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3733 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3734 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3735 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3736 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3737 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3738 if (g_bAIS_CPA_Alert) {
3739 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3740 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3743 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3746 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3747 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3748 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3751 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3752 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3753 ->Check(ps52plib->GetShowSoundings());
3755 bool light_state =
false;
3757 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3759 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3760 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3761 light_state = (pOLE->nViz == 1);
3766 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3767 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3771 DisCat nset = ps52plib->GetDisplayCategory();
3772 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3773 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3774 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3775 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3777 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3778 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3780 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3781 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3782 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3787void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3788 if (!m_pMenuBar)
return;
3790 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3792 if (cc->GetUpMode() == NORTH_UP_MODE)
3793 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3794 else if (cc->GetUpMode() == COURSE_UP_MODE)
3795 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3797 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3799 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3800 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3801 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3802 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3803 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3804 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3805 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3806 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3807 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3808 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3809 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3810 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3811 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3812 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3813 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3816 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3817 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3820 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3822 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3823 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3828 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3832 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3833 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3834 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3835 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3836 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3837 ->Check(cc->GetShowENCDataQual());
3838 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3840 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3841 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3842 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3847void MyFrame::InvalidateAllCanvasUndo() {
3849 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3851 if (cc) cc->undo->InvalidateUndo();
3855void MyFrame::SubmergeAllCanvasToolbars() {
3857 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3859 if (cc) cc->SubmergeToolbar();
3863void MyFrame::SurfaceAllCanvasToolbars() {
3864 if (g_bshowToolbar) {
3866 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3868 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3875void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3877 if (lon > 180.0) lon -= 360.0;
3882 cc->JumpToPosition(lat, lon,
scale);
3885 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3889void MyFrame::UpdateCanvasConfigDescriptors() {
3891 for (
unsigned int i = 0;
3892 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3893 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3901 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3902 cc->GroupID = chart->m_groupIndex;
3905 cc->
bQuilt = chart->GetQuiltMode();
3911 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3913 cc->
bFollow = chart->m_bFollow;
3918 int upmode = chart->GetUpMode();
3919 if (upmode == COURSE_UP_MODE)
3921 else if (upmode == HEAD_UP_MODE)
3928void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3929 if (!RBBox.GetValid())
return;
3931 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3932 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3935 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3936 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3944 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3945 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3947 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3948 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3950 cc->GetSize(&ww, &wh);
3952 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3954 ppm = wxMin(ppm, 1.0);
3960void MyFrame::PrepareOptionsClose(
options *settings,
3961 int settings_return_value) {
3963 options_lastPage = settings->lastPage;
3968 if (options_lastPage == 1) options_lastPage = 0;
3970 options_subpage = settings->lastSubPage;
3971 options_lastWindowPos = settings->lastWindowPos;
3972 options_lastWindowSize = settings->lastWindowSize;
3975 androidEnableBackButton(
true);
3976 androidEnableOptionsMenu(
true);
3977 androidRestoreFullScreen();
3978 androidEnableRotation();
3981 EnableSettingsTool(
true);
3984void MyFrame::DoOptionsDialog() {
3985 EnableSettingsTool(
false);
3988 AbstractPlatform::ShowBusySpinner();
3991 pConfig->SetPath(
"/Settings");
3992 pConfig->Read(
"OptionsSizeX", &sx, -1);
3993 pConfig->Read(
"OptionsSizeY", &sy, -1);
3995 wxWindow *optionsParent =
this;
3997 optionsParent = GetPrimaryCanvas();
4000 callbacks.prepare_close = [&](
options *me,
int changes) {
4001 PrepareOptionsClose(me, changes);
4003 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4004 ProcessOptionsDialog(changes, workdir_list);
4007 wxPoint(-1, -1), wxSize(sx, sy));
4009 AbstractPlatform::HideBusySpinner();
4013 g_options->SetInitChartDir(*pInit_Chart_Dir);
4017 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4018 g_options->SetWorkDirListPtr(pWorkDirArray);
4024 prev_locale = g_locale;
4025 g_options->SetInitialPage(options_lastPage, options_subpage);
4028 g_options->lastWindowPos = options_lastWindowPos;
4029 if (options_lastWindowPos != wxPoint(0, 0)) {
4031 g_options->SetSize(options_lastWindowSize);
4035 if (options_lastWindowSize != wxSize(0, 0)) {
4036 g_options->SetSize(options_lastWindowSize);
4041 androidEnableBackButton(
false);
4042 androidEnableOptionsMenu(
false);
4043 androidDisableFullScreen();
4051 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4054 wxString chart_file_name;
4055 if (cc->GetQuiltMode()) {
4056 int dbi = cc->GetQuiltRefChartdbIndex();
4057 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4059 if (cc->m_singleChart)
4060 chart_file_name = cc->m_singleChart->GetFullPath();
4063 pathArray.Add(chart_file_name);
4069 last_canvasConfig = g_canvasConfig;
4072 g_last_ChartScaleFactor = g_ChartScaleFactor;
4078void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4079 bool b_need_refresh =
false;
4082 if ((rr & VISIT_CHARTS) &&
4083 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4085 UpdateChartDatabaseInplace(*pNewDirArray,
4086 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4089 b_need_refresh =
true;
4094 if (rr & STYLE_CHANGED) {
4097 _(
"Please restart OpenCPN to activate language or style changes."),
4098 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4101 bool charts_updating =
4102 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4103 if (!charts_updating) RefreshGroupIndices();
4105 if (rr & TIDES_CHANGED) {
4111 if (rr & S52_CHANGED) {
4112 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4123 g_Platform->GetDisplayDPmm());
4126 double stuffcog = NAN;
4127 double stuffsog = NAN;
4128 if (!std::isnan(
gCog)) stuffcog =
gCog;
4129 if (!std::isnan(
gSog)) stuffsog =
gSog;
4131 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4132 COGFilterTable[i] = stuffcog;
4133 SOGFilterTable[i] = stuffsog;
4136 SetChartUpdatePeriod();
4138 if (rr & GL_CHANGED) {
4142 b_need_refresh =
true;
4145 if (rr & S52_CHANGED) {
4146 b_need_refresh =
true;
4150 if (rr & REBUILD_RASTER_CACHE) {
4152 GetPrimaryCanvas()->Disable();
4154 GetPrimaryCanvas()->Enable();
4159 if (g_config_display_size_manual &&
4167 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4174 int rrt = rr & S52_CHANGED;
4176 (rrt == S52_CHANGED) ||
4177 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4187 ps52plib->SetScaleFactorExp(
4188 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4189 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4193 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4195 if (cc) cc->ApplyGlobalSettings();
4203 if (!charts_updating) {
4204 bool ztc = g_bEnableZoomToCursor;
4205 g_bEnableZoomToCursor =
false;
4207 if (!GetPrimaryCanvas()->IsFrozen())
4209 g_bEnableZoomToCursor = ztc;
4214 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4223 SetGPSCompassScale();
4225 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4228 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4229 if (!charts_updating) cc->UpdateCanvasControlBar();
4232 UpdateGPSCompassStatusBoxes();
4234 SetAllToolbarScale();
4235 RequestNewToolbars();
4237 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4240 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4243 cc->RebuildCursors();
4248 bool b_masterScaleChange =
false;
4250 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4251 b_masterScaleChange =
true;
4253 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4254 RequestNewMasterToolbar(
true);
4256 bool bMuiChange =
false;
4262 if (b_masterScaleChange || bMuiChange) {
4264 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4267 cc->ProcessNewGUIScale();
4273 if (rr & LOCALE_CHANGED) {
4274 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4276 rr |= NEED_NEW_OPTIONS;
4285 g_last_ChartScaleFactor = g_ChartScaleFactor;
4290bool MyFrame::CheckGroup(
int igroup) {
4291 if (igroup == 0)
return true;
4295 if (!pGroup->m_element_array.size())
4298 for (
const auto &elem : pGroup->m_element_array) {
4299 for (
unsigned int ic = 0;
4300 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4301 auto &cte =
ChartData->GetChartTableEntry(ic);
4302 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4304 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4311bool MyFrame::ScrubGroupArray() {
4316 bool b_change =
false;
4317 unsigned int igroup = 0;
4318 while (igroup < g_pGroupArray->GetCount()) {
4319 bool b_chart_in_element =
false;
4322 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4323 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4325 for (
unsigned int ic = 0;
4326 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4327 auto &cte =
ChartData->GetChartTableEntry(ic);
4328 wxString chart_full_path = cte.GetFullSystemPath();
4330 if (chart_full_path.StartsWith(element_root)) {
4331 b_chart_in_element =
true;
4337 if (!b_chart_in_element) {
4338 wxString test_string =
"GSHH";
4339 if (element_root.Upper().Contains(test_string))
4340 b_chart_in_element =
true;
4343 if (!b_chart_in_element)
4345 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4357void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4359 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4361 if (cc && (cc != ccThis)) cc->Refresh();
4366void MyFrame::ChartsRefresh() {
4369 AbstractPlatform::ShowBusySpinner();
4371 bool b_run = FrameTimer1.IsRunning();
4374 FrameTenHzTimer.Stop();
4377 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4380 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4381 if (cc->GetQuiltMode()) {
4382 currentIndex = cc->GetQuiltReferenceChartIndex();
4384 cc->canvasChartsRefresh(currentIndex);
4388 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4389 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4391 AbstractPlatform::HideBusySpinner();
4394void MyFrame::InvalidateAllQuilts() {
4395 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4398 cc->InvalidateQuilt();
4399 cc->SetQuiltRefChart(-1);
4400 cc->m_singleChart = NULL;
4405bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4407 const wxString &ChartListFileName) {
4408 bool b_run = FrameTimer1.IsRunning();
4410 FrameTenHzTimer.Stop();
4412 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4413 FrameCOGTimer.Stop();
4416 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4419 cc->InvalidateQuilt();
4420 cc->SetQuiltRefChart(-1);
4421 cc->m_singleChart = NULL;
4431 AbstractPlatform::ShowBusySpinner();
4434 wxString longmsg = _(
"OpenCPN Chart Update");
4436 ".................................................................."
4439 Updateprog =
new wxGenericProgressDialog();
4442 Updateprog->SetFont(*qFont);
4444 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4445 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4446 wxPD_REMAINING_TIME);
4448 DimeControl(Updateprog);
4453 wxLogMessage(
"Starting chart database Update...");
4457 m_gshhg_chart_loc = gWorldMapLocation;
4458 gWorldMapLocation = wxEmptyString;
4462 AbstractPlatform::HideBusySpinner();
4466void MyFrame::FinalizeChartDBUpdate() {
4468 if (!g_bDeferredInitDone) {
4470 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4473 bool b_groupchange = ScrubGroupArray();
4475 RefreshGroupIndices();
4477 if (b_groupchange) {
4478 pConfig->DestroyConfigGroups();
4483 if (g_bDeferredInitDone) ScheduleReloadCharts();
4488 cc->ToggleCanvasQuiltMode();
4490 bool cur_mode = cc->GetQuiltMode();
4492 if( !cc->GetQuiltMode() )
4493 cc->SetQuiltMode(
true );
4495 if( cc->GetQuiltMode() ) {
4496 cc->SetQuiltMode(
false );
4497 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4501 if( cur_mode != cc->GetQuiltMode() ){
4507 g_bQuiltEnable = cc->GetQuiltMode();
4511 ps52plib->GenerateStateHash();
4519 DoStackDelta(cc, -1);
4525 DoStackDelta(cc, 1);
4528void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4530void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4532void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4534 cc->DoCanvasStackDelta(direction);
4538void MyFrame::PositionIENCToolbar() {
4542 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4544 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4552void MyFrame::OnInitTimer(wxTimerEvent &event) {
4555 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4559 wxLog::FlushActive();
4561 switch (m_iInitCount++) {
4563 EnableSettingsTool(
false);
4568 if (g_bInlandEcdis) {
4569 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4570 double range_set = 500.;
4572 range = wxRound(range * 10) / 10.;
4576 else if (range > 2000.)
4578 else if (range > 1600.)
4580 else if (range > 1200.)
4582 else if (range > 800.)
4587 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4591 g_Platform->SetFullscreen(g_bFullscreen);
4595 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4598 cc->SetGroupIndex(0,
false);
4605 StartRebuildChartDatabase();
4616 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4630 3 * GetCharHeight());
4632 m_data_monitor->Center();
4640 pConfig->SetPath(
"/Settings");
4641 pConfig->Read(
"OptionsSizeX", &sx, -1);
4642 pConfig->Read(
"OptionsSizeY", &sy, -1);
4644 wxWindow *optionsParent =
this;
4646 optionsParent = GetPrimaryCanvas();
4648 BuildiENCToolbar(
true, m_toolbar_callbacks);
4655 if (!g_params.empty()) {
4656 for (
size_t n = 0; n < g_params.size(); n++) {
4657 wxString path = g_params[n];
4658 if (::wxFileExists(path)) {
4660 pSet->load_file(path.fn_str());
4663 pSet->LoadAllGPXObjects(
4664 !pSet->IsOpenCPN(), wpt_dups,
4666 LLBBox box = pSet->GetBBox();
4667 if (box.GetValid()) {
4668 CenterView(GetPrimaryCanvas(), box);
4677 InitAppMsgBusListener();
4682 auto loader = PluginLoader::GetInstance();
4683 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4684 if (!b_haveWMM)
gVar = g_UserVar;
4692 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4695 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4697 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4700 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4704 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4705 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4706 NavObj_dB::GetInstance().LoadNavObjects();
4709 if (!g_AW1GUID.IsEmpty()) {
4712 if (!g_AW2GUID.IsEmpty()) {
4718 appendOSDirSlash(&layerdir);
4719 layerdir.Append(
"layers");
4721 if (wxDir::Exists(layerdir)) {
4723 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4724 wxLogMessage(laymsg);
4725 pConfig->LoadLayers(layerdir);
4730 if (!g_kiosk_startup) {
4731 AbstractPlatform::ShowBusySpinner();
4734 pConfig->SetPath(
"/Settings");
4735 pConfig->Read(
"OptionsSizeX", &sx, -1);
4736 pConfig->Read(
"OptionsSizeY", &sy, -1);
4738 wxWindow *optionsParent =
this;
4740 optionsParent = GetPrimaryCanvas();
4743 callbacks.prepare_close = [&](
options *me,
int changes) {
4744 PrepareOptionsClose(me, changes);
4746 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4747 ProcessOptionsDialog(changes, workdir_list);
4750 wxPoint(-1, -1), wxSize(sx, sy));
4751 AbstractPlatform::HideBusySpinner();
4758 wxLogMessage(
"OnInitTimer...Last Call");
4762 RequestNewMasterToolbar();
4764 PositionIENCToolbar();
4766 g_bDeferredInitDone =
true;
4776 GetPrimaryCanvas()->SetFocus();
4777 GetPrimaryCanvas()->Enable();
4780 if (b_reloadForPlugins) {
4786 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4788 if (cc) cc->SetFirstAuto(
true);
4796 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4798 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4802 cc->CheckGroupValid();
4803 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4804 cc->SetShowGPSCompassWindow(
true);
4809 androidEnableBackButton(
true);
4810 androidEnableRotation();
4811 androidEnableOptionItems(
true);
4815 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4821 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4823 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4825 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4831 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4833 wxLog::FlushActive();
4835 RefreshAllCanvas(
true);
4836 UsbWatchDaemon::GetInstance().Start();
4837 EnableSettingsTool(
true);
4843void MyFrame::InitAppMsgBusListener() {
4844 auto &msgbus = AppMsgBus::GetInstance();
4847 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4848 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4852 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4853 HandleBasicNavMsg(basicnav_msg);
4857 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4858 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4862 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4863 HandleGPSWatchdogMsg(msg);
4870void MyFrame::ReleaseApiListeners() {}
4875 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4876 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4877 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4878 server.open_file_cb = [&](
const std::string &path) {
4879 return m_open_gpx_file(path);
4886void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4887 if (msg->gps_watchdog <= 0) {
4888 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4892 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4897 if (m_fix_start_time.IsValid()) {
4898 wxDateTime now = wxDateTime::Now();
4899 wxTimeSpan span = now - m_fix_start_time;
4900 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4901 auto ¬eman = NotificationManager::GetInstance();
4902 wxString msg = _(
"GNSS Position fix lost");
4903 noteman.AddNotification(NotificationSeverity::kCritical,
4905 m_fix_start_time = wxInvalidDateTime;
4909 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4910 bool last_bVelocityValid = bVelocityValid;
4911 bVelocityValid =
false;
4918void MyFrame::CalculateCOGAverage() {
4920 if (!std::isnan(
gCog)) {
4923 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4926 double sum = 0., count = 0;
4928 double adder = COGTable[i];
4929 if (std::isnan(adder))
continue;
4931 if (fabs(adder -
g_COGAvg) > 180.) {
4945 else if (sum >= 360.)
4954void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4955 m_fixtime = msg->time;
4956 double hdt_data_interval = 0;
4957 double fix_time_interval = 0;
4959 double msgtime = msg->set_time.tv_sec;
4960 double m1 = msg->set_time.tv_nsec / 1e9;
4963 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4964 ((msg->vflag & POS_VALID) == POS_VALID)) {
4966 if (!m_fix_start_time.IsValid()) {
4967 m_fix_start_time = wxDateTime::Now();
4972 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4975 fix_time_gt_last = fix_time_gt;
4976 uint64_t fix_time_gt_now =
4977 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4978 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4982 double implied_sog = dist / (fix_time_interval / 3600);
4987 gLat_gt_m1 = gLat_gt;
4988 gLon_gt_m1 = gLon_gt;
4992 fix_time_gt = fix_time_gt_now;
4996 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
4997 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
4998 gCog_gt_m1 = gCog_gt;
5008 if (!std::isnan(gCog_gt_m1)) {
5010 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5017 if ((fix_time_gt - fix_time_gt_last) > .08) {
5022 if (gCog_gt > gCog_gt_m1) {
5023 if ((gCog_gt - gCog_gt_m1) > 180.)
5028 if ((gCog_gt_m1 - gCog_gt) > 180.)
5033 difft = fabs(gCog_gt - gCog_gt_m1);
5034 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5042 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5043 tentative_cog_rate_gt *= 1e9;
5044 cog_rate_gt = tentative_cog_rate_gt;
5052 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5055static double hdt_avg;
5056 double hdt_norm =
gHdt;
5057 if(
gHdt > 180) hdt_norm -= 360;
5060 hdt_avg += hdt_norm * 0.1;
5065 if (!std::isnan(
gHdt)) {
5067 uint64_t hdt_time_gt_last = hdt_time_gt;
5068 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5069 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5072 if (hdt_data_interval > .09) {
5074 gHdt_gt_m1 = gHdt_gt;
5077 if (!std::isnan(gHdt_gt_m1)) {
5079 double tentative_hdt_rate_gt =
5080 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5081 tentative_hdt_rate_gt *= 1e9;
5083 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5084 hdt_rate_gt = tentative_hdt_rate_gt;
5092 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5095 CalculateCOGAverage();
5103 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5104 if ((msg->vflag & POS_VALID) == POS_VALID)
5109 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5111 bVelocityValid =
true;
5115void MyFrame::UpdateStatusBar() {
5118 unsigned long uiCurrentTickCount;
5119 m_MMEAeventTime.SetToCurrent();
5120 uiCurrentTickCount =
5121 m_MMEAeventTime.GetMillisecond() / 100;
5122 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5123 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5124 m_ulLastNMEATicktime = uiCurrentTickCount;
5126 if (m_tick_idx++ > 6) m_tick_idx = 0;
5131 if (NULL != GetStatusBar()) {
5134 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5137 wxString s1(tick_buf, wxConvUTF8);
5139 s1 += toSDMM(1,
gLat);
5141 s1 += toSDMM(2,
gLon);
5143 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5147 if (!std::isnan(
gSog))
5148 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5150 sogcog.Printf(
"SOG --- ");
5154 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5156 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5158 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5159 (
int)toMagnetic(
gCog), 0x00B0);
5161 cogs.Printf((
"COG ---%c"), 0x00B0);
5163 sogcog.Append(cogs);
5164 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5169void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5170 MemFootTimer.Stop();
5172 int memsize = GetApplicationMemoryUse();
5175 printf(
"Memsize: %d \n", memsize);
5178 if (memsize > (g_MemFootMB * 1000)) {
5182 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5183 unsigned int nCache = pCache->GetCount();
5186 for (
unsigned int i = 0; i < nCache; i++) {
5196 for (
unsigned int i = 0; i < nCache - 1; i++) {
5197 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5199 pcea[i] = pcea[i + 1];
5210 unsigned int idelete = 0;
5211 unsigned int idelete_max = pCache->GetCount();
5214 unsigned int minimum_cache = 1;
5215 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5217 while ((memsize > (g_MemFootMB * 1000)) &&
5218 (pCache->GetCount() > minimum_cache) &&
5219 (idelete < idelete_max)) {
5220 int memsizeb = memsize;
5224 memsize = GetApplicationMemoryUse();
5225 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5233 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5238void MyFrame::CheckToolbarPosition() {
5241 static bool bMaximized;
5243 if (IsMaximized() && !bMaximized) {
5250 PositionIENCToolbar();
5251 }
else if (!IsMaximized() && bMaximized) {
5259 PositionIENCToolbar();
5264void MyFrame::ProcessUnitTest() {
5265 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5272 cc->m_bFollow =
false;
5274 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5275 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5278 if (cc->m_groupIndex > 0) {
5279 while (ut_index < ChartData->GetChartTableEntries() &&
5280 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5284 if (ut_index < ChartData->GetChartTableEntries()) {
5288 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5289 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5296 if (cc->GetQuiltMode()) {
5297 if (cc->IsChartQuiltableRef(ut_index))
5298 cc->SelectQuiltRefdbChart(ut_index);
5300 cc->SelectdbChart(ut_index);
5303 if (g_unit_test_1) {
5311 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5312 cte->GetLatMin(), cte->GetLonMax(), NULL,
5316 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5317 cte->GetLatMax(), cte->GetLonMin(), NULL,
5320 cc->GetSize(&ww, &wh);
5321 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5323 ppm = wxMin(ppm, 1.0);
5330 if (ut_index > ut_index_max) exit(0);
5341 bool b_rotate =
false;
5343 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5346 if (!b_rotate && !g_btenhertz)
return;
5348 bool b_update =
false;
5350 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5353 struct timespec now;
5354 clock_gettime(CLOCK_MONOTONIC, &now);
5355 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5356 double diffc = diff / 1e9;
5359 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5360 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5361 if (gCog_tentative < 0.) gCog_tentative += 360.;
5362 gCog = gCog_tentative;
5366 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5367 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5368 double diffc = diff / 1e9;
5369 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5373 if (gSog_gt && !std::isnan(gCog_gt)) {
5374 double delta_t = diffc / 3600;
5375 double distance = gSog_gt * delta_t;
5378 double angr = gCog_gt / 180 * M_PI;
5379 double latr = gLat_gt * M_PI / 180;
5380 double D = distance / 3443;
5381 double sD = sin(D), cD = cos(D);
5382 double sy = sin(latr), cy = cos(latr);
5383 double sa = sin(angr), ca = cos(angr);
5385 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5386 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5396 if (cc) cc->DoCanvasCOGSet();
5405 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5406 bool bnew = cc->DoCanvasUpdate();
5407 if (!bnew) cc->UpdateShips();
5416 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5419bool MyFrame::ProcessQuitFlag() {
5423 FrameTenHzTimer.Stop();
5425 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5426 if (top) top->Close(
true);
5433void MyFrame::ProcessDeferredTrackOn() {
5436 if (g_bDeferredStartTrack) {
5437 if (!g_bTrackActive) {
5440 g_bDeferredStartTrack =
false;
5443 g_bDeferredStartTrack =
false;
5448void MyFrame::ProcessAnchorWatch() {
5456 double d = g_nAWMax;
5459 bool toofar =
false;
5460 bool tooclose =
false;
5461 if (d >= 0.0) toofar = (dist * 1852. > d);
5462 if (d < 0.0) tooclose = (dist * 1852 < -d);
5464 if (tooclose || toofar)
5465 AnchorAlertOn1 =
true;
5467 AnchorAlertOn1 =
false;
5469 AnchorAlertOn1 =
false;
5477 double d = g_nAWMax;
5480 bool toofar =
false;
5481 bool tooclose =
false;
5482 if (d >= 0) toofar = (dist * 1852. > d);
5483 if (d < 0) tooclose = (dist * 1852 < -d);
5485 if (tooclose || toofar)
5486 AnchorAlertOn2 =
true;
5488 AnchorAlertOn2 =
false;
5490 AnchorAlertOn2 =
false;
5493 AnchorAlertOn1 =
true;
5496void MyFrame::SendFixToPlugins() {
5507 GPSData.
nSats = g_SatsInView;
5509 wxDateTime tCheck((time_t)m_fixtime);
5510 if (tCheck.IsValid()) {
5519 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5522 SendPositionFixToAllPlugIns(&GPSData);
5526void MyFrame::ProcessLogAndBells() {
5529 wxDateTime lognow = wxDateTime::Now();
5530 int hourLOC = lognow.GetHour();
5531 int minuteLOC = lognow.GetMinute();
5533 int minuteUTC = lognow.GetMinute();
5534 int second = lognow.GetSecond();
5536 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5537 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5538 (minuteUTC == 30)) {
5539 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5540 wxString day = lognow.FormatISODate();
5541 wxString utc = lognow.FormatISOTime();
5542 wxString navmsg =
"LOGBOOK: ";
5550 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5554 if (std::isnan(
gCog))
5555 cog.Printf(
"COG ----- ");
5557 cog.Printf(
"COG %10.5f ",
gCog);
5560 if (std::isnan(
gSog))
5561 sog.Printf(
"SOG ----- ");
5563 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5569 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5572 wxLogMessage(navmsg);
5573 g_loglast_time = lognow;
5575 int bells = (hourLOC % 4) * 2;
5576 if (minuteLOC != 0) bells++;
5577 if (!bells) bells = 8;
5579 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5580 m_BellsToPlay = bells;
5581 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5582 wxPostEvent(
this, ev);
5589 CheckToolbarPosition();
5593 if (ProcessQuitFlag())
return;
5595 if (bDBUpdateInProgress)
return;
5598 FrameTenHzTimer.Stop();
5600 ProcessDeferredTrackOn();
5602 ProcessAnchorWatch();
5603 ProcessLogAndBells();
5605 if (ShouldRestartTrack()) TrackDailyRestart();
5608 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5609 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5610 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5616 if (
gSog > 3.0) g_bCruising =
true;
5622 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5624 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5630 bool bnew_view =
false;
5631 if (!g_btenhertz) bnew_view = DoChartUpdate();
5638 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5641 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5644 cc->DrawBlinkObjects();
5647 if (bactiveRouteUpdate) {
5654 cc->SetOwnShipState(SHIP_NORMAL);
5656 if (cc->GetQuiltMode()) {
5657 double erf = cc->GetQuiltMaxErrorFactor();
5658 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5660 if (cc->m_singleChart) {
5661 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5662 cc->SetOwnShipState(SHIP_LOWACCURACY);
5666 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5669 (bVelocityValid != m_last_bVelocityValid) ||
5670 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5671 if (!g_bopengl) cc->UpdateShips();
5679 m_last_bVelocityValid = bVelocityValid;
5684 bool brq_dynamic =
false;
5686 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5687 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5689 if (pic->m_enabled && pic->m_init_state) {
5690 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5697 if (brq_dynamic) bnew_view =
true;
5701 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5704 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5709 if (cc->GetglCanvas()) {
5711 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5713 if ((!g_btenhertz)) {
5714 if (cc->m_bFollow) {
5715 cc->DoCanvasUpdate();
5732 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5746 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5747 g_pais_query_dialog_active->UpdateText();
5750 if (g_pAISTargetList && (0 == (g_tick % (5))))
5751 g_pAISTargetList->UpdateAISTargetList();
5754 UpdateGPSCompassStatusBoxes();
5759 console->RefreshConsoleData();
5766 if (m_bdefer_resize) {
5767 if (0 == (g_tick % (5))) {
5768 printf(
"___RESIZE\n");
5769 SetSize(m_defer_size);
5771 m_bdefer_resize =
false;
5778 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5780 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5781 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5785double MyFrame::GetMag(
double a,
double lat,
double lon) {
5786 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5787 auto loader = PluginLoader::GetInstance();
5788 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5795 wxDateTime now = wxDateTime::Now();
5796 SendJSON_WMM_Var_Request(lat, lon, now);
5797 if (fabs(gQueryVar) < 360.0)
5798 Variance = gQueryVar;
5800 return toMagnetic(a, Variance);
5803bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5809 v[
"Year"] = date.GetYear();
5810 v[
"Month"] = date.GetMonth();
5811 v[
"Day"] = date.GetDay();
5813 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5819void MyFrame::TouchAISActive() {
5821 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5823 if (cc) cc->TouchAISToolActive();
5827void MyFrame::UpdateAISTool() {
5831 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5833 if (cc) cc->UpdateAISTBTool();
5838void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5840 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5842 if (cc) cc->SetbTCUpdate(
true);
5845 RefreshAllCanvas(
false);
5850void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5854 bool b_rotate =
false;
5855 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5857 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5861 FrameCOGTimer.Stop();
5868 int period_ms = 100;
5870 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5873void MyFrame::DoCOGSet() {
5875 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5877 if (cc) cc->DoCanvasCOGSet();
5881void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5887 wxFont oldfont = pdc->GetFont();
5889 pdc->SetFont(*pFont);
5890 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5891 pdc->SetBackgroundMode(wxTRANSPARENT);
5893 pdc->DrawText(str, x, y + 1);
5894 pdc->DrawText(str, x, y - 1);
5895 pdc->DrawText(str, x + 1, y);
5896 pdc->DrawText(str, x - 1, y);
5898 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5900 pdc->DrawText(str, x, y);
5902 pdc->SetFont(oldfont);
5906void MyFrame::UpdateRotationState(
double rotation) {
5908 g_bCourseUp =
false;
5910 if (fabs(rotation) > .001) {
5911 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5912 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5914 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5917 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5918 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5920 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5924 UpdateGPSCompassStatusBoxes(
true);
5928void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5930 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5932 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5938int MyFrame::GetApplicationMemoryUse() {
5944 wxWindow *fWin = wxWindow::FindFocus();
5946 wxArrayString outputArray;
5947 wxString cmd(
"ps --no-headers -o vsize ");
5948 unsigned long pid = wxGetProcessId();
5950 cmd1.Printf(
"%ld", pid);
5952 wxExecute(cmd, outputArray);
5954 if (outputArray.GetCount()) {
5955 wxString s = outputArray.Item(0);
5957 if (s.ToLong(&vtmp)) memsize = vtmp;
5960 if (fWin) fWin->SetFocus();
5966 PROCESS_MEMORY_COUNTERS pmc;
5968 unsigned long processID = wxGetProcessId();
5970 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5972 if (NULL == hProcess)
return 0;
5974 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5992 memsize = pmc.WorkingSetSize / 1024;
5995 CloseHandle(hProcess);
6002double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6003 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6006void MyFrame::SetChartUpdatePeriod() {
6009 g_ChartUpdatePeriod = 0;
6014 bool bskewdc =
false;
6015 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6018 if (!g_bopengl && !cc->GetVP().b_quilt) {
6019 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6021 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6025 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6027 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6032 cc->UpdateCanvasControlBar();
6035void MyFrame::selectChartDisplay(
int type,
int family) {
6037 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6039 if (cc) cc->selectCanvasChartDisplay(type, family);
6042 UpdateGlobalMenuItems();
6051bool MyFrame::DoChartUpdate() {
6052 bool return_val =
false;
6055 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6057 if (cc) return_val |= cc->DoCanvasUpdate();
6063void MyFrame::MouseEvent(wxMouseEvent &event) {
6065 event.GetPosition(&x, &y);
6070#include <mach/mach.h>
6071#include <mach/message.h>
6072#include <mach/kern_return.h>
6073#include <mach/task_info.h>
6075#include <malloc/malloc.h>
6082#if defined(__linux__)
6083#include "sys/types.h"
6084#include "sys/sysinfo.h"
6087void MyFrame::DoPrint(
void) {
6089 g_PrintingInProgress =
true;
6092 GetPrimaryCanvas()->GetglCanvas()->Render();
6093 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6103 printer.Initialize(wxLANDSCAPE);
6104 printer.EnablePageNumbers(
false);
6105 printer.Print(
this, &printout);
6123 g_PrintingInProgress =
false;
6126 GetPrimaryCanvas()->SetFocus();
6132 wxString message_ID =
event.GetID();
6133 wxString message_JSONText =
event.GetJSONText();
6141 if (message_ID ==
"WMM_VARIATION_BOAT") {
6149 int numErrors = reader.
Parse(message_JSONText, &root);
6150 if (numErrors > 0) {
6156 wxString decl = root[
"Decl"].
AsString();
6158 decl.ToDouble(&decl_val);
6164 if (message_ID ==
"WMM_VARIATION") {
6172 int numErrors = reader.
Parse(message_JSONText, &root);
6173 if (numErrors > 0) {
6179 wxString decl = root[
"Decl"].
AsString();
6181 decl.ToDouble(&decl_val);
6183 gQueryVar = decl_val;
6186 if (message_ID ==
"GRIB_TIMELINE") {
6189 int numErrors = r.
Parse(message_JSONText, &v);
6191 if (numErrors > 0) {
6192 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6197 wxDateTime oldTimeSource = gTimeSource;
6199 if (v[
"Day"].AsInt() == -1) {
6200 gTimeSource = wxInvalidDateTime;
6201 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6203 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6204 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6205 v[
"Second"].AsInt());
6209 if (oldTimeSource != gTimeSource) {
6211 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6213 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6218 cc->pCwin->Refresh(
false);
6224 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6227 wxString trk_id = wxEmptyString;
6229 int numErrors = reader.
Parse(message_JSONText, &root);
6230 if (numErrors > 0)
return;
6235 v[
"Track_ID"] = trk_id;
6237 wxString name = wxEmptyString;
6238 if (ptrack->m_GUID == trk_id) {
6239 name = ptrack->GetName();
6240 if (name.IsEmpty()) {
6246 name = _(
"(Unnamed Track)");
6253 v[
"TotalNodes"] = ptrack->GetnPoints();
6254 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6256 v[
"lat"] = tp->m_lat;
6257 v[
"lon"] = tp->m_lon;
6260 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6261 SendJSONMessageToAllPlugins(msg_id, v);
6267 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6268 SendJSONMessageToAllPlugins(msg_id, v);
6270 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6273 wxString guid = wxEmptyString;
6275 int numErrors = reader.
Parse(message_JSONText, &root);
6276 if (numErrors > 0) {
6285 wxString name = wxEmptyString;
6287 if ((*it)->m_GUID == guid) {
6288 name = (*it)->m_RouteNameString;
6289 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6295 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6296 itp != (*it)->pRoutePointList->end(); itp++) {
6297 w[i][
"lat"] = (*itp)->m_lat;
6298 w[i][
"lon"] = (*itp)->m_lon;
6299 w[i][
"Name"] = (*itp)->GetName();
6300 w[i][
"Description"] = (*itp)->GetDescription();
6301 w[i][
"GUID"] = (*itp)->m_GUID;
6302 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6304 auto node = (*itp)->m_HyperlinkList->begin();
6305 if (node != (*itp)->m_HyperlinkList->end()) {
6307 while (node != (*itp)->m_HyperlinkList->end()) {
6309 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6310 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6311 httpLink->DescrText;
6318 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6319 SendJSONMessageToAllPlugins(msg_id, v);
6326 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6327 SendJSONMessageToAllPlugins(msg_id, v);
6328 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6333 int numErrors = reader.
Parse(message_JSONText, &root);
6334 if (numErrors > 0)
return;
6337 wxString str = root[
"mode"].
AsString();
6338 if (str ==
"Track") route =
false;
6343 for (RouteList::iterator it =
pRouteList->begin();
6345 wxString name = (*it)->m_RouteNameString;
6346 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6348 v[i][
"error"] =
false;
6349 v[i][
"name"] = name;
6350 v[i][
"GUID"] = (*it)->m_GUID;
6351 v[i][
"active"] = (*it)->IsActive();
6356 wxString name = ptrack->GetName();
6357 if (name.IsEmpty()) {
6363 name = _(
"(Unnamed Track)");
6365 v[i][
"error"] =
false;
6366 v[i][
"name"] = name;
6367 v[i][
"GUID"] = ptrack->m_GUID;
6372 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6373 SendJSONMessageToAllPlugins(msg_id, v);
6376 v[0][
"error"] =
true;
6377 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6378 SendJSONMessageToAllPlugins(msg_id, v);
6380 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6382 v[0][
"error"] =
true;
6385 v[0][
"error"] =
false;
6386 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6387 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6388 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6389 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6390 v[0][
"active_waypoint_lat"] =
6392 v[0][
"active_waypoint_lon"] =
6396 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6397 SendJSONMessageToAllPlugins(msg_id, v);
6401void MyFrame::FilterCogSog() {
6402 if (g_bfilter_cogsog) {
6404 double cog_last =
gCog;
6407 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6408 COGFilterTable[i] = COGFilterTable[i - 1];
6409 COGFilterTable[0] = cog_last;
6412 if (!std::isnan(cog_last)) {
6414 double sum = 0., count = 0;
6415 for (
int i = 0; i < g_COGFilterSec; i++) {
6416 double adder = COGFilterTable[i];
6417 if (std::isnan(adder))
continue;
6419 if (fabs(adder - cog_last) > 180.) {
6420 if ((adder - cog_last) > 0.)
6433 else if (sum >= 360.)
6440 double sog_last =
gSog;
6443 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6444 SOGFilterTable[i] = SOGFilterTable[i - 1];
6445 SOGFilterTable[0] = sog_last;
6448 if (!std::isnan(
gSog)) {
6449 double sum = 0., count = 0;
6450 for (
int i = 0; i < g_SOGFilterSec; i++) {
6451 if (std::isnan(SOGFilterTable[i]))
continue;
6453 sum += SOGFilterTable[i];
6463void MyFrame::LoadHarmonics() {
6466 ptcmgr->LoadDataSources(TideCurrentDataSet);
6468 bool b_newdataset =
false;
6471 for (
auto a :
ptcmgr->GetDataSet()) {
6472 bool b_foundi =
false;
6473 for (
auto b : TideCurrentDataSet) {
6480 b_newdataset =
true;
6485 for (
auto a : TideCurrentDataSet) {
6486 bool b_foundi =
false;
6487 for (
auto b :
ptcmgr->GetDataSet()) {
6494 b_newdataset =
true;
6499 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6503void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6504 if (!ptarget)
return;
6507 wxDateTime mob_time = wxDateTime::Now();
6508 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6509 mob_label += _(
" on ");
6510 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6513 mob_label, wxEmptyString);
6514 pWP_MOB->SetShared(
true);
6516 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6518 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6520 pWP_MOB->SetUseSca(
false);
6528 wxString(_(
"Own ship")), wxEmptyString);
6530 pWP_MOB->SetUseSca(
false);
6537 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6553 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6554 SendJSONMessageToAllPlugins(msg_id, v);
6557 if (RouteManagerDialog::getInstanceFlag()) {
6564 RefreshAllCanvas(
false);
6566 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6567 mob_message += _(
" Time: ");
6568 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6569 mob_message += _(
" Ownship Position: ");
6570 mob_message += toSDMM(1,
gLat);
6572 mob_message += toSDMM(2,
gLon);
6573 mob_message += _(
" MOB Position: ");
6574 mob_message += toSDMM(1, ptarget->Lat);
6576 mob_message += toSDMM(2, ptarget->Lon);
6577 wxLogMessage(mob_message);
6580void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6584 OwnPoint->m_lat =
gLat;
6585 OwnPoint->m_lon =
gLon;
6587 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6592 MOB_Point->m_lat = ptarget->Lat;
6593 MOB_Point->m_lon = ptarget->Lon;
6595 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6596 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6598 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6599 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6602 RefreshAllCanvas(
false);
6605 wxDateTime mob_time = wxDateTime::Now();
6607 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6608 mob_message += _(
" Time: ");
6609 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6610 mob_message += _(
" Ownship Position: ");
6611 mob_message += toSDMM(1,
gLat);
6613 mob_message += toSDMM(2,
gLon);
6614 mob_message += _(
" MOB Position: ");
6615 mob_message += toSDMM(1, ptarget->Lat);
6617 mob_message += toSDMM(2, ptarget->Lon);
6619 wxLogMessage(mob_message);
6623void MyFrame::applySettingsString(wxString settings) {
6625 int last_UIScaleFactor = g_GUIScaleFactor;
6626 bool previous_expert = g_bUIexpert;
6627 g_last_ChartScaleFactor = g_ChartScaleFactor;
6628 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6631 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6637 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6639 if (rr & S52_CHANGED) {
6641 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6643 ->ClearCNSYLUPArray();
6644 ps52plib->GenerateStateHash();
6648 ProcessOptionsDialog(rr, pNewDirArray);
6653 bool b_newToolbar =
false;
6655 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6657 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6659 if (rr & TOOLBAR_CHANGED) {
6660 b_newToolbar =
true;
6665 if (previous_expert && !g_bUIexpert) {
6666 androidForceFullRepaint();
6670 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6674 SetGPSCompassScale();
6676 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6678 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6680 UpdateGPSCompassStatusBoxes(
true);
6683 AbstractPlatform::ShowBusySpinner();
6685 SetAllToolbarScale();
6689 AbstractPlatform::HideBusySpinner();
6691 RequestNewMasterToolbar(
true);
6698 UpdateControlBar(GetPrimaryCanvas());
6704 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6707#ifdef wxHAS_POWER_EVENTS
6708void MyFrame::OnSuspending(wxPowerEvent &event) {
6712 wxLogMessage(
"System suspend starting...");
6715void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6718 wxLogMessage(
"System is going to suspend.");
6721void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6724 wxLogMessage(
"System suspend was cancelled.");
6727int g_last_resume_ticks;
6728void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6729 wxDateTime now = wxDateTime::Now();
6730 wxLogMessage(
"System resumed from suspend.");
6732 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6735 wxLogMessage(
"Restarting streams.");
6736 g_last_resume_ticks = now.GetTicks();
6740 g_pMUX->ClearStreams();
6742 g_pMUX->StartAllStreams();
6751 if (IsMaximized()) {
6756 wxSize sz = GetSize();
6757 SetSize(wxSize(sz.x - 1, sz.y));
6769void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6770 bool btbRebuild =
false;
6772 bool b_reshow =
true;
6775 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6776 if ((ff > 0.01f) || bforcenew) {
6786 long orient = g_Platform->GetDefaultToolbarOrientation();
6787 wxWindow *toolbarParent =
this;
6789 toolbarParent = GetPrimaryCanvas();
6792 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6793 m_toolbar_callbacks);
6795 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6802 g_bmasterToolbarFull =
true;
6806 CreateMasterToolbar();
6821bool MyFrame::CollapseGlobalToolbar() {
6823 m_nMasterToolCountShown = 1;
6827 g_bmasterToolbarFull =
false;
6843 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6844 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6845 tic->m_bRequired =
true;
6850 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6851 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6855 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6856 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6857 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6862 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6863 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6867 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6868 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6869 _(
"Enable Tracking"),
"MUI_track");
6873 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6874 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6886 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6887 _(
"Print Chart"),
"MUI_print");
6891 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6892 _(
"About OpenCPN"),
"MUI_help");
6896 AddDefaultPositionPlugInTools();
6900 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6901 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6912 ArrayOfPlugInToolbarTools tool_array =
6914 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6916 if (!pttc->b_viz)
continue;
6918 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6921 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6922 if (g_bTrackActive) {
6923 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6930bool MyFrame::CheckAndAddPlugInTool() {
6938 if (!tb)
return false;
6940 int n_tools = tb->GetToolsCount();
6944 ArrayOfPlugInToolbarTools tool_array =
6947 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6949 if (pttc->position == n_tools) {
6950 wxBitmap *ptool_bmp;
6952 switch (global_color_scheme) {
6953 case GLOBAL_COLOR_SCHEME_DAY:
6954 ptool_bmp = pttc->bitmap_day;
6957 case GLOBAL_COLOR_SCHEME_DUSK:
6958 ptool_bmp = pttc->bitmap_dusk;
6960 case GLOBAL_COLOR_SCHEME_NIGHT:
6961 ptool_bmp = pttc->bitmap_night;
6964 ptool_bmp = pttc->bitmap_day;
6969 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6971 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6972 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6973 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6974 tic->m_bPlugin =
true;
6983 while (CheckAndAddPlugInTool()) {
6989bool MyFrame::AddDefaultPositionPlugInTools() {
6996 ArrayOfPlugInToolbarTools tool_array =
6999 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7003 if (!pttc->b_viz)
continue;
7005 if (pttc->position == -1)
7007 wxBitmap *ptool_bmp;
7009 switch (global_color_scheme) {
7010 case GLOBAL_COLOR_SCHEME_DAY:
7011 ptool_bmp = pttc->bitmap_day;
7013 case GLOBAL_COLOR_SCHEME_DUSK:
7014 ptool_bmp = pttc->bitmap_dusk;
7016 case GLOBAL_COLOR_SCHEME_NIGHT:
7017 ptool_bmp = pttc->bitmap_night;
7020 ptool_bmp = pttc->bitmap_day;
7025 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7027 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7028 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7029 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7030 tic->m_bPlugin =
true;
7049typedef struct _MSW_COLOR_SPEC {
7051 wxString S52_RGB_COLOR;
7055MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7056 {COLOR_MENUTEXT,
"UITX1", 0},
7057 {COLOR_BTNSHADOW,
"UIBCK", 0},
7060void SaveSystemColors() {
7074 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7075 while (pcspec->COLOR_NAME != -1) {
7076 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7081void RestoreSystemColors() {
7082 int element[NCOLORS];
7083 int rgbcolor[NCOLORS];
7086 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7087 while (pcspec->COLOR_NAME != -1) {
7088 element[i] = pcspec->COLOR_NAME;
7089 rgbcolor[i] = pcspec->SysRGB_COLOR;
7094 if (pSetSysColors) {
7095 pSetSysColors(i, (
unsigned long *)&element[0],
7096 (
unsigned long *)&rgbcolor[0]);
7102void SetSystemColors(ColorScheme cs) {
7104 int element[NCOLORS];
7105 int rgbcolor[NCOLORS];
7107 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7108 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7109 while (pcspec->COLOR_NAME != -1) {
7110 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7111 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7112 element[i] = pcspec->COLOR_NAME;
7118 pSetSysColors(i, (
unsigned long *)&element[0],
7119 (
unsigned long *)&rgbcolor[0]);
7123 RestoreSystemColors();
7130static const WORD MAX_CONSOLE_LINES =
7135void RedirectIOToConsole()
7140 wxIntPtr lStdHandle;
7142 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7152 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7153 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7154 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7158 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7159 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7160 fp = _fdopen(hConHandle,
"w");
7162 setvbuf(stdout, NULL, _IONBF, 0);
7166 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7167 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7168 fp = _fdopen(hConHandle,
"r");
7170 setvbuf(stdin, NULL, _IONBF, 0);
7174 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7175 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7176 fp = _fdopen(hConHandle,
"w");
7178 setvbuf(stderr, NULL, _IONBF, 0);
7189 FontMgr::Get().SetLocale(g_locale);
7210 if (g_pais_query_dialog_active) {
7211 g_pais_query_dialog_active->Destroy();
7212 g_pais_query_dialog_active = NULL;
7215 auto alert_dlg_active =
7217 if (alert_dlg_active) {
7218 alert_dlg_active->Destroy();
7219 g_pais_alert_dialog_active =
nullptr;
7222 if (g_pAISTargetList) {
7224 g_pAISTargetList->Disconnect_decoder();
7225 g_pAISTargetList->Destroy();
7226 g_pAISTargetList = NULL;
7230 if (gFrame->m_pMenuBar) {
7231 gFrame->SetMenuBar(NULL);
7232 gFrame->m_pMenuBar->Destroy();
7233 gFrame->m_pMenuBar = NULL;
7235 gFrame->BuildMenuBar();
7238 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7240 if (cc) cc->CanvasApplyLocale();
7245 wxString perspective;
7247 pConfig->Read(
"AUIPerspective", &perspective);
7261 bool bno_load =
false;
7262 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7264 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7265 wxAuiPaneInfo pane = pane_array_val[i];
7266 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7272 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7277 gFrame->RequestNewToolbars(
true);
7278 gFrame->RequestNewMasterToolbar(
true);
7285 : wxThread(wxTHREAD_JOINABLE) {
7286 m_filename = filename;
7297 newChart->SetNativeScale(m_scale);
7298 newChart->SetFullExtent(m_ext);
7300 newChart->FindOrCreateSenc(m_filename);
7305 wxString m_filename;
7311static double chart_dist(
int index) {
7317 if (cte.GetBBox().Contains(
gLat,
gLon))
7322 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7323 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7324 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7327 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7328 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7330 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7336WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7337static int CompareInts(
int n1,
int n2) {
7338 double d1 = chart_dist(n1);
7339 double d2 = chart_dist(n2);
7340 return (
int)(d1 - d2);
7345 wxString chart_path;
7350WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7352#include <wx/arrimpl.cpp>
7355void ParseAllENC(wxWindow *parent) {
7356 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7364 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7367 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7369 idx_sorted_by_distance.Add(i);
7373 if (count == 0)
return;
7375 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7381 ArrayOfCompressTargets ct_array;
7382 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7383 int i = idx_sorted_by_distance[j];
7386 double distance = chart_dist(i);
7388 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7391 pct->distance = distance;
7392 pct->chart_path = filename;
7394 ct_array.push_back(pct);
7397 int thread_count = 0;
7400 if (g_nCPUCount > 0)
7401 thread_count = g_nCPUCount;
7403 thread_count = wxThread::GetCPUCount();
7405 if (thread_count < 1) {
7414 for(
int t = 0; t < thread_count; t++)
7418 wxGenericProgressDialog *prog =
nullptr;
7422 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7423 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7425 prog =
new wxGenericProgressDialog();
7427 prog->SetFont(*qFont);
7429 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7430 count + 1, parent, style);
7439 prog->ShowWindowModal();
7448 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7449 wxString filename = ct_array[j].chart_path;
7450 double distance = ct_array[j].distance;
7451 int index =
ChartData->FinddbIndex(filename);
7452 if (index < 0)
continue;
7455 ext.NLAT = cte.GetLatMax();
7456 ext.SLAT = cte.GetLatMin();
7457 ext.WLON = cte.GetLonMin();
7458 ext.ELON = cte.GetLonMax();
7460 int scale = cte.GetScale();
7463 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7466 if (wxThread::IsMain()) {
7468 wxSize sz = prog->GetSize();
7473 prog->Update(count, msg, &skip);
7485 newChart->SetNativeScale(
scale);
7486 newChart->SetFullExtent(ext);
7487 newChart->DisableBackgroundSENC();
7489 newChart->FindOrCreateSenc(filename,
7493 if (wxThread::IsMain()) {
7494 msg.Printf(_(
"ENC Completed."));
7496 prog->Update(count, msg, &skip);
7506 for (
int t = 0;; t = (t + 1) % thread_count) {
7513 if (!workers[t]->IsAlive()) {
7526#if defined(__WXMSW__) || defined(__WXOSX__)
7533 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().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
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.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
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.
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.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
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.
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.