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().FullSchemaMigrate(
this);
4706 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4707 NavObj_dB::GetInstance().LoadNavObjects();
4710 if (!g_AW1GUID.IsEmpty()) {
4713 if (!g_AW2GUID.IsEmpty()) {
4719 appendOSDirSlash(&layerdir);
4720 layerdir.Append(
"layers");
4722 if (wxDir::Exists(layerdir)) {
4724 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4725 wxLogMessage(laymsg);
4726 pConfig->LoadLayers(layerdir);
4731 if (!g_kiosk_startup) {
4732 AbstractPlatform::ShowBusySpinner();
4735 pConfig->SetPath(
"/Settings");
4736 pConfig->Read(
"OptionsSizeX", &sx, -1);
4737 pConfig->Read(
"OptionsSizeY", &sy, -1);
4739 wxWindow *optionsParent =
this;
4741 optionsParent = GetPrimaryCanvas();
4744 callbacks.prepare_close = [&](
options *me,
int changes) {
4745 PrepareOptionsClose(me, changes);
4747 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4748 ProcessOptionsDialog(changes, workdir_list);
4751 wxPoint(-1, -1), wxSize(sx, sy));
4752 AbstractPlatform::HideBusySpinner();
4759 wxLogMessage(
"OnInitTimer...Last Call");
4763 RequestNewMasterToolbar();
4765 PositionIENCToolbar();
4767 g_bDeferredInitDone =
true;
4777 GetPrimaryCanvas()->SetFocus();
4778 GetPrimaryCanvas()->Enable();
4781 if (b_reloadForPlugins) {
4787 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4789 if (cc) cc->SetFirstAuto(
true);
4797 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4799 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4803 cc->CheckGroupValid();
4804 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4805 cc->SetShowGPSCompassWindow(
true);
4810 androidEnableBackButton(
true);
4811 androidEnableRotation();
4812 androidEnableOptionItems(
true);
4816 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4822 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4824 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4826 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4832 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4834 wxLog::FlushActive();
4836 RefreshAllCanvas(
true);
4837 UsbWatchDaemon::GetInstance().Start();
4838 EnableSettingsTool(
true);
4844void MyFrame::InitAppMsgBusListener() {
4845 auto &msgbus = AppMsgBus::GetInstance();
4848 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4849 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4853 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4854 HandleBasicNavMsg(basicnav_msg);
4858 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4859 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4863 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4864 HandleGPSWatchdogMsg(msg);
4871void MyFrame::ReleaseApiListeners() {}
4876 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4877 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4878 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4879 server.open_file_cb = [&](
const std::string &path) {
4880 return m_open_gpx_file(path);
4887void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4888 if (msg->gps_watchdog <= 0) {
4889 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4893 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4898 if (m_fix_start_time.IsValid()) {
4899 wxDateTime now = wxDateTime::Now();
4900 wxTimeSpan span = now - m_fix_start_time;
4901 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4902 auto ¬eman = NotificationManager::GetInstance();
4903 wxString msg = _(
"GNSS Position fix lost");
4904 noteman.AddNotification(NotificationSeverity::kCritical,
4906 m_fix_start_time = wxInvalidDateTime;
4910 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4911 bool last_bVelocityValid = bVelocityValid;
4912 bVelocityValid =
false;
4919void MyFrame::CalculateCOGAverage() {
4921 if (!std::isnan(
gCog)) {
4924 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4927 double sum = 0., count = 0;
4929 double adder = COGTable[i];
4930 if (std::isnan(adder))
continue;
4932 if (fabs(adder -
g_COGAvg) > 180.) {
4946 else if (sum >= 360.)
4955void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4956 m_fixtime = msg->time;
4957 double hdt_data_interval = 0;
4958 double fix_time_interval = 0;
4960 double msgtime = msg->set_time.tv_sec;
4961 double m1 = msg->set_time.tv_nsec / 1e9;
4964 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4965 ((msg->vflag & POS_VALID) == POS_VALID)) {
4967 if (!m_fix_start_time.IsValid()) {
4968 m_fix_start_time = wxDateTime::Now();
4973 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4976 fix_time_gt_last = fix_time_gt;
4977 uint64_t fix_time_gt_now =
4978 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4979 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4983 double implied_sog = dist / (fix_time_interval / 3600);
4988 gLat_gt_m1 = gLat_gt;
4989 gLon_gt_m1 = gLon_gt;
4993 fix_time_gt = fix_time_gt_now;
4997 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
4998 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
4999 gCog_gt_m1 = gCog_gt;
5009 if (!std::isnan(gCog_gt_m1)) {
5011 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5018 if ((fix_time_gt - fix_time_gt_last) > .08) {
5023 if (gCog_gt > gCog_gt_m1) {
5024 if ((gCog_gt - gCog_gt_m1) > 180.)
5029 if ((gCog_gt_m1 - gCog_gt) > 180.)
5034 difft = fabs(gCog_gt - gCog_gt_m1);
5035 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5043 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5044 tentative_cog_rate_gt *= 1e9;
5045 cog_rate_gt = tentative_cog_rate_gt;
5053 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5056static double hdt_avg;
5057 double hdt_norm =
gHdt;
5058 if(
gHdt > 180) hdt_norm -= 360;
5061 hdt_avg += hdt_norm * 0.1;
5066 if (!std::isnan(
gHdt)) {
5068 uint64_t hdt_time_gt_last = hdt_time_gt;
5069 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5070 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5073 if (hdt_data_interval > .09) {
5075 gHdt_gt_m1 = gHdt_gt;
5078 if (!std::isnan(gHdt_gt_m1)) {
5080 double tentative_hdt_rate_gt =
5081 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5082 tentative_hdt_rate_gt *= 1e9;
5084 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5085 hdt_rate_gt = tentative_hdt_rate_gt;
5093 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5096 CalculateCOGAverage();
5104 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5105 if ((msg->vflag & POS_VALID) == POS_VALID)
5110 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5112 bVelocityValid =
true;
5116void MyFrame::UpdateStatusBar() {
5119 unsigned long uiCurrentTickCount;
5120 m_MMEAeventTime.SetToCurrent();
5121 uiCurrentTickCount =
5122 m_MMEAeventTime.GetMillisecond() / 100;
5123 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5124 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5125 m_ulLastNMEATicktime = uiCurrentTickCount;
5127 if (m_tick_idx++ > 6) m_tick_idx = 0;
5132 if (NULL != GetStatusBar()) {
5135 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5138 wxString s1(tick_buf, wxConvUTF8);
5140 s1 += toSDMM(1,
gLat);
5142 s1 += toSDMM(2,
gLon);
5144 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5148 if (!std::isnan(
gSog))
5149 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5151 sogcog.Printf(
"SOG --- ");
5155 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5157 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5159 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5160 (
int)toMagnetic(
gCog), 0x00B0);
5162 cogs.Printf((
"COG ---%c"), 0x00B0);
5164 sogcog.Append(cogs);
5165 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5170void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5171 MemFootTimer.Stop();
5173 int memsize = GetApplicationMemoryUse();
5176 printf(
"Memsize: %d \n", memsize);
5179 if (memsize > (g_MemFootMB * 1000)) {
5183 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5184 unsigned int nCache = pCache->GetCount();
5187 for (
unsigned int i = 0; i < nCache; i++) {
5197 for (
unsigned int i = 0; i < nCache - 1; i++) {
5198 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5200 pcea[i] = pcea[i + 1];
5211 unsigned int idelete = 0;
5212 unsigned int idelete_max = pCache->GetCount();
5215 unsigned int minimum_cache = 1;
5216 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5218 while ((memsize > (g_MemFootMB * 1000)) &&
5219 (pCache->GetCount() > minimum_cache) &&
5220 (idelete < idelete_max)) {
5221 int memsizeb = memsize;
5225 memsize = GetApplicationMemoryUse();
5226 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5234 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5239void MyFrame::CheckToolbarPosition() {
5242 static bool bMaximized;
5244 if (IsMaximized() && !bMaximized) {
5251 PositionIENCToolbar();
5252 }
else if (!IsMaximized() && bMaximized) {
5260 PositionIENCToolbar();
5265void MyFrame::ProcessUnitTest() {
5266 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5273 cc->m_bFollow =
false;
5275 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5276 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5279 if (cc->m_groupIndex > 0) {
5280 while (ut_index < ChartData->GetChartTableEntries() &&
5281 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5285 if (ut_index < ChartData->GetChartTableEntries()) {
5289 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5290 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5297 if (cc->GetQuiltMode()) {
5298 if (cc->IsChartQuiltableRef(ut_index))
5299 cc->SelectQuiltRefdbChart(ut_index);
5301 cc->SelectdbChart(ut_index);
5304 if (g_unit_test_1) {
5312 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5313 cte->GetLatMin(), cte->GetLonMax(), NULL,
5317 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5318 cte->GetLatMax(), cte->GetLonMin(), NULL,
5321 cc->GetSize(&ww, &wh);
5322 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5324 ppm = wxMin(ppm, 1.0);
5331 if (ut_index > ut_index_max) exit(0);
5342 bool b_rotate =
false;
5344 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5347 if (!b_rotate && !g_btenhertz)
return;
5349 bool b_update =
false;
5351 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5354 struct timespec now;
5355 clock_gettime(CLOCK_MONOTONIC, &now);
5356 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5357 double diffc = diff / 1e9;
5360 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5361 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5362 if (gCog_tentative < 0.) gCog_tentative += 360.;
5363 gCog = gCog_tentative;
5367 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5368 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5369 double diffc = diff / 1e9;
5370 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5374 if (gSog_gt && !std::isnan(gCog_gt)) {
5375 double delta_t = diffc / 3600;
5376 double distance = gSog_gt * delta_t;
5379 double angr = gCog_gt / 180 * M_PI;
5380 double latr = gLat_gt * M_PI / 180;
5381 double D = distance / 3443;
5382 double sD = sin(D), cD = cos(D);
5383 double sy = sin(latr), cy = cos(latr);
5384 double sa = sin(angr), ca = cos(angr);
5386 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5387 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5397 if (cc) cc->DoCanvasCOGSet();
5406 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5407 bool bnew = cc->DoCanvasUpdate();
5408 if (!bnew) cc->UpdateShips();
5417 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5420bool MyFrame::ProcessQuitFlag() {
5424 FrameTenHzTimer.Stop();
5426 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5427 if (top) top->Close(
true);
5434void MyFrame::ProcessDeferredTrackOn() {
5437 if (g_bDeferredStartTrack) {
5438 if (!g_bTrackActive) {
5441 g_bDeferredStartTrack =
false;
5444 g_bDeferredStartTrack =
false;
5449void MyFrame::ProcessAnchorWatch() {
5457 double d = g_nAWMax;
5460 bool toofar =
false;
5461 bool tooclose =
false;
5462 if (d >= 0.0) toofar = (dist * 1852. > d);
5463 if (d < 0.0) tooclose = (dist * 1852 < -d);
5465 if (tooclose || toofar)
5466 AnchorAlertOn1 =
true;
5468 AnchorAlertOn1 =
false;
5470 AnchorAlertOn1 =
false;
5478 double d = g_nAWMax;
5481 bool toofar =
false;
5482 bool tooclose =
false;
5483 if (d >= 0) toofar = (dist * 1852. > d);
5484 if (d < 0) tooclose = (dist * 1852 < -d);
5486 if (tooclose || toofar)
5487 AnchorAlertOn2 =
true;
5489 AnchorAlertOn2 =
false;
5491 AnchorAlertOn2 =
false;
5494 AnchorAlertOn1 =
true;
5497void MyFrame::SendFixToPlugins() {
5508 GPSData.
nSats = g_SatsInView;
5510 wxDateTime tCheck((time_t)m_fixtime);
5511 if (tCheck.IsValid()) {
5520 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5523 SendPositionFixToAllPlugIns(&GPSData);
5527void MyFrame::ProcessLogAndBells() {
5530 wxDateTime lognow = wxDateTime::Now();
5531 int hourLOC = lognow.GetHour();
5532 int minuteLOC = lognow.GetMinute();
5534 int minuteUTC = lognow.GetMinute();
5535 int second = lognow.GetSecond();
5537 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5538 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5539 (minuteUTC == 30)) {
5540 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5541 wxString day = lognow.FormatISODate();
5542 wxString utc = lognow.FormatISOTime();
5543 wxString navmsg =
"LOGBOOK: ";
5551 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5555 if (std::isnan(
gCog))
5556 cog.Printf(
"COG ----- ");
5558 cog.Printf(
"COG %10.5f ",
gCog);
5561 if (std::isnan(
gSog))
5562 sog.Printf(
"SOG ----- ");
5564 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5570 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5573 wxLogMessage(navmsg);
5574 g_loglast_time = lognow;
5576 int bells = (hourLOC % 4) * 2;
5577 if (minuteLOC != 0) bells++;
5578 if (!bells) bells = 8;
5580 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5581 m_BellsToPlay = bells;
5582 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5583 wxPostEvent(
this, ev);
5590 CheckToolbarPosition();
5594 if (ProcessQuitFlag())
return;
5596 if (bDBUpdateInProgress)
return;
5599 FrameTenHzTimer.Stop();
5601 ProcessDeferredTrackOn();
5603 ProcessAnchorWatch();
5604 ProcessLogAndBells();
5606 if (ShouldRestartTrack()) TrackDailyRestart();
5609 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5610 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5611 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5617 if (
gSog > 3.0) g_bCruising =
true;
5623 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5625 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5631 bool bnew_view =
false;
5632 if (!g_btenhertz) bnew_view = DoChartUpdate();
5639 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5642 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5645 cc->DrawBlinkObjects();
5648 if (bactiveRouteUpdate) {
5655 cc->SetOwnShipState(SHIP_NORMAL);
5657 if (cc->GetQuiltMode()) {
5658 double erf = cc->GetQuiltMaxErrorFactor();
5659 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5661 if (cc->m_singleChart) {
5662 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5663 cc->SetOwnShipState(SHIP_LOWACCURACY);
5667 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5670 (bVelocityValid != m_last_bVelocityValid) ||
5671 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5672 if (!g_bopengl) cc->UpdateShips();
5680 m_last_bVelocityValid = bVelocityValid;
5685 bool brq_dynamic =
false;
5687 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5688 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5690 if (pic->m_enabled && pic->m_init_state) {
5691 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5698 if (brq_dynamic) bnew_view =
true;
5702 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5705 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5710 if (cc->GetglCanvas()) {
5712 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5714 if ((!g_btenhertz)) {
5715 if (cc->m_bFollow) {
5716 cc->DoCanvasUpdate();
5733 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5747 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5748 g_pais_query_dialog_active->UpdateText();
5751 if (g_pAISTargetList && (0 == (g_tick % (5))))
5752 g_pAISTargetList->UpdateAISTargetList();
5755 UpdateGPSCompassStatusBoxes();
5760 console->RefreshConsoleData();
5767 if (m_bdefer_resize) {
5768 if (0 == (g_tick % (5))) {
5769 printf(
"___RESIZE\n");
5770 SetSize(m_defer_size);
5772 m_bdefer_resize =
false;
5779 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5781 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5782 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5786double MyFrame::GetMag(
double a,
double lat,
double lon) {
5787 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5788 auto loader = PluginLoader::GetInstance();
5789 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5796 wxDateTime now = wxDateTime::Now();
5797 SendJSON_WMM_Var_Request(lat, lon, now);
5798 if (fabs(gQueryVar) < 360.0)
5799 Variance = gQueryVar;
5801 return toMagnetic(a, Variance);
5804bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5810 v[
"Year"] = date.GetYear();
5811 v[
"Month"] = date.GetMonth();
5812 v[
"Day"] = date.GetDay();
5814 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5820void MyFrame::TouchAISActive() {
5822 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5824 if (cc) cc->TouchAISToolActive();
5828void MyFrame::UpdateAISTool() {
5832 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5834 if (cc) cc->UpdateAISTBTool();
5839void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5841 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5843 if (cc) cc->SetbTCUpdate(
true);
5846 RefreshAllCanvas(
false);
5851void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5855 bool b_rotate =
false;
5856 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5858 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5862 FrameCOGTimer.Stop();
5869 int period_ms = 100;
5871 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5874void MyFrame::DoCOGSet() {
5876 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5878 if (cc) cc->DoCanvasCOGSet();
5882void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5888 wxFont oldfont = pdc->GetFont();
5890 pdc->SetFont(*pFont);
5891 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5892 pdc->SetBackgroundMode(wxTRANSPARENT);
5894 pdc->DrawText(str, x, y + 1);
5895 pdc->DrawText(str, x, y - 1);
5896 pdc->DrawText(str, x + 1, y);
5897 pdc->DrawText(str, x - 1, y);
5899 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5901 pdc->DrawText(str, x, y);
5903 pdc->SetFont(oldfont);
5907void MyFrame::UpdateRotationState(
double rotation) {
5909 g_bCourseUp =
false;
5911 if (fabs(rotation) > .001) {
5912 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5913 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5915 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5918 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5919 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5921 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5925 UpdateGPSCompassStatusBoxes(
true);
5929void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5931 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5933 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5939int MyFrame::GetApplicationMemoryUse() {
5945 wxWindow *fWin = wxWindow::FindFocus();
5947 wxArrayString outputArray;
5948 wxString cmd(
"ps --no-headers -o vsize ");
5949 unsigned long pid = wxGetProcessId();
5951 cmd1.Printf(
"%ld", pid);
5953 wxExecute(cmd, outputArray);
5955 if (outputArray.GetCount()) {
5956 wxString s = outputArray.Item(0);
5958 if (s.ToLong(&vtmp)) memsize = vtmp;
5961 if (fWin) fWin->SetFocus();
5967 PROCESS_MEMORY_COUNTERS pmc;
5969 unsigned long processID = wxGetProcessId();
5971 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5973 if (NULL == hProcess)
return 0;
5975 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5993 memsize = pmc.WorkingSetSize / 1024;
5996 CloseHandle(hProcess);
6003double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6004 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6007void MyFrame::SetChartUpdatePeriod() {
6010 g_ChartUpdatePeriod = 0;
6015 bool bskewdc =
false;
6016 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6019 if (!g_bopengl && !cc->GetVP().b_quilt) {
6020 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6022 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6026 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6028 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6033 cc->UpdateCanvasControlBar();
6036void MyFrame::selectChartDisplay(
int type,
int family) {
6038 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6040 if (cc) cc->selectCanvasChartDisplay(type, family);
6043 UpdateGlobalMenuItems();
6052bool MyFrame::DoChartUpdate() {
6053 bool return_val =
false;
6056 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6058 if (cc) return_val |= cc->DoCanvasUpdate();
6064void MyFrame::MouseEvent(wxMouseEvent &event) {
6066 event.GetPosition(&x, &y);
6071#include <mach/mach.h>
6072#include <mach/message.h>
6073#include <mach/kern_return.h>
6074#include <mach/task_info.h>
6076#include <malloc/malloc.h>
6083#if defined(__linux__)
6084#include "sys/types.h"
6085#include "sys/sysinfo.h"
6088void MyFrame::DoPrint(
void) {
6090 g_PrintingInProgress =
true;
6093 GetPrimaryCanvas()->GetglCanvas()->Render();
6094 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6104 printer.Initialize(wxLANDSCAPE);
6105 printer.EnablePageNumbers(
false);
6106 printer.Print(
this, &printout);
6124 g_PrintingInProgress =
false;
6127 GetPrimaryCanvas()->SetFocus();
6133 wxString message_ID =
event.GetID();
6134 wxString message_JSONText =
event.GetJSONText();
6142 if (message_ID ==
"WMM_VARIATION_BOAT") {
6150 int numErrors = reader.
Parse(message_JSONText, &root);
6151 if (numErrors > 0) {
6157 wxString decl = root[
"Decl"].
AsString();
6159 decl.ToDouble(&decl_val);
6165 if (message_ID ==
"WMM_VARIATION") {
6173 int numErrors = reader.
Parse(message_JSONText, &root);
6174 if (numErrors > 0) {
6180 wxString decl = root[
"Decl"].
AsString();
6182 decl.ToDouble(&decl_val);
6184 gQueryVar = decl_val;
6187 if (message_ID ==
"GRIB_TIMELINE") {
6190 int numErrors = r.
Parse(message_JSONText, &v);
6192 if (numErrors > 0) {
6193 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6198 wxDateTime oldTimeSource = gTimeSource;
6200 if (v[
"Day"].AsInt() == -1) {
6201 gTimeSource = wxInvalidDateTime;
6202 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6204 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6205 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6206 v[
"Second"].AsInt());
6210 if (oldTimeSource != gTimeSource) {
6212 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6214 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6219 cc->pCwin->Refresh(
false);
6225 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6228 wxString trk_id = wxEmptyString;
6230 int numErrors = reader.
Parse(message_JSONText, &root);
6231 if (numErrors > 0)
return;
6236 v[
"Track_ID"] = trk_id;
6238 wxString name = wxEmptyString;
6239 if (ptrack->m_GUID == trk_id) {
6240 name = ptrack->GetName();
6241 if (name.IsEmpty()) {
6247 name = _(
"(Unnamed Track)");
6254 v[
"TotalNodes"] = ptrack->GetnPoints();
6255 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6257 v[
"lat"] = tp->m_lat;
6258 v[
"lon"] = tp->m_lon;
6261 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6262 SendJSONMessageToAllPlugins(msg_id, v);
6268 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6269 SendJSONMessageToAllPlugins(msg_id, v);
6271 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6274 wxString guid = wxEmptyString;
6276 int numErrors = reader.
Parse(message_JSONText, &root);
6277 if (numErrors > 0) {
6286 wxString name = wxEmptyString;
6288 if ((*it)->m_GUID == guid) {
6289 name = (*it)->m_RouteNameString;
6290 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6296 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6297 itp != (*it)->pRoutePointList->end(); itp++) {
6298 w[i][
"lat"] = (*itp)->m_lat;
6299 w[i][
"lon"] = (*itp)->m_lon;
6300 w[i][
"Name"] = (*itp)->GetName();
6301 w[i][
"Description"] = (*itp)->GetDescription();
6302 w[i][
"GUID"] = (*itp)->m_GUID;
6303 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6305 auto node = (*itp)->m_HyperlinkList->begin();
6306 if (node != (*itp)->m_HyperlinkList->end()) {
6308 while (node != (*itp)->m_HyperlinkList->end()) {
6310 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6311 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6312 httpLink->DescrText;
6319 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6320 SendJSONMessageToAllPlugins(msg_id, v);
6327 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6328 SendJSONMessageToAllPlugins(msg_id, v);
6329 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6334 int numErrors = reader.
Parse(message_JSONText, &root);
6335 if (numErrors > 0)
return;
6338 wxString str = root[
"mode"].
AsString();
6339 if (str ==
"Track") route =
false;
6344 for (RouteList::iterator it =
pRouteList->begin();
6346 wxString name = (*it)->m_RouteNameString;
6347 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6349 v[i][
"error"] =
false;
6350 v[i][
"name"] = name;
6351 v[i][
"GUID"] = (*it)->m_GUID;
6352 v[i][
"active"] = (*it)->IsActive();
6357 wxString name = ptrack->GetName();
6358 if (name.IsEmpty()) {
6364 name = _(
"(Unnamed Track)");
6366 v[i][
"error"] =
false;
6367 v[i][
"name"] = name;
6368 v[i][
"GUID"] = ptrack->m_GUID;
6373 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6374 SendJSONMessageToAllPlugins(msg_id, v);
6377 v[0][
"error"] =
true;
6378 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6379 SendJSONMessageToAllPlugins(msg_id, v);
6381 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6383 v[0][
"error"] =
true;
6386 v[0][
"error"] =
false;
6387 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6388 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6389 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6390 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6391 v[0][
"active_waypoint_lat"] =
6393 v[0][
"active_waypoint_lon"] =
6397 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6398 SendJSONMessageToAllPlugins(msg_id, v);
6402void MyFrame::FilterCogSog() {
6403 if (g_bfilter_cogsog) {
6405 double cog_last =
gCog;
6408 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6409 COGFilterTable[i] = COGFilterTable[i - 1];
6410 COGFilterTable[0] = cog_last;
6413 if (!std::isnan(cog_last)) {
6415 double sum = 0., count = 0;
6416 for (
int i = 0; i < g_COGFilterSec; i++) {
6417 double adder = COGFilterTable[i];
6418 if (std::isnan(adder))
continue;
6420 if (fabs(adder - cog_last) > 180.) {
6421 if ((adder - cog_last) > 0.)
6434 else if (sum >= 360.)
6441 double sog_last =
gSog;
6444 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6445 SOGFilterTable[i] = SOGFilterTable[i - 1];
6446 SOGFilterTable[0] = sog_last;
6449 if (!std::isnan(
gSog)) {
6450 double sum = 0., count = 0;
6451 for (
int i = 0; i < g_SOGFilterSec; i++) {
6452 if (std::isnan(SOGFilterTable[i]))
continue;
6454 sum += SOGFilterTable[i];
6464void MyFrame::LoadHarmonics() {
6467 ptcmgr->LoadDataSources(TideCurrentDataSet);
6469 bool b_newdataset =
false;
6472 for (
auto a :
ptcmgr->GetDataSet()) {
6473 bool b_foundi =
false;
6474 for (
auto b : TideCurrentDataSet) {
6481 b_newdataset =
true;
6486 for (
auto a : TideCurrentDataSet) {
6487 bool b_foundi =
false;
6488 for (
auto b :
ptcmgr->GetDataSet()) {
6495 b_newdataset =
true;
6500 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6504void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6505 if (!ptarget)
return;
6508 wxDateTime mob_time = wxDateTime::Now();
6509 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6510 mob_label += _(
" on ");
6511 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6514 mob_label, wxEmptyString);
6515 pWP_MOB->SetShared(
true);
6517 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6519 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6521 pWP_MOB->SetUseSca(
false);
6529 wxString(_(
"Own ship")), wxEmptyString);
6531 pWP_MOB->SetUseSca(
false);
6538 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6554 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6555 SendJSONMessageToAllPlugins(msg_id, v);
6558 if (RouteManagerDialog::getInstanceFlag()) {
6565 RefreshAllCanvas(
false);
6567 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6568 mob_message += _(
" Time: ");
6569 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6570 mob_message += _(
" Ownship Position: ");
6571 mob_message += toSDMM(1,
gLat);
6573 mob_message += toSDMM(2,
gLon);
6574 mob_message += _(
" MOB Position: ");
6575 mob_message += toSDMM(1, ptarget->Lat);
6577 mob_message += toSDMM(2, ptarget->Lon);
6578 wxLogMessage(mob_message);
6581void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6585 OwnPoint->m_lat =
gLat;
6586 OwnPoint->m_lon =
gLon;
6588 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6593 MOB_Point->m_lat = ptarget->Lat;
6594 MOB_Point->m_lon = ptarget->Lon;
6596 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6597 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6599 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6600 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6603 RefreshAllCanvas(
false);
6606 wxDateTime mob_time = wxDateTime::Now();
6608 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6609 mob_message += _(
" Time: ");
6610 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6611 mob_message += _(
" Ownship Position: ");
6612 mob_message += toSDMM(1,
gLat);
6614 mob_message += toSDMM(2,
gLon);
6615 mob_message += _(
" MOB Position: ");
6616 mob_message += toSDMM(1, ptarget->Lat);
6618 mob_message += toSDMM(2, ptarget->Lon);
6620 wxLogMessage(mob_message);
6624void MyFrame::applySettingsString(wxString settings) {
6626 int last_UIScaleFactor = g_GUIScaleFactor;
6627 bool previous_expert = g_bUIexpert;
6628 g_last_ChartScaleFactor = g_ChartScaleFactor;
6629 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6632 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6638 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6640 if (rr & S52_CHANGED) {
6642 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6644 ->ClearCNSYLUPArray();
6645 ps52plib->GenerateStateHash();
6649 ProcessOptionsDialog(rr, pNewDirArray);
6654 bool b_newToolbar =
false;
6656 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6658 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6660 if (rr & TOOLBAR_CHANGED) {
6661 b_newToolbar =
true;
6666 if (previous_expert && !g_bUIexpert) {
6667 androidForceFullRepaint();
6671 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6675 SetGPSCompassScale();
6677 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6679 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6681 UpdateGPSCompassStatusBoxes(
true);
6684 AbstractPlatform::ShowBusySpinner();
6686 SetAllToolbarScale();
6690 AbstractPlatform::HideBusySpinner();
6692 RequestNewMasterToolbar(
true);
6699 UpdateControlBar(GetPrimaryCanvas());
6705 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6708#ifdef wxHAS_POWER_EVENTS
6709void MyFrame::OnSuspending(wxPowerEvent &event) {
6713 wxLogMessage(
"System suspend starting...");
6716void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6719 wxLogMessage(
"System is going to suspend.");
6722void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6725 wxLogMessage(
"System suspend was cancelled.");
6728int g_last_resume_ticks;
6729void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6730 wxDateTime now = wxDateTime::Now();
6731 wxLogMessage(
"System resumed from suspend.");
6733 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6736 wxLogMessage(
"Restarting streams.");
6737 g_last_resume_ticks = now.GetTicks();
6741 g_pMUX->ClearStreams();
6743 g_pMUX->StartAllStreams();
6752 if (IsMaximized()) {
6757 wxSize sz = GetSize();
6758 SetSize(wxSize(sz.x - 1, sz.y));
6770void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6771 bool btbRebuild =
false;
6773 bool b_reshow =
true;
6776 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6777 if ((ff > 0.01f) || bforcenew) {
6787 long orient = g_Platform->GetDefaultToolbarOrientation();
6788 wxWindow *toolbarParent =
this;
6790 toolbarParent = GetPrimaryCanvas();
6793 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6794 m_toolbar_callbacks);
6796 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6803 g_bmasterToolbarFull =
true;
6807 CreateMasterToolbar();
6822bool MyFrame::CollapseGlobalToolbar() {
6824 m_nMasterToolCountShown = 1;
6828 g_bmasterToolbarFull =
false;
6844 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6845 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6846 tic->m_bRequired =
true;
6851 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6852 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6856 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6857 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6858 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6863 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6864 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6868 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6869 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6870 _(
"Enable Tracking"),
"MUI_track");
6874 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6875 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6887 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6888 _(
"Print Chart"),
"MUI_print");
6892 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6893 _(
"About OpenCPN"),
"MUI_help");
6897 AddDefaultPositionPlugInTools();
6901 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6902 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6913 ArrayOfPlugInToolbarTools tool_array =
6915 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6917 if (!pttc->b_viz)
continue;
6919 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6922 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6923 if (g_bTrackActive) {
6924 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6931bool MyFrame::CheckAndAddPlugInTool() {
6939 if (!tb)
return false;
6941 int n_tools = tb->GetToolsCount();
6945 ArrayOfPlugInToolbarTools tool_array =
6948 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6950 if (pttc->position == n_tools) {
6951 wxBitmap *ptool_bmp;
6953 switch (global_color_scheme) {
6954 case GLOBAL_COLOR_SCHEME_DAY:
6955 ptool_bmp = pttc->bitmap_day;
6958 case GLOBAL_COLOR_SCHEME_DUSK:
6959 ptool_bmp = pttc->bitmap_dusk;
6961 case GLOBAL_COLOR_SCHEME_NIGHT:
6962 ptool_bmp = pttc->bitmap_night;
6965 ptool_bmp = pttc->bitmap_day;
6970 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6972 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6973 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6974 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6975 tic->m_bPlugin =
true;
6984 while (CheckAndAddPlugInTool()) {
6990bool MyFrame::AddDefaultPositionPlugInTools() {
6997 ArrayOfPlugInToolbarTools tool_array =
7000 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7004 if (!pttc->b_viz)
continue;
7006 if (pttc->position == -1)
7008 wxBitmap *ptool_bmp;
7010 switch (global_color_scheme) {
7011 case GLOBAL_COLOR_SCHEME_DAY:
7012 ptool_bmp = pttc->bitmap_day;
7014 case GLOBAL_COLOR_SCHEME_DUSK:
7015 ptool_bmp = pttc->bitmap_dusk;
7017 case GLOBAL_COLOR_SCHEME_NIGHT:
7018 ptool_bmp = pttc->bitmap_night;
7021 ptool_bmp = pttc->bitmap_day;
7026 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7028 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7029 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7030 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7031 tic->m_bPlugin =
true;
7050typedef struct _MSW_COLOR_SPEC {
7052 wxString S52_RGB_COLOR;
7056MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7057 {COLOR_MENUTEXT,
"UITX1", 0},
7058 {COLOR_BTNSHADOW,
"UIBCK", 0},
7061void SaveSystemColors() {
7075 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7076 while (pcspec->COLOR_NAME != -1) {
7077 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7082void RestoreSystemColors() {
7083 int element[NCOLORS];
7084 int rgbcolor[NCOLORS];
7087 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7088 while (pcspec->COLOR_NAME != -1) {
7089 element[i] = pcspec->COLOR_NAME;
7090 rgbcolor[i] = pcspec->SysRGB_COLOR;
7095 if (pSetSysColors) {
7096 pSetSysColors(i, (
unsigned long *)&element[0],
7097 (
unsigned long *)&rgbcolor[0]);
7103void SetSystemColors(ColorScheme cs) {
7105 int element[NCOLORS];
7106 int rgbcolor[NCOLORS];
7108 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7109 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7110 while (pcspec->COLOR_NAME != -1) {
7111 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7112 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7113 element[i] = pcspec->COLOR_NAME;
7119 pSetSysColors(i, (
unsigned long *)&element[0],
7120 (
unsigned long *)&rgbcolor[0]);
7124 RestoreSystemColors();
7131static const WORD MAX_CONSOLE_LINES =
7136void RedirectIOToConsole()
7141 wxIntPtr lStdHandle;
7143 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7153 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7154 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7155 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7159 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7160 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7161 fp = _fdopen(hConHandle,
"w");
7163 setvbuf(stdout, NULL, _IONBF, 0);
7167 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7168 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7169 fp = _fdopen(hConHandle,
"r");
7171 setvbuf(stdin, NULL, _IONBF, 0);
7175 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7176 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7177 fp = _fdopen(hConHandle,
"w");
7179 setvbuf(stderr, NULL, _IONBF, 0);
7190 FontMgr::Get().SetLocale(g_locale);
7211 if (g_pais_query_dialog_active) {
7212 g_pais_query_dialog_active->Destroy();
7213 g_pais_query_dialog_active = NULL;
7216 auto alert_dlg_active =
7218 if (alert_dlg_active) {
7219 alert_dlg_active->Destroy();
7220 g_pais_alert_dialog_active =
nullptr;
7223 if (g_pAISTargetList) {
7225 g_pAISTargetList->Disconnect_decoder();
7226 g_pAISTargetList->Destroy();
7227 g_pAISTargetList = NULL;
7231 if (gFrame->m_pMenuBar) {
7232 gFrame->SetMenuBar(NULL);
7233 gFrame->m_pMenuBar->Destroy();
7234 gFrame->m_pMenuBar = NULL;
7236 gFrame->BuildMenuBar();
7239 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7241 if (cc) cc->CanvasApplyLocale();
7246 wxString perspective;
7248 pConfig->Read(
"AUIPerspective", &perspective);
7262 bool bno_load =
false;
7263 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7265 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7266 wxAuiPaneInfo pane = pane_array_val[i];
7267 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7273 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7278 gFrame->RequestNewToolbars(
true);
7279 gFrame->RequestNewMasterToolbar(
true);
7286 : wxThread(wxTHREAD_JOINABLE) {
7287 m_filename = filename;
7298 newChart->SetNativeScale(m_scale);
7299 newChart->SetFullExtent(m_ext);
7301 newChart->FindOrCreateSenc(m_filename);
7306 wxString m_filename;
7312static double chart_dist(
int index) {
7318 if (cte.GetBBox().Contains(
gLat,
gLon))
7323 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7324 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7325 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7328 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7329 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7331 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7337WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7338static int CompareInts(
int n1,
int n2) {
7339 double d1 = chart_dist(n1);
7340 double d2 = chart_dist(n2);
7341 return (
int)(d1 - d2);
7346 wxString chart_path;
7351WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7353#include <wx/arrimpl.cpp>
7356void ParseAllENC(wxWindow *parent) {
7357 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7365 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7368 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7370 idx_sorted_by_distance.Add(i);
7374 if (count == 0)
return;
7376 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7382 ArrayOfCompressTargets ct_array;
7383 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7384 int i = idx_sorted_by_distance[j];
7387 double distance = chart_dist(i);
7389 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7392 pct->distance = distance;
7393 pct->chart_path = filename;
7395 ct_array.push_back(pct);
7398 int thread_count = 0;
7401 if (g_nCPUCount > 0)
7402 thread_count = g_nCPUCount;
7404 thread_count = wxThread::GetCPUCount();
7406 if (thread_count < 1) {
7415 for(
int t = 0; t < thread_count; t++)
7419 wxGenericProgressDialog *prog =
nullptr;
7423 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7424 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7426 prog =
new wxGenericProgressDialog();
7428 prog->SetFont(*qFont);
7430 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7431 count + 1, parent, style);
7440 prog->ShowWindowModal();
7449 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7450 wxString filename = ct_array[j].chart_path;
7451 double distance = ct_array[j].distance;
7452 int index =
ChartData->FinddbIndex(filename);
7453 if (index < 0)
continue;
7456 ext.NLAT = cte.GetLatMax();
7457 ext.SLAT = cte.GetLatMin();
7458 ext.WLON = cte.GetLonMin();
7459 ext.ELON = cte.GetLonMax();
7461 int scale = cte.GetScale();
7464 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7467 if (wxThread::IsMain()) {
7469 wxSize sz = prog->GetSize();
7474 prog->Update(count, msg, &skip);
7486 newChart->SetNativeScale(
scale);
7487 newChart->SetFullExtent(ext);
7488 newChart->DisableBackgroundSENC();
7490 newChart->FindOrCreateSenc(filename,
7494 if (wxThread::IsMain()) {
7495 msg.Printf(_(
"ENC Completed."));
7497 prog->Update(count, msg, &skip);
7507 for (
int t = 0;; t = (t + 1) % thread_count) {
7514 if (!workers[t]->IsAlive()) {
7527#if defined(__WXMSW__) || defined(__WXOSX__)
7534 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.