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_ulLastNMEATicktime = 0;
548 m_data_monitor->Hide();
550 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
554 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
557 InitTimer.SetOwner(
this, INIT_TIMER);
559 m_initializing =
false;
562 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
565 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
568 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
571 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
574 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
576 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
585 m_bTimeIsSet =
false;
588 m_bdefer_resize =
false;
591 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
592 COGFilterTable[i] = NAN;
593 SOGFilterTable[i] = NAN;
595 m_last_bGPSValid =
false;
596 m_last_bVelocityValid =
false;
606 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
611 double process_noise_std = 1.0;
612 double measurement_noise_std = 0.5;
614 m_ChartUpdatePeriod = 1;
619 log_callbacks.log_is_active = [&]() {
620 auto log = GetDataMonitor();
621 return log && log->IsVisible();
623 log_callbacks.log_message = [&](
Logline ll) {
624 NmeaLog *monitor = GetDataMonitor();
627 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
630 ais_callbacks.confirm_stop_track = []() {
631 int r = OCPNMessageBox(
633 _(
"This AIS target has Persistent tracking selected by MMSI "
635 "A Persistent track recording will therefore be restarted for this "
637 "Do you instead want to stop Persistent tracking for this target?"),
638 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
639 return r == wxID_YES;
641 ais_callbacks.get_target_mmsi = []() {
642 auto alert_dlg_active =
644 assert(alert_dlg_active);
645 return alert_dlg_active->Get_Dialog_MMSI();
653 wxLogMessage(
" **** Connect stuff");
659 Connect(wxEVT_OCPN_MSG,
660 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
668 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
676#if defined(__WXGTK__) || defined(__WXQT__)
677 wxIcon app_icon(opencpn);
685 wxDynamicLibrary dllUser32(
"user32.dll");
687 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
688 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
693 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
698 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
699 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
701 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
703 [&](wxCommandEvent) { Refresh(); });
704 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
706 m_update_statusbar_listener.Init(
707 GuiEvents::GetInstance().gframe_update_status_bar,
709 m_center_aistarget_listener.Init(
710 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
711 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
712 CenterAisTarget(ais_target);
717 EnableFullScreenView();
719 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
725 FrameTenHzTimer.Stop();
740 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
746void MyFrame::FreezeCharts() {
749 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
751 if (cc && !cc->IsFrozen()) cc->Freeze();
755void MyFrame::CenterAisTarget(
756 const std::shared_ptr<const AisTargetData> &ais_target) {
764 double factor = cc->GetScaleValue() / 5000.0;
765 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
771void MyFrame::ThawCharts() {
774 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
776 if (cc && cc->IsFrozen()) cc->Thaw();
783 switch (event.type) {
784 case SENC_BUILD_STARTED:
787 case SENC_BUILD_DONE_NOERROR:
789 chart =
event.m_ticket->m_chart;
791 chart->PostInit(FULL_INIT, global_color_scheme);
793 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
795 if (cc) cc->ClearS52PLIBStateHash();
800 delete event.m_ticket;
802 case SENC_BUILD_DONE_ERROR:
810void MyFrame::RebuildChartDatabase() {
811 bool b_SetInitialPoint =
false;
814 ArrayOfCDI ChartDirArray;
815 pConfig->LoadChartDirArray(ChartDirArray);
817 if (ChartDirArray.GetCount()) {
822 _(
"OpenCPN needs to update the chart database from config file "
826 wxICON_INFORMATION | wxOK);
834 _(
"Rebuilding chart database from configuration file entries..."));
838 wxString dummy1 = _(
"Elapsed time : ");
839 wxString dummy2 = _(
"Estimated time : ");
840 wxString dummy3 = _(
"Remaining time : ");
841 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
842 _(
"OpenCPN Chart Update"), line, 100, NULL,
843 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
844 wxPD_REMAINING_TIME);
847 ChartData->SaveBinary(ChartListFileName);
857void MyFrame::OnBellsFinished(wxCommandEvent &event) {
858 int bells = wxMin(m_BellsToPlay, 2);
859 if (bells <= 0)
return;
861 wxString soundfile =
"sounds";
862 appendOSDirSlash(&soundfile);
863 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
864 soundfile.Prepend(g_Platform->GetSharedDataDir());
865 wxLogMessage(
"Using bells sound file: " + soundfile);
867 o_sound::Sound *sound = bells_sound[bells - 1];
868 sound->SetFinishedCallback(onBellsFinishedCB,
this);
869 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
870 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
871 sound->Load(soundfile);
872 if (!sound->IsOk()) {
873 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
877 m_BellsToPlay -= bells;
880void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
882void MyFrame::OnMaximize(wxMaximizeEvent &event) {
889ColorScheme GetColorScheme() {
return global_color_scheme; }
891ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
893void MyFrame::ReloadAllVP() {
894 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
896 if (cc) cc->ReloadVP();
900void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
901 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
904 global_color_scheme = cs;
907 case GLOBAL_COLOR_SCHEME_DAY:
910 case GLOBAL_COLOR_SCHEME_DUSK:
913 case GLOBAL_COLOR_SCHEME_NIGHT:
914 SchemeName =
"NIGHT";
921 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
923 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
924 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
925 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
926 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
927 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
929 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
958 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
959 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
963 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
966 unsigned Usercolortable_index = 0;
967 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
968 colTable *ct = (colTable *)UserColorTableArray->Item(i);
969 if (SchemeName.IsSameAs(*ct->tableName)) {
970 Usercolortable_index = i;
975 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
979 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
984 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
987 cc->SetColorScheme(cs);
988 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
989 cc->HideChartInfoWindow();
990 cc->SetQuiltChartHiLiteIndex(-1);
996 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1008 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1021 if (g_pais_query_dialog_active) {
1022 bool b_isshown = g_pais_query_dialog_active->IsShown();
1023 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1024 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1026 g_pais_query_dialog_active->Close();
1029 g_pais_query_dialog_active->
Create(
1030 this, -1, _(
"AIS Target Query"),
1031 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1032 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1033 g_pais_query_dialog_active->UpdateText();
1034 if (b_isshown) g_pais_query_dialog_active->Show();
1037 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1039 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1043 ApplyGlobalColorSchemetoStatusBar();
1045 UpdateAllToolbars(cs);
1050 bool btoolbarFull = g_bmasterToolbarFull;
1056 if (!btoolbarFull) {
1058 RequestNewMasterToolbar();
1060 CollapseGlobalToolbar();
1063 RequestNewMasterToolbar();
1072void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1073 if (m_pStatusBar != NULL) {
1074 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1075 m_pStatusBar->ClearBackground();
1080 if (g_canvasArray.GetCount() > 0)
1081 return g_canvasArray.Item(0);
1085void MyFrame::CancelAllMouseRoute() {
1087 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1089 if (cc) cc->CancelMouseRoute();
1093void MyFrame::NotifyChildrenResize() {}
1095void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1103 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1111 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1120 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1123 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1124 config_array.Item(i)->canvas = NULL;
1130 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1131 g_canvasArray.RemoveAt(i);
1135 switch (g_canvasConfig) {
1138 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1141 g_canvasArray.Add(cc);
1143 cc = g_canvasArray[0];
1149 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1150 cc->GetglCanvas()->Show();
1153 config_array.Item(0)->canvas = cc;
1157 cc->ApplyCanvasConfig(config_array.Item(0));
1161 cc->ConfigureChartBar();
1162 cc->SetColorScheme(global_color_scheme);
1163 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1164 cc->SetShowGPS(
true);
1167 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1169 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1175 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1177 g_canvasArray.Add(cc);
1179 cc = g_canvasArray[0];
1185 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1188 config_array.Item(0)->canvas = cc;
1190 cc->ApplyCanvasConfig(config_array.Item(0));
1193 cc->ConfigureChartBar();
1194 cc->SetColorScheme(global_color_scheme);
1195 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1196 cc->SetShowGPS(
false);
1199 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1201 .CaptionVisible(
false)
1203 .CloseButton(
false);
1208 g_canvasArray.Add(cc);
1212 if (config_array.GetCount() < 2) {
1214 pcc->configIndex = 1;
1218 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1219 config_array.Add(pcc);
1222 config_array.Item(1)->canvas = cc;
1224 cc->ApplyCanvasConfig(config_array.Item(1));
1227 cc->ConfigureChartBar();
1228 cc->SetColorScheme(global_color_scheme);
1229 cc->SetShowGPS(
true);
1233 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1235 .CaptionVisible(
false)
1237 .CloseButton(
false);
1238 g_pauimgr->GetPane(cc).RightDockable(
true);
1242 config_array.Item(1)->canvasSize =
1243 wxSize(GetClientSize().x / 2, GetClientSize().y);
1244 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1249 if (b_useStoredSize) {
1250 int ccw = config_array.Item(1)->canvasSize.x;
1251 int cch = config_array.Item(1)->canvasSize.y;
1254 if (ccw < GetClientSize().x / 10) {
1255 ccw = GetClientSize().x / 2;
1256 cch = GetClientSize().y;
1259 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1260 cc->SetSize(ccw, cch);
1274 if (g_canvasArray.size() > 1)
1278 console->SetColorScheme(global_color_scheme);
1283 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1289void MyFrame::RequestNewToolbars(
bool bforcenew) {
1290 if (b_inCloseWindow) {
1294 BuildiENCToolbar(bforcenew);
1295 PositionIENCToolbar();
1304void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1310void MyFrame::SetAllToolbarScale() {
1311 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1314void MyFrame::SetGPSCompassScale() {
1315 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1319 wxPoint screenPoint = ::wxGetMousePosition();
1322 switch (g_canvasConfig) {
1324 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1327 if (canvas->GetScreenRect().Contains(
1331 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1334 if (canvas->GetScreenRect().Contains(
1341 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1344 if (canvas->GetScreenRect().Contains(
1345 canvas->ScreenToClient(screenPoint)))
1353int MyFrame::GetCanvasIndexUnderMouse() {
1354 wxPoint screenPoint = ::wxGetMousePosition();
1357 switch (g_canvasConfig) {
1359 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1362 if (canvas->GetScreenRect().Contains(
1366 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1369 if (canvas->GetScreenRect().Contains(
1376 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1379 if (canvas->GetScreenRect().Contains(
1380 canvas->ScreenToClient(screenPoint)))
1388bool MyFrame::DropMarker(
bool atOwnShip) {
1395 if (!canvas)
return false;
1402 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1404 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1406 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1411 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1412 pRouteManagerDialog->UpdateWptListCtrl();
1417 RefreshAllCanvas(
false);
1422void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1423 if (g_canvasConfig != 0) {
1426 int nTargetGTK = -1;
1428 wxWindow *source = FindFocus();
1434 switch (g_canvasConfig) {
1436 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1439 if (canvas && (canvas == test)) {
1444 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1447 if (canvas && (canvas == test)) {
1455 int nfinalTarget = nTarget;
1457 nfinalTarget = nTargetGTK;
1459 target = ConfigMgr::Get()
1460 .GetCanvasConfigArray()
1465 target->Refresh(
true);
1476void MyFrame::FastClose() {
1478 FrameTenHzTimer.Stop();
1480 FrameTimer1.Start(1);
1484void MyFrame::OnExit(wxCommandEvent &event) {
1488void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1491 if (b_inCloseWindow) {
1501 if (!g_bDeferredInitDone)
return;
1518 if (bDBUpdateInProgress)
return;
1520 b_inCloseWindow =
true;
1522 ::wxSetCursor(wxCURSOR_WAIT);
1526 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1528 if (cc && cc->IsMeasureActive()) {
1529 cc->CancelMeasureRoute();
1534 SendPreShutdownHookToPlugins();
1538 if (g_pAISTargetList) {
1539 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1540 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1541 g_pauimgr->DetachPane(g_pAISTargetList);
1552 pConfig->SetPath(
"/AUI");
1553 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1568 SetCursor(wxCURSOR_WAIT);
1570 RefreshAllCanvas(
true);
1576 RestoreScreenBrightness();
1587 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1588 g_iENCToolbarPosY = tbp_incanvas.y;
1589 g_iENCToolbarPosX = tbp_incanvas.x;
1593 g_bframemax = IsMaximized();
1596 FrameTenHzTimer.Stop();
1598 FrameCOGTimer.Stop();
1612 if (g_bAutoAnchorMark) {
1613 bool watching_anchor =
false;
1621 wxDateTime now = wxDateTime::Now();
1622 wxTimeSpan uptime = now.Subtract(g_start_time);
1624 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1625 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1630 if (g_declutter_anchorage) {
1631 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1632 if (pr->GetName().StartsWith(
"Anchorage")) {
1633 double a =
gLat - pr->m_lat;
1634 double b =
gLon - pr->m_lon;
1635 double l = sqrt((a * a) + (b * b));
1638 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1640 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1641 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1649 wxString name = now.Format();
1650 name.Prepend(_(
"Anchorage created "));
1656 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1661 pConfig->UpdateSettings();
1665 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1669 NavObj_dB::GetInstance().Close();
1673 pConfig->DeleteGroup(
"/Routes");
1674 pConfig->DeleteGroup(
"/Marks");
1700 if (g_pAISTargetList) {
1701 g_pAISTargetList->Disconnect_decoder();
1702 g_pAISTargetList->Destroy();
1709 if (RouteManagerDialog::getInstanceFlag()) {
1710 if (pRouteManagerDialog) {
1711 pRouteManagerDialog->Destroy();
1712 pRouteManagerDialog = NULL;
1726 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1728 if (cc) cc->Destroy();
1731 g_canvasArray.Clear();
1752 MyApp &app = wxGetApp();
1753 app.m_comm_bridge.SaveConfig();
1773 auto ®istry = CommDriverRegistry::GetInstance();
1774 registry.CloseAllDrivers();
1777 for (
auto *cp : TheConnectionParams()) {
1782 while (pLayerList->size())
delete *pLayerList->begin();
1786 ReleaseApiListeners();
1789 g_bTempShowMenuBar =
false;
1791#define THREAD_WAIT_SECONDS 5
1801 wxLogMessage(
"Starting compressor pool drain");
1802 wxDateTime now = wxDateTime::Now();
1803 time_t stall = now.GetTicks();
1804 time_t end = stall + THREAD_WAIT_SECONDS;
1807 while (stall < end) {
1808 wxDateTime later = wxDateTime::Now();
1809 stall = later.GetTicks();
1812 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1821 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1827 uninitIXNetSystem();
1831 wxLogMessage(
"gFrame destroyed.");
1834#ifndef USE_ANDROID_GLES2
1835 qDebug() <<
"Calling OnExit()";
1839 wxTheApp->ExitMainLoop();
1842void MyFrame::OnMove(wxMoveEvent &event) {
1843 auto idx = wxDisplay::GetFromWindow(
this);
1856 DEBUG_LOG <<
"Moved to " << idx
1857#if wxCHECK_VERSION(3, 1, 6)
1858 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1859 << wxDisplay(idx).GetPPI().GetY()
1860 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1862 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1863 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1864 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1865 << wxGetDisplaySizeMM().GetY()
1866 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1875 if (g_config_display_size_manual) {
1884 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1887 cc->SetMUIBarPosition();
1896 UpdateGPSCompassStatusBoxes();
1906 PositionIENCToolbar();
1912 g_nframewin_posx = GetPosition().x;
1913 g_nframewin_posy = GetPosition().y;
1916void MyFrame::ProcessCanvasResize() {
1917 UpdateGPSCompassStatusBoxes(
true);
1921 PositionIENCToolbar();
1924 TriggerRecaptureTimer();
1928void MyFrame::TriggerRecaptureTimer() {
1929 m_recaptureTimer.Start(
1930 1000, wxTIMER_ONE_SHOT);
1933void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1935void MyFrame::SetCanvasSizes(wxSize frameSize) {
1936 if (!g_canvasArray.GetCount())
return;
1939 int cccw = frameSize.x;
1940 int ccch = frameSize.y;
1944 switch (g_canvasConfig) {
1948 cc = g_canvasArray.Item(0);
1950 cc->GetSize( &cur_width, &cur_height );
1951 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1953 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1955 cc->SetSize( 0, 0, cccw, ccch );
1963 cc = g_canvasArray.Item(1);
1965 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1966 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1968 ccw = wxMin(ccw, cccw * 8 / 10);
1969 ccw = wxMax(ccw, cccw * 2 / 10);
1973 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1980 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1997void MyFrame::OnIconize(wxIconizeEvent &event) {
2007 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2009 if (cc && cc->GetMUIBar()) {
2010 if (cc->GetMUIBar()->GetCanvasOptions()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2012 cc->GetMUIBar()->PushCanvasOptions();
2021void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2023void MyFrame::ODoSetSize() {
2025 GetClientSize(&x, &y);
2028 if (m_pStatusBar != NULL) {
2029 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2030 int currentCount = m_pStatusBar->GetFieldsCount();
2031 if (currentCount != m_StatusBarFieldCount) {
2032 if ((currentCount > 0) && (currentCount < 7)) {
2035 int widths[] = {2, 2, 2, 2, 2, 2};
2036 m_pStatusBar->SetStatusWidths(currentCount, widths);
2039 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2042 if (m_StatusBarFieldCount) {
2047 if (m_StatusBarFieldCount > 2) {
2048 int widths[] = {-6, -5, -5, -6, -4};
2049 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2050 }
else if (m_StatusBarFieldCount == 2) {
2051 int cwidth = x * 90 / 100;
2052 int widths[] = {100, 100};
2053 widths[0] = cwidth * 6.4 / 10.0;
2054 widths[1] = cwidth * 3.6 / 10.0;
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2057 int widths[] = {100, 100};
2058 widths[0] = x * 90 / 100;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2062 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2063 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2064 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2066 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2068 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2076 m_pStatusBar->GetFieldRect(0, stat_box);
2079 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2081 wxFont sys_font = *wxNORMAL_FONT;
2082 int try_font_size = sys_font.GetPointSize();
2085 int min_font_size = 10;
2095 wxFont *statusBarFont =
2096 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2097 int font_size = statusBarFont->GetPointSize();
2099 font_size = wxMin(font_size,
2102 wxMax(font_size, min_font_size);
2105 font_size = statusBarFont->GetPointSize();
2112 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2113 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2115 int min_height = stat_box.height;
2117 m_pStatusBar->SetFont(*pstat_font);
2118 m_pStatusBar->SetForegroundColour(
2119 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2121 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2123 (min_height >> 1) * 2;
2124 m_pStatusBar->SetMinHeight(min_height);
2133 SetCanvasSizes(GetClientSize());
2135 UpdateGPSCompassStatusBoxes(
true);
2137 if (
console) PositionConsole();
2140 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2142 if (cc) cc->FormatPianoKeys();
2148 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2149 GetPrimaryCanvas()->GetCompass()->GetRect());
2175 options_lastWindowSize = wxSize(0, 0);
2176 options_lastWindowPos = wxPoint(0, 0);
2183 if (!b_inCloseWindow) {
2186 resizeAndroidPersistents();
2190 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2191 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2197void MyFrame::PositionConsole() {
2198#if defined(__WXMSW__) || defined(__WXMAC__)
2199 if (NULL == GetPrimaryCanvas())
return;
2201 int ccx, ccy, ccsx, ccsy, consx, consy;
2203 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2206 consoleHost->GetSize(&ccsx, &ccsy);
2207 consoleHost->GetPosition(&ccx, &ccy);
2209 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2210 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2211 consoleHost = GetPrimaryCanvas();
2216 if (consoleHost->GetCompass()) {
2217 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2219 if (compass_rect.y < 100)
2220 yOffset = compass_rect.y + compass_rect.height + 45;
2224 wxSize csz =
console->GetSize();
2228 wxPoint screen_pos =
2229 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2232 if (NULL == GetPrimaryCanvas())
return;
2234 int ccx, ccy, ccsx, ccsy, consx, consy;
2236 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2239 consoleHost->GetSize(&ccsx, &ccsy);
2240 consoleHost->GetPosition(&ccx, &ccy);
2242 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2243 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2244 consoleHost = GetPrimaryCanvas();
2247 int yTopOffset = 60;
2248 int yBottomOffset = 0;
2250 if (consoleHost->GetCompass()) {
2251 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2253 if (compass_rect.y < 100)
2254 yTopOffset = compass_rect.y + compass_rect.height;
2256 if (consoleHost->GetMUIBar()) {
2257 wxRect mui_rect = consoleHost->GetMUIBarRect();
2258 yBottomOffset = ccsy - mui_rect.y;
2262 wxSize csz =
console->GetSize();
2265 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2267 if (consy < yAvail) {
2268 yFinal = (yAvail - consy) / 2;
2269 yFinal += yTopOffset;
2270 }
else if (
console->GetCDI()->IsShown()) {
2271 int cdi_height =
console->GetCDI()->GetSize().y;
2272 int consy_no_cdi = consy - cdi_height;
2273 yFinal = (yAvail - consy_no_cdi) / 2;
2274 yFinal += yTopOffset;
2278 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2283void MyFrame::UpdateAllFonts() {
2292 DestroyPersistentDialogs();
2294 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2299void MyFrame::DestroyPersistentDialogs() {
2300 if (g_pais_query_dialog_active) {
2301 g_pais_query_dialog_active->Hide();
2302 g_pais_query_dialog_active->Destroy();
2303 g_pais_query_dialog_active = NULL;
2331void MyFrame::RefreshGroupIndices() {
2333 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2335 if (cc) cc->canvasRefreshGroupIndex();
2339void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2342 switch (event.GetId()) {
2343 case ID_MENU_SCALE_OUT:
2344 DoStackDelta(GetPrimaryCanvas(), 1);
2348 case ID_MENU_SCALE_IN:
2349 DoStackDelta(GetPrimaryCanvas(), -1);
2353 case ID_MENU_ZOOM_IN: {
2354 if (GetFocusCanvas()) {
2355 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2360 case ID_MENU_ZOOM_OUT: {
2361 if (GetFocusCanvas()) {
2362 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2367 case ID_MENU_ROUTE_NEW: {
2368 if (GetFocusCanvas()) {
2369 if (0 == GetFocusCanvas()->m_routeState) {
2370 GetFocusCanvas()->StartRoute();
2372 GetFocusCanvas()->FinishRoute();
2378 case ID_MENU_TOOL_MEASURE: {
2379 GetPrimaryCanvas()->StartMeasureRoute();
2383 case ID_MENU_TOOL_NMEA_DBG_LOG:
2384 m_data_monitor->Show();
2385 m_data_monitor->Raise();
2388 case ID_MENU_TOOL_IO_MONITOR:
2389 m_data_monitor->Show();
2392 case ID_MENU_MARK_BOAT: {
2397 case ID_MENU_MARK_CURSOR: {
2402 case ID_MENU_NAV_FOLLOW: {
2403 if (
gFrame->GetPrimaryCanvas())
2404 gFrame->GetPrimaryCanvas()->TogglebFollow();
2408 case ID_MENU_CHART_OUTLINES: {
2409 ToggleChartOutlines(GetFocusCanvas());
2413 case ID_MENU_CHART_QUILTING: {
2414 ToggleQuiltMode(GetFocusCanvas());
2418 case ID_MENU_UI_CHARTBAR: {
2419 ToggleChartBar(GetFocusCanvas());
2423 case ID_MENU_ENC_TEXT:
2425 ToggleENCText(GetFocusCanvas());
2428 case ID_MENU_ENC_LIGHTS: {
2429 ToggleLights(GetFocusCanvas());
2432 case ID_MENU_ENC_SOUNDINGS: {
2433 ToggleSoundings(GetFocusCanvas());
2436 case ID_MENU_ENC_ANCHOR: {
2437 ToggleAnchor(GetFocusCanvas());
2440 case ID_MENU_ENC_DATA_QUALITY: {
2441 ToggleDataQuality(GetFocusCanvas());
2444 case ID_MENU_SHOW_NAVOBJECTS: {
2445 ToggleNavobjects(GetFocusCanvas());
2449 case ID_MENU_AIS_TARGETS: {
2450 ToggleAISDisplay(GetFocusCanvas());
2453 case ID_MENU_AIS_MOORED_TARGETS: {
2454 g_bHideMoored = !g_bHideMoored;
2457 case ID_MENU_AIS_SCALED_TARGETS: {
2458 ToggleAISMinimizeTargets(GetFocusCanvas());
2462 case ID_MENU_AIS_TARGETLIST: {
2463 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2467 case ID_MENU_AIS_TRACKS: {
2468 g_bAISShowTracks = !g_bAISShowTracks;
2469 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2473 case ID_MENU_AIS_CPADIALOG: {
2474 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2475 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2476 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2477 if (g_bAIS_CPA_Alert) {
2478 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2483 case ID_MENU_AIS_CPASOUND: {
2484 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2485 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2489 case ID_MENU_AIS_CPAWARNING: {
2490 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2491 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2495 case wxID_PREFERENCES:
2502 case ID_SETTINGS_NEW: {
2507 case ID_SETTINGS_DELETE: {
2510 g_pOptions =
nullptr;
2514 case ID_RELOAD_CHARTS: {
2519 case ID_MENU_SETTINGS_BASIC: {
2522 androidDisableFullScreen();
2524 DoAndroidPreferences();
2531 case ID_MENU_UI_FULLSCREEN: {
2536 case ID_MENU_SHOW_CURRENTS: {
2537 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2538 GetFocusCanvas()->ReloadVP();
2539 GetFocusCanvas()->Refresh(
false);
2543 case ID_MENU_SHOW_TIDES: {
2544 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2545 GetFocusCanvas()->ReloadVP();
2546 GetFocusCanvas()->Refresh(
false);
2566 case ID_MENU_UI_COLSCHEME:
2567 case ID_COLSCHEME: {
2568 ToggleColorScheme();
2577 case ID_MENU_OQUIT: {
2582 case ID_MENU_ROUTE_MANAGER:
2583 case ID_ROUTEMANAGER: {
2584 pRouteManagerDialog = RouteManagerDialog::getInstance(
2587 if (pRouteManagerDialog->IsShown())
2588 pRouteManagerDialog->Hide();
2590 pRouteManagerDialog->UpdateRouteListCtrl();
2591 pRouteManagerDialog->UpdateTrkListCtrl();
2592 pRouteManagerDialog->UpdateWptListCtrl();
2593 pRouteManagerDialog->UpdateLayListCtrl();
2595 pRouteManagerDialog->Show();
2599 pRouteManagerDialog->Centre();
2600 pRouteManagerDialog->Raise();
2606 case ID_MENU_NAV_TRACK:
2608 if (!g_bTrackActive) {
2610 g_bTrackCarryOver =
true;
2613 g_bTrackCarryOver =
false;
2614 RefreshAllCanvas(
true);
2619 case ID_MENU_CHART_NORTHUP: {
2620 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2623 case ID_MENU_CHART_COGUP: {
2624 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2627 case ID_MENU_CHART_HEADUP: {
2628 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2632 case ID_MENU_MARK_MOB:
2638 case ID_MASTERTOGGLE: {
2640 wxString tip = _(
"Show Toolbar");
2641 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2643 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2645 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2648 if (g_bmasterToolbarFull)
2649 m_nMasterToolCountShown =
2653 m_nMasterToolCountShown = 2;
2655 m_nMasterToolCountShown =
2658 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2666 case ID_CMD_SELECT_CHART_TYPE: {
2667 selectChartDisplay(event.GetExtraLong(), -1);
2671 case ID_CMD_SELECT_CHART_FAMILY: {
2672 selectChartDisplay(-1, event.GetExtraLong());
2676 case ID_CMD_APPLY_SETTINGS: {
2677 applySettingsString(event.GetString());
2679 androidRestoreFullScreen();
2685 case ID_CMD_NULL_REFRESH: {
2690 case ID_CMD_SETVP: {
2691 setStringVP(event.GetString());
2695 case ID_CMD_INVALIDATE: {
2701 case ID_CMD_POST_JSON_TO_PLUGINS: {
2707 int numErrors = reader.
Parse(event.GetString(), &root);
2708 if (numErrors == 0) {
2709 if (root[
"MessageID"].IsString()) {
2710 wxString MsgID = root[
"MessageID"].
AsString();
2734 ArrayOfPlugInToolbarTools tool_array =
2736 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2738 if (event.GetId() == pttc->id) {
2739 if (pttc->m_pplugin)
2761bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2762 bool viz_now = g_bmasterToolbarFull;
2765 wxString tip = _(
"Show Toolbar");
2767 tip = _(
"Hide Toolbar");
2769 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2772 bool toggle =
false;
2773 if (viz && !g_bmasterToolbarFull)
2776 else if (!viz && g_bmasterToolbarFull)
2780 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2783 if (g_bmasterToolbarFull)
2784 m_nMasterToolCountShown =
2788 m_nMasterToolCountShown = 2;
2790 m_nMasterToolCountShown =
2793 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2799void MyFrame::ScheduleReloadCharts() {
2800 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2801 evt.SetId(ID_RELOAD_CHARTS);
2802 GetEventHandler()->AddPendingEvent(evt);
2805void MyFrame::ScheduleDeleteSettingsDialog() {
2806 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2807 evt.SetId(ID_SETTINGS_DELETE);
2808 GetEventHandler()->AddPendingEvent(evt);
2811void MyFrame::ScheduleSettingsDialog() {
2812 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2813 evt.SetId(ID_SETTINGS);
2814 GetEventHandler()->AddPendingEvent(evt);
2817void MyFrame::ScheduleSettingsDialogNew() {
2818 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2819 evt.SetId(ID_SETTINGS_NEW);
2820 GetEventHandler()->AddPendingEvent(evt);
2823void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2824 UpdateCanvasConfigDescriptors();
2826 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2827 CreateCanvasLayout(
true);
2829 CreateCanvasLayout();
2833 ConfigureStatusBar();
2834 wxSize lastOptSize = options_lastWindowSize;
2839 options_lastWindowSize = lastOptSize;
2843 ScheduleSettingsDialogNew();
2845 ScheduleSettingsDialog();
2850 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2853 int index_hint = -1;
2854 if (i < pathArray.GetCount())
2855 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2856 cc->canvasChartsRefresh(index_hint);
2857 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2866 return GetPrimaryCanvas();
2869void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2870 if (g_bmasterToolbarFull) {
2871#ifndef OCPN_TOOLBAR_ANIMATE
2872 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2875 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2876 m_nMasterToolCountShown++;
2881 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2889#ifndef OCPN_TOOLBAR_ANIMATE
2890 m_nMasterToolCountShown = 1;
2892 if (m_nMasterToolCountShown > 1) {
2893 m_nMasterToolCountShown--;
2897 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2907void MyFrame::InvalidateAllGL() {
2910 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2920void MyFrame::RefreshAllCanvas(
bool bErase) {
2922 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2925 cc->Refresh(bErase);
2930void MyFrame::setStringVP(wxString VPS) {
2935 wxStringTokenizer tkz(VPS,
";");
2937 wxString token = tkz.GetNextToken();
2939 token.ToDouble(&lat);
2941 token = tkz.GetNextToken();
2943 token.ToDouble(&lon);
2945 token = tkz.GetNextToken();
2947 token.ToDouble(&scale_ppm);
2949 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2952void MyFrame::DoSettingsNew() {
2959void MyFrame::DoSettings() {
2963 ApplyGlobalSettings(
true);
2966 bool b_loadHarmonics =
false;
2967 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2970 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2973 if (b_loadHarmonics) LoadHarmonics();
2981 g_bShowChartBar = !g_bShowChartBar;
2983 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2988 if (g_bShowChartBar) {
2990 UpdateControlBar(cc);
2993 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2996void MyFrame::ToggleColorScheme() {
2997 static bool lastIsNight;
2998 ColorScheme s = GetColorScheme();
3001 if (lastIsNight && is == 3)
3004 lastIsNight =
false;
3006 if (lastIsNight) is = 2;
3007 if (is == 3) lastIsNight =
true;
3008 s = (ColorScheme)is;
3009 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3011 SetAndApplyColorScheme(s);
3014void MyFrame::ToggleFullScreen() {
3015 bool to = !IsFullScreen();
3020 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3022 ShowFullScreen(to, style);
3025 UpdateAllToolbars(global_color_scheme);
3027 UpdateControlBar(GetPrimaryCanvas());
3029 TriggerRecaptureTimer();
3032void MyFrame::ActivateMOB() {
3034 wxDateTime mob_time = wxDateTime::Now();
3035 wxString mob_label(_(
"MAN OVERBOARD"));
3036 mob_label += _(
" on ");
3037 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3041 pWP_MOB->SetShared(
true);
3043 pWP_MOB->SetWaypointArrivalRadius(
3045 pWP_MOB->SetUseSca(
false);
3047 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3055 new RoutePoint(zlat, zlon, g_default_wp_icon,
3056 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3057 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3062 temp_route->AddPoint(pWP_src);
3063 temp_route->AddPoint(pWP_MOB);
3065 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3075 temp_route->SetRouteArrivalRadius(-1.0);
3081 v[
"GUID"] = temp_route->
m_GUID;
3082 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3083 SendJSONMessageToAllPlugins(msg_id, v);
3086 if (RouteManagerDialog::getInstanceFlag()) {
3087 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3088 pRouteManagerDialog->UpdateRouteListCtrl();
3089 pRouteManagerDialog->UpdateWptListCtrl();
3094 RefreshAllCanvas(
false);
3096 wxString mob_message(_(
"MAN OVERBOARD"));
3097 mob_message += _(
" Time: ");
3098 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3099 mob_message += _(
" Position: ");
3100 mob_message += toSDMM(1,
gLat);
3102 mob_message += toSDMM(2,
gLon);
3103 wxLogMessage(mob_message);
3105void MyFrame::TrackOn() {
3106 g_bTrackActive =
true;
3114 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3116 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3118 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3121 androidSetTrackTool(
true);
3124 if (RouteManagerDialog::getInstanceFlag()) {
3125 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3126 pRouteManagerDialog->UpdateTrkListCtrl();
3127 pRouteManagerDialog->UpdateRouteListCtrl();
3133 if (name.IsEmpty()) {
3139 name = _(
"(Unnamed Track)");
3143 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3144 SendJSONMessageToAllPlugins(msg_id, v);
3145 g_FlushNavobjChangesTimeout =
3149Track *MyFrame::TrackOff(
bool do_add_point) {
3154 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3156 SendJSONMessageToAllPlugins(msg_id, v);
3165 if (g_bTrackDaily) {
3170 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3171 return_val = pExtendTrack;
3178 g_bTrackActive =
false;
3180 if (RouteManagerDialog::getInstanceFlag()) {
3181 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3182 pRouteManagerDialog->UpdateTrkListCtrl();
3183 pRouteManagerDialog->UpdateRouteListCtrl();
3187 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3189 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3190 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3193 androidSetTrackTool(
false);
3197 m_target_rotate_time = wxInvalidDateTime;
3202void MyFrame::InitializeTrackRestart() {
3203 if (!g_bTrackDaily)
return;
3204 if (m_target_rotate_time.IsValid())
return;
3207 switch (g_track_rotate_time_type) {
3209 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3211 case TIME_TYPE_COMPUTER:
3212 rotate_at = g_track_rotate_time;
3216 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3217 rotate_at = g_track_rotate_time + utc_offset;
3220 if (rotate_at > 86400)
3222 else if (rotate_at < 0)
3225 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3226 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3229 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3230 m_target_rotate_time += wxTimeSpan(24);
3234bool MyFrame::ShouldRestartTrack() {
3236 InitializeTrackRestart();
3238 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3239 m_target_rotate_time += wxTimeSpan(24);
3245void MyFrame::TrackDailyRestart() {
3247 Track *pPreviousTrack = TrackOff(
true);
3254 if (pPreviousTrack) {
3255 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3259 if (RouteManagerDialog::getInstanceFlag()) {
3260 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3261 pRouteManagerDialog->UpdateTrkListCtrl();
3262 pRouteManagerDialog->UpdateRouteListCtrl();
3267void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3269 cc->SetUpMode(mode);
3271 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3272 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3273 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3276 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3281 cc->SetShowENCText(!cc->GetShowENCText());
3283 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3291void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3294 cc->SetENCDisplayCategory(nset);
3296 UpdateGlobalMenuItems();
3307 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3309 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3318 cc->SetShowENCLights(!cc->GetShowENCLights());
3320 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3330void MyFrame::ToggleRocks(
void )
3336 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3337 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3338 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3339 pOLE->nViz = !pOLE->nViz;
3343 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3344 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3345 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3348 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3352 ps52plib->GenerateStateHash();
3359 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3361 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3369 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3371 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3386 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3387 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3392 cc->SetShowAIS(!cc->GetShowAIS());
3393 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3397void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3398 cc->SetAttenAIS(!cc->GetAttenAIS());
3399 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3405 cc->m_bFollow =
true;
3408 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3412 SetChartUpdatePeriod();
3420 cc->m_bFollow =
false;
3422 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3426 SetChartUpdatePeriod();
3429void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3430 cc->SetShowOutlines(!cc->GetShowOutlines());
3432 RefreshAllCanvas(
false);
3436 if (g_bopengl) InvalidateAllGL();
3439 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3442void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3444void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3446 bool enabled = m_pMenuBar->IsEnabled(item_id);
3447 m_pMenuBar->Enable(item_id,
false);
3448 m_pMenuBar->Check(item_id, state);
3449 m_pMenuBar->Enable(item_id, enabled);
3453void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3460void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3461 wxBitmap *bmpRollover) {
3463 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3468void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3469 wxString rolloverSVGfile,
3470 wxString toggledSVGfile) {
3473 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3477void MyFrame::ConfigureStatusBar() {
3479 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3482 UseNativeStatusBar(
false);
3485 if (g_bShowStatusBar) {
3486 if (!m_pStatusBar) {
3488 CreateStatusBar(m_StatusBarFieldCount, 0);
3489 ApplyGlobalColorSchemetoStatusBar();
3494 m_pStatusBar->Destroy();
3495 m_pStatusBar = NULL;
3501void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3502 ConfigureStatusBar();
3504 wxSize lastOptSize = options_lastWindowSize;
3510 options_lastWindowSize = lastOptSize;
3512 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3515wxString _menuText(wxString name, wxString shortcut) {
3519 menutext <<
"\t" << shortcut;
3524void MyFrame::BuildMenuBar() {
3530 bool showMenuBar =
true;
3532 bool showMenuBar = g_bShowMenuBar;
3544 m_pMenuBar =
new wxMenuBar();
3545 RegisterGlobalMenuItems();
3546 SetMenuBar(m_pMenuBar);
3550 UpdateGlobalMenuItems();
3555 m_pMenuBar->Destroy();
3561void MyFrame::RegisterGlobalMenuItems() {
3562 if (!m_pMenuBar)
return;
3564 wxMenu *nav_menu =
new wxMenu();
3565 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3566 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3567 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3568 nav_menu->AppendSeparator();
3569 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3570 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3571 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3572 nav_menu->AppendSeparator();
3574 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3575 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3577 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3578 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3580 nav_menu->AppendSeparator();
3581 nav_menu->Append(ID_MENU_SCALE_IN,
3582 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3583 nav_menu->Append(ID_MENU_SCALE_OUT,
3584 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3586 nav_menu->AppendSeparator();
3587 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3589 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3591 wxMenu *view_menu =
new wxMenu();
3593 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3594 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3595 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3596 _menuText(_(
"Show Chart Outlines"),
"O"));
3598 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3599 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3600 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3601 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3603 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3604 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3606 view_menu->AppendSeparator();
3608 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3609 _menuText(_(
"Show ENC text"),
"T"));
3610 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3611 _menuText(_(
"Show ENC Lights"),
"L"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3613 _menuText(_(
"Show ENC Soundings"),
"S"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3615 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3617 _menuText(_(
"Show ENC Data Quality"),
"U"));
3618 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3619 _menuText(_(
"Show Navobjects"),
"V"));
3621 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3622 _menuText(_(
"Show ENC text"),
"Alt-T"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3624 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3625 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3626 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3627 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3628 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3630 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3631 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3632 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3634 view_menu->AppendSeparator();
3635 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3636 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3637 view_menu->AppendSeparator();
3639 view_menu->Append(ID_MENU_UI_COLSCHEME,
3640 _menuText(_(
"Change Color Scheme"),
"C"));
3642 view_menu->Append(ID_MENU_UI_COLSCHEME,
3643 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3646 view_menu->AppendSeparator();
3648 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3649 _menuText(_(
"Toggle Full Screen"),
"F11"));
3651 m_pMenuBar->Append(view_menu, _(
"&View"));
3653 wxMenu *ais_menu =
new wxMenu();
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3656 _(
"Attenuate less critical AIS targets"));
3657 ais_menu->AppendSeparator();
3658 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3659 _(
"Hide Moored AIS Targets"));
3660 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3661 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3665 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3666 _menuText(_(
"Show CPA Warnings"),
"W"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3669 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3672 ais_menu->AppendSeparator();
3673 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3674 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3676 wxMenu *tools_menu =
new wxMenu();
3677 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3678 _menuText(_(
"Data Monitor"),
"Alt-C"));
3680 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3681 _menuText(_(
"Measure Distance"),
"M"));
3683 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3684 _menuText(_(
"Measure Distance"),
"Alt-M"));
3687 tools_menu->AppendSeparator();
3688 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3689 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3690 tools_menu->AppendSeparator();
3691 tools_menu->Append(ID_MENU_MARK_BOAT,
3692 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3693 tools_menu->Append(ID_MENU_MARK_CURSOR,
3694 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3695 tools_menu->AppendSeparator();
3699 _menuText(_(
"Drop MOB Marker"),
3701 tools_menu->AppendSeparator();
3702 tools_menu->Append(wxID_PREFERENCES,
3703 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3705 tools_menu->Append(ID_MENU_MARK_MOB,
3706 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3707 tools_menu->AppendSeparator();
3708 tools_menu->Append(wxID_PREFERENCES,
3709 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3711 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3714 wxMenu *window_menu =
new wxMenu();
3715 m_pMenuBar->Append(window_menu, _(
"&Window"));
3718 wxMenu *help_menu =
new wxMenu();
3719 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3720 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3721 m_pMenuBar->Append(help_menu, _(
"&Help"));
3724 UpdateGlobalMenuItems();
3727void MyFrame::UpdateGlobalMenuItems() {
3728 if (!m_pMenuBar)
return;
3730 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3731 ->Check(GetPrimaryCanvas()->m_bFollow);
3732 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3733 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3734 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3735 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3736 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3737 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3738 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3739 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3740 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3741 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3744 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3745 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3746 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3748 if (g_bAIS_CPA_Alert) {
3749 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3750 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3753 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3756 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3757 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3758 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3761 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3762 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3763 ->Check(ps52plib->GetShowSoundings());
3765 bool light_state =
false;
3767 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3769 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3770 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3771 light_state = (pOLE->nViz == 1);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3777 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3781 DisCat nset = ps52plib->GetDisplayCategory();
3782 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3783 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3784 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3785 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3786 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3787 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3788 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3790 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3791 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3792 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3797void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3798 if (!m_pMenuBar)
return;
3800 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3802 if (cc->GetUpMode() == NORTH_UP_MODE)
3803 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3804 else if (cc->GetUpMode() == COURSE_UP_MODE)
3805 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3807 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3809 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3810 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3811 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3812 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3813 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3814 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3815 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3816 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3817 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3818 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3819 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3820 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3821 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3822 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3823 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3826 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3827 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3830 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3832 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3833 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3838 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3842 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3843 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3844 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3845 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3846 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3847 ->Check(cc->GetShowENCDataQual());
3848 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3850 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3851 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3852 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3857void MyFrame::InvalidateAllCanvasUndo() {
3859 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3861 if (cc) cc->undo->InvalidateUndo();
3865void MyFrame::SubmergeAllCanvasToolbars() {
3867 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3869 if (cc) cc->SubmergeToolbar();
3873void MyFrame::SurfaceAllCanvasToolbars() {
3874 if (g_bshowToolbar) {
3876 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3878 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3885void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3887 if (lon > 180.0) lon -= 360.0;
3892 cc->JumpToPosition(lat, lon,
scale);
3895 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3899void MyFrame::UpdateCanvasConfigDescriptors() {
3901 for (
unsigned int i = 0;
3902 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3903 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3911 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3912 cc->GroupID = chart->m_groupIndex;
3915 cc->
bQuilt = chart->GetQuiltMode();
3922 cc->
bFollow = chart->m_bFollow;
3927 int upmode = chart->GetUpMode();
3928 if (upmode == COURSE_UP_MODE)
3930 else if (upmode == HEAD_UP_MODE)
3937void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3938 if (!RBBox.GetValid())
return;
3940 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3941 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3944 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3945 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3953 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3954 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3956 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3957 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3959 cc->GetSize(&ww, &wh);
3961 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3963 ppm = wxMin(ppm, 1.0);
3969void MyFrame::PrepareOptionsClose(
options *settings,
3970 int settings_return_value) {
3972 options_lastPage = settings->lastPage;
3977 if (options_lastPage == 1) options_lastPage = 0;
3979 options_subpage = settings->lastSubPage;
3980 options_lastWindowPos = settings->lastWindowPos;
3981 options_lastWindowSize = settings->lastWindowSize;
3984 androidEnableBackButton(
true);
3985 androidEnableOptionsMenu(
true);
3986 androidRestoreFullScreen();
3987 androidEnableRotation();
3992void MyFrame::DoOptionsDialog() {
3994 AbstractPlatform::ShowBusySpinner();
3997 pConfig->SetPath(
"/Settings");
3998 pConfig->Read(
"OptionsSizeX", &sx, -1);
3999 pConfig->Read(
"OptionsSizeY", &sy, -1);
4001 wxWindow *optionsParent =
this;
4003 optionsParent = GetPrimaryCanvas();
4008 AbstractPlatform::HideBusySpinner();
4012 g_options->SetInitChartDir(*pInit_Chart_Dir);
4016 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4017 g_options->SetWorkDirListPtr(pWorkDirArray);
4023 prev_locale = g_locale;
4024 g_options->SetInitialPage(options_lastPage, options_subpage);
4027 g_options->lastWindowPos = options_lastWindowPos;
4028 if (options_lastWindowPos != wxPoint(0, 0)) {
4030 g_options->SetSize(options_lastWindowSize);
4034 if (options_lastWindowSize != wxSize(0, 0)) {
4035 g_options->SetSize(options_lastWindowSize);
4040 androidEnableBackButton(
false);
4041 androidEnableOptionsMenu(
false);
4042 androidDisableFullScreen();
4050 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4053 wxString chart_file_name;
4054 if (cc->GetQuiltMode()) {
4055 int dbi = cc->GetQuiltRefChartdbIndex();
4056 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4058 if (cc->m_singleChart)
4059 chart_file_name = cc->m_singleChart->GetFullPath();
4062 pathArray.Add(chart_file_name);
4068 last_canvasConfig = g_canvasConfig;
4071 g_last_ChartScaleFactor = g_ChartScaleFactor;
4077void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4078 bool b_need_refresh =
false;
4080 if ((rr & VISIT_CHARTS) &&
4081 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4083 UpdateChartDatabaseInplace(*pNewDirArray,
4084 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4087 b_need_refresh =
true;
4091 if (rr & STYLE_CHANGED) {
4094 _(
"Please restart OpenCPN to activate language or style changes."),
4095 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4098 bool b_groupchange =
false;
4099 if (((rr & VISIT_CHARTS) &&
4100 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4101 (rr & GROUPS_CHANGED)) {
4102 b_groupchange = ScrubGroupArray();
4104 RefreshGroupIndices();
4107 if (rr & GROUPS_CHANGED || b_groupchange) {
4108 pConfig->DestroyConfigGroups();
4112 if (rr & TIDES_CHANGED) {
4118 if (rr & S52_CHANGED) {
4119 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4122 pConfig->UpdateSettings();
4130 g_Platform->GetDisplayDPmm());
4133 double stuffcog = NAN;
4134 double stuffsog = NAN;
4135 if (!std::isnan(
gCog)) stuffcog =
gCog;
4136 if (!std::isnan(
gSog)) stuffsog =
gSog;
4138 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4139 COGFilterTable[i] = stuffcog;
4140 SOGFilterTable[i] = stuffsog;
4143 SetChartUpdatePeriod();
4145 if (rr & GL_CHANGED) {
4149 b_need_refresh =
true;
4152 if (rr & S52_CHANGED) {
4153 b_need_refresh =
true;
4157 if (rr & REBUILD_RASTER_CACHE) {
4159 GetPrimaryCanvas()->Disable();
4161 GetPrimaryCanvas()->Enable();
4166 if (g_config_display_size_manual &&
4174 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4181 int rrt = rr & S52_CHANGED;
4183 (rrt == S52_CHANGED) ||
4184 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4194 ps52plib->SetScaleFactorExp(
4195 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4196 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4200 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4202 if (cc) cc->ApplyGlobalSettings();
4207 bool ztc = g_bEnableZoomToCursor;
4208 g_bEnableZoomToCursor =
4212 if (!GetPrimaryCanvas()->IsFrozen())
4214 g_bEnableZoomToCursor = ztc;
4217 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4226 SetGPSCompassScale();
4228 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4231 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4232 cc->UpdateCanvasControlBar();
4235 UpdateGPSCompassStatusBoxes();
4237 SetAllToolbarScale();
4238 RequestNewToolbars();
4241 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4244 cc->RebuildCursors();
4249 bool b_masterScaleChange =
false;
4250 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4251 b_masterScaleChange =
true;
4253 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4254 RequestNewMasterToolbar(
true);
4256 bool bMuiChange =
false;
4262 if (b_masterScaleChange || bMuiChange) {
4264 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4267 cc->ProcessNewGUIScale();
4273 if (rr & LOCALE_CHANGED) {
4274 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4276 rr |= NEED_NEW_OPTIONS;
4285 g_last_ChartScaleFactor = g_ChartScaleFactor;
4287 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4292bool MyFrame::CheckGroup(
int igroup) {
4293 if (igroup == 0)
return true;
4297 if (!pGroup->m_element_array.size())
4300 for (
const auto &elem : pGroup->m_element_array) {
4301 for (
unsigned int ic = 0;
4302 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4304 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4306 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4313bool MyFrame::ScrubGroupArray() {
4318 bool b_change =
false;
4319 unsigned int igroup = 0;
4320 while (igroup < g_pGroupArray->GetCount()) {
4321 bool b_chart_in_element =
false;
4324 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4325 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4327 for (
unsigned int ic = 0;
4328 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4330 wxString chart_full_path = pcte->GetFullSystemPath();
4332 if (chart_full_path.StartsWith(element_root)) {
4333 b_chart_in_element =
true;
4339 if (!b_chart_in_element) {
4340 wxString test_string =
"GSHH";
4341 if (element_root.Upper().Contains(test_string))
4342 b_chart_in_element =
true;
4345 if (!b_chart_in_element)
4347 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4359void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4361 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4363 if (cc && (cc != ccThis)) cc->Refresh();
4368void MyFrame::ChartsRefresh() {
4371 AbstractPlatform::ShowBusySpinner();
4373 bool b_run = FrameTimer1.IsRunning();
4376 FrameTenHzTimer.Stop();
4379 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4382 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4383 if (cc->GetQuiltMode()) {
4384 currentIndex = cc->GetQuiltReferenceChartIndex();
4386 cc->canvasChartsRefresh(currentIndex);
4390 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4391 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4393 AbstractPlatform::HideBusySpinner();
4396void MyFrame::InvalidateAllQuilts() {
4397 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4400 cc->InvalidateQuilt();
4401 cc->SetQuiltRefChart(-1);
4402 cc->m_singleChart = NULL;
4407bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4409 const wxString &ChartListFileName) {
4410 bool b_run = FrameTimer1.IsRunning();
4412 FrameTenHzTimer.Stop();
4414 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4415 FrameCOGTimer.Stop();
4418 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4421 cc->InvalidateQuilt();
4422 cc->SetQuiltRefChart(-1);
4423 cc->m_singleChart = NULL;
4433 AbstractPlatform::ShowBusySpinner();
4435 wxGenericProgressDialog *pprog =
nullptr;
4437 wxString longmsg = _(
"OpenCPN Chart Update");
4439 ".................................................................."
4442 pprog =
new wxGenericProgressDialog();
4445 pprog->SetFont(*qFont);
4447 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4448 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4449 wxPD_REMAINING_TIME);
4456 wxLogMessage(
"Starting chart database Update...");
4457 wxString gshhg_chart_loc = gWorldMapLocation;
4458 gWorldMapLocation = wxEmptyString;
4462 ChartData->SaveBinary(ChartListFileName);
4463 wxLogMessage(
"Finished chart database Update");
4465 if (gWorldMapLocation.empty()) {
4469 gWorldMapLocation = gDefaultWorldMapLocation;
4470 gshhg_chart_loc = wxEmptyString;
4473 if (gWorldMapLocation != gshhg_chart_loc) {
4475 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4477 if (cc) cc->ResetWorldBackgroundChart();
4480 gshhsCrossesLandReset();
4485 AbstractPlatform::HideBusySpinner();
4487 pConfig->UpdateChartDirs(DirArray);
4490 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4491 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4493 if (b_runCOGTimer) {
4495 int period_ms = 100;
4497 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4504 cc->ToggleCanvasQuiltMode();
4506 bool cur_mode = cc->GetQuiltMode();
4508 if( !cc->GetQuiltMode() )
4509 cc->SetQuiltMode(
true );
4511 if( cc->GetQuiltMode() ) {
4512 cc->SetQuiltMode(
false );
4513 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4517 if( cur_mode != cc->GetQuiltMode() ){
4523 g_bQuiltEnable = cc->GetQuiltMode();
4527 ps52plib->GenerateStateHash();
4532void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4534void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4536void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4538 cc->DoCanvasStackDelta(direction);
4542void MyFrame::PositionIENCToolbar() {
4546 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4548 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4556void MyFrame::OnInitTimer(wxTimerEvent &event) {
4559 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4563 wxLog::FlushActive();
4565 switch (m_iInitCount++) {
4570 if (g_bInlandEcdis) {
4571 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4572 double range_set = 500.;
4574 range = wxRound(range * 10) / 10.;
4578 else if (range > 2000.)
4580 else if (range > 1600.)
4582 else if (range > 1200.)
4584 else if (range > 800.)
4589 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4593 g_Platform->SetFullscreen(g_bFullscreen);
4597 RebuildChartDatabase();
4598 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4601 cc->SetGroupIndex(0,
false);
4609 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4610 CHART_FAMILY_RASTER)) {
4615 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4616 CHART_FAMILY_VECTOR)) {
4629 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4632 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4634 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4637 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4641 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4642 NavObj_dB::GetInstance().LoadNavObjects();
4645 if (!g_AW1GUID.IsEmpty()) {
4648 if (!g_AW2GUID.IsEmpty()) {
4654 appendOSDirSlash(&layerdir);
4655 layerdir.Append(
"layers");
4657 if (wxDir::Exists(layerdir)) {
4659 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4660 wxLogMessage(laymsg);
4661 pConfig->LoadLayers(layerdir);
4671 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4685 3 * GetCharHeight());
4687 m_data_monitor->Center();
4695 pConfig->SetPath(
"/Settings");
4696 pConfig->Read(
"OptionsSizeX", &sx, -1);
4697 pConfig->Read(
"OptionsSizeY", &sy, -1);
4699 wxWindow *optionsParent =
this;
4701 optionsParent = GetPrimaryCanvas();
4707 BuildiENCToolbar(
true);
4714 if (!g_params.empty()) {
4715 for (
size_t n = 0; n < g_params.size(); n++) {
4716 wxString path = g_params[n];
4717 if (::wxFileExists(path)) {
4719 pSet->load_file(path.fn_str());
4722 pSet->LoadAllGPXObjects(
4723 !pSet->IsOpenCPN(), wpt_dups,
4725 LLBBox box = pSet->GetBBox();
4726 if (box.GetValid()) {
4727 CenterView(GetPrimaryCanvas(), box);
4736 InitAppMsgBusListener();
4741 auto loader = PluginLoader::GetInstance();
4742 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4743 if (!b_haveWMM)
gVar = g_UserVar;
4751 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4754 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4756 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4759 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4763 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4764 NavObj_dB::GetInstance().LoadNavObjects();
4767 if (!g_AW1GUID.IsEmpty()) {
4770 if (!g_AW2GUID.IsEmpty()) {
4776 appendOSDirSlash(&layerdir);
4777 layerdir.Append(
"layers");
4779 if (wxDir::Exists(layerdir)) {
4781 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4782 wxLogMessage(laymsg);
4783 pConfig->LoadLayers(layerdir);
4790 wxLogMessage(
"OnInitTimer...Last Call");
4794 RequestNewMasterToolbar();
4796 PositionIENCToolbar();
4798 g_bDeferredInitDone =
true;
4808 GetPrimaryCanvas()->SetFocus();
4809 GetPrimaryCanvas()->Enable();
4816 if (b_reloadForPlugins) {
4822 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4824 if (cc) cc->SetFirstAuto(
true);
4832 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4834 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4838 cc->CheckGroupValid();
4843 androidEnableBackButton(
true);
4844 androidEnableRotation();
4845 androidEnableOptionItems(
true);
4851 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4857 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4859 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4861 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4867 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4869 wxLog::FlushActive();
4871 RefreshAllCanvas(
true);
4872 wxGetApp().m_usb_watcher.Start();
4878void MyFrame::InitAppMsgBusListener() {
4879 auto &msgbus = AppMsgBus::GetInstance();
4882 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4883 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4887 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4888 HandleBasicNavMsg(basicnav_msg);
4892 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4893 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4897 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4898 HandleGPSWatchdogMsg(msg);
4905void MyFrame::ReleaseApiListeners() {}
4910 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4911 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4912 server.SetGetRestApiEndpointCb(
4913 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4914 server.open_file_cb = [](
const std::string &path) {
4915 return wxGetApp().OpenFile(path);
4922void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4923 if (msg->gps_watchdog <= 0) {
4924 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4928 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4933 if (m_fix_start_time.IsValid()) {
4934 wxDateTime now = wxDateTime::Now();
4935 wxTimeSpan span = now - m_fix_start_time;
4936 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4937 auto ¬eman = NotificationManager::GetInstance();
4938 wxString msg = _(
"GNSS Position fix lost");
4939 noteman.AddNotification(NotificationSeverity::kCritical,
4941 m_fix_start_time = wxInvalidDateTime;
4945 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4946 bool last_bVelocityValid = bVelocityValid;
4947 bVelocityValid =
false;
4954void MyFrame::CalculateCOGAverage() {
4956 if (!std::isnan(
gCog)) {
4959 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4962 double sum = 0., count = 0;
4964 double adder = COGTable[i];
4965 if (std::isnan(adder))
continue;
4967 if (fabs(adder -
g_COGAvg) > 180.) {
4981 else if (sum >= 360.)
4990void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4991 m_fixtime = msg->time;
4992 double hdt_data_interval = 0;
4993 double fix_time_interval = 0;
4995 double msgtime = msg->set_time.tv_sec;
4996 double m1 = msg->set_time.tv_nsec / 1e9;
4999 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5000 ((msg->vflag & POS_VALID) == POS_VALID)) {
5002 if (!m_fix_start_time.IsValid()) {
5003 m_fix_start_time = wxDateTime::Now();
5008 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5011 fix_time_gt_last = fix_time_gt;
5012 uint64_t fix_time_gt_now =
5013 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5014 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5018 double implied_sog = dist / (fix_time_interval / 3600);
5023 gLat_gt_m1 = gLat_gt;
5024 gLon_gt_m1 = gLon_gt;
5028 fix_time_gt = fix_time_gt_now;
5032 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5033 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5034 gCog_gt_m1 = gCog_gt;
5044 if (!std::isnan(gCog_gt_m1)) {
5046 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5053 if ((fix_time_gt - fix_time_gt_last) > .08) {
5058 if (gCog_gt > gCog_gt_m1) {
5059 if ((gCog_gt - gCog_gt_m1) > 180.)
5064 if ((gCog_gt_m1 - gCog_gt) > 180.)
5069 difft = fabs(gCog_gt - gCog_gt_m1);
5070 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5078 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5079 tentative_cog_rate_gt *= 1e9;
5080 cog_rate_gt = tentative_cog_rate_gt;
5088 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5091static double hdt_avg;
5092 double hdt_norm =
gHdt;
5093 if(
gHdt > 180) hdt_norm -= 360;
5096 hdt_avg += hdt_norm * 0.1;
5101 if (!std::isnan(
gHdt)) {
5103 uint64_t hdt_time_gt_last = hdt_time_gt;
5104 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5105 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5108 if (hdt_data_interval > .09) {
5110 gHdt_gt_m1 = gHdt_gt;
5113 if (!std::isnan(gHdt_gt_m1)) {
5115 double tentative_hdt_rate_gt =
5116 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5117 tentative_hdt_rate_gt *= 1e9;
5119 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5120 hdt_rate_gt = tentative_hdt_rate_gt;
5128 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5131 CalculateCOGAverage();
5139 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5140 if ((msg->vflag & POS_VALID) == POS_VALID)
5145 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5147 bVelocityValid =
true;
5151void MyFrame::UpdateStatusBar() {
5154 unsigned long uiCurrentTickCount;
5155 m_MMEAeventTime.SetToCurrent();
5156 uiCurrentTickCount =
5157 m_MMEAeventTime.GetMillisecond() / 100;
5158 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5159 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5160 m_ulLastNMEATicktime = uiCurrentTickCount;
5162 if (m_tick_idx++ > 6) m_tick_idx = 0;
5167 if (NULL != GetStatusBar()) {
5170 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5173 wxString s1(tick_buf, wxConvUTF8);
5175 s1 += toSDMM(1,
gLat);
5177 s1 += toSDMM(2,
gLon);
5179 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5183 if (!std::isnan(
gSog))
5184 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5186 sogcog.Printf(
"SOG --- ");
5190 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5192 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5194 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5195 (
int)toMagnetic(
gCog), 0x00B0);
5197 cogs.Printf((
"COG ---%c"), 0x00B0);
5199 sogcog.Append(cogs);
5200 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5205void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5206 MemFootTimer.Stop();
5208 int memsize = GetApplicationMemoryUse();
5211 printf(
"Memsize: %d \n", memsize);
5214 if (memsize > (g_MemFootMB * 1000)) {
5218 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5219 unsigned int nCache = pCache->GetCount();
5222 for (
unsigned int i = 0; i < nCache; i++) {
5232 for (
unsigned int i = 0; i < nCache - 1; i++) {
5233 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5235 pcea[i] = pcea[i + 1];
5246 unsigned int idelete = 0;
5247 unsigned int idelete_max = pCache->GetCount();
5250 unsigned int minimum_cache = 1;
5251 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5253 while ((memsize > (g_MemFootMB * 1000)) &&
5254 (pCache->GetCount() > minimum_cache) &&
5255 (idelete < idelete_max)) {
5256 int memsizeb = memsize;
5260 memsize = GetApplicationMemoryUse();
5261 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5269 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5274void MyFrame::CheckToolbarPosition() {
5277 static bool bMaximized;
5279 if (IsMaximized() && !bMaximized) {
5286 PositionIENCToolbar();
5287 }
else if (!IsMaximized() && bMaximized) {
5295 PositionIENCToolbar();
5300void MyFrame::ProcessUnitTest() {
5301 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5308 cc->m_bFollow =
false;
5310 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5311 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5314 if (cc->m_groupIndex > 0) {
5315 while (ut_index < ChartData->GetChartTableEntries() &&
5316 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5320 if (ut_index < ChartData->GetChartTableEntries()) {
5324 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5325 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5332 if (cc->GetQuiltMode()) {
5333 if (cc->IsChartQuiltableRef(ut_index))
5334 cc->SelectQuiltRefdbChart(ut_index);
5336 cc->SelectdbChart(ut_index);
5339 if (g_unit_test_1) {
5347 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5348 cte->GetLatMin(), cte->GetLonMax(), NULL,
5352 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5353 cte->GetLatMax(), cte->GetLonMin(), NULL,
5356 cc->GetSize(&ww, &wh);
5357 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5359 ppm = wxMin(ppm, 1.0);
5366 if (ut_index > ut_index_max) exit(0);
5377 bool b_rotate =
false;
5379 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5382 if (!b_rotate && !g_btenhertz)
return;
5384 bool b_update =
false;
5386 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5389 struct timespec now;
5390 clock_gettime(CLOCK_MONOTONIC, &now);
5391 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5392 double diffc = diff / 1e9;
5395 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5396 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5397 if (gCog_tentative < 0.) gCog_tentative += 360.;
5398 gCog = gCog_tentative;
5402 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5403 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5404 double diffc = diff / 1e9;
5405 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5409 if (gSog_gt && !std::isnan(gCog_gt)) {
5410 double delta_t = diffc / 3600;
5411 double distance = gSog_gt * delta_t;
5414 double angr = gCog_gt / 180 * M_PI;
5415 double latr = gLat_gt * M_PI / 180;
5416 double D = distance / 3443;
5417 double sD = sin(D), cD = cos(D);
5418 double sy = sin(latr), cy = cos(latr);
5419 double sa = sin(angr), ca = cos(angr);
5421 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5422 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5432 if (cc) cc->DoCanvasCOGSet();
5443 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5444 cc->DoCanvasUpdate();
5453 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5456void MyFrame::ProcessQuitFlag() {
5459 wxLogMessage(
"Got quitflag from SIGNAL");
5461 FrameTenHzTimer.Stop();
5468void MyFrame::ProcessDeferredTrackOn() {
5471 if (g_bDeferredStartTrack) {
5472 if (!g_bTrackActive) {
5475 g_bDeferredStartTrack =
false;
5478 g_bDeferredStartTrack =
false;
5483void MyFrame::ProcessAnchorWatch() {
5491 double d = g_nAWMax;
5493 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5494 bool toofar =
false;
5495 bool tooclose =
false;
5496 if (d >= 0.0) toofar = (dist * 1852. > d);
5497 if (d < 0.0) tooclose = (dist * 1852 < -d);
5499 if (tooclose || toofar)
5500 AnchorAlertOn1 =
true;
5502 AnchorAlertOn1 =
false;
5504 AnchorAlertOn1 =
false;
5512 double d = g_nAWMax;
5514 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5515 bool toofar =
false;
5516 bool tooclose =
false;
5517 if (d >= 0) toofar = (dist * 1852. > d);
5518 if (d < 0) tooclose = (dist * 1852 < -d);
5520 if (tooclose || toofar)
5521 AnchorAlertOn2 =
true;
5523 AnchorAlertOn2 =
false;
5525 AnchorAlertOn2 =
false;
5528 AnchorAlertOn1 =
true;
5531void MyFrame::SendFixToPlugins() {
5542 GPSData.
nSats = g_SatsInView;
5544 wxDateTime tCheck((time_t)m_fixtime);
5545 if (tCheck.IsValid()) {
5554 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5557 SendPositionFixToAllPlugIns(&GPSData);
5561void MyFrame::ProcessLogAndBells() {
5564 wxDateTime lognow = wxDateTime::Now();
5565 int hourLOC = lognow.GetHour();
5566 int minuteLOC = lognow.GetMinute();
5568 int minuteUTC = lognow.GetMinute();
5569 int second = lognow.GetSecond();
5571 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5572 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5573 (minuteUTC == 30)) {
5574 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5575 wxString day = lognow.FormatISODate();
5576 wxString utc = lognow.FormatISOTime();
5577 wxString navmsg =
"LOGBOOK: ";
5585 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5589 if (std::isnan(
gCog))
5590 cog.Printf(
"COG ----- ");
5592 cog.Printf(
"COG %10.5f ",
gCog);
5595 if (std::isnan(
gSog))
5596 sog.Printf(
"SOG ----- ");
5598 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5604 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5607 wxLogMessage(navmsg);
5608 g_loglast_time = lognow;
5610 int bells = (hourLOC % 4) * 2;
5611 if (minuteLOC != 0) bells++;
5612 if (!bells) bells = 8;
5614 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5615 m_BellsToPlay = bells;
5616 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5617 wxPostEvent(
this, ev);
5624 CheckToolbarPosition();
5630 if (bDBUpdateInProgress)
return;
5633 FrameTenHzTimer.Stop();
5635 ProcessDeferredTrackOn();
5637 ProcessAnchorWatch();
5638 ProcessLogAndBells();
5640 if (ShouldRestartTrack()) TrackDailyRestart();
5643 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5644 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5645 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5651 if (
gSog > 3.0) g_bCruising =
true;
5657 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5659 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5665 bool bnew_view =
false;
5666 if (!g_btenhertz) bnew_view = DoChartUpdate();
5673 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5676 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5679 cc->DrawBlinkObjects();
5682 if (bactiveRouteUpdate) {
5689 cc->SetOwnShipState(SHIP_NORMAL);
5691 if (cc->GetQuiltMode()) {
5692 double erf = cc->GetQuiltMaxErrorFactor();
5693 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5695 if (cc->m_singleChart) {
5696 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5697 cc->SetOwnShipState(SHIP_LOWACCURACY);
5701 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5704 (bVelocityValid != m_last_bVelocityValid) ||
5705 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5706 if (!g_bopengl) cc->UpdateShips();
5714 m_last_bVelocityValid = bVelocityValid;
5719 bool brq_dynamic =
false;
5721 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5722 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5724 if (pic->m_enabled && pic->m_init_state) {
5725 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5732 if (brq_dynamic) bnew_view =
true;
5736 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5739 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5744 if (cc->GetglCanvas()) {
5746 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5749 if (cc->m_bFollow) {
5750 cc->DoCanvasUpdate();
5757 if (std::isnan(
gCog)) cc->Refresh(
false);
5770 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5784 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5785 g_pais_query_dialog_active->UpdateText();
5788 if (g_pAISTargetList && (0 == (g_tick % (5))))
5789 g_pAISTargetList->UpdateAISTargetList();
5792 UpdateGPSCompassStatusBoxes();
5797 console->RefreshConsoleData();
5804 if (m_bdefer_resize) {
5805 if (0 == (g_tick % (5))) {
5806 printf(
"___RESIZE\n");
5807 SetSize(m_defer_size);
5809 m_bdefer_resize =
false;
5816 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5818 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5819 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5823double MyFrame::GetMag(
double a,
double lat,
double lon) {
5824 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5825 auto loader = PluginLoader::GetInstance();
5826 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5833 wxDateTime now = wxDateTime::Now();
5834 SendJSON_WMM_Var_Request(lat, lon, now);
5835 if (fabs(gQueryVar) < 360.0)
5836 Variance = gQueryVar;
5838 return toMagnetic(a, Variance);
5841bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5847 v[
"Year"] = date.GetYear();
5848 v[
"Month"] = date.GetMonth();
5849 v[
"Day"] = date.GetDay();
5851 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5857void MyFrame::TouchAISActive() {
5859 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5861 if (cc) cc->TouchAISToolActive();
5865void MyFrame::UpdateAISTool() {
5869 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5871 if (cc) cc->UpdateAISTBTool();
5876void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5878 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5880 if (cc) cc->SetbTCUpdate(
true);
5883 RefreshAllCanvas(
false);
5888void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5892 bool b_rotate =
false;
5893 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5895 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5899 FrameCOGTimer.Stop();
5906 int period_ms = 100;
5908 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5911void MyFrame::DoCOGSet() {
5913 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5915 if (cc) cc->DoCanvasCOGSet();
5919void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5925 wxFont oldfont = pdc->GetFont();
5927 pdc->SetFont(*pFont);
5928 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5929 pdc->SetBackgroundMode(wxTRANSPARENT);
5931 pdc->DrawText(str, x, y + 1);
5932 pdc->DrawText(str, x, y - 1);
5933 pdc->DrawText(str, x + 1, y);
5934 pdc->DrawText(str, x - 1, y);
5936 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5938 pdc->DrawText(str, x, y);
5940 pdc->SetFont(oldfont);
5944void MyFrame::UpdateRotationState(
double rotation) {
5946 g_bCourseUp =
false;
5948 if (fabs(rotation) > .001) {
5949 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5950 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5952 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5955 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5956 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5958 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5962 UpdateGPSCompassStatusBoxes(
true);
5966void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5968 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5970 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5976int MyFrame::GetApplicationMemoryUse() {
5982 wxWindow *fWin = wxWindow::FindFocus();
5984 wxArrayString outputArray;
5985 wxString cmd(
"ps --no-headers -o vsize ");
5986 unsigned long pid = wxGetProcessId();
5988 cmd1.Printf(
"%ld", pid);
5990 wxExecute(cmd, outputArray);
5992 if (outputArray.GetCount()) {
5993 wxString s = outputArray.Item(0);
5995 if (s.ToLong(&vtmp)) memsize = vtmp;
5998 if (fWin) fWin->SetFocus();
6004 PROCESS_MEMORY_COUNTERS pmc;
6006 unsigned long processID = wxGetProcessId();
6008 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6010 if (NULL == hProcess)
return 0;
6012 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6030 memsize = pmc.WorkingSetSize / 1024;
6033 CloseHandle(hProcess);
6040double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6041 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6044void MyFrame::SetChartUpdatePeriod() {
6047 g_ChartUpdatePeriod = 0;
6052 bool bskewdc =
false;
6053 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6056 if (!g_bopengl && !cc->GetVP().b_quilt) {
6057 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6059 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6063 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6065 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6070 cc->UpdateCanvasControlBar();
6073void MyFrame::selectChartDisplay(
int type,
int family) {
6075 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6077 if (cc) cc->selectCanvasChartDisplay(type, family);
6080 UpdateGlobalMenuItems();
6089bool MyFrame::DoChartUpdate() {
6090 bool return_val =
false;
6093 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6095 if (cc) return_val |= cc->DoCanvasUpdate();
6101void MyFrame::MouseEvent(wxMouseEvent &event) {
6103 event.GetPosition(&x, &y);
6108#include <mach/mach.h>
6109#include <mach/message.h>
6110#include <mach/kern_return.h>
6111#include <mach/task_info.h>
6113#include <malloc/malloc.h>
6120#if defined(__linux__)
6121#include "sys/types.h"
6122#include "sys/sysinfo.h"
6125void MyFrame::DoPrint(
void) {
6127 g_PrintingInProgress =
true;
6130 GetPrimaryCanvas()->GetglCanvas()->Render();
6131 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6141 printer.Initialize(wxLANDSCAPE);
6142 printer.EnablePageNumbers(
false);
6143 printer.Print(
this, &printout);
6161 g_PrintingInProgress =
false;
6164 GetPrimaryCanvas()->SetFocus();
6170 wxString message_ID =
event.GetID();
6171 wxString message_JSONText =
event.GetJSONText();
6179 if (message_ID ==
"WMM_VARIATION_BOAT") {
6187 int numErrors = reader.
Parse(message_JSONText, &root);
6188 if (numErrors > 0) {
6194 wxString decl = root[
"Decl"].
AsString();
6196 decl.ToDouble(&decl_val);
6202 if (message_ID ==
"WMM_VARIATION") {
6210 int numErrors = reader.
Parse(message_JSONText, &root);
6211 if (numErrors > 0) {
6217 wxString decl = root[
"Decl"].
AsString();
6219 decl.ToDouble(&decl_val);
6221 gQueryVar = decl_val;
6224 if (message_ID ==
"GRIB_TIMELINE") {
6227 int numErrors = r.
Parse(message_JSONText, &v);
6229 if (numErrors > 0) {
6230 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6235 wxDateTime oldTimeSource = gTimeSource;
6237 if (v[
"Day"].AsInt() == -1) {
6238 gTimeSource = wxInvalidDateTime;
6239 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6241 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6242 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6243 v[
"Second"].AsInt());
6247 if (oldTimeSource != gTimeSource) {
6249 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6251 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6256 cc->pCwin->Refresh(
false);
6262 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6265 wxString trk_id = wxEmptyString;
6267 int numErrors = reader.
Parse(message_JSONText, &root);
6268 if (numErrors > 0)
return;
6273 v[
"Track_ID"] = trk_id;
6275 wxString name = wxEmptyString;
6276 if (ptrack->m_GUID == trk_id) {
6277 name = ptrack->GetName();
6278 if (name.IsEmpty()) {
6284 name = _(
"(Unnamed Track)");
6291 v[
"TotalNodes"] = ptrack->GetnPoints();
6292 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6294 v[
"lat"] = tp->m_lat;
6295 v[
"lon"] = tp->m_lon;
6298 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6299 SendJSONMessageToAllPlugins(msg_id, v);
6305 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6306 SendJSONMessageToAllPlugins(msg_id, v);
6308 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6311 wxString guid = wxEmptyString;
6313 int numErrors = reader.
Parse(message_JSONText, &root);
6314 if (numErrors > 0) {
6323 wxString name = wxEmptyString;
6325 if ((*it)->m_GUID == guid) {
6326 name = (*it)->m_RouteNameString;
6327 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6333 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6334 itp != (*it)->pRoutePointList->end(); itp++) {
6335 w[i][
"lat"] = (*itp)->m_lat;
6336 w[i][
"lon"] = (*itp)->m_lon;
6337 w[i][
"Name"] = (*itp)->GetName();
6338 w[i][
"Description"] = (*itp)->GetDescription();
6339 w[i][
"GUID"] = (*itp)->m_GUID;
6340 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6342 auto node = (*itp)->m_HyperlinkList->begin();
6343 if (node != (*itp)->m_HyperlinkList->end()) {
6345 while (node != (*itp)->m_HyperlinkList->end()) {
6347 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6348 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6349 httpLink->DescrText;
6356 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6357 SendJSONMessageToAllPlugins(msg_id, v);
6364 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6365 SendJSONMessageToAllPlugins(msg_id, v);
6366 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6371 int numErrors = reader.
Parse(message_JSONText, &root);
6372 if (numErrors > 0)
return;
6375 wxString str = root[
"mode"].
AsString();
6376 if (str ==
"Track") route =
false;
6381 for (RouteList::iterator it =
pRouteList->begin();
6383 wxString name = (*it)->m_RouteNameString;
6384 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6386 v[i][
"error"] =
false;
6387 v[i][
"name"] = name;
6388 v[i][
"GUID"] = (*it)->m_GUID;
6389 v[i][
"active"] = (*it)->IsActive();
6394 wxString name = ptrack->GetName();
6395 if (name.IsEmpty()) {
6401 name = _(
"(Unnamed Track)");
6403 v[i][
"error"] =
false;
6404 v[i][
"name"] = name;
6405 v[i][
"GUID"] = ptrack->m_GUID;
6410 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6411 SendJSONMessageToAllPlugins(msg_id, v);
6414 v[0][
"error"] =
true;
6415 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6416 SendJSONMessageToAllPlugins(msg_id, v);
6418 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6420 v[0][
"error"] =
true;
6423 v[0][
"error"] =
false;
6424 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6425 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6426 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6427 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6428 v[0][
"active_waypoint_lat"] =
6430 v[0][
"active_waypoint_lon"] =
6434 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6435 SendJSONMessageToAllPlugins(msg_id, v);
6439void MyFrame::FilterCogSog() {
6440 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6442 double cog_last =
gCog;
6445 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6446 COGFilterTable[i] = COGFilterTable[i - 1];
6447 COGFilterTable[0] = cog_last;
6450 if (!std::isnan(cog_last)) {
6452 double sum = 0., count = 0;
6453 for (
int i = 0; i < g_COGFilterSec; i++) {
6454 double adder = COGFilterTable[i];
6455 if (std::isnan(adder))
continue;
6457 if (fabs(adder - cog_last) > 180.) {
6458 if ((adder - cog_last) > 0.)
6471 else if (sum >= 360.)
6478 double sog_last =
gSog;
6481 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6482 SOGFilterTable[i] = SOGFilterTable[i - 1];
6483 SOGFilterTable[0] = sog_last;
6486 if (!std::isnan(
gSog)) {
6487 double sum = 0., count = 0;
6488 for (
int i = 0; i < g_SOGFilterSec; i++) {
6489 if (std::isnan(SOGFilterTable[i]))
continue;
6491 sum += SOGFilterTable[i];
6501void MyFrame::LoadHarmonics() {
6504 ptcmgr->LoadDataSources(TideCurrentDataSet);
6506 bool b_newdataset =
false;
6509 for (
auto a :
ptcmgr->GetDataSet()) {
6510 bool b_foundi =
false;
6511 for (
auto b : TideCurrentDataSet) {
6518 b_newdataset =
true;
6523 for (
auto a : TideCurrentDataSet) {
6524 bool b_foundi =
false;
6525 for (
auto b :
ptcmgr->GetDataSet()) {
6532 b_newdataset =
true;
6537 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6541void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6542 if (!ptarget)
return;
6545 wxDateTime mob_time = wxDateTime::Now();
6546 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6547 mob_label += _(
" on ");
6548 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6551 mob_label, wxEmptyString);
6552 pWP_MOB->SetShared(
true);
6554 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6556 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6558 pWP_MOB->SetUseSca(
false);
6566 wxString(_(
"Own ship")), wxEmptyString);
6568 pWP_MOB->SetUseSca(
false);
6575 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6591 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6592 SendJSONMessageToAllPlugins(msg_id, v);
6595 if (RouteManagerDialog::getInstanceFlag()) {
6596 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6597 pRouteManagerDialog->UpdateRouteListCtrl();
6598 pRouteManagerDialog->UpdateWptListCtrl();
6602 RefreshAllCanvas(
false);
6604 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6605 mob_message += _(
" Time: ");
6606 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6607 mob_message += _(
" Ownship Position: ");
6608 mob_message += toSDMM(1,
gLat);
6610 mob_message += toSDMM(2,
gLon);
6611 mob_message += _(
" MOB Position: ");
6612 mob_message += toSDMM(1, ptarget->Lat);
6614 mob_message += toSDMM(2, ptarget->Lon);
6615 wxLogMessage(mob_message);
6618void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6622 OwnPoint->m_lat =
gLat;
6623 OwnPoint->m_lon =
gLon;
6625 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6630 MOB_Point->m_lat = ptarget->Lat;
6631 MOB_Point->m_lon = ptarget->Lon;
6633 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6634 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6636 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6637 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6640 RefreshAllCanvas(
false);
6643 wxDateTime mob_time = wxDateTime::Now();
6645 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6646 mob_message += _(
" Time: ");
6647 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6648 mob_message += _(
" Ownship Position: ");
6649 mob_message += toSDMM(1,
gLat);
6651 mob_message += toSDMM(2,
gLon);
6652 mob_message += _(
" MOB Position: ");
6653 mob_message += toSDMM(1, ptarget->Lat);
6655 mob_message += toSDMM(2, ptarget->Lon);
6657 wxLogMessage(mob_message);
6661void MyFrame::applySettingsString(wxString settings) {
6663 int last_UIScaleFactor = g_GUIScaleFactor;
6664 bool previous_expert = g_bUIexpert;
6665 g_last_ChartScaleFactor = g_ChartScaleFactor;
6666 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6669 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6672 pConfig->UpdateSettings();
6675 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6677 if (rr & S52_CHANGED) {
6679 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6681 ->ClearCNSYLUPArray();
6682 ps52plib->GenerateStateHash();
6686 ProcessOptionsDialog(rr, pNewDirArray);
6691 bool b_newToolbar =
false;
6693 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6695 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6697 if (rr & TOOLBAR_CHANGED) {
6698 b_newToolbar =
true;
6703 if (previous_expert && !g_bUIexpert) {
6704 androidForceFullRepaint();
6708 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6712 SetGPSCompassScale();
6714 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6716 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6718 UpdateGPSCompassStatusBoxes(
true);
6721 AbstractPlatform::ShowBusySpinner();
6723 SetAllToolbarScale();
6727 AbstractPlatform::HideBusySpinner();
6729 RequestNewMasterToolbar(
true);
6736 UpdateControlBar(GetPrimaryCanvas());
6742 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6745#ifdef wxHAS_POWER_EVENTS
6746void MyFrame::OnSuspending(wxPowerEvent &event) {
6750 wxLogMessage(
"System suspend starting...");
6753void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6756 wxLogMessage(
"System is going to suspend.");
6759void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6762 wxLogMessage(
"System suspend was cancelled.");
6765int g_last_resume_ticks;
6766void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6767 wxDateTime now = wxDateTime::Now();
6768 wxLogMessage(
"System resumed from suspend.");
6770 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6773 wxLogMessage(
"Restarting streams.");
6774 g_last_resume_ticks = now.GetTicks();
6778 g_pMUX->ClearStreams();
6780 g_pMUX->StartAllStreams();
6789 if (IsMaximized()) {
6794 wxSize sz = GetSize();
6795 SetSize(wxSize(sz.x - 1, sz.y));
6807void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6808 bool btbRebuild =
false;
6810 bool b_reshow =
true;
6813 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6814 if ((ff > 0.01f) || bforcenew) {
6824 long orient = g_Platform->GetDefaultToolbarOrientation();
6825 wxWindow *toolbarParent =
this;
6827 toolbarParent = GetPrimaryCanvas();
6830 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6832 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6839 g_bmasterToolbarFull =
true;
6843 CreateMasterToolbar();
6858bool MyFrame::CollapseGlobalToolbar() {
6860 m_nMasterToolCountShown = 1;
6864 g_bmasterToolbarFull =
false;
6880 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6881 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6882 tic->m_bRequired =
true;
6887 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6888 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6892 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6893 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6894 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6899 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6900 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6904 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6905 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6906 _(
"Enable Tracking"),
"MUI_track");
6910 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6911 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6923 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6924 _(
"Print Chart"),
"MUI_print");
6928 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6929 _(
"About OpenCPN"),
"MUI_help");
6933 AddDefaultPositionPlugInTools();
6937 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6938 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6949 ArrayOfPlugInToolbarTools tool_array =
6951 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6953 if (!pttc->b_viz)
continue;
6955 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6958 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6959 if (g_bTrackActive) {
6960 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6967bool MyFrame::CheckAndAddPlugInTool() {
6975 if (!tb)
return false;
6977 int n_tools = tb->GetToolsCount();
6981 ArrayOfPlugInToolbarTools tool_array =
6984 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6986 if (pttc->position == n_tools) {
6987 wxBitmap *ptool_bmp;
6989 switch (global_color_scheme) {
6990 case GLOBAL_COLOR_SCHEME_DAY:
6991 ptool_bmp = pttc->bitmap_day;
6994 case GLOBAL_COLOR_SCHEME_DUSK:
6995 ptool_bmp = pttc->bitmap_dusk;
6997 case GLOBAL_COLOR_SCHEME_NIGHT:
6998 ptool_bmp = pttc->bitmap_night;
7001 ptool_bmp = pttc->bitmap_day;
7006 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7008 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7009 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7010 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7011 tic->m_bPlugin =
true;
7020 while (CheckAndAddPlugInTool()) {
7026bool MyFrame::AddDefaultPositionPlugInTools() {
7033 ArrayOfPlugInToolbarTools tool_array =
7036 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7040 if (!pttc->b_viz)
continue;
7042 if (pttc->position == -1)
7044 wxBitmap *ptool_bmp;
7046 switch (global_color_scheme) {
7047 case GLOBAL_COLOR_SCHEME_DAY:
7048 ptool_bmp = pttc->bitmap_day;
7050 case GLOBAL_COLOR_SCHEME_DUSK:
7051 ptool_bmp = pttc->bitmap_dusk;
7053 case GLOBAL_COLOR_SCHEME_NIGHT:
7054 ptool_bmp = pttc->bitmap_night;
7057 ptool_bmp = pttc->bitmap_day;
7062 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7064 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7065 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7066 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7067 tic->m_bPlugin =
true;
7082wxColour GetGlobalColor(wxString colorName);
7084static const char *usercolors[] = {
7091 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7092 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7093 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7094 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7095 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7099 "UWHIT; 255;255;255;",
7102 "COMPT; 245;247;244",
7106 "DILG0; 255;255;255;",
7108 "DILG0; 238;239;242;",
7110 "DILG1; 212;208;200;",
7111 "DILG2; 255;255;255;",
7123 "CHGRF; 163; 180; 183;",
7125 "CHYLW; 244; 218; 72;",
7126 "CHWHT; 212; 234; 238;",
7129 "UINFM; 197; 69; 195;",
7131 "UINFG; 104; 228; 86;",
7133 "UINFR; 241; 84; 105;",
7134 "UINFF; 125; 137; 140;",
7138 "UDKRD; 124; 16; 0;",
7140 "UARTE; 200; 0; 0;",
7143 "NODTA; 163; 180; 183;",
7145 "SNDG1; 125; 137; 140;",
7147 "SCLBR; 235; 125; 54;",
7150 "UIBDR; 125; 137; 140;",
7151 "UIBCK; 212; 234; 238;",
7152 "UINFB; 58; 120; 240;",
7155 "UINFO; 235; 125; 54;",
7158 "PLRTE; 220; 64; 37;",
7159 "CHMGD; 197; 69; 195;",
7163 "DASHB; 255;255;255;",
7164 "DASHL; 175;175;175;",
7165 "DASHF; 50; 50; 50;",
7166 "DASHR; 200; 0; 0;",
7168 "DASHN; 200;120; 0;",
7169 "DASH1; 204;204;255;",
7170 "DASH2; 122;131;172;",
7171 "COMP1; 211;211;211;",
7174 "GREY3; 40; 40; 40;",
7175 "BLUE4; 100;100;200;",
7176 "VIO01; 171; 33;141;",
7177 "VIO02; 209;115;213;",
7178 "BLUEBACK; 212;234;238;",
7179 "LANDBACK; 201;185;122;",
7185 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7186 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7187 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7188 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7189 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7190 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7191 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7193 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7194 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7195 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7197 "DILG0; 110;110;110;",
7198 "DILG1; 110;110;110;",
7200 "DILG3; 130;130;130;",
7202 "UITX1; 41; 46; 46;",
7205 "UARTE; 64; 64; 64;",
7207 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7208 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7209 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7210 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7212 "DASHB; 77; 77; 77;",
7213 "DASHL; 54; 54; 54;",
7215 "DASHR; 58; 21; 21;",
7216 "DASHG; 21; 58; 21;",
7217 "DASHN; 100; 50; 0;",
7218 "DASH1; 76; 76;113;",
7219 "DASH2; 48; 52; 72;",
7220 "COMP1; 107;107;107;",
7222 "GREY3; 20; 20; 20;",
7223 "BLUE4; 80; 80;160;",
7224 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7225 "LANDBACK; 201;185;122;",
7231 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7232 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7233 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7234 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7235 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7236 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7237 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7238 "DILG0; 80; 80; 80;",
7239 "DILG1; 80; 80; 80;",
7241 "DILG3; 65; 65; 65;",
7242 "DILG4; 220;220;220;",
7243 "UITX1; 31; 34; 35;",
7246 "UARTE; 64; 64; 64;",
7248 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7249 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7250 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7252 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7253 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7254 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7255 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7258 "DASHL; 20; 20; 20;",
7259 "DASHF; 64; 64; 64;",
7260 "DASHR; 70; 15; 15;",
7261 "DASHG; 15; 70; 15;",
7262 "DASHN; 17; 80; 56;",
7263 "DASH1; 48; 52; 72;",
7264 "DASH2; 36; 36; 53;",
7265 "COMP1; 24; 24; 24;",
7267 "GREY3; 10; 10; 10;",
7268 "BLUE4; 70; 70;140;",
7269 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7270 "LANDBACK; 201;185;122;",
7274int get_static_line(
char *d,
const char **p,
int index,
int n) {
7275 if (!strcmp(p[index],
"*****"))
return 0;
7277 strncpy(d, p[index], n);
7281void InitializeUserColors() {
7282 const char **p = usercolors;
7290 UserColorTableArray =
new wxArrayPtrVoid;
7291 UserColourHashTableArray =
new wxArrayPtrVoid;
7295 ct->tableName =
new wxString(
"DAY");
7296 ct->color =
new wxArrayPtrVoid;
7297 UserColorTableArray->Add((
void *)ct);
7300 ct->tableName =
new wxString(
"DUSK");
7301 ct->color =
new wxArrayPtrVoid;
7302 UserColorTableArray->Add((
void *)ct);
7305 ct->tableName =
new wxString(
"NIGHT");
7306 ct->color =
new wxArrayPtrVoid;
7307 UserColorTableArray->Add((
void *)ct);
7309 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7310 if (!strncmp(buf,
"Table", 5)) {
7311 sscanf(buf,
"Table:%s", TableName);
7313 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7314 ctp = (colTable *)(UserColorTableArray->Item(it));
7315 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7324 while (buf[j] !=
';' && j < 20) {
7330 S52color *c =
new S52color;
7331 strcpy(c->colName, name);
7333 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7346 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7347 wxColorHashMap *phash =
new wxColorHashMap;
7348 UserColourHashTableArray->Add((
void *)phash);
7350 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7352 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7353 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7355 wxColour c(c2->R, c2->G, c2->B);
7356 wxString key(c2->colName, wxConvUTF8);
7364 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7367void DeInitializeUserColors() {
7368 if (!UserColorTableArray)
return;
7369 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7370 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7372 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7373 S52color *c = (S52color *)ct->color->Item(j);
7377 delete ct->tableName;
7383 delete UserColorTableArray;
7385 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7386 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7390 delete UserColourHashTableArray;
7397typedef struct _MSW_COLOR_SPEC {
7399 wxString S52_RGB_COLOR;
7403MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7404 {COLOR_MENUTEXT,
"UITX1", 0},
7405 {COLOR_BTNSHADOW,
"UIBCK", 0},
7408void SaveSystemColors() {
7422 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7423 while (pcspec->COLOR_NAME != -1) {
7424 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7429void RestoreSystemColors() {
7430 int element[NCOLORS];
7431 int rgbcolor[NCOLORS];
7434 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7435 while (pcspec->COLOR_NAME != -1) {
7436 element[i] = pcspec->COLOR_NAME;
7437 rgbcolor[i] = pcspec->SysRGB_COLOR;
7443 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7448void SetSystemColors(ColorScheme cs) {
7450 int element[NCOLORS];
7451 int rgbcolor[NCOLORS];
7453 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7454 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7455 while (pcspec->COLOR_NAME != -1) {
7456 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7457 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7458 element[i] = pcspec->COLOR_NAME;
7464 pSetSysColors(i, (
unsigned long *)&element[0],
7465 (
unsigned long *)&rgbcolor[0]);
7469 RestoreSystemColors();
7474wxColor GetDimColor(wxColor c) {
7475 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7476 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7480 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7481 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7483 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7484 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7485 hsv.value = hsv.value * factor;
7486 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7488 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7494double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7495 double const AnchorPointMaxDist)
7498 if (d < AnchorPointMinDist)
7499 return AnchorPointMinDist;
7500 else if (d > AnchorPointMaxDist)
7501 return AnchorPointMaxDist;
7507 if (d > -AnchorPointMinDist)
7508 return -AnchorPointMinDist;
7509 else if (d < -AnchorPointMaxDist)
7510 return -AnchorPointMaxDist;
7517static const WORD MAX_CONSOLE_LINES =
7522void RedirectIOToConsole()
7527 wxIntPtr lStdHandle;
7529 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7539 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7540 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7541 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7545 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7546 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7547 fp = _fdopen(hConHandle,
"w");
7549 setvbuf(stdout, NULL, _IONBF, 0);
7553 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7554 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7555 fp = _fdopen(hConHandle,
"r");
7557 setvbuf(stdin, NULL, _IONBF, 0);
7561 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7562 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7563 fp = _fdopen(hConHandle,
"w");
7565 setvbuf(stderr, NULL, _IONBF, 0);
7577bool TestGLCanvas(wxString prog_dir) {
7579 wxString test_app = prog_dir;
7580 test_app +=
"ocpn_gltest1.exe";
7582 if (::wxFileExists(test_app)) {
7583 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7584 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7585 if (proc_return == 0)
7586 printf(
"GLCanvas OK\n");
7588 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7590 return (proc_return == 0);
7600bool ReloadLocale() {
7605 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7612 FontMgr::Get().SetLocale(g_locale);
7626 if (pRouteManagerDialog) {
7627 pRouteManagerDialog->Hide();
7628 pRouteManagerDialog->Destroy();
7629 pRouteManagerDialog = NULL;
7633 if (g_pais_query_dialog_active) {
7634 g_pais_query_dialog_active->Destroy();
7635 g_pais_query_dialog_active = NULL;
7638 auto alert_dlg_active =
7640 if (alert_dlg_active) {
7641 alert_dlg_active->Destroy();
7642 g_pais_alert_dialog_active =
nullptr;
7645 if (g_pAISTargetList) {
7647 g_pAISTargetList->Disconnect_decoder();
7648 g_pAISTargetList->Destroy();
7649 g_pAISTargetList = NULL;
7653 if (gFrame->m_pMenuBar) {
7654 gFrame->SetMenuBar(NULL);
7655 gFrame->m_pMenuBar->Destroy();
7656 gFrame->m_pMenuBar = NULL;
7658 gFrame->BuildMenuBar();
7661 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7663 if (cc) cc->CanvasApplyLocale();
7668 wxString perspective;
7669 pConfig->SetPath(
"/AUI");
7670 pConfig->Read(
"AUIPerspective", &perspective);
7684 bool bno_load =
false;
7685 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7687 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7688 wxAuiPaneInfo pane = pane_array_val[i];
7689 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7695 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7700 gFrame->RequestNewToolbars(
true);
7701 gFrame->RequestNewMasterToolbar(
true);
7718 g_csv_locn = g_Platform->GetSharedDataDir();
7719 g_csv_locn.Append(
"s57data");
7723 appendOSDirSlash(&g_csv_locn);
7724 g_csv_locn.Append(
"s57data");
7729 if (g_SENCPrefix.IsEmpty()) {
7731 appendOSDirSlash(&g_SENCPrefix);
7732 g_SENCPrefix.Append(
"SENC");
7736 wxFileName f(g_SENCPrefix);
7738 g_SENCPrefix = f.GetFullPath();
7740 g_SENCPrefix =
"SENC";
7746 bool b_force_legacy =
false;
7748 if (g_UserPresLibData.IsEmpty()) {
7749 plib_data = g_csv_locn;
7750 appendOSDirSlash(&plib_data);
7751 plib_data.Append(
"S52RAZDS.RLE");
7753 plib_data = g_UserPresLibData;
7754 b_force_legacy =
true;
7757 ps52plib =
new s52plib(plib_data, b_force_legacy);
7772 if (!ps52plib->m_bOK) {
7775 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7777 wxString look_data_dir;
7778 look_data_dir.Append(std_path.GetUserDataDir());
7779 appendOSDirSlash(&look_data_dir);
7780 wxString tentative_SData_Locn = look_data_dir;
7781 look_data_dir.Append(
"s57data");
7783 plib_data = look_data_dir;
7784 appendOSDirSlash(&plib_data);
7785 plib_data.Append(
"S52RAZDS.RLE");
7787 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7788 ps52plib =
new s52plib(plib_data);
7790 if (ps52plib->m_bOK) {
7791 g_csv_locn = look_data_dir;
7800 if (!ps52plib->m_bOK) {
7803 wxString look_data_dir;
7804 look_data_dir = g_Platform->GetSharedDataDir();
7805 look_data_dir.Append(
"s57data");
7807 plib_data = look_data_dir;
7808 appendOSDirSlash(&plib_data);
7809 plib_data.Append(
"S52RAZDS.RLE");
7811 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7812 ps52plib =
new s52plib(plib_data);
7814 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7817 if (ps52plib->m_bOK) {
7818 wxLogMessage(
"Using s57data in " + g_csv_locn);
7820 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7825 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7827 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7828 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7829 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7830 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7833 pConfig->LoadS57Config();
7834 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7840 ps52plib->SetDIPFactor(dip_factor);
7845 ps52plib->SetScaleFactorExp(
7846 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7847 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7854 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7855 ps52plib->SetGLRendererString(renderer);
7858 ps52plib->SetGLOptions(
7859 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7860 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7861 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7866 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7875 : wxThread(wxTHREAD_JOINABLE) {
7876 m_filename = filename;
7887 newChart->SetNativeScale(m_scale);
7888 newChart->SetFullExtent(m_ext);
7890 newChart->FindOrCreateSenc(m_filename);
7895 wxString m_filename;
7901static double chart_dist(
int index) {
7907 if (cte.GetBBox().Contains(
gLat,
gLon))
7912 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7913 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7914 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7917 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7918 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7920 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7926WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7927static int CompareInts(
int n1,
int n2) {
7928 double d1 = chart_dist(n1);
7929 double d2 = chart_dist(n2);
7930 return (
int)(d1 - d2);
7935 wxString chart_path;
7940WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7942#include <wx/arrimpl.cpp>
7945void ParseAllENC(wxWindow *parent) {
7946 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7954 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7957 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7959 idx_sorted_by_distance.Add(i);
7963 if (count == 0)
return;
7965 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7971 ArrayOfCompressTargets ct_array;
7972 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7973 int i = idx_sorted_by_distance[j];
7976 double distance = chart_dist(i);
7978 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7981 pct->distance = distance;
7982 pct->chart_path = filename;
7984 ct_array.push_back(pct);
7987 int thread_count = 0;
7990 if (g_nCPUCount > 0)
7991 thread_count = g_nCPUCount;
7993 thread_count = wxThread::GetCPUCount();
7995 if (thread_count < 1) {
8004 for(
int t = 0; t < thread_count; t++)
8008 wxGenericProgressDialog *prog =
nullptr;
8012 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8013 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8015 prog =
new wxGenericProgressDialog();
8017 prog->SetFont(*qFont);
8019 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8020 count + 1, parent, style);
8029 prog->ShowWindowModal();
8038 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8039 wxString filename = ct_array[j].chart_path;
8040 double distance = ct_array[j].distance;
8041 int index =
ChartData->FinddbIndex(filename);
8042 if (index < 0)
continue;
8045 ext.NLAT = cte.GetLatMax();
8046 ext.SLAT = cte.GetLatMin();
8047 ext.WLON = cte.GetLonMin();
8048 ext.ELON = cte.GetLonMax();
8050 int scale = cte.GetScale();
8053 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8056 if (wxThread::IsMain()) {
8058 wxSize sz = prog->GetSize();
8063 prog->Update(count, msg, &skip);
8075 newChart->SetNativeScale(
scale);
8076 newChart->SetFullExtent(ext);
8077 newChart->DisableBackgroundSENC();
8079 newChart->FindOrCreateSenc(filename,
8083 if (wxThread::IsMain()) {
8084 msg.Printf(_(
"ENC Completed."));
8086 prog->Update(count, msg, &skip);
8096 for (
int t = 0;; t = (t + 1) % thread_count) {
8103 if (!workers[t]->IsAlive()) {
8116#if defined(__WXMSW__) || defined(__WXOSX__)
8123 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
s57RegistrarMgr * m_pRegistrarMan
Global instance.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
WaypointMan drawing stuff.