52#include <wx/stdpaths.h>
53#include <wx/tokenzr.h>
54#include <wx/display.h>
55#include <wx/jsonreader.h>
79#include "model/nav_object_database.h"
91#include "ais_info_gui.h"
92#include "dialog_alert.h"
96#include "ais_info_gui.h"
120#include "load_errors_dlg.h"
123#include "N2KParser.h"
130#include "OCPN_Sound.h"
143#include "SoundFactory.h"
144#include "SystemCmdSound.h"
154#include "androidUTIL.h"
162arrayofCanvasPtr g_canvasArray;
168GLenum g_texture_rectangle_format;
171#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
172extern wxLocale *plocale_def_lang;
176extern bool g_b_EnableVBO;
177extern GLenum g_texture_rectangle_format;
181static int g_last_ChartScaleFactor;
182static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
183static int options_subpage = 0;
184static bool b_reloadForPlugins;
186static wxSize options_lastWindowSize(0, 0);
187static wxPoint options_lastWindowPos(0, 0);
191static double gQueryVar = 361.0;
193static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
194static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
195static std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
197static wxArrayPtrVoid *UserColourHashTableArray;
202typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
203typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
205static SetSysColors_t pSetSysColors;
206static GetSysColor_t pGetSysColor;
208void SaveSystemColors();
209void RestoreSystemColors();
214DWORD color_3ddkshadow;
216DWORD color_activecaption;
217DWORD color_gradientactivecaption;
218DWORD color_captiontext;
219DWORD color_windowframe;
220DWORD color_inactiveborder;
225#include <wx/msw/msvcrt.h>
229static const long long lNaN = 0xfff8000000000000;
230#define NAN (*(double *)&lNaN)
233static wxArrayPtrVoid *UserColorTableArray = 0;
236static double gLat_gt, gLon_gt;
237static double gLat_gt_m1, gLon_gt_m1;
238static uint64_t fix_time_gt;
239static uint64_t fix_time_gt_last;
241static double gSog_gt, gHdt_gt;
242static double gCog_gt_m1, gHdt_gt_m1;
243static uint64_t hdt_time_gt;
244static double cog_rate_gt, hdt_rate_gt;
246void InitializeUserColors();
247void DeInitializeUserColors();
248void SetSystemColors(ColorScheme cs);
250static bool LoadAllPlugIns(
bool load_enabled) {
251 AbstractPlatform::ShowBusySpinner();
252 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
253 AbstractPlatform::HideBusySpinner();
257static void LaunchLocalHelp() {
259 androidLaunchHelpView();
261 wxString def_lang_canonical =
"en_US";
264 if (plocale_def_lang)
265 def_lang_canonical = plocale_def_lang->GetCanonicalName();
268 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
270 wxString help_try = help_locn + def_lang_canonical +
".html";
272 if (!::wxFileExists(help_try)) {
273 help_try = help_locn +
"en_US" +
".html";
275 if (!::wxFileExists(help_try)) {
276 help_try = help_locn +
"web" +
".html";
279 if (!::wxFileExists(help_try))
return;
282 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
286static void DoHelpDialog() {
298 [] { LaunchLocalHelp(); });
310#if defined(__WXGTK__) || defined(__WXQT__)
311#include "bitmaps/opencpn.xpm"
325void BuildiENCToolbar(
bool bnew) {
326 if (g_bInlandEcdis) {
330 wxPoint tbp_incanvas =
333 g_iENCToolbarPosY = tbp_incanvas.y;
334 g_iENCToolbarPosX = tbp_incanvas.x;
342 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
346 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
349 g_iENCToolbarPosY = -1;
352 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
358 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
362 double tool_scale_factor =
363 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
366 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
376bool ShowNavWarning() {
379OpenCPN is distributed in the hope that it will be useful, \
380but WITHOUT ANY WARRANTY; without even the implied \
381warranty of MERCHANTABILITY or FITNESS FOR A \
382PARTICULAR PURPOSE.\n\n\
383See the GNU General Public License for more details.\n\n\
384OpenCPN must only be used in conjunction with approved \
385paper charts and traditional methods of navigation.\n\n\
386DO NOT rely upon OpenCPN for safety of life or property.\n\n\
387Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
389 wxString vs = wxString::Format(
" .. Version %s", VERSION_FULL);
392 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
395 msg.Replace(
"\n",
"<br>");
397 std::stringstream html;
398 html <<
"<html><body><p>";
399 html << msg.ToStdString();
400 html <<
"</p></body></html>";
402 std::string title = _(
"Welcome to OpenCPN").ToStdString();
403 std::string action = _(
"Agree").ToStdString();
405 info_dlg.SetInitialSize();
406 info_dlg.AddHtmlContent(html);
407 int agreed = info_dlg.ShowModal();
408 return agreed == wxID_OK;
413 if (chart ==
nullptr)
return false;
416 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
418 if (cc && cc->m_singleChart == chart) {
425#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
428static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
429 const char *prop_name) {
433 unsigned long ret_nitems;
434 unsigned long ret_bytes_after;
435 unsigned char *ret_prop;
437 xa_prop_name = XInternAtom(disp, prop_name, False);
445 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
446 &xa_ret_type, &ret_format, &ret_nitems,
447 &ret_bytes_after, &ret_prop) != Success)
450 if (xa_ret_type != xa_prop_type) {
454 return (
char *)ret_prop;
459static bool isTransparentToolbarInOpenGLOK() {
466 if (!g_bdisable_opengl) {
467 Display *disp = XOpenDisplay(NULL);
469 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
471 "_NET_SUPPORTING_WM_CHECK")) ||
472 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
474 "_WIN_SUPPORTING_WM_CHECK"))) {
477 if ((wm_name = get_X11_property(disp, *sup_window,
478 XInternAtom(disp,
"UTF8_STRING", False),
480 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
483 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
504wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
506BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
507EVT_CLOSE(MyFrame::OnCloseWindow)
508EVT_MENU(wxID_EXIT, MyFrame::OnExit)
509EVT_SIZE(MyFrame::OnSize)
510EVT_MOVE(MyFrame::OnMove)
511EVT_ICONIZE(MyFrame::OnIconize)
512EVT_MENU(-1, MyFrame::OnToolLeftClick)
513EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
515EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
516EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
517EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
519EVT_MAXIMIZE(MyFrame::OnMaximize)
520EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
521 MyFrame::RequestNewToolbarArgEvent)
522EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
524EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
525EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
526EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
528#ifdef wxHAS_POWER_EVENTS
529EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
530EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
531EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
532EVT_POWER_RESUME(MyFrame::OnResume)
543static
void onBellsFinishedCB(
void *ptr) {
544 auto framePtr =
static_cast<MyFrame *
>(ptr);
546 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
547 wxPostEvent(framePtr, ev);
552 auto msg = ev.GetString().ToStdString();
553 auto ¬eman = NotificationManager::GetInstance();
554 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
557static NmeaLog *GetDataMonitor() {
558 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
559 return dynamic_cast<NmeaLog *
>(w);
563MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
564 const wxSize &size,
long style,
565 wxAuiDefaultDockArt *pauidockart)
566 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
567 m_connections_dlg(nullptr),
569 m_pauidockart(pauidockart) {
581 m_last_track_rotation_ts = 0;
582 m_ulLastNMEATicktime = 0;
583 m_data_monitor->Hide();
585 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
589 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
592 InitTimer.SetOwner(
this, INIT_TIMER);
594 m_initializing =
false;
597 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
600 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
603 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
606 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
609 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
611 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
620 m_bTimeIsSet =
false;
623 m_bdefer_resize =
false;
626 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
627 COGFilterTable[i] = NAN;
628 SOGFilterTable[i] = NAN;
630 m_last_bGPSValid =
false;
631 m_last_bVelocityValid =
false;
641 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
646 double process_noise_std = 1.0;
647 double measurement_noise_std = 0.5;
649 m_ChartUpdatePeriod = 1;
654 log_callbacks.log_is_active = [&]() {
655 auto log = GetDataMonitor();
656 return log && log->IsVisible();
658 log_callbacks.log_message = [&](
Logline ll) {
659 NmeaLog *monitor = GetDataMonitor();
662 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
665 ais_callbacks.confirm_stop_track = []() {
666 int r = OCPNMessageBox(
668 _(
"This AIS target has Persistent tracking selected by MMSI "
670 "A Persistent track recording will therefore be restarted for this "
672 "Do you instead want to stop Persistent tracking for this target?"),
673 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
674 return r == wxID_YES;
676 ais_callbacks.get_target_mmsi = []() {
677 auto alert_dlg_active =
679 assert(alert_dlg_active);
680 return alert_dlg_active->Get_Dialog_MMSI();
688 wxLogMessage(
" **** Connect stuff");
694 Connect(wxEVT_OCPN_MSG,
695 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
703 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
711#if defined(__WXGTK__) || defined(__WXQT__)
712 wxIcon app_icon(opencpn);
720 wxDynamicLibrary dllUser32(
"user32.dll");
722 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
723 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
728 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
733 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
734 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
736 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
738 [&](wxCommandEvent) { Refresh(); });
739 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
744 EnableFullScreenView();
746 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
752 FrameTenHzTimer.Stop();
767 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
773void MyFrame::FreezeCharts() {
776 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
778 if (cc && !cc->IsFrozen()) cc->Freeze();
783void MyFrame::ThawCharts() {
786 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
788 if (cc && cc->IsFrozen()) cc->Thaw();
795 switch (event.type) {
796 case SENC_BUILD_STARTED:
799 case SENC_BUILD_DONE_NOERROR:
801 chart =
event.m_ticket->m_chart;
803 chart->PostInit(FULL_INIT, global_color_scheme);
805 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
807 if (cc) cc->ClearS52PLIBStateHash();
812 delete event.m_ticket;
814 case SENC_BUILD_DONE_ERROR:
822void MyFrame::RebuildChartDatabase() {
823 bool b_SetInitialPoint =
false;
826 ArrayOfCDI ChartDirArray;
827 pConfig->LoadChartDirArray(ChartDirArray);
829 if (ChartDirArray.GetCount()) {
834 _(
"OpenCPN needs to update the chart database from config file "
838 wxICON_INFORMATION | wxOK);
846 _(
"Rebuilding chart database from configuration file entries..."));
850 wxString dummy1 = _(
"Elapsed time : ");
851 wxString dummy2 = _(
"Estimated time : ");
852 wxString dummy3 = _(
"Remaining time : ");
853 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
854 _(
"OpenCPN Chart Update"), line, 100, NULL,
855 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
856 wxPD_REMAINING_TIME);
859 ChartData->SaveBinary(ChartListFileName);
869void MyFrame::OnBellsFinished(wxCommandEvent &event) {
870 int bells = wxMin(m_BellsToPlay, 2);
871 if (bells <= 0)
return;
873 wxString soundfile =
"sounds";
874 appendOSDirSlash(&soundfile);
875 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
876 soundfile.Prepend(g_Platform->GetSharedDataDir());
877 wxLogMessage(
"Using bells sound file: " + soundfile);
879 OcpnSound *sound = bells_sound[bells - 1];
880 sound->SetFinishedCallback(onBellsFinishedCB,
this);
881 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
882 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
883 sound->Load(soundfile);
884 if (!sound->IsOk()) {
885 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
889 m_BellsToPlay -= bells;
892void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
894void MyFrame::OnMaximize(wxMaximizeEvent &event) {
901ColorScheme GetColorScheme() {
return global_color_scheme; }
903ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
905void MyFrame::ReloadAllVP() {
906 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
908 if (cc) cc->ReloadVP();
912void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
913 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
916 global_color_scheme = cs;
919 case GLOBAL_COLOR_SCHEME_DAY:
922 case GLOBAL_COLOR_SCHEME_DUSK:
925 case GLOBAL_COLOR_SCHEME_NIGHT:
926 SchemeName =
"NIGHT";
933 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
935 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
936 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
937 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
938 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
939 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
941 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
970 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
971 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
975 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
978 unsigned Usercolortable_index = 0;
979 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
980 colTable *ct = (colTable *)UserColorTableArray->Item(i);
981 if (SchemeName.IsSameAs(*ct->tableName)) {
982 Usercolortable_index = i;
987 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
991 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
996 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
999 cc->SetColorScheme(cs);
1000 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1001 cc->HideChartInfoWindow();
1002 cc->SetQuiltChartHiLiteIndex(-1);
1008 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1020 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1033 if (g_pais_query_dialog_active) {
1034 bool b_isshown = g_pais_query_dialog_active->IsShown();
1035 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1036 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1038 g_pais_query_dialog_active->Close();
1041 g_pais_query_dialog_active->
Create(
1042 this, -1, _(
"AIS Target Query"),
1043 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1044 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1045 g_pais_query_dialog_active->UpdateText();
1046 if (b_isshown) g_pais_query_dialog_active->Show();
1049 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1051 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1055 ApplyGlobalColorSchemetoStatusBar();
1057 UpdateAllToolbars(cs);
1062 bool btoolbarFull = g_bmasterToolbarFull;
1068 if (!btoolbarFull) {
1070 RequestNewMasterToolbar();
1072 CollapseGlobalToolbar();
1075 RequestNewMasterToolbar();
1084void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1085 if (m_pStatusBar != NULL) {
1086 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1087 m_pStatusBar->ClearBackground();
1092 if (g_canvasArray.GetCount() > 0)
1093 return g_canvasArray.Item(0);
1097void MyFrame::CancelAllMouseRoute() {
1099 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1101 if (cc) cc->CancelMouseRoute();
1105void MyFrame::NotifyChildrenResize() {}
1107void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1115 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1123 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1132 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1135 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1136 config_array.Item(i)->canvas = NULL;
1142 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1143 g_canvasArray.RemoveAt(i);
1147 switch (g_canvasConfig) {
1150 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1153 g_canvasArray.Add(cc);
1155 cc = g_canvasArray[0];
1161 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1162 cc->GetglCanvas()->Show();
1165 config_array.Item(0)->canvas = cc;
1169 cc->ApplyCanvasConfig(config_array.Item(0));
1173 cc->ConfigureChartBar();
1174 cc->SetColorScheme(global_color_scheme);
1175 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1176 cc->SetShowGPS(
true);
1179 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1181 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1187 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1189 g_canvasArray.Add(cc);
1191 cc = g_canvasArray[0];
1197 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1200 config_array.Item(0)->canvas = cc;
1202 cc->ApplyCanvasConfig(config_array.Item(0));
1205 cc->ConfigureChartBar();
1206 cc->SetColorScheme(global_color_scheme);
1207 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1208 cc->SetShowGPS(
false);
1211 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1213 .CaptionVisible(
false)
1215 .CloseButton(
false);
1220 g_canvasArray.Add(cc);
1224 if (config_array.GetCount() < 2) {
1226 pcc->configIndex = 1;
1230 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1231 config_array.Add(pcc);
1234 config_array.Item(1)->canvas = cc;
1236 cc->ApplyCanvasConfig(config_array.Item(1));
1239 cc->ConfigureChartBar();
1240 cc->SetColorScheme(global_color_scheme);
1241 cc->SetShowGPS(
true);
1245 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1247 .CaptionVisible(
false)
1249 .CloseButton(
false);
1250 g_pauimgr->GetPane(cc).RightDockable(
true);
1254 config_array.Item(1)->canvasSize =
1255 wxSize(GetClientSize().x / 2, GetClientSize().y);
1256 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1261 if (b_useStoredSize) {
1262 int ccw = config_array.Item(1)->canvasSize.x;
1263 int cch = config_array.Item(1)->canvasSize.y;
1266 if (ccw < GetClientSize().x / 10) {
1267 ccw = GetClientSize().x / 2;
1268 cch = GetClientSize().y;
1271 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1272 cc->SetSize(ccw, cch);
1286 if (g_canvasArray.size() > 1)
1290 console->SetColorScheme(global_color_scheme);
1295 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1301void MyFrame::RequestNewToolbars(
bool bforcenew) {
1302 if (b_inCloseWindow) {
1306 BuildiENCToolbar(bforcenew);
1307 PositionIENCToolbar();
1316void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1322void MyFrame::SetAllToolbarScale() {
1323 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1326void MyFrame::SetGPSCompassScale() {
1327 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1331 wxPoint screenPoint = ::wxGetMousePosition();
1334 switch (g_canvasConfig) {
1336 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1339 if (canvas->GetScreenRect().Contains(
1343 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1346 if (canvas->GetScreenRect().Contains(
1353 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1356 if (canvas->GetScreenRect().Contains(
1357 canvas->ScreenToClient(screenPoint)))
1365int MyFrame::GetCanvasIndexUnderMouse() {
1366 wxPoint screenPoint = ::wxGetMousePosition();
1369 switch (g_canvasConfig) {
1371 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1374 if (canvas->GetScreenRect().Contains(
1378 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1381 if (canvas->GetScreenRect().Contains(
1388 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1391 if (canvas->GetScreenRect().Contains(
1392 canvas->ScreenToClient(screenPoint)))
1400bool MyFrame::DropMarker(
bool atOwnShip) {
1407 if (!canvas)
return false;
1414 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1416 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1418 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1423 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1424 pRouteManagerDialog->UpdateWptListCtrl();
1429 RefreshAllCanvas(
false);
1434void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1435 if (g_canvasConfig != 0) {
1438 int nTargetGTK = -1;
1440 wxWindow *source = FindFocus();
1446 switch (g_canvasConfig) {
1448 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1451 if (canvas && (canvas == test)) {
1456 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1459 if (canvas && (canvas == test)) {
1467 int nfinalTarget = nTarget;
1469 nfinalTarget = nTargetGTK;
1471 target = ConfigMgr::Get()
1472 .GetCanvasConfigArray()
1477 target->Refresh(
true);
1488void MyFrame::FastClose() {
1490 FrameTenHzTimer.Stop();
1492 FrameTimer1.Start(1);
1496void MyFrame::OnExit(wxCommandEvent &event) {
1500void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1503 if (b_inCloseWindow) {
1513 if (!g_bDeferredInitDone)
return;
1530 if (bDBUpdateInProgress)
return;
1532 b_inCloseWindow =
true;
1534 ::wxSetCursor(wxCURSOR_WAIT);
1538 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1540 if (cc && cc->IsMeasureActive()) {
1541 cc->CancelMeasureRoute();
1546 SendPreShutdownHookToPlugins();
1550 if (g_pAISTargetList) {
1551 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1552 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1553 g_pauimgr->DetachPane(g_pAISTargetList);
1564 pConfig->SetPath(
"/AUI");
1565 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1580 SetCursor(wxCURSOR_WAIT);
1582 RefreshAllCanvas(
true);
1588 RestoreScreenBrightness();
1599 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1600 g_iENCToolbarPosY = tbp_incanvas.y;
1601 g_iENCToolbarPosX = tbp_incanvas.x;
1605 g_bframemax = IsMaximized();
1608 FrameTenHzTimer.Stop();
1610 FrameCOGTimer.Stop();
1624 if (g_bAutoAnchorMark) {
1625 bool watching_anchor =
false;
1633 wxDateTime now = wxDateTime::Now();
1634 wxTimeSpan uptime = now.Subtract(g_start_time);
1636 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1637 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1642 if (g_declutter_anchorage) {
1643 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1644 if (pr->GetName().StartsWith(
"Anchorage")) {
1645 double a =
gLat - pr->m_lat;
1646 double b =
gLon - pr->m_lon;
1647 double l = sqrt((a * a) + (b * b));
1650 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1652 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1653 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1661 wxString name = now.Format();
1662 name.Prepend(_(
"Anchorage created "));
1668 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1673 pConfig->UpdateSettings();
1677 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1681 NavObj_dB::GetInstance().Close();
1685 pConfig->DeleteGroup(
"/Routes");
1686 pConfig->DeleteGroup(
"/Marks");
1712 if (g_pAISTargetList) {
1713 g_pAISTargetList->Disconnect_decoder();
1714 g_pAISTargetList->Destroy();
1721 if (RouteManagerDialog::getInstanceFlag()) {
1722 if (pRouteManagerDialog) {
1723 pRouteManagerDialog->Destroy();
1724 pRouteManagerDialog = NULL;
1738 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1740 if (cc) cc->Destroy();
1743 g_canvasArray.Clear();
1764 MyApp &app = wxGetApp();
1765 app.m_comm_bridge.SaveConfig();
1785 auto ®istry = CommDriverRegistry::GetInstance();
1786 registry.CloseAllDrivers();
1789 for (
auto *cp : TheConnectionParams()) {
1794 for (
auto it = pLayerList->begin(); it != pLayerList->end(); ++it) {
1800 ReleaseApiListeners();
1803 g_bTempShowMenuBar =
false;
1805#define THREAD_WAIT_SECONDS 5
1815 wxLogMessage(
"Starting compressor pool drain");
1816 wxDateTime now = wxDateTime::Now();
1817 time_t stall = now.GetTicks();
1818 time_t end = stall + THREAD_WAIT_SECONDS;
1821 while (stall < end) {
1822 wxDateTime later = wxDateTime::Now();
1823 stall = later.GetTicks();
1826 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1835 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1841 uninitIXNetSystem();
1845 wxLogMessage(
"gFrame destroyed.");
1848#ifndef USE_ANDROID_GLES2
1849 qDebug() <<
"Calling OnExit()";
1853 wxTheApp->ExitMainLoop();
1856void MyFrame::OnMove(wxMoveEvent &event) {
1857 auto idx = wxDisplay::GetFromWindow(
this);
1870 DEBUG_LOG <<
"Moved to " << idx
1871#if wxCHECK_VERSION(3, 1, 6)
1872 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1873 << wxDisplay(idx).GetPPI().GetY()
1874 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1876 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1877 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1878 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1879 << wxGetDisplaySizeMM().GetY()
1880 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1889 if (g_config_display_size_manual) {
1898 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1901 cc->SetMUIBarPosition();
1910 UpdateGPSCompassStatusBoxes();
1920 PositionIENCToolbar();
1926 g_nframewin_posx = GetPosition().x;
1927 g_nframewin_posy = GetPosition().y;
1930void MyFrame::ProcessCanvasResize() {
1931 UpdateGPSCompassStatusBoxes(
true);
1935 PositionIENCToolbar();
1938 TriggerRecaptureTimer();
1942void MyFrame::TriggerRecaptureTimer() {
1943 m_recaptureTimer.Start(
1944 1000, wxTIMER_ONE_SHOT);
1947void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
1949void MyFrame::SetCanvasSizes(wxSize frameSize) {
1950 if (!g_canvasArray.GetCount())
return;
1953 int cccw = frameSize.x;
1954 int ccch = frameSize.y;
1958 switch (g_canvasConfig) {
1962 cc = g_canvasArray.Item(0);
1964 cc->GetSize( &cur_width, &cur_height );
1965 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1967 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1969 cc->SetSize( 0, 0, cccw, ccch );
1977 cc = g_canvasArray.Item(1);
1979 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1980 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1982 ccw = wxMin(ccw, cccw * 8 / 10);
1983 ccw = wxMax(ccw, cccw * 2 / 10);
1987 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1994 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2011void MyFrame::OnIconize(wxIconizeEvent &event) {
2021 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2023 if (cc && cc->GetMUIBar()) {
2024 if (cc->GetMUIBar()->GetCanvasOptions()) {
2025 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2026 cc->GetMUIBar()->PushCanvasOptions();
2035void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2037void MyFrame::ODoSetSize() {
2039 GetClientSize(&x, &y);
2042 if (m_pStatusBar != NULL) {
2043 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2044 int currentCount = m_pStatusBar->GetFieldsCount();
2045 if (currentCount != m_StatusBarFieldCount) {
2046 if ((currentCount > 0) && (currentCount < 7)) {
2049 int widths[] = {2, 2, 2, 2, 2, 2};
2050 m_pStatusBar->SetStatusWidths(currentCount, widths);
2053 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2056 if (m_StatusBarFieldCount) {
2061 if (m_StatusBarFieldCount > 2) {
2062 int widths[] = {-6, -5, -5, -6, -4};
2063 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2064 }
else if (m_StatusBarFieldCount == 2) {
2065 int cwidth = x * 90 / 100;
2066 int widths[] = {100, 100};
2067 widths[0] = cwidth * 6.4 / 10.0;
2068 widths[1] = cwidth * 3.6 / 10.0;
2069 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2071 int widths[] = {100, 100};
2072 widths[0] = x * 90 / 100;
2073 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2076 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2077 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2078 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2080 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2082 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2090 m_pStatusBar->GetFieldRect(0, stat_box);
2093 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2095 wxFont sys_font = *wxNORMAL_FONT;
2096 int try_font_size = sys_font.GetPointSize();
2099 int min_font_size = 10;
2109 wxFont *statusBarFont =
2110 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2111 int font_size = statusBarFont->GetPointSize();
2113 font_size = wxMin(font_size,
2116 wxMax(font_size, min_font_size);
2119 font_size = statusBarFont->GetPointSize();
2126 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2127 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2129 int min_height = stat_box.height;
2131 m_pStatusBar->SetFont(*pstat_font);
2132 m_pStatusBar->SetForegroundColour(
2133 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2135 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2137 (min_height >> 1) * 2;
2138 m_pStatusBar->SetMinHeight(min_height);
2147 SetCanvasSizes(GetClientSize());
2149 UpdateGPSCompassStatusBoxes(
true);
2151 if (
console) PositionConsole();
2154 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2156 if (cc) cc->FormatPianoKeys();
2162 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2163 GetPrimaryCanvas()->GetCompass()->GetRect());
2189 options_lastWindowSize = wxSize(0, 0);
2190 options_lastWindowPos = wxPoint(0, 0);
2197 if (!b_inCloseWindow) {
2200 resizeAndroidPersistents();
2204 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2205 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2211void MyFrame::PositionConsole() {
2212#if defined(__WXMSW__) || defined(__WXMAC__)
2213 if (NULL == GetPrimaryCanvas())
return;
2215 int ccx, ccy, ccsx, ccsy, consx, consy;
2217 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2220 consoleHost->GetSize(&ccsx, &ccsy);
2221 consoleHost->GetPosition(&ccx, &ccy);
2223 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2224 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2225 consoleHost = GetPrimaryCanvas();
2230 if (consoleHost->GetCompass()) {
2231 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2233 if (compass_rect.y < 100)
2234 yOffset = compass_rect.y + compass_rect.height + 45;
2238 wxSize csz =
console->GetSize();
2242 wxPoint screen_pos =
2243 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2246 if (NULL == GetPrimaryCanvas())
return;
2248 int ccx, ccy, ccsx, ccsy, consx, consy;
2250 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2253 consoleHost->GetSize(&ccsx, &ccsy);
2254 consoleHost->GetPosition(&ccx, &ccy);
2256 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2257 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2258 consoleHost = GetPrimaryCanvas();
2261 int yTopOffset = 60;
2262 int yBottomOffset = 0;
2264 if (consoleHost->GetCompass()) {
2265 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2267 if (compass_rect.y < 100)
2268 yTopOffset = compass_rect.y + compass_rect.height;
2270 if (consoleHost->GetMUIBar()) {
2271 wxRect mui_rect = consoleHost->GetMUIBarRect();
2272 yBottomOffset = ccsy - mui_rect.y;
2276 wxSize csz =
console->GetSize();
2279 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2281 if (consy < yAvail) {
2282 yFinal = (yAvail - consy) / 2;
2283 yFinal += yTopOffset;
2284 }
else if (
console->GetCDI()->IsShown()) {
2285 int cdi_height =
console->GetCDI()->GetSize().y;
2286 int consy_no_cdi = consy - cdi_height;
2287 yFinal = (yAvail - consy_no_cdi) / 2;
2288 yFinal += yTopOffset;
2292 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2297void MyFrame::UpdateAllFonts() {
2306 DestroyPersistentDialogs();
2308 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2313void MyFrame::DestroyPersistentDialogs() {
2314 if (g_pais_query_dialog_active) {
2315 g_pais_query_dialog_active->Hide();
2316 g_pais_query_dialog_active->Destroy();
2317 g_pais_query_dialog_active = NULL;
2345void MyFrame::RefreshGroupIndices() {
2347 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2349 if (cc) cc->canvasRefreshGroupIndex();
2353void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2356 switch (event.GetId()) {
2357 case ID_MENU_SCALE_OUT:
2358 DoStackDelta(GetPrimaryCanvas(), 1);
2362 case ID_MENU_SCALE_IN:
2363 DoStackDelta(GetPrimaryCanvas(), -1);
2367 case ID_MENU_ZOOM_IN: {
2368 if (GetFocusCanvas()) {
2369 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2374 case ID_MENU_ZOOM_OUT: {
2375 if (GetFocusCanvas()) {
2376 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2381 case ID_MENU_ROUTE_NEW: {
2382 if (GetFocusCanvas()) {
2383 if (0 == GetFocusCanvas()->m_routeState) {
2384 GetFocusCanvas()->StartRoute();
2386 GetFocusCanvas()->FinishRoute();
2392 case ID_MENU_TOOL_MEASURE: {
2393 GetPrimaryCanvas()->StartMeasureRoute();
2397 case ID_MENU_TOOL_NMEA_DBG_LOG:
2398 m_data_monitor->Show();
2399 m_data_monitor->Raise();
2402 case ID_MENU_TOOL_IO_MONITOR:
2403 m_data_monitor->Show();
2406 case ID_MENU_MARK_BOAT: {
2411 case ID_MENU_MARK_CURSOR: {
2416 case ID_MENU_NAV_FOLLOW: {
2417 if (
gFrame->GetPrimaryCanvas())
2418 gFrame->GetPrimaryCanvas()->TogglebFollow();
2422 case ID_MENU_CHART_OUTLINES: {
2423 ToggleChartOutlines(GetFocusCanvas());
2427 case ID_MENU_CHART_QUILTING: {
2428 ToggleQuiltMode(GetFocusCanvas());
2432 case ID_MENU_UI_CHARTBAR: {
2433 ToggleChartBar(GetFocusCanvas());
2437 case ID_MENU_ENC_TEXT:
2439 ToggleENCText(GetFocusCanvas());
2442 case ID_MENU_ENC_LIGHTS: {
2443 ToggleLights(GetFocusCanvas());
2446 case ID_MENU_ENC_SOUNDINGS: {
2447 ToggleSoundings(GetFocusCanvas());
2450 case ID_MENU_ENC_ANCHOR: {
2451 ToggleAnchor(GetFocusCanvas());
2454 case ID_MENU_ENC_DATA_QUALITY: {
2455 ToggleDataQuality(GetFocusCanvas());
2458 case ID_MENU_SHOW_NAVOBJECTS: {
2459 ToggleNavobjects(GetFocusCanvas());
2463 case ID_MENU_AIS_TARGETS: {
2464 ToggleAISDisplay(GetFocusCanvas());
2467 case ID_MENU_AIS_MOORED_TARGETS: {
2468 g_bHideMoored = !g_bHideMoored;
2471 case ID_MENU_AIS_SCALED_TARGETS: {
2472 ToggleAISMinimizeTargets(GetFocusCanvas());
2476 case ID_MENU_AIS_TARGETLIST: {
2477 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2481 case ID_MENU_AIS_TRACKS: {
2482 g_bAISShowTracks = !g_bAISShowTracks;
2483 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2487 case ID_MENU_AIS_CPADIALOG: {
2488 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2489 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2490 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2491 if (g_bAIS_CPA_Alert) {
2492 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2497 case ID_MENU_AIS_CPASOUND: {
2498 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2499 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2503 case ID_MENU_AIS_CPAWARNING: {
2504 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2505 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2509 case wxID_PREFERENCES:
2516 case ID_SETTINGS_NEW: {
2521 case ID_SETTINGS_DELETE: {
2524 g_pOptions =
nullptr;
2528 case ID_RELOAD_CHARTS: {
2533 case ID_MENU_SETTINGS_BASIC: {
2536 androidDisableFullScreen();
2538 DoAndroidPreferences();
2545 case ID_MENU_UI_FULLSCREEN: {
2550 case ID_MENU_SHOW_CURRENTS: {
2551 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2552 GetFocusCanvas()->ReloadVP();
2553 GetFocusCanvas()->Refresh(
false);
2557 case ID_MENU_SHOW_TIDES: {
2558 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2559 GetFocusCanvas()->ReloadVP();
2560 GetFocusCanvas()->Refresh(
false);
2580 case ID_MENU_UI_COLSCHEME:
2581 case ID_COLSCHEME: {
2582 ToggleColorScheme();
2591 case ID_MENU_OQUIT: {
2596 case ID_MENU_ROUTE_MANAGER:
2597 case ID_ROUTEMANAGER: {
2598 pRouteManagerDialog = RouteManagerDialog::getInstance(
2601 if (pRouteManagerDialog->IsShown())
2602 pRouteManagerDialog->Hide();
2604 pRouteManagerDialog->UpdateRouteListCtrl();
2605 pRouteManagerDialog->UpdateTrkListCtrl();
2606 pRouteManagerDialog->UpdateWptListCtrl();
2607 pRouteManagerDialog->UpdateLayListCtrl();
2609 pRouteManagerDialog->Show();
2613 pRouteManagerDialog->Centre();
2614 pRouteManagerDialog->Raise();
2620 case ID_MENU_NAV_TRACK:
2622 if (!g_bTrackActive) {
2624 g_bTrackCarryOver =
true;
2627 g_bTrackCarryOver =
false;
2628 RefreshAllCanvas(
true);
2633 case ID_MENU_CHART_NORTHUP: {
2634 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2637 case ID_MENU_CHART_COGUP: {
2638 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2641 case ID_MENU_CHART_HEADUP: {
2642 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2646 case ID_MENU_MARK_MOB:
2652 case ID_MASTERTOGGLE: {
2654 wxString tip = _(
"Show Toolbar");
2655 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2657 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2659 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2662 if (g_bmasterToolbarFull)
2663 m_nMasterToolCountShown =
2667 m_nMasterToolCountShown = 2;
2669 m_nMasterToolCountShown =
2672 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2680 case ID_CMD_SELECT_CHART_TYPE: {
2681 selectChartDisplay(event.GetExtraLong(), -1);
2685 case ID_CMD_SELECT_CHART_FAMILY: {
2686 selectChartDisplay(-1, event.GetExtraLong());
2690 case ID_CMD_APPLY_SETTINGS: {
2691 applySettingsString(event.GetString());
2693 androidRestoreFullScreen();
2699 case ID_CMD_NULL_REFRESH: {
2704 case ID_CMD_SETVP: {
2705 setStringVP(event.GetString());
2709 case ID_CMD_INVALIDATE: {
2715 case ID_CMD_POST_JSON_TO_PLUGINS: {
2721 int numErrors = reader.
Parse(event.GetString(), &root);
2722 if (numErrors == 0) {
2723 if (root[
"MessageID"].IsString()) {
2724 wxString MsgID = root[
"MessageID"].
AsString();
2748 ArrayOfPlugInToolbarTools tool_array =
2750 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2752 if (event.GetId() == pttc->id) {
2753 if (pttc->m_pplugin)
2775bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2776 bool viz_now = g_bmasterToolbarFull;
2779 wxString tip = _(
"Show Toolbar");
2781 tip = _(
"Hide Toolbar");
2783 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2786 bool toggle =
false;
2787 if (viz && !g_bmasterToolbarFull)
2790 else if (!viz && g_bmasterToolbarFull)
2794 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2797 if (g_bmasterToolbarFull)
2798 m_nMasterToolCountShown =
2802 m_nMasterToolCountShown = 2;
2804 m_nMasterToolCountShown =
2807 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2813void MyFrame::ScheduleReloadCharts() {
2814 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2815 evt.SetId(ID_RELOAD_CHARTS);
2816 GetEventHandler()->AddPendingEvent(evt);
2819void MyFrame::ScheduleDeleteSettingsDialog() {
2820 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2821 evt.SetId(ID_SETTINGS_DELETE);
2822 GetEventHandler()->AddPendingEvent(evt);
2825void MyFrame::ScheduleSettingsDialog() {
2826 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2827 evt.SetId(ID_SETTINGS);
2828 GetEventHandler()->AddPendingEvent(evt);
2831void MyFrame::ScheduleSettingsDialogNew() {
2832 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2833 evt.SetId(ID_SETTINGS_NEW);
2834 GetEventHandler()->AddPendingEvent(evt);
2837void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2838 UpdateCanvasConfigDescriptors();
2840 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2841 CreateCanvasLayout(
true);
2843 CreateCanvasLayout();
2847 ConfigureStatusBar();
2848 wxSize lastOptSize = options_lastWindowSize;
2853 options_lastWindowSize = lastOptSize;
2857 ScheduleSettingsDialogNew();
2859 ScheduleSettingsDialog();
2864 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2867 int index_hint = -1;
2868 if (i < pathArray.GetCount())
2869 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2870 cc->canvasChartsRefresh(index_hint);
2871 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2880 return GetPrimaryCanvas();
2883void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2884 if (g_bmasterToolbarFull) {
2885#ifndef OCPN_TOOLBAR_ANIMATE
2886 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2889 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2890 m_nMasterToolCountShown++;
2895 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2903#ifndef OCPN_TOOLBAR_ANIMATE
2904 m_nMasterToolCountShown = 1;
2906 if (m_nMasterToolCountShown > 1) {
2907 m_nMasterToolCountShown--;
2911 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2921void MyFrame::InvalidateAllGL() {
2924 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2934void MyFrame::RefreshAllCanvas(
bool bErase) {
2936 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2939 cc->Refresh(bErase);
2944void MyFrame::setStringVP(wxString VPS) {
2949 wxStringTokenizer tkz(VPS,
";");
2951 wxString token = tkz.GetNextToken();
2953 token.ToDouble(&lat);
2955 token = tkz.GetNextToken();
2957 token.ToDouble(&lon);
2959 token = tkz.GetNextToken();
2961 token.ToDouble(&scale_ppm);
2963 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2966void MyFrame::DoSettingsNew() {
2973void MyFrame::DoSettings() {
2977 ApplyGlobalSettings(
true);
2980 bool b_loadHarmonics =
false;
2981 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2984 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2987 if (b_loadHarmonics) LoadHarmonics();
2995 g_bShowChartBar = !g_bShowChartBar;
2997 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3002 if (g_bShowChartBar) {
3004 UpdateControlBar(cc);
3007 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3010void MyFrame::ToggleColorScheme() {
3011 static bool lastIsNight;
3012 ColorScheme s = GetColorScheme();
3015 if (lastIsNight && is == 3)
3018 lastIsNight =
false;
3020 if (lastIsNight) is = 2;
3021 if (is == 3) lastIsNight =
true;
3022 s = (ColorScheme)is;
3023 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3025 SetAndApplyColorScheme(s);
3028void MyFrame::ToggleFullScreen() {
3029 bool to = !IsFullScreen();
3034 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3036 ShowFullScreen(to, style);
3039 UpdateAllToolbars(global_color_scheme);
3041 UpdateControlBar(GetPrimaryCanvas());
3043 TriggerRecaptureTimer();
3046void MyFrame::ActivateMOB() {
3048 wxDateTime mob_time = wxDateTime::Now();
3049 wxString mob_label(_(
"MAN OVERBOARD"));
3050 mob_label += _(
" on ");
3051 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3055 pWP_MOB->SetShared(
true);
3057 pWP_MOB->SetWaypointArrivalRadius(
3059 pWP_MOB->SetUseSca(
false);
3061 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3069 new RoutePoint(zlat, zlon, g_default_wp_icon,
3070 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3071 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3076 temp_route->AddPoint(pWP_src);
3077 temp_route->AddPoint(pWP_MOB);
3079 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3089 temp_route->SetRouteArrivalRadius(-1.0);
3095 v[
"GUID"] = temp_route->
m_GUID;
3096 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3097 SendJSONMessageToAllPlugins(msg_id, v);
3100 if (RouteManagerDialog::getInstanceFlag()) {
3101 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3102 pRouteManagerDialog->UpdateRouteListCtrl();
3103 pRouteManagerDialog->UpdateWptListCtrl();
3108 RefreshAllCanvas(
false);
3110 wxString mob_message(_(
"MAN OVERBOARD"));
3111 mob_message += _(
" Time: ");
3112 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3113 mob_message += _(
" Position: ");
3114 mob_message += toSDMM(1,
gLat);
3116 mob_message += toSDMM(2,
gLon);
3117 wxLogMessage(mob_message);
3119void MyFrame::TrackOn() {
3120 g_bTrackActive =
true;
3128 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3130 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3132 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3135 androidSetTrackTool(
true);
3138 if (RouteManagerDialog::getInstanceFlag()) {
3139 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3140 pRouteManagerDialog->UpdateTrkListCtrl();
3141 pRouteManagerDialog->UpdateRouteListCtrl();
3147 if (name.IsEmpty()) {
3153 name = _(
"(Unnamed Track)");
3157 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3158 SendJSONMessageToAllPlugins(msg_id, v);
3159 g_FlushNavobjChangesTimeout =
3163Track *MyFrame::TrackOff(
bool do_add_point) {
3168 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3170 SendJSONMessageToAllPlugins(msg_id, v);
3179 if (g_bTrackDaily) {
3184 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3185 return_val = pExtendTrack;
3192 g_bTrackActive =
false;
3194 if (RouteManagerDialog::getInstanceFlag()) {
3195 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3196 pRouteManagerDialog->UpdateTrkListCtrl();
3197 pRouteManagerDialog->UpdateRouteListCtrl();
3201 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3203 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3204 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3207 androidSetTrackTool(
false);
3210 g_FlushNavobjChangesTimeout =
3216bool MyFrame::ShouldRestartTrack() {
3218 time_t now = wxDateTime::Now().GetTicks();
3219 time_t today = wxDateTime::Today().GetTicks();
3221 switch (g_track_rotate_time_type) {
3223 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3225 case TIME_TYPE_COMPUTER:
3226 rotate_at = g_track_rotate_time;
3230 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3231 rotate_at = g_track_rotate_time + utc_offset;
3234 if (rotate_at > 86400)
3236 else if (rotate_at < 0)
3238 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3239 now - today >= rotate_at) {
3240 if (m_last_track_rotation_ts == 0) {
3241 if (now - today > rotate_at)
3242 m_last_track_rotation_ts = today + rotate_at;
3244 m_last_track_rotation_ts = today + rotate_at - 86400;
3247 m_last_track_rotation_ts = now;
3253void MyFrame::TrackDailyRestart() {
3255 Track *pPreviousTrack = TrackOff(
true);
3262 if (pPreviousTrack) {
3263 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3267 if (RouteManagerDialog::getInstanceFlag()) {
3268 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3269 pRouteManagerDialog->UpdateTrkListCtrl();
3270 pRouteManagerDialog->UpdateRouteListCtrl();
3275void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3277 cc->SetUpMode(mode);
3279 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3280 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3281 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3284 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3289 cc->SetShowENCText(!cc->GetShowENCText());
3291 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3299void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3302 cc->SetENCDisplayCategory(nset);
3304 UpdateGlobalMenuItems();
3315 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3317 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3326 cc->SetShowENCLights(!cc->GetShowENCLights());
3328 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3338void MyFrame::ToggleRocks(
void )
3344 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3345 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3346 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3347 pOLE->nViz = !pOLE->nViz;
3351 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3352 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3353 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3356 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3360 ps52plib->GenerateStateHash();
3367 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3369 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3377 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3379 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3394 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3395 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3400 cc->SetShowAIS(!cc->GetShowAIS());
3401 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3405void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3406 cc->SetAttenAIS(!cc->GetAttenAIS());
3407 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3413 cc->m_bFollow =
true;
3416 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3420 SetChartUpdatePeriod();
3428 cc->m_bFollow =
false;
3430 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3434 SetChartUpdatePeriod();
3437void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3438 cc->SetShowOutlines(!cc->GetShowOutlines());
3440 RefreshAllCanvas(
false);
3444 if (g_bopengl) InvalidateAllGL();
3447 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3450void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3452void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3454 bool enabled = m_pMenuBar->IsEnabled(item_id);
3455 m_pMenuBar->Enable(item_id,
false);
3456 m_pMenuBar->Check(item_id, state);
3457 m_pMenuBar->Enable(item_id, enabled);
3461void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3468void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3469 wxBitmap *bmpRollover) {
3471 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3476void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3477 wxString rolloverSVGfile,
3478 wxString toggledSVGfile) {
3481 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3485void MyFrame::ConfigureStatusBar() {
3487 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3490 UseNativeStatusBar(
false);
3493 if (g_bShowStatusBar) {
3494 if (!m_pStatusBar) {
3496 CreateStatusBar(m_StatusBarFieldCount, 0);
3497 ApplyGlobalColorSchemetoStatusBar();
3502 m_pStatusBar->Destroy();
3503 m_pStatusBar = NULL;
3509void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3510 ConfigureStatusBar();
3512 wxSize lastOptSize = options_lastWindowSize;
3518 options_lastWindowSize = lastOptSize;
3520 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3523wxString _menuText(wxString name, wxString shortcut) {
3527 menutext <<
"\t" << shortcut;
3532void MyFrame::BuildMenuBar() {
3538 bool showMenuBar =
true;
3540 bool showMenuBar = g_bShowMenuBar;
3552 m_pMenuBar =
new wxMenuBar();
3553 RegisterGlobalMenuItems();
3554 SetMenuBar(m_pMenuBar);
3558 UpdateGlobalMenuItems();
3563 m_pMenuBar->Destroy();
3569void MyFrame::RegisterGlobalMenuItems() {
3570 if (!m_pMenuBar)
return;
3572 wxMenu *nav_menu =
new wxMenu();
3573 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3574 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3575 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3576 nav_menu->AppendSeparator();
3577 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3578 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3579 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3580 nav_menu->AppendSeparator();
3582 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3583 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3585 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3586 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3588 nav_menu->AppendSeparator();
3589 nav_menu->Append(ID_MENU_SCALE_IN,
3590 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3591 nav_menu->Append(ID_MENU_SCALE_OUT,
3592 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3594 nav_menu->AppendSeparator();
3595 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3597 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3599 wxMenu *view_menu =
new wxMenu();
3601 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3602 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3603 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3604 _menuText(_(
"Show Chart Outlines"),
"O"));
3606 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3607 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3608 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3609 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3611 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3612 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3614 view_menu->AppendSeparator();
3616 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3617 _menuText(_(
"Show ENC text"),
"T"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3619 _menuText(_(
"Show ENC Lights"),
"L"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3621 _menuText(_(
"Show ENC Soundings"),
"S"));
3622 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3623 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3624 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3625 _menuText(_(
"Show ENC Data Quality"),
"U"));
3626 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3627 _menuText(_(
"Show Navobjects"),
"V"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3630 _menuText(_(
"Show ENC text"),
"Alt-T"));
3631 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3632 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3633 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3634 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3635 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3636 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3637 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3638 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3639 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3640 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3642 view_menu->AppendSeparator();
3643 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3644 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3645 view_menu->AppendSeparator();
3647 view_menu->Append(ID_MENU_UI_COLSCHEME,
3648 _menuText(_(
"Change Color Scheme"),
"C"));
3650 view_menu->Append(ID_MENU_UI_COLSCHEME,
3651 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3654 view_menu->AppendSeparator();
3656 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3657 _menuText(_(
"Toggle Full Screen"),
"F11"));
3659 m_pMenuBar->Append(view_menu, _(
"&View"));
3661 wxMenu *ais_menu =
new wxMenu();
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3663 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3664 _(
"Attenuate less critical AIS targets"));
3665 ais_menu->AppendSeparator();
3666 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3667 _(
"Hide Moored AIS Targets"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3669 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3670 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3673 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3674 _menuText(_(
"Show CPA Warnings"),
"W"));
3676 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3677 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3680 ais_menu->AppendSeparator();
3681 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3682 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3684 wxMenu *tools_menu =
new wxMenu();
3685 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3686 _menuText(_(
"Data Monitor"),
"Alt-C"));
3688 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3689 _menuText(_(
"Measure Distance"),
"M"));
3691 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3692 _menuText(_(
"Measure Distance"),
"Alt-M"));
3695 tools_menu->AppendSeparator();
3696 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3697 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3698 tools_menu->AppendSeparator();
3699 tools_menu->Append(ID_MENU_MARK_BOAT,
3700 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3701 tools_menu->Append(ID_MENU_MARK_CURSOR,
3702 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3703 tools_menu->AppendSeparator();
3707 _menuText(_(
"Drop MOB Marker"),
3709 tools_menu->AppendSeparator();
3710 tools_menu->Append(wxID_PREFERENCES,
3711 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3713 tools_menu->Append(ID_MENU_MARK_MOB,
3714 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3715 tools_menu->AppendSeparator();
3716 tools_menu->Append(wxID_PREFERENCES,
3717 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3719 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3722 wxMenu *window_menu =
new wxMenu();
3723 m_pMenuBar->Append(window_menu, _(
"&Window"));
3726 wxMenu *help_menu =
new wxMenu();
3727 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3728 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3729 m_pMenuBar->Append(help_menu, _(
"&Help"));
3732 UpdateGlobalMenuItems();
3735void MyFrame::UpdateGlobalMenuItems() {
3736 if (!m_pMenuBar)
return;
3738 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3739 ->Check(GetPrimaryCanvas()->m_bFollow);
3740 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3741 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3742 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3743 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3744 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3745 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3746 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3747 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3748 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3749 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3750 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3751 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3753 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3754 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3755 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3756 if (g_bAIS_CPA_Alert) {
3757 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3758 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3760 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3761 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3764 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3765 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3766 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3769 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3770 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3771 ->Check(ps52plib->GetShowSoundings());
3773 bool light_state =
false;
3775 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3777 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3778 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3779 light_state = (pOLE->nViz == 1);
3784 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3785 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3789 DisCat nset = ps52plib->GetDisplayCategory();
3790 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3791 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3792 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3793 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3794 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3795 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3796 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3798 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3799 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3800 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3805void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3806 if (!m_pMenuBar)
return;
3808 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3810 if (cc->GetUpMode() == NORTH_UP_MODE)
3811 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3812 else if (cc->GetUpMode() == COURSE_UP_MODE)
3813 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3815 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3817 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3818 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3819 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3820 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3821 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3822 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3823 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3824 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3825 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3826 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3827 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3828 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3829 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3830 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3831 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3834 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3835 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3838 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3840 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3841 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3846 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3850 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3851 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3852 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3853 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3854 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3855 ->Check(cc->GetShowENCDataQual());
3856 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3858 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3859 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3860 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3865void MyFrame::InvalidateAllCanvasUndo() {
3867 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3869 if (cc) cc->undo->InvalidateUndo();
3873void MyFrame::SubmergeAllCanvasToolbars() {
3875 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3877 if (cc) cc->SubmergeToolbar();
3881void MyFrame::SurfaceAllCanvasToolbars() {
3882 if (g_bshowToolbar) {
3884 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3886 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3893void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3895 if (lon > 180.0) lon -= 360.0;
3900 cc->JumpToPosition(lat, lon,
scale);
3903 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3907void MyFrame::UpdateCanvasConfigDescriptors() {
3909 for (
unsigned int i = 0;
3910 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3911 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3919 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3920 cc->GroupID = chart->m_groupIndex;
3923 cc->
bQuilt = chart->GetQuiltMode();
3930 cc->
bFollow = chart->m_bFollow;
3935 int upmode = chart->GetUpMode();
3936 if (upmode == COURSE_UP_MODE)
3938 else if (upmode == HEAD_UP_MODE)
3945void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3946 if (!RBBox.GetValid())
return;
3948 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3949 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3952 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3953 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3961 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3962 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3964 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3965 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3967 cc->GetSize(&ww, &wh);
3969 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3971 ppm = wxMin(ppm, 1.0);
3977void MyFrame::PrepareOptionsClose(
options *settings,
3978 int settings_return_value) {
3980 options_lastPage = settings->lastPage;
3985 if (options_lastPage == 1) options_lastPage = 0;
3987 options_subpage = settings->lastSubPage;
3988 options_lastWindowPos = settings->lastWindowPos;
3989 options_lastWindowSize = settings->lastWindowSize;
3992 androidEnableBackButton(
true);
3993 androidEnableOptionsMenu(
true);
3994 androidRestoreFullScreen();
3995 androidEnableRotation();
4000void MyFrame::DoOptionsDialog() {
4002 AbstractPlatform::ShowBusySpinner();
4005 pConfig->SetPath(
"/Settings");
4006 pConfig->Read(
"OptionsSizeX", &sx, -1);
4007 pConfig->Read(
"OptionsSizeY", &sy, -1);
4009 wxWindow *optionsParent =
this;
4011 optionsParent = GetPrimaryCanvas();
4016 AbstractPlatform::HideBusySpinner();
4020 g_options->SetInitChartDir(*pInit_Chart_Dir);
4024 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4025 g_options->SetWorkDirListPtr(pWorkDirArray);
4031 prev_locale = g_locale;
4032 g_options->SetInitialPage(options_lastPage, options_subpage);
4035 g_options->lastWindowPos = options_lastWindowPos;
4036 if (options_lastWindowPos != wxPoint(0, 0)) {
4038 g_options->SetSize(options_lastWindowSize);
4042 if (options_lastWindowSize != wxSize(0, 0)) {
4043 g_options->SetSize(options_lastWindowSize);
4048 androidEnableBackButton(
false);
4049 androidEnableOptionsMenu(
false);
4050 androidDisableFullScreen();
4058 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4061 wxString chart_file_name;
4062 if (cc->GetQuiltMode()) {
4063 int dbi = cc->GetQuiltRefChartdbIndex();
4064 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4066 if (cc->m_singleChart)
4067 chart_file_name = cc->m_singleChart->GetFullPath();
4070 pathArray.Add(chart_file_name);
4076 last_canvasConfig = g_canvasConfig;
4079 g_last_ChartScaleFactor = g_ChartScaleFactor;
4085void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4086 bool b_need_refresh =
false;
4088 if ((rr & VISIT_CHARTS) &&
4089 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4091 UpdateChartDatabaseInplace(*pNewDirArray,
4092 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4095 b_need_refresh =
true;
4099 if (rr & STYLE_CHANGED) {
4102 _(
"Please restart OpenCPN to activate language or style changes."),
4103 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4106 bool b_groupchange =
false;
4107 if (((rr & VISIT_CHARTS) &&
4108 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4109 (rr & GROUPS_CHANGED)) {
4110 b_groupchange = ScrubGroupArray();
4112 RefreshGroupIndices();
4115 if (rr & GROUPS_CHANGED || b_groupchange) {
4116 pConfig->DestroyConfigGroups();
4120 if (rr & TIDES_CHANGED) {
4126 if (rr & S52_CHANGED) {
4127 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4130 pConfig->UpdateSettings();
4138 g_Platform->GetDisplayDPmm());
4141 double stuffcog = NAN;
4142 double stuffsog = NAN;
4143 if (!std::isnan(
gCog)) stuffcog =
gCog;
4144 if (!std::isnan(
gSog)) stuffsog =
gSog;
4146 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4147 COGFilterTable[i] = stuffcog;
4148 SOGFilterTable[i] = stuffsog;
4151 SetChartUpdatePeriod();
4153 if (rr & GL_CHANGED) {
4157 b_need_refresh =
true;
4160 if (rr & S52_CHANGED) {
4161 b_need_refresh =
true;
4165 if (rr & REBUILD_RASTER_CACHE) {
4167 GetPrimaryCanvas()->Disable();
4169 GetPrimaryCanvas()->Enable();
4174 if (g_config_display_size_manual &&
4182 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4189 int rrt = rr & S52_CHANGED;
4191 (rrt == S52_CHANGED) ||
4192 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4202 ps52plib->SetScaleFactorExp(
4203 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4204 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4208 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4210 if (cc) cc->ApplyGlobalSettings();
4215 bool ztc = g_bEnableZoomToCursor;
4216 g_bEnableZoomToCursor =
4220 if (!GetPrimaryCanvas()->IsFrozen())
4222 g_bEnableZoomToCursor = ztc;
4225 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4234 SetGPSCompassScale();
4236 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4239 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4240 cc->UpdateCanvasControlBar();
4243 UpdateGPSCompassStatusBoxes();
4245 SetAllToolbarScale();
4246 RequestNewToolbars();
4249 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4252 cc->RebuildCursors();
4257 bool b_masterScaleChange =
false;
4258 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4259 b_masterScaleChange =
true;
4261 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4262 RequestNewMasterToolbar(
true);
4264 bool bMuiChange =
false;
4270 if (b_masterScaleChange || bMuiChange) {
4272 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4275 cc->ProcessNewGUIScale();
4281 if (rr & LOCALE_CHANGED) {
4282 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4284 rr |= NEED_NEW_OPTIONS;
4293 g_last_ChartScaleFactor = g_ChartScaleFactor;
4295 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4300bool MyFrame::CheckGroup(
int igroup) {
4301 if (igroup == 0)
return true;
4305 if (!pGroup->m_element_array.size())
4308 for (
const auto &elem : pGroup->m_element_array) {
4309 for (
unsigned int ic = 0;
4310 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4312 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4314 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4321bool MyFrame::ScrubGroupArray() {
4326 bool b_change =
false;
4327 unsigned int igroup = 0;
4328 while (igroup < g_pGroupArray->GetCount()) {
4329 bool b_chart_in_element =
false;
4332 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4333 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4335 for (
unsigned int ic = 0;
4336 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4338 wxString chart_full_path = pcte->GetFullSystemPath();
4340 if (chart_full_path.StartsWith(element_root)) {
4341 b_chart_in_element =
true;
4347 if (!b_chart_in_element) {
4348 wxString test_string =
"GSHH";
4349 if (element_root.Upper().Contains(test_string))
4350 b_chart_in_element =
true;
4353 if (!b_chart_in_element)
4355 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4367void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4369 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4371 if (cc && (cc != ccThis)) cc->Refresh();
4376void MyFrame::ChartsRefresh() {
4379 AbstractPlatform::ShowBusySpinner();
4381 bool b_run = FrameTimer1.IsRunning();
4384 FrameTenHzTimer.Stop();
4387 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4390 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4391 if (cc->GetQuiltMode()) {
4392 currentIndex = cc->GetQuiltReferenceChartIndex();
4394 cc->canvasChartsRefresh(currentIndex);
4398 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4399 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4401 AbstractPlatform::HideBusySpinner();
4404void MyFrame::InvalidateAllQuilts() {
4405 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4408 cc->InvalidateQuilt();
4409 cc->SetQuiltRefChart(-1);
4410 cc->m_singleChart = NULL;
4415bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4417 const wxString &ChartListFileName) {
4418 bool b_run = FrameTimer1.IsRunning();
4420 FrameTenHzTimer.Stop();
4422 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4423 FrameCOGTimer.Stop();
4426 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4429 cc->InvalidateQuilt();
4430 cc->SetQuiltRefChart(-1);
4431 cc->m_singleChart = NULL;
4441 AbstractPlatform::ShowBusySpinner();
4443 wxGenericProgressDialog *pprog =
nullptr;
4445 wxString longmsg = _(
"OpenCPN Chart Update");
4447 ".................................................................."
4450 pprog =
new wxGenericProgressDialog();
4453 pprog->SetFont(*qFont);
4455 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4456 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4457 wxPD_REMAINING_TIME);
4464 wxLogMessage(
"Starting chart database Update...");
4465 wxString gshhg_chart_loc = gWorldMapLocation;
4466 gWorldMapLocation = wxEmptyString;
4470 ChartData->SaveBinary(ChartListFileName);
4471 wxLogMessage(
"Finished chart database Update");
4473 if (gWorldMapLocation.empty()) {
4477 gWorldMapLocation = gDefaultWorldMapLocation;
4478 gshhg_chart_loc = wxEmptyString;
4481 if (gWorldMapLocation != gshhg_chart_loc) {
4483 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4485 if (cc) cc->ResetWorldBackgroundChart();
4488 gshhsCrossesLandReset();
4493 AbstractPlatform::HideBusySpinner();
4495 pConfig->UpdateChartDirs(DirArray);
4498 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4499 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4501 if (b_runCOGTimer) {
4503 int period_ms = 100;
4505 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4512 cc->ToggleCanvasQuiltMode();
4514 bool cur_mode = cc->GetQuiltMode();
4516 if( !cc->GetQuiltMode() )
4517 cc->SetQuiltMode(
true );
4519 if( cc->GetQuiltMode() ) {
4520 cc->SetQuiltMode(
false );
4521 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4525 if( cur_mode != cc->GetQuiltMode() ){
4531 g_bQuiltEnable = cc->GetQuiltMode();
4535 ps52plib->GenerateStateHash();
4540void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4542void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4544void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4546 cc->DoCanvasStackDelta(direction);
4550void MyFrame::PositionIENCToolbar() {
4554 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4556 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4564void MyFrame::OnInitTimer(wxTimerEvent &event) {
4567 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4570 wxLog::FlushActive();
4572 switch (m_iInitCount++) {
4576 if (g_bInlandEcdis) {
4577 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4578 double range_set = 500.;
4580 range = wxRound(range * 10) / 10.;
4584 else if (range > 2000.)
4586 else if (range > 1600.)
4588 else if (range > 1200.)
4590 else if (range > 800.)
4595 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4599 g_Platform->SetFullscreen(g_bFullscreen);
4603 RebuildChartDatabase();
4604 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4607 cc->SetGroupIndex(0,
false);
4615 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4616 CHART_FAMILY_RASTER)) {
4621 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4622 CHART_FAMILY_VECTOR)) {
4634 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4637 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4639 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4642 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4646 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4647 NavObj_dB::GetInstance().LoadNavObjects();
4650 if (!g_AW1GUID.IsEmpty()) {
4653 if (!g_AW2GUID.IsEmpty()) {
4659 appendOSDirSlash(&layerdir);
4660 layerdir.Append(
"layers");
4662 if (wxDir::Exists(layerdir)) {
4664 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4665 wxLogMessage(laymsg);
4666 pConfig->LoadLayers(layerdir);
4673 for (
auto *cp : TheConnectionParams()) {
4676 cp->b_IsSetup = TRUE;
4683 if (m_initializing)
break;
4684 m_initializing =
true;
4685 AbstractPlatform::ShowBusySpinner();
4687 AbstractPlatform::HideBusySpinner();
4689 RequestNewMasterToolbar();
4692 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4696 wxString perspective;
4697 pConfig->SetPath(
"/AUI");
4698 pConfig->Read(
"AUIPerspective", &perspective);
4705 bool bno_load =
false;
4707 wxArrayString name_array;
4708 wxStringTokenizer st(perspective,
"|;");
4709 while (st.HasMoreTokens()) {
4710 wxString s1 = st.GetNextToken();
4711 if (s1.StartsWith(
"name=")) {
4712 wxString sc = s1.AfterFirst(
'=');
4717 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
4718 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4719 wxAuiPaneInfo pane = pane_array_val.Item(i);
4723 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4729 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
4733 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4743 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4746 wxSize frameSize = GetClientSize();
4747 wxSize minSize =
g_pauimgr->GetPane(cc).min_size;
4748 int width = wxMax(minSize.x, frameSize.x / 10);
4749 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4763 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4778 3 * GetCharHeight());
4780 m_data_monitor->Center();
4788 pConfig->SetPath(
"/Settings");
4789 pConfig->Read(
"OptionsSizeX", &sx, -1);
4790 pConfig->Read(
"OptionsSizeY", &sy, -1);
4792 wxWindow *optionsParent =
this;
4794 optionsParent = GetPrimaryCanvas();
4799 BuildiENCToolbar(
true);
4806 if (!g_params.empty()) {
4807 for (
size_t n = 0; n < g_params.size(); n++) {
4808 wxString path = g_params[n];
4809 if (::wxFileExists(path)) {
4811 pSet->load_file(path.fn_str());
4814 pSet->LoadAllGPXObjects(
4815 !pSet->IsOpenCPN(), wpt_dups,
4817 LLBBox box = pSet->GetBBox();
4818 if (box.GetValid()) {
4819 CenterView(GetPrimaryCanvas(), box);
4828 InitAppMsgBusListener();
4833 auto loader = PluginLoader::GetInstance();
4834 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4835 if (!b_haveWMM)
gVar = g_UserVar;
4842 wxLogMessage(
"OnInitTimer...Last Call");
4844 PositionIENCToolbar();
4846 g_bDeferredInitDone =
true;
4848 GetPrimaryCanvas()->SetFocus();
4855 if (b_reloadForPlugins) {
4861 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4863 if (cc) cc->SetFirstAuto(
true);
4871 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4873 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4877 cc->CheckGroupValid();
4882 androidEnableBackButton(
true);
4883 androidEnableRotation();
4884 androidEnableOptionItems(
true);
4897 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
4899 wxLog::FlushActive();
4901 RefreshAllCanvas(
true);
4902 wxGetApp().m_usb_watcher.Start();
4908void MyFrame::InitAppMsgBusListener() {
4909 auto &msgbus = AppMsgBus::GetInstance();
4912 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4913 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4917 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4918 HandleBasicNavMsg(basicnav_msg);
4922 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4923 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4927 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4928 HandleGPSWatchdogMsg(msg);
4935void MyFrame::ReleaseApiListeners() {}
4940 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4941 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4942 server.SetGetRestApiEndpointCb(
4943 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4944 server.open_file_cb = [](
const std::string &path) {
4945 return wxGetApp().OpenFile(path);
4952void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4953 if (msg->gps_watchdog <= 0) {
4954 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4958 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4963 if (m_fix_start_time.IsValid()) {
4964 wxDateTime now = wxDateTime::Now();
4965 wxTimeSpan span = now - m_fix_start_time;
4966 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4967 auto ¬eman = NotificationManager::GetInstance();
4968 wxString msg = _(
"GNSS Position fix lost");
4969 noteman.AddNotification(NotificationSeverity::kCritical,
4971 m_fix_start_time = wxInvalidDateTime;
4975 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4976 bool last_bVelocityValid = bVelocityValid;
4977 bVelocityValid =
false;
4984void MyFrame::CalculateCOGAverage() {
4986 if (!std::isnan(
gCog)) {
4989 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4992 double sum = 0., count = 0;
4994 double adder = COGTable[i];
4995 if (std::isnan(adder))
continue;
4997 if (fabs(adder -
g_COGAvg) > 180.) {
5011 else if (sum >= 360.)
5020void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5021 m_fixtime = msg->time;
5022 double hdt_data_interval = 0;
5023 double fix_time_interval = 0;
5025 double msgtime = msg->set_time.tv_sec;
5026 double m1 = msg->set_time.tv_nsec / 1e9;
5029 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5030 ((msg->vflag & POS_VALID) == POS_VALID)) {
5032 if (!m_fix_start_time.IsValid()) {
5033 m_fix_start_time = wxDateTime::Now();
5038 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5041 fix_time_gt_last = fix_time_gt;
5042 uint64_t fix_time_gt_now =
5043 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5044 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5048 double implied_sog = dist / (fix_time_interval / 3600);
5053 gLat_gt_m1 = gLat_gt;
5054 gLon_gt_m1 = gLon_gt;
5058 fix_time_gt = fix_time_gt_now;
5062 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5063 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5064 gCog_gt_m1 = gCog_gt;
5074 if (!std::isnan(gCog_gt_m1)) {
5076 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5083 if ((fix_time_gt - fix_time_gt_last) > .08) {
5088 if (gCog_gt > gCog_gt_m1) {
5089 if ((gCog_gt - gCog_gt_m1) > 180.)
5094 if ((gCog_gt_m1 - gCog_gt) > 180.)
5099 difft = fabs(gCog_gt - gCog_gt_m1);
5100 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5108 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5109 tentative_cog_rate_gt *= 1e9;
5110 cog_rate_gt = tentative_cog_rate_gt;
5118 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5121static double hdt_avg;
5122 double hdt_norm =
gHdt;
5123 if(
gHdt > 180) hdt_norm -= 360;
5126 hdt_avg += hdt_norm * 0.1;
5131 if (!std::isnan(
gHdt)) {
5133 uint64_t hdt_time_gt_last = hdt_time_gt;
5134 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5135 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5138 if (hdt_data_interval > .09) {
5140 gHdt_gt_m1 = gHdt_gt;
5143 if (!std::isnan(gHdt_gt_m1)) {
5145 double tentative_hdt_rate_gt =
5146 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5147 tentative_hdt_rate_gt *= 1e9;
5149 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5150 hdt_rate_gt = tentative_hdt_rate_gt;
5158 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5161 CalculateCOGAverage();
5169 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5170 if ((msg->vflag & POS_VALID) == POS_VALID)
5175 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5177 bVelocityValid =
true;
5181void MyFrame::UpdateStatusBar() {
5184 unsigned long uiCurrentTickCount;
5185 m_MMEAeventTime.SetToCurrent();
5186 uiCurrentTickCount =
5187 m_MMEAeventTime.GetMillisecond() / 100;
5188 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5189 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5190 m_ulLastNMEATicktime = uiCurrentTickCount;
5192 if (m_tick_idx++ > 6) m_tick_idx = 0;
5197 if (NULL != GetStatusBar()) {
5200 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5203 wxString s1(tick_buf, wxConvUTF8);
5205 s1 += toSDMM(1,
gLat);
5207 s1 += toSDMM(2,
gLon);
5209 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5213 if (!std::isnan(
gSog))
5214 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5216 sogcog.Printf(
"SOG --- ");
5220 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5222 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5224 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5225 (
int)toMagnetic(
gCog), 0x00B0);
5227 cogs.Printf((
"COG ---%c"), 0x00B0);
5229 sogcog.Append(cogs);
5230 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5235void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5236 MemFootTimer.Stop();
5238 int memsize = GetApplicationMemoryUse();
5241 printf(
"Memsize: %d \n", memsize);
5244 if (memsize > (g_MemFootMB * 1000)) {
5248 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5249 unsigned int nCache = pCache->GetCount();
5252 for (
unsigned int i = 0; i < nCache; i++) {
5262 for (
unsigned int i = 0; i < nCache - 1; i++) {
5263 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5265 pcea[i] = pcea[i + 1];
5276 unsigned int idelete = 0;
5277 unsigned int idelete_max = pCache->GetCount();
5280 unsigned int minimum_cache = 1;
5281 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5283 while ((memsize > (g_MemFootMB * 1000)) &&
5284 (pCache->GetCount() > minimum_cache) &&
5285 (idelete < idelete_max)) {
5286 int memsizeb = memsize;
5290 memsize = GetApplicationMemoryUse();
5291 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5299 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5304void MyFrame::CheckToolbarPosition() {
5307 static bool bMaximized;
5309 if (IsMaximized() && !bMaximized) {
5316 PositionIENCToolbar();
5317 }
else if (!IsMaximized() && bMaximized) {
5325 PositionIENCToolbar();
5330void MyFrame::ProcessUnitTest() {
5331 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5338 cc->m_bFollow =
false;
5340 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5341 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5344 if (cc->m_groupIndex > 0) {
5345 while (ut_index < ChartData->GetChartTableEntries() &&
5346 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5350 if (ut_index < ChartData->GetChartTableEntries()) {
5354 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5355 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5362 if (cc->GetQuiltMode()) {
5363 if (cc->IsChartQuiltableRef(ut_index))
5364 cc->SelectQuiltRefdbChart(ut_index);
5366 cc->SelectdbChart(ut_index);
5369 if (g_unit_test_1) {
5377 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5378 cte->GetLatMin(), cte->GetLonMax(), NULL,
5382 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5383 cte->GetLatMax(), cte->GetLonMin(), NULL,
5386 cc->GetSize(&ww, &wh);
5387 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5389 ppm = wxMin(ppm, 1.0);
5396 if (ut_index > ut_index_max) exit(0);
5407 bool b_rotate =
false;
5409 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5412 if (!b_rotate && !g_btenhertz)
return;
5414 bool b_update =
false;
5416 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5419 struct timespec now;
5420 clock_gettime(CLOCK_MONOTONIC, &now);
5421 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5422 double diffc = diff / 1e9;
5425 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5426 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5427 if (gCog_tentative < 0.) gCog_tentative += 360.;
5428 gCog = gCog_tentative;
5432 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5433 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5434 double diffc = diff / 1e9;
5435 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5439 if (gSog_gt && !std::isnan(gCog_gt)) {
5440 double delta_t = diffc / 3600;
5441 double distance = gSog_gt * delta_t;
5444 double angr = gCog_gt / 180 * M_PI;
5445 double latr = gLat_gt * M_PI / 180;
5446 double D = distance / 3443;
5447 double sD = sin(D), cD = cos(D);
5448 double sy = sin(latr), cy = cos(latr);
5449 double sa = sin(angr), ca = cos(angr);
5451 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5452 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5462 if (cc) cc->DoCanvasCOGSet();
5473 if (b_rotate || cc->m_bFollow) {
5474 cc->DoCanvasUpdate();
5483 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5486void MyFrame::ProcessQuitFlag() {
5489 wxLogMessage(
"Got quitflag from SIGNAL");
5491 FrameTenHzTimer.Stop();
5498void MyFrame::ProcessDeferredTrackOn() {
5501 if (g_bDeferredStartTrack) {
5502 if (!g_bTrackActive) {
5505 g_bDeferredStartTrack =
false;
5508 g_bDeferredStartTrack =
false;
5513void MyFrame::ProcessAnchorWatch() {
5521 double d = g_nAWMax;
5523 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5524 bool toofar =
false;
5525 bool tooclose =
false;
5526 if (d >= 0.0) toofar = (dist * 1852. > d);
5527 if (d < 0.0) tooclose = (dist * 1852 < -d);
5529 if (tooclose || toofar)
5530 AnchorAlertOn1 =
true;
5532 AnchorAlertOn1 =
false;
5534 AnchorAlertOn1 =
false;
5542 double d = g_nAWMax;
5544 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5545 bool toofar =
false;
5546 bool tooclose =
false;
5547 if (d >= 0) toofar = (dist * 1852. > d);
5548 if (d < 0) tooclose = (dist * 1852 < -d);
5550 if (tooclose || toofar)
5551 AnchorAlertOn2 =
true;
5553 AnchorAlertOn2 =
false;
5555 AnchorAlertOn2 =
false;
5558 AnchorAlertOn1 =
true;
5561void MyFrame::SendFixToPlugins() {
5572 GPSData.
nSats = g_SatsInView;
5574 wxDateTime tCheck((time_t)m_fixtime);
5575 if (tCheck.IsValid()) {
5584 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5587 SendPositionFixToAllPlugIns(&GPSData);
5591void MyFrame::ProcessLogAndBells() {
5594 wxDateTime lognow = wxDateTime::Now();
5595 int hourLOC = lognow.GetHour();
5596 int minuteLOC = lognow.GetMinute();
5598 int minuteUTC = lognow.GetMinute();
5599 int second = lognow.GetSecond();
5601 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5602 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5603 (minuteUTC == 30)) {
5604 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5605 wxString day = lognow.FormatISODate();
5606 wxString utc = lognow.FormatISOTime();
5607 wxString navmsg =
"LOGBOOK: ";
5615 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5619 if (std::isnan(
gCog))
5620 cog.Printf(
"COG ----- ");
5622 cog.Printf(
"COG %10.5f ",
gCog);
5625 if (std::isnan(
gSog))
5626 sog.Printf(
"SOG ----- ");
5628 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5634 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5637 wxLogMessage(navmsg);
5638 g_loglast_time = lognow;
5640 int bells = (hourLOC % 4) * 2;
5641 if (minuteLOC != 0) bells++;
5642 if (!bells) bells = 8;
5644 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5645 m_BellsToPlay = bells;
5646 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5647 wxPostEvent(
this, ev);
5654 CheckToolbarPosition();
5660 if (bDBUpdateInProgress)
return;
5663 FrameTenHzTimer.Stop();
5665 ProcessDeferredTrackOn();
5667 ProcessAnchorWatch();
5668 ProcessLogAndBells();
5670 if (ShouldRestartTrack()) TrackDailyRestart();
5673 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5674 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5675 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5681 if (
gSog > 3.0) g_bCruising =
true;
5687 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5689 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5695 bool bnew_view =
false;
5696 if (!g_btenhertz) bnew_view = DoChartUpdate();
5703 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5706 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5709 cc->DrawBlinkObjects();
5712 if (bactiveRouteUpdate) {
5719 cc->SetOwnShipState(SHIP_NORMAL);
5721 if (cc->GetQuiltMode()) {
5722 double erf = cc->GetQuiltMaxErrorFactor();
5723 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5725 if (cc->m_singleChart) {
5726 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5727 cc->SetOwnShipState(SHIP_LOWACCURACY);
5731 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5734 (bVelocityValid != m_last_bVelocityValid) ||
5735 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5736 if (!g_bopengl) cc->UpdateShips();
5744 m_last_bVelocityValid = bVelocityValid;
5749 bool brq_dynamic =
false;
5751 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5752 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5754 if (pic->m_enabled && pic->m_init_state) {
5755 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5762 if (brq_dynamic) bnew_view =
true;
5766 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5769 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5774 if (cc->GetglCanvas()) {
5776 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5779 if (cc->m_bFollow) {
5780 cc->DoCanvasUpdate();
5787 if (std::isnan(
gCog)) cc->Refresh(
false);
5800 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5814 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5815 g_pais_query_dialog_active->UpdateText();
5818 if (g_pAISTargetList && (0 == (g_tick % (5))))
5819 g_pAISTargetList->UpdateAISTargetList();
5822 UpdateGPSCompassStatusBoxes();
5827 console->RefreshConsoleData();
5834 if (m_bdefer_resize) {
5835 if (0 == (g_tick % (5))) {
5836 printf(
"___RESIZE\n");
5837 SetSize(m_defer_size);
5839 m_bdefer_resize =
false;
5846 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5848 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5849 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5853double MyFrame::GetMag(
double a,
double lat,
double lon) {
5854 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5855 auto loader = PluginLoader::GetInstance();
5856 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5863 wxDateTime now = wxDateTime::Now();
5864 SendJSON_WMM_Var_Request(lat, lon, now);
5865 if (fabs(gQueryVar) < 360.0)
5866 Variance = gQueryVar;
5868 return toMagnetic(a, Variance);
5871bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5877 v[
"Year"] = date.GetYear();
5878 v[
"Month"] = date.GetMonth();
5879 v[
"Day"] = date.GetDay();
5881 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5887void MyFrame::TouchAISActive() {
5889 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5891 if (cc) cc->TouchAISToolActive();
5895void MyFrame::UpdateAISTool() {
5899 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5901 if (cc) cc->UpdateAISTBTool();
5906void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5908 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5910 if (cc) cc->SetbTCUpdate(
true);
5913 RefreshAllCanvas(
false);
5918void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5922 bool b_rotate =
false;
5923 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5925 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5929 FrameCOGTimer.Stop();
5936 int period_ms = 100;
5938 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5941void MyFrame::DoCOGSet() {
5943 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5945 if (cc) cc->DoCanvasCOGSet();
5949void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5955 wxFont oldfont = pdc->GetFont();
5957 pdc->SetFont(*pFont);
5958 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5959 pdc->SetBackgroundMode(wxTRANSPARENT);
5961 pdc->DrawText(str, x, y + 1);
5962 pdc->DrawText(str, x, y - 1);
5963 pdc->DrawText(str, x + 1, y);
5964 pdc->DrawText(str, x - 1, y);
5966 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5968 pdc->DrawText(str, x, y);
5970 pdc->SetFont(oldfont);
5974void MyFrame::UpdateRotationState(
double rotation) {
5976 g_bCourseUp =
false;
5978 if (fabs(rotation) > .001) {
5979 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5980 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5982 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5985 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5986 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5988 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5992 UpdateGPSCompassStatusBoxes(
true);
5996void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5998 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6000 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6006int MyFrame::GetApplicationMemoryUse() {
6012 wxWindow *fWin = wxWindow::FindFocus();
6014 wxArrayString outputArray;
6015 wxString cmd(
"ps --no-headers -o vsize ");
6016 unsigned long pid = wxGetProcessId();
6018 cmd1.Printf(
"%ld", pid);
6020 wxExecute(cmd, outputArray);
6022 if (outputArray.GetCount()) {
6023 wxString s = outputArray.Item(0);
6025 if (s.ToLong(&vtmp)) memsize = vtmp;
6028 if (fWin) fWin->SetFocus();
6034 PROCESS_MEMORY_COUNTERS pmc;
6036 unsigned long processID = wxGetProcessId();
6038 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6040 if (NULL == hProcess)
return 0;
6042 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6060 memsize = pmc.WorkingSetSize / 1024;
6063 CloseHandle(hProcess);
6070double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6071 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6074void MyFrame::SetChartUpdatePeriod() {
6077 g_ChartUpdatePeriod = 0;
6082 bool bskewdc =
false;
6083 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6086 if (!g_bopengl && !cc->GetVP().b_quilt) {
6087 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6089 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6093 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6095 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6100 cc->UpdateCanvasControlBar();
6103void MyFrame::selectChartDisplay(
int type,
int family) {
6105 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6107 if (cc) cc->selectCanvasChartDisplay(type, family);
6110 UpdateGlobalMenuItems();
6119bool MyFrame::DoChartUpdate() {
6120 bool return_val =
false;
6123 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6125 if (cc) return_val |= cc->DoCanvasUpdate();
6131void MyFrame::MouseEvent(wxMouseEvent &event) {
6133 event.GetPosition(&x, &y);
6138#include <mach/mach.h>
6139#include <mach/message.h>
6140#include <mach/kern_return.h>
6141#include <mach/task_info.h>
6143#include <malloc/malloc.h>
6150#if defined(__linux__)
6151#include "sys/types.h"
6152#include "sys/sysinfo.h"
6155void MyFrame::DoPrint(
void) {
6157 g_PrintingInProgress =
true;
6160 GetPrimaryCanvas()->GetglCanvas()->Render();
6161 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6171 printer.Initialize(wxLANDSCAPE);
6172 printer.EnablePageNumbers(
false);
6173 printer.Print(
this, &printout);
6191 g_PrintingInProgress =
false;
6194 GetPrimaryCanvas()->SetFocus();
6200 wxString message_ID =
event.GetID();
6201 wxString message_JSONText =
event.GetJSONText();
6209 if (message_ID ==
"WMM_VARIATION_BOAT") {
6217 int numErrors = reader.
Parse(message_JSONText, &root);
6218 if (numErrors > 0) {
6224 wxString decl = root[
"Decl"].
AsString();
6226 decl.ToDouble(&decl_val);
6232 if (message_ID ==
"WMM_VARIATION") {
6240 int numErrors = reader.
Parse(message_JSONText, &root);
6241 if (numErrors > 0) {
6247 wxString decl = root[
"Decl"].
AsString();
6249 decl.ToDouble(&decl_val);
6251 gQueryVar = decl_val;
6254 if (message_ID ==
"GRIB_TIMELINE") {
6257 int numErrors = r.
Parse(message_JSONText, &v);
6259 if (numErrors > 0) {
6260 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6265 wxDateTime oldTimeSource = gTimeSource;
6267 if (v[
"Day"].AsInt() == -1) {
6268 gTimeSource = wxInvalidDateTime;
6269 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6271 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6272 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6273 v[
"Second"].AsInt());
6277 if (oldTimeSource != gTimeSource) {
6279 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6281 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6286 cc->pCwin->Refresh(
false);
6292 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6295 wxString trk_id = wxEmptyString;
6297 int numErrors = reader.
Parse(message_JSONText, &root);
6298 if (numErrors > 0)
return;
6303 v[
"Track_ID"] = trk_id;
6305 wxString name = wxEmptyString;
6306 if (ptrack->m_GUID == trk_id) {
6307 name = ptrack->GetName();
6308 if (name.IsEmpty()) {
6314 name = _(
"(Unnamed Track)");
6321 v[
"TotalNodes"] = ptrack->GetnPoints();
6322 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6324 v[
"lat"] = tp->m_lat;
6325 v[
"lon"] = tp->m_lon;
6328 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6329 SendJSONMessageToAllPlugins(msg_id, v);
6335 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6336 SendJSONMessageToAllPlugins(msg_id, v);
6338 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6341 wxString guid = wxEmptyString;
6343 int numErrors = reader.
Parse(message_JSONText, &root);
6344 if (numErrors > 0) {
6353 wxString name = wxEmptyString;
6355 if ((*it)->m_GUID == guid) {
6356 name = (*it)->m_RouteNameString;
6357 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6363 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6364 itp != (*it)->pRoutePointList->end(); itp++) {
6365 w[i][
"lat"] = (*itp)->m_lat;
6366 w[i][
"lon"] = (*itp)->m_lon;
6367 w[i][
"Name"] = (*itp)->GetName();
6368 w[i][
"Description"] = (*itp)->GetDescription();
6369 w[i][
"GUID"] = (*itp)->m_GUID;
6370 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6372 auto node = (*itp)->m_HyperlinkList->begin();
6373 if (node != (*itp)->m_HyperlinkList->end()) {
6375 while (node != (*itp)->m_HyperlinkList->end()) {
6377 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6378 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6379 httpLink->DescrText;
6386 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6387 SendJSONMessageToAllPlugins(msg_id, v);
6394 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6395 SendJSONMessageToAllPlugins(msg_id, v);
6396 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6401 int numErrors = reader.
Parse(message_JSONText, &root);
6402 if (numErrors > 0)
return;
6405 wxString str = root[
"mode"].
AsString();
6406 if (str ==
"Track") route =
false;
6411 for (RouteList::iterator it =
pRouteList->begin();
6413 wxString name = (*it)->m_RouteNameString;
6414 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6416 v[i][
"error"] =
false;
6417 v[i][
"name"] = name;
6418 v[i][
"GUID"] = (*it)->m_GUID;
6419 v[i][
"active"] = (*it)->IsActive();
6424 wxString name = ptrack->GetName();
6425 if (name.IsEmpty()) {
6431 name = _(
"(Unnamed Track)");
6433 v[i][
"error"] =
false;
6434 v[i][
"name"] = name;
6435 v[i][
"GUID"] = ptrack->m_GUID;
6440 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6441 SendJSONMessageToAllPlugins(msg_id, v);
6444 v[0][
"error"] =
true;
6445 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6446 SendJSONMessageToAllPlugins(msg_id, v);
6448 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6450 v[0][
"error"] =
true;
6453 v[0][
"error"] =
false;
6454 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6455 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6456 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6457 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6458 v[0][
"active_waypoint_lat"] =
6460 v[0][
"active_waypoint_lon"] =
6464 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6465 SendJSONMessageToAllPlugins(msg_id, v);
6469void MyFrame::FilterCogSog() {
6470 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6472 double cog_last =
gCog;
6475 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6476 COGFilterTable[i] = COGFilterTable[i - 1];
6477 COGFilterTable[0] = cog_last;
6480 if (!std::isnan(cog_last)) {
6482 double sum = 0., count = 0;
6483 for (
int i = 0; i < g_COGFilterSec; i++) {
6484 double adder = COGFilterTable[i];
6485 if (std::isnan(adder))
continue;
6487 if (fabs(adder - cog_last) > 180.) {
6488 if ((adder - cog_last) > 0.)
6501 else if (sum >= 360.)
6508 double sog_last =
gSog;
6511 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6512 SOGFilterTable[i] = SOGFilterTable[i - 1];
6513 SOGFilterTable[0] = sog_last;
6516 if (!std::isnan(
gSog)) {
6517 double sum = 0., count = 0;
6518 for (
int i = 0; i < g_SOGFilterSec; i++) {
6519 if (std::isnan(SOGFilterTable[i]))
continue;
6521 sum += SOGFilterTable[i];
6531void MyFrame::LoadHarmonics() {
6534 ptcmgr->LoadDataSources(TideCurrentDataSet);
6536 bool b_newdataset =
false;
6539 for (
auto a :
ptcmgr->GetDataSet()) {
6540 bool b_foundi =
false;
6541 for (
auto b : TideCurrentDataSet) {
6548 b_newdataset =
true;
6553 for (
auto a : TideCurrentDataSet) {
6554 bool b_foundi =
false;
6555 for (
auto b :
ptcmgr->GetDataSet()) {
6562 b_newdataset =
true;
6567 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6571void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6572 if (!ptarget)
return;
6575 wxDateTime mob_time = wxDateTime::Now();
6576 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6577 mob_label += _(
" on ");
6578 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6581 mob_label, wxEmptyString);
6582 pWP_MOB->SetShared(
true);
6584 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6586 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6588 pWP_MOB->SetUseSca(
false);
6596 wxString(_(
"Own ship")), wxEmptyString);
6598 pWP_MOB->SetUseSca(
false);
6605 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6621 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6622 SendJSONMessageToAllPlugins(msg_id, v);
6625 if (RouteManagerDialog::getInstanceFlag()) {
6626 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6627 pRouteManagerDialog->UpdateRouteListCtrl();
6628 pRouteManagerDialog->UpdateWptListCtrl();
6632 RefreshAllCanvas(
false);
6634 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6635 mob_message += _(
" Time: ");
6636 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6637 mob_message += _(
" Ownship Position: ");
6638 mob_message += toSDMM(1,
gLat);
6640 mob_message += toSDMM(2,
gLon);
6641 mob_message += _(
" MOB Position: ");
6642 mob_message += toSDMM(1, ptarget->Lat);
6644 mob_message += toSDMM(2, ptarget->Lon);
6645 wxLogMessage(mob_message);
6648void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6652 OwnPoint->m_lat =
gLat;
6653 OwnPoint->m_lon =
gLon;
6655 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6660 MOB_Point->m_lat = ptarget->Lat;
6661 MOB_Point->m_lon = ptarget->Lon;
6663 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6664 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6666 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6667 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6670 RefreshAllCanvas(
false);
6673 wxDateTime mob_time = wxDateTime::Now();
6675 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6676 mob_message += _(
" Time: ");
6677 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6678 mob_message += _(
" Ownship Position: ");
6679 mob_message += toSDMM(1,
gLat);
6681 mob_message += toSDMM(2,
gLon);
6682 mob_message += _(
" MOB Position: ");
6683 mob_message += toSDMM(1, ptarget->Lat);
6685 mob_message += toSDMM(2, ptarget->Lon);
6687 wxLogMessage(mob_message);
6691void MyFrame::applySettingsString(wxString settings) {
6693 int last_UIScaleFactor = g_GUIScaleFactor;
6694 bool previous_expert = g_bUIexpert;
6695 g_last_ChartScaleFactor = g_ChartScaleFactor;
6696 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6699 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6702 pConfig->UpdateSettings();
6705 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6707 if (rr & S52_CHANGED) {
6709 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6711 ->ClearCNSYLUPArray();
6712 ps52plib->GenerateStateHash();
6716 ProcessOptionsDialog(rr, pNewDirArray);
6721 bool b_newToolbar =
false;
6723 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6725 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6727 if (rr & TOOLBAR_CHANGED) {
6728 b_newToolbar =
true;
6733 if (previous_expert && !g_bUIexpert) {
6734 androidForceFullRepaint();
6738 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6742 SetGPSCompassScale();
6744 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6746 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6748 UpdateGPSCompassStatusBoxes(
true);
6751 AbstractPlatform::ShowBusySpinner();
6753 SetAllToolbarScale();
6757 AbstractPlatform::HideBusySpinner();
6759 RequestNewMasterToolbar(
true);
6766 UpdateControlBar(GetPrimaryCanvas());
6772 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6775#ifdef wxHAS_POWER_EVENTS
6776void MyFrame::OnSuspending(wxPowerEvent &event) {
6780 wxLogMessage(
"System suspend starting...");
6783void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6786 wxLogMessage(
"System is going to suspend.");
6789void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6792 wxLogMessage(
"System suspend was cancelled.");
6795int g_last_resume_ticks;
6796void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6797 wxDateTime now = wxDateTime::Now();
6798 wxLogMessage(
"System resumed from suspend.");
6800 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6803 wxLogMessage(
"Restarting streams.");
6804 g_last_resume_ticks = now.GetTicks();
6808 g_pMUX->ClearStreams();
6810 g_pMUX->StartAllStreams();
6819 if (IsMaximized()) {
6824 wxSize sz = GetSize();
6825 SetSize(wxSize(sz.x - 1, sz.y));
6837void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6838 bool btbRebuild =
false;
6840 bool b_reshow =
true;
6843 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6844 if ((ff > 0.01f) || bforcenew) {
6854 long orient = g_Platform->GetDefaultToolbarOrientation();
6855 wxWindow *toolbarParent =
this;
6857 toolbarParent = GetPrimaryCanvas();
6860 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6862 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6869 g_bmasterToolbarFull =
true;
6873 CreateMasterToolbar();
6888bool MyFrame::CollapseGlobalToolbar() {
6890 m_nMasterToolCountShown = 1;
6894 g_bmasterToolbarFull =
false;
6910 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6911 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6912 tic->m_bRequired =
true;
6917 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6918 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6922 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6923 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6924 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6929 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6930 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6934 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6935 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6936 _(
"Enable Tracking"),
"MUI_track");
6940 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6941 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6953 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6954 _(
"Print Chart"),
"MUI_print");
6958 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6959 _(
"About OpenCPN"),
"MUI_help");
6963 AddDefaultPositionPlugInTools();
6967 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6968 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6979 ArrayOfPlugInToolbarTools tool_array =
6981 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6983 if (!pttc->b_viz)
continue;
6985 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6988 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6989 if (g_bTrackActive) {
6990 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6997bool MyFrame::CheckAndAddPlugInTool() {
7005 if (!tb)
return false;
7007 int n_tools = tb->GetToolsCount();
7011 ArrayOfPlugInToolbarTools tool_array =
7014 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7016 if (pttc->position == n_tools) {
7017 wxBitmap *ptool_bmp;
7019 switch (global_color_scheme) {
7020 case GLOBAL_COLOR_SCHEME_DAY:
7021 ptool_bmp = pttc->bitmap_day;
7024 case GLOBAL_COLOR_SCHEME_DUSK:
7025 ptool_bmp = pttc->bitmap_dusk;
7027 case GLOBAL_COLOR_SCHEME_NIGHT:
7028 ptool_bmp = pttc->bitmap_night;
7031 ptool_bmp = pttc->bitmap_day;
7036 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7038 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7039 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7040 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7041 tic->m_bPlugin =
true;
7050 while (CheckAndAddPlugInTool()) {
7056bool MyFrame::AddDefaultPositionPlugInTools() {
7063 ArrayOfPlugInToolbarTools tool_array =
7066 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7070 if (!pttc->b_viz)
continue;
7072 if (pttc->position == -1)
7074 wxBitmap *ptool_bmp;
7076 switch (global_color_scheme) {
7077 case GLOBAL_COLOR_SCHEME_DAY:
7078 ptool_bmp = pttc->bitmap_day;
7080 case GLOBAL_COLOR_SCHEME_DUSK:
7081 ptool_bmp = pttc->bitmap_dusk;
7083 case GLOBAL_COLOR_SCHEME_NIGHT:
7084 ptool_bmp = pttc->bitmap_night;
7087 ptool_bmp = pttc->bitmap_day;
7092 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7094 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7095 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7096 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7097 tic->m_bPlugin =
true;
7112wxColour GetGlobalColor(wxString colorName);
7114static const char *usercolors[] = {
7121 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7122 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7123 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7124 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7125 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7129 "UWHIT; 255;255;255;",
7132 "COMPT; 245;247;244",
7136 "DILG0; 255;255;255;",
7138 "DILG0; 238;239;242;",
7140 "DILG1; 212;208;200;",
7141 "DILG2; 255;255;255;",
7153 "CHGRF; 163; 180; 183;",
7155 "CHYLW; 244; 218; 72;",
7156 "CHWHT; 212; 234; 238;",
7159 "UINFM; 197; 69; 195;",
7161 "UINFG; 104; 228; 86;",
7163 "UINFR; 241; 84; 105;",
7164 "UINFF; 125; 137; 140;",
7168 "UDKRD; 124; 16; 0;",
7170 "UARTE; 200; 0; 0;",
7173 "NODTA; 163; 180; 183;",
7175 "SNDG1; 125; 137; 140;",
7177 "SCLBR; 235; 125; 54;",
7180 "UIBDR; 125; 137; 140;",
7181 "UIBCK; 212; 234; 238;",
7182 "UINFB; 58; 120; 240;",
7185 "UINFO; 235; 125; 54;",
7188 "PLRTE; 220; 64; 37;",
7189 "CHMGD; 197; 69; 195;",
7193 "DASHB; 255;255;255;",
7194 "DASHL; 175;175;175;",
7195 "DASHF; 50; 50; 50;",
7196 "DASHR; 200; 0; 0;",
7198 "DASHN; 200;120; 0;",
7199 "DASH1; 204;204;255;",
7200 "DASH2; 122;131;172;",
7201 "COMP1; 211;211;211;",
7204 "GREY3; 40; 40; 40;",
7205 "BLUE4; 100;100;200;",
7206 "VIO01; 171; 33;141;",
7207 "VIO02; 209;115;213;",
7208 "BLUEBACK; 212;234;238;",
7209 "LANDBACK; 201;185;122;",
7215 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7216 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7217 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7218 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7219 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7220 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7221 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7223 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7224 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7225 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7227 "DILG0; 110;110;110;",
7228 "DILG1; 110;110;110;",
7230 "DILG3; 130;130;130;",
7232 "UITX1; 41; 46; 46;",
7235 "UARTE; 64; 64; 64;",
7237 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7238 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7239 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7240 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7242 "DASHB; 77; 77; 77;",
7243 "DASHL; 54; 54; 54;",
7245 "DASHR; 58; 21; 21;",
7246 "DASHG; 21; 58; 21;",
7247 "DASHN; 100; 50; 0;",
7248 "DASH1; 76; 76;113;",
7249 "DASH2; 48; 52; 72;",
7250 "COMP1; 107;107;107;",
7252 "GREY3; 20; 20; 20;",
7253 "BLUE4; 80; 80;160;",
7254 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7255 "LANDBACK; 201;185;122;",
7261 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7262 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7263 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7264 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7265 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7266 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7267 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7268 "DILG0; 80; 80; 80;",
7269 "DILG1; 80; 80; 80;",
7271 "DILG3; 65; 65; 65;",
7272 "DILG4; 220;220;220;",
7273 "UITX1; 31; 34; 35;",
7276 "UARTE; 64; 64; 64;",
7278 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7279 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7280 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7282 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7283 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7284 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7285 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7288 "DASHL; 20; 20; 20;",
7289 "DASHF; 64; 64; 64;",
7290 "DASHR; 70; 15; 15;",
7291 "DASHG; 15; 70; 15;",
7292 "DASHN; 17; 80; 56;",
7293 "DASH1; 48; 52; 72;",
7294 "DASH2; 36; 36; 53;",
7295 "COMP1; 24; 24; 24;",
7297 "GREY3; 10; 10; 10;",
7298 "BLUE4; 70; 70;140;",
7299 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7300 "LANDBACK; 201;185;122;",
7304int get_static_line(
char *d,
const char **p,
int index,
int n) {
7305 if (!strcmp(p[index],
"*****"))
return 0;
7307 strncpy(d, p[index], n);
7311void InitializeUserColors() {
7312 const char **p = usercolors;
7320 UserColorTableArray =
new wxArrayPtrVoid;
7321 UserColourHashTableArray =
new wxArrayPtrVoid;
7325 ct->tableName =
new wxString(
"DAY");
7326 ct->color =
new wxArrayPtrVoid;
7327 UserColorTableArray->Add((
void *)ct);
7330 ct->tableName =
new wxString(
"DUSK");
7331 ct->color =
new wxArrayPtrVoid;
7332 UserColorTableArray->Add((
void *)ct);
7335 ct->tableName =
new wxString(
"NIGHT");
7336 ct->color =
new wxArrayPtrVoid;
7337 UserColorTableArray->Add((
void *)ct);
7339 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7340 if (!strncmp(buf,
"Table", 5)) {
7341 sscanf(buf,
"Table:%s", TableName);
7343 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7344 ctp = (colTable *)(UserColorTableArray->Item(it));
7345 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7354 while (buf[j] !=
';' && j < 20) {
7360 S52color *c =
new S52color;
7361 strcpy(c->colName, name);
7363 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7376 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7377 wxColorHashMap *phash =
new wxColorHashMap;
7378 UserColourHashTableArray->Add((
void *)phash);
7380 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7382 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7383 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7385 wxColour c(c2->R, c2->G, c2->B);
7386 wxString key(c2->colName, wxConvUTF8);
7394 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7397void DeInitializeUserColors() {
7398 if (!UserColorTableArray)
return;
7399 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7400 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7402 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7403 S52color *c = (S52color *)ct->color->Item(j);
7407 delete ct->tableName;
7413 delete UserColorTableArray;
7415 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7416 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7420 delete UserColourHashTableArray;
7427typedef struct _MSW_COLOR_SPEC {
7429 wxString S52_RGB_COLOR;
7433MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7434 {COLOR_MENUTEXT,
"UITX1", 0},
7435 {COLOR_BTNSHADOW,
"UIBCK", 0},
7438void SaveSystemColors() {
7452 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7453 while (pcspec->COLOR_NAME != -1) {
7454 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7459void RestoreSystemColors() {
7460 int element[NCOLORS];
7461 int rgbcolor[NCOLORS];
7464 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7465 while (pcspec->COLOR_NAME != -1) {
7466 element[i] = pcspec->COLOR_NAME;
7467 rgbcolor[i] = pcspec->SysRGB_COLOR;
7473 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7478void SetSystemColors(ColorScheme cs) {
7480 int element[NCOLORS];
7481 int rgbcolor[NCOLORS];
7483 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7484 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7485 while (pcspec->COLOR_NAME != -1) {
7486 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7487 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7488 element[i] = pcspec->COLOR_NAME;
7494 pSetSysColors(i, (
unsigned long *)&element[0],
7495 (
unsigned long *)&rgbcolor[0]);
7499 RestoreSystemColors();
7504wxColor GetDimColor(wxColor c) {
7505 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7506 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7510 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7511 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7513 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7514 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7515 hsv.value = hsv.value * factor;
7516 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7518 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7524double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7525 double const AnchorPointMaxDist)
7528 if (d < AnchorPointMinDist)
7529 return AnchorPointMinDist;
7530 else if (d > AnchorPointMaxDist)
7531 return AnchorPointMaxDist;
7537 if (d > -AnchorPointMinDist)
7538 return -AnchorPointMinDist;
7539 else if (d < -AnchorPointMaxDist)
7540 return -AnchorPointMaxDist;
7547static const WORD MAX_CONSOLE_LINES =
7552void RedirectIOToConsole()
7557 wxIntPtr lStdHandle;
7559 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7569 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7570 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7571 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7575 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7576 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7577 fp = _fdopen(hConHandle,
"w");
7579 setvbuf(stdout, NULL, _IONBF, 0);
7583 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7584 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7585 fp = _fdopen(hConHandle,
"r");
7587 setvbuf(stdin, NULL, _IONBF, 0);
7591 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7592 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7593 fp = _fdopen(hConHandle,
"w");
7595 setvbuf(stderr, NULL, _IONBF, 0);
7607bool TestGLCanvas(wxString prog_dir) {
7609 wxString test_app = prog_dir;
7610 test_app +=
"ocpn_gltest1.exe";
7612 if (::wxFileExists(test_app)) {
7613 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7614 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7615 if (proc_return == 0)
7616 printf(
"GLCanvas OK\n");
7618 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7620 return (proc_return == 0);
7630bool ReloadLocale() {
7635 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7642 FontMgr::Get().SetLocale(g_locale);
7656 if (pRouteManagerDialog) {
7657 pRouteManagerDialog->Hide();
7658 pRouteManagerDialog->Destroy();
7659 pRouteManagerDialog = NULL;
7663 if (g_pais_query_dialog_active) {
7664 g_pais_query_dialog_active->Destroy();
7665 g_pais_query_dialog_active = NULL;
7668 auto alert_dlg_active =
7670 if (alert_dlg_active) {
7671 alert_dlg_active->Destroy();
7672 g_pais_alert_dialog_active =
nullptr;
7675 if (g_pAISTargetList) {
7677 g_pAISTargetList->Disconnect_decoder();
7678 g_pAISTargetList->Destroy();
7679 g_pAISTargetList = NULL;
7683 if (gFrame->m_pMenuBar) {
7684 gFrame->SetMenuBar(NULL);
7685 gFrame->m_pMenuBar->Destroy();
7686 gFrame->m_pMenuBar = NULL;
7688 gFrame->BuildMenuBar();
7691 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7693 if (cc) cc->CanvasApplyLocale();
7698 wxString perspective;
7699 pConfig->SetPath(
"/AUI");
7700 pConfig->Read(
"AUIPerspective", &perspective);
7714 bool bno_load =
false;
7715 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7717 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7718 wxAuiPaneInfo pane = pane_array_val[i];
7719 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7725 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7730 gFrame->RequestNewToolbars(
true);
7731 gFrame->RequestNewMasterToolbar(
true);
7748 g_csv_locn = g_Platform->GetSharedDataDir();
7749 g_csv_locn.Append(
"s57data");
7753 appendOSDirSlash(&g_csv_locn);
7754 g_csv_locn.Append(
"s57data");
7759 if (g_SENCPrefix.IsEmpty()) {
7761 appendOSDirSlash(&g_SENCPrefix);
7762 g_SENCPrefix.Append(
"SENC");
7766 wxFileName f(g_SENCPrefix);
7768 g_SENCPrefix = f.GetFullPath();
7770 g_SENCPrefix =
"SENC";
7776 bool b_force_legacy =
false;
7778 if (g_UserPresLibData.IsEmpty()) {
7779 plib_data = g_csv_locn;
7780 appendOSDirSlash(&plib_data);
7781 plib_data.Append(
"S52RAZDS.RLE");
7783 plib_data = g_UserPresLibData;
7784 b_force_legacy =
true;
7787 ps52plib =
new s52plib(plib_data, b_force_legacy);
7802 if (!ps52plib->m_bOK) {
7805 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7807 wxString look_data_dir;
7808 look_data_dir.Append(std_path.GetUserDataDir());
7809 appendOSDirSlash(&look_data_dir);
7810 wxString tentative_SData_Locn = look_data_dir;
7811 look_data_dir.Append(
"s57data");
7813 plib_data = look_data_dir;
7814 appendOSDirSlash(&plib_data);
7815 plib_data.Append(
"S52RAZDS.RLE");
7817 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7818 ps52plib =
new s52plib(plib_data);
7820 if (ps52plib->m_bOK) {
7821 g_csv_locn = look_data_dir;
7830 if (!ps52plib->m_bOK) {
7833 wxString look_data_dir;
7834 look_data_dir = g_Platform->GetSharedDataDir();
7835 look_data_dir.Append(
"s57data");
7837 plib_data = look_data_dir;
7838 appendOSDirSlash(&plib_data);
7839 plib_data.Append(
"S52RAZDS.RLE");
7841 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7842 ps52plib =
new s52plib(plib_data);
7844 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7847 if (ps52plib->m_bOK) {
7848 wxLogMessage(
"Using s57data in " + g_csv_locn);
7850 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7855 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7857 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7858 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7859 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7860 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7863 pConfig->LoadS57Config();
7864 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7870 ps52plib->SetDIPFactor(dip_factor);
7875 ps52plib->SetScaleFactorExp(
7876 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7877 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7884 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7885 ps52plib->SetGLRendererString(renderer);
7888 ps52plib->SetGLOptions(
7889 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7890 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7891 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7896 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7905 : wxThread(wxTHREAD_JOINABLE) {
7906 m_filename = filename;
7917 newChart->SetNativeScale(m_scale);
7918 newChart->SetFullExtent(m_ext);
7920 newChart->FindOrCreateSenc(m_filename);
7925 wxString m_filename;
7931static double chart_dist(
int index) {
7937 if (cte.GetBBox().Contains(
gLat,
gLon))
7942 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7943 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7944 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7947 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7948 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7950 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7956WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7957static int CompareInts(
int n1,
int n2) {
7958 double d1 = chart_dist(n1);
7959 double d2 = chart_dist(n2);
7960 return (
int)(d1 - d2);
7965 wxString chart_path;
7970WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7972#include <wx/arrimpl.cpp>
7975void ParseAllENC(wxWindow *parent) {
7976 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7984 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7987 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7989 idx_sorted_by_distance.Add(i);
7993 if (count == 0)
return;
7995 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
8001 ArrayOfCompressTargets ct_array;
8002 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8003 int i = idx_sorted_by_distance[j];
8006 double distance = chart_dist(i);
8008 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8011 pct->distance = distance;
8012 pct->chart_path = filename;
8014 ct_array.push_back(pct);
8017 int thread_count = 0;
8020 if (g_nCPUCount > 0)
8021 thread_count = g_nCPUCount;
8023 thread_count = wxThread::GetCPUCount();
8025 if (thread_count < 1) {
8034 for(
int t = 0; t < thread_count; t++)
8038 wxGenericProgressDialog *prog =
nullptr;
8042 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8043 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8045 prog =
new wxGenericProgressDialog();
8047 prog->SetFont(*qFont);
8049 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8050 count + 1, parent, style);
8059 prog->ShowWindowModal();
8068 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8069 wxString filename = ct_array[j].chart_path;
8070 double distance = ct_array[j].distance;
8071 int index =
ChartData->FinddbIndex(filename);
8072 if (index < 0)
continue;
8075 ext.NLAT = cte.GetLatMax();
8076 ext.SLAT = cte.GetLatMin();
8077 ext.WLON = cte.GetLonMin();
8078 ext.ELON = cte.GetLonMax();
8080 int scale = cte.GetScale();
8083 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8086 if (wxThread::IsMain()) {
8088 wxSize sz = prog->GetSize();
8093 prog->Update(count, msg, &skip);
8105 newChart->SetNativeScale(
scale);
8106 newChart->SetFullExtent(ext);
8107 newChart->DisableBackgroundSENC();
8109 newChart->FindOrCreateSenc(filename,
8113 if (wxThread::IsMain()) {
8114 msg.Printf(_(
"ENC Completed."));
8116 prog->Update(count, msg, &skip);
8126 for (
int t = 0;; t = (t + 1) % thread_count) {
8133 if (!workers[t]->IsAlive()) {
8146#if defined(__WXMSW__) || defined(__WXOSX__)
8153 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.