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());
473wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
475BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
476EVT_CLOSE(MyFrame::OnCloseWindow)
477EVT_MENU(wxID_EXIT, MyFrame::OnExit)
478EVT_SIZE(MyFrame::OnSize)
479EVT_MOVE(MyFrame::OnMove)
480EVT_ICONIZE(MyFrame::OnIconize)
481EVT_MENU(-1, MyFrame::OnToolLeftClick)
482EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
484EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
485EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
486EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
488EVT_MAXIMIZE(MyFrame::OnMaximize)
489EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
490 MyFrame::RequestNewToolbarArgEvent)
491EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
493EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
494EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
495EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
497#ifdef wxHAS_POWER_EVENTS
498EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
499EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
500EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
501EVT_POWER_RESUME(MyFrame::OnResume)
512static
void onBellsFinishedCB(
void *ptr) {
513 auto framePtr =
static_cast<MyFrame *
>(ptr);
515 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
516 wxPostEvent(framePtr, ev);
521 auto msg = ev.GetString().ToStdString();
522 auto ¬eman = NotificationManager::GetInstance();
523 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
526static NmeaLog *GetDataMonitor() {
527 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
528 return dynamic_cast<NmeaLog *
>(w);
531MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
532 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
533 OpenFileFunc open_gpx_file)
535 m_connections_dlg(nullptr),
537 m_pauidockart(pauidockart),
538 m_rest_server(rest_server),
539 m_open_gpx_file(open_gpx_file) {
551 m_ulLastNMEATicktime = 0;
552 m_data_monitor->Hide();
554 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
558 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
561 InitTimer.SetOwner(
this, INIT_TIMER);
563 m_initializing =
false;
564 m_toolbar_callbacks.render_gl_textures =
566 [&](
ocpnDC &dc,
float *coords,
float *uv) {
567 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
568 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
571 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
575 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
578 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
581 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
584 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
587 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
589 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
598 m_bTimeIsSet =
false;
599 m_bdefer_resize =
false;
602 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
603 COGFilterTable[i] = NAN;
604 SOGFilterTable[i] = NAN;
606 m_last_bGPSValid =
false;
607 m_last_bVelocityValid =
false;
617 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
622 double process_noise_std = 1.0;
623 double measurement_noise_std = 0.5;
627 m_ChartUpdatePeriod = 1;
632 log_callbacks.log_is_active = [&]() {
633 auto log = GetDataMonitor();
634 return log && log->IsVisible();
636 log_callbacks.log_message = [&](
Logline ll) {
637 NmeaLog *monitor = GetDataMonitor();
640 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
643 ais_callbacks.confirm_stop_track = []() {
644 int r = OCPNMessageBox(
646 _(
"This AIS target has Persistent tracking selected by MMSI "
648 "A Persistent track recording will therefore be restarted for this "
650 "Do you instead want to stop Persistent tracking for this target?"),
651 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
652 return r == wxID_YES;
654 ais_callbacks.get_target_mmsi = []() {
655 auto alert_dlg_active =
657 assert(alert_dlg_active);
658 return alert_dlg_active->Get_Dialog_MMSI();
666 wxLogMessage(
" **** Connect stuff");
672 Connect(wxEVT_OCPN_MSG,
673 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
681 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
689#if defined(__WXGTK__) || defined(__WXQT__)
690 wxIcon app_icon(opencpn);
698 wxDynamicLibrary dllUser32(
"user32.dll");
700 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
701 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
706 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
711 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
712 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
714 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
715 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
716 [&](wxCommandEvent) { Refresh(); });
717 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
719 m_update_statusbar_listener.Init(
720 GuiEvents::GetInstance().gframe_update_status_bar,
722 m_center_aistarget_listener.Init(
723 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
724 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
725 CenterAisTarget(ais_target);
727 m_reload_charts_listener.Init(
728 GuiEvents::GetInstance().on_finalize_chartdbs,
729 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
733 EnableFullScreenView();
735 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
741 FrameTenHzTimer.Stop();
756 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
762void MyFrame::FreezeCharts() {
765 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
767 if (cc && !cc->IsFrozen()) cc->Freeze();
771void MyFrame::CenterAisTarget(
772 const std::shared_ptr<const AisTargetData> &ais_target) {
780 double factor = cc->GetScaleValue() / 5000.0;
781 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
787void MyFrame::ThawCharts() {
790 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
792 if (cc && cc->IsFrozen()) cc->Thaw();
799 switch (event.type) {
800 case SENC_BUILD_STARTED:
803 case SENC_BUILD_DONE_NOERROR:
805 chart =
event.m_ticket->m_chart;
807 chart->PostInit(FULL_INIT, global_color_scheme);
809 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
811 if (cc) cc->ClearS52PLIBStateHash();
816 delete event.m_ticket;
818 case SENC_BUILD_DONE_ERROR:
826void MyFrame::RebuildChartDatabase() {
827 bool b_SetInitialPoint =
false;
830 ArrayOfCDI ChartDirArray;
831 pConfig->LoadChartDirArray(ChartDirArray);
833 if (ChartDirArray.GetCount()) {
838 _(
"OpenCPN needs to update the chart database from config file "
842 wxICON_INFORMATION | wxOK);
850 _(
"Rebuilding chart database from configuration file entries..."));
854 wxString dummy1 = _(
"Elapsed time : ");
855 wxString dummy2 = _(
"Estimated time : ");
856 wxString dummy3 = _(
"Remaining time : ");
857 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
858 _(
"OpenCPN Chart Update"), line, 100, NULL,
859 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
860 wxPD_REMAINING_TIME);
863 ChartData->SaveBinary(ChartListFileName);
873void MyFrame::OnBellsFinished(wxCommandEvent &event) {
874 int bells = wxMin(m_BellsToPlay, 2);
875 if (bells <= 0)
return;
877 wxString soundfile =
"sounds";
878 appendOSDirSlash(&soundfile);
879 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
880 soundfile.Prepend(g_Platform->GetSharedDataDir());
881 wxLogMessage(
"Using bells sound file: " + soundfile);
883 o_sound::Sound *sound = bells_sound[bells - 1];
884 sound->SetFinishedCallback(onBellsFinishedCB,
this);
885 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
886 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
887 sound->Load(soundfile);
888 if (!sound->IsOk()) {
889 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
893 m_BellsToPlay -= bells;
896void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
898void MyFrame::OnMaximize(wxMaximizeEvent &event) {
905void MyFrame::ReloadAllVP() {
906 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
908 if (cc) cc->ReloadVP();
912void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
913 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
916 global_color_scheme = cs;
919 case GLOBAL_COLOR_SCHEME_DAY:
922 case GLOBAL_COLOR_SCHEME_DUSK:
925 case GLOBAL_COLOR_SCHEME_NIGHT:
926 SchemeName =
"NIGHT";
933 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
935 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
936 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
937 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
938 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
939 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
941 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
970 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
971 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
975 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
977 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
981 user_colors::GetMapByScheme(SchemeName.ToStdString());
986 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
989 cc->SetColorScheme(cs);
990 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
991 cc->HideChartInfoWindow();
992 cc->SetQuiltChartHiLiteIndex(-1);
998 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1010 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1023 if (g_pais_query_dialog_active) {
1024 bool b_isshown = g_pais_query_dialog_active->IsShown();
1025 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1026 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1028 g_pais_query_dialog_active->Close();
1031 g_pais_query_dialog_active->
Create(
1032 this, -1, _(
"AIS Target Query"),
1033 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1034 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1035 g_pais_query_dialog_active->UpdateText();
1036 if (b_isshown) g_pais_query_dialog_active->Show();
1041 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1045 ApplyGlobalColorSchemetoStatusBar();
1047 UpdateAllToolbars(cs);
1052 bool btoolbarFull = g_bmasterToolbarFull;
1058 if (!btoolbarFull) {
1060 RequestNewMasterToolbar();
1062 CollapseGlobalToolbar();
1065 RequestNewMasterToolbar();
1074void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1075 if (m_pStatusBar != NULL) {
1076 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1077 m_pStatusBar->ClearBackground();
1088void MyFrame::CancelAllMouseRoute() {
1090 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1092 if (cc) cc->CancelMouseRoute();
1096void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1104 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1112 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1121 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1124 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1125 config_array.Item(i)->canvas = NULL;
1131 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1136 switch (g_canvasConfig) {
1150 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1151 cc->GetglCanvas()->Show();
1154 config_array.Item(0)->canvas = cc;
1158 cc->ApplyCanvasConfig(config_array.Item(0));
1162 cc->ConfigureChartBar();
1163 cc->SetColorScheme(global_color_scheme);
1164 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1165 cc->SetShowGPS(
true);
1168 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1170 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1186 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1189 config_array.Item(0)->canvas = cc;
1191 cc->ApplyCanvasConfig(config_array.Item(0));
1194 cc->ConfigureChartBar();
1195 cc->SetColorScheme(global_color_scheme);
1196 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1197 cc->SetShowGPS(
false);
1200 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1202 .CaptionVisible(
false)
1204 .CloseButton(
false);
1213 if (config_array.GetCount() < 2) {
1215 pcc->configIndex = 1;
1219 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1220 config_array.Add(pcc);
1223 config_array.Item(1)->canvas = cc;
1225 cc->ApplyCanvasConfig(config_array.Item(1));
1228 cc->ConfigureChartBar();
1229 cc->SetColorScheme(global_color_scheme);
1230 cc->SetShowGPS(
true);
1234 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1236 .CaptionVisible(
false)
1238 .CloseButton(
false);
1239 g_pauimgr->GetPane(cc).RightDockable(
true);
1243 config_array.Item(1)->canvasSize =
1244 wxSize(GetClientSize().x / 2, GetClientSize().y);
1245 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1250 if (b_useStoredSize) {
1251 int ccw = config_array.Item(1)->canvasSize.x;
1252 int cch = config_array.Item(1)->canvasSize.y;
1255 if (ccw < GetClientSize().x / 10) {
1256 ccw = GetClientSize().x / 2;
1257 cch = GetClientSize().y;
1260 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1261 cc->SetSize(ccw, cch);
1279 console->SetColorScheme(global_color_scheme);
1284 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1290void MyFrame::RequestNewToolbars(
bool bforcenew) {
1291 if (b_inCloseWindow) {
1295 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1296 PositionIENCToolbar();
1305void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1311void MyFrame::SetAllToolbarScale() {
1312 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1315void MyFrame::SetGPSCompassScale() {
1316 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1320 wxPoint screenPoint = ::wxGetMousePosition();
1323 switch (g_canvasConfig) {
1325 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1328 if (canvas->GetScreenRect().Contains(
1332 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1335 if (canvas->GetScreenRect().Contains(
1342 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1345 if (canvas->GetScreenRect().Contains(
1346 canvas->ScreenToClient(screenPoint)))
1354int MyFrame::GetCanvasIndexUnderMouse() {
1355 wxPoint screenPoint = ::wxGetMousePosition();
1358 switch (g_canvasConfig) {
1360 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1363 if (canvas->GetScreenRect().Contains(
1367 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1370 if (canvas->GetScreenRect().Contains(
1377 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1380 if (canvas->GetScreenRect().Contains(
1381 canvas->ScreenToClient(screenPoint)))
1389bool MyFrame::DropMarker(
bool atOwnShip) {
1396 if (!canvas)
return false;
1403 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1405 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1407 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1418 RefreshAllCanvas(
false);
1423void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1424 if (g_canvasConfig != 0) {
1427 int nTargetGTK = -1;
1429 wxWindow *source = FindFocus();
1435 switch (g_canvasConfig) {
1437 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1440 if (canvas && (canvas == test)) {
1445 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1448 if (canvas && (canvas == test)) {
1456 int nfinalTarget = nTarget;
1458 nfinalTarget = nTargetGTK;
1460 target = ConfigMgr::Get()
1461 .GetCanvasConfigArray()
1466 target->Refresh(
true);
1477void MyFrame::FastClose() {
1479 FrameTenHzTimer.Stop();
1481 FrameTimer1.Start(1);
1485void MyFrame::OnExit(wxCommandEvent &event) {
1489void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1492 if (b_inCloseWindow) {
1502 if (!g_bDeferredInitDone)
return;
1519 if (bDBUpdateInProgress)
return;
1521 b_inCloseWindow =
true;
1523 ::wxSetCursor(wxCURSOR_WAIT);
1527 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1529 if (cc && cc->IsMeasureActive()) {
1530 cc->CancelMeasureRoute();
1535 SendPreShutdownHookToPlugins();
1539 if (g_pAISTargetList) {
1540 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1541 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1542 g_pauimgr->DetachPane(g_pAISTargetList);
1569 SetCursor(wxCURSOR_WAIT);
1571 RefreshAllCanvas(
true);
1577 RestoreScreenBrightness();
1588 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1589 g_iENCToolbarPosY = tbp_incanvas.y;
1590 g_iENCToolbarPosX = tbp_incanvas.x;
1594 g_bframemax = IsMaximized();
1597 FrameTenHzTimer.Stop();
1599 FrameCOGTimer.Stop();
1613 if (g_bAutoAnchorMark) {
1614 bool watching_anchor =
false;
1622 wxDateTime now = wxDateTime::Now();
1623 wxTimeSpan uptime = now.Subtract(g_start_time);
1625 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1626 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1631 if (g_declutter_anchorage) {
1632 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1633 if (pr->GetName().StartsWith(
"Anchorage")) {
1634 double a =
gLat - pr->m_lat;
1635 double b =
gLon - pr->m_lon;
1636 double l = sqrt((a * a) + (b * b));
1639 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1641 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1642 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1650 wxString name = now.Format();
1651 name.Prepend(_(
"Anchorage created "));
1657 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1666 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1670 NavObj_dB::GetInstance().Close();
1674 pConfig->DeleteGroup(
"/Routes");
1675 pConfig->DeleteGroup(
"/Marks");
1701 if (g_pAISTargetList) {
1702 g_pAISTargetList->Disconnect_decoder();
1703 g_pAISTargetList->Destroy();
1710 if (RouteManagerDialog::getInstanceFlag()) {
1727 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1729 if (cc) cc->Destroy();
1753 CommBridge::GetInstance().SaveConfig();
1773 auto ®istry = CommDriverRegistry::GetInstance();
1774 registry.CloseAllDrivers();
1777 for (
auto *cp : TheConnectionParams()) {
1782 while (pLayerList->size())
delete *pLayerList->begin();
1786 ReleaseApiListeners();
1789 g_bTempShowMenuBar =
false;
1791#define THREAD_WAIT_SECONDS 5
1801 wxLogMessage(
"Starting compressor pool drain");
1802 wxDateTime now = wxDateTime::Now();
1803 time_t stall = now.GetTicks();
1804 time_t end = stall + THREAD_WAIT_SECONDS;
1807 while (stall < end) {
1808 wxDateTime later = wxDateTime::Now();
1809 stall = later.GetTicks();
1812 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1821 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1827 uninitIXNetSystem();
1831 wxLogMessage(
"gFrame destroyed.");
1834#ifndef USE_ANDROID_GLES2
1835 qDebug() <<
"Calling OnExit()";
1839 wxTheApp->ExitMainLoop();
1842void MyFrame::OnMove(wxMoveEvent &event) {
1843 auto idx = wxDisplay::GetFromWindow(
this);
1856 DEBUG_LOG <<
"Moved to " << idx
1857#if wxCHECK_VERSION(3, 1, 6)
1858 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1859 << wxDisplay(idx).GetPPI().GetY()
1860 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1862 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1863 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1864 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1865 << wxGetDisplaySizeMM().GetY()
1866 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1875 if (g_config_display_size_manual) {
1884 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1887 cc->SetMUIBarPosition();
1896 UpdateGPSCompassStatusBoxes();
1906 PositionIENCToolbar();
1912 g_nframewin_posx = GetPosition().x;
1913 g_nframewin_posy = GetPosition().y;
1916void MyFrame::ProcessCanvasResize() {
1917 UpdateGPSCompassStatusBoxes(
true);
1921 PositionIENCToolbar();
1924 TriggerRecaptureTimer();
1928void MyFrame::TriggerRecaptureTimer() {
1929 m_recaptureTimer.Start(
1930 1000, wxTIMER_ONE_SHOT);
1933void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1935void MyFrame::SetCanvasSizes(wxSize frameSize) {
1939 int cccw = frameSize.x;
1940 int ccch = frameSize.y;
1944 switch (g_canvasConfig) {
1950 cc->GetSize( &cur_width, &cur_height );
1951 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1953 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1955 cc->SetSize( 0, 0, cccw, ccch );
1965 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1966 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1968 ccw = wxMin(ccw, cccw * 8 / 10);
1969 ccw = wxMax(ccw, cccw * 2 / 10);
1973 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1980 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1997void MyFrame::OnIconize(wxIconizeEvent &event) {
2007 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2009 if (cc && cc->GetMUIBar()) {
2010 if (cc->GetMUIBar()->GetCanvasOptions()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2012 cc->GetMUIBar()->PushCanvasOptions();
2021void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2023void MyFrame::ODoSetSize() {
2025 GetClientSize(&x, &y);
2028 if (m_pStatusBar != NULL) {
2029 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2030 int currentCount = m_pStatusBar->GetFieldsCount();
2031 if (currentCount != m_StatusBarFieldCount) {
2032 if ((currentCount > 0) && (currentCount < 7)) {
2035 int widths[] = {2, 2, 2, 2, 2, 2};
2036 m_pStatusBar->SetStatusWidths(currentCount, widths);
2039 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2042 if (m_StatusBarFieldCount) {
2047 if (m_StatusBarFieldCount > 2) {
2048 int widths[] = {-6, -5, -5, -6, -4};
2049 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2050 }
else if (m_StatusBarFieldCount == 2) {
2051 int cwidth = x * 90 / 100;
2052 int widths[] = {100, 100};
2053 widths[0] = cwidth * 6.4 / 10.0;
2054 widths[1] = cwidth * 3.6 / 10.0;
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2057 int widths[] = {100, 100};
2058 widths[0] = x * 90 / 100;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2062 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2063 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2064 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2066 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2068 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2076 m_pStatusBar->GetFieldRect(0, stat_box);
2079 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2081 wxFont sys_font = *wxNORMAL_FONT;
2082 int try_font_size = sys_font.GetPointSize();
2085 int min_font_size = 10;
2095 wxFont *statusBarFont =
2096 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2097 int font_size = statusBarFont->GetPointSize();
2099 font_size = wxMin(font_size,
2102 wxMax(font_size, min_font_size);
2105 font_size = statusBarFont->GetPointSize();
2112 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2113 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2115 int min_height = stat_box.height;
2117 m_pStatusBar->SetFont(*pstat_font);
2118 m_pStatusBar->SetForegroundColour(
2119 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2121 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2123 (min_height >> 1) * 2;
2124 m_pStatusBar->SetMinHeight(min_height);
2133 SetCanvasSizes(GetClientSize());
2135 UpdateGPSCompassStatusBoxes(
true);
2137 if (
console) PositionConsole();
2140 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2142 if (cc) cc->FormatPianoKeys();
2148 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2149 GetPrimaryCanvas()->GetCompass()->GetRect());
2175 options_lastWindowSize = wxSize(0, 0);
2176 options_lastWindowPos = wxPoint(0, 0);
2183 if (!b_inCloseWindow) {
2186 resizeAndroidPersistents();
2190 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2191 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2197void MyFrame::PositionConsole() {
2198#if defined(__WXMSW__) || defined(__WXMAC__)
2199 if (NULL == GetPrimaryCanvas())
return;
2201 int ccx, ccy, ccsx, ccsy, consx, consy;
2206 consoleHost->GetSize(&ccsx, &ccsy);
2207 consoleHost->GetPosition(&ccx, &ccy);
2209 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2210 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2211 consoleHost = GetPrimaryCanvas();
2216 if (consoleHost->GetCompass()) {
2217 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2219 if (compass_rect.y < 100)
2220 yOffset = compass_rect.y + compass_rect.height + 45;
2224 wxSize csz =
console->GetSize();
2228 wxPoint screen_pos =
2229 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2232 if (NULL == GetPrimaryCanvas())
return;
2234 int ccx, ccy, ccsx, ccsy, consx, consy;
2239 consoleHost->GetSize(&ccsx, &ccsy);
2240 consoleHost->GetPosition(&ccx, &ccy);
2242 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2243 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2244 consoleHost = GetPrimaryCanvas();
2247 int yTopOffset = 60;
2248 int yBottomOffset = 0;
2250 if (consoleHost->GetCompass()) {
2251 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2253 if (compass_rect.y < 100)
2254 yTopOffset = compass_rect.y + compass_rect.height;
2256 if (consoleHost->GetMUIBar()) {
2257 wxRect mui_rect = consoleHost->GetMUIBarRect();
2258 yBottomOffset = ccsy - mui_rect.y;
2262 wxSize csz =
console->GetSize();
2265 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2267 if (consy < yAvail) {
2268 yFinal = (yAvail - consy) / 2;
2269 yFinal += yTopOffset;
2270 }
else if (
console->GetCDI()->IsShown()) {
2271 int cdi_height =
console->GetCDI()->GetSize().y;
2272 int consy_no_cdi = consy - cdi_height;
2273 yFinal = (yAvail - consy_no_cdi) / 2;
2274 yFinal += yTopOffset;
2278 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2283void MyFrame::UpdateAllFonts() {
2292 DestroyPersistentDialogs();
2294 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2299void MyFrame::DestroyPersistentDialogs() {
2300 if (g_pais_query_dialog_active) {
2301 g_pais_query_dialog_active->Hide();
2302 g_pais_query_dialog_active->Destroy();
2303 g_pais_query_dialog_active = NULL;
2331void MyFrame::RefreshGroupIndices() {
2333 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2335 if (cc) cc->canvasRefreshGroupIndex();
2339void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2342 switch (event.GetId()) {
2343 case ID_MENU_SCALE_OUT:
2344 DoStackDelta(GetPrimaryCanvas(), 1);
2348 case ID_MENU_SCALE_IN:
2349 DoStackDelta(GetPrimaryCanvas(), -1);
2353 case ID_MENU_ZOOM_IN: {
2354 if (GetFocusCanvas()) {
2355 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2360 case ID_MENU_ZOOM_OUT: {
2361 if (GetFocusCanvas()) {
2362 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2367 case ID_MENU_ROUTE_NEW: {
2368 if (GetFocusCanvas()) {
2369 if (0 == GetFocusCanvas()->m_routeState) {
2370 GetFocusCanvas()->StartRoute();
2372 GetFocusCanvas()->FinishRoute();
2378 case ID_MENU_TOOL_MEASURE: {
2379 GetPrimaryCanvas()->StartMeasureRoute();
2383 case ID_MENU_TOOL_NMEA_DBG_LOG:
2384 m_data_monitor->Show();
2385 m_data_monitor->Raise();
2388 case ID_MENU_TOOL_IO_MONITOR:
2389 m_data_monitor->Show();
2392 case ID_MENU_MARK_BOAT: {
2397 case ID_MENU_MARK_CURSOR: {
2402 case ID_MENU_NAV_FOLLOW: {
2403 if (
gFrame->GetPrimaryCanvas())
2404 gFrame->GetPrimaryCanvas()->TogglebFollow();
2408 case ID_MENU_CHART_OUTLINES: {
2409 ToggleChartOutlines(GetFocusCanvas());
2413 case ID_MENU_CHART_QUILTING: {
2414 ToggleQuiltMode(GetFocusCanvas());
2418 case ID_MENU_UI_CHARTBAR: {
2419 ToggleChartBar(GetFocusCanvas());
2423 case ID_MENU_ENC_TEXT:
2425 ToggleENCText(GetFocusCanvas());
2428 case ID_MENU_ENC_LIGHTS: {
2429 ToggleLights(GetFocusCanvas());
2432 case ID_MENU_ENC_SOUNDINGS: {
2433 ToggleSoundings(GetFocusCanvas());
2436 case ID_MENU_ENC_ANCHOR: {
2437 ToggleAnchor(GetFocusCanvas());
2440 case ID_MENU_ENC_DATA_QUALITY: {
2441 ToggleDataQuality(GetFocusCanvas());
2444 case ID_MENU_SHOW_NAVOBJECTS: {
2445 ToggleNavobjects(GetFocusCanvas());
2449 case ID_MENU_AIS_TARGETS: {
2450 ToggleAISDisplay(GetFocusCanvas());
2453 case ID_MENU_AIS_MOORED_TARGETS: {
2454 g_bHideMoored = !g_bHideMoored;
2457 case ID_MENU_AIS_SCALED_TARGETS: {
2458 ToggleAISMinimizeTargets(GetFocusCanvas());
2462 case ID_MENU_AIS_TARGETLIST: {
2463 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2467 case ID_MENU_AIS_TRACKS: {
2468 g_bAISShowTracks = !g_bAISShowTracks;
2469 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2473 case ID_MENU_AIS_CPADIALOG: {
2474 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2475 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2476 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2477 if (g_bAIS_CPA_Alert) {
2478 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2483 case ID_MENU_AIS_CPASOUND: {
2484 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2485 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2489 case ID_MENU_AIS_CPAWARNING: {
2490 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2491 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2495 case wxID_PREFERENCES:
2502 case ID_SETTINGS_NEW: {
2507 case ID_SETTINGS_DELETE: {
2510 g_pOptions =
nullptr;
2514 case ID_RELOAD_CHARTS: {
2519 case ID_MENU_SETTINGS_BASIC: {
2521 androidDisableFullScreen();
2523 DoAndroidPreferences();
2530 case ID_MENU_UI_FULLSCREEN: {
2535 case ID_MENU_SHOW_CURRENTS: {
2536 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2537 GetFocusCanvas()->ReloadVP();
2538 GetFocusCanvas()->Refresh(
false);
2542 case ID_MENU_SHOW_TIDES: {
2543 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2544 GetFocusCanvas()->ReloadVP();
2545 GetFocusCanvas()->Refresh(
false);
2565 case ID_MENU_UI_COLSCHEME:
2566 case ID_COLSCHEME: {
2567 ToggleColorScheme();
2576 case ID_MENU_OQUIT: {
2581 case ID_MENU_ROUTE_MANAGER:
2582 case ID_ROUTEMANAGER: {
2605 case ID_MENU_NAV_TRACK:
2607 if (!g_bTrackActive) {
2609 g_bTrackCarryOver =
true;
2612 g_bTrackCarryOver =
false;
2613 RefreshAllCanvas(
true);
2618 case ID_MENU_CHART_NORTHUP: {
2619 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2622 case ID_MENU_CHART_COGUP: {
2623 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2626 case ID_MENU_CHART_HEADUP: {
2627 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2631 case ID_MENU_MARK_MOB:
2637 case ID_MASTERTOGGLE: {
2639 wxString tip = _(
"Show Toolbar");
2640 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2642 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2644 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2647 if (g_bmasterToolbarFull)
2648 m_nMasterToolCountShown =
2652 m_nMasterToolCountShown = 2;
2654 m_nMasterToolCountShown =
2657 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2665 case ID_CMD_SELECT_CHART_TYPE: {
2666 selectChartDisplay(event.GetExtraLong(), -1);
2670 case ID_CMD_SELECT_CHART_FAMILY: {
2671 selectChartDisplay(-1, event.GetExtraLong());
2675 case ID_CMD_APPLY_SETTINGS: {
2676 applySettingsString(event.GetString());
2678 androidRestoreFullScreen();
2684 case ID_CMD_NULL_REFRESH: {
2689 case ID_CMD_SETVP: {
2690 setStringVP(event.GetString());
2694 case ID_CMD_INVALIDATE: {
2700 case ID_CMD_POST_JSON_TO_PLUGINS: {
2706 int numErrors = reader.
Parse(event.GetString(), &root);
2707 if (numErrors == 0) {
2708 if (root[
"MessageID"].IsString()) {
2709 wxString MsgID = root[
"MessageID"].
AsString();
2733 ArrayOfPlugInToolbarTools tool_array =
2735 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2737 if (event.GetId() == pttc->id) {
2738 if (pttc->m_pplugin)
2760bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2761 bool viz_now = g_bmasterToolbarFull;
2764 wxString tip = _(
"Show Toolbar");
2766 tip = _(
"Hide Toolbar");
2768 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2771 bool toggle =
false;
2772 if (viz && !g_bmasterToolbarFull)
2775 else if (!viz && g_bmasterToolbarFull)
2779 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2782 if (g_bmasterToolbarFull)
2783 m_nMasterToolCountShown =
2787 m_nMasterToolCountShown = 2;
2789 m_nMasterToolCountShown =
2792 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2798void MyFrame::ScheduleReloadCharts() {
2799 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2800 evt.SetId(ID_RELOAD_CHARTS);
2801 GetEventHandler()->AddPendingEvent(evt);
2804void MyFrame::ScheduleDeleteSettingsDialog() {
2805 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2806 evt.SetId(ID_SETTINGS_DELETE);
2807 GetEventHandler()->AddPendingEvent(evt);
2810void MyFrame::ScheduleSettingsDialog() {
2811 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2812 evt.SetId(ID_SETTINGS);
2813 GetEventHandler()->AddPendingEvent(evt);
2816void MyFrame::ScheduleSettingsDialogNew() {
2817 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2818 evt.SetId(ID_SETTINGS_NEW);
2819 GetEventHandler()->AddPendingEvent(evt);
2822void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2823 UpdateCanvasConfigDescriptors();
2825 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2826 CreateCanvasLayout(
true);
2828 CreateCanvasLayout();
2832 ConfigureStatusBar();
2833 wxSize lastOptSize = options_lastWindowSize;
2838 options_lastWindowSize = lastOptSize;
2842 ScheduleSettingsDialogNew();
2844 ScheduleSettingsDialog();
2849 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2852 int index_hint = -1;
2853 if (i < pathArray.GetCount())
2854 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2855 cc->canvasChartsRefresh(index_hint);
2856 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2865 return GetPrimaryCanvas();
2868void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2869 if (g_bmasterToolbarFull) {
2870#ifndef OCPN_TOOLBAR_ANIMATE
2871 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2874 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2875 m_nMasterToolCountShown++;
2880 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2888#ifndef OCPN_TOOLBAR_ANIMATE
2889 m_nMasterToolCountShown = 1;
2891 if (m_nMasterToolCountShown > 1) {
2892 m_nMasterToolCountShown--;
2896 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2906void MyFrame::InvalidateAllGL() {
2909 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2919void MyFrame::RefreshAllCanvas(
bool bErase) {
2921 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2924 cc->Refresh(bErase);
2929void MyFrame::setStringVP(wxString VPS) {
2934 wxStringTokenizer tkz(VPS,
";");
2936 wxString token = tkz.GetNextToken();
2938 token.ToDouble(&lat);
2940 token = tkz.GetNextToken();
2942 token.ToDouble(&lon);
2944 token = tkz.GetNextToken();
2946 token.ToDouble(&scale_ppm);
2948 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2951void MyFrame::DoSettingsNew() {
2958void MyFrame::DoSettings() {
2963 ApplyGlobalSettings(
true);
2966 bool b_loadHarmonics =
false;
2967 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2970 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2973 if (b_loadHarmonics) LoadHarmonics();
2981 g_bShowChartBar = !g_bShowChartBar;
2983 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2988 if (g_bShowChartBar) {
2990 UpdateControlBar(cc);
2993 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2996void MyFrame::ToggleColorScheme() {
2997 static bool lastIsNight;
2998 ColorScheme s = user_colors::GetColorScheme();
3001 if (lastIsNight && is == 3)
3004 lastIsNight =
false;
3006 if (lastIsNight) is = 2;
3007 if (is == 3) lastIsNight =
true;
3008 s = (ColorScheme)is;
3009 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3011 SetAndApplyColorScheme(s);
3014void MyFrame::ToggleFullScreen() {
3015 bool to = !IsFullScreen();
3020 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3022 ShowFullScreen(to, style);
3025 UpdateAllToolbars(global_color_scheme);
3027 UpdateControlBar(GetPrimaryCanvas());
3029 TriggerRecaptureTimer();
3032void MyFrame::ActivateMOB() {
3034 wxDateTime mob_time = wxDateTime::Now();
3035 wxString mob_label(_(
"MAN OVERBOARD"));
3036 mob_label += _(
" on ");
3037 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3041 pWP_MOB->SetShared(
true);
3043 pWP_MOB->SetWaypointArrivalRadius(
3045 pWP_MOB->SetUseSca(
false);
3047 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3055 new RoutePoint(zlat, zlon, g_default_wp_icon,
3056 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3057 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3062 temp_route->AddPoint(pWP_src);
3063 temp_route->AddPoint(pWP_MOB);
3065 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3075 temp_route->SetRouteArrivalRadius(-1.0);
3081 v[
"GUID"] = temp_route->
m_GUID;
3082 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3083 SendJSONMessageToAllPlugins(msg_id, v);
3086 if (RouteManagerDialog::getInstanceFlag()) {
3094 RefreshAllCanvas(
false);
3096 wxString mob_message(_(
"MAN OVERBOARD"));
3097 mob_message += _(
" Time: ");
3098 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3099 mob_message += _(
" Position: ");
3100 mob_message += toSDMM(1,
gLat);
3102 mob_message += toSDMM(2,
gLon);
3103 wxLogMessage(mob_message);
3105void MyFrame::TrackOn() {
3106 g_bTrackActive =
true;
3114 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3116 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3118 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3121 androidSetTrackTool(
true);
3124 if (RouteManagerDialog::getInstanceFlag()) {
3133 if (name.IsEmpty()) {
3139 name = _(
"(Unnamed Track)");
3143 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3144 SendJSONMessageToAllPlugins(msg_id, v);
3145 g_FlushNavobjChangesTimeout =
3149Track *MyFrame::TrackOff(
bool do_add_point) {
3154 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3156 SendJSONMessageToAllPlugins(msg_id, v);
3165 if (g_bTrackDaily) {
3170 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3171 return_val = pExtendTrack;
3178 g_bTrackActive =
false;
3180 if (RouteManagerDialog::getInstanceFlag()) {
3187 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3189 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3190 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3193 androidSetTrackTool(
false);
3197 m_target_rotate_time = wxInvalidDateTime;
3202void MyFrame::InitializeTrackRestart() {
3203 if (!g_bTrackDaily)
return;
3204 if (m_target_rotate_time.IsValid())
return;
3207 switch (g_track_rotate_time_type) {
3209 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3211 case TIME_TYPE_COMPUTER:
3212 rotate_at = g_track_rotate_time;
3216 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3217 rotate_at = g_track_rotate_time + utc_offset;
3220 if (rotate_at > 86400)
3222 else if (rotate_at < 0)
3225 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3226 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3229 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3230 m_target_rotate_time += wxTimeSpan(24);
3234bool MyFrame::ShouldRestartTrack() {
3236 InitializeTrackRestart();
3238 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3239 m_target_rotate_time += wxTimeSpan(24);
3245void MyFrame::TrackDailyRestart() {
3247 Track *pPreviousTrack = TrackOff(
true);
3254 if (pPreviousTrack) {
3255 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3259 if (RouteManagerDialog::getInstanceFlag()) {
3267void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3269 cc->SetUpMode(mode);
3271 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3272 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3273 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3276 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3281 cc->SetShowENCText(!cc->GetShowENCText());
3283 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3291void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3294 cc->SetENCDisplayCategory(nset);
3296 UpdateGlobalMenuItems();
3307 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3309 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3318 cc->SetShowENCLights(!cc->GetShowENCLights());
3320 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3330void MyFrame::ToggleRocks(
void )
3336 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3337 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3338 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3339 pOLE->nViz = !pOLE->nViz;
3343 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3344 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3345 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3348 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3352 ps52plib->GenerateStateHash();
3359 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3361 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3369 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3371 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3386 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3387 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3392 cc->SetShowAIS(!cc->GetShowAIS());
3393 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3397void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3398 cc->SetAttenAIS(!cc->GetAttenAIS());
3399 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3405 cc->m_bFollow =
true;
3408 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3412 SetChartUpdatePeriod();
3420 cc->m_bFollow =
false;
3422 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3426 SetChartUpdatePeriod();
3429void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3430 cc->SetShowOutlines(!cc->GetShowOutlines());
3432 RefreshAllCanvas(
false);
3436 if (g_bopengl) InvalidateAllGL();
3439 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3442void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3444void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3446 bool enabled = m_pMenuBar->IsEnabled(item_id);
3447 m_pMenuBar->Enable(item_id,
false);
3448 m_pMenuBar->Check(item_id, state);
3449 m_pMenuBar->Enable(item_id, enabled);
3453void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3460void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3461 wxBitmap *bmpRollover) {
3463 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3468void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3469 wxString rolloverSVGfile,
3470 wxString toggledSVGfile) {
3473 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3477void MyFrame::ConfigureStatusBar() {
3479 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3482 UseNativeStatusBar(
false);
3485 if (g_bShowStatusBar) {
3486 if (!m_pStatusBar) {
3488 CreateStatusBar(m_StatusBarFieldCount, 0);
3489 ApplyGlobalColorSchemetoStatusBar();
3494 m_pStatusBar->Destroy();
3495 m_pStatusBar = NULL;
3501void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3502 ConfigureStatusBar();
3504 wxSize lastOptSize = options_lastWindowSize;
3510 options_lastWindowSize = lastOptSize;
3512 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3515void MyFrame::BuildMenuBar() {
3521 bool showMenuBar =
true;
3523 bool showMenuBar = g_bShowMenuBar;
3535 m_pMenuBar =
new wxMenuBar();
3536 RegisterGlobalMenuItems();
3537 SetMenuBar(m_pMenuBar);
3541 UpdateGlobalMenuItems();
3546 m_pMenuBar->Destroy();
3552void MyFrame::RegisterGlobalMenuItems() {
3553 if (!m_pMenuBar)
return;
3555 wxMenu *nav_menu =
new wxMenu();
3556 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3557 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3558 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3559 nav_menu->AppendSeparator();
3560 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3561 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3562 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3563 nav_menu->AppendSeparator();
3565 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3566 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3568 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3569 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3571 nav_menu->AppendSeparator();
3572 nav_menu->Append(ID_MENU_SCALE_IN,
3573 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3574 nav_menu->Append(ID_MENU_SCALE_OUT,
3575 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3577 nav_menu->AppendSeparator();
3578 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3580 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3582 wxMenu *view_menu =
new wxMenu();
3584 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3585 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3586 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3587 _menuText(_(
"Show Chart Outlines"),
"O"));
3589 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3590 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3591 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3592 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3594 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3595 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3597 view_menu->AppendSeparator();
3599 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3600 _menuText(_(
"Show ENC text"),
"T"));
3601 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3602 _menuText(_(
"Show ENC Lights"),
"L"));
3603 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3604 _menuText(_(
"Show ENC Soundings"),
"S"));
3605 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3606 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3607 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3608 _menuText(_(
"Show ENC Data Quality"),
"U"));
3609 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3610 _menuText(_(
"Show Navobjects"),
"V"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3613 _menuText(_(
"Show ENC text"),
"Alt-T"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3615 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3617 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3619 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3621 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3622 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3623 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3625 view_menu->AppendSeparator();
3626 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3627 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3628 view_menu->AppendSeparator();
3630 view_menu->Append(ID_MENU_UI_COLSCHEME,
3631 _menuText(_(
"Change Color Scheme"),
"C"));
3633 view_menu->Append(ID_MENU_UI_COLSCHEME,
3634 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3637 view_menu->AppendSeparator();
3639 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3640 _menuText(_(
"Toggle Full Screen"),
"F11"));
3642 m_pMenuBar->Append(view_menu, _(
"&View"));
3644 wxMenu *ais_menu =
new wxMenu();
3645 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3646 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3647 _(
"Attenuate less critical AIS targets"));
3648 ais_menu->AppendSeparator();
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3650 _(
"Hide Moored AIS Targets"));
3651 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3652 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3653 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3656 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3657 _menuText(_(
"Show CPA Warnings"),
"W"));
3659 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3660 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3663 ais_menu->AppendSeparator();
3664 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3665 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3667 wxMenu *tools_menu =
new wxMenu();
3668 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3669 _menuText(_(
"Data Monitor"),
"E"));
3671 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3672 _menuText(_(
"Measure Distance"),
"M"));
3674 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3675 _menuText(_(
"Measure Distance"),
"Alt-M"));
3678 tools_menu->AppendSeparator();
3679 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3680 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3681 tools_menu->AppendSeparator();
3682 tools_menu->Append(ID_MENU_MARK_BOAT,
3683 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3684 tools_menu->Append(ID_MENU_MARK_CURSOR,
3685 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3686 tools_menu->AppendSeparator();
3690 _menuText(_(
"Drop MOB Marker"),
3692 tools_menu->AppendSeparator();
3693 tools_menu->Append(wxID_PREFERENCES,
3694 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3696 tools_menu->Append(ID_MENU_MARK_MOB,
3697 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3698 tools_menu->AppendSeparator();
3699 tools_menu->Append(wxID_PREFERENCES,
3700 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3702 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3705 wxMenu *window_menu =
new wxMenu();
3706 m_pMenuBar->Append(window_menu, _(
"&Window"));
3709 wxMenu *help_menu =
new wxMenu();
3710 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3711 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3712 m_pMenuBar->Append(help_menu, _(
"&Help"));
3715 UpdateGlobalMenuItems();
3718void MyFrame::UpdateGlobalMenuItems() {
3719 if (!m_pMenuBar)
return;
3721 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3722 ->Check(GetPrimaryCanvas()->m_bFollow);
3723 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3724 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3725 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3726 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3727 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3728 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3729 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3730 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3731 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3732 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3733 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3734 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3735 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3736 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3737 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3739 if (g_bAIS_CPA_Alert) {
3740 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3741 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3744 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3748 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3749 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3752 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3753 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3754 ->Check(ps52plib->GetShowSoundings());
3756 bool light_state =
false;
3758 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3760 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3761 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3762 light_state = (pOLE->nViz == 1);
3767 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3768 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3772 DisCat nset = ps52plib->GetDisplayCategory();
3773 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3774 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3775 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3776 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3777 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3778 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3779 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3781 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3782 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3783 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3788void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3789 if (!m_pMenuBar)
return;
3791 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3793 if (cc->GetUpMode() == NORTH_UP_MODE)
3794 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3795 else if (cc->GetUpMode() == COURSE_UP_MODE)
3796 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3798 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3800 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3801 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3802 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3803 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3804 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3805 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3806 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3807 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3808 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3809 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3810 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3811 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3812 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3813 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3814 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3817 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3818 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3821 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3823 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3824 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3829 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3833 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3834 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3835 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3836 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3837 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3838 ->Check(cc->GetShowENCDataQual());
3839 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3841 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3842 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3843 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3848void MyFrame::InvalidateAllCanvasUndo() {
3850 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3852 if (cc) cc->undo->InvalidateUndo();
3856void MyFrame::SubmergeAllCanvasToolbars() {
3858 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3860 if (cc) cc->SubmergeToolbar();
3864void MyFrame::SurfaceAllCanvasToolbars() {
3865 if (g_bshowToolbar) {
3867 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3869 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3876void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3878 if (lon > 180.0) lon -= 360.0;
3883 cc->JumpToPosition(lat, lon,
scale);
3886 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3890void MyFrame::UpdateCanvasConfigDescriptors() {
3892 for (
unsigned int i = 0;
3893 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3894 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3902 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3903 cc->GroupID = chart->m_groupIndex;
3906 cc->
bQuilt = chart->GetQuiltMode();
3913 cc->
bFollow = chart->m_bFollow;
3918 int upmode = chart->GetUpMode();
3919 if (upmode == COURSE_UP_MODE)
3921 else if (upmode == HEAD_UP_MODE)
3928void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3929 if (!RBBox.GetValid())
return;
3931 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3932 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3935 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3936 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3944 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3945 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3947 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3948 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3950 cc->GetSize(&ww, &wh);
3952 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3954 ppm = wxMin(ppm, 1.0);
3960void MyFrame::PrepareOptionsClose(
options *settings,
3961 int settings_return_value) {
3963 options_lastPage = settings->lastPage;
3968 if (options_lastPage == 1) options_lastPage = 0;
3970 options_subpage = settings->lastSubPage;
3971 options_lastWindowPos = settings->lastWindowPos;
3972 options_lastWindowSize = settings->lastWindowSize;
3975 androidEnableBackButton(
true);
3976 androidEnableOptionsMenu(
true);
3977 androidRestoreFullScreen();
3978 androidEnableRotation();
3983void MyFrame::DoOptionsDialog() {
3985 AbstractPlatform::ShowBusySpinner();
3988 pConfig->SetPath(
"/Settings");
3989 pConfig->Read(
"OptionsSizeX", &sx, -1);
3990 pConfig->Read(
"OptionsSizeY", &sy, -1);
3992 wxWindow *optionsParent =
this;
3994 optionsParent = GetPrimaryCanvas();
3997 callbacks.prepare_close = [&](
options *me,
int changes) {
3998 PrepareOptionsClose(me, changes);
4000 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4001 ProcessOptionsDialog(changes, workdir_list);
4004 wxPoint(-1, -1), wxSize(sx, sy));
4006 AbstractPlatform::HideBusySpinner();
4010 g_options->SetInitChartDir(*pInit_Chart_Dir);
4014 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4015 g_options->SetWorkDirListPtr(pWorkDirArray);
4021 prev_locale = g_locale;
4022 g_options->SetInitialPage(options_lastPage, options_subpage);
4025 g_options->lastWindowPos = options_lastWindowPos;
4026 if (options_lastWindowPos != wxPoint(0, 0)) {
4028 g_options->SetSize(options_lastWindowSize);
4032 if (options_lastWindowSize != wxSize(0, 0)) {
4033 g_options->SetSize(options_lastWindowSize);
4038 androidEnableBackButton(
false);
4039 androidEnableOptionsMenu(
false);
4040 androidDisableFullScreen();
4048 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4051 wxString chart_file_name;
4052 if (cc->GetQuiltMode()) {
4053 int dbi = cc->GetQuiltRefChartdbIndex();
4054 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4056 if (cc->m_singleChart)
4057 chart_file_name = cc->m_singleChart->GetFullPath();
4060 pathArray.Add(chart_file_name);
4066 last_canvasConfig = g_canvasConfig;
4069 g_last_ChartScaleFactor = g_ChartScaleFactor;
4075void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4076 bool b_need_refresh =
false;
4079 if ((rr & VISIT_CHARTS) &&
4080 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4082 UpdateChartDatabaseInplace(*pNewDirArray,
4083 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4086 b_need_refresh =
true;
4091 if (rr & STYLE_CHANGED) {
4094 _(
"Please restart OpenCPN to activate language or style changes."),
4095 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4098 bool charts_updating =
4099 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4100 if (!charts_updating) RefreshGroupIndices();
4102 if (rr & TIDES_CHANGED) {
4108 if (rr & S52_CHANGED) {
4109 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4120 g_Platform->GetDisplayDPmm());
4123 double stuffcog = NAN;
4124 double stuffsog = NAN;
4125 if (!std::isnan(
gCog)) stuffcog =
gCog;
4126 if (!std::isnan(
gSog)) stuffsog =
gSog;
4128 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4129 COGFilterTable[i] = stuffcog;
4130 SOGFilterTable[i] = stuffsog;
4133 SetChartUpdatePeriod();
4135 if (rr & GL_CHANGED) {
4139 b_need_refresh =
true;
4142 if (rr & S52_CHANGED) {
4143 b_need_refresh =
true;
4147 if (rr & REBUILD_RASTER_CACHE) {
4149 GetPrimaryCanvas()->Disable();
4151 GetPrimaryCanvas()->Enable();
4156 if (g_config_display_size_manual &&
4164 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4171 int rrt = rr & S52_CHANGED;
4173 (rrt == S52_CHANGED) ||
4174 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4184 ps52plib->SetScaleFactorExp(
4185 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4186 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4190 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4192 if (cc) cc->ApplyGlobalSettings();
4200 if (!charts_updating) {
4201 bool ztc = g_bEnableZoomToCursor;
4202 g_bEnableZoomToCursor =
false;
4204 if (!GetPrimaryCanvas()->IsFrozen())
4206 g_bEnableZoomToCursor = ztc;
4211 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4220 SetGPSCompassScale();
4222 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4225 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4226 if (!charts_updating) cc->UpdateCanvasControlBar();
4229 UpdateGPSCompassStatusBoxes();
4231 SetAllToolbarScale();
4232 RequestNewToolbars();
4234 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4237 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4240 cc->RebuildCursors();
4245 bool b_masterScaleChange =
false;
4246 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4247 b_masterScaleChange =
true;
4249 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4250 RequestNewMasterToolbar(
true);
4252 bool bMuiChange =
false;
4258 if (b_masterScaleChange || bMuiChange) {
4260 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4263 cc->ProcessNewGUIScale();
4269 if (rr & LOCALE_CHANGED) {
4270 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4272 rr |= NEED_NEW_OPTIONS;
4281 g_last_ChartScaleFactor = g_ChartScaleFactor;
4286bool MyFrame::CheckGroup(
int igroup) {
4287 if (igroup == 0)
return true;
4291 if (!pGroup->m_element_array.size())
4294 for (
const auto &elem : pGroup->m_element_array) {
4295 for (
unsigned int ic = 0;
4296 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4297 auto &cte =
ChartData->GetChartTableEntry(ic);
4298 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4300 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4307bool MyFrame::ScrubGroupArray() {
4312 bool b_change =
false;
4313 unsigned int igroup = 0;
4314 while (igroup < g_pGroupArray->GetCount()) {
4315 bool b_chart_in_element =
false;
4318 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4319 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4321 for (
unsigned int ic = 0;
4322 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4323 auto &cte =
ChartData->GetChartTableEntry(ic);
4324 wxString chart_full_path = cte.GetFullSystemPath();
4326 if (chart_full_path.StartsWith(element_root)) {
4327 b_chart_in_element =
true;
4333 if (!b_chart_in_element) {
4334 wxString test_string =
"GSHH";
4335 if (element_root.Upper().Contains(test_string))
4336 b_chart_in_element =
true;
4339 if (!b_chart_in_element)
4341 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4353void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4355 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4357 if (cc && (cc != ccThis)) cc->Refresh();
4362void MyFrame::ChartsRefresh() {
4365 AbstractPlatform::ShowBusySpinner();
4367 bool b_run = FrameTimer1.IsRunning();
4370 FrameTenHzTimer.Stop();
4373 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4376 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4377 if (cc->GetQuiltMode()) {
4378 currentIndex = cc->GetQuiltReferenceChartIndex();
4380 cc->canvasChartsRefresh(currentIndex);
4384 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4385 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4387 AbstractPlatform::HideBusySpinner();
4390void MyFrame::InvalidateAllQuilts() {
4391 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4394 cc->InvalidateQuilt();
4395 cc->SetQuiltRefChart(-1);
4396 cc->m_singleChart = NULL;
4401bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4403 const wxString &ChartListFileName) {
4404 bool b_run = FrameTimer1.IsRunning();
4406 FrameTenHzTimer.Stop();
4408 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4409 FrameCOGTimer.Stop();
4412 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4415 cc->InvalidateQuilt();
4416 cc->SetQuiltRefChart(-1);
4417 cc->m_singleChart = NULL;
4427 AbstractPlatform::ShowBusySpinner();
4430 wxString longmsg = _(
"OpenCPN Chart Update");
4432 ".................................................................."
4435 Updateprog =
new wxGenericProgressDialog();
4438 Updateprog->SetFont(*qFont);
4440 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4441 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4442 wxPD_REMAINING_TIME);
4444 DimeControl(Updateprog);
4449 wxLogMessage(
"Starting chart database Update...");
4453 m_gshhg_chart_loc = gWorldMapLocation;
4454 gWorldMapLocation = wxEmptyString;
4458 AbstractPlatform::HideBusySpinner();
4462void MyFrame::FinalizeChartDBUpdate() {
4464 bool b_groupchange = ScrubGroupArray();
4466 RefreshGroupIndices();
4468 if (b_groupchange) {
4469 pConfig->DestroyConfigGroups();
4474 ScheduleReloadCharts();
4479 cc->ToggleCanvasQuiltMode();
4481 bool cur_mode = cc->GetQuiltMode();
4483 if( !cc->GetQuiltMode() )
4484 cc->SetQuiltMode(
true );
4486 if( cc->GetQuiltMode() ) {
4487 cc->SetQuiltMode(
false );
4488 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4492 if( cur_mode != cc->GetQuiltMode() ){
4498 g_bQuiltEnable = cc->GetQuiltMode();
4502 ps52plib->GenerateStateHash();
4510 DoStackDelta(cc, -1);
4516 DoStackDelta(cc, 1);
4519void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4521void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4523void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4525 cc->DoCanvasStackDelta(direction);
4529void MyFrame::PositionIENCToolbar() {
4533 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4535 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4543void MyFrame::OnInitTimer(wxTimerEvent &event) {
4546 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4550 wxLog::FlushActive();
4552 switch (m_iInitCount++) {
4557 if (g_bInlandEcdis) {
4558 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4559 double range_set = 500.;
4561 range = wxRound(range * 10) / 10.;
4565 else if (range > 2000.)
4567 else if (range > 1600.)
4569 else if (range > 1200.)
4571 else if (range > 800.)
4576 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4580 g_Platform->SetFullscreen(g_bFullscreen);
4584 RebuildChartDatabase();
4585 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4588 cc->SetGroupIndex(0,
false);
4596 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4597 CHART_FAMILY_RASTER)) {
4602 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4603 CHART_FAMILY_VECTOR)) {
4616 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4619 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4621 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4624 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4628 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4629 NavObj_dB::GetInstance().LoadNavObjects();
4632 if (!g_AW1GUID.IsEmpty()) {
4635 if (!g_AW2GUID.IsEmpty()) {
4641 appendOSDirSlash(&layerdir);
4642 layerdir.Append(
"layers");
4644 if (wxDir::Exists(layerdir)) {
4646 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4647 wxLogMessage(laymsg);
4648 pConfig->LoadLayers(layerdir);
4658 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4672 3 * GetCharHeight());
4674 m_data_monitor->Center();
4682 pConfig->SetPath(
"/Settings");
4683 pConfig->Read(
"OptionsSizeX", &sx, -1);
4684 pConfig->Read(
"OptionsSizeY", &sy, -1);
4686 wxWindow *optionsParent =
this;
4688 optionsParent = GetPrimaryCanvas();
4694 BuildiENCToolbar(
true, m_toolbar_callbacks);
4701 if (!g_params.empty()) {
4702 for (
size_t n = 0; n < g_params.size(); n++) {
4703 wxString path = g_params[n];
4704 if (::wxFileExists(path)) {
4706 pSet->load_file(path.fn_str());
4709 pSet->LoadAllGPXObjects(
4710 !pSet->IsOpenCPN(), wpt_dups,
4712 LLBBox box = pSet->GetBBox();
4713 if (box.GetValid()) {
4714 CenterView(GetPrimaryCanvas(), box);
4723 InitAppMsgBusListener();
4728 auto loader = PluginLoader::GetInstance();
4729 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4730 if (!b_haveWMM)
gVar = g_UserVar;
4738 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4741 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4743 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4746 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4750 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4751 NavObj_dB::GetInstance().LoadNavObjects();
4754 if (!g_AW1GUID.IsEmpty()) {
4757 if (!g_AW2GUID.IsEmpty()) {
4763 appendOSDirSlash(&layerdir);
4764 layerdir.Append(
"layers");
4766 if (wxDir::Exists(layerdir)) {
4768 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4769 wxLogMessage(laymsg);
4770 pConfig->LoadLayers(layerdir);
4777 wxLogMessage(
"OnInitTimer...Last Call");
4781 RequestNewMasterToolbar();
4783 PositionIENCToolbar();
4785 g_bDeferredInitDone =
true;
4795 GetPrimaryCanvas()->SetFocus();
4796 GetPrimaryCanvas()->Enable();
4803 if (b_reloadForPlugins) {
4809 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4811 if (cc) cc->SetFirstAuto(
true);
4819 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4821 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4825 cc->CheckGroupValid();
4830 androidEnableBackButton(
true);
4831 androidEnableRotation();
4832 androidEnableOptionItems(
true);
4838 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4844 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4846 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4848 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4854 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4856 wxLog::FlushActive();
4858 RefreshAllCanvas(
true);
4859 UsbWatchDaemon::GetInstance().Start();
4865void MyFrame::InitAppMsgBusListener() {
4866 auto &msgbus = AppMsgBus::GetInstance();
4869 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4870 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4874 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4875 HandleBasicNavMsg(basicnav_msg);
4879 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4880 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4884 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4885 HandleGPSWatchdogMsg(msg);
4892void MyFrame::ReleaseApiListeners() {}
4897 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4898 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4899 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4900 server.open_file_cb = [&](
const std::string &path) {
4901 return m_open_gpx_file(path);
4908void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4909 if (msg->gps_watchdog <= 0) {
4910 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4914 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4919 if (m_fix_start_time.IsValid()) {
4920 wxDateTime now = wxDateTime::Now();
4921 wxTimeSpan span = now - m_fix_start_time;
4922 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4923 auto ¬eman = NotificationManager::GetInstance();
4924 wxString msg = _(
"GNSS Position fix lost");
4925 noteman.AddNotification(NotificationSeverity::kCritical,
4927 m_fix_start_time = wxInvalidDateTime;
4931 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4932 bool last_bVelocityValid = bVelocityValid;
4933 bVelocityValid =
false;
4940void MyFrame::CalculateCOGAverage() {
4942 if (!std::isnan(
gCog)) {
4945 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4948 double sum = 0., count = 0;
4950 double adder = COGTable[i];
4951 if (std::isnan(adder))
continue;
4953 if (fabs(adder -
g_COGAvg) > 180.) {
4967 else if (sum >= 360.)
4976void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4977 m_fixtime = msg->time;
4978 double hdt_data_interval = 0;
4979 double fix_time_interval = 0;
4981 double msgtime = msg->set_time.tv_sec;
4982 double m1 = msg->set_time.tv_nsec / 1e9;
4985 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4986 ((msg->vflag & POS_VALID) == POS_VALID)) {
4988 if (!m_fix_start_time.IsValid()) {
4989 m_fix_start_time = wxDateTime::Now();
4994 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4997 fix_time_gt_last = fix_time_gt;
4998 uint64_t fix_time_gt_now =
4999 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5000 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5004 double implied_sog = dist / (fix_time_interval / 3600);
5009 gLat_gt_m1 = gLat_gt;
5010 gLon_gt_m1 = gLon_gt;
5014 fix_time_gt = fix_time_gt_now;
5018 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5019 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5020 gCog_gt_m1 = gCog_gt;
5030 if (!std::isnan(gCog_gt_m1)) {
5032 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5039 if ((fix_time_gt - fix_time_gt_last) > .08) {
5044 if (gCog_gt > gCog_gt_m1) {
5045 if ((gCog_gt - gCog_gt_m1) > 180.)
5050 if ((gCog_gt_m1 - gCog_gt) > 180.)
5055 difft = fabs(gCog_gt - gCog_gt_m1);
5056 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5064 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5065 tentative_cog_rate_gt *= 1e9;
5066 cog_rate_gt = tentative_cog_rate_gt;
5074 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5077static double hdt_avg;
5078 double hdt_norm =
gHdt;
5079 if(
gHdt > 180) hdt_norm -= 360;
5082 hdt_avg += hdt_norm * 0.1;
5087 if (!std::isnan(
gHdt)) {
5089 uint64_t hdt_time_gt_last = hdt_time_gt;
5090 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5091 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5094 if (hdt_data_interval > .09) {
5096 gHdt_gt_m1 = gHdt_gt;
5099 if (!std::isnan(gHdt_gt_m1)) {
5101 double tentative_hdt_rate_gt =
5102 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5103 tentative_hdt_rate_gt *= 1e9;
5105 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5106 hdt_rate_gt = tentative_hdt_rate_gt;
5114 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5117 CalculateCOGAverage();
5125 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5126 if ((msg->vflag & POS_VALID) == POS_VALID)
5131 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5133 bVelocityValid =
true;
5137void MyFrame::UpdateStatusBar() {
5140 unsigned long uiCurrentTickCount;
5141 m_MMEAeventTime.SetToCurrent();
5142 uiCurrentTickCount =
5143 m_MMEAeventTime.GetMillisecond() / 100;
5144 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5145 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5146 m_ulLastNMEATicktime = uiCurrentTickCount;
5148 if (m_tick_idx++ > 6) m_tick_idx = 0;
5153 if (NULL != GetStatusBar()) {
5156 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5159 wxString s1(tick_buf, wxConvUTF8);
5161 s1 += toSDMM(1,
gLat);
5163 s1 += toSDMM(2,
gLon);
5165 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5169 if (!std::isnan(
gSog))
5170 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5172 sogcog.Printf(
"SOG --- ");
5176 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5178 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5180 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5181 (
int)toMagnetic(
gCog), 0x00B0);
5183 cogs.Printf((
"COG ---%c"), 0x00B0);
5185 sogcog.Append(cogs);
5186 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5191void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5192 MemFootTimer.Stop();
5194 int memsize = GetApplicationMemoryUse();
5197 printf(
"Memsize: %d \n", memsize);
5200 if (memsize > (g_MemFootMB * 1000)) {
5204 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5205 unsigned int nCache = pCache->GetCount();
5208 for (
unsigned int i = 0; i < nCache; i++) {
5218 for (
unsigned int i = 0; i < nCache - 1; i++) {
5219 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5221 pcea[i] = pcea[i + 1];
5232 unsigned int idelete = 0;
5233 unsigned int idelete_max = pCache->GetCount();
5236 unsigned int minimum_cache = 1;
5237 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5239 while ((memsize > (g_MemFootMB * 1000)) &&
5240 (pCache->GetCount() > minimum_cache) &&
5241 (idelete < idelete_max)) {
5242 int memsizeb = memsize;
5246 memsize = GetApplicationMemoryUse();
5247 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5255 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5260void MyFrame::CheckToolbarPosition() {
5263 static bool bMaximized;
5265 if (IsMaximized() && !bMaximized) {
5272 PositionIENCToolbar();
5273 }
else if (!IsMaximized() && bMaximized) {
5281 PositionIENCToolbar();
5286void MyFrame::ProcessUnitTest() {
5287 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5294 cc->m_bFollow =
false;
5296 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5297 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5300 if (cc->m_groupIndex > 0) {
5301 while (ut_index < ChartData->GetChartTableEntries() &&
5302 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5306 if (ut_index < ChartData->GetChartTableEntries()) {
5310 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5311 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5318 if (cc->GetQuiltMode()) {
5319 if (cc->IsChartQuiltableRef(ut_index))
5320 cc->SelectQuiltRefdbChart(ut_index);
5322 cc->SelectdbChart(ut_index);
5325 if (g_unit_test_1) {
5333 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5334 cte->GetLatMin(), cte->GetLonMax(), NULL,
5338 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5339 cte->GetLatMax(), cte->GetLonMin(), NULL,
5342 cc->GetSize(&ww, &wh);
5343 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5345 ppm = wxMin(ppm, 1.0);
5352 if (ut_index > ut_index_max) exit(0);
5363 bool b_rotate =
false;
5365 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5368 if (!b_rotate && !g_btenhertz)
return;
5370 bool b_update =
false;
5372 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5375 struct timespec now;
5376 clock_gettime(CLOCK_MONOTONIC, &now);
5377 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5378 double diffc = diff / 1e9;
5381 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5382 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5383 if (gCog_tentative < 0.) gCog_tentative += 360.;
5384 gCog = gCog_tentative;
5388 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5389 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5390 double diffc = diff / 1e9;
5391 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5395 if (gSog_gt && !std::isnan(gCog_gt)) {
5396 double delta_t = diffc / 3600;
5397 double distance = gSog_gt * delta_t;
5400 double angr = gCog_gt / 180 * M_PI;
5401 double latr = gLat_gt * M_PI / 180;
5402 double D = distance / 3443;
5403 double sD = sin(D), cD = cos(D);
5404 double sy = sin(latr), cy = cos(latr);
5405 double sa = sin(angr), ca = cos(angr);
5407 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5408 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5418 if (cc) cc->DoCanvasCOGSet();
5427 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5428 cc->DoCanvasUpdate();
5437 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5440bool MyFrame::ProcessQuitFlag() {
5444 FrameTenHzTimer.Stop();
5446 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5447 if (top) top->Close(
true);
5454void MyFrame::ProcessDeferredTrackOn() {
5457 if (g_bDeferredStartTrack) {
5458 if (!g_bTrackActive) {
5461 g_bDeferredStartTrack =
false;
5464 g_bDeferredStartTrack =
false;
5469void MyFrame::ProcessAnchorWatch() {
5477 double d = g_nAWMax;
5480 bool toofar =
false;
5481 bool tooclose =
false;
5482 if (d >= 0.0) toofar = (dist * 1852. > d);
5483 if (d < 0.0) tooclose = (dist * 1852 < -d);
5485 if (tooclose || toofar)
5486 AnchorAlertOn1 =
true;
5488 AnchorAlertOn1 =
false;
5490 AnchorAlertOn1 =
false;
5498 double d = g_nAWMax;
5501 bool toofar =
false;
5502 bool tooclose =
false;
5503 if (d >= 0) toofar = (dist * 1852. > d);
5504 if (d < 0) tooclose = (dist * 1852 < -d);
5506 if (tooclose || toofar)
5507 AnchorAlertOn2 =
true;
5509 AnchorAlertOn2 =
false;
5511 AnchorAlertOn2 =
false;
5514 AnchorAlertOn1 =
true;
5517void MyFrame::SendFixToPlugins() {
5528 GPSData.
nSats = g_SatsInView;
5530 wxDateTime tCheck((time_t)m_fixtime);
5531 if (tCheck.IsValid()) {
5540 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5543 SendPositionFixToAllPlugIns(&GPSData);
5547void MyFrame::ProcessLogAndBells() {
5550 wxDateTime lognow = wxDateTime::Now();
5551 int hourLOC = lognow.GetHour();
5552 int minuteLOC = lognow.GetMinute();
5554 int minuteUTC = lognow.GetMinute();
5555 int second = lognow.GetSecond();
5557 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5558 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5559 (minuteUTC == 30)) {
5560 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5561 wxString day = lognow.FormatISODate();
5562 wxString utc = lognow.FormatISOTime();
5563 wxString navmsg =
"LOGBOOK: ";
5571 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5575 if (std::isnan(
gCog))
5576 cog.Printf(
"COG ----- ");
5578 cog.Printf(
"COG %10.5f ",
gCog);
5581 if (std::isnan(
gSog))
5582 sog.Printf(
"SOG ----- ");
5584 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5590 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5593 wxLogMessage(navmsg);
5594 g_loglast_time = lognow;
5596 int bells = (hourLOC % 4) * 2;
5597 if (minuteLOC != 0) bells++;
5598 if (!bells) bells = 8;
5600 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5601 m_BellsToPlay = bells;
5602 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5603 wxPostEvent(
this, ev);
5610 CheckToolbarPosition();
5614 if (ProcessQuitFlag())
return;
5616 if (bDBUpdateInProgress)
return;
5619 FrameTenHzTimer.Stop();
5621 ProcessDeferredTrackOn();
5623 ProcessAnchorWatch();
5624 ProcessLogAndBells();
5626 if (ShouldRestartTrack()) TrackDailyRestart();
5629 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5630 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5631 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5637 if (
gSog > 3.0) g_bCruising =
true;
5643 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5645 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5651 bool bnew_view =
false;
5652 if (!g_btenhertz) bnew_view = DoChartUpdate();
5659 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5662 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5665 cc->DrawBlinkObjects();
5668 if (bactiveRouteUpdate) {
5675 cc->SetOwnShipState(SHIP_NORMAL);
5677 if (cc->GetQuiltMode()) {
5678 double erf = cc->GetQuiltMaxErrorFactor();
5679 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5681 if (cc->m_singleChart) {
5682 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5683 cc->SetOwnShipState(SHIP_LOWACCURACY);
5687 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5690 (bVelocityValid != m_last_bVelocityValid) ||
5691 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5692 if (!g_bopengl) cc->UpdateShips();
5700 m_last_bVelocityValid = bVelocityValid;
5705 bool brq_dynamic =
false;
5707 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5708 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5710 if (pic->m_enabled && pic->m_init_state) {
5711 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5718 if (brq_dynamic) bnew_view =
true;
5722 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5725 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5730 if (cc->GetglCanvas()) {
5732 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5735 if (cc->m_bFollow) {
5736 cc->DoCanvasUpdate();
5753 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5767 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5768 g_pais_query_dialog_active->UpdateText();
5771 if (g_pAISTargetList && (0 == (g_tick % (5))))
5772 g_pAISTargetList->UpdateAISTargetList();
5775 UpdateGPSCompassStatusBoxes();
5780 console->RefreshConsoleData();
5787 if (m_bdefer_resize) {
5788 if (0 == (g_tick % (5))) {
5789 printf(
"___RESIZE\n");
5790 SetSize(m_defer_size);
5792 m_bdefer_resize =
false;
5799 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5801 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5802 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5806double MyFrame::GetMag(
double a,
double lat,
double lon) {
5807 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5808 auto loader = PluginLoader::GetInstance();
5809 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5816 wxDateTime now = wxDateTime::Now();
5817 SendJSON_WMM_Var_Request(lat, lon, now);
5818 if (fabs(gQueryVar) < 360.0)
5819 Variance = gQueryVar;
5821 return toMagnetic(a, Variance);
5824bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5830 v[
"Year"] = date.GetYear();
5831 v[
"Month"] = date.GetMonth();
5832 v[
"Day"] = date.GetDay();
5834 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5840void MyFrame::TouchAISActive() {
5842 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5844 if (cc) cc->TouchAISToolActive();
5848void MyFrame::UpdateAISTool() {
5852 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5854 if (cc) cc->UpdateAISTBTool();
5859void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5861 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5863 if (cc) cc->SetbTCUpdate(
true);
5866 RefreshAllCanvas(
false);
5871void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5875 bool b_rotate =
false;
5876 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5878 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5882 FrameCOGTimer.Stop();
5889 int period_ms = 100;
5891 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5894void MyFrame::DoCOGSet() {
5896 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5898 if (cc) cc->DoCanvasCOGSet();
5902void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5908 wxFont oldfont = pdc->GetFont();
5910 pdc->SetFont(*pFont);
5911 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5912 pdc->SetBackgroundMode(wxTRANSPARENT);
5914 pdc->DrawText(str, x, y + 1);
5915 pdc->DrawText(str, x, y - 1);
5916 pdc->DrawText(str, x + 1, y);
5917 pdc->DrawText(str, x - 1, y);
5919 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5921 pdc->DrawText(str, x, y);
5923 pdc->SetFont(oldfont);
5927void MyFrame::UpdateRotationState(
double rotation) {
5929 g_bCourseUp =
false;
5931 if (fabs(rotation) > .001) {
5932 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5933 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5935 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5938 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5939 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5941 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5945 UpdateGPSCompassStatusBoxes(
true);
5949void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5951 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5953 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5959int MyFrame::GetApplicationMemoryUse() {
5965 wxWindow *fWin = wxWindow::FindFocus();
5967 wxArrayString outputArray;
5968 wxString cmd(
"ps --no-headers -o vsize ");
5969 unsigned long pid = wxGetProcessId();
5971 cmd1.Printf(
"%ld", pid);
5973 wxExecute(cmd, outputArray);
5975 if (outputArray.GetCount()) {
5976 wxString s = outputArray.Item(0);
5978 if (s.ToLong(&vtmp)) memsize = vtmp;
5981 if (fWin) fWin->SetFocus();
5987 PROCESS_MEMORY_COUNTERS pmc;
5989 unsigned long processID = wxGetProcessId();
5991 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5993 if (NULL == hProcess)
return 0;
5995 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6013 memsize = pmc.WorkingSetSize / 1024;
6016 CloseHandle(hProcess);
6023double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6024 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6027void MyFrame::SetChartUpdatePeriod() {
6030 g_ChartUpdatePeriod = 0;
6035 bool bskewdc =
false;
6036 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6039 if (!g_bopengl && !cc->GetVP().b_quilt) {
6040 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6042 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6046 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6048 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6053 cc->UpdateCanvasControlBar();
6056void MyFrame::selectChartDisplay(
int type,
int family) {
6058 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6060 if (cc) cc->selectCanvasChartDisplay(type, family);
6063 UpdateGlobalMenuItems();
6072bool MyFrame::DoChartUpdate() {
6073 bool return_val =
false;
6076 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6078 if (cc) return_val |= cc->DoCanvasUpdate();
6084void MyFrame::MouseEvent(wxMouseEvent &event) {
6086 event.GetPosition(&x, &y);
6091#include <mach/mach.h>
6092#include <mach/message.h>
6093#include <mach/kern_return.h>
6094#include <mach/task_info.h>
6096#include <malloc/malloc.h>
6103#if defined(__linux__)
6104#include "sys/types.h"
6105#include "sys/sysinfo.h"
6108void MyFrame::DoPrint(
void) {
6110 g_PrintingInProgress =
true;
6113 GetPrimaryCanvas()->GetglCanvas()->Render();
6114 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6124 printer.Initialize(wxLANDSCAPE);
6125 printer.EnablePageNumbers(
false);
6126 printer.Print(
this, &printout);
6144 g_PrintingInProgress =
false;
6147 GetPrimaryCanvas()->SetFocus();
6153 wxString message_ID =
event.GetID();
6154 wxString message_JSONText =
event.GetJSONText();
6162 if (message_ID ==
"WMM_VARIATION_BOAT") {
6170 int numErrors = reader.
Parse(message_JSONText, &root);
6171 if (numErrors > 0) {
6177 wxString decl = root[
"Decl"].
AsString();
6179 decl.ToDouble(&decl_val);
6185 if (message_ID ==
"WMM_VARIATION") {
6193 int numErrors = reader.
Parse(message_JSONText, &root);
6194 if (numErrors > 0) {
6200 wxString decl = root[
"Decl"].
AsString();
6202 decl.ToDouble(&decl_val);
6204 gQueryVar = decl_val;
6207 if (message_ID ==
"GRIB_TIMELINE") {
6210 int numErrors = r.
Parse(message_JSONText, &v);
6212 if (numErrors > 0) {
6213 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6218 wxDateTime oldTimeSource = gTimeSource;
6220 if (v[
"Day"].AsInt() == -1) {
6221 gTimeSource = wxInvalidDateTime;
6222 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6224 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6225 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6226 v[
"Second"].AsInt());
6230 if (oldTimeSource != gTimeSource) {
6232 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6234 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6239 cc->pCwin->Refresh(
false);
6245 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6248 wxString trk_id = wxEmptyString;
6250 int numErrors = reader.
Parse(message_JSONText, &root);
6251 if (numErrors > 0)
return;
6256 v[
"Track_ID"] = trk_id;
6258 wxString name = wxEmptyString;
6259 if (ptrack->m_GUID == trk_id) {
6260 name = ptrack->GetName();
6261 if (name.IsEmpty()) {
6267 name = _(
"(Unnamed Track)");
6274 v[
"TotalNodes"] = ptrack->GetnPoints();
6275 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6277 v[
"lat"] = tp->m_lat;
6278 v[
"lon"] = tp->m_lon;
6281 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6282 SendJSONMessageToAllPlugins(msg_id, v);
6288 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6289 SendJSONMessageToAllPlugins(msg_id, v);
6291 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6294 wxString guid = wxEmptyString;
6296 int numErrors = reader.
Parse(message_JSONText, &root);
6297 if (numErrors > 0) {
6306 wxString name = wxEmptyString;
6308 if ((*it)->m_GUID == guid) {
6309 name = (*it)->m_RouteNameString;
6310 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6316 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6317 itp != (*it)->pRoutePointList->end(); itp++) {
6318 w[i][
"lat"] = (*itp)->m_lat;
6319 w[i][
"lon"] = (*itp)->m_lon;
6320 w[i][
"Name"] = (*itp)->GetName();
6321 w[i][
"Description"] = (*itp)->GetDescription();
6322 w[i][
"GUID"] = (*itp)->m_GUID;
6323 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6325 auto node = (*itp)->m_HyperlinkList->begin();
6326 if (node != (*itp)->m_HyperlinkList->end()) {
6328 while (node != (*itp)->m_HyperlinkList->end()) {
6330 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6331 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6332 httpLink->DescrText;
6339 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6340 SendJSONMessageToAllPlugins(msg_id, v);
6347 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6348 SendJSONMessageToAllPlugins(msg_id, v);
6349 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6354 int numErrors = reader.
Parse(message_JSONText, &root);
6355 if (numErrors > 0)
return;
6358 wxString str = root[
"mode"].
AsString();
6359 if (str ==
"Track") route =
false;
6364 for (RouteList::iterator it =
pRouteList->begin();
6366 wxString name = (*it)->m_RouteNameString;
6367 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6369 v[i][
"error"] =
false;
6370 v[i][
"name"] = name;
6371 v[i][
"GUID"] = (*it)->m_GUID;
6372 v[i][
"active"] = (*it)->IsActive();
6377 wxString name = ptrack->GetName();
6378 if (name.IsEmpty()) {
6384 name = _(
"(Unnamed Track)");
6386 v[i][
"error"] =
false;
6387 v[i][
"name"] = name;
6388 v[i][
"GUID"] = ptrack->m_GUID;
6393 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6394 SendJSONMessageToAllPlugins(msg_id, v);
6397 v[0][
"error"] =
true;
6398 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6399 SendJSONMessageToAllPlugins(msg_id, v);
6401 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6403 v[0][
"error"] =
true;
6406 v[0][
"error"] =
false;
6407 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6408 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6409 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6410 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6411 v[0][
"active_waypoint_lat"] =
6413 v[0][
"active_waypoint_lon"] =
6417 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6418 SendJSONMessageToAllPlugins(msg_id, v);
6422void MyFrame::FilterCogSog() {
6423 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6425 double cog_last =
gCog;
6428 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6429 COGFilterTable[i] = COGFilterTable[i - 1];
6430 COGFilterTable[0] = cog_last;
6433 if (!std::isnan(cog_last)) {
6435 double sum = 0., count = 0;
6436 for (
int i = 0; i < g_COGFilterSec; i++) {
6437 double adder = COGFilterTable[i];
6438 if (std::isnan(adder))
continue;
6440 if (fabs(adder - cog_last) > 180.) {
6441 if ((adder - cog_last) > 0.)
6454 else if (sum >= 360.)
6461 double sog_last =
gSog;
6464 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6465 SOGFilterTable[i] = SOGFilterTable[i - 1];
6466 SOGFilterTable[0] = sog_last;
6469 if (!std::isnan(
gSog)) {
6470 double sum = 0., count = 0;
6471 for (
int i = 0; i < g_SOGFilterSec; i++) {
6472 if (std::isnan(SOGFilterTable[i]))
continue;
6474 sum += SOGFilterTable[i];
6484void MyFrame::LoadHarmonics() {
6487 ptcmgr->LoadDataSources(TideCurrentDataSet);
6489 bool b_newdataset =
false;
6492 for (
auto a :
ptcmgr->GetDataSet()) {
6493 bool b_foundi =
false;
6494 for (
auto b : TideCurrentDataSet) {
6501 b_newdataset =
true;
6506 for (
auto a : TideCurrentDataSet) {
6507 bool b_foundi =
false;
6508 for (
auto b :
ptcmgr->GetDataSet()) {
6515 b_newdataset =
true;
6520 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6524void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6525 if (!ptarget)
return;
6528 wxDateTime mob_time = wxDateTime::Now();
6529 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6530 mob_label += _(
" on ");
6531 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6534 mob_label, wxEmptyString);
6535 pWP_MOB->SetShared(
true);
6537 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6539 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6541 pWP_MOB->SetUseSca(
false);
6549 wxString(_(
"Own ship")), wxEmptyString);
6551 pWP_MOB->SetUseSca(
false);
6558 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6574 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6575 SendJSONMessageToAllPlugins(msg_id, v);
6578 if (RouteManagerDialog::getInstanceFlag()) {
6585 RefreshAllCanvas(
false);
6587 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6588 mob_message += _(
" Time: ");
6589 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6590 mob_message += _(
" Ownship Position: ");
6591 mob_message += toSDMM(1,
gLat);
6593 mob_message += toSDMM(2,
gLon);
6594 mob_message += _(
" MOB Position: ");
6595 mob_message += toSDMM(1, ptarget->Lat);
6597 mob_message += toSDMM(2, ptarget->Lon);
6598 wxLogMessage(mob_message);
6601void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6605 OwnPoint->m_lat =
gLat;
6606 OwnPoint->m_lon =
gLon;
6608 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6613 MOB_Point->m_lat = ptarget->Lat;
6614 MOB_Point->m_lon = ptarget->Lon;
6616 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6617 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6619 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6620 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6623 RefreshAllCanvas(
false);
6626 wxDateTime mob_time = wxDateTime::Now();
6628 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6629 mob_message += _(
" Time: ");
6630 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6631 mob_message += _(
" Ownship Position: ");
6632 mob_message += toSDMM(1,
gLat);
6634 mob_message += toSDMM(2,
gLon);
6635 mob_message += _(
" MOB Position: ");
6636 mob_message += toSDMM(1, ptarget->Lat);
6638 mob_message += toSDMM(2, ptarget->Lon);
6640 wxLogMessage(mob_message);
6644void MyFrame::applySettingsString(wxString settings) {
6646 int last_UIScaleFactor = g_GUIScaleFactor;
6647 bool previous_expert = g_bUIexpert;
6648 g_last_ChartScaleFactor = g_ChartScaleFactor;
6649 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6652 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6658 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6660 if (rr & S52_CHANGED) {
6662 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6664 ->ClearCNSYLUPArray();
6665 ps52plib->GenerateStateHash();
6669 ProcessOptionsDialog(rr, pNewDirArray);
6674 bool b_newToolbar =
false;
6676 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6678 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6680 if (rr & TOOLBAR_CHANGED) {
6681 b_newToolbar =
true;
6686 if (previous_expert && !g_bUIexpert) {
6687 androidForceFullRepaint();
6691 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6695 SetGPSCompassScale();
6697 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6699 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6701 UpdateGPSCompassStatusBoxes(
true);
6704 AbstractPlatform::ShowBusySpinner();
6706 SetAllToolbarScale();
6710 AbstractPlatform::HideBusySpinner();
6712 RequestNewMasterToolbar(
true);
6719 UpdateControlBar(GetPrimaryCanvas());
6725 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6728#ifdef wxHAS_POWER_EVENTS
6729void MyFrame::OnSuspending(wxPowerEvent &event) {
6733 wxLogMessage(
"System suspend starting...");
6736void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6739 wxLogMessage(
"System is going to suspend.");
6742void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6745 wxLogMessage(
"System suspend was cancelled.");
6748int g_last_resume_ticks;
6749void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6750 wxDateTime now = wxDateTime::Now();
6751 wxLogMessage(
"System resumed from suspend.");
6753 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6756 wxLogMessage(
"Restarting streams.");
6757 g_last_resume_ticks = now.GetTicks();
6761 g_pMUX->ClearStreams();
6763 g_pMUX->StartAllStreams();
6772 if (IsMaximized()) {
6777 wxSize sz = GetSize();
6778 SetSize(wxSize(sz.x - 1, sz.y));
6790void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6791 bool btbRebuild =
false;
6793 bool b_reshow =
true;
6796 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6797 if ((ff > 0.01f) || bforcenew) {
6807 long orient = g_Platform->GetDefaultToolbarOrientation();
6808 wxWindow *toolbarParent =
this;
6810 toolbarParent = GetPrimaryCanvas();
6813 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6814 m_toolbar_callbacks);
6816 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6823 g_bmasterToolbarFull =
true;
6827 CreateMasterToolbar();
6842bool MyFrame::CollapseGlobalToolbar() {
6844 m_nMasterToolCountShown = 1;
6848 g_bmasterToolbarFull =
false;
6864 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6865 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6866 tic->m_bRequired =
true;
6871 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6872 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6876 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6877 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6878 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6883 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6884 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6888 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6889 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6890 _(
"Enable Tracking"),
"MUI_track");
6894 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6895 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6907 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6908 _(
"Print Chart"),
"MUI_print");
6912 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6913 _(
"About OpenCPN"),
"MUI_help");
6917 AddDefaultPositionPlugInTools();
6921 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6922 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6933 ArrayOfPlugInToolbarTools tool_array =
6935 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6937 if (!pttc->b_viz)
continue;
6939 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6942 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6943 if (g_bTrackActive) {
6944 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6951bool MyFrame::CheckAndAddPlugInTool() {
6959 if (!tb)
return false;
6961 int n_tools = tb->GetToolsCount();
6965 ArrayOfPlugInToolbarTools tool_array =
6968 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6970 if (pttc->position == n_tools) {
6971 wxBitmap *ptool_bmp;
6973 switch (global_color_scheme) {
6974 case GLOBAL_COLOR_SCHEME_DAY:
6975 ptool_bmp = pttc->bitmap_day;
6978 case GLOBAL_COLOR_SCHEME_DUSK:
6979 ptool_bmp = pttc->bitmap_dusk;
6981 case GLOBAL_COLOR_SCHEME_NIGHT:
6982 ptool_bmp = pttc->bitmap_night;
6985 ptool_bmp = pttc->bitmap_day;
6990 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6992 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6993 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6994 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6995 tic->m_bPlugin =
true;
7004 while (CheckAndAddPlugInTool()) {
7010bool MyFrame::AddDefaultPositionPlugInTools() {
7017 ArrayOfPlugInToolbarTools tool_array =
7020 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7024 if (!pttc->b_viz)
continue;
7026 if (pttc->position == -1)
7028 wxBitmap *ptool_bmp;
7030 switch (global_color_scheme) {
7031 case GLOBAL_COLOR_SCHEME_DAY:
7032 ptool_bmp = pttc->bitmap_day;
7034 case GLOBAL_COLOR_SCHEME_DUSK:
7035 ptool_bmp = pttc->bitmap_dusk;
7037 case GLOBAL_COLOR_SCHEME_NIGHT:
7038 ptool_bmp = pttc->bitmap_night;
7041 ptool_bmp = pttc->bitmap_day;
7046 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7048 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7049 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7050 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7051 tic->m_bPlugin =
true;
7070typedef struct _MSW_COLOR_SPEC {
7072 wxString S52_RGB_COLOR;
7076MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7077 {COLOR_MENUTEXT,
"UITX1", 0},
7078 {COLOR_BTNSHADOW,
"UIBCK", 0},
7081void SaveSystemColors() {
7095 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7096 while (pcspec->COLOR_NAME != -1) {
7097 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7102void RestoreSystemColors() {
7103 int element[NCOLORS];
7104 int rgbcolor[NCOLORS];
7107 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7108 while (pcspec->COLOR_NAME != -1) {
7109 element[i] = pcspec->COLOR_NAME;
7110 rgbcolor[i] = pcspec->SysRGB_COLOR;
7115 if (pSetSysColors) {
7116 pSetSysColors(i, (
unsigned long *)&element[0],
7117 (
unsigned long *)&rgbcolor[0]);
7123void SetSystemColors(ColorScheme cs) {
7125 int element[NCOLORS];
7126 int rgbcolor[NCOLORS];
7128 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7129 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7130 while (pcspec->COLOR_NAME != -1) {
7131 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7132 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7133 element[i] = pcspec->COLOR_NAME;
7139 pSetSysColors(i, (
unsigned long *)&element[0],
7140 (
unsigned long *)&rgbcolor[0]);
7144 RestoreSystemColors();
7151static const WORD MAX_CONSOLE_LINES =
7156void RedirectIOToConsole()
7161 wxIntPtr lStdHandle;
7163 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7173 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7174 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7175 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7179 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7180 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7181 fp = _fdopen(hConHandle,
"w");
7183 setvbuf(stdout, NULL, _IONBF, 0);
7187 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7188 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7189 fp = _fdopen(hConHandle,
"r");
7191 setvbuf(stdin, NULL, _IONBF, 0);
7195 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7196 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7197 fp = _fdopen(hConHandle,
"w");
7199 setvbuf(stderr, NULL, _IONBF, 0);
7210 FontMgr::Get().SetLocale(g_locale);
7231 if (g_pais_query_dialog_active) {
7232 g_pais_query_dialog_active->Destroy();
7233 g_pais_query_dialog_active = NULL;
7236 auto alert_dlg_active =
7238 if (alert_dlg_active) {
7239 alert_dlg_active->Destroy();
7240 g_pais_alert_dialog_active =
nullptr;
7243 if (g_pAISTargetList) {
7245 g_pAISTargetList->Disconnect_decoder();
7246 g_pAISTargetList->Destroy();
7247 g_pAISTargetList = NULL;
7251 if (gFrame->m_pMenuBar) {
7252 gFrame->SetMenuBar(NULL);
7253 gFrame->m_pMenuBar->Destroy();
7254 gFrame->m_pMenuBar = NULL;
7256 gFrame->BuildMenuBar();
7259 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7261 if (cc) cc->CanvasApplyLocale();
7266 wxString perspective;
7268 pConfig->Read(
"AUIPerspective", &perspective);
7282 bool bno_load =
false;
7283 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7285 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7286 wxAuiPaneInfo pane = pane_array_val[i];
7287 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7293 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7298 gFrame->RequestNewToolbars(
true);
7299 gFrame->RequestNewMasterToolbar(
true);
7306 : wxThread(wxTHREAD_JOINABLE) {
7307 m_filename = filename;
7318 newChart->SetNativeScale(m_scale);
7319 newChart->SetFullExtent(m_ext);
7321 newChart->FindOrCreateSenc(m_filename);
7326 wxString m_filename;
7332static double chart_dist(
int index) {
7338 if (cte.GetBBox().Contains(
gLat,
gLon))
7343 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7344 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7345 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7348 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7349 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7351 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7357WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7358static int CompareInts(
int n1,
int n2) {
7359 double d1 = chart_dist(n1);
7360 double d2 = chart_dist(n2);
7361 return (
int)(d1 - d2);
7366 wxString chart_path;
7371WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7373#include <wx/arrimpl.cpp>
7376void ParseAllENC(wxWindow *parent) {
7377 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7385 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7388 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7390 idx_sorted_by_distance.Add(i);
7394 if (count == 0)
return;
7396 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7402 ArrayOfCompressTargets ct_array;
7403 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7404 int i = idx_sorted_by_distance[j];
7407 double distance = chart_dist(i);
7409 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7412 pct->distance = distance;
7413 pct->chart_path = filename;
7415 ct_array.push_back(pct);
7418 int thread_count = 0;
7421 if (g_nCPUCount > 0)
7422 thread_count = g_nCPUCount;
7424 thread_count = wxThread::GetCPUCount();
7426 if (thread_count < 1) {
7435 for(
int t = 0; t < thread_count; t++)
7439 wxGenericProgressDialog *prog =
nullptr;
7443 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7444 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7446 prog =
new wxGenericProgressDialog();
7448 prog->SetFont(*qFont);
7450 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7451 count + 1, parent, style);
7460 prog->ShowWindowModal();
7469 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7470 wxString filename = ct_array[j].chart_path;
7471 double distance = ct_array[j].distance;
7472 int index =
ChartData->FinddbIndex(filename);
7473 if (index < 0)
continue;
7476 ext.NLAT = cte.GetLatMax();
7477 ext.SLAT = cte.GetLatMin();
7478 ext.WLON = cte.GetLonMin();
7479 ext.ELON = cte.GetLonMax();
7481 int scale = cte.GetScale();
7484 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7487 if (wxThread::IsMain()) {
7489 wxSize sz = prog->GetSize();
7494 prog->Update(count, msg, &skip);
7506 newChart->SetNativeScale(
scale);
7507 newChart->SetFullExtent(ext);
7508 newChart->DisableBackgroundSENC();
7510 newChart->FindOrCreateSenc(filename,
7514 if (wxThread::IsMain()) {
7515 msg.Printf(_(
"ENC Completed."));
7517 prog->Update(count, msg, &skip);
7527 for (
int t = 0;; t = (t + 1) % thread_count) {
7534 if (!workers[t]->IsAlive()) {
7547#if defined(__WXMSW__) || defined(__WXOSX__)
7554 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.