53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
82#include "model/nav_object_database.h"
94#include "ais_info_gui.h"
95#include "dialog_alert.h"
99#include "ais_info_gui.h"
123#include "load_errors_dlg.h"
126#include "N2KParser.h"
154#include "androidUTIL.h"
162arrayofCanvasPtr g_canvasArray;
168GLenum g_texture_rectangle_format;
171#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
172extern wxLocale *plocale_def_lang;
176extern bool g_b_EnableVBO;
177extern GLenum g_texture_rectangle_format;
181static int g_last_ChartScaleFactor;
182static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
183static int options_subpage = 0;
184static bool b_reloadForPlugins;
186static wxSize options_lastWindowSize(0, 0);
187static wxPoint options_lastWindowPos(0, 0);
191static double gQueryVar = 361.0;
193static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
194static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
196static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
199static wxArrayPtrVoid *UserColourHashTableArray;
204typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
205typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
207static SetSysColors_t pSetSysColors;
208static GetSysColor_t pGetSysColor;
210void SaveSystemColors();
211void RestoreSystemColors();
216DWORD color_3ddkshadow;
218DWORD color_activecaption;
219DWORD color_gradientactivecaption;
220DWORD color_captiontext;
221DWORD color_windowframe;
222DWORD color_inactiveborder;
227#include <wx/msw/msvcrt.h>
231static const long long lNaN = 0xfff8000000000000;
232#define NAN (*(double *)&lNaN)
235static wxArrayPtrVoid *UserColorTableArray = 0;
238static double gLat_gt, gLon_gt;
239static double gLat_gt_m1, gLon_gt_m1;
240static uint64_t fix_time_gt;
241static uint64_t fix_time_gt_last;
243static double gSog_gt, gHdt_gt;
244static double gCog_gt_m1, gHdt_gt_m1;
245static uint64_t hdt_time_gt;
246static double cog_rate_gt, hdt_rate_gt;
248void InitializeUserColors();
249void DeInitializeUserColors();
250void SetSystemColors(ColorScheme cs);
252static bool LoadAllPlugIns(
bool load_enabled) {
253 AbstractPlatform::ShowBusySpinner();
254 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
255 AbstractPlatform::HideBusySpinner();
259static void LaunchLocalHelp() {
261 androidLaunchHelpView();
263 wxString def_lang_canonical =
"en_US";
266 if (plocale_def_lang)
267 def_lang_canonical = plocale_def_lang->GetCanonicalName();
270 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
272 wxString help_try = help_locn + def_lang_canonical +
".html";
274 if (!::wxFileExists(help_try)) {
275 help_try = help_locn +
"en_US" +
".html";
277 if (!::wxFileExists(help_try)) {
278 help_try = help_locn +
"web" +
".html";
281 if (!::wxFileExists(help_try))
return;
284 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
288static void DoHelpDialog() {
300 [] { LaunchLocalHelp(); });
312#if defined(__WXGTK__) || defined(__WXQT__)
313#include "bitmaps/opencpn.xpm"
327void BuildiENCToolbar(
bool bnew) {
328 if (g_bInlandEcdis) {
332 wxPoint tbp_incanvas =
335 g_iENCToolbarPosY = tbp_incanvas.y;
336 g_iENCToolbarPosX = tbp_incanvas.x;
344 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
348 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
351 g_iENCToolbarPosY = -1;
354 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
360 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
364 double tool_scale_factor =
365 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
368 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
379 if (chart ==
nullptr)
return false;
382 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
384 if (cc && cc->m_singleChart == chart) {
391#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
394static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
395 const char *prop_name) {
399 unsigned long ret_nitems;
400 unsigned long ret_bytes_after;
401 unsigned char *ret_prop;
403 xa_prop_name = XInternAtom(disp, prop_name, False);
411 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
412 &xa_ret_type, &ret_format, &ret_nitems,
413 &ret_bytes_after, &ret_prop) != Success)
416 if (xa_ret_type != xa_prop_type) {
420 return (
char *)ret_prop;
425static bool isTransparentToolbarInOpenGLOK() {
432 if (!g_bdisable_opengl) {
433 Display *disp = XOpenDisplay(NULL);
435 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_NET_SUPPORTING_WM_CHECK")) ||
438 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
440 "_WIN_SUPPORTING_WM_CHECK"))) {
443 if ((wm_name = get_X11_property(disp, *sup_window,
444 XInternAtom(disp,
"UTF8_STRING", False),
446 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
449 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
470wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
472BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
473EVT_CLOSE(MyFrame::OnCloseWindow)
474EVT_MENU(wxID_EXIT, MyFrame::OnExit)
475EVT_SIZE(MyFrame::OnSize)
476EVT_MOVE(MyFrame::OnMove)
477EVT_ICONIZE(MyFrame::OnIconize)
478EVT_MENU(-1, MyFrame::OnToolLeftClick)
479EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
481EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
482EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
483EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
485EVT_MAXIMIZE(MyFrame::OnMaximize)
486EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
487 MyFrame::RequestNewToolbarArgEvent)
488EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
490EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
491EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
492EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
494#ifdef wxHAS_POWER_EVENTS
495EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
496EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
497EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
498EVT_POWER_RESUME(MyFrame::OnResume)
509static
void onBellsFinishedCB(
void *ptr) {
510 auto framePtr =
static_cast<MyFrame *
>(ptr);
512 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
513 wxPostEvent(framePtr, ev);
518 auto msg = ev.GetString().ToStdString();
519 auto ¬eman = NotificationManager::GetInstance();
520 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
523static NmeaLog *GetDataMonitor() {
524 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
525 return dynamic_cast<NmeaLog *
>(w);
529MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
530 const wxSize &size,
long style,
531 wxAuiDefaultDockArt *pauidockart)
532 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
533 m_connections_dlg(nullptr),
535 m_pauidockart(pauidockart) {
547 m_last_track_rotation_ts = 0;
548 m_ulLastNMEATicktime = 0;
549 m_data_monitor->Hide();
551 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
555 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
558 InitTimer.SetOwner(
this, INIT_TIMER);
560 m_initializing =
false;
563 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
566 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
569 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
572 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
575 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
577 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
586 m_bTimeIsSet =
false;
589 m_bdefer_resize =
false;
592 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
593 COGFilterTable[i] = NAN;
594 SOGFilterTable[i] = NAN;
596 m_last_bGPSValid =
false;
597 m_last_bVelocityValid =
false;
607 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
612 double process_noise_std = 1.0;
613 double measurement_noise_std = 0.5;
615 m_ChartUpdatePeriod = 1;
620 log_callbacks.log_is_active = [&]() {
621 auto log = GetDataMonitor();
622 return log && log->IsVisible();
624 log_callbacks.log_message = [&](
Logline ll) {
625 NmeaLog *monitor = GetDataMonitor();
628 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
631 ais_callbacks.confirm_stop_track = []() {
632 int r = OCPNMessageBox(
634 _(
"This AIS target has Persistent tracking selected by MMSI "
636 "A Persistent track recording will therefore be restarted for this "
638 "Do you instead want to stop Persistent tracking for this target?"),
639 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
640 return r == wxID_YES;
642 ais_callbacks.get_target_mmsi = []() {
643 auto alert_dlg_active =
645 assert(alert_dlg_active);
646 return alert_dlg_active->Get_Dialog_MMSI();
654 wxLogMessage(
" **** Connect stuff");
660 Connect(wxEVT_OCPN_MSG,
661 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
669 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
677#if defined(__WXGTK__) || defined(__WXQT__)
678 wxIcon app_icon(opencpn);
686 wxDynamicLibrary dllUser32(
"user32.dll");
688 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
689 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
694 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
699 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
700 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
702 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
704 [&](wxCommandEvent) { Refresh(); });
705 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
707 m_update_statusbar_listener.Init(
708 GuiEvents::GetInstance().gframe_update_status_bar,
710 m_center_aistarget_listener.Init(
711 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
712 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
713 CenterAisTarget(ais_target);
718 EnableFullScreenView();
720 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
726 FrameTenHzTimer.Stop();
741 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
747void MyFrame::FreezeCharts() {
750 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
752 if (cc && !cc->IsFrozen()) cc->Freeze();
756void MyFrame::CenterAisTarget(
757 const std::shared_ptr<const AisTargetData> &ais_target) {
765 double factor = cc->GetScaleValue() / 5000.0;
766 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
772void MyFrame::ThawCharts() {
775 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
777 if (cc && cc->IsFrozen()) cc->Thaw();
784 switch (event.type) {
785 case SENC_BUILD_STARTED:
788 case SENC_BUILD_DONE_NOERROR:
790 chart =
event.m_ticket->m_chart;
792 chart->PostInit(FULL_INIT, global_color_scheme);
794 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
796 if (cc) cc->ClearS52PLIBStateHash();
801 delete event.m_ticket;
803 case SENC_BUILD_DONE_ERROR:
811void MyFrame::RebuildChartDatabase() {
812 bool b_SetInitialPoint =
false;
815 ArrayOfCDI ChartDirArray;
816 pConfig->LoadChartDirArray(ChartDirArray);
818 if (ChartDirArray.GetCount()) {
823 _(
"OpenCPN needs to update the chart database from config file "
827 wxICON_INFORMATION | wxOK);
835 _(
"Rebuilding chart database from configuration file entries..."));
839 wxString dummy1 = _(
"Elapsed time : ");
840 wxString dummy2 = _(
"Estimated time : ");
841 wxString dummy3 = _(
"Remaining time : ");
842 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
843 _(
"OpenCPN Chart Update"), line, 100, NULL,
844 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
845 wxPD_REMAINING_TIME);
848 ChartData->SaveBinary(ChartListFileName);
858void MyFrame::OnBellsFinished(wxCommandEvent &event) {
859 int bells = wxMin(m_BellsToPlay, 2);
860 if (bells <= 0)
return;
862 wxString soundfile =
"sounds";
863 appendOSDirSlash(&soundfile);
864 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
865 soundfile.Prepend(g_Platform->GetSharedDataDir());
866 wxLogMessage(
"Using bells sound file: " + soundfile);
868 o_sound::Sound *sound = bells_sound[bells - 1];
869 sound->SetFinishedCallback(onBellsFinishedCB,
this);
870 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
871 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
872 sound->Load(soundfile);
873 if (!sound->IsOk()) {
874 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
878 m_BellsToPlay -= bells;
881void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
883void MyFrame::OnMaximize(wxMaximizeEvent &event) {
890ColorScheme GetColorScheme() {
return global_color_scheme; }
892ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
894void MyFrame::ReloadAllVP() {
895 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
897 if (cc) cc->ReloadVP();
901void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
902 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
905 global_color_scheme = cs;
908 case GLOBAL_COLOR_SCHEME_DAY:
911 case GLOBAL_COLOR_SCHEME_DUSK:
914 case GLOBAL_COLOR_SCHEME_NIGHT:
915 SchemeName =
"NIGHT";
922 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
924 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
925 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
926 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
927 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
928 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
930 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
959 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
960 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
964 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
967 unsigned Usercolortable_index = 0;
968 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
969 colTable *ct = (colTable *)UserColorTableArray->Item(i);
970 if (SchemeName.IsSameAs(*ct->tableName)) {
971 Usercolortable_index = i;
976 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
980 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
985 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
988 cc->SetColorScheme(cs);
989 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
990 cc->HideChartInfoWindow();
991 cc->SetQuiltChartHiLiteIndex(-1);
997 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1009 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1022 if (g_pais_query_dialog_active) {
1023 bool b_isshown = g_pais_query_dialog_active->IsShown();
1024 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1025 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1027 g_pais_query_dialog_active->Close();
1030 g_pais_query_dialog_active->
Create(
1031 this, -1, _(
"AIS Target Query"),
1032 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1033 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1034 g_pais_query_dialog_active->UpdateText();
1035 if (b_isshown) g_pais_query_dialog_active->Show();
1038 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1040 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1044 ApplyGlobalColorSchemetoStatusBar();
1046 UpdateAllToolbars(cs);
1051 bool btoolbarFull = g_bmasterToolbarFull;
1057 if (!btoolbarFull) {
1059 RequestNewMasterToolbar();
1061 CollapseGlobalToolbar();
1064 RequestNewMasterToolbar();
1073void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1074 if (m_pStatusBar != NULL) {
1075 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1076 m_pStatusBar->ClearBackground();
1081 if (g_canvasArray.GetCount() > 0)
1082 return g_canvasArray.Item(0);
1086void MyFrame::CancelAllMouseRoute() {
1088 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1090 if (cc) cc->CancelMouseRoute();
1094void MyFrame::NotifyChildrenResize() {}
1096void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1104 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1112 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1121 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1124 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1125 config_array.Item(i)->canvas = NULL;
1131 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1132 g_canvasArray.RemoveAt(i);
1136 switch (g_canvasConfig) {
1139 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1142 g_canvasArray.Add(cc);
1144 cc = g_canvasArray[0];
1150 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1151 cc->GetglCanvas()->Show();
1154 config_array.Item(0)->canvas = cc;
1158 cc->ApplyCanvasConfig(config_array.Item(0));
1162 cc->ConfigureChartBar();
1163 cc->SetColorScheme(global_color_scheme);
1164 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1165 cc->SetShowGPS(
true);
1168 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1170 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1176 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1178 g_canvasArray.Add(cc);
1180 cc = g_canvasArray[0];
1186 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1189 config_array.Item(0)->canvas = cc;
1191 cc->ApplyCanvasConfig(config_array.Item(0));
1194 cc->ConfigureChartBar();
1195 cc->SetColorScheme(global_color_scheme);
1196 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1197 cc->SetShowGPS(
false);
1200 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1202 .CaptionVisible(
false)
1204 .CloseButton(
false);
1209 g_canvasArray.Add(cc);
1213 if (config_array.GetCount() < 2) {
1215 pcc->configIndex = 1;
1219 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1220 config_array.Add(pcc);
1223 config_array.Item(1)->canvas = cc;
1225 cc->ApplyCanvasConfig(config_array.Item(1));
1228 cc->ConfigureChartBar();
1229 cc->SetColorScheme(global_color_scheme);
1230 cc->SetShowGPS(
true);
1234 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1236 .CaptionVisible(
false)
1238 .CloseButton(
false);
1239 g_pauimgr->GetPane(cc).RightDockable(
true);
1243 config_array.Item(1)->canvasSize =
1244 wxSize(GetClientSize().x / 2, GetClientSize().y);
1245 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1250 if (b_useStoredSize) {
1251 int ccw = config_array.Item(1)->canvasSize.x;
1252 int cch = config_array.Item(1)->canvasSize.y;
1255 if (ccw < GetClientSize().x / 10) {
1256 ccw = GetClientSize().x / 2;
1257 cch = GetClientSize().y;
1260 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1261 cc->SetSize(ccw, cch);
1275 if (g_canvasArray.size() > 1)
1279 console->SetColorScheme(global_color_scheme);
1284 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1290void MyFrame::RequestNewToolbars(
bool bforcenew) {
1291 if (b_inCloseWindow) {
1295 BuildiENCToolbar(bforcenew);
1296 PositionIENCToolbar();
1305void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1311void MyFrame::SetAllToolbarScale() {
1312 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1315void MyFrame::SetGPSCompassScale() {
1316 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1320 wxPoint screenPoint = ::wxGetMousePosition();
1323 switch (g_canvasConfig) {
1325 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1328 if (canvas->GetScreenRect().Contains(
1332 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1335 if (canvas->GetScreenRect().Contains(
1342 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1345 if (canvas->GetScreenRect().Contains(
1346 canvas->ScreenToClient(screenPoint)))
1354int MyFrame::GetCanvasIndexUnderMouse() {
1355 wxPoint screenPoint = ::wxGetMousePosition();
1358 switch (g_canvasConfig) {
1360 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1363 if (canvas->GetScreenRect().Contains(
1367 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1370 if (canvas->GetScreenRect().Contains(
1377 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1380 if (canvas->GetScreenRect().Contains(
1381 canvas->ScreenToClient(screenPoint)))
1389bool MyFrame::DropMarker(
bool atOwnShip) {
1396 if (!canvas)
return false;
1403 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1405 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1407 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1412 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1413 pRouteManagerDialog->UpdateWptListCtrl();
1418 RefreshAllCanvas(
false);
1423void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1424 if (g_canvasConfig != 0) {
1427 int nTargetGTK = -1;
1429 wxWindow *source = FindFocus();
1435 switch (g_canvasConfig) {
1437 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1440 if (canvas && (canvas == test)) {
1445 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1448 if (canvas && (canvas == test)) {
1456 int nfinalTarget = nTarget;
1458 nfinalTarget = nTargetGTK;
1460 target = ConfigMgr::Get()
1461 .GetCanvasConfigArray()
1466 target->Refresh(
true);
1477void MyFrame::FastClose() {
1479 FrameTenHzTimer.Stop();
1481 FrameTimer1.Start(1);
1485void MyFrame::OnExit(wxCommandEvent &event) {
1489void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1492 if (b_inCloseWindow) {
1502 if (!g_bDeferredInitDone)
return;
1519 if (bDBUpdateInProgress)
return;
1521 b_inCloseWindow =
true;
1523 ::wxSetCursor(wxCURSOR_WAIT);
1527 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1529 if (cc && cc->IsMeasureActive()) {
1530 cc->CancelMeasureRoute();
1535 SendPreShutdownHookToPlugins();
1539 if (g_pAISTargetList) {
1540 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1541 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1542 g_pauimgr->DetachPane(g_pAISTargetList);
1553 pConfig->SetPath(
"/AUI");
1554 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1569 SetCursor(wxCURSOR_WAIT);
1571 RefreshAllCanvas(
true);
1577 RestoreScreenBrightness();
1588 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1589 g_iENCToolbarPosY = tbp_incanvas.y;
1590 g_iENCToolbarPosX = tbp_incanvas.x;
1594 g_bframemax = IsMaximized();
1597 FrameTenHzTimer.Stop();
1599 FrameCOGTimer.Stop();
1613 if (g_bAutoAnchorMark) {
1614 bool watching_anchor =
false;
1622 wxDateTime now = wxDateTime::Now();
1623 wxTimeSpan uptime = now.Subtract(g_start_time);
1625 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1626 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1631 if (g_declutter_anchorage) {
1632 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1633 if (pr->GetName().StartsWith(
"Anchorage")) {
1634 double a =
gLat - pr->m_lat;
1635 double b =
gLon - pr->m_lon;
1636 double l = sqrt((a * a) + (b * b));
1639 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1641 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1642 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1650 wxString name = now.Format();
1651 name.Prepend(_(
"Anchorage created "));
1657 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1662 pConfig->UpdateSettings();
1666 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1670 NavObj_dB::GetInstance().Close();
1674 pConfig->DeleteGroup(
"/Routes");
1675 pConfig->DeleteGroup(
"/Marks");
1701 if (g_pAISTargetList) {
1702 g_pAISTargetList->Disconnect_decoder();
1703 g_pAISTargetList->Destroy();
1710 if (RouteManagerDialog::getInstanceFlag()) {
1711 if (pRouteManagerDialog) {
1712 pRouteManagerDialog->Destroy();
1713 pRouteManagerDialog = NULL;
1727 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1729 if (cc) cc->Destroy();
1732 g_canvasArray.Clear();
1753 MyApp &app = wxGetApp();
1754 app.m_comm_bridge.SaveConfig();
1774 auto ®istry = CommDriverRegistry::GetInstance();
1775 registry.CloseAllDrivers();
1778 for (
auto *cp : TheConnectionParams()) {
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();
1832 wxLogMessage(
"gFrame destroyed.");
1835#ifndef USE_ANDROID_GLES2
1836 qDebug() <<
"Calling OnExit()";
1840 wxTheApp->ExitMainLoop();
1843void MyFrame::OnMove(wxMoveEvent &event) {
1844 auto idx = wxDisplay::GetFromWindow(
this);
1857 DEBUG_LOG <<
"Moved to " << idx
1858#if wxCHECK_VERSION(3, 1, 6)
1859 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1860 << wxDisplay(idx).GetPPI().GetY()
1861 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1863 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1864 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1865 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1866 << wxGetDisplaySizeMM().GetY()
1867 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1876 if (g_config_display_size_manual) {
1885 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1888 cc->SetMUIBarPosition();
1897 UpdateGPSCompassStatusBoxes();
1907 PositionIENCToolbar();
1913 g_nframewin_posx = GetPosition().x;
1914 g_nframewin_posy = GetPosition().y;
1917void MyFrame::ProcessCanvasResize() {
1918 UpdateGPSCompassStatusBoxes(
true);
1922 PositionIENCToolbar();
1925 TriggerRecaptureTimer();
1929void MyFrame::TriggerRecaptureTimer() {
1930 m_recaptureTimer.Start(
1931 1000, wxTIMER_ONE_SHOT);
1934void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1936void MyFrame::SetCanvasSizes(wxSize frameSize) {
1937 if (!g_canvasArray.GetCount())
return;
1940 int cccw = frameSize.x;
1941 int ccch = frameSize.y;
1945 switch (g_canvasConfig) {
1949 cc = g_canvasArray.Item(0);
1951 cc->GetSize( &cur_width, &cur_height );
1952 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1954 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1956 cc->SetSize( 0, 0, cccw, ccch );
1964 cc = g_canvasArray.Item(1);
1966 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1967 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1969 ccw = wxMin(ccw, cccw * 8 / 10);
1970 ccw = wxMax(ccw, cccw * 2 / 10);
1974 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1981 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1998void MyFrame::OnIconize(wxIconizeEvent &event) {
2008 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2010 if (cc && cc->GetMUIBar()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()) {
2012 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2013 cc->GetMUIBar()->PushCanvasOptions();
2022void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2024void MyFrame::ODoSetSize() {
2026 GetClientSize(&x, &y);
2029 if (m_pStatusBar != NULL) {
2030 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2031 int currentCount = m_pStatusBar->GetFieldsCount();
2032 if (currentCount != m_StatusBarFieldCount) {
2033 if ((currentCount > 0) && (currentCount < 7)) {
2036 int widths[] = {2, 2, 2, 2, 2, 2};
2037 m_pStatusBar->SetStatusWidths(currentCount, widths);
2040 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2043 if (m_StatusBarFieldCount) {
2048 if (m_StatusBarFieldCount > 2) {
2049 int widths[] = {-6, -5, -5, -6, -4};
2050 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2051 }
else if (m_StatusBarFieldCount == 2) {
2052 int cwidth = x * 90 / 100;
2053 int widths[] = {100, 100};
2054 widths[0] = cwidth * 6.4 / 10.0;
2055 widths[1] = cwidth * 3.6 / 10.0;
2056 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2058 int widths[] = {100, 100};
2059 widths[0] = x * 90 / 100;
2060 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2063 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2064 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2065 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2067 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2069 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2077 m_pStatusBar->GetFieldRect(0, stat_box);
2080 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2082 wxFont sys_font = *wxNORMAL_FONT;
2083 int try_font_size = sys_font.GetPointSize();
2086 int min_font_size = 10;
2096 wxFont *statusBarFont =
2097 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2098 int font_size = statusBarFont->GetPointSize();
2100 font_size = wxMin(font_size,
2103 wxMax(font_size, min_font_size);
2106 font_size = statusBarFont->GetPointSize();
2113 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2114 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2116 int min_height = stat_box.height;
2118 m_pStatusBar->SetFont(*pstat_font);
2119 m_pStatusBar->SetForegroundColour(
2120 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2122 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2124 (min_height >> 1) * 2;
2125 m_pStatusBar->SetMinHeight(min_height);
2134 SetCanvasSizes(GetClientSize());
2136 UpdateGPSCompassStatusBoxes(
true);
2138 if (
console) PositionConsole();
2141 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2143 if (cc) cc->FormatPianoKeys();
2149 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2150 GetPrimaryCanvas()->GetCompass()->GetRect());
2176 options_lastWindowSize = wxSize(0, 0);
2177 options_lastWindowPos = wxPoint(0, 0);
2184 if (!b_inCloseWindow) {
2187 resizeAndroidPersistents();
2191 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2192 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2198void MyFrame::PositionConsole() {
2199#if defined(__WXMSW__) || defined(__WXMAC__)
2200 if (NULL == GetPrimaryCanvas())
return;
2202 int ccx, ccy, ccsx, ccsy, consx, consy;
2204 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2207 consoleHost->GetSize(&ccsx, &ccsy);
2208 consoleHost->GetPosition(&ccx, &ccy);
2210 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2211 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2212 consoleHost = GetPrimaryCanvas();
2217 if (consoleHost->GetCompass()) {
2218 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2220 if (compass_rect.y < 100)
2221 yOffset = compass_rect.y + compass_rect.height + 45;
2225 wxSize csz =
console->GetSize();
2229 wxPoint screen_pos =
2230 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2233 if (NULL == GetPrimaryCanvas())
return;
2235 int ccx, ccy, ccsx, ccsy, consx, consy;
2237 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2240 consoleHost->GetSize(&ccsx, &ccsy);
2241 consoleHost->GetPosition(&ccx, &ccy);
2243 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2244 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2245 consoleHost = GetPrimaryCanvas();
2248 int yTopOffset = 60;
2249 int yBottomOffset = 0;
2251 if (consoleHost->GetCompass()) {
2252 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2254 if (compass_rect.y < 100)
2255 yTopOffset = compass_rect.y + compass_rect.height;
2257 if (consoleHost->GetMUIBar()) {
2258 wxRect mui_rect = consoleHost->GetMUIBarRect();
2259 yBottomOffset = ccsy - mui_rect.y;
2263 wxSize csz =
console->GetSize();
2266 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2268 if (consy < yAvail) {
2269 yFinal = (yAvail - consy) / 2;
2270 yFinal += yTopOffset;
2271 }
else if (
console->GetCDI()->IsShown()) {
2272 int cdi_height =
console->GetCDI()->GetSize().y;
2273 int consy_no_cdi = consy - cdi_height;
2274 yFinal = (yAvail - consy_no_cdi) / 2;
2275 yFinal += yTopOffset;
2279 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2284void MyFrame::UpdateAllFonts() {
2293 DestroyPersistentDialogs();
2295 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2300void MyFrame::DestroyPersistentDialogs() {
2301 if (g_pais_query_dialog_active) {
2302 g_pais_query_dialog_active->Hide();
2303 g_pais_query_dialog_active->Destroy();
2304 g_pais_query_dialog_active = NULL;
2332void MyFrame::RefreshGroupIndices() {
2334 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2336 if (cc) cc->canvasRefreshGroupIndex();
2340void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2343 switch (event.GetId()) {
2344 case ID_MENU_SCALE_OUT:
2345 DoStackDelta(GetPrimaryCanvas(), 1);
2349 case ID_MENU_SCALE_IN:
2350 DoStackDelta(GetPrimaryCanvas(), -1);
2354 case ID_MENU_ZOOM_IN: {
2355 if (GetFocusCanvas()) {
2356 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2361 case ID_MENU_ZOOM_OUT: {
2362 if (GetFocusCanvas()) {
2363 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2368 case ID_MENU_ROUTE_NEW: {
2369 if (GetFocusCanvas()) {
2370 if (0 == GetFocusCanvas()->m_routeState) {
2371 GetFocusCanvas()->StartRoute();
2373 GetFocusCanvas()->FinishRoute();
2379 case ID_MENU_TOOL_MEASURE: {
2380 GetPrimaryCanvas()->StartMeasureRoute();
2384 case ID_MENU_TOOL_NMEA_DBG_LOG:
2385 m_data_monitor->Show();
2386 m_data_monitor->Raise();
2389 case ID_MENU_TOOL_IO_MONITOR:
2390 m_data_monitor->Show();
2393 case ID_MENU_MARK_BOAT: {
2398 case ID_MENU_MARK_CURSOR: {
2403 case ID_MENU_NAV_FOLLOW: {
2404 if (
gFrame->GetPrimaryCanvas())
2405 gFrame->GetPrimaryCanvas()->TogglebFollow();
2409 case ID_MENU_CHART_OUTLINES: {
2410 ToggleChartOutlines(GetFocusCanvas());
2414 case ID_MENU_CHART_QUILTING: {
2415 ToggleQuiltMode(GetFocusCanvas());
2419 case ID_MENU_UI_CHARTBAR: {
2420 ToggleChartBar(GetFocusCanvas());
2424 case ID_MENU_ENC_TEXT:
2426 ToggleENCText(GetFocusCanvas());
2429 case ID_MENU_ENC_LIGHTS: {
2430 ToggleLights(GetFocusCanvas());
2433 case ID_MENU_ENC_SOUNDINGS: {
2434 ToggleSoundings(GetFocusCanvas());
2437 case ID_MENU_ENC_ANCHOR: {
2438 ToggleAnchor(GetFocusCanvas());
2441 case ID_MENU_ENC_DATA_QUALITY: {
2442 ToggleDataQuality(GetFocusCanvas());
2445 case ID_MENU_SHOW_NAVOBJECTS: {
2446 ToggleNavobjects(GetFocusCanvas());
2450 case ID_MENU_AIS_TARGETS: {
2451 ToggleAISDisplay(GetFocusCanvas());
2454 case ID_MENU_AIS_MOORED_TARGETS: {
2455 g_bHideMoored = !g_bHideMoored;
2458 case ID_MENU_AIS_SCALED_TARGETS: {
2459 ToggleAISMinimizeTargets(GetFocusCanvas());
2463 case ID_MENU_AIS_TARGETLIST: {
2464 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2468 case ID_MENU_AIS_TRACKS: {
2469 g_bAISShowTracks = !g_bAISShowTracks;
2470 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2474 case ID_MENU_AIS_CPADIALOG: {
2475 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2476 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2477 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2478 if (g_bAIS_CPA_Alert) {
2479 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2484 case ID_MENU_AIS_CPASOUND: {
2485 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2486 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2490 case ID_MENU_AIS_CPAWARNING: {
2491 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2492 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2496 case wxID_PREFERENCES:
2503 case ID_SETTINGS_NEW: {
2508 case ID_SETTINGS_DELETE: {
2511 g_pOptions =
nullptr;
2515 case ID_RELOAD_CHARTS: {
2520 case ID_MENU_SETTINGS_BASIC: {
2523 androidDisableFullScreen();
2525 DoAndroidPreferences();
2532 case ID_MENU_UI_FULLSCREEN: {
2537 case ID_MENU_SHOW_CURRENTS: {
2538 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2539 GetFocusCanvas()->ReloadVP();
2540 GetFocusCanvas()->Refresh(
false);
2544 case ID_MENU_SHOW_TIDES: {
2545 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2546 GetFocusCanvas()->ReloadVP();
2547 GetFocusCanvas()->Refresh(
false);
2567 case ID_MENU_UI_COLSCHEME:
2568 case ID_COLSCHEME: {
2569 ToggleColorScheme();
2578 case ID_MENU_OQUIT: {
2583 case ID_MENU_ROUTE_MANAGER:
2584 case ID_ROUTEMANAGER: {
2585 pRouteManagerDialog = RouteManagerDialog::getInstance(
2588 if (pRouteManagerDialog->IsShown())
2589 pRouteManagerDialog->Hide();
2591 pRouteManagerDialog->UpdateRouteListCtrl();
2592 pRouteManagerDialog->UpdateTrkListCtrl();
2593 pRouteManagerDialog->UpdateWptListCtrl();
2594 pRouteManagerDialog->UpdateLayListCtrl();
2596 pRouteManagerDialog->Show();
2600 pRouteManagerDialog->Centre();
2601 pRouteManagerDialog->Raise();
2607 case ID_MENU_NAV_TRACK:
2609 if (!g_bTrackActive) {
2611 g_bTrackCarryOver =
true;
2614 g_bTrackCarryOver =
false;
2615 RefreshAllCanvas(
true);
2620 case ID_MENU_CHART_NORTHUP: {
2621 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2624 case ID_MENU_CHART_COGUP: {
2625 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2628 case ID_MENU_CHART_HEADUP: {
2629 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2633 case ID_MENU_MARK_MOB:
2639 case ID_MASTERTOGGLE: {
2641 wxString tip = _(
"Show Toolbar");
2642 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2644 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2646 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2649 if (g_bmasterToolbarFull)
2650 m_nMasterToolCountShown =
2654 m_nMasterToolCountShown = 2;
2656 m_nMasterToolCountShown =
2659 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2667 case ID_CMD_SELECT_CHART_TYPE: {
2668 selectChartDisplay(event.GetExtraLong(), -1);
2672 case ID_CMD_SELECT_CHART_FAMILY: {
2673 selectChartDisplay(-1, event.GetExtraLong());
2677 case ID_CMD_APPLY_SETTINGS: {
2678 applySettingsString(event.GetString());
2680 androidRestoreFullScreen();
2686 case ID_CMD_NULL_REFRESH: {
2691 case ID_CMD_SETVP: {
2692 setStringVP(event.GetString());
2696 case ID_CMD_INVALIDATE: {
2702 case ID_CMD_POST_JSON_TO_PLUGINS: {
2708 int numErrors = reader.
Parse(event.GetString(), &root);
2709 if (numErrors == 0) {
2710 if (root[
"MessageID"].IsString()) {
2711 wxString MsgID = root[
"MessageID"].
AsString();
2735 ArrayOfPlugInToolbarTools tool_array =
2737 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2739 if (event.GetId() == pttc->id) {
2740 if (pttc->m_pplugin)
2762bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2763 bool viz_now = g_bmasterToolbarFull;
2766 wxString tip = _(
"Show Toolbar");
2768 tip = _(
"Hide Toolbar");
2770 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2773 bool toggle =
false;
2774 if (viz && !g_bmasterToolbarFull)
2777 else if (!viz && g_bmasterToolbarFull)
2781 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2784 if (g_bmasterToolbarFull)
2785 m_nMasterToolCountShown =
2789 m_nMasterToolCountShown = 2;
2791 m_nMasterToolCountShown =
2794 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2800void MyFrame::ScheduleReloadCharts() {
2801 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2802 evt.SetId(ID_RELOAD_CHARTS);
2803 GetEventHandler()->AddPendingEvent(evt);
2806void MyFrame::ScheduleDeleteSettingsDialog() {
2807 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2808 evt.SetId(ID_SETTINGS_DELETE);
2809 GetEventHandler()->AddPendingEvent(evt);
2812void MyFrame::ScheduleSettingsDialog() {
2813 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2814 evt.SetId(ID_SETTINGS);
2815 GetEventHandler()->AddPendingEvent(evt);
2818void MyFrame::ScheduleSettingsDialogNew() {
2819 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2820 evt.SetId(ID_SETTINGS_NEW);
2821 GetEventHandler()->AddPendingEvent(evt);
2824void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2825 UpdateCanvasConfigDescriptors();
2827 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2828 CreateCanvasLayout(
true);
2830 CreateCanvasLayout();
2834 ConfigureStatusBar();
2835 wxSize lastOptSize = options_lastWindowSize;
2840 options_lastWindowSize = lastOptSize;
2844 ScheduleSettingsDialogNew();
2846 ScheduleSettingsDialog();
2851 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2854 int index_hint = -1;
2855 if (i < pathArray.GetCount())
2856 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2857 cc->canvasChartsRefresh(index_hint);
2858 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2867 return GetPrimaryCanvas();
2870void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2871 if (g_bmasterToolbarFull) {
2872#ifndef OCPN_TOOLBAR_ANIMATE
2873 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2876 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2877 m_nMasterToolCountShown++;
2882 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2890#ifndef OCPN_TOOLBAR_ANIMATE
2891 m_nMasterToolCountShown = 1;
2893 if (m_nMasterToolCountShown > 1) {
2894 m_nMasterToolCountShown--;
2898 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2908void MyFrame::InvalidateAllGL() {
2911 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2921void MyFrame::RefreshAllCanvas(
bool bErase) {
2923 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2926 cc->Refresh(bErase);
2931void MyFrame::setStringVP(wxString VPS) {
2936 wxStringTokenizer tkz(VPS,
";");
2938 wxString token = tkz.GetNextToken();
2940 token.ToDouble(&lat);
2942 token = tkz.GetNextToken();
2944 token.ToDouble(&lon);
2946 token = tkz.GetNextToken();
2948 token.ToDouble(&scale_ppm);
2950 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2953void MyFrame::DoSettingsNew() {
2960void MyFrame::DoSettings() {
2964 ApplyGlobalSettings(
true);
2967 bool b_loadHarmonics =
false;
2968 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2971 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2974 if (b_loadHarmonics) LoadHarmonics();
2982 g_bShowChartBar = !g_bShowChartBar;
2984 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2989 if (g_bShowChartBar) {
2991 UpdateControlBar(cc);
2994 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2997void MyFrame::ToggleColorScheme() {
2998 static bool lastIsNight;
2999 ColorScheme s = GetColorScheme();
3002 if (lastIsNight && is == 3)
3005 lastIsNight =
false;
3007 if (lastIsNight) is = 2;
3008 if (is == 3) lastIsNight =
true;
3009 s = (ColorScheme)is;
3010 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3012 SetAndApplyColorScheme(s);
3015void MyFrame::ToggleFullScreen() {
3016 bool to = !IsFullScreen();
3021 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3023 ShowFullScreen(to, style);
3026 UpdateAllToolbars(global_color_scheme);
3028 UpdateControlBar(GetPrimaryCanvas());
3030 TriggerRecaptureTimer();
3033void MyFrame::ActivateMOB() {
3035 wxDateTime mob_time = wxDateTime::Now();
3036 wxString mob_label(_(
"MAN OVERBOARD"));
3037 mob_label += _(
" on ");
3038 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3042 pWP_MOB->SetShared(
true);
3044 pWP_MOB->SetWaypointArrivalRadius(
3046 pWP_MOB->SetUseSca(
false);
3048 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3056 new RoutePoint(zlat, zlon, g_default_wp_icon,
3057 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3058 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3063 temp_route->AddPoint(pWP_src);
3064 temp_route->AddPoint(pWP_MOB);
3066 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3076 temp_route->SetRouteArrivalRadius(-1.0);
3082 v[
"GUID"] = temp_route->
m_GUID;
3083 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3084 SendJSONMessageToAllPlugins(msg_id, v);
3087 if (RouteManagerDialog::getInstanceFlag()) {
3088 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3089 pRouteManagerDialog->UpdateRouteListCtrl();
3090 pRouteManagerDialog->UpdateWptListCtrl();
3095 RefreshAllCanvas(
false);
3097 wxString mob_message(_(
"MAN OVERBOARD"));
3098 mob_message += _(
" Time: ");
3099 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3100 mob_message += _(
" Position: ");
3101 mob_message += toSDMM(1,
gLat);
3103 mob_message += toSDMM(2,
gLon);
3104 wxLogMessage(mob_message);
3106void MyFrame::TrackOn() {
3107 g_bTrackActive =
true;
3115 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3117 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3119 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3122 androidSetTrackTool(
true);
3125 if (RouteManagerDialog::getInstanceFlag()) {
3126 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3127 pRouteManagerDialog->UpdateTrkListCtrl();
3128 pRouteManagerDialog->UpdateRouteListCtrl();
3134 if (name.IsEmpty()) {
3140 name = _(
"(Unnamed Track)");
3144 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3145 SendJSONMessageToAllPlugins(msg_id, v);
3146 g_FlushNavobjChangesTimeout =
3150Track *MyFrame::TrackOff(
bool do_add_point) {
3155 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3157 SendJSONMessageToAllPlugins(msg_id, v);
3166 if (g_bTrackDaily) {
3171 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3172 return_val = pExtendTrack;
3179 g_bTrackActive =
false;
3181 if (RouteManagerDialog::getInstanceFlag()) {
3182 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3183 pRouteManagerDialog->UpdateTrkListCtrl();
3184 pRouteManagerDialog->UpdateRouteListCtrl();
3188 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3190 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3191 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3194 androidSetTrackTool(
false);
3197 g_FlushNavobjChangesTimeout =
3203bool MyFrame::ShouldRestartTrack() {
3205 time_t now = wxDateTime::Now().GetTicks();
3206 time_t today = wxDateTime::Today().GetTicks();
3208 switch (g_track_rotate_time_type) {
3210 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3212 case TIME_TYPE_COMPUTER:
3213 rotate_at = g_track_rotate_time;
3217 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3218 rotate_at = g_track_rotate_time + utc_offset;
3221 if (rotate_at > 86400)
3223 else if (rotate_at < 0)
3225 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3226 now - today >= rotate_at) {
3227 if (m_last_track_rotation_ts == 0) {
3228 if (now - today > rotate_at)
3229 m_last_track_rotation_ts = today + rotate_at;
3231 m_last_track_rotation_ts = today + rotate_at - 86400;
3234 m_last_track_rotation_ts = now;
3240void MyFrame::TrackDailyRestart() {
3242 Track *pPreviousTrack = TrackOff(
true);
3249 if (pPreviousTrack) {
3250 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3254 if (RouteManagerDialog::getInstanceFlag()) {
3255 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3256 pRouteManagerDialog->UpdateTrkListCtrl();
3257 pRouteManagerDialog->UpdateRouteListCtrl();
3262void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3264 cc->SetUpMode(mode);
3266 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3267 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3268 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3271 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3276 cc->SetShowENCText(!cc->GetShowENCText());
3278 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3286void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3289 cc->SetENCDisplayCategory(nset);
3291 UpdateGlobalMenuItems();
3302 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3304 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3313 cc->SetShowENCLights(!cc->GetShowENCLights());
3315 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3325void MyFrame::ToggleRocks(
void )
3331 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3332 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3333 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3334 pOLE->nViz = !pOLE->nViz;
3338 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3339 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3340 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3343 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3347 ps52plib->GenerateStateHash();
3354 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3356 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3364 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3366 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3381 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3382 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3387 cc->SetShowAIS(!cc->GetShowAIS());
3388 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3392void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3393 cc->SetAttenAIS(!cc->GetAttenAIS());
3394 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3400 cc->m_bFollow =
true;
3403 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3407 SetChartUpdatePeriod();
3415 cc->m_bFollow =
false;
3417 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3421 SetChartUpdatePeriod();
3424void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3425 cc->SetShowOutlines(!cc->GetShowOutlines());
3427 RefreshAllCanvas(
false);
3431 if (g_bopengl) InvalidateAllGL();
3434 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3437void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3439void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3441 bool enabled = m_pMenuBar->IsEnabled(item_id);
3442 m_pMenuBar->Enable(item_id,
false);
3443 m_pMenuBar->Check(item_id, state);
3444 m_pMenuBar->Enable(item_id, enabled);
3448void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3455void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3456 wxBitmap *bmpRollover) {
3458 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3463void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3464 wxString rolloverSVGfile,
3465 wxString toggledSVGfile) {
3468 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3472void MyFrame::ConfigureStatusBar() {
3474 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3477 UseNativeStatusBar(
false);
3480 if (g_bShowStatusBar) {
3481 if (!m_pStatusBar) {
3483 CreateStatusBar(m_StatusBarFieldCount, 0);
3484 ApplyGlobalColorSchemetoStatusBar();
3489 m_pStatusBar->Destroy();
3490 m_pStatusBar = NULL;
3496void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3497 ConfigureStatusBar();
3499 wxSize lastOptSize = options_lastWindowSize;
3505 options_lastWindowSize = lastOptSize;
3507 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3510wxString _menuText(wxString name, wxString shortcut) {
3514 menutext <<
"\t" << shortcut;
3519void MyFrame::BuildMenuBar() {
3525 bool showMenuBar =
true;
3527 bool showMenuBar = g_bShowMenuBar;
3539 m_pMenuBar =
new wxMenuBar();
3540 RegisterGlobalMenuItems();
3541 SetMenuBar(m_pMenuBar);
3545 UpdateGlobalMenuItems();
3550 m_pMenuBar->Destroy();
3556void MyFrame::RegisterGlobalMenuItems() {
3557 if (!m_pMenuBar)
return;
3559 wxMenu *nav_menu =
new wxMenu();
3560 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3561 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3562 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3563 nav_menu->AppendSeparator();
3564 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3565 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3566 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3567 nav_menu->AppendSeparator();
3569 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3570 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3572 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3573 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3575 nav_menu->AppendSeparator();
3576 nav_menu->Append(ID_MENU_SCALE_IN,
3577 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3578 nav_menu->Append(ID_MENU_SCALE_OUT,
3579 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3581 nav_menu->AppendSeparator();
3582 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3584 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3586 wxMenu *view_menu =
new wxMenu();
3588 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3589 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3590 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3591 _menuText(_(
"Show Chart Outlines"),
"O"));
3593 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3594 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3595 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3596 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3598 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3599 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3601 view_menu->AppendSeparator();
3603 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3604 _menuText(_(
"Show ENC text"),
"T"));
3605 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3606 _menuText(_(
"Show ENC Lights"),
"L"));
3607 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3608 _menuText(_(
"Show ENC Soundings"),
"S"));
3609 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3610 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3611 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3612 _menuText(_(
"Show ENC Data Quality"),
"U"));
3613 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3614 _menuText(_(
"Show Navobjects"),
"V"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3617 _menuText(_(
"Show ENC text"),
"Alt-T"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3619 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3621 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3622 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3623 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3624 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3625 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3626 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3627 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3629 view_menu->AppendSeparator();
3630 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3631 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3632 view_menu->AppendSeparator();
3634 view_menu->Append(ID_MENU_UI_COLSCHEME,
3635 _menuText(_(
"Change Color Scheme"),
"C"));
3637 view_menu->Append(ID_MENU_UI_COLSCHEME,
3638 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3641 view_menu->AppendSeparator();
3643 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3644 _menuText(_(
"Toggle Full Screen"),
"F11"));
3646 m_pMenuBar->Append(view_menu, _(
"&View"));
3648 wxMenu *ais_menu =
new wxMenu();
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3650 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3651 _(
"Attenuate less critical AIS targets"));
3652 ais_menu->AppendSeparator();
3653 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3654 _(
"Hide Moored AIS Targets"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3656 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3657 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3660 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3661 _menuText(_(
"Show CPA Warnings"),
"W"));
3663 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3664 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3667 ais_menu->AppendSeparator();
3668 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3669 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3671 wxMenu *tools_menu =
new wxMenu();
3672 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3673 _menuText(_(
"Data Monitor"),
"Alt-C"));
3675 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3676 _menuText(_(
"Measure Distance"),
"M"));
3678 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3679 _menuText(_(
"Measure Distance"),
"Alt-M"));
3682 tools_menu->AppendSeparator();
3683 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3684 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3685 tools_menu->AppendSeparator();
3686 tools_menu->Append(ID_MENU_MARK_BOAT,
3687 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3688 tools_menu->Append(ID_MENU_MARK_CURSOR,
3689 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3690 tools_menu->AppendSeparator();
3694 _menuText(_(
"Drop MOB Marker"),
3696 tools_menu->AppendSeparator();
3697 tools_menu->Append(wxID_PREFERENCES,
3698 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3700 tools_menu->Append(ID_MENU_MARK_MOB,
3701 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3702 tools_menu->AppendSeparator();
3703 tools_menu->Append(wxID_PREFERENCES,
3704 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3706 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3709 wxMenu *window_menu =
new wxMenu();
3710 m_pMenuBar->Append(window_menu, _(
"&Window"));
3713 wxMenu *help_menu =
new wxMenu();
3714 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3715 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3716 m_pMenuBar->Append(help_menu, _(
"&Help"));
3719 UpdateGlobalMenuItems();
3722void MyFrame::UpdateGlobalMenuItems() {
3723 if (!m_pMenuBar)
return;
3725 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3726 ->Check(GetPrimaryCanvas()->m_bFollow);
3727 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3728 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3729 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3730 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3731 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3732 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3733 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3734 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3735 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3736 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3737 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3739 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3740 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3741 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3743 if (g_bAIS_CPA_Alert) {
3744 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3745 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3748 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3751 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3752 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3753 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3756 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3757 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3758 ->Check(ps52plib->GetShowSoundings());
3760 bool light_state =
false;
3762 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3764 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3765 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3766 light_state = (pOLE->nViz == 1);
3771 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3772 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3776 DisCat nset = ps52plib->GetDisplayCategory();
3777 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3778 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3779 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3780 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3781 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3782 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3783 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3785 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3786 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3787 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3792void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3793 if (!m_pMenuBar)
return;
3795 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3797 if (cc->GetUpMode() == NORTH_UP_MODE)
3798 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3799 else if (cc->GetUpMode() == COURSE_UP_MODE)
3800 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3802 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3804 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3805 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3806 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3807 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3808 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3809 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3810 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3811 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3812 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3813 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3814 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3815 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3816 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3817 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3818 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3821 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3822 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3825 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3827 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3828 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3833 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3837 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3838 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3839 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3840 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3841 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3842 ->Check(cc->GetShowENCDataQual());
3843 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3845 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3846 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3847 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3852void MyFrame::InvalidateAllCanvasUndo() {
3854 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3856 if (cc) cc->undo->InvalidateUndo();
3860void MyFrame::SubmergeAllCanvasToolbars() {
3862 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3864 if (cc) cc->SubmergeToolbar();
3868void MyFrame::SurfaceAllCanvasToolbars() {
3869 if (g_bshowToolbar) {
3871 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3873 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3880void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3882 if (lon > 180.0) lon -= 360.0;
3887 cc->JumpToPosition(lat, lon,
scale);
3890 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3894void MyFrame::UpdateCanvasConfigDescriptors() {
3896 for (
unsigned int i = 0;
3897 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3898 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3906 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3907 cc->GroupID = chart->m_groupIndex;
3910 cc->
bQuilt = chart->GetQuiltMode();
3917 cc->
bFollow = chart->m_bFollow;
3922 int upmode = chart->GetUpMode();
3923 if (upmode == COURSE_UP_MODE)
3925 else if (upmode == HEAD_UP_MODE)
3932void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3933 if (!RBBox.GetValid())
return;
3935 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3936 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3939 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3940 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3948 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3949 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3951 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3952 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3954 cc->GetSize(&ww, &wh);
3956 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3958 ppm = wxMin(ppm, 1.0);
3964void MyFrame::PrepareOptionsClose(
options *settings,
3965 int settings_return_value) {
3967 options_lastPage = settings->lastPage;
3972 if (options_lastPage == 1) options_lastPage = 0;
3974 options_subpage = settings->lastSubPage;
3975 options_lastWindowPos = settings->lastWindowPos;
3976 options_lastWindowSize = settings->lastWindowSize;
3979 androidEnableBackButton(
true);
3980 androidEnableOptionsMenu(
true);
3981 androidRestoreFullScreen();
3982 androidEnableRotation();
3987void MyFrame::DoOptionsDialog() {
3989 AbstractPlatform::ShowBusySpinner();
3992 pConfig->SetPath(
"/Settings");
3993 pConfig->Read(
"OptionsSizeX", &sx, -1);
3994 pConfig->Read(
"OptionsSizeY", &sy, -1);
3996 wxWindow *optionsParent =
this;
3998 optionsParent = GetPrimaryCanvas();
4003 AbstractPlatform::HideBusySpinner();
4007 g_options->SetInitChartDir(*pInit_Chart_Dir);
4011 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4012 g_options->SetWorkDirListPtr(pWorkDirArray);
4018 prev_locale = g_locale;
4019 g_options->SetInitialPage(options_lastPage, options_subpage);
4022 g_options->lastWindowPos = options_lastWindowPos;
4023 if (options_lastWindowPos != wxPoint(0, 0)) {
4025 g_options->SetSize(options_lastWindowSize);
4029 if (options_lastWindowSize != wxSize(0, 0)) {
4030 g_options->SetSize(options_lastWindowSize);
4035 androidEnableBackButton(
false);
4036 androidEnableOptionsMenu(
false);
4037 androidDisableFullScreen();
4045 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4048 wxString chart_file_name;
4049 if (cc->GetQuiltMode()) {
4050 int dbi = cc->GetQuiltRefChartdbIndex();
4051 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4053 if (cc->m_singleChart)
4054 chart_file_name = cc->m_singleChart->GetFullPath();
4057 pathArray.Add(chart_file_name);
4063 last_canvasConfig = g_canvasConfig;
4066 g_last_ChartScaleFactor = g_ChartScaleFactor;
4072void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4073 bool b_need_refresh =
false;
4075 if ((rr & VISIT_CHARTS) &&
4076 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4078 UpdateChartDatabaseInplace(*pNewDirArray,
4079 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4082 b_need_refresh =
true;
4086 if (rr & STYLE_CHANGED) {
4089 _(
"Please restart OpenCPN to activate language or style changes."),
4090 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4093 bool b_groupchange =
false;
4094 if (((rr & VISIT_CHARTS) &&
4095 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4096 (rr & GROUPS_CHANGED)) {
4097 b_groupchange = ScrubGroupArray();
4099 RefreshGroupIndices();
4102 if (rr & GROUPS_CHANGED || b_groupchange) {
4103 pConfig->DestroyConfigGroups();
4107 if (rr & TIDES_CHANGED) {
4113 if (rr & S52_CHANGED) {
4114 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4117 pConfig->UpdateSettings();
4125 g_Platform->GetDisplayDPmm());
4128 double stuffcog = NAN;
4129 double stuffsog = NAN;
4130 if (!std::isnan(
gCog)) stuffcog =
gCog;
4131 if (!std::isnan(
gSog)) stuffsog =
gSog;
4133 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4134 COGFilterTable[i] = stuffcog;
4135 SOGFilterTable[i] = stuffsog;
4138 SetChartUpdatePeriod();
4140 if (rr & GL_CHANGED) {
4144 b_need_refresh =
true;
4147 if (rr & S52_CHANGED) {
4148 b_need_refresh =
true;
4152 if (rr & REBUILD_RASTER_CACHE) {
4154 GetPrimaryCanvas()->Disable();
4156 GetPrimaryCanvas()->Enable();
4161 if (g_config_display_size_manual &&
4169 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4176 int rrt = rr & S52_CHANGED;
4178 (rrt == S52_CHANGED) ||
4179 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4189 ps52plib->SetScaleFactorExp(
4190 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4191 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4195 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4197 if (cc) cc->ApplyGlobalSettings();
4202 bool ztc = g_bEnableZoomToCursor;
4203 g_bEnableZoomToCursor =
4207 if (!GetPrimaryCanvas()->IsFrozen())
4209 g_bEnableZoomToCursor = ztc;
4212 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4221 SetGPSCompassScale();
4223 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4226 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4227 cc->UpdateCanvasControlBar();
4230 UpdateGPSCompassStatusBoxes();
4232 SetAllToolbarScale();
4233 RequestNewToolbars();
4236 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4239 cc->RebuildCursors();
4244 bool b_masterScaleChange =
false;
4245 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4246 b_masterScaleChange =
true;
4248 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4249 RequestNewMasterToolbar(
true);
4251 bool bMuiChange =
false;
4257 if (b_masterScaleChange || bMuiChange) {
4259 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4262 cc->ProcessNewGUIScale();
4268 if (rr & LOCALE_CHANGED) {
4269 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4271 rr |= NEED_NEW_OPTIONS;
4280 g_last_ChartScaleFactor = g_ChartScaleFactor;
4282 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4287bool MyFrame::CheckGroup(
int igroup) {
4288 if (igroup == 0)
return true;
4292 if (!pGroup->m_element_array.size())
4295 for (
const auto &elem : pGroup->m_element_array) {
4296 for (
unsigned int ic = 0;
4297 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4299 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4301 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4308bool MyFrame::ScrubGroupArray() {
4313 bool b_change =
false;
4314 unsigned int igroup = 0;
4315 while (igroup < g_pGroupArray->GetCount()) {
4316 bool b_chart_in_element =
false;
4319 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4320 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4322 for (
unsigned int ic = 0;
4323 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4325 wxString chart_full_path = pcte->GetFullSystemPath();
4327 if (chart_full_path.StartsWith(element_root)) {
4328 b_chart_in_element =
true;
4334 if (!b_chart_in_element) {
4335 wxString test_string =
"GSHH";
4336 if (element_root.Upper().Contains(test_string))
4337 b_chart_in_element =
true;
4340 if (!b_chart_in_element)
4342 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4354void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4356 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4358 if (cc && (cc != ccThis)) cc->Refresh();
4363void MyFrame::ChartsRefresh() {
4366 AbstractPlatform::ShowBusySpinner();
4368 bool b_run = FrameTimer1.IsRunning();
4371 FrameTenHzTimer.Stop();
4374 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4377 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4378 if (cc->GetQuiltMode()) {
4379 currentIndex = cc->GetQuiltReferenceChartIndex();
4381 cc->canvasChartsRefresh(currentIndex);
4385 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4386 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4388 AbstractPlatform::HideBusySpinner();
4391void MyFrame::InvalidateAllQuilts() {
4392 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4395 cc->InvalidateQuilt();
4396 cc->SetQuiltRefChart(-1);
4397 cc->m_singleChart = NULL;
4402bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4404 const wxString &ChartListFileName) {
4405 bool b_run = FrameTimer1.IsRunning();
4407 FrameTenHzTimer.Stop();
4409 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4410 FrameCOGTimer.Stop();
4413 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4416 cc->InvalidateQuilt();
4417 cc->SetQuiltRefChart(-1);
4418 cc->m_singleChart = NULL;
4428 AbstractPlatform::ShowBusySpinner();
4430 wxGenericProgressDialog *pprog =
nullptr;
4432 wxString longmsg = _(
"OpenCPN Chart Update");
4434 ".................................................................."
4437 pprog =
new wxGenericProgressDialog();
4440 pprog->SetFont(*qFont);
4442 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4443 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4444 wxPD_REMAINING_TIME);
4451 wxLogMessage(
"Starting chart database Update...");
4452 wxString gshhg_chart_loc = gWorldMapLocation;
4453 gWorldMapLocation = wxEmptyString;
4457 ChartData->SaveBinary(ChartListFileName);
4458 wxLogMessage(
"Finished chart database Update");
4460 if (gWorldMapLocation.empty()) {
4464 gWorldMapLocation = gDefaultWorldMapLocation;
4465 gshhg_chart_loc = wxEmptyString;
4468 if (gWorldMapLocation != gshhg_chart_loc) {
4470 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4472 if (cc) cc->ResetWorldBackgroundChart();
4475 gshhsCrossesLandReset();
4480 AbstractPlatform::HideBusySpinner();
4482 pConfig->UpdateChartDirs(DirArray);
4485 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4486 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4488 if (b_runCOGTimer) {
4490 int period_ms = 100;
4492 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4499 cc->ToggleCanvasQuiltMode();
4501 bool cur_mode = cc->GetQuiltMode();
4503 if( !cc->GetQuiltMode() )
4504 cc->SetQuiltMode(
true );
4506 if( cc->GetQuiltMode() ) {
4507 cc->SetQuiltMode(
false );
4508 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4512 if( cur_mode != cc->GetQuiltMode() ){
4518 g_bQuiltEnable = cc->GetQuiltMode();
4522 ps52plib->GenerateStateHash();
4527void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4529void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4531void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4533 cc->DoCanvasStackDelta(direction);
4537void MyFrame::PositionIENCToolbar() {
4541 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4543 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4551void MyFrame::OnInitTimer(wxTimerEvent &event) {
4554 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4558 wxLog::FlushActive();
4560 switch (m_iInitCount++) {
4565 if (g_bInlandEcdis) {
4566 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4567 double range_set = 500.;
4569 range = wxRound(range * 10) / 10.;
4573 else if (range > 2000.)
4575 else if (range > 1600.)
4577 else if (range > 1200.)
4579 else if (range > 800.)
4584 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4588 g_Platform->SetFullscreen(g_bFullscreen);
4592 RebuildChartDatabase();
4593 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4596 cc->SetGroupIndex(0,
false);
4604 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4605 CHART_FAMILY_RASTER)) {
4610 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4611 CHART_FAMILY_VECTOR)) {
4624 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4627 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4629 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4632 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4636 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4637 NavObj_dB::GetInstance().LoadNavObjects();
4640 if (!g_AW1GUID.IsEmpty()) {
4643 if (!g_AW2GUID.IsEmpty()) {
4649 appendOSDirSlash(&layerdir);
4650 layerdir.Append(
"layers");
4652 if (wxDir::Exists(layerdir)) {
4654 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4655 wxLogMessage(laymsg);
4656 pConfig->LoadLayers(layerdir);
4666 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4680 3 * GetCharHeight());
4682 m_data_monitor->Center();
4690 pConfig->SetPath(
"/Settings");
4691 pConfig->Read(
"OptionsSizeX", &sx, -1);
4692 pConfig->Read(
"OptionsSizeY", &sy, -1);
4694 wxWindow *optionsParent =
this;
4696 optionsParent = GetPrimaryCanvas();
4702 BuildiENCToolbar(
true);
4709 if (!g_params.empty()) {
4710 for (
size_t n = 0; n < g_params.size(); n++) {
4711 wxString path = g_params[n];
4712 if (::wxFileExists(path)) {
4714 pSet->load_file(path.fn_str());
4717 pSet->LoadAllGPXObjects(
4718 !pSet->IsOpenCPN(), wpt_dups,
4720 LLBBox box = pSet->GetBBox();
4721 if (box.GetValid()) {
4722 CenterView(GetPrimaryCanvas(), box);
4731 InitAppMsgBusListener();
4736 auto loader = PluginLoader::GetInstance();
4737 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4738 if (!b_haveWMM)
gVar = g_UserVar;
4746 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4749 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4751 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4754 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4758 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4759 NavObj_dB::GetInstance().LoadNavObjects();
4762 if (!g_AW1GUID.IsEmpty()) {
4765 if (!g_AW2GUID.IsEmpty()) {
4771 appendOSDirSlash(&layerdir);
4772 layerdir.Append(
"layers");
4774 if (wxDir::Exists(layerdir)) {
4776 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4777 wxLogMessage(laymsg);
4778 pConfig->LoadLayers(layerdir);
4785 wxLogMessage(
"OnInitTimer...Last Call");
4787 RequestNewMasterToolbar();
4789 PositionIENCToolbar();
4791 g_bDeferredInitDone =
true;
4801 GetPrimaryCanvas()->SetFocus();
4802 GetPrimaryCanvas()->Enable();
4809 if (b_reloadForPlugins) {
4815 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4817 if (cc) cc->SetFirstAuto(
true);
4825 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4827 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4831 cc->CheckGroupValid();
4836 androidEnableBackButton(
true);
4837 androidEnableRotation();
4838 androidEnableOptionItems(
true);
4844 if (g_start_fullscreen) ToggleFullScreen();
4850 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4852 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4854 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4860 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4862 wxLog::FlushActive();
4864 RefreshAllCanvas(
true);
4865 wxGetApp().m_usb_watcher.Start();
4871void MyFrame::InitAppMsgBusListener() {
4872 auto &msgbus = AppMsgBus::GetInstance();
4875 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4876 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4880 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4881 HandleBasicNavMsg(basicnav_msg);
4885 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4886 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4890 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4891 HandleGPSWatchdogMsg(msg);
4898void MyFrame::ReleaseApiListeners() {}
4903 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4904 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4905 server.SetGetRestApiEndpointCb(
4906 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4907 server.open_file_cb = [](
const std::string &path) {
4908 return wxGetApp().OpenFile(path);
4915void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4916 if (msg->gps_watchdog <= 0) {
4917 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4921 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4926 if (m_fix_start_time.IsValid()) {
4927 wxDateTime now = wxDateTime::Now();
4928 wxTimeSpan span = now - m_fix_start_time;
4929 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4930 auto ¬eman = NotificationManager::GetInstance();
4931 wxString msg = _(
"GNSS Position fix lost");
4932 noteman.AddNotification(NotificationSeverity::kCritical,
4934 m_fix_start_time = wxInvalidDateTime;
4938 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4939 bool last_bVelocityValid = bVelocityValid;
4940 bVelocityValid =
false;
4947void MyFrame::CalculateCOGAverage() {
4949 if (!std::isnan(
gCog)) {
4952 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4955 double sum = 0., count = 0;
4957 double adder = COGTable[i];
4958 if (std::isnan(adder))
continue;
4960 if (fabs(adder -
g_COGAvg) > 180.) {
4974 else if (sum >= 360.)
4983void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4984 m_fixtime = msg->time;
4985 double hdt_data_interval = 0;
4986 double fix_time_interval = 0;
4988 double msgtime = msg->set_time.tv_sec;
4989 double m1 = msg->set_time.tv_nsec / 1e9;
4992 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4993 ((msg->vflag & POS_VALID) == POS_VALID)) {
4995 if (!m_fix_start_time.IsValid()) {
4996 m_fix_start_time = wxDateTime::Now();
5001 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5004 fix_time_gt_last = fix_time_gt;
5005 uint64_t fix_time_gt_now =
5006 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5007 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5011 double implied_sog = dist / (fix_time_interval / 3600);
5016 gLat_gt_m1 = gLat_gt;
5017 gLon_gt_m1 = gLon_gt;
5021 fix_time_gt = fix_time_gt_now;
5025 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5026 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5027 gCog_gt_m1 = gCog_gt;
5037 if (!std::isnan(gCog_gt_m1)) {
5039 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5046 if ((fix_time_gt - fix_time_gt_last) > .08) {
5051 if (gCog_gt > gCog_gt_m1) {
5052 if ((gCog_gt - gCog_gt_m1) > 180.)
5057 if ((gCog_gt_m1 - gCog_gt) > 180.)
5062 difft = fabs(gCog_gt - gCog_gt_m1);
5063 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5071 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5072 tentative_cog_rate_gt *= 1e9;
5073 cog_rate_gt = tentative_cog_rate_gt;
5081 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5084static double hdt_avg;
5085 double hdt_norm =
gHdt;
5086 if(
gHdt > 180) hdt_norm -= 360;
5089 hdt_avg += hdt_norm * 0.1;
5094 if (!std::isnan(
gHdt)) {
5096 uint64_t hdt_time_gt_last = hdt_time_gt;
5097 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5098 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5101 if (hdt_data_interval > .09) {
5103 gHdt_gt_m1 = gHdt_gt;
5106 if (!std::isnan(gHdt_gt_m1)) {
5108 double tentative_hdt_rate_gt =
5109 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5110 tentative_hdt_rate_gt *= 1e9;
5112 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5113 hdt_rate_gt = tentative_hdt_rate_gt;
5121 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5124 CalculateCOGAverage();
5132 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5133 if ((msg->vflag & POS_VALID) == POS_VALID)
5138 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5140 bVelocityValid =
true;
5144void MyFrame::UpdateStatusBar() {
5147 unsigned long uiCurrentTickCount;
5148 m_MMEAeventTime.SetToCurrent();
5149 uiCurrentTickCount =
5150 m_MMEAeventTime.GetMillisecond() / 100;
5151 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5152 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5153 m_ulLastNMEATicktime = uiCurrentTickCount;
5155 if (m_tick_idx++ > 6) m_tick_idx = 0;
5160 if (NULL != GetStatusBar()) {
5163 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5166 wxString s1(tick_buf, wxConvUTF8);
5168 s1 += toSDMM(1,
gLat);
5170 s1 += toSDMM(2,
gLon);
5172 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5176 if (!std::isnan(
gSog))
5177 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5179 sogcog.Printf(
"SOG --- ");
5183 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5185 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5187 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5188 (
int)toMagnetic(
gCog), 0x00B0);
5190 cogs.Printf((
"COG ---%c"), 0x00B0);
5192 sogcog.Append(cogs);
5193 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5198void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5199 MemFootTimer.Stop();
5201 int memsize = GetApplicationMemoryUse();
5204 printf(
"Memsize: %d \n", memsize);
5207 if (memsize > (g_MemFootMB * 1000)) {
5211 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5212 unsigned int nCache = pCache->GetCount();
5215 for (
unsigned int i = 0; i < nCache; i++) {
5225 for (
unsigned int i = 0; i < nCache - 1; i++) {
5226 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5228 pcea[i] = pcea[i + 1];
5239 unsigned int idelete = 0;
5240 unsigned int idelete_max = pCache->GetCount();
5243 unsigned int minimum_cache = 1;
5244 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5246 while ((memsize > (g_MemFootMB * 1000)) &&
5247 (pCache->GetCount() > minimum_cache) &&
5248 (idelete < idelete_max)) {
5249 int memsizeb = memsize;
5253 memsize = GetApplicationMemoryUse();
5254 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5262 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5267void MyFrame::CheckToolbarPosition() {
5270 static bool bMaximized;
5272 if (IsMaximized() && !bMaximized) {
5279 PositionIENCToolbar();
5280 }
else if (!IsMaximized() && bMaximized) {
5288 PositionIENCToolbar();
5293void MyFrame::ProcessUnitTest() {
5294 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5301 cc->m_bFollow =
false;
5303 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5304 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5307 if (cc->m_groupIndex > 0) {
5308 while (ut_index < ChartData->GetChartTableEntries() &&
5309 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5313 if (ut_index < ChartData->GetChartTableEntries()) {
5317 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5318 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5325 if (cc->GetQuiltMode()) {
5326 if (cc->IsChartQuiltableRef(ut_index))
5327 cc->SelectQuiltRefdbChart(ut_index);
5329 cc->SelectdbChart(ut_index);
5332 if (g_unit_test_1) {
5340 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5341 cte->GetLatMin(), cte->GetLonMax(), NULL,
5345 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5346 cte->GetLatMax(), cte->GetLonMin(), NULL,
5349 cc->GetSize(&ww, &wh);
5350 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5352 ppm = wxMin(ppm, 1.0);
5359 if (ut_index > ut_index_max) exit(0);
5370 bool b_rotate =
false;
5372 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5375 if (!b_rotate && !g_btenhertz)
return;
5377 bool b_update =
false;
5379 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5382 struct timespec now;
5383 clock_gettime(CLOCK_MONOTONIC, &now);
5384 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5385 double diffc = diff / 1e9;
5388 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5389 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5390 if (gCog_tentative < 0.) gCog_tentative += 360.;
5391 gCog = gCog_tentative;
5395 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5396 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5397 double diffc = diff / 1e9;
5398 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5402 if (gSog_gt && !std::isnan(gCog_gt)) {
5403 double delta_t = diffc / 3600;
5404 double distance = gSog_gt * delta_t;
5407 double angr = gCog_gt / 180 * M_PI;
5408 double latr = gLat_gt * M_PI / 180;
5409 double D = distance / 3443;
5410 double sD = sin(D), cD = cos(D);
5411 double sy = sin(latr), cy = cos(latr);
5412 double sa = sin(angr), ca = cos(angr);
5414 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5415 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5425 if (cc) cc->DoCanvasCOGSet();
5436 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5437 cc->DoCanvasUpdate();
5446 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5449void MyFrame::ProcessQuitFlag() {
5452 wxLogMessage(
"Got quitflag from SIGNAL");
5454 FrameTenHzTimer.Stop();
5461void MyFrame::ProcessDeferredTrackOn() {
5464 if (g_bDeferredStartTrack) {
5465 if (!g_bTrackActive) {
5468 g_bDeferredStartTrack =
false;
5471 g_bDeferredStartTrack =
false;
5476void MyFrame::ProcessAnchorWatch() {
5484 double d = g_nAWMax;
5486 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5487 bool toofar =
false;
5488 bool tooclose =
false;
5489 if (d >= 0.0) toofar = (dist * 1852. > d);
5490 if (d < 0.0) tooclose = (dist * 1852 < -d);
5492 if (tooclose || toofar)
5493 AnchorAlertOn1 =
true;
5495 AnchorAlertOn1 =
false;
5497 AnchorAlertOn1 =
false;
5505 double d = g_nAWMax;
5507 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5508 bool toofar =
false;
5509 bool tooclose =
false;
5510 if (d >= 0) toofar = (dist * 1852. > d);
5511 if (d < 0) tooclose = (dist * 1852 < -d);
5513 if (tooclose || toofar)
5514 AnchorAlertOn2 =
true;
5516 AnchorAlertOn2 =
false;
5518 AnchorAlertOn2 =
false;
5521 AnchorAlertOn1 =
true;
5524void MyFrame::SendFixToPlugins() {
5535 GPSData.
nSats = g_SatsInView;
5537 wxDateTime tCheck((time_t)m_fixtime);
5538 if (tCheck.IsValid()) {
5547 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5550 SendPositionFixToAllPlugIns(&GPSData);
5554void MyFrame::ProcessLogAndBells() {
5557 wxDateTime lognow = wxDateTime::Now();
5558 int hourLOC = lognow.GetHour();
5559 int minuteLOC = lognow.GetMinute();
5561 int minuteUTC = lognow.GetMinute();
5562 int second = lognow.GetSecond();
5564 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5565 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5566 (minuteUTC == 30)) {
5567 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5568 wxString day = lognow.FormatISODate();
5569 wxString utc = lognow.FormatISOTime();
5570 wxString navmsg =
"LOGBOOK: ";
5578 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5582 if (std::isnan(
gCog))
5583 cog.Printf(
"COG ----- ");
5585 cog.Printf(
"COG %10.5f ",
gCog);
5588 if (std::isnan(
gSog))
5589 sog.Printf(
"SOG ----- ");
5591 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5597 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5600 wxLogMessage(navmsg);
5601 g_loglast_time = lognow;
5603 int bells = (hourLOC % 4) * 2;
5604 if (minuteLOC != 0) bells++;
5605 if (!bells) bells = 8;
5607 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5608 m_BellsToPlay = bells;
5609 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5610 wxPostEvent(
this, ev);
5617 CheckToolbarPosition();
5623 if (bDBUpdateInProgress)
return;
5626 FrameTenHzTimer.Stop();
5628 ProcessDeferredTrackOn();
5630 ProcessAnchorWatch();
5631 ProcessLogAndBells();
5633 if (ShouldRestartTrack()) TrackDailyRestart();
5636 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5637 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5638 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5644 if (
gSog > 3.0) g_bCruising =
true;
5650 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5652 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5658 bool bnew_view =
false;
5659 if (!g_btenhertz) bnew_view = DoChartUpdate();
5666 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5669 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5672 cc->DrawBlinkObjects();
5675 if (bactiveRouteUpdate) {
5682 cc->SetOwnShipState(SHIP_NORMAL);
5684 if (cc->GetQuiltMode()) {
5685 double erf = cc->GetQuiltMaxErrorFactor();
5686 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5688 if (cc->m_singleChart) {
5689 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5690 cc->SetOwnShipState(SHIP_LOWACCURACY);
5694 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5697 (bVelocityValid != m_last_bVelocityValid) ||
5698 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5699 if (!g_bopengl) cc->UpdateShips();
5707 m_last_bVelocityValid = bVelocityValid;
5712 bool brq_dynamic =
false;
5714 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5715 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5717 if (pic->m_enabled && pic->m_init_state) {
5718 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5725 if (brq_dynamic) bnew_view =
true;
5729 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5732 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5737 if (cc->GetglCanvas()) {
5739 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5742 if (cc->m_bFollow) {
5743 cc->DoCanvasUpdate();
5750 if (std::isnan(
gCog)) cc->Refresh(
false);
5763 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5777 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5778 g_pais_query_dialog_active->UpdateText();
5781 if (g_pAISTargetList && (0 == (g_tick % (5))))
5782 g_pAISTargetList->UpdateAISTargetList();
5785 UpdateGPSCompassStatusBoxes();
5790 console->RefreshConsoleData();
5797 if (m_bdefer_resize) {
5798 if (0 == (g_tick % (5))) {
5799 printf(
"___RESIZE\n");
5800 SetSize(m_defer_size);
5802 m_bdefer_resize =
false;
5809 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5811 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5812 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5816double MyFrame::GetMag(
double a,
double lat,
double lon) {
5817 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5818 auto loader = PluginLoader::GetInstance();
5819 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5826 wxDateTime now = wxDateTime::Now();
5827 SendJSON_WMM_Var_Request(lat, lon, now);
5828 if (fabs(gQueryVar) < 360.0)
5829 Variance = gQueryVar;
5831 return toMagnetic(a, Variance);
5834bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5840 v[
"Year"] = date.GetYear();
5841 v[
"Month"] = date.GetMonth();
5842 v[
"Day"] = date.GetDay();
5844 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5850void MyFrame::TouchAISActive() {
5852 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5854 if (cc) cc->TouchAISToolActive();
5858void MyFrame::UpdateAISTool() {
5862 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5864 if (cc) cc->UpdateAISTBTool();
5869void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5871 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5873 if (cc) cc->SetbTCUpdate(
true);
5876 RefreshAllCanvas(
false);
5881void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5885 bool b_rotate =
false;
5886 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5888 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5892 FrameCOGTimer.Stop();
5899 int period_ms = 100;
5901 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5904void MyFrame::DoCOGSet() {
5906 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5908 if (cc) cc->DoCanvasCOGSet();
5912void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5918 wxFont oldfont = pdc->GetFont();
5920 pdc->SetFont(*pFont);
5921 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5922 pdc->SetBackgroundMode(wxTRANSPARENT);
5924 pdc->DrawText(str, x, y + 1);
5925 pdc->DrawText(str, x, y - 1);
5926 pdc->DrawText(str, x + 1, y);
5927 pdc->DrawText(str, x - 1, y);
5929 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5931 pdc->DrawText(str, x, y);
5933 pdc->SetFont(oldfont);
5937void MyFrame::UpdateRotationState(
double rotation) {
5939 g_bCourseUp =
false;
5941 if (fabs(rotation) > .001) {
5942 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5943 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5945 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5948 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5949 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5951 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5955 UpdateGPSCompassStatusBoxes(
true);
5959void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5961 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5963 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5969int MyFrame::GetApplicationMemoryUse() {
5975 wxWindow *fWin = wxWindow::FindFocus();
5977 wxArrayString outputArray;
5978 wxString cmd(
"ps --no-headers -o vsize ");
5979 unsigned long pid = wxGetProcessId();
5981 cmd1.Printf(
"%ld", pid);
5983 wxExecute(cmd, outputArray);
5985 if (outputArray.GetCount()) {
5986 wxString s = outputArray.Item(0);
5988 if (s.ToLong(&vtmp)) memsize = vtmp;
5991 if (fWin) fWin->SetFocus();
5997 PROCESS_MEMORY_COUNTERS pmc;
5999 unsigned long processID = wxGetProcessId();
6001 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6003 if (NULL == hProcess)
return 0;
6005 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6023 memsize = pmc.WorkingSetSize / 1024;
6026 CloseHandle(hProcess);
6033double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6034 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6037void MyFrame::SetChartUpdatePeriod() {
6040 g_ChartUpdatePeriod = 0;
6045 bool bskewdc =
false;
6046 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6049 if (!g_bopengl && !cc->GetVP().b_quilt) {
6050 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6052 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6056 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6058 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6063 cc->UpdateCanvasControlBar();
6066void MyFrame::selectChartDisplay(
int type,
int family) {
6068 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6070 if (cc) cc->selectCanvasChartDisplay(type, family);
6073 UpdateGlobalMenuItems();
6082bool MyFrame::DoChartUpdate() {
6083 bool return_val =
false;
6086 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6088 if (cc) return_val |= cc->DoCanvasUpdate();
6094void MyFrame::MouseEvent(wxMouseEvent &event) {
6096 event.GetPosition(&x, &y);
6101#include <mach/mach.h>
6102#include <mach/message.h>
6103#include <mach/kern_return.h>
6104#include <mach/task_info.h>
6106#include <malloc/malloc.h>
6113#if defined(__linux__)
6114#include "sys/types.h"
6115#include "sys/sysinfo.h"
6118void MyFrame::DoPrint(
void) {
6120 g_PrintingInProgress =
true;
6123 GetPrimaryCanvas()->GetglCanvas()->Render();
6124 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6134 printer.Initialize(wxLANDSCAPE);
6135 printer.EnablePageNumbers(
false);
6136 printer.Print(
this, &printout);
6154 g_PrintingInProgress =
false;
6157 GetPrimaryCanvas()->SetFocus();
6163 wxString message_ID =
event.GetID();
6164 wxString message_JSONText =
event.GetJSONText();
6172 if (message_ID ==
"WMM_VARIATION_BOAT") {
6180 int numErrors = reader.
Parse(message_JSONText, &root);
6181 if (numErrors > 0) {
6187 wxString decl = root[
"Decl"].
AsString();
6189 decl.ToDouble(&decl_val);
6195 if (message_ID ==
"WMM_VARIATION") {
6203 int numErrors = reader.
Parse(message_JSONText, &root);
6204 if (numErrors > 0) {
6210 wxString decl = root[
"Decl"].
AsString();
6212 decl.ToDouble(&decl_val);
6214 gQueryVar = decl_val;
6217 if (message_ID ==
"GRIB_TIMELINE") {
6220 int numErrors = r.
Parse(message_JSONText, &v);
6222 if (numErrors > 0) {
6223 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6228 wxDateTime oldTimeSource = gTimeSource;
6230 if (v[
"Day"].AsInt() == -1) {
6231 gTimeSource = wxInvalidDateTime;
6232 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6234 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6235 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6236 v[
"Second"].AsInt());
6240 if (oldTimeSource != gTimeSource) {
6242 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6244 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6249 cc->pCwin->Refresh(
false);
6255 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6258 wxString trk_id = wxEmptyString;
6260 int numErrors = reader.
Parse(message_JSONText, &root);
6261 if (numErrors > 0)
return;
6266 v[
"Track_ID"] = trk_id;
6268 wxString name = wxEmptyString;
6269 if (ptrack->m_GUID == trk_id) {
6270 name = ptrack->GetName();
6271 if (name.IsEmpty()) {
6277 name = _(
"(Unnamed Track)");
6284 v[
"TotalNodes"] = ptrack->GetnPoints();
6285 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6287 v[
"lat"] = tp->m_lat;
6288 v[
"lon"] = tp->m_lon;
6291 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6292 SendJSONMessageToAllPlugins(msg_id, v);
6298 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6299 SendJSONMessageToAllPlugins(msg_id, v);
6301 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6304 wxString guid = wxEmptyString;
6306 int numErrors = reader.
Parse(message_JSONText, &root);
6307 if (numErrors > 0) {
6316 wxString name = wxEmptyString;
6318 if ((*it)->m_GUID == guid) {
6319 name = (*it)->m_RouteNameString;
6320 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6326 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6327 itp != (*it)->pRoutePointList->end(); itp++) {
6328 w[i][
"lat"] = (*itp)->m_lat;
6329 w[i][
"lon"] = (*itp)->m_lon;
6330 w[i][
"Name"] = (*itp)->GetName();
6331 w[i][
"Description"] = (*itp)->GetDescription();
6332 w[i][
"GUID"] = (*itp)->m_GUID;
6333 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6335 auto node = (*itp)->m_HyperlinkList->begin();
6336 if (node != (*itp)->m_HyperlinkList->end()) {
6338 while (node != (*itp)->m_HyperlinkList->end()) {
6340 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6341 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6342 httpLink->DescrText;
6349 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6350 SendJSONMessageToAllPlugins(msg_id, v);
6357 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6358 SendJSONMessageToAllPlugins(msg_id, v);
6359 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6364 int numErrors = reader.
Parse(message_JSONText, &root);
6365 if (numErrors > 0)
return;
6368 wxString str = root[
"mode"].
AsString();
6369 if (str ==
"Track") route =
false;
6374 for (RouteList::iterator it =
pRouteList->begin();
6376 wxString name = (*it)->m_RouteNameString;
6377 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6379 v[i][
"error"] =
false;
6380 v[i][
"name"] = name;
6381 v[i][
"GUID"] = (*it)->m_GUID;
6382 v[i][
"active"] = (*it)->IsActive();
6387 wxString name = ptrack->GetName();
6388 if (name.IsEmpty()) {
6394 name = _(
"(Unnamed Track)");
6396 v[i][
"error"] =
false;
6397 v[i][
"name"] = name;
6398 v[i][
"GUID"] = ptrack->m_GUID;
6403 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6404 SendJSONMessageToAllPlugins(msg_id, v);
6407 v[0][
"error"] =
true;
6408 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6409 SendJSONMessageToAllPlugins(msg_id, v);
6411 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6413 v[0][
"error"] =
true;
6416 v[0][
"error"] =
false;
6417 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6418 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6419 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6420 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6421 v[0][
"active_waypoint_lat"] =
6423 v[0][
"active_waypoint_lon"] =
6427 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6428 SendJSONMessageToAllPlugins(msg_id, v);
6432void MyFrame::FilterCogSog() {
6433 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6435 double cog_last =
gCog;
6438 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6439 COGFilterTable[i] = COGFilterTable[i - 1];
6440 COGFilterTable[0] = cog_last;
6443 if (!std::isnan(cog_last)) {
6445 double sum = 0., count = 0;
6446 for (
int i = 0; i < g_COGFilterSec; i++) {
6447 double adder = COGFilterTable[i];
6448 if (std::isnan(adder))
continue;
6450 if (fabs(adder - cog_last) > 180.) {
6451 if ((adder - cog_last) > 0.)
6464 else if (sum >= 360.)
6471 double sog_last =
gSog;
6474 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6475 SOGFilterTable[i] = SOGFilterTable[i - 1];
6476 SOGFilterTable[0] = sog_last;
6479 if (!std::isnan(
gSog)) {
6480 double sum = 0., count = 0;
6481 for (
int i = 0; i < g_SOGFilterSec; i++) {
6482 if (std::isnan(SOGFilterTable[i]))
continue;
6484 sum += SOGFilterTable[i];
6494void MyFrame::LoadHarmonics() {
6497 ptcmgr->LoadDataSources(TideCurrentDataSet);
6499 bool b_newdataset =
false;
6502 for (
auto a :
ptcmgr->GetDataSet()) {
6503 bool b_foundi =
false;
6504 for (
auto b : TideCurrentDataSet) {
6511 b_newdataset =
true;
6516 for (
auto a : TideCurrentDataSet) {
6517 bool b_foundi =
false;
6518 for (
auto b :
ptcmgr->GetDataSet()) {
6525 b_newdataset =
true;
6530 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6534void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6535 if (!ptarget)
return;
6538 wxDateTime mob_time = wxDateTime::Now();
6539 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6540 mob_label += _(
" on ");
6541 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6544 mob_label, wxEmptyString);
6545 pWP_MOB->SetShared(
true);
6547 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6549 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6551 pWP_MOB->SetUseSca(
false);
6559 wxString(_(
"Own ship")), wxEmptyString);
6561 pWP_MOB->SetUseSca(
false);
6568 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6584 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6585 SendJSONMessageToAllPlugins(msg_id, v);
6588 if (RouteManagerDialog::getInstanceFlag()) {
6589 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6590 pRouteManagerDialog->UpdateRouteListCtrl();
6591 pRouteManagerDialog->UpdateWptListCtrl();
6595 RefreshAllCanvas(
false);
6597 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6598 mob_message += _(
" Time: ");
6599 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6600 mob_message += _(
" Ownship Position: ");
6601 mob_message += toSDMM(1,
gLat);
6603 mob_message += toSDMM(2,
gLon);
6604 mob_message += _(
" MOB Position: ");
6605 mob_message += toSDMM(1, ptarget->Lat);
6607 mob_message += toSDMM(2, ptarget->Lon);
6608 wxLogMessage(mob_message);
6611void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6615 OwnPoint->m_lat =
gLat;
6616 OwnPoint->m_lon =
gLon;
6618 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6623 MOB_Point->m_lat = ptarget->Lat;
6624 MOB_Point->m_lon = ptarget->Lon;
6626 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6627 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6629 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6630 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6633 RefreshAllCanvas(
false);
6636 wxDateTime mob_time = wxDateTime::Now();
6638 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6639 mob_message += _(
" Time: ");
6640 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6641 mob_message += _(
" Ownship Position: ");
6642 mob_message += toSDMM(1,
gLat);
6644 mob_message += toSDMM(2,
gLon);
6645 mob_message += _(
" MOB Position: ");
6646 mob_message += toSDMM(1, ptarget->Lat);
6648 mob_message += toSDMM(2, ptarget->Lon);
6650 wxLogMessage(mob_message);
6654void MyFrame::applySettingsString(wxString settings) {
6656 int last_UIScaleFactor = g_GUIScaleFactor;
6657 bool previous_expert = g_bUIexpert;
6658 g_last_ChartScaleFactor = g_ChartScaleFactor;
6659 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6662 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6665 pConfig->UpdateSettings();
6668 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6670 if (rr & S52_CHANGED) {
6672 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6674 ->ClearCNSYLUPArray();
6675 ps52plib->GenerateStateHash();
6679 ProcessOptionsDialog(rr, pNewDirArray);
6684 bool b_newToolbar =
false;
6686 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6688 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6690 if (rr & TOOLBAR_CHANGED) {
6691 b_newToolbar =
true;
6696 if (previous_expert && !g_bUIexpert) {
6697 androidForceFullRepaint();
6701 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6705 SetGPSCompassScale();
6707 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6709 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6711 UpdateGPSCompassStatusBoxes(
true);
6714 AbstractPlatform::ShowBusySpinner();
6716 SetAllToolbarScale();
6720 AbstractPlatform::HideBusySpinner();
6722 RequestNewMasterToolbar(
true);
6729 UpdateControlBar(GetPrimaryCanvas());
6735 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6738#ifdef wxHAS_POWER_EVENTS
6739void MyFrame::OnSuspending(wxPowerEvent &event) {
6743 wxLogMessage(
"System suspend starting...");
6746void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6749 wxLogMessage(
"System is going to suspend.");
6752void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6755 wxLogMessage(
"System suspend was cancelled.");
6758int g_last_resume_ticks;
6759void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6760 wxDateTime now = wxDateTime::Now();
6761 wxLogMessage(
"System resumed from suspend.");
6763 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6766 wxLogMessage(
"Restarting streams.");
6767 g_last_resume_ticks = now.GetTicks();
6771 g_pMUX->ClearStreams();
6773 g_pMUX->StartAllStreams();
6782 if (IsMaximized()) {
6787 wxSize sz = GetSize();
6788 SetSize(wxSize(sz.x - 1, sz.y));
6800void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6801 bool btbRebuild =
false;
6803 bool b_reshow =
true;
6806 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6807 if ((ff > 0.01f) || bforcenew) {
6817 long orient = g_Platform->GetDefaultToolbarOrientation();
6818 wxWindow *toolbarParent =
this;
6820 toolbarParent = GetPrimaryCanvas();
6823 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6825 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6832 g_bmasterToolbarFull =
true;
6836 CreateMasterToolbar();
6851bool MyFrame::CollapseGlobalToolbar() {
6853 m_nMasterToolCountShown = 1;
6857 g_bmasterToolbarFull =
false;
6873 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6874 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6875 tic->m_bRequired =
true;
6880 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6881 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6885 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6886 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6887 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6892 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6893 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6897 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6898 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6899 _(
"Enable Tracking"),
"MUI_track");
6903 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6904 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6916 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6917 _(
"Print Chart"),
"MUI_print");
6921 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6922 _(
"About OpenCPN"),
"MUI_help");
6926 AddDefaultPositionPlugInTools();
6930 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6931 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6942 ArrayOfPlugInToolbarTools tool_array =
6944 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6946 if (!pttc->b_viz)
continue;
6948 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6951 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6952 if (g_bTrackActive) {
6953 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6960bool MyFrame::CheckAndAddPlugInTool() {
6968 if (!tb)
return false;
6970 int n_tools = tb->GetToolsCount();
6974 ArrayOfPlugInToolbarTools tool_array =
6977 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6979 if (pttc->position == n_tools) {
6980 wxBitmap *ptool_bmp;
6982 switch (global_color_scheme) {
6983 case GLOBAL_COLOR_SCHEME_DAY:
6984 ptool_bmp = pttc->bitmap_day;
6987 case GLOBAL_COLOR_SCHEME_DUSK:
6988 ptool_bmp = pttc->bitmap_dusk;
6990 case GLOBAL_COLOR_SCHEME_NIGHT:
6991 ptool_bmp = pttc->bitmap_night;
6994 ptool_bmp = pttc->bitmap_day;
6999 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7001 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7002 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7003 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7004 tic->m_bPlugin =
true;
7013 while (CheckAndAddPlugInTool()) {
7019bool MyFrame::AddDefaultPositionPlugInTools() {
7026 ArrayOfPlugInToolbarTools tool_array =
7029 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7033 if (!pttc->b_viz)
continue;
7035 if (pttc->position == -1)
7037 wxBitmap *ptool_bmp;
7039 switch (global_color_scheme) {
7040 case GLOBAL_COLOR_SCHEME_DAY:
7041 ptool_bmp = pttc->bitmap_day;
7043 case GLOBAL_COLOR_SCHEME_DUSK:
7044 ptool_bmp = pttc->bitmap_dusk;
7046 case GLOBAL_COLOR_SCHEME_NIGHT:
7047 ptool_bmp = pttc->bitmap_night;
7050 ptool_bmp = pttc->bitmap_day;
7055 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7057 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7058 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7059 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7060 tic->m_bPlugin =
true;
7075wxColour GetGlobalColor(wxString colorName);
7077static const char *usercolors[] = {
7084 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7085 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7086 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7087 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7088 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7092 "UWHIT; 255;255;255;",
7095 "COMPT; 245;247;244",
7099 "DILG0; 255;255;255;",
7101 "DILG0; 238;239;242;",
7103 "DILG1; 212;208;200;",
7104 "DILG2; 255;255;255;",
7116 "CHGRF; 163; 180; 183;",
7118 "CHYLW; 244; 218; 72;",
7119 "CHWHT; 212; 234; 238;",
7122 "UINFM; 197; 69; 195;",
7124 "UINFG; 104; 228; 86;",
7126 "UINFR; 241; 84; 105;",
7127 "UINFF; 125; 137; 140;",
7131 "UDKRD; 124; 16; 0;",
7133 "UARTE; 200; 0; 0;",
7136 "NODTA; 163; 180; 183;",
7138 "SNDG1; 125; 137; 140;",
7140 "SCLBR; 235; 125; 54;",
7143 "UIBDR; 125; 137; 140;",
7144 "UIBCK; 212; 234; 238;",
7145 "UINFB; 58; 120; 240;",
7148 "UINFO; 235; 125; 54;",
7151 "PLRTE; 220; 64; 37;",
7152 "CHMGD; 197; 69; 195;",
7156 "DASHB; 255;255;255;",
7157 "DASHL; 175;175;175;",
7158 "DASHF; 50; 50; 50;",
7159 "DASHR; 200; 0; 0;",
7161 "DASHN; 200;120; 0;",
7162 "DASH1; 204;204;255;",
7163 "DASH2; 122;131;172;",
7164 "COMP1; 211;211;211;",
7167 "GREY3; 40; 40; 40;",
7168 "BLUE4; 100;100;200;",
7169 "VIO01; 171; 33;141;",
7170 "VIO02; 209;115;213;",
7171 "BLUEBACK; 212;234;238;",
7172 "LANDBACK; 201;185;122;",
7178 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7179 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7180 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7181 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7182 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7183 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7184 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7186 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7187 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7188 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7190 "DILG0; 110;110;110;",
7191 "DILG1; 110;110;110;",
7193 "DILG3; 130;130;130;",
7195 "UITX1; 41; 46; 46;",
7198 "UARTE; 64; 64; 64;",
7200 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7201 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7202 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7203 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7205 "DASHB; 77; 77; 77;",
7206 "DASHL; 54; 54; 54;",
7208 "DASHR; 58; 21; 21;",
7209 "DASHG; 21; 58; 21;",
7210 "DASHN; 100; 50; 0;",
7211 "DASH1; 76; 76;113;",
7212 "DASH2; 48; 52; 72;",
7213 "COMP1; 107;107;107;",
7215 "GREY3; 20; 20; 20;",
7216 "BLUE4; 80; 80;160;",
7217 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7218 "LANDBACK; 201;185;122;",
7224 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7225 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7226 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7227 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7228 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7229 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7230 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7231 "DILG0; 80; 80; 80;",
7232 "DILG1; 80; 80; 80;",
7234 "DILG3; 65; 65; 65;",
7235 "DILG4; 220;220;220;",
7236 "UITX1; 31; 34; 35;",
7239 "UARTE; 64; 64; 64;",
7241 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7242 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7243 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7245 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7246 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7247 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7248 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7251 "DASHL; 20; 20; 20;",
7252 "DASHF; 64; 64; 64;",
7253 "DASHR; 70; 15; 15;",
7254 "DASHG; 15; 70; 15;",
7255 "DASHN; 17; 80; 56;",
7256 "DASH1; 48; 52; 72;",
7257 "DASH2; 36; 36; 53;",
7258 "COMP1; 24; 24; 24;",
7260 "GREY3; 10; 10; 10;",
7261 "BLUE4; 70; 70;140;",
7262 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7263 "LANDBACK; 201;185;122;",
7267int get_static_line(
char *d,
const char **p,
int index,
int n) {
7268 if (!strcmp(p[index],
"*****"))
return 0;
7270 strncpy(d, p[index], n);
7274void InitializeUserColors() {
7275 const char **p = usercolors;
7283 UserColorTableArray =
new wxArrayPtrVoid;
7284 UserColourHashTableArray =
new wxArrayPtrVoid;
7288 ct->tableName =
new wxString(
"DAY");
7289 ct->color =
new wxArrayPtrVoid;
7290 UserColorTableArray->Add((
void *)ct);
7293 ct->tableName =
new wxString(
"DUSK");
7294 ct->color =
new wxArrayPtrVoid;
7295 UserColorTableArray->Add((
void *)ct);
7298 ct->tableName =
new wxString(
"NIGHT");
7299 ct->color =
new wxArrayPtrVoid;
7300 UserColorTableArray->Add((
void *)ct);
7302 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7303 if (!strncmp(buf,
"Table", 5)) {
7304 sscanf(buf,
"Table:%s", TableName);
7306 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7307 ctp = (colTable *)(UserColorTableArray->Item(it));
7308 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7317 while (buf[j] !=
';' && j < 20) {
7323 S52color *c =
new S52color;
7324 strcpy(c->colName, name);
7326 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7339 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7340 wxColorHashMap *phash =
new wxColorHashMap;
7341 UserColourHashTableArray->Add((
void *)phash);
7343 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7345 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7346 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7348 wxColour c(c2->R, c2->G, c2->B);
7349 wxString key(c2->colName, wxConvUTF8);
7357 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7360void DeInitializeUserColors() {
7361 if (!UserColorTableArray)
return;
7362 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7363 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7365 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7366 S52color *c = (S52color *)ct->color->Item(j);
7370 delete ct->tableName;
7376 delete UserColorTableArray;
7378 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7379 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7383 delete UserColourHashTableArray;
7390typedef struct _MSW_COLOR_SPEC {
7392 wxString S52_RGB_COLOR;
7396MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7397 {COLOR_MENUTEXT,
"UITX1", 0},
7398 {COLOR_BTNSHADOW,
"UIBCK", 0},
7401void SaveSystemColors() {
7415 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7416 while (pcspec->COLOR_NAME != -1) {
7417 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7422void RestoreSystemColors() {
7423 int element[NCOLORS];
7424 int rgbcolor[NCOLORS];
7427 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7428 while (pcspec->COLOR_NAME != -1) {
7429 element[i] = pcspec->COLOR_NAME;
7430 rgbcolor[i] = pcspec->SysRGB_COLOR;
7436 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7441void SetSystemColors(ColorScheme cs) {
7443 int element[NCOLORS];
7444 int rgbcolor[NCOLORS];
7446 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7447 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7448 while (pcspec->COLOR_NAME != -1) {
7449 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7450 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7451 element[i] = pcspec->COLOR_NAME;
7457 pSetSysColors(i, (
unsigned long *)&element[0],
7458 (
unsigned long *)&rgbcolor[0]);
7462 RestoreSystemColors();
7467wxColor GetDimColor(wxColor c) {
7468 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7469 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7473 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7474 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7476 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7477 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7478 hsv.value = hsv.value * factor;
7479 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7481 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7487double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7488 double const AnchorPointMaxDist)
7491 if (d < AnchorPointMinDist)
7492 return AnchorPointMinDist;
7493 else if (d > AnchorPointMaxDist)
7494 return AnchorPointMaxDist;
7500 if (d > -AnchorPointMinDist)
7501 return -AnchorPointMinDist;
7502 else if (d < -AnchorPointMaxDist)
7503 return -AnchorPointMaxDist;
7510static const WORD MAX_CONSOLE_LINES =
7515void RedirectIOToConsole()
7520 wxIntPtr lStdHandle;
7522 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7532 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7533 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7534 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7538 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7539 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7540 fp = _fdopen(hConHandle,
"w");
7542 setvbuf(stdout, NULL, _IONBF, 0);
7546 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7547 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7548 fp = _fdopen(hConHandle,
"r");
7550 setvbuf(stdin, NULL, _IONBF, 0);
7554 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7555 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7556 fp = _fdopen(hConHandle,
"w");
7558 setvbuf(stderr, NULL, _IONBF, 0);
7570bool TestGLCanvas(wxString prog_dir) {
7572 wxString test_app = prog_dir;
7573 test_app +=
"ocpn_gltest1.exe";
7575 if (::wxFileExists(test_app)) {
7576 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7577 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7578 if (proc_return == 0)
7579 printf(
"GLCanvas OK\n");
7581 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7583 return (proc_return == 0);
7593bool ReloadLocale() {
7598 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7605 FontMgr::Get().SetLocale(g_locale);
7619 if (pRouteManagerDialog) {
7620 pRouteManagerDialog->Hide();
7621 pRouteManagerDialog->Destroy();
7622 pRouteManagerDialog = NULL;
7626 if (g_pais_query_dialog_active) {
7627 g_pais_query_dialog_active->Destroy();
7628 g_pais_query_dialog_active = NULL;
7631 auto alert_dlg_active =
7633 if (alert_dlg_active) {
7634 alert_dlg_active->Destroy();
7635 g_pais_alert_dialog_active =
nullptr;
7638 if (g_pAISTargetList) {
7640 g_pAISTargetList->Disconnect_decoder();
7641 g_pAISTargetList->Destroy();
7642 g_pAISTargetList = NULL;
7646 if (gFrame->m_pMenuBar) {
7647 gFrame->SetMenuBar(NULL);
7648 gFrame->m_pMenuBar->Destroy();
7649 gFrame->m_pMenuBar = NULL;
7651 gFrame->BuildMenuBar();
7654 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7656 if (cc) cc->CanvasApplyLocale();
7661 wxString perspective;
7662 pConfig->SetPath(
"/AUI");
7663 pConfig->Read(
"AUIPerspective", &perspective);
7677 bool bno_load =
false;
7678 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7680 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7681 wxAuiPaneInfo pane = pane_array_val[i];
7682 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7688 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7693 gFrame->RequestNewToolbars(
true);
7694 gFrame->RequestNewMasterToolbar(
true);
7711 g_csv_locn = g_Platform->GetSharedDataDir();
7712 g_csv_locn.Append(
"s57data");
7716 appendOSDirSlash(&g_csv_locn);
7717 g_csv_locn.Append(
"s57data");
7722 if (g_SENCPrefix.IsEmpty()) {
7724 appendOSDirSlash(&g_SENCPrefix);
7725 g_SENCPrefix.Append(
"SENC");
7729 wxFileName f(g_SENCPrefix);
7731 g_SENCPrefix = f.GetFullPath();
7733 g_SENCPrefix =
"SENC";
7739 bool b_force_legacy =
false;
7741 if (g_UserPresLibData.IsEmpty()) {
7742 plib_data = g_csv_locn;
7743 appendOSDirSlash(&plib_data);
7744 plib_data.Append(
"S52RAZDS.RLE");
7746 plib_data = g_UserPresLibData;
7747 b_force_legacy =
true;
7750 ps52plib =
new s52plib(plib_data, b_force_legacy);
7765 if (!ps52plib->m_bOK) {
7768 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7770 wxString look_data_dir;
7771 look_data_dir.Append(std_path.GetUserDataDir());
7772 appendOSDirSlash(&look_data_dir);
7773 wxString tentative_SData_Locn = look_data_dir;
7774 look_data_dir.Append(
"s57data");
7776 plib_data = look_data_dir;
7777 appendOSDirSlash(&plib_data);
7778 plib_data.Append(
"S52RAZDS.RLE");
7780 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7781 ps52plib =
new s52plib(plib_data);
7783 if (ps52plib->m_bOK) {
7784 g_csv_locn = look_data_dir;
7793 if (!ps52plib->m_bOK) {
7796 wxString look_data_dir;
7797 look_data_dir = g_Platform->GetSharedDataDir();
7798 look_data_dir.Append(
"s57data");
7800 plib_data = look_data_dir;
7801 appendOSDirSlash(&plib_data);
7802 plib_data.Append(
"S52RAZDS.RLE");
7804 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7805 ps52plib =
new s52plib(plib_data);
7807 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7810 if (ps52plib->m_bOK) {
7811 wxLogMessage(
"Using s57data in " + g_csv_locn);
7813 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7818 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7820 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7821 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7822 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7823 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7826 pConfig->LoadS57Config();
7827 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7833 ps52plib->SetDIPFactor(dip_factor);
7838 ps52plib->SetScaleFactorExp(
7839 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7840 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7847 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7848 ps52plib->SetGLRendererString(renderer);
7851 ps52plib->SetGLOptions(
7852 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7853 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7854 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7859 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7868 : wxThread(wxTHREAD_JOINABLE) {
7869 m_filename = filename;
7880 newChart->SetNativeScale(m_scale);
7881 newChart->SetFullExtent(m_ext);
7883 newChart->FindOrCreateSenc(m_filename);
7888 wxString m_filename;
7894static double chart_dist(
int index) {
7900 if (cte.GetBBox().Contains(
gLat,
gLon))
7905 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7906 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7907 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7910 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7911 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7913 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7919WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7920static int CompareInts(
int n1,
int n2) {
7921 double d1 = chart_dist(n1);
7922 double d2 = chart_dist(n2);
7923 return (
int)(d1 - d2);
7928 wxString chart_path;
7933WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7935#include <wx/arrimpl.cpp>
7938void ParseAllENC(wxWindow *parent) {
7939 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7947 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7950 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7952 idx_sorted_by_distance.Add(i);
7956 if (count == 0)
return;
7958 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7964 ArrayOfCompressTargets ct_array;
7965 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7966 int i = idx_sorted_by_distance[j];
7969 double distance = chart_dist(i);
7971 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7974 pct->distance = distance;
7975 pct->chart_path = filename;
7977 ct_array.push_back(pct);
7980 int thread_count = 0;
7983 if (g_nCPUCount > 0)
7984 thread_count = g_nCPUCount;
7986 thread_count = wxThread::GetCPUCount();
7988 if (thread_count < 1) {
7997 for(
int t = 0; t < thread_count; t++)
8001 wxGenericProgressDialog *prog =
nullptr;
8005 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8006 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8008 prog =
new wxGenericProgressDialog();
8010 prog->SetFont(*qFont);
8012 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8013 count + 1, parent, style);
8022 prog->ShowWindowModal();
8031 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8032 wxString filename = ct_array[j].chart_path;
8033 double distance = ct_array[j].distance;
8034 int index =
ChartData->FinddbIndex(filename);
8035 if (index < 0)
continue;
8038 ext.NLAT = cte.GetLatMax();
8039 ext.SLAT = cte.GetLatMin();
8040 ext.WLON = cte.GetLonMin();
8041 ext.ELON = cte.GetLonMax();
8043 int scale = cte.GetScale();
8046 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8049 if (wxThread::IsMain()) {
8051 wxSize sz = prog->GetSize();
8056 prog->Update(count, msg, &skip);
8068 newChart->SetNativeScale(
scale);
8069 newChart->SetFullExtent(ext);
8070 newChart->DisableBackgroundSENC();
8072 newChart->FindOrCreateSenc(filename,
8076 if (wxThread::IsMain()) {
8077 msg.Printf(_(
"ENC Completed."));
8079 prog->Update(count, msg, &skip);
8089 for (
int t = 0;; t = (t + 1) % thread_count) {
8096 if (!workers[t]->IsAlive()) {
8109#if defined(__WXMSW__) || defined(__WXOSX__)
8116 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.
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.
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,...
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.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
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.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
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.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
s57RegistrarMgr * m_pRegistrarMan
Global instance.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
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.
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.
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.
WaypointMan drawing stuff.