53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
83#include "model/nav_object_database.h"
97#include "ais_info_gui.h"
98#include "dialog_alert.h"
102#include "ais_info_gui.h"
126#include "load_errors_dlg.h"
129#include "N2KParser.h"
152#include "user_colors.h"
158#include "androidUTIL.h"
162static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
173GLenum g_texture_rectangle_format;
176#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
177extern wxLocale *plocale_def_lang;
181extern bool g_b_EnableVBO;
182extern GLenum g_texture_rectangle_format;
186static int g_last_ChartScaleFactor;
187static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
188static int options_subpage = 0;
189static bool b_reloadForPlugins;
191static wxSize options_lastWindowSize(0, 0);
192static wxPoint options_lastWindowPos(0, 0);
196static double gQueryVar = 361.0;
198static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
199static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
201static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
207typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
208typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
210static SetSysColors_t pSetSysColors;
211static GetSysColor_t pGetSysColor;
213void SaveSystemColors();
214void RestoreSystemColors();
219DWORD color_3ddkshadow;
221DWORD color_activecaption;
222DWORD color_gradientactivecaption;
223DWORD color_captiontext;
224DWORD color_windowframe;
225DWORD color_inactiveborder;
230#include <wx/msw/msvcrt.h>
234static const long long lNaN = 0xfff8000000000000;
235#define NAN (*(double *)&lNaN)
239static double gLat_gt, gLon_gt;
240static double gLat_gt_m1, gLon_gt_m1;
241static uint64_t fix_time_gt;
242static uint64_t fix_time_gt_last;
244static double gSog_gt, gHdt_gt;
245static double gCog_gt_m1, gHdt_gt_m1;
246static uint64_t hdt_time_gt;
247static double cog_rate_gt, hdt_rate_gt;
249void InitializeUserColors();
250void DeInitializeUserColors();
251void SetSystemColors(ColorScheme cs);
253static bool LoadAllPlugIns(
bool load_enabled) {
254 AbstractPlatform::ShowBusySpinner();
255 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
256 AbstractPlatform::HideBusySpinner();
260static void LaunchLocalHelp() {
262 androidLaunchHelpView();
264 wxString def_lang_canonical =
"en_US";
267 if (plocale_def_lang)
268 def_lang_canonical = plocale_def_lang->GetCanonicalName();
271 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
273 wxString help_try = help_locn + def_lang_canonical +
".html";
275 if (!::wxFileExists(help_try)) {
276 help_try = help_locn +
"en_US" +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"web" +
".html";
282 if (!::wxFileExists(help_try))
return;
285 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
290static wxString _menuText(wxString name, wxString shortcut) {
294 menutext <<
"\t" << shortcut;
299static void DoHelpDialog() {
311 [] { LaunchLocalHelp(); });
323#if defined(__WXGTK__) || defined(__WXQT__)
324#include "bitmaps/opencpn.xpm"
339 if (g_bInlandEcdis) {
343 wxPoint tbp_incanvas =
346 g_iENCToolbarPosY = tbp_incanvas.y;
347 g_iENCToolbarPosX = tbp_incanvas.x;
355 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
359 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
362 g_iENCToolbarPosY = -1;
365 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
371 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
375 double tool_scale_factor =
376 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
378 tool_scale_factor, callbacks);
388#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
391static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
392 const char *prop_name) {
396 unsigned long ret_nitems;
397 unsigned long ret_bytes_after;
398 unsigned char *ret_prop;
400 xa_prop_name = XInternAtom(disp, prop_name, False);
408 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
409 &xa_ret_type, &ret_format, &ret_nitems,
410 &ret_bytes_after, &ret_prop) != Success)
413 if (xa_ret_type != xa_prop_type) {
417 return (
char *)ret_prop;
422static bool isTransparentToolbarInOpenGLOK() {
429 if (!g_bdisable_opengl) {
430 Display *disp = XOpenDisplay(NULL);
432 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
434 "_NET_SUPPORTING_WM_CHECK")) ||
435 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_WIN_SUPPORTING_WM_CHECK"))) {
440 if ((wm_name = get_X11_property(disp, *sup_window,
441 XInternAtom(disp,
"UTF8_STRING", False),
443 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
446 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
461wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
463 font->GetFamily(), font->GetStyle(),
464 font->GetWeight(),
false, font->GetFaceName());
466wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
467 wxFontStyle style, wxFontWeight weight,
468 const wxString faceName,
double scale) {
472wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
473 return GetOCPNScaledFont_PlugIn(label, Ptsize);
482wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
484BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
485EVT_CLOSE(MyFrame::OnCloseWindow)
486EVT_MENU(wxID_EXIT, MyFrame::OnExit)
487EVT_SIZE(MyFrame::OnSize)
488EVT_MOVE(MyFrame::OnMove)
489EVT_ICONIZE(MyFrame::OnIconize)
490EVT_MENU(-1, MyFrame::OnToolLeftClick)
491EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
493EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
494EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
495EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
497EVT_MAXIMIZE(MyFrame::OnMaximize)
498EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
499 MyFrame::RequestNewToolbarArgEvent)
500EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
502EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
503EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
504EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
506#ifdef wxHAS_POWER_EVENTS
507EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
508EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
509EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
510EVT_POWER_RESUME(MyFrame::OnResume)
521static
void onBellsFinishedCB(
void *ptr) {
522 auto framePtr =
static_cast<MyFrame *
>(ptr);
524 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
525 wxPostEvent(framePtr, ev);
530 auto msg = ev.GetString().ToStdString();
531 auto ¬eman = NotificationManager::GetInstance();
532 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
535static NmeaLog *GetDataMonitor() {
536 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
537 return dynamic_cast<NmeaLog *
>(w);
540MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
541 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
542 OpenFileFunc open_gpx_file)
544 m_connections_dlg(nullptr),
546 m_pauidockart(pauidockart),
547 m_rest_server(rest_server),
548 m_open_gpx_file(open_gpx_file) {
560 m_ulLastNMEATicktime = 0;
561 m_data_monitor->Hide();
563 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
567 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
570 InitTimer.SetOwner(
this, INIT_TIMER);
572 m_initializing =
false;
573 m_toolbar_callbacks.render_gl_textures =
575 [&](
ocpnDC &dc,
float *coords,
float *uv) {
576 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
577 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
580 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
584 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
587 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
590 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
593 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
596 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
598 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
607 m_bTimeIsSet =
false;
608 m_bdefer_resize =
false;
611 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
612 COGFilterTable[i] = NAN;
613 SOGFilterTable[i] = NAN;
615 m_last_bGPSValid =
false;
616 m_last_bVelocityValid =
false;
626 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
631 double process_noise_std = 1.0;
632 double measurement_noise_std = 0.5;
636 m_ChartUpdatePeriod = 1;
641 log_callbacks.log_is_active = [&]() {
642 auto log = GetDataMonitor();
643 return log && log->IsVisible();
645 log_callbacks.log_message = [&](
Logline ll) {
646 NmeaLog *monitor = GetDataMonitor();
649 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
652 ais_callbacks.confirm_stop_track = []() {
653 int r = OCPNMessageBox(
655 _(
"This AIS target has Persistent tracking selected by MMSI "
657 "A Persistent track recording will therefore be restarted for this "
659 "Do you instead want to stop Persistent tracking for this target?"),
660 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
661 return r == wxID_YES;
663 ais_callbacks.get_target_mmsi = []() {
664 auto alert_dlg_active =
666 assert(alert_dlg_active);
667 return alert_dlg_active->Get_Dialog_MMSI();
675 wxLogMessage(
" **** Connect stuff");
681 Connect(wxEVT_OCPN_MSG,
682 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
690 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
698#if defined(__WXGTK__) || defined(__WXQT__)
699 wxIcon app_icon(opencpn);
707 wxDynamicLibrary dllUser32(
"user32.dll");
709 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
710 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
715 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
720 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
721 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
723 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
724 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
725 [&](wxCommandEvent) { Refresh(); });
726 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
728 m_update_statusbar_listener.Init(
729 GuiEvents::GetInstance().gframe_update_status_bar,
731 m_center_aistarget_listener.Init(
732 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
733 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
734 CenterAisTarget(ais_target);
736 m_reload_charts_listener.Init(
737 GuiEvents::GetInstance().on_finalize_chartdbs,
738 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
742 EnableFullScreenView();
744 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
750 FrameTenHzTimer.Stop();
765 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
771void MyFrame::FreezeCharts() {
774 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
776 if (cc && !cc->IsFrozen()) cc->Freeze();
780void MyFrame::CenterAisTarget(
781 const std::shared_ptr<const AisTargetData> &ais_target) {
789 double factor = cc->GetScaleValue() / 5000.0;
790 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
796void MyFrame::ThawCharts() {
799 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
801 if (cc && cc->IsFrozen()) cc->Thaw();
808 switch (event.type) {
809 case SENC_BUILD_STARTED:
812 case SENC_BUILD_DONE_NOERROR:
814 chart =
event.m_ticket->m_chart;
816 chart->PostInit(FULL_INIT, global_color_scheme);
818 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
820 if (cc) cc->ClearS52PLIBStateHash();
825 delete event.m_ticket;
827 case SENC_BUILD_DONE_ERROR:
835void MyFrame::StartRebuildChartDatabase() {
836 bool b_SetInitialPoint =
false;
839 ArrayOfCDI ChartDirArray;
840 pConfig->LoadChartDirArray(ChartDirArray);
842 if (ChartDirArray.GetCount()) {
847 _(
"OpenCPN needs to update the chart database from config file "
851 wxICON_INFORMATION | wxOK);
859 _(
"Rebuilding chart database from configuration file entries..."));
863 wxString dummy1 = _(
"Elapsed time : ");
864 wxString dummy2 = _(
"Estimated time : ");
865 wxString dummy3 = _(
"Remaining time : ");
866 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
867 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
875void MyFrame::OnBellsFinished(wxCommandEvent &event) {
876 int bells = wxMin(m_BellsToPlay, 2);
877 if (bells <= 0)
return;
879 wxString soundfile =
"sounds";
880 appendOSDirSlash(&soundfile);
881 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
882 soundfile.Prepend(g_Platform->GetSharedDataDir());
883 wxLogMessage(
"Using bells sound file: " + soundfile);
885 o_sound::Sound *sound = bells_sound[bells - 1];
886 sound->SetFinishedCallback(onBellsFinishedCB,
this);
887 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
888 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
889 sound->Load(soundfile);
890 if (!sound->IsOk()) {
891 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
895 m_BellsToPlay -= bells;
898void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
900void MyFrame::OnMaximize(wxMaximizeEvent &event) {
907void MyFrame::ReloadAllVP() {
908 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
910 if (cc) cc->ReloadVP();
914void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
915 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
918 global_color_scheme = cs;
921 case GLOBAL_COLOR_SCHEME_DAY:
924 case GLOBAL_COLOR_SCHEME_DUSK:
927 case GLOBAL_COLOR_SCHEME_NIGHT:
928 SchemeName =
"NIGHT";
935 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
937 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
938 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
939 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
940 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
941 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
943 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
972 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
973 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
977 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
979 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
983 user_colors::GetMapByScheme(SchemeName.ToStdString());
988 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
991 cc->SetColorScheme(cs);
992 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
993 cc->HideChartInfoWindow();
994 cc->SetQuiltChartHiLiteIndex(-1);
1000 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1012 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1025 if (g_pais_query_dialog_active) {
1026 bool b_isshown = g_pais_query_dialog_active->IsShown();
1027 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1028 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1030 g_pais_query_dialog_active->Close();
1033 g_pais_query_dialog_active->
Create(
1034 this, -1, _(
"AIS Target Query"),
1035 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1036 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1037 g_pais_query_dialog_active->UpdateText();
1038 if (b_isshown) g_pais_query_dialog_active->Show();
1043 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1047 ApplyGlobalColorSchemetoStatusBar();
1049 UpdateAllToolbars(cs);
1054 bool btoolbarFull = g_bmasterToolbarFull;
1060 if (!btoolbarFull) {
1062 RequestNewMasterToolbar();
1064 CollapseGlobalToolbar();
1067 RequestNewMasterToolbar();
1076void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1077 if (m_pStatusBar != NULL) {
1078 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1079 m_pStatusBar->ClearBackground();
1090void MyFrame::CancelAllMouseRoute() {
1092 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1094 if (cc) cc->CancelMouseRoute();
1098void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1106 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1114 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1123 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1126 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1127 config_array.Item(i)->canvas = NULL;
1133 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1138 switch (g_canvasConfig) {
1152 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1153 cc->GetglCanvas()->Show();
1156 config_array.Item(0)->canvas = cc;
1160 cc->ApplyCanvasConfig(config_array.Item(0));
1164 cc->ConfigureChartBar();
1165 cc->SetColorScheme(global_color_scheme);
1166 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1167 cc->SetShowGPS(
true);
1170 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1172 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1188 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1191 config_array.Item(0)->canvas = cc;
1193 cc->ApplyCanvasConfig(config_array.Item(0));
1196 cc->ConfigureChartBar();
1197 cc->SetColorScheme(global_color_scheme);
1198 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1199 cc->SetShowGPS(
false);
1202 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1204 .CaptionVisible(
false)
1206 .CloseButton(
false);
1215 if (config_array.GetCount() < 2) {
1217 pcc->configIndex = 1;
1221 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1222 config_array.Add(pcc);
1225 config_array.Item(1)->canvas = cc;
1227 cc->ApplyCanvasConfig(config_array.Item(1));
1230 cc->ConfigureChartBar();
1231 cc->SetColorScheme(global_color_scheme);
1232 cc->SetShowGPS(
true);
1234 cc->SetShowGPSCompassWindow(
true);
1237 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1239 .CaptionVisible(
false)
1241 .CloseButton(
false);
1242 g_pauimgr->GetPane(cc).RightDockable(
true);
1246 config_array.Item(1)->canvasSize =
1247 wxSize(GetClientSize().x / 2, GetClientSize().y);
1248 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1253 if (b_useStoredSize) {
1254 int ccw = config_array.Item(1)->canvasSize.x;
1255 int cch = config_array.Item(1)->canvasSize.y;
1258 if (ccw < GetClientSize().x / 10) {
1259 ccw = GetClientSize().x / 2;
1260 cch = GetClientSize().y;
1263 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1264 cc->SetSize(ccw, cch);
1282 console->SetColorScheme(global_color_scheme);
1287 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1293void MyFrame::RequestNewToolbars(
bool bforcenew) {
1294 if (b_inCloseWindow) {
1298 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1299 PositionIENCToolbar();
1308void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1314void MyFrame::SetAllToolbarScale() {
1315 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1318void MyFrame::SetGPSCompassScale() {
1319 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1323 wxPoint screenPoint = ::wxGetMousePosition();
1326 switch (g_canvasConfig) {
1328 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1331 if (canvas->GetScreenRect().Contains(
1335 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1338 if (canvas->GetScreenRect().Contains(
1345 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1348 if (canvas->GetScreenRect().Contains(
1349 canvas->ScreenToClient(screenPoint)))
1357int MyFrame::GetCanvasIndexUnderMouse() {
1358 wxPoint screenPoint = ::wxGetMousePosition();
1361 switch (g_canvasConfig) {
1363 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1366 if (canvas->GetScreenRect().Contains(
1370 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1373 if (canvas->GetScreenRect().Contains(
1380 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1383 if (canvas->GetScreenRect().Contains(
1384 canvas->ScreenToClient(screenPoint)))
1392bool MyFrame::DropMarker(
bool atOwnShip) {
1399 if (!canvas)
return false;
1406 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1408 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1410 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1421 RefreshAllCanvas(
false);
1426void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1427 if (g_canvasConfig != 0) {
1430 int nTargetGTK = -1;
1432 wxWindow *source = FindFocus();
1438 switch (g_canvasConfig) {
1440 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1443 if (canvas && (canvas == test)) {
1448 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1451 if (canvas && (canvas == test)) {
1459 int nfinalTarget = nTarget;
1461 nfinalTarget = nTargetGTK;
1463 target = ConfigMgr::Get()
1464 .GetCanvasConfigArray()
1469 target->Refresh(
true);
1480void MyFrame::FastClose() {
1482 FrameTenHzTimer.Stop();
1484 FrameTimer1.Start(1);
1488void MyFrame::OnExit(wxCommandEvent &event) {
1492void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1495 if (b_inCloseWindow) {
1505 if (!g_bDeferredInitDone)
return;
1522 if (bDBUpdateInProgress)
return;
1524 b_inCloseWindow =
true;
1526 ::wxSetCursor(wxCURSOR_WAIT);
1530 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1532 if (cc && cc->IsMeasureActive()) {
1533 cc->CancelMeasureRoute();
1538 SendPreShutdownHookToPlugins();
1542 if (g_pAISTargetList) {
1543 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1544 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1545 g_pauimgr->DetachPane(g_pAISTargetList);
1572 SetCursor(wxCURSOR_WAIT);
1574 RefreshAllCanvas(
true);
1580 RestoreScreenBrightness();
1591 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1592 g_iENCToolbarPosY = tbp_incanvas.y;
1593 g_iENCToolbarPosX = tbp_incanvas.x;
1597 g_bframemax = IsMaximized();
1600 FrameTenHzTimer.Stop();
1602 FrameCOGTimer.Stop();
1616 if (g_bAutoAnchorMark) {
1617 bool watching_anchor =
false;
1625 wxDateTime now = wxDateTime::Now();
1626 wxTimeSpan uptime = now.Subtract(g_start_time);
1628 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1629 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1634 if (g_declutter_anchorage) {
1635 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1636 if (pr->GetName().StartsWith(
"Anchorage")) {
1637 double a =
gLat - pr->m_lat;
1638 double b =
gLon - pr->m_lon;
1639 double l = sqrt((a * a) + (b * b));
1642 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1644 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1645 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1653 wxString name = now.Format();
1654 name.Prepend(_(
"Anchorage created "));
1660 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1669 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1673 NavObj_dB::GetInstance().Close();
1677 pConfig->DeleteGroup(
"/Routes");
1678 pConfig->DeleteGroup(
"/Marks");
1697 if (g_pAISTargetList) {
1698 g_pAISTargetList->Disconnect_decoder();
1699 g_pAISTargetList->Destroy();
1706 if (RouteManagerDialog::getInstanceFlag()) {
1723 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1725 if (cc) cc->Destroy();
1749 CommBridge::GetInstance().SaveConfig();
1769 auto ®istry = CommDriverRegistry::GetInstance();
1770 registry.CloseAllDrivers();
1773 for (
auto *cp : TheConnectionParams()) {
1778 while (pLayerList->size())
delete *pLayerList->begin();
1782 ReleaseApiListeners();
1785 g_bTempShowMenuBar =
false;
1787#define THREAD_WAIT_SECONDS 5
1797 wxLogMessage(
"Starting compressor pool drain");
1798 wxDateTime now = wxDateTime::Now();
1799 time_t stall = now.GetTicks();
1800 time_t end = stall + THREAD_WAIT_SECONDS;
1803 while (stall < end) {
1804 wxDateTime later = wxDateTime::Now();
1805 stall = later.GetTicks();
1808 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1817 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1823 uninitIXNetSystem();
1831 wxLogMessage(
"gFrame destroyed.");
1834#ifndef USE_ANDROID_GLES2
1835 qDebug() <<
"Calling OnExit()";
1839 wxTheApp->ExitMainLoop();
1842void MyFrame::OnMove(wxMoveEvent &event) {
1843 auto idx = wxDisplay::GetFromWindow(
this);
1856 DEBUG_LOG <<
"Moved to " << idx
1857#if wxCHECK_VERSION(3, 1, 6)
1858 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1859 << wxDisplay(idx).GetPPI().GetY()
1860 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1862 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1863 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1864 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1865 << wxGetDisplaySizeMM().GetY()
1866 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1875 if (g_config_display_size_manual) {
1884 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1887 cc->SetMUIBarPosition();
1896 UpdateGPSCompassStatusBoxes();
1906 PositionIENCToolbar();
1912 g_nframewin_posx = GetPosition().x;
1913 g_nframewin_posy = GetPosition().y;
1916void MyFrame::ProcessCanvasResize() {
1917 UpdateGPSCompassStatusBoxes(
true);
1921 PositionIENCToolbar();
1924 TriggerRecaptureTimer();
1928void MyFrame::TriggerRecaptureTimer() {
1929 m_recaptureTimer.Start(
1930 1000, wxTIMER_ONE_SHOT);
1933void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1935void MyFrame::SetCanvasSizes(wxSize frameSize) {
1939 int cccw = frameSize.x;
1940 int ccch = frameSize.y;
1944 switch (g_canvasConfig) {
1950 cc->GetSize( &cur_width, &cur_height );
1951 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1953 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1955 cc->SetSize( 0, 0, cccw, ccch );
1965 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1966 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1968 ccw = wxMin(ccw, cccw * 8 / 10);
1969 ccw = wxMax(ccw, cccw * 2 / 10);
1973 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1980 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1997void MyFrame::OnIconize(wxIconizeEvent &event) {
2007 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2009 if (cc && cc->GetMUIBar()) {
2010 if (cc->GetMUIBar()->GetCanvasOptions()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2012 cc->GetMUIBar()->PushCanvasOptions();
2021void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2023void MyFrame::ODoSetSize() {
2025 GetClientSize(&x, &y);
2028 if (m_pStatusBar != NULL) {
2029 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2030 int currentCount = m_pStatusBar->GetFieldsCount();
2031 if (currentCount != m_StatusBarFieldCount) {
2032 if ((currentCount > 0) && (currentCount < 7)) {
2035 int widths[] = {2, 2, 2, 2, 2, 2};
2036 m_pStatusBar->SetStatusWidths(currentCount, widths);
2039 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2042 if (m_StatusBarFieldCount) {
2047 if (m_StatusBarFieldCount > 2) {
2048 int widths[] = {-6, -5, -5, -6, -4};
2049 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2050 }
else if (m_StatusBarFieldCount == 2) {
2051 int cwidth = x * 90 / 100;
2052 int widths[] = {100, 100};
2053 widths[0] = cwidth * 6.4 / 10.0;
2054 widths[1] = cwidth * 3.6 / 10.0;
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2057 int widths[] = {100, 100};
2058 widths[0] = x * 90 / 100;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2062 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2063 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2064 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2066 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2068 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2076 m_pStatusBar->GetFieldRect(0, stat_box);
2079 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2081 wxFont sys_font = *wxNORMAL_FONT;
2082 int try_font_size = sys_font.GetPointSize();
2085 int min_font_size = 10;
2095 wxFont *statusBarFont =
2096 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2097 int font_size = statusBarFont->GetPointSize();
2099 font_size = wxMin(font_size,
2102 wxMax(font_size, min_font_size);
2105 font_size = statusBarFont->GetPointSize();
2112 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2113 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2115 int min_height = stat_box.height;
2117 m_pStatusBar->SetFont(*pstat_font);
2118 m_pStatusBar->SetForegroundColour(
2119 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2121 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2123 (min_height >> 1) * 2;
2124 m_pStatusBar->SetMinHeight(min_height);
2133 SetCanvasSizes(GetClientSize());
2135 UpdateGPSCompassStatusBoxes(
true);
2137 if (
console) PositionConsole();
2140 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2142 if (cc) cc->FormatPianoKeys();
2148 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2149 GetPrimaryCanvas()->GetCompass()->GetRect());
2175 options_lastWindowSize = wxSize(0, 0);
2176 options_lastWindowPos = wxPoint(0, 0);
2183 if (!b_inCloseWindow) {
2186 resizeAndroidPersistents();
2190 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2191 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2197void MyFrame::PositionConsole() {
2198#if defined(__WXMSW__) || defined(__WXMAC__)
2199 if (NULL == GetPrimaryCanvas())
return;
2201 int ccx, ccy, ccsx, ccsy, consx, consy;
2206 consoleHost->GetSize(&ccsx, &ccsy);
2207 consoleHost->GetPosition(&ccx, &ccy);
2209 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2210 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2211 consoleHost = GetPrimaryCanvas();
2216 if (consoleHost->GetCompass()) {
2217 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2219 if (compass_rect.y < 100)
2220 yOffset = compass_rect.y + compass_rect.height + 45;
2224 wxSize csz =
console->GetSize();
2228 wxPoint screen_pos =
2229 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2232 if (NULL == GetPrimaryCanvas())
return;
2234 int ccx, ccy, ccsx, ccsy, consx, consy;
2239 consoleHost->GetSize(&ccsx, &ccsy);
2240 consoleHost->GetPosition(&ccx, &ccy);
2242 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2243 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2244 consoleHost = GetPrimaryCanvas();
2247 int yTopOffset = 60;
2248 int yBottomOffset = 0;
2250 if (consoleHost->GetCompass()) {
2251 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2253 if (compass_rect.y < 100)
2254 yTopOffset = compass_rect.y + compass_rect.height;
2256 if (consoleHost->GetMUIBar()) {
2257 wxRect mui_rect = consoleHost->GetMUIBarRect();
2258 yBottomOffset = ccsy - mui_rect.y;
2262 wxSize csz =
console->GetSize();
2265 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2267 if (consy < yAvail) {
2268 yFinal = (yAvail - consy) / 2;
2269 yFinal += yTopOffset;
2270 }
else if (
console->GetCDI()->IsShown()) {
2271 int cdi_height =
console->GetCDI()->GetSize().y;
2272 int consy_no_cdi = consy - cdi_height;
2273 yFinal = (yAvail - consy_no_cdi) / 2;
2274 yFinal += yTopOffset;
2278 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2283void MyFrame::UpdateAllFonts() {
2292 DestroyPersistentDialogs();
2294 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2299void MyFrame::DestroyPersistentDialogs() {
2300 if (g_pais_query_dialog_active) {
2301 g_pais_query_dialog_active->Hide();
2302 g_pais_query_dialog_active->Destroy();
2303 g_pais_query_dialog_active = NULL;
2331void MyFrame::RefreshGroupIndices() {
2333 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2335 if (cc) cc->canvasRefreshGroupIndex();
2339void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2342 switch (event.GetId()) {
2343 case ID_MENU_SCALE_OUT:
2344 DoStackDelta(GetPrimaryCanvas(), 1);
2348 case ID_MENU_SCALE_IN:
2349 DoStackDelta(GetPrimaryCanvas(), -1);
2353 case ID_MENU_ZOOM_IN: {
2354 if (GetFocusCanvas()) {
2355 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2360 case ID_MENU_ZOOM_OUT: {
2361 if (GetFocusCanvas()) {
2362 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2367 case ID_MENU_ROUTE_NEW: {
2368 if (GetFocusCanvas()) {
2369 if (0 == GetFocusCanvas()->m_routeState) {
2370 GetFocusCanvas()->StartRoute();
2372 GetFocusCanvas()->FinishRoute();
2378 case ID_MENU_TOOL_MEASURE: {
2379 GetPrimaryCanvas()->StartMeasureRoute();
2383 case ID_MENU_TOOL_NMEA_DBG_LOG:
2384 m_data_monitor->Show();
2385 m_data_monitor->Raise();
2388 case ID_MENU_TOOL_IO_MONITOR:
2389 m_data_monitor->Show();
2392 case ID_MENU_MARK_BOAT: {
2397 case ID_MENU_MARK_CURSOR: {
2402 case ID_MENU_NAV_FOLLOW: {
2403 if (
gFrame->GetPrimaryCanvas())
2404 gFrame->GetPrimaryCanvas()->TogglebFollow();
2408 case ID_MENU_CHART_OUTLINES: {
2409 ToggleChartOutlines(GetFocusCanvas());
2413 case ID_MENU_CHART_QUILTING: {
2414 ToggleQuiltMode(GetFocusCanvas());
2418 case ID_MENU_UI_CHARTBAR: {
2419 ToggleChartBar(GetFocusCanvas());
2423 case ID_MENU_ENC_TEXT:
2425 ToggleENCText(GetFocusCanvas());
2428 case ID_MENU_ENC_LIGHTS: {
2429 ToggleLights(GetFocusCanvas());
2432 case ID_MENU_ENC_SOUNDINGS: {
2433 ToggleSoundings(GetFocusCanvas());
2436 case ID_MENU_ENC_ANCHOR: {
2437 ToggleAnchor(GetFocusCanvas());
2440 case ID_MENU_ENC_DATA_QUALITY: {
2441 ToggleDataQuality(GetFocusCanvas());
2444 case ID_MENU_SHOW_NAVOBJECTS: {
2445 ToggleNavobjects(GetFocusCanvas());
2449 case ID_MENU_AIS_TARGETS: {
2450 ToggleAISDisplay(GetFocusCanvas());
2453 case ID_MENU_AIS_MOORED_TARGETS: {
2454 g_bHideMoored = !g_bHideMoored;
2457 case ID_MENU_AIS_SCALED_TARGETS: {
2458 ToggleAISMinimizeTargets(GetFocusCanvas());
2462 case ID_MENU_AIS_TARGETLIST: {
2463 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2467 case ID_MENU_AIS_TRACKS: {
2468 g_bAISShowTracks = !g_bAISShowTracks;
2469 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2473 case ID_MENU_AIS_CPADIALOG: {
2474 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2475 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2476 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2477 if (g_bAIS_CPA_Alert) {
2478 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2483 case ID_MENU_AIS_CPASOUND: {
2484 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2485 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2489 case ID_MENU_AIS_CPAWARNING: {
2490 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2491 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2495 case wxID_PREFERENCES:
2502 case ID_SETTINGS_NEW: {
2507 case ID_SETTINGS_DELETE: {
2510 g_pOptions =
nullptr;
2514 case ID_RELOAD_CHARTS: {
2519 case ID_MENU_SETTINGS_BASIC: {
2521 androidDisableFullScreen();
2523 DoAndroidPreferences();
2530 case ID_MENU_UI_FULLSCREEN: {
2535 case ID_MENU_SHOW_CURRENTS: {
2536 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2537 GetFocusCanvas()->ReloadVP();
2538 GetFocusCanvas()->Refresh(
false);
2542 case ID_MENU_SHOW_TIDES: {
2543 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2544 GetFocusCanvas()->ReloadVP();
2545 GetFocusCanvas()->Refresh(
false);
2565 case ID_MENU_UI_COLSCHEME:
2566 case ID_COLSCHEME: {
2567 ToggleColorScheme();
2576 case ID_MENU_OQUIT: {
2581 case ID_MENU_ROUTE_MANAGER:
2582 case ID_ROUTEMANAGER: {
2605 case ID_MENU_NAV_TRACK:
2607 if (!g_bTrackActive) {
2609 g_bTrackCarryOver =
true;
2612 g_bTrackCarryOver =
false;
2613 RefreshAllCanvas(
true);
2618 case ID_MENU_CHART_NORTHUP: {
2619 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2622 case ID_MENU_CHART_COGUP: {
2623 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2626 case ID_MENU_CHART_HEADUP: {
2627 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2631 case ID_MENU_MARK_MOB:
2637 case ID_MASTERTOGGLE: {
2639 wxString tip = _(
"Show Toolbar");
2640 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2642 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2644 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2647 if (g_bmasterToolbarFull)
2648 m_nMasterToolCountShown =
2652 m_nMasterToolCountShown = 2;
2654 m_nMasterToolCountShown =
2657 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2665 case ID_CMD_SELECT_CHART_TYPE: {
2666 selectChartDisplay(event.GetExtraLong(), -1);
2670 case ID_CMD_SELECT_CHART_FAMILY: {
2671 selectChartDisplay(-1, event.GetExtraLong());
2675 case ID_CMD_APPLY_SETTINGS: {
2676 applySettingsString(event.GetString());
2678 androidRestoreFullScreen();
2684 case ID_CMD_NULL_REFRESH: {
2689 case ID_CMD_SETVP: {
2690 setStringVP(event.GetString());
2694 case ID_CMD_INVALIDATE: {
2700 case ID_CMD_POST_JSON_TO_PLUGINS: {
2706 int numErrors = reader.
Parse(event.GetString(), &root);
2707 if (numErrors == 0) {
2708 if (root[
"MessageID"].IsString()) {
2709 wxString MsgID = root[
"MessageID"].
AsString();
2733 ArrayOfPlugInToolbarTools tool_array =
2735 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2737 if (event.GetId() == pttc->id) {
2738 if (pttc->m_pplugin)
2760bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2761 bool viz_now = g_bmasterToolbarFull;
2764 wxString tip = _(
"Show Toolbar");
2766 tip = _(
"Hide Toolbar");
2768 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2771 bool toggle =
false;
2772 if (viz && !g_bmasterToolbarFull)
2775 else if (!viz && g_bmasterToolbarFull)
2779 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2782 if (g_bmasterToolbarFull)
2783 m_nMasterToolCountShown =
2787 m_nMasterToolCountShown = 2;
2789 m_nMasterToolCountShown =
2792 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2798void MyFrame::ScheduleReloadCharts() {
2799 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2800 evt.SetId(ID_RELOAD_CHARTS);
2801 GetEventHandler()->AddPendingEvent(evt);
2804void MyFrame::ScheduleDeleteSettingsDialog() {
2805 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2806 evt.SetId(ID_SETTINGS_DELETE);
2807 GetEventHandler()->AddPendingEvent(evt);
2810void MyFrame::ScheduleSettingsDialog() {
2811 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2812 evt.SetId(ID_SETTINGS);
2813 GetEventHandler()->AddPendingEvent(evt);
2816void MyFrame::ScheduleSettingsDialogNew() {
2817 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2818 evt.SetId(ID_SETTINGS_NEW);
2819 GetEventHandler()->AddPendingEvent(evt);
2822void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2823 UpdateCanvasConfigDescriptors();
2825 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2826 CreateCanvasLayout(
true);
2828 CreateCanvasLayout();
2832 ConfigureStatusBar();
2833 wxSize lastOptSize = options_lastWindowSize;
2838 options_lastWindowSize = lastOptSize;
2842 ScheduleSettingsDialogNew();
2844 ScheduleSettingsDialog();
2849 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2852 int index_hint = -1;
2853 if (i < pathArray.GetCount())
2854 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2855 cc->canvasChartsRefresh(index_hint);
2856 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2865 return GetPrimaryCanvas();
2868void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2869 if (g_bmasterToolbarFull) {
2870#ifndef OCPN_TOOLBAR_ANIMATE
2871 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2874 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2875 m_nMasterToolCountShown++;
2880 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2888#ifndef OCPN_TOOLBAR_ANIMATE
2889 m_nMasterToolCountShown = 1;
2891 if (m_nMasterToolCountShown > 1) {
2892 m_nMasterToolCountShown--;
2896 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2906void MyFrame::InvalidateAllGL() {
2909 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2919void MyFrame::RefreshAllCanvas(
bool bErase) {
2921 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2924 cc->Refresh(bErase);
2929void MyFrame::setStringVP(wxString VPS) {
2934 wxStringTokenizer tkz(VPS,
";");
2936 wxString token = tkz.GetNextToken();
2938 token.ToDouble(&lat);
2940 token = tkz.GetNextToken();
2942 token.ToDouble(&lon);
2944 token = tkz.GetNextToken();
2946 token.ToDouble(&scale_ppm);
2948 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2951void MyFrame::DoSettingsNew() {
2958void MyFrame::DoSettings() {
2963 ApplyGlobalSettings(
true);
2966 bool b_loadHarmonics =
false;
2967 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2970 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2973 if (b_loadHarmonics) LoadHarmonics();
2981 g_bShowChartBar = !g_bShowChartBar;
2983 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2988 if (g_bShowChartBar) {
2990 UpdateControlBar(cc);
2993 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2996void MyFrame::ToggleColorScheme() {
2997 static bool lastIsNight;
2998 ColorScheme s = user_colors::GetColorScheme();
3001 if (lastIsNight && is == 3)
3004 lastIsNight =
false;
3006 if (lastIsNight) is = 2;
3007 if (is == 3) lastIsNight =
true;
3008 s = (ColorScheme)is;
3009 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3011 SetAndApplyColorScheme(s);
3014void MyFrame::ToggleFullScreen() {
3015 bool to = !IsFullScreen();
3020 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3022 ShowFullScreen(to, style);
3025 UpdateAllToolbars(global_color_scheme);
3027 UpdateControlBar(GetPrimaryCanvas());
3029 TriggerRecaptureTimer();
3032void MyFrame::ActivateMOB() {
3034 wxDateTime mob_time = wxDateTime::Now();
3035 wxString mob_label(_(
"MAN OVERBOARD"));
3036 mob_label += _(
" on ");
3037 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3041 pWP_MOB->SetShared(
true);
3043 pWP_MOB->SetWaypointArrivalRadius(
3045 pWP_MOB->SetUseSca(
false);
3047 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3055 new RoutePoint(zlat, zlon, g_default_wp_icon,
3056 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3057 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3062 temp_route->AddPoint(pWP_src);
3063 temp_route->AddPoint(pWP_MOB);
3065 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3075 temp_route->SetRouteArrivalRadius(-1.0);
3081 v[
"GUID"] = temp_route->
m_GUID;
3082 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3083 SendJSONMessageToAllPlugins(msg_id, v);
3086 if (RouteManagerDialog::getInstanceFlag()) {
3094 RefreshAllCanvas(
false);
3096 wxString mob_message(_(
"MAN OVERBOARD"));
3097 mob_message += _(
" Time: ");
3098 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3099 mob_message += _(
" Position: ");
3100 mob_message += toSDMM(1,
gLat);
3102 mob_message += toSDMM(2,
gLon);
3103 wxLogMessage(mob_message);
3105void MyFrame::TrackOn() {
3106 g_bTrackActive =
true;
3114 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3116 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3118 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3121 androidSetTrackTool(
true);
3124 if (RouteManagerDialog::getInstanceFlag()) {
3133 if (name.IsEmpty()) {
3139 name = _(
"(Unnamed Track)");
3143 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3144 SendJSONMessageToAllPlugins(msg_id, v);
3145 g_FlushNavobjChangesTimeout =
3149Track *MyFrame::TrackOff(
bool do_add_point) {
3154 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3156 SendJSONMessageToAllPlugins(msg_id, v);
3165 if (g_bTrackDaily) {
3170 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3171 return_val = pExtendTrack;
3178 g_bTrackActive =
false;
3180 if (RouteManagerDialog::getInstanceFlag()) {
3187 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3189 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3190 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3193 androidSetTrackTool(
false);
3197 m_target_rotate_time = wxInvalidDateTime;
3202void MyFrame::InitializeTrackRestart() {
3203 if (!g_bTrackDaily)
return;
3204 if (m_target_rotate_time.IsValid())
return;
3207 switch (g_track_rotate_time_type) {
3209 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3211 case TIME_TYPE_COMPUTER:
3212 rotate_at = g_track_rotate_time;
3216 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3217 rotate_at = g_track_rotate_time + utc_offset;
3220 if (rotate_at > 86400)
3222 else if (rotate_at < 0)
3225 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3226 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3229 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3230 m_target_rotate_time += wxTimeSpan(24);
3234bool MyFrame::ShouldRestartTrack() {
3236 InitializeTrackRestart();
3238 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3239 m_target_rotate_time += wxTimeSpan(24);
3245void MyFrame::TrackDailyRestart() {
3247 Track *pPreviousTrack = TrackOff(
true);
3254 if (pPreviousTrack) {
3255 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3259 if (RouteManagerDialog::getInstanceFlag()) {
3267void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3269 cc->SetUpMode(mode);
3271 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3272 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3273 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3276 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3281 cc->SetShowENCText(!cc->GetShowENCText());
3283 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3291void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3294 cc->SetENCDisplayCategory(nset);
3296 UpdateGlobalMenuItems();
3307 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3309 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3318 cc->SetShowENCLights(!cc->GetShowENCLights());
3320 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3330void MyFrame::ToggleRocks(
void )
3336 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3337 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3338 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3339 pOLE->nViz = !pOLE->nViz;
3343 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3344 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3345 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3348 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3352 ps52plib->GenerateStateHash();
3359 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3361 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3369 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3371 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3386 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3387 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3392 cc->SetShowAIS(!cc->GetShowAIS());
3393 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3397void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3398 cc->SetAttenAIS(!cc->GetAttenAIS());
3399 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3405 cc->m_bFollow =
true;
3408 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3412 SetChartUpdatePeriod();
3420 cc->m_bFollow =
false;
3422 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3426 SetChartUpdatePeriod();
3429void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3430 cc->SetShowOutlines(!cc->GetShowOutlines());
3432 RefreshAllCanvas(
false);
3436 if (g_bopengl) InvalidateAllGL();
3439 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3442void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3444void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3446 bool enabled = m_pMenuBar->IsEnabled(item_id);
3447 m_pMenuBar->Enable(item_id,
false);
3448 m_pMenuBar->Check(item_id, state);
3449 m_pMenuBar->Enable(item_id, enabled);
3453void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3460void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3461 wxBitmap *bmpRollover) {
3463 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3468void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3469 wxString rolloverSVGfile,
3470 wxString toggledSVGfile) {
3473 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3477void MyFrame::ConfigureStatusBar() {
3479 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3482 UseNativeStatusBar(
false);
3485 if (g_bShowStatusBar) {
3486 if (!m_pStatusBar) {
3488 CreateStatusBar(m_StatusBarFieldCount, 0);
3489 ApplyGlobalColorSchemetoStatusBar();
3494 m_pStatusBar->Destroy();
3495 m_pStatusBar = NULL;
3501void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3502 ConfigureStatusBar();
3504 wxSize lastOptSize = options_lastWindowSize;
3510 options_lastWindowSize = lastOptSize;
3512 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3515void MyFrame::BuildMenuBar() {
3521 bool showMenuBar =
true;
3523 bool showMenuBar = g_bShowMenuBar;
3535 m_pMenuBar =
new wxMenuBar();
3536 RegisterGlobalMenuItems();
3537 SetMenuBar(m_pMenuBar);
3541 UpdateGlobalMenuItems();
3546 m_pMenuBar->Destroy();
3552void MyFrame::RegisterGlobalMenuItems() {
3553 if (!m_pMenuBar)
return;
3555 wxMenu *nav_menu =
new wxMenu();
3556 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3557 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3558 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3559 nav_menu->AppendSeparator();
3560 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3561 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3562 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3563 nav_menu->AppendSeparator();
3565 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3566 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3568 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3569 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3571 nav_menu->AppendSeparator();
3572 nav_menu->Append(ID_MENU_SCALE_IN,
3573 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3574 nav_menu->Append(ID_MENU_SCALE_OUT,
3575 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3577 nav_menu->AppendSeparator();
3578 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3580 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3582 wxMenu *view_menu =
new wxMenu();
3584 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3585 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3586 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3587 _menuText(_(
"Show Chart Outlines"),
"O"));
3589 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3590 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3591 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3592 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3594 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3595 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3597 view_menu->AppendSeparator();
3599 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3600 _menuText(_(
"Show ENC text"),
"T"));
3601 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3602 _menuText(_(
"Show ENC Lights"),
"L"));
3603 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3604 _menuText(_(
"Show ENC Soundings"),
"S"));
3605 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3606 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3607 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3608 _menuText(_(
"Show ENC Data Quality"),
"U"));
3609 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3610 _menuText(_(
"Show Navobjects"),
"V"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3613 _menuText(_(
"Show ENC text"),
"Alt-T"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3615 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3617 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3619 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3621 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3622 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3623 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3625 view_menu->AppendSeparator();
3626 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3627 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3628 view_menu->AppendSeparator();
3630 view_menu->Append(ID_MENU_UI_COLSCHEME,
3631 _menuText(_(
"Change Color Scheme"),
"C"));
3633 view_menu->Append(ID_MENU_UI_COLSCHEME,
3634 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3637 view_menu->AppendSeparator();
3639 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3640 _menuText(_(
"Toggle Full Screen"),
"F11"));
3642 m_pMenuBar->Append(view_menu, _(
"&View"));
3644 wxMenu *ais_menu =
new wxMenu();
3645 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3646 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3647 _(
"Attenuate less critical AIS targets"));
3648 ais_menu->AppendSeparator();
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3650 _(
"Hide Moored AIS Targets"));
3651 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3652 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3653 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3656 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3657 _menuText(_(
"Show CPA Warnings"),
"W"));
3659 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3660 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3663 ais_menu->AppendSeparator();
3664 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3665 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3667 wxMenu *tools_menu =
new wxMenu();
3669 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3670 _menuText(_(
"Data Monitor"),
"E"));
3671 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3672 _menuText(_(
"Measure Distance"),
"M"));
3674 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3675 _menuText(_(
"Data Monitor"),
"Alt-E"));
3676 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3677 _menuText(_(
"Measure Distance"),
"Alt-M"));
3680 tools_menu->AppendSeparator();
3681 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3682 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3683 tools_menu->AppendSeparator();
3684 tools_menu->Append(ID_MENU_MARK_BOAT,
3685 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3686 tools_menu->Append(ID_MENU_MARK_CURSOR,
3687 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3688 tools_menu->AppendSeparator();
3692 _menuText(_(
"Drop MOB Marker"),
3694 tools_menu->AppendSeparator();
3695 tools_menu->Append(wxID_PREFERENCES,
3696 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3698 tools_menu->Append(ID_MENU_MARK_MOB,
3699 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3700 tools_menu->AppendSeparator();
3701 tools_menu->Append(wxID_PREFERENCES,
3702 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3704 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3707 wxMenu *window_menu =
new wxMenu();
3708 m_pMenuBar->Append(window_menu, _(
"&Window"));
3711 wxMenu *help_menu =
new wxMenu();
3712 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3713 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3714 m_pMenuBar->Append(help_menu, _(
"&Help"));
3717 UpdateGlobalMenuItems();
3720void MyFrame::UpdateGlobalMenuItems() {
3721 if (!m_pMenuBar)
return;
3723 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3724 ->Check(GetPrimaryCanvas()->m_bFollow);
3725 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3726 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3727 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3728 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3729 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3730 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3731 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3732 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3733 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3734 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3735 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3736 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3737 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3739 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3740 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3741 if (g_bAIS_CPA_Alert) {
3742 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3743 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3745 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3746 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3749 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3750 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3751 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3754 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3755 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3756 ->Check(ps52plib->GetShowSoundings());
3758 bool light_state =
false;
3760 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3762 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3763 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3764 light_state = (pOLE->nViz == 1);
3769 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3770 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3774 DisCat nset = ps52plib->GetDisplayCategory();
3775 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3776 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3777 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3778 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3779 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3780 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3781 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3783 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3784 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3785 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3790void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3791 if (!m_pMenuBar)
return;
3793 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3795 if (cc->GetUpMode() == NORTH_UP_MODE)
3796 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3797 else if (cc->GetUpMode() == COURSE_UP_MODE)
3798 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3800 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3802 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3803 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3804 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3805 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3806 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3807 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3808 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3809 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3810 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3811 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3812 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3813 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3814 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3815 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3816 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3819 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3820 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3823 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3825 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3826 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3831 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3835 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3836 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3837 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3838 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3839 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3840 ->Check(cc->GetShowENCDataQual());
3841 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3843 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3844 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3845 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3850void MyFrame::InvalidateAllCanvasUndo() {
3852 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3854 if (cc) cc->undo->InvalidateUndo();
3858void MyFrame::SubmergeAllCanvasToolbars() {
3860 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3862 if (cc) cc->SubmergeToolbar();
3866void MyFrame::SurfaceAllCanvasToolbars() {
3867 if (g_bshowToolbar) {
3869 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3871 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3878void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3880 if (lon > 180.0) lon -= 360.0;
3885 cc->JumpToPosition(lat, lon,
scale);
3888 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3892void MyFrame::UpdateCanvasConfigDescriptors() {
3894 for (
unsigned int i = 0;
3895 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3896 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3904 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3905 cc->GroupID = chart->m_groupIndex;
3908 cc->
bQuilt = chart->GetQuiltMode();
3914 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3916 cc->
bFollow = chart->m_bFollow;
3921 int upmode = chart->GetUpMode();
3922 if (upmode == COURSE_UP_MODE)
3924 else if (upmode == HEAD_UP_MODE)
3931void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3932 if (!RBBox.GetValid())
return;
3934 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3935 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3938 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3939 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3947 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3948 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3950 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3951 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3953 cc->GetSize(&ww, &wh);
3955 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3957 ppm = wxMin(ppm, 1.0);
3963void MyFrame::PrepareOptionsClose(
options *settings,
3964 int settings_return_value) {
3966 options_lastPage = settings->lastPage;
3971 if (options_lastPage == 1) options_lastPage = 0;
3973 options_subpage = settings->lastSubPage;
3974 options_lastWindowPos = settings->lastWindowPos;
3975 options_lastWindowSize = settings->lastWindowSize;
3978 androidEnableBackButton(
true);
3979 androidEnableOptionsMenu(
true);
3980 androidRestoreFullScreen();
3981 androidEnableRotation();
3984 EnableSettingsTool(
true);
3987void MyFrame::DoOptionsDialog() {
3988 EnableSettingsTool(
false);
3991 AbstractPlatform::ShowBusySpinner();
3994 pConfig->SetPath(
"/Settings");
3995 pConfig->Read(
"OptionsSizeX", &sx, -1);
3996 pConfig->Read(
"OptionsSizeY", &sy, -1);
3998 wxWindow *optionsParent =
this;
4000 optionsParent = GetPrimaryCanvas();
4003 callbacks.prepare_close = [&](
options *me,
int changes) {
4004 PrepareOptionsClose(me, changes);
4006 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4007 ProcessOptionsDialog(changes, workdir_list);
4010 wxPoint(-1, -1), wxSize(sx, sy));
4012 AbstractPlatform::HideBusySpinner();
4016 g_options->SetInitChartDir(*pInit_Chart_Dir);
4020 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4021 g_options->SetWorkDirListPtr(pWorkDirArray);
4027 prev_locale = g_locale;
4028 g_options->SetInitialPage(options_lastPage, options_subpage);
4031 g_options->lastWindowPos = options_lastWindowPos;
4032 if (options_lastWindowPos != wxPoint(0, 0)) {
4034 g_options->SetSize(options_lastWindowSize);
4038 if (options_lastWindowSize != wxSize(0, 0)) {
4039 g_options->SetSize(options_lastWindowSize);
4044 androidEnableBackButton(
false);
4045 androidEnableOptionsMenu(
false);
4046 androidDisableFullScreen();
4054 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4057 wxString chart_file_name;
4058 if (cc->GetQuiltMode()) {
4059 int dbi = cc->GetQuiltRefChartdbIndex();
4060 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4062 if (cc->m_singleChart)
4063 chart_file_name = cc->m_singleChart->GetFullPath();
4066 pathArray.Add(chart_file_name);
4072 last_canvasConfig = g_canvasConfig;
4075 g_last_ChartScaleFactor = g_ChartScaleFactor;
4081void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4082 bool b_need_refresh =
false;
4085 if ((rr & VISIT_CHARTS) &&
4086 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4088 UpdateChartDatabaseInplace(*pNewDirArray,
4089 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4092 b_need_refresh =
true;
4097 if (rr & STYLE_CHANGED) {
4100 _(
"Please restart OpenCPN to activate language or style changes."),
4101 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4104 bool charts_updating =
4105 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4106 if (!charts_updating) RefreshGroupIndices();
4108 if (rr & TIDES_CHANGED) {
4114 if (rr & S52_CHANGED) {
4115 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4126 g_Platform->GetDisplayDPmm());
4129 double stuffcog = NAN;
4130 double stuffsog = NAN;
4131 if (!std::isnan(
gCog)) stuffcog =
gCog;
4132 if (!std::isnan(
gSog)) stuffsog =
gSog;
4134 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4135 COGFilterTable[i] = stuffcog;
4136 SOGFilterTable[i] = stuffsog;
4139 SetChartUpdatePeriod();
4141 if (rr & GL_CHANGED) {
4145 b_need_refresh =
true;
4148 if (rr & S52_CHANGED) {
4149 b_need_refresh =
true;
4153 if (rr & REBUILD_RASTER_CACHE) {
4155 GetPrimaryCanvas()->Disable();
4157 GetPrimaryCanvas()->Enable();
4162 if (g_config_display_size_manual &&
4170 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4177 int rrt = rr & S52_CHANGED;
4179 (rrt == S52_CHANGED) ||
4180 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4190 ps52plib->SetScaleFactorExp(
4191 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4192 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4196 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4198 if (cc) cc->ApplyGlobalSettings();
4206 if (!charts_updating) {
4207 bool ztc = g_bEnableZoomToCursor;
4208 g_bEnableZoomToCursor =
false;
4210 if (!GetPrimaryCanvas()->IsFrozen())
4212 g_bEnableZoomToCursor = ztc;
4217 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4226 SetGPSCompassScale();
4228 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4231 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4232 if (!charts_updating) cc->UpdateCanvasControlBar();
4235 UpdateGPSCompassStatusBoxes();
4237 SetAllToolbarScale();
4238 RequestNewToolbars();
4240 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4243 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4246 cc->RebuildCursors();
4251 bool b_masterScaleChange =
false;
4252 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4253 b_masterScaleChange =
true;
4255 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4256 RequestNewMasterToolbar(
true);
4258 bool bMuiChange =
false;
4264 if (b_masterScaleChange || bMuiChange) {
4266 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4269 cc->ProcessNewGUIScale();
4275 if (rr & LOCALE_CHANGED) {
4276 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4278 rr |= NEED_NEW_OPTIONS;
4287 g_last_ChartScaleFactor = g_ChartScaleFactor;
4292bool MyFrame::CheckGroup(
int igroup) {
4293 if (igroup == 0)
return true;
4297 if (!pGroup->m_element_array.size())
4300 for (
const auto &elem : pGroup->m_element_array) {
4301 for (
unsigned int ic = 0;
4302 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4303 auto &cte =
ChartData->GetChartTableEntry(ic);
4304 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4306 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4313bool MyFrame::ScrubGroupArray() {
4318 bool b_change =
false;
4319 unsigned int igroup = 0;
4320 while (igroup < g_pGroupArray->GetCount()) {
4321 bool b_chart_in_element =
false;
4324 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4325 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4327 for (
unsigned int ic = 0;
4328 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4329 auto &cte =
ChartData->GetChartTableEntry(ic);
4330 wxString chart_full_path = cte.GetFullSystemPath();
4332 if (chart_full_path.StartsWith(element_root)) {
4333 b_chart_in_element =
true;
4339 if (!b_chart_in_element) {
4340 wxString test_string =
"GSHH";
4341 if (element_root.Upper().Contains(test_string))
4342 b_chart_in_element =
true;
4345 if (!b_chart_in_element)
4347 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4359void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4361 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4363 if (cc && (cc != ccThis)) cc->Refresh();
4368void MyFrame::ChartsRefresh() {
4371 AbstractPlatform::ShowBusySpinner();
4373 bool b_run = FrameTimer1.IsRunning();
4376 FrameTenHzTimer.Stop();
4379 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4382 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4383 if (cc->GetQuiltMode()) {
4384 currentIndex = cc->GetQuiltReferenceChartIndex();
4386 cc->canvasChartsRefresh(currentIndex);
4390 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4391 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4393 AbstractPlatform::HideBusySpinner();
4396void MyFrame::InvalidateAllQuilts() {
4397 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4400 cc->InvalidateQuilt();
4401 cc->SetQuiltRefChart(-1);
4402 cc->m_singleChart = NULL;
4407bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4409 const wxString &ChartListFileName) {
4410 bool b_run = FrameTimer1.IsRunning();
4412 FrameTenHzTimer.Stop();
4414 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4415 FrameCOGTimer.Stop();
4418 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4421 cc->InvalidateQuilt();
4422 cc->SetQuiltRefChart(-1);
4423 cc->m_singleChart = NULL;
4433 AbstractPlatform::ShowBusySpinner();
4436 wxString longmsg = _(
"OpenCPN Chart Update");
4438 ".................................................................."
4441 Updateprog =
new wxGenericProgressDialog();
4444 Updateprog->SetFont(*qFont);
4446 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4447 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4448 wxPD_REMAINING_TIME);
4450 DimeControl(Updateprog);
4455 wxLogMessage(
"Starting chart database Update...");
4459 m_gshhg_chart_loc = gWorldMapLocation;
4460 gWorldMapLocation = wxEmptyString;
4464 AbstractPlatform::HideBusySpinner();
4468void MyFrame::FinalizeChartDBUpdate() {
4470 if (!g_bDeferredInitDone) {
4472 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4475 bool b_groupchange = ScrubGroupArray();
4477 RefreshGroupIndices();
4479 if (b_groupchange) {
4480 pConfig->DestroyConfigGroups();
4485 if (g_bDeferredInitDone) ScheduleReloadCharts();
4490 cc->ToggleCanvasQuiltMode();
4492 bool cur_mode = cc->GetQuiltMode();
4494 if( !cc->GetQuiltMode() )
4495 cc->SetQuiltMode(
true );
4497 if( cc->GetQuiltMode() ) {
4498 cc->SetQuiltMode(
false );
4499 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4503 if( cur_mode != cc->GetQuiltMode() ){
4509 g_bQuiltEnable = cc->GetQuiltMode();
4513 ps52plib->GenerateStateHash();
4521 DoStackDelta(cc, -1);
4527 DoStackDelta(cc, 1);
4530void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4532void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4534void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4536 cc->DoCanvasStackDelta(direction);
4540void MyFrame::PositionIENCToolbar() {
4544 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4546 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4554void MyFrame::OnInitTimer(wxTimerEvent &event) {
4557 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4561 wxLog::FlushActive();
4563 switch (m_iInitCount++) {
4565 EnableSettingsTool(
false);
4570 if (g_bInlandEcdis) {
4571 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4572 double range_set = 500.;
4574 range = wxRound(range * 10) / 10.;
4578 else if (range > 2000.)
4580 else if (range > 1600.)
4582 else if (range > 1200.)
4584 else if (range > 800.)
4589 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4593 g_Platform->SetFullscreen(g_bFullscreen);
4597 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4600 cc->SetGroupIndex(0,
false);
4607 StartRebuildChartDatabase();
4618 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4632 3 * GetCharHeight());
4634 m_data_monitor->Center();
4642 pConfig->SetPath(
"/Settings");
4643 pConfig->Read(
"OptionsSizeX", &sx, -1);
4644 pConfig->Read(
"OptionsSizeY", &sy, -1);
4646 wxWindow *optionsParent =
this;
4648 optionsParent = GetPrimaryCanvas();
4650 BuildiENCToolbar(
true, m_toolbar_callbacks);
4657 if (!g_params.empty()) {
4658 for (
size_t n = 0; n < g_params.size(); n++) {
4659 wxString path = g_params[n];
4660 if (::wxFileExists(path)) {
4662 pSet->load_file(path.fn_str());
4665 pSet->LoadAllGPXObjects(
4666 !pSet->IsOpenCPN(), wpt_dups,
4668 LLBBox box = pSet->GetBBox();
4669 if (box.GetValid()) {
4670 CenterView(GetPrimaryCanvas(), box);
4679 InitAppMsgBusListener();
4684 auto loader = PluginLoader::GetInstance();
4685 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4686 if (!b_haveWMM)
gVar = g_UserVar;
4694 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4697 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4699 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4702 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4706 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4707 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4708 NavObj_dB::GetInstance().LoadNavObjects();
4711 if (!g_AW1GUID.IsEmpty()) {
4714 if (!g_AW2GUID.IsEmpty()) {
4720 appendOSDirSlash(&layerdir);
4721 layerdir.Append(
"layers");
4723 if (wxDir::Exists(layerdir)) {
4725 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4726 wxLogMessage(laymsg);
4727 pConfig->LoadLayers(layerdir);
4732 if (!g_kiosk_startup) {
4733 AbstractPlatform::ShowBusySpinner();
4736 pConfig->SetPath(
"/Settings");
4737 pConfig->Read(
"OptionsSizeX", &sx, -1);
4738 pConfig->Read(
"OptionsSizeY", &sy, -1);
4740 wxWindow *optionsParent =
this;
4742 optionsParent = GetPrimaryCanvas();
4745 callbacks.prepare_close = [&](
options *me,
int changes) {
4746 PrepareOptionsClose(me, changes);
4748 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4749 ProcessOptionsDialog(changes, workdir_list);
4752 wxPoint(-1, -1), wxSize(sx, sy));
4753 AbstractPlatform::HideBusySpinner();
4760 wxLogMessage(
"OnInitTimer...Last Call");
4764 RequestNewMasterToolbar();
4766 PositionIENCToolbar();
4768 g_bDeferredInitDone =
true;
4778 GetPrimaryCanvas()->SetFocus();
4779 GetPrimaryCanvas()->Enable();
4782 if (b_reloadForPlugins) {
4788 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4790 if (cc) cc->SetFirstAuto(
true);
4798 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4800 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4804 cc->CheckGroupValid();
4805 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4806 cc->SetShowGPSCompassWindow(
true);
4811 androidEnableBackButton(
true);
4812 androidEnableRotation();
4813 androidEnableOptionItems(
true);
4817 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4823 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4825 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4827 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4833 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4835 wxLog::FlushActive();
4837 RefreshAllCanvas(
true);
4838 UsbWatchDaemon::GetInstance().Start();
4839 EnableSettingsTool(
true);
4845void MyFrame::InitAppMsgBusListener() {
4846 auto &msgbus = AppMsgBus::GetInstance();
4849 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4850 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4854 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4855 HandleBasicNavMsg(basicnav_msg);
4859 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4860 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4864 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4865 HandleGPSWatchdogMsg(msg);
4872void MyFrame::ReleaseApiListeners() {}
4877 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4878 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4879 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4880 server.open_file_cb = [&](
const std::string &path) {
4881 return m_open_gpx_file(path);
4888void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4889 if (msg->gps_watchdog <= 0) {
4890 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4894 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4899 if (m_fix_start_time.IsValid()) {
4900 wxDateTime now = wxDateTime::Now();
4901 wxTimeSpan span = now - m_fix_start_time;
4902 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4903 auto ¬eman = NotificationManager::GetInstance();
4904 wxString msg = _(
"GNSS Position fix lost");
4905 noteman.AddNotification(NotificationSeverity::kCritical,
4907 m_fix_start_time = wxInvalidDateTime;
4911 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4912 bool last_bVelocityValid = bVelocityValid;
4913 bVelocityValid =
false;
4920void MyFrame::CalculateCOGAverage() {
4922 if (!std::isnan(
gCog)) {
4925 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4928 double sum = 0., count = 0;
4930 double adder = COGTable[i];
4931 if (std::isnan(adder))
continue;
4933 if (fabs(adder -
g_COGAvg) > 180.) {
4947 else if (sum >= 360.)
4956void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4957 m_fixtime = msg->time;
4958 double hdt_data_interval = 0;
4959 double fix_time_interval = 0;
4961 double msgtime = msg->set_time.tv_sec;
4962 double m1 = msg->set_time.tv_nsec / 1e9;
4965 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4966 ((msg->vflag & POS_VALID) == POS_VALID)) {
4968 if (!m_fix_start_time.IsValid()) {
4969 m_fix_start_time = wxDateTime::Now();
4974 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4977 fix_time_gt_last = fix_time_gt;
4978 uint64_t fix_time_gt_now =
4979 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4980 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4984 double implied_sog = dist / (fix_time_interval / 3600);
4989 gLat_gt_m1 = gLat_gt;
4990 gLon_gt_m1 = gLon_gt;
4994 fix_time_gt = fix_time_gt_now;
4998 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
4999 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5000 gCog_gt_m1 = gCog_gt;
5010 if (!std::isnan(gCog_gt_m1)) {
5012 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5019 if ((fix_time_gt - fix_time_gt_last) > .08) {
5024 if (gCog_gt > gCog_gt_m1) {
5025 if ((gCog_gt - gCog_gt_m1) > 180.)
5030 if ((gCog_gt_m1 - gCog_gt) > 180.)
5035 difft = fabs(gCog_gt - gCog_gt_m1);
5036 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5044 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5045 tentative_cog_rate_gt *= 1e9;
5046 cog_rate_gt = tentative_cog_rate_gt;
5054 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5057static double hdt_avg;
5058 double hdt_norm =
gHdt;
5059 if(
gHdt > 180) hdt_norm -= 360;
5062 hdt_avg += hdt_norm * 0.1;
5067 if (!std::isnan(
gHdt)) {
5069 uint64_t hdt_time_gt_last = hdt_time_gt;
5070 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5071 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5074 if (hdt_data_interval > .09) {
5076 gHdt_gt_m1 = gHdt_gt;
5079 if (!std::isnan(gHdt_gt_m1)) {
5081 double tentative_hdt_rate_gt =
5082 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5083 tentative_hdt_rate_gt *= 1e9;
5085 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5086 hdt_rate_gt = tentative_hdt_rate_gt;
5094 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5097 CalculateCOGAverage();
5105 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5106 if ((msg->vflag & POS_VALID) == POS_VALID)
5111 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5113 bVelocityValid =
true;
5117void MyFrame::UpdateStatusBar() {
5120 unsigned long uiCurrentTickCount;
5121 m_MMEAeventTime.SetToCurrent();
5122 uiCurrentTickCount =
5123 m_MMEAeventTime.GetMillisecond() / 100;
5124 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5125 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5126 m_ulLastNMEATicktime = uiCurrentTickCount;
5128 if (m_tick_idx++ > 6) m_tick_idx = 0;
5133 if (NULL != GetStatusBar()) {
5136 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5139 wxString s1(tick_buf, wxConvUTF8);
5141 s1 += toSDMM(1,
gLat);
5143 s1 += toSDMM(2,
gLon);
5145 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5149 if (!std::isnan(
gSog))
5150 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5152 sogcog.Printf(
"SOG --- ");
5156 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5158 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5160 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5161 (
int)toMagnetic(
gCog), 0x00B0);
5163 cogs.Printf((
"COG ---%c"), 0x00B0);
5165 sogcog.Append(cogs);
5166 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5171void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5172 MemFootTimer.Stop();
5174 int memsize = GetApplicationMemoryUse();
5177 printf(
"Memsize: %d \n", memsize);
5180 if (memsize > (g_MemFootMB * 1000)) {
5184 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5185 unsigned int nCache = pCache->GetCount();
5188 for (
unsigned int i = 0; i < nCache; i++) {
5198 for (
unsigned int i = 0; i < nCache - 1; i++) {
5199 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5201 pcea[i] = pcea[i + 1];
5212 unsigned int idelete = 0;
5213 unsigned int idelete_max = pCache->GetCount();
5216 unsigned int minimum_cache = 1;
5217 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5219 while ((memsize > (g_MemFootMB * 1000)) &&
5220 (pCache->GetCount() > minimum_cache) &&
5221 (idelete < idelete_max)) {
5222 int memsizeb = memsize;
5226 memsize = GetApplicationMemoryUse();
5227 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5235 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5240void MyFrame::CheckToolbarPosition() {
5243 static bool bMaximized;
5245 if (IsMaximized() && !bMaximized) {
5252 PositionIENCToolbar();
5253 }
else if (!IsMaximized() && bMaximized) {
5261 PositionIENCToolbar();
5266void MyFrame::ProcessUnitTest() {
5267 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5274 cc->m_bFollow =
false;
5276 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5277 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5280 if (cc->m_groupIndex > 0) {
5281 while (ut_index < ChartData->GetChartTableEntries() &&
5282 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5286 if (ut_index < ChartData->GetChartTableEntries()) {
5290 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5291 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5298 if (cc->GetQuiltMode()) {
5299 if (cc->IsChartQuiltableRef(ut_index))
5300 cc->SelectQuiltRefdbChart(ut_index);
5302 cc->SelectdbChart(ut_index);
5305 if (g_unit_test_1) {
5313 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5314 cte->GetLatMin(), cte->GetLonMax(), NULL,
5318 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5319 cte->GetLatMax(), cte->GetLonMin(), NULL,
5322 cc->GetSize(&ww, &wh);
5323 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5325 ppm = wxMin(ppm, 1.0);
5332 if (ut_index > ut_index_max) exit(0);
5343 bool b_rotate =
false;
5345 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5348 if (!b_rotate && !g_btenhertz)
return;
5350 bool b_update =
false;
5352 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5355 struct timespec now;
5356 clock_gettime(CLOCK_MONOTONIC, &now);
5357 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5358 double diffc = diff / 1e9;
5361 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5362 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5363 if (gCog_tentative < 0.) gCog_tentative += 360.;
5364 gCog = gCog_tentative;
5368 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5369 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5370 double diffc = diff / 1e9;
5371 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5375 if (gSog_gt && !std::isnan(gCog_gt)) {
5376 double delta_t = diffc / 3600;
5377 double distance = gSog_gt * delta_t;
5380 double angr = gCog_gt / 180 * M_PI;
5381 double latr = gLat_gt * M_PI / 180;
5382 double D = distance / 3443;
5383 double sD = sin(D), cD = cos(D);
5384 double sy = sin(latr), cy = cos(latr);
5385 double sa = sin(angr), ca = cos(angr);
5387 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5388 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5398 if (cc) cc->DoCanvasCOGSet();
5407 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5408 bool bnew = cc->DoCanvasUpdate();
5409 if (!bnew) cc->UpdateShips();
5418 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5421bool MyFrame::ProcessQuitFlag() {
5425 FrameTenHzTimer.Stop();
5427 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5428 if (top) top->Close(
true);
5435void MyFrame::ProcessDeferredTrackOn() {
5438 if (g_bDeferredStartTrack) {
5439 if (!g_bTrackActive) {
5442 g_bDeferredStartTrack =
false;
5445 g_bDeferredStartTrack =
false;
5450void MyFrame::ProcessAnchorWatch() {
5458 double d = g_nAWMax;
5461 bool toofar =
false;
5462 bool tooclose =
false;
5463 if (d >= 0.0) toofar = (dist * 1852. > d);
5464 if (d < 0.0) tooclose = (dist * 1852 < -d);
5466 if (tooclose || toofar)
5467 AnchorAlertOn1 =
true;
5469 AnchorAlertOn1 =
false;
5471 AnchorAlertOn1 =
false;
5479 double d = g_nAWMax;
5482 bool toofar =
false;
5483 bool tooclose =
false;
5484 if (d >= 0) toofar = (dist * 1852. > d);
5485 if (d < 0) tooclose = (dist * 1852 < -d);
5487 if (tooclose || toofar)
5488 AnchorAlertOn2 =
true;
5490 AnchorAlertOn2 =
false;
5492 AnchorAlertOn2 =
false;
5495 AnchorAlertOn1 =
true;
5498void MyFrame::SendFixToPlugins() {
5509 GPSData.
nSats = g_SatsInView;
5511 wxDateTime tCheck((time_t)m_fixtime);
5512 if (tCheck.IsValid()) {
5521 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5524 SendPositionFixToAllPlugIns(&GPSData);
5528void MyFrame::ProcessLogAndBells() {
5531 wxDateTime lognow = wxDateTime::Now();
5532 int hourLOC = lognow.GetHour();
5533 int minuteLOC = lognow.GetMinute();
5535 int minuteUTC = lognow.GetMinute();
5536 int second = lognow.GetSecond();
5538 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5539 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5540 (minuteUTC == 30)) {
5541 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5542 wxString day = lognow.FormatISODate();
5543 wxString utc = lognow.FormatISOTime();
5544 wxString navmsg =
"LOGBOOK: ";
5552 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5556 if (std::isnan(
gCog))
5557 cog.Printf(
"COG ----- ");
5559 cog.Printf(
"COG %10.5f ",
gCog);
5562 if (std::isnan(
gSog))
5563 sog.Printf(
"SOG ----- ");
5565 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5571 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5574 wxLogMessage(navmsg);
5575 g_loglast_time = lognow;
5577 int bells = (hourLOC % 4) * 2;
5578 if (minuteLOC != 0) bells++;
5579 if (!bells) bells = 8;
5581 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5582 m_BellsToPlay = bells;
5583 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5584 wxPostEvent(
this, ev);
5591 CheckToolbarPosition();
5595 if (ProcessQuitFlag())
return;
5597 if (bDBUpdateInProgress)
return;
5600 FrameTenHzTimer.Stop();
5602 ProcessDeferredTrackOn();
5604 ProcessAnchorWatch();
5605 ProcessLogAndBells();
5607 if (ShouldRestartTrack()) TrackDailyRestart();
5610 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5611 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5612 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5618 if (
gSog > 3.0) g_bCruising =
true;
5624 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5626 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5632 bool bnew_view =
false;
5633 if (!g_btenhertz) bnew_view = DoChartUpdate();
5640 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5643 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5646 cc->DrawBlinkObjects();
5649 if (bactiveRouteUpdate) {
5656 cc->SetOwnShipState(SHIP_NORMAL);
5658 if (cc->GetQuiltMode()) {
5659 double erf = cc->GetQuiltMaxErrorFactor();
5660 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5662 if (cc->m_singleChart) {
5663 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5664 cc->SetOwnShipState(SHIP_LOWACCURACY);
5668 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5671 (bVelocityValid != m_last_bVelocityValid) ||
5672 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5673 if (!g_bopengl) cc->UpdateShips();
5681 m_last_bVelocityValid = bVelocityValid;
5686 bool brq_dynamic =
false;
5688 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5689 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5691 if (pic->m_enabled && pic->m_init_state) {
5692 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5699 if (brq_dynamic) bnew_view =
true;
5703 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5706 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5711 if (cc->GetglCanvas()) {
5713 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5715 if ((!g_btenhertz)) {
5716 if (cc->m_bFollow) {
5717 cc->DoCanvasUpdate();
5734 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5748 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5749 g_pais_query_dialog_active->UpdateText();
5752 if (g_pAISTargetList && (0 == (g_tick % (5))))
5753 g_pAISTargetList->UpdateAISTargetList();
5756 UpdateGPSCompassStatusBoxes();
5761 console->RefreshConsoleData();
5768 if (m_bdefer_resize) {
5769 if (0 == (g_tick % (5))) {
5770 printf(
"___RESIZE\n");
5771 SetSize(m_defer_size);
5773 m_bdefer_resize =
false;
5780 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5782 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5783 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5787double MyFrame::GetMag(
double a,
double lat,
double lon) {
5788 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5789 auto loader = PluginLoader::GetInstance();
5790 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5797 wxDateTime now = wxDateTime::Now();
5798 SendJSON_WMM_Var_Request(lat, lon, now);
5799 if (fabs(gQueryVar) < 360.0)
5800 Variance = gQueryVar;
5802 return toMagnetic(a, Variance);
5805bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5811 v[
"Year"] = date.GetYear();
5812 v[
"Month"] = date.GetMonth();
5813 v[
"Day"] = date.GetDay();
5815 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5821void MyFrame::TouchAISActive() {
5823 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5825 if (cc) cc->TouchAISToolActive();
5829void MyFrame::UpdateAISTool() {
5833 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5835 if (cc) cc->UpdateAISTBTool();
5840void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5842 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5844 if (cc) cc->SetbTCUpdate(
true);
5847 RefreshAllCanvas(
false);
5852void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5856 bool b_rotate =
false;
5857 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5859 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5863 FrameCOGTimer.Stop();
5870 int period_ms = 100;
5872 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5875void MyFrame::DoCOGSet() {
5877 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5879 if (cc) cc->DoCanvasCOGSet();
5883void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5889 wxFont oldfont = pdc->GetFont();
5891 pdc->SetFont(*pFont);
5892 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5893 pdc->SetBackgroundMode(wxTRANSPARENT);
5895 pdc->DrawText(str, x, y + 1);
5896 pdc->DrawText(str, x, y - 1);
5897 pdc->DrawText(str, x + 1, y);
5898 pdc->DrawText(str, x - 1, y);
5900 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5902 pdc->DrawText(str, x, y);
5904 pdc->SetFont(oldfont);
5908void MyFrame::UpdateRotationState(
double rotation) {
5910 g_bCourseUp =
false;
5912 if (fabs(rotation) > .001) {
5913 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5914 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5916 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5919 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5920 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5922 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5926 UpdateGPSCompassStatusBoxes(
true);
5930void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5932 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5934 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5940int MyFrame::GetApplicationMemoryUse() {
5946 wxWindow *fWin = wxWindow::FindFocus();
5948 wxArrayString outputArray;
5949 wxString cmd(
"ps --no-headers -o vsize ");
5950 unsigned long pid = wxGetProcessId();
5952 cmd1.Printf(
"%ld", pid);
5954 wxExecute(cmd, outputArray);
5956 if (outputArray.GetCount()) {
5957 wxString s = outputArray.Item(0);
5959 if (s.ToLong(&vtmp)) memsize = vtmp;
5962 if (fWin) fWin->SetFocus();
5968 PROCESS_MEMORY_COUNTERS pmc;
5970 unsigned long processID = wxGetProcessId();
5972 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5974 if (NULL == hProcess)
return 0;
5976 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5994 memsize = pmc.WorkingSetSize / 1024;
5997 CloseHandle(hProcess);
6004double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6005 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6008void MyFrame::SetChartUpdatePeriod() {
6011 g_ChartUpdatePeriod = 0;
6016 bool bskewdc =
false;
6017 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6020 if (!g_bopengl && !cc->GetVP().b_quilt) {
6021 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6023 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6027 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6029 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6034 cc->UpdateCanvasControlBar();
6037void MyFrame::selectChartDisplay(
int type,
int family) {
6039 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6041 if (cc) cc->selectCanvasChartDisplay(type, family);
6044 UpdateGlobalMenuItems();
6053bool MyFrame::DoChartUpdate() {
6054 bool return_val =
false;
6057 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6059 if (cc) return_val |= cc->DoCanvasUpdate();
6065void MyFrame::MouseEvent(wxMouseEvent &event) {
6067 event.GetPosition(&x, &y);
6072#include <mach/mach.h>
6073#include <mach/message.h>
6074#include <mach/kern_return.h>
6075#include <mach/task_info.h>
6077#include <malloc/malloc.h>
6084#if defined(__linux__)
6085#include "sys/types.h"
6086#include "sys/sysinfo.h"
6089void MyFrame::DoPrint(
void) {
6091 g_PrintingInProgress =
true;
6094 GetPrimaryCanvas()->GetglCanvas()->Render();
6095 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6105 printer.Initialize(wxLANDSCAPE);
6106 printer.EnablePageNumbers(
false);
6107 printer.Print(
this, &printout);
6125 g_PrintingInProgress =
false;
6128 GetPrimaryCanvas()->SetFocus();
6134 wxString message_ID =
event.GetID();
6135 wxString message_JSONText =
event.GetJSONText();
6143 if (message_ID ==
"WMM_VARIATION_BOAT") {
6151 int numErrors = reader.
Parse(message_JSONText, &root);
6152 if (numErrors > 0) {
6158 wxString decl = root[
"Decl"].
AsString();
6160 decl.ToDouble(&decl_val);
6166 if (message_ID ==
"WMM_VARIATION") {
6174 int numErrors = reader.
Parse(message_JSONText, &root);
6175 if (numErrors > 0) {
6181 wxString decl = root[
"Decl"].
AsString();
6183 decl.ToDouble(&decl_val);
6185 gQueryVar = decl_val;
6188 if (message_ID ==
"GRIB_TIMELINE") {
6191 int numErrors = r.
Parse(message_JSONText, &v);
6193 if (numErrors > 0) {
6194 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6199 wxDateTime oldTimeSource = gTimeSource;
6201 if (v[
"Day"].AsInt() == -1) {
6202 gTimeSource = wxInvalidDateTime;
6203 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6205 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6206 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6207 v[
"Second"].AsInt());
6211 if (oldTimeSource != gTimeSource) {
6213 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6215 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6220 cc->pCwin->Refresh(
false);
6226 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6229 wxString trk_id = wxEmptyString;
6231 int numErrors = reader.
Parse(message_JSONText, &root);
6232 if (numErrors > 0)
return;
6237 v[
"Track_ID"] = trk_id;
6239 wxString name = wxEmptyString;
6240 if (ptrack->m_GUID == trk_id) {
6241 name = ptrack->GetName();
6242 if (name.IsEmpty()) {
6248 name = _(
"(Unnamed Track)");
6255 v[
"TotalNodes"] = ptrack->GetnPoints();
6256 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6258 v[
"lat"] = tp->m_lat;
6259 v[
"lon"] = tp->m_lon;
6262 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6263 SendJSONMessageToAllPlugins(msg_id, v);
6269 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6270 SendJSONMessageToAllPlugins(msg_id, v);
6272 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6275 wxString guid = wxEmptyString;
6277 int numErrors = reader.
Parse(message_JSONText, &root);
6278 if (numErrors > 0) {
6287 wxString name = wxEmptyString;
6289 if ((*it)->m_GUID == guid) {
6290 name = (*it)->m_RouteNameString;
6291 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6297 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6298 itp != (*it)->pRoutePointList->end(); itp++) {
6299 w[i][
"lat"] = (*itp)->m_lat;
6300 w[i][
"lon"] = (*itp)->m_lon;
6301 w[i][
"Name"] = (*itp)->GetName();
6302 w[i][
"Description"] = (*itp)->GetDescription();
6303 w[i][
"GUID"] = (*itp)->m_GUID;
6304 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6306 auto node = (*itp)->m_HyperlinkList->begin();
6307 if (node != (*itp)->m_HyperlinkList->end()) {
6309 while (node != (*itp)->m_HyperlinkList->end()) {
6311 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6312 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6313 httpLink->DescrText;
6320 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6321 SendJSONMessageToAllPlugins(msg_id, v);
6328 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6329 SendJSONMessageToAllPlugins(msg_id, v);
6330 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6335 int numErrors = reader.
Parse(message_JSONText, &root);
6336 if (numErrors > 0)
return;
6339 wxString str = root[
"mode"].
AsString();
6340 if (str ==
"Track") route =
false;
6345 for (RouteList::iterator it =
pRouteList->begin();
6347 wxString name = (*it)->m_RouteNameString;
6348 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6350 v[i][
"error"] =
false;
6351 v[i][
"name"] = name;
6352 v[i][
"GUID"] = (*it)->m_GUID;
6353 v[i][
"active"] = (*it)->IsActive();
6358 wxString name = ptrack->GetName();
6359 if (name.IsEmpty()) {
6365 name = _(
"(Unnamed Track)");
6367 v[i][
"error"] =
false;
6368 v[i][
"name"] = name;
6369 v[i][
"GUID"] = ptrack->m_GUID;
6374 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6375 SendJSONMessageToAllPlugins(msg_id, v);
6378 v[0][
"error"] =
true;
6379 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6380 SendJSONMessageToAllPlugins(msg_id, v);
6382 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6384 v[0][
"error"] =
true;
6387 v[0][
"error"] =
false;
6388 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6389 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6390 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6391 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6392 v[0][
"active_waypoint_lat"] =
6394 v[0][
"active_waypoint_lon"] =
6398 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6399 SendJSONMessageToAllPlugins(msg_id, v);
6403void MyFrame::FilterCogSog() {
6404 if (g_bfilter_cogsog) {
6406 double cog_last =
gCog;
6409 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6410 COGFilterTable[i] = COGFilterTable[i - 1];
6411 COGFilterTable[0] = cog_last;
6414 if (!std::isnan(cog_last)) {
6416 double sum = 0., count = 0;
6417 for (
int i = 0; i < g_COGFilterSec; i++) {
6418 double adder = COGFilterTable[i];
6419 if (std::isnan(adder))
continue;
6421 if (fabs(adder - cog_last) > 180.) {
6422 if ((adder - cog_last) > 0.)
6435 else if (sum >= 360.)
6442 double sog_last =
gSog;
6445 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6446 SOGFilterTable[i] = SOGFilterTable[i - 1];
6447 SOGFilterTable[0] = sog_last;
6450 if (!std::isnan(
gSog)) {
6451 double sum = 0., count = 0;
6452 for (
int i = 0; i < g_SOGFilterSec; i++) {
6453 if (std::isnan(SOGFilterTable[i]))
continue;
6455 sum += SOGFilterTable[i];
6465void MyFrame::LoadHarmonics() {
6468 ptcmgr->LoadDataSources(TideCurrentDataSet);
6470 bool b_newdataset =
false;
6473 for (
auto a :
ptcmgr->GetDataSet()) {
6474 bool b_foundi =
false;
6475 for (
auto b : TideCurrentDataSet) {
6482 b_newdataset =
true;
6487 for (
auto a : TideCurrentDataSet) {
6488 bool b_foundi =
false;
6489 for (
auto b :
ptcmgr->GetDataSet()) {
6496 b_newdataset =
true;
6501 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6505void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6506 if (!ptarget)
return;
6509 wxDateTime mob_time = wxDateTime::Now();
6510 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6511 mob_label += _(
" on ");
6512 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6515 mob_label, wxEmptyString);
6516 pWP_MOB->SetShared(
true);
6518 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6520 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6522 pWP_MOB->SetUseSca(
false);
6530 wxString(_(
"Own ship")), wxEmptyString);
6532 pWP_MOB->SetUseSca(
false);
6539 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6555 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6556 SendJSONMessageToAllPlugins(msg_id, v);
6559 if (RouteManagerDialog::getInstanceFlag()) {
6566 RefreshAllCanvas(
false);
6568 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6569 mob_message += _(
" Time: ");
6570 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6571 mob_message += _(
" Ownship Position: ");
6572 mob_message += toSDMM(1,
gLat);
6574 mob_message += toSDMM(2,
gLon);
6575 mob_message += _(
" MOB Position: ");
6576 mob_message += toSDMM(1, ptarget->Lat);
6578 mob_message += toSDMM(2, ptarget->Lon);
6579 wxLogMessage(mob_message);
6582void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6586 OwnPoint->m_lat =
gLat;
6587 OwnPoint->m_lon =
gLon;
6589 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6594 MOB_Point->m_lat = ptarget->Lat;
6595 MOB_Point->m_lon = ptarget->Lon;
6597 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6598 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6600 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6601 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6604 RefreshAllCanvas(
false);
6607 wxDateTime mob_time = wxDateTime::Now();
6609 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6610 mob_message += _(
" Time: ");
6611 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6612 mob_message += _(
" Ownship Position: ");
6613 mob_message += toSDMM(1,
gLat);
6615 mob_message += toSDMM(2,
gLon);
6616 mob_message += _(
" MOB Position: ");
6617 mob_message += toSDMM(1, ptarget->Lat);
6619 mob_message += toSDMM(2, ptarget->Lon);
6621 wxLogMessage(mob_message);
6625void MyFrame::applySettingsString(wxString settings) {
6627 int last_UIScaleFactor = g_GUIScaleFactor;
6628 bool previous_expert = g_bUIexpert;
6629 g_last_ChartScaleFactor = g_ChartScaleFactor;
6630 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6633 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6639 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6641 if (rr & S52_CHANGED) {
6643 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6645 ->ClearCNSYLUPArray();
6646 ps52plib->GenerateStateHash();
6650 ProcessOptionsDialog(rr, pNewDirArray);
6655 bool b_newToolbar =
false;
6657 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6659 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6661 if (rr & TOOLBAR_CHANGED) {
6662 b_newToolbar =
true;
6667 if (previous_expert && !g_bUIexpert) {
6668 androidForceFullRepaint();
6672 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6676 SetGPSCompassScale();
6678 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6680 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6682 UpdateGPSCompassStatusBoxes(
true);
6685 AbstractPlatform::ShowBusySpinner();
6687 SetAllToolbarScale();
6691 AbstractPlatform::HideBusySpinner();
6693 RequestNewMasterToolbar(
true);
6700 UpdateControlBar(GetPrimaryCanvas());
6706 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6709#ifdef wxHAS_POWER_EVENTS
6710void MyFrame::OnSuspending(wxPowerEvent &event) {
6714 wxLogMessage(
"System suspend starting...");
6717void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6720 wxLogMessage(
"System is going to suspend.");
6723void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6726 wxLogMessage(
"System suspend was cancelled.");
6729int g_last_resume_ticks;
6730void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6731 wxDateTime now = wxDateTime::Now();
6732 wxLogMessage(
"System resumed from suspend.");
6734 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6737 wxLogMessage(
"Restarting streams.");
6738 g_last_resume_ticks = now.GetTicks();
6742 g_pMUX->ClearStreams();
6744 g_pMUX->StartAllStreams();
6753 if (IsMaximized()) {
6758 wxSize sz = GetSize();
6759 SetSize(wxSize(sz.x - 1, sz.y));
6771void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6772 bool btbRebuild =
false;
6774 bool b_reshow =
true;
6777 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6778 if ((ff > 0.01f) || bforcenew) {
6788 long orient = g_Platform->GetDefaultToolbarOrientation();
6789 wxWindow *toolbarParent =
this;
6791 toolbarParent = GetPrimaryCanvas();
6794 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6795 m_toolbar_callbacks);
6797 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6804 g_bmasterToolbarFull =
true;
6808 CreateMasterToolbar();
6823bool MyFrame::CollapseGlobalToolbar() {
6825 m_nMasterToolCountShown = 1;
6829 g_bmasterToolbarFull =
false;
6845 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6846 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6847 tic->m_bRequired =
true;
6852 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6853 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6857 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6858 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6859 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6864 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6865 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6869 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6870 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6871 _(
"Enable Tracking"),
"MUI_track");
6875 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6876 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6888 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6889 _(
"Print Chart"),
"MUI_print");
6893 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6894 _(
"About OpenCPN"),
"MUI_help");
6898 AddDefaultPositionPlugInTools();
6902 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6903 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6914 ArrayOfPlugInToolbarTools tool_array =
6916 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6918 if (!pttc->b_viz)
continue;
6920 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6923 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6924 if (g_bTrackActive) {
6925 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6932bool MyFrame::CheckAndAddPlugInTool() {
6940 if (!tb)
return false;
6942 int n_tools = tb->GetToolsCount();
6946 ArrayOfPlugInToolbarTools tool_array =
6949 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6951 if (pttc->position == n_tools) {
6952 wxBitmap *ptool_bmp;
6954 switch (global_color_scheme) {
6955 case GLOBAL_COLOR_SCHEME_DAY:
6956 ptool_bmp = pttc->bitmap_day;
6959 case GLOBAL_COLOR_SCHEME_DUSK:
6960 ptool_bmp = pttc->bitmap_dusk;
6962 case GLOBAL_COLOR_SCHEME_NIGHT:
6963 ptool_bmp = pttc->bitmap_night;
6966 ptool_bmp = pttc->bitmap_day;
6971 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6973 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6974 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6975 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6976 tic->m_bPlugin =
true;
6985 while (CheckAndAddPlugInTool()) {
6991bool MyFrame::AddDefaultPositionPlugInTools() {
6998 ArrayOfPlugInToolbarTools tool_array =
7001 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7005 if (!pttc->b_viz)
continue;
7007 if (pttc->position == -1)
7009 wxBitmap *ptool_bmp;
7011 switch (global_color_scheme) {
7012 case GLOBAL_COLOR_SCHEME_DAY:
7013 ptool_bmp = pttc->bitmap_day;
7015 case GLOBAL_COLOR_SCHEME_DUSK:
7016 ptool_bmp = pttc->bitmap_dusk;
7018 case GLOBAL_COLOR_SCHEME_NIGHT:
7019 ptool_bmp = pttc->bitmap_night;
7022 ptool_bmp = pttc->bitmap_day;
7027 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7029 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7030 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7031 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7032 tic->m_bPlugin =
true;
7051typedef struct _MSW_COLOR_SPEC {
7053 wxString S52_RGB_COLOR;
7057MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7058 {COLOR_MENUTEXT,
"UITX1", 0},
7059 {COLOR_BTNSHADOW,
"UIBCK", 0},
7062void SaveSystemColors() {
7076 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7077 while (pcspec->COLOR_NAME != -1) {
7078 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7083void RestoreSystemColors() {
7084 int element[NCOLORS];
7085 int rgbcolor[NCOLORS];
7088 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7089 while (pcspec->COLOR_NAME != -1) {
7090 element[i] = pcspec->COLOR_NAME;
7091 rgbcolor[i] = pcspec->SysRGB_COLOR;
7096 if (pSetSysColors) {
7097 pSetSysColors(i, (
unsigned long *)&element[0],
7098 (
unsigned long *)&rgbcolor[0]);
7104void SetSystemColors(ColorScheme cs) {
7106 int element[NCOLORS];
7107 int rgbcolor[NCOLORS];
7109 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7110 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7111 while (pcspec->COLOR_NAME != -1) {
7112 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7113 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7114 element[i] = pcspec->COLOR_NAME;
7120 pSetSysColors(i, (
unsigned long *)&element[0],
7121 (
unsigned long *)&rgbcolor[0]);
7125 RestoreSystemColors();
7132static const WORD MAX_CONSOLE_LINES =
7137void RedirectIOToConsole()
7142 wxIntPtr lStdHandle;
7144 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7154 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7155 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7156 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7160 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7161 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7162 fp = _fdopen(hConHandle,
"w");
7164 setvbuf(stdout, NULL, _IONBF, 0);
7168 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7169 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7170 fp = _fdopen(hConHandle,
"r");
7172 setvbuf(stdin, NULL, _IONBF, 0);
7176 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7177 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7178 fp = _fdopen(hConHandle,
"w");
7180 setvbuf(stderr, NULL, _IONBF, 0);
7191 FontMgr::Get().SetLocale(g_locale);
7212 if (g_pais_query_dialog_active) {
7213 g_pais_query_dialog_active->Destroy();
7214 g_pais_query_dialog_active = NULL;
7217 auto alert_dlg_active =
7219 if (alert_dlg_active) {
7220 alert_dlg_active->Destroy();
7221 g_pais_alert_dialog_active =
nullptr;
7224 if (g_pAISTargetList) {
7226 g_pAISTargetList->Disconnect_decoder();
7227 g_pAISTargetList->Destroy();
7228 g_pAISTargetList = NULL;
7232 if (gFrame->m_pMenuBar) {
7233 gFrame->SetMenuBar(NULL);
7234 gFrame->m_pMenuBar->Destroy();
7235 gFrame->m_pMenuBar = NULL;
7237 gFrame->BuildMenuBar();
7240 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7242 if (cc) cc->CanvasApplyLocale();
7247 wxString perspective;
7249 pConfig->Read(
"AUIPerspective", &perspective);
7263 bool bno_load =
false;
7264 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7266 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7267 wxAuiPaneInfo pane = pane_array_val[i];
7268 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7274 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7279 gFrame->RequestNewToolbars(
true);
7280 gFrame->RequestNewMasterToolbar(
true);
7287 : wxThread(wxTHREAD_JOINABLE) {
7288 m_filename = filename;
7299 newChart->SetNativeScale(m_scale);
7300 newChart->SetFullExtent(m_ext);
7302 newChart->FindOrCreateSenc(m_filename);
7307 wxString m_filename;
7313static double chart_dist(
int index) {
7319 if (cte.GetBBox().Contains(
gLat,
gLon))
7324 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7325 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7326 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7329 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7330 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7332 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7338WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7339static int CompareInts(
int n1,
int n2) {
7340 double d1 = chart_dist(n1);
7341 double d2 = chart_dist(n2);
7342 return (
int)(d1 - d2);
7347 wxString chart_path;
7352WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7354#include <wx/arrimpl.cpp>
7357void ParseAllENC(wxWindow *parent) {
7358 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7366 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7369 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7371 idx_sorted_by_distance.Add(i);
7375 if (count == 0)
return;
7377 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7383 ArrayOfCompressTargets ct_array;
7384 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7385 int i = idx_sorted_by_distance[j];
7388 double distance = chart_dist(i);
7390 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7393 pct->distance = distance;
7394 pct->chart_path = filename;
7396 ct_array.push_back(pct);
7399 int thread_count = 0;
7402 if (g_nCPUCount > 0)
7403 thread_count = g_nCPUCount;
7405 thread_count = wxThread::GetCPUCount();
7407 if (thread_count < 1) {
7416 for(
int t = 0; t < thread_count; t++)
7420 wxGenericProgressDialog *prog =
nullptr;
7424 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7425 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7427 prog =
new wxGenericProgressDialog();
7429 prog->SetFont(*qFont);
7431 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7432 count + 1, parent, style);
7441 prog->ShowWindowModal();
7450 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7451 wxString filename = ct_array[j].chart_path;
7452 double distance = ct_array[j].distance;
7453 int index =
ChartData->FinddbIndex(filename);
7454 if (index < 0)
continue;
7457 ext.NLAT = cte.GetLatMax();
7458 ext.SLAT = cte.GetLatMin();
7459 ext.WLON = cte.GetLonMin();
7460 ext.ELON = cte.GetLonMax();
7462 int scale = cte.GetScale();
7465 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7468 if (wxThread::IsMain()) {
7470 wxSize sz = prog->GetSize();
7475 prog->Update(count, msg, &skip);
7487 newChart->SetNativeScale(
scale);
7488 newChart->SetFullExtent(ext);
7489 newChart->DisableBackgroundSENC();
7491 newChart->FindOrCreateSenc(filename,
7495 if (wxThread::IsMain()) {
7496 msg.Printf(_(
"ENC Completed."));
7498 prog->Update(count, msg, &skip);
7508 for (
int t = 0;; t = (t + 1) % thread_count) {
7515 if (!workers[t]->IsAlive()) {
7528#if defined(__WXMSW__) || defined(__WXOSX__)
7535 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.