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"
104#include "ais_info_gui.h"
128#include "load_errors_dlg.h"
131#include "N2KParser.h"
154#include "user_colors.h"
160#include "androidUTIL.h"
164static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
175GLenum g_texture_rectangle_format;
178#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
179extern wxLocale *plocale_def_lang;
183extern bool g_b_EnableVBO;
184extern GLenum g_texture_rectangle_format;
188static int g_last_ChartScaleFactor;
189static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
190static int options_subpage = 0;
191static bool b_reloadForPlugins;
193static wxSize options_lastWindowSize(0, 0);
194static wxPoint options_lastWindowPos(0, 0);
198static double gQueryVar = 361.0;
200static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
201static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
203static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
209typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
210typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
212static SetSysColors_t pSetSysColors;
213static GetSysColor_t pGetSysColor;
215void SaveSystemColors();
216void RestoreSystemColors();
221DWORD color_3ddkshadow;
223DWORD color_activecaption;
224DWORD color_gradientactivecaption;
225DWORD color_captiontext;
226DWORD color_windowframe;
227DWORD color_inactiveborder;
232#include <wx/msw/msvcrt.h>
236static const long long lNaN = 0xfff8000000000000;
237#define NAN (*(double *)&lNaN)
241static double gLat_gt, gLon_gt;
242static double gLat_gt_m1, gLon_gt_m1;
243static uint64_t fix_time_gt;
244static uint64_t fix_time_gt_last;
246static double gSog_gt, gHdt_gt;
247static double gCog_gt_m1, gHdt_gt_m1;
248static uint64_t hdt_time_gt;
249static double cog_rate_gt, hdt_rate_gt;
251void InitializeUserColors();
252void DeInitializeUserColors();
253void SetSystemColors(ColorScheme cs);
255static bool LoadAllPlugIns(
bool load_enabled) {
256 AbstractPlatform::ShowBusySpinner();
257 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
258 AbstractPlatform::HideBusySpinner();
262static void LaunchLocalHelp() {
264 androidLaunchHelpView();
266 wxString def_lang_canonical =
"en_US";
269 if (plocale_def_lang)
270 def_lang_canonical = plocale_def_lang->GetCanonicalName();
273 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
275 wxString help_try = help_locn + def_lang_canonical +
".html";
277 if (!::wxFileExists(help_try)) {
278 help_try = help_locn +
"en_US" +
".html";
280 if (!::wxFileExists(help_try)) {
281 help_try = help_locn +
"web" +
".html";
284 if (!::wxFileExists(help_try))
return;
287 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
292static wxString _menuText(wxString name, wxString shortcut) {
296 menutext <<
"\t" << shortcut;
301static void DoHelpDialog() {
313 [] { LaunchLocalHelp(); });
325#if defined(__WXGTK__) || defined(__WXQT__)
326#include "bitmaps/opencpn.xpm"
341 if (g_bInlandEcdis) {
345 wxPoint tbp_incanvas =
348 g_iENCToolbarPosY = tbp_incanvas.y;
349 g_iENCToolbarPosX = tbp_incanvas.x;
357 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
361 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
364 g_iENCToolbarPosY = -1;
367 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
373 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
377 double tool_scale_factor =
378 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
380 tool_scale_factor, callbacks);
390#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
393static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
394 const char *prop_name) {
398 unsigned long ret_nitems;
399 unsigned long ret_bytes_after;
400 unsigned char *ret_prop;
402 xa_prop_name = XInternAtom(disp, prop_name, False);
410 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
411 &xa_ret_type, &ret_format, &ret_nitems,
412 &ret_bytes_after, &ret_prop) != Success)
415 if (xa_ret_type != xa_prop_type) {
419 return (
char *)ret_prop;
424static bool isTransparentToolbarInOpenGLOK() {
431 if (!g_bdisable_opengl) {
432 Display *disp = XOpenDisplay(NULL);
434 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
436 "_NET_SUPPORTING_WM_CHECK")) ||
437 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
439 "_WIN_SUPPORTING_WM_CHECK"))) {
442 if ((wm_name = get_X11_property(disp, *sup_window,
443 XInternAtom(disp,
"UTF8_STRING", False),
445 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
448 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
463wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
465 font->GetFamily(), font->GetStyle(),
466 font->GetWeight(),
false, font->GetFaceName());
468wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
469 wxFontStyle style, wxFontWeight weight,
470 const wxString faceName,
double scale) {
474wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
475 return GetOCPNScaledFont_PlugIn(label, Ptsize);
484wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
486BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
487EVT_CLOSE(MyFrame::OnCloseWindow)
488EVT_MENU(wxID_EXIT, MyFrame::OnExit)
489EVT_SIZE(MyFrame::OnSize)
490EVT_MOVE(MyFrame::OnMove)
491EVT_ICONIZE(MyFrame::OnIconize)
492EVT_MENU(-1, MyFrame::OnToolLeftClick)
493EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
495EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
496EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
497EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
499EVT_MAXIMIZE(MyFrame::OnMaximize)
500EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
501 MyFrame::RequestNewToolbarArgEvent)
502EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
504EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
505EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
506EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
508#ifdef wxHAS_POWER_EVENTS
509EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
510EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
511EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
512EVT_POWER_RESUME(MyFrame::OnResume)
523static
void onBellsFinishedCB(
void *ptr) {
524 auto framePtr =
static_cast<MyFrame *
>(ptr);
526 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
527 wxPostEvent(framePtr, ev);
532 auto msg = ev.GetString().ToStdString();
533 auto ¬eman = NotificationManager::GetInstance();
534 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
537static NmeaLog *GetDataMonitor() {
538 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
539 return dynamic_cast<NmeaLog *
>(w);
542MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
543 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
544 OpenFileFunc open_gpx_file)
546 m_connections_dlg(nullptr),
548 m_pauidockart(pauidockart),
549 m_rest_server(rest_server),
550 m_open_gpx_file(open_gpx_file) {
562 m_ulLastNMEATicktime = 0;
563 m_data_monitor->Hide();
565 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
569 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
572 InitTimer.SetOwner(
this, INIT_TIMER);
574 m_initializing =
false;
575 m_toolbar_callbacks.render_gl_textures =
577 [&](
ocpnDC &dc,
float *coords,
float *uv) {
578 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
579 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
582 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
586 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
589 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
592 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
595 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
598 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
600 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
609 m_bTimeIsSet =
false;
610 m_bdefer_resize =
false;
613 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
614 COGFilterTable[i] = NAN;
615 SOGFilterTable[i] = NAN;
617 m_last_bGPSValid =
false;
618 m_last_bVelocityValid =
false;
628 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
633 double process_noise_std = 1.0;
634 double measurement_noise_std = 0.5;
638 m_ChartUpdatePeriod = 1;
643 log_callbacks.log_is_active = [&]() {
644 auto log = GetDataMonitor();
645 return log && log->IsVisible();
647 log_callbacks.log_message = [&](
Logline ll) {
648 NmeaLog *monitor = GetDataMonitor();
651 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
654 ais_callbacks.confirm_stop_track = []() {
655 int r = OCPNMessageBox(
657 _(
"This AIS target has Persistent tracking selected by MMSI "
659 "A Persistent track recording will therefore be restarted for this "
661 "Do you instead want to stop Persistent tracking for this target?"),
662 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
663 return r == wxID_YES;
665 ais_callbacks.get_target_mmsi = []() {
666 auto alert_dlg_active =
668 assert(alert_dlg_active);
669 return alert_dlg_active->Get_Dialog_MMSI();
677 wxLogMessage(
" **** Connect stuff");
683 Connect(wxEVT_OCPN_MSG,
684 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
692 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
700#if defined(__WXGTK__) || defined(__WXQT__)
701 wxIcon app_icon(opencpn);
709 wxDynamicLibrary dllUser32(
"user32.dll");
711 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
712 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
717 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
722 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
723 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
725 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
726 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
727 [&](wxCommandEvent) { Refresh(); });
728 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
730 m_update_statusbar_listener.Init(
731 GuiEvents::GetInstance().gframe_update_status_bar,
733 m_center_aistarget_listener.Init(
734 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
735 auto ais_target = obs::UnpackEvtPointer<AisTargetData>(ev);
736 CenterAisTarget(ais_target);
738 m_reload_charts_listener.Init(
739 GuiEvents::GetInstance().on_finalize_chartdbs,
740 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
744 EnableFullScreenView();
746 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
752 FrameTenHzTimer.Stop();
767 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
773void MyFrame::FreezeCharts() {
776 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
778 if (cc && !cc->IsFrozen()) cc->Freeze();
782void MyFrame::CenterAisTarget(
783 const std::shared_ptr<const AisTargetData> &ais_target) {
791 double factor = cc->GetScaleValue() / 5000.0;
792 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
798void MyFrame::ThawCharts() {
801 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
803 if (cc && cc->IsFrozen()) cc->Thaw();
810 switch (event.type) {
811 case SENC_BUILD_STARTED:
814 case SENC_BUILD_DONE_NOERROR:
816 chart =
event.m_ticket->m_chart;
818 chart->PostInit(FULL_INIT, global_color_scheme);
820 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
822 if (cc) cc->ClearS52PLIBStateHash();
829 delete event.m_ticket;
831 case SENC_BUILD_DONE_ERROR:
832 wxLogDebug(
"SENC build done: SENC_BUILD_DONE_ERROR");
835 delete event.m_ticket;
842bool MyFrame::StartRebuildChartDatabase() {
843 bool b_SetInitialPoint =
false;
846 ArrayOfCDI ChartDirArray;
847 pConfig->LoadChartDirArray(ChartDirArray);
849 if (ChartDirArray.GetCount()) {
854 _(
"OpenCPN needs to update the chart database from config file "
858 wxICON_INFORMATION | wxOK);
866 _(
"Rebuilding chart database from configuration file entries..."));
870 wxString dummy1 = _(
"Elapsed time : ");
871 wxString dummy2 = _(
"Estimated time : ");
872 wxString dummy3 = _(
"Remaining time : ");
873 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
874 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
884void MyFrame::OnBellsFinished(wxCommandEvent &event) {
885 int bells = wxMin(m_BellsToPlay, 2);
886 if (bells <= 0)
return;
888 wxString soundfile =
"sounds";
889 appendOSDirSlash(&soundfile);
890 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
891 soundfile.Prepend(g_Platform->GetSharedDataDir());
892 wxLogMessage(
"Using bells sound file: " + soundfile);
894 o_sound::Sound *sound = bells_sound[bells - 1];
895 sound->SetFinishedCallback(onBellsFinishedCB,
this);
896 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
897 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
898 sound->Load(soundfile);
899 if (!sound->IsOk()) {
900 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
904 m_BellsToPlay -= bells;
907void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
909void MyFrame::OnMaximize(wxMaximizeEvent &event) {
916void MyFrame::ReloadAllVP() {
917 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
919 if (cc) cc->ReloadVP();
923void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
924 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
927 global_color_scheme = cs;
930 case GLOBAL_COLOR_SCHEME_DAY:
933 case GLOBAL_COLOR_SCHEME_DUSK:
936 case GLOBAL_COLOR_SCHEME_NIGHT:
937 SchemeName =
"NIGHT";
944 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
946 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
947 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
948 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
949 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
950 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
952 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
981 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
982 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
986 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
988 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
992 user_colors::GetMapByScheme(SchemeName.ToStdString());
997 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1000 cc->SetColorScheme(cs);
1001 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1002 cc->HideChartInfoWindow();
1003 cc->SetQuiltChartHiLiteIndex(-1);
1009 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1021 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1034 if (g_pais_query_dialog_active) {
1035 bool b_isshown = g_pais_query_dialog_active->IsShown();
1036 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1037 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1039 g_pais_query_dialog_active->Close();
1042 g_pais_query_dialog_active->
Create(
1043 this, -1, _(
"AIS Target Query"),
1044 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1045 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1046 g_pais_query_dialog_active->UpdateText();
1047 if (b_isshown) g_pais_query_dialog_active->Show();
1052 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1056 ApplyGlobalColorSchemetoStatusBar();
1058 UpdateAllToolbars(cs);
1063 bool btoolbarFull = g_bmasterToolbarFull;
1069 if (!btoolbarFull) {
1071 RequestNewMasterToolbar();
1073 CollapseGlobalToolbar();
1076 RequestNewMasterToolbar();
1085void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1086 if (m_pStatusBar != NULL) {
1087 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1088 m_pStatusBar->ClearBackground();
1099void MyFrame::CancelAllMouseRoute() {
1101 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1103 if (cc) cc->CancelMouseRoute();
1107void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1115 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1123 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1132 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1135 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1136 config_array.Item(i)->canvas = NULL;
1142 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1147 switch (g_canvasConfig) {
1161 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1162 cc->GetglCanvas()->Show();
1165 config_array.Item(0)->canvas = cc;
1169 cc->ApplyCanvasConfig(config_array.Item(0));
1173 cc->ConfigureChartBar();
1174 cc->SetColorScheme(global_color_scheme);
1175 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1176 cc->SetShowGPS(
true);
1179 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1181 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1197 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1200 config_array.Item(0)->canvas = cc;
1202 cc->ApplyCanvasConfig(config_array.Item(0));
1205 cc->ConfigureChartBar();
1206 cc->SetColorScheme(global_color_scheme);
1207 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1208 cc->SetShowGPS(
false);
1211 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1213 .CaptionVisible(
false)
1215 .CloseButton(
false);
1224 if (config_array.GetCount() < 2) {
1226 pcc->configIndex = 1;
1230 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1231 config_array.Add(pcc);
1234 config_array.Item(1)->canvas = cc;
1236 cc->ApplyCanvasConfig(config_array.Item(1));
1239 cc->ConfigureChartBar();
1240 cc->SetColorScheme(global_color_scheme);
1241 cc->SetShowGPS(
true);
1243 cc->SetShowGPSCompassWindow(
true);
1246 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1248 .CaptionVisible(
false)
1250 .CloseButton(
false);
1251 g_pauimgr->GetPane(cc).RightDockable(
true);
1255 config_array.Item(1)->canvasSize =
1256 wxSize(GetClientSize().x / 2, GetClientSize().y);
1257 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1262 if (b_useStoredSize) {
1263 int ccw = config_array.Item(1)->canvasSize.x;
1264 int cch = config_array.Item(1)->canvasSize.y;
1267 if (ccw < GetClientSize().x / 10) {
1268 ccw = GetClientSize().x / 2;
1269 cch = GetClientSize().y;
1272 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1273 cc->SetSize(ccw, cch);
1291 console->SetColorScheme(global_color_scheme);
1296 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1302void MyFrame::RequestNewToolbars(
bool bforcenew) {
1303 if (b_inCloseWindow) {
1307 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1308 PositionIENCToolbar();
1317void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1323void MyFrame::SetAllToolbarScale() {
1324 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1327void MyFrame::SetGPSCompassScale() {
1328 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1332 wxPoint screenPoint = ::wxGetMousePosition();
1335 switch (g_canvasConfig) {
1337 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1340 if (canvas->GetScreenRect().Contains(
1344 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1347 if (canvas->GetScreenRect().Contains(
1354 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1357 if (canvas->GetScreenRect().Contains(
1358 canvas->ScreenToClient(screenPoint)))
1366int MyFrame::GetCanvasIndexUnderMouse() {
1367 wxPoint screenPoint = ::wxGetMousePosition();
1370 switch (g_canvasConfig) {
1372 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1375 if (canvas->GetScreenRect().Contains(
1379 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1382 if (canvas->GetScreenRect().Contains(
1389 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1392 if (canvas->GetScreenRect().Contains(
1393 canvas->ScreenToClient(screenPoint)))
1401bool MyFrame::DropMarker(
bool atOwnShip) {
1408 if (!canvas)
return false;
1415 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1417 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1419 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1430 RefreshAllCanvas(
false);
1435void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1436 if (g_canvasConfig != 0) {
1439 int nTargetGTK = -1;
1441 wxWindow *source = FindFocus();
1447 switch (g_canvasConfig) {
1449 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1452 if (canvas && (canvas == test)) {
1457 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1460 if (canvas && (canvas == test)) {
1468 int nfinalTarget = nTarget;
1470 nfinalTarget = nTargetGTK;
1472 target = ConfigMgr::Get()
1473 .GetCanvasConfigArray()
1478 target->Refresh(
true);
1489void MyFrame::FastClose() {
1491 FrameTenHzTimer.Stop();
1493 FrameTimer1.Start(1);
1497void MyFrame::OnExit(wxCommandEvent &event) {
1501void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1504 if (b_inCloseWindow) {
1514 if (!g_bDeferredInitDone)
return;
1531 if (bDBUpdateInProgress)
return;
1533 b_inCloseWindow =
true;
1535 ::wxSetCursor(wxCURSOR_WAIT);
1539 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1541 if (cc && cc->IsMeasureActive()) {
1542 cc->CancelMeasureRoute();
1547 SendPreShutdownHookToPlugins();
1551 if (g_pAISTargetList) {
1552 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1553 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1554 g_pauimgr->DetachPane(g_pAISTargetList);
1581 SetCursor(wxCURSOR_WAIT);
1583 RefreshAllCanvas(
true);
1589 RestoreScreenBrightness();
1600 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1601 g_iENCToolbarPosY = tbp_incanvas.y;
1602 g_iENCToolbarPosX = tbp_incanvas.x;
1606 g_bframemax = IsMaximized();
1609 FrameTenHzTimer.Stop();
1611 FrameCOGTimer.Stop();
1625 if (g_bAutoAnchorMark) {
1626 bool watching_anchor =
false;
1634 wxDateTime now = wxDateTime::Now();
1635 wxTimeSpan uptime = now.Subtract(g_start_time);
1637 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1638 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1643 if (g_declutter_anchorage) {
1644 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1645 if (pr->GetName().StartsWith(
"Anchorage")) {
1646 double a =
gLat - pr->m_lat;
1647 double b =
gLon - pr->m_lon;
1648 double l = sqrt((a * a) + (b * b));
1651 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1653 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1654 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1662 wxString name = now.Format();
1663 name.Prepend(_(
"Anchorage created "));
1669 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1678 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1682 NavObj_dB::GetInstance().Close();
1686 pConfig->DeleteGroup(
"/Routes");
1687 pConfig->DeleteGroup(
"/Marks");
1706 if (g_pAISTargetList) {
1707 g_pAISTargetList->Disconnect_decoder();
1708 g_pAISTargetList->Destroy();
1711 if (RouteManagerDialog::getInstanceFlag()) {
1728 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1730 if (cc) cc->Destroy();
1754 CommBridge::GetInstance().SaveConfig();
1774 auto ®istry = CommDriverRegistry::GetInstance();
1775 registry.CloseAllDrivers();
1783 while (pLayerList->size())
delete *pLayerList->begin();
1787 ReleaseApiListeners();
1790 g_bTempShowMenuBar =
false;
1792#define THREAD_WAIT_SECONDS 5
1802 wxLogMessage(
"Starting compressor pool drain");
1803 wxDateTime now = wxDateTime::Now();
1804 time_t stall = now.GetTicks();
1805 time_t end = stall + THREAD_WAIT_SECONDS;
1808 while (stall < end) {
1809 wxDateTime later = wxDateTime::Now();
1810 stall = later.GetTicks();
1813 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1822 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1828 uninitIXNetSystem();
1836 wxLogMessage(
"gFrame destroyed.");
1839#ifndef USE_ANDROID_GLES2
1840 qDebug() <<
"Calling OnExit()";
1844 wxTheApp->ExitMainLoop();
1847void MyFrame::OnMove(wxMoveEvent &event) {
1848 auto idx = wxDisplay::GetFromWindow(
this);
1861 DEBUG_LOG <<
"Moved to " << idx
1862#if wxCHECK_VERSION(3, 1, 6)
1863 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1864 << wxDisplay(idx).GetPPI().GetY()
1865 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1867 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1868 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1869 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1870 << wxGetDisplaySizeMM().GetY()
1871 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1880 if (g_config_display_size_manual) {
1889 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1892 cc->SetMUIBarPosition();
1901 UpdateGPSCompassStatusBoxes();
1911 PositionIENCToolbar();
1917 g_nframewin_posx = GetPosition().x;
1918 g_nframewin_posy = GetPosition().y;
1921void MyFrame::ProcessCanvasResize() {
1922 UpdateGPSCompassStatusBoxes(
true);
1926 PositionIENCToolbar();
1929 TriggerRecaptureTimer();
1933void MyFrame::TriggerRecaptureTimer() {
1934 m_recaptureTimer.Start(
1935 1000, wxTIMER_ONE_SHOT);
1938void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1940void MyFrame::SetCanvasSizes(wxSize frameSize) {
1944 int cccw = frameSize.x;
1945 int ccch = frameSize.y;
1949 switch (g_canvasConfig) {
1955 cc->GetSize( &cur_width, &cur_height );
1956 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1958 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1960 cc->SetSize( 0, 0, cccw, ccch );
1970 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1971 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1973 ccw = wxMin(ccw, cccw * 8 / 10);
1974 ccw = wxMax(ccw, cccw * 2 / 10);
1978 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1985 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2002void MyFrame::OnIconize(wxIconizeEvent &event) {
2012 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2014 if (cc && cc->GetMUIBar()) {
2015 if (cc->GetMUIBar()->GetCanvasOptions()) {
2016 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2017 cc->GetMUIBar()->PushCanvasOptions();
2026void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2028void MyFrame::ODoSetSize() {
2030 GetClientSize(&x, &y);
2033 if (m_pStatusBar != NULL) {
2034 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2035 int currentCount = m_pStatusBar->GetFieldsCount();
2036 if (currentCount != m_StatusBarFieldCount) {
2037 if ((currentCount > 0) && (currentCount < 7)) {
2040 int widths[] = {2, 2, 2, 2, 2, 2};
2041 m_pStatusBar->SetStatusWidths(currentCount, widths);
2044 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2047 if (m_StatusBarFieldCount) {
2052 if (m_StatusBarFieldCount > 2) {
2053 int widths[] = {-6, -5, -5, -6, -4};
2054 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2055 }
else if (m_StatusBarFieldCount == 2) {
2056 int cwidth = x * 90 / 100;
2057 int widths[] = {100, 100};
2058 widths[0] = cwidth * 6.4 / 10.0;
2059 widths[1] = cwidth * 3.6 / 10.0;
2060 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2062 int widths[] = {100, 100};
2063 widths[0] = x * 90 / 100;
2064 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2067 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2068 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2069 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2071 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2073 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2081 m_pStatusBar->GetFieldRect(0, stat_box);
2084 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2086 wxFont sys_font = *wxNORMAL_FONT;
2087 int try_font_size = sys_font.GetPointSize();
2090 int min_font_size = 10;
2100 wxFont *statusBarFont =
2101 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2102 int font_size = statusBarFont->GetPointSize();
2104 font_size = wxMin(font_size,
2107 wxMax(font_size, min_font_size);
2110 font_size = statusBarFont->GetPointSize();
2117 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2118 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2120 int min_height = stat_box.height;
2122 m_pStatusBar->SetFont(*pstat_font);
2123 m_pStatusBar->SetForegroundColour(
2124 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2126 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2128 (min_height >> 1) * 2;
2129 m_pStatusBar->SetMinHeight(min_height);
2138 SetCanvasSizes(GetClientSize());
2140 UpdateGPSCompassStatusBoxes(
true);
2142 if (
console) PositionConsole();
2145 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2147 if (cc) cc->FormatPianoKeys();
2153 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2154 GetPrimaryCanvas()->GetCompass()->GetRect());
2180 options_lastWindowSize = wxSize(0, 0);
2181 options_lastWindowPos = wxPoint(0, 0);
2188 if (!b_inCloseWindow) {
2191 resizeAndroidPersistents();
2195 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2196 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2202void MyFrame::PositionConsole() {
2203#if defined(__WXMSW__) || defined(__WXMAC__)
2204 if (NULL == GetPrimaryCanvas())
return;
2206 int ccx, ccy, ccsx, ccsy, consx, consy;
2211 consoleHost->GetSize(&ccsx, &ccsy);
2212 consoleHost->GetPosition(&ccx, &ccy);
2214 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2215 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2216 consoleHost = GetPrimaryCanvas();
2221 if (consoleHost->GetCompass()) {
2222 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2224 if (compass_rect.y < 100)
2225 yOffset = compass_rect.y + compass_rect.height + 45;
2229 wxSize csz =
console->GetSize();
2233 wxPoint screen_pos =
2234 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2237 if (NULL == GetPrimaryCanvas())
return;
2239 int ccx, ccy, ccsx, ccsy, consx, consy;
2244 consoleHost->GetSize(&ccsx, &ccsy);
2245 consoleHost->GetPosition(&ccx, &ccy);
2247 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2248 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2249 consoleHost = GetPrimaryCanvas();
2252 int yTopOffset = 60;
2253 int yBottomOffset = 0;
2255 if (consoleHost->GetCompass()) {
2256 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2258 if (compass_rect.y < 100)
2259 yTopOffset = compass_rect.y + compass_rect.height;
2261 if (consoleHost->GetMUIBar()) {
2262 wxRect mui_rect = consoleHost->GetMUIBarRect();
2263 yBottomOffset = ccsy - mui_rect.y;
2267 wxSize csz =
console->GetSize();
2270 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2272 if (consy < yAvail) {
2273 yFinal = (yAvail - consy) / 2;
2274 yFinal += yTopOffset;
2275 }
else if (
console->GetCDI()->IsShown()) {
2276 int cdi_height =
console->GetCDI()->GetSize().y;
2277 int consy_no_cdi = consy - cdi_height;
2278 yFinal = (yAvail - consy_no_cdi) / 2;
2279 yFinal += yTopOffset;
2283 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2288void MyFrame::UpdateAllFonts() {
2297 DestroyPersistentDialogs();
2299 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2304void MyFrame::DestroyPersistentDialogs() {
2305 if (g_pais_query_dialog_active) {
2306 g_pais_query_dialog_active->Hide();
2307 g_pais_query_dialog_active->Destroy();
2308 g_pais_query_dialog_active = NULL;
2336void MyFrame::RefreshGroupIndices() {
2338 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2340 if (cc) cc->canvasRefreshGroupIndex();
2344bool MyFrame::DisableTbarTooltips() {
2349 wxLogWarning(
"Global g_MainToolbar has not been created.");
2353void MyFrame::EnableTbarTooltips() {
2359void MyFrame::HideTbarTooltip() {
2365void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2367 switch (event.GetId()) {
2368 case ID_MENU_SCALE_OUT:
2369 DoStackDelta(GetPrimaryCanvas(), 1);
2373 case ID_MENU_SCALE_IN:
2374 DoStackDelta(GetPrimaryCanvas(), -1);
2378 case ID_MENU_ZOOM_IN: {
2379 if (GetFocusCanvas()) {
2380 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2385 case ID_MENU_ZOOM_OUT: {
2386 if (GetFocusCanvas()) {
2387 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2392 case ID_MENU_ROUTE_NEW: {
2393 if (GetFocusCanvas()) {
2394 if (0 == GetFocusCanvas()->m_routeState) {
2395 GetFocusCanvas()->StartRoute();
2397 GetFocusCanvas()->FinishRoute();
2403 case ID_MENU_TOOL_MEASURE: {
2404 GetPrimaryCanvas()->StartMeasureRoute();
2408 case ID_MENU_TOOL_NMEA_DBG_LOG:
2409 m_data_monitor->Show();
2410 m_data_monitor->Raise();
2413 case ID_MENU_TOOL_IO_MONITOR:
2414 m_data_monitor->Show();
2417 case ID_MENU_MARK_BOAT: {
2422 case ID_MENU_MARK_CURSOR: {
2427 case ID_MENU_NAV_FOLLOW: {
2428 if (
gFrame->GetPrimaryCanvas())
2429 gFrame->GetPrimaryCanvas()->TogglebFollow();
2433 case ID_MENU_CHART_OUTLINES: {
2434 ToggleChartOutlines(GetFocusCanvas());
2438 case ID_MENU_CHART_QUILTING: {
2439 ToggleQuiltMode(GetFocusCanvas());
2443 case ID_MENU_UI_CHARTBAR: {
2444 ToggleChartBar(GetFocusCanvas());
2448 case ID_MENU_ENC_TEXT:
2450 ToggleENCText(GetFocusCanvas());
2453 case ID_MENU_ENC_LIGHTS: {
2454 ToggleLights(GetFocusCanvas());
2457 case ID_MENU_ENC_SOUNDINGS: {
2458 ToggleSoundings(GetFocusCanvas());
2461 case ID_MENU_ENC_ANCHOR: {
2462 ToggleAnchor(GetFocusCanvas());
2465 case ID_MENU_ENC_DATA_QUALITY: {
2466 ToggleDataQuality(GetFocusCanvas());
2469 case ID_MENU_SHOW_NAVOBJECTS: {
2470 ToggleNavobjects(GetFocusCanvas());
2474 case ID_MENU_AIS_TARGETS: {
2475 ToggleAISDisplay(GetFocusCanvas());
2478 case ID_MENU_AIS_MOORED_TARGETS: {
2479 g_bHideMoored = !g_bHideMoored;
2482 case ID_MENU_AIS_SCALED_TARGETS: {
2483 ToggleAISMinimizeTargets(GetFocusCanvas());
2487 case ID_MENU_AIS_TARGETLIST: {
2488 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2492 case ID_MENU_AIS_TRACKS: {
2493 g_bAISShowTracks = !g_bAISShowTracks;
2494 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2498 case ID_MENU_AIS_CPADIALOG: {
2499 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2500 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2501 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2502 if (g_bAIS_CPA_Alert) {
2503 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2508 case ID_MENU_AIS_CPASOUND: {
2509 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2510 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2514 case ID_MENU_AIS_CPAWARNING: {
2515 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2516 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2520 case wxID_PREFERENCES:
2527 case ID_SETTINGS_NEW: {
2532 case ID_SETTINGS_DELETE: {
2535 g_pOptions =
nullptr;
2539 case ID_RELOAD_CHARTS: {
2544 case ID_MENU_SETTINGS_BASIC: {
2546 androidDisableFullScreen();
2548 DoAndroidPreferences();
2555 case ID_MENU_UI_FULLSCREEN: {
2560 case ID_MENU_SHOW_CURRENTS: {
2561 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2562 GetFocusCanvas()->ReloadVP();
2563 GetFocusCanvas()->Refresh(
false);
2567 case ID_MENU_SHOW_TIDES: {
2568 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2569 GetFocusCanvas()->ReloadVP();
2570 GetFocusCanvas()->Refresh(
false);
2590 case ID_MENU_UI_COLSCHEME:
2591 case ID_COLSCHEME: {
2592 ToggleColorScheme();
2601 case ID_MENU_OQUIT: {
2606 case ID_MENU_ROUTE_MANAGER:
2607 case ID_ROUTEMANAGER: {
2630 case ID_MENU_NAV_TRACK:
2632 if (!g_bTrackActive) {
2634 g_bTrackCarryOver =
true;
2637 g_bTrackCarryOver =
false;
2638 RefreshAllCanvas(
true);
2643 case ID_MENU_CHART_NORTHUP: {
2644 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2647 case ID_MENU_CHART_COGUP: {
2648 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2651 case ID_MENU_CHART_HEADUP: {
2652 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2656 case ID_MENU_MARK_MOB:
2662 case ID_MASTERTOGGLE: {
2664 wxString tip = _(
"Show Toolbar");
2665 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2667 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2669 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2672 if (g_bmasterToolbarFull)
2673 m_nMasterToolCountShown =
2677 m_nMasterToolCountShown = 2;
2679 m_nMasterToolCountShown =
2682 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2690 case ID_CMD_SELECT_CHART_TYPE: {
2691 selectChartDisplay(event.GetExtraLong(), -1);
2695 case ID_CMD_SELECT_CHART_FAMILY: {
2696 selectChartDisplay(-1, event.GetExtraLong());
2700 case ID_CMD_APPLY_SETTINGS: {
2701 applySettingsString(event.GetString());
2703 androidRestoreFullScreen();
2709 case ID_CMD_NULL_REFRESH: {
2714 case ID_CMD_SETVP: {
2715 setStringVP(event.GetString());
2719 case ID_CMD_INVALIDATE: {
2725 case ID_CMD_POST_JSON_TO_PLUGINS: {
2728 nlohmann::json root;
2730 root = nlohmann::json::parse(event.GetString().ToStdString());
2731 if (root[
"MessageID"].is_string()) {
2732 std::string msg_id = root[
"MessageID"].get<std::string>();
2735 }
catch (nlohmann::json::exception &) {
2757 ArrayOfPlugInToolbarTools tool_array =
2759 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2761 if (event.GetId() == pttc->id) {
2762 if (pttc->m_pplugin)
2784bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2785 bool viz_now = g_bmasterToolbarFull;
2788 wxString tip = _(
"Show Toolbar");
2790 tip = _(
"Hide Toolbar");
2792 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2795 bool toggle =
false;
2796 if (viz && !g_bmasterToolbarFull)
2799 else if (!viz && g_bmasterToolbarFull)
2803 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2806 if (g_bmasterToolbarFull)
2807 m_nMasterToolCountShown =
2811 m_nMasterToolCountShown = 2;
2813 m_nMasterToolCountShown =
2816 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2822void MyFrame::ScheduleReloadCharts() {
2823 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2824 evt.SetId(ID_RELOAD_CHARTS);
2825 GetEventHandler()->AddPendingEvent(evt);
2828void MyFrame::ScheduleDeleteSettingsDialog() {
2829 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2830 evt.SetId(ID_SETTINGS_DELETE);
2831 GetEventHandler()->AddPendingEvent(evt);
2834void MyFrame::ScheduleSettingsDialog() {
2835 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2836 evt.SetId(ID_SETTINGS);
2837 GetEventHandler()->AddPendingEvent(evt);
2840void MyFrame::ScheduleSettingsDialogNew() {
2841 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2842 evt.SetId(ID_SETTINGS_NEW);
2843 GetEventHandler()->AddPendingEvent(evt);
2846void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2847 UpdateCanvasConfigDescriptors();
2849 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2850 CreateCanvasLayout(
true);
2852 CreateCanvasLayout();
2856 ConfigureStatusBar();
2857 wxSize lastOptSize = options_lastWindowSize;
2862 options_lastWindowSize = lastOptSize;
2866 ScheduleSettingsDialogNew();
2868 ScheduleSettingsDialog();
2873 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2876 int index_hint = -1;
2877 if (i < pathArray.GetCount())
2878 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2879 cc->canvasChartsRefresh(index_hint);
2880 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2889 return GetPrimaryCanvas();
2892void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2894 if (g_bmasterToolbarFull) {
2895#ifndef OCPN_TOOLBAR_ANIMATE
2896 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2899 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2900 m_nMasterToolCountShown++;
2905 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2913#ifndef OCPN_TOOLBAR_ANIMATE
2914 m_nMasterToolCountShown = 1;
2916 if (m_nMasterToolCountShown > 1) {
2917 m_nMasterToolCountShown--;
2921 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2931void MyFrame::InvalidateAllGL() {
2934 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2944void MyFrame::RefreshAllCanvas(
bool bErase) {
2946 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2949 cc->Refresh(bErase);
2954void MyFrame::setStringVP(wxString VPS) {
2959 wxStringTokenizer tkz(VPS,
";");
2961 wxString token = tkz.GetNextToken();
2963 token.ToDouble(&lat);
2965 token = tkz.GetNextToken();
2967 token.ToDouble(&lon);
2969 token = tkz.GetNextToken();
2971 token.ToDouble(&scale_ppm);
2973 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2976void MyFrame::DoSettingsNew() {
2983void MyFrame::DoSettings() {
2984 if (!g_bDeferredInitDone) {
2985 wxLogWarning(
"Ignoring settings request while OpenCPN is initializing.");
2993 ApplyGlobalSettings(
true);
2996 bool b_loadHarmonics =
false;
2997 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3000 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3003 if (b_loadHarmonics) LoadHarmonics();
3011 g_bShowChartBar = !g_bShowChartBar;
3013 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3018 if (g_bShowChartBar) {
3020 UpdateControlBar(cc);
3023 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3026void MyFrame::ToggleColorScheme() {
3027 static bool lastIsNight;
3028 ColorScheme s = user_colors::GetColorScheme();
3031 if (lastIsNight && is == 3)
3034 lastIsNight =
false;
3036 if (lastIsNight) is = 2;
3037 if (is == 3) lastIsNight =
true;
3038 s = (ColorScheme)is;
3039 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3041 SetAndApplyColorScheme(s);
3044void MyFrame::ToggleFullScreen() {
3045 bool to = !IsFullScreen();
3050 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3052 ShowFullScreen(to, style);
3055 UpdateAllToolbars(global_color_scheme);
3057 UpdateControlBar(GetPrimaryCanvas());
3059 TriggerRecaptureTimer();
3062void MyFrame::ActivateMOB() {
3064 wxDateTime mob_time = wxDateTime::Now();
3065 wxString mob_label(_(
"MAN OVERBOARD"));
3066 mob_label += _(
" on ");
3067 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3071 pWP_MOB->SetShared(
true);
3073 pWP_MOB->SetWaypointArrivalRadius(
3075 pWP_MOB->SetUseSca(
false);
3077 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3085 new RoutePoint(zlat, zlon, g_default_wp_icon,
3086 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3087 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3092 temp_route->AddPoint(pWP_src);
3093 temp_route->AddPoint(pWP_MOB);
3095 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3105 temp_route->SetRouteArrivalRadius(-1.0);
3111 v[
"GUID"] = temp_route->
m_GUID;
3112 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
3115 if (RouteManagerDialog::getInstanceFlag()) {
3123 RefreshAllCanvas(
false);
3125 wxString mob_message(_(
"MAN OVERBOARD"));
3126 mob_message += _(
" Time: ");
3127 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3128 mob_message += _(
" Position: ");
3129 mob_message += toSDMM(1,
gLat);
3131 mob_message += toSDMM(2,
gLon);
3132 wxLogMessage(mob_message);
3134void MyFrame::TrackOn() {
3135 g_bTrackActive =
true;
3143 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3145 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3147 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3150 androidSetTrackTool(
true);
3153 if (RouteManagerDialog::getInstanceFlag()) {
3162 if (name.IsEmpty()) {
3168 name = _(
"(Unnamed Track)");
3172 SendJsonMessageToAllPlugins(
"OCPN_TRK_ACTIVATED", v);
3174 g_FlushNavobjChangesTimeout = 30;
3177Track *MyFrame::TrackOff(
bool do_add_point) {
3183 SendJsonMessageToAllPlugins(
"OCPN_TRK_DEACTIVATED", v);
3192 if (g_bTrackDaily) {
3197 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3198 return_val = pExtendTrack;
3205 g_bTrackActive =
false;
3207 if (RouteManagerDialog::getInstanceFlag()) {
3214 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3216 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3217 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3220 androidSetTrackTool(
false);
3224 m_target_rotate_time = wxInvalidDateTime;
3229void MyFrame::InitializeTrackRestart() {
3230 if (!g_bTrackDaily)
return;
3231 if (m_target_rotate_time.IsValid())
return;
3234 switch (g_track_rotate_time_type) {
3236 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3238 case TIME_TYPE_COMPUTER:
3239 rotate_at = g_track_rotate_time;
3243 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3244 rotate_at = g_track_rotate_time + utc_offset;
3247 if (rotate_at > 86400)
3249 else if (rotate_at < 0)
3252 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3253 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3256 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3257 m_target_rotate_time += wxTimeSpan(24);
3261bool MyFrame::ShouldRestartTrack() {
3263 InitializeTrackRestart();
3265 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3266 m_target_rotate_time += wxTimeSpan(24);
3272void MyFrame::TrackDailyRestart() {
3274 Track *pPreviousTrack = TrackOff(
true);
3281 if (pPreviousTrack) {
3282 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3286 if (RouteManagerDialog::getInstanceFlag()) {
3294void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3296 cc->SetUpMode(mode);
3298 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3299 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3300 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3303 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3308 cc->SetShowENCText(!cc->GetShowENCText());
3310 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3318void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3321 cc->SetENCDisplayCategory(nset);
3323 UpdateGlobalMenuItems();
3334 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3336 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3345 cc->SetShowENCLights(!cc->GetShowENCLights());
3347 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3357void MyFrame::ToggleRocks(
void )
3363 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3364 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3365 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3366 pOLE->nViz = !pOLE->nViz;
3370 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3371 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3372 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3375 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3379 ps52plib->GenerateStateHash();
3386 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3388 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3396 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3398 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3413 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3414 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3419 cc->SetShowAIS(!cc->GetShowAIS());
3420 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3424void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3425 cc->SetAttenAIS(!cc->GetAttenAIS());
3426 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3432 cc->m_bFollow =
true;
3435 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3439 SetChartUpdatePeriod();
3447 cc->m_bFollow =
false;
3449 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3453 SetChartUpdatePeriod();
3456void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3457 cc->SetShowOutlines(!cc->GetShowOutlines());
3459 RefreshAllCanvas(
false);
3463 if (g_bopengl) InvalidateAllGL();
3466 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3469void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3471void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3473 bool enabled = m_pMenuBar->IsEnabled(item_id);
3474 m_pMenuBar->Enable(item_id,
false);
3475 m_pMenuBar->Check(item_id, state);
3476 m_pMenuBar->Enable(item_id, enabled);
3480void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3487void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3488 wxBitmap *bmpRollover) {
3490 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3495void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3496 wxString rolloverSVGfile,
3497 wxString toggledSVGfile) {
3500 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3504void MyFrame::ConfigureStatusBar() {
3506 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3509 UseNativeStatusBar(
false);
3512 if (g_bShowStatusBar) {
3513 if (!m_pStatusBar) {
3515 CreateStatusBar(m_StatusBarFieldCount, 0);
3516 ApplyGlobalColorSchemetoStatusBar();
3521 m_pStatusBar->Destroy();
3522 m_pStatusBar = NULL;
3528void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3529 ConfigureStatusBar();
3531 wxSize lastOptSize = options_lastWindowSize;
3537 options_lastWindowSize = lastOptSize;
3539 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3542void MyFrame::BuildMenuBar() {
3548 bool showMenuBar =
true;
3550 bool showMenuBar = g_bShowMenuBar;
3562 m_pMenuBar =
new wxMenuBar();
3563 RegisterGlobalMenuItems();
3564 SetMenuBar(m_pMenuBar);
3568 UpdateGlobalMenuItems();
3573 m_pMenuBar->Destroy();
3579void MyFrame::RegisterGlobalMenuItems() {
3580 if (!m_pMenuBar)
return;
3582 wxMenu *nav_menu =
new wxMenu();
3583 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3584 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3585 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3586 nav_menu->AppendSeparator();
3587 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3588 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3589 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3590 nav_menu->AppendSeparator();
3592 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3593 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3595 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3596 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3598 nav_menu->AppendSeparator();
3599 nav_menu->Append(ID_MENU_SCALE_IN,
3600 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3601 nav_menu->Append(ID_MENU_SCALE_OUT,
3602 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3604 nav_menu->AppendSeparator();
3605 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3607 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3609 wxMenu *view_menu =
new wxMenu();
3611 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3612 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3613 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3614 _menuText(_(
"Show Chart Outlines"),
"O"));
3616 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3617 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3618 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3619 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3621 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3622 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3624 view_menu->AppendSeparator();
3626 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3627 _menuText(_(
"Show ENC text"),
"T"));
3628 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3629 _menuText(_(
"Show ENC Lights"),
"L"));
3630 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3631 _menuText(_(
"Show ENC Soundings"),
"S"));
3632 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3633 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3634 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3635 _menuText(_(
"Show ENC Data Quality"),
"U"));
3636 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3637 _menuText(_(
"Show Navobjects"),
"V"));
3639 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3640 _menuText(_(
"Show ENC text"),
"Alt-T"));
3641 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3642 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3643 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3644 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3645 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3646 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3647 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3648 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3649 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3650 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3652 view_menu->AppendSeparator();
3653 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3654 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3655 view_menu->AppendSeparator();
3657 view_menu->Append(ID_MENU_UI_COLSCHEME,
3658 _menuText(_(
"Change Color Scheme"),
"C"));
3660 view_menu->Append(ID_MENU_UI_COLSCHEME,
3661 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3664 view_menu->AppendSeparator();
3666 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3667 _menuText(_(
"Toggle Full Screen"),
"F11"));
3669 m_pMenuBar->Append(view_menu, _(
"&View"));
3671 wxMenu *ais_menu =
new wxMenu();
3672 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3673 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3674 _(
"Attenuate less critical AIS targets"));
3675 ais_menu->AppendSeparator();
3676 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3677 _(
"Hide Moored AIS Targets"));
3678 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3679 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3680 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3683 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3684 _menuText(_(
"Show CPA Warnings"),
"W"));
3686 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3687 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3690 ais_menu->AppendSeparator();
3691 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3692 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3694 wxMenu *tools_menu =
new wxMenu();
3696 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3697 _menuText(_(
"Data Monitor"),
"E"));
3698 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3699 _menuText(_(
"Measure Distance"),
"M"));
3701 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3702 _menuText(_(
"Data Monitor"),
"Alt-E"));
3703 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3704 _menuText(_(
"Measure Distance"),
"Alt-M"));
3707 tools_menu->AppendSeparator();
3708 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3709 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3710 tools_menu->AppendSeparator();
3711 tools_menu->Append(ID_MENU_MARK_BOAT,
3712 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3713 tools_menu->Append(ID_MENU_MARK_CURSOR,
3714 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3715 tools_menu->AppendSeparator();
3719 _menuText(_(
"Drop MOB Marker"),
3721 tools_menu->AppendSeparator();
3722 tools_menu->Append(wxID_PREFERENCES,
3723 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3725 tools_menu->Append(ID_MENU_MARK_MOB,
3726 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3727 tools_menu->AppendSeparator();
3728 tools_menu->Append(wxID_PREFERENCES,
3729 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3731 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3734 wxMenu *window_menu =
new wxMenu();
3735 m_pMenuBar->Append(window_menu, _(
"&Window"));
3738 wxMenu *help_menu =
new wxMenu();
3739 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3740 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3741 m_pMenuBar->Append(help_menu, _(
"&Help"));
3744 UpdateGlobalMenuItems();
3745 EnableSettingsTool(g_bDeferredInitDone);
3748void MyFrame::UpdateGlobalMenuItems() {
3749 if (!m_pMenuBar)
return;
3751 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3752 ->Check(GetPrimaryCanvas()->m_bFollow);
3753 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3754 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3755 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3756 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3757 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3758 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3759 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3760 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3761 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3762 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3763 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3764 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3765 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3766 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3767 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3768 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3769 if (g_bAIS_CPA_Alert) {
3770 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3771 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3773 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3774 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3777 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3778 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3779 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3782 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3783 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3784 ->Check(ps52plib->GetShowSoundings());
3786 bool light_state =
false;
3788 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3790 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3791 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3792 light_state = (pOLE->nViz == 1);
3797 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3798 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3802 DisCat nset = ps52plib->GetDisplayCategory();
3803 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3804 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3805 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3806 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3807 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3808 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3809 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3811 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3812 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3813 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3818void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3819 if (!m_pMenuBar)
return;
3821 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3823 if (cc->GetUpMode() == NORTH_UP_MODE)
3824 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3825 else if (cc->GetUpMode() == COURSE_UP_MODE)
3826 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3828 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3830 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3831 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3832 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3833 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3834 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3835 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3836 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3837 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3838 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3839 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3840 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3841 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3842 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3843 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3844 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3847 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3848 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3851 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3853 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3854 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3859 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3863 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3864 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3865 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3866 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3867 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3868 ->Check(cc->GetShowENCDataQual());
3869 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3871 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3872 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3873 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3878void MyFrame::InvalidateAllCanvasUndo() {
3880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3882 if (cc) cc->undo->InvalidateUndo();
3886void MyFrame::SubmergeAllCanvasToolbars() {
3888 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3890 if (cc) cc->SubmergeToolbar();
3894void MyFrame::SurfaceAllCanvasToolbars() {
3895 if (g_bshowToolbar) {
3897 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3899 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3906void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3908 if (lon > 180.0) lon -= 360.0;
3913 cc->JumpToPosition(lat, lon,
scale);
3916 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3920void MyFrame::UpdateCanvasConfigDescriptors() {
3922 for (
unsigned int i = 0;
3923 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3924 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3932 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3933 cc->GroupID = chart->m_groupIndex;
3936 cc->
bQuilt = chart->GetQuiltMode();
3942 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3944 cc->
bFollow = chart->m_bFollow;
3949 int upmode = chart->GetUpMode();
3950 if (upmode == COURSE_UP_MODE)
3952 else if (upmode == HEAD_UP_MODE)
3959void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3960 if (!RBBox.GetValid())
return;
3962 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3963 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3966 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3967 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3975 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3976 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3978 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3979 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3981 cc->GetSize(&ww, &wh);
3983 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3985 ppm = wxMin(ppm, 1.0);
3991void MyFrame::PrepareOptionsClose(
options *settings,
3992 int settings_return_value) {
3994 options_lastPage = settings->lastPage;
3999 if (options_lastPage == 1) options_lastPage = 0;
4001 options_subpage = settings->lastSubPage;
4002 options_lastWindowPos = settings->lastWindowPos;
4003 options_lastWindowSize = settings->lastWindowSize;
4006 androidEnableBackButton(
true);
4007 androidEnableOptionsMenu(
true);
4008 androidRestoreFullScreen();
4009 androidEnableRotation();
4012 EnableSettingsTool(
true);
4015void MyFrame::DoOptionsDialog() {
4016 EnableSettingsTool(
false);
4019 AbstractPlatform::ShowBusySpinner();
4022 pConfig->SetPath(
"/Settings");
4023 pConfig->Read(
"OptionsSizeX", &sx, -1);
4024 pConfig->Read(
"OptionsSizeY", &sy, -1);
4026 wxWindow *optionsParent =
this;
4028 optionsParent = GetPrimaryCanvas();
4031 callbacks.prepare_close = [&](
options *me,
int changes) {
4032 PrepareOptionsClose(me, changes);
4034 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4035 ProcessOptionsDialog(changes, workdir_list);
4038 wxPoint(-1, -1), wxSize(sx, sy));
4040 AbstractPlatform::HideBusySpinner();
4044 g_options->SetInitChartDir(*pInit_Chart_Dir);
4048 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4049 g_options->SetWorkDirListPtr(pWorkDirArray);
4055 prev_locale = g_locale;
4056 g_options->SetInitialPage(options_lastPage, options_subpage);
4059 g_options->lastWindowPos = options_lastWindowPos;
4060 if (options_lastWindowPos != wxPoint(0, 0)) {
4062 g_options->SetSize(options_lastWindowSize);
4066 if (options_lastWindowSize != wxSize(0, 0)) {
4067 g_options->SetSize(options_lastWindowSize);
4072 androidEnableBackButton(
false);
4073 androidEnableOptionsMenu(
false);
4074 androidDisableFullScreen();
4082 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4085 wxString chart_file_name;
4086 if (cc->GetQuiltMode()) {
4087 int dbi = cc->GetQuiltRefChartdbIndex();
4088 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4090 if (cc->m_singleChart)
4091 chart_file_name = cc->m_singleChart->GetFullPath();
4094 pathArray.Add(chart_file_name);
4100 last_canvasConfig = g_canvasConfig;
4103 g_last_ChartScaleFactor = g_ChartScaleFactor;
4109void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4110 bool b_need_refresh =
false;
4113 if ((rr & VISIT_CHARTS) &&
4114 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4116 UpdateChartDatabaseInplace(*pNewDirArray,
4117 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4120 b_need_refresh =
true;
4125 if (rr & STYLE_CHANGED) {
4128 _(
"Please restart OpenCPN to activate language or style changes."),
4129 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4132 bool charts_updating =
4133 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4134 if (!charts_updating) RefreshGroupIndices();
4136 if (rr & TIDES_CHANGED) {
4142 if (rr & S52_CHANGED) {
4143 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4154 g_Platform->GetDisplayDPmm());
4157 double stuffcog = NAN;
4158 double stuffsog = NAN;
4159 if (!std::isnan(
gCog)) stuffcog =
gCog;
4160 if (!std::isnan(
gSog)) stuffsog =
gSog;
4162 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4163 COGFilterTable[i] = stuffcog;
4164 SOGFilterTable[i] = stuffsog;
4167 SetChartUpdatePeriod();
4169 if (rr & GL_CHANGED) {
4173 b_need_refresh =
true;
4176 if (rr & S52_CHANGED) {
4177 b_need_refresh =
true;
4181 if (rr & REBUILD_RASTER_CACHE) {
4183 GetPrimaryCanvas()->Disable();
4185 GetPrimaryCanvas()->Enable();
4190 if (g_config_display_size_manual &&
4198 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4205 int rrt = rr & S52_CHANGED;
4207 (rrt == S52_CHANGED) ||
4208 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4218 ps52plib->SetScaleFactorExp(
4219 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4220 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4224 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4226 if (cc) cc->ApplyGlobalSettings();
4234 if (!charts_updating) {
4235 bool ztc = g_bEnableZoomToCursor;
4236 g_bEnableZoomToCursor =
false;
4238 if (!GetPrimaryCanvas()->IsFrozen())
4240 g_bEnableZoomToCursor = ztc;
4245 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4254 SetGPSCompassScale();
4256 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4259 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4260 if (!charts_updating) cc->UpdateCanvasControlBar();
4263 UpdateGPSCompassStatusBoxes();
4265 SetAllToolbarScale();
4266 RequestNewToolbars();
4268 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4271 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4274 cc->RebuildCursors();
4279 bool b_masterScaleChange =
false;
4281 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4282 b_masterScaleChange =
true;
4284 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4285 RequestNewMasterToolbar(
true);
4287 bool bMuiChange =
false;
4293 if (b_masterScaleChange || bMuiChange) {
4295 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4298 cc->ProcessNewGUIScale();
4304 if (rr & LOCALE_CHANGED) {
4305 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4307 rr |= NEED_NEW_OPTIONS;
4316 g_last_ChartScaleFactor = g_ChartScaleFactor;
4321bool MyFrame::CheckGroup(
int igroup) {
4322 if (igroup == 0)
return true;
4326 if (!pGroup->m_element_array.size())
4329 for (
const auto &elem : pGroup->m_element_array) {
4330 for (
unsigned int ic = 0;
4331 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4332 auto &cte =
ChartData->GetChartTableEntry(ic);
4333 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4335 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4342bool MyFrame::ScrubGroupArray() {
4347 bool b_change =
false;
4348 unsigned int igroup = 0;
4349 while (igroup < g_pGroupArray->GetCount()) {
4350 bool b_chart_in_element =
false;
4353 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4354 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4356 for (
unsigned int ic = 0;
4357 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4358 auto &cte =
ChartData->GetChartTableEntry(ic);
4359 wxString chart_full_path = cte.GetFullSystemPath();
4361 if (chart_full_path.StartsWith(element_root)) {
4362 b_chart_in_element =
true;
4368 if (!b_chart_in_element) {
4369 wxString test_string =
"GSHH";
4370 if (element_root.Upper().Contains(test_string))
4371 b_chart_in_element =
true;
4374 if (!b_chart_in_element)
4376 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4388void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4390 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4392 if (cc && (cc != ccThis)) cc->Refresh();
4397void MyFrame::ChartsRefresh() {
4400 AbstractPlatform::ShowBusySpinner();
4402 bool b_run = FrameTimer1.IsRunning();
4405 FrameTenHzTimer.Stop();
4408 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4411 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4412 if (cc->GetQuiltMode()) {
4413 currentIndex = cc->GetQuiltReferenceChartIndex();
4415 cc->canvasChartsRefresh(currentIndex);
4419 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4420 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4422 AbstractPlatform::HideBusySpinner();
4425void MyFrame::InvalidateAllQuilts() {
4426 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4429 cc->InvalidateQuilt();
4430 cc->SetQuiltRefChart(-1);
4431 cc->m_singleChart = NULL;
4436bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4438 const wxString &ChartListFileName) {
4439 bool b_run = FrameTimer1.IsRunning();
4441 FrameTenHzTimer.Stop();
4443 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4444 FrameCOGTimer.Stop();
4447 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4450 cc->InvalidateQuilt();
4451 cc->SetQuiltRefChart(-1);
4452 cc->m_singleChart = NULL;
4462 AbstractPlatform::ShowBusySpinner();
4465 wxString longmsg = _(
"OpenCPN Chart Update");
4467 ".................................................................."
4470 Updateprog =
new wxGenericProgressDialog();
4473 Updateprog->SetFont(*qFont);
4475 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4476 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4477 wxPD_REMAINING_TIME);
4479 DimeControl(Updateprog);
4484 wxLogMessage(
"Starting chart database Update...");
4488 m_gshhg_chart_loc = gWorldMapLocation;
4489 gWorldMapLocation = wxEmptyString;
4493 AbstractPlatform::HideBusySpinner();
4497void MyFrame::FinalizeChartDBUpdate() {
4499 if (!g_bDeferredInitDone) {
4501 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4504 bool b_groupchange = ScrubGroupArray();
4506 RefreshGroupIndices();
4508 if (b_groupchange) {
4509 pConfig->DestroyConfigGroups();
4514 if (g_bDeferredInitDone) ScheduleReloadCharts();
4519 cc->ToggleCanvasQuiltMode();
4521 bool cur_mode = cc->GetQuiltMode();
4523 if( !cc->GetQuiltMode() )
4524 cc->SetQuiltMode(
true );
4526 if( cc->GetQuiltMode() ) {
4527 cc->SetQuiltMode(
false );
4528 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4532 if( cur_mode != cc->GetQuiltMode() ){
4538 g_bQuiltEnable = cc->GetQuiltMode();
4542 ps52plib->GenerateStateHash();
4550 DoStackDelta(cc, -1);
4556 DoStackDelta(cc, 1);
4559void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4561void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4563void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4565 cc->DoCanvasStackDelta(direction);
4569void MyFrame::PositionIENCToolbar() {
4573 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4575 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4583void MyFrame::OnInitTimer(wxTimerEvent &event) {
4586 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4590 wxLog::FlushActive();
4592 switch (m_iInitCount++) {
4594 EnableSettingsTool(
false);
4599 if (g_bInlandEcdis) {
4600 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4601 double range_set = 500.;
4603 range = wxRound(range * 10) / 10.;
4607 else if (range > 2000.)
4609 else if (range > 1600.)
4611 else if (range > 1200.)
4613 else if (range > 800.)
4618 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4622 g_Platform->SetFullscreen(g_bFullscreen);
4626 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4629 cc->SetGroupIndex(0,
false);
4635 const bool update_started = StartRebuildChartDatabase();
4637 if (update_started) {
4649 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4663 3 * GetCharHeight());
4665 m_data_monitor->Center();
4673 pConfig->SetPath(
"/Settings");
4674 pConfig->Read(
"OptionsSizeX", &sx, -1);
4675 pConfig->Read(
"OptionsSizeY", &sy, -1);
4677 wxWindow *optionsParent =
this;
4679 optionsParent = GetPrimaryCanvas();
4681 BuildiENCToolbar(
true, m_toolbar_callbacks);
4688 if (!g_params.empty()) {
4689 for (
size_t n = 0; n < g_params.size(); n++) {
4690 wxString path = g_params[n];
4691 if (::wxFileExists(path)) {
4693 pSet->load_file(path.fn_str());
4696 pSet->LoadAllGPXObjects(
4697 !pSet->IsOpenCPN(), wpt_dups,
4699 LLBBox box = pSet->GetBBox();
4700 if (box.GetValid()) {
4701 CenterView(GetPrimaryCanvas(), box);
4710 InitAppMsgBusListener();
4715 auto loader = PluginLoader::GetInstance();
4716 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4717 if (!b_haveWMM)
gVar = g_UserVar;
4725 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4728 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4730 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4733 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4737 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4738 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4739 NavObj_dB::GetInstance().LoadNavObjects();
4742 if (!g_AW1GUID.IsEmpty()) {
4745 if (!g_AW2GUID.IsEmpty()) {
4751 appendOSDirSlash(&layerdir);
4752 layerdir.Append(
"layers");
4754 if (wxDir::Exists(layerdir)) {
4756 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4757 wxLogMessage(laymsg);
4758 pConfig->LoadLayers(layerdir);
4763 if (!g_kiosk_startup) {
4764 AbstractPlatform::ShowBusySpinner();
4767 pConfig->SetPath(
"/Settings");
4768 pConfig->Read(
"OptionsSizeX", &sx, -1);
4769 pConfig->Read(
"OptionsSizeY", &sy, -1);
4771 wxWindow *optionsParent =
this;
4773 optionsParent = GetPrimaryCanvas();
4776 callbacks.prepare_close = [&](
options *me,
int changes) {
4777 PrepareOptionsClose(me, changes);
4779 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4780 ProcessOptionsDialog(changes, workdir_list);
4783 wxPoint(-1, -1), wxSize(sx, sy));
4784 AbstractPlatform::HideBusySpinner();
4791 wxLogMessage(
"OnInitTimer...Last Call");
4795 RequestNewMasterToolbar();
4797 PositionIENCToolbar();
4799 g_bDeferredInitDone =
true;
4809 GetPrimaryCanvas()->SetFocus();
4810 GetPrimaryCanvas()->Enable();
4813 if (b_reloadForPlugins) {
4819 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4821 if (cc) cc->SetFirstAuto(
true);
4829 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4831 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4835 cc->CheckGroupValid();
4836 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4837 cc->SetShowGPSCompassWindow(
true);
4842 androidEnableBackButton(
true);
4843 androidEnableRotation();
4844 androidEnableOptionItems(
true);
4848 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4854 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4856 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4858 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4864 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4866 wxLog::FlushActive();
4868 RefreshAllCanvas(
true);
4869 UsbWatchDaemon::GetInstance().Start();
4870 EnableSettingsTool(g_bDeferredInitDone);
4876void MyFrame::InitAppMsgBusListener() {
4877 auto &msgbus = AppMsgBus::GetInstance();
4880 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4881 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4885 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4886 HandleBasicNavMsg(basicnav_msg);
4890 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4891 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4895 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4896 HandleGPSWatchdogMsg(msg);
4903void MyFrame::ReleaseApiListeners() {}
4908 m_on_raise_listener.Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4909 m_on_quit_listener.Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4910 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4911 server.open_file_cb = [&](
const std::string &path) {
4912 return m_open_gpx_file(path);
4919void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4920 if (msg->gps_watchdog <= 0) {
4921 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4925 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4930 if (m_fix_start_time.IsValid()) {
4931 wxDateTime now = wxDateTime::Now();
4932 wxTimeSpan span = now - m_fix_start_time;
4933 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4934 auto ¬eman = NotificationManager::GetInstance();
4935 wxString msg = _(
"GNSS Position fix lost");
4936 noteman.AddNotification(NotificationSeverity::kCritical,
4938 m_fix_start_time = wxInvalidDateTime;
4942 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4943 bool last_bVelocityValid = bVelocityValid;
4944 bVelocityValid =
false;
4951void MyFrame::CalculateCOGAverage() {
4953 if (!std::isnan(
gCog)) {
4956 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4959 double sum = 0., count = 0;
4961 double adder = COGTable[i];
4962 if (std::isnan(adder))
continue;
4964 if (fabs(adder -
g_COGAvg) > 180.) {
4978 else if (sum >= 360.)
4987void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4988 m_fixtime = msg->time;
4989 double hdt_data_interval = 0;
4990 double fix_time_interval = 0;
4992 double msgtime = msg->set_time.tv_sec;
4993 double m1 = msg->set_time.tv_nsec / 1e9;
4996 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4997 ((msg->vflag & POS_VALID) == POS_VALID)) {
4999 if (!m_fix_start_time.IsValid()) {
5000 m_fix_start_time = wxDateTime::Now();
5005 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5008 fix_time_gt_last = fix_time_gt;
5009 uint64_t fix_time_gt_now =
5010 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5011 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5015 double implied_sog = dist / (fix_time_interval / 3600);
5020 gLat_gt_m1 = gLat_gt;
5021 gLon_gt_m1 = gLon_gt;
5025 fix_time_gt = fix_time_gt_now;
5029 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5030 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5031 gCog_gt_m1 = gCog_gt;
5041 if (!std::isnan(gCog_gt_m1)) {
5043 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5050 if ((fix_time_gt - fix_time_gt_last) > .08) {
5055 if (gCog_gt > gCog_gt_m1) {
5056 if ((gCog_gt - gCog_gt_m1) > 180.)
5061 if ((gCog_gt_m1 - gCog_gt) > 180.)
5066 difft = fabs(gCog_gt - gCog_gt_m1);
5067 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5075 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5076 tentative_cog_rate_gt *= 1e9;
5077 cog_rate_gt = tentative_cog_rate_gt;
5085 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5088static double hdt_avg;
5089 double hdt_norm =
gHdt;
5090 if(
gHdt > 180) hdt_norm -= 360;
5093 hdt_avg += hdt_norm * 0.1;
5098 if (!std::isnan(
gHdt)) {
5100 uint64_t hdt_time_gt_last = hdt_time_gt;
5101 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5102 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5105 if (hdt_data_interval > .09) {
5107 gHdt_gt_m1 = gHdt_gt;
5110 if (!std::isnan(gHdt_gt_m1)) {
5112 double tentative_hdt_rate_gt =
5113 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5114 tentative_hdt_rate_gt *= 1e9;
5116 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5117 hdt_rate_gt = tentative_hdt_rate_gt;
5125 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5128 CalculateCOGAverage();
5136 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5137 if ((msg->vflag & POS_VALID) == POS_VALID)
5142 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5144 bVelocityValid =
true;
5148void MyFrame::UpdateStatusBar() {
5151 unsigned long uiCurrentTickCount;
5152 m_MMEAeventTime.SetToCurrent();
5153 uiCurrentTickCount =
5154 m_MMEAeventTime.GetMillisecond() / 100;
5155 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5156 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5157 m_ulLastNMEATicktime = uiCurrentTickCount;
5159 if (m_tick_idx++ > 6) m_tick_idx = 0;
5164 if (NULL != GetStatusBar()) {
5167 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5170 wxString s1(tick_buf, wxConvUTF8);
5172 s1 += toSDMM(1,
gLat);
5174 s1 += toSDMM(2,
gLon);
5176 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5180 if (!std::isnan(
gSog))
5181 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5183 sogcog.Printf(
"SOG --- ");
5187 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5189 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5191 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5192 (
int)toMagnetic(
gCog), 0x00B0);
5194 cogs.Printf((
"COG ---%c"), 0x00B0);
5196 sogcog.Append(cogs);
5197 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5202void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5203 MemFootTimer.Stop();
5205 int memsize = GetApplicationMemoryUse();
5208 printf(
"Memsize: %d \n", memsize);
5211 if (memsize > (g_MemFootMB * 1000)) {
5215 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5216 unsigned int nCache = pCache->GetCount();
5219 for (
unsigned int i = 0; i < nCache; i++) {
5229 for (
unsigned int i = 0; i < nCache - 1; i++) {
5230 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5232 pcea[i] = pcea[i + 1];
5243 unsigned int idelete = 0;
5244 unsigned int idelete_max = pCache->GetCount();
5247 unsigned int minimum_cache = 1;
5248 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5250 while ((memsize > (g_MemFootMB * 1000)) &&
5251 (pCache->GetCount() > minimum_cache) &&
5252 (idelete < idelete_max)) {
5253 int memsizeb = memsize;
5257 memsize = GetApplicationMemoryUse();
5258 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5266 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5271void MyFrame::ProcessUnitTest() {
5272 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5279 cc->m_bFollow =
false;
5281 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5282 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5285 if (cc->m_groupIndex > 0) {
5286 while (ut_index < ChartData->GetChartTableEntries() &&
5287 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5291 if (ut_index < ChartData->GetChartTableEntries()) {
5295 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5296 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5303 if (cc->GetQuiltMode()) {
5304 if (cc->IsChartQuiltableRef(ut_index))
5305 cc->SelectQuiltRefdbChart(ut_index);
5307 cc->SelectdbChart(ut_index);
5310 if (g_unit_test_1) {
5318 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5319 cte->GetLatMin(), cte->GetLonMax(), NULL,
5323 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5324 cte->GetLatMax(), cte->GetLonMin(), NULL,
5327 cc->GetSize(&ww, &wh);
5328 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5330 ppm = wxMin(ppm, 1.0);
5337 if (ut_index > ut_index_max) exit(0);
5348 bool b_rotate =
false;
5350 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5353 if (!b_rotate && !g_btenhertz)
return;
5355 bool b_update =
false;
5357 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5360 struct timespec now;
5361 clock_gettime(CLOCK_MONOTONIC, &now);
5362 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5363 double diffc = diff / 1e9;
5366 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5367 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5368 if (gCog_tentative < 0.) gCog_tentative += 360.;
5369 gCog = gCog_tentative;
5373 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5374 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5375 double diffc = diff / 1e9;
5376 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5380 if (gSog_gt && !std::isnan(gCog_gt)) {
5381 double delta_t = diffc / 3600;
5382 double distance = gSog_gt * delta_t;
5385 double angr = gCog_gt / 180 * M_PI;
5386 double latr = gLat_gt * M_PI / 180;
5387 double D = distance / 3443;
5388 double sD = sin(D), cD = cos(D);
5389 double sy = sin(latr), cy = cos(latr);
5390 double sa = sin(angr), ca = cos(angr);
5392 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5393 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5403 if (cc) cc->DoCanvasCOGSet();
5412 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5413 bool bnew = cc->DoCanvasUpdate();
5414 if (!bnew) cc->UpdateShips();
5423 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5426bool MyFrame::ProcessQuitFlag() {
5430 FrameTenHzTimer.Stop();
5432 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5433 if (top) top->Close(
true);
5440void MyFrame::ProcessDeferredTrackOn() {
5443 if (g_bDeferredStartTrack) {
5444 if (!g_bTrackActive) {
5447 g_bDeferredStartTrack =
false;
5450 g_bDeferredStartTrack =
false;
5455void MyFrame::ProcessAnchorWatch() {
5463 double d = g_nAWMax;
5466 bool toofar =
false;
5467 bool tooclose =
false;
5468 if (d >= 0.0) toofar = (dist * 1852. > d);
5469 if (d < 0.0) tooclose = (dist * 1852 < -d);
5471 if (tooclose || toofar)
5472 AnchorAlertOn1 =
true;
5474 AnchorAlertOn1 =
false;
5476 AnchorAlertOn1 =
false;
5484 double d = g_nAWMax;
5487 bool toofar =
false;
5488 bool tooclose =
false;
5489 if (d >= 0) toofar = (dist * 1852. > d);
5490 if (d < 0) tooclose = (dist * 1852 < -d);
5492 if (tooclose || toofar)
5493 AnchorAlertOn2 =
true;
5495 AnchorAlertOn2 =
false;
5497 AnchorAlertOn2 =
false;
5500 AnchorAlertOn1 =
true;
5503void MyFrame::SendFixToPlugins() {
5514 GPSData.
nSats = g_SatsInView;
5516 wxDateTime tCheck((time_t)m_fixtime);
5517 if (tCheck.IsValid()) {
5526 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5529 SendPositionFixToAllPlugIns(&GPSData);
5533void MyFrame::ProcessLogAndBells() {
5536 wxDateTime lognow = wxDateTime::Now();
5537 int hourLOC = lognow.GetHour();
5538 int minuteLOC = lognow.GetMinute();
5540 int minuteUTC = lognow.GetMinute();
5541 int second = lognow.GetSecond();
5543 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5544 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5545 (minuteUTC == 30)) {
5546 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5547 wxString day = lognow.FormatISODate();
5548 wxString utc = lognow.FormatISOTime();
5549 wxString navmsg =
"LOGBOOK: ";
5557 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5561 if (std::isnan(
gCog))
5562 cog.Printf(
"COG ----- ");
5564 cog.Printf(
"COG %10.5f ",
gCog);
5567 if (std::isnan(
gSog))
5568 sog.Printf(
"SOG ----- ");
5570 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5576 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5579 wxLogMessage(navmsg);
5580 g_loglast_time = lognow;
5582 int bells = (hourLOC % 4) * 2;
5583 if (minuteLOC != 0) bells++;
5584 if (!bells) bells = 8;
5586 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5587 m_BellsToPlay = bells;
5588 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5589 wxPostEvent(
this, ev);
5598 if (ProcessQuitFlag())
return;
5600 if (bDBUpdateInProgress)
return;
5603 FrameTenHzTimer.Stop();
5605 ProcessDeferredTrackOn();
5607 ProcessAnchorWatch();
5608 ProcessLogAndBells();
5610 if (ShouldRestartTrack()) TrackDailyRestart();
5613 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5614 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5615 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5621 if (
gSog > 3.0) g_bCruising =
true;
5627 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5629 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5635 bool bnew_view =
false;
5636 if (!g_btenhertz) bnew_view = DoChartUpdate();
5643 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5646 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5649 cc->DrawBlinkObjects();
5652 if (bactiveRouteUpdate) {
5659 cc->SetOwnShipState(SHIP_NORMAL);
5661 if (cc->GetQuiltMode()) {
5662 double erf = cc->GetQuiltMaxErrorFactor();
5663 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5665 if (cc->m_singleChart) {
5666 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5667 cc->SetOwnShipState(SHIP_LOWACCURACY);
5671 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5674 (bVelocityValid != m_last_bVelocityValid) ||
5675 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5676 if (!g_bopengl) cc->UpdateShips();
5684 m_last_bVelocityValid = bVelocityValid;
5689 bool brq_dynamic =
false;
5691 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5692 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5694 if (pic->m_enabled && pic->m_init_state) {
5695 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5702 if (brq_dynamic) bnew_view =
true;
5706 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5709 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5714 if (cc->GetglCanvas()) {
5716 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5718 if ((!g_btenhertz)) {
5719 if (cc->m_bFollow) {
5720 cc->DoCanvasUpdate();
5737 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5751 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5752 g_pais_query_dialog_active->UpdateText();
5755 if (g_pAISTargetList && (0 == (g_tick % (5))))
5756 g_pAISTargetList->UpdateAISTargetList();
5759 UpdateGPSCompassStatusBoxes();
5764 console->RefreshConsoleData();
5771 if (m_bdefer_resize) {
5772 if (0 == (g_tick % (5))) {
5773 printf(
"___RESIZE\n");
5774 SetSize(m_defer_size);
5776 m_bdefer_resize =
false;
5783 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5785 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5786 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5790double MyFrame::GetMag(
double a,
double lat,
double lon) {
5791 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5792 auto loader = PluginLoader::GetInstance();
5793 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5800 wxDateTime now = wxDateTime::Now();
5801 SendJSON_WMM_Var_Request(lat, lon, now);
5802 if (fabs(gQueryVar) < 360.0)
5803 Variance = gQueryVar;
5805 return toMagnetic(a, Variance);
5808bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5814 v[
"Year"] = date.GetYear();
5815 v[
"Month"] = date.GetMonth();
5816 v[
"Day"] = date.GetDay();
5818 SendJsonMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5824void MyFrame::TouchAISActive() {
5826 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5828 if (cc) cc->TouchAISToolActive();
5832void MyFrame::UpdateAISTool() {
5836 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5838 if (cc) cc->UpdateAISTBTool();
5843void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5845 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5847 if (cc) cc->SetbTCUpdate(
true);
5850 RefreshAllCanvas(
false);
5855void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5859 bool b_rotate =
false;
5860 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5862 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5866 FrameCOGTimer.Stop();
5873 int period_ms = 100;
5875 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5878void MyFrame::DoCOGSet() {
5880 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5882 if (cc) cc->DoCanvasCOGSet();
5886void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5892 wxFont oldfont = pdc->GetFont();
5894 pdc->SetFont(*pFont);
5895 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5896 pdc->SetBackgroundMode(wxTRANSPARENT);
5898 pdc->DrawText(str, x, y + 1);
5899 pdc->DrawText(str, x, y - 1);
5900 pdc->DrawText(str, x + 1, y);
5901 pdc->DrawText(str, x - 1, y);
5903 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5905 pdc->DrawText(str, x, y);
5907 pdc->SetFont(oldfont);
5911void MyFrame::UpdateRotationState(
double rotation) {
5913 g_bCourseUp =
false;
5915 if (fabs(rotation) > .001) {
5916 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5917 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5919 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5922 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5923 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5925 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5929 UpdateGPSCompassStatusBoxes(
true);
5933void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5935 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5937 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5943int MyFrame::GetApplicationMemoryUse() {
5949 wxWindow *fWin = wxWindow::FindFocus();
5951 wxArrayString outputArray;
5952 wxString cmd(
"ps --no-headers -o vsize ");
5953 unsigned long pid = wxGetProcessId();
5955 cmd1.Printf(
"%ld", pid);
5957 wxExecute(cmd, outputArray);
5959 if (outputArray.GetCount()) {
5960 wxString s = outputArray.Item(0);
5962 if (s.ToLong(&vtmp)) memsize = vtmp;
5965 if (fWin) fWin->SetFocus();
5971 PROCESS_MEMORY_COUNTERS pmc;
5973 unsigned long processID = wxGetProcessId();
5975 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5977 if (NULL == hProcess)
return 0;
5979 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
5997 memsize = pmc.WorkingSetSize / 1024;
6000 CloseHandle(hProcess);
6007double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6008 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6011void MyFrame::SetChartUpdatePeriod() {
6014 g_ChartUpdatePeriod = 0;
6019 bool bskewdc =
false;
6020 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6023 if (!g_bopengl && !cc->GetVP().b_quilt) {
6024 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6026 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6030 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6032 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6037 cc->UpdateCanvasControlBar();
6040void MyFrame::selectChartDisplay(
int type,
int family) {
6042 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6044 if (cc) cc->selectCanvasChartDisplay(type, family);
6047 UpdateGlobalMenuItems();
6056bool MyFrame::DoChartUpdate() {
6057 bool return_val =
false;
6060 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6062 if (cc) return_val |= cc->DoCanvasUpdate();
6068void MyFrame::MouseEvent(wxMouseEvent &event) {
6070 event.GetPosition(&x, &y);
6075#include <mach/mach.h>
6076#include <mach/message.h>
6077#include <mach/kern_return.h>
6078#include <mach/task_info.h>
6080#include <malloc/malloc.h>
6087#if defined(__linux__)
6088#include "sys/types.h"
6089#include "sys/sysinfo.h"
6092void MyFrame::DoPrint(
void) {
6094 g_PrintingInProgress =
true;
6097 GetPrimaryCanvas()->GetglCanvas()->Render();
6098 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6108 printer.Initialize(wxLANDSCAPE);
6109 printer.EnablePageNumbers(
false);
6112 bool tooltips_were_enabled = DisableTbarTooltips();
6113 printer.Print(
this, &printout);
6114 if (tooltips_were_enabled) {
6115 EnableTbarTooltips();
6134 g_PrintingInProgress =
false;
6137 GetPrimaryCanvas()->SetFocus();
6143 wxString message_ID =
event.GetID();
6144 wxString message_JSONText =
event.GetJSONText();
6152 if (message_ID ==
"WMM_VARIATION_BOAT") {
6153 nlohmann::json root;
6155 root = nlohmann::json::parse(message_JSONText);
6156 }
catch (nlohmann::json::exception &) {
6161 gVar = root[
"Decl"].get<
double>();
6162 }
catch (nlohmann::json::exception &) {
6168 if (message_ID ==
"WMM_VARIATION") {
6169 nlohmann::json root;
6171 root = nlohmann::json::parse(message_JSONText);
6172 }
catch (nlohmann::json::exception &) {
6176 double decl_val = 0.0;
6177 if (root[
"Decl"].is_number()) {
6178 decl_val = root[
"Decl"].get<
double>();
6179 }
else if (root[
"Decl"].is_string()) {
6180 decl_val = std::stod(root[
"Decl"].get<std::string>());
6183 gQueryVar = decl_val;
6186 if (message_ID ==
"GRIB_TIMELINE") {
6189 v = nlohmann::json::parse(message_JSONText);
6190 }
catch (nlohmann::json::exception &) {
6191 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6194 wxDateTime oldTimeSource = gTimeSource;
6196 if (v[
"Day"].get<int>() == -1) {
6197 gTimeSource = wxInvalidDateTime;
6198 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6200 gTimeSource.Set(v[
"Day"].get<int>(),
6201 (wxDateTime::Month)v[
"Month"].get<int>(),
6202 v[
"Year"].get<int>(), v[
"Hour"].get<int>(),
6203 v[
"Minute"].get<int>(), v[
"Second"].get<int>());
6207 if (oldTimeSource != gTimeSource) {
6209 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6211 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6216 cc->pCwin->Refresh(
false);
6222 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6223 nlohmann::json root;
6224 wxString trk_id =
"";
6227 root = nlohmann::json::parse(message_JSONText);
6228 }
catch (nlohmann::json::exception &) {
6231 if (root.contains(
"Track_ID")) trk_id = root[
"Track_ID"].get<std::string>();
6234 v[
"Track_ID"] = trk_id;
6236 wxString name = wxEmptyString;
6237 if (ptrack->m_GUID == trk_id) {
6238 name = ptrack->GetName();
6239 if (name.IsEmpty()) {
6245 name = _(
"(Unnamed Track)");
6252 v[
"TotalNodes"] = ptrack->GetnPoints();
6253 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6255 v[
"lat"] = tp->m_lat;
6256 v[
"lon"] = tp->m_lon;
6259 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6264 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6266 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6267 nlohmann::json root;
6270 root = nlohmann::json::parse(message_JSONText);
6271 }
catch (nlohmann::json::exception &) {
6275 if (root.contains(
"GUID")) guid = root[
"GUID"].get<std::string>();
6280 wxString name = wxEmptyString;
6282 if ((*it)->m_GUID == guid) {
6283 name = (*it)->m_RouteNameString;
6284 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6290 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6291 itp != (*it)->pRoutePointList->end(); itp++) {
6292 w[i][
"lat"] = (*itp)->m_lat;
6293 w[i][
"lon"] = (*itp)->m_lon;
6294 w[i][
"Name"] = (*itp)->GetName();
6295 w[i][
"Description"] = (*itp)->GetDescription();
6296 w[i][
"GUID"] = (*itp)->m_GUID;
6297 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6299 auto node = (*itp)->m_HyperlinkList->begin();
6300 if (node != (*itp)->m_HyperlinkList->end()) {
6302 while (node != (*itp)->m_HyperlinkList->end()) {
6304 v[i][
"WPLink" + std::to_string(n)] = httpLink->Link;
6305 v[i][
"WPLinkDesciption" + std::to_string(n++)] =
6306 httpLink->DescrText;
6313 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6319 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6320 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6321 nlohmann::json root;
6324 root = nlohmann::json::parse(message_JSONText);
6325 }
catch (nlohmann::json::exception &) {
6328 if (root.contains(
"mode")) {
6329 if (root[
"mode"].get<std::string>() ==
"Track") route =
false;
6334 for (RouteList::iterator it =
pRouteList->begin();
6336 wxString name = (*it)->m_RouteNameString;
6337 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6339 v[i][
"error"] =
false;
6340 v[i][
"name"] = name;
6341 v[i][
"GUID"] = (*it)->m_GUID;
6342 v[i][
"active"] = (*it)->IsActive();
6347 wxString name = ptrack->GetName();
6348 if (name.IsEmpty()) {
6354 name = _(
"(Unnamed Track)");
6356 v[i][
"error"] =
false;
6357 v[i][
"name"] = name;
6358 v[i][
"GUID"] = ptrack->m_GUID;
6363 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6366 v[0][
"error"] =
true;
6367 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6369 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6371 v[0][
"error"] =
true;
6374 v[0][
"error"] =
false;
6375 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6376 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6377 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6378 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6379 v[0][
"active_waypoint_lat"] =
6381 v[0][
"active_waypoint_lon"] =
6385 SendJsonMessageToAllPlugins(
"OCPN_ACTIVE_ROUTELEG_RESPONSE", v);
6389void MyFrame::FilterCogSog() {
6390 if (g_bfilter_cogsog) {
6392 double cog_last =
gCog;
6395 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6396 COGFilterTable[i] = COGFilterTable[i - 1];
6397 COGFilterTable[0] = cog_last;
6400 if (!std::isnan(cog_last)) {
6402 double sum = 0., count = 0;
6403 for (
int i = 0; i < g_COGFilterSec; i++) {
6404 double adder = COGFilterTable[i];
6405 if (std::isnan(adder))
continue;
6407 if (fabs(adder - cog_last) > 180.) {
6408 if ((adder - cog_last) > 0.)
6421 else if (sum >= 360.)
6428 double sog_last =
gSog;
6431 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6432 SOGFilterTable[i] = SOGFilterTable[i - 1];
6433 SOGFilterTable[0] = sog_last;
6436 if (!std::isnan(
gSog)) {
6437 double sum = 0., count = 0;
6438 for (
int i = 0; i < g_SOGFilterSec; i++) {
6439 if (std::isnan(SOGFilterTable[i]))
continue;
6441 sum += SOGFilterTable[i];
6451void MyFrame::LoadHarmonics() {
6454 ptcmgr->LoadDataSources(TideCurrentDataSet);
6456 bool b_newdataset =
false;
6459 for (
auto a :
ptcmgr->GetDataSet()) {
6460 bool b_foundi =
false;
6461 for (
auto b : TideCurrentDataSet) {
6468 b_newdataset =
true;
6473 for (
auto a : TideCurrentDataSet) {
6474 bool b_foundi =
false;
6475 for (
auto b :
ptcmgr->GetDataSet()) {
6482 b_newdataset =
true;
6487 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6491void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6492 if (!ptarget)
return;
6495 wxDateTime mob_time = wxDateTime::Now();
6496 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6497 mob_label += _(
" on ");
6498 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6501 mob_label, wxEmptyString);
6502 pWP_MOB->SetShared(
true);
6504 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6506 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6508 pWP_MOB->SetUseSca(
false);
6516 wxString(_(
"Own ship")), wxEmptyString);
6518 pWP_MOB->SetUseSca(
false);
6525 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6541 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
6544 if (RouteManagerDialog::getInstanceFlag()) {
6551 RefreshAllCanvas(
false);
6553 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6554 mob_message += _(
" Time: ");
6555 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6556 mob_message += _(
" Ownship Position: ");
6557 mob_message += toSDMM(1,
gLat);
6559 mob_message += toSDMM(2,
gLon);
6560 mob_message += _(
" MOB Position: ");
6561 mob_message += toSDMM(1, ptarget->Lat);
6563 mob_message += toSDMM(2, ptarget->Lon);
6564 wxLogMessage(mob_message);
6567void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6571 OwnPoint->m_lat =
gLat;
6572 OwnPoint->m_lon =
gLon;
6574 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6579 MOB_Point->m_lat = ptarget->Lat;
6580 MOB_Point->m_lon = ptarget->Lon;
6582 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6583 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6585 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6586 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6589 RefreshAllCanvas(
false);
6592 wxDateTime mob_time = wxDateTime::Now();
6594 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6595 mob_message += _(
" Time: ");
6596 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6597 mob_message += _(
" Ownship Position: ");
6598 mob_message += toSDMM(1,
gLat);
6600 mob_message += toSDMM(2,
gLon);
6601 mob_message += _(
" MOB Position: ");
6602 mob_message += toSDMM(1, ptarget->Lat);
6604 mob_message += toSDMM(2, ptarget->Lon);
6606 wxLogMessage(mob_message);
6610void MyFrame::applySettingsString(wxString settings) {
6612 int last_UIScaleFactor = g_GUIScaleFactor;
6613 bool previous_expert = g_bUIexpert;
6614 g_last_ChartScaleFactor = g_ChartScaleFactor;
6615 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6618 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6624 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6626 if (rr & S52_CHANGED) {
6628 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6630 ->ClearCNSYLUPArray();
6631 ps52plib->GenerateStateHash();
6635 ProcessOptionsDialog(rr, pNewDirArray);
6640 bool b_newToolbar =
false;
6642 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6644 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6646 if (rr & TOOLBAR_CHANGED) {
6647 b_newToolbar =
true;
6652 if (previous_expert && !g_bUIexpert) {
6653 androidForceFullRepaint();
6657 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6661 SetGPSCompassScale();
6663 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6665 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6667 UpdateGPSCompassStatusBoxes(
true);
6670 AbstractPlatform::ShowBusySpinner();
6672 SetAllToolbarScale();
6676 AbstractPlatform::HideBusySpinner();
6678 RequestNewMasterToolbar(
true);
6685 UpdateControlBar(GetPrimaryCanvas());
6691 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6694#ifdef wxHAS_POWER_EVENTS
6695void MyFrame::OnSuspending(wxPowerEvent &event) {
6699 wxLogMessage(
"System suspend starting...");
6702void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6705 wxLogMessage(
"System is going to suspend.");
6708void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6711 wxLogMessage(
"System suspend was cancelled.");
6714int g_last_resume_ticks;
6715void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6716 wxDateTime now = wxDateTime::Now();
6717 wxLogMessage(
"System resumed from suspend.");
6719 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6722 wxLogMessage(
"Restarting streams.");
6723 g_last_resume_ticks = now.GetTicks();
6727 g_pMUX->ClearStreams();
6729 g_pMUX->StartAllStreams();
6738 if (IsMaximized()) {
6743 wxSize sz = GetSize();
6744 SetSize(wxSize(sz.x - 1, sz.y));
6756void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6757 bool btbRebuild =
false;
6759 bool b_reshow =
true;
6762 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6763 if ((ff > 0.01f) || bforcenew) {
6773 long orient = g_Platform->GetDefaultToolbarOrientation();
6774 wxWindow *toolbarParent =
this;
6776 toolbarParent = GetPrimaryCanvas();
6779 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6780 m_toolbar_callbacks);
6782 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6789 g_bmasterToolbarFull =
true;
6793 CreateMasterToolbar();
6808bool MyFrame::CollapseGlobalToolbar() {
6810 m_nMasterToolCountShown = 1;
6814 g_bmasterToolbarFull =
false;
6830 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6831 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6832 tic->m_bRequired =
true;
6837 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6838 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6842 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6843 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6844 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6849 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6850 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6854 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6855 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6856 _(
"Enable Tracking"),
"MUI_track");
6860 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6861 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6873 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6874 _(
"Print Chart"),
"MUI_print");
6878 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6879 _(
"About OpenCPN"),
"MUI_help");
6883 AddDefaultPositionPlugInTools();
6887 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6888 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6899 ArrayOfPlugInToolbarTools tool_array =
6901 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6903 if (!pttc->b_viz)
continue;
6905 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6908 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6909 if (g_bTrackActive) {
6910 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6917bool MyFrame::CheckAndAddPlugInTool() {
6925 if (!tb)
return false;
6927 int n_tools = tb->GetToolsCount();
6931 ArrayOfPlugInToolbarTools tool_array =
6934 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6936 if (pttc->position == n_tools) {
6937 wxBitmap *ptool_bmp;
6939 switch (global_color_scheme) {
6940 case GLOBAL_COLOR_SCHEME_DAY:
6941 ptool_bmp = pttc->bitmap_day;
6944 case GLOBAL_COLOR_SCHEME_DUSK:
6945 ptool_bmp = pttc->bitmap_dusk;
6947 case GLOBAL_COLOR_SCHEME_NIGHT:
6948 ptool_bmp = pttc->bitmap_night;
6951 ptool_bmp = pttc->bitmap_day;
6956 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6958 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6959 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6960 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6961 tic->m_bPlugin =
true;
6970 while (CheckAndAddPlugInTool()) {
6976bool MyFrame::AddDefaultPositionPlugInTools() {
6983 ArrayOfPlugInToolbarTools tool_array =
6986 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6990 if (!pttc->b_viz)
continue;
6992 if (pttc->position == -1)
6994 wxBitmap *ptool_bmp;
6996 switch (global_color_scheme) {
6997 case GLOBAL_COLOR_SCHEME_DAY:
6998 ptool_bmp = pttc->bitmap_day;
7000 case GLOBAL_COLOR_SCHEME_DUSK:
7001 ptool_bmp = pttc->bitmap_dusk;
7003 case GLOBAL_COLOR_SCHEME_NIGHT:
7004 ptool_bmp = pttc->bitmap_night;
7007 ptool_bmp = pttc->bitmap_day;
7012 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7014 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7015 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7016 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7017 tic->m_bPlugin =
true;
7036typedef struct _MSW_COLOR_SPEC {
7038 wxString S52_RGB_COLOR;
7042MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7043 {COLOR_MENUTEXT,
"UITX1", 0},
7044 {COLOR_BTNSHADOW,
"UIBCK", 0},
7047void SaveSystemColors() {
7061 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7062 while (pcspec->COLOR_NAME != -1) {
7063 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7068void RestoreSystemColors() {
7069 int element[NCOLORS];
7070 int rgbcolor[NCOLORS];
7073 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7074 while (pcspec->COLOR_NAME != -1) {
7075 element[i] = pcspec->COLOR_NAME;
7076 rgbcolor[i] = pcspec->SysRGB_COLOR;
7081 if (pSetSysColors) {
7082 pSetSysColors(i, (
unsigned long *)&element[0],
7083 (
unsigned long *)&rgbcolor[0]);
7089void SetSystemColors(ColorScheme cs) {
7091 int element[NCOLORS];
7092 int rgbcolor[NCOLORS];
7094 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7095 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7096 while (pcspec->COLOR_NAME != -1) {
7097 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7098 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7099 element[i] = pcspec->COLOR_NAME;
7105 pSetSysColors(i, (
unsigned long *)&element[0],
7106 (
unsigned long *)&rgbcolor[0]);
7110 RestoreSystemColors();
7117static const WORD MAX_CONSOLE_LINES =
7122void RedirectIOToConsole()
7127 wxIntPtr lStdHandle;
7129 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7139 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7140 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7141 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7145 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7146 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7147 fp = _fdopen(hConHandle,
"w");
7149 setvbuf(stdout, NULL, _IONBF, 0);
7153 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7154 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7155 fp = _fdopen(hConHandle,
"r");
7157 setvbuf(stdin, NULL, _IONBF, 0);
7161 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7162 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7163 fp = _fdopen(hConHandle,
"w");
7165 setvbuf(stderr, NULL, _IONBF, 0);
7176 FontMgr::Get().SetLocale(g_locale);
7197 if (g_pais_query_dialog_active) {
7198 g_pais_query_dialog_active->Destroy();
7199 g_pais_query_dialog_active = NULL;
7202 auto alert_dlg_active =
7204 if (alert_dlg_active) {
7205 alert_dlg_active->Destroy();
7206 g_pais_alert_dialog_active =
nullptr;
7209 if (g_pAISTargetList) {
7211 g_pAISTargetList->Disconnect_decoder();
7212 g_pAISTargetList->Destroy();
7213 g_pAISTargetList = NULL;
7217 if (gFrame->m_pMenuBar) {
7218 gFrame->SetMenuBar(NULL);
7219 gFrame->m_pMenuBar->Destroy();
7220 gFrame->m_pMenuBar = NULL;
7222 gFrame->BuildMenuBar();
7225 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7227 if (cc) cc->CanvasApplyLocale();
7232 wxString perspective;
7234 pConfig->Read(
"AUIPerspective", &perspective);
7248 bool bno_load =
false;
7249 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7251 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7252 wxAuiPaneInfo pane = pane_array_val[i];
7253 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7259 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7264 gFrame->RequestNewToolbars(
true);
7265 gFrame->RequestNewMasterToolbar(
true);
7272 : wxThread(wxTHREAD_JOINABLE) {
7273 m_filename = filename;
7284 newChart->SetNativeScale(m_scale);
7285 newChart->SetFullExtent(m_ext);
7287 newChart->FindOrCreateSenc(m_filename);
7292 wxString m_filename;
7298static double chart_dist(
int index) {
7304 if (cte.GetBBox().Contains(
gLat,
gLon))
7309 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7310 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7311 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7314 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7315 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7317 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7323WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7324static int CompareInts(
int n1,
int n2) {
7325 double d1 = chart_dist(n1);
7326 double d2 = chart_dist(n2);
7327 return (
int)(d1 - d2);
7332 wxString chart_path;
7337WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7339#include <wx/arrimpl.cpp>
7342void ParseAllENC(wxWindow *parent) {
7343 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7351 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7354 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7356 idx_sorted_by_distance.Add(i);
7360 if (count == 0)
return;
7362 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7368 ArrayOfCompressTargets ct_array;
7369 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7370 int i = idx_sorted_by_distance[j];
7373 double distance = chart_dist(i);
7375 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7378 pct->distance = distance;
7379 pct->chart_path = filename;
7381 ct_array.push_back(pct);
7384 int thread_count = 0;
7387 if (g_nCPUCount > 0)
7388 thread_count = g_nCPUCount;
7390 thread_count = wxThread::GetCPUCount();
7392 if (thread_count < 1) {
7401 for(
int t = 0; t < thread_count; t++)
7405 wxGenericProgressDialog *prog =
nullptr;
7409 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7410 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7412 prog =
new wxGenericProgressDialog();
7414 prog->SetFont(*qFont);
7416 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7417 count + 1, parent, style);
7426 prog->ShowWindowModal();
7435 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7436 wxString filename = ct_array[j].chart_path;
7437 double distance = ct_array[j].distance;
7438 int index =
ChartData->FinddbIndex(filename);
7439 if (index < 0)
continue;
7442 ext.NLAT = cte.GetLatMax();
7443 ext.SLAT = cte.GetLatMin();
7444 ext.WLON = cte.GetLonMin();
7445 ext.ELON = cte.GetLonMax();
7447 int scale = cte.GetScale();
7450 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7453 if (wxThread::IsMain()) {
7455 wxSize sz = prog->GetSize();
7460 prog->Update(count, msg, &skip);
7472 newChart->SetNativeScale(
scale);
7473 newChart->SetFullExtent(ext);
7474 newChart->DisableBackgroundSENC();
7476 newChart->FindOrCreateSenc(filename,
7480 if (wxThread::IsMain()) {
7481 msg.Printf(_(
"ENC Completed."));
7483 prog->Update(count, msg, &skip);
7493 for (
int t = 0;; t = (t + 1) % thread_count) {
7500 if (!workers[t]->IsAlive()) {
7513#if defined(__WXMSW__) || defined(__WXOSX__)
7520 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.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listeners on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
AbstractRestServer implementation and interface to underlying IO thread.
std::string GetEndpoint() override
Return HTTPS url to local rest server.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
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.
void Notify() override
Notify all listeners, no data supplied.
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.
std::vector< ConnectionParams * > & TheConnectionParams()
Return global list of connections.
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.