56#include <wx/stdpaths.h>
57#include <wx/tokenzr.h>
58#include <wx/display.h>
59#include <wx/jsonreader.h>
61#include "o_sound/o_sound.h"
86#include "model/nav_object_database.h"
100#include "ais_info_gui.h"
101#include "dialog_alert.h"
105#include "ais_info_gui.h"
129#include "load_errors_dlg.h"
132#include "N2KParser.h"
155#include "user_colors.h"
161#include "androidUTIL.h"
165static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
176GLenum g_texture_rectangle_format;
179#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
180extern wxLocale *plocale_def_lang;
184extern bool g_b_EnableVBO;
185extern GLenum g_texture_rectangle_format;
189static int g_last_ChartScaleFactor;
190static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
191static int options_subpage = 0;
192static bool b_reloadForPlugins;
194static wxSize options_lastWindowSize(0, 0);
195static wxPoint options_lastWindowPos(0, 0);
199static double gQueryVar = 361.0;
201static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
202static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
204static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
210typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
211typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
213static SetSysColors_t pSetSysColors;
214static GetSysColor_t pGetSysColor;
216void SaveSystemColors();
217void RestoreSystemColors();
222DWORD color_3ddkshadow;
224DWORD color_activecaption;
225DWORD color_gradientactivecaption;
226DWORD color_captiontext;
227DWORD color_windowframe;
228DWORD color_inactiveborder;
233#include <wx/msw/msvcrt.h>
237static const long long lNaN = 0xfff8000000000000;
238#define NAN (*(double *)&lNaN)
242static double gLat_gt, gLon_gt;
243static double gLat_gt_m1, gLon_gt_m1;
244static uint64_t fix_time_gt;
245static uint64_t fix_time_gt_last;
247static double gSog_gt, gHdt_gt;
248static double gCog_gt_m1, gHdt_gt_m1;
249static uint64_t hdt_time_gt;
250static double cog_rate_gt, hdt_rate_gt;
252void InitializeUserColors();
253void DeInitializeUserColors();
254void SetSystemColors(ColorScheme cs);
256static bool LoadAllPlugIns(
bool load_enabled) {
257 AbstractPlatform::ShowBusySpinner();
258 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
259 AbstractPlatform::HideBusySpinner();
263static void LaunchLocalHelp() {
265 androidLaunchHelpView();
267 wxString def_lang_canonical =
"en_US";
270 if (plocale_def_lang)
271 def_lang_canonical = plocale_def_lang->GetCanonicalName();
274 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
276 wxString help_try = help_locn + def_lang_canonical +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"en_US" +
".html";
281 if (!::wxFileExists(help_try)) {
282 help_try = help_locn +
"web" +
".html";
285 if (!::wxFileExists(help_try))
return;
288 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
293static wxString _menuText(wxString name, wxString shortcut) {
297 menutext <<
"\t" << shortcut;
302static void DoHelpDialog() {
314 [] { LaunchLocalHelp(); });
326#if defined(__WXGTK__) || defined(__WXQT__)
327#include "bitmaps/opencpn.xpm"
342 if (g_bInlandEcdis) {
346 wxPoint tbp_incanvas =
349 g_iENCToolbarPosY = tbp_incanvas.y;
350 g_iENCToolbarPosX = tbp_incanvas.x;
358 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
362 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
365 g_iENCToolbarPosY = -1;
368 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
374 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
378 double tool_scale_factor =
379 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
381 tool_scale_factor, callbacks);
391#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
394static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
395 const char *prop_name) {
399 unsigned long ret_nitems;
400 unsigned long ret_bytes_after;
401 unsigned char *ret_prop;
403 xa_prop_name = XInternAtom(disp, prop_name, False);
411 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
412 &xa_ret_type, &ret_format, &ret_nitems,
413 &ret_bytes_after, &ret_prop) != Success)
416 if (xa_ret_type != xa_prop_type) {
420 return (
char *)ret_prop;
425static bool isTransparentToolbarInOpenGLOK() {
432 if (!g_bdisable_opengl) {
433 Display *disp = XOpenDisplay(NULL);
435 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_NET_SUPPORTING_WM_CHECK")) ||
438 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
440 "_WIN_SUPPORTING_WM_CHECK"))) {
443 if ((wm_name = get_X11_property(disp, *sup_window,
444 XInternAtom(disp,
"UTF8_STRING", False),
446 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
449 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
464wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
466 font->GetFamily(), font->GetStyle(),
467 font->GetWeight(),
false, font->GetFaceName());
469wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
470 wxFontStyle style, wxFontWeight weight,
471 const wxString faceName,
double scale) {
475wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
476 return GetOCPNScaledFont_PlugIn(label, Ptsize);
485wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
487BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
488EVT_CLOSE(MyFrame::OnCloseWindow)
489EVT_MENU(wxID_EXIT, MyFrame::OnExit)
490EVT_SIZE(MyFrame::OnSize)
491EVT_MOVE(MyFrame::OnMove)
492EVT_ICONIZE(MyFrame::OnIconize)
493EVT_MENU(-1, MyFrame::OnToolLeftClick)
494EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
496EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
497EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
498EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
500EVT_MAXIMIZE(MyFrame::OnMaximize)
501EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
502 MyFrame::RequestNewToolbarArgEvent)
503EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
505EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
506EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
507EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
509#ifdef wxHAS_POWER_EVENTS
510EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
511EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
512EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
513EVT_POWER_RESUME(MyFrame::OnResume)
524static
void onBellsFinishedCB(
void *ptr) {
525 auto framePtr =
static_cast<MyFrame *
>(ptr);
527 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
528 wxPostEvent(framePtr, ev);
533 auto msg = ev.GetString().ToStdString();
534 auto ¬eman = NotificationManager::GetInstance();
535 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
538static NmeaLog *GetDataMonitor() {
539 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
540 return dynamic_cast<NmeaLog *
>(w);
543MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
544 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
545 OpenFileFunc open_gpx_file)
547 m_connections_dlg(nullptr),
549 m_pauidockart(pauidockart),
550 m_rest_server(rest_server),
551 m_open_gpx_file(open_gpx_file) {
563 m_ulLastNMEATicktime = 0;
564 m_data_monitor->Hide();
566 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
570 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
573 InitTimer.SetOwner(
this, INIT_TIMER);
575 m_initializing =
false;
576 m_toolbar_callbacks.render_gl_textures =
578 [&](
ocpnDC &dc,
float *coords,
float *uv) {
579 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
580 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
583 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
587 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
590 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
593 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
596 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
599 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
601 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
610 m_bTimeIsSet =
false;
611 m_bdefer_resize =
false;
614 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
615 COGFilterTable[i] = NAN;
616 SOGFilterTable[i] = NAN;
618 m_last_bGPSValid =
false;
619 m_last_bVelocityValid =
false;
629 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
634 double process_noise_std = 1.0;
635 double measurement_noise_std = 0.5;
639 m_ChartUpdatePeriod = 1;
644 log_callbacks.log_is_active = [&]() {
645 auto log = GetDataMonitor();
646 return log && log->IsVisible();
648 log_callbacks.log_message = [&](
Logline ll) {
649 NmeaLog *monitor = GetDataMonitor();
652 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
655 ais_callbacks.confirm_stop_track = []() {
656 int r = OCPNMessageBox(
658 _(
"This AIS target has Persistent tracking selected by MMSI "
660 "A Persistent track recording will therefore be restarted for this "
662 "Do you instead want to stop Persistent tracking for this target?"),
663 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
664 return r == wxID_YES;
666 ais_callbacks.get_target_mmsi = []() {
667 auto alert_dlg_active =
669 assert(alert_dlg_active);
670 return alert_dlg_active->Get_Dialog_MMSI();
678 wxLogMessage(
" **** Connect stuff");
684 Connect(wxEVT_OCPN_MSG,
685 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
693 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
701#if defined(__WXGTK__) || defined(__WXQT__)
702 wxIcon app_icon(opencpn);
710 wxDynamicLibrary dllUser32(
"user32.dll");
712 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
713 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
718 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
723 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
724 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
726 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
727 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
728 [&](wxCommandEvent) { Refresh(); });
729 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
731 m_update_statusbar_listener.Init(
732 GuiEvents::GetInstance().gframe_update_status_bar,
734 m_center_aistarget_listener.Init(
735 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
736 auto ais_target = obs::UnpackEvtPointer<AisTargetData>(ev);
737 CenterAisTarget(ais_target);
739 m_reload_charts_listener.Init(
740 GuiEvents::GetInstance().on_finalize_chartdbs,
741 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
745 EnableFullScreenView();
747 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
753 FrameTenHzTimer.Stop();
768 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
774void MyFrame::FreezeCharts() {
777 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
779 if (cc && !cc->IsFrozen()) cc->Freeze();
783void MyFrame::CenterAisTarget(
784 const std::shared_ptr<const AisTargetData> &ais_target) {
792 double factor = cc->GetScaleValue() / 5000.0;
793 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
799void MyFrame::ThawCharts() {
802 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
804 if (cc && cc->IsFrozen()) cc->Thaw();
811 switch (event.type) {
812 case SENC_BUILD_STARTED:
815 case SENC_BUILD_DONE_NOERROR:
817 chart =
event.m_ticket->m_chart;
819 chart->PostInit(FULL_INIT, global_color_scheme);
821 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
823 if (cc) cc->ClearS52PLIBStateHash();
830 delete event.m_ticket;
832 case SENC_BUILD_DONE_ERROR:
833 wxLogDebug(
"SENC build done: SENC_BUILD_DONE_ERROR");
836 delete event.m_ticket;
843void MyFrame::StartRebuildChartDatabase() {
844 bool b_SetInitialPoint =
false;
847 ArrayOfCDI ChartDirArray;
848 pConfig->LoadChartDirArray(ChartDirArray);
850 if (ChartDirArray.GetCount()) {
855 _(
"OpenCPN needs to update the chart database from config file "
859 wxICON_INFORMATION | wxOK);
867 _(
"Rebuilding chart database from configuration file entries..."));
871 wxString dummy1 = _(
"Elapsed time : ");
872 wxString dummy2 = _(
"Estimated time : ");
873 wxString dummy3 = _(
"Remaining time : ");
874 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
875 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
883void MyFrame::OnBellsFinished(wxCommandEvent &event) {
884 int bells = wxMin(m_BellsToPlay, 2);
885 if (bells <= 0)
return;
887 wxString soundfile =
"sounds";
888 appendOSDirSlash(&soundfile);
889 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
890 soundfile.Prepend(g_Platform->GetSharedDataDir());
891 wxLogMessage(
"Using bells sound file: " + soundfile);
893 o_sound::Sound *sound = bells_sound[bells - 1];
894 sound->SetFinishedCallback(onBellsFinishedCB,
this);
895 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
896 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
897 sound->Load(soundfile);
898 if (!sound->IsOk()) {
899 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
903 m_BellsToPlay -= bells;
906void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
908void MyFrame::OnMaximize(wxMaximizeEvent &event) {
915void MyFrame::ReloadAllVP() {
916 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
918 if (cc) cc->ReloadVP();
922void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
923 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
926 global_color_scheme = cs;
929 case GLOBAL_COLOR_SCHEME_DAY:
932 case GLOBAL_COLOR_SCHEME_DUSK:
935 case GLOBAL_COLOR_SCHEME_NIGHT:
936 SchemeName =
"NIGHT";
943 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
945 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
946 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
947 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
948 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
949 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
951 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
980 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
981 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
985 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
987 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
991 user_colors::GetMapByScheme(SchemeName.ToStdString());
996 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
999 cc->SetColorScheme(cs);
1000 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1001 cc->HideChartInfoWindow();
1002 cc->SetQuiltChartHiLiteIndex(-1);
1008 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1020 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1033 if (g_pais_query_dialog_active) {
1034 bool b_isshown = g_pais_query_dialog_active->IsShown();
1035 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1036 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1038 g_pais_query_dialog_active->Close();
1041 g_pais_query_dialog_active->
Create(
1042 this, -1, _(
"AIS Target Query"),
1043 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1044 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1045 g_pais_query_dialog_active->UpdateText();
1046 if (b_isshown) g_pais_query_dialog_active->Show();
1051 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1055 ApplyGlobalColorSchemetoStatusBar();
1057 UpdateAllToolbars(cs);
1062 bool btoolbarFull = g_bmasterToolbarFull;
1068 if (!btoolbarFull) {
1070 RequestNewMasterToolbar();
1072 CollapseGlobalToolbar();
1075 RequestNewMasterToolbar();
1084void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1085 if (m_pStatusBar != NULL) {
1086 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1087 m_pStatusBar->ClearBackground();
1098void MyFrame::CancelAllMouseRoute() {
1100 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1102 if (cc) cc->CancelMouseRoute();
1106void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1114 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1122 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1131 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1134 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1135 config_array.Item(i)->canvas = NULL;
1141 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1146 switch (g_canvasConfig) {
1160 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1161 cc->GetglCanvas()->Show();
1164 config_array.Item(0)->canvas = cc;
1168 cc->ApplyCanvasConfig(config_array.Item(0));
1172 cc->ConfigureChartBar();
1173 cc->SetColorScheme(global_color_scheme);
1174 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1175 cc->SetShowGPS(
true);
1178 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1180 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1196 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1199 config_array.Item(0)->canvas = cc;
1201 cc->ApplyCanvasConfig(config_array.Item(0));
1204 cc->ConfigureChartBar();
1205 cc->SetColorScheme(global_color_scheme);
1206 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1207 cc->SetShowGPS(
false);
1210 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1212 .CaptionVisible(
false)
1214 .CloseButton(
false);
1223 if (config_array.GetCount() < 2) {
1225 pcc->configIndex = 1;
1229 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1230 config_array.Add(pcc);
1233 config_array.Item(1)->canvas = cc;
1235 cc->ApplyCanvasConfig(config_array.Item(1));
1238 cc->ConfigureChartBar();
1239 cc->SetColorScheme(global_color_scheme);
1240 cc->SetShowGPS(
true);
1242 cc->SetShowGPSCompassWindow(
true);
1245 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1247 .CaptionVisible(
false)
1249 .CloseButton(
false);
1250 g_pauimgr->GetPane(cc).RightDockable(
true);
1254 config_array.Item(1)->canvasSize =
1255 wxSize(GetClientSize().x / 2, GetClientSize().y);
1256 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1261 if (b_useStoredSize) {
1262 int ccw = config_array.Item(1)->canvasSize.x;
1263 int cch = config_array.Item(1)->canvasSize.y;
1266 if (ccw < GetClientSize().x / 10) {
1267 ccw = GetClientSize().x / 2;
1268 cch = GetClientSize().y;
1271 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1272 cc->SetSize(ccw, cch);
1290 console->SetColorScheme(global_color_scheme);
1295 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1301void MyFrame::RequestNewToolbars(
bool bforcenew) {
1302 if (b_inCloseWindow) {
1306 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1307 PositionIENCToolbar();
1316void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1322void MyFrame::SetAllToolbarScale() {
1323 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1326void MyFrame::SetGPSCompassScale() {
1327 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1331 wxPoint screenPoint = ::wxGetMousePosition();
1334 switch (g_canvasConfig) {
1336 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1339 if (canvas->GetScreenRect().Contains(
1343 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1346 if (canvas->GetScreenRect().Contains(
1353 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1356 if (canvas->GetScreenRect().Contains(
1357 canvas->ScreenToClient(screenPoint)))
1365int MyFrame::GetCanvasIndexUnderMouse() {
1366 wxPoint screenPoint = ::wxGetMousePosition();
1369 switch (g_canvasConfig) {
1371 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1374 if (canvas->GetScreenRect().Contains(
1378 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1381 if (canvas->GetScreenRect().Contains(
1388 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1391 if (canvas->GetScreenRect().Contains(
1392 canvas->ScreenToClient(screenPoint)))
1400bool MyFrame::DropMarker(
bool atOwnShip) {
1407 if (!canvas)
return false;
1414 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1416 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1418 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1429 RefreshAllCanvas(
false);
1434void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1435 if (g_canvasConfig != 0) {
1438 int nTargetGTK = -1;
1440 wxWindow *source = FindFocus();
1446 switch (g_canvasConfig) {
1448 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1451 if (canvas && (canvas == test)) {
1456 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1459 if (canvas && (canvas == test)) {
1467 int nfinalTarget = nTarget;
1469 nfinalTarget = nTargetGTK;
1471 target = ConfigMgr::Get()
1472 .GetCanvasConfigArray()
1477 target->Refresh(
true);
1488void MyFrame::FastClose() {
1490 FrameTenHzTimer.Stop();
1492 FrameTimer1.Start(1);
1496void MyFrame::OnExit(wxCommandEvent &event) {
1500void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1503 if (b_inCloseWindow) {
1513 if (!g_bDeferredInitDone)
return;
1530 if (bDBUpdateInProgress)
return;
1532 b_inCloseWindow =
true;
1534 ::wxSetCursor(wxCURSOR_WAIT);
1538 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1540 if (cc && cc->IsMeasureActive()) {
1541 cc->CancelMeasureRoute();
1546 SendPreShutdownHookToPlugins();
1550 if (g_pAISTargetList) {
1551 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1552 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1553 g_pauimgr->DetachPane(g_pAISTargetList);
1580 SetCursor(wxCURSOR_WAIT);
1582 RefreshAllCanvas(
true);
1588 RestoreScreenBrightness();
1599 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1600 g_iENCToolbarPosY = tbp_incanvas.y;
1601 g_iENCToolbarPosX = tbp_incanvas.x;
1605 g_bframemax = IsMaximized();
1608 FrameTenHzTimer.Stop();
1610 FrameCOGTimer.Stop();
1624 if (g_bAutoAnchorMark) {
1625 bool watching_anchor =
false;
1633 wxDateTime now = wxDateTime::Now();
1634 wxTimeSpan uptime = now.Subtract(g_start_time);
1636 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1637 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1642 if (g_declutter_anchorage) {
1643 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1644 if (pr->GetName().StartsWith(
"Anchorage")) {
1645 double a =
gLat - pr->m_lat;
1646 double b =
gLon - pr->m_lon;
1647 double l = sqrt((a * a) + (b * b));
1650 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1652 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1653 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1661 wxString name = now.Format();
1662 name.Prepend(_(
"Anchorage created "));
1668 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1677 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1681 NavObj_dB::GetInstance().Close();
1685 pConfig->DeleteGroup(
"/Routes");
1686 pConfig->DeleteGroup(
"/Marks");
1705 if (g_pAISTargetList) {
1706 g_pAISTargetList->Disconnect_decoder();
1707 g_pAISTargetList->Destroy();
1710 if (RouteManagerDialog::getInstanceFlag()) {
1727 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1729 if (cc) cc->Destroy();
1753 CommBridge::GetInstance().SaveConfig();
1773 auto ®istry = CommDriverRegistry::GetInstance();
1774 registry.CloseAllDrivers();
1777 for (
auto *cp : TheConnectionParams()) {
1782 while (pLayerList->size())
delete *pLayerList->begin();
1786 ReleaseApiListeners();
1789 g_bTempShowMenuBar =
false;
1791#define THREAD_WAIT_SECONDS 5
1801 wxLogMessage(
"Starting compressor pool drain");
1802 wxDateTime now = wxDateTime::Now();
1803 time_t stall = now.GetTicks();
1804 time_t end = stall + THREAD_WAIT_SECONDS;
1807 while (stall < end) {
1808 wxDateTime later = wxDateTime::Now();
1809 stall = later.GetTicks();
1812 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1821 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1827 uninitIXNetSystem();
1835 wxLogMessage(
"gFrame destroyed.");
1838#ifndef USE_ANDROID_GLES2
1839 qDebug() <<
"Calling OnExit()";
1843 wxTheApp->ExitMainLoop();
1846void MyFrame::OnMove(wxMoveEvent &event) {
1847 auto idx = wxDisplay::GetFromWindow(
this);
1860 DEBUG_LOG <<
"Moved to " << idx
1861#if wxCHECK_VERSION(3, 1, 6)
1862 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1863 << wxDisplay(idx).GetPPI().GetY()
1864 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1866 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1867 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1868 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1869 << wxGetDisplaySizeMM().GetY()
1870 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1879 if (g_config_display_size_manual) {
1888 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1891 cc->SetMUIBarPosition();
1900 UpdateGPSCompassStatusBoxes();
1910 PositionIENCToolbar();
1916 g_nframewin_posx = GetPosition().x;
1917 g_nframewin_posy = GetPosition().y;
1920void MyFrame::ProcessCanvasResize() {
1921 UpdateGPSCompassStatusBoxes(
true);
1925 PositionIENCToolbar();
1928 TriggerRecaptureTimer();
1932void MyFrame::TriggerRecaptureTimer() {
1933 m_recaptureTimer.Start(
1934 1000, wxTIMER_ONE_SHOT);
1937void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1939void MyFrame::SetCanvasSizes(wxSize frameSize) {
1943 int cccw = frameSize.x;
1944 int ccch = frameSize.y;
1948 switch (g_canvasConfig) {
1954 cc->GetSize( &cur_width, &cur_height );
1955 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1957 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1959 cc->SetSize( 0, 0, cccw, ccch );
1969 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1970 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1972 ccw = wxMin(ccw, cccw * 8 / 10);
1973 ccw = wxMax(ccw, cccw * 2 / 10);
1977 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1984 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2001void MyFrame::OnIconize(wxIconizeEvent &event) {
2011 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2013 if (cc && cc->GetMUIBar()) {
2014 if (cc->GetMUIBar()->GetCanvasOptions()) {
2015 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2016 cc->GetMUIBar()->PushCanvasOptions();
2025void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2027void MyFrame::ODoSetSize() {
2029 GetClientSize(&x, &y);
2032 if (m_pStatusBar != NULL) {
2033 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2034 int currentCount = m_pStatusBar->GetFieldsCount();
2035 if (currentCount != m_StatusBarFieldCount) {
2036 if ((currentCount > 0) && (currentCount < 7)) {
2039 int widths[] = {2, 2, 2, 2, 2, 2};
2040 m_pStatusBar->SetStatusWidths(currentCount, widths);
2043 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2046 if (m_StatusBarFieldCount) {
2051 if (m_StatusBarFieldCount > 2) {
2052 int widths[] = {-6, -5, -5, -6, -4};
2053 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2054 }
else if (m_StatusBarFieldCount == 2) {
2055 int cwidth = x * 90 / 100;
2056 int widths[] = {100, 100};
2057 widths[0] = cwidth * 6.4 / 10.0;
2058 widths[1] = cwidth * 3.6 / 10.0;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2061 int widths[] = {100, 100};
2062 widths[0] = x * 90 / 100;
2063 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2066 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2067 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2068 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2070 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2072 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2080 m_pStatusBar->GetFieldRect(0, stat_box);
2083 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2085 wxFont sys_font = *wxNORMAL_FONT;
2086 int try_font_size = sys_font.GetPointSize();
2089 int min_font_size = 10;
2099 wxFont *statusBarFont =
2100 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2101 int font_size = statusBarFont->GetPointSize();
2103 font_size = wxMin(font_size,
2106 wxMax(font_size, min_font_size);
2109 font_size = statusBarFont->GetPointSize();
2116 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2117 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2119 int min_height = stat_box.height;
2121 m_pStatusBar->SetFont(*pstat_font);
2122 m_pStatusBar->SetForegroundColour(
2123 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2125 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2127 (min_height >> 1) * 2;
2128 m_pStatusBar->SetMinHeight(min_height);
2137 SetCanvasSizes(GetClientSize());
2139 UpdateGPSCompassStatusBoxes(
true);
2141 if (
console) PositionConsole();
2144 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2146 if (cc) cc->FormatPianoKeys();
2152 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2153 GetPrimaryCanvas()->GetCompass()->GetRect());
2179 options_lastWindowSize = wxSize(0, 0);
2180 options_lastWindowPos = wxPoint(0, 0);
2187 if (!b_inCloseWindow) {
2190 resizeAndroidPersistents();
2194 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2195 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2201void MyFrame::PositionConsole() {
2202#if defined(__WXMSW__) || defined(__WXMAC__)
2203 if (NULL == GetPrimaryCanvas())
return;
2205 int ccx, ccy, ccsx, ccsy, consx, consy;
2210 consoleHost->GetSize(&ccsx, &ccsy);
2211 consoleHost->GetPosition(&ccx, &ccy);
2213 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2214 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2215 consoleHost = GetPrimaryCanvas();
2220 if (consoleHost->GetCompass()) {
2221 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2223 if (compass_rect.y < 100)
2224 yOffset = compass_rect.y + compass_rect.height + 45;
2228 wxSize csz =
console->GetSize();
2232 wxPoint screen_pos =
2233 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2236 if (NULL == GetPrimaryCanvas())
return;
2238 int ccx, ccy, ccsx, ccsy, consx, consy;
2243 consoleHost->GetSize(&ccsx, &ccsy);
2244 consoleHost->GetPosition(&ccx, &ccy);
2246 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2247 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2248 consoleHost = GetPrimaryCanvas();
2251 int yTopOffset = 60;
2252 int yBottomOffset = 0;
2254 if (consoleHost->GetCompass()) {
2255 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2257 if (compass_rect.y < 100)
2258 yTopOffset = compass_rect.y + compass_rect.height;
2260 if (consoleHost->GetMUIBar()) {
2261 wxRect mui_rect = consoleHost->GetMUIBarRect();
2262 yBottomOffset = ccsy - mui_rect.y;
2266 wxSize csz =
console->GetSize();
2269 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2271 if (consy < yAvail) {
2272 yFinal = (yAvail - consy) / 2;
2273 yFinal += yTopOffset;
2274 }
else if (
console->GetCDI()->IsShown()) {
2275 int cdi_height =
console->GetCDI()->GetSize().y;
2276 int consy_no_cdi = consy - cdi_height;
2277 yFinal = (yAvail - consy_no_cdi) / 2;
2278 yFinal += yTopOffset;
2282 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2287void MyFrame::UpdateAllFonts() {
2296 DestroyPersistentDialogs();
2298 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2303void MyFrame::DestroyPersistentDialogs() {
2304 if (g_pais_query_dialog_active) {
2305 g_pais_query_dialog_active->Hide();
2306 g_pais_query_dialog_active->Destroy();
2307 g_pais_query_dialog_active = NULL;
2335void MyFrame::RefreshGroupIndices() {
2337 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2339 if (cc) cc->canvasRefreshGroupIndex();
2343bool MyFrame::DisableTbarTooltips() {
2348 wxLogWarning(
"Global g_MainToolbar has not been created.");
2352void MyFrame::EnableTbarTooltips() {
2358void MyFrame::HideTbarTooltip() {
2364void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2366 switch (event.GetId()) {
2367 case ID_MENU_SCALE_OUT:
2368 DoStackDelta(GetPrimaryCanvas(), 1);
2372 case ID_MENU_SCALE_IN:
2373 DoStackDelta(GetPrimaryCanvas(), -1);
2377 case ID_MENU_ZOOM_IN: {
2378 if (GetFocusCanvas()) {
2379 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2384 case ID_MENU_ZOOM_OUT: {
2385 if (GetFocusCanvas()) {
2386 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2391 case ID_MENU_ROUTE_NEW: {
2392 if (GetFocusCanvas()) {
2393 if (0 == GetFocusCanvas()->m_routeState) {
2394 GetFocusCanvas()->StartRoute();
2396 GetFocusCanvas()->FinishRoute();
2402 case ID_MENU_TOOL_MEASURE: {
2403 GetPrimaryCanvas()->StartMeasureRoute();
2407 case ID_MENU_TOOL_NMEA_DBG_LOG:
2408 m_data_monitor->Show();
2409 m_data_monitor->Raise();
2412 case ID_MENU_TOOL_IO_MONITOR:
2413 m_data_monitor->Show();
2416 case ID_MENU_MARK_BOAT: {
2421 case ID_MENU_MARK_CURSOR: {
2426 case ID_MENU_NAV_FOLLOW: {
2427 if (
gFrame->GetPrimaryCanvas())
2428 gFrame->GetPrimaryCanvas()->TogglebFollow();
2432 case ID_MENU_CHART_OUTLINES: {
2433 ToggleChartOutlines(GetFocusCanvas());
2437 case ID_MENU_CHART_QUILTING: {
2438 ToggleQuiltMode(GetFocusCanvas());
2442 case ID_MENU_UI_CHARTBAR: {
2443 ToggleChartBar(GetFocusCanvas());
2447 case ID_MENU_ENC_TEXT:
2449 ToggleENCText(GetFocusCanvas());
2452 case ID_MENU_ENC_LIGHTS: {
2453 ToggleLights(GetFocusCanvas());
2456 case ID_MENU_ENC_SOUNDINGS: {
2457 ToggleSoundings(GetFocusCanvas());
2460 case ID_MENU_ENC_ANCHOR: {
2461 ToggleAnchor(GetFocusCanvas());
2464 case ID_MENU_ENC_DATA_QUALITY: {
2465 ToggleDataQuality(GetFocusCanvas());
2468 case ID_MENU_SHOW_NAVOBJECTS: {
2469 ToggleNavobjects(GetFocusCanvas());
2473 case ID_MENU_AIS_TARGETS: {
2474 ToggleAISDisplay(GetFocusCanvas());
2477 case ID_MENU_AIS_MOORED_TARGETS: {
2478 g_bHideMoored = !g_bHideMoored;
2481 case ID_MENU_AIS_SCALED_TARGETS: {
2482 ToggleAISMinimizeTargets(GetFocusCanvas());
2486 case ID_MENU_AIS_TARGETLIST: {
2487 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2491 case ID_MENU_AIS_TRACKS: {
2492 g_bAISShowTracks = !g_bAISShowTracks;
2493 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2497 case ID_MENU_AIS_CPADIALOG: {
2498 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2499 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2500 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2501 if (g_bAIS_CPA_Alert) {
2502 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2507 case ID_MENU_AIS_CPASOUND: {
2508 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2509 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2513 case ID_MENU_AIS_CPAWARNING: {
2514 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2515 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2519 case wxID_PREFERENCES:
2526 case ID_SETTINGS_NEW: {
2531 case ID_SETTINGS_DELETE: {
2534 g_pOptions =
nullptr;
2538 case ID_RELOAD_CHARTS: {
2543 case ID_MENU_SETTINGS_BASIC: {
2545 androidDisableFullScreen();
2547 DoAndroidPreferences();
2554 case ID_MENU_UI_FULLSCREEN: {
2559 case ID_MENU_SHOW_CURRENTS: {
2560 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2561 GetFocusCanvas()->ReloadVP();
2562 GetFocusCanvas()->Refresh(
false);
2566 case ID_MENU_SHOW_TIDES: {
2567 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2568 GetFocusCanvas()->ReloadVP();
2569 GetFocusCanvas()->Refresh(
false);
2589 case ID_MENU_UI_COLSCHEME:
2590 case ID_COLSCHEME: {
2591 ToggleColorScheme();
2600 case ID_MENU_OQUIT: {
2605 case ID_MENU_ROUTE_MANAGER:
2606 case ID_ROUTEMANAGER: {
2629 case ID_MENU_NAV_TRACK:
2631 if (!g_bTrackActive) {
2633 g_bTrackCarryOver =
true;
2636 g_bTrackCarryOver =
false;
2637 RefreshAllCanvas(
true);
2642 case ID_MENU_CHART_NORTHUP: {
2643 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2646 case ID_MENU_CHART_COGUP: {
2647 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2650 case ID_MENU_CHART_HEADUP: {
2651 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2655 case ID_MENU_MARK_MOB:
2661 case ID_MASTERTOGGLE: {
2663 wxString tip = _(
"Show Toolbar");
2664 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2666 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2668 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2671 if (g_bmasterToolbarFull)
2672 m_nMasterToolCountShown =
2676 m_nMasterToolCountShown = 2;
2678 m_nMasterToolCountShown =
2681 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2689 case ID_CMD_SELECT_CHART_TYPE: {
2690 selectChartDisplay(event.GetExtraLong(), -1);
2694 case ID_CMD_SELECT_CHART_FAMILY: {
2695 selectChartDisplay(-1, event.GetExtraLong());
2699 case ID_CMD_APPLY_SETTINGS: {
2700 applySettingsString(event.GetString());
2702 androidRestoreFullScreen();
2708 case ID_CMD_NULL_REFRESH: {
2713 case ID_CMD_SETVP: {
2714 setStringVP(event.GetString());
2718 case ID_CMD_INVALIDATE: {
2724 case ID_CMD_POST_JSON_TO_PLUGINS: {
2727 nlohmann::json root;
2729 root = nlohmann::json::parse(event.GetString().ToStdString());
2730 if (root[
"MessageID"].is_string()) {
2731 std::string msg_id = root[
"MessageID"].get<std::string>();
2734 }
catch (nlohmann::json::exception &) {
2756 ArrayOfPlugInToolbarTools tool_array =
2758 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2760 if (event.GetId() == pttc->id) {
2761 if (pttc->m_pplugin)
2783bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2784 bool viz_now = g_bmasterToolbarFull;
2787 wxString tip = _(
"Show Toolbar");
2789 tip = _(
"Hide Toolbar");
2791 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2794 bool toggle =
false;
2795 if (viz && !g_bmasterToolbarFull)
2798 else if (!viz && g_bmasterToolbarFull)
2802 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2805 if (g_bmasterToolbarFull)
2806 m_nMasterToolCountShown =
2810 m_nMasterToolCountShown = 2;
2812 m_nMasterToolCountShown =
2815 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2821void MyFrame::ScheduleReloadCharts() {
2822 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2823 evt.SetId(ID_RELOAD_CHARTS);
2824 GetEventHandler()->AddPendingEvent(evt);
2827void MyFrame::ScheduleDeleteSettingsDialog() {
2828 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2829 evt.SetId(ID_SETTINGS_DELETE);
2830 GetEventHandler()->AddPendingEvent(evt);
2833void MyFrame::ScheduleSettingsDialog() {
2834 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2835 evt.SetId(ID_SETTINGS);
2836 GetEventHandler()->AddPendingEvent(evt);
2839void MyFrame::ScheduleSettingsDialogNew() {
2840 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2841 evt.SetId(ID_SETTINGS_NEW);
2842 GetEventHandler()->AddPendingEvent(evt);
2845void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2846 UpdateCanvasConfigDescriptors();
2848 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2849 CreateCanvasLayout(
true);
2851 CreateCanvasLayout();
2855 ConfigureStatusBar();
2856 wxSize lastOptSize = options_lastWindowSize;
2861 options_lastWindowSize = lastOptSize;
2865 ScheduleSettingsDialogNew();
2867 ScheduleSettingsDialog();
2872 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2875 int index_hint = -1;
2876 if (i < pathArray.GetCount())
2877 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2878 cc->canvasChartsRefresh(index_hint);
2879 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2888 return GetPrimaryCanvas();
2891void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2893 if (g_bmasterToolbarFull) {
2894#ifndef OCPN_TOOLBAR_ANIMATE
2895 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2898 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2899 m_nMasterToolCountShown++;
2904 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2912#ifndef OCPN_TOOLBAR_ANIMATE
2913 m_nMasterToolCountShown = 1;
2915 if (m_nMasterToolCountShown > 1) {
2916 m_nMasterToolCountShown--;
2920 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2930void MyFrame::InvalidateAllGL() {
2933 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2943void MyFrame::RefreshAllCanvas(
bool bErase) {
2945 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2948 cc->Refresh(bErase);
2953void MyFrame::setStringVP(wxString VPS) {
2958 wxStringTokenizer tkz(VPS,
";");
2960 wxString token = tkz.GetNextToken();
2962 token.ToDouble(&lat);
2964 token = tkz.GetNextToken();
2966 token.ToDouble(&lon);
2968 token = tkz.GetNextToken();
2970 token.ToDouble(&scale_ppm);
2972 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2975void MyFrame::DoSettingsNew() {
2982void MyFrame::DoSettings() {
2987 ApplyGlobalSettings(
true);
2990 bool b_loadHarmonics =
false;
2991 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2994 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2997 if (b_loadHarmonics) LoadHarmonics();
3005 g_bShowChartBar = !g_bShowChartBar;
3007 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3012 if (g_bShowChartBar) {
3014 UpdateControlBar(cc);
3017 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3020void MyFrame::ToggleColorScheme() {
3021 static bool lastIsNight;
3022 ColorScheme s = user_colors::GetColorScheme();
3025 if (lastIsNight && is == 3)
3028 lastIsNight =
false;
3030 if (lastIsNight) is = 2;
3031 if (is == 3) lastIsNight =
true;
3032 s = (ColorScheme)is;
3033 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3035 SetAndApplyColorScheme(s);
3038void MyFrame::ToggleFullScreen() {
3039 bool to = !IsFullScreen();
3044 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3046 ShowFullScreen(to, style);
3049 UpdateAllToolbars(global_color_scheme);
3051 UpdateControlBar(GetPrimaryCanvas());
3053 TriggerRecaptureTimer();
3056void MyFrame::ActivateMOB() {
3058 wxDateTime mob_time = wxDateTime::Now();
3059 wxString mob_label(_(
"MAN OVERBOARD"));
3060 mob_label += _(
" on ");
3061 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3065 pWP_MOB->SetShared(
true);
3067 pWP_MOB->SetWaypointArrivalRadius(
3069 pWP_MOB->SetUseSca(
false);
3071 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3079 new RoutePoint(zlat, zlon, g_default_wp_icon,
3080 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3081 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3086 temp_route->AddPoint(pWP_src);
3087 temp_route->AddPoint(pWP_MOB);
3089 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3099 temp_route->SetRouteArrivalRadius(-1.0);
3105 v[
"GUID"] = temp_route->
m_GUID;
3106 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
3109 if (RouteManagerDialog::getInstanceFlag()) {
3117 RefreshAllCanvas(
false);
3119 wxString mob_message(_(
"MAN OVERBOARD"));
3120 mob_message += _(
" Time: ");
3121 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3122 mob_message += _(
" Position: ");
3123 mob_message += toSDMM(1,
gLat);
3125 mob_message += toSDMM(2,
gLon);
3126 wxLogMessage(mob_message);
3128void MyFrame::TrackOn() {
3129 g_bTrackActive =
true;
3137 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3139 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3141 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3144 androidSetTrackTool(
true);
3147 if (RouteManagerDialog::getInstanceFlag()) {
3156 if (name.IsEmpty()) {
3162 name = _(
"(Unnamed Track)");
3166 SendJsonMessageToAllPlugins(
"OCPN_TRK_ACTIVATED", v);
3168 g_FlushNavobjChangesTimeout = 30;
3171Track *MyFrame::TrackOff(
bool do_add_point) {
3177 SendJsonMessageToAllPlugins(
"OCPN_TRK_DEACTIVATED", v);
3186 if (g_bTrackDaily) {
3191 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3192 return_val = pExtendTrack;
3199 g_bTrackActive =
false;
3201 if (RouteManagerDialog::getInstanceFlag()) {
3208 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3210 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3211 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3214 androidSetTrackTool(
false);
3218 m_target_rotate_time = wxInvalidDateTime;
3223void MyFrame::InitializeTrackRestart() {
3224 if (!g_bTrackDaily)
return;
3225 if (m_target_rotate_time.IsValid())
return;
3228 switch (g_track_rotate_time_type) {
3230 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3232 case TIME_TYPE_COMPUTER:
3233 rotate_at = g_track_rotate_time;
3237 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3238 rotate_at = g_track_rotate_time + utc_offset;
3241 if (rotate_at > 86400)
3243 else if (rotate_at < 0)
3246 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3247 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3250 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3251 m_target_rotate_time += wxTimeSpan(24);
3255bool MyFrame::ShouldRestartTrack() {
3257 InitializeTrackRestart();
3259 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3260 m_target_rotate_time += wxTimeSpan(24);
3266void MyFrame::TrackDailyRestart() {
3268 Track *pPreviousTrack = TrackOff(
true);
3275 if (pPreviousTrack) {
3276 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3280 if (RouteManagerDialog::getInstanceFlag()) {
3288void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3290 cc->SetUpMode(mode);
3292 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3293 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3294 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3297 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3302 cc->SetShowENCText(!cc->GetShowENCText());
3304 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3312void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3315 cc->SetENCDisplayCategory(nset);
3317 UpdateGlobalMenuItems();
3328 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3330 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3339 cc->SetShowENCLights(!cc->GetShowENCLights());
3341 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3351void MyFrame::ToggleRocks(
void )
3357 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3358 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3359 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3360 pOLE->nViz = !pOLE->nViz;
3364 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3365 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3366 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3369 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3373 ps52plib->GenerateStateHash();
3380 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3382 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3390 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3392 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3407 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3408 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3413 cc->SetShowAIS(!cc->GetShowAIS());
3414 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3418void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3419 cc->SetAttenAIS(!cc->GetAttenAIS());
3420 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3426 cc->m_bFollow =
true;
3429 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3433 SetChartUpdatePeriod();
3441 cc->m_bFollow =
false;
3443 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3447 SetChartUpdatePeriod();
3450void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3451 cc->SetShowOutlines(!cc->GetShowOutlines());
3453 RefreshAllCanvas(
false);
3457 if (g_bopengl) InvalidateAllGL();
3460 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3463void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3465void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3467 bool enabled = m_pMenuBar->IsEnabled(item_id);
3468 m_pMenuBar->Enable(item_id,
false);
3469 m_pMenuBar->Check(item_id, state);
3470 m_pMenuBar->Enable(item_id, enabled);
3474void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3481void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3482 wxBitmap *bmpRollover) {
3484 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3489void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3490 wxString rolloverSVGfile,
3491 wxString toggledSVGfile) {
3494 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3498void MyFrame::ConfigureStatusBar() {
3500 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3503 UseNativeStatusBar(
false);
3506 if (g_bShowStatusBar) {
3507 if (!m_pStatusBar) {
3509 CreateStatusBar(m_StatusBarFieldCount, 0);
3510 ApplyGlobalColorSchemetoStatusBar();
3515 m_pStatusBar->Destroy();
3516 m_pStatusBar = NULL;
3522void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3523 ConfigureStatusBar();
3525 wxSize lastOptSize = options_lastWindowSize;
3531 options_lastWindowSize = lastOptSize;
3533 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3536void MyFrame::BuildMenuBar() {
3542 bool showMenuBar =
true;
3544 bool showMenuBar = g_bShowMenuBar;
3556 m_pMenuBar =
new wxMenuBar();
3557 RegisterGlobalMenuItems();
3558 SetMenuBar(m_pMenuBar);
3562 UpdateGlobalMenuItems();
3567 m_pMenuBar->Destroy();
3573void MyFrame::RegisterGlobalMenuItems() {
3574 if (!m_pMenuBar)
return;
3576 wxMenu *nav_menu =
new wxMenu();
3577 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3578 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3579 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3580 nav_menu->AppendSeparator();
3581 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3582 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3583 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3584 nav_menu->AppendSeparator();
3586 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3587 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3589 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3590 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3592 nav_menu->AppendSeparator();
3593 nav_menu->Append(ID_MENU_SCALE_IN,
3594 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3595 nav_menu->Append(ID_MENU_SCALE_OUT,
3596 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3598 nav_menu->AppendSeparator();
3599 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3601 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3603 wxMenu *view_menu =
new wxMenu();
3605 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3606 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3607 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3608 _menuText(_(
"Show Chart Outlines"),
"O"));
3610 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3611 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3612 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3613 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3615 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3616 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3618 view_menu->AppendSeparator();
3620 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3621 _menuText(_(
"Show ENC text"),
"T"));
3622 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3623 _menuText(_(
"Show ENC Lights"),
"L"));
3624 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3625 _menuText(_(
"Show ENC Soundings"),
"S"));
3626 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3627 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3628 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3629 _menuText(_(
"Show ENC Data Quality"),
"U"));
3630 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3631 _menuText(_(
"Show Navobjects"),
"V"));
3633 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3634 _menuText(_(
"Show ENC text"),
"Alt-T"));
3635 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3636 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3637 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3638 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3639 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3640 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3641 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3642 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3643 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3644 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3646 view_menu->AppendSeparator();
3647 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3648 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3649 view_menu->AppendSeparator();
3651 view_menu->Append(ID_MENU_UI_COLSCHEME,
3652 _menuText(_(
"Change Color Scheme"),
"C"));
3654 view_menu->Append(ID_MENU_UI_COLSCHEME,
3655 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3658 view_menu->AppendSeparator();
3660 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3661 _menuText(_(
"Toggle Full Screen"),
"F11"));
3663 m_pMenuBar->Append(view_menu, _(
"&View"));
3665 wxMenu *ais_menu =
new wxMenu();
3666 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3667 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3668 _(
"Attenuate less critical AIS targets"));
3669 ais_menu->AppendSeparator();
3670 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3671 _(
"Hide Moored AIS Targets"));
3672 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3673 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3674 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3677 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3678 _menuText(_(
"Show CPA Warnings"),
"W"));
3680 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3681 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3684 ais_menu->AppendSeparator();
3685 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3686 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3688 wxMenu *tools_menu =
new wxMenu();
3690 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3691 _menuText(_(
"Data Monitor"),
"E"));
3692 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3693 _menuText(_(
"Measure Distance"),
"M"));
3695 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3696 _menuText(_(
"Data Monitor"),
"Alt-E"));
3697 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3698 _menuText(_(
"Measure Distance"),
"Alt-M"));
3701 tools_menu->AppendSeparator();
3702 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3703 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3704 tools_menu->AppendSeparator();
3705 tools_menu->Append(ID_MENU_MARK_BOAT,
3706 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3707 tools_menu->Append(ID_MENU_MARK_CURSOR,
3708 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3709 tools_menu->AppendSeparator();
3713 _menuText(_(
"Drop MOB Marker"),
3715 tools_menu->AppendSeparator();
3716 tools_menu->Append(wxID_PREFERENCES,
3717 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3719 tools_menu->Append(ID_MENU_MARK_MOB,
3720 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3721 tools_menu->AppendSeparator();
3722 tools_menu->Append(wxID_PREFERENCES,
3723 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3725 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3728 wxMenu *window_menu =
new wxMenu();
3729 m_pMenuBar->Append(window_menu, _(
"&Window"));
3732 wxMenu *help_menu =
new wxMenu();
3733 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3734 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3735 m_pMenuBar->Append(help_menu, _(
"&Help"));
3738 UpdateGlobalMenuItems();
3741void MyFrame::UpdateGlobalMenuItems() {
3742 if (!m_pMenuBar)
return;
3744 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3745 ->Check(GetPrimaryCanvas()->m_bFollow);
3746 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3747 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3748 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3749 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3750 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3751 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3752 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3753 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3754 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3755 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3756 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3757 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3758 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3759 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3760 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3761 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3762 if (g_bAIS_CPA_Alert) {
3763 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3764 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3766 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3767 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3770 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3771 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3772 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3775 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3776 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3777 ->Check(ps52plib->GetShowSoundings());
3779 bool light_state =
false;
3781 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3783 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3784 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3785 light_state = (pOLE->nViz == 1);
3790 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3791 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3795 DisCat nset = ps52plib->GetDisplayCategory();
3796 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3797 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3798 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3799 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3800 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3801 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3802 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3804 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3805 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3806 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3811void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3812 if (!m_pMenuBar)
return;
3814 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3816 if (cc->GetUpMode() == NORTH_UP_MODE)
3817 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3818 else if (cc->GetUpMode() == COURSE_UP_MODE)
3819 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3821 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3823 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3824 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3825 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3826 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3827 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3828 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3829 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3830 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3831 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3832 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3833 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3834 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3835 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3836 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3837 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3840 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3841 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3844 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3846 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3847 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3852 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3856 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3857 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3858 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3859 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3860 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3861 ->Check(cc->GetShowENCDataQual());
3862 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3864 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3865 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3866 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3871void MyFrame::InvalidateAllCanvasUndo() {
3873 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3875 if (cc) cc->undo->InvalidateUndo();
3879void MyFrame::SubmergeAllCanvasToolbars() {
3881 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3883 if (cc) cc->SubmergeToolbar();
3887void MyFrame::SurfaceAllCanvasToolbars() {
3888 if (g_bshowToolbar) {
3890 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3892 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3899void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3901 if (lon > 180.0) lon -= 360.0;
3906 cc->JumpToPosition(lat, lon,
scale);
3909 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3913void MyFrame::UpdateCanvasConfigDescriptors() {
3915 for (
unsigned int i = 0;
3916 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3917 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3925 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3926 cc->GroupID = chart->m_groupIndex;
3929 cc->
bQuilt = chart->GetQuiltMode();
3935 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3937 cc->
bFollow = chart->m_bFollow;
3942 int upmode = chart->GetUpMode();
3943 if (upmode == COURSE_UP_MODE)
3945 else if (upmode == HEAD_UP_MODE)
3952void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3953 if (!RBBox.GetValid())
return;
3955 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3956 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3959 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3960 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3968 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3969 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3971 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3972 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3974 cc->GetSize(&ww, &wh);
3976 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3978 ppm = wxMin(ppm, 1.0);
3984void MyFrame::PrepareOptionsClose(
options *settings,
3985 int settings_return_value) {
3987 options_lastPage = settings->lastPage;
3992 if (options_lastPage == 1) options_lastPage = 0;
3994 options_subpage = settings->lastSubPage;
3995 options_lastWindowPos = settings->lastWindowPos;
3996 options_lastWindowSize = settings->lastWindowSize;
3999 androidEnableBackButton(
true);
4000 androidEnableOptionsMenu(
true);
4001 androidRestoreFullScreen();
4002 androidEnableRotation();
4005 EnableSettingsTool(
true);
4008void MyFrame::DoOptionsDialog() {
4009 EnableSettingsTool(
false);
4012 AbstractPlatform::ShowBusySpinner();
4015 pConfig->SetPath(
"/Settings");
4016 pConfig->Read(
"OptionsSizeX", &sx, -1);
4017 pConfig->Read(
"OptionsSizeY", &sy, -1);
4019 wxWindow *optionsParent =
this;
4021 optionsParent = GetPrimaryCanvas();
4024 callbacks.prepare_close = [&](
options *me,
int changes) {
4025 PrepareOptionsClose(me, changes);
4027 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4028 ProcessOptionsDialog(changes, workdir_list);
4031 wxPoint(-1, -1), wxSize(sx, sy));
4033 AbstractPlatform::HideBusySpinner();
4037 g_options->SetInitChartDir(*pInit_Chart_Dir);
4041 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4042 g_options->SetWorkDirListPtr(pWorkDirArray);
4048 prev_locale = g_locale;
4049 g_options->SetInitialPage(options_lastPage, options_subpage);
4052 g_options->lastWindowPos = options_lastWindowPos;
4053 if (options_lastWindowPos != wxPoint(0, 0)) {
4055 g_options->SetSize(options_lastWindowSize);
4059 if (options_lastWindowSize != wxSize(0, 0)) {
4060 g_options->SetSize(options_lastWindowSize);
4065 androidEnableBackButton(
false);
4066 androidEnableOptionsMenu(
false);
4067 androidDisableFullScreen();
4075 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4078 wxString chart_file_name;
4079 if (cc->GetQuiltMode()) {
4080 int dbi = cc->GetQuiltRefChartdbIndex();
4081 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4083 if (cc->m_singleChart)
4084 chart_file_name = cc->m_singleChart->GetFullPath();
4087 pathArray.Add(chart_file_name);
4093 last_canvasConfig = g_canvasConfig;
4096 g_last_ChartScaleFactor = g_ChartScaleFactor;
4102void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4103 bool b_need_refresh =
false;
4106 if ((rr & VISIT_CHARTS) &&
4107 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4109 UpdateChartDatabaseInplace(*pNewDirArray,
4110 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4113 b_need_refresh =
true;
4118 if (rr & STYLE_CHANGED) {
4121 _(
"Please restart OpenCPN to activate language or style changes."),
4122 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4125 bool charts_updating =
4126 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4127 if (!charts_updating) RefreshGroupIndices();
4129 if (rr & TIDES_CHANGED) {
4135 if (rr & S52_CHANGED) {
4136 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4147 g_Platform->GetDisplayDPmm());
4150 double stuffcog = NAN;
4151 double stuffsog = NAN;
4152 if (!std::isnan(
gCog)) stuffcog =
gCog;
4153 if (!std::isnan(
gSog)) stuffsog =
gSog;
4155 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4156 COGFilterTable[i] = stuffcog;
4157 SOGFilterTable[i] = stuffsog;
4160 SetChartUpdatePeriod();
4162 if (rr & GL_CHANGED) {
4166 b_need_refresh =
true;
4169 if (rr & S52_CHANGED) {
4170 b_need_refresh =
true;
4174 if (rr & REBUILD_RASTER_CACHE) {
4176 GetPrimaryCanvas()->Disable();
4178 GetPrimaryCanvas()->Enable();
4183 if (g_config_display_size_manual &&
4191 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4198 int rrt = rr & S52_CHANGED;
4200 (rrt == S52_CHANGED) ||
4201 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4211 ps52plib->SetScaleFactorExp(
4212 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4213 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4217 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4219 if (cc) cc->ApplyGlobalSettings();
4227 if (!charts_updating) {
4228 bool ztc = g_bEnableZoomToCursor;
4229 g_bEnableZoomToCursor =
false;
4231 if (!GetPrimaryCanvas()->IsFrozen())
4233 g_bEnableZoomToCursor = ztc;
4238 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4247 SetGPSCompassScale();
4249 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4252 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4253 if (!charts_updating) cc->UpdateCanvasControlBar();
4256 UpdateGPSCompassStatusBoxes();
4258 SetAllToolbarScale();
4259 RequestNewToolbars();
4261 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4264 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4267 cc->RebuildCursors();
4272 bool b_masterScaleChange =
false;
4274 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4275 b_masterScaleChange =
true;
4277 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4278 RequestNewMasterToolbar(
true);
4280 bool bMuiChange =
false;
4286 if (b_masterScaleChange || bMuiChange) {
4288 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4291 cc->ProcessNewGUIScale();
4297 if (rr & LOCALE_CHANGED) {
4298 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4300 rr |= NEED_NEW_OPTIONS;
4309 g_last_ChartScaleFactor = g_ChartScaleFactor;
4314bool MyFrame::CheckGroup(
int igroup) {
4315 if (igroup == 0)
return true;
4319 if (!pGroup->m_element_array.size())
4322 for (
const auto &elem : pGroup->m_element_array) {
4323 for (
unsigned int ic = 0;
4324 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4325 auto &cte =
ChartData->GetChartTableEntry(ic);
4326 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4328 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4335bool MyFrame::ScrubGroupArray() {
4340 bool b_change =
false;
4341 unsigned int igroup = 0;
4342 while (igroup < g_pGroupArray->GetCount()) {
4343 bool b_chart_in_element =
false;
4346 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4347 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4349 for (
unsigned int ic = 0;
4350 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4351 auto &cte =
ChartData->GetChartTableEntry(ic);
4352 wxString chart_full_path = cte.GetFullSystemPath();
4354 if (chart_full_path.StartsWith(element_root)) {
4355 b_chart_in_element =
true;
4361 if (!b_chart_in_element) {
4362 wxString test_string =
"GSHH";
4363 if (element_root.Upper().Contains(test_string))
4364 b_chart_in_element =
true;
4367 if (!b_chart_in_element)
4369 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4381void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4383 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4385 if (cc && (cc != ccThis)) cc->Refresh();
4390void MyFrame::ChartsRefresh() {
4393 AbstractPlatform::ShowBusySpinner();
4395 bool b_run = FrameTimer1.IsRunning();
4398 FrameTenHzTimer.Stop();
4401 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4404 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4405 if (cc->GetQuiltMode()) {
4406 currentIndex = cc->GetQuiltReferenceChartIndex();
4408 cc->canvasChartsRefresh(currentIndex);
4412 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4413 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4415 AbstractPlatform::HideBusySpinner();
4418void MyFrame::InvalidateAllQuilts() {
4419 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4422 cc->InvalidateQuilt();
4423 cc->SetQuiltRefChart(-1);
4424 cc->m_singleChart = NULL;
4429bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4431 const wxString &ChartListFileName) {
4432 bool b_run = FrameTimer1.IsRunning();
4434 FrameTenHzTimer.Stop();
4436 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4437 FrameCOGTimer.Stop();
4440 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4443 cc->InvalidateQuilt();
4444 cc->SetQuiltRefChart(-1);
4445 cc->m_singleChart = NULL;
4455 AbstractPlatform::ShowBusySpinner();
4458 wxString longmsg = _(
"OpenCPN Chart Update");
4460 ".................................................................."
4463 Updateprog =
new wxGenericProgressDialog();
4466 Updateprog->SetFont(*qFont);
4468 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4469 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4470 wxPD_REMAINING_TIME);
4472 DimeControl(Updateprog);
4477 wxLogMessage(
"Starting chart database Update...");
4481 m_gshhg_chart_loc = gWorldMapLocation;
4482 gWorldMapLocation = wxEmptyString;
4486 AbstractPlatform::HideBusySpinner();
4490void MyFrame::FinalizeChartDBUpdate() {
4492 if (!g_bDeferredInitDone) {
4494 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4497 bool b_groupchange = ScrubGroupArray();
4499 RefreshGroupIndices();
4501 if (b_groupchange) {
4502 pConfig->DestroyConfigGroups();
4507 if (g_bDeferredInitDone) ScheduleReloadCharts();
4512 cc->ToggleCanvasQuiltMode();
4514 bool cur_mode = cc->GetQuiltMode();
4516 if( !cc->GetQuiltMode() )
4517 cc->SetQuiltMode(
true );
4519 if( cc->GetQuiltMode() ) {
4520 cc->SetQuiltMode(
false );
4521 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4525 if( cur_mode != cc->GetQuiltMode() ){
4531 g_bQuiltEnable = cc->GetQuiltMode();
4535 ps52plib->GenerateStateHash();
4543 DoStackDelta(cc, -1);
4549 DoStackDelta(cc, 1);
4552void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4554void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4556void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4558 cc->DoCanvasStackDelta(direction);
4562void MyFrame::PositionIENCToolbar() {
4566 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4568 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4576void MyFrame::OnInitTimer(wxTimerEvent &event) {
4579 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4583 wxLog::FlushActive();
4585 switch (m_iInitCount++) {
4587 EnableSettingsTool(
false);
4592 if (g_bInlandEcdis) {
4593 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4594 double range_set = 500.;
4596 range = wxRound(range * 10) / 10.;
4600 else if (range > 2000.)
4602 else if (range > 1600.)
4604 else if (range > 1200.)
4606 else if (range > 800.)
4611 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4615 g_Platform->SetFullscreen(g_bFullscreen);
4619 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4622 cc->SetGroupIndex(0,
false);
4629 StartRebuildChartDatabase();
4640 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4654 3 * GetCharHeight());
4656 m_data_monitor->Center();
4664 pConfig->SetPath(
"/Settings");
4665 pConfig->Read(
"OptionsSizeX", &sx, -1);
4666 pConfig->Read(
"OptionsSizeY", &sy, -1);
4668 wxWindow *optionsParent =
this;
4670 optionsParent = GetPrimaryCanvas();
4672 BuildiENCToolbar(
true, m_toolbar_callbacks);
4679 if (!g_params.empty()) {
4680 for (
size_t n = 0; n < g_params.size(); n++) {
4681 wxString path = g_params[n];
4682 if (::wxFileExists(path)) {
4684 pSet->load_file(path.fn_str());
4687 pSet->LoadAllGPXObjects(
4688 !pSet->IsOpenCPN(), wpt_dups,
4690 LLBBox box = pSet->GetBBox();
4691 if (box.GetValid()) {
4692 CenterView(GetPrimaryCanvas(), box);
4701 InitAppMsgBusListener();
4706 auto loader = PluginLoader::GetInstance();
4707 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4708 if (!b_haveWMM)
gVar = g_UserVar;
4716 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4719 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4721 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4724 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4728 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4729 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4730 NavObj_dB::GetInstance().LoadNavObjects();
4733 if (!g_AW1GUID.IsEmpty()) {
4736 if (!g_AW2GUID.IsEmpty()) {
4742 appendOSDirSlash(&layerdir);
4743 layerdir.Append(
"layers");
4745 if (wxDir::Exists(layerdir)) {
4747 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4748 wxLogMessage(laymsg);
4749 pConfig->LoadLayers(layerdir);
4754 if (!g_kiosk_startup) {
4755 AbstractPlatform::ShowBusySpinner();
4758 pConfig->SetPath(
"/Settings");
4759 pConfig->Read(
"OptionsSizeX", &sx, -1);
4760 pConfig->Read(
"OptionsSizeY", &sy, -1);
4762 wxWindow *optionsParent =
this;
4764 optionsParent = GetPrimaryCanvas();
4767 callbacks.prepare_close = [&](
options *me,
int changes) {
4768 PrepareOptionsClose(me, changes);
4770 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4771 ProcessOptionsDialog(changes, workdir_list);
4774 wxPoint(-1, -1), wxSize(sx, sy));
4775 AbstractPlatform::HideBusySpinner();
4782 wxLogMessage(
"OnInitTimer...Last Call");
4786 RequestNewMasterToolbar();
4788 PositionIENCToolbar();
4790 g_bDeferredInitDone =
true;
4800 GetPrimaryCanvas()->SetFocus();
4801 GetPrimaryCanvas()->Enable();
4804 if (b_reloadForPlugins) {
4810 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4812 if (cc) cc->SetFirstAuto(
true);
4820 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4822 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4826 cc->CheckGroupValid();
4827 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4828 cc->SetShowGPSCompassWindow(
true);
4833 androidEnableBackButton(
true);
4834 androidEnableRotation();
4835 androidEnableOptionItems(
true);
4839 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4845 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4847 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4849 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4855 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4857 wxLog::FlushActive();
4859 RefreshAllCanvas(
true);
4860 UsbWatchDaemon::GetInstance().Start();
4861 EnableSettingsTool(
true);
4867void MyFrame::InitAppMsgBusListener() {
4868 auto &msgbus = AppMsgBus::GetInstance();
4871 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4872 listener_basic_navdata.Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4876 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4877 HandleBasicNavMsg(basicnav_msg);
4881 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4882 listener_gps_watchdog.Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4886 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4887 HandleGPSWatchdogMsg(msg);
4894void MyFrame::ReleaseApiListeners() {}
4899 m_on_raise_listener.Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4900 m_on_quit_listener.Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4901 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4902 server.open_file_cb = [&](
const std::string &path) {
4903 return m_open_gpx_file(path);
4910void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4911 if (msg->gps_watchdog <= 0) {
4912 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4916 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4921 if (m_fix_start_time.IsValid()) {
4922 wxDateTime now = wxDateTime::Now();
4923 wxTimeSpan span = now - m_fix_start_time;
4924 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4925 auto ¬eman = NotificationManager::GetInstance();
4926 wxString msg = _(
"GNSS Position fix lost");
4927 noteman.AddNotification(NotificationSeverity::kCritical,
4929 m_fix_start_time = wxInvalidDateTime;
4933 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4934 bool last_bVelocityValid = bVelocityValid;
4935 bVelocityValid =
false;
4942void MyFrame::CalculateCOGAverage() {
4944 if (!std::isnan(
gCog)) {
4947 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4950 double sum = 0., count = 0;
4952 double adder = COGTable[i];
4953 if (std::isnan(adder))
continue;
4955 if (fabs(adder -
g_COGAvg) > 180.) {
4969 else if (sum >= 360.)
4978void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4979 m_fixtime = msg->time;
4980 double hdt_data_interval = 0;
4981 double fix_time_interval = 0;
4983 double msgtime = msg->set_time.tv_sec;
4984 double m1 = msg->set_time.tv_nsec / 1e9;
4987 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4988 ((msg->vflag & POS_VALID) == POS_VALID)) {
4990 if (!m_fix_start_time.IsValid()) {
4991 m_fix_start_time = wxDateTime::Now();
4996 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4999 fix_time_gt_last = fix_time_gt;
5000 uint64_t fix_time_gt_now =
5001 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5002 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5006 double implied_sog = dist / (fix_time_interval / 3600);
5011 gLat_gt_m1 = gLat_gt;
5012 gLon_gt_m1 = gLon_gt;
5016 fix_time_gt = fix_time_gt_now;
5020 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5021 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5022 gCog_gt_m1 = gCog_gt;
5032 if (!std::isnan(gCog_gt_m1)) {
5034 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5041 if ((fix_time_gt - fix_time_gt_last) > .08) {
5046 if (gCog_gt > gCog_gt_m1) {
5047 if ((gCog_gt - gCog_gt_m1) > 180.)
5052 if ((gCog_gt_m1 - gCog_gt) > 180.)
5057 difft = fabs(gCog_gt - gCog_gt_m1);
5058 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5066 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5067 tentative_cog_rate_gt *= 1e9;
5068 cog_rate_gt = tentative_cog_rate_gt;
5076 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5079static double hdt_avg;
5080 double hdt_norm =
gHdt;
5081 if(
gHdt > 180) hdt_norm -= 360;
5084 hdt_avg += hdt_norm * 0.1;
5089 if (!std::isnan(
gHdt)) {
5091 uint64_t hdt_time_gt_last = hdt_time_gt;
5092 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5093 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5096 if (hdt_data_interval > .09) {
5098 gHdt_gt_m1 = gHdt_gt;
5101 if (!std::isnan(gHdt_gt_m1)) {
5103 double tentative_hdt_rate_gt =
5104 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5105 tentative_hdt_rate_gt *= 1e9;
5107 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5108 hdt_rate_gt = tentative_hdt_rate_gt;
5116 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5119 CalculateCOGAverage();
5127 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5128 if ((msg->vflag & POS_VALID) == POS_VALID)
5133 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5135 bVelocityValid =
true;
5139void MyFrame::UpdateStatusBar() {
5142 unsigned long uiCurrentTickCount;
5143 m_MMEAeventTime.SetToCurrent();
5144 uiCurrentTickCount =
5145 m_MMEAeventTime.GetMillisecond() / 100;
5146 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5147 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5148 m_ulLastNMEATicktime = uiCurrentTickCount;
5150 if (m_tick_idx++ > 6) m_tick_idx = 0;
5155 if (NULL != GetStatusBar()) {
5158 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5161 wxString s1(tick_buf, wxConvUTF8);
5163 s1 += toSDMM(1,
gLat);
5165 s1 += toSDMM(2,
gLon);
5167 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5171 if (!std::isnan(
gSog))
5172 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5174 sogcog.Printf(
"SOG --- ");
5178 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5180 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5182 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5183 (
int)toMagnetic(
gCog), 0x00B0);
5185 cogs.Printf((
"COG ---%c"), 0x00B0);
5187 sogcog.Append(cogs);
5188 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5193void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5194 MemFootTimer.Stop();
5196 int memsize = GetApplicationMemoryUse();
5199 printf(
"Memsize: %d \n", memsize);
5202 if (memsize > (g_MemFootMB * 1000)) {
5206 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5207 unsigned int nCache = pCache->GetCount();
5210 for (
unsigned int i = 0; i < nCache; i++) {
5220 for (
unsigned int i = 0; i < nCache - 1; i++) {
5221 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5223 pcea[i] = pcea[i + 1];
5234 unsigned int idelete = 0;
5235 unsigned int idelete_max = pCache->GetCount();
5238 unsigned int minimum_cache = 1;
5239 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5241 while ((memsize > (g_MemFootMB * 1000)) &&
5242 (pCache->GetCount() > minimum_cache) &&
5243 (idelete < idelete_max)) {
5244 int memsizeb = memsize;
5248 memsize = GetApplicationMemoryUse();
5249 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5257 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5262void MyFrame::CheckToolbarPosition() {
5265 static bool bMaximized;
5267 if (IsMaximized() && !bMaximized) {
5274 PositionIENCToolbar();
5275 }
else if (!IsMaximized() && bMaximized) {
5283 PositionIENCToolbar();
5288void MyFrame::ProcessUnitTest() {
5289 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5296 cc->m_bFollow =
false;
5298 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5299 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5302 if (cc->m_groupIndex > 0) {
5303 while (ut_index < ChartData->GetChartTableEntries() &&
5304 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5308 if (ut_index < ChartData->GetChartTableEntries()) {
5312 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5313 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5320 if (cc->GetQuiltMode()) {
5321 if (cc->IsChartQuiltableRef(ut_index))
5322 cc->SelectQuiltRefdbChart(ut_index);
5324 cc->SelectdbChart(ut_index);
5327 if (g_unit_test_1) {
5335 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5336 cte->GetLatMin(), cte->GetLonMax(), NULL,
5340 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5341 cte->GetLatMax(), cte->GetLonMin(), NULL,
5344 cc->GetSize(&ww, &wh);
5345 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5347 ppm = wxMin(ppm, 1.0);
5354 if (ut_index > ut_index_max) exit(0);
5365 bool b_rotate =
false;
5367 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5370 if (!b_rotate && !g_btenhertz)
return;
5372 bool b_update =
false;
5374 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5377 struct timespec now;
5378 clock_gettime(CLOCK_MONOTONIC, &now);
5379 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5380 double diffc = diff / 1e9;
5383 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5384 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5385 if (gCog_tentative < 0.) gCog_tentative += 360.;
5386 gCog = gCog_tentative;
5390 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5391 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5392 double diffc = diff / 1e9;
5393 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5397 if (gSog_gt && !std::isnan(gCog_gt)) {
5398 double delta_t = diffc / 3600;
5399 double distance = gSog_gt * delta_t;
5402 double angr = gCog_gt / 180 * M_PI;
5403 double latr = gLat_gt * M_PI / 180;
5404 double D = distance / 3443;
5405 double sD = sin(D), cD = cos(D);
5406 double sy = sin(latr), cy = cos(latr);
5407 double sa = sin(angr), ca = cos(angr);
5409 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5410 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5420 if (cc) cc->DoCanvasCOGSet();
5429 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5430 bool bnew = cc->DoCanvasUpdate();
5431 if (!bnew) cc->UpdateShips();
5440 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5443bool MyFrame::ProcessQuitFlag() {
5447 FrameTenHzTimer.Stop();
5449 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5450 if (top) top->Close(
true);
5457void MyFrame::ProcessDeferredTrackOn() {
5460 if (g_bDeferredStartTrack) {
5461 if (!g_bTrackActive) {
5464 g_bDeferredStartTrack =
false;
5467 g_bDeferredStartTrack =
false;
5472void MyFrame::ProcessAnchorWatch() {
5480 double d = g_nAWMax;
5483 bool toofar =
false;
5484 bool tooclose =
false;
5485 if (d >= 0.0) toofar = (dist * 1852. > d);
5486 if (d < 0.0) tooclose = (dist * 1852 < -d);
5488 if (tooclose || toofar)
5489 AnchorAlertOn1 =
true;
5491 AnchorAlertOn1 =
false;
5493 AnchorAlertOn1 =
false;
5501 double d = g_nAWMax;
5504 bool toofar =
false;
5505 bool tooclose =
false;
5506 if (d >= 0) toofar = (dist * 1852. > d);
5507 if (d < 0) tooclose = (dist * 1852 < -d);
5509 if (tooclose || toofar)
5510 AnchorAlertOn2 =
true;
5512 AnchorAlertOn2 =
false;
5514 AnchorAlertOn2 =
false;
5517 AnchorAlertOn1 =
true;
5520void MyFrame::SendFixToPlugins() {
5531 GPSData.
nSats = g_SatsInView;
5533 wxDateTime tCheck((time_t)m_fixtime);
5534 if (tCheck.IsValid()) {
5543 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5546 SendPositionFixToAllPlugIns(&GPSData);
5550void MyFrame::ProcessLogAndBells() {
5553 wxDateTime lognow = wxDateTime::Now();
5554 int hourLOC = lognow.GetHour();
5555 int minuteLOC = lognow.GetMinute();
5557 int minuteUTC = lognow.GetMinute();
5558 int second = lognow.GetSecond();
5560 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5561 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5562 (minuteUTC == 30)) {
5563 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5564 wxString day = lognow.FormatISODate();
5565 wxString utc = lognow.FormatISOTime();
5566 wxString navmsg =
"LOGBOOK: ";
5574 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5578 if (std::isnan(
gCog))
5579 cog.Printf(
"COG ----- ");
5581 cog.Printf(
"COG %10.5f ",
gCog);
5584 if (std::isnan(
gSog))
5585 sog.Printf(
"SOG ----- ");
5587 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5593 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5596 wxLogMessage(navmsg);
5597 g_loglast_time = lognow;
5599 int bells = (hourLOC % 4) * 2;
5600 if (minuteLOC != 0) bells++;
5601 if (!bells) bells = 8;
5603 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5604 m_BellsToPlay = bells;
5605 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5606 wxPostEvent(
this, ev);
5613 CheckToolbarPosition();
5617 if (ProcessQuitFlag())
return;
5619 if (bDBUpdateInProgress)
return;
5622 FrameTenHzTimer.Stop();
5624 ProcessDeferredTrackOn();
5626 ProcessAnchorWatch();
5627 ProcessLogAndBells();
5629 if (ShouldRestartTrack()) TrackDailyRestart();
5632 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5633 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5634 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5640 if (
gSog > 3.0) g_bCruising =
true;
5646 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5648 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5654 bool bnew_view =
false;
5655 if (!g_btenhertz) bnew_view = DoChartUpdate();
5662 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5665 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5668 cc->DrawBlinkObjects();
5671 if (bactiveRouteUpdate) {
5678 cc->SetOwnShipState(SHIP_NORMAL);
5680 if (cc->GetQuiltMode()) {
5681 double erf = cc->GetQuiltMaxErrorFactor();
5682 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5684 if (cc->m_singleChart) {
5685 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5686 cc->SetOwnShipState(SHIP_LOWACCURACY);
5690 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5693 (bVelocityValid != m_last_bVelocityValid) ||
5694 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5695 if (!g_bopengl) cc->UpdateShips();
5703 m_last_bVelocityValid = bVelocityValid;
5708 bool brq_dynamic =
false;
5710 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5711 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5713 if (pic->m_enabled && pic->m_init_state) {
5714 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5721 if (brq_dynamic) bnew_view =
true;
5725 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5728 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5733 if (cc->GetglCanvas()) {
5735 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5737 if ((!g_btenhertz)) {
5738 if (cc->m_bFollow) {
5739 cc->DoCanvasUpdate();
5756 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5770 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5771 g_pais_query_dialog_active->UpdateText();
5774 if (g_pAISTargetList && (0 == (g_tick % (5))))
5775 g_pAISTargetList->UpdateAISTargetList();
5778 UpdateGPSCompassStatusBoxes();
5783 console->RefreshConsoleData();
5790 if (m_bdefer_resize) {
5791 if (0 == (g_tick % (5))) {
5792 printf(
"___RESIZE\n");
5793 SetSize(m_defer_size);
5795 m_bdefer_resize =
false;
5802 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5804 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5805 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5809double MyFrame::GetMag(
double a,
double lat,
double lon) {
5810 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5811 auto loader = PluginLoader::GetInstance();
5812 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5819 wxDateTime now = wxDateTime::Now();
5820 SendJSON_WMM_Var_Request(lat, lon, now);
5821 if (fabs(gQueryVar) < 360.0)
5822 Variance = gQueryVar;
5824 return toMagnetic(a, Variance);
5827bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5833 v[
"Year"] = date.GetYear();
5834 v[
"Month"] = date.GetMonth();
5835 v[
"Day"] = date.GetDay();
5837 SendJsonMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5843void MyFrame::TouchAISActive() {
5845 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5847 if (cc) cc->TouchAISToolActive();
5851void MyFrame::UpdateAISTool() {
5855 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5857 if (cc) cc->UpdateAISTBTool();
5862void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5864 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5866 if (cc) cc->SetbTCUpdate(
true);
5869 RefreshAllCanvas(
false);
5874void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5878 bool b_rotate =
false;
5879 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5881 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5885 FrameCOGTimer.Stop();
5892 int period_ms = 100;
5894 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5897void MyFrame::DoCOGSet() {
5899 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5901 if (cc) cc->DoCanvasCOGSet();
5905void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5911 wxFont oldfont = pdc->GetFont();
5913 pdc->SetFont(*pFont);
5914 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5915 pdc->SetBackgroundMode(wxTRANSPARENT);
5917 pdc->DrawText(str, x, y + 1);
5918 pdc->DrawText(str, x, y - 1);
5919 pdc->DrawText(str, x + 1, y);
5920 pdc->DrawText(str, x - 1, y);
5922 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5924 pdc->DrawText(str, x, y);
5926 pdc->SetFont(oldfont);
5930void MyFrame::UpdateRotationState(
double rotation) {
5932 g_bCourseUp =
false;
5934 if (fabs(rotation) > .001) {
5935 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5936 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5938 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5941 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5942 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5944 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5948 UpdateGPSCompassStatusBoxes(
true);
5952void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5954 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5956 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5962int MyFrame::GetApplicationMemoryUse() {
5968 wxWindow *fWin = wxWindow::FindFocus();
5970 wxArrayString outputArray;
5971 wxString cmd(
"ps --no-headers -o vsize ");
5972 unsigned long pid = wxGetProcessId();
5974 cmd1.Printf(
"%ld", pid);
5976 wxExecute(cmd, outputArray);
5978 if (outputArray.GetCount()) {
5979 wxString s = outputArray.Item(0);
5981 if (s.ToLong(&vtmp)) memsize = vtmp;
5984 if (fWin) fWin->SetFocus();
5990 PROCESS_MEMORY_COUNTERS pmc;
5992 unsigned long processID = wxGetProcessId();
5994 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5996 if (NULL == hProcess)
return 0;
5998 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6016 memsize = pmc.WorkingSetSize / 1024;
6019 CloseHandle(hProcess);
6026double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6027 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6030void MyFrame::SetChartUpdatePeriod() {
6033 g_ChartUpdatePeriod = 0;
6038 bool bskewdc =
false;
6039 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6042 if (!g_bopengl && !cc->GetVP().b_quilt) {
6043 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6045 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6049 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6051 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6056 cc->UpdateCanvasControlBar();
6059void MyFrame::selectChartDisplay(
int type,
int family) {
6061 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6063 if (cc) cc->selectCanvasChartDisplay(type, family);
6066 UpdateGlobalMenuItems();
6075bool MyFrame::DoChartUpdate() {
6076 bool return_val =
false;
6079 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6081 if (cc) return_val |= cc->DoCanvasUpdate();
6087void MyFrame::MouseEvent(wxMouseEvent &event) {
6089 event.GetPosition(&x, &y);
6094#include <mach/mach.h>
6095#include <mach/message.h>
6096#include <mach/kern_return.h>
6097#include <mach/task_info.h>
6099#include <malloc/malloc.h>
6106#if defined(__linux__)
6107#include "sys/types.h"
6108#include "sys/sysinfo.h"
6111void MyFrame::DoPrint(
void) {
6113 g_PrintingInProgress =
true;
6116 GetPrimaryCanvas()->GetglCanvas()->Render();
6117 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6127 printer.Initialize(wxLANDSCAPE);
6128 printer.EnablePageNumbers(
false);
6131 bool tooltips_were_enabled = DisableTbarTooltips();
6132 printer.Print(
this, &printout);
6133 if (tooltips_were_enabled) {
6134 EnableTbarTooltips();
6153 g_PrintingInProgress =
false;
6156 GetPrimaryCanvas()->SetFocus();
6162 wxString message_ID =
event.GetID();
6163 wxString message_JSONText =
event.GetJSONText();
6171 if (message_ID ==
"WMM_VARIATION_BOAT") {
6172 nlohmann::json root;
6174 root = nlohmann::json::parse(message_JSONText);
6175 }
catch (nlohmann::json::exception &) {
6180 gVar = root[
"Decl"].get<
double>();
6181 }
catch (nlohmann::json::exception &) {
6187 if (message_ID ==
"WMM_VARIATION") {
6188 nlohmann::json root;
6190 root = nlohmann::json::parse(message_JSONText);
6191 }
catch (nlohmann::json::exception &) {
6194 wxString decl = root[
"Decl"].get<std::string>();
6196 decl.ToDouble(&decl_val);
6198 gQueryVar = decl_val;
6201 if (message_ID ==
"GRIB_TIMELINE") {
6204 v = nlohmann::json::parse(message_JSONText);
6205 }
catch (nlohmann::json::exception &) {
6206 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6209 wxDateTime oldTimeSource = gTimeSource;
6211 if (v[
"Day"].get<int>() == -1) {
6212 gTimeSource = wxInvalidDateTime;
6213 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6215 gTimeSource.Set(v[
"Day"].get<int>(),
6216 (wxDateTime::Month)v[
"Month"].get<int>(),
6217 v[
"Year"].get<int>(), v[
"Hour"].get<int>(),
6218 v[
"Minute"].get<int>(), v[
"Second"].get<int>());
6222 if (oldTimeSource != gTimeSource) {
6224 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6226 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6231 cc->pCwin->Refresh(
false);
6237 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6238 nlohmann::json root;
6239 wxString trk_id =
"";
6242 root = nlohmann::json::parse(message_JSONText);
6243 }
catch (nlohmann::json::exception &) {
6246 if (root.contains(
"Track_ID")) trk_id = root[
"Track_ID"].get<std::string>();
6249 v[
"Track_ID"] = trk_id;
6251 wxString name = wxEmptyString;
6252 if (ptrack->m_GUID == trk_id) {
6253 name = ptrack->GetName();
6254 if (name.IsEmpty()) {
6260 name = _(
"(Unnamed Track)");
6267 v[
"TotalNodes"] = ptrack->GetnPoints();
6268 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6270 v[
"lat"] = tp->m_lat;
6271 v[
"lon"] = tp->m_lon;
6274 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6279 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6281 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6282 nlohmann::json root;
6285 root = nlohmann::json::parse(message_JSONText);
6286 }
catch (nlohmann::json::exception &) {
6290 if (root.contains(
"GUID")) guid = root[
"GUID"].get<std::string>();
6295 wxString name = wxEmptyString;
6297 if ((*it)->m_GUID == guid) {
6298 name = (*it)->m_RouteNameString;
6299 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6305 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6306 itp != (*it)->pRoutePointList->end(); itp++) {
6307 w[i][
"lat"] = (*itp)->m_lat;
6308 w[i][
"lon"] = (*itp)->m_lon;
6309 w[i][
"Name"] = (*itp)->GetName();
6310 w[i][
"Description"] = (*itp)->GetDescription();
6311 w[i][
"GUID"] = (*itp)->m_GUID;
6312 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6314 auto node = (*itp)->m_HyperlinkList->begin();
6315 if (node != (*itp)->m_HyperlinkList->end()) {
6317 while (node != (*itp)->m_HyperlinkList->end()) {
6319 v[i][
"WPLink" + std::to_string(n)] = httpLink->Link;
6320 v[i][
"WPLinkDesciption" + std::to_string(n++)] =
6321 httpLink->DescrText;
6328 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6334 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6335 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6336 nlohmann::json root;
6339 root = nlohmann::json::parse(message_JSONText);
6340 }
catch (nlohmann::json::exception &) {
6343 if (root.contains(
"mode")) {
6344 if (root[
"mode"].get<std::string>() ==
"Track") route =
false;
6349 for (RouteList::iterator it =
pRouteList->begin();
6351 wxString name = (*it)->m_RouteNameString;
6352 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6354 v[i][
"error"] =
false;
6355 v[i][
"name"] = name;
6356 v[i][
"GUID"] = (*it)->m_GUID;
6357 v[i][
"active"] = (*it)->IsActive();
6362 wxString name = ptrack->GetName();
6363 if (name.IsEmpty()) {
6369 name = _(
"(Unnamed Track)");
6371 v[i][
"error"] =
false;
6372 v[i][
"name"] = name;
6373 v[i][
"GUID"] = ptrack->m_GUID;
6378 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6381 v[0][
"error"] =
true;
6382 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6384 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6386 v[0][
"error"] =
true;
6389 v[0][
"error"] =
false;
6390 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6391 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6392 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6393 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6394 v[0][
"active_waypoint_lat"] =
6396 v[0][
"active_waypoint_lon"] =
6400 SendJsonMessageToAllPlugins(
"OCPN_ACTIVE_ROUTELEG_RESPONSE", v);
6404void MyFrame::FilterCogSog() {
6405 if (g_bfilter_cogsog) {
6407 double cog_last =
gCog;
6410 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6411 COGFilterTable[i] = COGFilterTable[i - 1];
6412 COGFilterTable[0] = cog_last;
6415 if (!std::isnan(cog_last)) {
6417 double sum = 0., count = 0;
6418 for (
int i = 0; i < g_COGFilterSec; i++) {
6419 double adder = COGFilterTable[i];
6420 if (std::isnan(adder))
continue;
6422 if (fabs(adder - cog_last) > 180.) {
6423 if ((adder - cog_last) > 0.)
6436 else if (sum >= 360.)
6443 double sog_last =
gSog;
6446 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6447 SOGFilterTable[i] = SOGFilterTable[i - 1];
6448 SOGFilterTable[0] = sog_last;
6451 if (!std::isnan(
gSog)) {
6452 double sum = 0., count = 0;
6453 for (
int i = 0; i < g_SOGFilterSec; i++) {
6454 if (std::isnan(SOGFilterTable[i]))
continue;
6456 sum += SOGFilterTable[i];
6466void MyFrame::LoadHarmonics() {
6469 ptcmgr->LoadDataSources(TideCurrentDataSet);
6471 bool b_newdataset =
false;
6474 for (
auto a :
ptcmgr->GetDataSet()) {
6475 bool b_foundi =
false;
6476 for (
auto b : TideCurrentDataSet) {
6483 b_newdataset =
true;
6488 for (
auto a : TideCurrentDataSet) {
6489 bool b_foundi =
false;
6490 for (
auto b :
ptcmgr->GetDataSet()) {
6497 b_newdataset =
true;
6502 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6506void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6507 if (!ptarget)
return;
6510 wxDateTime mob_time = wxDateTime::Now();
6511 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6512 mob_label += _(
" on ");
6513 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6516 mob_label, wxEmptyString);
6517 pWP_MOB->SetShared(
true);
6519 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6521 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6523 pWP_MOB->SetUseSca(
false);
6531 wxString(_(
"Own ship")), wxEmptyString);
6533 pWP_MOB->SetUseSca(
false);
6540 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6556 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
6559 if (RouteManagerDialog::getInstanceFlag()) {
6566 RefreshAllCanvas(
false);
6568 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6569 mob_message += _(
" Time: ");
6570 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6571 mob_message += _(
" Ownship Position: ");
6572 mob_message += toSDMM(1,
gLat);
6574 mob_message += toSDMM(2,
gLon);
6575 mob_message += _(
" MOB Position: ");
6576 mob_message += toSDMM(1, ptarget->Lat);
6578 mob_message += toSDMM(2, ptarget->Lon);
6579 wxLogMessage(mob_message);
6582void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6586 OwnPoint->m_lat =
gLat;
6587 OwnPoint->m_lon =
gLon;
6589 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6594 MOB_Point->m_lat = ptarget->Lat;
6595 MOB_Point->m_lon = ptarget->Lon;
6597 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6598 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6600 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6601 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6604 RefreshAllCanvas(
false);
6607 wxDateTime mob_time = wxDateTime::Now();
6609 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6610 mob_message += _(
" Time: ");
6611 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6612 mob_message += _(
" Ownship Position: ");
6613 mob_message += toSDMM(1,
gLat);
6615 mob_message += toSDMM(2,
gLon);
6616 mob_message += _(
" MOB Position: ");
6617 mob_message += toSDMM(1, ptarget->Lat);
6619 mob_message += toSDMM(2, ptarget->Lon);
6621 wxLogMessage(mob_message);
6625void MyFrame::applySettingsString(wxString settings) {
6627 int last_UIScaleFactor = g_GUIScaleFactor;
6628 bool previous_expert = g_bUIexpert;
6629 g_last_ChartScaleFactor = g_ChartScaleFactor;
6630 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6633 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6639 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6641 if (rr & S52_CHANGED) {
6643 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6645 ->ClearCNSYLUPArray();
6646 ps52plib->GenerateStateHash();
6650 ProcessOptionsDialog(rr, pNewDirArray);
6655 bool b_newToolbar =
false;
6657 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6659 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6661 if (rr & TOOLBAR_CHANGED) {
6662 b_newToolbar =
true;
6667 if (previous_expert && !g_bUIexpert) {
6668 androidForceFullRepaint();
6672 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6676 SetGPSCompassScale();
6678 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6680 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6682 UpdateGPSCompassStatusBoxes(
true);
6685 AbstractPlatform::ShowBusySpinner();
6687 SetAllToolbarScale();
6691 AbstractPlatform::HideBusySpinner();
6693 RequestNewMasterToolbar(
true);
6700 UpdateControlBar(GetPrimaryCanvas());
6706 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6709#ifdef wxHAS_POWER_EVENTS
6710void MyFrame::OnSuspending(wxPowerEvent &event) {
6714 wxLogMessage(
"System suspend starting...");
6717void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6720 wxLogMessage(
"System is going to suspend.");
6723void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6726 wxLogMessage(
"System suspend was cancelled.");
6729int g_last_resume_ticks;
6730void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6731 wxDateTime now = wxDateTime::Now();
6732 wxLogMessage(
"System resumed from suspend.");
6734 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6735 SystemEvents::GetInstance().
evt_resume.Notify();
6737 wxLogMessage(
"Restarting streams.");
6738 g_last_resume_ticks = now.GetTicks();
6742 g_pMUX->ClearStreams();
6744 g_pMUX->StartAllStreams();
6753 if (IsMaximized()) {
6758 wxSize sz = GetSize();
6759 SetSize(wxSize(sz.x - 1, sz.y));
6771void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6772 bool btbRebuild =
false;
6774 bool b_reshow =
true;
6777 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6778 if ((ff > 0.01f) || bforcenew) {
6788 long orient = g_Platform->GetDefaultToolbarOrientation();
6789 wxWindow *toolbarParent =
this;
6791 toolbarParent = GetPrimaryCanvas();
6794 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6795 m_toolbar_callbacks);
6797 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6804 g_bmasterToolbarFull =
true;
6808 CreateMasterToolbar();
6823bool MyFrame::CollapseGlobalToolbar() {
6825 m_nMasterToolCountShown = 1;
6829 g_bmasterToolbarFull =
false;
6845 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6846 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6847 tic->m_bRequired =
true;
6852 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6853 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6857 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6858 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6859 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6864 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6865 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6869 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6870 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6871 _(
"Enable Tracking"),
"MUI_track");
6875 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6876 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6888 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6889 _(
"Print Chart"),
"MUI_print");
6893 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6894 _(
"About OpenCPN"),
"MUI_help");
6898 AddDefaultPositionPlugInTools();
6902 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6903 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6914 ArrayOfPlugInToolbarTools tool_array =
6916 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6918 if (!pttc->b_viz)
continue;
6920 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6923 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6924 if (g_bTrackActive) {
6925 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6932bool MyFrame::CheckAndAddPlugInTool() {
6940 if (!tb)
return false;
6942 int n_tools = tb->GetToolsCount();
6946 ArrayOfPlugInToolbarTools tool_array =
6949 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6951 if (pttc->position == n_tools) {
6952 wxBitmap *ptool_bmp;
6954 switch (global_color_scheme) {
6955 case GLOBAL_COLOR_SCHEME_DAY:
6956 ptool_bmp = pttc->bitmap_day;
6959 case GLOBAL_COLOR_SCHEME_DUSK:
6960 ptool_bmp = pttc->bitmap_dusk;
6962 case GLOBAL_COLOR_SCHEME_NIGHT:
6963 ptool_bmp = pttc->bitmap_night;
6966 ptool_bmp = pttc->bitmap_day;
6971 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6973 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6974 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6975 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6976 tic->m_bPlugin =
true;
6985 while (CheckAndAddPlugInTool()) {
6991bool MyFrame::AddDefaultPositionPlugInTools() {
6998 ArrayOfPlugInToolbarTools tool_array =
7001 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7005 if (!pttc->b_viz)
continue;
7007 if (pttc->position == -1)
7009 wxBitmap *ptool_bmp;
7011 switch (global_color_scheme) {
7012 case GLOBAL_COLOR_SCHEME_DAY:
7013 ptool_bmp = pttc->bitmap_day;
7015 case GLOBAL_COLOR_SCHEME_DUSK:
7016 ptool_bmp = pttc->bitmap_dusk;
7018 case GLOBAL_COLOR_SCHEME_NIGHT:
7019 ptool_bmp = pttc->bitmap_night;
7022 ptool_bmp = pttc->bitmap_day;
7027 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7029 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7030 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7031 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7032 tic->m_bPlugin =
true;
7051typedef struct _MSW_COLOR_SPEC {
7053 wxString S52_RGB_COLOR;
7057MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7058 {COLOR_MENUTEXT,
"UITX1", 0},
7059 {COLOR_BTNSHADOW,
"UIBCK", 0},
7062void SaveSystemColors() {
7076 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7077 while (pcspec->COLOR_NAME != -1) {
7078 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7083void RestoreSystemColors() {
7084 int element[NCOLORS];
7085 int rgbcolor[NCOLORS];
7088 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7089 while (pcspec->COLOR_NAME != -1) {
7090 element[i] = pcspec->COLOR_NAME;
7091 rgbcolor[i] = pcspec->SysRGB_COLOR;
7096 if (pSetSysColors) {
7097 pSetSysColors(i, (
unsigned long *)&element[0],
7098 (
unsigned long *)&rgbcolor[0]);
7104void SetSystemColors(ColorScheme cs) {
7106 int element[NCOLORS];
7107 int rgbcolor[NCOLORS];
7109 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7110 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7111 while (pcspec->COLOR_NAME != -1) {
7112 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7113 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7114 element[i] = pcspec->COLOR_NAME;
7120 pSetSysColors(i, (
unsigned long *)&element[0],
7121 (
unsigned long *)&rgbcolor[0]);
7125 RestoreSystemColors();
7132static const WORD MAX_CONSOLE_LINES =
7137void RedirectIOToConsole()
7142 wxIntPtr lStdHandle;
7144 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7154 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7155 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7156 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7160 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7161 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7162 fp = _fdopen(hConHandle,
"w");
7164 setvbuf(stdout, NULL, _IONBF, 0);
7168 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7169 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7170 fp = _fdopen(hConHandle,
"r");
7172 setvbuf(stdin, NULL, _IONBF, 0);
7176 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7177 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7178 fp = _fdopen(hConHandle,
"w");
7180 setvbuf(stderr, NULL, _IONBF, 0);
7191 FontMgr::Get().SetLocale(g_locale);
7212 if (g_pais_query_dialog_active) {
7213 g_pais_query_dialog_active->Destroy();
7214 g_pais_query_dialog_active = NULL;
7217 auto alert_dlg_active =
7219 if (alert_dlg_active) {
7220 alert_dlg_active->Destroy();
7221 g_pais_alert_dialog_active =
nullptr;
7224 if (g_pAISTargetList) {
7226 g_pAISTargetList->Disconnect_decoder();
7227 g_pAISTargetList->Destroy();
7228 g_pAISTargetList = NULL;
7232 if (gFrame->m_pMenuBar) {
7233 gFrame->SetMenuBar(NULL);
7234 gFrame->m_pMenuBar->Destroy();
7235 gFrame->m_pMenuBar = NULL;
7237 gFrame->BuildMenuBar();
7240 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7242 if (cc) cc->CanvasApplyLocale();
7247 wxString perspective;
7249 pConfig->Read(
"AUIPerspective", &perspective);
7263 bool bno_load =
false;
7264 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7266 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7267 wxAuiPaneInfo pane = pane_array_val[i];
7268 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7274 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7279 gFrame->RequestNewToolbars(
true);
7280 gFrame->RequestNewMasterToolbar(
true);
7287 : wxThread(wxTHREAD_JOINABLE) {
7288 m_filename = filename;
7299 newChart->SetNativeScale(m_scale);
7300 newChart->SetFullExtent(m_ext);
7302 newChart->FindOrCreateSenc(m_filename);
7307 wxString m_filename;
7313static double chart_dist(
int index) {
7319 if (cte.GetBBox().Contains(
gLat,
gLon))
7324 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7325 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7326 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7329 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7330 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7332 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7338WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7339static int CompareInts(
int n1,
int n2) {
7340 double d1 = chart_dist(n1);
7341 double d2 = chart_dist(n2);
7342 return (
int)(d1 - d2);
7347 wxString chart_path;
7352WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7354#include <wx/arrimpl.cpp>
7357void ParseAllENC(wxWindow *parent) {
7358 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7366 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7369 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7371 idx_sorted_by_distance.Add(i);
7375 if (count == 0)
return;
7377 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7383 ArrayOfCompressTargets ct_array;
7384 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7385 int i = idx_sorted_by_distance[j];
7388 double distance = chart_dist(i);
7390 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7393 pct->distance = distance;
7394 pct->chart_path = filename;
7396 ct_array.push_back(pct);
7399 int thread_count = 0;
7402 if (g_nCPUCount > 0)
7403 thread_count = g_nCPUCount;
7405 thread_count = wxThread::GetCPUCount();
7407 if (thread_count < 1) {
7416 for(
int t = 0; t < thread_count; t++)
7420 wxGenericProgressDialog *prog =
nullptr;
7424 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7425 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7427 prog =
new wxGenericProgressDialog();
7429 prog->SetFont(*qFont);
7431 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7432 count + 1, parent, style);
7441 prog->ShowWindowModal();
7450 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7451 wxString filename = ct_array[j].chart_path;
7452 double distance = ct_array[j].distance;
7453 int index =
ChartData->FinddbIndex(filename);
7454 if (index < 0)
continue;
7457 ext.NLAT = cte.GetLatMax();
7458 ext.SLAT = cte.GetLatMin();
7459 ext.WLON = cte.GetLonMin();
7460 ext.ELON = cte.GetLonMax();
7462 int scale = cte.GetScale();
7465 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7468 if (wxThread::IsMain()) {
7470 wxSize sz = prog->GetSize();
7475 prog->Update(count, msg, &skip);
7487 newChart->SetNativeScale(
scale);
7488 newChart->SetFullExtent(ext);
7489 newChart->DisableBackgroundSENC();
7491 newChart->FindOrCreateSenc(filename,
7495 if (wxThread::IsMain()) {
7496 msg.Printf(_(
"ENC Completed."));
7498 prog->Update(count, msg, &skip);
7508 for (
int t = 0;; t = (t + 1) % thread_count) {
7515 if (!workers[t]->IsAlive()) {
7528#if defined(__WXMSW__) || defined(__WXOSX__)
7535 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().
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.
obs::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.
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.
obs::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.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
CommBridge class and helpers.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
double AnchorDistFix(double const d, double const AnchorPointMinDist, double const AnchorPointMaxDist)
Return constrained value of d so that AnchorPointMinDist < abs(d) < AnchorPointMaxDist.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Miscellaneous utilities, many of which string related.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
Generic hardware events interface.
WaypointMan drawing stuff.