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");
1704 if (g_pAISTargetList) {
1705 g_pAISTargetList->Disconnect_decoder();
1706 g_pAISTargetList->Destroy();
1713 if (RouteManagerDialog::getInstanceFlag()) {
1730 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1732 if (cc) cc->Destroy();
1756 CommBridge::GetInstance().SaveConfig();
1776 auto ®istry = CommDriverRegistry::GetInstance();
1777 registry.CloseAllDrivers();
1780 for (
auto *cp : TheConnectionParams()) {
1785 while (pLayerList->size())
delete *pLayerList->begin();
1789 ReleaseApiListeners();
1792 g_bTempShowMenuBar =
false;
1794#define THREAD_WAIT_SECONDS 5
1804 wxLogMessage(
"Starting compressor pool drain");
1805 wxDateTime now = wxDateTime::Now();
1806 time_t stall = now.GetTicks();
1807 time_t end = stall + THREAD_WAIT_SECONDS;
1810 while (stall < end) {
1811 wxDateTime later = wxDateTime::Now();
1812 stall = later.GetTicks();
1815 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1824 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1830 uninitIXNetSystem();
1834 wxLogMessage(
"gFrame destroyed.");
1837#ifndef USE_ANDROID_GLES2
1838 qDebug() <<
"Calling OnExit()";
1842 wxTheApp->ExitMainLoop();
1845void MyFrame::OnMove(wxMoveEvent &event) {
1846 auto idx = wxDisplay::GetFromWindow(
this);
1859 DEBUG_LOG <<
"Moved to " << idx
1860#if wxCHECK_VERSION(3, 1, 6)
1861 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1862 << wxDisplay(idx).GetPPI().GetY()
1863 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1865 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1866 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1867 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1868 << wxGetDisplaySizeMM().GetY()
1869 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1878 if (g_config_display_size_manual) {
1887 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1890 cc->SetMUIBarPosition();
1899 UpdateGPSCompassStatusBoxes();
1909 PositionIENCToolbar();
1915 g_nframewin_posx = GetPosition().x;
1916 g_nframewin_posy = GetPosition().y;
1919void MyFrame::ProcessCanvasResize() {
1920 UpdateGPSCompassStatusBoxes(
true);
1924 PositionIENCToolbar();
1927 TriggerRecaptureTimer();
1931void MyFrame::TriggerRecaptureTimer() {
1932 m_recaptureTimer.Start(
1933 1000, wxTIMER_ONE_SHOT);
1936void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1938void MyFrame::SetCanvasSizes(wxSize frameSize) {
1942 int cccw = frameSize.x;
1943 int ccch = frameSize.y;
1947 switch (g_canvasConfig) {
1953 cc->GetSize( &cur_width, &cur_height );
1954 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1956 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1958 cc->SetSize( 0, 0, cccw, ccch );
1968 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1969 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1971 ccw = wxMin(ccw, cccw * 8 / 10);
1972 ccw = wxMax(ccw, cccw * 2 / 10);
1976 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1983 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2000void MyFrame::OnIconize(wxIconizeEvent &event) {
2010 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2012 if (cc && cc->GetMUIBar()) {
2013 if (cc->GetMUIBar()->GetCanvasOptions()) {
2014 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2015 cc->GetMUIBar()->PushCanvasOptions();
2024void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2026void MyFrame::ODoSetSize() {
2028 GetClientSize(&x, &y);
2031 if (m_pStatusBar != NULL) {
2032 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2033 int currentCount = m_pStatusBar->GetFieldsCount();
2034 if (currentCount != m_StatusBarFieldCount) {
2035 if ((currentCount > 0) && (currentCount < 7)) {
2038 int widths[] = {2, 2, 2, 2, 2, 2};
2039 m_pStatusBar->SetStatusWidths(currentCount, widths);
2042 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2045 if (m_StatusBarFieldCount) {
2050 if (m_StatusBarFieldCount > 2) {
2051 int widths[] = {-6, -5, -5, -6, -4};
2052 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2053 }
else if (m_StatusBarFieldCount == 2) {
2054 int cwidth = x * 90 / 100;
2055 int widths[] = {100, 100};
2056 widths[0] = cwidth * 6.4 / 10.0;
2057 widths[1] = cwidth * 3.6 / 10.0;
2058 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2060 int widths[] = {100, 100};
2061 widths[0] = x * 90 / 100;
2062 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2065 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2066 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2067 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2069 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2071 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2079 m_pStatusBar->GetFieldRect(0, stat_box);
2082 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2084 wxFont sys_font = *wxNORMAL_FONT;
2085 int try_font_size = sys_font.GetPointSize();
2088 int min_font_size = 10;
2098 wxFont *statusBarFont =
2099 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2100 int font_size = statusBarFont->GetPointSize();
2102 font_size = wxMin(font_size,
2105 wxMax(font_size, min_font_size);
2108 font_size = statusBarFont->GetPointSize();
2115 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2116 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2118 int min_height = stat_box.height;
2120 m_pStatusBar->SetFont(*pstat_font);
2121 m_pStatusBar->SetForegroundColour(
2122 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2124 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2126 (min_height >> 1) * 2;
2127 m_pStatusBar->SetMinHeight(min_height);
2136 SetCanvasSizes(GetClientSize());
2138 UpdateGPSCompassStatusBoxes(
true);
2140 if (
console) PositionConsole();
2143 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2145 if (cc) cc->FormatPianoKeys();
2151 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2152 GetPrimaryCanvas()->GetCompass()->GetRect());
2178 options_lastWindowSize = wxSize(0, 0);
2179 options_lastWindowPos = wxPoint(0, 0);
2186 if (!b_inCloseWindow) {
2189 resizeAndroidPersistents();
2193 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2194 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2200void MyFrame::PositionConsole() {
2201#if defined(__WXMSW__) || defined(__WXMAC__)
2202 if (NULL == GetPrimaryCanvas())
return;
2204 int ccx, ccy, ccsx, ccsy, consx, consy;
2209 consoleHost->GetSize(&ccsx, &ccsy);
2210 consoleHost->GetPosition(&ccx, &ccy);
2212 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2213 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2214 consoleHost = GetPrimaryCanvas();
2219 if (consoleHost->GetCompass()) {
2220 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2222 if (compass_rect.y < 100)
2223 yOffset = compass_rect.y + compass_rect.height + 45;
2227 wxSize csz =
console->GetSize();
2231 wxPoint screen_pos =
2232 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2235 if (NULL == GetPrimaryCanvas())
return;
2237 int ccx, ccy, ccsx, ccsy, consx, consy;
2242 consoleHost->GetSize(&ccsx, &ccsy);
2243 consoleHost->GetPosition(&ccx, &ccy);
2245 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2246 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2247 consoleHost = GetPrimaryCanvas();
2250 int yTopOffset = 60;
2251 int yBottomOffset = 0;
2253 if (consoleHost->GetCompass()) {
2254 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2256 if (compass_rect.y < 100)
2257 yTopOffset = compass_rect.y + compass_rect.height;
2259 if (consoleHost->GetMUIBar()) {
2260 wxRect mui_rect = consoleHost->GetMUIBarRect();
2261 yBottomOffset = ccsy - mui_rect.y;
2265 wxSize csz =
console->GetSize();
2268 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2270 if (consy < yAvail) {
2271 yFinal = (yAvail - consy) / 2;
2272 yFinal += yTopOffset;
2273 }
else if (
console->GetCDI()->IsShown()) {
2274 int cdi_height =
console->GetCDI()->GetSize().y;
2275 int consy_no_cdi = consy - cdi_height;
2276 yFinal = (yAvail - consy_no_cdi) / 2;
2277 yFinal += yTopOffset;
2281 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2286void MyFrame::UpdateAllFonts() {
2295 DestroyPersistentDialogs();
2297 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2302void MyFrame::DestroyPersistentDialogs() {
2303 if (g_pais_query_dialog_active) {
2304 g_pais_query_dialog_active->Hide();
2305 g_pais_query_dialog_active->Destroy();
2306 g_pais_query_dialog_active = NULL;
2334void MyFrame::RefreshGroupIndices() {
2336 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2338 if (cc) cc->canvasRefreshGroupIndex();
2342void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2345 switch (event.GetId()) {
2346 case ID_MENU_SCALE_OUT:
2347 DoStackDelta(GetPrimaryCanvas(), 1);
2351 case ID_MENU_SCALE_IN:
2352 DoStackDelta(GetPrimaryCanvas(), -1);
2356 case ID_MENU_ZOOM_IN: {
2357 if (GetFocusCanvas()) {
2358 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2363 case ID_MENU_ZOOM_OUT: {
2364 if (GetFocusCanvas()) {
2365 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2370 case ID_MENU_ROUTE_NEW: {
2371 if (GetFocusCanvas()) {
2372 if (0 == GetFocusCanvas()->m_routeState) {
2373 GetFocusCanvas()->StartRoute();
2375 GetFocusCanvas()->FinishRoute();
2381 case ID_MENU_TOOL_MEASURE: {
2382 GetPrimaryCanvas()->StartMeasureRoute();
2386 case ID_MENU_TOOL_NMEA_DBG_LOG:
2387 m_data_monitor->Show();
2388 m_data_monitor->Raise();
2391 case ID_MENU_TOOL_IO_MONITOR:
2392 m_data_monitor->Show();
2395 case ID_MENU_MARK_BOAT: {
2400 case ID_MENU_MARK_CURSOR: {
2405 case ID_MENU_NAV_FOLLOW: {
2406 if (
gFrame->GetPrimaryCanvas())
2407 gFrame->GetPrimaryCanvas()->TogglebFollow();
2411 case ID_MENU_CHART_OUTLINES: {
2412 ToggleChartOutlines(GetFocusCanvas());
2416 case ID_MENU_CHART_QUILTING: {
2417 ToggleQuiltMode(GetFocusCanvas());
2421 case ID_MENU_UI_CHARTBAR: {
2422 ToggleChartBar(GetFocusCanvas());
2426 case ID_MENU_ENC_TEXT:
2428 ToggleENCText(GetFocusCanvas());
2431 case ID_MENU_ENC_LIGHTS: {
2432 ToggleLights(GetFocusCanvas());
2435 case ID_MENU_ENC_SOUNDINGS: {
2436 ToggleSoundings(GetFocusCanvas());
2439 case ID_MENU_ENC_ANCHOR: {
2440 ToggleAnchor(GetFocusCanvas());
2443 case ID_MENU_ENC_DATA_QUALITY: {
2444 ToggleDataQuality(GetFocusCanvas());
2447 case ID_MENU_SHOW_NAVOBJECTS: {
2448 ToggleNavobjects(GetFocusCanvas());
2452 case ID_MENU_AIS_TARGETS: {
2453 ToggleAISDisplay(GetFocusCanvas());
2456 case ID_MENU_AIS_MOORED_TARGETS: {
2457 g_bHideMoored = !g_bHideMoored;
2460 case ID_MENU_AIS_SCALED_TARGETS: {
2461 ToggleAISMinimizeTargets(GetFocusCanvas());
2465 case ID_MENU_AIS_TARGETLIST: {
2466 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2470 case ID_MENU_AIS_TRACKS: {
2471 g_bAISShowTracks = !g_bAISShowTracks;
2472 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2476 case ID_MENU_AIS_CPADIALOG: {
2477 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2478 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2479 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2480 if (g_bAIS_CPA_Alert) {
2481 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2486 case ID_MENU_AIS_CPASOUND: {
2487 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2488 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2492 case ID_MENU_AIS_CPAWARNING: {
2493 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2494 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2498 case wxID_PREFERENCES:
2505 case ID_SETTINGS_NEW: {
2510 case ID_SETTINGS_DELETE: {
2513 g_pOptions =
nullptr;
2517 case ID_RELOAD_CHARTS: {
2522 case ID_MENU_SETTINGS_BASIC: {
2524 androidDisableFullScreen();
2526 DoAndroidPreferences();
2533 case ID_MENU_UI_FULLSCREEN: {
2538 case ID_MENU_SHOW_CURRENTS: {
2539 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2540 GetFocusCanvas()->ReloadVP();
2541 GetFocusCanvas()->Refresh(
false);
2545 case ID_MENU_SHOW_TIDES: {
2546 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2547 GetFocusCanvas()->ReloadVP();
2548 GetFocusCanvas()->Refresh(
false);
2568 case ID_MENU_UI_COLSCHEME:
2569 case ID_COLSCHEME: {
2570 ToggleColorScheme();
2579 case ID_MENU_OQUIT: {
2584 case ID_MENU_ROUTE_MANAGER:
2585 case ID_ROUTEMANAGER: {
2608 case ID_MENU_NAV_TRACK:
2610 if (!g_bTrackActive) {
2612 g_bTrackCarryOver =
true;
2615 g_bTrackCarryOver =
false;
2616 RefreshAllCanvas(
true);
2621 case ID_MENU_CHART_NORTHUP: {
2622 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2625 case ID_MENU_CHART_COGUP: {
2626 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2629 case ID_MENU_CHART_HEADUP: {
2630 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2634 case ID_MENU_MARK_MOB:
2640 case ID_MASTERTOGGLE: {
2642 wxString tip = _(
"Show Toolbar");
2643 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2645 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2647 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2650 if (g_bmasterToolbarFull)
2651 m_nMasterToolCountShown =
2655 m_nMasterToolCountShown = 2;
2657 m_nMasterToolCountShown =
2660 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2668 case ID_CMD_SELECT_CHART_TYPE: {
2669 selectChartDisplay(event.GetExtraLong(), -1);
2673 case ID_CMD_SELECT_CHART_FAMILY: {
2674 selectChartDisplay(-1, event.GetExtraLong());
2678 case ID_CMD_APPLY_SETTINGS: {
2679 applySettingsString(event.GetString());
2681 androidRestoreFullScreen();
2687 case ID_CMD_NULL_REFRESH: {
2692 case ID_CMD_SETVP: {
2693 setStringVP(event.GetString());
2697 case ID_CMD_INVALIDATE: {
2703 case ID_CMD_POST_JSON_TO_PLUGINS: {
2709 int numErrors = reader.
Parse(event.GetString(), &root);
2710 if (numErrors == 0) {
2711 if (root[
"MessageID"].IsString()) {
2712 wxString MsgID = root[
"MessageID"].
AsString();
2736 ArrayOfPlugInToolbarTools tool_array =
2738 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2740 if (event.GetId() == pttc->id) {
2741 if (pttc->m_pplugin)
2763bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2764 bool viz_now = g_bmasterToolbarFull;
2767 wxString tip = _(
"Show Toolbar");
2769 tip = _(
"Hide Toolbar");
2771 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2774 bool toggle =
false;
2775 if (viz && !g_bmasterToolbarFull)
2778 else if (!viz && g_bmasterToolbarFull)
2782 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2785 if (g_bmasterToolbarFull)
2786 m_nMasterToolCountShown =
2790 m_nMasterToolCountShown = 2;
2792 m_nMasterToolCountShown =
2795 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2801void MyFrame::ScheduleReloadCharts() {
2802 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2803 evt.SetId(ID_RELOAD_CHARTS);
2804 GetEventHandler()->AddPendingEvent(evt);
2807void MyFrame::ScheduleDeleteSettingsDialog() {
2808 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2809 evt.SetId(ID_SETTINGS_DELETE);
2810 GetEventHandler()->AddPendingEvent(evt);
2813void MyFrame::ScheduleSettingsDialog() {
2814 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2815 evt.SetId(ID_SETTINGS);
2816 GetEventHandler()->AddPendingEvent(evt);
2819void MyFrame::ScheduleSettingsDialogNew() {
2820 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2821 evt.SetId(ID_SETTINGS_NEW);
2822 GetEventHandler()->AddPendingEvent(evt);
2825void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2826 UpdateCanvasConfigDescriptors();
2828 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2829 CreateCanvasLayout(
true);
2831 CreateCanvasLayout();
2835 ConfigureStatusBar();
2836 wxSize lastOptSize = options_lastWindowSize;
2841 options_lastWindowSize = lastOptSize;
2845 ScheduleSettingsDialogNew();
2847 ScheduleSettingsDialog();
2852 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2855 int index_hint = -1;
2856 if (i < pathArray.GetCount())
2857 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2858 cc->canvasChartsRefresh(index_hint);
2859 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2868 return GetPrimaryCanvas();
2871void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2872 if (g_bmasterToolbarFull) {
2873#ifndef OCPN_TOOLBAR_ANIMATE
2874 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2877 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2878 m_nMasterToolCountShown++;
2883 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2891#ifndef OCPN_TOOLBAR_ANIMATE
2892 m_nMasterToolCountShown = 1;
2894 if (m_nMasterToolCountShown > 1) {
2895 m_nMasterToolCountShown--;
2899 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2909void MyFrame::InvalidateAllGL() {
2912 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2922void MyFrame::RefreshAllCanvas(
bool bErase) {
2924 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2927 cc->Refresh(bErase);
2932void MyFrame::setStringVP(wxString VPS) {
2937 wxStringTokenizer tkz(VPS,
";");
2939 wxString token = tkz.GetNextToken();
2941 token.ToDouble(&lat);
2943 token = tkz.GetNextToken();
2945 token.ToDouble(&lon);
2947 token = tkz.GetNextToken();
2949 token.ToDouble(&scale_ppm);
2951 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2954void MyFrame::DoSettingsNew() {
2961void MyFrame::DoSettings() {
2966 ApplyGlobalSettings(
true);
2969 bool b_loadHarmonics =
false;
2970 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2973 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2976 if (b_loadHarmonics) LoadHarmonics();
2984 g_bShowChartBar = !g_bShowChartBar;
2986 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2991 if (g_bShowChartBar) {
2993 UpdateControlBar(cc);
2996 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2999void MyFrame::ToggleColorScheme() {
3000 static bool lastIsNight;
3001 ColorScheme s = user_colors::GetColorScheme();
3004 if (lastIsNight && is == 3)
3007 lastIsNight =
false;
3009 if (lastIsNight) is = 2;
3010 if (is == 3) lastIsNight =
true;
3011 s = (ColorScheme)is;
3012 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3014 SetAndApplyColorScheme(s);
3017void MyFrame::ToggleFullScreen() {
3018 bool to = !IsFullScreen();
3023 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3025 ShowFullScreen(to, style);
3028 UpdateAllToolbars(global_color_scheme);
3030 UpdateControlBar(GetPrimaryCanvas());
3032 TriggerRecaptureTimer();
3035void MyFrame::ActivateMOB() {
3037 wxDateTime mob_time = wxDateTime::Now();
3038 wxString mob_label(_(
"MAN OVERBOARD"));
3039 mob_label += _(
" on ");
3040 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3044 pWP_MOB->SetShared(
true);
3046 pWP_MOB->SetWaypointArrivalRadius(
3048 pWP_MOB->SetUseSca(
false);
3050 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3058 new RoutePoint(zlat, zlon, g_default_wp_icon,
3059 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3060 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3065 temp_route->AddPoint(pWP_src);
3066 temp_route->AddPoint(pWP_MOB);
3068 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3078 temp_route->SetRouteArrivalRadius(-1.0);
3084 v[
"GUID"] = temp_route->
m_GUID;
3085 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3086 SendJSONMessageToAllPlugins(msg_id, v);
3089 if (RouteManagerDialog::getInstanceFlag()) {
3097 RefreshAllCanvas(
false);
3099 wxString mob_message(_(
"MAN OVERBOARD"));
3100 mob_message += _(
" Time: ");
3101 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3102 mob_message += _(
" Position: ");
3103 mob_message += toSDMM(1,
gLat);
3105 mob_message += toSDMM(2,
gLon);
3106 wxLogMessage(mob_message);
3108void MyFrame::TrackOn() {
3109 g_bTrackActive =
true;
3117 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3119 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3121 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3124 androidSetTrackTool(
true);
3127 if (RouteManagerDialog::getInstanceFlag()) {
3136 if (name.IsEmpty()) {
3142 name = _(
"(Unnamed Track)");
3146 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3147 SendJSONMessageToAllPlugins(msg_id, v);
3148 g_FlushNavobjChangesTimeout =
3152Track *MyFrame::TrackOff(
bool do_add_point) {
3157 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3159 SendJSONMessageToAllPlugins(msg_id, v);
3168 if (g_bTrackDaily) {
3173 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3174 return_val = pExtendTrack;
3181 g_bTrackActive =
false;
3183 if (RouteManagerDialog::getInstanceFlag()) {
3190 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3192 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3193 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3196 androidSetTrackTool(
false);
3200 m_target_rotate_time = wxInvalidDateTime;
3205void MyFrame::InitializeTrackRestart() {
3206 if (!g_bTrackDaily)
return;
3207 if (m_target_rotate_time.IsValid())
return;
3210 switch (g_track_rotate_time_type) {
3212 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3214 case TIME_TYPE_COMPUTER:
3215 rotate_at = g_track_rotate_time;
3219 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3220 rotate_at = g_track_rotate_time + utc_offset;
3223 if (rotate_at > 86400)
3225 else if (rotate_at < 0)
3228 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3229 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3232 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3233 m_target_rotate_time += wxTimeSpan(24);
3237bool MyFrame::ShouldRestartTrack() {
3239 InitializeTrackRestart();
3241 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3242 m_target_rotate_time += wxTimeSpan(24);
3248void MyFrame::TrackDailyRestart() {
3250 Track *pPreviousTrack = TrackOff(
true);
3257 if (pPreviousTrack) {
3258 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3262 if (RouteManagerDialog::getInstanceFlag()) {
3270void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3272 cc->SetUpMode(mode);
3274 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3275 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3276 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3279 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3284 cc->SetShowENCText(!cc->GetShowENCText());
3286 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3294void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3297 cc->SetENCDisplayCategory(nset);
3299 UpdateGlobalMenuItems();
3310 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3312 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3321 cc->SetShowENCLights(!cc->GetShowENCLights());
3323 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3333void MyFrame::ToggleRocks(
void )
3339 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3340 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3341 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3342 pOLE->nViz = !pOLE->nViz;
3346 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3347 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3348 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3351 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3355 ps52plib->GenerateStateHash();
3362 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3364 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3372 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3374 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3389 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3390 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3395 cc->SetShowAIS(!cc->GetShowAIS());
3396 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3400void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3401 cc->SetAttenAIS(!cc->GetAttenAIS());
3402 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3408 cc->m_bFollow =
true;
3411 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3415 SetChartUpdatePeriod();
3423 cc->m_bFollow =
false;
3425 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3429 SetChartUpdatePeriod();
3432void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3433 cc->SetShowOutlines(!cc->GetShowOutlines());
3435 RefreshAllCanvas(
false);
3439 if (g_bopengl) InvalidateAllGL();
3442 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3445void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3447void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3449 bool enabled = m_pMenuBar->IsEnabled(item_id);
3450 m_pMenuBar->Enable(item_id,
false);
3451 m_pMenuBar->Check(item_id, state);
3452 m_pMenuBar->Enable(item_id, enabled);
3456void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3463void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3464 wxBitmap *bmpRollover) {
3466 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3471void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3472 wxString rolloverSVGfile,
3473 wxString toggledSVGfile) {
3476 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3480void MyFrame::ConfigureStatusBar() {
3482 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3485 UseNativeStatusBar(
false);
3488 if (g_bShowStatusBar) {
3489 if (!m_pStatusBar) {
3491 CreateStatusBar(m_StatusBarFieldCount, 0);
3492 ApplyGlobalColorSchemetoStatusBar();
3497 m_pStatusBar->Destroy();
3498 m_pStatusBar = NULL;
3504void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3505 ConfigureStatusBar();
3507 wxSize lastOptSize = options_lastWindowSize;
3513 options_lastWindowSize = lastOptSize;
3515 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3518void MyFrame::BuildMenuBar() {
3524 bool showMenuBar =
true;
3526 bool showMenuBar = g_bShowMenuBar;
3538 m_pMenuBar =
new wxMenuBar();
3539 RegisterGlobalMenuItems();
3540 SetMenuBar(m_pMenuBar);
3544 UpdateGlobalMenuItems();
3549 m_pMenuBar->Destroy();
3555void MyFrame::RegisterGlobalMenuItems() {
3556 if (!m_pMenuBar)
return;
3558 wxMenu *nav_menu =
new wxMenu();
3559 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3560 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3561 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3562 nav_menu->AppendSeparator();
3563 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3564 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3565 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3566 nav_menu->AppendSeparator();
3568 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3569 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3571 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3572 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3574 nav_menu->AppendSeparator();
3575 nav_menu->Append(ID_MENU_SCALE_IN,
3576 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3577 nav_menu->Append(ID_MENU_SCALE_OUT,
3578 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3580 nav_menu->AppendSeparator();
3581 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3583 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3585 wxMenu *view_menu =
new wxMenu();
3587 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3588 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3589 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3590 _menuText(_(
"Show Chart Outlines"),
"O"));
3592 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3593 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3594 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3595 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3597 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3598 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3600 view_menu->AppendSeparator();
3602 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3603 _menuText(_(
"Show ENC text"),
"T"));
3604 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3605 _menuText(_(
"Show ENC Lights"),
"L"));
3606 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3607 _menuText(_(
"Show ENC Soundings"),
"S"));
3608 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3609 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3610 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3611 _menuText(_(
"Show ENC Data Quality"),
"U"));
3612 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3613 _menuText(_(
"Show Navobjects"),
"V"));
3615 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3616 _menuText(_(
"Show ENC text"),
"Alt-T"));
3617 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3618 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3619 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3620 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3621 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3622 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3624 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3625 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3626 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3628 view_menu->AppendSeparator();
3629 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3630 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3631 view_menu->AppendSeparator();
3633 view_menu->Append(ID_MENU_UI_COLSCHEME,
3634 _menuText(_(
"Change Color Scheme"),
"C"));
3636 view_menu->Append(ID_MENU_UI_COLSCHEME,
3637 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3640 view_menu->AppendSeparator();
3642 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3643 _menuText(_(
"Toggle Full Screen"),
"F11"));
3645 m_pMenuBar->Append(view_menu, _(
"&View"));
3647 wxMenu *ais_menu =
new wxMenu();
3648 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3650 _(
"Attenuate less critical AIS targets"));
3651 ais_menu->AppendSeparator();
3652 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3653 _(
"Hide Moored AIS Targets"));
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3656 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3659 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3660 _menuText(_(
"Show CPA Warnings"),
"W"));
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3663 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3666 ais_menu->AppendSeparator();
3667 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3668 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3670 wxMenu *tools_menu =
new wxMenu();
3672 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3673 _menuText(_(
"Data Monitor"),
"E"));
3674 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3675 _menuText(_(
"Measure Distance"),
"M"));
3677 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3678 _menuText(_(
"Data Monitor"),
"Alt-E"));
3679 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3680 _menuText(_(
"Measure Distance"),
"Alt-M"));
3683 tools_menu->AppendSeparator();
3684 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3685 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3686 tools_menu->AppendSeparator();
3687 tools_menu->Append(ID_MENU_MARK_BOAT,
3688 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3689 tools_menu->Append(ID_MENU_MARK_CURSOR,
3690 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3691 tools_menu->AppendSeparator();
3695 _menuText(_(
"Drop MOB Marker"),
3697 tools_menu->AppendSeparator();
3698 tools_menu->Append(wxID_PREFERENCES,
3699 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3701 tools_menu->Append(ID_MENU_MARK_MOB,
3702 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3703 tools_menu->AppendSeparator();
3704 tools_menu->Append(wxID_PREFERENCES,
3705 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3707 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3710 wxMenu *window_menu =
new wxMenu();
3711 m_pMenuBar->Append(window_menu, _(
"&Window"));
3714 wxMenu *help_menu =
new wxMenu();
3715 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3716 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3717 m_pMenuBar->Append(help_menu, _(
"&Help"));
3720 UpdateGlobalMenuItems();
3723void MyFrame::UpdateGlobalMenuItems() {
3724 if (!m_pMenuBar)
return;
3726 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3727 ->Check(GetPrimaryCanvas()->m_bFollow);
3728 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3729 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3730 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3731 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3732 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3733 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3734 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3735 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3736 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3737 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3739 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3740 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3741 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3744 if (g_bAIS_CPA_Alert) {
3745 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3746 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3748 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3749 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3753 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3754 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3757 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3758 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3759 ->Check(ps52plib->GetShowSoundings());
3761 bool light_state =
false;
3763 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3765 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3766 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3767 light_state = (pOLE->nViz == 1);
3772 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3773 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3777 DisCat nset = ps52plib->GetDisplayCategory();
3778 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3779 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3780 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3781 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3782 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3783 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3784 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3786 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3787 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3788 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3793void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3794 if (!m_pMenuBar)
return;
3796 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3798 if (cc->GetUpMode() == NORTH_UP_MODE)
3799 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3800 else if (cc->GetUpMode() == COURSE_UP_MODE)
3801 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3803 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3805 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3806 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3807 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3808 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3809 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3810 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3811 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3812 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3813 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3814 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3815 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3816 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3817 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3818 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3819 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3822 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3823 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3826 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3828 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3829 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3834 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3838 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3839 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3840 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3841 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3842 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3843 ->Check(cc->GetShowENCDataQual());
3844 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3846 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3847 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3848 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3853void MyFrame::InvalidateAllCanvasUndo() {
3855 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3857 if (cc) cc->undo->InvalidateUndo();
3861void MyFrame::SubmergeAllCanvasToolbars() {
3863 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3865 if (cc) cc->SubmergeToolbar();
3869void MyFrame::SurfaceAllCanvasToolbars() {
3870 if (g_bshowToolbar) {
3872 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3874 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3881void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3883 if (lon > 180.0) lon -= 360.0;
3888 cc->JumpToPosition(lat, lon,
scale);
3891 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3895void MyFrame::UpdateCanvasConfigDescriptors() {
3897 for (
unsigned int i = 0;
3898 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3899 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3907 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3908 cc->GroupID = chart->m_groupIndex;
3911 cc->
bQuilt = chart->GetQuiltMode();
3917 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3919 cc->
bFollow = chart->m_bFollow;
3924 int upmode = chart->GetUpMode();
3925 if (upmode == COURSE_UP_MODE)
3927 else if (upmode == HEAD_UP_MODE)
3934void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3935 if (!RBBox.GetValid())
return;
3937 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3938 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3941 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3942 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3950 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3951 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3953 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3954 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3956 cc->GetSize(&ww, &wh);
3958 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3960 ppm = wxMin(ppm, 1.0);
3966void MyFrame::PrepareOptionsClose(
options *settings,
3967 int settings_return_value) {
3969 options_lastPage = settings->lastPage;
3974 if (options_lastPage == 1) options_lastPage = 0;
3976 options_subpage = settings->lastSubPage;
3977 options_lastWindowPos = settings->lastWindowPos;
3978 options_lastWindowSize = settings->lastWindowSize;
3981 androidEnableBackButton(
true);
3982 androidEnableOptionsMenu(
true);
3983 androidRestoreFullScreen();
3984 androidEnableRotation();
3987 EnableSettingsTool(
true);
3990void MyFrame::DoOptionsDialog() {
3991 EnableSettingsTool(
false);
3994 AbstractPlatform::ShowBusySpinner();
3997 pConfig->SetPath(
"/Settings");
3998 pConfig->Read(
"OptionsSizeX", &sx, -1);
3999 pConfig->Read(
"OptionsSizeY", &sy, -1);
4001 wxWindow *optionsParent =
this;
4003 optionsParent = GetPrimaryCanvas();
4006 callbacks.prepare_close = [&](
options *me,
int changes) {
4007 PrepareOptionsClose(me, changes);
4009 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4010 ProcessOptionsDialog(changes, workdir_list);
4013 wxPoint(-1, -1), wxSize(sx, sy));
4015 AbstractPlatform::HideBusySpinner();
4019 g_options->SetInitChartDir(*pInit_Chart_Dir);
4023 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4024 g_options->SetWorkDirListPtr(pWorkDirArray);
4030 prev_locale = g_locale;
4031 g_options->SetInitialPage(options_lastPage, options_subpage);
4034 g_options->lastWindowPos = options_lastWindowPos;
4035 if (options_lastWindowPos != wxPoint(0, 0)) {
4037 g_options->SetSize(options_lastWindowSize);
4041 if (options_lastWindowSize != wxSize(0, 0)) {
4042 g_options->SetSize(options_lastWindowSize);
4047 androidEnableBackButton(
false);
4048 androidEnableOptionsMenu(
false);
4049 androidDisableFullScreen();
4057 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4060 wxString chart_file_name;
4061 if (cc->GetQuiltMode()) {
4062 int dbi = cc->GetQuiltRefChartdbIndex();
4063 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4065 if (cc->m_singleChart)
4066 chart_file_name = cc->m_singleChart->GetFullPath();
4069 pathArray.Add(chart_file_name);
4075 last_canvasConfig = g_canvasConfig;
4078 g_last_ChartScaleFactor = g_ChartScaleFactor;
4084void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4085 bool b_need_refresh =
false;
4088 if ((rr & VISIT_CHARTS) &&
4089 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4091 UpdateChartDatabaseInplace(*pNewDirArray,
4092 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4095 b_need_refresh =
true;
4100 if (rr & STYLE_CHANGED) {
4103 _(
"Please restart OpenCPN to activate language or style changes."),
4104 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4107 bool charts_updating =
4108 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4109 if (!charts_updating) RefreshGroupIndices();
4111 if (rr & TIDES_CHANGED) {
4117 if (rr & S52_CHANGED) {
4118 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4129 g_Platform->GetDisplayDPmm());
4132 double stuffcog = NAN;
4133 double stuffsog = NAN;
4134 if (!std::isnan(
gCog)) stuffcog =
gCog;
4135 if (!std::isnan(
gSog)) stuffsog =
gSog;
4137 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4138 COGFilterTable[i] = stuffcog;
4139 SOGFilterTable[i] = stuffsog;
4142 SetChartUpdatePeriod();
4144 if (rr & GL_CHANGED) {
4148 b_need_refresh =
true;
4151 if (rr & S52_CHANGED) {
4152 b_need_refresh =
true;
4156 if (rr & REBUILD_RASTER_CACHE) {
4158 GetPrimaryCanvas()->Disable();
4160 GetPrimaryCanvas()->Enable();
4165 if (g_config_display_size_manual &&
4173 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4180 int rrt = rr & S52_CHANGED;
4182 (rrt == S52_CHANGED) ||
4183 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4193 ps52plib->SetScaleFactorExp(
4194 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4195 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4199 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4201 if (cc) cc->ApplyGlobalSettings();
4209 if (!charts_updating) {
4210 bool ztc = g_bEnableZoomToCursor;
4211 g_bEnableZoomToCursor =
false;
4213 if (!GetPrimaryCanvas()->IsFrozen())
4215 g_bEnableZoomToCursor = ztc;
4220 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4229 SetGPSCompassScale();
4231 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4234 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4235 if (!charts_updating) cc->UpdateCanvasControlBar();
4238 UpdateGPSCompassStatusBoxes();
4240 SetAllToolbarScale();
4241 RequestNewToolbars();
4243 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4246 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4249 cc->RebuildCursors();
4254 bool b_masterScaleChange =
false;
4255 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4256 b_masterScaleChange =
true;
4258 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4259 RequestNewMasterToolbar(
true);
4261 bool bMuiChange =
false;
4267 if (b_masterScaleChange || bMuiChange) {
4269 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4272 cc->ProcessNewGUIScale();
4278 if (rr & LOCALE_CHANGED) {
4279 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4281 rr |= NEED_NEW_OPTIONS;
4290 g_last_ChartScaleFactor = g_ChartScaleFactor;
4295bool MyFrame::CheckGroup(
int igroup) {
4296 if (igroup == 0)
return true;
4300 if (!pGroup->m_element_array.size())
4303 for (
const auto &elem : pGroup->m_element_array) {
4304 for (
unsigned int ic = 0;
4305 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4306 auto &cte =
ChartData->GetChartTableEntry(ic);
4307 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4309 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4316bool MyFrame::ScrubGroupArray() {
4321 bool b_change =
false;
4322 unsigned int igroup = 0;
4323 while (igroup < g_pGroupArray->GetCount()) {
4324 bool b_chart_in_element =
false;
4327 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4328 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4330 for (
unsigned int ic = 0;
4331 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4332 auto &cte =
ChartData->GetChartTableEntry(ic);
4333 wxString chart_full_path = cte.GetFullSystemPath();
4335 if (chart_full_path.StartsWith(element_root)) {
4336 b_chart_in_element =
true;
4342 if (!b_chart_in_element) {
4343 wxString test_string =
"GSHH";
4344 if (element_root.Upper().Contains(test_string))
4345 b_chart_in_element =
true;
4348 if (!b_chart_in_element)
4350 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4362void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4364 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4366 if (cc && (cc != ccThis)) cc->Refresh();
4371void MyFrame::ChartsRefresh() {
4374 AbstractPlatform::ShowBusySpinner();
4376 bool b_run = FrameTimer1.IsRunning();
4379 FrameTenHzTimer.Stop();
4382 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4385 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4386 if (cc->GetQuiltMode()) {
4387 currentIndex = cc->GetQuiltReferenceChartIndex();
4389 cc->canvasChartsRefresh(currentIndex);
4393 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4394 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4396 AbstractPlatform::HideBusySpinner();
4399void MyFrame::InvalidateAllQuilts() {
4400 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4403 cc->InvalidateQuilt();
4404 cc->SetQuiltRefChart(-1);
4405 cc->m_singleChart = NULL;
4410bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4412 const wxString &ChartListFileName) {
4413 bool b_run = FrameTimer1.IsRunning();
4415 FrameTenHzTimer.Stop();
4417 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4418 FrameCOGTimer.Stop();
4421 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4424 cc->InvalidateQuilt();
4425 cc->SetQuiltRefChart(-1);
4426 cc->m_singleChart = NULL;
4436 AbstractPlatform::ShowBusySpinner();
4439 wxString longmsg = _(
"OpenCPN Chart Update");
4441 ".................................................................."
4444 Updateprog =
new wxGenericProgressDialog();
4447 Updateprog->SetFont(*qFont);
4449 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4450 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4451 wxPD_REMAINING_TIME);
4453 DimeControl(Updateprog);
4458 wxLogMessage(
"Starting chart database Update...");
4462 m_gshhg_chart_loc = gWorldMapLocation;
4463 gWorldMapLocation = wxEmptyString;
4467 AbstractPlatform::HideBusySpinner();
4471void MyFrame::FinalizeChartDBUpdate() {
4473 if (!g_bDeferredInitDone) {
4475 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4478 bool b_groupchange = ScrubGroupArray();
4480 RefreshGroupIndices();
4482 if (b_groupchange) {
4483 pConfig->DestroyConfigGroups();
4488 if (g_bDeferredInitDone) ScheduleReloadCharts();
4493 cc->ToggleCanvasQuiltMode();
4495 bool cur_mode = cc->GetQuiltMode();
4497 if( !cc->GetQuiltMode() )
4498 cc->SetQuiltMode(
true );
4500 if( cc->GetQuiltMode() ) {
4501 cc->SetQuiltMode(
false );
4502 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4506 if( cur_mode != cc->GetQuiltMode() ){
4512 g_bQuiltEnable = cc->GetQuiltMode();
4516 ps52plib->GenerateStateHash();
4524 DoStackDelta(cc, -1);
4530 DoStackDelta(cc, 1);
4533void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4535void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4537void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4539 cc->DoCanvasStackDelta(direction);
4543void MyFrame::PositionIENCToolbar() {
4547 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4549 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4557void MyFrame::OnInitTimer(wxTimerEvent &event) {
4560 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4564 wxLog::FlushActive();
4566 switch (m_iInitCount++) {
4568 EnableSettingsTool(
false);
4573 if (g_bInlandEcdis) {
4574 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4575 double range_set = 500.;
4577 range = wxRound(range * 10) / 10.;
4581 else if (range > 2000.)
4583 else if (range > 1600.)
4585 else if (range > 1200.)
4587 else if (range > 800.)
4592 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4596 g_Platform->SetFullscreen(g_bFullscreen);
4600 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4603 cc->SetGroupIndex(0,
false);
4610 StartRebuildChartDatabase();
4621 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4635 3 * GetCharHeight());
4637 m_data_monitor->Center();
4645 pConfig->SetPath(
"/Settings");
4646 pConfig->Read(
"OptionsSizeX", &sx, -1);
4647 pConfig->Read(
"OptionsSizeY", &sy, -1);
4649 wxWindow *optionsParent =
this;
4651 optionsParent = GetPrimaryCanvas();
4653 BuildiENCToolbar(
true, m_toolbar_callbacks);
4660 if (!g_params.empty()) {
4661 for (
size_t n = 0; n < g_params.size(); n++) {
4662 wxString path = g_params[n];
4663 if (::wxFileExists(path)) {
4665 pSet->load_file(path.fn_str());
4668 pSet->LoadAllGPXObjects(
4669 !pSet->IsOpenCPN(), wpt_dups,
4671 LLBBox box = pSet->GetBBox();
4672 if (box.GetValid()) {
4673 CenterView(GetPrimaryCanvas(), box);
4682 InitAppMsgBusListener();
4687 auto loader = PluginLoader::GetInstance();
4688 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4689 if (!b_haveWMM)
gVar = g_UserVar;
4697 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4700 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4702 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4705 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4709 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4710 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4711 NavObj_dB::GetInstance().LoadNavObjects();
4714 if (!g_AW1GUID.IsEmpty()) {
4717 if (!g_AW2GUID.IsEmpty()) {
4723 appendOSDirSlash(&layerdir);
4724 layerdir.Append(
"layers");
4726 if (wxDir::Exists(layerdir)) {
4728 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4729 wxLogMessage(laymsg);
4730 pConfig->LoadLayers(layerdir);
4735 if (!g_kiosk_startup) {
4736 AbstractPlatform::ShowBusySpinner();
4739 pConfig->SetPath(
"/Settings");
4740 pConfig->Read(
"OptionsSizeX", &sx, -1);
4741 pConfig->Read(
"OptionsSizeY", &sy, -1);
4743 wxWindow *optionsParent =
this;
4745 optionsParent = GetPrimaryCanvas();
4748 callbacks.prepare_close = [&](
options *me,
int changes) {
4749 PrepareOptionsClose(me, changes);
4751 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4752 ProcessOptionsDialog(changes, workdir_list);
4755 wxPoint(-1, -1), wxSize(sx, sy));
4756 AbstractPlatform::HideBusySpinner();
4763 wxLogMessage(
"OnInitTimer...Last Call");
4767 RequestNewMasterToolbar();
4769 PositionIENCToolbar();
4771 g_bDeferredInitDone =
true;
4781 GetPrimaryCanvas()->SetFocus();
4782 GetPrimaryCanvas()->Enable();
4785 if (b_reloadForPlugins) {
4791 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4793 if (cc) cc->SetFirstAuto(
true);
4801 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4803 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4807 cc->CheckGroupValid();
4808 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4809 cc->SetShowGPSCompassWindow(
true);
4814 androidEnableBackButton(
true);
4815 androidEnableRotation();
4816 androidEnableOptionItems(
true);
4820 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4826 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4828 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4830 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4836 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4838 wxLog::FlushActive();
4840 RefreshAllCanvas(
true);
4841 UsbWatchDaemon::GetInstance().Start();
4842 EnableSettingsTool(
true);
4848void MyFrame::InitAppMsgBusListener() {
4849 auto &msgbus = AppMsgBus::GetInstance();
4852 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4853 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4857 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4858 HandleBasicNavMsg(basicnav_msg);
4862 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4863 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4867 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4868 HandleGPSWatchdogMsg(msg);
4875void MyFrame::ReleaseApiListeners() {}
4880 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4881 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4882 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4883 server.open_file_cb = [&](
const std::string &path) {
4884 return m_open_gpx_file(path);
4891void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4892 if (msg->gps_watchdog <= 0) {
4893 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4897 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4902 if (m_fix_start_time.IsValid()) {
4903 wxDateTime now = wxDateTime::Now();
4904 wxTimeSpan span = now - m_fix_start_time;
4905 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4906 auto ¬eman = NotificationManager::GetInstance();
4907 wxString msg = _(
"GNSS Position fix lost");
4908 noteman.AddNotification(NotificationSeverity::kCritical,
4910 m_fix_start_time = wxInvalidDateTime;
4914 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4915 bool last_bVelocityValid = bVelocityValid;
4916 bVelocityValid =
false;
4923void MyFrame::CalculateCOGAverage() {
4925 if (!std::isnan(
gCog)) {
4928 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4931 double sum = 0., count = 0;
4933 double adder = COGTable[i];
4934 if (std::isnan(adder))
continue;
4936 if (fabs(adder -
g_COGAvg) > 180.) {
4950 else if (sum >= 360.)
4959void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4960 m_fixtime = msg->time;
4961 double hdt_data_interval = 0;
4962 double fix_time_interval = 0;
4964 double msgtime = msg->set_time.tv_sec;
4965 double m1 = msg->set_time.tv_nsec / 1e9;
4968 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4969 ((msg->vflag & POS_VALID) == POS_VALID)) {
4971 if (!m_fix_start_time.IsValid()) {
4972 m_fix_start_time = wxDateTime::Now();
4977 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4980 fix_time_gt_last = fix_time_gt;
4981 uint64_t fix_time_gt_now =
4982 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4983 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4987 double implied_sog = dist / (fix_time_interval / 3600);
4992 gLat_gt_m1 = gLat_gt;
4993 gLon_gt_m1 = gLon_gt;
4997 fix_time_gt = fix_time_gt_now;
5001 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5002 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5003 gCog_gt_m1 = gCog_gt;
5013 if (!std::isnan(gCog_gt_m1)) {
5015 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5022 if ((fix_time_gt - fix_time_gt_last) > .08) {
5027 if (gCog_gt > gCog_gt_m1) {
5028 if ((gCog_gt - gCog_gt_m1) > 180.)
5033 if ((gCog_gt_m1 - gCog_gt) > 180.)
5038 difft = fabs(gCog_gt - gCog_gt_m1);
5039 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5047 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5048 tentative_cog_rate_gt *= 1e9;
5049 cog_rate_gt = tentative_cog_rate_gt;
5057 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5060static double hdt_avg;
5061 double hdt_norm =
gHdt;
5062 if(
gHdt > 180) hdt_norm -= 360;
5065 hdt_avg += hdt_norm * 0.1;
5070 if (!std::isnan(
gHdt)) {
5072 uint64_t hdt_time_gt_last = hdt_time_gt;
5073 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5074 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5077 if (hdt_data_interval > .09) {
5079 gHdt_gt_m1 = gHdt_gt;
5082 if (!std::isnan(gHdt_gt_m1)) {
5084 double tentative_hdt_rate_gt =
5085 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5086 tentative_hdt_rate_gt *= 1e9;
5088 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5089 hdt_rate_gt = tentative_hdt_rate_gt;
5097 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5100 CalculateCOGAverage();
5108 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5109 if ((msg->vflag & POS_VALID) == POS_VALID)
5114 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5116 bVelocityValid =
true;
5120void MyFrame::UpdateStatusBar() {
5123 unsigned long uiCurrentTickCount;
5124 m_MMEAeventTime.SetToCurrent();
5125 uiCurrentTickCount =
5126 m_MMEAeventTime.GetMillisecond() / 100;
5127 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5128 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5129 m_ulLastNMEATicktime = uiCurrentTickCount;
5131 if (m_tick_idx++ > 6) m_tick_idx = 0;
5136 if (NULL != GetStatusBar()) {
5139 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5142 wxString s1(tick_buf, wxConvUTF8);
5144 s1 += toSDMM(1,
gLat);
5146 s1 += toSDMM(2,
gLon);
5148 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5152 if (!std::isnan(
gSog))
5153 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5155 sogcog.Printf(
"SOG --- ");
5159 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5161 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5163 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5164 (
int)toMagnetic(
gCog), 0x00B0);
5166 cogs.Printf((
"COG ---%c"), 0x00B0);
5168 sogcog.Append(cogs);
5169 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5174void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5175 MemFootTimer.Stop();
5177 int memsize = GetApplicationMemoryUse();
5180 printf(
"Memsize: %d \n", memsize);
5183 if (memsize > (g_MemFootMB * 1000)) {
5187 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5188 unsigned int nCache = pCache->GetCount();
5191 for (
unsigned int i = 0; i < nCache; i++) {
5201 for (
unsigned int i = 0; i < nCache - 1; i++) {
5202 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5204 pcea[i] = pcea[i + 1];
5215 unsigned int idelete = 0;
5216 unsigned int idelete_max = pCache->GetCount();
5219 unsigned int minimum_cache = 1;
5220 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5222 while ((memsize > (g_MemFootMB * 1000)) &&
5223 (pCache->GetCount() > minimum_cache) &&
5224 (idelete < idelete_max)) {
5225 int memsizeb = memsize;
5229 memsize = GetApplicationMemoryUse();
5230 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5238 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5243void MyFrame::CheckToolbarPosition() {
5246 static bool bMaximized;
5248 if (IsMaximized() && !bMaximized) {
5255 PositionIENCToolbar();
5256 }
else if (!IsMaximized() && bMaximized) {
5264 PositionIENCToolbar();
5269void MyFrame::ProcessUnitTest() {
5270 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5277 cc->m_bFollow =
false;
5279 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5280 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5283 if (cc->m_groupIndex > 0) {
5284 while (ut_index < ChartData->GetChartTableEntries() &&
5285 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5289 if (ut_index < ChartData->GetChartTableEntries()) {
5293 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5294 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5301 if (cc->GetQuiltMode()) {
5302 if (cc->IsChartQuiltableRef(ut_index))
5303 cc->SelectQuiltRefdbChart(ut_index);
5305 cc->SelectdbChart(ut_index);
5308 if (g_unit_test_1) {
5316 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5317 cte->GetLatMin(), cte->GetLonMax(), NULL,
5321 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5322 cte->GetLatMax(), cte->GetLonMin(), NULL,
5325 cc->GetSize(&ww, &wh);
5326 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5328 ppm = wxMin(ppm, 1.0);
5335 if (ut_index > ut_index_max) exit(0);
5346 bool b_rotate =
false;
5348 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5351 if (!b_rotate && !g_btenhertz)
return;
5353 bool b_update =
false;
5355 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5358 struct timespec now;
5359 clock_gettime(CLOCK_MONOTONIC, &now);
5360 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5361 double diffc = diff / 1e9;
5364 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5365 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5366 if (gCog_tentative < 0.) gCog_tentative += 360.;
5367 gCog = gCog_tentative;
5371 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5372 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5373 double diffc = diff / 1e9;
5374 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5378 if (gSog_gt && !std::isnan(gCog_gt)) {
5379 double delta_t = diffc / 3600;
5380 double distance = gSog_gt * delta_t;
5383 double angr = gCog_gt / 180 * M_PI;
5384 double latr = gLat_gt * M_PI / 180;
5385 double D = distance / 3443;
5386 double sD = sin(D), cD = cos(D);
5387 double sy = sin(latr), cy = cos(latr);
5388 double sa = sin(angr), ca = cos(angr);
5390 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5391 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5401 if (cc) cc->DoCanvasCOGSet();
5410 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5411 bool bnew = cc->DoCanvasUpdate();
5412 if (!bnew) cc->UpdateShips();
5421 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5424bool MyFrame::ProcessQuitFlag() {
5428 FrameTenHzTimer.Stop();
5430 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5431 if (top) top->Close(
true);
5438void MyFrame::ProcessDeferredTrackOn() {
5441 if (g_bDeferredStartTrack) {
5442 if (!g_bTrackActive) {
5445 g_bDeferredStartTrack =
false;
5448 g_bDeferredStartTrack =
false;
5453void MyFrame::ProcessAnchorWatch() {
5461 double d = g_nAWMax;
5464 bool toofar =
false;
5465 bool tooclose =
false;
5466 if (d >= 0.0) toofar = (dist * 1852. > d);
5467 if (d < 0.0) tooclose = (dist * 1852 < -d);
5469 if (tooclose || toofar)
5470 AnchorAlertOn1 =
true;
5472 AnchorAlertOn1 =
false;
5474 AnchorAlertOn1 =
false;
5482 double d = g_nAWMax;
5485 bool toofar =
false;
5486 bool tooclose =
false;
5487 if (d >= 0) toofar = (dist * 1852. > d);
5488 if (d < 0) tooclose = (dist * 1852 < -d);
5490 if (tooclose || toofar)
5491 AnchorAlertOn2 =
true;
5493 AnchorAlertOn2 =
false;
5495 AnchorAlertOn2 =
false;
5498 AnchorAlertOn1 =
true;
5501void MyFrame::SendFixToPlugins() {
5512 GPSData.
nSats = g_SatsInView;
5514 wxDateTime tCheck((time_t)m_fixtime);
5515 if (tCheck.IsValid()) {
5524 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5527 SendPositionFixToAllPlugIns(&GPSData);
5531void MyFrame::ProcessLogAndBells() {
5534 wxDateTime lognow = wxDateTime::Now();
5535 int hourLOC = lognow.GetHour();
5536 int minuteLOC = lognow.GetMinute();
5538 int minuteUTC = lognow.GetMinute();
5539 int second = lognow.GetSecond();
5541 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5542 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5543 (minuteUTC == 30)) {
5544 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5545 wxString day = lognow.FormatISODate();
5546 wxString utc = lognow.FormatISOTime();
5547 wxString navmsg =
"LOGBOOK: ";
5555 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5559 if (std::isnan(
gCog))
5560 cog.Printf(
"COG ----- ");
5562 cog.Printf(
"COG %10.5f ",
gCog);
5565 if (std::isnan(
gSog))
5566 sog.Printf(
"SOG ----- ");
5568 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5574 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5577 wxLogMessage(navmsg);
5578 g_loglast_time = lognow;
5580 int bells = (hourLOC % 4) * 2;
5581 if (minuteLOC != 0) bells++;
5582 if (!bells) bells = 8;
5584 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5585 m_BellsToPlay = bells;
5586 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5587 wxPostEvent(
this, ev);
5594 CheckToolbarPosition();
5598 if (ProcessQuitFlag())
return;
5600 if (bDBUpdateInProgress)
return;
5603 FrameTenHzTimer.Stop();
5605 ProcessDeferredTrackOn();
5607 ProcessAnchorWatch();
5608 ProcessLogAndBells();
5610 if (ShouldRestartTrack()) TrackDailyRestart();
5613 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5614 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5615 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5621 if (
gSog > 3.0) g_bCruising =
true;
5627 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5629 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5635 bool bnew_view =
false;
5636 if (!g_btenhertz) bnew_view = DoChartUpdate();
5643 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5646 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5649 cc->DrawBlinkObjects();
5652 if (bactiveRouteUpdate) {
5659 cc->SetOwnShipState(SHIP_NORMAL);
5661 if (cc->GetQuiltMode()) {
5662 double erf = cc->GetQuiltMaxErrorFactor();
5663 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5665 if (cc->m_singleChart) {
5666 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5667 cc->SetOwnShipState(SHIP_LOWACCURACY);
5671 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5674 (bVelocityValid != m_last_bVelocityValid) ||
5675 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5676 if (!g_bopengl) cc->UpdateShips();
5684 m_last_bVelocityValid = bVelocityValid;
5689 bool brq_dynamic =
false;
5691 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5692 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5694 if (pic->m_enabled && pic->m_init_state) {
5695 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5702 if (brq_dynamic) bnew_view =
true;
5706 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5709 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5714 if (cc->GetglCanvas()) {
5716 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5718 if ((!g_btenhertz)) {
5719 if (cc->m_bFollow) {
5720 cc->DoCanvasUpdate();
5737 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5751 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5752 g_pais_query_dialog_active->UpdateText();
5755 if (g_pAISTargetList && (0 == (g_tick % (5))))
5756 g_pAISTargetList->UpdateAISTargetList();
5759 UpdateGPSCompassStatusBoxes();
5764 console->RefreshConsoleData();
5771 if (m_bdefer_resize) {
5772 if (0 == (g_tick % (5))) {
5773 printf(
"___RESIZE\n");
5774 SetSize(m_defer_size);
5776 m_bdefer_resize =
false;
5783 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5785 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5786 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5790double MyFrame::GetMag(
double a,
double lat,
double lon) {
5791 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5792 auto loader = PluginLoader::GetInstance();
5793 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5800 wxDateTime now = wxDateTime::Now();
5801 SendJSON_WMM_Var_Request(lat, lon, now);
5802 if (fabs(gQueryVar) < 360.0)
5803 Variance = gQueryVar;
5805 return toMagnetic(a, Variance);
5808bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5814 v[
"Year"] = date.GetYear();
5815 v[
"Month"] = date.GetMonth();
5816 v[
"Day"] = date.GetDay();
5818 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5824void MyFrame::TouchAISActive() {
5826 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5828 if (cc) cc->TouchAISToolActive();
5832void MyFrame::UpdateAISTool() {
5836 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5838 if (cc) cc->UpdateAISTBTool();
5843void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5845 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5847 if (cc) cc->SetbTCUpdate(
true);
5850 RefreshAllCanvas(
false);
5855void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5859 bool b_rotate =
false;
5860 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5862 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5866 FrameCOGTimer.Stop();
5873 int period_ms = 100;
5875 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5878void MyFrame::DoCOGSet() {
5880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5882 if (cc) cc->DoCanvasCOGSet();
5886void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5892 wxFont oldfont = pdc->GetFont();
5894 pdc->SetFont(*pFont);
5895 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5896 pdc->SetBackgroundMode(wxTRANSPARENT);
5898 pdc->DrawText(str, x, y + 1);
5899 pdc->DrawText(str, x, y - 1);
5900 pdc->DrawText(str, x + 1, y);
5901 pdc->DrawText(str, x - 1, y);
5903 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5905 pdc->DrawText(str, x, y);
5907 pdc->SetFont(oldfont);
5911void MyFrame::UpdateRotationState(
double rotation) {
5913 g_bCourseUp =
false;
5915 if (fabs(rotation) > .001) {
5916 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5917 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5919 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5922 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5923 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5925 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5929 UpdateGPSCompassStatusBoxes(
true);
5933void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5935 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5937 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5943int MyFrame::GetApplicationMemoryUse() {
5949 wxWindow *fWin = wxWindow::FindFocus();
5951 wxArrayString outputArray;
5952 wxString cmd(
"ps --no-headers -o vsize ");
5953 unsigned long pid = wxGetProcessId();
5955 cmd1.Printf(
"%ld", pid);
5957 wxExecute(cmd, outputArray);
5959 if (outputArray.GetCount()) {
5960 wxString s = outputArray.Item(0);
5962 if (s.ToLong(&vtmp)) memsize = vtmp;
5965 if (fWin) fWin->SetFocus();
5971 PROCESS_MEMORY_COUNTERS pmc;
5973 unsigned long processID = wxGetProcessId();
5975 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5977 if (NULL == hProcess)
return 0;
5979 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5997 memsize = pmc.WorkingSetSize / 1024;
6000 CloseHandle(hProcess);
6007double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6008 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6011void MyFrame::SetChartUpdatePeriod() {
6014 g_ChartUpdatePeriod = 0;
6019 bool bskewdc =
false;
6020 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6023 if (!g_bopengl && !cc->GetVP().b_quilt) {
6024 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6026 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6030 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6032 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6037 cc->UpdateCanvasControlBar();
6040void MyFrame::selectChartDisplay(
int type,
int family) {
6042 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6044 if (cc) cc->selectCanvasChartDisplay(type, family);
6047 UpdateGlobalMenuItems();
6056bool MyFrame::DoChartUpdate() {
6057 bool return_val =
false;
6060 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6062 if (cc) return_val |= cc->DoCanvasUpdate();
6068void MyFrame::MouseEvent(wxMouseEvent &event) {
6070 event.GetPosition(&x, &y);
6075#include <mach/mach.h>
6076#include <mach/message.h>
6077#include <mach/kern_return.h>
6078#include <mach/task_info.h>
6080#include <malloc/malloc.h>
6087#if defined(__linux__)
6088#include "sys/types.h"
6089#include "sys/sysinfo.h"
6092void MyFrame::DoPrint(
void) {
6094 g_PrintingInProgress =
true;
6097 GetPrimaryCanvas()->GetglCanvas()->Render();
6098 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6108 printer.Initialize(wxLANDSCAPE);
6109 printer.EnablePageNumbers(
false);
6110 printer.Print(
this, &printout);
6128 g_PrintingInProgress =
false;
6131 GetPrimaryCanvas()->SetFocus();
6137 wxString message_ID =
event.GetID();
6138 wxString message_JSONText =
event.GetJSONText();
6146 if (message_ID ==
"WMM_VARIATION_BOAT") {
6154 int numErrors = reader.
Parse(message_JSONText, &root);
6155 if (numErrors > 0) {
6161 wxString decl = root[
"Decl"].
AsString();
6163 decl.ToDouble(&decl_val);
6169 if (message_ID ==
"WMM_VARIATION") {
6177 int numErrors = reader.
Parse(message_JSONText, &root);
6178 if (numErrors > 0) {
6184 wxString decl = root[
"Decl"].
AsString();
6186 decl.ToDouble(&decl_val);
6188 gQueryVar = decl_val;
6191 if (message_ID ==
"GRIB_TIMELINE") {
6194 int numErrors = r.
Parse(message_JSONText, &v);
6196 if (numErrors > 0) {
6197 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6202 wxDateTime oldTimeSource = gTimeSource;
6204 if (v[
"Day"].AsInt() == -1) {
6205 gTimeSource = wxInvalidDateTime;
6206 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6208 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6209 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6210 v[
"Second"].AsInt());
6214 if (oldTimeSource != gTimeSource) {
6216 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6218 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6223 cc->pCwin->Refresh(
false);
6229 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6232 wxString trk_id = wxEmptyString;
6234 int numErrors = reader.
Parse(message_JSONText, &root);
6235 if (numErrors > 0)
return;
6240 v[
"Track_ID"] = trk_id;
6242 wxString name = wxEmptyString;
6243 if (ptrack->m_GUID == trk_id) {
6244 name = ptrack->GetName();
6245 if (name.IsEmpty()) {
6251 name = _(
"(Unnamed Track)");
6258 v[
"TotalNodes"] = ptrack->GetnPoints();
6259 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6261 v[
"lat"] = tp->m_lat;
6262 v[
"lon"] = tp->m_lon;
6265 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6266 SendJSONMessageToAllPlugins(msg_id, v);
6272 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6273 SendJSONMessageToAllPlugins(msg_id, v);
6275 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6278 wxString guid = wxEmptyString;
6280 int numErrors = reader.
Parse(message_JSONText, &root);
6281 if (numErrors > 0) {
6290 wxString name = wxEmptyString;
6292 if ((*it)->m_GUID == guid) {
6293 name = (*it)->m_RouteNameString;
6294 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6300 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6301 itp != (*it)->pRoutePointList->end(); itp++) {
6302 w[i][
"lat"] = (*itp)->m_lat;
6303 w[i][
"lon"] = (*itp)->m_lon;
6304 w[i][
"Name"] = (*itp)->GetName();
6305 w[i][
"Description"] = (*itp)->GetDescription();
6306 w[i][
"GUID"] = (*itp)->m_GUID;
6307 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6309 auto node = (*itp)->m_HyperlinkList->begin();
6310 if (node != (*itp)->m_HyperlinkList->end()) {
6312 while (node != (*itp)->m_HyperlinkList->end()) {
6314 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6315 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6316 httpLink->DescrText;
6323 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6324 SendJSONMessageToAllPlugins(msg_id, v);
6331 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6332 SendJSONMessageToAllPlugins(msg_id, v);
6333 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6338 int numErrors = reader.
Parse(message_JSONText, &root);
6339 if (numErrors > 0)
return;
6342 wxString str = root[
"mode"].
AsString();
6343 if (str ==
"Track") route =
false;
6348 for (RouteList::iterator it =
pRouteList->begin();
6350 wxString name = (*it)->m_RouteNameString;
6351 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6353 v[i][
"error"] =
false;
6354 v[i][
"name"] = name;
6355 v[i][
"GUID"] = (*it)->m_GUID;
6356 v[i][
"active"] = (*it)->IsActive();
6361 wxString name = ptrack->GetName();
6362 if (name.IsEmpty()) {
6368 name = _(
"(Unnamed Track)");
6370 v[i][
"error"] =
false;
6371 v[i][
"name"] = name;
6372 v[i][
"GUID"] = ptrack->m_GUID;
6377 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6378 SendJSONMessageToAllPlugins(msg_id, v);
6381 v[0][
"error"] =
true;
6382 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6383 SendJSONMessageToAllPlugins(msg_id, v);
6385 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6387 v[0][
"error"] =
true;
6390 v[0][
"error"] =
false;
6391 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6392 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6393 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6394 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6395 v[0][
"active_waypoint_lat"] =
6397 v[0][
"active_waypoint_lon"] =
6401 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6402 SendJSONMessageToAllPlugins(msg_id, v);
6406void MyFrame::FilterCogSog() {
6407 if (g_bfilter_cogsog) {
6409 double cog_last =
gCog;
6412 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6413 COGFilterTable[i] = COGFilterTable[i - 1];
6414 COGFilterTable[0] = cog_last;
6417 if (!std::isnan(cog_last)) {
6419 double sum = 0., count = 0;
6420 for (
int i = 0; i < g_COGFilterSec; i++) {
6421 double adder = COGFilterTable[i];
6422 if (std::isnan(adder))
continue;
6424 if (fabs(adder - cog_last) > 180.) {
6425 if ((adder - cog_last) > 0.)
6438 else if (sum >= 360.)
6445 double sog_last =
gSog;
6448 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6449 SOGFilterTable[i] = SOGFilterTable[i - 1];
6450 SOGFilterTable[0] = sog_last;
6453 if (!std::isnan(
gSog)) {
6454 double sum = 0., count = 0;
6455 for (
int i = 0; i < g_SOGFilterSec; i++) {
6456 if (std::isnan(SOGFilterTable[i]))
continue;
6458 sum += SOGFilterTable[i];
6468void MyFrame::LoadHarmonics() {
6471 ptcmgr->LoadDataSources(TideCurrentDataSet);
6473 bool b_newdataset =
false;
6476 for (
auto a :
ptcmgr->GetDataSet()) {
6477 bool b_foundi =
false;
6478 for (
auto b : TideCurrentDataSet) {
6485 b_newdataset =
true;
6490 for (
auto a : TideCurrentDataSet) {
6491 bool b_foundi =
false;
6492 for (
auto b :
ptcmgr->GetDataSet()) {
6499 b_newdataset =
true;
6504 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6508void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6509 if (!ptarget)
return;
6512 wxDateTime mob_time = wxDateTime::Now();
6513 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6514 mob_label += _(
" on ");
6515 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6518 mob_label, wxEmptyString);
6519 pWP_MOB->SetShared(
true);
6521 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6523 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6525 pWP_MOB->SetUseSca(
false);
6533 wxString(_(
"Own ship")), wxEmptyString);
6535 pWP_MOB->SetUseSca(
false);
6542 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6558 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6559 SendJSONMessageToAllPlugins(msg_id, v);
6562 if (RouteManagerDialog::getInstanceFlag()) {
6569 RefreshAllCanvas(
false);
6571 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6572 mob_message += _(
" Time: ");
6573 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6574 mob_message += _(
" Ownship Position: ");
6575 mob_message += toSDMM(1,
gLat);
6577 mob_message += toSDMM(2,
gLon);
6578 mob_message += _(
" MOB Position: ");
6579 mob_message += toSDMM(1, ptarget->Lat);
6581 mob_message += toSDMM(2, ptarget->Lon);
6582 wxLogMessage(mob_message);
6585void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6589 OwnPoint->m_lat =
gLat;
6590 OwnPoint->m_lon =
gLon;
6592 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6597 MOB_Point->m_lat = ptarget->Lat;
6598 MOB_Point->m_lon = ptarget->Lon;
6600 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6601 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6603 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6604 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6607 RefreshAllCanvas(
false);
6610 wxDateTime mob_time = wxDateTime::Now();
6612 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6613 mob_message += _(
" Time: ");
6614 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6615 mob_message += _(
" Ownship Position: ");
6616 mob_message += toSDMM(1,
gLat);
6618 mob_message += toSDMM(2,
gLon);
6619 mob_message += _(
" MOB Position: ");
6620 mob_message += toSDMM(1, ptarget->Lat);
6622 mob_message += toSDMM(2, ptarget->Lon);
6624 wxLogMessage(mob_message);
6628void MyFrame::applySettingsString(wxString settings) {
6630 int last_UIScaleFactor = g_GUIScaleFactor;
6631 bool previous_expert = g_bUIexpert;
6632 g_last_ChartScaleFactor = g_ChartScaleFactor;
6633 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6636 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6642 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6644 if (rr & S52_CHANGED) {
6646 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6648 ->ClearCNSYLUPArray();
6649 ps52plib->GenerateStateHash();
6653 ProcessOptionsDialog(rr, pNewDirArray);
6658 bool b_newToolbar =
false;
6660 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6662 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6664 if (rr & TOOLBAR_CHANGED) {
6665 b_newToolbar =
true;
6670 if (previous_expert && !g_bUIexpert) {
6671 androidForceFullRepaint();
6675 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6679 SetGPSCompassScale();
6681 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6683 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6685 UpdateGPSCompassStatusBoxes(
true);
6688 AbstractPlatform::ShowBusySpinner();
6690 SetAllToolbarScale();
6694 AbstractPlatform::HideBusySpinner();
6696 RequestNewMasterToolbar(
true);
6703 UpdateControlBar(GetPrimaryCanvas());
6709 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6712#ifdef wxHAS_POWER_EVENTS
6713void MyFrame::OnSuspending(wxPowerEvent &event) {
6717 wxLogMessage(
"System suspend starting...");
6720void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6723 wxLogMessage(
"System is going to suspend.");
6726void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6729 wxLogMessage(
"System suspend was cancelled.");
6732int g_last_resume_ticks;
6733void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6734 wxDateTime now = wxDateTime::Now();
6735 wxLogMessage(
"System resumed from suspend.");
6737 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6740 wxLogMessage(
"Restarting streams.");
6741 g_last_resume_ticks = now.GetTicks();
6745 g_pMUX->ClearStreams();
6747 g_pMUX->StartAllStreams();
6756 if (IsMaximized()) {
6761 wxSize sz = GetSize();
6762 SetSize(wxSize(sz.x - 1, sz.y));
6774void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6775 bool btbRebuild =
false;
6777 bool b_reshow =
true;
6780 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6781 if ((ff > 0.01f) || bforcenew) {
6791 long orient = g_Platform->GetDefaultToolbarOrientation();
6792 wxWindow *toolbarParent =
this;
6794 toolbarParent = GetPrimaryCanvas();
6797 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6798 m_toolbar_callbacks);
6800 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6807 g_bmasterToolbarFull =
true;
6811 CreateMasterToolbar();
6826bool MyFrame::CollapseGlobalToolbar() {
6828 m_nMasterToolCountShown = 1;
6832 g_bmasterToolbarFull =
false;
6848 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6849 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6850 tic->m_bRequired =
true;
6855 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6856 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6860 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6861 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6862 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6867 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6868 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6872 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6873 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6874 _(
"Enable Tracking"),
"MUI_track");
6878 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6879 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6891 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6892 _(
"Print Chart"),
"MUI_print");
6896 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6897 _(
"About OpenCPN"),
"MUI_help");
6901 AddDefaultPositionPlugInTools();
6905 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6906 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6917 ArrayOfPlugInToolbarTools tool_array =
6919 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6921 if (!pttc->b_viz)
continue;
6923 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6926 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6927 if (g_bTrackActive) {
6928 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6935bool MyFrame::CheckAndAddPlugInTool() {
6943 if (!tb)
return false;
6945 int n_tools = tb->GetToolsCount();
6949 ArrayOfPlugInToolbarTools tool_array =
6952 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6954 if (pttc->position == n_tools) {
6955 wxBitmap *ptool_bmp;
6957 switch (global_color_scheme) {
6958 case GLOBAL_COLOR_SCHEME_DAY:
6959 ptool_bmp = pttc->bitmap_day;
6962 case GLOBAL_COLOR_SCHEME_DUSK:
6963 ptool_bmp = pttc->bitmap_dusk;
6965 case GLOBAL_COLOR_SCHEME_NIGHT:
6966 ptool_bmp = pttc->bitmap_night;
6969 ptool_bmp = pttc->bitmap_day;
6974 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6976 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6977 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6978 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6979 tic->m_bPlugin =
true;
6988 while (CheckAndAddPlugInTool()) {
6994bool MyFrame::AddDefaultPositionPlugInTools() {
7001 ArrayOfPlugInToolbarTools tool_array =
7004 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7008 if (!pttc->b_viz)
continue;
7010 if (pttc->position == -1)
7012 wxBitmap *ptool_bmp;
7014 switch (global_color_scheme) {
7015 case GLOBAL_COLOR_SCHEME_DAY:
7016 ptool_bmp = pttc->bitmap_day;
7018 case GLOBAL_COLOR_SCHEME_DUSK:
7019 ptool_bmp = pttc->bitmap_dusk;
7021 case GLOBAL_COLOR_SCHEME_NIGHT:
7022 ptool_bmp = pttc->bitmap_night;
7025 ptool_bmp = pttc->bitmap_day;
7030 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7032 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7033 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7034 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7035 tic->m_bPlugin =
true;
7054typedef struct _MSW_COLOR_SPEC {
7056 wxString S52_RGB_COLOR;
7060MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7061 {COLOR_MENUTEXT,
"UITX1", 0},
7062 {COLOR_BTNSHADOW,
"UIBCK", 0},
7065void SaveSystemColors() {
7079 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7080 while (pcspec->COLOR_NAME != -1) {
7081 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7086void RestoreSystemColors() {
7087 int element[NCOLORS];
7088 int rgbcolor[NCOLORS];
7091 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7092 while (pcspec->COLOR_NAME != -1) {
7093 element[i] = pcspec->COLOR_NAME;
7094 rgbcolor[i] = pcspec->SysRGB_COLOR;
7099 if (pSetSysColors) {
7100 pSetSysColors(i, (
unsigned long *)&element[0],
7101 (
unsigned long *)&rgbcolor[0]);
7107void SetSystemColors(ColorScheme cs) {
7109 int element[NCOLORS];
7110 int rgbcolor[NCOLORS];
7112 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7113 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7114 while (pcspec->COLOR_NAME != -1) {
7115 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7116 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7117 element[i] = pcspec->COLOR_NAME;
7123 pSetSysColors(i, (
unsigned long *)&element[0],
7124 (
unsigned long *)&rgbcolor[0]);
7128 RestoreSystemColors();
7135static const WORD MAX_CONSOLE_LINES =
7140void RedirectIOToConsole()
7145 wxIntPtr lStdHandle;
7147 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7157 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7158 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7159 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7163 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7164 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7165 fp = _fdopen(hConHandle,
"w");
7167 setvbuf(stdout, NULL, _IONBF, 0);
7171 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7172 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7173 fp = _fdopen(hConHandle,
"r");
7175 setvbuf(stdin, NULL, _IONBF, 0);
7179 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7180 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7181 fp = _fdopen(hConHandle,
"w");
7183 setvbuf(stderr, NULL, _IONBF, 0);
7194 FontMgr::Get().SetLocale(g_locale);
7215 if (g_pais_query_dialog_active) {
7216 g_pais_query_dialog_active->Destroy();
7217 g_pais_query_dialog_active = NULL;
7220 auto alert_dlg_active =
7222 if (alert_dlg_active) {
7223 alert_dlg_active->Destroy();
7224 g_pais_alert_dialog_active =
nullptr;
7227 if (g_pAISTargetList) {
7229 g_pAISTargetList->Disconnect_decoder();
7230 g_pAISTargetList->Destroy();
7231 g_pAISTargetList = NULL;
7235 if (gFrame->m_pMenuBar) {
7236 gFrame->SetMenuBar(NULL);
7237 gFrame->m_pMenuBar->Destroy();
7238 gFrame->m_pMenuBar = NULL;
7240 gFrame->BuildMenuBar();
7243 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7245 if (cc) cc->CanvasApplyLocale();
7250 wxString perspective;
7252 pConfig->Read(
"AUIPerspective", &perspective);
7266 bool bno_load =
false;
7267 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7269 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7270 wxAuiPaneInfo pane = pane_array_val[i];
7271 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7277 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7282 gFrame->RequestNewToolbars(
true);
7283 gFrame->RequestNewMasterToolbar(
true);
7290 : wxThread(wxTHREAD_JOINABLE) {
7291 m_filename = filename;
7302 newChart->SetNativeScale(m_scale);
7303 newChart->SetFullExtent(m_ext);
7305 newChart->FindOrCreateSenc(m_filename);
7310 wxString m_filename;
7316static double chart_dist(
int index) {
7322 if (cte.GetBBox().Contains(
gLat,
gLon))
7327 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7328 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7329 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7332 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7333 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7335 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7341WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7342static int CompareInts(
int n1,
int n2) {
7343 double d1 = chart_dist(n1);
7344 double d2 = chart_dist(n2);
7345 return (
int)(d1 - d2);
7350 wxString chart_path;
7355WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7357#include <wx/arrimpl.cpp>
7360void ParseAllENC(wxWindow *parent) {
7361 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7369 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7372 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7374 idx_sorted_by_distance.Add(i);
7378 if (count == 0)
return;
7380 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7386 ArrayOfCompressTargets ct_array;
7387 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7388 int i = idx_sorted_by_distance[j];
7391 double distance = chart_dist(i);
7393 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7396 pct->distance = distance;
7397 pct->chart_path = filename;
7399 ct_array.push_back(pct);
7402 int thread_count = 0;
7405 if (g_nCPUCount > 0)
7406 thread_count = g_nCPUCount;
7408 thread_count = wxThread::GetCPUCount();
7410 if (thread_count < 1) {
7419 for(
int t = 0; t < thread_count; t++)
7423 wxGenericProgressDialog *prog =
nullptr;
7427 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7428 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7430 prog =
new wxGenericProgressDialog();
7432 prog->SetFont(*qFont);
7434 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7435 count + 1, parent, style);
7444 prog->ShowWindowModal();
7453 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7454 wxString filename = ct_array[j].chart_path;
7455 double distance = ct_array[j].distance;
7456 int index =
ChartData->FinddbIndex(filename);
7457 if (index < 0)
continue;
7460 ext.NLAT = cte.GetLatMax();
7461 ext.SLAT = cte.GetLatMin();
7462 ext.WLON = cte.GetLonMin();
7463 ext.ELON = cte.GetLonMax();
7465 int scale = cte.GetScale();
7468 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7471 if (wxThread::IsMain()) {
7473 wxSize sz = prog->GetSize();
7478 prog->Update(count, msg, &skip);
7490 newChart->SetNativeScale(
scale);
7491 newChart->SetFullExtent(ext);
7492 newChart->DisableBackgroundSENC();
7494 newChart->FindOrCreateSenc(filename,
7498 if (wxThread::IsMain()) {
7499 msg.Printf(_(
"ENC Completed."));
7501 prog->Update(count, msg, &skip);
7511 for (
int t = 0;; t = (t + 1) % thread_count) {
7518 if (!workers[t]->IsAlive()) {
7531#if defined(__WXMSW__) || defined(__WXOSX__)
7538 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.