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);
1236 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1238 .CaptionVisible(
false)
1240 .CloseButton(
false);
1241 g_pauimgr->GetPane(cc).RightDockable(
true);
1245 config_array.Item(1)->canvasSize =
1246 wxSize(GetClientSize().x / 2, GetClientSize().y);
1247 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1252 if (b_useStoredSize) {
1253 int ccw = config_array.Item(1)->canvasSize.x;
1254 int cch = config_array.Item(1)->canvasSize.y;
1257 if (ccw < GetClientSize().x / 10) {
1258 ccw = GetClientSize().x / 2;
1259 cch = GetClientSize().y;
1262 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1263 cc->SetSize(ccw, cch);
1281 console->SetColorScheme(global_color_scheme);
1286 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1292void MyFrame::RequestNewToolbars(
bool bforcenew) {
1293 if (b_inCloseWindow) {
1297 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1298 PositionIENCToolbar();
1307void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1313void MyFrame::SetAllToolbarScale() {
1314 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1317void MyFrame::SetGPSCompassScale() {
1318 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1322 wxPoint screenPoint = ::wxGetMousePosition();
1325 switch (g_canvasConfig) {
1327 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1330 if (canvas->GetScreenRect().Contains(
1334 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1337 if (canvas->GetScreenRect().Contains(
1344 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1347 if (canvas->GetScreenRect().Contains(
1348 canvas->ScreenToClient(screenPoint)))
1356int MyFrame::GetCanvasIndexUnderMouse() {
1357 wxPoint screenPoint = ::wxGetMousePosition();
1360 switch (g_canvasConfig) {
1362 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1365 if (canvas->GetScreenRect().Contains(
1369 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1372 if (canvas->GetScreenRect().Contains(
1379 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1382 if (canvas->GetScreenRect().Contains(
1383 canvas->ScreenToClient(screenPoint)))
1391bool MyFrame::DropMarker(
bool atOwnShip) {
1398 if (!canvas)
return false;
1405 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1407 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1409 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1420 RefreshAllCanvas(
false);
1425void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1426 if (g_canvasConfig != 0) {
1429 int nTargetGTK = -1;
1431 wxWindow *source = FindFocus();
1437 switch (g_canvasConfig) {
1439 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1442 if (canvas && (canvas == test)) {
1447 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1450 if (canvas && (canvas == test)) {
1458 int nfinalTarget = nTarget;
1460 nfinalTarget = nTargetGTK;
1462 target = ConfigMgr::Get()
1463 .GetCanvasConfigArray()
1468 target->Refresh(
true);
1479void MyFrame::FastClose() {
1481 FrameTenHzTimer.Stop();
1483 FrameTimer1.Start(1);
1487void MyFrame::OnExit(wxCommandEvent &event) {
1491void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1494 if (b_inCloseWindow) {
1504 if (!g_bDeferredInitDone)
return;
1521 if (bDBUpdateInProgress)
return;
1523 b_inCloseWindow =
true;
1525 ::wxSetCursor(wxCURSOR_WAIT);
1529 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1531 if (cc && cc->IsMeasureActive()) {
1532 cc->CancelMeasureRoute();
1537 SendPreShutdownHookToPlugins();
1541 if (g_pAISTargetList) {
1542 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1543 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1544 g_pauimgr->DetachPane(g_pAISTargetList);
1571 SetCursor(wxCURSOR_WAIT);
1573 RefreshAllCanvas(
true);
1579 RestoreScreenBrightness();
1590 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1591 g_iENCToolbarPosY = tbp_incanvas.y;
1592 g_iENCToolbarPosX = tbp_incanvas.x;
1596 g_bframemax = IsMaximized();
1599 FrameTenHzTimer.Stop();
1601 FrameCOGTimer.Stop();
1615 if (g_bAutoAnchorMark) {
1616 bool watching_anchor =
false;
1624 wxDateTime now = wxDateTime::Now();
1625 wxTimeSpan uptime = now.Subtract(g_start_time);
1627 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1628 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1633 if (g_declutter_anchorage) {
1634 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1635 if (pr->GetName().StartsWith(
"Anchorage")) {
1636 double a =
gLat - pr->m_lat;
1637 double b =
gLon - pr->m_lon;
1638 double l = sqrt((a * a) + (b * b));
1641 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1643 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1644 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1652 wxString name = now.Format();
1653 name.Prepend(_(
"Anchorage created "));
1659 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1668 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1672 NavObj_dB::GetInstance().Close();
1676 pConfig->DeleteGroup(
"/Routes");
1677 pConfig->DeleteGroup(
"/Marks");
1703 if (g_pAISTargetList) {
1704 g_pAISTargetList->Disconnect_decoder();
1705 g_pAISTargetList->Destroy();
1712 if (RouteManagerDialog::getInstanceFlag()) {
1729 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1731 if (cc) cc->Destroy();
1755 CommBridge::GetInstance().SaveConfig();
1775 auto ®istry = CommDriverRegistry::GetInstance();
1776 registry.CloseAllDrivers();
1779 for (
auto *cp : TheConnectionParams()) {
1784 while (pLayerList->size())
delete *pLayerList->begin();
1788 ReleaseApiListeners();
1791 g_bTempShowMenuBar =
false;
1793#define THREAD_WAIT_SECONDS 5
1803 wxLogMessage(
"Starting compressor pool drain");
1804 wxDateTime now = wxDateTime::Now();
1805 time_t stall = now.GetTicks();
1806 time_t end = stall + THREAD_WAIT_SECONDS;
1809 while (stall < end) {
1810 wxDateTime later = wxDateTime::Now();
1811 stall = later.GetTicks();
1814 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1823 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1829 uninitIXNetSystem();
1833 wxLogMessage(
"gFrame destroyed.");
1836#ifndef USE_ANDROID_GLES2
1837 qDebug() <<
"Calling OnExit()";
1841 wxTheApp->ExitMainLoop();
1844void MyFrame::OnMove(wxMoveEvent &event) {
1845 auto idx = wxDisplay::GetFromWindow(
this);
1858 DEBUG_LOG <<
"Moved to " << idx
1859#if wxCHECK_VERSION(3, 1, 6)
1860 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1861 << wxDisplay(idx).GetPPI().GetY()
1862 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1864 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1865 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1866 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1867 << wxGetDisplaySizeMM().GetY()
1868 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1877 if (g_config_display_size_manual) {
1886 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1889 cc->SetMUIBarPosition();
1898 UpdateGPSCompassStatusBoxes();
1908 PositionIENCToolbar();
1914 g_nframewin_posx = GetPosition().x;
1915 g_nframewin_posy = GetPosition().y;
1918void MyFrame::ProcessCanvasResize() {
1919 UpdateGPSCompassStatusBoxes(
true);
1923 PositionIENCToolbar();
1926 TriggerRecaptureTimer();
1930void MyFrame::TriggerRecaptureTimer() {
1931 m_recaptureTimer.Start(
1932 1000, wxTIMER_ONE_SHOT);
1935void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1937void MyFrame::SetCanvasSizes(wxSize frameSize) {
1941 int cccw = frameSize.x;
1942 int ccch = frameSize.y;
1946 switch (g_canvasConfig) {
1952 cc->GetSize( &cur_width, &cur_height );
1953 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1955 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1957 cc->SetSize( 0, 0, cccw, ccch );
1967 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1968 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1970 ccw = wxMin(ccw, cccw * 8 / 10);
1971 ccw = wxMax(ccw, cccw * 2 / 10);
1975 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1982 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1999void MyFrame::OnIconize(wxIconizeEvent &event) {
2009 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2011 if (cc && cc->GetMUIBar()) {
2012 if (cc->GetMUIBar()->GetCanvasOptions()) {
2013 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2014 cc->GetMUIBar()->PushCanvasOptions();
2023void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2025void MyFrame::ODoSetSize() {
2027 GetClientSize(&x, &y);
2030 if (m_pStatusBar != NULL) {
2031 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2032 int currentCount = m_pStatusBar->GetFieldsCount();
2033 if (currentCount != m_StatusBarFieldCount) {
2034 if ((currentCount > 0) && (currentCount < 7)) {
2037 int widths[] = {2, 2, 2, 2, 2, 2};
2038 m_pStatusBar->SetStatusWidths(currentCount, widths);
2041 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2044 if (m_StatusBarFieldCount) {
2049 if (m_StatusBarFieldCount > 2) {
2050 int widths[] = {-6, -5, -5, -6, -4};
2051 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2052 }
else if (m_StatusBarFieldCount == 2) {
2053 int cwidth = x * 90 / 100;
2054 int widths[] = {100, 100};
2055 widths[0] = cwidth * 6.4 / 10.0;
2056 widths[1] = cwidth * 3.6 / 10.0;
2057 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2059 int widths[] = {100, 100};
2060 widths[0] = x * 90 / 100;
2061 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2064 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2065 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2066 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2068 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2070 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2078 m_pStatusBar->GetFieldRect(0, stat_box);
2081 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2083 wxFont sys_font = *wxNORMAL_FONT;
2084 int try_font_size = sys_font.GetPointSize();
2087 int min_font_size = 10;
2097 wxFont *statusBarFont =
2098 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2099 int font_size = statusBarFont->GetPointSize();
2101 font_size = wxMin(font_size,
2104 wxMax(font_size, min_font_size);
2107 font_size = statusBarFont->GetPointSize();
2114 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2115 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2117 int min_height = stat_box.height;
2119 m_pStatusBar->SetFont(*pstat_font);
2120 m_pStatusBar->SetForegroundColour(
2121 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2123 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2125 (min_height >> 1) * 2;
2126 m_pStatusBar->SetMinHeight(min_height);
2135 SetCanvasSizes(GetClientSize());
2137 UpdateGPSCompassStatusBoxes(
true);
2139 if (
console) PositionConsole();
2142 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2144 if (cc) cc->FormatPianoKeys();
2150 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2151 GetPrimaryCanvas()->GetCompass()->GetRect());
2177 options_lastWindowSize = wxSize(0, 0);
2178 options_lastWindowPos = wxPoint(0, 0);
2185 if (!b_inCloseWindow) {
2188 resizeAndroidPersistents();
2192 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2193 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2199void MyFrame::PositionConsole() {
2200#if defined(__WXMSW__) || defined(__WXMAC__)
2201 if (NULL == GetPrimaryCanvas())
return;
2203 int ccx, ccy, ccsx, ccsy, consx, consy;
2208 consoleHost->GetSize(&ccsx, &ccsy);
2209 consoleHost->GetPosition(&ccx, &ccy);
2211 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2212 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2213 consoleHost = GetPrimaryCanvas();
2218 if (consoleHost->GetCompass()) {
2219 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2221 if (compass_rect.y < 100)
2222 yOffset = compass_rect.y + compass_rect.height + 45;
2226 wxSize csz =
console->GetSize();
2230 wxPoint screen_pos =
2231 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2234 if (NULL == GetPrimaryCanvas())
return;
2236 int ccx, ccy, ccsx, ccsy, consx, consy;
2241 consoleHost->GetSize(&ccsx, &ccsy);
2242 consoleHost->GetPosition(&ccx, &ccy);
2244 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2245 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2246 consoleHost = GetPrimaryCanvas();
2249 int yTopOffset = 60;
2250 int yBottomOffset = 0;
2252 if (consoleHost->GetCompass()) {
2253 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2255 if (compass_rect.y < 100)
2256 yTopOffset = compass_rect.y + compass_rect.height;
2258 if (consoleHost->GetMUIBar()) {
2259 wxRect mui_rect = consoleHost->GetMUIBarRect();
2260 yBottomOffset = ccsy - mui_rect.y;
2264 wxSize csz =
console->GetSize();
2267 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2269 if (consy < yAvail) {
2270 yFinal = (yAvail - consy) / 2;
2271 yFinal += yTopOffset;
2272 }
else if (
console->GetCDI()->IsShown()) {
2273 int cdi_height =
console->GetCDI()->GetSize().y;
2274 int consy_no_cdi = consy - cdi_height;
2275 yFinal = (yAvail - consy_no_cdi) / 2;
2276 yFinal += yTopOffset;
2280 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2285void MyFrame::UpdateAllFonts() {
2294 DestroyPersistentDialogs();
2296 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2301void MyFrame::DestroyPersistentDialogs() {
2302 if (g_pais_query_dialog_active) {
2303 g_pais_query_dialog_active->Hide();
2304 g_pais_query_dialog_active->Destroy();
2305 g_pais_query_dialog_active = NULL;
2333void MyFrame::RefreshGroupIndices() {
2335 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2337 if (cc) cc->canvasRefreshGroupIndex();
2341void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2344 switch (event.GetId()) {
2345 case ID_MENU_SCALE_OUT:
2346 DoStackDelta(GetPrimaryCanvas(), 1);
2350 case ID_MENU_SCALE_IN:
2351 DoStackDelta(GetPrimaryCanvas(), -1);
2355 case ID_MENU_ZOOM_IN: {
2356 if (GetFocusCanvas()) {
2357 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2362 case ID_MENU_ZOOM_OUT: {
2363 if (GetFocusCanvas()) {
2364 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2369 case ID_MENU_ROUTE_NEW: {
2370 if (GetFocusCanvas()) {
2371 if (0 == GetFocusCanvas()->m_routeState) {
2372 GetFocusCanvas()->StartRoute();
2374 GetFocusCanvas()->FinishRoute();
2380 case ID_MENU_TOOL_MEASURE: {
2381 GetPrimaryCanvas()->StartMeasureRoute();
2385 case ID_MENU_TOOL_NMEA_DBG_LOG:
2386 m_data_monitor->Show();
2387 m_data_monitor->Raise();
2390 case ID_MENU_TOOL_IO_MONITOR:
2391 m_data_monitor->Show();
2394 case ID_MENU_MARK_BOAT: {
2399 case ID_MENU_MARK_CURSOR: {
2404 case ID_MENU_NAV_FOLLOW: {
2405 if (
gFrame->GetPrimaryCanvas())
2406 gFrame->GetPrimaryCanvas()->TogglebFollow();
2410 case ID_MENU_CHART_OUTLINES: {
2411 ToggleChartOutlines(GetFocusCanvas());
2415 case ID_MENU_CHART_QUILTING: {
2416 ToggleQuiltMode(GetFocusCanvas());
2420 case ID_MENU_UI_CHARTBAR: {
2421 ToggleChartBar(GetFocusCanvas());
2425 case ID_MENU_ENC_TEXT:
2427 ToggleENCText(GetFocusCanvas());
2430 case ID_MENU_ENC_LIGHTS: {
2431 ToggleLights(GetFocusCanvas());
2434 case ID_MENU_ENC_SOUNDINGS: {
2435 ToggleSoundings(GetFocusCanvas());
2438 case ID_MENU_ENC_ANCHOR: {
2439 ToggleAnchor(GetFocusCanvas());
2442 case ID_MENU_ENC_DATA_QUALITY: {
2443 ToggleDataQuality(GetFocusCanvas());
2446 case ID_MENU_SHOW_NAVOBJECTS: {
2447 ToggleNavobjects(GetFocusCanvas());
2451 case ID_MENU_AIS_TARGETS: {
2452 ToggleAISDisplay(GetFocusCanvas());
2455 case ID_MENU_AIS_MOORED_TARGETS: {
2456 g_bHideMoored = !g_bHideMoored;
2459 case ID_MENU_AIS_SCALED_TARGETS: {
2460 ToggleAISMinimizeTargets(GetFocusCanvas());
2464 case ID_MENU_AIS_TARGETLIST: {
2465 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2469 case ID_MENU_AIS_TRACKS: {
2470 g_bAISShowTracks = !g_bAISShowTracks;
2471 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2475 case ID_MENU_AIS_CPADIALOG: {
2476 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2477 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2478 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2479 if (g_bAIS_CPA_Alert) {
2480 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2485 case ID_MENU_AIS_CPASOUND: {
2486 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2487 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2491 case ID_MENU_AIS_CPAWARNING: {
2492 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2493 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2497 case wxID_PREFERENCES:
2504 case ID_SETTINGS_NEW: {
2509 case ID_SETTINGS_DELETE: {
2512 g_pOptions =
nullptr;
2516 case ID_RELOAD_CHARTS: {
2521 case ID_MENU_SETTINGS_BASIC: {
2523 androidDisableFullScreen();
2525 DoAndroidPreferences();
2532 case ID_MENU_UI_FULLSCREEN: {
2537 case ID_MENU_SHOW_CURRENTS: {
2538 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2539 GetFocusCanvas()->ReloadVP();
2540 GetFocusCanvas()->Refresh(
false);
2544 case ID_MENU_SHOW_TIDES: {
2545 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2546 GetFocusCanvas()->ReloadVP();
2547 GetFocusCanvas()->Refresh(
false);
2567 case ID_MENU_UI_COLSCHEME:
2568 case ID_COLSCHEME: {
2569 ToggleColorScheme();
2578 case ID_MENU_OQUIT: {
2583 case ID_MENU_ROUTE_MANAGER:
2584 case ID_ROUTEMANAGER: {
2607 case ID_MENU_NAV_TRACK:
2609 if (!g_bTrackActive) {
2611 g_bTrackCarryOver =
true;
2614 g_bTrackCarryOver =
false;
2615 RefreshAllCanvas(
true);
2620 case ID_MENU_CHART_NORTHUP: {
2621 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2624 case ID_MENU_CHART_COGUP: {
2625 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2628 case ID_MENU_CHART_HEADUP: {
2629 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2633 case ID_MENU_MARK_MOB:
2639 case ID_MASTERTOGGLE: {
2641 wxString tip = _(
"Show Toolbar");
2642 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2644 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2646 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2649 if (g_bmasterToolbarFull)
2650 m_nMasterToolCountShown =
2654 m_nMasterToolCountShown = 2;
2656 m_nMasterToolCountShown =
2659 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2667 case ID_CMD_SELECT_CHART_TYPE: {
2668 selectChartDisplay(event.GetExtraLong(), -1);
2672 case ID_CMD_SELECT_CHART_FAMILY: {
2673 selectChartDisplay(-1, event.GetExtraLong());
2677 case ID_CMD_APPLY_SETTINGS: {
2678 applySettingsString(event.GetString());
2680 androidRestoreFullScreen();
2686 case ID_CMD_NULL_REFRESH: {
2691 case ID_CMD_SETVP: {
2692 setStringVP(event.GetString());
2696 case ID_CMD_INVALIDATE: {
2702 case ID_CMD_POST_JSON_TO_PLUGINS: {
2708 int numErrors = reader.
Parse(event.GetString(), &root);
2709 if (numErrors == 0) {
2710 if (root[
"MessageID"].IsString()) {
2711 wxString MsgID = root[
"MessageID"].
AsString();
2735 ArrayOfPlugInToolbarTools tool_array =
2737 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2739 if (event.GetId() == pttc->id) {
2740 if (pttc->m_pplugin)
2762bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2763 bool viz_now = g_bmasterToolbarFull;
2766 wxString tip = _(
"Show Toolbar");
2768 tip = _(
"Hide Toolbar");
2770 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2773 bool toggle =
false;
2774 if (viz && !g_bmasterToolbarFull)
2777 else if (!viz && g_bmasterToolbarFull)
2781 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2784 if (g_bmasterToolbarFull)
2785 m_nMasterToolCountShown =
2789 m_nMasterToolCountShown = 2;
2791 m_nMasterToolCountShown =
2794 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2800void MyFrame::ScheduleReloadCharts() {
2801 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2802 evt.SetId(ID_RELOAD_CHARTS);
2803 GetEventHandler()->AddPendingEvent(evt);
2806void MyFrame::ScheduleDeleteSettingsDialog() {
2807 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2808 evt.SetId(ID_SETTINGS_DELETE);
2809 GetEventHandler()->AddPendingEvent(evt);
2812void MyFrame::ScheduleSettingsDialog() {
2813 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2814 evt.SetId(ID_SETTINGS);
2815 GetEventHandler()->AddPendingEvent(evt);
2818void MyFrame::ScheduleSettingsDialogNew() {
2819 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2820 evt.SetId(ID_SETTINGS_NEW);
2821 GetEventHandler()->AddPendingEvent(evt);
2824void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2825 UpdateCanvasConfigDescriptors();
2827 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2828 CreateCanvasLayout(
true);
2830 CreateCanvasLayout();
2834 ConfigureStatusBar();
2835 wxSize lastOptSize = options_lastWindowSize;
2840 options_lastWindowSize = lastOptSize;
2844 ScheduleSettingsDialogNew();
2846 ScheduleSettingsDialog();
2851 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2854 int index_hint = -1;
2855 if (i < pathArray.GetCount())
2856 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2857 cc->canvasChartsRefresh(index_hint);
2858 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2867 return GetPrimaryCanvas();
2870void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2871 if (g_bmasterToolbarFull) {
2872#ifndef OCPN_TOOLBAR_ANIMATE
2873 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2876 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2877 m_nMasterToolCountShown++;
2882 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2890#ifndef OCPN_TOOLBAR_ANIMATE
2891 m_nMasterToolCountShown = 1;
2893 if (m_nMasterToolCountShown > 1) {
2894 m_nMasterToolCountShown--;
2898 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2908void MyFrame::InvalidateAllGL() {
2911 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2921void MyFrame::RefreshAllCanvas(
bool bErase) {
2923 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2926 cc->Refresh(bErase);
2931void MyFrame::setStringVP(wxString VPS) {
2936 wxStringTokenizer tkz(VPS,
";");
2938 wxString token = tkz.GetNextToken();
2940 token.ToDouble(&lat);
2942 token = tkz.GetNextToken();
2944 token.ToDouble(&lon);
2946 token = tkz.GetNextToken();
2948 token.ToDouble(&scale_ppm);
2950 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2953void MyFrame::DoSettingsNew() {
2960void MyFrame::DoSettings() {
2965 ApplyGlobalSettings(
true);
2968 bool b_loadHarmonics =
false;
2969 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2972 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2975 if (b_loadHarmonics) LoadHarmonics();
2983 g_bShowChartBar = !g_bShowChartBar;
2985 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2990 if (g_bShowChartBar) {
2992 UpdateControlBar(cc);
2995 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2998void MyFrame::ToggleColorScheme() {
2999 static bool lastIsNight;
3000 ColorScheme s = user_colors::GetColorScheme();
3003 if (lastIsNight && is == 3)
3006 lastIsNight =
false;
3008 if (lastIsNight) is = 2;
3009 if (is == 3) lastIsNight =
true;
3010 s = (ColorScheme)is;
3011 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3013 SetAndApplyColorScheme(s);
3016void MyFrame::ToggleFullScreen() {
3017 bool to = !IsFullScreen();
3022 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3024 ShowFullScreen(to, style);
3027 UpdateAllToolbars(global_color_scheme);
3029 UpdateControlBar(GetPrimaryCanvas());
3031 TriggerRecaptureTimer();
3034void MyFrame::ActivateMOB() {
3036 wxDateTime mob_time = wxDateTime::Now();
3037 wxString mob_label(_(
"MAN OVERBOARD"));
3038 mob_label += _(
" on ");
3039 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3043 pWP_MOB->SetShared(
true);
3045 pWP_MOB->SetWaypointArrivalRadius(
3047 pWP_MOB->SetUseSca(
false);
3049 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3057 new RoutePoint(zlat, zlon, g_default_wp_icon,
3058 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3059 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3064 temp_route->AddPoint(pWP_src);
3065 temp_route->AddPoint(pWP_MOB);
3067 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3077 temp_route->SetRouteArrivalRadius(-1.0);
3083 v[
"GUID"] = temp_route->
m_GUID;
3084 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3085 SendJSONMessageToAllPlugins(msg_id, v);
3088 if (RouteManagerDialog::getInstanceFlag()) {
3096 RefreshAllCanvas(
false);
3098 wxString mob_message(_(
"MAN OVERBOARD"));
3099 mob_message += _(
" Time: ");
3100 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3101 mob_message += _(
" Position: ");
3102 mob_message += toSDMM(1,
gLat);
3104 mob_message += toSDMM(2,
gLon);
3105 wxLogMessage(mob_message);
3107void MyFrame::TrackOn() {
3108 g_bTrackActive =
true;
3116 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3118 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3120 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3123 androidSetTrackTool(
true);
3126 if (RouteManagerDialog::getInstanceFlag()) {
3135 if (name.IsEmpty()) {
3141 name = _(
"(Unnamed Track)");
3145 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3146 SendJSONMessageToAllPlugins(msg_id, v);
3147 g_FlushNavobjChangesTimeout =
3151Track *MyFrame::TrackOff(
bool do_add_point) {
3156 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3158 SendJSONMessageToAllPlugins(msg_id, v);
3167 if (g_bTrackDaily) {
3172 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3173 return_val = pExtendTrack;
3180 g_bTrackActive =
false;
3182 if (RouteManagerDialog::getInstanceFlag()) {
3189 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3191 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3192 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3195 androidSetTrackTool(
false);
3199 m_target_rotate_time = wxInvalidDateTime;
3204void MyFrame::InitializeTrackRestart() {
3205 if (!g_bTrackDaily)
return;
3206 if (m_target_rotate_time.IsValid())
return;
3209 switch (g_track_rotate_time_type) {
3211 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3213 case TIME_TYPE_COMPUTER:
3214 rotate_at = g_track_rotate_time;
3218 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3219 rotate_at = g_track_rotate_time + utc_offset;
3222 if (rotate_at > 86400)
3224 else if (rotate_at < 0)
3227 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3228 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3231 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3232 m_target_rotate_time += wxTimeSpan(24);
3236bool MyFrame::ShouldRestartTrack() {
3238 InitializeTrackRestart();
3240 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3241 m_target_rotate_time += wxTimeSpan(24);
3247void MyFrame::TrackDailyRestart() {
3249 Track *pPreviousTrack = TrackOff(
true);
3256 if (pPreviousTrack) {
3257 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3261 if (RouteManagerDialog::getInstanceFlag()) {
3269void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3271 cc->SetUpMode(mode);
3273 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3274 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3275 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3278 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3283 cc->SetShowENCText(!cc->GetShowENCText());
3285 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3293void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3296 cc->SetENCDisplayCategory(nset);
3298 UpdateGlobalMenuItems();
3309 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3311 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3320 cc->SetShowENCLights(!cc->GetShowENCLights());
3322 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3332void MyFrame::ToggleRocks(
void )
3338 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3339 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3340 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3341 pOLE->nViz = !pOLE->nViz;
3345 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3346 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3347 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3350 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3354 ps52plib->GenerateStateHash();
3361 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3363 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3371 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3373 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3388 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3389 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3394 cc->SetShowAIS(!cc->GetShowAIS());
3395 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3399void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3400 cc->SetAttenAIS(!cc->GetAttenAIS());
3401 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3407 cc->m_bFollow =
true;
3410 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3414 SetChartUpdatePeriod();
3422 cc->m_bFollow =
false;
3424 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3428 SetChartUpdatePeriod();
3431void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3432 cc->SetShowOutlines(!cc->GetShowOutlines());
3434 RefreshAllCanvas(
false);
3438 if (g_bopengl) InvalidateAllGL();
3441 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3444void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3446void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3448 bool enabled = m_pMenuBar->IsEnabled(item_id);
3449 m_pMenuBar->Enable(item_id,
false);
3450 m_pMenuBar->Check(item_id, state);
3451 m_pMenuBar->Enable(item_id, enabled);
3455void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3462void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3463 wxBitmap *bmpRollover) {
3465 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3470void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3471 wxString rolloverSVGfile,
3472 wxString toggledSVGfile) {
3475 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3479void MyFrame::ConfigureStatusBar() {
3481 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3484 UseNativeStatusBar(
false);
3487 if (g_bShowStatusBar) {
3488 if (!m_pStatusBar) {
3490 CreateStatusBar(m_StatusBarFieldCount, 0);
3491 ApplyGlobalColorSchemetoStatusBar();
3496 m_pStatusBar->Destroy();
3497 m_pStatusBar = NULL;
3503void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3504 ConfigureStatusBar();
3506 wxSize lastOptSize = options_lastWindowSize;
3512 options_lastWindowSize = lastOptSize;
3514 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3517void MyFrame::BuildMenuBar() {
3523 bool showMenuBar =
true;
3525 bool showMenuBar = g_bShowMenuBar;
3537 m_pMenuBar =
new wxMenuBar();
3538 RegisterGlobalMenuItems();
3539 SetMenuBar(m_pMenuBar);
3543 UpdateGlobalMenuItems();
3548 m_pMenuBar->Destroy();
3554void MyFrame::RegisterGlobalMenuItems() {
3555 if (!m_pMenuBar)
return;
3557 wxMenu *nav_menu =
new wxMenu();
3558 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3559 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3560 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3561 nav_menu->AppendSeparator();
3562 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3563 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3564 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3565 nav_menu->AppendSeparator();
3567 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3568 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3570 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3571 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3573 nav_menu->AppendSeparator();
3574 nav_menu->Append(ID_MENU_SCALE_IN,
3575 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3576 nav_menu->Append(ID_MENU_SCALE_OUT,
3577 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3579 nav_menu->AppendSeparator();
3580 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3582 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3584 wxMenu *view_menu =
new wxMenu();
3586 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3587 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3588 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3589 _menuText(_(
"Show Chart Outlines"),
"O"));
3591 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3592 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3593 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3594 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3596 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3597 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3599 view_menu->AppendSeparator();
3601 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3602 _menuText(_(
"Show ENC text"),
"T"));
3603 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3604 _menuText(_(
"Show ENC Lights"),
"L"));
3605 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3606 _menuText(_(
"Show ENC Soundings"),
"S"));
3607 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3608 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3609 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3610 _menuText(_(
"Show ENC Data Quality"),
"U"));
3611 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3612 _menuText(_(
"Show Navobjects"),
"V"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3615 _menuText(_(
"Show ENC text"),
"Alt-T"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3617 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3619 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3621 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3622 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3623 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3624 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3625 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3627 view_menu->AppendSeparator();
3628 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3629 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3630 view_menu->AppendSeparator();
3632 view_menu->Append(ID_MENU_UI_COLSCHEME,
3633 _menuText(_(
"Change Color Scheme"),
"C"));
3635 view_menu->Append(ID_MENU_UI_COLSCHEME,
3636 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3639 view_menu->AppendSeparator();
3641 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3642 _menuText(_(
"Toggle Full Screen"),
"F11"));
3644 m_pMenuBar->Append(view_menu, _(
"&View"));
3646 wxMenu *ais_menu =
new wxMenu();
3647 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3648 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3649 _(
"Attenuate less critical AIS targets"));
3650 ais_menu->AppendSeparator();
3651 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3652 _(
"Hide Moored AIS Targets"));
3653 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3658 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3659 _menuText(_(
"Show CPA Warnings"),
"W"));
3661 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3662 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3665 ais_menu->AppendSeparator();
3666 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3667 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3669 wxMenu *tools_menu =
new wxMenu();
3670 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3671 _menuText(_(
"Data Monitor"),
"E"));
3673 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3674 _menuText(_(
"Measure Distance"),
"M"));
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();
3915 cc->
bFollow = chart->m_bFollow;
3920 int upmode = chart->GetUpMode();
3921 if (upmode == COURSE_UP_MODE)
3923 else if (upmode == HEAD_UP_MODE)
3930void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3931 if (!RBBox.GetValid())
return;
3933 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3934 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3937 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3938 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3946 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3947 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3949 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3950 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3952 cc->GetSize(&ww, &wh);
3954 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3956 ppm = wxMin(ppm, 1.0);
3962void MyFrame::PrepareOptionsClose(
options *settings,
3963 int settings_return_value) {
3965 options_lastPage = settings->lastPage;
3970 if (options_lastPage == 1) options_lastPage = 0;
3972 options_subpage = settings->lastSubPage;
3973 options_lastWindowPos = settings->lastWindowPos;
3974 options_lastWindowSize = settings->lastWindowSize;
3977 androidEnableBackButton(
true);
3978 androidEnableOptionsMenu(
true);
3979 androidRestoreFullScreen();
3980 androidEnableRotation();
3983 EnableSettingsTool(
true);
3986void MyFrame::DoOptionsDialog() {
3987 EnableSettingsTool(
false);
3990 AbstractPlatform::ShowBusySpinner();
3993 pConfig->SetPath(
"/Settings");
3994 pConfig->Read(
"OptionsSizeX", &sx, -1);
3995 pConfig->Read(
"OptionsSizeY", &sy, -1);
3997 wxWindow *optionsParent =
this;
3999 optionsParent = GetPrimaryCanvas();
4002 callbacks.prepare_close = [&](
options *me,
int changes) {
4003 PrepareOptionsClose(me, changes);
4005 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4006 ProcessOptionsDialog(changes, workdir_list);
4009 wxPoint(-1, -1), wxSize(sx, sy));
4011 AbstractPlatform::HideBusySpinner();
4015 g_options->SetInitChartDir(*pInit_Chart_Dir);
4019 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4020 g_options->SetWorkDirListPtr(pWorkDirArray);
4026 prev_locale = g_locale;
4027 g_options->SetInitialPage(options_lastPage, options_subpage);
4030 g_options->lastWindowPos = options_lastWindowPos;
4031 if (options_lastWindowPos != wxPoint(0, 0)) {
4033 g_options->SetSize(options_lastWindowSize);
4037 if (options_lastWindowSize != wxSize(0, 0)) {
4038 g_options->SetSize(options_lastWindowSize);
4043 androidEnableBackButton(
false);
4044 androidEnableOptionsMenu(
false);
4045 androidDisableFullScreen();
4053 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4056 wxString chart_file_name;
4057 if (cc->GetQuiltMode()) {
4058 int dbi = cc->GetQuiltRefChartdbIndex();
4059 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4061 if (cc->m_singleChart)
4062 chart_file_name = cc->m_singleChart->GetFullPath();
4065 pathArray.Add(chart_file_name);
4071 last_canvasConfig = g_canvasConfig;
4074 g_last_ChartScaleFactor = g_ChartScaleFactor;
4080void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4081 bool b_need_refresh =
false;
4084 if ((rr & VISIT_CHARTS) &&
4085 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4087 UpdateChartDatabaseInplace(*pNewDirArray,
4088 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4091 b_need_refresh =
true;
4096 if (rr & STYLE_CHANGED) {
4099 _(
"Please restart OpenCPN to activate language or style changes."),
4100 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4103 bool charts_updating =
4104 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4105 if (!charts_updating) RefreshGroupIndices();
4107 if (rr & TIDES_CHANGED) {
4113 if (rr & S52_CHANGED) {
4114 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4125 g_Platform->GetDisplayDPmm());
4128 double stuffcog = NAN;
4129 double stuffsog = NAN;
4130 if (!std::isnan(
gCog)) stuffcog =
gCog;
4131 if (!std::isnan(
gSog)) stuffsog =
gSog;
4133 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4134 COGFilterTable[i] = stuffcog;
4135 SOGFilterTable[i] = stuffsog;
4138 SetChartUpdatePeriod();
4140 if (rr & GL_CHANGED) {
4144 b_need_refresh =
true;
4147 if (rr & S52_CHANGED) {
4148 b_need_refresh =
true;
4152 if (rr & REBUILD_RASTER_CACHE) {
4154 GetPrimaryCanvas()->Disable();
4156 GetPrimaryCanvas()->Enable();
4161 if (g_config_display_size_manual &&
4169 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4176 int rrt = rr & S52_CHANGED;
4178 (rrt == S52_CHANGED) ||
4179 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4189 ps52plib->SetScaleFactorExp(
4190 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4191 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4195 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4197 if (cc) cc->ApplyGlobalSettings();
4205 if (!charts_updating) {
4206 bool ztc = g_bEnableZoomToCursor;
4207 g_bEnableZoomToCursor =
false;
4209 if (!GetPrimaryCanvas()->IsFrozen())
4211 g_bEnableZoomToCursor = ztc;
4216 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4225 SetGPSCompassScale();
4227 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4230 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4231 if (!charts_updating) cc->UpdateCanvasControlBar();
4234 UpdateGPSCompassStatusBoxes();
4236 SetAllToolbarScale();
4237 RequestNewToolbars();
4239 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4242 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4245 cc->RebuildCursors();
4250 bool b_masterScaleChange =
false;
4251 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4252 b_masterScaleChange =
true;
4254 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4255 RequestNewMasterToolbar(
true);
4257 bool bMuiChange =
false;
4263 if (b_masterScaleChange || bMuiChange) {
4265 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4268 cc->ProcessNewGUIScale();
4274 if (rr & LOCALE_CHANGED) {
4275 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4277 rr |= NEED_NEW_OPTIONS;
4286 g_last_ChartScaleFactor = g_ChartScaleFactor;
4291bool MyFrame::CheckGroup(
int igroup) {
4292 if (igroup == 0)
return true;
4296 if (!pGroup->m_element_array.size())
4299 for (
const auto &elem : pGroup->m_element_array) {
4300 for (
unsigned int ic = 0;
4301 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4302 auto &cte =
ChartData->GetChartTableEntry(ic);
4303 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4305 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4312bool MyFrame::ScrubGroupArray() {
4317 bool b_change =
false;
4318 unsigned int igroup = 0;
4319 while (igroup < g_pGroupArray->GetCount()) {
4320 bool b_chart_in_element =
false;
4323 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4324 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4326 for (
unsigned int ic = 0;
4327 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4328 auto &cte =
ChartData->GetChartTableEntry(ic);
4329 wxString chart_full_path = cte.GetFullSystemPath();
4331 if (chart_full_path.StartsWith(element_root)) {
4332 b_chart_in_element =
true;
4338 if (!b_chart_in_element) {
4339 wxString test_string =
"GSHH";
4340 if (element_root.Upper().Contains(test_string))
4341 b_chart_in_element =
true;
4344 if (!b_chart_in_element)
4346 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4358void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4360 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4362 if (cc && (cc != ccThis)) cc->Refresh();
4367void MyFrame::ChartsRefresh() {
4370 AbstractPlatform::ShowBusySpinner();
4372 bool b_run = FrameTimer1.IsRunning();
4375 FrameTenHzTimer.Stop();
4378 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4381 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4382 if (cc->GetQuiltMode()) {
4383 currentIndex = cc->GetQuiltReferenceChartIndex();
4385 cc->canvasChartsRefresh(currentIndex);
4389 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4390 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4392 AbstractPlatform::HideBusySpinner();
4395void MyFrame::InvalidateAllQuilts() {
4396 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4399 cc->InvalidateQuilt();
4400 cc->SetQuiltRefChart(-1);
4401 cc->m_singleChart = NULL;
4406bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4408 const wxString &ChartListFileName) {
4409 bool b_run = FrameTimer1.IsRunning();
4411 FrameTenHzTimer.Stop();
4413 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4414 FrameCOGTimer.Stop();
4417 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4420 cc->InvalidateQuilt();
4421 cc->SetQuiltRefChart(-1);
4422 cc->m_singleChart = NULL;
4432 AbstractPlatform::ShowBusySpinner();
4435 wxString longmsg = _(
"OpenCPN Chart Update");
4437 ".................................................................."
4440 Updateprog =
new wxGenericProgressDialog();
4443 Updateprog->SetFont(*qFont);
4445 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4446 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4447 wxPD_REMAINING_TIME);
4449 DimeControl(Updateprog);
4454 wxLogMessage(
"Starting chart database Update...");
4458 m_gshhg_chart_loc = gWorldMapLocation;
4459 gWorldMapLocation = wxEmptyString;
4463 AbstractPlatform::HideBusySpinner();
4467void MyFrame::FinalizeChartDBUpdate() {
4469 if (!g_bDeferredInitDone) {
4471 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4474 bool b_groupchange = ScrubGroupArray();
4476 RefreshGroupIndices();
4478 if (b_groupchange) {
4479 pConfig->DestroyConfigGroups();
4484 if (g_bDeferredInitDone) ScheduleReloadCharts();
4489 cc->ToggleCanvasQuiltMode();
4491 bool cur_mode = cc->GetQuiltMode();
4493 if( !cc->GetQuiltMode() )
4494 cc->SetQuiltMode(
true );
4496 if( cc->GetQuiltMode() ) {
4497 cc->SetQuiltMode(
false );
4498 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4502 if( cur_mode != cc->GetQuiltMode() ){
4508 g_bQuiltEnable = cc->GetQuiltMode();
4512 ps52plib->GenerateStateHash();
4520 DoStackDelta(cc, -1);
4526 DoStackDelta(cc, 1);
4529void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4531void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4533void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4535 cc->DoCanvasStackDelta(direction);
4539void MyFrame::PositionIENCToolbar() {
4543 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4545 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4553void MyFrame::OnInitTimer(wxTimerEvent &event) {
4556 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4560 wxLog::FlushActive();
4562 switch (m_iInitCount++) {
4564 EnableSettingsTool(
false);
4569 if (g_bInlandEcdis) {
4570 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4571 double range_set = 500.;
4573 range = wxRound(range * 10) / 10.;
4577 else if (range > 2000.)
4579 else if (range > 1600.)
4581 else if (range > 1200.)
4583 else if (range > 800.)
4588 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4592 g_Platform->SetFullscreen(g_bFullscreen);
4596 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4599 cc->SetGroupIndex(0,
false);
4606 StartRebuildChartDatabase();
4617 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4631 3 * GetCharHeight());
4633 m_data_monitor->Center();
4641 pConfig->SetPath(
"/Settings");
4642 pConfig->Read(
"OptionsSizeX", &sx, -1);
4643 pConfig->Read(
"OptionsSizeY", &sy, -1);
4645 wxWindow *optionsParent =
this;
4647 optionsParent = GetPrimaryCanvas();
4649 BuildiENCToolbar(
true, m_toolbar_callbacks);
4656 if (!g_params.empty()) {
4657 for (
size_t n = 0; n < g_params.size(); n++) {
4658 wxString path = g_params[n];
4659 if (::wxFileExists(path)) {
4661 pSet->load_file(path.fn_str());
4664 pSet->LoadAllGPXObjects(
4665 !pSet->IsOpenCPN(), wpt_dups,
4667 LLBBox box = pSet->GetBBox();
4668 if (box.GetValid()) {
4669 CenterView(GetPrimaryCanvas(), box);
4678 InitAppMsgBusListener();
4683 auto loader = PluginLoader::GetInstance();
4684 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4685 if (!b_haveWMM)
gVar = g_UserVar;
4693 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4696 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4698 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4701 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4705 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4706 NavObj_dB::GetInstance().LoadNavObjects();
4709 if (!g_AW1GUID.IsEmpty()) {
4712 if (!g_AW2GUID.IsEmpty()) {
4718 appendOSDirSlash(&layerdir);
4719 layerdir.Append(
"layers");
4721 if (wxDir::Exists(layerdir)) {
4723 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4724 wxLogMessage(laymsg);
4725 pConfig->LoadLayers(layerdir);
4730 if (!g_kiosk_startup) {
4731 AbstractPlatform::ShowBusySpinner();
4734 pConfig->SetPath(
"/Settings");
4735 pConfig->Read(
"OptionsSizeX", &sx, -1);
4736 pConfig->Read(
"OptionsSizeY", &sy, -1);
4738 wxWindow *optionsParent =
this;
4740 optionsParent = GetPrimaryCanvas();
4743 callbacks.prepare_close = [&](
options *me,
int changes) {
4744 PrepareOptionsClose(me, changes);
4746 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4747 ProcessOptionsDialog(changes, workdir_list);
4750 wxPoint(-1, -1), wxSize(sx, sy));
4751 AbstractPlatform::HideBusySpinner();
4758 wxLogMessage(
"OnInitTimer...Last Call");
4762 RequestNewMasterToolbar();
4764 PositionIENCToolbar();
4766 g_bDeferredInitDone =
true;
4776 GetPrimaryCanvas()->SetFocus();
4777 GetPrimaryCanvas()->Enable();
4780 if (b_reloadForPlugins) {
4786 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4788 if (cc) cc->SetFirstAuto(
true);
4796 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4798 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4802 cc->CheckGroupValid();
4807 androidEnableBackButton(
true);
4808 androidEnableRotation();
4809 androidEnableOptionItems(
true);
4813 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4819 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4821 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4823 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4829 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4831 wxLog::FlushActive();
4833 RefreshAllCanvas(
true);
4834 UsbWatchDaemon::GetInstance().Start();
4835 EnableSettingsTool(
true);
4841void MyFrame::InitAppMsgBusListener() {
4842 auto &msgbus = AppMsgBus::GetInstance();
4845 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4846 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4850 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4851 HandleBasicNavMsg(basicnav_msg);
4855 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4856 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4860 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4861 HandleGPSWatchdogMsg(msg);
4868void MyFrame::ReleaseApiListeners() {}
4873 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4874 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4875 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4876 server.open_file_cb = [&](
const std::string &path) {
4877 return m_open_gpx_file(path);
4884void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4885 if (msg->gps_watchdog <= 0) {
4886 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4890 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4895 if (m_fix_start_time.IsValid()) {
4896 wxDateTime now = wxDateTime::Now();
4897 wxTimeSpan span = now - m_fix_start_time;
4898 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4899 auto ¬eman = NotificationManager::GetInstance();
4900 wxString msg = _(
"GNSS Position fix lost");
4901 noteman.AddNotification(NotificationSeverity::kCritical,
4903 m_fix_start_time = wxInvalidDateTime;
4907 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4908 bool last_bVelocityValid = bVelocityValid;
4909 bVelocityValid =
false;
4916void MyFrame::CalculateCOGAverage() {
4918 if (!std::isnan(
gCog)) {
4921 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4924 double sum = 0., count = 0;
4926 double adder = COGTable[i];
4927 if (std::isnan(adder))
continue;
4929 if (fabs(adder -
g_COGAvg) > 180.) {
4943 else if (sum >= 360.)
4952void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4953 m_fixtime = msg->time;
4954 double hdt_data_interval = 0;
4955 double fix_time_interval = 0;
4957 double msgtime = msg->set_time.tv_sec;
4958 double m1 = msg->set_time.tv_nsec / 1e9;
4961 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4962 ((msg->vflag & POS_VALID) == POS_VALID)) {
4964 if (!m_fix_start_time.IsValid()) {
4965 m_fix_start_time = wxDateTime::Now();
4970 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4973 fix_time_gt_last = fix_time_gt;
4974 uint64_t fix_time_gt_now =
4975 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4976 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4980 double implied_sog = dist / (fix_time_interval / 3600);
4985 gLat_gt_m1 = gLat_gt;
4986 gLon_gt_m1 = gLon_gt;
4990 fix_time_gt = fix_time_gt_now;
4994 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
4995 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
4996 gCog_gt_m1 = gCog_gt;
5006 if (!std::isnan(gCog_gt_m1)) {
5008 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5015 if ((fix_time_gt - fix_time_gt_last) > .08) {
5020 if (gCog_gt > gCog_gt_m1) {
5021 if ((gCog_gt - gCog_gt_m1) > 180.)
5026 if ((gCog_gt_m1 - gCog_gt) > 180.)
5031 difft = fabs(gCog_gt - gCog_gt_m1);
5032 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5040 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5041 tentative_cog_rate_gt *= 1e9;
5042 cog_rate_gt = tentative_cog_rate_gt;
5050 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5053static double hdt_avg;
5054 double hdt_norm =
gHdt;
5055 if(
gHdt > 180) hdt_norm -= 360;
5058 hdt_avg += hdt_norm * 0.1;
5063 if (!std::isnan(
gHdt)) {
5065 uint64_t hdt_time_gt_last = hdt_time_gt;
5066 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5067 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5070 if (hdt_data_interval > .09) {
5072 gHdt_gt_m1 = gHdt_gt;
5075 if (!std::isnan(gHdt_gt_m1)) {
5077 double tentative_hdt_rate_gt =
5078 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5079 tentative_hdt_rate_gt *= 1e9;
5081 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5082 hdt_rate_gt = tentative_hdt_rate_gt;
5090 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5093 CalculateCOGAverage();
5101 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5102 if ((msg->vflag & POS_VALID) == POS_VALID)
5107 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5109 bVelocityValid =
true;
5113void MyFrame::UpdateStatusBar() {
5116 unsigned long uiCurrentTickCount;
5117 m_MMEAeventTime.SetToCurrent();
5118 uiCurrentTickCount =
5119 m_MMEAeventTime.GetMillisecond() / 100;
5120 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5121 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5122 m_ulLastNMEATicktime = uiCurrentTickCount;
5124 if (m_tick_idx++ > 6) m_tick_idx = 0;
5129 if (NULL != GetStatusBar()) {
5132 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5135 wxString s1(tick_buf, wxConvUTF8);
5137 s1 += toSDMM(1,
gLat);
5139 s1 += toSDMM(2,
gLon);
5141 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5145 if (!std::isnan(
gSog))
5146 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5148 sogcog.Printf(
"SOG --- ");
5152 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5154 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5156 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5157 (
int)toMagnetic(
gCog), 0x00B0);
5159 cogs.Printf((
"COG ---%c"), 0x00B0);
5161 sogcog.Append(cogs);
5162 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5167void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5168 MemFootTimer.Stop();
5170 int memsize = GetApplicationMemoryUse();
5173 printf(
"Memsize: %d \n", memsize);
5176 if (memsize > (g_MemFootMB * 1000)) {
5180 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5181 unsigned int nCache = pCache->GetCount();
5184 for (
unsigned int i = 0; i < nCache; i++) {
5194 for (
unsigned int i = 0; i < nCache - 1; i++) {
5195 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5197 pcea[i] = pcea[i + 1];
5208 unsigned int idelete = 0;
5209 unsigned int idelete_max = pCache->GetCount();
5212 unsigned int minimum_cache = 1;
5213 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5215 while ((memsize > (g_MemFootMB * 1000)) &&
5216 (pCache->GetCount() > minimum_cache) &&
5217 (idelete < idelete_max)) {
5218 int memsizeb = memsize;
5222 memsize = GetApplicationMemoryUse();
5223 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5231 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5236void MyFrame::CheckToolbarPosition() {
5239 static bool bMaximized;
5241 if (IsMaximized() && !bMaximized) {
5248 PositionIENCToolbar();
5249 }
else if (!IsMaximized() && bMaximized) {
5257 PositionIENCToolbar();
5262void MyFrame::ProcessUnitTest() {
5263 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5270 cc->m_bFollow =
false;
5272 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5273 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5276 if (cc->m_groupIndex > 0) {
5277 while (ut_index < ChartData->GetChartTableEntries() &&
5278 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5282 if (ut_index < ChartData->GetChartTableEntries()) {
5286 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5287 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5294 if (cc->GetQuiltMode()) {
5295 if (cc->IsChartQuiltableRef(ut_index))
5296 cc->SelectQuiltRefdbChart(ut_index);
5298 cc->SelectdbChart(ut_index);
5301 if (g_unit_test_1) {
5309 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5310 cte->GetLatMin(), cte->GetLonMax(), NULL,
5314 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5315 cte->GetLatMax(), cte->GetLonMin(), NULL,
5318 cc->GetSize(&ww, &wh);
5319 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5321 ppm = wxMin(ppm, 1.0);
5328 if (ut_index > ut_index_max) exit(0);
5339 bool b_rotate =
false;
5341 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5344 if (!b_rotate && !g_btenhertz)
return;
5346 bool b_update =
false;
5348 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5351 struct timespec now;
5352 clock_gettime(CLOCK_MONOTONIC, &now);
5353 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5354 double diffc = diff / 1e9;
5357 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5358 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5359 if (gCog_tentative < 0.) gCog_tentative += 360.;
5360 gCog = gCog_tentative;
5364 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5365 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5366 double diffc = diff / 1e9;
5367 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5371 if (gSog_gt && !std::isnan(gCog_gt)) {
5372 double delta_t = diffc / 3600;
5373 double distance = gSog_gt * delta_t;
5376 double angr = gCog_gt / 180 * M_PI;
5377 double latr = gLat_gt * M_PI / 180;
5378 double D = distance / 3443;
5379 double sD = sin(D), cD = cos(D);
5380 double sy = sin(latr), cy = cos(latr);
5381 double sa = sin(angr), ca = cos(angr);
5383 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5384 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5394 if (cc) cc->DoCanvasCOGSet();
5403 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5404 bool bnew = cc->DoCanvasUpdate();
5405 if (!bnew) cc->UpdateShips();
5414 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5417bool MyFrame::ProcessQuitFlag() {
5421 FrameTenHzTimer.Stop();
5423 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5424 if (top) top->Close(
true);
5431void MyFrame::ProcessDeferredTrackOn() {
5434 if (g_bDeferredStartTrack) {
5435 if (!g_bTrackActive) {
5438 g_bDeferredStartTrack =
false;
5441 g_bDeferredStartTrack =
false;
5446void MyFrame::ProcessAnchorWatch() {
5454 double d = g_nAWMax;
5457 bool toofar =
false;
5458 bool tooclose =
false;
5459 if (d >= 0.0) toofar = (dist * 1852. > d);
5460 if (d < 0.0) tooclose = (dist * 1852 < -d);
5462 if (tooclose || toofar)
5463 AnchorAlertOn1 =
true;
5465 AnchorAlertOn1 =
false;
5467 AnchorAlertOn1 =
false;
5475 double d = g_nAWMax;
5478 bool toofar =
false;
5479 bool tooclose =
false;
5480 if (d >= 0) toofar = (dist * 1852. > d);
5481 if (d < 0) tooclose = (dist * 1852 < -d);
5483 if (tooclose || toofar)
5484 AnchorAlertOn2 =
true;
5486 AnchorAlertOn2 =
false;
5488 AnchorAlertOn2 =
false;
5491 AnchorAlertOn1 =
true;
5494void MyFrame::SendFixToPlugins() {
5505 GPSData.
nSats = g_SatsInView;
5507 wxDateTime tCheck((time_t)m_fixtime);
5508 if (tCheck.IsValid()) {
5517 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5520 SendPositionFixToAllPlugIns(&GPSData);
5524void MyFrame::ProcessLogAndBells() {
5527 wxDateTime lognow = wxDateTime::Now();
5528 int hourLOC = lognow.GetHour();
5529 int minuteLOC = lognow.GetMinute();
5531 int minuteUTC = lognow.GetMinute();
5532 int second = lognow.GetSecond();
5534 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5535 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5536 (minuteUTC == 30)) {
5537 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5538 wxString day = lognow.FormatISODate();
5539 wxString utc = lognow.FormatISOTime();
5540 wxString navmsg =
"LOGBOOK: ";
5548 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5552 if (std::isnan(
gCog))
5553 cog.Printf(
"COG ----- ");
5555 cog.Printf(
"COG %10.5f ",
gCog);
5558 if (std::isnan(
gSog))
5559 sog.Printf(
"SOG ----- ");
5561 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5567 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5570 wxLogMessage(navmsg);
5571 g_loglast_time = lognow;
5573 int bells = (hourLOC % 4) * 2;
5574 if (minuteLOC != 0) bells++;
5575 if (!bells) bells = 8;
5577 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5578 m_BellsToPlay = bells;
5579 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5580 wxPostEvent(
this, ev);
5587 CheckToolbarPosition();
5591 if (ProcessQuitFlag())
return;
5593 if (bDBUpdateInProgress)
return;
5596 FrameTenHzTimer.Stop();
5598 ProcessDeferredTrackOn();
5600 ProcessAnchorWatch();
5601 ProcessLogAndBells();
5603 if (ShouldRestartTrack()) TrackDailyRestart();
5606 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5607 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5608 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5614 if (
gSog > 3.0) g_bCruising =
true;
5620 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5622 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5628 bool bnew_view =
false;
5629 if (!g_btenhertz) bnew_view = DoChartUpdate();
5636 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5639 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5642 cc->DrawBlinkObjects();
5645 if (bactiveRouteUpdate) {
5652 cc->SetOwnShipState(SHIP_NORMAL);
5654 if (cc->GetQuiltMode()) {
5655 double erf = cc->GetQuiltMaxErrorFactor();
5656 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5658 if (cc->m_singleChart) {
5659 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5660 cc->SetOwnShipState(SHIP_LOWACCURACY);
5664 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5667 (bVelocityValid != m_last_bVelocityValid) ||
5668 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5669 if (!g_bopengl) cc->UpdateShips();
5677 m_last_bVelocityValid = bVelocityValid;
5682 bool brq_dynamic =
false;
5684 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5685 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5687 if (pic->m_enabled && pic->m_init_state) {
5688 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5695 if (brq_dynamic) bnew_view =
true;
5699 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5702 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5707 if (cc->GetglCanvas()) {
5709 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5711 if ((!g_btenhertz)) {
5712 if (cc->m_bFollow) {
5713 cc->DoCanvasUpdate();
5730 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5744 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5745 g_pais_query_dialog_active->UpdateText();
5748 if (g_pAISTargetList && (0 == (g_tick % (5))))
5749 g_pAISTargetList->UpdateAISTargetList();
5752 UpdateGPSCompassStatusBoxes();
5757 console->RefreshConsoleData();
5764 if (m_bdefer_resize) {
5765 if (0 == (g_tick % (5))) {
5766 printf(
"___RESIZE\n");
5767 SetSize(m_defer_size);
5769 m_bdefer_resize =
false;
5776 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5778 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5779 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5783double MyFrame::GetMag(
double a,
double lat,
double lon) {
5784 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5785 auto loader = PluginLoader::GetInstance();
5786 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5793 wxDateTime now = wxDateTime::Now();
5794 SendJSON_WMM_Var_Request(lat, lon, now);
5795 if (fabs(gQueryVar) < 360.0)
5796 Variance = gQueryVar;
5798 return toMagnetic(a, Variance);
5801bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5807 v[
"Year"] = date.GetYear();
5808 v[
"Month"] = date.GetMonth();
5809 v[
"Day"] = date.GetDay();
5811 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5817void MyFrame::TouchAISActive() {
5819 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5821 if (cc) cc->TouchAISToolActive();
5825void MyFrame::UpdateAISTool() {
5829 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5831 if (cc) cc->UpdateAISTBTool();
5836void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5838 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5840 if (cc) cc->SetbTCUpdate(
true);
5843 RefreshAllCanvas(
false);
5848void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5852 bool b_rotate =
false;
5853 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5855 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5859 FrameCOGTimer.Stop();
5866 int period_ms = 100;
5868 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5871void MyFrame::DoCOGSet() {
5873 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5875 if (cc) cc->DoCanvasCOGSet();
5879void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5885 wxFont oldfont = pdc->GetFont();
5887 pdc->SetFont(*pFont);
5888 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5889 pdc->SetBackgroundMode(wxTRANSPARENT);
5891 pdc->DrawText(str, x, y + 1);
5892 pdc->DrawText(str, x, y - 1);
5893 pdc->DrawText(str, x + 1, y);
5894 pdc->DrawText(str, x - 1, y);
5896 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5898 pdc->DrawText(str, x, y);
5900 pdc->SetFont(oldfont);
5904void MyFrame::UpdateRotationState(
double rotation) {
5906 g_bCourseUp =
false;
5908 if (fabs(rotation) > .001) {
5909 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5910 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5912 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5915 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5916 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5918 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5922 UpdateGPSCompassStatusBoxes(
true);
5926void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5928 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5930 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5936int MyFrame::GetApplicationMemoryUse() {
5942 wxWindow *fWin = wxWindow::FindFocus();
5944 wxArrayString outputArray;
5945 wxString cmd(
"ps --no-headers -o vsize ");
5946 unsigned long pid = wxGetProcessId();
5948 cmd1.Printf(
"%ld", pid);
5950 wxExecute(cmd, outputArray);
5952 if (outputArray.GetCount()) {
5953 wxString s = outputArray.Item(0);
5955 if (s.ToLong(&vtmp)) memsize = vtmp;
5958 if (fWin) fWin->SetFocus();
5964 PROCESS_MEMORY_COUNTERS pmc;
5966 unsigned long processID = wxGetProcessId();
5968 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5970 if (NULL == hProcess)
return 0;
5972 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5990 memsize = pmc.WorkingSetSize / 1024;
5993 CloseHandle(hProcess);
6000double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6001 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6004void MyFrame::SetChartUpdatePeriod() {
6007 g_ChartUpdatePeriod = 0;
6012 bool bskewdc =
false;
6013 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6016 if (!g_bopengl && !cc->GetVP().b_quilt) {
6017 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6019 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6023 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6025 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6030 cc->UpdateCanvasControlBar();
6033void MyFrame::selectChartDisplay(
int type,
int family) {
6035 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6037 if (cc) cc->selectCanvasChartDisplay(type, family);
6040 UpdateGlobalMenuItems();
6049bool MyFrame::DoChartUpdate() {
6050 bool return_val =
false;
6053 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6055 if (cc) return_val |= cc->DoCanvasUpdate();
6061void MyFrame::MouseEvent(wxMouseEvent &event) {
6063 event.GetPosition(&x, &y);
6068#include <mach/mach.h>
6069#include <mach/message.h>
6070#include <mach/kern_return.h>
6071#include <mach/task_info.h>
6073#include <malloc/malloc.h>
6080#if defined(__linux__)
6081#include "sys/types.h"
6082#include "sys/sysinfo.h"
6085void MyFrame::DoPrint(
void) {
6087 g_PrintingInProgress =
true;
6090 GetPrimaryCanvas()->GetglCanvas()->Render();
6091 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6101 printer.Initialize(wxLANDSCAPE);
6102 printer.EnablePageNumbers(
false);
6103 printer.Print(
this, &printout);
6121 g_PrintingInProgress =
false;
6124 GetPrimaryCanvas()->SetFocus();
6130 wxString message_ID =
event.GetID();
6131 wxString message_JSONText =
event.GetJSONText();
6139 if (message_ID ==
"WMM_VARIATION_BOAT") {
6147 int numErrors = reader.
Parse(message_JSONText, &root);
6148 if (numErrors > 0) {
6154 wxString decl = root[
"Decl"].
AsString();
6156 decl.ToDouble(&decl_val);
6162 if (message_ID ==
"WMM_VARIATION") {
6170 int numErrors = reader.
Parse(message_JSONText, &root);
6171 if (numErrors > 0) {
6177 wxString decl = root[
"Decl"].
AsString();
6179 decl.ToDouble(&decl_val);
6181 gQueryVar = decl_val;
6184 if (message_ID ==
"GRIB_TIMELINE") {
6187 int numErrors = r.
Parse(message_JSONText, &v);
6189 if (numErrors > 0) {
6190 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6195 wxDateTime oldTimeSource = gTimeSource;
6197 if (v[
"Day"].AsInt() == -1) {
6198 gTimeSource = wxInvalidDateTime;
6199 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6201 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6202 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6203 v[
"Second"].AsInt());
6207 if (oldTimeSource != gTimeSource) {
6209 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6211 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6216 cc->pCwin->Refresh(
false);
6222 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6225 wxString trk_id = wxEmptyString;
6227 int numErrors = reader.
Parse(message_JSONText, &root);
6228 if (numErrors > 0)
return;
6233 v[
"Track_ID"] = trk_id;
6235 wxString name = wxEmptyString;
6236 if (ptrack->m_GUID == trk_id) {
6237 name = ptrack->GetName();
6238 if (name.IsEmpty()) {
6244 name = _(
"(Unnamed Track)");
6251 v[
"TotalNodes"] = ptrack->GetnPoints();
6252 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6254 v[
"lat"] = tp->m_lat;
6255 v[
"lon"] = tp->m_lon;
6258 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6259 SendJSONMessageToAllPlugins(msg_id, v);
6265 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6266 SendJSONMessageToAllPlugins(msg_id, v);
6268 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6271 wxString guid = wxEmptyString;
6273 int numErrors = reader.
Parse(message_JSONText, &root);
6274 if (numErrors > 0) {
6283 wxString name = wxEmptyString;
6285 if ((*it)->m_GUID == guid) {
6286 name = (*it)->m_RouteNameString;
6287 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6293 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6294 itp != (*it)->pRoutePointList->end(); itp++) {
6295 w[i][
"lat"] = (*itp)->m_lat;
6296 w[i][
"lon"] = (*itp)->m_lon;
6297 w[i][
"Name"] = (*itp)->GetName();
6298 w[i][
"Description"] = (*itp)->GetDescription();
6299 w[i][
"GUID"] = (*itp)->m_GUID;
6300 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6302 auto node = (*itp)->m_HyperlinkList->begin();
6303 if (node != (*itp)->m_HyperlinkList->end()) {
6305 while (node != (*itp)->m_HyperlinkList->end()) {
6307 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6308 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6309 httpLink->DescrText;
6316 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6317 SendJSONMessageToAllPlugins(msg_id, v);
6324 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6325 SendJSONMessageToAllPlugins(msg_id, v);
6326 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6331 int numErrors = reader.
Parse(message_JSONText, &root);
6332 if (numErrors > 0)
return;
6335 wxString str = root[
"mode"].
AsString();
6336 if (str ==
"Track") route =
false;
6341 for (RouteList::iterator it =
pRouteList->begin();
6343 wxString name = (*it)->m_RouteNameString;
6344 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6346 v[i][
"error"] =
false;
6347 v[i][
"name"] = name;
6348 v[i][
"GUID"] = (*it)->m_GUID;
6349 v[i][
"active"] = (*it)->IsActive();
6354 wxString name = ptrack->GetName();
6355 if (name.IsEmpty()) {
6361 name = _(
"(Unnamed Track)");
6363 v[i][
"error"] =
false;
6364 v[i][
"name"] = name;
6365 v[i][
"GUID"] = ptrack->m_GUID;
6370 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6371 SendJSONMessageToAllPlugins(msg_id, v);
6374 v[0][
"error"] =
true;
6375 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6376 SendJSONMessageToAllPlugins(msg_id, v);
6378 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6380 v[0][
"error"] =
true;
6383 v[0][
"error"] =
false;
6384 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6385 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6386 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6387 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6388 v[0][
"active_waypoint_lat"] =
6390 v[0][
"active_waypoint_lon"] =
6394 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6395 SendJSONMessageToAllPlugins(msg_id, v);
6399void MyFrame::FilterCogSog() {
6400 if (g_bfilter_cogsog) {
6402 double cog_last =
gCog;
6405 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6406 COGFilterTable[i] = COGFilterTable[i - 1];
6407 COGFilterTable[0] = cog_last;
6410 if (!std::isnan(cog_last)) {
6412 double sum = 0., count = 0;
6413 for (
int i = 0; i < g_COGFilterSec; i++) {
6414 double adder = COGFilterTable[i];
6415 if (std::isnan(adder))
continue;
6417 if (fabs(adder - cog_last) > 180.) {
6418 if ((adder - cog_last) > 0.)
6431 else if (sum >= 360.)
6438 double sog_last =
gSog;
6441 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6442 SOGFilterTable[i] = SOGFilterTable[i - 1];
6443 SOGFilterTable[0] = sog_last;
6446 if (!std::isnan(
gSog)) {
6447 double sum = 0., count = 0;
6448 for (
int i = 0; i < g_SOGFilterSec; i++) {
6449 if (std::isnan(SOGFilterTable[i]))
continue;
6451 sum += SOGFilterTable[i];
6461void MyFrame::LoadHarmonics() {
6464 ptcmgr->LoadDataSources(TideCurrentDataSet);
6466 bool b_newdataset =
false;
6469 for (
auto a :
ptcmgr->GetDataSet()) {
6470 bool b_foundi =
false;
6471 for (
auto b : TideCurrentDataSet) {
6478 b_newdataset =
true;
6483 for (
auto a : TideCurrentDataSet) {
6484 bool b_foundi =
false;
6485 for (
auto b :
ptcmgr->GetDataSet()) {
6492 b_newdataset =
true;
6497 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6501void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6502 if (!ptarget)
return;
6505 wxDateTime mob_time = wxDateTime::Now();
6506 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6507 mob_label += _(
" on ");
6508 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6511 mob_label, wxEmptyString);
6512 pWP_MOB->SetShared(
true);
6514 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6516 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6518 pWP_MOB->SetUseSca(
false);
6526 wxString(_(
"Own ship")), wxEmptyString);
6528 pWP_MOB->SetUseSca(
false);
6535 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6551 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6552 SendJSONMessageToAllPlugins(msg_id, v);
6555 if (RouteManagerDialog::getInstanceFlag()) {
6562 RefreshAllCanvas(
false);
6564 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6565 mob_message += _(
" Time: ");
6566 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6567 mob_message += _(
" Ownship Position: ");
6568 mob_message += toSDMM(1,
gLat);
6570 mob_message += toSDMM(2,
gLon);
6571 mob_message += _(
" MOB Position: ");
6572 mob_message += toSDMM(1, ptarget->Lat);
6574 mob_message += toSDMM(2, ptarget->Lon);
6575 wxLogMessage(mob_message);
6578void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6582 OwnPoint->m_lat =
gLat;
6583 OwnPoint->m_lon =
gLon;
6585 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6590 MOB_Point->m_lat = ptarget->Lat;
6591 MOB_Point->m_lon = ptarget->Lon;
6593 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6594 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6596 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6597 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6600 RefreshAllCanvas(
false);
6603 wxDateTime mob_time = wxDateTime::Now();
6605 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6606 mob_message += _(
" Time: ");
6607 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6608 mob_message += _(
" Ownship Position: ");
6609 mob_message += toSDMM(1,
gLat);
6611 mob_message += toSDMM(2,
gLon);
6612 mob_message += _(
" MOB Position: ");
6613 mob_message += toSDMM(1, ptarget->Lat);
6615 mob_message += toSDMM(2, ptarget->Lon);
6617 wxLogMessage(mob_message);
6621void MyFrame::applySettingsString(wxString settings) {
6623 int last_UIScaleFactor = g_GUIScaleFactor;
6624 bool previous_expert = g_bUIexpert;
6625 g_last_ChartScaleFactor = g_ChartScaleFactor;
6626 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6629 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6635 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6637 if (rr & S52_CHANGED) {
6639 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6641 ->ClearCNSYLUPArray();
6642 ps52plib->GenerateStateHash();
6646 ProcessOptionsDialog(rr, pNewDirArray);
6651 bool b_newToolbar =
false;
6653 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6655 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6657 if (rr & TOOLBAR_CHANGED) {
6658 b_newToolbar =
true;
6663 if (previous_expert && !g_bUIexpert) {
6664 androidForceFullRepaint();
6668 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6672 SetGPSCompassScale();
6674 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6676 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6678 UpdateGPSCompassStatusBoxes(
true);
6681 AbstractPlatform::ShowBusySpinner();
6683 SetAllToolbarScale();
6687 AbstractPlatform::HideBusySpinner();
6689 RequestNewMasterToolbar(
true);
6696 UpdateControlBar(GetPrimaryCanvas());
6702 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6705#ifdef wxHAS_POWER_EVENTS
6706void MyFrame::OnSuspending(wxPowerEvent &event) {
6710 wxLogMessage(
"System suspend starting...");
6713void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6716 wxLogMessage(
"System is going to suspend.");
6719void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6722 wxLogMessage(
"System suspend was cancelled.");
6725int g_last_resume_ticks;
6726void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6727 wxDateTime now = wxDateTime::Now();
6728 wxLogMessage(
"System resumed from suspend.");
6730 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6733 wxLogMessage(
"Restarting streams.");
6734 g_last_resume_ticks = now.GetTicks();
6738 g_pMUX->ClearStreams();
6740 g_pMUX->StartAllStreams();
6749 if (IsMaximized()) {
6754 wxSize sz = GetSize();
6755 SetSize(wxSize(sz.x - 1, sz.y));
6767void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6768 bool btbRebuild =
false;
6770 bool b_reshow =
true;
6773 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6774 if ((ff > 0.01f) || bforcenew) {
6784 long orient = g_Platform->GetDefaultToolbarOrientation();
6785 wxWindow *toolbarParent =
this;
6787 toolbarParent = GetPrimaryCanvas();
6790 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6791 m_toolbar_callbacks);
6793 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6800 g_bmasterToolbarFull =
true;
6804 CreateMasterToolbar();
6819bool MyFrame::CollapseGlobalToolbar() {
6821 m_nMasterToolCountShown = 1;
6825 g_bmasterToolbarFull =
false;
6841 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6842 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6843 tic->m_bRequired =
true;
6848 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6849 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6853 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6854 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6855 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6860 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6861 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6865 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6866 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6867 _(
"Enable Tracking"),
"MUI_track");
6871 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6872 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6884 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6885 _(
"Print Chart"),
"MUI_print");
6889 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6890 _(
"About OpenCPN"),
"MUI_help");
6894 AddDefaultPositionPlugInTools();
6898 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6899 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6910 ArrayOfPlugInToolbarTools tool_array =
6912 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6914 if (!pttc->b_viz)
continue;
6916 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6919 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6920 if (g_bTrackActive) {
6921 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6928bool MyFrame::CheckAndAddPlugInTool() {
6936 if (!tb)
return false;
6938 int n_tools = tb->GetToolsCount();
6942 ArrayOfPlugInToolbarTools tool_array =
6945 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6947 if (pttc->position == n_tools) {
6948 wxBitmap *ptool_bmp;
6950 switch (global_color_scheme) {
6951 case GLOBAL_COLOR_SCHEME_DAY:
6952 ptool_bmp = pttc->bitmap_day;
6955 case GLOBAL_COLOR_SCHEME_DUSK:
6956 ptool_bmp = pttc->bitmap_dusk;
6958 case GLOBAL_COLOR_SCHEME_NIGHT:
6959 ptool_bmp = pttc->bitmap_night;
6962 ptool_bmp = pttc->bitmap_day;
6967 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6969 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6970 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6971 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6972 tic->m_bPlugin =
true;
6981 while (CheckAndAddPlugInTool()) {
6987bool MyFrame::AddDefaultPositionPlugInTools() {
6994 ArrayOfPlugInToolbarTools tool_array =
6997 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7001 if (!pttc->b_viz)
continue;
7003 if (pttc->position == -1)
7005 wxBitmap *ptool_bmp;
7007 switch (global_color_scheme) {
7008 case GLOBAL_COLOR_SCHEME_DAY:
7009 ptool_bmp = pttc->bitmap_day;
7011 case GLOBAL_COLOR_SCHEME_DUSK:
7012 ptool_bmp = pttc->bitmap_dusk;
7014 case GLOBAL_COLOR_SCHEME_NIGHT:
7015 ptool_bmp = pttc->bitmap_night;
7018 ptool_bmp = pttc->bitmap_day;
7023 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7025 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7026 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7027 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7028 tic->m_bPlugin =
true;
7047typedef struct _MSW_COLOR_SPEC {
7049 wxString S52_RGB_COLOR;
7053MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7054 {COLOR_MENUTEXT,
"UITX1", 0},
7055 {COLOR_BTNSHADOW,
"UIBCK", 0},
7058void SaveSystemColors() {
7072 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7073 while (pcspec->COLOR_NAME != -1) {
7074 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7079void RestoreSystemColors() {
7080 int element[NCOLORS];
7081 int rgbcolor[NCOLORS];
7084 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7085 while (pcspec->COLOR_NAME != -1) {
7086 element[i] = pcspec->COLOR_NAME;
7087 rgbcolor[i] = pcspec->SysRGB_COLOR;
7092 if (pSetSysColors) {
7093 pSetSysColors(i, (
unsigned long *)&element[0],
7094 (
unsigned long *)&rgbcolor[0]);
7100void SetSystemColors(ColorScheme cs) {
7102 int element[NCOLORS];
7103 int rgbcolor[NCOLORS];
7105 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7106 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7107 while (pcspec->COLOR_NAME != -1) {
7108 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7109 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7110 element[i] = pcspec->COLOR_NAME;
7116 pSetSysColors(i, (
unsigned long *)&element[0],
7117 (
unsigned long *)&rgbcolor[0]);
7121 RestoreSystemColors();
7128static const WORD MAX_CONSOLE_LINES =
7133void RedirectIOToConsole()
7138 wxIntPtr lStdHandle;
7140 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7150 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7151 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7152 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7156 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7157 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7158 fp = _fdopen(hConHandle,
"w");
7160 setvbuf(stdout, NULL, _IONBF, 0);
7164 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7165 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7166 fp = _fdopen(hConHandle,
"r");
7168 setvbuf(stdin, NULL, _IONBF, 0);
7172 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7173 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7174 fp = _fdopen(hConHandle,
"w");
7176 setvbuf(stderr, NULL, _IONBF, 0);
7187 FontMgr::Get().SetLocale(g_locale);
7208 if (g_pais_query_dialog_active) {
7209 g_pais_query_dialog_active->Destroy();
7210 g_pais_query_dialog_active = NULL;
7213 auto alert_dlg_active =
7215 if (alert_dlg_active) {
7216 alert_dlg_active->Destroy();
7217 g_pais_alert_dialog_active =
nullptr;
7220 if (g_pAISTargetList) {
7222 g_pAISTargetList->Disconnect_decoder();
7223 g_pAISTargetList->Destroy();
7224 g_pAISTargetList = NULL;
7228 if (gFrame->m_pMenuBar) {
7229 gFrame->SetMenuBar(NULL);
7230 gFrame->m_pMenuBar->Destroy();
7231 gFrame->m_pMenuBar = NULL;
7233 gFrame->BuildMenuBar();
7236 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7238 if (cc) cc->CanvasApplyLocale();
7243 wxString perspective;
7245 pConfig->Read(
"AUIPerspective", &perspective);
7259 bool bno_load =
false;
7260 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7262 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7263 wxAuiPaneInfo pane = pane_array_val[i];
7264 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7270 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7275 gFrame->RequestNewToolbars(
true);
7276 gFrame->RequestNewMasterToolbar(
true);
7283 : wxThread(wxTHREAD_JOINABLE) {
7284 m_filename = filename;
7295 newChart->SetNativeScale(m_scale);
7296 newChart->SetFullExtent(m_ext);
7298 newChart->FindOrCreateSenc(m_filename);
7303 wxString m_filename;
7309static double chart_dist(
int index) {
7315 if (cte.GetBBox().Contains(
gLat,
gLon))
7320 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7321 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7322 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7325 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7326 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7328 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7334WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7335static int CompareInts(
int n1,
int n2) {
7336 double d1 = chart_dist(n1);
7337 double d2 = chart_dist(n2);
7338 return (
int)(d1 - d2);
7343 wxString chart_path;
7348WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7350#include <wx/arrimpl.cpp>
7353void ParseAllENC(wxWindow *parent) {
7354 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7362 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7365 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7367 idx_sorted_by_distance.Add(i);
7371 if (count == 0)
return;
7373 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7379 ArrayOfCompressTargets ct_array;
7380 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7381 int i = idx_sorted_by_distance[j];
7384 double distance = chart_dist(i);
7386 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7389 pct->distance = distance;
7390 pct->chart_path = filename;
7392 ct_array.push_back(pct);
7395 int thread_count = 0;
7398 if (g_nCPUCount > 0)
7399 thread_count = g_nCPUCount;
7401 thread_count = wxThread::GetCPUCount();
7403 if (thread_count < 1) {
7412 for(
int t = 0; t < thread_count; t++)
7416 wxGenericProgressDialog *prog =
nullptr;
7420 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7421 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7423 prog =
new wxGenericProgressDialog();
7425 prog->SetFont(*qFont);
7427 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7428 count + 1, parent, style);
7437 prog->ShowWindowModal();
7446 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7447 wxString filename = ct_array[j].chart_path;
7448 double distance = ct_array[j].distance;
7449 int index =
ChartData->FinddbIndex(filename);
7450 if (index < 0)
continue;
7453 ext.NLAT = cte.GetLatMax();
7454 ext.SLAT = cte.GetLatMin();
7455 ext.WLON = cte.GetLonMin();
7456 ext.ELON = cte.GetLonMax();
7458 int scale = cte.GetScale();
7461 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7464 if (wxThread::IsMain()) {
7466 wxSize sz = prog->GetSize();
7471 prog->Update(count, msg, &skip);
7483 newChart->SetNativeScale(
scale);
7484 newChart->SetFullExtent(ext);
7485 newChart->DisableBackgroundSENC();
7487 newChart->FindOrCreateSenc(filename,
7491 if (wxThread::IsMain()) {
7492 msg.Printf(_(
"ENC Completed."));
7494 prog->Update(count, msg, &skip);
7504 for (
int t = 0;; t = (t + 1) % thread_count) {
7511 if (!workers[t]->IsAlive()) {
7524#if defined(__WXMSW__) || defined(__WXOSX__)
7531 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.