53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
83#include "model/nav_object_database.h"
97#include "ais_info_gui.h"
98#include "dialog_alert.h"
102#include "ais_info_gui.h"
126#include "load_errors_dlg.h"
129#include "N2KParser.h"
152#include "user_colors.h"
158#include "androidUTIL.h"
162static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
173GLenum g_texture_rectangle_format;
176#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
177extern wxLocale *plocale_def_lang;
181extern bool g_b_EnableVBO;
182extern GLenum g_texture_rectangle_format;
186static int g_last_ChartScaleFactor;
187static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
188static int options_subpage = 0;
189static bool b_reloadForPlugins;
191static wxSize options_lastWindowSize(0, 0);
192static wxPoint options_lastWindowPos(0, 0);
196static double gQueryVar = 361.0;
198static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
199static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
201static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
207typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
208typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
210static SetSysColors_t pSetSysColors;
211static GetSysColor_t pGetSysColor;
213void SaveSystemColors();
214void RestoreSystemColors();
219DWORD color_3ddkshadow;
221DWORD color_activecaption;
222DWORD color_gradientactivecaption;
223DWORD color_captiontext;
224DWORD color_windowframe;
225DWORD color_inactiveborder;
230#include <wx/msw/msvcrt.h>
234static const long long lNaN = 0xfff8000000000000;
235#define NAN (*(double *)&lNaN)
239static double gLat_gt, gLon_gt;
240static double gLat_gt_m1, gLon_gt_m1;
241static uint64_t fix_time_gt;
242static uint64_t fix_time_gt_last;
244static double gSog_gt, gHdt_gt;
245static double gCog_gt_m1, gHdt_gt_m1;
246static uint64_t hdt_time_gt;
247static double cog_rate_gt, hdt_rate_gt;
249void InitializeUserColors();
250void DeInitializeUserColors();
251void SetSystemColors(ColorScheme cs);
253static bool LoadAllPlugIns(
bool load_enabled) {
254 AbstractPlatform::ShowBusySpinner();
255 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
256 AbstractPlatform::HideBusySpinner();
260static void LaunchLocalHelp() {
262 androidLaunchHelpView();
264 wxString def_lang_canonical =
"en_US";
267 if (plocale_def_lang)
268 def_lang_canonical = plocale_def_lang->GetCanonicalName();
271 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
273 wxString help_try = help_locn + def_lang_canonical +
".html";
275 if (!::wxFileExists(help_try)) {
276 help_try = help_locn +
"en_US" +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"web" +
".html";
282 if (!::wxFileExists(help_try))
return;
285 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
290static wxString _menuText(wxString name, wxString shortcut) {
294 menutext <<
"\t" << shortcut;
299static void DoHelpDialog() {
311 [] { LaunchLocalHelp(); });
323#if defined(__WXGTK__) || defined(__WXQT__)
324#include "bitmaps/opencpn.xpm"
339 if (g_bInlandEcdis) {
343 wxPoint tbp_incanvas =
346 g_iENCToolbarPosY = tbp_incanvas.y;
347 g_iENCToolbarPosX = tbp_incanvas.x;
355 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
359 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
362 g_iENCToolbarPosY = -1;
365 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
371 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
375 double tool_scale_factor =
376 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
378 tool_scale_factor, callbacks);
388#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
391static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
392 const char *prop_name) {
396 unsigned long ret_nitems;
397 unsigned long ret_bytes_after;
398 unsigned char *ret_prop;
400 xa_prop_name = XInternAtom(disp, prop_name, False);
408 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
409 &xa_ret_type, &ret_format, &ret_nitems,
410 &ret_bytes_after, &ret_prop) != Success)
413 if (xa_ret_type != xa_prop_type) {
417 return (
char *)ret_prop;
422static bool isTransparentToolbarInOpenGLOK() {
429 if (!g_bdisable_opengl) {
430 Display *disp = XOpenDisplay(NULL);
432 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
434 "_NET_SUPPORTING_WM_CHECK")) ||
435 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_WIN_SUPPORTING_WM_CHECK"))) {
440 if ((wm_name = get_X11_property(disp, *sup_window,
441 XInternAtom(disp,
"UTF8_STRING", False),
443 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
446 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
461wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
463 font->GetFamily(), font->GetStyle(),
464 font->GetWeight(),
false, font->GetFaceName());
466wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
467 wxFontStyle style, wxFontWeight weight,
468 const wxString faceName,
double scale) {
472wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
473 return GetOCPNScaledFont_PlugIn(label, Ptsize);
482wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
484BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
485EVT_CLOSE(MyFrame::OnCloseWindow)
486EVT_MENU(wxID_EXIT, MyFrame::OnExit)
487EVT_SIZE(MyFrame::OnSize)
488EVT_MOVE(MyFrame::OnMove)
489EVT_ICONIZE(MyFrame::OnIconize)
490EVT_MENU(-1, MyFrame::OnToolLeftClick)
491EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
493EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
494EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
495EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
497EVT_MAXIMIZE(MyFrame::OnMaximize)
498EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
499 MyFrame::RequestNewToolbarArgEvent)
500EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
502EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
503EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
504EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
506#ifdef wxHAS_POWER_EVENTS
507EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
508EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
509EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
510EVT_POWER_RESUME(MyFrame::OnResume)
521static
void onBellsFinishedCB(
void *ptr) {
522 auto framePtr =
static_cast<MyFrame *
>(ptr);
524 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
525 wxPostEvent(framePtr, ev);
530 auto msg = ev.GetString().ToStdString();
531 auto ¬eman = NotificationManager::GetInstance();
532 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
535static NmeaLog *GetDataMonitor() {
536 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
537 return dynamic_cast<NmeaLog *
>(w);
540MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
541 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
542 OpenFileFunc open_gpx_file)
544 m_connections_dlg(nullptr),
546 m_pauidockart(pauidockart),
547 m_rest_server(rest_server),
548 m_open_gpx_file(open_gpx_file) {
560 m_ulLastNMEATicktime = 0;
561 m_data_monitor->Hide();
563 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
567 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
570 InitTimer.SetOwner(
this, INIT_TIMER);
572 m_initializing =
false;
573 m_toolbar_callbacks.render_gl_textures =
575 [&](
ocpnDC &dc,
float *coords,
float *uv) {
576 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
577 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
580 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
584 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
587 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
590 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
593 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
596 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
598 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
607 m_bTimeIsSet =
false;
608 m_bdefer_resize =
false;
611 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
612 COGFilterTable[i] = NAN;
613 SOGFilterTable[i] = NAN;
615 m_last_bGPSValid =
false;
616 m_last_bVelocityValid =
false;
626 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
631 double process_noise_std = 1.0;
632 double measurement_noise_std = 0.5;
636 m_ChartUpdatePeriod = 1;
641 log_callbacks.log_is_active = [&]() {
642 auto log = GetDataMonitor();
643 return log && log->IsVisible();
645 log_callbacks.log_message = [&](
Logline ll) {
646 NmeaLog *monitor = GetDataMonitor();
649 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
652 ais_callbacks.confirm_stop_track = []() {
653 int r = OCPNMessageBox(
655 _(
"This AIS target has Persistent tracking selected by MMSI "
657 "A Persistent track recording will therefore be restarted for this "
659 "Do you instead want to stop Persistent tracking for this target?"),
660 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
661 return r == wxID_YES;
663 ais_callbacks.get_target_mmsi = []() {
664 auto alert_dlg_active =
666 assert(alert_dlg_active);
667 return alert_dlg_active->Get_Dialog_MMSI();
675 wxLogMessage(
" **** Connect stuff");
681 Connect(wxEVT_OCPN_MSG,
682 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
690 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
698#if defined(__WXGTK__) || defined(__WXQT__)
699 wxIcon app_icon(opencpn);
707 wxDynamicLibrary dllUser32(
"user32.dll");
709 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
710 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
715 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
720 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
721 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
723 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
724 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
725 [&](wxCommandEvent) { Refresh(); });
726 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
728 m_update_statusbar_listener.Init(
729 GuiEvents::GetInstance().gframe_update_status_bar,
731 m_center_aistarget_listener.Init(
732 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
733 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
734 CenterAisTarget(ais_target);
736 m_reload_charts_listener.Init(
737 GuiEvents::GetInstance().on_finalize_chartdbs,
738 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
742 EnableFullScreenView();
744 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
750 FrameTenHzTimer.Stop();
765 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
771void MyFrame::FreezeCharts() {
774 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
776 if (cc && !cc->IsFrozen()) cc->Freeze();
780void MyFrame::CenterAisTarget(
781 const std::shared_ptr<const AisTargetData> &ais_target) {
789 double factor = cc->GetScaleValue() / 5000.0;
790 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
796void MyFrame::ThawCharts() {
799 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
801 if (cc && cc->IsFrozen()) cc->Thaw();
808 switch (event.type) {
809 case SENC_BUILD_STARTED:
812 case SENC_BUILD_DONE_NOERROR:
814 chart =
event.m_ticket->m_chart;
816 chart->PostInit(FULL_INIT, global_color_scheme);
818 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
820 if (cc) cc->ClearS52PLIBStateHash();
825 delete event.m_ticket;
827 case SENC_BUILD_DONE_ERROR:
835void MyFrame::RebuildChartDatabase() {
836 bool b_SetInitialPoint =
false;
839 ArrayOfCDI ChartDirArray;
840 pConfig->LoadChartDirArray(ChartDirArray);
842 if (ChartDirArray.GetCount()) {
847 _(
"OpenCPN needs to update the chart database from config file "
851 wxICON_INFORMATION | wxOK);
859 _(
"Rebuilding chart database from configuration file entries..."));
863 wxString dummy1 = _(
"Elapsed time : ");
864 wxString dummy2 = _(
"Estimated time : ");
865 wxString dummy3 = _(
"Remaining time : ");
866 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
867 _(
"OpenCPN Chart Update"), line, 100, NULL,
868 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
869 wxPD_REMAINING_TIME);
872 ChartData->SaveBinary(ChartListFileName);
882void MyFrame::OnBellsFinished(wxCommandEvent &event) {
883 int bells = wxMin(m_BellsToPlay, 2);
884 if (bells <= 0)
return;
886 wxString soundfile =
"sounds";
887 appendOSDirSlash(&soundfile);
888 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
889 soundfile.Prepend(g_Platform->GetSharedDataDir());
890 wxLogMessage(
"Using bells sound file: " + soundfile);
892 o_sound::Sound *sound = bells_sound[bells - 1];
893 sound->SetFinishedCallback(onBellsFinishedCB,
this);
894 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
895 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
896 sound->Load(soundfile);
897 if (!sound->IsOk()) {
898 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
902 m_BellsToPlay -= bells;
905void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
907void MyFrame::OnMaximize(wxMaximizeEvent &event) {
914void MyFrame::ReloadAllVP() {
915 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
917 if (cc) cc->ReloadVP();
921void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
922 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
925 global_color_scheme = cs;
928 case GLOBAL_COLOR_SCHEME_DAY:
931 case GLOBAL_COLOR_SCHEME_DUSK:
934 case GLOBAL_COLOR_SCHEME_NIGHT:
935 SchemeName =
"NIGHT";
942 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
944 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
945 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
946 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
947 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
948 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
950 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
979 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
980 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
984 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
986 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
990 user_colors::GetMapByScheme(SchemeName.ToStdString());
995 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
998 cc->SetColorScheme(cs);
999 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1000 cc->HideChartInfoWindow();
1001 cc->SetQuiltChartHiLiteIndex(-1);
1007 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1019 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1032 if (g_pais_query_dialog_active) {
1033 bool b_isshown = g_pais_query_dialog_active->IsShown();
1034 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1035 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1037 g_pais_query_dialog_active->Close();
1040 g_pais_query_dialog_active->
Create(
1041 this, -1, _(
"AIS Target Query"),
1042 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1043 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1044 g_pais_query_dialog_active->UpdateText();
1045 if (b_isshown) g_pais_query_dialog_active->Show();
1050 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1054 ApplyGlobalColorSchemetoStatusBar();
1056 UpdateAllToolbars(cs);
1061 bool btoolbarFull = g_bmasterToolbarFull;
1067 if (!btoolbarFull) {
1069 RequestNewMasterToolbar();
1071 CollapseGlobalToolbar();
1074 RequestNewMasterToolbar();
1083void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1084 if (m_pStatusBar != NULL) {
1085 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1086 m_pStatusBar->ClearBackground();
1097void MyFrame::CancelAllMouseRoute() {
1099 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1101 if (cc) cc->CancelMouseRoute();
1105void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1113 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1121 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1130 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1133 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1134 config_array.Item(i)->canvas = NULL;
1140 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1145 switch (g_canvasConfig) {
1159 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1160 cc->GetglCanvas()->Show();
1163 config_array.Item(0)->canvas = cc;
1167 cc->ApplyCanvasConfig(config_array.Item(0));
1171 cc->ConfigureChartBar();
1172 cc->SetColorScheme(global_color_scheme);
1173 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1174 cc->SetShowGPS(
true);
1177 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1179 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1195 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1198 config_array.Item(0)->canvas = cc;
1200 cc->ApplyCanvasConfig(config_array.Item(0));
1203 cc->ConfigureChartBar();
1204 cc->SetColorScheme(global_color_scheme);
1205 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1206 cc->SetShowGPS(
false);
1209 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1211 .CaptionVisible(
false)
1213 .CloseButton(
false);
1222 if (config_array.GetCount() < 2) {
1224 pcc->configIndex = 1;
1228 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1229 config_array.Add(pcc);
1232 config_array.Item(1)->canvas = cc;
1234 cc->ApplyCanvasConfig(config_array.Item(1));
1237 cc->ConfigureChartBar();
1238 cc->SetColorScheme(global_color_scheme);
1239 cc->SetShowGPS(
true);
1243 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1245 .CaptionVisible(
false)
1247 .CloseButton(
false);
1248 g_pauimgr->GetPane(cc).RightDockable(
true);
1252 config_array.Item(1)->canvasSize =
1253 wxSize(GetClientSize().x / 2, GetClientSize().y);
1254 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1259 if (b_useStoredSize) {
1260 int ccw = config_array.Item(1)->canvasSize.x;
1261 int cch = config_array.Item(1)->canvasSize.y;
1264 if (ccw < GetClientSize().x / 10) {
1265 ccw = GetClientSize().x / 2;
1266 cch = GetClientSize().y;
1269 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1270 cc->SetSize(ccw, cch);
1288 console->SetColorScheme(global_color_scheme);
1293 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1299void MyFrame::RequestNewToolbars(
bool bforcenew) {
1300 if (b_inCloseWindow) {
1304 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1305 PositionIENCToolbar();
1314void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1320void MyFrame::SetAllToolbarScale() {
1321 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1324void MyFrame::SetGPSCompassScale() {
1325 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1329 wxPoint screenPoint = ::wxGetMousePosition();
1332 switch (g_canvasConfig) {
1334 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1337 if (canvas->GetScreenRect().Contains(
1341 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1344 if (canvas->GetScreenRect().Contains(
1351 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1354 if (canvas->GetScreenRect().Contains(
1355 canvas->ScreenToClient(screenPoint)))
1363int MyFrame::GetCanvasIndexUnderMouse() {
1364 wxPoint screenPoint = ::wxGetMousePosition();
1367 switch (g_canvasConfig) {
1369 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1372 if (canvas->GetScreenRect().Contains(
1376 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1379 if (canvas->GetScreenRect().Contains(
1386 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1389 if (canvas->GetScreenRect().Contains(
1390 canvas->ScreenToClient(screenPoint)))
1398bool MyFrame::DropMarker(
bool atOwnShip) {
1405 if (!canvas)
return false;
1412 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1414 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1416 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1427 RefreshAllCanvas(
false);
1432void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1433 if (g_canvasConfig != 0) {
1436 int nTargetGTK = -1;
1438 wxWindow *source = FindFocus();
1444 switch (g_canvasConfig) {
1446 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1449 if (canvas && (canvas == test)) {
1454 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1457 if (canvas && (canvas == test)) {
1465 int nfinalTarget = nTarget;
1467 nfinalTarget = nTargetGTK;
1469 target = ConfigMgr::Get()
1470 .GetCanvasConfigArray()
1475 target->Refresh(
true);
1486void MyFrame::FastClose() {
1488 FrameTenHzTimer.Stop();
1490 FrameTimer1.Start(1);
1494void MyFrame::OnExit(wxCommandEvent &event) {
1498void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1501 if (b_inCloseWindow) {
1511 if (!g_bDeferredInitDone)
return;
1528 if (bDBUpdateInProgress)
return;
1530 b_inCloseWindow =
true;
1532 ::wxSetCursor(wxCURSOR_WAIT);
1536 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1538 if (cc && cc->IsMeasureActive()) {
1539 cc->CancelMeasureRoute();
1544 SendPreShutdownHookToPlugins();
1548 if (g_pAISTargetList) {
1549 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1550 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1551 g_pauimgr->DetachPane(g_pAISTargetList);
1578 SetCursor(wxCURSOR_WAIT);
1580 RefreshAllCanvas(
true);
1586 RestoreScreenBrightness();
1597 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1598 g_iENCToolbarPosY = tbp_incanvas.y;
1599 g_iENCToolbarPosX = tbp_incanvas.x;
1603 g_bframemax = IsMaximized();
1606 FrameTenHzTimer.Stop();
1608 FrameCOGTimer.Stop();
1622 if (g_bAutoAnchorMark) {
1623 bool watching_anchor =
false;
1631 wxDateTime now = wxDateTime::Now();
1632 wxTimeSpan uptime = now.Subtract(g_start_time);
1634 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1635 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1640 if (g_declutter_anchorage) {
1641 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1642 if (pr->GetName().StartsWith(
"Anchorage")) {
1643 double a =
gLat - pr->m_lat;
1644 double b =
gLon - pr->m_lon;
1645 double l = sqrt((a * a) + (b * b));
1648 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1650 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1651 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1659 wxString name = now.Format();
1660 name.Prepend(_(
"Anchorage created "));
1666 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1675 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1679 NavObj_dB::GetInstance().Close();
1683 pConfig->DeleteGroup(
"/Routes");
1684 pConfig->DeleteGroup(
"/Marks");
1710 if (g_pAISTargetList) {
1711 g_pAISTargetList->Disconnect_decoder();
1712 g_pAISTargetList->Destroy();
1719 if (RouteManagerDialog::getInstanceFlag()) {
1736 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1738 if (cc) cc->Destroy();
1762 CommBridge::GetInstance().SaveConfig();
1782 auto ®istry = CommDriverRegistry::GetInstance();
1783 registry.CloseAllDrivers();
1786 for (
auto *cp : TheConnectionParams()) {
1791 while (pLayerList->size())
delete *pLayerList->begin();
1795 ReleaseApiListeners();
1798 g_bTempShowMenuBar =
false;
1800#define THREAD_WAIT_SECONDS 5
1810 wxLogMessage(
"Starting compressor pool drain");
1811 wxDateTime now = wxDateTime::Now();
1812 time_t stall = now.GetTicks();
1813 time_t end = stall + THREAD_WAIT_SECONDS;
1816 while (stall < end) {
1817 wxDateTime later = wxDateTime::Now();
1818 stall = later.GetTicks();
1821 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1830 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1836 uninitIXNetSystem();
1840 wxLogMessage(
"gFrame destroyed.");
1843#ifndef USE_ANDROID_GLES2
1844 qDebug() <<
"Calling OnExit()";
1848 wxTheApp->ExitMainLoop();
1851void MyFrame::OnMove(wxMoveEvent &event) {
1852 auto idx = wxDisplay::GetFromWindow(
this);
1865 DEBUG_LOG <<
"Moved to " << idx
1866#if wxCHECK_VERSION(3, 1, 6)
1867 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1868 << wxDisplay(idx).GetPPI().GetY()
1869 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1871 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1872 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1873 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1874 << wxGetDisplaySizeMM().GetY()
1875 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1884 if (g_config_display_size_manual) {
1893 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1896 cc->SetMUIBarPosition();
1905 UpdateGPSCompassStatusBoxes();
1915 PositionIENCToolbar();
1921 g_nframewin_posx = GetPosition().x;
1922 g_nframewin_posy = GetPosition().y;
1925void MyFrame::ProcessCanvasResize() {
1926 UpdateGPSCompassStatusBoxes(
true);
1930 PositionIENCToolbar();
1933 TriggerRecaptureTimer();
1937void MyFrame::TriggerRecaptureTimer() {
1938 m_recaptureTimer.Start(
1939 1000, wxTIMER_ONE_SHOT);
1942void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1944void MyFrame::SetCanvasSizes(wxSize frameSize) {
1948 int cccw = frameSize.x;
1949 int ccch = frameSize.y;
1953 switch (g_canvasConfig) {
1959 cc->GetSize( &cur_width, &cur_height );
1960 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1962 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1964 cc->SetSize( 0, 0, cccw, ccch );
1974 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1975 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1977 ccw = wxMin(ccw, cccw * 8 / 10);
1978 ccw = wxMax(ccw, cccw * 2 / 10);
1982 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1989 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2006void MyFrame::OnIconize(wxIconizeEvent &event) {
2016 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2018 if (cc && cc->GetMUIBar()) {
2019 if (cc->GetMUIBar()->GetCanvasOptions()) {
2020 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2021 cc->GetMUIBar()->PushCanvasOptions();
2030void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2032void MyFrame::ODoSetSize() {
2034 GetClientSize(&x, &y);
2037 if (m_pStatusBar != NULL) {
2038 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2039 int currentCount = m_pStatusBar->GetFieldsCount();
2040 if (currentCount != m_StatusBarFieldCount) {
2041 if ((currentCount > 0) && (currentCount < 7)) {
2044 int widths[] = {2, 2, 2, 2, 2, 2};
2045 m_pStatusBar->SetStatusWidths(currentCount, widths);
2048 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2051 if (m_StatusBarFieldCount) {
2056 if (m_StatusBarFieldCount > 2) {
2057 int widths[] = {-6, -5, -5, -6, -4};
2058 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2059 }
else if (m_StatusBarFieldCount == 2) {
2060 int cwidth = x * 90 / 100;
2061 int widths[] = {100, 100};
2062 widths[0] = cwidth * 6.4 / 10.0;
2063 widths[1] = cwidth * 3.6 / 10.0;
2064 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2066 int widths[] = {100, 100};
2067 widths[0] = x * 90 / 100;
2068 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2071 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2072 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2073 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2075 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2077 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2085 m_pStatusBar->GetFieldRect(0, stat_box);
2088 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2090 wxFont sys_font = *wxNORMAL_FONT;
2091 int try_font_size = sys_font.GetPointSize();
2094 int min_font_size = 10;
2104 wxFont *statusBarFont =
2105 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2106 int font_size = statusBarFont->GetPointSize();
2108 font_size = wxMin(font_size,
2111 wxMax(font_size, min_font_size);
2114 font_size = statusBarFont->GetPointSize();
2121 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2122 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2124 int min_height = stat_box.height;
2126 m_pStatusBar->SetFont(*pstat_font);
2127 m_pStatusBar->SetForegroundColour(
2128 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2130 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2132 (min_height >> 1) * 2;
2133 m_pStatusBar->SetMinHeight(min_height);
2142 SetCanvasSizes(GetClientSize());
2144 UpdateGPSCompassStatusBoxes(
true);
2146 if (
console) PositionConsole();
2149 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2151 if (cc) cc->FormatPianoKeys();
2157 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2158 GetPrimaryCanvas()->GetCompass()->GetRect());
2184 options_lastWindowSize = wxSize(0, 0);
2185 options_lastWindowPos = wxPoint(0, 0);
2192 if (!b_inCloseWindow) {
2195 resizeAndroidPersistents();
2199 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2200 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2206void MyFrame::PositionConsole() {
2207#if defined(__WXMSW__) || defined(__WXMAC__)
2208 if (NULL == GetPrimaryCanvas())
return;
2210 int ccx, ccy, ccsx, ccsy, consx, consy;
2215 consoleHost->GetSize(&ccsx, &ccsy);
2216 consoleHost->GetPosition(&ccx, &ccy);
2218 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2219 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2220 consoleHost = GetPrimaryCanvas();
2225 if (consoleHost->GetCompass()) {
2226 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2228 if (compass_rect.y < 100)
2229 yOffset = compass_rect.y + compass_rect.height + 45;
2233 wxSize csz =
console->GetSize();
2237 wxPoint screen_pos =
2238 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2241 if (NULL == GetPrimaryCanvas())
return;
2243 int ccx, ccy, ccsx, ccsy, consx, consy;
2248 consoleHost->GetSize(&ccsx, &ccsy);
2249 consoleHost->GetPosition(&ccx, &ccy);
2251 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2252 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2253 consoleHost = GetPrimaryCanvas();
2256 int yTopOffset = 60;
2257 int yBottomOffset = 0;
2259 if (consoleHost->GetCompass()) {
2260 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2262 if (compass_rect.y < 100)
2263 yTopOffset = compass_rect.y + compass_rect.height;
2265 if (consoleHost->GetMUIBar()) {
2266 wxRect mui_rect = consoleHost->GetMUIBarRect();
2267 yBottomOffset = ccsy - mui_rect.y;
2271 wxSize csz =
console->GetSize();
2274 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2276 if (consy < yAvail) {
2277 yFinal = (yAvail - consy) / 2;
2278 yFinal += yTopOffset;
2279 }
else if (
console->GetCDI()->IsShown()) {
2280 int cdi_height =
console->GetCDI()->GetSize().y;
2281 int consy_no_cdi = consy - cdi_height;
2282 yFinal = (yAvail - consy_no_cdi) / 2;
2283 yFinal += yTopOffset;
2287 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2292void MyFrame::UpdateAllFonts() {
2301 DestroyPersistentDialogs();
2303 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2308void MyFrame::DestroyPersistentDialogs() {
2309 if (g_pais_query_dialog_active) {
2310 g_pais_query_dialog_active->Hide();
2311 g_pais_query_dialog_active->Destroy();
2312 g_pais_query_dialog_active = NULL;
2340void MyFrame::RefreshGroupIndices() {
2342 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2344 if (cc) cc->canvasRefreshGroupIndex();
2348void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2351 switch (event.GetId()) {
2352 case ID_MENU_SCALE_OUT:
2353 DoStackDelta(GetPrimaryCanvas(), 1);
2357 case ID_MENU_SCALE_IN:
2358 DoStackDelta(GetPrimaryCanvas(), -1);
2362 case ID_MENU_ZOOM_IN: {
2363 if (GetFocusCanvas()) {
2364 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2369 case ID_MENU_ZOOM_OUT: {
2370 if (GetFocusCanvas()) {
2371 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2376 case ID_MENU_ROUTE_NEW: {
2377 if (GetFocusCanvas()) {
2378 if (0 == GetFocusCanvas()->m_routeState) {
2379 GetFocusCanvas()->StartRoute();
2381 GetFocusCanvas()->FinishRoute();
2387 case ID_MENU_TOOL_MEASURE: {
2388 GetPrimaryCanvas()->StartMeasureRoute();
2392 case ID_MENU_TOOL_NMEA_DBG_LOG:
2393 m_data_monitor->Show();
2394 m_data_monitor->Raise();
2397 case ID_MENU_TOOL_IO_MONITOR:
2398 m_data_monitor->Show();
2401 case ID_MENU_MARK_BOAT: {
2406 case ID_MENU_MARK_CURSOR: {
2411 case ID_MENU_NAV_FOLLOW: {
2412 if (
gFrame->GetPrimaryCanvas())
2413 gFrame->GetPrimaryCanvas()->TogglebFollow();
2417 case ID_MENU_CHART_OUTLINES: {
2418 ToggleChartOutlines(GetFocusCanvas());
2422 case ID_MENU_CHART_QUILTING: {
2423 ToggleQuiltMode(GetFocusCanvas());
2427 case ID_MENU_UI_CHARTBAR: {
2428 ToggleChartBar(GetFocusCanvas());
2432 case ID_MENU_ENC_TEXT:
2434 ToggleENCText(GetFocusCanvas());
2437 case ID_MENU_ENC_LIGHTS: {
2438 ToggleLights(GetFocusCanvas());
2441 case ID_MENU_ENC_SOUNDINGS: {
2442 ToggleSoundings(GetFocusCanvas());
2445 case ID_MENU_ENC_ANCHOR: {
2446 ToggleAnchor(GetFocusCanvas());
2449 case ID_MENU_ENC_DATA_QUALITY: {
2450 ToggleDataQuality(GetFocusCanvas());
2453 case ID_MENU_SHOW_NAVOBJECTS: {
2454 ToggleNavobjects(GetFocusCanvas());
2458 case ID_MENU_AIS_TARGETS: {
2459 ToggleAISDisplay(GetFocusCanvas());
2462 case ID_MENU_AIS_MOORED_TARGETS: {
2463 g_bHideMoored = !g_bHideMoored;
2466 case ID_MENU_AIS_SCALED_TARGETS: {
2467 ToggleAISMinimizeTargets(GetFocusCanvas());
2471 case ID_MENU_AIS_TARGETLIST: {
2472 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2476 case ID_MENU_AIS_TRACKS: {
2477 g_bAISShowTracks = !g_bAISShowTracks;
2478 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2482 case ID_MENU_AIS_CPADIALOG: {
2483 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2484 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2485 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2486 if (g_bAIS_CPA_Alert) {
2487 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2492 case ID_MENU_AIS_CPASOUND: {
2493 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2494 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2498 case ID_MENU_AIS_CPAWARNING: {
2499 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2500 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2504 case wxID_PREFERENCES:
2511 case ID_SETTINGS_NEW: {
2516 case ID_SETTINGS_DELETE: {
2519 g_pOptions =
nullptr;
2523 case ID_RELOAD_CHARTS: {
2528 case ID_MENU_SETTINGS_BASIC: {
2530 androidDisableFullScreen();
2532 DoAndroidPreferences();
2539 case ID_MENU_UI_FULLSCREEN: {
2544 case ID_MENU_SHOW_CURRENTS: {
2545 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2546 GetFocusCanvas()->ReloadVP();
2547 GetFocusCanvas()->Refresh(
false);
2551 case ID_MENU_SHOW_TIDES: {
2552 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2553 GetFocusCanvas()->ReloadVP();
2554 GetFocusCanvas()->Refresh(
false);
2574 case ID_MENU_UI_COLSCHEME:
2575 case ID_COLSCHEME: {
2576 ToggleColorScheme();
2585 case ID_MENU_OQUIT: {
2590 case ID_MENU_ROUTE_MANAGER:
2591 case ID_ROUTEMANAGER: {
2614 case ID_MENU_NAV_TRACK:
2616 if (!g_bTrackActive) {
2618 g_bTrackCarryOver =
true;
2621 g_bTrackCarryOver =
false;
2622 RefreshAllCanvas(
true);
2627 case ID_MENU_CHART_NORTHUP: {
2628 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2631 case ID_MENU_CHART_COGUP: {
2632 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2635 case ID_MENU_CHART_HEADUP: {
2636 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2640 case ID_MENU_MARK_MOB:
2646 case ID_MASTERTOGGLE: {
2648 wxString tip = _(
"Show Toolbar");
2649 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2651 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2653 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2656 if (g_bmasterToolbarFull)
2657 m_nMasterToolCountShown =
2661 m_nMasterToolCountShown = 2;
2663 m_nMasterToolCountShown =
2666 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2674 case ID_CMD_SELECT_CHART_TYPE: {
2675 selectChartDisplay(event.GetExtraLong(), -1);
2679 case ID_CMD_SELECT_CHART_FAMILY: {
2680 selectChartDisplay(-1, event.GetExtraLong());
2684 case ID_CMD_APPLY_SETTINGS: {
2685 applySettingsString(event.GetString());
2687 androidRestoreFullScreen();
2693 case ID_CMD_NULL_REFRESH: {
2698 case ID_CMD_SETVP: {
2699 setStringVP(event.GetString());
2703 case ID_CMD_INVALIDATE: {
2709 case ID_CMD_POST_JSON_TO_PLUGINS: {
2715 int numErrors = reader.
Parse(event.GetString(), &root);
2716 if (numErrors == 0) {
2717 if (root[
"MessageID"].IsString()) {
2718 wxString MsgID = root[
"MessageID"].
AsString();
2742 ArrayOfPlugInToolbarTools tool_array =
2744 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2746 if (event.GetId() == pttc->id) {
2747 if (pttc->m_pplugin)
2769bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2770 bool viz_now = g_bmasterToolbarFull;
2773 wxString tip = _(
"Show Toolbar");
2775 tip = _(
"Hide Toolbar");
2777 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2780 bool toggle =
false;
2781 if (viz && !g_bmasterToolbarFull)
2784 else if (!viz && g_bmasterToolbarFull)
2788 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2791 if (g_bmasterToolbarFull)
2792 m_nMasterToolCountShown =
2796 m_nMasterToolCountShown = 2;
2798 m_nMasterToolCountShown =
2801 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2807void MyFrame::ScheduleReloadCharts() {
2808 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2809 evt.SetId(ID_RELOAD_CHARTS);
2810 GetEventHandler()->AddPendingEvent(evt);
2813void MyFrame::ScheduleDeleteSettingsDialog() {
2814 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2815 evt.SetId(ID_SETTINGS_DELETE);
2816 GetEventHandler()->AddPendingEvent(evt);
2819void MyFrame::ScheduleSettingsDialog() {
2820 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2821 evt.SetId(ID_SETTINGS);
2822 GetEventHandler()->AddPendingEvent(evt);
2825void MyFrame::ScheduleSettingsDialogNew() {
2826 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2827 evt.SetId(ID_SETTINGS_NEW);
2828 GetEventHandler()->AddPendingEvent(evt);
2831void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2832 UpdateCanvasConfigDescriptors();
2834 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2835 CreateCanvasLayout(
true);
2837 CreateCanvasLayout();
2841 ConfigureStatusBar();
2842 wxSize lastOptSize = options_lastWindowSize;
2847 options_lastWindowSize = lastOptSize;
2851 ScheduleSettingsDialogNew();
2853 ScheduleSettingsDialog();
2858 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2861 int index_hint = -1;
2862 if (i < pathArray.GetCount())
2863 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2864 cc->canvasChartsRefresh(index_hint);
2865 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2874 return GetPrimaryCanvas();
2877void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2878 if (g_bmasterToolbarFull) {
2879#ifndef OCPN_TOOLBAR_ANIMATE
2880 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2883 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2884 m_nMasterToolCountShown++;
2889 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2897#ifndef OCPN_TOOLBAR_ANIMATE
2898 m_nMasterToolCountShown = 1;
2900 if (m_nMasterToolCountShown > 1) {
2901 m_nMasterToolCountShown--;
2905 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2915void MyFrame::InvalidateAllGL() {
2918 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2928void MyFrame::RefreshAllCanvas(
bool bErase) {
2930 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2933 cc->Refresh(bErase);
2938void MyFrame::setStringVP(wxString VPS) {
2943 wxStringTokenizer tkz(VPS,
";");
2945 wxString token = tkz.GetNextToken();
2947 token.ToDouble(&lat);
2949 token = tkz.GetNextToken();
2951 token.ToDouble(&lon);
2953 token = tkz.GetNextToken();
2955 token.ToDouble(&scale_ppm);
2957 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2960void MyFrame::DoSettingsNew() {
2967void MyFrame::DoSettings() {
2972 ApplyGlobalSettings(
true);
2975 bool b_loadHarmonics =
false;
2976 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2979 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2982 if (b_loadHarmonics) LoadHarmonics();
2990 g_bShowChartBar = !g_bShowChartBar;
2992 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2997 if (g_bShowChartBar) {
2999 UpdateControlBar(cc);
3002 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3005void MyFrame::ToggleColorScheme() {
3006 static bool lastIsNight;
3007 ColorScheme s = user_colors::GetColorScheme();
3010 if (lastIsNight && is == 3)
3013 lastIsNight =
false;
3015 if (lastIsNight) is = 2;
3016 if (is == 3) lastIsNight =
true;
3017 s = (ColorScheme)is;
3018 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3020 SetAndApplyColorScheme(s);
3023void MyFrame::ToggleFullScreen() {
3024 bool to = !IsFullScreen();
3029 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3031 ShowFullScreen(to, style);
3034 UpdateAllToolbars(global_color_scheme);
3036 UpdateControlBar(GetPrimaryCanvas());
3038 TriggerRecaptureTimer();
3041void MyFrame::ActivateMOB() {
3043 wxDateTime mob_time = wxDateTime::Now();
3044 wxString mob_label(_(
"MAN OVERBOARD"));
3045 mob_label += _(
" on ");
3046 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3050 pWP_MOB->SetShared(
true);
3052 pWP_MOB->SetWaypointArrivalRadius(
3054 pWP_MOB->SetUseSca(
false);
3056 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3064 new RoutePoint(zlat, zlon, g_default_wp_icon,
3065 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3066 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3071 temp_route->AddPoint(pWP_src);
3072 temp_route->AddPoint(pWP_MOB);
3074 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3084 temp_route->SetRouteArrivalRadius(-1.0);
3090 v[
"GUID"] = temp_route->
m_GUID;
3091 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3092 SendJSONMessageToAllPlugins(msg_id, v);
3095 if (RouteManagerDialog::getInstanceFlag()) {
3103 RefreshAllCanvas(
false);
3105 wxString mob_message(_(
"MAN OVERBOARD"));
3106 mob_message += _(
" Time: ");
3107 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3108 mob_message += _(
" Position: ");
3109 mob_message += toSDMM(1,
gLat);
3111 mob_message += toSDMM(2,
gLon);
3112 wxLogMessage(mob_message);
3114void MyFrame::TrackOn() {
3115 g_bTrackActive =
true;
3123 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3125 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3127 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3130 androidSetTrackTool(
true);
3133 if (RouteManagerDialog::getInstanceFlag()) {
3142 if (name.IsEmpty()) {
3148 name = _(
"(Unnamed Track)");
3152 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3153 SendJSONMessageToAllPlugins(msg_id, v);
3154 g_FlushNavobjChangesTimeout =
3158Track *MyFrame::TrackOff(
bool do_add_point) {
3163 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3165 SendJSONMessageToAllPlugins(msg_id, v);
3174 if (g_bTrackDaily) {
3179 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3180 return_val = pExtendTrack;
3187 g_bTrackActive =
false;
3189 if (RouteManagerDialog::getInstanceFlag()) {
3196 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3198 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3199 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3202 androidSetTrackTool(
false);
3206 m_target_rotate_time = wxInvalidDateTime;
3211void MyFrame::InitializeTrackRestart() {
3212 if (!g_bTrackDaily)
return;
3213 if (m_target_rotate_time.IsValid())
return;
3216 switch (g_track_rotate_time_type) {
3218 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3220 case TIME_TYPE_COMPUTER:
3221 rotate_at = g_track_rotate_time;
3225 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3226 rotate_at = g_track_rotate_time + utc_offset;
3229 if (rotate_at > 86400)
3231 else if (rotate_at < 0)
3234 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3235 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3238 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3239 m_target_rotate_time += wxTimeSpan(24);
3243bool MyFrame::ShouldRestartTrack() {
3245 InitializeTrackRestart();
3247 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3248 m_target_rotate_time += wxTimeSpan(24);
3254void MyFrame::TrackDailyRestart() {
3256 Track *pPreviousTrack = TrackOff(
true);
3263 if (pPreviousTrack) {
3264 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3268 if (RouteManagerDialog::getInstanceFlag()) {
3276void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3278 cc->SetUpMode(mode);
3280 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3281 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3282 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3285 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3290 cc->SetShowENCText(!cc->GetShowENCText());
3292 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3300void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3303 cc->SetENCDisplayCategory(nset);
3305 UpdateGlobalMenuItems();
3316 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3318 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3327 cc->SetShowENCLights(!cc->GetShowENCLights());
3329 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3339void MyFrame::ToggleRocks(
void )
3345 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3346 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3347 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3348 pOLE->nViz = !pOLE->nViz;
3352 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3353 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3354 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3357 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3361 ps52plib->GenerateStateHash();
3368 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3370 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3378 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3380 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3395 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3396 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3401 cc->SetShowAIS(!cc->GetShowAIS());
3402 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3406void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3407 cc->SetAttenAIS(!cc->GetAttenAIS());
3408 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3414 cc->m_bFollow =
true;
3417 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3421 SetChartUpdatePeriod();
3429 cc->m_bFollow =
false;
3431 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3435 SetChartUpdatePeriod();
3438void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3439 cc->SetShowOutlines(!cc->GetShowOutlines());
3441 RefreshAllCanvas(
false);
3445 if (g_bopengl) InvalidateAllGL();
3448 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3451void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3453void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3455 bool enabled = m_pMenuBar->IsEnabled(item_id);
3456 m_pMenuBar->Enable(item_id,
false);
3457 m_pMenuBar->Check(item_id, state);
3458 m_pMenuBar->Enable(item_id, enabled);
3462void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3469void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3470 wxBitmap *bmpRollover) {
3472 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3477void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3478 wxString rolloverSVGfile,
3479 wxString toggledSVGfile) {
3482 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3486void MyFrame::ConfigureStatusBar() {
3488 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3491 UseNativeStatusBar(
false);
3494 if (g_bShowStatusBar) {
3495 if (!m_pStatusBar) {
3497 CreateStatusBar(m_StatusBarFieldCount, 0);
3498 ApplyGlobalColorSchemetoStatusBar();
3503 m_pStatusBar->Destroy();
3504 m_pStatusBar = NULL;
3510void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3511 ConfigureStatusBar();
3513 wxSize lastOptSize = options_lastWindowSize;
3519 options_lastWindowSize = lastOptSize;
3521 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3524void MyFrame::BuildMenuBar() {
3530 bool showMenuBar =
true;
3532 bool showMenuBar = g_bShowMenuBar;
3544 m_pMenuBar =
new wxMenuBar();
3545 RegisterGlobalMenuItems();
3546 SetMenuBar(m_pMenuBar);
3550 UpdateGlobalMenuItems();
3555 m_pMenuBar->Destroy();
3561void MyFrame::RegisterGlobalMenuItems() {
3562 if (!m_pMenuBar)
return;
3564 wxMenu *nav_menu =
new wxMenu();
3565 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3566 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3567 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3568 nav_menu->AppendSeparator();
3569 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3570 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3571 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3572 nav_menu->AppendSeparator();
3574 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3575 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3577 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3578 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3580 nav_menu->AppendSeparator();
3581 nav_menu->Append(ID_MENU_SCALE_IN,
3582 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3583 nav_menu->Append(ID_MENU_SCALE_OUT,
3584 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3586 nav_menu->AppendSeparator();
3587 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3589 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3591 wxMenu *view_menu =
new wxMenu();
3593 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3594 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3595 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3596 _menuText(_(
"Show Chart Outlines"),
"O"));
3598 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3599 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3600 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3601 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3603 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3604 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3606 view_menu->AppendSeparator();
3608 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3609 _menuText(_(
"Show ENC text"),
"T"));
3610 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3611 _menuText(_(
"Show ENC Lights"),
"L"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3613 _menuText(_(
"Show ENC Soundings"),
"S"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3615 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3617 _menuText(_(
"Show ENC Data Quality"),
"U"));
3618 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3619 _menuText(_(
"Show Navobjects"),
"V"));
3621 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3622 _menuText(_(
"Show ENC text"),
"Alt-T"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3624 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3625 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3626 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3627 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3628 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3630 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3631 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3632 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3634 view_menu->AppendSeparator();
3635 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3636 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3637 view_menu->AppendSeparator();
3639 view_menu->Append(ID_MENU_UI_COLSCHEME,
3640 _menuText(_(
"Change Color Scheme"),
"C"));
3642 view_menu->Append(ID_MENU_UI_COLSCHEME,
3643 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3646 view_menu->AppendSeparator();
3648 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3649 _menuText(_(
"Toggle Full Screen"),
"F11"));
3651 m_pMenuBar->Append(view_menu, _(
"&View"));
3653 wxMenu *ais_menu =
new wxMenu();
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3656 _(
"Attenuate less critical AIS targets"));
3657 ais_menu->AppendSeparator();
3658 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3659 _(
"Hide Moored AIS Targets"));
3660 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3661 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3665 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3666 _menuText(_(
"Show CPA Warnings"),
"W"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3669 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3672 ais_menu->AppendSeparator();
3673 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3674 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3676 wxMenu *tools_menu =
new wxMenu();
3677 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3678 _menuText(_(
"Data Monitor"),
"E"));
3680 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3681 _menuText(_(
"Measure Distance"),
"M"));
3683 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3684 _menuText(_(
"Measure Distance"),
"Alt-M"));
3687 tools_menu->AppendSeparator();
3688 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3689 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3690 tools_menu->AppendSeparator();
3691 tools_menu->Append(ID_MENU_MARK_BOAT,
3692 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3693 tools_menu->Append(ID_MENU_MARK_CURSOR,
3694 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3695 tools_menu->AppendSeparator();
3699 _menuText(_(
"Drop MOB Marker"),
3701 tools_menu->AppendSeparator();
3702 tools_menu->Append(wxID_PREFERENCES,
3703 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3705 tools_menu->Append(ID_MENU_MARK_MOB,
3706 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3707 tools_menu->AppendSeparator();
3708 tools_menu->Append(wxID_PREFERENCES,
3709 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3711 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3714 wxMenu *window_menu =
new wxMenu();
3715 m_pMenuBar->Append(window_menu, _(
"&Window"));
3718 wxMenu *help_menu =
new wxMenu();
3719 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3720 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3721 m_pMenuBar->Append(help_menu, _(
"&Help"));
3724 UpdateGlobalMenuItems();
3727void MyFrame::UpdateGlobalMenuItems() {
3728 if (!m_pMenuBar)
return;
3730 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3731 ->Check(GetPrimaryCanvas()->m_bFollow);
3732 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3733 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3734 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3735 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3736 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3737 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3738 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3739 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3740 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3741 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3744 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3745 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3746 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3748 if (g_bAIS_CPA_Alert) {
3749 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3750 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3753 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3756 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3757 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3758 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3761 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3762 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3763 ->Check(ps52plib->GetShowSoundings());
3765 bool light_state =
false;
3767 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3769 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3770 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3771 light_state = (pOLE->nViz == 1);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3777 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3781 DisCat nset = ps52plib->GetDisplayCategory();
3782 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3783 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3784 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3785 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3786 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3787 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3788 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3790 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3791 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3792 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3797void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3798 if (!m_pMenuBar)
return;
3800 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3802 if (cc->GetUpMode() == NORTH_UP_MODE)
3803 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3804 else if (cc->GetUpMode() == COURSE_UP_MODE)
3805 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3807 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3809 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3810 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3811 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3812 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3813 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3814 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3815 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3816 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3817 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3818 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3819 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3820 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3821 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3822 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3823 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3826 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3827 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3830 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3832 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3833 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3838 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3842 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3843 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3844 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3845 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3846 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3847 ->Check(cc->GetShowENCDataQual());
3848 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3850 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3851 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3852 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3857void MyFrame::InvalidateAllCanvasUndo() {
3859 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3861 if (cc) cc->undo->InvalidateUndo();
3865void MyFrame::SubmergeAllCanvasToolbars() {
3867 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3869 if (cc) cc->SubmergeToolbar();
3873void MyFrame::SurfaceAllCanvasToolbars() {
3874 if (g_bshowToolbar) {
3876 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3878 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3885void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3887 if (lon > 180.0) lon -= 360.0;
3892 cc->JumpToPosition(lat, lon,
scale);
3895 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3899void MyFrame::UpdateCanvasConfigDescriptors() {
3901 for (
unsigned int i = 0;
3902 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3903 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3911 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3912 cc->GroupID = chart->m_groupIndex;
3915 cc->
bQuilt = chart->GetQuiltMode();
3922 cc->
bFollow = chart->m_bFollow;
3927 int upmode = chart->GetUpMode();
3928 if (upmode == COURSE_UP_MODE)
3930 else if (upmode == HEAD_UP_MODE)
3937void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3938 if (!RBBox.GetValid())
return;
3940 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3941 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3944 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3945 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3953 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3954 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3956 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3957 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3959 cc->GetSize(&ww, &wh);
3961 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3963 ppm = wxMin(ppm, 1.0);
3969void MyFrame::PrepareOptionsClose(
options *settings,
3970 int settings_return_value) {
3972 options_lastPage = settings->lastPage;
3977 if (options_lastPage == 1) options_lastPage = 0;
3979 options_subpage = settings->lastSubPage;
3980 options_lastWindowPos = settings->lastWindowPos;
3981 options_lastWindowSize = settings->lastWindowSize;
3984 androidEnableBackButton(
true);
3985 androidEnableOptionsMenu(
true);
3986 androidRestoreFullScreen();
3987 androidEnableRotation();
3990 EnableSettingsTool(
true);
3993void MyFrame::DoOptionsDialog() {
3994 EnableSettingsTool(
false);
3997 AbstractPlatform::ShowBusySpinner();
4000 pConfig->SetPath(
"/Settings");
4001 pConfig->Read(
"OptionsSizeX", &sx, -1);
4002 pConfig->Read(
"OptionsSizeY", &sy, -1);
4004 wxWindow *optionsParent =
this;
4006 optionsParent = GetPrimaryCanvas();
4009 callbacks.prepare_close = [&](
options *me,
int changes) {
4010 PrepareOptionsClose(me, changes);
4012 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4013 ProcessOptionsDialog(changes, workdir_list);
4016 wxPoint(-1, -1), wxSize(sx, sy));
4018 AbstractPlatform::HideBusySpinner();
4022 g_options->SetInitChartDir(*pInit_Chart_Dir);
4026 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4027 g_options->SetWorkDirListPtr(pWorkDirArray);
4033 prev_locale = g_locale;
4034 g_options->SetInitialPage(options_lastPage, options_subpage);
4037 g_options->lastWindowPos = options_lastWindowPos;
4038 if (options_lastWindowPos != wxPoint(0, 0)) {
4040 g_options->SetSize(options_lastWindowSize);
4044 if (options_lastWindowSize != wxSize(0, 0)) {
4045 g_options->SetSize(options_lastWindowSize);
4050 androidEnableBackButton(
false);
4051 androidEnableOptionsMenu(
false);
4052 androidDisableFullScreen();
4060 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4063 wxString chart_file_name;
4064 if (cc->GetQuiltMode()) {
4065 int dbi = cc->GetQuiltRefChartdbIndex();
4066 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4068 if (cc->m_singleChart)
4069 chart_file_name = cc->m_singleChart->GetFullPath();
4072 pathArray.Add(chart_file_name);
4078 last_canvasConfig = g_canvasConfig;
4081 g_last_ChartScaleFactor = g_ChartScaleFactor;
4087void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4088 bool b_need_refresh =
false;
4091 if ((rr & VISIT_CHARTS) &&
4092 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4094 UpdateChartDatabaseInplace(*pNewDirArray,
4095 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4098 b_need_refresh =
true;
4103 if (rr & STYLE_CHANGED) {
4106 _(
"Please restart OpenCPN to activate language or style changes."),
4107 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4110 bool charts_updating =
4111 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4112 if (!charts_updating) RefreshGroupIndices();
4114 if (rr & TIDES_CHANGED) {
4120 if (rr & S52_CHANGED) {
4121 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4132 g_Platform->GetDisplayDPmm());
4135 double stuffcog = NAN;
4136 double stuffsog = NAN;
4137 if (!std::isnan(
gCog)) stuffcog =
gCog;
4138 if (!std::isnan(
gSog)) stuffsog =
gSog;
4140 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4141 COGFilterTable[i] = stuffcog;
4142 SOGFilterTable[i] = stuffsog;
4145 SetChartUpdatePeriod();
4147 if (rr & GL_CHANGED) {
4151 b_need_refresh =
true;
4154 if (rr & S52_CHANGED) {
4155 b_need_refresh =
true;
4159 if (rr & REBUILD_RASTER_CACHE) {
4161 GetPrimaryCanvas()->Disable();
4163 GetPrimaryCanvas()->Enable();
4168 if (g_config_display_size_manual &&
4176 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4183 int rrt = rr & S52_CHANGED;
4185 (rrt == S52_CHANGED) ||
4186 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4196 ps52plib->SetScaleFactorExp(
4197 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4198 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4202 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4204 if (cc) cc->ApplyGlobalSettings();
4212 if (!charts_updating) {
4213 bool ztc = g_bEnableZoomToCursor;
4214 g_bEnableZoomToCursor =
false;
4216 if (!GetPrimaryCanvas()->IsFrozen())
4218 g_bEnableZoomToCursor = ztc;
4223 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4232 SetGPSCompassScale();
4234 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4237 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4238 if (!charts_updating) cc->UpdateCanvasControlBar();
4241 UpdateGPSCompassStatusBoxes();
4243 SetAllToolbarScale();
4244 RequestNewToolbars();
4246 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4249 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4252 cc->RebuildCursors();
4257 bool b_masterScaleChange =
false;
4258 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4259 b_masterScaleChange =
true;
4261 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4262 RequestNewMasterToolbar(
true);
4264 bool bMuiChange =
false;
4270 if (b_masterScaleChange || bMuiChange) {
4272 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4275 cc->ProcessNewGUIScale();
4281 if (rr & LOCALE_CHANGED) {
4282 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4284 rr |= NEED_NEW_OPTIONS;
4293 g_last_ChartScaleFactor = g_ChartScaleFactor;
4298bool MyFrame::CheckGroup(
int igroup) {
4299 if (igroup == 0)
return true;
4303 if (!pGroup->m_element_array.size())
4306 for (
const auto &elem : pGroup->m_element_array) {
4307 for (
unsigned int ic = 0;
4308 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4309 auto &cte =
ChartData->GetChartTableEntry(ic);
4310 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4312 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4319bool MyFrame::ScrubGroupArray() {
4324 bool b_change =
false;
4325 unsigned int igroup = 0;
4326 while (igroup < g_pGroupArray->GetCount()) {
4327 bool b_chart_in_element =
false;
4330 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4331 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4333 for (
unsigned int ic = 0;
4334 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4335 auto &cte =
ChartData->GetChartTableEntry(ic);
4336 wxString chart_full_path = cte.GetFullSystemPath();
4338 if (chart_full_path.StartsWith(element_root)) {
4339 b_chart_in_element =
true;
4345 if (!b_chart_in_element) {
4346 wxString test_string =
"GSHH";
4347 if (element_root.Upper().Contains(test_string))
4348 b_chart_in_element =
true;
4351 if (!b_chart_in_element)
4353 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4365void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4367 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4369 if (cc && (cc != ccThis)) cc->Refresh();
4374void MyFrame::ChartsRefresh() {
4377 AbstractPlatform::ShowBusySpinner();
4379 bool b_run = FrameTimer1.IsRunning();
4382 FrameTenHzTimer.Stop();
4385 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4388 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4389 if (cc->GetQuiltMode()) {
4390 currentIndex = cc->GetQuiltReferenceChartIndex();
4392 cc->canvasChartsRefresh(currentIndex);
4396 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4397 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4399 AbstractPlatform::HideBusySpinner();
4402void MyFrame::InvalidateAllQuilts() {
4403 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4406 cc->InvalidateQuilt();
4407 cc->SetQuiltRefChart(-1);
4408 cc->m_singleChart = NULL;
4413bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4415 const wxString &ChartListFileName) {
4416 bool b_run = FrameTimer1.IsRunning();
4418 FrameTenHzTimer.Stop();
4420 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4421 FrameCOGTimer.Stop();
4424 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4427 cc->InvalidateQuilt();
4428 cc->SetQuiltRefChart(-1);
4429 cc->m_singleChart = NULL;
4439 AbstractPlatform::ShowBusySpinner();
4442 wxString longmsg = _(
"OpenCPN Chart Update");
4444 ".................................................................."
4447 Updateprog =
new wxGenericProgressDialog();
4450 Updateprog->SetFont(*qFont);
4452 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4453 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4454 wxPD_REMAINING_TIME);
4456 DimeControl(Updateprog);
4461 wxLogMessage(
"Starting chart database Update...");
4465 m_gshhg_chart_loc = gWorldMapLocation;
4466 gWorldMapLocation = wxEmptyString;
4470 AbstractPlatform::HideBusySpinner();
4474void MyFrame::FinalizeChartDBUpdate() {
4476 bool b_groupchange = ScrubGroupArray();
4478 RefreshGroupIndices();
4480 if (b_groupchange) {
4481 pConfig->DestroyConfigGroups();
4486 ScheduleReloadCharts();
4491 cc->ToggleCanvasQuiltMode();
4493 bool cur_mode = cc->GetQuiltMode();
4495 if( !cc->GetQuiltMode() )
4496 cc->SetQuiltMode(
true );
4498 if( cc->GetQuiltMode() ) {
4499 cc->SetQuiltMode(
false );
4500 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4504 if( cur_mode != cc->GetQuiltMode() ){
4510 g_bQuiltEnable = cc->GetQuiltMode();
4514 ps52plib->GenerateStateHash();
4522 DoStackDelta(cc, -1);
4528 DoStackDelta(cc, 1);
4531void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4533void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4535void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4537 cc->DoCanvasStackDelta(direction);
4541void MyFrame::PositionIENCToolbar() {
4545 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4547 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4555void MyFrame::OnInitTimer(wxTimerEvent &event) {
4558 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4562 wxLog::FlushActive();
4564 switch (m_iInitCount++) {
4566 EnableSettingsTool(
false);
4571 if (g_bInlandEcdis) {
4572 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4573 double range_set = 500.;
4575 range = wxRound(range * 10) / 10.;
4579 else if (range > 2000.)
4581 else if (range > 1600.)
4583 else if (range > 1200.)
4585 else if (range > 800.)
4590 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4594 g_Platform->SetFullscreen(g_bFullscreen);
4598 RebuildChartDatabase();
4599 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4602 cc->SetGroupIndex(0,
false);
4610 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4611 CHART_FAMILY_RASTER)) {
4616 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4617 CHART_FAMILY_VECTOR)) {
4630 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4633 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4635 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4638 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4642 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4643 NavObj_dB::GetInstance().LoadNavObjects();
4646 if (!g_AW1GUID.IsEmpty()) {
4649 if (!g_AW2GUID.IsEmpty()) {
4655 appendOSDirSlash(&layerdir);
4656 layerdir.Append(
"layers");
4658 if (wxDir::Exists(layerdir)) {
4660 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4661 wxLogMessage(laymsg);
4662 pConfig->LoadLayers(layerdir);
4672 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4686 3 * GetCharHeight());
4688 m_data_monitor->Center();
4696 pConfig->SetPath(
"/Settings");
4697 pConfig->Read(
"OptionsSizeX", &sx, -1);
4698 pConfig->Read(
"OptionsSizeY", &sy, -1);
4700 wxWindow *optionsParent =
this;
4702 optionsParent = GetPrimaryCanvas();
4704 BuildiENCToolbar(
true, m_toolbar_callbacks);
4711 if (!g_params.empty()) {
4712 for (
size_t n = 0; n < g_params.size(); n++) {
4713 wxString path = g_params[n];
4714 if (::wxFileExists(path)) {
4716 pSet->load_file(path.fn_str());
4719 pSet->LoadAllGPXObjects(
4720 !pSet->IsOpenCPN(), wpt_dups,
4722 LLBBox box = pSet->GetBBox();
4723 if (box.GetValid()) {
4724 CenterView(GetPrimaryCanvas(), box);
4733 InitAppMsgBusListener();
4738 auto loader = PluginLoader::GetInstance();
4739 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4740 if (!b_haveWMM)
gVar = g_UserVar;
4748 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4751 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4753 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4756 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4760 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4761 NavObj_dB::GetInstance().LoadNavObjects();
4764 if (!g_AW1GUID.IsEmpty()) {
4767 if (!g_AW2GUID.IsEmpty()) {
4773 appendOSDirSlash(&layerdir);
4774 layerdir.Append(
"layers");
4776 if (wxDir::Exists(layerdir)) {
4778 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4779 wxLogMessage(laymsg);
4780 pConfig->LoadLayers(layerdir);
4785 if (!g_kiosk_startup) {
4786 AbstractPlatform::ShowBusySpinner();
4789 pConfig->SetPath(
"/Settings");
4790 pConfig->Read(
"OptionsSizeX", &sx, -1);
4791 pConfig->Read(
"OptionsSizeY", &sy, -1);
4793 wxWindow *optionsParent =
this;
4795 optionsParent = GetPrimaryCanvas();
4798 callbacks.prepare_close = [&](
options *me,
int changes) {
4799 PrepareOptionsClose(me, changes);
4801 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4802 ProcessOptionsDialog(changes, workdir_list);
4805 wxPoint(-1, -1), wxSize(sx, sy));
4806 AbstractPlatform::HideBusySpinner();
4813 wxLogMessage(
"OnInitTimer...Last Call");
4817 RequestNewMasterToolbar();
4819 PositionIENCToolbar();
4821 g_bDeferredInitDone =
true;
4831 GetPrimaryCanvas()->SetFocus();
4832 GetPrimaryCanvas()->Enable();
4835 if (b_reloadForPlugins) {
4841 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4843 if (cc) cc->SetFirstAuto(
true);
4851 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4853 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4857 cc->CheckGroupValid();
4862 androidEnableBackButton(
true);
4863 androidEnableRotation();
4864 androidEnableOptionItems(
true);
4868 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4874 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4876 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4878 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4884 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4886 wxLog::FlushActive();
4888 RefreshAllCanvas(
true);
4889 UsbWatchDaemon::GetInstance().Start();
4890 EnableSettingsTool(
true);
4896void MyFrame::InitAppMsgBusListener() {
4897 auto &msgbus = AppMsgBus::GetInstance();
4900 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4901 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4905 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4906 HandleBasicNavMsg(basicnav_msg);
4910 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4911 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4915 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4916 HandleGPSWatchdogMsg(msg);
4923void MyFrame::ReleaseApiListeners() {}
4928 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4929 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4930 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4931 server.open_file_cb = [&](
const std::string &path) {
4932 return m_open_gpx_file(path);
4939void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4940 if (msg->gps_watchdog <= 0) {
4941 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4945 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4950 if (m_fix_start_time.IsValid()) {
4951 wxDateTime now = wxDateTime::Now();
4952 wxTimeSpan span = now - m_fix_start_time;
4953 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4954 auto ¬eman = NotificationManager::GetInstance();
4955 wxString msg = _(
"GNSS Position fix lost");
4956 noteman.AddNotification(NotificationSeverity::kCritical,
4958 m_fix_start_time = wxInvalidDateTime;
4962 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4963 bool last_bVelocityValid = bVelocityValid;
4964 bVelocityValid =
false;
4971void MyFrame::CalculateCOGAverage() {
4973 if (!std::isnan(
gCog)) {
4976 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4979 double sum = 0., count = 0;
4981 double adder = COGTable[i];
4982 if (std::isnan(adder))
continue;
4984 if (fabs(adder -
g_COGAvg) > 180.) {
4998 else if (sum >= 360.)
5007void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5008 m_fixtime = msg->time;
5009 double hdt_data_interval = 0;
5010 double fix_time_interval = 0;
5012 double msgtime = msg->set_time.tv_sec;
5013 double m1 = msg->set_time.tv_nsec / 1e9;
5016 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5017 ((msg->vflag & POS_VALID) == POS_VALID)) {
5019 if (!m_fix_start_time.IsValid()) {
5020 m_fix_start_time = wxDateTime::Now();
5025 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5028 fix_time_gt_last = fix_time_gt;
5029 uint64_t fix_time_gt_now =
5030 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5031 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5035 double implied_sog = dist / (fix_time_interval / 3600);
5040 gLat_gt_m1 = gLat_gt;
5041 gLon_gt_m1 = gLon_gt;
5045 fix_time_gt = fix_time_gt_now;
5049 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5050 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5051 gCog_gt_m1 = gCog_gt;
5061 if (!std::isnan(gCog_gt_m1)) {
5063 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5070 if ((fix_time_gt - fix_time_gt_last) > .08) {
5075 if (gCog_gt > gCog_gt_m1) {
5076 if ((gCog_gt - gCog_gt_m1) > 180.)
5081 if ((gCog_gt_m1 - gCog_gt) > 180.)
5086 difft = fabs(gCog_gt - gCog_gt_m1);
5087 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5095 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5096 tentative_cog_rate_gt *= 1e9;
5097 cog_rate_gt = tentative_cog_rate_gt;
5105 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5108static double hdt_avg;
5109 double hdt_norm =
gHdt;
5110 if(
gHdt > 180) hdt_norm -= 360;
5113 hdt_avg += hdt_norm * 0.1;
5118 if (!std::isnan(
gHdt)) {
5120 uint64_t hdt_time_gt_last = hdt_time_gt;
5121 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5122 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5125 if (hdt_data_interval > .09) {
5127 gHdt_gt_m1 = gHdt_gt;
5130 if (!std::isnan(gHdt_gt_m1)) {
5132 double tentative_hdt_rate_gt =
5133 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5134 tentative_hdt_rate_gt *= 1e9;
5136 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5137 hdt_rate_gt = tentative_hdt_rate_gt;
5145 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5148 CalculateCOGAverage();
5156 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5157 if ((msg->vflag & POS_VALID) == POS_VALID)
5162 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5164 bVelocityValid =
true;
5168void MyFrame::UpdateStatusBar() {
5171 unsigned long uiCurrentTickCount;
5172 m_MMEAeventTime.SetToCurrent();
5173 uiCurrentTickCount =
5174 m_MMEAeventTime.GetMillisecond() / 100;
5175 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5176 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5177 m_ulLastNMEATicktime = uiCurrentTickCount;
5179 if (m_tick_idx++ > 6) m_tick_idx = 0;
5184 if (NULL != GetStatusBar()) {
5187 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5190 wxString s1(tick_buf, wxConvUTF8);
5192 s1 += toSDMM(1,
gLat);
5194 s1 += toSDMM(2,
gLon);
5196 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5200 if (!std::isnan(
gSog))
5201 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5203 sogcog.Printf(
"SOG --- ");
5207 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5209 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5211 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5212 (
int)toMagnetic(
gCog), 0x00B0);
5214 cogs.Printf((
"COG ---%c"), 0x00B0);
5216 sogcog.Append(cogs);
5217 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5222void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5223 MemFootTimer.Stop();
5225 int memsize = GetApplicationMemoryUse();
5228 printf(
"Memsize: %d \n", memsize);
5231 if (memsize > (g_MemFootMB * 1000)) {
5235 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5236 unsigned int nCache = pCache->GetCount();
5239 for (
unsigned int i = 0; i < nCache; i++) {
5249 for (
unsigned int i = 0; i < nCache - 1; i++) {
5250 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5252 pcea[i] = pcea[i + 1];
5263 unsigned int idelete = 0;
5264 unsigned int idelete_max = pCache->GetCount();
5267 unsigned int minimum_cache = 1;
5268 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5270 while ((memsize > (g_MemFootMB * 1000)) &&
5271 (pCache->GetCount() > minimum_cache) &&
5272 (idelete < idelete_max)) {
5273 int memsizeb = memsize;
5277 memsize = GetApplicationMemoryUse();
5278 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5286 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5291void MyFrame::CheckToolbarPosition() {
5294 static bool bMaximized;
5296 if (IsMaximized() && !bMaximized) {
5303 PositionIENCToolbar();
5304 }
else if (!IsMaximized() && bMaximized) {
5312 PositionIENCToolbar();
5317void MyFrame::ProcessUnitTest() {
5318 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5325 cc->m_bFollow =
false;
5327 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5328 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5331 if (cc->m_groupIndex > 0) {
5332 while (ut_index < ChartData->GetChartTableEntries() &&
5333 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5337 if (ut_index < ChartData->GetChartTableEntries()) {
5341 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5342 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5349 if (cc->GetQuiltMode()) {
5350 if (cc->IsChartQuiltableRef(ut_index))
5351 cc->SelectQuiltRefdbChart(ut_index);
5353 cc->SelectdbChart(ut_index);
5356 if (g_unit_test_1) {
5364 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5365 cte->GetLatMin(), cte->GetLonMax(), NULL,
5369 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5370 cte->GetLatMax(), cte->GetLonMin(), NULL,
5373 cc->GetSize(&ww, &wh);
5374 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5376 ppm = wxMin(ppm, 1.0);
5383 if (ut_index > ut_index_max) exit(0);
5394 bool b_rotate =
false;
5396 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5399 if (!b_rotate && !g_btenhertz)
return;
5401 bool b_update =
false;
5403 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5406 struct timespec now;
5407 clock_gettime(CLOCK_MONOTONIC, &now);
5408 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5409 double diffc = diff / 1e9;
5412 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5413 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5414 if (gCog_tentative < 0.) gCog_tentative += 360.;
5415 gCog = gCog_tentative;
5419 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5420 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5421 double diffc = diff / 1e9;
5422 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5426 if (gSog_gt && !std::isnan(gCog_gt)) {
5427 double delta_t = diffc / 3600;
5428 double distance = gSog_gt * delta_t;
5431 double angr = gCog_gt / 180 * M_PI;
5432 double latr = gLat_gt * M_PI / 180;
5433 double D = distance / 3443;
5434 double sD = sin(D), cD = cos(D);
5435 double sy = sin(latr), cy = cos(latr);
5436 double sa = sin(angr), ca = cos(angr);
5438 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5439 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5449 if (cc) cc->DoCanvasCOGSet();
5458 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5459 bool bnew = cc->DoCanvasUpdate();
5460 if (!bnew) cc->UpdateShips();
5469 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5472bool MyFrame::ProcessQuitFlag() {
5476 FrameTenHzTimer.Stop();
5478 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5479 if (top) top->Close(
true);
5486void MyFrame::ProcessDeferredTrackOn() {
5489 if (g_bDeferredStartTrack) {
5490 if (!g_bTrackActive) {
5493 g_bDeferredStartTrack =
false;
5496 g_bDeferredStartTrack =
false;
5501void MyFrame::ProcessAnchorWatch() {
5509 double d = g_nAWMax;
5512 bool toofar =
false;
5513 bool tooclose =
false;
5514 if (d >= 0.0) toofar = (dist * 1852. > d);
5515 if (d < 0.0) tooclose = (dist * 1852 < -d);
5517 if (tooclose || toofar)
5518 AnchorAlertOn1 =
true;
5520 AnchorAlertOn1 =
false;
5522 AnchorAlertOn1 =
false;
5530 double d = g_nAWMax;
5533 bool toofar =
false;
5534 bool tooclose =
false;
5535 if (d >= 0) toofar = (dist * 1852. > d);
5536 if (d < 0) tooclose = (dist * 1852 < -d);
5538 if (tooclose || toofar)
5539 AnchorAlertOn2 =
true;
5541 AnchorAlertOn2 =
false;
5543 AnchorAlertOn2 =
false;
5546 AnchorAlertOn1 =
true;
5549void MyFrame::SendFixToPlugins() {
5560 GPSData.
nSats = g_SatsInView;
5562 wxDateTime tCheck((time_t)m_fixtime);
5563 if (tCheck.IsValid()) {
5572 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5575 SendPositionFixToAllPlugIns(&GPSData);
5579void MyFrame::ProcessLogAndBells() {
5582 wxDateTime lognow = wxDateTime::Now();
5583 int hourLOC = lognow.GetHour();
5584 int minuteLOC = lognow.GetMinute();
5586 int minuteUTC = lognow.GetMinute();
5587 int second = lognow.GetSecond();
5589 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5590 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5591 (minuteUTC == 30)) {
5592 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5593 wxString day = lognow.FormatISODate();
5594 wxString utc = lognow.FormatISOTime();
5595 wxString navmsg =
"LOGBOOK: ";
5603 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5607 if (std::isnan(
gCog))
5608 cog.Printf(
"COG ----- ");
5610 cog.Printf(
"COG %10.5f ",
gCog);
5613 if (std::isnan(
gSog))
5614 sog.Printf(
"SOG ----- ");
5616 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5622 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5625 wxLogMessage(navmsg);
5626 g_loglast_time = lognow;
5628 int bells = (hourLOC % 4) * 2;
5629 if (minuteLOC != 0) bells++;
5630 if (!bells) bells = 8;
5632 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5633 m_BellsToPlay = bells;
5634 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5635 wxPostEvent(
this, ev);
5642 CheckToolbarPosition();
5646 if (ProcessQuitFlag())
return;
5648 if (bDBUpdateInProgress)
return;
5651 FrameTenHzTimer.Stop();
5653 ProcessDeferredTrackOn();
5655 ProcessAnchorWatch();
5656 ProcessLogAndBells();
5658 if (ShouldRestartTrack()) TrackDailyRestart();
5661 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5662 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5663 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5669 if (
gSog > 3.0) g_bCruising =
true;
5675 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5677 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5683 bool bnew_view =
false;
5684 if (!g_btenhertz) bnew_view = DoChartUpdate();
5691 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5694 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5697 cc->DrawBlinkObjects();
5700 if (bactiveRouteUpdate) {
5707 cc->SetOwnShipState(SHIP_NORMAL);
5709 if (cc->GetQuiltMode()) {
5710 double erf = cc->GetQuiltMaxErrorFactor();
5711 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5713 if (cc->m_singleChart) {
5714 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5715 cc->SetOwnShipState(SHIP_LOWACCURACY);
5719 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5722 (bVelocityValid != m_last_bVelocityValid) ||
5723 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5724 if (!g_bopengl) cc->UpdateShips();
5732 m_last_bVelocityValid = bVelocityValid;
5737 bool brq_dynamic =
false;
5739 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5740 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5742 if (pic->m_enabled && pic->m_init_state) {
5743 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5750 if (brq_dynamic) bnew_view =
true;
5754 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5757 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5762 if (cc->GetglCanvas()) {
5764 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5766 if ((!g_btenhertz)) {
5767 if (cc->m_bFollow) {
5768 cc->DoCanvasUpdate();
5785 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5799 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5800 g_pais_query_dialog_active->UpdateText();
5803 if (g_pAISTargetList && (0 == (g_tick % (5))))
5804 g_pAISTargetList->UpdateAISTargetList();
5807 UpdateGPSCompassStatusBoxes();
5812 console->RefreshConsoleData();
5819 if (m_bdefer_resize) {
5820 if (0 == (g_tick % (5))) {
5821 printf(
"___RESIZE\n");
5822 SetSize(m_defer_size);
5824 m_bdefer_resize =
false;
5831 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5833 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5834 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5838double MyFrame::GetMag(
double a,
double lat,
double lon) {
5839 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5840 auto loader = PluginLoader::GetInstance();
5841 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5848 wxDateTime now = wxDateTime::Now();
5849 SendJSON_WMM_Var_Request(lat, lon, now);
5850 if (fabs(gQueryVar) < 360.0)
5851 Variance = gQueryVar;
5853 return toMagnetic(a, Variance);
5856bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5862 v[
"Year"] = date.GetYear();
5863 v[
"Month"] = date.GetMonth();
5864 v[
"Day"] = date.GetDay();
5866 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5872void MyFrame::TouchAISActive() {
5874 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5876 if (cc) cc->TouchAISToolActive();
5880void MyFrame::UpdateAISTool() {
5884 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5886 if (cc) cc->UpdateAISTBTool();
5891void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5893 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5895 if (cc) cc->SetbTCUpdate(
true);
5898 RefreshAllCanvas(
false);
5903void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5907 bool b_rotate =
false;
5908 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5910 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5914 FrameCOGTimer.Stop();
5921 int period_ms = 100;
5923 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5926void MyFrame::DoCOGSet() {
5928 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5930 if (cc) cc->DoCanvasCOGSet();
5934void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5940 wxFont oldfont = pdc->GetFont();
5942 pdc->SetFont(*pFont);
5943 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5944 pdc->SetBackgroundMode(wxTRANSPARENT);
5946 pdc->DrawText(str, x, y + 1);
5947 pdc->DrawText(str, x, y - 1);
5948 pdc->DrawText(str, x + 1, y);
5949 pdc->DrawText(str, x - 1, y);
5951 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5953 pdc->DrawText(str, x, y);
5955 pdc->SetFont(oldfont);
5959void MyFrame::UpdateRotationState(
double rotation) {
5961 g_bCourseUp =
false;
5963 if (fabs(rotation) > .001) {
5964 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5965 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5967 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5970 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5971 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5973 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5977 UpdateGPSCompassStatusBoxes(
true);
5981void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5983 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5985 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5991int MyFrame::GetApplicationMemoryUse() {
5997 wxWindow *fWin = wxWindow::FindFocus();
5999 wxArrayString outputArray;
6000 wxString cmd(
"ps --no-headers -o vsize ");
6001 unsigned long pid = wxGetProcessId();
6003 cmd1.Printf(
"%ld", pid);
6005 wxExecute(cmd, outputArray);
6007 if (outputArray.GetCount()) {
6008 wxString s = outputArray.Item(0);
6010 if (s.ToLong(&vtmp)) memsize = vtmp;
6013 if (fWin) fWin->SetFocus();
6019 PROCESS_MEMORY_COUNTERS pmc;
6021 unsigned long processID = wxGetProcessId();
6023 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6025 if (NULL == hProcess)
return 0;
6027 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6045 memsize = pmc.WorkingSetSize / 1024;
6048 CloseHandle(hProcess);
6055double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6056 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6059void MyFrame::SetChartUpdatePeriod() {
6062 g_ChartUpdatePeriod = 0;
6067 bool bskewdc =
false;
6068 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6071 if (!g_bopengl && !cc->GetVP().b_quilt) {
6072 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6074 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6078 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6080 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6085 cc->UpdateCanvasControlBar();
6088void MyFrame::selectChartDisplay(
int type,
int family) {
6090 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6092 if (cc) cc->selectCanvasChartDisplay(type, family);
6095 UpdateGlobalMenuItems();
6104bool MyFrame::DoChartUpdate() {
6105 bool return_val =
false;
6108 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6110 if (cc) return_val |= cc->DoCanvasUpdate();
6116void MyFrame::MouseEvent(wxMouseEvent &event) {
6118 event.GetPosition(&x, &y);
6123#include <mach/mach.h>
6124#include <mach/message.h>
6125#include <mach/kern_return.h>
6126#include <mach/task_info.h>
6128#include <malloc/malloc.h>
6135#if defined(__linux__)
6136#include "sys/types.h"
6137#include "sys/sysinfo.h"
6140void MyFrame::DoPrint(
void) {
6142 g_PrintingInProgress =
true;
6145 GetPrimaryCanvas()->GetglCanvas()->Render();
6146 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6156 printer.Initialize(wxLANDSCAPE);
6157 printer.EnablePageNumbers(
false);
6158 printer.Print(
this, &printout);
6176 g_PrintingInProgress =
false;
6179 GetPrimaryCanvas()->SetFocus();
6185 wxString message_ID =
event.GetID();
6186 wxString message_JSONText =
event.GetJSONText();
6194 if (message_ID ==
"WMM_VARIATION_BOAT") {
6202 int numErrors = reader.
Parse(message_JSONText, &root);
6203 if (numErrors > 0) {
6209 wxString decl = root[
"Decl"].
AsString();
6211 decl.ToDouble(&decl_val);
6217 if (message_ID ==
"WMM_VARIATION") {
6225 int numErrors = reader.
Parse(message_JSONText, &root);
6226 if (numErrors > 0) {
6232 wxString decl = root[
"Decl"].
AsString();
6234 decl.ToDouble(&decl_val);
6236 gQueryVar = decl_val;
6239 if (message_ID ==
"GRIB_TIMELINE") {
6242 int numErrors = r.
Parse(message_JSONText, &v);
6244 if (numErrors > 0) {
6245 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6250 wxDateTime oldTimeSource = gTimeSource;
6252 if (v[
"Day"].AsInt() == -1) {
6253 gTimeSource = wxInvalidDateTime;
6254 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6256 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6257 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6258 v[
"Second"].AsInt());
6262 if (oldTimeSource != gTimeSource) {
6264 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6266 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6271 cc->pCwin->Refresh(
false);
6277 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6280 wxString trk_id = wxEmptyString;
6282 int numErrors = reader.
Parse(message_JSONText, &root);
6283 if (numErrors > 0)
return;
6288 v[
"Track_ID"] = trk_id;
6290 wxString name = wxEmptyString;
6291 if (ptrack->m_GUID == trk_id) {
6292 name = ptrack->GetName();
6293 if (name.IsEmpty()) {
6299 name = _(
"(Unnamed Track)");
6306 v[
"TotalNodes"] = ptrack->GetnPoints();
6307 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6309 v[
"lat"] = tp->m_lat;
6310 v[
"lon"] = tp->m_lon;
6313 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6314 SendJSONMessageToAllPlugins(msg_id, v);
6320 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6321 SendJSONMessageToAllPlugins(msg_id, v);
6323 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6326 wxString guid = wxEmptyString;
6328 int numErrors = reader.
Parse(message_JSONText, &root);
6329 if (numErrors > 0) {
6338 wxString name = wxEmptyString;
6340 if ((*it)->m_GUID == guid) {
6341 name = (*it)->m_RouteNameString;
6342 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6348 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6349 itp != (*it)->pRoutePointList->end(); itp++) {
6350 w[i][
"lat"] = (*itp)->m_lat;
6351 w[i][
"lon"] = (*itp)->m_lon;
6352 w[i][
"Name"] = (*itp)->GetName();
6353 w[i][
"Description"] = (*itp)->GetDescription();
6354 w[i][
"GUID"] = (*itp)->m_GUID;
6355 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6357 auto node = (*itp)->m_HyperlinkList->begin();
6358 if (node != (*itp)->m_HyperlinkList->end()) {
6360 while (node != (*itp)->m_HyperlinkList->end()) {
6362 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6363 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6364 httpLink->DescrText;
6371 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6372 SendJSONMessageToAllPlugins(msg_id, v);
6379 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6380 SendJSONMessageToAllPlugins(msg_id, v);
6381 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6386 int numErrors = reader.
Parse(message_JSONText, &root);
6387 if (numErrors > 0)
return;
6390 wxString str = root[
"mode"].
AsString();
6391 if (str ==
"Track") route =
false;
6396 for (RouteList::iterator it =
pRouteList->begin();
6398 wxString name = (*it)->m_RouteNameString;
6399 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6401 v[i][
"error"] =
false;
6402 v[i][
"name"] = name;
6403 v[i][
"GUID"] = (*it)->m_GUID;
6404 v[i][
"active"] = (*it)->IsActive();
6409 wxString name = ptrack->GetName();
6410 if (name.IsEmpty()) {
6416 name = _(
"(Unnamed Track)");
6418 v[i][
"error"] =
false;
6419 v[i][
"name"] = name;
6420 v[i][
"GUID"] = ptrack->m_GUID;
6425 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6426 SendJSONMessageToAllPlugins(msg_id, v);
6429 v[0][
"error"] =
true;
6430 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6431 SendJSONMessageToAllPlugins(msg_id, v);
6433 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6435 v[0][
"error"] =
true;
6438 v[0][
"error"] =
false;
6439 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6440 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6441 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6442 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6443 v[0][
"active_waypoint_lat"] =
6445 v[0][
"active_waypoint_lon"] =
6449 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6450 SendJSONMessageToAllPlugins(msg_id, v);
6454void MyFrame::FilterCogSog() {
6455 if (g_bfilter_cogsog) {
6457 double cog_last =
gCog;
6460 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6461 COGFilterTable[i] = COGFilterTable[i - 1];
6462 COGFilterTable[0] = cog_last;
6465 if (!std::isnan(cog_last)) {
6467 double sum = 0., count = 0;
6468 for (
int i = 0; i < g_COGFilterSec; i++) {
6469 double adder = COGFilterTable[i];
6470 if (std::isnan(adder))
continue;
6472 if (fabs(adder - cog_last) > 180.) {
6473 if ((adder - cog_last) > 0.)
6486 else if (sum >= 360.)
6493 double sog_last =
gSog;
6496 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6497 SOGFilterTable[i] = SOGFilterTable[i - 1];
6498 SOGFilterTable[0] = sog_last;
6501 if (!std::isnan(
gSog)) {
6502 double sum = 0., count = 0;
6503 for (
int i = 0; i < g_SOGFilterSec; i++) {
6504 if (std::isnan(SOGFilterTable[i]))
continue;
6506 sum += SOGFilterTable[i];
6516void MyFrame::LoadHarmonics() {
6519 ptcmgr->LoadDataSources(TideCurrentDataSet);
6521 bool b_newdataset =
false;
6524 for (
auto a :
ptcmgr->GetDataSet()) {
6525 bool b_foundi =
false;
6526 for (
auto b : TideCurrentDataSet) {
6533 b_newdataset =
true;
6538 for (
auto a : TideCurrentDataSet) {
6539 bool b_foundi =
false;
6540 for (
auto b :
ptcmgr->GetDataSet()) {
6547 b_newdataset =
true;
6552 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6556void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6557 if (!ptarget)
return;
6560 wxDateTime mob_time = wxDateTime::Now();
6561 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6562 mob_label += _(
" on ");
6563 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6566 mob_label, wxEmptyString);
6567 pWP_MOB->SetShared(
true);
6569 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6571 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6573 pWP_MOB->SetUseSca(
false);
6581 wxString(_(
"Own ship")), wxEmptyString);
6583 pWP_MOB->SetUseSca(
false);
6590 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6606 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6607 SendJSONMessageToAllPlugins(msg_id, v);
6610 if (RouteManagerDialog::getInstanceFlag()) {
6617 RefreshAllCanvas(
false);
6619 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6620 mob_message += _(
" Time: ");
6621 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6622 mob_message += _(
" Ownship Position: ");
6623 mob_message += toSDMM(1,
gLat);
6625 mob_message += toSDMM(2,
gLon);
6626 mob_message += _(
" MOB Position: ");
6627 mob_message += toSDMM(1, ptarget->Lat);
6629 mob_message += toSDMM(2, ptarget->Lon);
6630 wxLogMessage(mob_message);
6633void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6637 OwnPoint->m_lat =
gLat;
6638 OwnPoint->m_lon =
gLon;
6640 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6645 MOB_Point->m_lat = ptarget->Lat;
6646 MOB_Point->m_lon = ptarget->Lon;
6648 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6649 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6651 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6652 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6655 RefreshAllCanvas(
false);
6658 wxDateTime mob_time = wxDateTime::Now();
6660 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6661 mob_message += _(
" Time: ");
6662 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6663 mob_message += _(
" Ownship Position: ");
6664 mob_message += toSDMM(1,
gLat);
6666 mob_message += toSDMM(2,
gLon);
6667 mob_message += _(
" MOB Position: ");
6668 mob_message += toSDMM(1, ptarget->Lat);
6670 mob_message += toSDMM(2, ptarget->Lon);
6672 wxLogMessage(mob_message);
6676void MyFrame::applySettingsString(wxString settings) {
6678 int last_UIScaleFactor = g_GUIScaleFactor;
6679 bool previous_expert = g_bUIexpert;
6680 g_last_ChartScaleFactor = g_ChartScaleFactor;
6681 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6684 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6690 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6692 if (rr & S52_CHANGED) {
6694 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6696 ->ClearCNSYLUPArray();
6697 ps52plib->GenerateStateHash();
6701 ProcessOptionsDialog(rr, pNewDirArray);
6706 bool b_newToolbar =
false;
6708 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6710 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6712 if (rr & TOOLBAR_CHANGED) {
6713 b_newToolbar =
true;
6718 if (previous_expert && !g_bUIexpert) {
6719 androidForceFullRepaint();
6723 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6727 SetGPSCompassScale();
6729 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6731 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6733 UpdateGPSCompassStatusBoxes(
true);
6736 AbstractPlatform::ShowBusySpinner();
6738 SetAllToolbarScale();
6742 AbstractPlatform::HideBusySpinner();
6744 RequestNewMasterToolbar(
true);
6751 UpdateControlBar(GetPrimaryCanvas());
6757 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6760#ifdef wxHAS_POWER_EVENTS
6761void MyFrame::OnSuspending(wxPowerEvent &event) {
6765 wxLogMessage(
"System suspend starting...");
6768void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6771 wxLogMessage(
"System is going to suspend.");
6774void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6777 wxLogMessage(
"System suspend was cancelled.");
6780int g_last_resume_ticks;
6781void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6782 wxDateTime now = wxDateTime::Now();
6783 wxLogMessage(
"System resumed from suspend.");
6785 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6788 wxLogMessage(
"Restarting streams.");
6789 g_last_resume_ticks = now.GetTicks();
6793 g_pMUX->ClearStreams();
6795 g_pMUX->StartAllStreams();
6804 if (IsMaximized()) {
6809 wxSize sz = GetSize();
6810 SetSize(wxSize(sz.x - 1, sz.y));
6822void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6823 bool btbRebuild =
false;
6825 bool b_reshow =
true;
6828 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6829 if ((ff > 0.01f) || bforcenew) {
6839 long orient = g_Platform->GetDefaultToolbarOrientation();
6840 wxWindow *toolbarParent =
this;
6842 toolbarParent = GetPrimaryCanvas();
6845 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6846 m_toolbar_callbacks);
6848 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6855 g_bmasterToolbarFull =
true;
6859 CreateMasterToolbar();
6874bool MyFrame::CollapseGlobalToolbar() {
6876 m_nMasterToolCountShown = 1;
6880 g_bmasterToolbarFull =
false;
6896 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6897 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6898 tic->m_bRequired =
true;
6903 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6904 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6908 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6909 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6910 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6915 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6916 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6920 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6921 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6922 _(
"Enable Tracking"),
"MUI_track");
6926 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6927 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6939 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6940 _(
"Print Chart"),
"MUI_print");
6944 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6945 _(
"About OpenCPN"),
"MUI_help");
6949 AddDefaultPositionPlugInTools();
6953 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6954 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6965 ArrayOfPlugInToolbarTools tool_array =
6967 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6969 if (!pttc->b_viz)
continue;
6971 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6974 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6975 if (g_bTrackActive) {
6976 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6983bool MyFrame::CheckAndAddPlugInTool() {
6991 if (!tb)
return false;
6993 int n_tools = tb->GetToolsCount();
6997 ArrayOfPlugInToolbarTools tool_array =
7000 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7002 if (pttc->position == n_tools) {
7003 wxBitmap *ptool_bmp;
7005 switch (global_color_scheme) {
7006 case GLOBAL_COLOR_SCHEME_DAY:
7007 ptool_bmp = pttc->bitmap_day;
7010 case GLOBAL_COLOR_SCHEME_DUSK:
7011 ptool_bmp = pttc->bitmap_dusk;
7013 case GLOBAL_COLOR_SCHEME_NIGHT:
7014 ptool_bmp = pttc->bitmap_night;
7017 ptool_bmp = pttc->bitmap_day;
7022 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7024 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7025 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7026 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7027 tic->m_bPlugin =
true;
7036 while (CheckAndAddPlugInTool()) {
7042bool MyFrame::AddDefaultPositionPlugInTools() {
7049 ArrayOfPlugInToolbarTools tool_array =
7052 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7056 if (!pttc->b_viz)
continue;
7058 if (pttc->position == -1)
7060 wxBitmap *ptool_bmp;
7062 switch (global_color_scheme) {
7063 case GLOBAL_COLOR_SCHEME_DAY:
7064 ptool_bmp = pttc->bitmap_day;
7066 case GLOBAL_COLOR_SCHEME_DUSK:
7067 ptool_bmp = pttc->bitmap_dusk;
7069 case GLOBAL_COLOR_SCHEME_NIGHT:
7070 ptool_bmp = pttc->bitmap_night;
7073 ptool_bmp = pttc->bitmap_day;
7078 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7080 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7081 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7082 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7083 tic->m_bPlugin =
true;
7102typedef struct _MSW_COLOR_SPEC {
7104 wxString S52_RGB_COLOR;
7108MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7109 {COLOR_MENUTEXT,
"UITX1", 0},
7110 {COLOR_BTNSHADOW,
"UIBCK", 0},
7113void SaveSystemColors() {
7127 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7128 while (pcspec->COLOR_NAME != -1) {
7129 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7134void RestoreSystemColors() {
7135 int element[NCOLORS];
7136 int rgbcolor[NCOLORS];
7139 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7140 while (pcspec->COLOR_NAME != -1) {
7141 element[i] = pcspec->COLOR_NAME;
7142 rgbcolor[i] = pcspec->SysRGB_COLOR;
7147 if (pSetSysColors) {
7148 pSetSysColors(i, (
unsigned long *)&element[0],
7149 (
unsigned long *)&rgbcolor[0]);
7155void SetSystemColors(ColorScheme cs) {
7157 int element[NCOLORS];
7158 int rgbcolor[NCOLORS];
7160 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7161 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7162 while (pcspec->COLOR_NAME != -1) {
7163 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7164 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7165 element[i] = pcspec->COLOR_NAME;
7171 pSetSysColors(i, (
unsigned long *)&element[0],
7172 (
unsigned long *)&rgbcolor[0]);
7176 RestoreSystemColors();
7183static const WORD MAX_CONSOLE_LINES =
7188void RedirectIOToConsole()
7193 wxIntPtr lStdHandle;
7195 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7205 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7206 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7207 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7211 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7212 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7213 fp = _fdopen(hConHandle,
"w");
7215 setvbuf(stdout, NULL, _IONBF, 0);
7219 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7220 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7221 fp = _fdopen(hConHandle,
"r");
7223 setvbuf(stdin, NULL, _IONBF, 0);
7227 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7228 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7229 fp = _fdopen(hConHandle,
"w");
7231 setvbuf(stderr, NULL, _IONBF, 0);
7242 FontMgr::Get().SetLocale(g_locale);
7263 if (g_pais_query_dialog_active) {
7264 g_pais_query_dialog_active->Destroy();
7265 g_pais_query_dialog_active = NULL;
7268 auto alert_dlg_active =
7270 if (alert_dlg_active) {
7271 alert_dlg_active->Destroy();
7272 g_pais_alert_dialog_active =
nullptr;
7275 if (g_pAISTargetList) {
7277 g_pAISTargetList->Disconnect_decoder();
7278 g_pAISTargetList->Destroy();
7279 g_pAISTargetList = NULL;
7283 if (gFrame->m_pMenuBar) {
7284 gFrame->SetMenuBar(NULL);
7285 gFrame->m_pMenuBar->Destroy();
7286 gFrame->m_pMenuBar = NULL;
7288 gFrame->BuildMenuBar();
7291 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7293 if (cc) cc->CanvasApplyLocale();
7298 wxString perspective;
7300 pConfig->Read(
"AUIPerspective", &perspective);
7314 bool bno_load =
false;
7315 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7317 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7318 wxAuiPaneInfo pane = pane_array_val[i];
7319 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7325 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7330 gFrame->RequestNewToolbars(
true);
7331 gFrame->RequestNewMasterToolbar(
true);
7338 : wxThread(wxTHREAD_JOINABLE) {
7339 m_filename = filename;
7350 newChart->SetNativeScale(m_scale);
7351 newChart->SetFullExtent(m_ext);
7353 newChart->FindOrCreateSenc(m_filename);
7358 wxString m_filename;
7364static double chart_dist(
int index) {
7370 if (cte.GetBBox().Contains(
gLat,
gLon))
7375 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7376 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7377 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7380 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7381 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7383 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7389WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7390static int CompareInts(
int n1,
int n2) {
7391 double d1 = chart_dist(n1);
7392 double d2 = chart_dist(n2);
7393 return (
int)(d1 - d2);
7398 wxString chart_path;
7403WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7405#include <wx/arrimpl.cpp>
7408void ParseAllENC(wxWindow *parent) {
7409 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7417 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7420 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7422 idx_sorted_by_distance.Add(i);
7426 if (count == 0)
return;
7428 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7434 ArrayOfCompressTargets ct_array;
7435 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7436 int i = idx_sorted_by_distance[j];
7439 double distance = chart_dist(i);
7441 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7444 pct->distance = distance;
7445 pct->chart_path = filename;
7447 ct_array.push_back(pct);
7450 int thread_count = 0;
7453 if (g_nCPUCount > 0)
7454 thread_count = g_nCPUCount;
7456 thread_count = wxThread::GetCPUCount();
7458 if (thread_count < 1) {
7467 for(
int t = 0; t < thread_count; t++)
7471 wxGenericProgressDialog *prog =
nullptr;
7475 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7476 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7478 prog =
new wxGenericProgressDialog();
7480 prog->SetFont(*qFont);
7482 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7483 count + 1, parent, style);
7492 prog->ShowWindowModal();
7501 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7502 wxString filename = ct_array[j].chart_path;
7503 double distance = ct_array[j].distance;
7504 int index =
ChartData->FinddbIndex(filename);
7505 if (index < 0)
continue;
7508 ext.NLAT = cte.GetLatMax();
7509 ext.SLAT = cte.GetLatMin();
7510 ext.WLON = cte.GetLonMin();
7511 ext.ELON = cte.GetLonMax();
7513 int scale = cte.GetScale();
7516 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7519 if (wxThread::IsMain()) {
7521 wxSize sz = prog->GetSize();
7526 prog->Update(count, msg, &skip);
7538 newChart->SetNativeScale(
scale);
7539 newChart->SetFullExtent(ext);
7540 newChart->DisableBackgroundSENC();
7542 newChart->FindOrCreateSenc(filename,
7546 if (wxThread::IsMain()) {
7547 msg.Printf(_(
"ENC Completed."));
7549 prog->Update(count, msg, &skip);
7559 for (
int t = 0;; t = (t + 1) % thread_count) {
7566 if (!workers[t]->IsAlive()) {
7579#if defined(__WXMSW__) || defined(__WXOSX__)
7586 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
AisInfoGui * g_pAISGUI
Global instance.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
arrayofCanvasPtr g_canvasArray
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Minimal ChartCAnvas interface with very little dependencies.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
AbstractRestServer implementation and interface to underlying IO thread.
std::string GetEndpoint() override
Return HTTPS url to local rest server.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
Device context class that can use either wxDC or OpenGL for drawing.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
CommBridge class and helpers.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
double AnchorDistFix(double const d, double const AnchorPointMinDist, double const AnchorPointMaxDist)
Return constrained value of d so that AnchorPointMinDist < abs(d) < AnchorPointMaxDist.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Miscellaneous utilities, many of which string related.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
Generic hardware events interface.
WaypointMan drawing stuff.