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,
710 EnableFullScreenView();
712 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
718 FrameTenHzTimer.Stop();
733 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
739void MyFrame::FreezeCharts() {
742 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
744 if (cc && !cc->IsFrozen()) cc->Freeze();
749void MyFrame::ThawCharts() {
752 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
754 if (cc && cc->IsFrozen()) cc->Thaw();
761 switch (event.type) {
762 case SENC_BUILD_STARTED:
765 case SENC_BUILD_DONE_NOERROR:
767 chart =
event.m_ticket->m_chart;
769 chart->PostInit(FULL_INIT, global_color_scheme);
771 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
773 if (cc) cc->ClearS52PLIBStateHash();
778 delete event.m_ticket;
780 case SENC_BUILD_DONE_ERROR:
788void MyFrame::RebuildChartDatabase() {
789 bool b_SetInitialPoint =
false;
792 ArrayOfCDI ChartDirArray;
793 pConfig->LoadChartDirArray(ChartDirArray);
795 if (ChartDirArray.GetCount()) {
800 _(
"OpenCPN needs to update the chart database from config file "
804 wxICON_INFORMATION | wxOK);
812 _(
"Rebuilding chart database from configuration file entries..."));
816 wxString dummy1 = _(
"Elapsed time : ");
817 wxString dummy2 = _(
"Estimated time : ");
818 wxString dummy3 = _(
"Remaining time : ");
819 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
820 _(
"OpenCPN Chart Update"), line, 100, NULL,
821 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
822 wxPD_REMAINING_TIME);
825 ChartData->SaveBinary(ChartListFileName);
835void MyFrame::OnBellsFinished(wxCommandEvent &event) {
836 int bells = wxMin(m_BellsToPlay, 2);
837 if (bells <= 0)
return;
839 wxString soundfile =
"sounds";
840 appendOSDirSlash(&soundfile);
841 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
842 soundfile.Prepend(g_Platform->GetSharedDataDir());
843 wxLogMessage(
"Using bells sound file: " + soundfile);
845 o_sound::Sound *sound = bells_sound[bells - 1];
846 sound->SetFinishedCallback(onBellsFinishedCB,
this);
847 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
848 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
849 sound->Load(soundfile);
850 if (!sound->IsOk()) {
851 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
855 m_BellsToPlay -= bells;
858void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
860void MyFrame::OnMaximize(wxMaximizeEvent &event) {
867ColorScheme GetColorScheme() {
return global_color_scheme; }
869ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
871void MyFrame::ReloadAllVP() {
872 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
874 if (cc) cc->ReloadVP();
878void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
879 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
882 global_color_scheme = cs;
885 case GLOBAL_COLOR_SCHEME_DAY:
888 case GLOBAL_COLOR_SCHEME_DUSK:
891 case GLOBAL_COLOR_SCHEME_NIGHT:
892 SchemeName =
"NIGHT";
899 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
901 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
902 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
903 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
904 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
905 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
907 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
936 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
937 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
941 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
944 unsigned Usercolortable_index = 0;
945 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
946 colTable *ct = (colTable *)UserColorTableArray->Item(i);
947 if (SchemeName.IsSameAs(*ct->tableName)) {
948 Usercolortable_index = i;
953 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
957 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
962 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
965 cc->SetColorScheme(cs);
966 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
967 cc->HideChartInfoWindow();
968 cc->SetQuiltChartHiLiteIndex(-1);
974 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
986 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
999 if (g_pais_query_dialog_active) {
1000 bool b_isshown = g_pais_query_dialog_active->IsShown();
1001 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1002 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1004 g_pais_query_dialog_active->Close();
1007 g_pais_query_dialog_active->
Create(
1008 this, -1, _(
"AIS Target Query"),
1009 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1010 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1011 g_pais_query_dialog_active->UpdateText();
1012 if (b_isshown) g_pais_query_dialog_active->Show();
1015 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1017 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1021 ApplyGlobalColorSchemetoStatusBar();
1023 UpdateAllToolbars(cs);
1028 bool btoolbarFull = g_bmasterToolbarFull;
1034 if (!btoolbarFull) {
1036 RequestNewMasterToolbar();
1038 CollapseGlobalToolbar();
1041 RequestNewMasterToolbar();
1050void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1051 if (m_pStatusBar != NULL) {
1052 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1053 m_pStatusBar->ClearBackground();
1058 if (g_canvasArray.GetCount() > 0)
1059 return g_canvasArray.Item(0);
1063void MyFrame::CancelAllMouseRoute() {
1065 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1067 if (cc) cc->CancelMouseRoute();
1071void MyFrame::NotifyChildrenResize() {}
1073void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1081 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1089 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1098 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1101 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1102 config_array.Item(i)->canvas = NULL;
1108 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1109 g_canvasArray.RemoveAt(i);
1113 switch (g_canvasConfig) {
1116 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1119 g_canvasArray.Add(cc);
1121 cc = g_canvasArray[0];
1127 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1128 cc->GetglCanvas()->Show();
1131 config_array.Item(0)->canvas = cc;
1135 cc->ApplyCanvasConfig(config_array.Item(0));
1139 cc->ConfigureChartBar();
1140 cc->SetColorScheme(global_color_scheme);
1141 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1142 cc->SetShowGPS(
true);
1145 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1147 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1153 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1155 g_canvasArray.Add(cc);
1157 cc = g_canvasArray[0];
1163 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1166 config_array.Item(0)->canvas = cc;
1168 cc->ApplyCanvasConfig(config_array.Item(0));
1171 cc->ConfigureChartBar();
1172 cc->SetColorScheme(global_color_scheme);
1173 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1174 cc->SetShowGPS(
false);
1177 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1179 .CaptionVisible(
false)
1181 .CloseButton(
false);
1186 g_canvasArray.Add(cc);
1190 if (config_array.GetCount() < 2) {
1192 pcc->configIndex = 1;
1196 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1197 config_array.Add(pcc);
1200 config_array.Item(1)->canvas = cc;
1202 cc->ApplyCanvasConfig(config_array.Item(1));
1205 cc->ConfigureChartBar();
1206 cc->SetColorScheme(global_color_scheme);
1207 cc->SetShowGPS(
true);
1211 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1213 .CaptionVisible(
false)
1215 .CloseButton(
false);
1216 g_pauimgr->GetPane(cc).RightDockable(
true);
1220 config_array.Item(1)->canvasSize =
1221 wxSize(GetClientSize().x / 2, GetClientSize().y);
1222 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1227 if (b_useStoredSize) {
1228 int ccw = config_array.Item(1)->canvasSize.x;
1229 int cch = config_array.Item(1)->canvasSize.y;
1232 if (ccw < GetClientSize().x / 10) {
1233 ccw = GetClientSize().x / 2;
1234 cch = GetClientSize().y;
1237 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1238 cc->SetSize(ccw, cch);
1252 if (g_canvasArray.size() > 1)
1256 console->SetColorScheme(global_color_scheme);
1261 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1267void MyFrame::RequestNewToolbars(
bool bforcenew) {
1268 if (b_inCloseWindow) {
1272 BuildiENCToolbar(bforcenew);
1273 PositionIENCToolbar();
1282void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1288void MyFrame::SetAllToolbarScale() {
1289 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1292void MyFrame::SetGPSCompassScale() {
1293 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1297 wxPoint screenPoint = ::wxGetMousePosition();
1300 switch (g_canvasConfig) {
1302 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1305 if (canvas->GetScreenRect().Contains(
1309 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1312 if (canvas->GetScreenRect().Contains(
1319 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1322 if (canvas->GetScreenRect().Contains(
1323 canvas->ScreenToClient(screenPoint)))
1331int MyFrame::GetCanvasIndexUnderMouse() {
1332 wxPoint screenPoint = ::wxGetMousePosition();
1335 switch (g_canvasConfig) {
1337 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1340 if (canvas->GetScreenRect().Contains(
1344 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1347 if (canvas->GetScreenRect().Contains(
1354 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1357 if (canvas->GetScreenRect().Contains(
1358 canvas->ScreenToClient(screenPoint)))
1366bool MyFrame::DropMarker(
bool atOwnShip) {
1373 if (!canvas)
return false;
1380 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1382 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1384 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1389 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1390 pRouteManagerDialog->UpdateWptListCtrl();
1395 RefreshAllCanvas(
false);
1400void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1401 if (g_canvasConfig != 0) {
1404 int nTargetGTK = -1;
1406 wxWindow *source = FindFocus();
1412 switch (g_canvasConfig) {
1414 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1417 if (canvas && (canvas == test)) {
1422 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1425 if (canvas && (canvas == test)) {
1433 int nfinalTarget = nTarget;
1435 nfinalTarget = nTargetGTK;
1437 target = ConfigMgr::Get()
1438 .GetCanvasConfigArray()
1443 target->Refresh(
true);
1454void MyFrame::FastClose() {
1456 FrameTenHzTimer.Stop();
1458 FrameTimer1.Start(1);
1462void MyFrame::OnExit(wxCommandEvent &event) {
1466void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1469 if (b_inCloseWindow) {
1479 if (!g_bDeferredInitDone)
return;
1496 if (bDBUpdateInProgress)
return;
1498 b_inCloseWindow =
true;
1500 ::wxSetCursor(wxCURSOR_WAIT);
1504 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1506 if (cc && cc->IsMeasureActive()) {
1507 cc->CancelMeasureRoute();
1512 SendPreShutdownHookToPlugins();
1516 if (g_pAISTargetList) {
1517 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1518 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1519 g_pauimgr->DetachPane(g_pAISTargetList);
1530 pConfig->SetPath(
"/AUI");
1531 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1546 SetCursor(wxCURSOR_WAIT);
1548 RefreshAllCanvas(
true);
1554 RestoreScreenBrightness();
1565 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1566 g_iENCToolbarPosY = tbp_incanvas.y;
1567 g_iENCToolbarPosX = tbp_incanvas.x;
1571 g_bframemax = IsMaximized();
1574 FrameTenHzTimer.Stop();
1576 FrameCOGTimer.Stop();
1590 if (g_bAutoAnchorMark) {
1591 bool watching_anchor =
false;
1599 wxDateTime now = wxDateTime::Now();
1600 wxTimeSpan uptime = now.Subtract(g_start_time);
1602 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1603 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1608 if (g_declutter_anchorage) {
1609 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1610 if (pr->GetName().StartsWith(
"Anchorage")) {
1611 double a =
gLat - pr->m_lat;
1612 double b =
gLon - pr->m_lon;
1613 double l = sqrt((a * a) + (b * b));
1616 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1618 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1619 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1627 wxString name = now.Format();
1628 name.Prepend(_(
"Anchorage created "));
1634 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1639 pConfig->UpdateSettings();
1643 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1647 NavObj_dB::GetInstance().Close();
1651 pConfig->DeleteGroup(
"/Routes");
1652 pConfig->DeleteGroup(
"/Marks");
1678 if (g_pAISTargetList) {
1679 g_pAISTargetList->Disconnect_decoder();
1680 g_pAISTargetList->Destroy();
1687 if (RouteManagerDialog::getInstanceFlag()) {
1688 if (pRouteManagerDialog) {
1689 pRouteManagerDialog->Destroy();
1690 pRouteManagerDialog = NULL;
1704 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1706 if (cc) cc->Destroy();
1709 g_canvasArray.Clear();
1730 MyApp &app = wxGetApp();
1731 app.m_comm_bridge.SaveConfig();
1751 auto ®istry = CommDriverRegistry::GetInstance();
1752 registry.CloseAllDrivers();
1755 for (
auto *cp : TheConnectionParams()) {
1760 while (pLayerList->size())
delete *pLayerList->begin();
1764 ReleaseApiListeners();
1767 g_bTempShowMenuBar =
false;
1769#define THREAD_WAIT_SECONDS 5
1779 wxLogMessage(
"Starting compressor pool drain");
1780 wxDateTime now = wxDateTime::Now();
1781 time_t stall = now.GetTicks();
1782 time_t end = stall + THREAD_WAIT_SECONDS;
1785 while (stall < end) {
1786 wxDateTime later = wxDateTime::Now();
1787 stall = later.GetTicks();
1790 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1799 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1805 uninitIXNetSystem();
1809 wxLogMessage(
"gFrame destroyed.");
1812#ifndef USE_ANDROID_GLES2
1813 qDebug() <<
"Calling OnExit()";
1817 wxTheApp->ExitMainLoop();
1820void MyFrame::OnMove(wxMoveEvent &event) {
1821 auto idx = wxDisplay::GetFromWindow(
this);
1834 DEBUG_LOG <<
"Moved to " << idx
1835#if wxCHECK_VERSION(3, 1, 6)
1836 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1837 << wxDisplay(idx).GetPPI().GetY()
1838 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1840 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1841 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1842 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1843 << wxGetDisplaySizeMM().GetY()
1844 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1853 if (g_config_display_size_manual) {
1862 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1865 cc->SetMUIBarPosition();
1874 UpdateGPSCompassStatusBoxes();
1884 PositionIENCToolbar();
1890 g_nframewin_posx = GetPosition().x;
1891 g_nframewin_posy = GetPosition().y;
1894void MyFrame::ProcessCanvasResize() {
1895 UpdateGPSCompassStatusBoxes(
true);
1899 PositionIENCToolbar();
1902 TriggerRecaptureTimer();
1906void MyFrame::TriggerRecaptureTimer() {
1907 m_recaptureTimer.Start(
1908 1000, wxTIMER_ONE_SHOT);
1911void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1913void MyFrame::SetCanvasSizes(wxSize frameSize) {
1914 if (!g_canvasArray.GetCount())
return;
1917 int cccw = frameSize.x;
1918 int ccch = frameSize.y;
1922 switch (g_canvasConfig) {
1926 cc = g_canvasArray.Item(0);
1928 cc->GetSize( &cur_width, &cur_height );
1929 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1931 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1933 cc->SetSize( 0, 0, cccw, ccch );
1941 cc = g_canvasArray.Item(1);
1943 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1944 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1946 ccw = wxMin(ccw, cccw * 8 / 10);
1947 ccw = wxMax(ccw, cccw * 2 / 10);
1951 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1958 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1975void MyFrame::OnIconize(wxIconizeEvent &event) {
1985 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1987 if (cc && cc->GetMUIBar()) {
1988 if (cc->GetMUIBar()->GetCanvasOptions()) {
1989 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
1990 cc->GetMUIBar()->PushCanvasOptions();
1999void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2001void MyFrame::ODoSetSize() {
2003 GetClientSize(&x, &y);
2006 if (m_pStatusBar != NULL) {
2007 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2008 int currentCount = m_pStatusBar->GetFieldsCount();
2009 if (currentCount != m_StatusBarFieldCount) {
2010 if ((currentCount > 0) && (currentCount < 7)) {
2013 int widths[] = {2, 2, 2, 2, 2, 2};
2014 m_pStatusBar->SetStatusWidths(currentCount, widths);
2017 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2020 if (m_StatusBarFieldCount) {
2025 if (m_StatusBarFieldCount > 2) {
2026 int widths[] = {-6, -5, -5, -6, -4};
2027 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2028 }
else if (m_StatusBarFieldCount == 2) {
2029 int cwidth = x * 90 / 100;
2030 int widths[] = {100, 100};
2031 widths[0] = cwidth * 6.4 / 10.0;
2032 widths[1] = cwidth * 3.6 / 10.0;
2033 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2035 int widths[] = {100, 100};
2036 widths[0] = x * 90 / 100;
2037 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2040 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2041 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2042 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2044 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2046 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2054 m_pStatusBar->GetFieldRect(0, stat_box);
2057 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2059 wxFont sys_font = *wxNORMAL_FONT;
2060 int try_font_size = sys_font.GetPointSize();
2063 int min_font_size = 10;
2073 wxFont *statusBarFont =
2074 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2075 int font_size = statusBarFont->GetPointSize();
2077 font_size = wxMin(font_size,
2080 wxMax(font_size, min_font_size);
2083 font_size = statusBarFont->GetPointSize();
2090 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2091 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2093 int min_height = stat_box.height;
2095 m_pStatusBar->SetFont(*pstat_font);
2096 m_pStatusBar->SetForegroundColour(
2097 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2099 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2101 (min_height >> 1) * 2;
2102 m_pStatusBar->SetMinHeight(min_height);
2111 SetCanvasSizes(GetClientSize());
2113 UpdateGPSCompassStatusBoxes(
true);
2115 if (
console) PositionConsole();
2118 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2120 if (cc) cc->FormatPianoKeys();
2126 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2127 GetPrimaryCanvas()->GetCompass()->GetRect());
2153 options_lastWindowSize = wxSize(0, 0);
2154 options_lastWindowPos = wxPoint(0, 0);
2161 if (!b_inCloseWindow) {
2164 resizeAndroidPersistents();
2168 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2169 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2175void MyFrame::PositionConsole() {
2176#if defined(__WXMSW__) || defined(__WXMAC__)
2177 if (NULL == GetPrimaryCanvas())
return;
2179 int ccx, ccy, ccsx, ccsy, consx, consy;
2181 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2184 consoleHost->GetSize(&ccsx, &ccsy);
2185 consoleHost->GetPosition(&ccx, &ccy);
2187 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2188 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2189 consoleHost = GetPrimaryCanvas();
2194 if (consoleHost->GetCompass()) {
2195 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2197 if (compass_rect.y < 100)
2198 yOffset = compass_rect.y + compass_rect.height + 45;
2202 wxSize csz =
console->GetSize();
2206 wxPoint screen_pos =
2207 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2210 if (NULL == GetPrimaryCanvas())
return;
2212 int ccx, ccy, ccsx, ccsy, consx, consy;
2214 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2217 consoleHost->GetSize(&ccsx, &ccsy);
2218 consoleHost->GetPosition(&ccx, &ccy);
2220 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2221 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2222 consoleHost = GetPrimaryCanvas();
2225 int yTopOffset = 60;
2226 int yBottomOffset = 0;
2228 if (consoleHost->GetCompass()) {
2229 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2231 if (compass_rect.y < 100)
2232 yTopOffset = compass_rect.y + compass_rect.height;
2234 if (consoleHost->GetMUIBar()) {
2235 wxRect mui_rect = consoleHost->GetMUIBarRect();
2236 yBottomOffset = ccsy - mui_rect.y;
2240 wxSize csz =
console->GetSize();
2243 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2245 if (consy < yAvail) {
2246 yFinal = (yAvail - consy) / 2;
2247 yFinal += yTopOffset;
2248 }
else if (
console->GetCDI()->IsShown()) {
2249 int cdi_height =
console->GetCDI()->GetSize().y;
2250 int consy_no_cdi = consy - cdi_height;
2251 yFinal = (yAvail - consy_no_cdi) / 2;
2252 yFinal += yTopOffset;
2256 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2261void MyFrame::UpdateAllFonts() {
2270 DestroyPersistentDialogs();
2272 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2277void MyFrame::DestroyPersistentDialogs() {
2278 if (g_pais_query_dialog_active) {
2279 g_pais_query_dialog_active->Hide();
2280 g_pais_query_dialog_active->Destroy();
2281 g_pais_query_dialog_active = NULL;
2309void MyFrame::RefreshGroupIndices() {
2311 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2313 if (cc) cc->canvasRefreshGroupIndex();
2317void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2320 switch (event.GetId()) {
2321 case ID_MENU_SCALE_OUT:
2322 DoStackDelta(GetPrimaryCanvas(), 1);
2326 case ID_MENU_SCALE_IN:
2327 DoStackDelta(GetPrimaryCanvas(), -1);
2331 case ID_MENU_ZOOM_IN: {
2332 if (GetFocusCanvas()) {
2333 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2338 case ID_MENU_ZOOM_OUT: {
2339 if (GetFocusCanvas()) {
2340 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2345 case ID_MENU_ROUTE_NEW: {
2346 if (GetFocusCanvas()) {
2347 if (0 == GetFocusCanvas()->m_routeState) {
2348 GetFocusCanvas()->StartRoute();
2350 GetFocusCanvas()->FinishRoute();
2356 case ID_MENU_TOOL_MEASURE: {
2357 GetPrimaryCanvas()->StartMeasureRoute();
2361 case ID_MENU_TOOL_NMEA_DBG_LOG:
2362 m_data_monitor->Show();
2363 m_data_monitor->Raise();
2366 case ID_MENU_TOOL_IO_MONITOR:
2367 m_data_monitor->Show();
2370 case ID_MENU_MARK_BOAT: {
2375 case ID_MENU_MARK_CURSOR: {
2380 case ID_MENU_NAV_FOLLOW: {
2381 if (
gFrame->GetPrimaryCanvas())
2382 gFrame->GetPrimaryCanvas()->TogglebFollow();
2386 case ID_MENU_CHART_OUTLINES: {
2387 ToggleChartOutlines(GetFocusCanvas());
2391 case ID_MENU_CHART_QUILTING: {
2392 ToggleQuiltMode(GetFocusCanvas());
2396 case ID_MENU_UI_CHARTBAR: {
2397 ToggleChartBar(GetFocusCanvas());
2401 case ID_MENU_ENC_TEXT:
2403 ToggleENCText(GetFocusCanvas());
2406 case ID_MENU_ENC_LIGHTS: {
2407 ToggleLights(GetFocusCanvas());
2410 case ID_MENU_ENC_SOUNDINGS: {
2411 ToggleSoundings(GetFocusCanvas());
2414 case ID_MENU_ENC_ANCHOR: {
2415 ToggleAnchor(GetFocusCanvas());
2418 case ID_MENU_ENC_DATA_QUALITY: {
2419 ToggleDataQuality(GetFocusCanvas());
2422 case ID_MENU_SHOW_NAVOBJECTS: {
2423 ToggleNavobjects(GetFocusCanvas());
2427 case ID_MENU_AIS_TARGETS: {
2428 ToggleAISDisplay(GetFocusCanvas());
2431 case ID_MENU_AIS_MOORED_TARGETS: {
2432 g_bHideMoored = !g_bHideMoored;
2435 case ID_MENU_AIS_SCALED_TARGETS: {
2436 ToggleAISMinimizeTargets(GetFocusCanvas());
2440 case ID_MENU_AIS_TARGETLIST: {
2441 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2445 case ID_MENU_AIS_TRACKS: {
2446 g_bAISShowTracks = !g_bAISShowTracks;
2447 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2451 case ID_MENU_AIS_CPADIALOG: {
2452 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2453 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2454 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2455 if (g_bAIS_CPA_Alert) {
2456 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2461 case ID_MENU_AIS_CPASOUND: {
2462 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2463 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2467 case ID_MENU_AIS_CPAWARNING: {
2468 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2469 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2473 case wxID_PREFERENCES:
2480 case ID_SETTINGS_NEW: {
2485 case ID_SETTINGS_DELETE: {
2488 g_pOptions =
nullptr;
2492 case ID_RELOAD_CHARTS: {
2497 case ID_MENU_SETTINGS_BASIC: {
2500 androidDisableFullScreen();
2502 DoAndroidPreferences();
2509 case ID_MENU_UI_FULLSCREEN: {
2514 case ID_MENU_SHOW_CURRENTS: {
2515 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2516 GetFocusCanvas()->ReloadVP();
2517 GetFocusCanvas()->Refresh(
false);
2521 case ID_MENU_SHOW_TIDES: {
2522 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2523 GetFocusCanvas()->ReloadVP();
2524 GetFocusCanvas()->Refresh(
false);
2544 case ID_MENU_UI_COLSCHEME:
2545 case ID_COLSCHEME: {
2546 ToggleColorScheme();
2555 case ID_MENU_OQUIT: {
2560 case ID_MENU_ROUTE_MANAGER:
2561 case ID_ROUTEMANAGER: {
2562 pRouteManagerDialog = RouteManagerDialog::getInstance(
2565 if (pRouteManagerDialog->IsShown())
2566 pRouteManagerDialog->Hide();
2568 pRouteManagerDialog->UpdateRouteListCtrl();
2569 pRouteManagerDialog->UpdateTrkListCtrl();
2570 pRouteManagerDialog->UpdateWptListCtrl();
2571 pRouteManagerDialog->UpdateLayListCtrl();
2573 pRouteManagerDialog->Show();
2577 pRouteManagerDialog->Centre();
2578 pRouteManagerDialog->Raise();
2584 case ID_MENU_NAV_TRACK:
2586 if (!g_bTrackActive) {
2588 g_bTrackCarryOver =
true;
2591 g_bTrackCarryOver =
false;
2592 RefreshAllCanvas(
true);
2597 case ID_MENU_CHART_NORTHUP: {
2598 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2601 case ID_MENU_CHART_COGUP: {
2602 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2605 case ID_MENU_CHART_HEADUP: {
2606 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2610 case ID_MENU_MARK_MOB:
2616 case ID_MASTERTOGGLE: {
2618 wxString tip = _(
"Show Toolbar");
2619 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2621 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2623 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2626 if (g_bmasterToolbarFull)
2627 m_nMasterToolCountShown =
2631 m_nMasterToolCountShown = 2;
2633 m_nMasterToolCountShown =
2636 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2644 case ID_CMD_SELECT_CHART_TYPE: {
2645 selectChartDisplay(event.GetExtraLong(), -1);
2649 case ID_CMD_SELECT_CHART_FAMILY: {
2650 selectChartDisplay(-1, event.GetExtraLong());
2654 case ID_CMD_APPLY_SETTINGS: {
2655 applySettingsString(event.GetString());
2657 androidRestoreFullScreen();
2663 case ID_CMD_NULL_REFRESH: {
2668 case ID_CMD_SETVP: {
2669 setStringVP(event.GetString());
2673 case ID_CMD_INVALIDATE: {
2679 case ID_CMD_POST_JSON_TO_PLUGINS: {
2685 int numErrors = reader.
Parse(event.GetString(), &root);
2686 if (numErrors == 0) {
2687 if (root[
"MessageID"].IsString()) {
2688 wxString MsgID = root[
"MessageID"].
AsString();
2712 ArrayOfPlugInToolbarTools tool_array =
2714 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2716 if (event.GetId() == pttc->id) {
2717 if (pttc->m_pplugin)
2739bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2740 bool viz_now = g_bmasterToolbarFull;
2743 wxString tip = _(
"Show Toolbar");
2745 tip = _(
"Hide Toolbar");
2747 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2750 bool toggle =
false;
2751 if (viz && !g_bmasterToolbarFull)
2754 else if (!viz && g_bmasterToolbarFull)
2758 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2761 if (g_bmasterToolbarFull)
2762 m_nMasterToolCountShown =
2766 m_nMasterToolCountShown = 2;
2768 m_nMasterToolCountShown =
2771 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2777void MyFrame::ScheduleReloadCharts() {
2778 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2779 evt.SetId(ID_RELOAD_CHARTS);
2780 GetEventHandler()->AddPendingEvent(evt);
2783void MyFrame::ScheduleDeleteSettingsDialog() {
2784 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2785 evt.SetId(ID_SETTINGS_DELETE);
2786 GetEventHandler()->AddPendingEvent(evt);
2789void MyFrame::ScheduleSettingsDialog() {
2790 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2791 evt.SetId(ID_SETTINGS);
2792 GetEventHandler()->AddPendingEvent(evt);
2795void MyFrame::ScheduleSettingsDialogNew() {
2796 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2797 evt.SetId(ID_SETTINGS_NEW);
2798 GetEventHandler()->AddPendingEvent(evt);
2801void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2802 UpdateCanvasConfigDescriptors();
2804 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2805 CreateCanvasLayout(
true);
2807 CreateCanvasLayout();
2811 ConfigureStatusBar();
2812 wxSize lastOptSize = options_lastWindowSize;
2817 options_lastWindowSize = lastOptSize;
2821 ScheduleSettingsDialogNew();
2823 ScheduleSettingsDialog();
2828 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2831 int index_hint = -1;
2832 if (i < pathArray.GetCount())
2833 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2834 cc->canvasChartsRefresh(index_hint);
2835 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2844 return GetPrimaryCanvas();
2847void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2848 if (g_bmasterToolbarFull) {
2849#ifndef OCPN_TOOLBAR_ANIMATE
2850 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2853 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2854 m_nMasterToolCountShown++;
2859 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2867#ifndef OCPN_TOOLBAR_ANIMATE
2868 m_nMasterToolCountShown = 1;
2870 if (m_nMasterToolCountShown > 1) {
2871 m_nMasterToolCountShown--;
2875 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2885void MyFrame::InvalidateAllGL() {
2888 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2898void MyFrame::RefreshAllCanvas(
bool bErase) {
2900 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2903 cc->Refresh(bErase);
2908void MyFrame::setStringVP(wxString VPS) {
2913 wxStringTokenizer tkz(VPS,
";");
2915 wxString token = tkz.GetNextToken();
2917 token.ToDouble(&lat);
2919 token = tkz.GetNextToken();
2921 token.ToDouble(&lon);
2923 token = tkz.GetNextToken();
2925 token.ToDouble(&scale_ppm);
2927 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2930void MyFrame::DoSettingsNew() {
2937void MyFrame::DoSettings() {
2941 ApplyGlobalSettings(
true);
2944 bool b_loadHarmonics =
false;
2945 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2948 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2951 if (b_loadHarmonics) LoadHarmonics();
2959 g_bShowChartBar = !g_bShowChartBar;
2961 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2966 if (g_bShowChartBar) {
2968 UpdateControlBar(cc);
2971 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2974void MyFrame::ToggleColorScheme() {
2975 static bool lastIsNight;
2976 ColorScheme s = GetColorScheme();
2979 if (lastIsNight && is == 3)
2982 lastIsNight =
false;
2984 if (lastIsNight) is = 2;
2985 if (is == 3) lastIsNight =
true;
2986 s = (ColorScheme)is;
2987 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
2989 SetAndApplyColorScheme(s);
2992void MyFrame::ToggleFullScreen() {
2993 bool to = !IsFullScreen();
2998 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3000 ShowFullScreen(to, style);
3003 UpdateAllToolbars(global_color_scheme);
3005 UpdateControlBar(GetPrimaryCanvas());
3007 TriggerRecaptureTimer();
3010void MyFrame::ActivateMOB() {
3012 wxDateTime mob_time = wxDateTime::Now();
3013 wxString mob_label(_(
"MAN OVERBOARD"));
3014 mob_label += _(
" on ");
3015 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3019 pWP_MOB->SetShared(
true);
3021 pWP_MOB->SetWaypointArrivalRadius(
3023 pWP_MOB->SetUseSca(
false);
3025 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3033 new RoutePoint(zlat, zlon, g_default_wp_icon,
3034 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3035 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3040 temp_route->AddPoint(pWP_src);
3041 temp_route->AddPoint(pWP_MOB);
3043 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3053 temp_route->SetRouteArrivalRadius(-1.0);
3059 v[
"GUID"] = temp_route->
m_GUID;
3060 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3061 SendJSONMessageToAllPlugins(msg_id, v);
3064 if (RouteManagerDialog::getInstanceFlag()) {
3065 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3066 pRouteManagerDialog->UpdateRouteListCtrl();
3067 pRouteManagerDialog->UpdateWptListCtrl();
3072 RefreshAllCanvas(
false);
3074 wxString mob_message(_(
"MAN OVERBOARD"));
3075 mob_message += _(
" Time: ");
3076 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3077 mob_message += _(
" Position: ");
3078 mob_message += toSDMM(1,
gLat);
3080 mob_message += toSDMM(2,
gLon);
3081 wxLogMessage(mob_message);
3083void MyFrame::TrackOn() {
3084 g_bTrackActive =
true;
3092 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3094 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3096 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3099 androidSetTrackTool(
true);
3102 if (RouteManagerDialog::getInstanceFlag()) {
3103 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3104 pRouteManagerDialog->UpdateTrkListCtrl();
3105 pRouteManagerDialog->UpdateRouteListCtrl();
3111 if (name.IsEmpty()) {
3117 name = _(
"(Unnamed Track)");
3121 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3122 SendJSONMessageToAllPlugins(msg_id, v);
3123 g_FlushNavobjChangesTimeout =
3127Track *MyFrame::TrackOff(
bool do_add_point) {
3132 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3134 SendJSONMessageToAllPlugins(msg_id, v);
3143 if (g_bTrackDaily) {
3148 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3149 return_val = pExtendTrack;
3156 g_bTrackActive =
false;
3158 if (RouteManagerDialog::getInstanceFlag()) {
3159 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3160 pRouteManagerDialog->UpdateTrkListCtrl();
3161 pRouteManagerDialog->UpdateRouteListCtrl();
3165 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3167 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3168 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3171 androidSetTrackTool(
false);
3174 g_FlushNavobjChangesTimeout =
3180bool MyFrame::ShouldRestartTrack() {
3182 time_t now = wxDateTime::Now().GetTicks();
3183 time_t today = wxDateTime::Today().GetTicks();
3185 switch (g_track_rotate_time_type) {
3187 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3189 case TIME_TYPE_COMPUTER:
3190 rotate_at = g_track_rotate_time;
3194 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3195 rotate_at = g_track_rotate_time + utc_offset;
3198 if (rotate_at > 86400)
3200 else if (rotate_at < 0)
3202 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3203 now - today >= rotate_at) {
3204 if (m_last_track_rotation_ts == 0) {
3205 if (now - today > rotate_at)
3206 m_last_track_rotation_ts = today + rotate_at;
3208 m_last_track_rotation_ts = today + rotate_at - 86400;
3211 m_last_track_rotation_ts = now;
3217void MyFrame::TrackDailyRestart() {
3219 Track *pPreviousTrack = TrackOff(
true);
3226 if (pPreviousTrack) {
3227 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3231 if (RouteManagerDialog::getInstanceFlag()) {
3232 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3233 pRouteManagerDialog->UpdateTrkListCtrl();
3234 pRouteManagerDialog->UpdateRouteListCtrl();
3239void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3241 cc->SetUpMode(mode);
3243 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3244 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3245 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3248 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3253 cc->SetShowENCText(!cc->GetShowENCText());
3255 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3263void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3266 cc->SetENCDisplayCategory(nset);
3268 UpdateGlobalMenuItems();
3279 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3281 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3290 cc->SetShowENCLights(!cc->GetShowENCLights());
3292 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3302void MyFrame::ToggleRocks(
void )
3308 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3309 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3310 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3311 pOLE->nViz = !pOLE->nViz;
3315 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3316 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3317 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3320 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3324 ps52plib->GenerateStateHash();
3331 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3333 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3341 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3343 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3358 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3359 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3364 cc->SetShowAIS(!cc->GetShowAIS());
3365 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3369void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3370 cc->SetAttenAIS(!cc->GetAttenAIS());
3371 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3377 cc->m_bFollow =
true;
3380 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3384 SetChartUpdatePeriod();
3392 cc->m_bFollow =
false;
3394 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3398 SetChartUpdatePeriod();
3401void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3402 cc->SetShowOutlines(!cc->GetShowOutlines());
3404 RefreshAllCanvas(
false);
3408 if (g_bopengl) InvalidateAllGL();
3411 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3414void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3416void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3418 bool enabled = m_pMenuBar->IsEnabled(item_id);
3419 m_pMenuBar->Enable(item_id,
false);
3420 m_pMenuBar->Check(item_id, state);
3421 m_pMenuBar->Enable(item_id, enabled);
3425void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3432void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3433 wxBitmap *bmpRollover) {
3435 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3440void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3441 wxString rolloverSVGfile,
3442 wxString toggledSVGfile) {
3445 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3449void MyFrame::ConfigureStatusBar() {
3451 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3454 UseNativeStatusBar(
false);
3457 if (g_bShowStatusBar) {
3458 if (!m_pStatusBar) {
3460 CreateStatusBar(m_StatusBarFieldCount, 0);
3461 ApplyGlobalColorSchemetoStatusBar();
3466 m_pStatusBar->Destroy();
3467 m_pStatusBar = NULL;
3473void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3474 ConfigureStatusBar();
3476 wxSize lastOptSize = options_lastWindowSize;
3482 options_lastWindowSize = lastOptSize;
3484 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3487wxString _menuText(wxString name, wxString shortcut) {
3491 menutext <<
"\t" << shortcut;
3496void MyFrame::BuildMenuBar() {
3502 bool showMenuBar =
true;
3504 bool showMenuBar = g_bShowMenuBar;
3516 m_pMenuBar =
new wxMenuBar();
3517 RegisterGlobalMenuItems();
3518 SetMenuBar(m_pMenuBar);
3522 UpdateGlobalMenuItems();
3527 m_pMenuBar->Destroy();
3533void MyFrame::RegisterGlobalMenuItems() {
3534 if (!m_pMenuBar)
return;
3536 wxMenu *nav_menu =
new wxMenu();
3537 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3538 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3539 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3540 nav_menu->AppendSeparator();
3541 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3542 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3543 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3544 nav_menu->AppendSeparator();
3546 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3547 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3549 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3550 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3552 nav_menu->AppendSeparator();
3553 nav_menu->Append(ID_MENU_SCALE_IN,
3554 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3555 nav_menu->Append(ID_MENU_SCALE_OUT,
3556 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3558 nav_menu->AppendSeparator();
3559 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3561 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3563 wxMenu *view_menu =
new wxMenu();
3565 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3566 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3567 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3568 _menuText(_(
"Show Chart Outlines"),
"O"));
3570 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3571 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3572 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3573 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3575 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3576 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3578 view_menu->AppendSeparator();
3580 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3581 _menuText(_(
"Show ENC text"),
"T"));
3582 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3583 _menuText(_(
"Show ENC Lights"),
"L"));
3584 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3585 _menuText(_(
"Show ENC Soundings"),
"S"));
3586 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3587 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3588 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3589 _menuText(_(
"Show ENC Data Quality"),
"U"));
3590 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3591 _menuText(_(
"Show Navobjects"),
"V"));
3593 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3594 _menuText(_(
"Show ENC text"),
"Alt-T"));
3595 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3596 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3597 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3598 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3599 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3600 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3601 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3602 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3603 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3604 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3606 view_menu->AppendSeparator();
3607 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3608 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3609 view_menu->AppendSeparator();
3611 view_menu->Append(ID_MENU_UI_COLSCHEME,
3612 _menuText(_(
"Change Color Scheme"),
"C"));
3614 view_menu->Append(ID_MENU_UI_COLSCHEME,
3615 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3618 view_menu->AppendSeparator();
3620 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3621 _menuText(_(
"Toggle Full Screen"),
"F11"));
3623 m_pMenuBar->Append(view_menu, _(
"&View"));
3625 wxMenu *ais_menu =
new wxMenu();
3626 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3627 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3628 _(
"Attenuate less critical AIS targets"));
3629 ais_menu->AppendSeparator();
3630 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3631 _(
"Hide Moored AIS Targets"));
3632 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3633 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3634 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3637 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3638 _menuText(_(
"Show CPA Warnings"),
"W"));
3640 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3641 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3644 ais_menu->AppendSeparator();
3645 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3646 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3648 wxMenu *tools_menu =
new wxMenu();
3649 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3650 _menuText(_(
"Data Monitor"),
"Alt-C"));
3652 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3653 _menuText(_(
"Measure Distance"),
"M"));
3655 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3656 _menuText(_(
"Measure Distance"),
"Alt-M"));
3659 tools_menu->AppendSeparator();
3660 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3661 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3662 tools_menu->AppendSeparator();
3663 tools_menu->Append(ID_MENU_MARK_BOAT,
3664 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3665 tools_menu->Append(ID_MENU_MARK_CURSOR,
3666 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3667 tools_menu->AppendSeparator();
3671 _menuText(_(
"Drop MOB Marker"),
3673 tools_menu->AppendSeparator();
3674 tools_menu->Append(wxID_PREFERENCES,
3675 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3677 tools_menu->Append(ID_MENU_MARK_MOB,
3678 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3679 tools_menu->AppendSeparator();
3680 tools_menu->Append(wxID_PREFERENCES,
3681 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3683 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3686 wxMenu *window_menu =
new wxMenu();
3687 m_pMenuBar->Append(window_menu, _(
"&Window"));
3690 wxMenu *help_menu =
new wxMenu();
3691 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3692 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3693 m_pMenuBar->Append(help_menu, _(
"&Help"));
3696 UpdateGlobalMenuItems();
3699void MyFrame::UpdateGlobalMenuItems() {
3700 if (!m_pMenuBar)
return;
3702 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3703 ->Check(GetPrimaryCanvas()->m_bFollow);
3704 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3705 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3706 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3707 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3708 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3709 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3710 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3711 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3712 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3713 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3714 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3715 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3716 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3717 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3718 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3719 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3720 if (g_bAIS_CPA_Alert) {
3721 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3722 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3724 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3725 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3728 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3729 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3730 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3733 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3734 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3735 ->Check(ps52plib->GetShowSoundings());
3737 bool light_state =
false;
3739 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3741 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3742 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3743 light_state = (pOLE->nViz == 1);
3748 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3749 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3753 DisCat nset = ps52plib->GetDisplayCategory();
3754 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3755 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3756 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3757 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3758 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3759 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3760 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3762 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3763 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3764 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3769void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3770 if (!m_pMenuBar)
return;
3772 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3774 if (cc->GetUpMode() == NORTH_UP_MODE)
3775 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3776 else if (cc->GetUpMode() == COURSE_UP_MODE)
3777 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3779 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3781 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3782 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3783 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3784 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3785 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3786 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3787 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3788 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3789 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3790 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3791 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3792 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3793 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3794 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3795 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3798 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3799 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3802 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3804 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3805 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3810 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3814 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3815 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3816 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3817 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3818 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3819 ->Check(cc->GetShowENCDataQual());
3820 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3822 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3823 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3824 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3829void MyFrame::InvalidateAllCanvasUndo() {
3831 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3833 if (cc) cc->undo->InvalidateUndo();
3837void MyFrame::SubmergeAllCanvasToolbars() {
3839 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3841 if (cc) cc->SubmergeToolbar();
3845void MyFrame::SurfaceAllCanvasToolbars() {
3846 if (g_bshowToolbar) {
3848 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3850 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3857void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3859 if (lon > 180.0) lon -= 360.0;
3864 cc->JumpToPosition(lat, lon,
scale);
3867 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3871void MyFrame::UpdateCanvasConfigDescriptors() {
3873 for (
unsigned int i = 0;
3874 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3875 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3883 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3884 cc->GroupID = chart->m_groupIndex;
3887 cc->
bQuilt = chart->GetQuiltMode();
3894 cc->
bFollow = chart->m_bFollow;
3899 int upmode = chart->GetUpMode();
3900 if (upmode == COURSE_UP_MODE)
3902 else if (upmode == HEAD_UP_MODE)
3909void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3910 if (!RBBox.GetValid())
return;
3912 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3913 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3916 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3917 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3925 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3926 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3928 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3929 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3931 cc->GetSize(&ww, &wh);
3933 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3935 ppm = wxMin(ppm, 1.0);
3941void MyFrame::PrepareOptionsClose(
options *settings,
3942 int settings_return_value) {
3944 options_lastPage = settings->lastPage;
3949 if (options_lastPage == 1) options_lastPage = 0;
3951 options_subpage = settings->lastSubPage;
3952 options_lastWindowPos = settings->lastWindowPos;
3953 options_lastWindowSize = settings->lastWindowSize;
3956 androidEnableBackButton(
true);
3957 androidEnableOptionsMenu(
true);
3958 androidRestoreFullScreen();
3959 androidEnableRotation();
3964void MyFrame::DoOptionsDialog() {
3966 AbstractPlatform::ShowBusySpinner();
3969 pConfig->SetPath(
"/Settings");
3970 pConfig->Read(
"OptionsSizeX", &sx, -1);
3971 pConfig->Read(
"OptionsSizeY", &sy, -1);
3973 wxWindow *optionsParent =
this;
3975 optionsParent = GetPrimaryCanvas();
3980 AbstractPlatform::HideBusySpinner();
3984 g_options->SetInitChartDir(*pInit_Chart_Dir);
3988 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
3989 g_options->SetWorkDirListPtr(pWorkDirArray);
3995 prev_locale = g_locale;
3996 g_options->SetInitialPage(options_lastPage, options_subpage);
3999 g_options->lastWindowPos = options_lastWindowPos;
4000 if (options_lastWindowPos != wxPoint(0, 0)) {
4002 g_options->SetSize(options_lastWindowSize);
4006 if (options_lastWindowSize != wxSize(0, 0)) {
4007 g_options->SetSize(options_lastWindowSize);
4012 androidEnableBackButton(
false);
4013 androidEnableOptionsMenu(
false);
4014 androidDisableFullScreen();
4022 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4025 wxString chart_file_name;
4026 if (cc->GetQuiltMode()) {
4027 int dbi = cc->GetQuiltRefChartdbIndex();
4028 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4030 if (cc->m_singleChart)
4031 chart_file_name = cc->m_singleChart->GetFullPath();
4034 pathArray.Add(chart_file_name);
4040 last_canvasConfig = g_canvasConfig;
4043 g_last_ChartScaleFactor = g_ChartScaleFactor;
4049void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4050 bool b_need_refresh =
false;
4052 if ((rr & VISIT_CHARTS) &&
4053 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4055 UpdateChartDatabaseInplace(*pNewDirArray,
4056 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4059 b_need_refresh =
true;
4063 if (rr & STYLE_CHANGED) {
4066 _(
"Please restart OpenCPN to activate language or style changes."),
4067 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4070 bool b_groupchange =
false;
4071 if (((rr & VISIT_CHARTS) &&
4072 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4073 (rr & GROUPS_CHANGED)) {
4074 b_groupchange = ScrubGroupArray();
4076 RefreshGroupIndices();
4079 if (rr & GROUPS_CHANGED || b_groupchange) {
4080 pConfig->DestroyConfigGroups();
4084 if (rr & TIDES_CHANGED) {
4090 if (rr & S52_CHANGED) {
4091 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4094 pConfig->UpdateSettings();
4102 g_Platform->GetDisplayDPmm());
4105 double stuffcog = NAN;
4106 double stuffsog = NAN;
4107 if (!std::isnan(
gCog)) stuffcog =
gCog;
4108 if (!std::isnan(
gSog)) stuffsog =
gSog;
4110 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4111 COGFilterTable[i] = stuffcog;
4112 SOGFilterTable[i] = stuffsog;
4115 SetChartUpdatePeriod();
4117 if (rr & GL_CHANGED) {
4121 b_need_refresh =
true;
4124 if (rr & S52_CHANGED) {
4125 b_need_refresh =
true;
4129 if (rr & REBUILD_RASTER_CACHE) {
4131 GetPrimaryCanvas()->Disable();
4133 GetPrimaryCanvas()->Enable();
4138 if (g_config_display_size_manual &&
4146 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4153 int rrt = rr & S52_CHANGED;
4155 (rrt == S52_CHANGED) ||
4156 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4166 ps52plib->SetScaleFactorExp(
4167 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4168 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4172 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4174 if (cc) cc->ApplyGlobalSettings();
4179 bool ztc = g_bEnableZoomToCursor;
4180 g_bEnableZoomToCursor =
4184 if (!GetPrimaryCanvas()->IsFrozen())
4186 g_bEnableZoomToCursor = ztc;
4189 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4198 SetGPSCompassScale();
4200 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4203 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4204 cc->UpdateCanvasControlBar();
4207 UpdateGPSCompassStatusBoxes();
4209 SetAllToolbarScale();
4210 RequestNewToolbars();
4213 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4216 cc->RebuildCursors();
4221 bool b_masterScaleChange =
false;
4222 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4223 b_masterScaleChange =
true;
4225 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4226 RequestNewMasterToolbar(
true);
4228 bool bMuiChange =
false;
4234 if (b_masterScaleChange || bMuiChange) {
4236 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4239 cc->ProcessNewGUIScale();
4245 if (rr & LOCALE_CHANGED) {
4246 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4248 rr |= NEED_NEW_OPTIONS;
4257 g_last_ChartScaleFactor = g_ChartScaleFactor;
4259 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4264bool MyFrame::CheckGroup(
int igroup) {
4265 if (igroup == 0)
return true;
4269 if (!pGroup->m_element_array.size())
4272 for (
const auto &elem : pGroup->m_element_array) {
4273 for (
unsigned int ic = 0;
4274 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4276 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4278 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4285bool MyFrame::ScrubGroupArray() {
4290 bool b_change =
false;
4291 unsigned int igroup = 0;
4292 while (igroup < g_pGroupArray->GetCount()) {
4293 bool b_chart_in_element =
false;
4296 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4297 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4299 for (
unsigned int ic = 0;
4300 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4302 wxString chart_full_path = pcte->GetFullSystemPath();
4304 if (chart_full_path.StartsWith(element_root)) {
4305 b_chart_in_element =
true;
4311 if (!b_chart_in_element) {
4312 wxString test_string =
"GSHH";
4313 if (element_root.Upper().Contains(test_string))
4314 b_chart_in_element =
true;
4317 if (!b_chart_in_element)
4319 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4331void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4333 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4335 if (cc && (cc != ccThis)) cc->Refresh();
4340void MyFrame::ChartsRefresh() {
4343 AbstractPlatform::ShowBusySpinner();
4345 bool b_run = FrameTimer1.IsRunning();
4348 FrameTenHzTimer.Stop();
4351 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4354 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4355 if (cc->GetQuiltMode()) {
4356 currentIndex = cc->GetQuiltReferenceChartIndex();
4358 cc->canvasChartsRefresh(currentIndex);
4362 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4363 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4365 AbstractPlatform::HideBusySpinner();
4368void MyFrame::InvalidateAllQuilts() {
4369 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4372 cc->InvalidateQuilt();
4373 cc->SetQuiltRefChart(-1);
4374 cc->m_singleChart = NULL;
4379bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4381 const wxString &ChartListFileName) {
4382 bool b_run = FrameTimer1.IsRunning();
4384 FrameTenHzTimer.Stop();
4386 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4387 FrameCOGTimer.Stop();
4390 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4393 cc->InvalidateQuilt();
4394 cc->SetQuiltRefChart(-1);
4395 cc->m_singleChart = NULL;
4405 AbstractPlatform::ShowBusySpinner();
4407 wxGenericProgressDialog *pprog =
nullptr;
4409 wxString longmsg = _(
"OpenCPN Chart Update");
4411 ".................................................................."
4414 pprog =
new wxGenericProgressDialog();
4417 pprog->SetFont(*qFont);
4419 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4420 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4421 wxPD_REMAINING_TIME);
4428 wxLogMessage(
"Starting chart database Update...");
4429 wxString gshhg_chart_loc = gWorldMapLocation;
4430 gWorldMapLocation = wxEmptyString;
4434 ChartData->SaveBinary(ChartListFileName);
4435 wxLogMessage(
"Finished chart database Update");
4437 if (gWorldMapLocation.empty()) {
4441 gWorldMapLocation = gDefaultWorldMapLocation;
4442 gshhg_chart_loc = wxEmptyString;
4445 if (gWorldMapLocation != gshhg_chart_loc) {
4447 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4449 if (cc) cc->ResetWorldBackgroundChart();
4452 gshhsCrossesLandReset();
4457 AbstractPlatform::HideBusySpinner();
4459 pConfig->UpdateChartDirs(DirArray);
4462 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4463 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4465 if (b_runCOGTimer) {
4467 int period_ms = 100;
4469 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4476 cc->ToggleCanvasQuiltMode();
4478 bool cur_mode = cc->GetQuiltMode();
4480 if( !cc->GetQuiltMode() )
4481 cc->SetQuiltMode(
true );
4483 if( cc->GetQuiltMode() ) {
4484 cc->SetQuiltMode(
false );
4485 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4489 if( cur_mode != cc->GetQuiltMode() ){
4495 g_bQuiltEnable = cc->GetQuiltMode();
4499 ps52plib->GenerateStateHash();
4504void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4506void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4508void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4510 cc->DoCanvasStackDelta(direction);
4514void MyFrame::PositionIENCToolbar() {
4518 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4520 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4528void MyFrame::OnInitTimer(wxTimerEvent &event) {
4531 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4535 wxLog::FlushActive();
4537 switch (m_iInitCount++) {
4542 if (g_bInlandEcdis) {
4543 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4544 double range_set = 500.;
4546 range = wxRound(range * 10) / 10.;
4550 else if (range > 2000.)
4552 else if (range > 1600.)
4554 else if (range > 1200.)
4556 else if (range > 800.)
4561 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4565 g_Platform->SetFullscreen(g_bFullscreen);
4569 RebuildChartDatabase();
4570 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4573 cc->SetGroupIndex(0,
false);
4581 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4582 CHART_FAMILY_RASTER)) {
4587 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4588 CHART_FAMILY_VECTOR)) {
4601 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4604 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4606 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4609 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4613 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4614 NavObj_dB::GetInstance().LoadNavObjects();
4617 if (!g_AW1GUID.IsEmpty()) {
4620 if (!g_AW2GUID.IsEmpty()) {
4626 appendOSDirSlash(&layerdir);
4627 layerdir.Append(
"layers");
4629 if (wxDir::Exists(layerdir)) {
4631 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4632 wxLogMessage(laymsg);
4633 pConfig->LoadLayers(layerdir);
4641 for (
auto *cp : TheConnectionParams()) {
4644 cp->b_IsSetup = TRUE;
4651 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4665 3 * GetCharHeight());
4667 m_data_monitor->Center();
4675 pConfig->SetPath(
"/Settings");
4676 pConfig->Read(
"OptionsSizeX", &sx, -1);
4677 pConfig->Read(
"OptionsSizeY", &sy, -1);
4679 wxWindow *optionsParent =
this;
4681 optionsParent = GetPrimaryCanvas();
4687 BuildiENCToolbar(
true);
4694 if (!g_params.empty()) {
4695 for (
size_t n = 0; n < g_params.size(); n++) {
4696 wxString path = g_params[n];
4697 if (::wxFileExists(path)) {
4699 pSet->load_file(path.fn_str());
4702 pSet->LoadAllGPXObjects(
4703 !pSet->IsOpenCPN(), wpt_dups,
4705 LLBBox box = pSet->GetBBox();
4706 if (box.GetValid()) {
4707 CenterView(GetPrimaryCanvas(), box);
4716 InitAppMsgBusListener();
4721 auto loader = PluginLoader::GetInstance();
4722 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4723 if (!b_haveWMM)
gVar = g_UserVar;
4731 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4734 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4736 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4739 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4743 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4744 NavObj_dB::GetInstance().LoadNavObjects();
4747 if (!g_AW1GUID.IsEmpty()) {
4750 if (!g_AW2GUID.IsEmpty()) {
4756 appendOSDirSlash(&layerdir);
4757 layerdir.Append(
"layers");
4759 if (wxDir::Exists(layerdir)) {
4761 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4762 wxLogMessage(laymsg);
4763 pConfig->LoadLayers(layerdir);
4770 wxLogMessage(
"OnInitTimer...Last Call");
4772 RequestNewMasterToolbar();
4774 PositionIENCToolbar();
4776 g_bDeferredInitDone =
true;
4786 GetPrimaryCanvas()->SetFocus();
4787 GetPrimaryCanvas()->Enable();
4794 if (b_reloadForPlugins) {
4800 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4802 if (cc) cc->SetFirstAuto(
true);
4810 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4812 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4816 cc->CheckGroupValid();
4821 androidEnableBackButton(
true);
4822 androidEnableRotation();
4823 androidEnableOptionItems(
true);
4829 if (g_start_fullscreen) ToggleFullScreen();
4835 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4837 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4839 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4845 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4847 wxLog::FlushActive();
4849 RefreshAllCanvas(
true);
4850 wxGetApp().m_usb_watcher.Start();
4856void MyFrame::InitAppMsgBusListener() {
4857 auto &msgbus = AppMsgBus::GetInstance();
4860 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4861 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4865 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4866 HandleBasicNavMsg(basicnav_msg);
4870 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4871 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4875 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4876 HandleGPSWatchdogMsg(msg);
4883void MyFrame::ReleaseApiListeners() {}
4888 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4889 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4890 server.SetGetRestApiEndpointCb(
4891 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4892 server.open_file_cb = [](
const std::string &path) {
4893 return wxGetApp().OpenFile(path);
4900void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4901 if (msg->gps_watchdog <= 0) {
4902 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4906 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4911 if (m_fix_start_time.IsValid()) {
4912 wxDateTime now = wxDateTime::Now();
4913 wxTimeSpan span = now - m_fix_start_time;
4914 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4915 auto ¬eman = NotificationManager::GetInstance();
4916 wxString msg = _(
"GNSS Position fix lost");
4917 noteman.AddNotification(NotificationSeverity::kCritical,
4919 m_fix_start_time = wxInvalidDateTime;
4923 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4924 bool last_bVelocityValid = bVelocityValid;
4925 bVelocityValid =
false;
4932void MyFrame::CalculateCOGAverage() {
4934 if (!std::isnan(
gCog)) {
4937 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4940 double sum = 0., count = 0;
4942 double adder = COGTable[i];
4943 if (std::isnan(adder))
continue;
4945 if (fabs(adder -
g_COGAvg) > 180.) {
4959 else if (sum >= 360.)
4968void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4969 m_fixtime = msg->time;
4970 double hdt_data_interval = 0;
4971 double fix_time_interval = 0;
4973 double msgtime = msg->set_time.tv_sec;
4974 double m1 = msg->set_time.tv_nsec / 1e9;
4977 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
4978 ((msg->vflag & POS_VALID) == POS_VALID)) {
4980 if (!m_fix_start_time.IsValid()) {
4981 m_fix_start_time = wxDateTime::Now();
4986 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
4989 fix_time_gt_last = fix_time_gt;
4990 uint64_t fix_time_gt_now =
4991 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
4992 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
4996 double implied_sog = dist / (fix_time_interval / 3600);
5001 gLat_gt_m1 = gLat_gt;
5002 gLon_gt_m1 = gLon_gt;
5006 fix_time_gt = fix_time_gt_now;
5010 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5011 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5012 gCog_gt_m1 = gCog_gt;
5022 if (!std::isnan(gCog_gt_m1)) {
5024 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5031 if ((fix_time_gt - fix_time_gt_last) > .08) {
5036 if (gCog_gt > gCog_gt_m1) {
5037 if ((gCog_gt - gCog_gt_m1) > 180.)
5042 if ((gCog_gt_m1 - gCog_gt) > 180.)
5047 difft = fabs(gCog_gt - gCog_gt_m1);
5048 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5056 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5057 tentative_cog_rate_gt *= 1e9;
5058 cog_rate_gt = tentative_cog_rate_gt;
5066 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5069static double hdt_avg;
5070 double hdt_norm =
gHdt;
5071 if(
gHdt > 180) hdt_norm -= 360;
5074 hdt_avg += hdt_norm * 0.1;
5079 if (!std::isnan(
gHdt)) {
5081 uint64_t hdt_time_gt_last = hdt_time_gt;
5082 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5083 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5086 if (hdt_data_interval > .09) {
5088 gHdt_gt_m1 = gHdt_gt;
5091 if (!std::isnan(gHdt_gt_m1)) {
5093 double tentative_hdt_rate_gt =
5094 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5095 tentative_hdt_rate_gt *= 1e9;
5097 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5098 hdt_rate_gt = tentative_hdt_rate_gt;
5106 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5109 CalculateCOGAverage();
5117 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5118 if ((msg->vflag & POS_VALID) == POS_VALID)
5123 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5125 bVelocityValid =
true;
5129void MyFrame::UpdateStatusBar() {
5132 unsigned long uiCurrentTickCount;
5133 m_MMEAeventTime.SetToCurrent();
5134 uiCurrentTickCount =
5135 m_MMEAeventTime.GetMillisecond() / 100;
5136 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5137 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5138 m_ulLastNMEATicktime = uiCurrentTickCount;
5140 if (m_tick_idx++ > 6) m_tick_idx = 0;
5145 if (NULL != GetStatusBar()) {
5148 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5151 wxString s1(tick_buf, wxConvUTF8);
5153 s1 += toSDMM(1,
gLat);
5155 s1 += toSDMM(2,
gLon);
5157 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5161 if (!std::isnan(
gSog))
5162 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5164 sogcog.Printf(
"SOG --- ");
5168 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5170 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5172 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5173 (
int)toMagnetic(
gCog), 0x00B0);
5175 cogs.Printf((
"COG ---%c"), 0x00B0);
5177 sogcog.Append(cogs);
5178 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5183void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5184 MemFootTimer.Stop();
5186 int memsize = GetApplicationMemoryUse();
5189 printf(
"Memsize: %d \n", memsize);
5192 if (memsize > (g_MemFootMB * 1000)) {
5196 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5197 unsigned int nCache = pCache->GetCount();
5200 for (
unsigned int i = 0; i < nCache; i++) {
5210 for (
unsigned int i = 0; i < nCache - 1; i++) {
5211 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5213 pcea[i] = pcea[i + 1];
5224 unsigned int idelete = 0;
5225 unsigned int idelete_max = pCache->GetCount();
5228 unsigned int minimum_cache = 1;
5229 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5231 while ((memsize > (g_MemFootMB * 1000)) &&
5232 (pCache->GetCount() > minimum_cache) &&
5233 (idelete < idelete_max)) {
5234 int memsizeb = memsize;
5238 memsize = GetApplicationMemoryUse();
5239 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5247 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5252void MyFrame::CheckToolbarPosition() {
5255 static bool bMaximized;
5257 if (IsMaximized() && !bMaximized) {
5264 PositionIENCToolbar();
5265 }
else if (!IsMaximized() && bMaximized) {
5273 PositionIENCToolbar();
5278void MyFrame::ProcessUnitTest() {
5279 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5286 cc->m_bFollow =
false;
5288 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5289 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5292 if (cc->m_groupIndex > 0) {
5293 while (ut_index < ChartData->GetChartTableEntries() &&
5294 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5298 if (ut_index < ChartData->GetChartTableEntries()) {
5302 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5303 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5310 if (cc->GetQuiltMode()) {
5311 if (cc->IsChartQuiltableRef(ut_index))
5312 cc->SelectQuiltRefdbChart(ut_index);
5314 cc->SelectdbChart(ut_index);
5317 if (g_unit_test_1) {
5325 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5326 cte->GetLatMin(), cte->GetLonMax(), NULL,
5330 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5331 cte->GetLatMax(), cte->GetLonMin(), NULL,
5334 cc->GetSize(&ww, &wh);
5335 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5337 ppm = wxMin(ppm, 1.0);
5344 if (ut_index > ut_index_max) exit(0);
5355 bool b_rotate =
false;
5357 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5360 if (!b_rotate && !g_btenhertz)
return;
5362 bool b_update =
false;
5364 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5367 struct timespec now;
5368 clock_gettime(CLOCK_MONOTONIC, &now);
5369 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5370 double diffc = diff / 1e9;
5373 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5374 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5375 if (gCog_tentative < 0.) gCog_tentative += 360.;
5376 gCog = gCog_tentative;
5380 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5381 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5382 double diffc = diff / 1e9;
5383 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5387 if (gSog_gt && !std::isnan(gCog_gt)) {
5388 double delta_t = diffc / 3600;
5389 double distance = gSog_gt * delta_t;
5392 double angr = gCog_gt / 180 * M_PI;
5393 double latr = gLat_gt * M_PI / 180;
5394 double D = distance / 3443;
5395 double sD = sin(D), cD = cos(D);
5396 double sy = sin(latr), cy = cos(latr);
5397 double sa = sin(angr), ca = cos(angr);
5399 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5400 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5410 if (cc) cc->DoCanvasCOGSet();
5421 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5422 cc->DoCanvasUpdate();
5431 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5434void MyFrame::ProcessQuitFlag() {
5437 wxLogMessage(
"Got quitflag from SIGNAL");
5439 FrameTenHzTimer.Stop();
5446void MyFrame::ProcessDeferredTrackOn() {
5449 if (g_bDeferredStartTrack) {
5450 if (!g_bTrackActive) {
5453 g_bDeferredStartTrack =
false;
5456 g_bDeferredStartTrack =
false;
5461void MyFrame::ProcessAnchorWatch() {
5469 double d = g_nAWMax;
5471 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5472 bool toofar =
false;
5473 bool tooclose =
false;
5474 if (d >= 0.0) toofar = (dist * 1852. > d);
5475 if (d < 0.0) tooclose = (dist * 1852 < -d);
5477 if (tooclose || toofar)
5478 AnchorAlertOn1 =
true;
5480 AnchorAlertOn1 =
false;
5482 AnchorAlertOn1 =
false;
5490 double d = g_nAWMax;
5492 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5493 bool toofar =
false;
5494 bool tooclose =
false;
5495 if (d >= 0) toofar = (dist * 1852. > d);
5496 if (d < 0) tooclose = (dist * 1852 < -d);
5498 if (tooclose || toofar)
5499 AnchorAlertOn2 =
true;
5501 AnchorAlertOn2 =
false;
5503 AnchorAlertOn2 =
false;
5506 AnchorAlertOn1 =
true;
5509void MyFrame::SendFixToPlugins() {
5520 GPSData.
nSats = g_SatsInView;
5522 wxDateTime tCheck((time_t)m_fixtime);
5523 if (tCheck.IsValid()) {
5532 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5535 SendPositionFixToAllPlugIns(&GPSData);
5539void MyFrame::ProcessLogAndBells() {
5542 wxDateTime lognow = wxDateTime::Now();
5543 int hourLOC = lognow.GetHour();
5544 int minuteLOC = lognow.GetMinute();
5546 int minuteUTC = lognow.GetMinute();
5547 int second = lognow.GetSecond();
5549 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5550 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5551 (minuteUTC == 30)) {
5552 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5553 wxString day = lognow.FormatISODate();
5554 wxString utc = lognow.FormatISOTime();
5555 wxString navmsg =
"LOGBOOK: ";
5563 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5567 if (std::isnan(
gCog))
5568 cog.Printf(
"COG ----- ");
5570 cog.Printf(
"COG %10.5f ",
gCog);
5573 if (std::isnan(
gSog))
5574 sog.Printf(
"SOG ----- ");
5576 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5582 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5585 wxLogMessage(navmsg);
5586 g_loglast_time = lognow;
5588 int bells = (hourLOC % 4) * 2;
5589 if (minuteLOC != 0) bells++;
5590 if (!bells) bells = 8;
5592 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5593 m_BellsToPlay = bells;
5594 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5595 wxPostEvent(
this, ev);
5602 CheckToolbarPosition();
5608 if (bDBUpdateInProgress)
return;
5611 FrameTenHzTimer.Stop();
5613 ProcessDeferredTrackOn();
5615 ProcessAnchorWatch();
5616 ProcessLogAndBells();
5618 if (ShouldRestartTrack()) TrackDailyRestart();
5621 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5622 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5623 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5629 if (
gSog > 3.0) g_bCruising =
true;
5635 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5637 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5643 bool bnew_view =
false;
5644 if (!g_btenhertz) bnew_view = DoChartUpdate();
5651 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5654 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5657 cc->DrawBlinkObjects();
5660 if (bactiveRouteUpdate) {
5667 cc->SetOwnShipState(SHIP_NORMAL);
5669 if (cc->GetQuiltMode()) {
5670 double erf = cc->GetQuiltMaxErrorFactor();
5671 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5673 if (cc->m_singleChart) {
5674 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5675 cc->SetOwnShipState(SHIP_LOWACCURACY);
5679 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5682 (bVelocityValid != m_last_bVelocityValid) ||
5683 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5684 if (!g_bopengl) cc->UpdateShips();
5692 m_last_bVelocityValid = bVelocityValid;
5697 bool brq_dynamic =
false;
5699 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5700 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5702 if (pic->m_enabled && pic->m_init_state) {
5703 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5710 if (brq_dynamic) bnew_view =
true;
5714 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5717 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5722 if (cc->GetglCanvas()) {
5724 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5727 if (cc->m_bFollow) {
5728 cc->DoCanvasUpdate();
5735 if (std::isnan(
gCog)) cc->Refresh(
false);
5748 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5762 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5763 g_pais_query_dialog_active->UpdateText();
5766 if (g_pAISTargetList && (0 == (g_tick % (5))))
5767 g_pAISTargetList->UpdateAISTargetList();
5770 UpdateGPSCompassStatusBoxes();
5775 console->RefreshConsoleData();
5782 if (m_bdefer_resize) {
5783 if (0 == (g_tick % (5))) {
5784 printf(
"___RESIZE\n");
5785 SetSize(m_defer_size);
5787 m_bdefer_resize =
false;
5794 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5796 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5797 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5801double MyFrame::GetMag(
double a,
double lat,
double lon) {
5802 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5803 auto loader = PluginLoader::GetInstance();
5804 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5811 wxDateTime now = wxDateTime::Now();
5812 SendJSON_WMM_Var_Request(lat, lon, now);
5813 if (fabs(gQueryVar) < 360.0)
5814 Variance = gQueryVar;
5816 return toMagnetic(a, Variance);
5819bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5825 v[
"Year"] = date.GetYear();
5826 v[
"Month"] = date.GetMonth();
5827 v[
"Day"] = date.GetDay();
5829 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5835void MyFrame::TouchAISActive() {
5837 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5839 if (cc) cc->TouchAISToolActive();
5843void MyFrame::UpdateAISTool() {
5847 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5849 if (cc) cc->UpdateAISTBTool();
5854void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5856 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5858 if (cc) cc->SetbTCUpdate(
true);
5861 RefreshAllCanvas(
false);
5866void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5870 bool b_rotate =
false;
5871 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5873 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5877 FrameCOGTimer.Stop();
5884 int period_ms = 100;
5886 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5889void MyFrame::DoCOGSet() {
5891 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5893 if (cc) cc->DoCanvasCOGSet();
5897void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5903 wxFont oldfont = pdc->GetFont();
5905 pdc->SetFont(*pFont);
5906 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5907 pdc->SetBackgroundMode(wxTRANSPARENT);
5909 pdc->DrawText(str, x, y + 1);
5910 pdc->DrawText(str, x, y - 1);
5911 pdc->DrawText(str, x + 1, y);
5912 pdc->DrawText(str, x - 1, y);
5914 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5916 pdc->DrawText(str, x, y);
5918 pdc->SetFont(oldfont);
5922void MyFrame::UpdateRotationState(
double rotation) {
5924 g_bCourseUp =
false;
5926 if (fabs(rotation) > .001) {
5927 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5928 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5930 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5933 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5934 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5936 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5940 UpdateGPSCompassStatusBoxes(
true);
5944void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5946 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5948 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5954int MyFrame::GetApplicationMemoryUse() {
5960 wxWindow *fWin = wxWindow::FindFocus();
5962 wxArrayString outputArray;
5963 wxString cmd(
"ps --no-headers -o vsize ");
5964 unsigned long pid = wxGetProcessId();
5966 cmd1.Printf(
"%ld", pid);
5968 wxExecute(cmd, outputArray);
5970 if (outputArray.GetCount()) {
5971 wxString s = outputArray.Item(0);
5973 if (s.ToLong(&vtmp)) memsize = vtmp;
5976 if (fWin) fWin->SetFocus();
5982 PROCESS_MEMORY_COUNTERS pmc;
5984 unsigned long processID = wxGetProcessId();
5986 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
5988 if (NULL == hProcess)
return 0;
5990 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6008 memsize = pmc.WorkingSetSize / 1024;
6011 CloseHandle(hProcess);
6018double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6019 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6022void MyFrame::SetChartUpdatePeriod() {
6025 g_ChartUpdatePeriod = 0;
6030 bool bskewdc =
false;
6031 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6034 if (!g_bopengl && !cc->GetVP().b_quilt) {
6035 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6037 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6041 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6043 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6048 cc->UpdateCanvasControlBar();
6051void MyFrame::selectChartDisplay(
int type,
int family) {
6053 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6055 if (cc) cc->selectCanvasChartDisplay(type, family);
6058 UpdateGlobalMenuItems();
6067bool MyFrame::DoChartUpdate() {
6068 bool return_val =
false;
6071 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6073 if (cc) return_val |= cc->DoCanvasUpdate();
6079void MyFrame::MouseEvent(wxMouseEvent &event) {
6081 event.GetPosition(&x, &y);
6086#include <mach/mach.h>
6087#include <mach/message.h>
6088#include <mach/kern_return.h>
6089#include <mach/task_info.h>
6091#include <malloc/malloc.h>
6098#if defined(__linux__)
6099#include "sys/types.h"
6100#include "sys/sysinfo.h"
6103void MyFrame::DoPrint(
void) {
6105 g_PrintingInProgress =
true;
6108 GetPrimaryCanvas()->GetglCanvas()->Render();
6109 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6119 printer.Initialize(wxLANDSCAPE);
6120 printer.EnablePageNumbers(
false);
6121 printer.Print(
this, &printout);
6139 g_PrintingInProgress =
false;
6142 GetPrimaryCanvas()->SetFocus();
6148 wxString message_ID =
event.GetID();
6149 wxString message_JSONText =
event.GetJSONText();
6157 if (message_ID ==
"WMM_VARIATION_BOAT") {
6165 int numErrors = reader.
Parse(message_JSONText, &root);
6166 if (numErrors > 0) {
6172 wxString decl = root[
"Decl"].
AsString();
6174 decl.ToDouble(&decl_val);
6180 if (message_ID ==
"WMM_VARIATION") {
6188 int numErrors = reader.
Parse(message_JSONText, &root);
6189 if (numErrors > 0) {
6195 wxString decl = root[
"Decl"].
AsString();
6197 decl.ToDouble(&decl_val);
6199 gQueryVar = decl_val;
6202 if (message_ID ==
"GRIB_TIMELINE") {
6205 int numErrors = r.
Parse(message_JSONText, &v);
6207 if (numErrors > 0) {
6208 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6213 wxDateTime oldTimeSource = gTimeSource;
6215 if (v[
"Day"].AsInt() == -1) {
6216 gTimeSource = wxInvalidDateTime;
6217 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6219 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6220 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6221 v[
"Second"].AsInt());
6225 if (oldTimeSource != gTimeSource) {
6227 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6229 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6234 cc->pCwin->Refresh(
false);
6240 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6243 wxString trk_id = wxEmptyString;
6245 int numErrors = reader.
Parse(message_JSONText, &root);
6246 if (numErrors > 0)
return;
6251 v[
"Track_ID"] = trk_id;
6253 wxString name = wxEmptyString;
6254 if (ptrack->m_GUID == trk_id) {
6255 name = ptrack->GetName();
6256 if (name.IsEmpty()) {
6262 name = _(
"(Unnamed Track)");
6269 v[
"TotalNodes"] = ptrack->GetnPoints();
6270 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6272 v[
"lat"] = tp->m_lat;
6273 v[
"lon"] = tp->m_lon;
6276 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6277 SendJSONMessageToAllPlugins(msg_id, v);
6283 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6284 SendJSONMessageToAllPlugins(msg_id, v);
6286 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6289 wxString guid = wxEmptyString;
6291 int numErrors = reader.
Parse(message_JSONText, &root);
6292 if (numErrors > 0) {
6301 wxString name = wxEmptyString;
6303 if ((*it)->m_GUID == guid) {
6304 name = (*it)->m_RouteNameString;
6305 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6311 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6312 itp != (*it)->pRoutePointList->end(); itp++) {
6313 w[i][
"lat"] = (*itp)->m_lat;
6314 w[i][
"lon"] = (*itp)->m_lon;
6315 w[i][
"Name"] = (*itp)->GetName();
6316 w[i][
"Description"] = (*itp)->GetDescription();
6317 w[i][
"GUID"] = (*itp)->m_GUID;
6318 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6320 auto node = (*itp)->m_HyperlinkList->begin();
6321 if (node != (*itp)->m_HyperlinkList->end()) {
6323 while (node != (*itp)->m_HyperlinkList->end()) {
6325 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6326 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6327 httpLink->DescrText;
6334 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6335 SendJSONMessageToAllPlugins(msg_id, v);
6342 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6343 SendJSONMessageToAllPlugins(msg_id, v);
6344 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6349 int numErrors = reader.
Parse(message_JSONText, &root);
6350 if (numErrors > 0)
return;
6353 wxString str = root[
"mode"].
AsString();
6354 if (str ==
"Track") route =
false;
6359 for (RouteList::iterator it =
pRouteList->begin();
6361 wxString name = (*it)->m_RouteNameString;
6362 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6364 v[i][
"error"] =
false;
6365 v[i][
"name"] = name;
6366 v[i][
"GUID"] = (*it)->m_GUID;
6367 v[i][
"active"] = (*it)->IsActive();
6372 wxString name = ptrack->GetName();
6373 if (name.IsEmpty()) {
6379 name = _(
"(Unnamed Track)");
6381 v[i][
"error"] =
false;
6382 v[i][
"name"] = name;
6383 v[i][
"GUID"] = ptrack->m_GUID;
6388 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6389 SendJSONMessageToAllPlugins(msg_id, v);
6392 v[0][
"error"] =
true;
6393 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6394 SendJSONMessageToAllPlugins(msg_id, v);
6396 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6398 v[0][
"error"] =
true;
6401 v[0][
"error"] =
false;
6402 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6403 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6404 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6405 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6406 v[0][
"active_waypoint_lat"] =
6408 v[0][
"active_waypoint_lon"] =
6412 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6413 SendJSONMessageToAllPlugins(msg_id, v);
6417void MyFrame::FilterCogSog() {
6418 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6420 double cog_last =
gCog;
6423 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6424 COGFilterTable[i] = COGFilterTable[i - 1];
6425 COGFilterTable[0] = cog_last;
6428 if (!std::isnan(cog_last)) {
6430 double sum = 0., count = 0;
6431 for (
int i = 0; i < g_COGFilterSec; i++) {
6432 double adder = COGFilterTable[i];
6433 if (std::isnan(adder))
continue;
6435 if (fabs(adder - cog_last) > 180.) {
6436 if ((adder - cog_last) > 0.)
6449 else if (sum >= 360.)
6456 double sog_last =
gSog;
6459 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6460 SOGFilterTable[i] = SOGFilterTable[i - 1];
6461 SOGFilterTable[0] = sog_last;
6464 if (!std::isnan(
gSog)) {
6465 double sum = 0., count = 0;
6466 for (
int i = 0; i < g_SOGFilterSec; i++) {
6467 if (std::isnan(SOGFilterTable[i]))
continue;
6469 sum += SOGFilterTable[i];
6479void MyFrame::LoadHarmonics() {
6482 ptcmgr->LoadDataSources(TideCurrentDataSet);
6484 bool b_newdataset =
false;
6487 for (
auto a :
ptcmgr->GetDataSet()) {
6488 bool b_foundi =
false;
6489 for (
auto b : TideCurrentDataSet) {
6496 b_newdataset =
true;
6501 for (
auto a : TideCurrentDataSet) {
6502 bool b_foundi =
false;
6503 for (
auto b :
ptcmgr->GetDataSet()) {
6510 b_newdataset =
true;
6515 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6519void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6520 if (!ptarget)
return;
6523 wxDateTime mob_time = wxDateTime::Now();
6524 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6525 mob_label += _(
" on ");
6526 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6529 mob_label, wxEmptyString);
6530 pWP_MOB->SetShared(
true);
6532 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6534 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6536 pWP_MOB->SetUseSca(
false);
6544 wxString(_(
"Own ship")), wxEmptyString);
6546 pWP_MOB->SetUseSca(
false);
6553 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6569 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6570 SendJSONMessageToAllPlugins(msg_id, v);
6573 if (RouteManagerDialog::getInstanceFlag()) {
6574 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6575 pRouteManagerDialog->UpdateRouteListCtrl();
6576 pRouteManagerDialog->UpdateWptListCtrl();
6580 RefreshAllCanvas(
false);
6582 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6583 mob_message += _(
" Time: ");
6584 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6585 mob_message += _(
" Ownship Position: ");
6586 mob_message += toSDMM(1,
gLat);
6588 mob_message += toSDMM(2,
gLon);
6589 mob_message += _(
" MOB Position: ");
6590 mob_message += toSDMM(1, ptarget->Lat);
6592 mob_message += toSDMM(2, ptarget->Lon);
6593 wxLogMessage(mob_message);
6596void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6600 OwnPoint->m_lat =
gLat;
6601 OwnPoint->m_lon =
gLon;
6603 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6608 MOB_Point->m_lat = ptarget->Lat;
6609 MOB_Point->m_lon = ptarget->Lon;
6611 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6612 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6614 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6615 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6618 RefreshAllCanvas(
false);
6621 wxDateTime mob_time = wxDateTime::Now();
6623 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6624 mob_message += _(
" Time: ");
6625 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6626 mob_message += _(
" Ownship Position: ");
6627 mob_message += toSDMM(1,
gLat);
6629 mob_message += toSDMM(2,
gLon);
6630 mob_message += _(
" MOB Position: ");
6631 mob_message += toSDMM(1, ptarget->Lat);
6633 mob_message += toSDMM(2, ptarget->Lon);
6635 wxLogMessage(mob_message);
6639void MyFrame::applySettingsString(wxString settings) {
6641 int last_UIScaleFactor = g_GUIScaleFactor;
6642 bool previous_expert = g_bUIexpert;
6643 g_last_ChartScaleFactor = g_ChartScaleFactor;
6644 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6647 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6650 pConfig->UpdateSettings();
6653 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6655 if (rr & S52_CHANGED) {
6657 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6659 ->ClearCNSYLUPArray();
6660 ps52plib->GenerateStateHash();
6664 ProcessOptionsDialog(rr, pNewDirArray);
6669 bool b_newToolbar =
false;
6671 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6673 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6675 if (rr & TOOLBAR_CHANGED) {
6676 b_newToolbar =
true;
6681 if (previous_expert && !g_bUIexpert) {
6682 androidForceFullRepaint();
6686 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6690 SetGPSCompassScale();
6692 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6694 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6696 UpdateGPSCompassStatusBoxes(
true);
6699 AbstractPlatform::ShowBusySpinner();
6701 SetAllToolbarScale();
6705 AbstractPlatform::HideBusySpinner();
6707 RequestNewMasterToolbar(
true);
6714 UpdateControlBar(GetPrimaryCanvas());
6720 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6723#ifdef wxHAS_POWER_EVENTS
6724void MyFrame::OnSuspending(wxPowerEvent &event) {
6728 wxLogMessage(
"System suspend starting...");
6731void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6734 wxLogMessage(
"System is going to suspend.");
6737void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6740 wxLogMessage(
"System suspend was cancelled.");
6743int g_last_resume_ticks;
6744void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6745 wxDateTime now = wxDateTime::Now();
6746 wxLogMessage(
"System resumed from suspend.");
6748 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6751 wxLogMessage(
"Restarting streams.");
6752 g_last_resume_ticks = now.GetTicks();
6756 g_pMUX->ClearStreams();
6758 g_pMUX->StartAllStreams();
6767 if (IsMaximized()) {
6772 wxSize sz = GetSize();
6773 SetSize(wxSize(sz.x - 1, sz.y));
6785void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6786 bool btbRebuild =
false;
6788 bool b_reshow =
true;
6791 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6792 if ((ff > 0.01f) || bforcenew) {
6802 long orient = g_Platform->GetDefaultToolbarOrientation();
6803 wxWindow *toolbarParent =
this;
6805 toolbarParent = GetPrimaryCanvas();
6808 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6810 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6817 g_bmasterToolbarFull =
true;
6821 CreateMasterToolbar();
6836bool MyFrame::CollapseGlobalToolbar() {
6838 m_nMasterToolCountShown = 1;
6842 g_bmasterToolbarFull =
false;
6858 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6859 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6860 tic->m_bRequired =
true;
6865 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6866 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6870 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6871 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6872 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6877 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6878 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6882 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6883 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6884 _(
"Enable Tracking"),
"MUI_track");
6888 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6889 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6901 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6902 _(
"Print Chart"),
"MUI_print");
6906 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6907 _(
"About OpenCPN"),
"MUI_help");
6911 AddDefaultPositionPlugInTools();
6915 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6916 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6927 ArrayOfPlugInToolbarTools tool_array =
6929 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6931 if (!pttc->b_viz)
continue;
6933 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6936 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6937 if (g_bTrackActive) {
6938 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6945bool MyFrame::CheckAndAddPlugInTool() {
6953 if (!tb)
return false;
6955 int n_tools = tb->GetToolsCount();
6959 ArrayOfPlugInToolbarTools tool_array =
6962 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6964 if (pttc->position == n_tools) {
6965 wxBitmap *ptool_bmp;
6967 switch (global_color_scheme) {
6968 case GLOBAL_COLOR_SCHEME_DAY:
6969 ptool_bmp = pttc->bitmap_day;
6972 case GLOBAL_COLOR_SCHEME_DUSK:
6973 ptool_bmp = pttc->bitmap_dusk;
6975 case GLOBAL_COLOR_SCHEME_NIGHT:
6976 ptool_bmp = pttc->bitmap_night;
6979 ptool_bmp = pttc->bitmap_day;
6984 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6986 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6987 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6988 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6989 tic->m_bPlugin =
true;
6998 while (CheckAndAddPlugInTool()) {
7004bool MyFrame::AddDefaultPositionPlugInTools() {
7011 ArrayOfPlugInToolbarTools tool_array =
7014 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7018 if (!pttc->b_viz)
continue;
7020 if (pttc->position == -1)
7022 wxBitmap *ptool_bmp;
7024 switch (global_color_scheme) {
7025 case GLOBAL_COLOR_SCHEME_DAY:
7026 ptool_bmp = pttc->bitmap_day;
7028 case GLOBAL_COLOR_SCHEME_DUSK:
7029 ptool_bmp = pttc->bitmap_dusk;
7031 case GLOBAL_COLOR_SCHEME_NIGHT:
7032 ptool_bmp = pttc->bitmap_night;
7035 ptool_bmp = pttc->bitmap_day;
7040 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7042 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7043 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7044 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7045 tic->m_bPlugin =
true;
7060wxColour GetGlobalColor(wxString colorName);
7062static const char *usercolors[] = {
7069 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7070 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7071 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7072 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7073 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7077 "UWHIT; 255;255;255;",
7080 "COMPT; 245;247;244",
7084 "DILG0; 255;255;255;",
7086 "DILG0; 238;239;242;",
7088 "DILG1; 212;208;200;",
7089 "DILG2; 255;255;255;",
7101 "CHGRF; 163; 180; 183;",
7103 "CHYLW; 244; 218; 72;",
7104 "CHWHT; 212; 234; 238;",
7107 "UINFM; 197; 69; 195;",
7109 "UINFG; 104; 228; 86;",
7111 "UINFR; 241; 84; 105;",
7112 "UINFF; 125; 137; 140;",
7116 "UDKRD; 124; 16; 0;",
7118 "UARTE; 200; 0; 0;",
7121 "NODTA; 163; 180; 183;",
7123 "SNDG1; 125; 137; 140;",
7125 "SCLBR; 235; 125; 54;",
7128 "UIBDR; 125; 137; 140;",
7129 "UIBCK; 212; 234; 238;",
7130 "UINFB; 58; 120; 240;",
7133 "UINFO; 235; 125; 54;",
7136 "PLRTE; 220; 64; 37;",
7137 "CHMGD; 197; 69; 195;",
7141 "DASHB; 255;255;255;",
7142 "DASHL; 175;175;175;",
7143 "DASHF; 50; 50; 50;",
7144 "DASHR; 200; 0; 0;",
7146 "DASHN; 200;120; 0;",
7147 "DASH1; 204;204;255;",
7148 "DASH2; 122;131;172;",
7149 "COMP1; 211;211;211;",
7152 "GREY3; 40; 40; 40;",
7153 "BLUE4; 100;100;200;",
7154 "VIO01; 171; 33;141;",
7155 "VIO02; 209;115;213;",
7156 "BLUEBACK; 212;234;238;",
7157 "LANDBACK; 201;185;122;",
7163 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7164 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7165 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7166 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7167 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7168 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7169 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7171 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7172 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7173 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7175 "DILG0; 110;110;110;",
7176 "DILG1; 110;110;110;",
7178 "DILG3; 130;130;130;",
7180 "UITX1; 41; 46; 46;",
7183 "UARTE; 64; 64; 64;",
7185 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7186 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7187 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7188 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7190 "DASHB; 77; 77; 77;",
7191 "DASHL; 54; 54; 54;",
7193 "DASHR; 58; 21; 21;",
7194 "DASHG; 21; 58; 21;",
7195 "DASHN; 100; 50; 0;",
7196 "DASH1; 76; 76;113;",
7197 "DASH2; 48; 52; 72;",
7198 "COMP1; 107;107;107;",
7200 "GREY3; 20; 20; 20;",
7201 "BLUE4; 80; 80;160;",
7202 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7203 "LANDBACK; 201;185;122;",
7209 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7210 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7211 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7212 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7213 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7214 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7215 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7216 "DILG0; 80; 80; 80;",
7217 "DILG1; 80; 80; 80;",
7219 "DILG3; 65; 65; 65;",
7220 "DILG4; 220;220;220;",
7221 "UITX1; 31; 34; 35;",
7224 "UARTE; 64; 64; 64;",
7226 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7227 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7228 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7230 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7231 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7232 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7233 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7236 "DASHL; 20; 20; 20;",
7237 "DASHF; 64; 64; 64;",
7238 "DASHR; 70; 15; 15;",
7239 "DASHG; 15; 70; 15;",
7240 "DASHN; 17; 80; 56;",
7241 "DASH1; 48; 52; 72;",
7242 "DASH2; 36; 36; 53;",
7243 "COMP1; 24; 24; 24;",
7245 "GREY3; 10; 10; 10;",
7246 "BLUE4; 70; 70;140;",
7247 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7248 "LANDBACK; 201;185;122;",
7252int get_static_line(
char *d,
const char **p,
int index,
int n) {
7253 if (!strcmp(p[index],
"*****"))
return 0;
7255 strncpy(d, p[index], n);
7259void InitializeUserColors() {
7260 const char **p = usercolors;
7268 UserColorTableArray =
new wxArrayPtrVoid;
7269 UserColourHashTableArray =
new wxArrayPtrVoid;
7273 ct->tableName =
new wxString(
"DAY");
7274 ct->color =
new wxArrayPtrVoid;
7275 UserColorTableArray->Add((
void *)ct);
7278 ct->tableName =
new wxString(
"DUSK");
7279 ct->color =
new wxArrayPtrVoid;
7280 UserColorTableArray->Add((
void *)ct);
7283 ct->tableName =
new wxString(
"NIGHT");
7284 ct->color =
new wxArrayPtrVoid;
7285 UserColorTableArray->Add((
void *)ct);
7287 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7288 if (!strncmp(buf,
"Table", 5)) {
7289 sscanf(buf,
"Table:%s", TableName);
7291 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7292 ctp = (colTable *)(UserColorTableArray->Item(it));
7293 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7302 while (buf[j] !=
';' && j < 20) {
7308 S52color *c =
new S52color;
7309 strcpy(c->colName, name);
7311 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7324 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7325 wxColorHashMap *phash =
new wxColorHashMap;
7326 UserColourHashTableArray->Add((
void *)phash);
7328 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7330 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7331 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7333 wxColour c(c2->R, c2->G, c2->B);
7334 wxString key(c2->colName, wxConvUTF8);
7342 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7345void DeInitializeUserColors() {
7346 if (!UserColorTableArray)
return;
7347 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7348 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7350 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7351 S52color *c = (S52color *)ct->color->Item(j);
7355 delete ct->tableName;
7361 delete UserColorTableArray;
7363 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7364 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7368 delete UserColourHashTableArray;
7375typedef struct _MSW_COLOR_SPEC {
7377 wxString S52_RGB_COLOR;
7381MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7382 {COLOR_MENUTEXT,
"UITX1", 0},
7383 {COLOR_BTNSHADOW,
"UIBCK", 0},
7386void SaveSystemColors() {
7400 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7401 while (pcspec->COLOR_NAME != -1) {
7402 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7407void RestoreSystemColors() {
7408 int element[NCOLORS];
7409 int rgbcolor[NCOLORS];
7412 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7413 while (pcspec->COLOR_NAME != -1) {
7414 element[i] = pcspec->COLOR_NAME;
7415 rgbcolor[i] = pcspec->SysRGB_COLOR;
7421 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7426void SetSystemColors(ColorScheme cs) {
7428 int element[NCOLORS];
7429 int rgbcolor[NCOLORS];
7431 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7432 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7433 while (pcspec->COLOR_NAME != -1) {
7434 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7435 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7436 element[i] = pcspec->COLOR_NAME;
7442 pSetSysColors(i, (
unsigned long *)&element[0],
7443 (
unsigned long *)&rgbcolor[0]);
7447 RestoreSystemColors();
7452wxColor GetDimColor(wxColor c) {
7453 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7454 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7458 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7459 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7461 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7462 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7463 hsv.value = hsv.value * factor;
7464 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7466 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7472double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7473 double const AnchorPointMaxDist)
7476 if (d < AnchorPointMinDist)
7477 return AnchorPointMinDist;
7478 else if (d > AnchorPointMaxDist)
7479 return AnchorPointMaxDist;
7485 if (d > -AnchorPointMinDist)
7486 return -AnchorPointMinDist;
7487 else if (d < -AnchorPointMaxDist)
7488 return -AnchorPointMaxDist;
7495static const WORD MAX_CONSOLE_LINES =
7500void RedirectIOToConsole()
7505 wxIntPtr lStdHandle;
7507 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7517 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7518 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7519 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7523 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7524 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7525 fp = _fdopen(hConHandle,
"w");
7527 setvbuf(stdout, NULL, _IONBF, 0);
7531 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7532 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7533 fp = _fdopen(hConHandle,
"r");
7535 setvbuf(stdin, NULL, _IONBF, 0);
7539 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7540 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7541 fp = _fdopen(hConHandle,
"w");
7543 setvbuf(stderr, NULL, _IONBF, 0);
7555bool TestGLCanvas(wxString prog_dir) {
7557 wxString test_app = prog_dir;
7558 test_app +=
"ocpn_gltest1.exe";
7560 if (::wxFileExists(test_app)) {
7561 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7562 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7563 if (proc_return == 0)
7564 printf(
"GLCanvas OK\n");
7566 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7568 return (proc_return == 0);
7578bool ReloadLocale() {
7583 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7590 FontMgr::Get().SetLocale(g_locale);
7604 if (pRouteManagerDialog) {
7605 pRouteManagerDialog->Hide();
7606 pRouteManagerDialog->Destroy();
7607 pRouteManagerDialog = NULL;
7611 if (g_pais_query_dialog_active) {
7612 g_pais_query_dialog_active->Destroy();
7613 g_pais_query_dialog_active = NULL;
7616 auto alert_dlg_active =
7618 if (alert_dlg_active) {
7619 alert_dlg_active->Destroy();
7620 g_pais_alert_dialog_active =
nullptr;
7623 if (g_pAISTargetList) {
7625 g_pAISTargetList->Disconnect_decoder();
7626 g_pAISTargetList->Destroy();
7627 g_pAISTargetList = NULL;
7631 if (gFrame->m_pMenuBar) {
7632 gFrame->SetMenuBar(NULL);
7633 gFrame->m_pMenuBar->Destroy();
7634 gFrame->m_pMenuBar = NULL;
7636 gFrame->BuildMenuBar();
7639 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7641 if (cc) cc->CanvasApplyLocale();
7646 wxString perspective;
7647 pConfig->SetPath(
"/AUI");
7648 pConfig->Read(
"AUIPerspective", &perspective);
7662 bool bno_load =
false;
7663 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7665 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7666 wxAuiPaneInfo pane = pane_array_val[i];
7667 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7673 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7678 gFrame->RequestNewToolbars(
true);
7679 gFrame->RequestNewMasterToolbar(
true);
7696 g_csv_locn = g_Platform->GetSharedDataDir();
7697 g_csv_locn.Append(
"s57data");
7701 appendOSDirSlash(&g_csv_locn);
7702 g_csv_locn.Append(
"s57data");
7707 if (g_SENCPrefix.IsEmpty()) {
7709 appendOSDirSlash(&g_SENCPrefix);
7710 g_SENCPrefix.Append(
"SENC");
7714 wxFileName f(g_SENCPrefix);
7716 g_SENCPrefix = f.GetFullPath();
7718 g_SENCPrefix =
"SENC";
7724 bool b_force_legacy =
false;
7726 if (g_UserPresLibData.IsEmpty()) {
7727 plib_data = g_csv_locn;
7728 appendOSDirSlash(&plib_data);
7729 plib_data.Append(
"S52RAZDS.RLE");
7731 plib_data = g_UserPresLibData;
7732 b_force_legacy =
true;
7735 ps52plib =
new s52plib(plib_data, b_force_legacy);
7750 if (!ps52plib->m_bOK) {
7753 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7755 wxString look_data_dir;
7756 look_data_dir.Append(std_path.GetUserDataDir());
7757 appendOSDirSlash(&look_data_dir);
7758 wxString tentative_SData_Locn = look_data_dir;
7759 look_data_dir.Append(
"s57data");
7761 plib_data = look_data_dir;
7762 appendOSDirSlash(&plib_data);
7763 plib_data.Append(
"S52RAZDS.RLE");
7765 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7766 ps52plib =
new s52plib(plib_data);
7768 if (ps52plib->m_bOK) {
7769 g_csv_locn = look_data_dir;
7778 if (!ps52plib->m_bOK) {
7781 wxString look_data_dir;
7782 look_data_dir = g_Platform->GetSharedDataDir();
7783 look_data_dir.Append(
"s57data");
7785 plib_data = look_data_dir;
7786 appendOSDirSlash(&plib_data);
7787 plib_data.Append(
"S52RAZDS.RLE");
7789 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7790 ps52plib =
new s52plib(plib_data);
7792 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7795 if (ps52plib->m_bOK) {
7796 wxLogMessage(
"Using s57data in " + g_csv_locn);
7798 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7803 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7805 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7806 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7807 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7808 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7811 pConfig->LoadS57Config();
7812 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7818 ps52plib->SetDIPFactor(dip_factor);
7823 ps52plib->SetScaleFactorExp(
7824 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7825 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7832 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7833 ps52plib->SetGLRendererString(renderer);
7836 ps52plib->SetGLOptions(
7837 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7838 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7839 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7844 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7853 : wxThread(wxTHREAD_JOINABLE) {
7854 m_filename = filename;
7865 newChart->SetNativeScale(m_scale);
7866 newChart->SetFullExtent(m_ext);
7868 newChart->FindOrCreateSenc(m_filename);
7873 wxString m_filename;
7879static double chart_dist(
int index) {
7885 if (cte.GetBBox().Contains(
gLat,
gLon))
7890 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7891 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7892 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7895 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7896 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7898 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7904WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7905static int CompareInts(
int n1,
int n2) {
7906 double d1 = chart_dist(n1);
7907 double d2 = chart_dist(n2);
7908 return (
int)(d1 - d2);
7913 wxString chart_path;
7918WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7920#include <wx/arrimpl.cpp>
7923void ParseAllENC(wxWindow *parent) {
7924 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7932 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7935 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7937 idx_sorted_by_distance.Add(i);
7941 if (count == 0)
return;
7943 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7949 ArrayOfCompressTargets ct_array;
7950 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7951 int i = idx_sorted_by_distance[j];
7954 double distance = chart_dist(i);
7956 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7959 pct->distance = distance;
7960 pct->chart_path = filename;
7962 ct_array.push_back(pct);
7965 int thread_count = 0;
7968 if (g_nCPUCount > 0)
7969 thread_count = g_nCPUCount;
7971 thread_count = wxThread::GetCPUCount();
7973 if (thread_count < 1) {
7982 for(
int t = 0; t < thread_count; t++)
7986 wxGenericProgressDialog *prog =
nullptr;
7990 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7991 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7993 prog =
new wxGenericProgressDialog();
7995 prog->SetFont(*qFont);
7997 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7998 count + 1, parent, style);
8007 prog->ShowWindowModal();
8016 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8017 wxString filename = ct_array[j].chart_path;
8018 double distance = ct_array[j].distance;
8019 int index =
ChartData->FinddbIndex(filename);
8020 if (index < 0)
continue;
8023 ext.NLAT = cte.GetLatMax();
8024 ext.SLAT = cte.GetLatMin();
8025 ext.WLON = cte.GetLonMin();
8026 ext.ELON = cte.GetLonMax();
8028 int scale = cte.GetScale();
8031 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8034 if (wxThread::IsMain()) {
8036 wxSize sz = prog->GetSize();
8041 prog->Update(count, msg, &skip);
8053 newChart->SetNativeScale(
scale);
8054 newChart->SetFullExtent(ext);
8055 newChart->DisableBackgroundSENC();
8057 newChart->FindOrCreateSenc(filename,
8061 if (wxThread::IsMain()) {
8062 msg.Printf(_(
"ENC Completed."));
8064 prog->Update(count, msg, &skip);
8074 for (
int t = 0;; t = (t + 1) % thread_count) {
8081 if (!workers[t]->IsAlive()) {
8094#if defined(__WXMSW__) || defined(__WXOSX__)
8101 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.
void MakeLoopbackDriver()
Create and register the loopback driver.
void MakeCommDriver(const ConnectionParams *params)
Create and register a driver for given connection.
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.