52#include <wx/stdpaths.h>
53#include <wx/tokenzr.h>
54#include <wx/display.h>
55#include <wx/jsonreader.h>
57#include "o_sound/o_sound.h"
81#include "model/nav_object_database.h"
93#include "ais_info_gui.h"
94#include "dialog_alert.h"
98#include "ais_info_gui.h"
122#include "load_errors_dlg.h"
125#include "N2KParser.h"
153#include "androidUTIL.h"
161arrayofCanvasPtr g_canvasArray;
167GLenum g_texture_rectangle_format;
170#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
171extern wxLocale *plocale_def_lang;
175extern bool g_b_EnableVBO;
176extern GLenum g_texture_rectangle_format;
180static int g_last_ChartScaleFactor;
181static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
182static int options_subpage = 0;
183static bool b_reloadForPlugins;
185static wxSize options_lastWindowSize(0, 0);
186static wxPoint options_lastWindowPos(0, 0);
190static double gQueryVar = 361.0;
192static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
193static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
195static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
198static wxArrayPtrVoid *UserColourHashTableArray;
203typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
204typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
206static SetSysColors_t pSetSysColors;
207static GetSysColor_t pGetSysColor;
209void SaveSystemColors();
210void RestoreSystemColors();
215DWORD color_3ddkshadow;
217DWORD color_activecaption;
218DWORD color_gradientactivecaption;
219DWORD color_captiontext;
220DWORD color_windowframe;
221DWORD color_inactiveborder;
226#include <wx/msw/msvcrt.h>
230static const long long lNaN = 0xfff8000000000000;
231#define NAN (*(double *)&lNaN)
234static wxArrayPtrVoid *UserColorTableArray = 0;
237static double gLat_gt, gLon_gt;
238static double gLat_gt_m1, gLon_gt_m1;
239static uint64_t fix_time_gt;
240static uint64_t fix_time_gt_last;
242static double gSog_gt, gHdt_gt;
243static double gCog_gt_m1, gHdt_gt_m1;
244static uint64_t hdt_time_gt;
245static double cog_rate_gt, hdt_rate_gt;
247void InitializeUserColors();
248void DeInitializeUserColors();
249void SetSystemColors(ColorScheme cs);
251static bool LoadAllPlugIns(
bool load_enabled) {
252 AbstractPlatform::ShowBusySpinner();
253 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
254 AbstractPlatform::HideBusySpinner();
258static void LaunchLocalHelp() {
260 androidLaunchHelpView();
262 wxString def_lang_canonical =
"en_US";
265 if (plocale_def_lang)
266 def_lang_canonical = plocale_def_lang->GetCanonicalName();
269 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
271 wxString help_try = help_locn + def_lang_canonical +
".html";
273 if (!::wxFileExists(help_try)) {
274 help_try = help_locn +
"en_US" +
".html";
276 if (!::wxFileExists(help_try)) {
277 help_try = help_locn +
"web" +
".html";
280 if (!::wxFileExists(help_try))
return;
283 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
287static void DoHelpDialog() {
299 [] { LaunchLocalHelp(); });
311#if defined(__WXGTK__) || defined(__WXQT__)
312#include "bitmaps/opencpn.xpm"
326void BuildiENCToolbar(
bool bnew) {
327 if (g_bInlandEcdis) {
331 wxPoint tbp_incanvas =
334 g_iENCToolbarPosY = tbp_incanvas.y;
335 g_iENCToolbarPosX = tbp_incanvas.x;
343 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
347 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
350 g_iENCToolbarPosY = -1;
353 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
359 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
363 double tool_scale_factor =
364 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
367 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
377bool ShowNavWarning() {
380OpenCPN is distributed in the hope that it will be useful, \
381but WITHOUT ANY WARRANTY; without even the implied \
382warranty of MERCHANTABILITY or FITNESS FOR A \
383PARTICULAR PURPOSE.\n\n\
384See the GNU General Public License for more details.\n\n\
385OpenCPN must only be used in conjunction with approved \
386paper charts and traditional methods of navigation.\n\n\
387DO NOT rely upon OpenCPN for safety of life or property.\n\n\
388Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
390 wxString vs = wxString::Format(
" .. Version %s", VERSION_FULL);
393 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
396 msg.Replace(
"\n",
"<br>");
398 std::stringstream html;
399 html <<
"<html><body><p>";
400 html << msg.ToStdString();
401 html <<
"</p></body></html>";
403 std::string title = _(
"Welcome to OpenCPN").ToStdString();
404 std::string action = _(
"Agree").ToStdString();
406 info_dlg.SetInitialSize();
407 info_dlg.AddHtmlContent(html);
408 int agreed = info_dlg.ShowModal();
409 return agreed == wxID_OK;
414 if (chart ==
nullptr)
return false;
417 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
419 if (cc && cc->m_singleChart == chart) {
426#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
429static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
430 const char *prop_name) {
434 unsigned long ret_nitems;
435 unsigned long ret_bytes_after;
436 unsigned char *ret_prop;
438 xa_prop_name = XInternAtom(disp, prop_name, False);
446 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
447 &xa_ret_type, &ret_format, &ret_nitems,
448 &ret_bytes_after, &ret_prop) != Success)
451 if (xa_ret_type != xa_prop_type) {
455 return (
char *)ret_prop;
460static bool isTransparentToolbarInOpenGLOK() {
467 if (!g_bdisable_opengl) {
468 Display *disp = XOpenDisplay(NULL);
470 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
472 "_NET_SUPPORTING_WM_CHECK")) ||
473 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
475 "_WIN_SUPPORTING_WM_CHECK"))) {
478 if ((wm_name = get_X11_property(disp, *sup_window,
479 XInternAtom(disp,
"UTF8_STRING", False),
481 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
484 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
505wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
507BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
508EVT_CLOSE(MyFrame::OnCloseWindow)
509EVT_MENU(wxID_EXIT, MyFrame::OnExit)
510EVT_SIZE(MyFrame::OnSize)
511EVT_MOVE(MyFrame::OnMove)
512EVT_ICONIZE(MyFrame::OnIconize)
513EVT_MENU(-1, MyFrame::OnToolLeftClick)
514EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
516EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
517EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
518EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
520EVT_MAXIMIZE(MyFrame::OnMaximize)
521EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
522 MyFrame::RequestNewToolbarArgEvent)
523EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
525EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
526EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
527EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
529#ifdef wxHAS_POWER_EVENTS
530EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
531EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
532EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
533EVT_POWER_RESUME(MyFrame::OnResume)
544static
void onBellsFinishedCB(
void *ptr) {
545 auto framePtr =
static_cast<MyFrame *
>(ptr);
547 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
548 wxPostEvent(framePtr, ev);
553 auto msg = ev.GetString().ToStdString();
554 auto ¬eman = NotificationManager::GetInstance();
555 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
558static NmeaLog *GetDataMonitor() {
559 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
560 return dynamic_cast<NmeaLog *
>(w);
564MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
565 const wxSize &size,
long style,
566 wxAuiDefaultDockArt *pauidockart)
567 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
568 m_connections_dlg(nullptr),
570 m_pauidockart(pauidockart) {
582 m_last_track_rotation_ts = 0;
583 m_ulLastNMEATicktime = 0;
584 m_data_monitor->Hide();
586 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
590 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
593 InitTimer.SetOwner(
this, INIT_TIMER);
595 m_initializing =
false;
598 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
601 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
604 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
607 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
610 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
612 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
621 m_bTimeIsSet =
false;
624 m_bdefer_resize =
false;
627 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
628 COGFilterTable[i] = NAN;
629 SOGFilterTable[i] = NAN;
631 m_last_bGPSValid =
false;
632 m_last_bVelocityValid =
false;
642 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
647 double process_noise_std = 1.0;
648 double measurement_noise_std = 0.5;
650 m_ChartUpdatePeriod = 1;
655 log_callbacks.log_is_active = [&]() {
656 auto log = GetDataMonitor();
657 return log && log->IsVisible();
659 log_callbacks.log_message = [&](
Logline ll) {
660 NmeaLog *monitor = GetDataMonitor();
663 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
666 ais_callbacks.confirm_stop_track = []() {
667 int r = OCPNMessageBox(
669 _(
"This AIS target has Persistent tracking selected by MMSI "
671 "A Persistent track recording will therefore be restarted for this "
673 "Do you instead want to stop Persistent tracking for this target?"),
674 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
675 return r == wxID_YES;
677 ais_callbacks.get_target_mmsi = []() {
678 auto alert_dlg_active =
680 assert(alert_dlg_active);
681 return alert_dlg_active->Get_Dialog_MMSI();
689 wxLogMessage(
" **** Connect stuff");
695 Connect(wxEVT_OCPN_MSG,
696 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
704 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
712#if defined(__WXGTK__) || defined(__WXQT__)
713 wxIcon app_icon(opencpn);
721 wxDynamicLibrary dllUser32(
"user32.dll");
723 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
724 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
729 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
734 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
735 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
737 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
739 [&](wxCommandEvent) { Refresh(); });
740 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
745 EnableFullScreenView();
747 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
753 FrameTenHzTimer.Stop();
768 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
774void MyFrame::FreezeCharts() {
777 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
779 if (cc && !cc->IsFrozen()) cc->Freeze();
784void MyFrame::ThawCharts() {
787 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
789 if (cc && cc->IsFrozen()) cc->Thaw();
796 switch (event.type) {
797 case SENC_BUILD_STARTED:
800 case SENC_BUILD_DONE_NOERROR:
802 chart =
event.m_ticket->m_chart;
804 chart->PostInit(FULL_INIT, global_color_scheme);
806 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
808 if (cc) cc->ClearS52PLIBStateHash();
813 delete event.m_ticket;
815 case SENC_BUILD_DONE_ERROR:
823void MyFrame::RebuildChartDatabase() {
824 bool b_SetInitialPoint =
false;
827 ArrayOfCDI ChartDirArray;
828 pConfig->LoadChartDirArray(ChartDirArray);
830 if (ChartDirArray.GetCount()) {
835 _(
"OpenCPN needs to update the chart database from config file "
839 wxICON_INFORMATION | wxOK);
847 _(
"Rebuilding chart database from configuration file entries..."));
851 wxString dummy1 = _(
"Elapsed time : ");
852 wxString dummy2 = _(
"Estimated time : ");
853 wxString dummy3 = _(
"Remaining time : ");
854 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
855 _(
"OpenCPN Chart Update"), line, 100, NULL,
856 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
857 wxPD_REMAINING_TIME);
860 ChartData->SaveBinary(ChartListFileName);
870void MyFrame::OnBellsFinished(wxCommandEvent &event) {
871 int bells = wxMin(m_BellsToPlay, 2);
872 if (bells <= 0)
return;
874 wxString soundfile =
"sounds";
875 appendOSDirSlash(&soundfile);
876 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
877 soundfile.Prepend(g_Platform->GetSharedDataDir());
878 wxLogMessage(
"Using bells sound file: " + soundfile);
880 o_sound::Sound *sound = bells_sound[bells - 1];
881 sound->SetFinishedCallback(onBellsFinishedCB,
this);
882 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
883 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
884 sound->Load(soundfile);
885 if (!sound->IsOk()) {
886 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
890 m_BellsToPlay -= bells;
893void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
895void MyFrame::OnMaximize(wxMaximizeEvent &event) {
902ColorScheme GetColorScheme() {
return global_color_scheme; }
904ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
906void MyFrame::ReloadAllVP() {
907 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
909 if (cc) cc->ReloadVP();
913void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
914 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
917 global_color_scheme = cs;
920 case GLOBAL_COLOR_SCHEME_DAY:
923 case GLOBAL_COLOR_SCHEME_DUSK:
926 case GLOBAL_COLOR_SCHEME_NIGHT:
927 SchemeName =
"NIGHT";
934 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
936 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
937 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
938 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
939 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
940 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
942 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
971 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
972 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
976 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
979 unsigned Usercolortable_index = 0;
980 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
981 colTable *ct = (colTable *)UserColorTableArray->Item(i);
982 if (SchemeName.IsSameAs(*ct->tableName)) {
983 Usercolortable_index = i;
988 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
992 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
997 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1000 cc->SetColorScheme(cs);
1001 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1002 cc->HideChartInfoWindow();
1003 cc->SetQuiltChartHiLiteIndex(-1);
1009 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1021 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1034 if (g_pais_query_dialog_active) {
1035 bool b_isshown = g_pais_query_dialog_active->IsShown();
1036 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1037 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1039 g_pais_query_dialog_active->Close();
1042 g_pais_query_dialog_active->
Create(
1043 this, -1, _(
"AIS Target Query"),
1044 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1045 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1046 g_pais_query_dialog_active->UpdateText();
1047 if (b_isshown) g_pais_query_dialog_active->Show();
1050 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1052 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1056 ApplyGlobalColorSchemetoStatusBar();
1058 UpdateAllToolbars(cs);
1063 bool btoolbarFull = g_bmasterToolbarFull;
1069 if (!btoolbarFull) {
1071 RequestNewMasterToolbar();
1073 CollapseGlobalToolbar();
1076 RequestNewMasterToolbar();
1085void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1086 if (m_pStatusBar != NULL) {
1087 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1088 m_pStatusBar->ClearBackground();
1093 if (g_canvasArray.GetCount() > 0)
1094 return g_canvasArray.Item(0);
1098void MyFrame::CancelAllMouseRoute() {
1100 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1102 if (cc) cc->CancelMouseRoute();
1106void MyFrame::NotifyChildrenResize() {}
1108void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1116 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1124 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1133 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1136 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1137 config_array.Item(i)->canvas = NULL;
1143 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1144 g_canvasArray.RemoveAt(i);
1148 switch (g_canvasConfig) {
1151 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1154 g_canvasArray.Add(cc);
1156 cc = g_canvasArray[0];
1162 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1163 cc->GetglCanvas()->Show();
1166 config_array.Item(0)->canvas = cc;
1170 cc->ApplyCanvasConfig(config_array.Item(0));
1174 cc->ConfigureChartBar();
1175 cc->SetColorScheme(global_color_scheme);
1176 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1177 cc->SetShowGPS(
true);
1180 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1182 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1188 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1190 g_canvasArray.Add(cc);
1192 cc = g_canvasArray[0];
1198 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1201 config_array.Item(0)->canvas = cc;
1203 cc->ApplyCanvasConfig(config_array.Item(0));
1206 cc->ConfigureChartBar();
1207 cc->SetColorScheme(global_color_scheme);
1208 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1209 cc->SetShowGPS(
false);
1212 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1214 .CaptionVisible(
false)
1216 .CloseButton(
false);
1221 g_canvasArray.Add(cc);
1225 if (config_array.GetCount() < 2) {
1227 pcc->configIndex = 1;
1231 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1232 config_array.Add(pcc);
1235 config_array.Item(1)->canvas = cc;
1237 cc->ApplyCanvasConfig(config_array.Item(1));
1240 cc->ConfigureChartBar();
1241 cc->SetColorScheme(global_color_scheme);
1242 cc->SetShowGPS(
true);
1246 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1248 .CaptionVisible(
false)
1250 .CloseButton(
false);
1251 g_pauimgr->GetPane(cc).RightDockable(
true);
1255 config_array.Item(1)->canvasSize =
1256 wxSize(GetClientSize().x / 2, GetClientSize().y);
1257 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1262 if (b_useStoredSize) {
1263 int ccw = config_array.Item(1)->canvasSize.x;
1264 int cch = config_array.Item(1)->canvasSize.y;
1267 if (ccw < GetClientSize().x / 10) {
1268 ccw = GetClientSize().x / 2;
1269 cch = GetClientSize().y;
1272 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1273 cc->SetSize(ccw, cch);
1287 if (g_canvasArray.size() > 1)
1291 console->SetColorScheme(global_color_scheme);
1296 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1302void MyFrame::RequestNewToolbars(
bool bforcenew) {
1303 if (b_inCloseWindow) {
1307 BuildiENCToolbar(bforcenew);
1308 PositionIENCToolbar();
1317void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1323void MyFrame::SetAllToolbarScale() {
1324 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1327void MyFrame::SetGPSCompassScale() {
1328 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1332 wxPoint screenPoint = ::wxGetMousePosition();
1335 switch (g_canvasConfig) {
1337 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1340 if (canvas->GetScreenRect().Contains(
1344 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1347 if (canvas->GetScreenRect().Contains(
1354 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1357 if (canvas->GetScreenRect().Contains(
1358 canvas->ScreenToClient(screenPoint)))
1366int MyFrame::GetCanvasIndexUnderMouse() {
1367 wxPoint screenPoint = ::wxGetMousePosition();
1370 switch (g_canvasConfig) {
1372 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1375 if (canvas->GetScreenRect().Contains(
1379 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1382 if (canvas->GetScreenRect().Contains(
1389 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1392 if (canvas->GetScreenRect().Contains(
1393 canvas->ScreenToClient(screenPoint)))
1401bool MyFrame::DropMarker(
bool atOwnShip) {
1408 if (!canvas)
return false;
1415 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1417 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1419 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1424 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1425 pRouteManagerDialog->UpdateWptListCtrl();
1430 RefreshAllCanvas(
false);
1435void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1436 if (g_canvasConfig != 0) {
1439 int nTargetGTK = -1;
1441 wxWindow *source = FindFocus();
1447 switch (g_canvasConfig) {
1449 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1452 if (canvas && (canvas == test)) {
1457 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1460 if (canvas && (canvas == test)) {
1468 int nfinalTarget = nTarget;
1470 nfinalTarget = nTargetGTK;
1472 target = ConfigMgr::Get()
1473 .GetCanvasConfigArray()
1478 target->Refresh(
true);
1489void MyFrame::FastClose() {
1491 FrameTenHzTimer.Stop();
1493 FrameTimer1.Start(1);
1497void MyFrame::OnExit(wxCommandEvent &event) {
1501void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1504 if (b_inCloseWindow) {
1514 if (!g_bDeferredInitDone)
return;
1531 if (bDBUpdateInProgress)
return;
1533 b_inCloseWindow =
true;
1535 ::wxSetCursor(wxCURSOR_WAIT);
1539 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1541 if (cc && cc->IsMeasureActive()) {
1542 cc->CancelMeasureRoute();
1547 SendPreShutdownHookToPlugins();
1551 if (g_pAISTargetList) {
1552 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1553 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1554 g_pauimgr->DetachPane(g_pAISTargetList);
1565 pConfig->SetPath(
"/AUI");
1566 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1581 SetCursor(wxCURSOR_WAIT);
1583 RefreshAllCanvas(
true);
1589 RestoreScreenBrightness();
1600 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1601 g_iENCToolbarPosY = tbp_incanvas.y;
1602 g_iENCToolbarPosX = tbp_incanvas.x;
1606 g_bframemax = IsMaximized();
1609 FrameTenHzTimer.Stop();
1611 FrameCOGTimer.Stop();
1625 if (g_bAutoAnchorMark) {
1626 bool watching_anchor =
false;
1634 wxDateTime now = wxDateTime::Now();
1635 wxTimeSpan uptime = now.Subtract(g_start_time);
1637 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1638 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1643 if (g_declutter_anchorage) {
1644 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1645 if (pr->GetName().StartsWith(
"Anchorage")) {
1646 double a =
gLat - pr->m_lat;
1647 double b =
gLon - pr->m_lon;
1648 double l = sqrt((a * a) + (b * b));
1651 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1653 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1654 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1662 wxString name = now.Format();
1663 name.Prepend(_(
"Anchorage created "));
1669 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1674 pConfig->UpdateSettings();
1678 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1682 NavObj_dB::GetInstance().Close();
1686 pConfig->DeleteGroup(
"/Routes");
1687 pConfig->DeleteGroup(
"/Marks");
1713 if (g_pAISTargetList) {
1714 g_pAISTargetList->Disconnect_decoder();
1715 g_pAISTargetList->Destroy();
1722 if (RouteManagerDialog::getInstanceFlag()) {
1723 if (pRouteManagerDialog) {
1724 pRouteManagerDialog->Destroy();
1725 pRouteManagerDialog = NULL;
1739 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1741 if (cc) cc->Destroy();
1744 g_canvasArray.Clear();
1765 MyApp &app = wxGetApp();
1766 app.m_comm_bridge.SaveConfig();
1786 auto ®istry = CommDriverRegistry::GetInstance();
1787 registry.CloseAllDrivers();
1790 for (
auto *cp : TheConnectionParams()) {
1795 while (pLayerList->size())
delete *pLayerList->begin();
1799 ReleaseApiListeners();
1802 g_bTempShowMenuBar =
false;
1804#define THREAD_WAIT_SECONDS 5
1814 wxLogMessage(
"Starting compressor pool drain");
1815 wxDateTime now = wxDateTime::Now();
1816 time_t stall = now.GetTicks();
1817 time_t end = stall + THREAD_WAIT_SECONDS;
1820 while (stall < end) {
1821 wxDateTime later = wxDateTime::Now();
1822 stall = later.GetTicks();
1825 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1834 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1840 uninitIXNetSystem();
1844 wxLogMessage(
"gFrame destroyed.");
1847#ifndef USE_ANDROID_GLES2
1848 qDebug() <<
"Calling OnExit()";
1852 wxTheApp->ExitMainLoop();
1855void MyFrame::OnMove(wxMoveEvent &event) {
1856 auto idx = wxDisplay::GetFromWindow(
this);
1869 DEBUG_LOG <<
"Moved to " << idx
1870#if wxCHECK_VERSION(3, 1, 6)
1871 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1872 << wxDisplay(idx).GetPPI().GetY()
1873 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1875 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1876 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1877 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1878 << wxGetDisplaySizeMM().GetY()
1879 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1888 if (g_config_display_size_manual) {
1897 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1900 cc->SetMUIBarPosition();
1909 UpdateGPSCompassStatusBoxes();
1919 PositionIENCToolbar();
1925 g_nframewin_posx = GetPosition().x;
1926 g_nframewin_posy = GetPosition().y;
1929void MyFrame::ProcessCanvasResize() {
1930 UpdateGPSCompassStatusBoxes(
true);
1934 PositionIENCToolbar();
1937 TriggerRecaptureTimer();
1941void MyFrame::TriggerRecaptureTimer() {
1942 m_recaptureTimer.Start(
1943 1000, wxTIMER_ONE_SHOT);
1946void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1948void MyFrame::SetCanvasSizes(wxSize frameSize) {
1949 if (!g_canvasArray.GetCount())
return;
1952 int cccw = frameSize.x;
1953 int ccch = frameSize.y;
1957 switch (g_canvasConfig) {
1961 cc = g_canvasArray.Item(0);
1963 cc->GetSize( &cur_width, &cur_height );
1964 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1966 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1968 cc->SetSize( 0, 0, cccw, ccch );
1976 cc = g_canvasArray.Item(1);
1978 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1979 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1981 ccw = wxMin(ccw, cccw * 8 / 10);
1982 ccw = wxMax(ccw, cccw * 2 / 10);
1986 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1993 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2010void MyFrame::OnIconize(wxIconizeEvent &event) {
2020 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2022 if (cc && cc->GetMUIBar()) {
2023 if (cc->GetMUIBar()->GetCanvasOptions()) {
2024 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2025 cc->GetMUIBar()->PushCanvasOptions();
2034void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2036void MyFrame::ODoSetSize() {
2038 GetClientSize(&x, &y);
2041 if (m_pStatusBar != NULL) {
2042 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2043 int currentCount = m_pStatusBar->GetFieldsCount();
2044 if (currentCount != m_StatusBarFieldCount) {
2045 if ((currentCount > 0) && (currentCount < 7)) {
2048 int widths[] = {2, 2, 2, 2, 2, 2};
2049 m_pStatusBar->SetStatusWidths(currentCount, widths);
2052 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2055 if (m_StatusBarFieldCount) {
2060 if (m_StatusBarFieldCount > 2) {
2061 int widths[] = {-6, -5, -5, -6, -4};
2062 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2063 }
else if (m_StatusBarFieldCount == 2) {
2064 int cwidth = x * 90 / 100;
2065 int widths[] = {100, 100};
2066 widths[0] = cwidth * 6.4 / 10.0;
2067 widths[1] = cwidth * 3.6 / 10.0;
2068 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2070 int widths[] = {100, 100};
2071 widths[0] = x * 90 / 100;
2072 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2075 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2076 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2077 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2079 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2081 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2089 m_pStatusBar->GetFieldRect(0, stat_box);
2092 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2094 wxFont sys_font = *wxNORMAL_FONT;
2095 int try_font_size = sys_font.GetPointSize();
2098 int min_font_size = 10;
2108 wxFont *statusBarFont =
2109 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2110 int font_size = statusBarFont->GetPointSize();
2112 font_size = wxMin(font_size,
2115 wxMax(font_size, min_font_size);
2118 font_size = statusBarFont->GetPointSize();
2125 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2126 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2128 int min_height = stat_box.height;
2130 m_pStatusBar->SetFont(*pstat_font);
2131 m_pStatusBar->SetForegroundColour(
2132 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2134 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2136 (min_height >> 1) * 2;
2137 m_pStatusBar->SetMinHeight(min_height);
2146 SetCanvasSizes(GetClientSize());
2148 UpdateGPSCompassStatusBoxes(
true);
2150 if (
console) PositionConsole();
2153 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2155 if (cc) cc->FormatPianoKeys();
2161 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2162 GetPrimaryCanvas()->GetCompass()->GetRect());
2188 options_lastWindowSize = wxSize(0, 0);
2189 options_lastWindowPos = wxPoint(0, 0);
2196 if (!b_inCloseWindow) {
2199 resizeAndroidPersistents();
2203 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2204 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2210void MyFrame::PositionConsole() {
2211#if defined(__WXMSW__) || defined(__WXMAC__)
2212 if (NULL == GetPrimaryCanvas())
return;
2214 int ccx, ccy, ccsx, ccsy, consx, consy;
2216 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2219 consoleHost->GetSize(&ccsx, &ccsy);
2220 consoleHost->GetPosition(&ccx, &ccy);
2222 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2223 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2224 consoleHost = GetPrimaryCanvas();
2229 if (consoleHost->GetCompass()) {
2230 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2232 if (compass_rect.y < 100)
2233 yOffset = compass_rect.y + compass_rect.height + 45;
2237 wxSize csz =
console->GetSize();
2241 wxPoint screen_pos =
2242 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2245 if (NULL == GetPrimaryCanvas())
return;
2247 int ccx, ccy, ccsx, ccsy, consx, consy;
2249 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2252 consoleHost->GetSize(&ccsx, &ccsy);
2253 consoleHost->GetPosition(&ccx, &ccy);
2255 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2256 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2257 consoleHost = GetPrimaryCanvas();
2260 int yTopOffset = 60;
2261 int yBottomOffset = 0;
2263 if (consoleHost->GetCompass()) {
2264 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2266 if (compass_rect.y < 100)
2267 yTopOffset = compass_rect.y + compass_rect.height;
2269 if (consoleHost->GetMUIBar()) {
2270 wxRect mui_rect = consoleHost->GetMUIBarRect();
2271 yBottomOffset = ccsy - mui_rect.y;
2275 wxSize csz =
console->GetSize();
2278 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2280 if (consy < yAvail) {
2281 yFinal = (yAvail - consy) / 2;
2282 yFinal += yTopOffset;
2283 }
else if (
console->GetCDI()->IsShown()) {
2284 int cdi_height =
console->GetCDI()->GetSize().y;
2285 int consy_no_cdi = consy - cdi_height;
2286 yFinal = (yAvail - consy_no_cdi) / 2;
2287 yFinal += yTopOffset;
2291 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2296void MyFrame::UpdateAllFonts() {
2305 DestroyPersistentDialogs();
2307 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2312void MyFrame::DestroyPersistentDialogs() {
2313 if (g_pais_query_dialog_active) {
2314 g_pais_query_dialog_active->Hide();
2315 g_pais_query_dialog_active->Destroy();
2316 g_pais_query_dialog_active = NULL;
2344void MyFrame::RefreshGroupIndices() {
2346 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2348 if (cc) cc->canvasRefreshGroupIndex();
2352void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2355 switch (event.GetId()) {
2356 case ID_MENU_SCALE_OUT:
2357 DoStackDelta(GetPrimaryCanvas(), 1);
2361 case ID_MENU_SCALE_IN:
2362 DoStackDelta(GetPrimaryCanvas(), -1);
2366 case ID_MENU_ZOOM_IN: {
2367 if (GetFocusCanvas()) {
2368 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2373 case ID_MENU_ZOOM_OUT: {
2374 if (GetFocusCanvas()) {
2375 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2380 case ID_MENU_ROUTE_NEW: {
2381 if (GetFocusCanvas()) {
2382 if (0 == GetFocusCanvas()->m_routeState) {
2383 GetFocusCanvas()->StartRoute();
2385 GetFocusCanvas()->FinishRoute();
2391 case ID_MENU_TOOL_MEASURE: {
2392 GetPrimaryCanvas()->StartMeasureRoute();
2396 case ID_MENU_TOOL_NMEA_DBG_LOG:
2397 m_data_monitor->Show();
2398 m_data_monitor->Raise();
2401 case ID_MENU_TOOL_IO_MONITOR:
2402 m_data_monitor->Show();
2405 case ID_MENU_MARK_BOAT: {
2410 case ID_MENU_MARK_CURSOR: {
2415 case ID_MENU_NAV_FOLLOW: {
2416 if (
gFrame->GetPrimaryCanvas())
2417 gFrame->GetPrimaryCanvas()->TogglebFollow();
2421 case ID_MENU_CHART_OUTLINES: {
2422 ToggleChartOutlines(GetFocusCanvas());
2426 case ID_MENU_CHART_QUILTING: {
2427 ToggleQuiltMode(GetFocusCanvas());
2431 case ID_MENU_UI_CHARTBAR: {
2432 ToggleChartBar(GetFocusCanvas());
2436 case ID_MENU_ENC_TEXT:
2438 ToggleENCText(GetFocusCanvas());
2441 case ID_MENU_ENC_LIGHTS: {
2442 ToggleLights(GetFocusCanvas());
2445 case ID_MENU_ENC_SOUNDINGS: {
2446 ToggleSoundings(GetFocusCanvas());
2449 case ID_MENU_ENC_ANCHOR: {
2450 ToggleAnchor(GetFocusCanvas());
2453 case ID_MENU_ENC_DATA_QUALITY: {
2454 ToggleDataQuality(GetFocusCanvas());
2457 case ID_MENU_SHOW_NAVOBJECTS: {
2458 ToggleNavobjects(GetFocusCanvas());
2462 case ID_MENU_AIS_TARGETS: {
2463 ToggleAISDisplay(GetFocusCanvas());
2466 case ID_MENU_AIS_MOORED_TARGETS: {
2467 g_bHideMoored = !g_bHideMoored;
2470 case ID_MENU_AIS_SCALED_TARGETS: {
2471 ToggleAISMinimizeTargets(GetFocusCanvas());
2475 case ID_MENU_AIS_TARGETLIST: {
2476 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2480 case ID_MENU_AIS_TRACKS: {
2481 g_bAISShowTracks = !g_bAISShowTracks;
2482 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2486 case ID_MENU_AIS_CPADIALOG: {
2487 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2488 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2489 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2490 if (g_bAIS_CPA_Alert) {
2491 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2496 case ID_MENU_AIS_CPASOUND: {
2497 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2498 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2502 case ID_MENU_AIS_CPAWARNING: {
2503 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2504 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2508 case wxID_PREFERENCES:
2515 case ID_SETTINGS_NEW: {
2520 case ID_SETTINGS_DELETE: {
2523 g_pOptions =
nullptr;
2527 case ID_RELOAD_CHARTS: {
2532 case ID_MENU_SETTINGS_BASIC: {
2535 androidDisableFullScreen();
2537 DoAndroidPreferences();
2544 case ID_MENU_UI_FULLSCREEN: {
2549 case ID_MENU_SHOW_CURRENTS: {
2550 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2551 GetFocusCanvas()->ReloadVP();
2552 GetFocusCanvas()->Refresh(
false);
2556 case ID_MENU_SHOW_TIDES: {
2557 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2558 GetFocusCanvas()->ReloadVP();
2559 GetFocusCanvas()->Refresh(
false);
2579 case ID_MENU_UI_COLSCHEME:
2580 case ID_COLSCHEME: {
2581 ToggleColorScheme();
2590 case ID_MENU_OQUIT: {
2595 case ID_MENU_ROUTE_MANAGER:
2596 case ID_ROUTEMANAGER: {
2597 pRouteManagerDialog = RouteManagerDialog::getInstance(
2600 if (pRouteManagerDialog->IsShown())
2601 pRouteManagerDialog->Hide();
2603 pRouteManagerDialog->UpdateRouteListCtrl();
2604 pRouteManagerDialog->UpdateTrkListCtrl();
2605 pRouteManagerDialog->UpdateWptListCtrl();
2606 pRouteManagerDialog->UpdateLayListCtrl();
2608 pRouteManagerDialog->Show();
2612 pRouteManagerDialog->Centre();
2613 pRouteManagerDialog->Raise();
2619 case ID_MENU_NAV_TRACK:
2621 if (!g_bTrackActive) {
2623 g_bTrackCarryOver =
true;
2626 g_bTrackCarryOver =
false;
2627 RefreshAllCanvas(
true);
2632 case ID_MENU_CHART_NORTHUP: {
2633 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2636 case ID_MENU_CHART_COGUP: {
2637 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2640 case ID_MENU_CHART_HEADUP: {
2641 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2645 case ID_MENU_MARK_MOB:
2651 case ID_MASTERTOGGLE: {
2653 wxString tip = _(
"Show Toolbar");
2654 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2656 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2658 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2661 if (g_bmasterToolbarFull)
2662 m_nMasterToolCountShown =
2666 m_nMasterToolCountShown = 2;
2668 m_nMasterToolCountShown =
2671 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2679 case ID_CMD_SELECT_CHART_TYPE: {
2680 selectChartDisplay(event.GetExtraLong(), -1);
2684 case ID_CMD_SELECT_CHART_FAMILY: {
2685 selectChartDisplay(-1, event.GetExtraLong());
2689 case ID_CMD_APPLY_SETTINGS: {
2690 applySettingsString(event.GetString());
2692 androidRestoreFullScreen();
2698 case ID_CMD_NULL_REFRESH: {
2703 case ID_CMD_SETVP: {
2704 setStringVP(event.GetString());
2708 case ID_CMD_INVALIDATE: {
2714 case ID_CMD_POST_JSON_TO_PLUGINS: {
2720 int numErrors = reader.
Parse(event.GetString(), &root);
2721 if (numErrors == 0) {
2722 if (root[
"MessageID"].IsString()) {
2723 wxString MsgID = root[
"MessageID"].
AsString();
2747 ArrayOfPlugInToolbarTools tool_array =
2749 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2751 if (event.GetId() == pttc->id) {
2752 if (pttc->m_pplugin)
2774bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2775 bool viz_now = g_bmasterToolbarFull;
2778 wxString tip = _(
"Show Toolbar");
2780 tip = _(
"Hide Toolbar");
2782 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2785 bool toggle =
false;
2786 if (viz && !g_bmasterToolbarFull)
2789 else if (!viz && g_bmasterToolbarFull)
2793 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2796 if (g_bmasterToolbarFull)
2797 m_nMasterToolCountShown =
2801 m_nMasterToolCountShown = 2;
2803 m_nMasterToolCountShown =
2806 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2812void MyFrame::ScheduleReloadCharts() {
2813 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2814 evt.SetId(ID_RELOAD_CHARTS);
2815 GetEventHandler()->AddPendingEvent(evt);
2818void MyFrame::ScheduleDeleteSettingsDialog() {
2819 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2820 evt.SetId(ID_SETTINGS_DELETE);
2821 GetEventHandler()->AddPendingEvent(evt);
2824void MyFrame::ScheduleSettingsDialog() {
2825 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2826 evt.SetId(ID_SETTINGS);
2827 GetEventHandler()->AddPendingEvent(evt);
2830void MyFrame::ScheduleSettingsDialogNew() {
2831 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2832 evt.SetId(ID_SETTINGS_NEW);
2833 GetEventHandler()->AddPendingEvent(evt);
2836void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2837 UpdateCanvasConfigDescriptors();
2839 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2840 CreateCanvasLayout(
true);
2842 CreateCanvasLayout();
2846 ConfigureStatusBar();
2847 wxSize lastOptSize = options_lastWindowSize;
2852 options_lastWindowSize = lastOptSize;
2856 ScheduleSettingsDialogNew();
2858 ScheduleSettingsDialog();
2863 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2866 int index_hint = -1;
2867 if (i < pathArray.GetCount())
2868 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2869 cc->canvasChartsRefresh(index_hint);
2870 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2879 return GetPrimaryCanvas();
2882void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2883 if (g_bmasterToolbarFull) {
2884#ifndef OCPN_TOOLBAR_ANIMATE
2885 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2888 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2889 m_nMasterToolCountShown++;
2894 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2902#ifndef OCPN_TOOLBAR_ANIMATE
2903 m_nMasterToolCountShown = 1;
2905 if (m_nMasterToolCountShown > 1) {
2906 m_nMasterToolCountShown--;
2910 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2920void MyFrame::InvalidateAllGL() {
2923 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2933void MyFrame::RefreshAllCanvas(
bool bErase) {
2935 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2938 cc->Refresh(bErase);
2943void MyFrame::setStringVP(wxString VPS) {
2948 wxStringTokenizer tkz(VPS,
";");
2950 wxString token = tkz.GetNextToken();
2952 token.ToDouble(&lat);
2954 token = tkz.GetNextToken();
2956 token.ToDouble(&lon);
2958 token = tkz.GetNextToken();
2960 token.ToDouble(&scale_ppm);
2962 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2965void MyFrame::DoSettingsNew() {
2972void MyFrame::DoSettings() {
2976 ApplyGlobalSettings(
true);
2979 bool b_loadHarmonics =
false;
2980 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2983 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2986 if (b_loadHarmonics) LoadHarmonics();
2994 g_bShowChartBar = !g_bShowChartBar;
2996 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3001 if (g_bShowChartBar) {
3003 UpdateControlBar(cc);
3006 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3009void MyFrame::ToggleColorScheme() {
3010 static bool lastIsNight;
3011 ColorScheme s = GetColorScheme();
3014 if (lastIsNight && is == 3)
3017 lastIsNight =
false;
3019 if (lastIsNight) is = 2;
3020 if (is == 3) lastIsNight =
true;
3021 s = (ColorScheme)is;
3022 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3024 SetAndApplyColorScheme(s);
3027void MyFrame::ToggleFullScreen() {
3028 bool to = !IsFullScreen();
3033 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3035 ShowFullScreen(to, style);
3038 UpdateAllToolbars(global_color_scheme);
3040 UpdateControlBar(GetPrimaryCanvas());
3042 TriggerRecaptureTimer();
3045void MyFrame::ActivateMOB() {
3047 wxDateTime mob_time = wxDateTime::Now();
3048 wxString mob_label(_(
"MAN OVERBOARD"));
3049 mob_label += _(
" on ");
3050 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3054 pWP_MOB->SetShared(
true);
3056 pWP_MOB->SetWaypointArrivalRadius(
3058 pWP_MOB->SetUseSca(
false);
3060 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3068 new RoutePoint(zlat, zlon, g_default_wp_icon,
3069 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3070 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3075 temp_route->AddPoint(pWP_src);
3076 temp_route->AddPoint(pWP_MOB);
3078 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3088 temp_route->SetRouteArrivalRadius(-1.0);
3094 v[
"GUID"] = temp_route->
m_GUID;
3095 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3096 SendJSONMessageToAllPlugins(msg_id, v);
3099 if (RouteManagerDialog::getInstanceFlag()) {
3100 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3101 pRouteManagerDialog->UpdateRouteListCtrl();
3102 pRouteManagerDialog->UpdateWptListCtrl();
3107 RefreshAllCanvas(
false);
3109 wxString mob_message(_(
"MAN OVERBOARD"));
3110 mob_message += _(
" Time: ");
3111 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3112 mob_message += _(
" Position: ");
3113 mob_message += toSDMM(1,
gLat);
3115 mob_message += toSDMM(2,
gLon);
3116 wxLogMessage(mob_message);
3118void MyFrame::TrackOn() {
3119 g_bTrackActive =
true;
3127 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3129 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3131 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3134 androidSetTrackTool(
true);
3137 if (RouteManagerDialog::getInstanceFlag()) {
3138 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3139 pRouteManagerDialog->UpdateTrkListCtrl();
3140 pRouteManagerDialog->UpdateRouteListCtrl();
3146 if (name.IsEmpty()) {
3152 name = _(
"(Unnamed Track)");
3156 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3157 SendJSONMessageToAllPlugins(msg_id, v);
3158 g_FlushNavobjChangesTimeout =
3162Track *MyFrame::TrackOff(
bool do_add_point) {
3167 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3169 SendJSONMessageToAllPlugins(msg_id, v);
3178 if (g_bTrackDaily) {
3183 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3184 return_val = pExtendTrack;
3191 g_bTrackActive =
false;
3193 if (RouteManagerDialog::getInstanceFlag()) {
3194 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3195 pRouteManagerDialog->UpdateTrkListCtrl();
3196 pRouteManagerDialog->UpdateRouteListCtrl();
3200 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3202 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3203 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3206 androidSetTrackTool(
false);
3209 g_FlushNavobjChangesTimeout =
3215bool MyFrame::ShouldRestartTrack() {
3217 time_t now = wxDateTime::Now().GetTicks();
3218 time_t today = wxDateTime::Today().GetTicks();
3220 switch (g_track_rotate_time_type) {
3222 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3224 case TIME_TYPE_COMPUTER:
3225 rotate_at = g_track_rotate_time;
3229 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3230 rotate_at = g_track_rotate_time + utc_offset;
3233 if (rotate_at > 86400)
3235 else if (rotate_at < 0)
3237 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3238 now - today >= rotate_at) {
3239 if (m_last_track_rotation_ts == 0) {
3240 if (now - today > rotate_at)
3241 m_last_track_rotation_ts = today + rotate_at;
3243 m_last_track_rotation_ts = today + rotate_at - 86400;
3246 m_last_track_rotation_ts = now;
3252void MyFrame::TrackDailyRestart() {
3254 Track *pPreviousTrack = TrackOff(
true);
3261 if (pPreviousTrack) {
3262 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3266 if (RouteManagerDialog::getInstanceFlag()) {
3267 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3268 pRouteManagerDialog->UpdateTrkListCtrl();
3269 pRouteManagerDialog->UpdateRouteListCtrl();
3274void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3276 cc->SetUpMode(mode);
3278 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3279 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3280 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3283 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3288 cc->SetShowENCText(!cc->GetShowENCText());
3290 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3298void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3301 cc->SetENCDisplayCategory(nset);
3303 UpdateGlobalMenuItems();
3314 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3316 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3325 cc->SetShowENCLights(!cc->GetShowENCLights());
3327 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3337void MyFrame::ToggleRocks(
void )
3343 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3344 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3345 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3346 pOLE->nViz = !pOLE->nViz;
3350 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3351 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3352 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3355 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3359 ps52plib->GenerateStateHash();
3366 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3368 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3376 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3378 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3393 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3394 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3399 cc->SetShowAIS(!cc->GetShowAIS());
3400 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3404void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3405 cc->SetAttenAIS(!cc->GetAttenAIS());
3406 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3412 cc->m_bFollow =
true;
3415 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3419 SetChartUpdatePeriod();
3427 cc->m_bFollow =
false;
3429 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3433 SetChartUpdatePeriod();
3436void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3437 cc->SetShowOutlines(!cc->GetShowOutlines());
3439 RefreshAllCanvas(
false);
3443 if (g_bopengl) InvalidateAllGL();
3446 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3449void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3451void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3453 bool enabled = m_pMenuBar->IsEnabled(item_id);
3454 m_pMenuBar->Enable(item_id,
false);
3455 m_pMenuBar->Check(item_id, state);
3456 m_pMenuBar->Enable(item_id, enabled);
3460void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3467void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3468 wxBitmap *bmpRollover) {
3470 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3475void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3476 wxString rolloverSVGfile,
3477 wxString toggledSVGfile) {
3480 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3484void MyFrame::ConfigureStatusBar() {
3486 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3489 UseNativeStatusBar(
false);
3492 if (g_bShowStatusBar) {
3493 if (!m_pStatusBar) {
3495 CreateStatusBar(m_StatusBarFieldCount, 0);
3496 ApplyGlobalColorSchemetoStatusBar();
3501 m_pStatusBar->Destroy();
3502 m_pStatusBar = NULL;
3508void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3509 ConfigureStatusBar();
3511 wxSize lastOptSize = options_lastWindowSize;
3517 options_lastWindowSize = lastOptSize;
3519 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3522wxString _menuText(wxString name, wxString shortcut) {
3526 menutext <<
"\t" << shortcut;
3531void MyFrame::BuildMenuBar() {
3537 bool showMenuBar =
true;
3539 bool showMenuBar = g_bShowMenuBar;
3551 m_pMenuBar =
new wxMenuBar();
3552 RegisterGlobalMenuItems();
3553 SetMenuBar(m_pMenuBar);
3557 UpdateGlobalMenuItems();
3562 m_pMenuBar->Destroy();
3568void MyFrame::RegisterGlobalMenuItems() {
3569 if (!m_pMenuBar)
return;
3571 wxMenu *nav_menu =
new wxMenu();
3572 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3573 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3574 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3575 nav_menu->AppendSeparator();
3576 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3577 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3578 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3579 nav_menu->AppendSeparator();
3581 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3582 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3584 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3585 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3587 nav_menu->AppendSeparator();
3588 nav_menu->Append(ID_MENU_SCALE_IN,
3589 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3590 nav_menu->Append(ID_MENU_SCALE_OUT,
3591 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3593 nav_menu->AppendSeparator();
3594 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3596 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3598 wxMenu *view_menu =
new wxMenu();
3600 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3601 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3602 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3603 _menuText(_(
"Show Chart Outlines"),
"O"));
3605 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3606 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3607 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3608 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3610 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3611 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3613 view_menu->AppendSeparator();
3615 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3616 _menuText(_(
"Show ENC text"),
"T"));
3617 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3618 _menuText(_(
"Show ENC Lights"),
"L"));
3619 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3620 _menuText(_(
"Show ENC Soundings"),
"S"));
3621 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3622 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3624 _menuText(_(
"Show ENC Data Quality"),
"U"));
3625 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3626 _menuText(_(
"Show Navobjects"),
"V"));
3628 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3629 _menuText(_(
"Show ENC text"),
"Alt-T"));
3630 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3631 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3632 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3633 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3634 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3635 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3636 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3637 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3638 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3639 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3641 view_menu->AppendSeparator();
3642 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3643 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3644 view_menu->AppendSeparator();
3646 view_menu->Append(ID_MENU_UI_COLSCHEME,
3647 _menuText(_(
"Change Color Scheme"),
"C"));
3649 view_menu->Append(ID_MENU_UI_COLSCHEME,
3650 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3653 view_menu->AppendSeparator();
3655 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3656 _menuText(_(
"Toggle Full Screen"),
"F11"));
3658 m_pMenuBar->Append(view_menu, _(
"&View"));
3660 wxMenu *ais_menu =
new wxMenu();
3661 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3663 _(
"Attenuate less critical AIS targets"));
3664 ais_menu->AppendSeparator();
3665 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3666 _(
"Hide Moored AIS Targets"));
3667 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3669 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3672 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3673 _menuText(_(
"Show CPA Warnings"),
"W"));
3675 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3676 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3679 ais_menu->AppendSeparator();
3680 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3681 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3683 wxMenu *tools_menu =
new wxMenu();
3684 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3685 _menuText(_(
"Data Monitor"),
"Alt-C"));
3687 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3688 _menuText(_(
"Measure Distance"),
"M"));
3690 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3691 _menuText(_(
"Measure Distance"),
"Alt-M"));
3694 tools_menu->AppendSeparator();
3695 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3696 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3697 tools_menu->AppendSeparator();
3698 tools_menu->Append(ID_MENU_MARK_BOAT,
3699 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3700 tools_menu->Append(ID_MENU_MARK_CURSOR,
3701 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3702 tools_menu->AppendSeparator();
3706 _menuText(_(
"Drop MOB Marker"),
3708 tools_menu->AppendSeparator();
3709 tools_menu->Append(wxID_PREFERENCES,
3710 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3712 tools_menu->Append(ID_MENU_MARK_MOB,
3713 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3714 tools_menu->AppendSeparator();
3715 tools_menu->Append(wxID_PREFERENCES,
3716 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3718 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3721 wxMenu *window_menu =
new wxMenu();
3722 m_pMenuBar->Append(window_menu, _(
"&Window"));
3725 wxMenu *help_menu =
new wxMenu();
3726 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3727 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3728 m_pMenuBar->Append(help_menu, _(
"&Help"));
3731 UpdateGlobalMenuItems();
3734void MyFrame::UpdateGlobalMenuItems() {
3735 if (!m_pMenuBar)
return;
3737 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3738 ->Check(GetPrimaryCanvas()->m_bFollow);
3739 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3740 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3741 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3742 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3743 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3744 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3745 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3746 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3747 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3748 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3749 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3750 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3751 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3753 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3754 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3755 if (g_bAIS_CPA_Alert) {
3756 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3757 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3759 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3760 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3763 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3764 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3765 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3768 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3769 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3770 ->Check(ps52plib->GetShowSoundings());
3772 bool light_state =
false;
3774 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3776 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3777 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3778 light_state = (pOLE->nViz == 1);
3783 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3784 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3788 DisCat nset = ps52plib->GetDisplayCategory();
3789 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3790 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3791 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3792 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3793 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3794 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3795 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3797 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3798 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3799 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3804void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3805 if (!m_pMenuBar)
return;
3807 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3809 if (cc->GetUpMode() == NORTH_UP_MODE)
3810 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3811 else if (cc->GetUpMode() == COURSE_UP_MODE)
3812 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3814 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3816 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3817 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3818 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3819 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3820 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3821 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3822 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3823 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3824 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3825 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3826 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3827 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3828 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3829 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3830 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3833 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3834 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3837 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3839 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3840 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3845 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3849 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3850 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3851 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3852 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3853 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3854 ->Check(cc->GetShowENCDataQual());
3855 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3857 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3858 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3859 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3864void MyFrame::InvalidateAllCanvasUndo() {
3866 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3868 if (cc) cc->undo->InvalidateUndo();
3872void MyFrame::SubmergeAllCanvasToolbars() {
3874 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3876 if (cc) cc->SubmergeToolbar();
3880void MyFrame::SurfaceAllCanvasToolbars() {
3881 if (g_bshowToolbar) {
3883 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3885 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3892void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3894 if (lon > 180.0) lon -= 360.0;
3899 cc->JumpToPosition(lat, lon,
scale);
3902 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3906void MyFrame::UpdateCanvasConfigDescriptors() {
3908 for (
unsigned int i = 0;
3909 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3910 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3918 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3919 cc->GroupID = chart->m_groupIndex;
3922 cc->
bQuilt = chart->GetQuiltMode();
3929 cc->
bFollow = chart->m_bFollow;
3934 int upmode = chart->GetUpMode();
3935 if (upmode == COURSE_UP_MODE)
3937 else if (upmode == HEAD_UP_MODE)
3944void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3945 if (!RBBox.GetValid())
return;
3947 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3948 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3951 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3952 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3960 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3961 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3963 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3964 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3966 cc->GetSize(&ww, &wh);
3968 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3970 ppm = wxMin(ppm, 1.0);
3976void MyFrame::PrepareOptionsClose(
options *settings,
3977 int settings_return_value) {
3979 options_lastPage = settings->lastPage;
3984 if (options_lastPage == 1) options_lastPage = 0;
3986 options_subpage = settings->lastSubPage;
3987 options_lastWindowPos = settings->lastWindowPos;
3988 options_lastWindowSize = settings->lastWindowSize;
3991 androidEnableBackButton(
true);
3992 androidEnableOptionsMenu(
true);
3993 androidRestoreFullScreen();
3994 androidEnableRotation();
3999void MyFrame::DoOptionsDialog() {
4001 AbstractPlatform::ShowBusySpinner();
4004 pConfig->SetPath(
"/Settings");
4005 pConfig->Read(
"OptionsSizeX", &sx, -1);
4006 pConfig->Read(
"OptionsSizeY", &sy, -1);
4008 wxWindow *optionsParent =
this;
4010 optionsParent = GetPrimaryCanvas();
4015 AbstractPlatform::HideBusySpinner();
4019 g_options->SetInitChartDir(*pInit_Chart_Dir);
4023 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4024 g_options->SetWorkDirListPtr(pWorkDirArray);
4030 prev_locale = g_locale;
4031 g_options->SetInitialPage(options_lastPage, options_subpage);
4034 g_options->lastWindowPos = options_lastWindowPos;
4035 if (options_lastWindowPos != wxPoint(0, 0)) {
4037 g_options->SetSize(options_lastWindowSize);
4041 if (options_lastWindowSize != wxSize(0, 0)) {
4042 g_options->SetSize(options_lastWindowSize);
4047 androidEnableBackButton(
false);
4048 androidEnableOptionsMenu(
false);
4049 androidDisableFullScreen();
4057 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4060 wxString chart_file_name;
4061 if (cc->GetQuiltMode()) {
4062 int dbi = cc->GetQuiltRefChartdbIndex();
4063 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4065 if (cc->m_singleChart)
4066 chart_file_name = cc->m_singleChart->GetFullPath();
4069 pathArray.Add(chart_file_name);
4075 last_canvasConfig = g_canvasConfig;
4078 g_last_ChartScaleFactor = g_ChartScaleFactor;
4084void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4085 bool b_need_refresh =
false;
4087 if ((rr & VISIT_CHARTS) &&
4088 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4090 UpdateChartDatabaseInplace(*pNewDirArray,
4091 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4094 b_need_refresh =
true;
4098 if (rr & STYLE_CHANGED) {
4101 _(
"Please restart OpenCPN to activate language or style changes."),
4102 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4105 bool b_groupchange =
false;
4106 if (((rr & VISIT_CHARTS) &&
4107 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4108 (rr & GROUPS_CHANGED)) {
4109 b_groupchange = ScrubGroupArray();
4111 RefreshGroupIndices();
4114 if (rr & GROUPS_CHANGED || b_groupchange) {
4115 pConfig->DestroyConfigGroups();
4119 if (rr & TIDES_CHANGED) {
4125 if (rr & S52_CHANGED) {
4126 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4129 pConfig->UpdateSettings();
4137 g_Platform->GetDisplayDPmm());
4140 double stuffcog = NAN;
4141 double stuffsog = NAN;
4142 if (!std::isnan(
gCog)) stuffcog =
gCog;
4143 if (!std::isnan(
gSog)) stuffsog =
gSog;
4145 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4146 COGFilterTable[i] = stuffcog;
4147 SOGFilterTable[i] = stuffsog;
4150 SetChartUpdatePeriod();
4152 if (rr & GL_CHANGED) {
4156 b_need_refresh =
true;
4159 if (rr & S52_CHANGED) {
4160 b_need_refresh =
true;
4164 if (rr & REBUILD_RASTER_CACHE) {
4166 GetPrimaryCanvas()->Disable();
4168 GetPrimaryCanvas()->Enable();
4173 if (g_config_display_size_manual &&
4181 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4188 int rrt = rr & S52_CHANGED;
4190 (rrt == S52_CHANGED) ||
4191 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4201 ps52plib->SetScaleFactorExp(
4202 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4203 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4207 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4209 if (cc) cc->ApplyGlobalSettings();
4214 bool ztc = g_bEnableZoomToCursor;
4215 g_bEnableZoomToCursor =
4219 if (!GetPrimaryCanvas()->IsFrozen())
4221 g_bEnableZoomToCursor = ztc;
4224 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4233 SetGPSCompassScale();
4235 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4238 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4239 cc->UpdateCanvasControlBar();
4242 UpdateGPSCompassStatusBoxes();
4244 SetAllToolbarScale();
4245 RequestNewToolbars();
4248 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4251 cc->RebuildCursors();
4256 bool b_masterScaleChange =
false;
4257 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4258 b_masterScaleChange =
true;
4260 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4261 RequestNewMasterToolbar(
true);
4263 bool bMuiChange =
false;
4269 if (b_masterScaleChange || bMuiChange) {
4271 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4274 cc->ProcessNewGUIScale();
4280 if (rr & LOCALE_CHANGED) {
4281 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4283 rr |= NEED_NEW_OPTIONS;
4292 g_last_ChartScaleFactor = g_ChartScaleFactor;
4294 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4299bool MyFrame::CheckGroup(
int igroup) {
4300 if (igroup == 0)
return true;
4304 if (!pGroup->m_element_array.size())
4307 for (
const auto &elem : pGroup->m_element_array) {
4308 for (
unsigned int ic = 0;
4309 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4311 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4313 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4320bool MyFrame::ScrubGroupArray() {
4325 bool b_change =
false;
4326 unsigned int igroup = 0;
4327 while (igroup < g_pGroupArray->GetCount()) {
4328 bool b_chart_in_element =
false;
4331 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4332 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4334 for (
unsigned int ic = 0;
4335 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4337 wxString chart_full_path = pcte->GetFullSystemPath();
4339 if (chart_full_path.StartsWith(element_root)) {
4340 b_chart_in_element =
true;
4346 if (!b_chart_in_element) {
4347 wxString test_string =
"GSHH";
4348 if (element_root.Upper().Contains(test_string))
4349 b_chart_in_element =
true;
4352 if (!b_chart_in_element)
4354 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4366void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4368 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4370 if (cc && (cc != ccThis)) cc->Refresh();
4375void MyFrame::ChartsRefresh() {
4378 AbstractPlatform::ShowBusySpinner();
4380 bool b_run = FrameTimer1.IsRunning();
4383 FrameTenHzTimer.Stop();
4386 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4389 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4390 if (cc->GetQuiltMode()) {
4391 currentIndex = cc->GetQuiltReferenceChartIndex();
4393 cc->canvasChartsRefresh(currentIndex);
4397 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4398 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4400 AbstractPlatform::HideBusySpinner();
4403void MyFrame::InvalidateAllQuilts() {
4404 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4407 cc->InvalidateQuilt();
4408 cc->SetQuiltRefChart(-1);
4409 cc->m_singleChart = NULL;
4414bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4416 const wxString &ChartListFileName) {
4417 bool b_run = FrameTimer1.IsRunning();
4419 FrameTenHzTimer.Stop();
4421 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4422 FrameCOGTimer.Stop();
4425 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4428 cc->InvalidateQuilt();
4429 cc->SetQuiltRefChart(-1);
4430 cc->m_singleChart = NULL;
4440 AbstractPlatform::ShowBusySpinner();
4442 wxGenericProgressDialog *pprog =
nullptr;
4444 wxString longmsg = _(
"OpenCPN Chart Update");
4446 ".................................................................."
4449 pprog =
new wxGenericProgressDialog();
4452 pprog->SetFont(*qFont);
4454 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4455 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4456 wxPD_REMAINING_TIME);
4463 wxLogMessage(
"Starting chart database Update...");
4464 wxString gshhg_chart_loc = gWorldMapLocation;
4465 gWorldMapLocation = wxEmptyString;
4469 ChartData->SaveBinary(ChartListFileName);
4470 wxLogMessage(
"Finished chart database Update");
4472 if (gWorldMapLocation.empty()) {
4476 gWorldMapLocation = gDefaultWorldMapLocation;
4477 gshhg_chart_loc = wxEmptyString;
4480 if (gWorldMapLocation != gshhg_chart_loc) {
4482 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4484 if (cc) cc->ResetWorldBackgroundChart();
4487 gshhsCrossesLandReset();
4492 AbstractPlatform::HideBusySpinner();
4494 pConfig->UpdateChartDirs(DirArray);
4497 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4498 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4500 if (b_runCOGTimer) {
4502 int period_ms = 100;
4504 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4511 cc->ToggleCanvasQuiltMode();
4513 bool cur_mode = cc->GetQuiltMode();
4515 if( !cc->GetQuiltMode() )
4516 cc->SetQuiltMode(
true );
4518 if( cc->GetQuiltMode() ) {
4519 cc->SetQuiltMode(
false );
4520 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4524 if( cur_mode != cc->GetQuiltMode() ){
4530 g_bQuiltEnable = cc->GetQuiltMode();
4534 ps52plib->GenerateStateHash();
4539void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4541void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4543void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4545 cc->DoCanvasStackDelta(direction);
4549void MyFrame::PositionIENCToolbar() {
4553 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4555 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4563void MyFrame::OnInitTimer(wxTimerEvent &event) {
4566 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4570 wxLog::FlushActive();
4572 switch (m_iInitCount++) {
4577 if (g_bInlandEcdis) {
4578 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4579 double range_set = 500.;
4581 range = wxRound(range * 10) / 10.;
4585 else if (range > 2000.)
4587 else if (range > 1600.)
4589 else if (range > 1200.)
4591 else if (range > 800.)
4596 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4600 g_Platform->SetFullscreen(g_bFullscreen);
4604 RebuildChartDatabase();
4605 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4608 cc->SetGroupIndex(0,
false);
4616 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4617 CHART_FAMILY_RASTER)) {
4622 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4623 CHART_FAMILY_VECTOR)) {
4636 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4639 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4641 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4644 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4648 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4649 NavObj_dB::GetInstance().LoadNavObjects();
4652 if (!g_AW1GUID.IsEmpty()) {
4655 if (!g_AW2GUID.IsEmpty()) {
4661 appendOSDirSlash(&layerdir);
4662 layerdir.Append(
"layers");
4664 if (wxDir::Exists(layerdir)) {
4666 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4667 wxLogMessage(laymsg);
4668 pConfig->LoadLayers(layerdir);
4676 for (
auto *cp : TheConnectionParams()) {
4679 cp->b_IsSetup = TRUE;
4686 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4700 3 * GetCharHeight());
4702 m_data_monitor->Center();
4710 pConfig->SetPath(
"/Settings");
4711 pConfig->Read(
"OptionsSizeX", &sx, -1);
4712 pConfig->Read(
"OptionsSizeY", &sy, -1);
4714 wxWindow *optionsParent =
this;
4716 optionsParent = GetPrimaryCanvas();
4722 BuildiENCToolbar(
true);
4729 if (!g_params.empty()) {
4730 for (
size_t n = 0; n < g_params.size(); n++) {
4731 wxString path = g_params[n];
4732 if (::wxFileExists(path)) {
4734 pSet->load_file(path.fn_str());
4737 pSet->LoadAllGPXObjects(
4738 !pSet->IsOpenCPN(), wpt_dups,
4740 LLBBox box = pSet->GetBBox();
4741 if (box.GetValid()) {
4742 CenterView(GetPrimaryCanvas(), box);
4751 InitAppMsgBusListener();
4756 auto loader = PluginLoader::GetInstance();
4757 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4758 if (!b_haveWMM)
gVar = g_UserVar;
4766 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4769 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4771 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4774 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4778 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4779 NavObj_dB::GetInstance().LoadNavObjects();
4782 if (!g_AW1GUID.IsEmpty()) {
4785 if (!g_AW2GUID.IsEmpty()) {
4791 appendOSDirSlash(&layerdir);
4792 layerdir.Append(
"layers");
4794 if (wxDir::Exists(layerdir)) {
4796 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4797 wxLogMessage(laymsg);
4798 pConfig->LoadLayers(layerdir);
4805 wxLogMessage(
"OnInitTimer...Last Call");
4807 RequestNewMasterToolbar();
4809 PositionIENCToolbar();
4811 g_bDeferredInitDone =
true;
4821 GetPrimaryCanvas()->SetFocus();
4822 GetPrimaryCanvas()->Enable();
4829 if (b_reloadForPlugins) {
4835 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4837 if (cc) cc->SetFirstAuto(
true);
4845 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4847 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4851 cc->CheckGroupValid();
4856 androidEnableBackButton(
true);
4857 androidEnableRotation();
4858 androidEnableOptionItems(
true);
4868 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4870 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4872 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4878 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4880 wxLog::FlushActive();
4882 RefreshAllCanvas(
true);
4883 wxGetApp().m_usb_watcher.Start();
4889void MyFrame::InitAppMsgBusListener() {
4890 auto &msgbus = AppMsgBus::GetInstance();
4893 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4894 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4898 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4899 HandleBasicNavMsg(basicnav_msg);
4903 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4904 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4908 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4909 HandleGPSWatchdogMsg(msg);
4916void MyFrame::ReleaseApiListeners() {}
4921 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4922 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4923 server.SetGetRestApiEndpointCb(
4924 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4925 server.open_file_cb = [](
const std::string &path) {
4926 return wxGetApp().OpenFile(path);
4933void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4934 if (msg->gps_watchdog <= 0) {
4935 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4939 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4944 if (m_fix_start_time.IsValid()) {
4945 wxDateTime now = wxDateTime::Now();
4946 wxTimeSpan span = now - m_fix_start_time;
4947 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4948 auto ¬eman = NotificationManager::GetInstance();
4949 wxString msg = _(
"GNSS Position fix lost");
4950 noteman.AddNotification(NotificationSeverity::kCritical,
4952 m_fix_start_time = wxInvalidDateTime;
4956 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4957 bool last_bVelocityValid = bVelocityValid;
4958 bVelocityValid =
false;
4965void MyFrame::CalculateCOGAverage() {
4967 if (!std::isnan(
gCog)) {
4970 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4973 double sum = 0., count = 0;
4975 double adder = COGTable[i];
4976 if (std::isnan(adder))
continue;
4978 if (fabs(adder -
g_COGAvg) > 180.) {
4992 else if (sum >= 360.)
5001void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5002 m_fixtime = msg->time;
5003 double hdt_data_interval = 0;
5004 double fix_time_interval = 0;
5006 double msgtime = msg->set_time.tv_sec;
5007 double m1 = msg->set_time.tv_nsec / 1e9;
5010 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5011 ((msg->vflag & POS_VALID) == POS_VALID)) {
5013 if (!m_fix_start_time.IsValid()) {
5014 m_fix_start_time = wxDateTime::Now();
5019 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5022 fix_time_gt_last = fix_time_gt;
5023 uint64_t fix_time_gt_now =
5024 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5025 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5029 double implied_sog = dist / (fix_time_interval / 3600);
5034 gLat_gt_m1 = gLat_gt;
5035 gLon_gt_m1 = gLon_gt;
5039 fix_time_gt = fix_time_gt_now;
5043 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5044 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5045 gCog_gt_m1 = gCog_gt;
5055 if (!std::isnan(gCog_gt_m1)) {
5057 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5064 if ((fix_time_gt - fix_time_gt_last) > .08) {
5069 if (gCog_gt > gCog_gt_m1) {
5070 if ((gCog_gt - gCog_gt_m1) > 180.)
5075 if ((gCog_gt_m1 - gCog_gt) > 180.)
5080 difft = fabs(gCog_gt - gCog_gt_m1);
5081 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5089 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5090 tentative_cog_rate_gt *= 1e9;
5091 cog_rate_gt = tentative_cog_rate_gt;
5099 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5102static double hdt_avg;
5103 double hdt_norm =
gHdt;
5104 if(
gHdt > 180) hdt_norm -= 360;
5107 hdt_avg += hdt_norm * 0.1;
5112 if (!std::isnan(
gHdt)) {
5114 uint64_t hdt_time_gt_last = hdt_time_gt;
5115 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5116 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5119 if (hdt_data_interval > .09) {
5121 gHdt_gt_m1 = gHdt_gt;
5124 if (!std::isnan(gHdt_gt_m1)) {
5126 double tentative_hdt_rate_gt =
5127 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5128 tentative_hdt_rate_gt *= 1e9;
5130 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5131 hdt_rate_gt = tentative_hdt_rate_gt;
5139 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5142 CalculateCOGAverage();
5150 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5151 if ((msg->vflag & POS_VALID) == POS_VALID)
5156 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5158 bVelocityValid =
true;
5162void MyFrame::UpdateStatusBar() {
5165 unsigned long uiCurrentTickCount;
5166 m_MMEAeventTime.SetToCurrent();
5167 uiCurrentTickCount =
5168 m_MMEAeventTime.GetMillisecond() / 100;
5169 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5170 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5171 m_ulLastNMEATicktime = uiCurrentTickCount;
5173 if (m_tick_idx++ > 6) m_tick_idx = 0;
5178 if (NULL != GetStatusBar()) {
5181 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5184 wxString s1(tick_buf, wxConvUTF8);
5186 s1 += toSDMM(1,
gLat);
5188 s1 += toSDMM(2,
gLon);
5190 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5194 if (!std::isnan(
gSog))
5195 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5197 sogcog.Printf(
"SOG --- ");
5201 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5203 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5205 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5206 (
int)toMagnetic(
gCog), 0x00B0);
5208 cogs.Printf((
"COG ---%c"), 0x00B0);
5210 sogcog.Append(cogs);
5211 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5216void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5217 MemFootTimer.Stop();
5219 int memsize = GetApplicationMemoryUse();
5222 printf(
"Memsize: %d \n", memsize);
5225 if (memsize > (g_MemFootMB * 1000)) {
5229 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5230 unsigned int nCache = pCache->GetCount();
5233 for (
unsigned int i = 0; i < nCache; i++) {
5243 for (
unsigned int i = 0; i < nCache - 1; i++) {
5244 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5246 pcea[i] = pcea[i + 1];
5257 unsigned int idelete = 0;
5258 unsigned int idelete_max = pCache->GetCount();
5261 unsigned int minimum_cache = 1;
5262 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5264 while ((memsize > (g_MemFootMB * 1000)) &&
5265 (pCache->GetCount() > minimum_cache) &&
5266 (idelete < idelete_max)) {
5267 int memsizeb = memsize;
5271 memsize = GetApplicationMemoryUse();
5272 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5280 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5285void MyFrame::CheckToolbarPosition() {
5288 static bool bMaximized;
5290 if (IsMaximized() && !bMaximized) {
5297 PositionIENCToolbar();
5298 }
else if (!IsMaximized() && bMaximized) {
5306 PositionIENCToolbar();
5311void MyFrame::ProcessUnitTest() {
5312 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5319 cc->m_bFollow =
false;
5321 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5322 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5325 if (cc->m_groupIndex > 0) {
5326 while (ut_index < ChartData->GetChartTableEntries() &&
5327 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5331 if (ut_index < ChartData->GetChartTableEntries()) {
5335 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5336 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5343 if (cc->GetQuiltMode()) {
5344 if (cc->IsChartQuiltableRef(ut_index))
5345 cc->SelectQuiltRefdbChart(ut_index);
5347 cc->SelectdbChart(ut_index);
5350 if (g_unit_test_1) {
5358 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5359 cte->GetLatMin(), cte->GetLonMax(), NULL,
5363 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5364 cte->GetLatMax(), cte->GetLonMin(), NULL,
5367 cc->GetSize(&ww, &wh);
5368 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5370 ppm = wxMin(ppm, 1.0);
5377 if (ut_index > ut_index_max) exit(0);
5388 bool b_rotate =
false;
5390 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5393 if (!b_rotate && !g_btenhertz)
return;
5395 bool b_update =
false;
5397 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5400 struct timespec now;
5401 clock_gettime(CLOCK_MONOTONIC, &now);
5402 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5403 double diffc = diff / 1e9;
5406 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5407 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5408 if (gCog_tentative < 0.) gCog_tentative += 360.;
5409 gCog = gCog_tentative;
5413 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5414 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5415 double diffc = diff / 1e9;
5416 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5420 if (gSog_gt && !std::isnan(gCog_gt)) {
5421 double delta_t = diffc / 3600;
5422 double distance = gSog_gt * delta_t;
5425 double angr = gCog_gt / 180 * M_PI;
5426 double latr = gLat_gt * M_PI / 180;
5427 double D = distance / 3443;
5428 double sD = sin(D), cD = cos(D);
5429 double sy = sin(latr), cy = cos(latr);
5430 double sa = sin(angr), ca = cos(angr);
5432 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5433 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5443 if (cc) cc->DoCanvasCOGSet();
5454 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5455 cc->DoCanvasUpdate();
5464 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5467void MyFrame::ProcessQuitFlag() {
5470 wxLogMessage(
"Got quitflag from SIGNAL");
5472 FrameTenHzTimer.Stop();
5479void MyFrame::ProcessDeferredTrackOn() {
5482 if (g_bDeferredStartTrack) {
5483 if (!g_bTrackActive) {
5486 g_bDeferredStartTrack =
false;
5489 g_bDeferredStartTrack =
false;
5494void MyFrame::ProcessAnchorWatch() {
5502 double d = g_nAWMax;
5504 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5505 bool toofar =
false;
5506 bool tooclose =
false;
5507 if (d >= 0.0) toofar = (dist * 1852. > d);
5508 if (d < 0.0) tooclose = (dist * 1852 < -d);
5510 if (tooclose || toofar)
5511 AnchorAlertOn1 =
true;
5513 AnchorAlertOn1 =
false;
5515 AnchorAlertOn1 =
false;
5523 double d = g_nAWMax;
5525 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5526 bool toofar =
false;
5527 bool tooclose =
false;
5528 if (d >= 0) toofar = (dist * 1852. > d);
5529 if (d < 0) tooclose = (dist * 1852 < -d);
5531 if (tooclose || toofar)
5532 AnchorAlertOn2 =
true;
5534 AnchorAlertOn2 =
false;
5536 AnchorAlertOn2 =
false;
5539 AnchorAlertOn1 =
true;
5542void MyFrame::SendFixToPlugins() {
5553 GPSData.
nSats = g_SatsInView;
5555 wxDateTime tCheck((time_t)m_fixtime);
5556 if (tCheck.IsValid()) {
5565 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5568 SendPositionFixToAllPlugIns(&GPSData);
5572void MyFrame::ProcessLogAndBells() {
5575 wxDateTime lognow = wxDateTime::Now();
5576 int hourLOC = lognow.GetHour();
5577 int minuteLOC = lognow.GetMinute();
5579 int minuteUTC = lognow.GetMinute();
5580 int second = lognow.GetSecond();
5582 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5583 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5584 (minuteUTC == 30)) {
5585 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5586 wxString day = lognow.FormatISODate();
5587 wxString utc = lognow.FormatISOTime();
5588 wxString navmsg =
"LOGBOOK: ";
5596 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5600 if (std::isnan(
gCog))
5601 cog.Printf(
"COG ----- ");
5603 cog.Printf(
"COG %10.5f ",
gCog);
5606 if (std::isnan(
gSog))
5607 sog.Printf(
"SOG ----- ");
5609 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5615 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5618 wxLogMessage(navmsg);
5619 g_loglast_time = lognow;
5621 int bells = (hourLOC % 4) * 2;
5622 if (minuteLOC != 0) bells++;
5623 if (!bells) bells = 8;
5625 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5626 m_BellsToPlay = bells;
5627 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5628 wxPostEvent(
this, ev);
5635 CheckToolbarPosition();
5641 if (bDBUpdateInProgress)
return;
5644 FrameTenHzTimer.Stop();
5646 ProcessDeferredTrackOn();
5648 ProcessAnchorWatch();
5649 ProcessLogAndBells();
5651 if (ShouldRestartTrack()) TrackDailyRestart();
5654 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5655 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5656 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5662 if (
gSog > 3.0) g_bCruising =
true;
5668 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5670 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5676 bool bnew_view =
false;
5677 if (!g_btenhertz) bnew_view = DoChartUpdate();
5684 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5687 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5690 cc->DrawBlinkObjects();
5693 if (bactiveRouteUpdate) {
5700 cc->SetOwnShipState(SHIP_NORMAL);
5702 if (cc->GetQuiltMode()) {
5703 double erf = cc->GetQuiltMaxErrorFactor();
5704 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5706 if (cc->m_singleChart) {
5707 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5708 cc->SetOwnShipState(SHIP_LOWACCURACY);
5712 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5715 (bVelocityValid != m_last_bVelocityValid) ||
5716 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5717 if (!g_bopengl) cc->UpdateShips();
5725 m_last_bVelocityValid = bVelocityValid;
5730 bool brq_dynamic =
false;
5732 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5733 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5735 if (pic->m_enabled && pic->m_init_state) {
5736 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5743 if (brq_dynamic) bnew_view =
true;
5747 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5750 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5755 if (cc->GetglCanvas()) {
5757 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5760 if (cc->m_bFollow) {
5761 cc->DoCanvasUpdate();
5768 if (std::isnan(
gCog)) cc->Refresh(
false);
5781 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5795 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5796 g_pais_query_dialog_active->UpdateText();
5799 if (g_pAISTargetList && (0 == (g_tick % (5))))
5800 g_pAISTargetList->UpdateAISTargetList();
5803 UpdateGPSCompassStatusBoxes();
5808 console->RefreshConsoleData();
5815 if (m_bdefer_resize) {
5816 if (0 == (g_tick % (5))) {
5817 printf(
"___RESIZE\n");
5818 SetSize(m_defer_size);
5820 m_bdefer_resize =
false;
5827 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5829 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5830 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5834double MyFrame::GetMag(
double a,
double lat,
double lon) {
5835 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5836 auto loader = PluginLoader::GetInstance();
5837 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5844 wxDateTime now = wxDateTime::Now();
5845 SendJSON_WMM_Var_Request(lat, lon, now);
5846 if (fabs(gQueryVar) < 360.0)
5847 Variance = gQueryVar;
5849 return toMagnetic(a, Variance);
5852bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5858 v[
"Year"] = date.GetYear();
5859 v[
"Month"] = date.GetMonth();
5860 v[
"Day"] = date.GetDay();
5862 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5868void MyFrame::TouchAISActive() {
5870 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5872 if (cc) cc->TouchAISToolActive();
5876void MyFrame::UpdateAISTool() {
5880 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5882 if (cc) cc->UpdateAISTBTool();
5887void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5889 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5891 if (cc) cc->SetbTCUpdate(
true);
5894 RefreshAllCanvas(
false);
5899void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5903 bool b_rotate =
false;
5904 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5906 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5910 FrameCOGTimer.Stop();
5917 int period_ms = 100;
5919 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5922void MyFrame::DoCOGSet() {
5924 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5926 if (cc) cc->DoCanvasCOGSet();
5930void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5936 wxFont oldfont = pdc->GetFont();
5938 pdc->SetFont(*pFont);
5939 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5940 pdc->SetBackgroundMode(wxTRANSPARENT);
5942 pdc->DrawText(str, x, y + 1);
5943 pdc->DrawText(str, x, y - 1);
5944 pdc->DrawText(str, x + 1, y);
5945 pdc->DrawText(str, x - 1, y);
5947 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5949 pdc->DrawText(str, x, y);
5951 pdc->SetFont(oldfont);
5955void MyFrame::UpdateRotationState(
double rotation) {
5957 g_bCourseUp =
false;
5959 if (fabs(rotation) > .001) {
5960 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5961 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5963 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5966 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5967 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5969 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5973 UpdateGPSCompassStatusBoxes(
true);
5977void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5979 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5981 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5987int MyFrame::GetApplicationMemoryUse() {
5993 wxWindow *fWin = wxWindow::FindFocus();
5995 wxArrayString outputArray;
5996 wxString cmd(
"ps --no-headers -o vsize ");
5997 unsigned long pid = wxGetProcessId();
5999 cmd1.Printf(
"%ld", pid);
6001 wxExecute(cmd, outputArray);
6003 if (outputArray.GetCount()) {
6004 wxString s = outputArray.Item(0);
6006 if (s.ToLong(&vtmp)) memsize = vtmp;
6009 if (fWin) fWin->SetFocus();
6015 PROCESS_MEMORY_COUNTERS pmc;
6017 unsigned long processID = wxGetProcessId();
6019 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6021 if (NULL == hProcess)
return 0;
6023 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6041 memsize = pmc.WorkingSetSize / 1024;
6044 CloseHandle(hProcess);
6051double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6052 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6055void MyFrame::SetChartUpdatePeriod() {
6058 g_ChartUpdatePeriod = 0;
6063 bool bskewdc =
false;
6064 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6067 if (!g_bopengl && !cc->GetVP().b_quilt) {
6068 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6070 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6074 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6076 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6081 cc->UpdateCanvasControlBar();
6084void MyFrame::selectChartDisplay(
int type,
int family) {
6086 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6088 if (cc) cc->selectCanvasChartDisplay(type, family);
6091 UpdateGlobalMenuItems();
6100bool MyFrame::DoChartUpdate() {
6101 bool return_val =
false;
6104 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6106 if (cc) return_val |= cc->DoCanvasUpdate();
6112void MyFrame::MouseEvent(wxMouseEvent &event) {
6114 event.GetPosition(&x, &y);
6119#include <mach/mach.h>
6120#include <mach/message.h>
6121#include <mach/kern_return.h>
6122#include <mach/task_info.h>
6124#include <malloc/malloc.h>
6131#if defined(__linux__)
6132#include "sys/types.h"
6133#include "sys/sysinfo.h"
6136void MyFrame::DoPrint(
void) {
6138 g_PrintingInProgress =
true;
6141 GetPrimaryCanvas()->GetglCanvas()->Render();
6142 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6152 printer.Initialize(wxLANDSCAPE);
6153 printer.EnablePageNumbers(
false);
6154 printer.Print(
this, &printout);
6172 g_PrintingInProgress =
false;
6175 GetPrimaryCanvas()->SetFocus();
6181 wxString message_ID =
event.GetID();
6182 wxString message_JSONText =
event.GetJSONText();
6190 if (message_ID ==
"WMM_VARIATION_BOAT") {
6198 int numErrors = reader.
Parse(message_JSONText, &root);
6199 if (numErrors > 0) {
6205 wxString decl = root[
"Decl"].
AsString();
6207 decl.ToDouble(&decl_val);
6213 if (message_ID ==
"WMM_VARIATION") {
6221 int numErrors = reader.
Parse(message_JSONText, &root);
6222 if (numErrors > 0) {
6228 wxString decl = root[
"Decl"].
AsString();
6230 decl.ToDouble(&decl_val);
6232 gQueryVar = decl_val;
6235 if (message_ID ==
"GRIB_TIMELINE") {
6238 int numErrors = r.
Parse(message_JSONText, &v);
6240 if (numErrors > 0) {
6241 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6246 wxDateTime oldTimeSource = gTimeSource;
6248 if (v[
"Day"].AsInt() == -1) {
6249 gTimeSource = wxInvalidDateTime;
6250 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6252 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6253 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6254 v[
"Second"].AsInt());
6258 if (oldTimeSource != gTimeSource) {
6260 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6262 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6267 cc->pCwin->Refresh(
false);
6273 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6276 wxString trk_id = wxEmptyString;
6278 int numErrors = reader.
Parse(message_JSONText, &root);
6279 if (numErrors > 0)
return;
6284 v[
"Track_ID"] = trk_id;
6286 wxString name = wxEmptyString;
6287 if (ptrack->m_GUID == trk_id) {
6288 name = ptrack->GetName();
6289 if (name.IsEmpty()) {
6295 name = _(
"(Unnamed Track)");
6302 v[
"TotalNodes"] = ptrack->GetnPoints();
6303 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6305 v[
"lat"] = tp->m_lat;
6306 v[
"lon"] = tp->m_lon;
6309 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6310 SendJSONMessageToAllPlugins(msg_id, v);
6316 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6317 SendJSONMessageToAllPlugins(msg_id, v);
6319 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6322 wxString guid = wxEmptyString;
6324 int numErrors = reader.
Parse(message_JSONText, &root);
6325 if (numErrors > 0) {
6334 wxString name = wxEmptyString;
6336 if ((*it)->m_GUID == guid) {
6337 name = (*it)->m_RouteNameString;
6338 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6344 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6345 itp != (*it)->pRoutePointList->end(); itp++) {
6346 w[i][
"lat"] = (*itp)->m_lat;
6347 w[i][
"lon"] = (*itp)->m_lon;
6348 w[i][
"Name"] = (*itp)->GetName();
6349 w[i][
"Description"] = (*itp)->GetDescription();
6350 w[i][
"GUID"] = (*itp)->m_GUID;
6351 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6353 auto node = (*itp)->m_HyperlinkList->begin();
6354 if (node != (*itp)->m_HyperlinkList->end()) {
6356 while (node != (*itp)->m_HyperlinkList->end()) {
6358 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6359 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6360 httpLink->DescrText;
6367 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6368 SendJSONMessageToAllPlugins(msg_id, v);
6375 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6376 SendJSONMessageToAllPlugins(msg_id, v);
6377 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6382 int numErrors = reader.
Parse(message_JSONText, &root);
6383 if (numErrors > 0)
return;
6386 wxString str = root[
"mode"].
AsString();
6387 if (str ==
"Track") route =
false;
6392 for (RouteList::iterator it =
pRouteList->begin();
6394 wxString name = (*it)->m_RouteNameString;
6395 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6397 v[i][
"error"] =
false;
6398 v[i][
"name"] = name;
6399 v[i][
"GUID"] = (*it)->m_GUID;
6400 v[i][
"active"] = (*it)->IsActive();
6405 wxString name = ptrack->GetName();
6406 if (name.IsEmpty()) {
6412 name = _(
"(Unnamed Track)");
6414 v[i][
"error"] =
false;
6415 v[i][
"name"] = name;
6416 v[i][
"GUID"] = ptrack->m_GUID;
6421 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6422 SendJSONMessageToAllPlugins(msg_id, v);
6425 v[0][
"error"] =
true;
6426 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6427 SendJSONMessageToAllPlugins(msg_id, v);
6429 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6431 v[0][
"error"] =
true;
6434 v[0][
"error"] =
false;
6435 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6436 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6437 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6438 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6439 v[0][
"active_waypoint_lat"] =
6441 v[0][
"active_waypoint_lon"] =
6445 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6446 SendJSONMessageToAllPlugins(msg_id, v);
6450void MyFrame::FilterCogSog() {
6451 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6453 double cog_last =
gCog;
6456 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6457 COGFilterTable[i] = COGFilterTable[i - 1];
6458 COGFilterTable[0] = cog_last;
6461 if (!std::isnan(cog_last)) {
6463 double sum = 0., count = 0;
6464 for (
int i = 0; i < g_COGFilterSec; i++) {
6465 double adder = COGFilterTable[i];
6466 if (std::isnan(adder))
continue;
6468 if (fabs(adder - cog_last) > 180.) {
6469 if ((adder - cog_last) > 0.)
6482 else if (sum >= 360.)
6489 double sog_last =
gSog;
6492 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6493 SOGFilterTable[i] = SOGFilterTable[i - 1];
6494 SOGFilterTable[0] = sog_last;
6497 if (!std::isnan(
gSog)) {
6498 double sum = 0., count = 0;
6499 for (
int i = 0; i < g_SOGFilterSec; i++) {
6500 if (std::isnan(SOGFilterTable[i]))
continue;
6502 sum += SOGFilterTable[i];
6512void MyFrame::LoadHarmonics() {
6515 ptcmgr->LoadDataSources(TideCurrentDataSet);
6517 bool b_newdataset =
false;
6520 for (
auto a :
ptcmgr->GetDataSet()) {
6521 bool b_foundi =
false;
6522 for (
auto b : TideCurrentDataSet) {
6529 b_newdataset =
true;
6534 for (
auto a : TideCurrentDataSet) {
6535 bool b_foundi =
false;
6536 for (
auto b :
ptcmgr->GetDataSet()) {
6543 b_newdataset =
true;
6548 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6552void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6553 if (!ptarget)
return;
6556 wxDateTime mob_time = wxDateTime::Now();
6557 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6558 mob_label += _(
" on ");
6559 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6562 mob_label, wxEmptyString);
6563 pWP_MOB->SetShared(
true);
6565 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6567 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6569 pWP_MOB->SetUseSca(
false);
6577 wxString(_(
"Own ship")), wxEmptyString);
6579 pWP_MOB->SetUseSca(
false);
6586 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6602 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6603 SendJSONMessageToAllPlugins(msg_id, v);
6606 if (RouteManagerDialog::getInstanceFlag()) {
6607 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6608 pRouteManagerDialog->UpdateRouteListCtrl();
6609 pRouteManagerDialog->UpdateWptListCtrl();
6613 RefreshAllCanvas(
false);
6615 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6616 mob_message += _(
" Time: ");
6617 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6618 mob_message += _(
" Ownship Position: ");
6619 mob_message += toSDMM(1,
gLat);
6621 mob_message += toSDMM(2,
gLon);
6622 mob_message += _(
" MOB Position: ");
6623 mob_message += toSDMM(1, ptarget->Lat);
6625 mob_message += toSDMM(2, ptarget->Lon);
6626 wxLogMessage(mob_message);
6629void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6633 OwnPoint->m_lat =
gLat;
6634 OwnPoint->m_lon =
gLon;
6636 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6641 MOB_Point->m_lat = ptarget->Lat;
6642 MOB_Point->m_lon = ptarget->Lon;
6644 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6645 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6647 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6648 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6651 RefreshAllCanvas(
false);
6654 wxDateTime mob_time = wxDateTime::Now();
6656 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6657 mob_message += _(
" Time: ");
6658 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6659 mob_message += _(
" Ownship Position: ");
6660 mob_message += toSDMM(1,
gLat);
6662 mob_message += toSDMM(2,
gLon);
6663 mob_message += _(
" MOB Position: ");
6664 mob_message += toSDMM(1, ptarget->Lat);
6666 mob_message += toSDMM(2, ptarget->Lon);
6668 wxLogMessage(mob_message);
6672void MyFrame::applySettingsString(wxString settings) {
6674 int last_UIScaleFactor = g_GUIScaleFactor;
6675 bool previous_expert = g_bUIexpert;
6676 g_last_ChartScaleFactor = g_ChartScaleFactor;
6677 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6680 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6683 pConfig->UpdateSettings();
6686 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6688 if (rr & S52_CHANGED) {
6690 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6692 ->ClearCNSYLUPArray();
6693 ps52plib->GenerateStateHash();
6697 ProcessOptionsDialog(rr, pNewDirArray);
6702 bool b_newToolbar =
false;
6704 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6706 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6708 if (rr & TOOLBAR_CHANGED) {
6709 b_newToolbar =
true;
6714 if (previous_expert && !g_bUIexpert) {
6715 androidForceFullRepaint();
6719 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6723 SetGPSCompassScale();
6725 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6727 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6729 UpdateGPSCompassStatusBoxes(
true);
6732 AbstractPlatform::ShowBusySpinner();
6734 SetAllToolbarScale();
6738 AbstractPlatform::HideBusySpinner();
6740 RequestNewMasterToolbar(
true);
6747 UpdateControlBar(GetPrimaryCanvas());
6753 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6756#ifdef wxHAS_POWER_EVENTS
6757void MyFrame::OnSuspending(wxPowerEvent &event) {
6761 wxLogMessage(
"System suspend starting...");
6764void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6767 wxLogMessage(
"System is going to suspend.");
6770void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6773 wxLogMessage(
"System suspend was cancelled.");
6776int g_last_resume_ticks;
6777void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6778 wxDateTime now = wxDateTime::Now();
6779 wxLogMessage(
"System resumed from suspend.");
6781 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6784 wxLogMessage(
"Restarting streams.");
6785 g_last_resume_ticks = now.GetTicks();
6789 g_pMUX->ClearStreams();
6791 g_pMUX->StartAllStreams();
6800 if (IsMaximized()) {
6805 wxSize sz = GetSize();
6806 SetSize(wxSize(sz.x - 1, sz.y));
6818void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6819 bool btbRebuild =
false;
6821 bool b_reshow =
true;
6824 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6825 if ((ff > 0.01f) || bforcenew) {
6835 long orient = g_Platform->GetDefaultToolbarOrientation();
6836 wxWindow *toolbarParent =
this;
6838 toolbarParent = GetPrimaryCanvas();
6841 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6843 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6850 g_bmasterToolbarFull =
true;
6854 CreateMasterToolbar();
6869bool MyFrame::CollapseGlobalToolbar() {
6871 m_nMasterToolCountShown = 1;
6875 g_bmasterToolbarFull =
false;
6891 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6892 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6893 tic->m_bRequired =
true;
6898 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6899 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6903 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6904 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6905 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6910 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6911 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6915 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6916 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6917 _(
"Enable Tracking"),
"MUI_track");
6921 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6922 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6934 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6935 _(
"Print Chart"),
"MUI_print");
6939 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6940 _(
"About OpenCPN"),
"MUI_help");
6944 AddDefaultPositionPlugInTools();
6948 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6949 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6960 ArrayOfPlugInToolbarTools tool_array =
6962 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6964 if (!pttc->b_viz)
continue;
6966 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6969 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6970 if (g_bTrackActive) {
6971 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6978bool MyFrame::CheckAndAddPlugInTool() {
6986 if (!tb)
return false;
6988 int n_tools = tb->GetToolsCount();
6992 ArrayOfPlugInToolbarTools tool_array =
6995 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6997 if (pttc->position == n_tools) {
6998 wxBitmap *ptool_bmp;
7000 switch (global_color_scheme) {
7001 case GLOBAL_COLOR_SCHEME_DAY:
7002 ptool_bmp = pttc->bitmap_day;
7005 case GLOBAL_COLOR_SCHEME_DUSK:
7006 ptool_bmp = pttc->bitmap_dusk;
7008 case GLOBAL_COLOR_SCHEME_NIGHT:
7009 ptool_bmp = pttc->bitmap_night;
7012 ptool_bmp = pttc->bitmap_day;
7017 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7019 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7020 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7021 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7022 tic->m_bPlugin =
true;
7031 while (CheckAndAddPlugInTool()) {
7037bool MyFrame::AddDefaultPositionPlugInTools() {
7044 ArrayOfPlugInToolbarTools tool_array =
7047 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7051 if (!pttc->b_viz)
continue;
7053 if (pttc->position == -1)
7055 wxBitmap *ptool_bmp;
7057 switch (global_color_scheme) {
7058 case GLOBAL_COLOR_SCHEME_DAY:
7059 ptool_bmp = pttc->bitmap_day;
7061 case GLOBAL_COLOR_SCHEME_DUSK:
7062 ptool_bmp = pttc->bitmap_dusk;
7064 case GLOBAL_COLOR_SCHEME_NIGHT:
7065 ptool_bmp = pttc->bitmap_night;
7068 ptool_bmp = pttc->bitmap_day;
7073 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7075 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7076 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7077 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7078 tic->m_bPlugin =
true;
7093wxColour GetGlobalColor(wxString colorName);
7095static const char *usercolors[] = {
7102 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7103 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7104 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7105 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7106 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7110 "UWHIT; 255;255;255;",
7113 "COMPT; 245;247;244",
7117 "DILG0; 255;255;255;",
7119 "DILG0; 238;239;242;",
7121 "DILG1; 212;208;200;",
7122 "DILG2; 255;255;255;",
7134 "CHGRF; 163; 180; 183;",
7136 "CHYLW; 244; 218; 72;",
7137 "CHWHT; 212; 234; 238;",
7140 "UINFM; 197; 69; 195;",
7142 "UINFG; 104; 228; 86;",
7144 "UINFR; 241; 84; 105;",
7145 "UINFF; 125; 137; 140;",
7149 "UDKRD; 124; 16; 0;",
7151 "UARTE; 200; 0; 0;",
7154 "NODTA; 163; 180; 183;",
7156 "SNDG1; 125; 137; 140;",
7158 "SCLBR; 235; 125; 54;",
7161 "UIBDR; 125; 137; 140;",
7162 "UIBCK; 212; 234; 238;",
7163 "UINFB; 58; 120; 240;",
7166 "UINFO; 235; 125; 54;",
7169 "PLRTE; 220; 64; 37;",
7170 "CHMGD; 197; 69; 195;",
7174 "DASHB; 255;255;255;",
7175 "DASHL; 175;175;175;",
7176 "DASHF; 50; 50; 50;",
7177 "DASHR; 200; 0; 0;",
7179 "DASHN; 200;120; 0;",
7180 "DASH1; 204;204;255;",
7181 "DASH2; 122;131;172;",
7182 "COMP1; 211;211;211;",
7185 "GREY3; 40; 40; 40;",
7186 "BLUE4; 100;100;200;",
7187 "VIO01; 171; 33;141;",
7188 "VIO02; 209;115;213;",
7189 "BLUEBACK; 212;234;238;",
7190 "LANDBACK; 201;185;122;",
7196 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7197 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7198 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7199 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7200 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7201 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7202 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7204 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7205 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7206 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7208 "DILG0; 110;110;110;",
7209 "DILG1; 110;110;110;",
7211 "DILG3; 130;130;130;",
7213 "UITX1; 41; 46; 46;",
7216 "UARTE; 64; 64; 64;",
7218 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7219 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7220 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7221 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7223 "DASHB; 77; 77; 77;",
7224 "DASHL; 54; 54; 54;",
7226 "DASHR; 58; 21; 21;",
7227 "DASHG; 21; 58; 21;",
7228 "DASHN; 100; 50; 0;",
7229 "DASH1; 76; 76;113;",
7230 "DASH2; 48; 52; 72;",
7231 "COMP1; 107;107;107;",
7233 "GREY3; 20; 20; 20;",
7234 "BLUE4; 80; 80;160;",
7235 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7236 "LANDBACK; 201;185;122;",
7242 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7243 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7244 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7245 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7246 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7247 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7248 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7249 "DILG0; 80; 80; 80;",
7250 "DILG1; 80; 80; 80;",
7252 "DILG3; 65; 65; 65;",
7253 "DILG4; 220;220;220;",
7254 "UITX1; 31; 34; 35;",
7257 "UARTE; 64; 64; 64;",
7259 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7260 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7261 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7263 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7264 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7265 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7266 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7269 "DASHL; 20; 20; 20;",
7270 "DASHF; 64; 64; 64;",
7271 "DASHR; 70; 15; 15;",
7272 "DASHG; 15; 70; 15;",
7273 "DASHN; 17; 80; 56;",
7274 "DASH1; 48; 52; 72;",
7275 "DASH2; 36; 36; 53;",
7276 "COMP1; 24; 24; 24;",
7278 "GREY3; 10; 10; 10;",
7279 "BLUE4; 70; 70;140;",
7280 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7281 "LANDBACK; 201;185;122;",
7285int get_static_line(
char *d,
const char **p,
int index,
int n) {
7286 if (!strcmp(p[index],
"*****"))
return 0;
7288 strncpy(d, p[index], n);
7292void InitializeUserColors() {
7293 const char **p = usercolors;
7301 UserColorTableArray =
new wxArrayPtrVoid;
7302 UserColourHashTableArray =
new wxArrayPtrVoid;
7306 ct->tableName =
new wxString(
"DAY");
7307 ct->color =
new wxArrayPtrVoid;
7308 UserColorTableArray->Add((
void *)ct);
7311 ct->tableName =
new wxString(
"DUSK");
7312 ct->color =
new wxArrayPtrVoid;
7313 UserColorTableArray->Add((
void *)ct);
7316 ct->tableName =
new wxString(
"NIGHT");
7317 ct->color =
new wxArrayPtrVoid;
7318 UserColorTableArray->Add((
void *)ct);
7320 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7321 if (!strncmp(buf,
"Table", 5)) {
7322 sscanf(buf,
"Table:%s", TableName);
7324 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7325 ctp = (colTable *)(UserColorTableArray->Item(it));
7326 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7335 while (buf[j] !=
';' && j < 20) {
7341 S52color *c =
new S52color;
7342 strcpy(c->colName, name);
7344 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7357 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7358 wxColorHashMap *phash =
new wxColorHashMap;
7359 UserColourHashTableArray->Add((
void *)phash);
7361 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7363 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7364 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7366 wxColour c(c2->R, c2->G, c2->B);
7367 wxString key(c2->colName, wxConvUTF8);
7375 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7378void DeInitializeUserColors() {
7379 if (!UserColorTableArray)
return;
7380 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7381 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7383 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7384 S52color *c = (S52color *)ct->color->Item(j);
7388 delete ct->tableName;
7394 delete UserColorTableArray;
7396 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7397 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7401 delete UserColourHashTableArray;
7408typedef struct _MSW_COLOR_SPEC {
7410 wxString S52_RGB_COLOR;
7414MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7415 {COLOR_MENUTEXT,
"UITX1", 0},
7416 {COLOR_BTNSHADOW,
"UIBCK", 0},
7419void SaveSystemColors() {
7433 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7434 while (pcspec->COLOR_NAME != -1) {
7435 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7440void RestoreSystemColors() {
7441 int element[NCOLORS];
7442 int rgbcolor[NCOLORS];
7445 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7446 while (pcspec->COLOR_NAME != -1) {
7447 element[i] = pcspec->COLOR_NAME;
7448 rgbcolor[i] = pcspec->SysRGB_COLOR;
7454 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7459void SetSystemColors(ColorScheme cs) {
7461 int element[NCOLORS];
7462 int rgbcolor[NCOLORS];
7464 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7465 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7466 while (pcspec->COLOR_NAME != -1) {
7467 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7468 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7469 element[i] = pcspec->COLOR_NAME;
7475 pSetSysColors(i, (
unsigned long *)&element[0],
7476 (
unsigned long *)&rgbcolor[0]);
7480 RestoreSystemColors();
7485wxColor GetDimColor(wxColor c) {
7486 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7487 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7491 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7492 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7494 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7495 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7496 hsv.value = hsv.value * factor;
7497 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7499 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7505double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7506 double const AnchorPointMaxDist)
7509 if (d < AnchorPointMinDist)
7510 return AnchorPointMinDist;
7511 else if (d > AnchorPointMaxDist)
7512 return AnchorPointMaxDist;
7518 if (d > -AnchorPointMinDist)
7519 return -AnchorPointMinDist;
7520 else if (d < -AnchorPointMaxDist)
7521 return -AnchorPointMaxDist;
7528static const WORD MAX_CONSOLE_LINES =
7533void RedirectIOToConsole()
7538 wxIntPtr lStdHandle;
7540 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7550 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7551 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7552 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7556 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7557 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7558 fp = _fdopen(hConHandle,
"w");
7560 setvbuf(stdout, NULL, _IONBF, 0);
7564 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7565 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7566 fp = _fdopen(hConHandle,
"r");
7568 setvbuf(stdin, NULL, _IONBF, 0);
7572 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7573 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7574 fp = _fdopen(hConHandle,
"w");
7576 setvbuf(stderr, NULL, _IONBF, 0);
7588bool TestGLCanvas(wxString prog_dir) {
7590 wxString test_app = prog_dir;
7591 test_app +=
"ocpn_gltest1.exe";
7593 if (::wxFileExists(test_app)) {
7594 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7595 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7596 if (proc_return == 0)
7597 printf(
"GLCanvas OK\n");
7599 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7601 return (proc_return == 0);
7611bool ReloadLocale() {
7616 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7623 FontMgr::Get().SetLocale(g_locale);
7637 if (pRouteManagerDialog) {
7638 pRouteManagerDialog->Hide();
7639 pRouteManagerDialog->Destroy();
7640 pRouteManagerDialog = NULL;
7644 if (g_pais_query_dialog_active) {
7645 g_pais_query_dialog_active->Destroy();
7646 g_pais_query_dialog_active = NULL;
7649 auto alert_dlg_active =
7651 if (alert_dlg_active) {
7652 alert_dlg_active->Destroy();
7653 g_pais_alert_dialog_active =
nullptr;
7656 if (g_pAISTargetList) {
7658 g_pAISTargetList->Disconnect_decoder();
7659 g_pAISTargetList->Destroy();
7660 g_pAISTargetList = NULL;
7664 if (gFrame->m_pMenuBar) {
7665 gFrame->SetMenuBar(NULL);
7666 gFrame->m_pMenuBar->Destroy();
7667 gFrame->m_pMenuBar = NULL;
7669 gFrame->BuildMenuBar();
7672 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7674 if (cc) cc->CanvasApplyLocale();
7679 wxString perspective;
7680 pConfig->SetPath(
"/AUI");
7681 pConfig->Read(
"AUIPerspective", &perspective);
7695 bool bno_load =
false;
7696 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7698 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7699 wxAuiPaneInfo pane = pane_array_val[i];
7700 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7706 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7711 gFrame->RequestNewToolbars(
true);
7712 gFrame->RequestNewMasterToolbar(
true);
7729 g_csv_locn = g_Platform->GetSharedDataDir();
7730 g_csv_locn.Append(
"s57data");
7734 appendOSDirSlash(&g_csv_locn);
7735 g_csv_locn.Append(
"s57data");
7740 if (g_SENCPrefix.IsEmpty()) {
7742 appendOSDirSlash(&g_SENCPrefix);
7743 g_SENCPrefix.Append(
"SENC");
7747 wxFileName f(g_SENCPrefix);
7749 g_SENCPrefix = f.GetFullPath();
7751 g_SENCPrefix =
"SENC";
7757 bool b_force_legacy =
false;
7759 if (g_UserPresLibData.IsEmpty()) {
7760 plib_data = g_csv_locn;
7761 appendOSDirSlash(&plib_data);
7762 plib_data.Append(
"S52RAZDS.RLE");
7764 plib_data = g_UserPresLibData;
7765 b_force_legacy =
true;
7768 ps52plib =
new s52plib(plib_data, b_force_legacy);
7783 if (!ps52plib->m_bOK) {
7786 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7788 wxString look_data_dir;
7789 look_data_dir.Append(std_path.GetUserDataDir());
7790 appendOSDirSlash(&look_data_dir);
7791 wxString tentative_SData_Locn = look_data_dir;
7792 look_data_dir.Append(
"s57data");
7794 plib_data = look_data_dir;
7795 appendOSDirSlash(&plib_data);
7796 plib_data.Append(
"S52RAZDS.RLE");
7798 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7799 ps52plib =
new s52plib(plib_data);
7801 if (ps52plib->m_bOK) {
7802 g_csv_locn = look_data_dir;
7811 if (!ps52plib->m_bOK) {
7814 wxString look_data_dir;
7815 look_data_dir = g_Platform->GetSharedDataDir();
7816 look_data_dir.Append(
"s57data");
7818 plib_data = look_data_dir;
7819 appendOSDirSlash(&plib_data);
7820 plib_data.Append(
"S52RAZDS.RLE");
7822 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7823 ps52plib =
new s52plib(plib_data);
7825 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7828 if (ps52plib->m_bOK) {
7829 wxLogMessage(
"Using s57data in " + g_csv_locn);
7831 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7836 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7838 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7839 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7840 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7841 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7844 pConfig->LoadS57Config();
7845 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7851 ps52plib->SetDIPFactor(dip_factor);
7856 ps52plib->SetScaleFactorExp(
7857 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7858 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7865 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7866 ps52plib->SetGLRendererString(renderer);
7869 ps52plib->SetGLOptions(
7870 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7871 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7872 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7877 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7886 : wxThread(wxTHREAD_JOINABLE) {
7887 m_filename = filename;
7898 newChart->SetNativeScale(m_scale);
7899 newChart->SetFullExtent(m_ext);
7901 newChart->FindOrCreateSenc(m_filename);
7906 wxString m_filename;
7912static double chart_dist(
int index) {
7918 if (cte.GetBBox().Contains(
gLat,
gLon))
7923 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7924 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7925 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7928 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7929 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7931 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7937WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7938static int CompareInts(
int n1,
int n2) {
7939 double d1 = chart_dist(n1);
7940 double d2 = chart_dist(n2);
7941 return (
int)(d1 - d2);
7946 wxString chart_path;
7951WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7953#include <wx/arrimpl.cpp>
7956void ParseAllENC(wxWindow *parent) {
7957 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7965 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7968 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7970 idx_sorted_by_distance.Add(i);
7974 if (count == 0)
return;
7976 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7982 ArrayOfCompressTargets ct_array;
7983 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7984 int i = idx_sorted_by_distance[j];
7987 double distance = chart_dist(i);
7989 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7992 pct->distance = distance;
7993 pct->chart_path = filename;
7995 ct_array.push_back(pct);
7998 int thread_count = 0;
8001 if (g_nCPUCount > 0)
8002 thread_count = g_nCPUCount;
8004 thread_count = wxThread::GetCPUCount();
8006 if (thread_count < 1) {
8015 for(
int t = 0; t < thread_count; t++)
8019 wxGenericProgressDialog *prog =
nullptr;
8023 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8024 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8026 prog =
new wxGenericProgressDialog();
8028 prog->SetFont(*qFont);
8030 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8031 count + 1, parent, style);
8040 prog->ShowWindowModal();
8049 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8050 wxString filename = ct_array[j].chart_path;
8051 double distance = ct_array[j].distance;
8052 int index =
ChartData->FinddbIndex(filename);
8053 if (index < 0)
continue;
8056 ext.NLAT = cte.GetLatMax();
8057 ext.SLAT = cte.GetLatMin();
8058 ext.WLON = cte.GetLonMin();
8059 ext.ELON = cte.GetLonMax();
8061 int scale = cte.GetScale();
8064 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8067 if (wxThread::IsMain()) {
8069 wxSize sz = prog->GetSize();
8074 prog->Update(count, msg, &skip);
8086 newChart->SetNativeScale(
scale);
8087 newChart->SetFullExtent(ext);
8088 newChart->DisableBackgroundSENC();
8090 newChart->FindOrCreateSenc(filename,
8094 if (wxThread::IsMain()) {
8095 msg.Printf(_(
"ENC Completed."));
8097 prog->Update(count, msg, &skip);
8107 for (
int t = 0;; t = (t + 1) % thread_count) {
8114 if (!workers[t]->IsAlive()) {
8127#if defined(__WXMSW__) || defined(__WXOSX__)
8134 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.
A modal message dialog with confirmation button and cancel button.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
void MakeLoopbackDriver()
Create and register the loopback driver.
void MakeCommDriver(const ConnectionParams *params)
Create and register a driver for given connection.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
s57RegistrarMgr * m_pRegistrarMan
Global instance.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
WaypointMan drawing stuff.