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);
289static wxString _menuText(wxString name, wxString shortcut) {
293 menutext <<
"\t" << shortcut;
298static void DoHelpDialog() {
310 [] { LaunchLocalHelp(); });
322#if defined(__WXGTK__) || defined(__WXQT__)
323#include "bitmaps/opencpn.xpm"
338 if (g_bInlandEcdis) {
342 wxPoint tbp_incanvas =
345 g_iENCToolbarPosY = tbp_incanvas.y;
346 g_iENCToolbarPosX = tbp_incanvas.x;
354 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
358 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
361 g_iENCToolbarPosY = -1;
364 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
370 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
374 double tool_scale_factor =
375 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
377 tool_scale_factor, callbacks);
387#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
390static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
391 const char *prop_name) {
395 unsigned long ret_nitems;
396 unsigned long ret_bytes_after;
397 unsigned char *ret_prop;
399 xa_prop_name = XInternAtom(disp, prop_name, False);
407 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
408 &xa_ret_type, &ret_format, &ret_nitems,
409 &ret_bytes_after, &ret_prop) != Success)
412 if (xa_ret_type != xa_prop_type) {
416 return (
char *)ret_prop;
421static bool isTransparentToolbarInOpenGLOK() {
428 if (!g_bdisable_opengl) {
429 Display *disp = XOpenDisplay(NULL);
431 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
433 "_NET_SUPPORTING_WM_CHECK")) ||
434 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
436 "_WIN_SUPPORTING_WM_CHECK"))) {
439 if ((wm_name = get_X11_property(disp, *sup_window,
440 XInternAtom(disp,
"UTF8_STRING", False),
442 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
445 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
460wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
462 font->GetFamily(), font->GetStyle(),
463 font->GetWeight(),
false, font->GetFaceName());
472wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
474BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
475EVT_CLOSE(MyFrame::OnCloseWindow)
476EVT_MENU(wxID_EXIT, MyFrame::OnExit)
477EVT_SIZE(MyFrame::OnSize)
478EVT_MOVE(MyFrame::OnMove)
479EVT_ICONIZE(MyFrame::OnIconize)
480EVT_MENU(-1, MyFrame::OnToolLeftClick)
481EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
483EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
484EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
485EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
487EVT_MAXIMIZE(MyFrame::OnMaximize)
488EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
489 MyFrame::RequestNewToolbarArgEvent)
490EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
492EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
493EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
494EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
496#ifdef wxHAS_POWER_EVENTS
497EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
498EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
499EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
500EVT_POWER_RESUME(MyFrame::OnResume)
511static
void onBellsFinishedCB(
void *ptr) {
512 auto framePtr =
static_cast<MyFrame *
>(ptr);
514 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
515 wxPostEvent(framePtr, ev);
520 auto msg = ev.GetString().ToStdString();
521 auto ¬eman = NotificationManager::GetInstance();
522 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
525static NmeaLog *GetDataMonitor() {
526 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
527 return dynamic_cast<NmeaLog *
>(w);
530MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
531 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
532 OpenFileFunc open_gpx_file)
533 : wxFrame(nullptr, -1, title, pos, size, kFrameStyle, kTopLevelWindowName),
534 m_connections_dlg(nullptr),
536 m_pauidockart(pauidockart),
537 m_rest_server(rest_server),
538 m_open_gpx_file(open_gpx_file) {
550 m_ulLastNMEATicktime = 0;
551 m_data_monitor->Hide();
553 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
557 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
560 InitTimer.SetOwner(
this, INIT_TIMER);
562 m_initializing =
false;
563 m_toolbar_callbacks.render_gl_textures =
565 [&](
ocpnDC &dc,
float *coords,
float *uv) {
566 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
567 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
570 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
574 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
577 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
580 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
583 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
586 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
588 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
597 m_bTimeIsSet =
false;
598 m_bdefer_resize =
false;
601 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
602 COGFilterTable[i] = NAN;
603 SOGFilterTable[i] = NAN;
605 m_last_bGPSValid =
false;
606 m_last_bVelocityValid =
false;
616 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
621 double process_noise_std = 1.0;
622 double measurement_noise_std = 0.5;
626 m_ChartUpdatePeriod = 1;
631 log_callbacks.log_is_active = [&]() {
632 auto log = GetDataMonitor();
633 return log && log->IsVisible();
635 log_callbacks.log_message = [&](
Logline ll) {
636 NmeaLog *monitor = GetDataMonitor();
639 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
642 ais_callbacks.confirm_stop_track = []() {
643 int r = OCPNMessageBox(
645 _(
"This AIS target has Persistent tracking selected by MMSI "
647 "A Persistent track recording will therefore be restarted for this "
649 "Do you instead want to stop Persistent tracking for this target?"),
650 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
651 return r == wxID_YES;
653 ais_callbacks.get_target_mmsi = []() {
654 auto alert_dlg_active =
656 assert(alert_dlg_active);
657 return alert_dlg_active->Get_Dialog_MMSI();
665 wxLogMessage(
" **** Connect stuff");
671 Connect(wxEVT_OCPN_MSG,
672 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
680 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
688#if defined(__WXGTK__) || defined(__WXQT__)
689 wxIcon app_icon(opencpn);
697 wxDynamicLibrary dllUser32(
"user32.dll");
699 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
700 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
705 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
710 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
711 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
713 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
714 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
715 [&](wxCommandEvent) { Refresh(); });
716 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
718 m_update_statusbar_listener.Init(
719 GuiEvents::GetInstance().gframe_update_status_bar,
721 m_center_aistarget_listener.Init(
722 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
723 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
724 CenterAisTarget(ais_target);
726 m_reload_charts_listener.Init(
727 GuiEvents::GetInstance().on_reload_charts,
732 EnableFullScreenView();
734 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
740 FrameTenHzTimer.Stop();
755 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
761void MyFrame::FreezeCharts() {
764 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
766 if (cc && !cc->IsFrozen()) cc->Freeze();
770void MyFrame::CenterAisTarget(
771 const std::shared_ptr<const AisTargetData> &ais_target) {
779 double factor = cc->GetScaleValue() / 5000.0;
780 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
786void MyFrame::ThawCharts() {
789 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
791 if (cc && cc->IsFrozen()) cc->Thaw();
798 switch (event.type) {
799 case SENC_BUILD_STARTED:
802 case SENC_BUILD_DONE_NOERROR:
804 chart =
event.m_ticket->m_chart;
806 chart->PostInit(FULL_INIT, global_color_scheme);
808 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
810 if (cc) cc->ClearS52PLIBStateHash();
815 delete event.m_ticket;
817 case SENC_BUILD_DONE_ERROR:
825void MyFrame::RebuildChartDatabase() {
826 bool b_SetInitialPoint =
false;
829 ArrayOfCDI ChartDirArray;
830 pConfig->LoadChartDirArray(ChartDirArray);
832 if (ChartDirArray.GetCount()) {
837 _(
"OpenCPN needs to update the chart database from config file "
841 wxICON_INFORMATION | wxOK);
849 _(
"Rebuilding chart database from configuration file entries..."));
853 wxString dummy1 = _(
"Elapsed time : ");
854 wxString dummy2 = _(
"Estimated time : ");
855 wxString dummy3 = _(
"Remaining time : ");
856 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
857 _(
"OpenCPN Chart Update"), line, 100, NULL,
858 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
859 wxPD_REMAINING_TIME);
862 ChartData->SaveBinary(ChartListFileName);
872void MyFrame::OnBellsFinished(wxCommandEvent &event) {
873 int bells = wxMin(m_BellsToPlay, 2);
874 if (bells <= 0)
return;
876 wxString soundfile =
"sounds";
877 appendOSDirSlash(&soundfile);
878 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
879 soundfile.Prepend(g_Platform->GetSharedDataDir());
880 wxLogMessage(
"Using bells sound file: " + soundfile);
882 o_sound::Sound *sound = bells_sound[bells - 1];
883 sound->SetFinishedCallback(onBellsFinishedCB,
this);
884 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
885 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
886 sound->Load(soundfile);
887 if (!sound->IsOk()) {
888 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
892 m_BellsToPlay -= bells;
895void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
897void MyFrame::OnMaximize(wxMaximizeEvent &event) {
904void MyFrame::ReloadAllVP() {
905 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
907 if (cc) cc->ReloadVP();
911void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
912 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
915 global_color_scheme = cs;
918 case GLOBAL_COLOR_SCHEME_DAY:
921 case GLOBAL_COLOR_SCHEME_DUSK:
924 case GLOBAL_COLOR_SCHEME_NIGHT:
925 SchemeName =
"NIGHT";
932 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
934 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
935 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
936 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
937 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
938 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
940 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
969 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
970 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
974 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
976 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
980 user_colors::GetMapByScheme(SchemeName.ToStdString());
985 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
988 cc->SetColorScheme(cs);
989 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
990 cc->HideChartInfoWindow();
991 cc->SetQuiltChartHiLiteIndex(-1);
997 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1009 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1022 if (g_pais_query_dialog_active) {
1023 bool b_isshown = g_pais_query_dialog_active->IsShown();
1024 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1025 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1027 g_pais_query_dialog_active->Close();
1030 g_pais_query_dialog_active->
Create(
1031 this, -1, _(
"AIS Target Query"),
1032 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1033 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1034 g_pais_query_dialog_active->UpdateText();
1035 if (b_isshown) g_pais_query_dialog_active->Show();
1040 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1044 ApplyGlobalColorSchemetoStatusBar();
1046 UpdateAllToolbars(cs);
1051 bool btoolbarFull = g_bmasterToolbarFull;
1057 if (!btoolbarFull) {
1059 RequestNewMasterToolbar();
1061 CollapseGlobalToolbar();
1064 RequestNewMasterToolbar();
1073void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1074 if (m_pStatusBar != NULL) {
1075 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1076 m_pStatusBar->ClearBackground();
1086void MyFrame::CancelAllMouseRoute() {
1088 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1090 if (cc) cc->CancelMouseRoute();
1094void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1102 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1110 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1119 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1122 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1123 config_array.Item(i)->canvas = NULL;
1129 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1134 switch (g_canvasConfig) {
1148 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1149 cc->GetglCanvas()->Show();
1152 config_array.Item(0)->canvas = cc;
1156 cc->ApplyCanvasConfig(config_array.Item(0));
1160 cc->ConfigureChartBar();
1161 cc->SetColorScheme(global_color_scheme);
1162 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1163 cc->SetShowGPS(
true);
1166 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1168 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1184 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1187 config_array.Item(0)->canvas = cc;
1189 cc->ApplyCanvasConfig(config_array.Item(0));
1192 cc->ConfigureChartBar();
1193 cc->SetColorScheme(global_color_scheme);
1194 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1195 cc->SetShowGPS(
false);
1198 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1200 .CaptionVisible(
false)
1202 .CloseButton(
false);
1211 if (config_array.GetCount() < 2) {
1213 pcc->configIndex = 1;
1217 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1218 config_array.Add(pcc);
1221 config_array.Item(1)->canvas = cc;
1223 cc->ApplyCanvasConfig(config_array.Item(1));
1226 cc->ConfigureChartBar();
1227 cc->SetColorScheme(global_color_scheme);
1228 cc->SetShowGPS(
true);
1232 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1234 .CaptionVisible(
false)
1236 .CloseButton(
false);
1237 g_pauimgr->GetPane(cc).RightDockable(
true);
1241 config_array.Item(1)->canvasSize =
1242 wxSize(GetClientSize().x / 2, GetClientSize().y);
1243 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1248 if (b_useStoredSize) {
1249 int ccw = config_array.Item(1)->canvasSize.x;
1250 int cch = config_array.Item(1)->canvasSize.y;
1253 if (ccw < GetClientSize().x / 10) {
1254 ccw = GetClientSize().x / 2;
1255 cch = GetClientSize().y;
1258 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1259 cc->SetSize(ccw, cch);
1277 console->SetColorScheme(global_color_scheme);
1282 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1288void MyFrame::RequestNewToolbars(
bool bforcenew) {
1289 if (b_inCloseWindow) {
1293 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1294 PositionIENCToolbar();
1303void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1309void MyFrame::SetAllToolbarScale() {
1310 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1313void MyFrame::SetGPSCompassScale() {
1314 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1318 wxPoint screenPoint = ::wxGetMousePosition();
1321 switch (g_canvasConfig) {
1323 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1326 if (canvas->GetScreenRect().Contains(
1330 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1333 if (canvas->GetScreenRect().Contains(
1340 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1343 if (canvas->GetScreenRect().Contains(
1344 canvas->ScreenToClient(screenPoint)))
1352int MyFrame::GetCanvasIndexUnderMouse() {
1353 wxPoint screenPoint = ::wxGetMousePosition();
1356 switch (g_canvasConfig) {
1358 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1361 if (canvas->GetScreenRect().Contains(
1365 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1368 if (canvas->GetScreenRect().Contains(
1375 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1378 if (canvas->GetScreenRect().Contains(
1379 canvas->ScreenToClient(screenPoint)))
1387bool MyFrame::DropMarker(
bool atOwnShip) {
1394 if (!canvas)
return false;
1401 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1403 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1405 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1416 RefreshAllCanvas(
false);
1421void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1422 if (g_canvasConfig != 0) {
1425 int nTargetGTK = -1;
1427 wxWindow *source = FindFocus();
1433 switch (g_canvasConfig) {
1435 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1438 if (canvas && (canvas == test)) {
1443 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1446 if (canvas && (canvas == test)) {
1454 int nfinalTarget = nTarget;
1456 nfinalTarget = nTargetGTK;
1458 target = ConfigMgr::Get()
1459 .GetCanvasConfigArray()
1464 target->Refresh(
true);
1475void MyFrame::FastClose() {
1477 FrameTenHzTimer.Stop();
1479 FrameTimer1.Start(1);
1483void MyFrame::OnExit(wxCommandEvent &event) {
1487void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1490 if (b_inCloseWindow) {
1500 if (!g_bDeferredInitDone)
return;
1517 if (bDBUpdateInProgress)
return;
1519 b_inCloseWindow =
true;
1521 ::wxSetCursor(wxCURSOR_WAIT);
1525 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1527 if (cc && cc->IsMeasureActive()) {
1528 cc->CancelMeasureRoute();
1533 SendPreShutdownHookToPlugins();
1537 if (g_pAISTargetList) {
1538 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1539 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1540 g_pauimgr->DetachPane(g_pAISTargetList);
1567 SetCursor(wxCURSOR_WAIT);
1569 RefreshAllCanvas(
true);
1575 RestoreScreenBrightness();
1586 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1587 g_iENCToolbarPosY = tbp_incanvas.y;
1588 g_iENCToolbarPosX = tbp_incanvas.x;
1592 g_bframemax = IsMaximized();
1595 FrameTenHzTimer.Stop();
1597 FrameCOGTimer.Stop();
1611 if (g_bAutoAnchorMark) {
1612 bool watching_anchor =
false;
1620 wxDateTime now = wxDateTime::Now();
1621 wxTimeSpan uptime = now.Subtract(g_start_time);
1623 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1624 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1629 if (g_declutter_anchorage) {
1630 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1631 if (pr->GetName().StartsWith(
"Anchorage")) {
1632 double a =
gLat - pr->m_lat;
1633 double b =
gLon - pr->m_lon;
1634 double l = sqrt((a * a) + (b * b));
1637 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1639 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1640 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1648 wxString name = now.Format();
1649 name.Prepend(_(
"Anchorage created "));
1655 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1664 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1668 NavObj_dB::GetInstance().Close();
1672 pConfig->DeleteGroup(
"/Routes");
1673 pConfig->DeleteGroup(
"/Marks");
1699 if (g_pAISTargetList) {
1700 g_pAISTargetList->Disconnect_decoder();
1701 g_pAISTargetList->Destroy();
1708 if (RouteManagerDialog::getInstanceFlag()) {
1725 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1727 if (cc) cc->Destroy();
1751 CommBridge::GetInstance().SaveConfig();
1771 auto ®istry = CommDriverRegistry::GetInstance();
1772 registry.CloseAllDrivers();
1775 for (
auto *cp : TheConnectionParams()) {
1780 while (pLayerList->size())
delete *pLayerList->begin();
1784 ReleaseApiListeners();
1787 g_bTempShowMenuBar =
false;
1789#define THREAD_WAIT_SECONDS 5
1799 wxLogMessage(
"Starting compressor pool drain");
1800 wxDateTime now = wxDateTime::Now();
1801 time_t stall = now.GetTicks();
1802 time_t end = stall + THREAD_WAIT_SECONDS;
1805 while (stall < end) {
1806 wxDateTime later = wxDateTime::Now();
1807 stall = later.GetTicks();
1810 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1819 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1825 uninitIXNetSystem();
1829 wxLogMessage(
"gFrame destroyed.");
1832#ifndef USE_ANDROID_GLES2
1833 qDebug() <<
"Calling OnExit()";
1837 wxTheApp->ExitMainLoop();
1840void MyFrame::OnMove(wxMoveEvent &event) {
1841 auto idx = wxDisplay::GetFromWindow(
this);
1854 DEBUG_LOG <<
"Moved to " << idx
1855#if wxCHECK_VERSION(3, 1, 6)
1856 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1857 << wxDisplay(idx).GetPPI().GetY()
1858 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1860 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1861 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1862 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1863 << wxGetDisplaySizeMM().GetY()
1864 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1873 if (g_config_display_size_manual) {
1882 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1885 cc->SetMUIBarPosition();
1894 UpdateGPSCompassStatusBoxes();
1904 PositionIENCToolbar();
1910 g_nframewin_posx = GetPosition().x;
1911 g_nframewin_posy = GetPosition().y;
1914void MyFrame::ProcessCanvasResize() {
1915 UpdateGPSCompassStatusBoxes(
true);
1919 PositionIENCToolbar();
1922 TriggerRecaptureTimer();
1926void MyFrame::TriggerRecaptureTimer() {
1927 m_recaptureTimer.Start(
1928 1000, wxTIMER_ONE_SHOT);
1931void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1933void MyFrame::SetCanvasSizes(wxSize frameSize) {
1937 int cccw = frameSize.x;
1938 int ccch = frameSize.y;
1942 switch (g_canvasConfig) {
1948 cc->GetSize( &cur_width, &cur_height );
1949 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1951 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1953 cc->SetSize( 0, 0, cccw, ccch );
1963 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1964 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1966 ccw = wxMin(ccw, cccw * 8 / 10);
1967 ccw = wxMax(ccw, cccw * 2 / 10);
1971 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1978 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1995void MyFrame::OnIconize(wxIconizeEvent &event) {
2005 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2007 if (cc && cc->GetMUIBar()) {
2008 if (cc->GetMUIBar()->GetCanvasOptions()) {
2009 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2010 cc->GetMUIBar()->PushCanvasOptions();
2019void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2021void MyFrame::ODoSetSize() {
2023 GetClientSize(&x, &y);
2026 if (m_pStatusBar != NULL) {
2027 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2028 int currentCount = m_pStatusBar->GetFieldsCount();
2029 if (currentCount != m_StatusBarFieldCount) {
2030 if ((currentCount > 0) && (currentCount < 7)) {
2033 int widths[] = {2, 2, 2, 2, 2, 2};
2034 m_pStatusBar->SetStatusWidths(currentCount, widths);
2037 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2040 if (m_StatusBarFieldCount) {
2045 if (m_StatusBarFieldCount > 2) {
2046 int widths[] = {-6, -5, -5, -6, -4};
2047 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2048 }
else if (m_StatusBarFieldCount == 2) {
2049 int cwidth = x * 90 / 100;
2050 int widths[] = {100, 100};
2051 widths[0] = cwidth * 6.4 / 10.0;
2052 widths[1] = cwidth * 3.6 / 10.0;
2053 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2055 int widths[] = {100, 100};
2056 widths[0] = x * 90 / 100;
2057 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2060 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2061 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2062 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2064 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2066 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2074 m_pStatusBar->GetFieldRect(0, stat_box);
2077 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2079 wxFont sys_font = *wxNORMAL_FONT;
2080 int try_font_size = sys_font.GetPointSize();
2083 int min_font_size = 10;
2093 wxFont *statusBarFont =
2094 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2095 int font_size = statusBarFont->GetPointSize();
2097 font_size = wxMin(font_size,
2100 wxMax(font_size, min_font_size);
2103 font_size = statusBarFont->GetPointSize();
2110 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2111 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2113 int min_height = stat_box.height;
2115 m_pStatusBar->SetFont(*pstat_font);
2116 m_pStatusBar->SetForegroundColour(
2117 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2119 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2121 (min_height >> 1) * 2;
2122 m_pStatusBar->SetMinHeight(min_height);
2131 SetCanvasSizes(GetClientSize());
2133 UpdateGPSCompassStatusBoxes(
true);
2135 if (
console) PositionConsole();
2138 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2140 if (cc) cc->FormatPianoKeys();
2146 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2147 GetPrimaryCanvas()->GetCompass()->GetRect());
2173 options_lastWindowSize = wxSize(0, 0);
2174 options_lastWindowPos = wxPoint(0, 0);
2181 if (!b_inCloseWindow) {
2184 resizeAndroidPersistents();
2188 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2189 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2195void MyFrame::PositionConsole() {
2196#if defined(__WXMSW__) || defined(__WXMAC__)
2197 if (NULL == GetPrimaryCanvas())
return;
2199 int ccx, ccy, ccsx, ccsy, consx, consy;
2204 consoleHost->GetSize(&ccsx, &ccsy);
2205 consoleHost->GetPosition(&ccx, &ccy);
2207 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2208 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2209 consoleHost = GetPrimaryCanvas();
2214 if (consoleHost->GetCompass()) {
2215 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2217 if (compass_rect.y < 100)
2218 yOffset = compass_rect.y + compass_rect.height + 45;
2222 wxSize csz =
console->GetSize();
2226 wxPoint screen_pos =
2227 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2230 if (NULL == GetPrimaryCanvas())
return;
2232 int ccx, ccy, ccsx, ccsy, consx, consy;
2237 consoleHost->GetSize(&ccsx, &ccsy);
2238 consoleHost->GetPosition(&ccx, &ccy);
2240 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2241 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2242 consoleHost = GetPrimaryCanvas();
2245 int yTopOffset = 60;
2246 int yBottomOffset = 0;
2248 if (consoleHost->GetCompass()) {
2249 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2251 if (compass_rect.y < 100)
2252 yTopOffset = compass_rect.y + compass_rect.height;
2254 if (consoleHost->GetMUIBar()) {
2255 wxRect mui_rect = consoleHost->GetMUIBarRect();
2256 yBottomOffset = ccsy - mui_rect.y;
2260 wxSize csz =
console->GetSize();
2263 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2265 if (consy < yAvail) {
2266 yFinal = (yAvail - consy) / 2;
2267 yFinal += yTopOffset;
2268 }
else if (
console->GetCDI()->IsShown()) {
2269 int cdi_height =
console->GetCDI()->GetSize().y;
2270 int consy_no_cdi = consy - cdi_height;
2271 yFinal = (yAvail - consy_no_cdi) / 2;
2272 yFinal += yTopOffset;
2276 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2281void MyFrame::UpdateAllFonts() {
2290 DestroyPersistentDialogs();
2292 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2297void MyFrame::DestroyPersistentDialogs() {
2298 if (g_pais_query_dialog_active) {
2299 g_pais_query_dialog_active->Hide();
2300 g_pais_query_dialog_active->Destroy();
2301 g_pais_query_dialog_active = NULL;
2329void MyFrame::RefreshGroupIndices() {
2331 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2333 if (cc) cc->canvasRefreshGroupIndex();
2337void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2340 switch (event.GetId()) {
2341 case ID_MENU_SCALE_OUT:
2342 DoStackDelta(GetPrimaryCanvas(), 1);
2346 case ID_MENU_SCALE_IN:
2347 DoStackDelta(GetPrimaryCanvas(), -1);
2351 case ID_MENU_ZOOM_IN: {
2352 if (GetFocusCanvas()) {
2353 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2358 case ID_MENU_ZOOM_OUT: {
2359 if (GetFocusCanvas()) {
2360 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2365 case ID_MENU_ROUTE_NEW: {
2366 if (GetFocusCanvas()) {
2367 if (0 == GetFocusCanvas()->m_routeState) {
2368 GetFocusCanvas()->StartRoute();
2370 GetFocusCanvas()->FinishRoute();
2376 case ID_MENU_TOOL_MEASURE: {
2377 GetPrimaryCanvas()->StartMeasureRoute();
2381 case ID_MENU_TOOL_NMEA_DBG_LOG:
2382 m_data_monitor->Show();
2383 m_data_monitor->Raise();
2386 case ID_MENU_TOOL_IO_MONITOR:
2387 m_data_monitor->Show();
2390 case ID_MENU_MARK_BOAT: {
2395 case ID_MENU_MARK_CURSOR: {
2400 case ID_MENU_NAV_FOLLOW: {
2401 if (
gFrame->GetPrimaryCanvas())
2402 gFrame->GetPrimaryCanvas()->TogglebFollow();
2406 case ID_MENU_CHART_OUTLINES: {
2407 ToggleChartOutlines(GetFocusCanvas());
2411 case ID_MENU_CHART_QUILTING: {
2412 ToggleQuiltMode(GetFocusCanvas());
2416 case ID_MENU_UI_CHARTBAR: {
2417 ToggleChartBar(GetFocusCanvas());
2421 case ID_MENU_ENC_TEXT:
2423 ToggleENCText(GetFocusCanvas());
2426 case ID_MENU_ENC_LIGHTS: {
2427 ToggleLights(GetFocusCanvas());
2430 case ID_MENU_ENC_SOUNDINGS: {
2431 ToggleSoundings(GetFocusCanvas());
2434 case ID_MENU_ENC_ANCHOR: {
2435 ToggleAnchor(GetFocusCanvas());
2438 case ID_MENU_ENC_DATA_QUALITY: {
2439 ToggleDataQuality(GetFocusCanvas());
2442 case ID_MENU_SHOW_NAVOBJECTS: {
2443 ToggleNavobjects(GetFocusCanvas());
2447 case ID_MENU_AIS_TARGETS: {
2448 ToggleAISDisplay(GetFocusCanvas());
2451 case ID_MENU_AIS_MOORED_TARGETS: {
2452 g_bHideMoored = !g_bHideMoored;
2455 case ID_MENU_AIS_SCALED_TARGETS: {
2456 ToggleAISMinimizeTargets(GetFocusCanvas());
2460 case ID_MENU_AIS_TARGETLIST: {
2461 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2465 case ID_MENU_AIS_TRACKS: {
2466 g_bAISShowTracks = !g_bAISShowTracks;
2467 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2471 case ID_MENU_AIS_CPADIALOG: {
2472 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2473 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2474 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2475 if (g_bAIS_CPA_Alert) {
2476 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2481 case ID_MENU_AIS_CPASOUND: {
2482 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2483 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2487 case ID_MENU_AIS_CPAWARNING: {
2488 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2489 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2493 case wxID_PREFERENCES:
2500 case ID_SETTINGS_NEW: {
2505 case ID_SETTINGS_DELETE: {
2508 g_pOptions =
nullptr;
2512 case ID_RELOAD_CHARTS: {
2517 case ID_MENU_SETTINGS_BASIC: {
2519 androidDisableFullScreen();
2521 DoAndroidPreferences();
2528 case ID_MENU_UI_FULLSCREEN: {
2533 case ID_MENU_SHOW_CURRENTS: {
2534 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2535 GetFocusCanvas()->ReloadVP();
2536 GetFocusCanvas()->Refresh(
false);
2540 case ID_MENU_SHOW_TIDES: {
2541 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2542 GetFocusCanvas()->ReloadVP();
2543 GetFocusCanvas()->Refresh(
false);
2563 case ID_MENU_UI_COLSCHEME:
2564 case ID_COLSCHEME: {
2565 ToggleColorScheme();
2574 case ID_MENU_OQUIT: {
2579 case ID_MENU_ROUTE_MANAGER:
2580 case ID_ROUTEMANAGER: {
2603 case ID_MENU_NAV_TRACK:
2605 if (!g_bTrackActive) {
2607 g_bTrackCarryOver =
true;
2610 g_bTrackCarryOver =
false;
2611 RefreshAllCanvas(
true);
2616 case ID_MENU_CHART_NORTHUP: {
2617 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2620 case ID_MENU_CHART_COGUP: {
2621 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2624 case ID_MENU_CHART_HEADUP: {
2625 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2629 case ID_MENU_MARK_MOB:
2635 case ID_MASTERTOGGLE: {
2637 wxString tip = _(
"Show Toolbar");
2638 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2640 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2642 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2645 if (g_bmasterToolbarFull)
2646 m_nMasterToolCountShown =
2650 m_nMasterToolCountShown = 2;
2652 m_nMasterToolCountShown =
2655 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2663 case ID_CMD_SELECT_CHART_TYPE: {
2664 selectChartDisplay(event.GetExtraLong(), -1);
2668 case ID_CMD_SELECT_CHART_FAMILY: {
2669 selectChartDisplay(-1, event.GetExtraLong());
2673 case ID_CMD_APPLY_SETTINGS: {
2674 applySettingsString(event.GetString());
2676 androidRestoreFullScreen();
2682 case ID_CMD_NULL_REFRESH: {
2687 case ID_CMD_SETVP: {
2688 setStringVP(event.GetString());
2692 case ID_CMD_INVALIDATE: {
2698 case ID_CMD_POST_JSON_TO_PLUGINS: {
2704 int numErrors = reader.
Parse(event.GetString(), &root);
2705 if (numErrors == 0) {
2706 if (root[
"MessageID"].IsString()) {
2707 wxString MsgID = root[
"MessageID"].
AsString();
2731 ArrayOfPlugInToolbarTools tool_array =
2733 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2735 if (event.GetId() == pttc->id) {
2736 if (pttc->m_pplugin)
2758bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2759 bool viz_now = g_bmasterToolbarFull;
2762 wxString tip = _(
"Show Toolbar");
2764 tip = _(
"Hide Toolbar");
2766 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2769 bool toggle =
false;
2770 if (viz && !g_bmasterToolbarFull)
2773 else if (!viz && g_bmasterToolbarFull)
2777 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2780 if (g_bmasterToolbarFull)
2781 m_nMasterToolCountShown =
2785 m_nMasterToolCountShown = 2;
2787 m_nMasterToolCountShown =
2790 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2796void MyFrame::ScheduleReloadCharts() {
2797 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2798 evt.SetId(ID_RELOAD_CHARTS);
2799 GetEventHandler()->AddPendingEvent(evt);
2802void MyFrame::ScheduleDeleteSettingsDialog() {
2803 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2804 evt.SetId(ID_SETTINGS_DELETE);
2805 GetEventHandler()->AddPendingEvent(evt);
2808void MyFrame::ScheduleSettingsDialog() {
2809 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2810 evt.SetId(ID_SETTINGS);
2811 GetEventHandler()->AddPendingEvent(evt);
2814void MyFrame::ScheduleSettingsDialogNew() {
2815 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2816 evt.SetId(ID_SETTINGS_NEW);
2817 GetEventHandler()->AddPendingEvent(evt);
2820void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2821 UpdateCanvasConfigDescriptors();
2823 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2824 CreateCanvasLayout(
true);
2826 CreateCanvasLayout();
2830 ConfigureStatusBar();
2831 wxSize lastOptSize = options_lastWindowSize;
2836 options_lastWindowSize = lastOptSize;
2840 ScheduleSettingsDialogNew();
2842 ScheduleSettingsDialog();
2847 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2850 int index_hint = -1;
2851 if (i < pathArray.GetCount())
2852 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2853 cc->canvasChartsRefresh(index_hint);
2854 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2863 return GetPrimaryCanvas();
2866void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2867 if (g_bmasterToolbarFull) {
2868#ifndef OCPN_TOOLBAR_ANIMATE
2869 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2872 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2873 m_nMasterToolCountShown++;
2878 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2886#ifndef OCPN_TOOLBAR_ANIMATE
2887 m_nMasterToolCountShown = 1;
2889 if (m_nMasterToolCountShown > 1) {
2890 m_nMasterToolCountShown--;
2894 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2904void MyFrame::InvalidateAllGL() {
2907 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2917void MyFrame::RefreshAllCanvas(
bool bErase) {
2919 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2922 cc->Refresh(bErase);
2927void MyFrame::setStringVP(wxString VPS) {
2932 wxStringTokenizer tkz(VPS,
";");
2934 wxString token = tkz.GetNextToken();
2936 token.ToDouble(&lat);
2938 token = tkz.GetNextToken();
2940 token.ToDouble(&lon);
2942 token = tkz.GetNextToken();
2944 token.ToDouble(&scale_ppm);
2946 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2949void MyFrame::DoSettingsNew() {
2956void MyFrame::DoSettings() {
2961 ApplyGlobalSettings(
true);
2964 bool b_loadHarmonics =
false;
2965 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2968 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2971 if (b_loadHarmonics) LoadHarmonics();
2979 g_bShowChartBar = !g_bShowChartBar;
2981 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2986 if (g_bShowChartBar) {
2988 UpdateControlBar(cc);
2991 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2994void MyFrame::ToggleColorScheme() {
2995 static bool lastIsNight;
2996 ColorScheme s = user_colors::GetColorScheme();
2999 if (lastIsNight && is == 3)
3002 lastIsNight =
false;
3004 if (lastIsNight) is = 2;
3005 if (is == 3) lastIsNight =
true;
3006 s = (ColorScheme)is;
3007 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3009 SetAndApplyColorScheme(s);
3012void MyFrame::ToggleFullScreen() {
3013 bool to = !IsFullScreen();
3018 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3020 ShowFullScreen(to, style);
3023 UpdateAllToolbars(global_color_scheme);
3025 UpdateControlBar(GetPrimaryCanvas());
3027 TriggerRecaptureTimer();
3030void MyFrame::ActivateMOB() {
3032 wxDateTime mob_time = wxDateTime::Now();
3033 wxString mob_label(_(
"MAN OVERBOARD"));
3034 mob_label += _(
" on ");
3035 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3039 pWP_MOB->SetShared(
true);
3041 pWP_MOB->SetWaypointArrivalRadius(
3043 pWP_MOB->SetUseSca(
false);
3045 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3053 new RoutePoint(zlat, zlon, g_default_wp_icon,
3054 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3055 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3060 temp_route->AddPoint(pWP_src);
3061 temp_route->AddPoint(pWP_MOB);
3063 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3073 temp_route->SetRouteArrivalRadius(-1.0);
3079 v[
"GUID"] = temp_route->
m_GUID;
3080 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3081 SendJSONMessageToAllPlugins(msg_id, v);
3084 if (RouteManagerDialog::getInstanceFlag()) {
3092 RefreshAllCanvas(
false);
3094 wxString mob_message(_(
"MAN OVERBOARD"));
3095 mob_message += _(
" Time: ");
3096 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3097 mob_message += _(
" Position: ");
3098 mob_message += toSDMM(1,
gLat);
3100 mob_message += toSDMM(2,
gLon);
3101 wxLogMessage(mob_message);
3103void MyFrame::TrackOn() {
3104 g_bTrackActive =
true;
3112 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3114 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3116 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3119 androidSetTrackTool(
true);
3122 if (RouteManagerDialog::getInstanceFlag()) {
3131 if (name.IsEmpty()) {
3137 name = _(
"(Unnamed Track)");
3141 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3142 SendJSONMessageToAllPlugins(msg_id, v);
3143 g_FlushNavobjChangesTimeout =
3147Track *MyFrame::TrackOff(
bool do_add_point) {
3152 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3154 SendJSONMessageToAllPlugins(msg_id, v);
3163 if (g_bTrackDaily) {
3168 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3169 return_val = pExtendTrack;
3176 g_bTrackActive =
false;
3178 if (RouteManagerDialog::getInstanceFlag()) {
3185 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3187 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3188 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3191 androidSetTrackTool(
false);
3195 m_target_rotate_time = wxInvalidDateTime;
3200void MyFrame::InitializeTrackRestart() {
3201 if (!g_bTrackDaily)
return;
3202 if (m_target_rotate_time.IsValid())
return;
3205 switch (g_track_rotate_time_type) {
3207 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3209 case TIME_TYPE_COMPUTER:
3210 rotate_at = g_track_rotate_time;
3214 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3215 rotate_at = g_track_rotate_time + utc_offset;
3218 if (rotate_at > 86400)
3220 else if (rotate_at < 0)
3223 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3224 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3227 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3228 m_target_rotate_time += wxTimeSpan(24);
3232bool MyFrame::ShouldRestartTrack() {
3234 InitializeTrackRestart();
3236 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3237 m_target_rotate_time += wxTimeSpan(24);
3243void MyFrame::TrackDailyRestart() {
3245 Track *pPreviousTrack = TrackOff(
true);
3252 if (pPreviousTrack) {
3253 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3257 if (RouteManagerDialog::getInstanceFlag()) {
3265void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3267 cc->SetUpMode(mode);
3269 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3270 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3271 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3274 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3279 cc->SetShowENCText(!cc->GetShowENCText());
3281 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3289void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3292 cc->SetENCDisplayCategory(nset);
3294 UpdateGlobalMenuItems();
3305 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3307 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3316 cc->SetShowENCLights(!cc->GetShowENCLights());
3318 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3328void MyFrame::ToggleRocks(
void )
3334 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3335 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3336 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3337 pOLE->nViz = !pOLE->nViz;
3341 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3342 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3343 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3346 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3350 ps52plib->GenerateStateHash();
3357 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3359 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3367 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3369 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3384 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3385 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3390 cc->SetShowAIS(!cc->GetShowAIS());
3391 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3395void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3396 cc->SetAttenAIS(!cc->GetAttenAIS());
3397 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3403 cc->m_bFollow =
true;
3406 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3410 SetChartUpdatePeriod();
3418 cc->m_bFollow =
false;
3420 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3424 SetChartUpdatePeriod();
3427void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3428 cc->SetShowOutlines(!cc->GetShowOutlines());
3430 RefreshAllCanvas(
false);
3434 if (g_bopengl) InvalidateAllGL();
3437 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3440void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3442void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3444 bool enabled = m_pMenuBar->IsEnabled(item_id);
3445 m_pMenuBar->Enable(item_id,
false);
3446 m_pMenuBar->Check(item_id, state);
3447 m_pMenuBar->Enable(item_id, enabled);
3451void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3458void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3459 wxBitmap *bmpRollover) {
3461 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3466void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3467 wxString rolloverSVGfile,
3468 wxString toggledSVGfile) {
3471 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3475void MyFrame::ConfigureStatusBar() {
3477 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3480 UseNativeStatusBar(
false);
3483 if (g_bShowStatusBar) {
3484 if (!m_pStatusBar) {
3486 CreateStatusBar(m_StatusBarFieldCount, 0);
3487 ApplyGlobalColorSchemetoStatusBar();
3492 m_pStatusBar->Destroy();
3493 m_pStatusBar = NULL;
3499void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3500 ConfigureStatusBar();
3502 wxSize lastOptSize = options_lastWindowSize;
3508 options_lastWindowSize = lastOptSize;
3510 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3513void MyFrame::BuildMenuBar() {
3519 bool showMenuBar =
true;
3521 bool showMenuBar = g_bShowMenuBar;
3533 m_pMenuBar =
new wxMenuBar();
3534 RegisterGlobalMenuItems();
3535 SetMenuBar(m_pMenuBar);
3539 UpdateGlobalMenuItems();
3544 m_pMenuBar->Destroy();
3550void MyFrame::RegisterGlobalMenuItems() {
3551 if (!m_pMenuBar)
return;
3553 wxMenu *nav_menu =
new wxMenu();
3554 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3555 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3556 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3557 nav_menu->AppendSeparator();
3558 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3559 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3560 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3561 nav_menu->AppendSeparator();
3563 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3564 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3566 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3567 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3569 nav_menu->AppendSeparator();
3570 nav_menu->Append(ID_MENU_SCALE_IN,
3571 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3572 nav_menu->Append(ID_MENU_SCALE_OUT,
3573 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3575 nav_menu->AppendSeparator();
3576 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3578 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3580 wxMenu *view_menu =
new wxMenu();
3582 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3583 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3584 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3585 _menuText(_(
"Show Chart Outlines"),
"O"));
3587 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3588 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3589 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3590 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3592 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3593 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3595 view_menu->AppendSeparator();
3597 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3598 _menuText(_(
"Show ENC text"),
"T"));
3599 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3600 _menuText(_(
"Show ENC Lights"),
"L"));
3601 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3602 _menuText(_(
"Show ENC Soundings"),
"S"));
3603 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3604 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3605 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3606 _menuText(_(
"Show ENC Data Quality"),
"U"));
3607 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3608 _menuText(_(
"Show Navobjects"),
"V"));
3610 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3611 _menuText(_(
"Show ENC text"),
"Alt-T"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3613 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3615 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3617 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3619 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3620 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3621 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3623 view_menu->AppendSeparator();
3624 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3625 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3626 view_menu->AppendSeparator();
3628 view_menu->Append(ID_MENU_UI_COLSCHEME,
3629 _menuText(_(
"Change Color Scheme"),
"C"));
3631 view_menu->Append(ID_MENU_UI_COLSCHEME,
3632 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3635 view_menu->AppendSeparator();
3637 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3638 _menuText(_(
"Toggle Full Screen"),
"F11"));
3640 m_pMenuBar->Append(view_menu, _(
"&View"));
3642 wxMenu *ais_menu =
new wxMenu();
3643 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3644 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3645 _(
"Attenuate less critical AIS targets"));
3646 ais_menu->AppendSeparator();
3647 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3648 _(
"Hide Moored AIS Targets"));
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3650 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3651 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3655 _menuText(_(
"Show CPA Warnings"),
"W"));
3657 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3658 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3661 ais_menu->AppendSeparator();
3662 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3663 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3665 wxMenu *tools_menu =
new wxMenu();
3666 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3667 _menuText(_(
"Data Monitor"),
"Alt-C"));
3669 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3670 _menuText(_(
"Measure Distance"),
"M"));
3672 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3673 _menuText(_(
"Measure Distance"),
"Alt-M"));
3676 tools_menu->AppendSeparator();
3677 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3678 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3679 tools_menu->AppendSeparator();
3680 tools_menu->Append(ID_MENU_MARK_BOAT,
3681 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3682 tools_menu->Append(ID_MENU_MARK_CURSOR,
3683 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3684 tools_menu->AppendSeparator();
3688 _menuText(_(
"Drop MOB Marker"),
3690 tools_menu->AppendSeparator();
3691 tools_menu->Append(wxID_PREFERENCES,
3692 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3694 tools_menu->Append(ID_MENU_MARK_MOB,
3695 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3696 tools_menu->AppendSeparator();
3697 tools_menu->Append(wxID_PREFERENCES,
3698 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3700 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3703 wxMenu *window_menu =
new wxMenu();
3704 m_pMenuBar->Append(window_menu, _(
"&Window"));
3707 wxMenu *help_menu =
new wxMenu();
3708 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3709 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3710 m_pMenuBar->Append(help_menu, _(
"&Help"));
3713 UpdateGlobalMenuItems();
3716void MyFrame::UpdateGlobalMenuItems() {
3717 if (!m_pMenuBar)
return;
3719 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3720 ->Check(GetPrimaryCanvas()->m_bFollow);
3721 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3722 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3723 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3724 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3725 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3726 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3727 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3728 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3729 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3730 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3731 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3732 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3733 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3734 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3735 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3736 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3737 if (g_bAIS_CPA_Alert) {
3738 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3739 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3741 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3742 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3745 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3746 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3747 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3750 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3751 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3752 ->Check(ps52plib->GetShowSoundings());
3754 bool light_state =
false;
3756 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3758 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3759 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3760 light_state = (pOLE->nViz == 1);
3765 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3766 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3770 DisCat nset = ps52plib->GetDisplayCategory();
3771 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3772 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3773 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3774 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3775 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3776 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3777 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3779 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3780 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3781 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3786void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3787 if (!m_pMenuBar)
return;
3789 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3791 if (cc->GetUpMode() == NORTH_UP_MODE)
3792 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3793 else if (cc->GetUpMode() == COURSE_UP_MODE)
3794 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3796 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3798 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3799 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3800 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3801 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3802 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3803 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3804 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3805 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3806 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3807 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3808 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3809 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3810 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3811 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3812 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3815 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3816 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3819 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3821 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3822 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3827 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3831 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3832 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3833 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3834 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3835 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3836 ->Check(cc->GetShowENCDataQual());
3837 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3839 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3840 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3841 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3846void MyFrame::InvalidateAllCanvasUndo() {
3848 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3850 if (cc) cc->undo->InvalidateUndo();
3854void MyFrame::SubmergeAllCanvasToolbars() {
3856 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3858 if (cc) cc->SubmergeToolbar();
3862void MyFrame::SurfaceAllCanvasToolbars() {
3863 if (g_bshowToolbar) {
3865 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3867 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3874void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3876 if (lon > 180.0) lon -= 360.0;
3881 cc->JumpToPosition(lat, lon,
scale);
3884 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3888void MyFrame::UpdateCanvasConfigDescriptors() {
3890 for (
unsigned int i = 0;
3891 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3892 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3900 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3901 cc->GroupID = chart->m_groupIndex;
3904 cc->
bQuilt = chart->GetQuiltMode();
3911 cc->
bFollow = chart->m_bFollow;
3916 int upmode = chart->GetUpMode();
3917 if (upmode == COURSE_UP_MODE)
3919 else if (upmode == HEAD_UP_MODE)
3926void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3927 if (!RBBox.GetValid())
return;
3929 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3930 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3933 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3934 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3942 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3943 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3945 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3946 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3948 cc->GetSize(&ww, &wh);
3950 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3952 ppm = wxMin(ppm, 1.0);
3958void MyFrame::PrepareOptionsClose(
options *settings,
3959 int settings_return_value) {
3961 options_lastPage = settings->lastPage;
3966 if (options_lastPage == 1) options_lastPage = 0;
3968 options_subpage = settings->lastSubPage;
3969 options_lastWindowPos = settings->lastWindowPos;
3970 options_lastWindowSize = settings->lastWindowSize;
3973 androidEnableBackButton(
true);
3974 androidEnableOptionsMenu(
true);
3975 androidRestoreFullScreen();
3976 androidEnableRotation();
3981void MyFrame::DoOptionsDialog() {
3983 AbstractPlatform::ShowBusySpinner();
3986 pConfig->SetPath(
"/Settings");
3987 pConfig->Read(
"OptionsSizeX", &sx, -1);
3988 pConfig->Read(
"OptionsSizeY", &sy, -1);
3990 wxWindow *optionsParent =
this;
3992 optionsParent = GetPrimaryCanvas();
3995 callbacks.prepare_close = [&](
options *me,
int changes) {
3996 PrepareOptionsClose(me, changes);
3998 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
3999 ProcessOptionsDialog(changes, workdir_list);
4002 wxPoint(-1, -1), wxSize(sx, sy));
4004 AbstractPlatform::HideBusySpinner();
4008 g_options->SetInitChartDir(*pInit_Chart_Dir);
4012 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4013 g_options->SetWorkDirListPtr(pWorkDirArray);
4019 prev_locale = g_locale;
4020 g_options->SetInitialPage(options_lastPage, options_subpage);
4023 g_options->lastWindowPos = options_lastWindowPos;
4024 if (options_lastWindowPos != wxPoint(0, 0)) {
4026 g_options->SetSize(options_lastWindowSize);
4030 if (options_lastWindowSize != wxSize(0, 0)) {
4031 g_options->SetSize(options_lastWindowSize);
4036 androidEnableBackButton(
false);
4037 androidEnableOptionsMenu(
false);
4038 androidDisableFullScreen();
4046 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4049 wxString chart_file_name;
4050 if (cc->GetQuiltMode()) {
4051 int dbi = cc->GetQuiltRefChartdbIndex();
4052 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4054 if (cc->m_singleChart)
4055 chart_file_name = cc->m_singleChart->GetFullPath();
4058 pathArray.Add(chart_file_name);
4064 last_canvasConfig = g_canvasConfig;
4067 g_last_ChartScaleFactor = g_ChartScaleFactor;
4073void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4074 bool b_need_refresh =
false;
4076 if ((rr & VISIT_CHARTS) &&
4077 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4079 UpdateChartDatabaseInplace(*pNewDirArray,
4080 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4083 b_need_refresh =
true;
4087 if (rr & STYLE_CHANGED) {
4090 _(
"Please restart OpenCPN to activate language or style changes."),
4091 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4094 bool b_groupchange =
false;
4095 if (((rr & VISIT_CHARTS) &&
4096 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4097 (rr & GROUPS_CHANGED)) {
4098 b_groupchange = ScrubGroupArray();
4100 RefreshGroupIndices();
4103 if (rr & GROUPS_CHANGED || b_groupchange) {
4104 pConfig->DestroyConfigGroups();
4108 if (rr & TIDES_CHANGED) {
4114 if (rr & S52_CHANGED) {
4115 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4126 g_Platform->GetDisplayDPmm());
4129 double stuffcog = NAN;
4130 double stuffsog = NAN;
4131 if (!std::isnan(
gCog)) stuffcog =
gCog;
4132 if (!std::isnan(
gSog)) stuffsog =
gSog;
4134 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4135 COGFilterTable[i] = stuffcog;
4136 SOGFilterTable[i] = stuffsog;
4139 SetChartUpdatePeriod();
4141 if (rr & GL_CHANGED) {
4145 b_need_refresh =
true;
4148 if (rr & S52_CHANGED) {
4149 b_need_refresh =
true;
4153 if (rr & REBUILD_RASTER_CACHE) {
4155 GetPrimaryCanvas()->Disable();
4157 GetPrimaryCanvas()->Enable();
4162 if (g_config_display_size_manual &&
4170 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4177 int rrt = rr & S52_CHANGED;
4179 (rrt == S52_CHANGED) ||
4180 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4190 ps52plib->SetScaleFactorExp(
4191 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4192 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4196 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4198 if (cc) cc->ApplyGlobalSettings();
4203 bool ztc = g_bEnableZoomToCursor;
4204 g_bEnableZoomToCursor =
4208 if (!GetPrimaryCanvas()->IsFrozen())
4210 g_bEnableZoomToCursor = ztc;
4213 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4222 SetGPSCompassScale();
4224 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4227 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4228 cc->UpdateCanvasControlBar();
4231 UpdateGPSCompassStatusBoxes();
4233 SetAllToolbarScale();
4234 RequestNewToolbars();
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;
4283 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4288bool MyFrame::CheckGroup(
int igroup) {
4289 if (igroup == 0)
return true;
4293 if (!pGroup->m_element_array.size())
4296 for (
const auto &elem : pGroup->m_element_array) {
4297 for (
unsigned int ic = 0;
4298 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4299 auto &cte =
ChartData->GetChartTableEntry(ic);
4300 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4302 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4309bool MyFrame::ScrubGroupArray() {
4314 bool b_change =
false;
4315 unsigned int igroup = 0;
4316 while (igroup < g_pGroupArray->GetCount()) {
4317 bool b_chart_in_element =
false;
4320 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4321 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4323 for (
unsigned int ic = 0;
4324 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4325 auto &cte =
ChartData->GetChartTableEntry(ic);
4326 wxString chart_full_path = cte.GetFullSystemPath();
4328 if (chart_full_path.StartsWith(element_root)) {
4329 b_chart_in_element =
true;
4335 if (!b_chart_in_element) {
4336 wxString test_string =
"GSHH";
4337 if (element_root.Upper().Contains(test_string))
4338 b_chart_in_element =
true;
4341 if (!b_chart_in_element)
4343 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4355void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4357 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4359 if (cc && (cc != ccThis)) cc->Refresh();
4364void MyFrame::ChartsRefresh() {
4367 AbstractPlatform::ShowBusySpinner();
4369 bool b_run = FrameTimer1.IsRunning();
4372 FrameTenHzTimer.Stop();
4375 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4378 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4379 if (cc->GetQuiltMode()) {
4380 currentIndex = cc->GetQuiltReferenceChartIndex();
4382 cc->canvasChartsRefresh(currentIndex);
4386 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4387 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4389 AbstractPlatform::HideBusySpinner();
4392void MyFrame::InvalidateAllQuilts() {
4393 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4396 cc->InvalidateQuilt();
4397 cc->SetQuiltRefChart(-1);
4398 cc->m_singleChart = NULL;
4403bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4405 const wxString &ChartListFileName) {
4406 bool b_run = FrameTimer1.IsRunning();
4408 FrameTenHzTimer.Stop();
4410 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4411 FrameCOGTimer.Stop();
4414 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4417 cc->InvalidateQuilt();
4418 cc->SetQuiltRefChart(-1);
4419 cc->m_singleChart = NULL;
4429 AbstractPlatform::ShowBusySpinner();
4432 wxString longmsg = _(
"OpenCPN Chart Update");
4434 ".................................................................."
4437 Updateprog =
new wxGenericProgressDialog();
4440 Updateprog->SetFont(*qFont);
4442 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4443 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4444 wxPD_REMAINING_TIME);
4446 DimeControl(Updateprog);
4451 wxLogMessage(
"Starting chart database Update...");
4455 m_gshhg_chart_loc = gWorldMapLocation;
4456 gWorldMapLocation = wxEmptyString;
4460 AbstractPlatform::HideBusySpinner();
4464void MyFrame::FinalizeChartDBUpdate() {
4466 ChartData->SaveBinary(ChartListFileName);
4467 wxLogMessage(
"Finished chart database Update");
4470 if (Updateprog) Updateprog->Destroy();
4471 Updateprog =
nullptr;
4475 if (gWorldMapLocation.empty()) {
4479 gWorldMapLocation = gDefaultWorldMapLocation;
4480 m_gshhg_chart_loc = wxEmptyString;
4484 if (gWorldMapLocation != m_gshhg_chart_loc) {
4486 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4488 if (cc) cc->ResetWorldBackgroundChart();
4491 gshhsCrossesLandReset();
4495 bool b_run = FrameTimer1.IsRunning();
4496 if (!b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4497 if (!b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4499 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4500 if (!b_runCOGTimer) {
4502 int period_ms = 100;
4504 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4510 cc->ToggleCanvasQuiltMode();
4512 bool cur_mode = cc->GetQuiltMode();
4514 if( !cc->GetQuiltMode() )
4515 cc->SetQuiltMode(
true );
4517 if( cc->GetQuiltMode() ) {
4518 cc->SetQuiltMode(
false );
4519 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4523 if( cur_mode != cc->GetQuiltMode() ){
4529 g_bQuiltEnable = cc->GetQuiltMode();
4533 ps52plib->GenerateStateHash();
4538void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4540void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4542void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4544 cc->DoCanvasStackDelta(direction);
4548void MyFrame::PositionIENCToolbar() {
4552 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4554 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4562void MyFrame::OnInitTimer(wxTimerEvent &event) {
4565 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4569 wxLog::FlushActive();
4571 switch (m_iInitCount++) {
4576 if (g_bInlandEcdis) {
4577 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4578 double range_set = 500.;
4580 range = wxRound(range * 10) / 10.;
4584 else if (range > 2000.)
4586 else if (range > 1600.)
4588 else if (range > 1200.)
4590 else if (range > 800.)
4595 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4599 g_Platform->SetFullscreen(g_bFullscreen);
4603 RebuildChartDatabase();
4604 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4607 cc->SetGroupIndex(0,
false);
4615 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4616 CHART_FAMILY_RASTER)) {
4621 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4622 CHART_FAMILY_VECTOR)) {
4635 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4638 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4640 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4643 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4647 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4648 NavObj_dB::GetInstance().LoadNavObjects();
4651 if (!g_AW1GUID.IsEmpty()) {
4654 if (!g_AW2GUID.IsEmpty()) {
4660 appendOSDirSlash(&layerdir);
4661 layerdir.Append(
"layers");
4663 if (wxDir::Exists(layerdir)) {
4665 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4666 wxLogMessage(laymsg);
4667 pConfig->LoadLayers(layerdir);
4677 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4691 3 * GetCharHeight());
4693 m_data_monitor->Center();
4701 pConfig->SetPath(
"/Settings");
4702 pConfig->Read(
"OptionsSizeX", &sx, -1);
4703 pConfig->Read(
"OptionsSizeY", &sy, -1);
4705 wxWindow *optionsParent =
this;
4707 optionsParent = GetPrimaryCanvas();
4713 BuildiENCToolbar(
true, m_toolbar_callbacks);
4720 if (!g_params.empty()) {
4721 for (
size_t n = 0; n < g_params.size(); n++) {
4722 wxString path = g_params[n];
4723 if (::wxFileExists(path)) {
4725 pSet->load_file(path.fn_str());
4728 pSet->LoadAllGPXObjects(
4729 !pSet->IsOpenCPN(), wpt_dups,
4731 LLBBox box = pSet->GetBBox();
4732 if (box.GetValid()) {
4733 CenterView(GetPrimaryCanvas(), box);
4742 InitAppMsgBusListener();
4747 auto loader = PluginLoader::GetInstance();
4748 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4749 if (!b_haveWMM)
gVar = g_UserVar;
4757 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4760 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4762 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4765 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4769 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4770 NavObj_dB::GetInstance().LoadNavObjects();
4773 if (!g_AW1GUID.IsEmpty()) {
4776 if (!g_AW2GUID.IsEmpty()) {
4782 appendOSDirSlash(&layerdir);
4783 layerdir.Append(
"layers");
4785 if (wxDir::Exists(layerdir)) {
4787 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4788 wxLogMessage(laymsg);
4789 pConfig->LoadLayers(layerdir);
4796 wxLogMessage(
"OnInitTimer...Last Call");
4800 RequestNewMasterToolbar();
4802 PositionIENCToolbar();
4804 g_bDeferredInitDone =
true;
4814 GetPrimaryCanvas()->SetFocus();
4815 GetPrimaryCanvas()->Enable();
4822 if (b_reloadForPlugins) {
4828 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4830 if (cc) cc->SetFirstAuto(
true);
4838 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4840 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4844 cc->CheckGroupValid();
4849 androidEnableBackButton(
true);
4850 androidEnableRotation();
4851 androidEnableOptionItems(
true);
4857 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4863 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4865 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4867 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4873 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4875 wxLog::FlushActive();
4877 RefreshAllCanvas(
true);
4878 UsbWatchDaemon::GetInstance().Start();
4884void MyFrame::InitAppMsgBusListener() {
4885 auto &msgbus = AppMsgBus::GetInstance();
4888 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4889 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4893 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4894 HandleBasicNavMsg(basicnav_msg);
4898 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4899 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4903 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4904 HandleGPSWatchdogMsg(msg);
4911void MyFrame::ReleaseApiListeners() {}
4916 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4917 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4918 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4919 server.open_file_cb = [&](
const std::string &path) {
4920 return m_open_gpx_file(path);
4927void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4928 if (msg->gps_watchdog <= 0) {
4929 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4933 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4938 if (m_fix_start_time.IsValid()) {
4939 wxDateTime now = wxDateTime::Now();
4940 wxTimeSpan span = now - m_fix_start_time;
4941 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4942 auto ¬eman = NotificationManager::GetInstance();
4943 wxString msg = _(
"GNSS Position fix lost");
4944 noteman.AddNotification(NotificationSeverity::kCritical,
4946 m_fix_start_time = wxInvalidDateTime;
4950 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4951 bool last_bVelocityValid = bVelocityValid;
4952 bVelocityValid =
false;
4959void MyFrame::CalculateCOGAverage() {
4961 if (!std::isnan(
gCog)) {
4964 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4967 double sum = 0., count = 0;
4969 double adder = COGTable[i];
4970 if (std::isnan(adder))
continue;
4972 if (fabs(adder -
g_COGAvg) > 180.) {
4986 else if (sum >= 360.)
4995void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4996 m_fixtime = msg->time;
4997 double hdt_data_interval = 0;
4998 double fix_time_interval = 0;
5000 double msgtime = msg->set_time.tv_sec;
5001 double m1 = msg->set_time.tv_nsec / 1e9;
5004 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5005 ((msg->vflag & POS_VALID) == POS_VALID)) {
5007 if (!m_fix_start_time.IsValid()) {
5008 m_fix_start_time = wxDateTime::Now();
5013 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5016 fix_time_gt_last = fix_time_gt;
5017 uint64_t fix_time_gt_now =
5018 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5019 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5023 double implied_sog = dist / (fix_time_interval / 3600);
5028 gLat_gt_m1 = gLat_gt;
5029 gLon_gt_m1 = gLon_gt;
5033 fix_time_gt = fix_time_gt_now;
5037 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5038 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5039 gCog_gt_m1 = gCog_gt;
5049 if (!std::isnan(gCog_gt_m1)) {
5051 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5058 if ((fix_time_gt - fix_time_gt_last) > .08) {
5063 if (gCog_gt > gCog_gt_m1) {
5064 if ((gCog_gt - gCog_gt_m1) > 180.)
5069 if ((gCog_gt_m1 - gCog_gt) > 180.)
5074 difft = fabs(gCog_gt - gCog_gt_m1);
5075 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5083 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5084 tentative_cog_rate_gt *= 1e9;
5085 cog_rate_gt = tentative_cog_rate_gt;
5093 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5096static double hdt_avg;
5097 double hdt_norm =
gHdt;
5098 if(
gHdt > 180) hdt_norm -= 360;
5101 hdt_avg += hdt_norm * 0.1;
5106 if (!std::isnan(
gHdt)) {
5108 uint64_t hdt_time_gt_last = hdt_time_gt;
5109 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5110 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5113 if (hdt_data_interval > .09) {
5115 gHdt_gt_m1 = gHdt_gt;
5118 if (!std::isnan(gHdt_gt_m1)) {
5120 double tentative_hdt_rate_gt =
5121 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5122 tentative_hdt_rate_gt *= 1e9;
5124 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5125 hdt_rate_gt = tentative_hdt_rate_gt;
5133 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5136 CalculateCOGAverage();
5144 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5145 if ((msg->vflag & POS_VALID) == POS_VALID)
5150 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5152 bVelocityValid =
true;
5156void MyFrame::UpdateStatusBar() {
5159 unsigned long uiCurrentTickCount;
5160 m_MMEAeventTime.SetToCurrent();
5161 uiCurrentTickCount =
5162 m_MMEAeventTime.GetMillisecond() / 100;
5163 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5164 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5165 m_ulLastNMEATicktime = uiCurrentTickCount;
5167 if (m_tick_idx++ > 6) m_tick_idx = 0;
5172 if (NULL != GetStatusBar()) {
5175 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5178 wxString s1(tick_buf, wxConvUTF8);
5180 s1 += toSDMM(1,
gLat);
5182 s1 += toSDMM(2,
gLon);
5184 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5188 if (!std::isnan(
gSog))
5189 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5191 sogcog.Printf(
"SOG --- ");
5195 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5197 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5199 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5200 (
int)toMagnetic(
gCog), 0x00B0);
5202 cogs.Printf((
"COG ---%c"), 0x00B0);
5204 sogcog.Append(cogs);
5205 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5210void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5211 MemFootTimer.Stop();
5213 int memsize = GetApplicationMemoryUse();
5216 printf(
"Memsize: %d \n", memsize);
5219 if (memsize > (g_MemFootMB * 1000)) {
5223 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5224 unsigned int nCache = pCache->GetCount();
5227 for (
unsigned int i = 0; i < nCache; i++) {
5237 for (
unsigned int i = 0; i < nCache - 1; i++) {
5238 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5240 pcea[i] = pcea[i + 1];
5251 unsigned int idelete = 0;
5252 unsigned int idelete_max = pCache->GetCount();
5255 unsigned int minimum_cache = 1;
5256 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5258 while ((memsize > (g_MemFootMB * 1000)) &&
5259 (pCache->GetCount() > minimum_cache) &&
5260 (idelete < idelete_max)) {
5261 int memsizeb = memsize;
5265 memsize = GetApplicationMemoryUse();
5266 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5274 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5279void MyFrame::CheckToolbarPosition() {
5282 static bool bMaximized;
5284 if (IsMaximized() && !bMaximized) {
5291 PositionIENCToolbar();
5292 }
else if (!IsMaximized() && bMaximized) {
5300 PositionIENCToolbar();
5305void MyFrame::ProcessUnitTest() {
5306 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5313 cc->m_bFollow =
false;
5315 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5316 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5319 if (cc->m_groupIndex > 0) {
5320 while (ut_index < ChartData->GetChartTableEntries() &&
5321 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5325 if (ut_index < ChartData->GetChartTableEntries()) {
5329 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5330 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5337 if (cc->GetQuiltMode()) {
5338 if (cc->IsChartQuiltableRef(ut_index))
5339 cc->SelectQuiltRefdbChart(ut_index);
5341 cc->SelectdbChart(ut_index);
5344 if (g_unit_test_1) {
5352 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5353 cte->GetLatMin(), cte->GetLonMax(), NULL,
5357 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5358 cte->GetLatMax(), cte->GetLonMin(), NULL,
5361 cc->GetSize(&ww, &wh);
5362 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5364 ppm = wxMin(ppm, 1.0);
5371 if (ut_index > ut_index_max) exit(0);
5382 bool b_rotate =
false;
5384 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5387 if (!b_rotate && !g_btenhertz)
return;
5389 bool b_update =
false;
5391 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5394 struct timespec now;
5395 clock_gettime(CLOCK_MONOTONIC, &now);
5396 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5397 double diffc = diff / 1e9;
5400 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5401 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5402 if (gCog_tentative < 0.) gCog_tentative += 360.;
5403 gCog = gCog_tentative;
5407 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5408 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5409 double diffc = diff / 1e9;
5410 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5414 if (gSog_gt && !std::isnan(gCog_gt)) {
5415 double delta_t = diffc / 3600;
5416 double distance = gSog_gt * delta_t;
5419 double angr = gCog_gt / 180 * M_PI;
5420 double latr = gLat_gt * M_PI / 180;
5421 double D = distance / 3443;
5422 double sD = sin(D), cD = cos(D);
5423 double sy = sin(latr), cy = cos(latr);
5424 double sa = sin(angr), ca = cos(angr);
5426 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5427 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5437 if (cc) cc->DoCanvasCOGSet();
5446 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5447 cc->DoCanvasUpdate();
5456 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5459bool MyFrame::ProcessQuitFlag() {
5463 FrameTenHzTimer.Stop();
5465 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5466 if (top) top->Close(
true);
5473void MyFrame::ProcessDeferredTrackOn() {
5476 if (g_bDeferredStartTrack) {
5477 if (!g_bTrackActive) {
5480 g_bDeferredStartTrack =
false;
5483 g_bDeferredStartTrack =
false;
5488void MyFrame::ProcessAnchorWatch() {
5496 double d = g_nAWMax;
5499 bool toofar =
false;
5500 bool tooclose =
false;
5501 if (d >= 0.0) toofar = (dist * 1852. > d);
5502 if (d < 0.0) tooclose = (dist * 1852 < -d);
5504 if (tooclose || toofar)
5505 AnchorAlertOn1 =
true;
5507 AnchorAlertOn1 =
false;
5509 AnchorAlertOn1 =
false;
5517 double d = g_nAWMax;
5520 bool toofar =
false;
5521 bool tooclose =
false;
5522 if (d >= 0) toofar = (dist * 1852. > d);
5523 if (d < 0) tooclose = (dist * 1852 < -d);
5525 if (tooclose || toofar)
5526 AnchorAlertOn2 =
true;
5528 AnchorAlertOn2 =
false;
5530 AnchorAlertOn2 =
false;
5533 AnchorAlertOn1 =
true;
5536void MyFrame::SendFixToPlugins() {
5547 GPSData.
nSats = g_SatsInView;
5549 wxDateTime tCheck((time_t)m_fixtime);
5550 if (tCheck.IsValid()) {
5559 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5562 SendPositionFixToAllPlugIns(&GPSData);
5566void MyFrame::ProcessLogAndBells() {
5569 wxDateTime lognow = wxDateTime::Now();
5570 int hourLOC = lognow.GetHour();
5571 int minuteLOC = lognow.GetMinute();
5573 int minuteUTC = lognow.GetMinute();
5574 int second = lognow.GetSecond();
5576 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5577 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5578 (minuteUTC == 30)) {
5579 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5580 wxString day = lognow.FormatISODate();
5581 wxString utc = lognow.FormatISOTime();
5582 wxString navmsg =
"LOGBOOK: ";
5590 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5594 if (std::isnan(
gCog))
5595 cog.Printf(
"COG ----- ");
5597 cog.Printf(
"COG %10.5f ",
gCog);
5600 if (std::isnan(
gSog))
5601 sog.Printf(
"SOG ----- ");
5603 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5609 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5612 wxLogMessage(navmsg);
5613 g_loglast_time = lognow;
5615 int bells = (hourLOC % 4) * 2;
5616 if (minuteLOC != 0) bells++;
5617 if (!bells) bells = 8;
5619 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5620 m_BellsToPlay = bells;
5621 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5622 wxPostEvent(
this, ev);
5629 CheckToolbarPosition();
5633 if (ProcessQuitFlag())
return;
5635 if (bDBUpdateInProgress)
return;
5638 FrameTenHzTimer.Stop();
5640 ProcessDeferredTrackOn();
5642 ProcessAnchorWatch();
5643 ProcessLogAndBells();
5645 if (ShouldRestartTrack()) TrackDailyRestart();
5648 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5649 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5650 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5656 if (
gSog > 3.0) g_bCruising =
true;
5662 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5664 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5670 bool bnew_view =
false;
5671 if (!g_btenhertz) bnew_view = DoChartUpdate();
5678 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5681 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5684 cc->DrawBlinkObjects();
5687 if (bactiveRouteUpdate) {
5694 cc->SetOwnShipState(SHIP_NORMAL);
5696 if (cc->GetQuiltMode()) {
5697 double erf = cc->GetQuiltMaxErrorFactor();
5698 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5700 if (cc->m_singleChart) {
5701 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5702 cc->SetOwnShipState(SHIP_LOWACCURACY);
5706 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5709 (bVelocityValid != m_last_bVelocityValid) ||
5710 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5711 if (!g_bopengl) cc->UpdateShips();
5719 m_last_bVelocityValid = bVelocityValid;
5724 bool brq_dynamic =
false;
5726 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5727 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5729 if (pic->m_enabled && pic->m_init_state) {
5730 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5737 if (brq_dynamic) bnew_view =
true;
5741 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5744 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5749 if (cc->GetglCanvas()) {
5751 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5754 if (cc->m_bFollow) {
5755 cc->DoCanvasUpdate();
5772 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5786 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5787 g_pais_query_dialog_active->UpdateText();
5790 if (g_pAISTargetList && (0 == (g_tick % (5))))
5791 g_pAISTargetList->UpdateAISTargetList();
5794 UpdateGPSCompassStatusBoxes();
5799 console->RefreshConsoleData();
5806 if (m_bdefer_resize) {
5807 if (0 == (g_tick % (5))) {
5808 printf(
"___RESIZE\n");
5809 SetSize(m_defer_size);
5811 m_bdefer_resize =
false;
5818 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5820 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5821 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5825double MyFrame::GetMag(
double a,
double lat,
double lon) {
5826 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5827 auto loader = PluginLoader::GetInstance();
5828 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5835 wxDateTime now = wxDateTime::Now();
5836 SendJSON_WMM_Var_Request(lat, lon, now);
5837 if (fabs(gQueryVar) < 360.0)
5838 Variance = gQueryVar;
5840 return toMagnetic(a, Variance);
5843bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5849 v[
"Year"] = date.GetYear();
5850 v[
"Month"] = date.GetMonth();
5851 v[
"Day"] = date.GetDay();
5853 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5859void MyFrame::TouchAISActive() {
5861 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5863 if (cc) cc->TouchAISToolActive();
5867void MyFrame::UpdateAISTool() {
5871 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5873 if (cc) cc->UpdateAISTBTool();
5878void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5882 if (cc) cc->SetbTCUpdate(
true);
5885 RefreshAllCanvas(
false);
5890void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5894 bool b_rotate =
false;
5895 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5897 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5901 FrameCOGTimer.Stop();
5908 int period_ms = 100;
5910 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5913void MyFrame::DoCOGSet() {
5915 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5917 if (cc) cc->DoCanvasCOGSet();
5921void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5927 wxFont oldfont = pdc->GetFont();
5929 pdc->SetFont(*pFont);
5930 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5931 pdc->SetBackgroundMode(wxTRANSPARENT);
5933 pdc->DrawText(str, x, y + 1);
5934 pdc->DrawText(str, x, y - 1);
5935 pdc->DrawText(str, x + 1, y);
5936 pdc->DrawText(str, x - 1, y);
5938 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5940 pdc->DrawText(str, x, y);
5942 pdc->SetFont(oldfont);
5946void MyFrame::UpdateRotationState(
double rotation) {
5948 g_bCourseUp =
false;
5950 if (fabs(rotation) > .001) {
5951 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5952 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5954 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5957 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5958 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5960 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5964 UpdateGPSCompassStatusBoxes(
true);
5968void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5970 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5972 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5978int MyFrame::GetApplicationMemoryUse() {
5984 wxWindow *fWin = wxWindow::FindFocus();
5986 wxArrayString outputArray;
5987 wxString cmd(
"ps --no-headers -o vsize ");
5988 unsigned long pid = wxGetProcessId();
5990 cmd1.Printf(
"%ld", pid);
5992 wxExecute(cmd, outputArray);
5994 if (outputArray.GetCount()) {
5995 wxString s = outputArray.Item(0);
5997 if (s.ToLong(&vtmp)) memsize = vtmp;
6000 if (fWin) fWin->SetFocus();
6006 PROCESS_MEMORY_COUNTERS pmc;
6008 unsigned long processID = wxGetProcessId();
6010 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6012 if (NULL == hProcess)
return 0;
6014 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6032 memsize = pmc.WorkingSetSize / 1024;
6035 CloseHandle(hProcess);
6042double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6043 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6046void MyFrame::SetChartUpdatePeriod() {
6049 g_ChartUpdatePeriod = 0;
6054 bool bskewdc =
false;
6055 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6058 if (!g_bopengl && !cc->GetVP().b_quilt) {
6059 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6061 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6065 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6067 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6072 cc->UpdateCanvasControlBar();
6075void MyFrame::selectChartDisplay(
int type,
int family) {
6077 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6079 if (cc) cc->selectCanvasChartDisplay(type, family);
6082 UpdateGlobalMenuItems();
6091bool MyFrame::DoChartUpdate() {
6092 bool return_val =
false;
6095 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6097 if (cc) return_val |= cc->DoCanvasUpdate();
6103void MyFrame::MouseEvent(wxMouseEvent &event) {
6105 event.GetPosition(&x, &y);
6110#include <mach/mach.h>
6111#include <mach/message.h>
6112#include <mach/kern_return.h>
6113#include <mach/task_info.h>
6115#include <malloc/malloc.h>
6122#if defined(__linux__)
6123#include "sys/types.h"
6124#include "sys/sysinfo.h"
6127void MyFrame::DoPrint(
void) {
6129 g_PrintingInProgress =
true;
6132 GetPrimaryCanvas()->GetglCanvas()->Render();
6133 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6143 printer.Initialize(wxLANDSCAPE);
6144 printer.EnablePageNumbers(
false);
6145 printer.Print(
this, &printout);
6163 g_PrintingInProgress =
false;
6166 GetPrimaryCanvas()->SetFocus();
6172 wxString message_ID =
event.GetID();
6173 wxString message_JSONText =
event.GetJSONText();
6181 if (message_ID ==
"WMM_VARIATION_BOAT") {
6189 int numErrors = reader.
Parse(message_JSONText, &root);
6190 if (numErrors > 0) {
6196 wxString decl = root[
"Decl"].
AsString();
6198 decl.ToDouble(&decl_val);
6204 if (message_ID ==
"WMM_VARIATION") {
6212 int numErrors = reader.
Parse(message_JSONText, &root);
6213 if (numErrors > 0) {
6219 wxString decl = root[
"Decl"].
AsString();
6221 decl.ToDouble(&decl_val);
6223 gQueryVar = decl_val;
6226 if (message_ID ==
"GRIB_TIMELINE") {
6229 int numErrors = r.
Parse(message_JSONText, &v);
6231 if (numErrors > 0) {
6232 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6237 wxDateTime oldTimeSource = gTimeSource;
6239 if (v[
"Day"].AsInt() == -1) {
6240 gTimeSource = wxInvalidDateTime;
6241 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6243 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6244 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6245 v[
"Second"].AsInt());
6249 if (oldTimeSource != gTimeSource) {
6251 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6253 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6258 cc->pCwin->Refresh(
false);
6264 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6267 wxString trk_id = wxEmptyString;
6269 int numErrors = reader.
Parse(message_JSONText, &root);
6270 if (numErrors > 0)
return;
6275 v[
"Track_ID"] = trk_id;
6277 wxString name = wxEmptyString;
6278 if (ptrack->m_GUID == trk_id) {
6279 name = ptrack->GetName();
6280 if (name.IsEmpty()) {
6286 name = _(
"(Unnamed Track)");
6293 v[
"TotalNodes"] = ptrack->GetnPoints();
6294 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6296 v[
"lat"] = tp->m_lat;
6297 v[
"lon"] = tp->m_lon;
6300 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6301 SendJSONMessageToAllPlugins(msg_id, v);
6307 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6308 SendJSONMessageToAllPlugins(msg_id, v);
6310 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6313 wxString guid = wxEmptyString;
6315 int numErrors = reader.
Parse(message_JSONText, &root);
6316 if (numErrors > 0) {
6325 wxString name = wxEmptyString;
6327 if ((*it)->m_GUID == guid) {
6328 name = (*it)->m_RouteNameString;
6329 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6335 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6336 itp != (*it)->pRoutePointList->end(); itp++) {
6337 w[i][
"lat"] = (*itp)->m_lat;
6338 w[i][
"lon"] = (*itp)->m_lon;
6339 w[i][
"Name"] = (*itp)->GetName();
6340 w[i][
"Description"] = (*itp)->GetDescription();
6341 w[i][
"GUID"] = (*itp)->m_GUID;
6342 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6344 auto node = (*itp)->m_HyperlinkList->begin();
6345 if (node != (*itp)->m_HyperlinkList->end()) {
6347 while (node != (*itp)->m_HyperlinkList->end()) {
6349 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6350 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6351 httpLink->DescrText;
6358 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6359 SendJSONMessageToAllPlugins(msg_id, v);
6366 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6367 SendJSONMessageToAllPlugins(msg_id, v);
6368 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6373 int numErrors = reader.
Parse(message_JSONText, &root);
6374 if (numErrors > 0)
return;
6377 wxString str = root[
"mode"].
AsString();
6378 if (str ==
"Track") route =
false;
6383 for (RouteList::iterator it =
pRouteList->begin();
6385 wxString name = (*it)->m_RouteNameString;
6386 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6388 v[i][
"error"] =
false;
6389 v[i][
"name"] = name;
6390 v[i][
"GUID"] = (*it)->m_GUID;
6391 v[i][
"active"] = (*it)->IsActive();
6396 wxString name = ptrack->GetName();
6397 if (name.IsEmpty()) {
6403 name = _(
"(Unnamed Track)");
6405 v[i][
"error"] =
false;
6406 v[i][
"name"] = name;
6407 v[i][
"GUID"] = ptrack->m_GUID;
6412 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6413 SendJSONMessageToAllPlugins(msg_id, v);
6416 v[0][
"error"] =
true;
6417 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6418 SendJSONMessageToAllPlugins(msg_id, v);
6420 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6422 v[0][
"error"] =
true;
6425 v[0][
"error"] =
false;
6426 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6427 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6428 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6429 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6430 v[0][
"active_waypoint_lat"] =
6432 v[0][
"active_waypoint_lon"] =
6436 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6437 SendJSONMessageToAllPlugins(msg_id, v);
6441void MyFrame::FilterCogSog() {
6442 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6444 double cog_last =
gCog;
6447 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6448 COGFilterTable[i] = COGFilterTable[i - 1];
6449 COGFilterTable[0] = cog_last;
6452 if (!std::isnan(cog_last)) {
6454 double sum = 0., count = 0;
6455 for (
int i = 0; i < g_COGFilterSec; i++) {
6456 double adder = COGFilterTable[i];
6457 if (std::isnan(adder))
continue;
6459 if (fabs(adder - cog_last) > 180.) {
6460 if ((adder - cog_last) > 0.)
6473 else if (sum >= 360.)
6480 double sog_last =
gSog;
6483 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6484 SOGFilterTable[i] = SOGFilterTable[i - 1];
6485 SOGFilterTable[0] = sog_last;
6488 if (!std::isnan(
gSog)) {
6489 double sum = 0., count = 0;
6490 for (
int i = 0; i < g_SOGFilterSec; i++) {
6491 if (std::isnan(SOGFilterTable[i]))
continue;
6493 sum += SOGFilterTable[i];
6503void MyFrame::LoadHarmonics() {
6506 ptcmgr->LoadDataSources(TideCurrentDataSet);
6508 bool b_newdataset =
false;
6511 for (
auto a :
ptcmgr->GetDataSet()) {
6512 bool b_foundi =
false;
6513 for (
auto b : TideCurrentDataSet) {
6520 b_newdataset =
true;
6525 for (
auto a : TideCurrentDataSet) {
6526 bool b_foundi =
false;
6527 for (
auto b :
ptcmgr->GetDataSet()) {
6534 b_newdataset =
true;
6539 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6543void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6544 if (!ptarget)
return;
6547 wxDateTime mob_time = wxDateTime::Now();
6548 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6549 mob_label += _(
" on ");
6550 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6553 mob_label, wxEmptyString);
6554 pWP_MOB->SetShared(
true);
6556 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6558 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6560 pWP_MOB->SetUseSca(
false);
6568 wxString(_(
"Own ship")), wxEmptyString);
6570 pWP_MOB->SetUseSca(
false);
6577 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6593 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6594 SendJSONMessageToAllPlugins(msg_id, v);
6597 if (RouteManagerDialog::getInstanceFlag()) {
6604 RefreshAllCanvas(
false);
6606 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6607 mob_message += _(
" Time: ");
6608 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6609 mob_message += _(
" Ownship Position: ");
6610 mob_message += toSDMM(1,
gLat);
6612 mob_message += toSDMM(2,
gLon);
6613 mob_message += _(
" MOB Position: ");
6614 mob_message += toSDMM(1, ptarget->Lat);
6616 mob_message += toSDMM(2, ptarget->Lon);
6617 wxLogMessage(mob_message);
6620void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6624 OwnPoint->m_lat =
gLat;
6625 OwnPoint->m_lon =
gLon;
6627 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6632 MOB_Point->m_lat = ptarget->Lat;
6633 MOB_Point->m_lon = ptarget->Lon;
6635 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6636 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6638 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6639 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6642 RefreshAllCanvas(
false);
6645 wxDateTime mob_time = wxDateTime::Now();
6647 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6648 mob_message += _(
" Time: ");
6649 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6650 mob_message += _(
" Ownship Position: ");
6651 mob_message += toSDMM(1,
gLat);
6653 mob_message += toSDMM(2,
gLon);
6654 mob_message += _(
" MOB Position: ");
6655 mob_message += toSDMM(1, ptarget->Lat);
6657 mob_message += toSDMM(2, ptarget->Lon);
6659 wxLogMessage(mob_message);
6663void MyFrame::applySettingsString(wxString settings) {
6665 int last_UIScaleFactor = g_GUIScaleFactor;
6666 bool previous_expert = g_bUIexpert;
6667 g_last_ChartScaleFactor = g_ChartScaleFactor;
6668 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6671 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6677 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6679 if (rr & S52_CHANGED) {
6681 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6683 ->ClearCNSYLUPArray();
6684 ps52plib->GenerateStateHash();
6688 ProcessOptionsDialog(rr, pNewDirArray);
6693 bool b_newToolbar =
false;
6695 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6697 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6699 if (rr & TOOLBAR_CHANGED) {
6700 b_newToolbar =
true;
6705 if (previous_expert && !g_bUIexpert) {
6706 androidForceFullRepaint();
6710 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6714 SetGPSCompassScale();
6716 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6718 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6720 UpdateGPSCompassStatusBoxes(
true);
6723 AbstractPlatform::ShowBusySpinner();
6725 SetAllToolbarScale();
6729 AbstractPlatform::HideBusySpinner();
6731 RequestNewMasterToolbar(
true);
6738 UpdateControlBar(GetPrimaryCanvas());
6744 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6747#ifdef wxHAS_POWER_EVENTS
6748void MyFrame::OnSuspending(wxPowerEvent &event) {
6752 wxLogMessage(
"System suspend starting...");
6755void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6758 wxLogMessage(
"System is going to suspend.");
6761void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6764 wxLogMessage(
"System suspend was cancelled.");
6767int g_last_resume_ticks;
6768void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6769 wxDateTime now = wxDateTime::Now();
6770 wxLogMessage(
"System resumed from suspend.");
6772 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6775 wxLogMessage(
"Restarting streams.");
6776 g_last_resume_ticks = now.GetTicks();
6780 g_pMUX->ClearStreams();
6782 g_pMUX->StartAllStreams();
6791 if (IsMaximized()) {
6796 wxSize sz = GetSize();
6797 SetSize(wxSize(sz.x - 1, sz.y));
6809void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6810 bool btbRebuild =
false;
6812 bool b_reshow =
true;
6815 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6816 if ((ff > 0.01f) || bforcenew) {
6826 long orient = g_Platform->GetDefaultToolbarOrientation();
6827 wxWindow *toolbarParent =
this;
6829 toolbarParent = GetPrimaryCanvas();
6832 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6833 m_toolbar_callbacks);
6835 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6842 g_bmasterToolbarFull =
true;
6846 CreateMasterToolbar();
6861bool MyFrame::CollapseGlobalToolbar() {
6863 m_nMasterToolCountShown = 1;
6867 g_bmasterToolbarFull =
false;
6883 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6884 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6885 tic->m_bRequired =
true;
6890 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6891 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6895 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6896 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6897 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6902 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6903 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6907 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6908 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6909 _(
"Enable Tracking"),
"MUI_track");
6913 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6914 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6926 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6927 _(
"Print Chart"),
"MUI_print");
6931 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6932 _(
"About OpenCPN"),
"MUI_help");
6936 AddDefaultPositionPlugInTools();
6940 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6941 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6952 ArrayOfPlugInToolbarTools tool_array =
6954 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6956 if (!pttc->b_viz)
continue;
6958 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6961 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6962 if (g_bTrackActive) {
6963 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6970bool MyFrame::CheckAndAddPlugInTool() {
6978 if (!tb)
return false;
6980 int n_tools = tb->GetToolsCount();
6984 ArrayOfPlugInToolbarTools tool_array =
6987 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6989 if (pttc->position == n_tools) {
6990 wxBitmap *ptool_bmp;
6992 switch (global_color_scheme) {
6993 case GLOBAL_COLOR_SCHEME_DAY:
6994 ptool_bmp = pttc->bitmap_day;
6997 case GLOBAL_COLOR_SCHEME_DUSK:
6998 ptool_bmp = pttc->bitmap_dusk;
7000 case GLOBAL_COLOR_SCHEME_NIGHT:
7001 ptool_bmp = pttc->bitmap_night;
7004 ptool_bmp = pttc->bitmap_day;
7009 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7011 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7012 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7013 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7014 tic->m_bPlugin =
true;
7023 while (CheckAndAddPlugInTool()) {
7029bool MyFrame::AddDefaultPositionPlugInTools() {
7036 ArrayOfPlugInToolbarTools tool_array =
7039 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7043 if (!pttc->b_viz)
continue;
7045 if (pttc->position == -1)
7047 wxBitmap *ptool_bmp;
7049 switch (global_color_scheme) {
7050 case GLOBAL_COLOR_SCHEME_DAY:
7051 ptool_bmp = pttc->bitmap_day;
7053 case GLOBAL_COLOR_SCHEME_DUSK:
7054 ptool_bmp = pttc->bitmap_dusk;
7056 case GLOBAL_COLOR_SCHEME_NIGHT:
7057 ptool_bmp = pttc->bitmap_night;
7060 ptool_bmp = pttc->bitmap_day;
7065 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7067 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7068 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7069 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7070 tic->m_bPlugin =
true;
7089typedef struct _MSW_COLOR_SPEC {
7091 wxString S52_RGB_COLOR;
7095MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7096 {COLOR_MENUTEXT,
"UITX1", 0},
7097 {COLOR_BTNSHADOW,
"UIBCK", 0},
7100void SaveSystemColors() {
7114 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7115 while (pcspec->COLOR_NAME != -1) {
7116 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7121void RestoreSystemColors() {
7122 int element[NCOLORS];
7123 int rgbcolor[NCOLORS];
7126 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7127 while (pcspec->COLOR_NAME != -1) {
7128 element[i] = pcspec->COLOR_NAME;
7129 rgbcolor[i] = pcspec->SysRGB_COLOR;
7134 if (pSetSysColors) {
7135 pSetSysColors(i, (
unsigned long *)&element[0],
7136 (
unsigned long *)&rgbcolor[0]);
7142void SetSystemColors(ColorScheme cs) {
7144 int element[NCOLORS];
7145 int rgbcolor[NCOLORS];
7147 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7148 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7149 while (pcspec->COLOR_NAME != -1) {
7150 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7151 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7152 element[i] = pcspec->COLOR_NAME;
7158 pSetSysColors(i, (
unsigned long *)&element[0],
7159 (
unsigned long *)&rgbcolor[0]);
7163 RestoreSystemColors();
7171static const WORD MAX_CONSOLE_LINES =
7176void RedirectIOToConsole()
7181 wxIntPtr lStdHandle;
7183 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7193 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7194 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7195 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7199 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7200 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7201 fp = _fdopen(hConHandle,
"w");
7203 setvbuf(stdout, NULL, _IONBF, 0);
7207 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7208 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7209 fp = _fdopen(hConHandle,
"r");
7211 setvbuf(stdin, NULL, _IONBF, 0);
7215 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7216 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7217 fp = _fdopen(hConHandle,
"w");
7219 setvbuf(stderr, NULL, _IONBF, 0);
7230 FontMgr::Get().SetLocale(g_locale);
7251 if (g_pais_query_dialog_active) {
7252 g_pais_query_dialog_active->Destroy();
7253 g_pais_query_dialog_active = NULL;
7256 auto alert_dlg_active =
7258 if (alert_dlg_active) {
7259 alert_dlg_active->Destroy();
7260 g_pais_alert_dialog_active =
nullptr;
7263 if (g_pAISTargetList) {
7265 g_pAISTargetList->Disconnect_decoder();
7266 g_pAISTargetList->Destroy();
7267 g_pAISTargetList = NULL;
7271 if (gFrame->m_pMenuBar) {
7272 gFrame->SetMenuBar(NULL);
7273 gFrame->m_pMenuBar->Destroy();
7274 gFrame->m_pMenuBar = NULL;
7276 gFrame->BuildMenuBar();
7279 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7281 if (cc) cc->CanvasApplyLocale();
7286 wxString perspective;
7288 pConfig->Read(
"AUIPerspective", &perspective);
7302 bool bno_load =
false;
7303 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7305 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7306 wxAuiPaneInfo pane = pane_array_val[i];
7307 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7313 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7318 gFrame->RequestNewToolbars(
true);
7319 gFrame->RequestNewMasterToolbar(
true);
7326 : wxThread(wxTHREAD_JOINABLE) {
7327 m_filename = filename;
7338 newChart->SetNativeScale(m_scale);
7339 newChart->SetFullExtent(m_ext);
7341 newChart->FindOrCreateSenc(m_filename);
7346 wxString m_filename;
7352static double chart_dist(
int index) {
7358 if (cte.GetBBox().Contains(
gLat,
gLon))
7363 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7364 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7365 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7368 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7369 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7371 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7377WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7378static int CompareInts(
int n1,
int n2) {
7379 double d1 = chart_dist(n1);
7380 double d2 = chart_dist(n2);
7381 return (
int)(d1 - d2);
7386 wxString chart_path;
7391WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7393#include <wx/arrimpl.cpp>
7396void ParseAllENC(wxWindow *parent) {
7397 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7405 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7408 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7410 idx_sorted_by_distance.Add(i);
7414 if (count == 0)
return;
7416 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7422 ArrayOfCompressTargets ct_array;
7423 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7424 int i = idx_sorted_by_distance[j];
7427 double distance = chart_dist(i);
7429 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7432 pct->distance = distance;
7433 pct->chart_path = filename;
7435 ct_array.push_back(pct);
7438 int thread_count = 0;
7441 if (g_nCPUCount > 0)
7442 thread_count = g_nCPUCount;
7444 thread_count = wxThread::GetCPUCount();
7446 if (thread_count < 1) {
7455 for(
int t = 0; t < thread_count; t++)
7459 wxGenericProgressDialog *prog =
nullptr;
7463 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7464 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7466 prog =
new wxGenericProgressDialog();
7468 prog->SetFont(*qFont);
7470 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7471 count + 1, parent, style);
7480 prog->ShowWindowModal();
7489 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7490 wxString filename = ct_array[j].chart_path;
7491 double distance = ct_array[j].distance;
7492 int index =
ChartData->FinddbIndex(filename);
7493 if (index < 0)
continue;
7496 ext.NLAT = cte.GetLatMax();
7497 ext.SLAT = cte.GetLatMin();
7498 ext.WLON = cte.GetLonMin();
7499 ext.ELON = cte.GetLonMax();
7501 int scale = cte.GetScale();
7504 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7507 if (wxThread::IsMain()) {
7509 wxSize sz = prog->GetSize();
7514 prog->Update(count, msg, &skip);
7526 newChart->SetNativeScale(
scale);
7527 newChart->SetFullExtent(ext);
7528 newChart->DisableBackgroundSENC();
7530 newChart->FindOrCreateSenc(filename,
7534 if (wxThread::IsMain()) {
7535 msg.Printf(_(
"ENC Completed."));
7537 prog->Update(count, msg, &skip);
7547 for (
int t = 0;; t = (t + 1) % thread_count) {
7554 if (!workers[t]->IsAlive()) {
7567#if defined(__WXMSW__) || defined(__WXOSX__)
7574 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,...
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.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
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.
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.