53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
83#include "model/nav_object_database.h"
97#include "ais_info_gui.h"
98#include "dialog_alert.h"
102#include "ais_info_gui.h"
126#include "load_errors_dlg.h"
129#include "N2KParser.h"
152#include "user_colors.h"
158#include "androidUTIL.h"
162static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
173GLenum g_texture_rectangle_format;
176#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
177extern wxLocale *plocale_def_lang;
181extern bool g_b_EnableVBO;
182extern GLenum g_texture_rectangle_format;
186static int g_last_ChartScaleFactor;
187static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
188static int options_subpage = 0;
189static bool b_reloadForPlugins;
191static wxSize options_lastWindowSize(0, 0);
192static wxPoint options_lastWindowPos(0, 0);
196static double gQueryVar = 361.0;
198static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
199static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
201static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
207typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
208typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
210static SetSysColors_t pSetSysColors;
211static GetSysColor_t pGetSysColor;
213void SaveSystemColors();
214void RestoreSystemColors();
219DWORD color_3ddkshadow;
221DWORD color_activecaption;
222DWORD color_gradientactivecaption;
223DWORD color_captiontext;
224DWORD color_windowframe;
225DWORD color_inactiveborder;
230#include <wx/msw/msvcrt.h>
234static const long long lNaN = 0xfff8000000000000;
235#define NAN (*(double *)&lNaN)
239static double gLat_gt, gLon_gt;
240static double gLat_gt_m1, gLon_gt_m1;
241static uint64_t fix_time_gt;
242static uint64_t fix_time_gt_last;
244static double gSog_gt, gHdt_gt;
245static double gCog_gt_m1, gHdt_gt_m1;
246static uint64_t hdt_time_gt;
247static double cog_rate_gt, hdt_rate_gt;
249void InitializeUserColors();
250void DeInitializeUserColors();
251void SetSystemColors(ColorScheme cs);
253static bool LoadAllPlugIns(
bool load_enabled) {
254 AbstractPlatform::ShowBusySpinner();
255 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
256 AbstractPlatform::HideBusySpinner();
260static void LaunchLocalHelp() {
262 androidLaunchHelpView();
264 wxString def_lang_canonical =
"en_US";
267 if (plocale_def_lang)
268 def_lang_canonical = plocale_def_lang->GetCanonicalName();
271 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
273 wxString help_try = help_locn + def_lang_canonical +
".html";
275 if (!::wxFileExists(help_try)) {
276 help_try = help_locn +
"en_US" +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"web" +
".html";
282 if (!::wxFileExists(help_try))
return;
285 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
290static wxString _menuText(wxString name, wxString shortcut) {
294 menutext <<
"\t" << shortcut;
299static void DoHelpDialog() {
311 [] { LaunchLocalHelp(); });
323#if defined(__WXGTK__) || defined(__WXQT__)
324#include "bitmaps/opencpn.xpm"
339 if (g_bInlandEcdis) {
343 wxPoint tbp_incanvas =
346 g_iENCToolbarPosY = tbp_incanvas.y;
347 g_iENCToolbarPosX = tbp_incanvas.x;
355 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
359 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
362 g_iENCToolbarPosY = -1;
365 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
371 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
375 double tool_scale_factor =
376 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
378 tool_scale_factor, callbacks);
388#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
391static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
392 const char *prop_name) {
396 unsigned long ret_nitems;
397 unsigned long ret_bytes_after;
398 unsigned char *ret_prop;
400 xa_prop_name = XInternAtom(disp, prop_name, False);
408 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
409 &xa_ret_type, &ret_format, &ret_nitems,
410 &ret_bytes_after, &ret_prop) != Success)
413 if (xa_ret_type != xa_prop_type) {
417 return (
char *)ret_prop;
422static bool isTransparentToolbarInOpenGLOK() {
429 if (!g_bdisable_opengl) {
430 Display *disp = XOpenDisplay(NULL);
432 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
434 "_NET_SUPPORTING_WM_CHECK")) ||
435 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_WIN_SUPPORTING_WM_CHECK"))) {
440 if ((wm_name = get_X11_property(disp, *sup_window,
441 XInternAtom(disp,
"UTF8_STRING", False),
443 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
446 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
461wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
463 font->GetFamily(), font->GetStyle(),
464 font->GetWeight(),
false, font->GetFaceName());
466wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
467 wxFontStyle style, wxFontWeight weight,
468 const wxString faceName,
double scale) {
472wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
473 return GetOCPNScaledFont_PlugIn(label, Ptsize);
482wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
484BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
485EVT_CLOSE(MyFrame::OnCloseWindow)
486EVT_MENU(wxID_EXIT, MyFrame::OnExit)
487EVT_SIZE(MyFrame::OnSize)
488EVT_MOVE(MyFrame::OnMove)
489EVT_ICONIZE(MyFrame::OnIconize)
490EVT_MENU(-1, MyFrame::OnToolLeftClick)
491EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
493EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
494EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
495EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
497EVT_MAXIMIZE(MyFrame::OnMaximize)
498EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
499 MyFrame::RequestNewToolbarArgEvent)
500EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
502EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
503EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
504EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
506#ifdef wxHAS_POWER_EVENTS
507EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
508EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
509EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
510EVT_POWER_RESUME(MyFrame::OnResume)
521static
void onBellsFinishedCB(
void *ptr) {
522 auto framePtr =
static_cast<MyFrame *
>(ptr);
524 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
525 wxPostEvent(framePtr, ev);
530 auto msg = ev.GetString().ToStdString();
531 auto ¬eman = NotificationManager::GetInstance();
532 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
535static NmeaLog *GetDataMonitor() {
536 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
537 return dynamic_cast<NmeaLog *
>(w);
540MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
541 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
542 OpenFileFunc open_gpx_file)
544 m_connections_dlg(nullptr),
546 m_pauidockart(pauidockart),
547 m_rest_server(rest_server),
548 m_open_gpx_file(open_gpx_file) {
560 m_ulLastNMEATicktime = 0;
561 m_data_monitor->Hide();
563 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
567 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
570 InitTimer.SetOwner(
this, INIT_TIMER);
572 m_initializing =
false;
573 m_toolbar_callbacks.render_gl_textures =
575 [&](
ocpnDC &dc,
float *coords,
float *uv) {
576 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
577 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
580 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
584 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
587 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
590 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
593 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
596 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
598 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
607 m_bTimeIsSet =
false;
608 m_bdefer_resize =
false;
611 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
612 COGFilterTable[i] = NAN;
613 SOGFilterTable[i] = NAN;
615 m_last_bGPSValid =
false;
616 m_last_bVelocityValid =
false;
626 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
631 double process_noise_std = 1.0;
632 double measurement_noise_std = 0.5;
636 m_ChartUpdatePeriod = 1;
641 log_callbacks.log_is_active = [&]() {
642 auto log = GetDataMonitor();
643 return log && log->IsVisible();
645 log_callbacks.log_message = [&](
Logline ll) {
646 NmeaLog *monitor = GetDataMonitor();
649 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
652 ais_callbacks.confirm_stop_track = []() {
653 int r = OCPNMessageBox(
655 _(
"This AIS target has Persistent tracking selected by MMSI "
657 "A Persistent track recording will therefore be restarted for this "
659 "Do you instead want to stop Persistent tracking for this target?"),
660 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
661 return r == wxID_YES;
663 ais_callbacks.get_target_mmsi = []() {
664 auto alert_dlg_active =
666 assert(alert_dlg_active);
667 return alert_dlg_active->Get_Dialog_MMSI();
675 wxLogMessage(
" **** Connect stuff");
681 Connect(wxEVT_OCPN_MSG,
682 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
690 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
698#if defined(__WXGTK__) || defined(__WXQT__)
699 wxIcon app_icon(opencpn);
707 wxDynamicLibrary dllUser32(
"user32.dll");
709 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
710 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
715 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
720 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
721 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
723 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
724 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
725 [&](wxCommandEvent) { Refresh(); });
726 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
728 m_update_statusbar_listener.Init(
729 GuiEvents::GetInstance().gframe_update_status_bar,
731 m_center_aistarget_listener.Init(
732 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
733 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
734 CenterAisTarget(ais_target);
736 m_reload_charts_listener.Init(
737 GuiEvents::GetInstance().on_finalize_chartdbs,
738 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
742 EnableFullScreenView();
744 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
750 FrameTenHzTimer.Stop();
765 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
771void MyFrame::FreezeCharts() {
774 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
776 if (cc && !cc->IsFrozen()) cc->Freeze();
780void MyFrame::CenterAisTarget(
781 const std::shared_ptr<const AisTargetData> &ais_target) {
789 double factor = cc->GetScaleValue() / 5000.0;
790 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
796void MyFrame::ThawCharts() {
799 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
801 if (cc && cc->IsFrozen()) cc->Thaw();
808 switch (event.type) {
809 case SENC_BUILD_STARTED:
812 case SENC_BUILD_DONE_NOERROR:
814 chart =
event.m_ticket->m_chart;
816 chart->PostInit(FULL_INIT, global_color_scheme);
818 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
820 if (cc) cc->ClearS52PLIBStateHash();
827 delete event.m_ticket;
829 case SENC_BUILD_DONE_ERROR:
830 wxLogDebug(
"SENC build done: SENC_BUILD_DONE_ERROR");
833 delete event.m_ticket;
840void MyFrame::StartRebuildChartDatabase() {
841 bool b_SetInitialPoint =
false;
844 ArrayOfCDI ChartDirArray;
845 pConfig->LoadChartDirArray(ChartDirArray);
847 if (ChartDirArray.GetCount()) {
852 _(
"OpenCPN needs to update the chart database from config file "
856 wxICON_INFORMATION | wxOK);
864 _(
"Rebuilding chart database from configuration file entries..."));
868 wxString dummy1 = _(
"Elapsed time : ");
869 wxString dummy2 = _(
"Estimated time : ");
870 wxString dummy3 = _(
"Remaining time : ");
871 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
872 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
880void MyFrame::OnBellsFinished(wxCommandEvent &event) {
881 int bells = wxMin(m_BellsToPlay, 2);
882 if (bells <= 0)
return;
884 wxString soundfile =
"sounds";
885 appendOSDirSlash(&soundfile);
886 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
887 soundfile.Prepend(g_Platform->GetSharedDataDir());
888 wxLogMessage(
"Using bells sound file: " + soundfile);
890 o_sound::Sound *sound = bells_sound[bells - 1];
891 sound->SetFinishedCallback(onBellsFinishedCB,
this);
892 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
893 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
894 sound->Load(soundfile);
895 if (!sound->IsOk()) {
896 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
900 m_BellsToPlay -= bells;
903void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
905void MyFrame::OnMaximize(wxMaximizeEvent &event) {
912void MyFrame::ReloadAllVP() {
913 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
915 if (cc) cc->ReloadVP();
919void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
920 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
923 global_color_scheme = cs;
926 case GLOBAL_COLOR_SCHEME_DAY:
929 case GLOBAL_COLOR_SCHEME_DUSK:
932 case GLOBAL_COLOR_SCHEME_NIGHT:
933 SchemeName =
"NIGHT";
940 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
942 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
943 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
944 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
945 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
946 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
948 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
977 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
978 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
982 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
984 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
988 user_colors::GetMapByScheme(SchemeName.ToStdString());
993 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
996 cc->SetColorScheme(cs);
997 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
998 cc->HideChartInfoWindow();
999 cc->SetQuiltChartHiLiteIndex(-1);
1005 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1017 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1030 if (g_pais_query_dialog_active) {
1031 bool b_isshown = g_pais_query_dialog_active->IsShown();
1032 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1033 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1035 g_pais_query_dialog_active->Close();
1038 g_pais_query_dialog_active->
Create(
1039 this, -1, _(
"AIS Target Query"),
1040 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1041 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1042 g_pais_query_dialog_active->UpdateText();
1043 if (b_isshown) g_pais_query_dialog_active->Show();
1048 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1052 ApplyGlobalColorSchemetoStatusBar();
1054 UpdateAllToolbars(cs);
1059 bool btoolbarFull = g_bmasterToolbarFull;
1065 if (!btoolbarFull) {
1067 RequestNewMasterToolbar();
1069 CollapseGlobalToolbar();
1072 RequestNewMasterToolbar();
1081void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1082 if (m_pStatusBar != NULL) {
1083 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1084 m_pStatusBar->ClearBackground();
1095void MyFrame::CancelAllMouseRoute() {
1097 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1099 if (cc) cc->CancelMouseRoute();
1103void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1111 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1119 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1128 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1131 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1132 config_array.Item(i)->canvas = NULL;
1138 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1143 switch (g_canvasConfig) {
1157 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1158 cc->GetglCanvas()->Show();
1161 config_array.Item(0)->canvas = cc;
1165 cc->ApplyCanvasConfig(config_array.Item(0));
1169 cc->ConfigureChartBar();
1170 cc->SetColorScheme(global_color_scheme);
1171 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1172 cc->SetShowGPS(
true);
1175 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1177 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1193 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1196 config_array.Item(0)->canvas = cc;
1198 cc->ApplyCanvasConfig(config_array.Item(0));
1201 cc->ConfigureChartBar();
1202 cc->SetColorScheme(global_color_scheme);
1203 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1204 cc->SetShowGPS(
false);
1207 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1209 .CaptionVisible(
false)
1211 .CloseButton(
false);
1220 if (config_array.GetCount() < 2) {
1222 pcc->configIndex = 1;
1226 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1227 config_array.Add(pcc);
1230 config_array.Item(1)->canvas = cc;
1232 cc->ApplyCanvasConfig(config_array.Item(1));
1235 cc->ConfigureChartBar();
1236 cc->SetColorScheme(global_color_scheme);
1237 cc->SetShowGPS(
true);
1239 cc->SetShowGPSCompassWindow(
true);
1242 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1244 .CaptionVisible(
false)
1246 .CloseButton(
false);
1247 g_pauimgr->GetPane(cc).RightDockable(
true);
1251 config_array.Item(1)->canvasSize =
1252 wxSize(GetClientSize().x / 2, GetClientSize().y);
1253 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1258 if (b_useStoredSize) {
1259 int ccw = config_array.Item(1)->canvasSize.x;
1260 int cch = config_array.Item(1)->canvasSize.y;
1263 if (ccw < GetClientSize().x / 10) {
1264 ccw = GetClientSize().x / 2;
1265 cch = GetClientSize().y;
1268 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1269 cc->SetSize(ccw, cch);
1287 console->SetColorScheme(global_color_scheme);
1292 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1298void MyFrame::RequestNewToolbars(
bool bforcenew) {
1299 if (b_inCloseWindow) {
1303 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1304 PositionIENCToolbar();
1313void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1319void MyFrame::SetAllToolbarScale() {
1320 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1323void MyFrame::SetGPSCompassScale() {
1324 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1328 wxPoint screenPoint = ::wxGetMousePosition();
1331 switch (g_canvasConfig) {
1333 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1336 if (canvas->GetScreenRect().Contains(
1340 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1343 if (canvas->GetScreenRect().Contains(
1350 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1353 if (canvas->GetScreenRect().Contains(
1354 canvas->ScreenToClient(screenPoint)))
1362int MyFrame::GetCanvasIndexUnderMouse() {
1363 wxPoint screenPoint = ::wxGetMousePosition();
1366 switch (g_canvasConfig) {
1368 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1371 if (canvas->GetScreenRect().Contains(
1375 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1378 if (canvas->GetScreenRect().Contains(
1385 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1388 if (canvas->GetScreenRect().Contains(
1389 canvas->ScreenToClient(screenPoint)))
1397bool MyFrame::DropMarker(
bool atOwnShip) {
1404 if (!canvas)
return false;
1411 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1413 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1415 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1426 RefreshAllCanvas(
false);
1431void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1432 if (g_canvasConfig != 0) {
1435 int nTargetGTK = -1;
1437 wxWindow *source = FindFocus();
1443 switch (g_canvasConfig) {
1445 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1448 if (canvas && (canvas == test)) {
1453 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1456 if (canvas && (canvas == test)) {
1464 int nfinalTarget = nTarget;
1466 nfinalTarget = nTargetGTK;
1468 target = ConfigMgr::Get()
1469 .GetCanvasConfigArray()
1474 target->Refresh(
true);
1485void MyFrame::FastClose() {
1487 FrameTenHzTimer.Stop();
1489 FrameTimer1.Start(1);
1493void MyFrame::OnExit(wxCommandEvent &event) {
1497void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1500 if (b_inCloseWindow) {
1510 if (!g_bDeferredInitDone)
return;
1527 if (bDBUpdateInProgress)
return;
1529 b_inCloseWindow =
true;
1531 ::wxSetCursor(wxCURSOR_WAIT);
1535 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1537 if (cc && cc->IsMeasureActive()) {
1538 cc->CancelMeasureRoute();
1543 SendPreShutdownHookToPlugins();
1547 if (g_pAISTargetList) {
1548 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1549 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1550 g_pauimgr->DetachPane(g_pAISTargetList);
1577 SetCursor(wxCURSOR_WAIT);
1579 RefreshAllCanvas(
true);
1585 RestoreScreenBrightness();
1596 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1597 g_iENCToolbarPosY = tbp_incanvas.y;
1598 g_iENCToolbarPosX = tbp_incanvas.x;
1602 g_bframemax = IsMaximized();
1605 FrameTenHzTimer.Stop();
1607 FrameCOGTimer.Stop();
1621 if (g_bAutoAnchorMark) {
1622 bool watching_anchor =
false;
1630 wxDateTime now = wxDateTime::Now();
1631 wxTimeSpan uptime = now.Subtract(g_start_time);
1633 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1634 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1639 if (g_declutter_anchorage) {
1640 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1641 if (pr->GetName().StartsWith(
"Anchorage")) {
1642 double a =
gLat - pr->m_lat;
1643 double b =
gLon - pr->m_lon;
1644 double l = sqrt((a * a) + (b * b));
1647 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1649 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1650 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1658 wxString name = now.Format();
1659 name.Prepend(_(
"Anchorage created "));
1665 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1674 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1678 NavObj_dB::GetInstance().Close();
1682 pConfig->DeleteGroup(
"/Routes");
1683 pConfig->DeleteGroup(
"/Marks");
1702 if (g_pAISTargetList) {
1703 g_pAISTargetList->Disconnect_decoder();
1704 g_pAISTargetList->Destroy();
1707 if (RouteManagerDialog::getInstanceFlag()) {
1724 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1726 if (cc) cc->Destroy();
1750 CommBridge::GetInstance().SaveConfig();
1770 auto ®istry = CommDriverRegistry::GetInstance();
1771 registry.CloseAllDrivers();
1774 for (
auto *cp : TheConnectionParams()) {
1779 while (pLayerList->size())
delete *pLayerList->begin();
1783 ReleaseApiListeners();
1786 g_bTempShowMenuBar =
false;
1788#define THREAD_WAIT_SECONDS 5
1798 wxLogMessage(
"Starting compressor pool drain");
1799 wxDateTime now = wxDateTime::Now();
1800 time_t stall = now.GetTicks();
1801 time_t end = stall + THREAD_WAIT_SECONDS;
1804 while (stall < end) {
1805 wxDateTime later = wxDateTime::Now();
1806 stall = later.GetTicks();
1809 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1818 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1824 uninitIXNetSystem();
1832 wxLogMessage(
"gFrame destroyed.");
1835#ifndef USE_ANDROID_GLES2
1836 qDebug() <<
"Calling OnExit()";
1840 wxTheApp->ExitMainLoop();
1843void MyFrame::OnMove(wxMoveEvent &event) {
1844 auto idx = wxDisplay::GetFromWindow(
this);
1857 DEBUG_LOG <<
"Moved to " << idx
1858#if wxCHECK_VERSION(3, 1, 6)
1859 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1860 << wxDisplay(idx).GetPPI().GetY()
1861 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1863 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1864 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1865 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1866 << wxGetDisplaySizeMM().GetY()
1867 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1876 if (g_config_display_size_manual) {
1885 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1888 cc->SetMUIBarPosition();
1897 UpdateGPSCompassStatusBoxes();
1907 PositionIENCToolbar();
1913 g_nframewin_posx = GetPosition().x;
1914 g_nframewin_posy = GetPosition().y;
1917void MyFrame::ProcessCanvasResize() {
1918 UpdateGPSCompassStatusBoxes(
true);
1922 PositionIENCToolbar();
1925 TriggerRecaptureTimer();
1929void MyFrame::TriggerRecaptureTimer() {
1930 m_recaptureTimer.Start(
1931 1000, wxTIMER_ONE_SHOT);
1934void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1936void MyFrame::SetCanvasSizes(wxSize frameSize) {
1940 int cccw = frameSize.x;
1941 int ccch = frameSize.y;
1945 switch (g_canvasConfig) {
1951 cc->GetSize( &cur_width, &cur_height );
1952 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1954 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1956 cc->SetSize( 0, 0, cccw, ccch );
1966 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1967 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1969 ccw = wxMin(ccw, cccw * 8 / 10);
1970 ccw = wxMax(ccw, cccw * 2 / 10);
1974 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1981 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1998void MyFrame::OnIconize(wxIconizeEvent &event) {
2008 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2010 if (cc && cc->GetMUIBar()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()) {
2012 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2013 cc->GetMUIBar()->PushCanvasOptions();
2022void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2024void MyFrame::ODoSetSize() {
2026 GetClientSize(&x, &y);
2029 if (m_pStatusBar != NULL) {
2030 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2031 int currentCount = m_pStatusBar->GetFieldsCount();
2032 if (currentCount != m_StatusBarFieldCount) {
2033 if ((currentCount > 0) && (currentCount < 7)) {
2036 int widths[] = {2, 2, 2, 2, 2, 2};
2037 m_pStatusBar->SetStatusWidths(currentCount, widths);
2040 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2043 if (m_StatusBarFieldCount) {
2048 if (m_StatusBarFieldCount > 2) {
2049 int widths[] = {-6, -5, -5, -6, -4};
2050 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2051 }
else if (m_StatusBarFieldCount == 2) {
2052 int cwidth = x * 90 / 100;
2053 int widths[] = {100, 100};
2054 widths[0] = cwidth * 6.4 / 10.0;
2055 widths[1] = cwidth * 3.6 / 10.0;
2056 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2058 int widths[] = {100, 100};
2059 widths[0] = x * 90 / 100;
2060 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2063 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2064 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2065 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2067 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2069 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2077 m_pStatusBar->GetFieldRect(0, stat_box);
2080 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2082 wxFont sys_font = *wxNORMAL_FONT;
2083 int try_font_size = sys_font.GetPointSize();
2086 int min_font_size = 10;
2096 wxFont *statusBarFont =
2097 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2098 int font_size = statusBarFont->GetPointSize();
2100 font_size = wxMin(font_size,
2103 wxMax(font_size, min_font_size);
2106 font_size = statusBarFont->GetPointSize();
2113 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2114 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2116 int min_height = stat_box.height;
2118 m_pStatusBar->SetFont(*pstat_font);
2119 m_pStatusBar->SetForegroundColour(
2120 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2122 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2124 (min_height >> 1) * 2;
2125 m_pStatusBar->SetMinHeight(min_height);
2134 SetCanvasSizes(GetClientSize());
2136 UpdateGPSCompassStatusBoxes(
true);
2138 if (
console) PositionConsole();
2141 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2143 if (cc) cc->FormatPianoKeys();
2149 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2150 GetPrimaryCanvas()->GetCompass()->GetRect());
2176 options_lastWindowSize = wxSize(0, 0);
2177 options_lastWindowPos = wxPoint(0, 0);
2184 if (!b_inCloseWindow) {
2187 resizeAndroidPersistents();
2191 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2192 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2198void MyFrame::PositionConsole() {
2199#if defined(__WXMSW__) || defined(__WXMAC__)
2200 if (NULL == GetPrimaryCanvas())
return;
2202 int ccx, ccy, ccsx, ccsy, consx, consy;
2207 consoleHost->GetSize(&ccsx, &ccsy);
2208 consoleHost->GetPosition(&ccx, &ccy);
2210 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2211 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2212 consoleHost = GetPrimaryCanvas();
2217 if (consoleHost->GetCompass()) {
2218 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2220 if (compass_rect.y < 100)
2221 yOffset = compass_rect.y + compass_rect.height + 45;
2225 wxSize csz =
console->GetSize();
2229 wxPoint screen_pos =
2230 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2233 if (NULL == GetPrimaryCanvas())
return;
2235 int ccx, ccy, ccsx, ccsy, consx, consy;
2240 consoleHost->GetSize(&ccsx, &ccsy);
2241 consoleHost->GetPosition(&ccx, &ccy);
2243 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2244 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2245 consoleHost = GetPrimaryCanvas();
2248 int yTopOffset = 60;
2249 int yBottomOffset = 0;
2251 if (consoleHost->GetCompass()) {
2252 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2254 if (compass_rect.y < 100)
2255 yTopOffset = compass_rect.y + compass_rect.height;
2257 if (consoleHost->GetMUIBar()) {
2258 wxRect mui_rect = consoleHost->GetMUIBarRect();
2259 yBottomOffset = ccsy - mui_rect.y;
2263 wxSize csz =
console->GetSize();
2266 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2268 if (consy < yAvail) {
2269 yFinal = (yAvail - consy) / 2;
2270 yFinal += yTopOffset;
2271 }
else if (
console->GetCDI()->IsShown()) {
2272 int cdi_height =
console->GetCDI()->GetSize().y;
2273 int consy_no_cdi = consy - cdi_height;
2274 yFinal = (yAvail - consy_no_cdi) / 2;
2275 yFinal += yTopOffset;
2279 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2284void MyFrame::UpdateAllFonts() {
2293 DestroyPersistentDialogs();
2295 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2300void MyFrame::DestroyPersistentDialogs() {
2301 if (g_pais_query_dialog_active) {
2302 g_pais_query_dialog_active->Hide();
2303 g_pais_query_dialog_active->Destroy();
2304 g_pais_query_dialog_active = NULL;
2332void MyFrame::RefreshGroupIndices() {
2334 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2336 if (cc) cc->canvasRefreshGroupIndex();
2340bool MyFrame::DisableTbarTooltips() {
2345 wxLogWarning(
"Global g_MainToolbar has not been created.");
2349void MyFrame::EnableTbarTooltips() {
2355void MyFrame::HideTbarTooltip() {
2361void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2363 switch (event.GetId()) {
2364 case ID_MENU_SCALE_OUT:
2365 DoStackDelta(GetPrimaryCanvas(), 1);
2369 case ID_MENU_SCALE_IN:
2370 DoStackDelta(GetPrimaryCanvas(), -1);
2374 case ID_MENU_ZOOM_IN: {
2375 if (GetFocusCanvas()) {
2376 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2381 case ID_MENU_ZOOM_OUT: {
2382 if (GetFocusCanvas()) {
2383 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2388 case ID_MENU_ROUTE_NEW: {
2389 if (GetFocusCanvas()) {
2390 if (0 == GetFocusCanvas()->m_routeState) {
2391 GetFocusCanvas()->StartRoute();
2393 GetFocusCanvas()->FinishRoute();
2399 case ID_MENU_TOOL_MEASURE: {
2400 GetPrimaryCanvas()->StartMeasureRoute();
2404 case ID_MENU_TOOL_NMEA_DBG_LOG:
2405 m_data_monitor->Show();
2406 m_data_monitor->Raise();
2409 case ID_MENU_TOOL_IO_MONITOR:
2410 m_data_monitor->Show();
2413 case ID_MENU_MARK_BOAT: {
2418 case ID_MENU_MARK_CURSOR: {
2423 case ID_MENU_NAV_FOLLOW: {
2424 if (
gFrame->GetPrimaryCanvas())
2425 gFrame->GetPrimaryCanvas()->TogglebFollow();
2429 case ID_MENU_CHART_OUTLINES: {
2430 ToggleChartOutlines(GetFocusCanvas());
2434 case ID_MENU_CHART_QUILTING: {
2435 ToggleQuiltMode(GetFocusCanvas());
2439 case ID_MENU_UI_CHARTBAR: {
2440 ToggleChartBar(GetFocusCanvas());
2444 case ID_MENU_ENC_TEXT:
2446 ToggleENCText(GetFocusCanvas());
2449 case ID_MENU_ENC_LIGHTS: {
2450 ToggleLights(GetFocusCanvas());
2453 case ID_MENU_ENC_SOUNDINGS: {
2454 ToggleSoundings(GetFocusCanvas());
2457 case ID_MENU_ENC_ANCHOR: {
2458 ToggleAnchor(GetFocusCanvas());
2461 case ID_MENU_ENC_DATA_QUALITY: {
2462 ToggleDataQuality(GetFocusCanvas());
2465 case ID_MENU_SHOW_NAVOBJECTS: {
2466 ToggleNavobjects(GetFocusCanvas());
2470 case ID_MENU_AIS_TARGETS: {
2471 ToggleAISDisplay(GetFocusCanvas());
2474 case ID_MENU_AIS_MOORED_TARGETS: {
2475 g_bHideMoored = !g_bHideMoored;
2478 case ID_MENU_AIS_SCALED_TARGETS: {
2479 ToggleAISMinimizeTargets(GetFocusCanvas());
2483 case ID_MENU_AIS_TARGETLIST: {
2484 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2488 case ID_MENU_AIS_TRACKS: {
2489 g_bAISShowTracks = !g_bAISShowTracks;
2490 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2494 case ID_MENU_AIS_CPADIALOG: {
2495 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2496 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2497 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2498 if (g_bAIS_CPA_Alert) {
2499 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2504 case ID_MENU_AIS_CPASOUND: {
2505 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2506 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2510 case ID_MENU_AIS_CPAWARNING: {
2511 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2512 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2516 case wxID_PREFERENCES:
2523 case ID_SETTINGS_NEW: {
2528 case ID_SETTINGS_DELETE: {
2531 g_pOptions =
nullptr;
2535 case ID_RELOAD_CHARTS: {
2540 case ID_MENU_SETTINGS_BASIC: {
2542 androidDisableFullScreen();
2544 DoAndroidPreferences();
2551 case ID_MENU_UI_FULLSCREEN: {
2556 case ID_MENU_SHOW_CURRENTS: {
2557 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2558 GetFocusCanvas()->ReloadVP();
2559 GetFocusCanvas()->Refresh(
false);
2563 case ID_MENU_SHOW_TIDES: {
2564 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2565 GetFocusCanvas()->ReloadVP();
2566 GetFocusCanvas()->Refresh(
false);
2586 case ID_MENU_UI_COLSCHEME:
2587 case ID_COLSCHEME: {
2588 ToggleColorScheme();
2597 case ID_MENU_OQUIT: {
2602 case ID_MENU_ROUTE_MANAGER:
2603 case ID_ROUTEMANAGER: {
2626 case ID_MENU_NAV_TRACK:
2628 if (!g_bTrackActive) {
2630 g_bTrackCarryOver =
true;
2633 g_bTrackCarryOver =
false;
2634 RefreshAllCanvas(
true);
2639 case ID_MENU_CHART_NORTHUP: {
2640 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2643 case ID_MENU_CHART_COGUP: {
2644 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2647 case ID_MENU_CHART_HEADUP: {
2648 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2652 case ID_MENU_MARK_MOB:
2658 case ID_MASTERTOGGLE: {
2660 wxString tip = _(
"Show Toolbar");
2661 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2663 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2665 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2668 if (g_bmasterToolbarFull)
2669 m_nMasterToolCountShown =
2673 m_nMasterToolCountShown = 2;
2675 m_nMasterToolCountShown =
2678 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2686 case ID_CMD_SELECT_CHART_TYPE: {
2687 selectChartDisplay(event.GetExtraLong(), -1);
2691 case ID_CMD_SELECT_CHART_FAMILY: {
2692 selectChartDisplay(-1, event.GetExtraLong());
2696 case ID_CMD_APPLY_SETTINGS: {
2697 applySettingsString(event.GetString());
2699 androidRestoreFullScreen();
2705 case ID_CMD_NULL_REFRESH: {
2710 case ID_CMD_SETVP: {
2711 setStringVP(event.GetString());
2715 case ID_CMD_INVALIDATE: {
2721 case ID_CMD_POST_JSON_TO_PLUGINS: {
2727 int numErrors = reader.
Parse(event.GetString(), &root);
2728 if (numErrors == 0) {
2729 if (root[
"MessageID"].IsString()) {
2730 wxString MsgID = root[
"MessageID"].
AsString();
2754 ArrayOfPlugInToolbarTools tool_array =
2756 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2758 if (event.GetId() == pttc->id) {
2759 if (pttc->m_pplugin)
2781bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2782 bool viz_now = g_bmasterToolbarFull;
2785 wxString tip = _(
"Show Toolbar");
2787 tip = _(
"Hide Toolbar");
2789 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2792 bool toggle =
false;
2793 if (viz && !g_bmasterToolbarFull)
2796 else if (!viz && g_bmasterToolbarFull)
2800 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2803 if (g_bmasterToolbarFull)
2804 m_nMasterToolCountShown =
2808 m_nMasterToolCountShown = 2;
2810 m_nMasterToolCountShown =
2813 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2819void MyFrame::ScheduleReloadCharts() {
2820 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2821 evt.SetId(ID_RELOAD_CHARTS);
2822 GetEventHandler()->AddPendingEvent(evt);
2825void MyFrame::ScheduleDeleteSettingsDialog() {
2826 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2827 evt.SetId(ID_SETTINGS_DELETE);
2828 GetEventHandler()->AddPendingEvent(evt);
2831void MyFrame::ScheduleSettingsDialog() {
2832 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2833 evt.SetId(ID_SETTINGS);
2834 GetEventHandler()->AddPendingEvent(evt);
2837void MyFrame::ScheduleSettingsDialogNew() {
2838 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2839 evt.SetId(ID_SETTINGS_NEW);
2840 GetEventHandler()->AddPendingEvent(evt);
2843void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2844 UpdateCanvasConfigDescriptors();
2846 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2847 CreateCanvasLayout(
true);
2849 CreateCanvasLayout();
2853 ConfigureStatusBar();
2854 wxSize lastOptSize = options_lastWindowSize;
2859 options_lastWindowSize = lastOptSize;
2863 ScheduleSettingsDialogNew();
2865 ScheduleSettingsDialog();
2870 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2873 int index_hint = -1;
2874 if (i < pathArray.GetCount())
2875 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2876 cc->canvasChartsRefresh(index_hint);
2877 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2886 return GetPrimaryCanvas();
2889void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2891 if (g_bmasterToolbarFull) {
2892#ifndef OCPN_TOOLBAR_ANIMATE
2893 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2896 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2897 m_nMasterToolCountShown++;
2902 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2910#ifndef OCPN_TOOLBAR_ANIMATE
2911 m_nMasterToolCountShown = 1;
2913 if (m_nMasterToolCountShown > 1) {
2914 m_nMasterToolCountShown--;
2918 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2928void MyFrame::InvalidateAllGL() {
2931 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2941void MyFrame::RefreshAllCanvas(
bool bErase) {
2943 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2946 cc->Refresh(bErase);
2951void MyFrame::setStringVP(wxString VPS) {
2956 wxStringTokenizer tkz(VPS,
";");
2958 wxString token = tkz.GetNextToken();
2960 token.ToDouble(&lat);
2962 token = tkz.GetNextToken();
2964 token.ToDouble(&lon);
2966 token = tkz.GetNextToken();
2968 token.ToDouble(&scale_ppm);
2970 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2973void MyFrame::DoSettingsNew() {
2980void MyFrame::DoSettings() {
2985 ApplyGlobalSettings(
true);
2988 bool b_loadHarmonics =
false;
2989 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2992 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2995 if (b_loadHarmonics) LoadHarmonics();
3003 g_bShowChartBar = !g_bShowChartBar;
3005 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3010 if (g_bShowChartBar) {
3012 UpdateControlBar(cc);
3015 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3018void MyFrame::ToggleColorScheme() {
3019 static bool lastIsNight;
3020 ColorScheme s = user_colors::GetColorScheme();
3023 if (lastIsNight && is == 3)
3026 lastIsNight =
false;
3028 if (lastIsNight) is = 2;
3029 if (is == 3) lastIsNight =
true;
3030 s = (ColorScheme)is;
3031 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3033 SetAndApplyColorScheme(s);
3036void MyFrame::ToggleFullScreen() {
3037 bool to = !IsFullScreen();
3042 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3044 ShowFullScreen(to, style);
3047 UpdateAllToolbars(global_color_scheme);
3049 UpdateControlBar(GetPrimaryCanvas());
3051 TriggerRecaptureTimer();
3054void MyFrame::ActivateMOB() {
3056 wxDateTime mob_time = wxDateTime::Now();
3057 wxString mob_label(_(
"MAN OVERBOARD"));
3058 mob_label += _(
" on ");
3059 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3063 pWP_MOB->SetShared(
true);
3065 pWP_MOB->SetWaypointArrivalRadius(
3067 pWP_MOB->SetUseSca(
false);
3069 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3077 new RoutePoint(zlat, zlon, g_default_wp_icon,
3078 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3079 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3084 temp_route->AddPoint(pWP_src);
3085 temp_route->AddPoint(pWP_MOB);
3087 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3097 temp_route->SetRouteArrivalRadius(-1.0);
3103 v[
"GUID"] = temp_route->
m_GUID;
3104 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3105 SendJSONMessageToAllPlugins(msg_id, v);
3108 if (RouteManagerDialog::getInstanceFlag()) {
3116 RefreshAllCanvas(
false);
3118 wxString mob_message(_(
"MAN OVERBOARD"));
3119 mob_message += _(
" Time: ");
3120 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3121 mob_message += _(
" Position: ");
3122 mob_message += toSDMM(1,
gLat);
3124 mob_message += toSDMM(2,
gLon);
3125 wxLogMessage(mob_message);
3127void MyFrame::TrackOn() {
3128 g_bTrackActive =
true;
3136 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3138 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3140 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3143 androidSetTrackTool(
true);
3146 if (RouteManagerDialog::getInstanceFlag()) {
3155 if (name.IsEmpty()) {
3161 name = _(
"(Unnamed Track)");
3165 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3166 SendJSONMessageToAllPlugins(msg_id, v);
3167 g_FlushNavobjChangesTimeout =
3171Track *MyFrame::TrackOff(
bool do_add_point) {
3176 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3178 SendJSONMessageToAllPlugins(msg_id, v);
3187 if (g_bTrackDaily) {
3192 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3193 return_val = pExtendTrack;
3200 g_bTrackActive =
false;
3202 if (RouteManagerDialog::getInstanceFlag()) {
3209 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3211 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3212 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3215 androidSetTrackTool(
false);
3219 m_target_rotate_time = wxInvalidDateTime;
3224void MyFrame::InitializeTrackRestart() {
3225 if (!g_bTrackDaily)
return;
3226 if (m_target_rotate_time.IsValid())
return;
3229 switch (g_track_rotate_time_type) {
3231 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3233 case TIME_TYPE_COMPUTER:
3234 rotate_at = g_track_rotate_time;
3238 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3239 rotate_at = g_track_rotate_time + utc_offset;
3242 if (rotate_at > 86400)
3244 else if (rotate_at < 0)
3247 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3248 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3251 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3252 m_target_rotate_time += wxTimeSpan(24);
3256bool MyFrame::ShouldRestartTrack() {
3258 InitializeTrackRestart();
3260 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3261 m_target_rotate_time += wxTimeSpan(24);
3267void MyFrame::TrackDailyRestart() {
3269 Track *pPreviousTrack = TrackOff(
true);
3276 if (pPreviousTrack) {
3277 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3281 if (RouteManagerDialog::getInstanceFlag()) {
3289void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3291 cc->SetUpMode(mode);
3293 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3294 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3295 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3298 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3303 cc->SetShowENCText(!cc->GetShowENCText());
3305 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3313void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3316 cc->SetENCDisplayCategory(nset);
3318 UpdateGlobalMenuItems();
3329 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3331 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3340 cc->SetShowENCLights(!cc->GetShowENCLights());
3342 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3352void MyFrame::ToggleRocks(
void )
3358 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3359 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3360 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3361 pOLE->nViz = !pOLE->nViz;
3365 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3366 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3367 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3370 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3374 ps52plib->GenerateStateHash();
3381 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3383 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3391 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3393 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3408 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3409 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3414 cc->SetShowAIS(!cc->GetShowAIS());
3415 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3419void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3420 cc->SetAttenAIS(!cc->GetAttenAIS());
3421 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3427 cc->m_bFollow =
true;
3430 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3434 SetChartUpdatePeriod();
3442 cc->m_bFollow =
false;
3444 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3448 SetChartUpdatePeriod();
3451void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3452 cc->SetShowOutlines(!cc->GetShowOutlines());
3454 RefreshAllCanvas(
false);
3458 if (g_bopengl) InvalidateAllGL();
3461 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3464void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3466void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3468 bool enabled = m_pMenuBar->IsEnabled(item_id);
3469 m_pMenuBar->Enable(item_id,
false);
3470 m_pMenuBar->Check(item_id, state);
3471 m_pMenuBar->Enable(item_id, enabled);
3475void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3482void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3483 wxBitmap *bmpRollover) {
3485 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3490void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3491 wxString rolloverSVGfile,
3492 wxString toggledSVGfile) {
3495 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3499void MyFrame::ConfigureStatusBar() {
3501 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3504 UseNativeStatusBar(
false);
3507 if (g_bShowStatusBar) {
3508 if (!m_pStatusBar) {
3510 CreateStatusBar(m_StatusBarFieldCount, 0);
3511 ApplyGlobalColorSchemetoStatusBar();
3516 m_pStatusBar->Destroy();
3517 m_pStatusBar = NULL;
3523void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3524 ConfigureStatusBar();
3526 wxSize lastOptSize = options_lastWindowSize;
3532 options_lastWindowSize = lastOptSize;
3534 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3537void MyFrame::BuildMenuBar() {
3543 bool showMenuBar =
true;
3545 bool showMenuBar = g_bShowMenuBar;
3557 m_pMenuBar =
new wxMenuBar();
3558 RegisterGlobalMenuItems();
3559 SetMenuBar(m_pMenuBar);
3563 UpdateGlobalMenuItems();
3568 m_pMenuBar->Destroy();
3574void MyFrame::RegisterGlobalMenuItems() {
3575 if (!m_pMenuBar)
return;
3577 wxMenu *nav_menu =
new wxMenu();
3578 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3579 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3580 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3581 nav_menu->AppendSeparator();
3582 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3583 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3584 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3585 nav_menu->AppendSeparator();
3587 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3588 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3590 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3591 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3593 nav_menu->AppendSeparator();
3594 nav_menu->Append(ID_MENU_SCALE_IN,
3595 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3596 nav_menu->Append(ID_MENU_SCALE_OUT,
3597 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3599 nav_menu->AppendSeparator();
3600 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3602 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3604 wxMenu *view_menu =
new wxMenu();
3606 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3607 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3608 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3609 _menuText(_(
"Show Chart Outlines"),
"O"));
3611 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3612 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3613 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3614 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3616 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3617 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3619 view_menu->AppendSeparator();
3621 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3622 _menuText(_(
"Show ENC text"),
"T"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3624 _menuText(_(
"Show ENC Lights"),
"L"));
3625 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3626 _menuText(_(
"Show ENC Soundings"),
"S"));
3627 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3628 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3630 _menuText(_(
"Show ENC Data Quality"),
"U"));
3631 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3632 _menuText(_(
"Show Navobjects"),
"V"));
3634 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3635 _menuText(_(
"Show ENC text"),
"Alt-T"));
3636 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3637 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3638 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3639 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3640 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3641 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3642 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3643 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3644 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3645 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3647 view_menu->AppendSeparator();
3648 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3649 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3650 view_menu->AppendSeparator();
3652 view_menu->Append(ID_MENU_UI_COLSCHEME,
3653 _menuText(_(
"Change Color Scheme"),
"C"));
3655 view_menu->Append(ID_MENU_UI_COLSCHEME,
3656 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3659 view_menu->AppendSeparator();
3661 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3662 _menuText(_(
"Toggle Full Screen"),
"F11"));
3664 m_pMenuBar->Append(view_menu, _(
"&View"));
3666 wxMenu *ais_menu =
new wxMenu();
3667 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3669 _(
"Attenuate less critical AIS targets"));
3670 ais_menu->AppendSeparator();
3671 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3672 _(
"Hide Moored AIS Targets"));
3673 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3674 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3675 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3678 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3679 _menuText(_(
"Show CPA Warnings"),
"W"));
3681 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3682 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3685 ais_menu->AppendSeparator();
3686 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3687 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3689 wxMenu *tools_menu =
new wxMenu();
3691 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3692 _menuText(_(
"Data Monitor"),
"E"));
3693 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3694 _menuText(_(
"Measure Distance"),
"M"));
3696 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3697 _menuText(_(
"Data Monitor"),
"Alt-E"));
3698 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3699 _menuText(_(
"Measure Distance"),
"Alt-M"));
3702 tools_menu->AppendSeparator();
3703 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3704 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3705 tools_menu->AppendSeparator();
3706 tools_menu->Append(ID_MENU_MARK_BOAT,
3707 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3708 tools_menu->Append(ID_MENU_MARK_CURSOR,
3709 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3710 tools_menu->AppendSeparator();
3714 _menuText(_(
"Drop MOB Marker"),
3716 tools_menu->AppendSeparator();
3717 tools_menu->Append(wxID_PREFERENCES,
3718 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3720 tools_menu->Append(ID_MENU_MARK_MOB,
3721 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3722 tools_menu->AppendSeparator();
3723 tools_menu->Append(wxID_PREFERENCES,
3724 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3726 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3729 wxMenu *window_menu =
new wxMenu();
3730 m_pMenuBar->Append(window_menu, _(
"&Window"));
3733 wxMenu *help_menu =
new wxMenu();
3734 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3735 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3736 m_pMenuBar->Append(help_menu, _(
"&Help"));
3739 UpdateGlobalMenuItems();
3742void MyFrame::UpdateGlobalMenuItems() {
3743 if (!m_pMenuBar)
return;
3745 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3746 ->Check(GetPrimaryCanvas()->m_bFollow);
3747 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3748 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3749 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3750 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3751 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3752 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3753 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3754 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3755 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3756 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3757 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3758 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3759 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3760 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3761 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3762 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3763 if (g_bAIS_CPA_Alert) {
3764 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3765 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3767 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3768 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3771 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3772 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3773 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3777 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3778 ->Check(ps52plib->GetShowSoundings());
3780 bool light_state =
false;
3782 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3784 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3785 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3786 light_state = (pOLE->nViz == 1);
3791 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3792 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3796 DisCat nset = ps52plib->GetDisplayCategory();
3797 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3798 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3799 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3800 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3801 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3802 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3803 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3805 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3806 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3807 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3812void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3813 if (!m_pMenuBar)
return;
3815 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3817 if (cc->GetUpMode() == NORTH_UP_MODE)
3818 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3819 else if (cc->GetUpMode() == COURSE_UP_MODE)
3820 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3822 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3824 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3825 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3826 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3827 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3828 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3829 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3830 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3831 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3832 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3833 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3834 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3835 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3836 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3837 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3838 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3841 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3842 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3845 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3847 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3848 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3853 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3857 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3858 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3859 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3860 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3861 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3862 ->Check(cc->GetShowENCDataQual());
3863 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3865 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3866 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3867 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3872void MyFrame::InvalidateAllCanvasUndo() {
3874 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3876 if (cc) cc->undo->InvalidateUndo();
3880void MyFrame::SubmergeAllCanvasToolbars() {
3882 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3884 if (cc) cc->SubmergeToolbar();
3888void MyFrame::SurfaceAllCanvasToolbars() {
3889 if (g_bshowToolbar) {
3891 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3893 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3900void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3902 if (lon > 180.0) lon -= 360.0;
3907 cc->JumpToPosition(lat, lon,
scale);
3910 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3914void MyFrame::UpdateCanvasConfigDescriptors() {
3916 for (
unsigned int i = 0;
3917 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3918 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3926 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3927 cc->GroupID = chart->m_groupIndex;
3930 cc->
bQuilt = chart->GetQuiltMode();
3936 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3938 cc->
bFollow = chart->m_bFollow;
3943 int upmode = chart->GetUpMode();
3944 if (upmode == COURSE_UP_MODE)
3946 else if (upmode == HEAD_UP_MODE)
3953void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3954 if (!RBBox.GetValid())
return;
3956 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3957 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3960 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3961 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3969 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3970 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3972 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3973 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3975 cc->GetSize(&ww, &wh);
3977 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3979 ppm = wxMin(ppm, 1.0);
3985void MyFrame::PrepareOptionsClose(
options *settings,
3986 int settings_return_value) {
3988 options_lastPage = settings->lastPage;
3993 if (options_lastPage == 1) options_lastPage = 0;
3995 options_subpage = settings->lastSubPage;
3996 options_lastWindowPos = settings->lastWindowPos;
3997 options_lastWindowSize = settings->lastWindowSize;
4000 androidEnableBackButton(
true);
4001 androidEnableOptionsMenu(
true);
4002 androidRestoreFullScreen();
4003 androidEnableRotation();
4006 EnableSettingsTool(
true);
4009void MyFrame::DoOptionsDialog() {
4010 EnableSettingsTool(
false);
4013 AbstractPlatform::ShowBusySpinner();
4016 pConfig->SetPath(
"/Settings");
4017 pConfig->Read(
"OptionsSizeX", &sx, -1);
4018 pConfig->Read(
"OptionsSizeY", &sy, -1);
4020 wxWindow *optionsParent =
this;
4022 optionsParent = GetPrimaryCanvas();
4025 callbacks.prepare_close = [&](
options *me,
int changes) {
4026 PrepareOptionsClose(me, changes);
4028 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4029 ProcessOptionsDialog(changes, workdir_list);
4032 wxPoint(-1, -1), wxSize(sx, sy));
4034 AbstractPlatform::HideBusySpinner();
4038 g_options->SetInitChartDir(*pInit_Chart_Dir);
4042 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4043 g_options->SetWorkDirListPtr(pWorkDirArray);
4049 prev_locale = g_locale;
4050 g_options->SetInitialPage(options_lastPage, options_subpage);
4053 g_options->lastWindowPos = options_lastWindowPos;
4054 if (options_lastWindowPos != wxPoint(0, 0)) {
4056 g_options->SetSize(options_lastWindowSize);
4060 if (options_lastWindowSize != wxSize(0, 0)) {
4061 g_options->SetSize(options_lastWindowSize);
4066 androidEnableBackButton(
false);
4067 androidEnableOptionsMenu(
false);
4068 androidDisableFullScreen();
4076 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4079 wxString chart_file_name;
4080 if (cc->GetQuiltMode()) {
4081 int dbi = cc->GetQuiltRefChartdbIndex();
4082 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4084 if (cc->m_singleChart)
4085 chart_file_name = cc->m_singleChart->GetFullPath();
4088 pathArray.Add(chart_file_name);
4094 last_canvasConfig = g_canvasConfig;
4097 g_last_ChartScaleFactor = g_ChartScaleFactor;
4103void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4104 bool b_need_refresh =
false;
4107 if ((rr & VISIT_CHARTS) &&
4108 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4110 UpdateChartDatabaseInplace(*pNewDirArray,
4111 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4114 b_need_refresh =
true;
4119 if (rr & STYLE_CHANGED) {
4122 _(
"Please restart OpenCPN to activate language or style changes."),
4123 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4126 bool charts_updating =
4127 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4128 if (!charts_updating) RefreshGroupIndices();
4130 if (rr & TIDES_CHANGED) {
4136 if (rr & S52_CHANGED) {
4137 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4148 g_Platform->GetDisplayDPmm());
4151 double stuffcog = NAN;
4152 double stuffsog = NAN;
4153 if (!std::isnan(
gCog)) stuffcog =
gCog;
4154 if (!std::isnan(
gSog)) stuffsog =
gSog;
4156 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4157 COGFilterTable[i] = stuffcog;
4158 SOGFilterTable[i] = stuffsog;
4161 SetChartUpdatePeriod();
4163 if (rr & GL_CHANGED) {
4167 b_need_refresh =
true;
4170 if (rr & S52_CHANGED) {
4171 b_need_refresh =
true;
4175 if (rr & REBUILD_RASTER_CACHE) {
4177 GetPrimaryCanvas()->Disable();
4179 GetPrimaryCanvas()->Enable();
4184 if (g_config_display_size_manual &&
4192 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4199 int rrt = rr & S52_CHANGED;
4201 (rrt == S52_CHANGED) ||
4202 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4212 ps52plib->SetScaleFactorExp(
4213 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4214 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4218 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4220 if (cc) cc->ApplyGlobalSettings();
4228 if (!charts_updating) {
4229 bool ztc = g_bEnableZoomToCursor;
4230 g_bEnableZoomToCursor =
false;
4232 if (!GetPrimaryCanvas()->IsFrozen())
4234 g_bEnableZoomToCursor = ztc;
4239 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4248 SetGPSCompassScale();
4250 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4253 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4254 if (!charts_updating) cc->UpdateCanvasControlBar();
4257 UpdateGPSCompassStatusBoxes();
4259 SetAllToolbarScale();
4260 RequestNewToolbars();
4262 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4265 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4268 cc->RebuildCursors();
4273 bool b_masterScaleChange =
false;
4275 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4276 b_masterScaleChange =
true;
4278 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4279 RequestNewMasterToolbar(
true);
4281 bool bMuiChange =
false;
4287 if (b_masterScaleChange || bMuiChange) {
4289 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4292 cc->ProcessNewGUIScale();
4298 if (rr & LOCALE_CHANGED) {
4299 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4301 rr |= NEED_NEW_OPTIONS;
4310 g_last_ChartScaleFactor = g_ChartScaleFactor;
4315bool MyFrame::CheckGroup(
int igroup) {
4316 if (igroup == 0)
return true;
4320 if (!pGroup->m_element_array.size())
4323 for (
const auto &elem : pGroup->m_element_array) {
4324 for (
unsigned int ic = 0;
4325 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4326 auto &cte =
ChartData->GetChartTableEntry(ic);
4327 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4329 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4336bool MyFrame::ScrubGroupArray() {
4341 bool b_change =
false;
4342 unsigned int igroup = 0;
4343 while (igroup < g_pGroupArray->GetCount()) {
4344 bool b_chart_in_element =
false;
4347 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4348 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4350 for (
unsigned int ic = 0;
4351 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4352 auto &cte =
ChartData->GetChartTableEntry(ic);
4353 wxString chart_full_path = cte.GetFullSystemPath();
4355 if (chart_full_path.StartsWith(element_root)) {
4356 b_chart_in_element =
true;
4362 if (!b_chart_in_element) {
4363 wxString test_string =
"GSHH";
4364 if (element_root.Upper().Contains(test_string))
4365 b_chart_in_element =
true;
4368 if (!b_chart_in_element)
4370 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4382void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4384 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4386 if (cc && (cc != ccThis)) cc->Refresh();
4391void MyFrame::ChartsRefresh() {
4394 AbstractPlatform::ShowBusySpinner();
4396 bool b_run = FrameTimer1.IsRunning();
4399 FrameTenHzTimer.Stop();
4402 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4405 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4406 if (cc->GetQuiltMode()) {
4407 currentIndex = cc->GetQuiltReferenceChartIndex();
4409 cc->canvasChartsRefresh(currentIndex);
4413 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4414 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4416 AbstractPlatform::HideBusySpinner();
4419void MyFrame::InvalidateAllQuilts() {
4420 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4423 cc->InvalidateQuilt();
4424 cc->SetQuiltRefChart(-1);
4425 cc->m_singleChart = NULL;
4430bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4432 const wxString &ChartListFileName) {
4433 bool b_run = FrameTimer1.IsRunning();
4435 FrameTenHzTimer.Stop();
4437 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4438 FrameCOGTimer.Stop();
4441 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4444 cc->InvalidateQuilt();
4445 cc->SetQuiltRefChart(-1);
4446 cc->m_singleChart = NULL;
4456 AbstractPlatform::ShowBusySpinner();
4459 wxString longmsg = _(
"OpenCPN Chart Update");
4461 ".................................................................."
4464 Updateprog =
new wxGenericProgressDialog();
4467 Updateprog->SetFont(*qFont);
4469 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4470 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4471 wxPD_REMAINING_TIME);
4473 DimeControl(Updateprog);
4478 wxLogMessage(
"Starting chart database Update...");
4482 m_gshhg_chart_loc = gWorldMapLocation;
4483 gWorldMapLocation = wxEmptyString;
4487 AbstractPlatform::HideBusySpinner();
4491void MyFrame::FinalizeChartDBUpdate() {
4493 if (!g_bDeferredInitDone) {
4495 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4498 bool b_groupchange = ScrubGroupArray();
4500 RefreshGroupIndices();
4502 if (b_groupchange) {
4503 pConfig->DestroyConfigGroups();
4508 if (g_bDeferredInitDone) ScheduleReloadCharts();
4513 cc->ToggleCanvasQuiltMode();
4515 bool cur_mode = cc->GetQuiltMode();
4517 if( !cc->GetQuiltMode() )
4518 cc->SetQuiltMode(
true );
4520 if( cc->GetQuiltMode() ) {
4521 cc->SetQuiltMode(
false );
4522 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4526 if( cur_mode != cc->GetQuiltMode() ){
4532 g_bQuiltEnable = cc->GetQuiltMode();
4536 ps52plib->GenerateStateHash();
4544 DoStackDelta(cc, -1);
4550 DoStackDelta(cc, 1);
4553void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4555void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4557void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4559 cc->DoCanvasStackDelta(direction);
4563void MyFrame::PositionIENCToolbar() {
4567 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4569 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4577void MyFrame::OnInitTimer(wxTimerEvent &event) {
4580 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4584 wxLog::FlushActive();
4586 switch (m_iInitCount++) {
4588 EnableSettingsTool(
false);
4593 if (g_bInlandEcdis) {
4594 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4595 double range_set = 500.;
4597 range = wxRound(range * 10) / 10.;
4601 else if (range > 2000.)
4603 else if (range > 1600.)
4605 else if (range > 1200.)
4607 else if (range > 800.)
4612 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4616 g_Platform->SetFullscreen(g_bFullscreen);
4620 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4623 cc->SetGroupIndex(0,
false);
4630 StartRebuildChartDatabase();
4641 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4655 3 * GetCharHeight());
4657 m_data_monitor->Center();
4665 pConfig->SetPath(
"/Settings");
4666 pConfig->Read(
"OptionsSizeX", &sx, -1);
4667 pConfig->Read(
"OptionsSizeY", &sy, -1);
4669 wxWindow *optionsParent =
this;
4671 optionsParent = GetPrimaryCanvas();
4673 BuildiENCToolbar(
true, m_toolbar_callbacks);
4680 if (!g_params.empty()) {
4681 for (
size_t n = 0; n < g_params.size(); n++) {
4682 wxString path = g_params[n];
4683 if (::wxFileExists(path)) {
4685 pSet->load_file(path.fn_str());
4688 pSet->LoadAllGPXObjects(
4689 !pSet->IsOpenCPN(), wpt_dups,
4691 LLBBox box = pSet->GetBBox();
4692 if (box.GetValid()) {
4693 CenterView(GetPrimaryCanvas(), box);
4702 InitAppMsgBusListener();
4707 auto loader = PluginLoader::GetInstance();
4708 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4709 if (!b_haveWMM)
gVar = g_UserVar;
4717 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4720 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4722 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4725 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4729 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4730 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4731 NavObj_dB::GetInstance().LoadNavObjects();
4734 if (!g_AW1GUID.IsEmpty()) {
4737 if (!g_AW2GUID.IsEmpty()) {
4743 appendOSDirSlash(&layerdir);
4744 layerdir.Append(
"layers");
4746 if (wxDir::Exists(layerdir)) {
4748 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4749 wxLogMessage(laymsg);
4750 pConfig->LoadLayers(layerdir);
4755 if (!g_kiosk_startup) {
4756 AbstractPlatform::ShowBusySpinner();
4759 pConfig->SetPath(
"/Settings");
4760 pConfig->Read(
"OptionsSizeX", &sx, -1);
4761 pConfig->Read(
"OptionsSizeY", &sy, -1);
4763 wxWindow *optionsParent =
this;
4765 optionsParent = GetPrimaryCanvas();
4768 callbacks.prepare_close = [&](
options *me,
int changes) {
4769 PrepareOptionsClose(me, changes);
4771 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4772 ProcessOptionsDialog(changes, workdir_list);
4775 wxPoint(-1, -1), wxSize(sx, sy));
4776 AbstractPlatform::HideBusySpinner();
4783 wxLogMessage(
"OnInitTimer...Last Call");
4787 RequestNewMasterToolbar();
4789 PositionIENCToolbar();
4791 g_bDeferredInitDone =
true;
4801 GetPrimaryCanvas()->SetFocus();
4802 GetPrimaryCanvas()->Enable();
4805 if (b_reloadForPlugins) {
4811 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4813 if (cc) cc->SetFirstAuto(
true);
4821 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4823 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4827 cc->CheckGroupValid();
4828 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4829 cc->SetShowGPSCompassWindow(
true);
4834 androidEnableBackButton(
true);
4835 androidEnableRotation();
4836 androidEnableOptionItems(
true);
4840 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4846 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4848 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4850 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4856 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4858 wxLog::FlushActive();
4860 RefreshAllCanvas(
true);
4861 UsbWatchDaemon::GetInstance().Start();
4862 EnableSettingsTool(
true);
4868void MyFrame::InitAppMsgBusListener() {
4869 auto &msgbus = AppMsgBus::GetInstance();
4872 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4873 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4877 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4878 HandleBasicNavMsg(basicnav_msg);
4882 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4883 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4887 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4888 HandleGPSWatchdogMsg(msg);
4895void MyFrame::ReleaseApiListeners() {}
4900 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4901 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4902 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4903 server.open_file_cb = [&](
const std::string &path) {
4904 return m_open_gpx_file(path);
4911void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4912 if (msg->gps_watchdog <= 0) {
4913 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4917 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4922 if (m_fix_start_time.IsValid()) {
4923 wxDateTime now = wxDateTime::Now();
4924 wxTimeSpan span = now - m_fix_start_time;
4925 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4926 auto ¬eman = NotificationManager::GetInstance();
4927 wxString msg = _(
"GNSS Position fix lost");
4928 noteman.AddNotification(NotificationSeverity::kCritical,
4930 m_fix_start_time = wxInvalidDateTime;
4934 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4935 bool last_bVelocityValid = bVelocityValid;
4936 bVelocityValid =
false;
4943void MyFrame::CalculateCOGAverage() {
4945 if (!std::isnan(
gCog)) {
4948 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4951 double sum = 0., count = 0;
4953 double adder = COGTable[i];
4954 if (std::isnan(adder))
continue;
4956 if (fabs(adder -
g_COGAvg) > 180.) {
4970 else if (sum >= 360.)
4979void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4980 m_fixtime = msg->time;
4981 double hdt_data_interval = 0;
4982 double fix_time_interval = 0;
4984 double msgtime = msg->set_time.tv_sec;
4985 double m1 = msg->set_time.tv_nsec / 1e9;
4988 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4989 ((msg->vflag & POS_VALID) == POS_VALID)) {
4991 if (!m_fix_start_time.IsValid()) {
4992 m_fix_start_time = wxDateTime::Now();
4997 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5000 fix_time_gt_last = fix_time_gt;
5001 uint64_t fix_time_gt_now =
5002 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5003 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5007 double implied_sog = dist / (fix_time_interval / 3600);
5012 gLat_gt_m1 = gLat_gt;
5013 gLon_gt_m1 = gLon_gt;
5017 fix_time_gt = fix_time_gt_now;
5021 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5022 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5023 gCog_gt_m1 = gCog_gt;
5033 if (!std::isnan(gCog_gt_m1)) {
5035 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5042 if ((fix_time_gt - fix_time_gt_last) > .08) {
5047 if (gCog_gt > gCog_gt_m1) {
5048 if ((gCog_gt - gCog_gt_m1) > 180.)
5053 if ((gCog_gt_m1 - gCog_gt) > 180.)
5058 difft = fabs(gCog_gt - gCog_gt_m1);
5059 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5067 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5068 tentative_cog_rate_gt *= 1e9;
5069 cog_rate_gt = tentative_cog_rate_gt;
5077 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5080static double hdt_avg;
5081 double hdt_norm =
gHdt;
5082 if(
gHdt > 180) hdt_norm -= 360;
5085 hdt_avg += hdt_norm * 0.1;
5090 if (!std::isnan(
gHdt)) {
5092 uint64_t hdt_time_gt_last = hdt_time_gt;
5093 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5094 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5097 if (hdt_data_interval > .09) {
5099 gHdt_gt_m1 = gHdt_gt;
5102 if (!std::isnan(gHdt_gt_m1)) {
5104 double tentative_hdt_rate_gt =
5105 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5106 tentative_hdt_rate_gt *= 1e9;
5108 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5109 hdt_rate_gt = tentative_hdt_rate_gt;
5117 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5120 CalculateCOGAverage();
5128 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5129 if ((msg->vflag & POS_VALID) == POS_VALID)
5134 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5136 bVelocityValid =
true;
5140void MyFrame::UpdateStatusBar() {
5143 unsigned long uiCurrentTickCount;
5144 m_MMEAeventTime.SetToCurrent();
5145 uiCurrentTickCount =
5146 m_MMEAeventTime.GetMillisecond() / 100;
5147 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5148 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5149 m_ulLastNMEATicktime = uiCurrentTickCount;
5151 if (m_tick_idx++ > 6) m_tick_idx = 0;
5156 if (NULL != GetStatusBar()) {
5159 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5162 wxString s1(tick_buf, wxConvUTF8);
5164 s1 += toSDMM(1,
gLat);
5166 s1 += toSDMM(2,
gLon);
5168 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5172 if (!std::isnan(
gSog))
5173 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5175 sogcog.Printf(
"SOG --- ");
5179 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5181 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5183 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5184 (
int)toMagnetic(
gCog), 0x00B0);
5186 cogs.Printf((
"COG ---%c"), 0x00B0);
5188 sogcog.Append(cogs);
5189 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5194void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5195 MemFootTimer.Stop();
5197 int memsize = GetApplicationMemoryUse();
5200 printf(
"Memsize: %d \n", memsize);
5203 if (memsize > (g_MemFootMB * 1000)) {
5207 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5208 unsigned int nCache = pCache->GetCount();
5211 for (
unsigned int i = 0; i < nCache; i++) {
5221 for (
unsigned int i = 0; i < nCache - 1; i++) {
5222 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5224 pcea[i] = pcea[i + 1];
5235 unsigned int idelete = 0;
5236 unsigned int idelete_max = pCache->GetCount();
5239 unsigned int minimum_cache = 1;
5240 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5242 while ((memsize > (g_MemFootMB * 1000)) &&
5243 (pCache->GetCount() > minimum_cache) &&
5244 (idelete < idelete_max)) {
5245 int memsizeb = memsize;
5249 memsize = GetApplicationMemoryUse();
5250 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5258 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5263void MyFrame::CheckToolbarPosition() {
5266 static bool bMaximized;
5268 if (IsMaximized() && !bMaximized) {
5275 PositionIENCToolbar();
5276 }
else if (!IsMaximized() && bMaximized) {
5284 PositionIENCToolbar();
5289void MyFrame::ProcessUnitTest() {
5290 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5297 cc->m_bFollow =
false;
5299 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5300 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5303 if (cc->m_groupIndex > 0) {
5304 while (ut_index < ChartData->GetChartTableEntries() &&
5305 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5309 if (ut_index < ChartData->GetChartTableEntries()) {
5313 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5314 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5321 if (cc->GetQuiltMode()) {
5322 if (cc->IsChartQuiltableRef(ut_index))
5323 cc->SelectQuiltRefdbChart(ut_index);
5325 cc->SelectdbChart(ut_index);
5328 if (g_unit_test_1) {
5336 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5337 cte->GetLatMin(), cte->GetLonMax(), NULL,
5341 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5342 cte->GetLatMax(), cte->GetLonMin(), NULL,
5345 cc->GetSize(&ww, &wh);
5346 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5348 ppm = wxMin(ppm, 1.0);
5355 if (ut_index > ut_index_max) exit(0);
5366 bool b_rotate =
false;
5368 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5371 if (!b_rotate && !g_btenhertz)
return;
5373 bool b_update =
false;
5375 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5378 struct timespec now;
5379 clock_gettime(CLOCK_MONOTONIC, &now);
5380 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5381 double diffc = diff / 1e9;
5384 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5385 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5386 if (gCog_tentative < 0.) gCog_tentative += 360.;
5387 gCog = gCog_tentative;
5391 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5392 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5393 double diffc = diff / 1e9;
5394 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5398 if (gSog_gt && !std::isnan(gCog_gt)) {
5399 double delta_t = diffc / 3600;
5400 double distance = gSog_gt * delta_t;
5403 double angr = gCog_gt / 180 * M_PI;
5404 double latr = gLat_gt * M_PI / 180;
5405 double D = distance / 3443;
5406 double sD = sin(D), cD = cos(D);
5407 double sy = sin(latr), cy = cos(latr);
5408 double sa = sin(angr), ca = cos(angr);
5410 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5411 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5421 if (cc) cc->DoCanvasCOGSet();
5430 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5431 bool bnew = cc->DoCanvasUpdate();
5432 if (!bnew) cc->UpdateShips();
5441 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5444bool MyFrame::ProcessQuitFlag() {
5448 FrameTenHzTimer.Stop();
5450 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5451 if (top) top->Close(
true);
5458void MyFrame::ProcessDeferredTrackOn() {
5461 if (g_bDeferredStartTrack) {
5462 if (!g_bTrackActive) {
5465 g_bDeferredStartTrack =
false;
5468 g_bDeferredStartTrack =
false;
5473void MyFrame::ProcessAnchorWatch() {
5481 double d = g_nAWMax;
5484 bool toofar =
false;
5485 bool tooclose =
false;
5486 if (d >= 0.0) toofar = (dist * 1852. > d);
5487 if (d < 0.0) tooclose = (dist * 1852 < -d);
5489 if (tooclose || toofar)
5490 AnchorAlertOn1 =
true;
5492 AnchorAlertOn1 =
false;
5494 AnchorAlertOn1 =
false;
5502 double d = g_nAWMax;
5505 bool toofar =
false;
5506 bool tooclose =
false;
5507 if (d >= 0) toofar = (dist * 1852. > d);
5508 if (d < 0) tooclose = (dist * 1852 < -d);
5510 if (tooclose || toofar)
5511 AnchorAlertOn2 =
true;
5513 AnchorAlertOn2 =
false;
5515 AnchorAlertOn2 =
false;
5518 AnchorAlertOn1 =
true;
5521void MyFrame::SendFixToPlugins() {
5532 GPSData.
nSats = g_SatsInView;
5534 wxDateTime tCheck((time_t)m_fixtime);
5535 if (tCheck.IsValid()) {
5544 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5547 SendPositionFixToAllPlugIns(&GPSData);
5551void MyFrame::ProcessLogAndBells() {
5554 wxDateTime lognow = wxDateTime::Now();
5555 int hourLOC = lognow.GetHour();
5556 int minuteLOC = lognow.GetMinute();
5558 int minuteUTC = lognow.GetMinute();
5559 int second = lognow.GetSecond();
5561 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5562 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5563 (minuteUTC == 30)) {
5564 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5565 wxString day = lognow.FormatISODate();
5566 wxString utc = lognow.FormatISOTime();
5567 wxString navmsg =
"LOGBOOK: ";
5575 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5579 if (std::isnan(
gCog))
5580 cog.Printf(
"COG ----- ");
5582 cog.Printf(
"COG %10.5f ",
gCog);
5585 if (std::isnan(
gSog))
5586 sog.Printf(
"SOG ----- ");
5588 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5594 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5597 wxLogMessage(navmsg);
5598 g_loglast_time = lognow;
5600 int bells = (hourLOC % 4) * 2;
5601 if (minuteLOC != 0) bells++;
5602 if (!bells) bells = 8;
5604 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5605 m_BellsToPlay = bells;
5606 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5607 wxPostEvent(
this, ev);
5614 CheckToolbarPosition();
5618 if (ProcessQuitFlag())
return;
5620 if (bDBUpdateInProgress)
return;
5623 FrameTenHzTimer.Stop();
5625 ProcessDeferredTrackOn();
5627 ProcessAnchorWatch();
5628 ProcessLogAndBells();
5630 if (ShouldRestartTrack()) TrackDailyRestart();
5633 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5634 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5635 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5641 if (
gSog > 3.0) g_bCruising =
true;
5647 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5649 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5655 bool bnew_view =
false;
5656 if (!g_btenhertz) bnew_view = DoChartUpdate();
5663 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5666 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5669 cc->DrawBlinkObjects();
5672 if (bactiveRouteUpdate) {
5679 cc->SetOwnShipState(SHIP_NORMAL);
5681 if (cc->GetQuiltMode()) {
5682 double erf = cc->GetQuiltMaxErrorFactor();
5683 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5685 if (cc->m_singleChart) {
5686 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5687 cc->SetOwnShipState(SHIP_LOWACCURACY);
5691 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5694 (bVelocityValid != m_last_bVelocityValid) ||
5695 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5696 if (!g_bopengl) cc->UpdateShips();
5704 m_last_bVelocityValid = bVelocityValid;
5709 bool brq_dynamic =
false;
5711 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5712 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5714 if (pic->m_enabled && pic->m_init_state) {
5715 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5722 if (brq_dynamic) bnew_view =
true;
5726 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5729 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5734 if (cc->GetglCanvas()) {
5736 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5738 if ((!g_btenhertz)) {
5739 if (cc->m_bFollow) {
5740 cc->DoCanvasUpdate();
5757 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5771 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5772 g_pais_query_dialog_active->UpdateText();
5775 if (g_pAISTargetList && (0 == (g_tick % (5))))
5776 g_pAISTargetList->UpdateAISTargetList();
5779 UpdateGPSCompassStatusBoxes();
5784 console->RefreshConsoleData();
5791 if (m_bdefer_resize) {
5792 if (0 == (g_tick % (5))) {
5793 printf(
"___RESIZE\n");
5794 SetSize(m_defer_size);
5796 m_bdefer_resize =
false;
5803 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5805 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5806 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5810double MyFrame::GetMag(
double a,
double lat,
double lon) {
5811 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5812 auto loader = PluginLoader::GetInstance();
5813 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5820 wxDateTime now = wxDateTime::Now();
5821 SendJSON_WMM_Var_Request(lat, lon, now);
5822 if (fabs(gQueryVar) < 360.0)
5823 Variance = gQueryVar;
5825 return toMagnetic(a, Variance);
5828bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5834 v[
"Year"] = date.GetYear();
5835 v[
"Month"] = date.GetMonth();
5836 v[
"Day"] = date.GetDay();
5838 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5844void MyFrame::TouchAISActive() {
5846 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5848 if (cc) cc->TouchAISToolActive();
5852void MyFrame::UpdateAISTool() {
5856 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5858 if (cc) cc->UpdateAISTBTool();
5863void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5865 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5867 if (cc) cc->SetbTCUpdate(
true);
5870 RefreshAllCanvas(
false);
5875void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5879 bool b_rotate =
false;
5880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5882 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5886 FrameCOGTimer.Stop();
5893 int period_ms = 100;
5895 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5898void MyFrame::DoCOGSet() {
5900 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5902 if (cc) cc->DoCanvasCOGSet();
5906void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5912 wxFont oldfont = pdc->GetFont();
5914 pdc->SetFont(*pFont);
5915 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5916 pdc->SetBackgroundMode(wxTRANSPARENT);
5918 pdc->DrawText(str, x, y + 1);
5919 pdc->DrawText(str, x, y - 1);
5920 pdc->DrawText(str, x + 1, y);
5921 pdc->DrawText(str, x - 1, y);
5923 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5925 pdc->DrawText(str, x, y);
5927 pdc->SetFont(oldfont);
5931void MyFrame::UpdateRotationState(
double rotation) {
5933 g_bCourseUp =
false;
5935 if (fabs(rotation) > .001) {
5936 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5937 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5939 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5942 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5943 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5945 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5949 UpdateGPSCompassStatusBoxes(
true);
5953void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5955 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5957 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5963int MyFrame::GetApplicationMemoryUse() {
5969 wxWindow *fWin = wxWindow::FindFocus();
5971 wxArrayString outputArray;
5972 wxString cmd(
"ps --no-headers -o vsize ");
5973 unsigned long pid = wxGetProcessId();
5975 cmd1.Printf(
"%ld", pid);
5977 wxExecute(cmd, outputArray);
5979 if (outputArray.GetCount()) {
5980 wxString s = outputArray.Item(0);
5982 if (s.ToLong(&vtmp)) memsize = vtmp;
5985 if (fWin) fWin->SetFocus();
5991 PROCESS_MEMORY_COUNTERS pmc;
5993 unsigned long processID = wxGetProcessId();
5995 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5997 if (NULL == hProcess)
return 0;
5999 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6017 memsize = pmc.WorkingSetSize / 1024;
6020 CloseHandle(hProcess);
6027double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6028 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6031void MyFrame::SetChartUpdatePeriod() {
6034 g_ChartUpdatePeriod = 0;
6039 bool bskewdc =
false;
6040 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6043 if (!g_bopengl && !cc->GetVP().b_quilt) {
6044 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6046 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6050 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6052 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6057 cc->UpdateCanvasControlBar();
6060void MyFrame::selectChartDisplay(
int type,
int family) {
6062 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6064 if (cc) cc->selectCanvasChartDisplay(type, family);
6067 UpdateGlobalMenuItems();
6076bool MyFrame::DoChartUpdate() {
6077 bool return_val =
false;
6080 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6082 if (cc) return_val |= cc->DoCanvasUpdate();
6088void MyFrame::MouseEvent(wxMouseEvent &event) {
6090 event.GetPosition(&x, &y);
6095#include <mach/mach.h>
6096#include <mach/message.h>
6097#include <mach/kern_return.h>
6098#include <mach/task_info.h>
6100#include <malloc/malloc.h>
6107#if defined(__linux__)
6108#include "sys/types.h"
6109#include "sys/sysinfo.h"
6112void MyFrame::DoPrint(
void) {
6114 g_PrintingInProgress =
true;
6117 GetPrimaryCanvas()->GetglCanvas()->Render();
6118 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6128 printer.Initialize(wxLANDSCAPE);
6129 printer.EnablePageNumbers(
false);
6132 bool tooltips_were_enabled = DisableTbarTooltips();
6133 printer.Print(
this, &printout);
6134 if (tooltips_were_enabled) {
6135 EnableTbarTooltips();
6154 g_PrintingInProgress =
false;
6157 GetPrimaryCanvas()->SetFocus();
6163 wxString message_ID =
event.GetID();
6164 wxString message_JSONText =
event.GetJSONText();
6172 if (message_ID ==
"WMM_VARIATION_BOAT") {
6180 int numErrors = reader.
Parse(message_JSONText, &root);
6181 if (numErrors > 0) {
6187 wxString decl = root[
"Decl"].
AsString();
6189 decl.ToDouble(&decl_val);
6195 if (message_ID ==
"WMM_VARIATION") {
6203 int numErrors = reader.
Parse(message_JSONText, &root);
6204 if (numErrors > 0) {
6210 wxString decl = root[
"Decl"].
AsString();
6212 decl.ToDouble(&decl_val);
6214 gQueryVar = decl_val;
6217 if (message_ID ==
"GRIB_TIMELINE") {
6220 int numErrors = r.
Parse(message_JSONText, &v);
6222 if (numErrors > 0) {
6223 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6228 wxDateTime oldTimeSource = gTimeSource;
6230 if (v[
"Day"].AsInt() == -1) {
6231 gTimeSource = wxInvalidDateTime;
6232 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6234 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6235 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6236 v[
"Second"].AsInt());
6240 if (oldTimeSource != gTimeSource) {
6242 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6244 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6249 cc->pCwin->Refresh(
false);
6255 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6258 wxString trk_id = wxEmptyString;
6260 int numErrors = reader.
Parse(message_JSONText, &root);
6261 if (numErrors > 0)
return;
6266 v[
"Track_ID"] = trk_id;
6268 wxString name = wxEmptyString;
6269 if (ptrack->m_GUID == trk_id) {
6270 name = ptrack->GetName();
6271 if (name.IsEmpty()) {
6277 name = _(
"(Unnamed Track)");
6284 v[
"TotalNodes"] = ptrack->GetnPoints();
6285 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6287 v[
"lat"] = tp->m_lat;
6288 v[
"lon"] = tp->m_lon;
6291 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6292 SendJSONMessageToAllPlugins(msg_id, v);
6298 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6299 SendJSONMessageToAllPlugins(msg_id, v);
6301 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6304 wxString guid = wxEmptyString;
6306 int numErrors = reader.
Parse(message_JSONText, &root);
6307 if (numErrors > 0) {
6316 wxString name = wxEmptyString;
6318 if ((*it)->m_GUID == guid) {
6319 name = (*it)->m_RouteNameString;
6320 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6326 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6327 itp != (*it)->pRoutePointList->end(); itp++) {
6328 w[i][
"lat"] = (*itp)->m_lat;
6329 w[i][
"lon"] = (*itp)->m_lon;
6330 w[i][
"Name"] = (*itp)->GetName();
6331 w[i][
"Description"] = (*itp)->GetDescription();
6332 w[i][
"GUID"] = (*itp)->m_GUID;
6333 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6335 auto node = (*itp)->m_HyperlinkList->begin();
6336 if (node != (*itp)->m_HyperlinkList->end()) {
6338 while (node != (*itp)->m_HyperlinkList->end()) {
6340 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6341 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6342 httpLink->DescrText;
6349 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6350 SendJSONMessageToAllPlugins(msg_id, v);
6357 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6358 SendJSONMessageToAllPlugins(msg_id, v);
6359 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6364 int numErrors = reader.
Parse(message_JSONText, &root);
6365 if (numErrors > 0)
return;
6368 wxString str = root[
"mode"].
AsString();
6369 if (str ==
"Track") route =
false;
6374 for (RouteList::iterator it =
pRouteList->begin();
6376 wxString name = (*it)->m_RouteNameString;
6377 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6379 v[i][
"error"] =
false;
6380 v[i][
"name"] = name;
6381 v[i][
"GUID"] = (*it)->m_GUID;
6382 v[i][
"active"] = (*it)->IsActive();
6387 wxString name = ptrack->GetName();
6388 if (name.IsEmpty()) {
6394 name = _(
"(Unnamed Track)");
6396 v[i][
"error"] =
false;
6397 v[i][
"name"] = name;
6398 v[i][
"GUID"] = ptrack->m_GUID;
6403 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6404 SendJSONMessageToAllPlugins(msg_id, v);
6407 v[0][
"error"] =
true;
6408 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6409 SendJSONMessageToAllPlugins(msg_id, v);
6411 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6413 v[0][
"error"] =
true;
6416 v[0][
"error"] =
false;
6417 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6418 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6419 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6420 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6421 v[0][
"active_waypoint_lat"] =
6423 v[0][
"active_waypoint_lon"] =
6427 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6428 SendJSONMessageToAllPlugins(msg_id, v);
6432void MyFrame::FilterCogSog() {
6433 if (g_bfilter_cogsog) {
6435 double cog_last =
gCog;
6438 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6439 COGFilterTable[i] = COGFilterTable[i - 1];
6440 COGFilterTable[0] = cog_last;
6443 if (!std::isnan(cog_last)) {
6445 double sum = 0., count = 0;
6446 for (
int i = 0; i < g_COGFilterSec; i++) {
6447 double adder = COGFilterTable[i];
6448 if (std::isnan(adder))
continue;
6450 if (fabs(adder - cog_last) > 180.) {
6451 if ((adder - cog_last) > 0.)
6464 else if (sum >= 360.)
6471 double sog_last =
gSog;
6474 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6475 SOGFilterTable[i] = SOGFilterTable[i - 1];
6476 SOGFilterTable[0] = sog_last;
6479 if (!std::isnan(
gSog)) {
6480 double sum = 0., count = 0;
6481 for (
int i = 0; i < g_SOGFilterSec; i++) {
6482 if (std::isnan(SOGFilterTable[i]))
continue;
6484 sum += SOGFilterTable[i];
6494void MyFrame::LoadHarmonics() {
6497 ptcmgr->LoadDataSources(TideCurrentDataSet);
6499 bool b_newdataset =
false;
6502 for (
auto a :
ptcmgr->GetDataSet()) {
6503 bool b_foundi =
false;
6504 for (
auto b : TideCurrentDataSet) {
6511 b_newdataset =
true;
6516 for (
auto a : TideCurrentDataSet) {
6517 bool b_foundi =
false;
6518 for (
auto b :
ptcmgr->GetDataSet()) {
6525 b_newdataset =
true;
6530 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6534void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6535 if (!ptarget)
return;
6538 wxDateTime mob_time = wxDateTime::Now();
6539 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6540 mob_label += _(
" on ");
6541 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6544 mob_label, wxEmptyString);
6545 pWP_MOB->SetShared(
true);
6547 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6549 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6551 pWP_MOB->SetUseSca(
false);
6559 wxString(_(
"Own ship")), wxEmptyString);
6561 pWP_MOB->SetUseSca(
false);
6568 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6584 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6585 SendJSONMessageToAllPlugins(msg_id, v);
6588 if (RouteManagerDialog::getInstanceFlag()) {
6595 RefreshAllCanvas(
false);
6597 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6598 mob_message += _(
" Time: ");
6599 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6600 mob_message += _(
" Ownship Position: ");
6601 mob_message += toSDMM(1,
gLat);
6603 mob_message += toSDMM(2,
gLon);
6604 mob_message += _(
" MOB Position: ");
6605 mob_message += toSDMM(1, ptarget->Lat);
6607 mob_message += toSDMM(2, ptarget->Lon);
6608 wxLogMessage(mob_message);
6611void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6615 OwnPoint->m_lat =
gLat;
6616 OwnPoint->m_lon =
gLon;
6618 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6623 MOB_Point->m_lat = ptarget->Lat;
6624 MOB_Point->m_lon = ptarget->Lon;
6626 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6627 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6629 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6630 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6633 RefreshAllCanvas(
false);
6636 wxDateTime mob_time = wxDateTime::Now();
6638 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6639 mob_message += _(
" Time: ");
6640 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6641 mob_message += _(
" Ownship Position: ");
6642 mob_message += toSDMM(1,
gLat);
6644 mob_message += toSDMM(2,
gLon);
6645 mob_message += _(
" MOB Position: ");
6646 mob_message += toSDMM(1, ptarget->Lat);
6648 mob_message += toSDMM(2, ptarget->Lon);
6650 wxLogMessage(mob_message);
6654void MyFrame::applySettingsString(wxString settings) {
6656 int last_UIScaleFactor = g_GUIScaleFactor;
6657 bool previous_expert = g_bUIexpert;
6658 g_last_ChartScaleFactor = g_ChartScaleFactor;
6659 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6662 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6668 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6670 if (rr & S52_CHANGED) {
6672 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6674 ->ClearCNSYLUPArray();
6675 ps52plib->GenerateStateHash();
6679 ProcessOptionsDialog(rr, pNewDirArray);
6684 bool b_newToolbar =
false;
6686 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6688 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6690 if (rr & TOOLBAR_CHANGED) {
6691 b_newToolbar =
true;
6696 if (previous_expert && !g_bUIexpert) {
6697 androidForceFullRepaint();
6701 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6705 SetGPSCompassScale();
6707 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6709 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6711 UpdateGPSCompassStatusBoxes(
true);
6714 AbstractPlatform::ShowBusySpinner();
6716 SetAllToolbarScale();
6720 AbstractPlatform::HideBusySpinner();
6722 RequestNewMasterToolbar(
true);
6729 UpdateControlBar(GetPrimaryCanvas());
6735 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6738#ifdef wxHAS_POWER_EVENTS
6739void MyFrame::OnSuspending(wxPowerEvent &event) {
6743 wxLogMessage(
"System suspend starting...");
6746void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6749 wxLogMessage(
"System is going to suspend.");
6752void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6755 wxLogMessage(
"System suspend was cancelled.");
6758int g_last_resume_ticks;
6759void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6760 wxDateTime now = wxDateTime::Now();
6761 wxLogMessage(
"System resumed from suspend.");
6763 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6766 wxLogMessage(
"Restarting streams.");
6767 g_last_resume_ticks = now.GetTicks();
6771 g_pMUX->ClearStreams();
6773 g_pMUX->StartAllStreams();
6782 if (IsMaximized()) {
6787 wxSize sz = GetSize();
6788 SetSize(wxSize(sz.x - 1, sz.y));
6800void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6801 bool btbRebuild =
false;
6803 bool b_reshow =
true;
6806 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6807 if ((ff > 0.01f) || bforcenew) {
6817 long orient = g_Platform->GetDefaultToolbarOrientation();
6818 wxWindow *toolbarParent =
this;
6820 toolbarParent = GetPrimaryCanvas();
6823 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6824 m_toolbar_callbacks);
6826 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6833 g_bmasterToolbarFull =
true;
6837 CreateMasterToolbar();
6852bool MyFrame::CollapseGlobalToolbar() {
6854 m_nMasterToolCountShown = 1;
6858 g_bmasterToolbarFull =
false;
6874 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6875 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6876 tic->m_bRequired =
true;
6881 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6882 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6886 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6887 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6888 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6893 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6894 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6898 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6899 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6900 _(
"Enable Tracking"),
"MUI_track");
6904 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6905 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6917 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6918 _(
"Print Chart"),
"MUI_print");
6922 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6923 _(
"About OpenCPN"),
"MUI_help");
6927 AddDefaultPositionPlugInTools();
6931 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6932 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6943 ArrayOfPlugInToolbarTools tool_array =
6945 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6947 if (!pttc->b_viz)
continue;
6949 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6952 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6953 if (g_bTrackActive) {
6954 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6961bool MyFrame::CheckAndAddPlugInTool() {
6969 if (!tb)
return false;
6971 int n_tools = tb->GetToolsCount();
6975 ArrayOfPlugInToolbarTools tool_array =
6978 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6980 if (pttc->position == n_tools) {
6981 wxBitmap *ptool_bmp;
6983 switch (global_color_scheme) {
6984 case GLOBAL_COLOR_SCHEME_DAY:
6985 ptool_bmp = pttc->bitmap_day;
6988 case GLOBAL_COLOR_SCHEME_DUSK:
6989 ptool_bmp = pttc->bitmap_dusk;
6991 case GLOBAL_COLOR_SCHEME_NIGHT:
6992 ptool_bmp = pttc->bitmap_night;
6995 ptool_bmp = pttc->bitmap_day;
7000 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7002 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7003 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7004 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7005 tic->m_bPlugin =
true;
7014 while (CheckAndAddPlugInTool()) {
7020bool MyFrame::AddDefaultPositionPlugInTools() {
7027 ArrayOfPlugInToolbarTools tool_array =
7030 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7034 if (!pttc->b_viz)
continue;
7036 if (pttc->position == -1)
7038 wxBitmap *ptool_bmp;
7040 switch (global_color_scheme) {
7041 case GLOBAL_COLOR_SCHEME_DAY:
7042 ptool_bmp = pttc->bitmap_day;
7044 case GLOBAL_COLOR_SCHEME_DUSK:
7045 ptool_bmp = pttc->bitmap_dusk;
7047 case GLOBAL_COLOR_SCHEME_NIGHT:
7048 ptool_bmp = pttc->bitmap_night;
7051 ptool_bmp = pttc->bitmap_day;
7056 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7058 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7059 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7060 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7061 tic->m_bPlugin =
true;
7080typedef struct _MSW_COLOR_SPEC {
7082 wxString S52_RGB_COLOR;
7086MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7087 {COLOR_MENUTEXT,
"UITX1", 0},
7088 {COLOR_BTNSHADOW,
"UIBCK", 0},
7091void SaveSystemColors() {
7105 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7106 while (pcspec->COLOR_NAME != -1) {
7107 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7112void RestoreSystemColors() {
7113 int element[NCOLORS];
7114 int rgbcolor[NCOLORS];
7117 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7118 while (pcspec->COLOR_NAME != -1) {
7119 element[i] = pcspec->COLOR_NAME;
7120 rgbcolor[i] = pcspec->SysRGB_COLOR;
7125 if (pSetSysColors) {
7126 pSetSysColors(i, (
unsigned long *)&element[0],
7127 (
unsigned long *)&rgbcolor[0]);
7133void SetSystemColors(ColorScheme cs) {
7135 int element[NCOLORS];
7136 int rgbcolor[NCOLORS];
7138 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7139 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7140 while (pcspec->COLOR_NAME != -1) {
7141 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7142 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7143 element[i] = pcspec->COLOR_NAME;
7149 pSetSysColors(i, (
unsigned long *)&element[0],
7150 (
unsigned long *)&rgbcolor[0]);
7154 RestoreSystemColors();
7161static const WORD MAX_CONSOLE_LINES =
7166void RedirectIOToConsole()
7171 wxIntPtr lStdHandle;
7173 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7183 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7184 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7185 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7189 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7190 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7191 fp = _fdopen(hConHandle,
"w");
7193 setvbuf(stdout, NULL, _IONBF, 0);
7197 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7198 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7199 fp = _fdopen(hConHandle,
"r");
7201 setvbuf(stdin, NULL, _IONBF, 0);
7205 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7206 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7207 fp = _fdopen(hConHandle,
"w");
7209 setvbuf(stderr, NULL, _IONBF, 0);
7220 FontMgr::Get().SetLocale(g_locale);
7241 if (g_pais_query_dialog_active) {
7242 g_pais_query_dialog_active->Destroy();
7243 g_pais_query_dialog_active = NULL;
7246 auto alert_dlg_active =
7248 if (alert_dlg_active) {
7249 alert_dlg_active->Destroy();
7250 g_pais_alert_dialog_active =
nullptr;
7253 if (g_pAISTargetList) {
7255 g_pAISTargetList->Disconnect_decoder();
7256 g_pAISTargetList->Destroy();
7257 g_pAISTargetList = NULL;
7261 if (gFrame->m_pMenuBar) {
7262 gFrame->SetMenuBar(NULL);
7263 gFrame->m_pMenuBar->Destroy();
7264 gFrame->m_pMenuBar = NULL;
7266 gFrame->BuildMenuBar();
7269 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7271 if (cc) cc->CanvasApplyLocale();
7276 wxString perspective;
7278 pConfig->Read(
"AUIPerspective", &perspective);
7292 bool bno_load =
false;
7293 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7295 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7296 wxAuiPaneInfo pane = pane_array_val[i];
7297 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7303 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7308 gFrame->RequestNewToolbars(
true);
7309 gFrame->RequestNewMasterToolbar(
true);
7316 : wxThread(wxTHREAD_JOINABLE) {
7317 m_filename = filename;
7328 newChart->SetNativeScale(m_scale);
7329 newChart->SetFullExtent(m_ext);
7331 newChart->FindOrCreateSenc(m_filename);
7336 wxString m_filename;
7342static double chart_dist(
int index) {
7348 if (cte.GetBBox().Contains(
gLat,
gLon))
7353 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7354 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7355 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7358 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7359 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7361 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7367WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7368static int CompareInts(
int n1,
int n2) {
7369 double d1 = chart_dist(n1);
7370 double d2 = chart_dist(n2);
7371 return (
int)(d1 - d2);
7376 wxString chart_path;
7381WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7383#include <wx/arrimpl.cpp>
7386void ParseAllENC(wxWindow *parent) {
7387 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7395 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7398 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7400 idx_sorted_by_distance.Add(i);
7404 if (count == 0)
return;
7406 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7412 ArrayOfCompressTargets ct_array;
7413 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7414 int i = idx_sorted_by_distance[j];
7417 double distance = chart_dist(i);
7419 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7422 pct->distance = distance;
7423 pct->chart_path = filename;
7425 ct_array.push_back(pct);
7428 int thread_count = 0;
7431 if (g_nCPUCount > 0)
7432 thread_count = g_nCPUCount;
7434 thread_count = wxThread::GetCPUCount();
7436 if (thread_count < 1) {
7445 for(
int t = 0; t < thread_count; t++)
7449 wxGenericProgressDialog *prog =
nullptr;
7453 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7454 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7456 prog =
new wxGenericProgressDialog();
7458 prog->SetFont(*qFont);
7460 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7461 count + 1, parent, style);
7470 prog->ShowWindowModal();
7479 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7480 wxString filename = ct_array[j].chart_path;
7481 double distance = ct_array[j].distance;
7482 int index =
ChartData->FinddbIndex(filename);
7483 if (index < 0)
continue;
7486 ext.NLAT = cte.GetLatMax();
7487 ext.SLAT = cte.GetLatMin();
7488 ext.WLON = cte.GetLonMin();
7489 ext.ELON = cte.GetLonMax();
7491 int scale = cte.GetScale();
7494 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7497 if (wxThread::IsMain()) {
7499 wxSize sz = prog->GetSize();
7504 prog->Update(count, msg, &skip);
7516 newChart->SetNativeScale(
scale);
7517 newChart->SetFullExtent(ext);
7518 newChart->DisableBackgroundSENC();
7520 newChart->FindOrCreateSenc(filename,
7524 if (wxThread::IsMain()) {
7525 msg.Printf(_(
"ENC Completed."));
7527 prog->Update(count, msg, &skip);
7537 for (
int t = 0;; t = (t + 1) % thread_count) {
7544 if (!workers[t]->IsAlive()) {
7557#if defined(__WXMSW__) || defined(__WXOSX__)
7564 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
AisInfoGui * g_pAISGUI
Global instance.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
arrayofCanvasPtr g_canvasArray
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Minimal ChartCAnvas interface with very little dependencies.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
AbstractRestServer implementation and interface to underlying IO thread.
std::string GetEndpoint() override
Return HTTPS url to local rest server.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
Device context class that can use either wxDC or OpenGL for drawing.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
CommBridge class and helpers.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
double AnchorDistFix(double const d, double const AnchorPointMinDist, double const AnchorPointMaxDist)
Return constrained value of d so that AnchorPointMinDist < abs(d) < AnchorPointMaxDist.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Miscellaneous utilities, many of which string related.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
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.