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::SwitchKBFocus(
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 cc->DoCanvasUpdate();
5468 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5471bool MyFrame::ProcessQuitFlag() {
5475 FrameTenHzTimer.Stop();
5477 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5478 if (top) top->Close(
true);
5485void MyFrame::ProcessDeferredTrackOn() {
5488 if (g_bDeferredStartTrack) {
5489 if (!g_bTrackActive) {
5492 g_bDeferredStartTrack =
false;
5495 g_bDeferredStartTrack =
false;
5500void MyFrame::ProcessAnchorWatch() {
5508 double d = g_nAWMax;
5511 bool toofar =
false;
5512 bool tooclose =
false;
5513 if (d >= 0.0) toofar = (dist * 1852. > d);
5514 if (d < 0.0) tooclose = (dist * 1852 < -d);
5516 if (tooclose || toofar)
5517 AnchorAlertOn1 =
true;
5519 AnchorAlertOn1 =
false;
5521 AnchorAlertOn1 =
false;
5529 double d = g_nAWMax;
5532 bool toofar =
false;
5533 bool tooclose =
false;
5534 if (d >= 0) toofar = (dist * 1852. > d);
5535 if (d < 0) tooclose = (dist * 1852 < -d);
5537 if (tooclose || toofar)
5538 AnchorAlertOn2 =
true;
5540 AnchorAlertOn2 =
false;
5542 AnchorAlertOn2 =
false;
5545 AnchorAlertOn1 =
true;
5548void MyFrame::SendFixToPlugins() {
5559 GPSData.
nSats = g_SatsInView;
5561 wxDateTime tCheck((time_t)m_fixtime);
5562 if (tCheck.IsValid()) {
5571 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5574 SendPositionFixToAllPlugIns(&GPSData);
5578void MyFrame::ProcessLogAndBells() {
5581 wxDateTime lognow = wxDateTime::Now();
5582 int hourLOC = lognow.GetHour();
5583 int minuteLOC = lognow.GetMinute();
5585 int minuteUTC = lognow.GetMinute();
5586 int second = lognow.GetSecond();
5588 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5589 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5590 (minuteUTC == 30)) {
5591 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5592 wxString day = lognow.FormatISODate();
5593 wxString utc = lognow.FormatISOTime();
5594 wxString navmsg =
"LOGBOOK: ";
5602 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5606 if (std::isnan(
gCog))
5607 cog.Printf(
"COG ----- ");
5609 cog.Printf(
"COG %10.5f ",
gCog);
5612 if (std::isnan(
gSog))
5613 sog.Printf(
"SOG ----- ");
5615 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5621 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5624 wxLogMessage(navmsg);
5625 g_loglast_time = lognow;
5627 int bells = (hourLOC % 4) * 2;
5628 if (minuteLOC != 0) bells++;
5629 if (!bells) bells = 8;
5631 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5632 m_BellsToPlay = bells;
5633 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5634 wxPostEvent(
this, ev);
5641 CheckToolbarPosition();
5645 if (ProcessQuitFlag())
return;
5647 if (bDBUpdateInProgress)
return;
5650 FrameTenHzTimer.Stop();
5652 ProcessDeferredTrackOn();
5654 ProcessAnchorWatch();
5655 ProcessLogAndBells();
5657 if (ShouldRestartTrack()) TrackDailyRestart();
5660 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5661 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5662 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5668 if (
gSog > 3.0) g_bCruising =
true;
5674 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5676 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5682 bool bnew_view =
false;
5683 if (!g_btenhertz) bnew_view = DoChartUpdate();
5690 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5693 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5696 cc->DrawBlinkObjects();
5699 if (bactiveRouteUpdate) {
5706 cc->SetOwnShipState(SHIP_NORMAL);
5708 if (cc->GetQuiltMode()) {
5709 double erf = cc->GetQuiltMaxErrorFactor();
5710 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5712 if (cc->m_singleChart) {
5713 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5714 cc->SetOwnShipState(SHIP_LOWACCURACY);
5718 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5721 (bVelocityValid != m_last_bVelocityValid) ||
5722 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5723 if (!g_bopengl) cc->UpdateShips();
5731 m_last_bVelocityValid = bVelocityValid;
5736 bool brq_dynamic =
false;
5738 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5739 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5741 if (pic->m_enabled && pic->m_init_state) {
5742 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5749 if (brq_dynamic) bnew_view =
true;
5753 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5756 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5761 if (cc->GetglCanvas()) {
5763 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5766 if (cc->m_bFollow) {
5767 cc->DoCanvasUpdate();
5784 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5798 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5799 g_pais_query_dialog_active->UpdateText();
5802 if (g_pAISTargetList && (0 == (g_tick % (5))))
5803 g_pAISTargetList->UpdateAISTargetList();
5806 UpdateGPSCompassStatusBoxes();
5811 console->RefreshConsoleData();
5818 if (m_bdefer_resize) {
5819 if (0 == (g_tick % (5))) {
5820 printf(
"___RESIZE\n");
5821 SetSize(m_defer_size);
5823 m_bdefer_resize =
false;
5830 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5832 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5833 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5837double MyFrame::GetMag(
double a,
double lat,
double lon) {
5838 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5839 auto loader = PluginLoader::GetInstance();
5840 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5847 wxDateTime now = wxDateTime::Now();
5848 SendJSON_WMM_Var_Request(lat, lon, now);
5849 if (fabs(gQueryVar) < 360.0)
5850 Variance = gQueryVar;
5852 return toMagnetic(a, Variance);
5855bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5861 v[
"Year"] = date.GetYear();
5862 v[
"Month"] = date.GetMonth();
5863 v[
"Day"] = date.GetDay();
5865 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5871void MyFrame::TouchAISActive() {
5873 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5875 if (cc) cc->TouchAISToolActive();
5879void MyFrame::UpdateAISTool() {
5883 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5885 if (cc) cc->UpdateAISTBTool();
5890void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5892 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5894 if (cc) cc->SetbTCUpdate(
true);
5897 RefreshAllCanvas(
false);
5902void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5906 bool b_rotate =
false;
5907 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5909 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5913 FrameCOGTimer.Stop();
5920 int period_ms = 100;
5922 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5925void MyFrame::DoCOGSet() {
5927 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5929 if (cc) cc->DoCanvasCOGSet();
5933void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5939 wxFont oldfont = pdc->GetFont();
5941 pdc->SetFont(*pFont);
5942 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5943 pdc->SetBackgroundMode(wxTRANSPARENT);
5945 pdc->DrawText(str, x, y + 1);
5946 pdc->DrawText(str, x, y - 1);
5947 pdc->DrawText(str, x + 1, y);
5948 pdc->DrawText(str, x - 1, y);
5950 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5952 pdc->DrawText(str, x, y);
5954 pdc->SetFont(oldfont);
5958void MyFrame::UpdateRotationState(
double rotation) {
5960 g_bCourseUp =
false;
5962 if (fabs(rotation) > .001) {
5963 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5964 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5966 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5969 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5970 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5972 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5976 UpdateGPSCompassStatusBoxes(
true);
5980void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5982 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5984 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5990int MyFrame::GetApplicationMemoryUse() {
5996 wxWindow *fWin = wxWindow::FindFocus();
5998 wxArrayString outputArray;
5999 wxString cmd(
"ps --no-headers -o vsize ");
6000 unsigned long pid = wxGetProcessId();
6002 cmd1.Printf(
"%ld", pid);
6004 wxExecute(cmd, outputArray);
6006 if (outputArray.GetCount()) {
6007 wxString s = outputArray.Item(0);
6009 if (s.ToLong(&vtmp)) memsize = vtmp;
6012 if (fWin) fWin->SetFocus();
6018 PROCESS_MEMORY_COUNTERS pmc;
6020 unsigned long processID = wxGetProcessId();
6022 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6024 if (NULL == hProcess)
return 0;
6026 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6044 memsize = pmc.WorkingSetSize / 1024;
6047 CloseHandle(hProcess);
6054double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6055 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6058void MyFrame::SetChartUpdatePeriod() {
6061 g_ChartUpdatePeriod = 0;
6066 bool bskewdc =
false;
6067 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6070 if (!g_bopengl && !cc->GetVP().b_quilt) {
6071 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6073 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6077 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6079 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6084 cc->UpdateCanvasControlBar();
6087void MyFrame::selectChartDisplay(
int type,
int family) {
6089 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6091 if (cc) cc->selectCanvasChartDisplay(type, family);
6094 UpdateGlobalMenuItems();
6103bool MyFrame::DoChartUpdate() {
6104 bool return_val =
false;
6107 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6109 if (cc) return_val |= cc->DoCanvasUpdate();
6115void MyFrame::MouseEvent(wxMouseEvent &event) {
6117 event.GetPosition(&x, &y);
6122#include <mach/mach.h>
6123#include <mach/message.h>
6124#include <mach/kern_return.h>
6125#include <mach/task_info.h>
6127#include <malloc/malloc.h>
6134#if defined(__linux__)
6135#include "sys/types.h"
6136#include "sys/sysinfo.h"
6139void MyFrame::DoPrint(
void) {
6141 g_PrintingInProgress =
true;
6144 GetPrimaryCanvas()->GetglCanvas()->Render();
6145 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6155 printer.Initialize(wxLANDSCAPE);
6156 printer.EnablePageNumbers(
false);
6157 printer.Print(
this, &printout);
6175 g_PrintingInProgress =
false;
6178 GetPrimaryCanvas()->SetFocus();
6184 wxString message_ID =
event.GetID();
6185 wxString message_JSONText =
event.GetJSONText();
6193 if (message_ID ==
"WMM_VARIATION_BOAT") {
6201 int numErrors = reader.
Parse(message_JSONText, &root);
6202 if (numErrors > 0) {
6208 wxString decl = root[
"Decl"].
AsString();
6210 decl.ToDouble(&decl_val);
6216 if (message_ID ==
"WMM_VARIATION") {
6224 int numErrors = reader.
Parse(message_JSONText, &root);
6225 if (numErrors > 0) {
6231 wxString decl = root[
"Decl"].
AsString();
6233 decl.ToDouble(&decl_val);
6235 gQueryVar = decl_val;
6238 if (message_ID ==
"GRIB_TIMELINE") {
6241 int numErrors = r.
Parse(message_JSONText, &v);
6243 if (numErrors > 0) {
6244 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6249 wxDateTime oldTimeSource = gTimeSource;
6251 if (v[
"Day"].AsInt() == -1) {
6252 gTimeSource = wxInvalidDateTime;
6253 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6255 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6256 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6257 v[
"Second"].AsInt());
6261 if (oldTimeSource != gTimeSource) {
6263 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6265 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6270 cc->pCwin->Refresh(
false);
6276 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6279 wxString trk_id = wxEmptyString;
6281 int numErrors = reader.
Parse(message_JSONText, &root);
6282 if (numErrors > 0)
return;
6287 v[
"Track_ID"] = trk_id;
6289 wxString name = wxEmptyString;
6290 if (ptrack->m_GUID == trk_id) {
6291 name = ptrack->GetName();
6292 if (name.IsEmpty()) {
6298 name = _(
"(Unnamed Track)");
6305 v[
"TotalNodes"] = ptrack->GetnPoints();
6306 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6308 v[
"lat"] = tp->m_lat;
6309 v[
"lon"] = tp->m_lon;
6312 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6313 SendJSONMessageToAllPlugins(msg_id, v);
6319 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6320 SendJSONMessageToAllPlugins(msg_id, v);
6322 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6325 wxString guid = wxEmptyString;
6327 int numErrors = reader.
Parse(message_JSONText, &root);
6328 if (numErrors > 0) {
6337 wxString name = wxEmptyString;
6339 if ((*it)->m_GUID == guid) {
6340 name = (*it)->m_RouteNameString;
6341 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6347 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6348 itp != (*it)->pRoutePointList->end(); itp++) {
6349 w[i][
"lat"] = (*itp)->m_lat;
6350 w[i][
"lon"] = (*itp)->m_lon;
6351 w[i][
"Name"] = (*itp)->GetName();
6352 w[i][
"Description"] = (*itp)->GetDescription();
6353 w[i][
"GUID"] = (*itp)->m_GUID;
6354 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6356 auto node = (*itp)->m_HyperlinkList->begin();
6357 if (node != (*itp)->m_HyperlinkList->end()) {
6359 while (node != (*itp)->m_HyperlinkList->end()) {
6361 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6362 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6363 httpLink->DescrText;
6370 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6371 SendJSONMessageToAllPlugins(msg_id, v);
6378 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6379 SendJSONMessageToAllPlugins(msg_id, v);
6380 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6385 int numErrors = reader.
Parse(message_JSONText, &root);
6386 if (numErrors > 0)
return;
6389 wxString str = root[
"mode"].
AsString();
6390 if (str ==
"Track") route =
false;
6395 for (RouteList::iterator it =
pRouteList->begin();
6397 wxString name = (*it)->m_RouteNameString;
6398 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6400 v[i][
"error"] =
false;
6401 v[i][
"name"] = name;
6402 v[i][
"GUID"] = (*it)->m_GUID;
6403 v[i][
"active"] = (*it)->IsActive();
6408 wxString name = ptrack->GetName();
6409 if (name.IsEmpty()) {
6415 name = _(
"(Unnamed Track)");
6417 v[i][
"error"] =
false;
6418 v[i][
"name"] = name;
6419 v[i][
"GUID"] = ptrack->m_GUID;
6424 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6425 SendJSONMessageToAllPlugins(msg_id, v);
6428 v[0][
"error"] =
true;
6429 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6430 SendJSONMessageToAllPlugins(msg_id, v);
6432 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6434 v[0][
"error"] =
true;
6437 v[0][
"error"] =
false;
6438 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6439 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6440 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6441 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6442 v[0][
"active_waypoint_lat"] =
6444 v[0][
"active_waypoint_lon"] =
6448 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6449 SendJSONMessageToAllPlugins(msg_id, v);
6453void MyFrame::FilterCogSog() {
6454 if (g_bfilter_cogsog) {
6456 double cog_last =
gCog;
6459 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6460 COGFilterTable[i] = COGFilterTable[i - 1];
6461 COGFilterTable[0] = cog_last;
6464 if (!std::isnan(cog_last)) {
6466 double sum = 0., count = 0;
6467 for (
int i = 0; i < g_COGFilterSec; i++) {
6468 double adder = COGFilterTable[i];
6469 if (std::isnan(adder))
continue;
6471 if (fabs(adder - cog_last) > 180.) {
6472 if ((adder - cog_last) > 0.)
6485 else if (sum >= 360.)
6492 double sog_last =
gSog;
6495 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6496 SOGFilterTable[i] = SOGFilterTable[i - 1];
6497 SOGFilterTable[0] = sog_last;
6500 if (!std::isnan(
gSog)) {
6501 double sum = 0., count = 0;
6502 for (
int i = 0; i < g_SOGFilterSec; i++) {
6503 if (std::isnan(SOGFilterTable[i]))
continue;
6505 sum += SOGFilterTable[i];
6515void MyFrame::LoadHarmonics() {
6518 ptcmgr->LoadDataSources(TideCurrentDataSet);
6520 bool b_newdataset =
false;
6523 for (
auto a :
ptcmgr->GetDataSet()) {
6524 bool b_foundi =
false;
6525 for (
auto b : TideCurrentDataSet) {
6532 b_newdataset =
true;
6537 for (
auto a : TideCurrentDataSet) {
6538 bool b_foundi =
false;
6539 for (
auto b :
ptcmgr->GetDataSet()) {
6546 b_newdataset =
true;
6551 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6555void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6556 if (!ptarget)
return;
6559 wxDateTime mob_time = wxDateTime::Now();
6560 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6561 mob_label += _(
" on ");
6562 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6565 mob_label, wxEmptyString);
6566 pWP_MOB->SetShared(
true);
6568 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6570 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6572 pWP_MOB->SetUseSca(
false);
6580 wxString(_(
"Own ship")), wxEmptyString);
6582 pWP_MOB->SetUseSca(
false);
6589 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6605 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6606 SendJSONMessageToAllPlugins(msg_id, v);
6609 if (RouteManagerDialog::getInstanceFlag()) {
6616 RefreshAllCanvas(
false);
6618 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6619 mob_message += _(
" Time: ");
6620 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6621 mob_message += _(
" Ownship Position: ");
6622 mob_message += toSDMM(1,
gLat);
6624 mob_message += toSDMM(2,
gLon);
6625 mob_message += _(
" MOB Position: ");
6626 mob_message += toSDMM(1, ptarget->Lat);
6628 mob_message += toSDMM(2, ptarget->Lon);
6629 wxLogMessage(mob_message);
6632void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6636 OwnPoint->m_lat =
gLat;
6637 OwnPoint->m_lon =
gLon;
6639 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6644 MOB_Point->m_lat = ptarget->Lat;
6645 MOB_Point->m_lon = ptarget->Lon;
6647 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6648 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6650 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6651 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6654 RefreshAllCanvas(
false);
6657 wxDateTime mob_time = wxDateTime::Now();
6659 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6660 mob_message += _(
" Time: ");
6661 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6662 mob_message += _(
" Ownship Position: ");
6663 mob_message += toSDMM(1,
gLat);
6665 mob_message += toSDMM(2,
gLon);
6666 mob_message += _(
" MOB Position: ");
6667 mob_message += toSDMM(1, ptarget->Lat);
6669 mob_message += toSDMM(2, ptarget->Lon);
6671 wxLogMessage(mob_message);
6675void MyFrame::applySettingsString(wxString settings) {
6677 int last_UIScaleFactor = g_GUIScaleFactor;
6678 bool previous_expert = g_bUIexpert;
6679 g_last_ChartScaleFactor = g_ChartScaleFactor;
6680 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6683 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6689 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6691 if (rr & S52_CHANGED) {
6693 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6695 ->ClearCNSYLUPArray();
6696 ps52plib->GenerateStateHash();
6700 ProcessOptionsDialog(rr, pNewDirArray);
6705 bool b_newToolbar =
false;
6707 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6709 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6711 if (rr & TOOLBAR_CHANGED) {
6712 b_newToolbar =
true;
6717 if (previous_expert && !g_bUIexpert) {
6718 androidForceFullRepaint();
6722 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6726 SetGPSCompassScale();
6728 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6730 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6732 UpdateGPSCompassStatusBoxes(
true);
6735 AbstractPlatform::ShowBusySpinner();
6737 SetAllToolbarScale();
6741 AbstractPlatform::HideBusySpinner();
6743 RequestNewMasterToolbar(
true);
6750 UpdateControlBar(GetPrimaryCanvas());
6756 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6759#ifdef wxHAS_POWER_EVENTS
6760void MyFrame::OnSuspending(wxPowerEvent &event) {
6764 wxLogMessage(
"System suspend starting...");
6767void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6770 wxLogMessage(
"System is going to suspend.");
6773void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6776 wxLogMessage(
"System suspend was cancelled.");
6779int g_last_resume_ticks;
6780void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6781 wxDateTime now = wxDateTime::Now();
6782 wxLogMessage(
"System resumed from suspend.");
6784 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6787 wxLogMessage(
"Restarting streams.");
6788 g_last_resume_ticks = now.GetTicks();
6792 g_pMUX->ClearStreams();
6794 g_pMUX->StartAllStreams();
6803 if (IsMaximized()) {
6808 wxSize sz = GetSize();
6809 SetSize(wxSize(sz.x - 1, sz.y));
6821void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6822 bool btbRebuild =
false;
6824 bool b_reshow =
true;
6827 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6828 if ((ff > 0.01f) || bforcenew) {
6838 long orient = g_Platform->GetDefaultToolbarOrientation();
6839 wxWindow *toolbarParent =
this;
6841 toolbarParent = GetPrimaryCanvas();
6844 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6845 m_toolbar_callbacks);
6847 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6854 g_bmasterToolbarFull =
true;
6858 CreateMasterToolbar();
6873bool MyFrame::CollapseGlobalToolbar() {
6875 m_nMasterToolCountShown = 1;
6879 g_bmasterToolbarFull =
false;
6895 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6896 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6897 tic->m_bRequired =
true;
6902 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6903 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6907 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6908 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6909 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6914 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6915 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6919 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6920 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6921 _(
"Enable Tracking"),
"MUI_track");
6925 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6926 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6938 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6939 _(
"Print Chart"),
"MUI_print");
6943 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6944 _(
"About OpenCPN"),
"MUI_help");
6948 AddDefaultPositionPlugInTools();
6952 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6953 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6964 ArrayOfPlugInToolbarTools tool_array =
6966 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6968 if (!pttc->b_viz)
continue;
6970 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6973 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6974 if (g_bTrackActive) {
6975 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6982bool MyFrame::CheckAndAddPlugInTool() {
6990 if (!tb)
return false;
6992 int n_tools = tb->GetToolsCount();
6996 ArrayOfPlugInToolbarTools tool_array =
6999 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7001 if (pttc->position == n_tools) {
7002 wxBitmap *ptool_bmp;
7004 switch (global_color_scheme) {
7005 case GLOBAL_COLOR_SCHEME_DAY:
7006 ptool_bmp = pttc->bitmap_day;
7009 case GLOBAL_COLOR_SCHEME_DUSK:
7010 ptool_bmp = pttc->bitmap_dusk;
7012 case GLOBAL_COLOR_SCHEME_NIGHT:
7013 ptool_bmp = pttc->bitmap_night;
7016 ptool_bmp = pttc->bitmap_day;
7021 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7023 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7024 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7025 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7026 tic->m_bPlugin =
true;
7035 while (CheckAndAddPlugInTool()) {
7041bool MyFrame::AddDefaultPositionPlugInTools() {
7048 ArrayOfPlugInToolbarTools tool_array =
7051 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7055 if (!pttc->b_viz)
continue;
7057 if (pttc->position == -1)
7059 wxBitmap *ptool_bmp;
7061 switch (global_color_scheme) {
7062 case GLOBAL_COLOR_SCHEME_DAY:
7063 ptool_bmp = pttc->bitmap_day;
7065 case GLOBAL_COLOR_SCHEME_DUSK:
7066 ptool_bmp = pttc->bitmap_dusk;
7068 case GLOBAL_COLOR_SCHEME_NIGHT:
7069 ptool_bmp = pttc->bitmap_night;
7072 ptool_bmp = pttc->bitmap_day;
7077 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7079 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7080 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7081 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7082 tic->m_bPlugin =
true;
7101typedef struct _MSW_COLOR_SPEC {
7103 wxString S52_RGB_COLOR;
7107MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7108 {COLOR_MENUTEXT,
"UITX1", 0},
7109 {COLOR_BTNSHADOW,
"UIBCK", 0},
7112void SaveSystemColors() {
7126 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7127 while (pcspec->COLOR_NAME != -1) {
7128 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7133void RestoreSystemColors() {
7134 int element[NCOLORS];
7135 int rgbcolor[NCOLORS];
7138 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7139 while (pcspec->COLOR_NAME != -1) {
7140 element[i] = pcspec->COLOR_NAME;
7141 rgbcolor[i] = pcspec->SysRGB_COLOR;
7146 if (pSetSysColors) {
7147 pSetSysColors(i, (
unsigned long *)&element[0],
7148 (
unsigned long *)&rgbcolor[0]);
7154void SetSystemColors(ColorScheme cs) {
7156 int element[NCOLORS];
7157 int rgbcolor[NCOLORS];
7159 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7160 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7161 while (pcspec->COLOR_NAME != -1) {
7162 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7163 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7164 element[i] = pcspec->COLOR_NAME;
7170 pSetSysColors(i, (
unsigned long *)&element[0],
7171 (
unsigned long *)&rgbcolor[0]);
7175 RestoreSystemColors();
7182static const WORD MAX_CONSOLE_LINES =
7187void RedirectIOToConsole()
7192 wxIntPtr lStdHandle;
7194 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7204 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7205 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7206 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7210 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7211 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7212 fp = _fdopen(hConHandle,
"w");
7214 setvbuf(stdout, NULL, _IONBF, 0);
7218 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7219 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7220 fp = _fdopen(hConHandle,
"r");
7222 setvbuf(stdin, NULL, _IONBF, 0);
7226 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7227 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7228 fp = _fdopen(hConHandle,
"w");
7230 setvbuf(stderr, NULL, _IONBF, 0);
7241 FontMgr::Get().SetLocale(g_locale);
7262 if (g_pais_query_dialog_active) {
7263 g_pais_query_dialog_active->Destroy();
7264 g_pais_query_dialog_active = NULL;
7267 auto alert_dlg_active =
7269 if (alert_dlg_active) {
7270 alert_dlg_active->Destroy();
7271 g_pais_alert_dialog_active =
nullptr;
7274 if (g_pAISTargetList) {
7276 g_pAISTargetList->Disconnect_decoder();
7277 g_pAISTargetList->Destroy();
7278 g_pAISTargetList = NULL;
7282 if (gFrame->m_pMenuBar) {
7283 gFrame->SetMenuBar(NULL);
7284 gFrame->m_pMenuBar->Destroy();
7285 gFrame->m_pMenuBar = NULL;
7287 gFrame->BuildMenuBar();
7290 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7292 if (cc) cc->CanvasApplyLocale();
7297 wxString perspective;
7299 pConfig->Read(
"AUIPerspective", &perspective);
7313 bool bno_load =
false;
7314 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7316 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7317 wxAuiPaneInfo pane = pane_array_val[i];
7318 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7324 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7329 gFrame->RequestNewToolbars(
true);
7330 gFrame->RequestNewMasterToolbar(
true);
7337 : wxThread(wxTHREAD_JOINABLE) {
7338 m_filename = filename;
7349 newChart->SetNativeScale(m_scale);
7350 newChart->SetFullExtent(m_ext);
7352 newChart->FindOrCreateSenc(m_filename);
7357 wxString m_filename;
7363static double chart_dist(
int index) {
7369 if (cte.GetBBox().Contains(
gLat,
gLon))
7374 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7375 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7376 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7379 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7380 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7382 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7388WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7389static int CompareInts(
int n1,
int n2) {
7390 double d1 = chart_dist(n1);
7391 double d2 = chart_dist(n2);
7392 return (
int)(d1 - d2);
7397 wxString chart_path;
7402WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7404#include <wx/arrimpl.cpp>
7407void ParseAllENC(wxWindow *parent) {
7408 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7416 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7419 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7421 idx_sorted_by_distance.Add(i);
7425 if (count == 0)
return;
7427 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7433 ArrayOfCompressTargets ct_array;
7434 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7435 int i = idx_sorted_by_distance[j];
7438 double distance = chart_dist(i);
7440 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7443 pct->distance = distance;
7444 pct->chart_path = filename;
7446 ct_array.push_back(pct);
7449 int thread_count = 0;
7452 if (g_nCPUCount > 0)
7453 thread_count = g_nCPUCount;
7455 thread_count = wxThread::GetCPUCount();
7457 if (thread_count < 1) {
7466 for(
int t = 0; t < thread_count; t++)
7470 wxGenericProgressDialog *prog =
nullptr;
7474 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7475 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7477 prog =
new wxGenericProgressDialog();
7479 prog->SetFont(*qFont);
7481 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7482 count + 1, parent, style);
7491 prog->ShowWindowModal();
7500 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7501 wxString filename = ct_array[j].chart_path;
7502 double distance = ct_array[j].distance;
7503 int index =
ChartData->FinddbIndex(filename);
7504 if (index < 0)
continue;
7507 ext.NLAT = cte.GetLatMax();
7508 ext.SLAT = cte.GetLatMin();
7509 ext.WLON = cte.GetLonMin();
7510 ext.ELON = cte.GetLonMax();
7512 int scale = cte.GetScale();
7515 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7518 if (wxThread::IsMain()) {
7520 wxSize sz = prog->GetSize();
7525 prog->Update(count, msg, &skip);
7537 newChart->SetNativeScale(
scale);
7538 newChart->SetFullExtent(ext);
7539 newChart->DisableBackgroundSENC();
7541 newChart->FindOrCreateSenc(filename,
7545 if (wxThread::IsMain()) {
7546 msg.Printf(_(
"ENC Completed."));
7548 prog->Update(count, msg, &skip);
7558 for (
int t = 0;; t = (t + 1) % thread_count) {
7565 if (!workers[t]->IsAlive()) {
7578#if defined(__WXMSW__) || defined(__WXOSX__)
7585 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.