52#include <wx/stdpaths.h>
53#include <wx/tokenzr.h>
54#include <wx/display.h>
55#include <wx/jsonreader.h>
59#include "model/ais_target_data.h"
60#include "model/autopilot_output.h"
64#include "model/comm_n0183_output.h"
66#include "model/comm_vars.h"
68#include "model/cutil.h"
69#include "model/georef.h"
73#include "model/idents.h"
78#include "model/nav_object_database.h"
79#include "model/navutil_base.h"
81#include "model/own_ship.h"
84#include "model/routeman.h"
85#include "model/select.h"
88#include "model/track.h"
90#include "dialog_alert.h"
94#include "ais_info_gui.h"
114#include "glChartCanvas.h"
115#include "GoToPositionDialog.h"
117#include "iENCToolbar.h"
119#include "load_errors_dlg.h"
122#include "N2KParser.h"
126#include "OCPN_AUIManager.h"
127#include "ocpn_frame.h"
128#include "OCPNPlatform.h"
129#include "OCPN_Sound.h"
132#include "print_dialog.h"
133#include "printout_chart.h"
134#include "routemanagerdialog.h"
135#include "routeman_gui.h"
136#include "route_point_gui.h"
137#include "RoutePropDlgImpl.h"
140#include "S57QueryDialog.h"
141#include "SystemCmdSound.h"
145#include "TrackPropDlg.h"
146#include "waypointman_gui.h"
151#include "androidUTIL.h"
157WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
165extern arrayofCanvasPtr g_canvasArray;
178extern About *g_pAboutDlgLegacy;
182extern wxString g_locale;
183extern ColorScheme global_color_scheme;
188GLenum g_texture_rectangle_format;
191#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
192extern wxLocale *plocale_def_lang;
199extern s52plib *ps52plib;
203extern bool g_b_legacy_input_filter_behaviour;
204extern bool g_bTrackActive;
206extern bool g_bmasterToolbarFull;
207extern int g_nAutoHideToolbar;
208extern bool g_bAutoHideToolbar;
209extern bool g_bshowToolbar;
210extern int g_maintoolbar_x;
211extern int g_maintoolbar_y;
212extern wxString g_toolbarConfig;
213extern float g_toolbar_scalefactor;
214extern float g_compass_scalefactor;
215extern bool g_bShowMenuBar;
216extern bool g_bShowCompassWin;
218extern bool g_benable_rotate;
219extern int g_GUIScaleFactor;
220extern int g_ChartScaleFactor;
221extern int g_last_ChartScaleFactor;
222extern int g_ShipScaleFactor;
223extern float g_ShipScaleFactorExp;
224extern int g_ENCTextScaleFactor;
226extern bool g_bShowTide;
227extern bool g_bShowCurrent;
228extern bool g_bUIexpert;
229extern RouteList *pRouteList;
230extern wxString g_default_wp_icon;
231extern std::vector<std::string> TideCurrentDataSet;
232extern wxString g_TCData_Dir;
234extern char nmea_tick_chars[];
235extern double AnchorPointMinDist;
236extern bool AnchorAlertOn1, AnchorAlertOn2;
237extern wxString g_AW1GUID;
238extern wxString g_AW2GUID;
239extern bool g_bCruising;
243extern std::vector<Track *> g_TrackList;
244extern double gQueryVar;
245extern int g_ChartUpdatePeriod;
246extern int g_SkewCompUpdatePeriod;
247extern bool g_bCourseUp;
248extern bool g_bLookAhead;
249extern bool g_bskew_comp;
250extern bool g_bPauseTest;
252extern bool g_bPlayShipsBells;
253extern wxDateTime g_loglast_time;
254extern int g_nAWDefault;
256extern bool g_bDeferredStartTrack;
260extern bool g_bDeferredInitDone;
261extern int options_lastPage;
262extern int options_subpage;
263extern bool b_reloadForPlugins;
265extern int g_NeedDBUpdate;
266extern bool g_bFullscreen;
267extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
269extern bool g_bEnableZoomToCursor;
272extern wxString ChartListFileName;
273extern bool g_bFullscreenToolbar;
274extern arrayofCanvasPtr g_canvasArray;
275extern wxString g_lastAppliedTemplateGUID;
276extern wxPoint options_lastWindowPos;
277extern wxSize options_lastWindowSize;
278extern unsigned int g_canvasConfig;
279extern bool g_bFullScreenQuilt;
280extern bool g_bQuiltEnable;
281extern wxString *pInit_Chart_Dir;
282extern bool g_bShowOutlines;
283extern bool g_bTempShowMenuBar;
284extern bool g_bShowStatusBar;
285extern bool g_FlushNavobjChanges;
286extern int g_FlushNavobjChangesTimeout;
287extern bool g_bShowChartBar;
288extern double g_plus_minus_zoom_factor;
289extern int g_nframewin_x;
290extern int g_nframewin_y;
291extern int g_nframewin_posx;
292extern int g_nframewin_posy;
293extern bool g_bframemax;
294extern LayerList *pLayerList;
295extern bool g_bAutoAnchorMark;
296extern wxDateTime g_start_time;
297extern bool g_bcompression_wait;
298extern bool g_bquiting;
299extern bool b_inCloseWindow;
300extern bool b_inCompressAllCharts;
301extern long g_maintoolbar_orient;
302extern wxAuiDefaultDockArt *g_pauidockart;
303extern int g_click_stop;
304extern wxString g_CmdSoundString;
305extern std::vector<OcpnSound *> bells_sound;
306extern char bells_sound_file_name[2][12];
307extern int g_sticky_chart;
308extern int g_sticky_projection;
309extern wxArrayPtrVoid *UserColourHashTableArray;
310extern wxColorHashMap *pcurrent_user_color_hash;
313extern bool g_own_ship_sog_cog_calc;
314extern int g_own_ship_sog_cog_calc_damp_sec;
315extern bool g_bHasHwClock;
316extern bool s_bSetSystemTime;
317extern bool bVelocityValid;
318extern int gHDx_Watchdog;
321extern bool g_bUseGLL;
322extern int g_MemFootMB;
325extern int g_chart_zoom_modifier_vector;
326extern bool g_config_display_size_manual;
327extern bool g_PrintingInProgress;
328extern bool g_disable_main_toolbar;
329extern bool g_btenhertz;
330extern bool g_declutter_anchorage;
337typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
338typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
340SetSysColors_t pSetSysColors;
341GetSysColor_t pGetSysColor;
343void SaveSystemColors(
void);
344void RestoreSystemColors(
void);
349DWORD color_3ddkshadow;
351DWORD color_activecaption;
352DWORD color_gradientactivecaption;
353DWORD color_captiontext;
354DWORD color_windowframe;
355DWORD color_inactiveborder;
360#include <wx/msw/msvcrt.h>
364static const long long lNaN = 0xfff8000000000000;
365#define NAN (*(double *)&lNaN)
368static wxArrayPtrVoid *UserColorTableArray = 0;
371double gLat_gt, gLon_gt;
372double gLat_gt_m1, gLon_gt_m1;
374uint64_t fix_time_gt_last;
376double gSog_gt, gHdt_gt;
377double gCog_gt_m1, gHdt_gt_m1;
379double cog_rate_gt, hdt_rate_gt;
382void appendOSDirSlash(wxString *pString);
384void InitializeUserColors(
void);
385void DeInitializeUserColors(
void);
386void SetSystemColors(ColorScheme cs);
388static bool LoadAllPlugIns(
bool load_enabled) {
389 AbstractPlatform::ShowBusySpinner();
390 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
391 AbstractPlatform::HideBusySpinner();
395static void LaunchLocalHelp(
void) {
397 androidLaunchHelpView();
399 wxString def_lang_canonical =
"en_US";
402 if (plocale_def_lang)
403 def_lang_canonical = plocale_def_lang->GetCanonicalName();
406 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
408 wxString help_try = help_locn + def_lang_canonical +
".html";
410 if (!::wxFileExists(help_try)) {
411 help_try = help_locn +
"en_US" +
".html";
413 if (!::wxFileExists(help_try)) {
414 help_try = help_locn +
"web" +
".html";
417 if (!::wxFileExists(help_try))
return;
420 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
424static void DoHelpDialog(
void) {
429 g_pAboutDlg->SetFocus();
434 if (!g_pAboutDlgLegacy)
435 g_pAboutDlgLegacy =
new About(gFrame, g_Platform->GetSharedDataDir(),
436 [] { LaunchLocalHelp(); });
438 g_pAboutDlgLegacy->SetFocus();
439 g_pAboutDlgLegacy->Show();
448#if defined(__WXGTK__) || defined(__WXQT__)
449#include "bitmaps/opencpn.xpm"
463void BuildiENCToolbar(
bool bnew) {
464 if (g_bInlandEcdis) {
467 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
468 wxPoint tbp_incanvas =
471 g_iENCToolbarPosY = tbp_incanvas.y;
472 g_iENCToolbarPosX = tbp_incanvas.x;
474 delete g_iENCToolbar;
479 if (!g_iENCToolbar) {
480 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
484 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
486 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
487 g_iENCToolbarPosY = -1;
490 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
496 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
500 double tool_scale_factor =
501 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
504 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
505 g_iENCToolbar->SetColorScheme(global_color_scheme);
506 g_iENCToolbar->EnableSubmerge(
false);
509 delete g_iENCToolbar;
510 g_iENCToolbar = NULL;
514bool ShowNavWarning() {
517OpenCPN is distributed in the hope that it will be useful, \
518but WITHOUT ANY WARRANTY; without even the implied \
519warranty of MERCHANTABILITY or FITNESS FOR A \
520PARTICULAR PURPOSE.\n\n\
521See the GNU General Public License for more details.\n\n\
522OpenCPN must only be used in conjunction with approved \
523paper charts and traditional methods of navigation.\n\n\
524DO NOT rely upon OpenCPN for safety of life or property.\n\n\
525Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
527 wxString vs = wxString::Format(
" .. Version %s", VERSION_FULL);
530 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
533 msg.Replace(
"\n",
"<br>");
535 std::stringstream html;
536 html <<
"<html><body><p>";
537 html << msg.ToStdString();
538 html <<
"</p></body></html>";
540 std::string title = _(
"Welcome to OpenCPN").ToStdString();
541 std::string action = _(
"Agree").ToStdString();
543 info_dlg.SetInitialSize();
544 info_dlg.AddHtmlContent(html);
545 int agreed = info_dlg.ShowModal();
546 return agreed == wxID_OK;
551 if (chart ==
nullptr)
return false;
554 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
556 if (cc && cc->m_singleChart == chart) {
563#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
566static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
567 const char *prop_name) {
571 unsigned long ret_nitems;
572 unsigned long ret_bytes_after;
573 unsigned char *ret_prop;
575 xa_prop_name = XInternAtom(disp, prop_name, False);
583 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
584 &xa_ret_type, &ret_format, &ret_nitems,
585 &ret_bytes_after, &ret_prop) != Success)
588 if (xa_ret_type != xa_prop_type) {
592 return (
char *)ret_prop;
597static bool isTransparentToolbarInOpenGLOK(
void) {
604 if (!g_bdisable_opengl) {
605 Display *disp = XOpenDisplay(NULL);
607 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
609 "_NET_SUPPORTING_WM_CHECK")) ||
610 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
612 "_WIN_SUPPORTING_WM_CHECK"))) {
615 if ((wm_name = get_X11_property(disp, *sup_window,
616 XInternAtom(disp,
"UTF8_STRING", False),
618 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
621 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
642wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
644BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
645EVT_CLOSE(MyFrame::OnCloseWindow)
646EVT_MENU(wxID_EXIT, MyFrame::OnExit)
647EVT_SIZE(MyFrame::OnSize)
648EVT_MOVE(MyFrame::OnMove)
649EVT_ICONIZE(MyFrame::OnIconize)
650EVT_MENU(-1, MyFrame::OnToolLeftClick)
651EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
653EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
654EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
655EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
657EVT_MAXIMIZE(MyFrame::OnMaximize)
658EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
659 MyFrame::RequestNewToolbarArgEvent)
660EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
662EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
663EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
664EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
666#ifdef wxHAS_POWER_EVENTS
667EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
668EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
669EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
670EVT_POWER_RESUME(MyFrame::OnResume)
681static
void onBellsFinishedCB(
void *ptr) {
682 auto framePtr =
static_cast<MyFrame *
>(ptr);
684 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
685 wxPostEvent(framePtr, ev);
690 auto msg = ev.GetString().ToStdString();
691 auto ¬eman = NotificationManager::GetInstance();
692 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
695static NmeaLog *GetDataMonitor() {
696 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
697 return dynamic_cast<NmeaLog *
>(w);
701MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
702 const wxSize &size,
long style)
703 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
704 m_connections_dlg(nullptr),
706 g_current_monitor = wxDisplay::GetFromWindow(
this);
712 g_current_monitor_dip_px_ratio =
713 g_monitor_info[g_current_monitor].width_px /
714 g_monitor_info[g_current_monitor].width;
717 m_last_track_rotation_ts = 0;
718 m_ulLastNMEATicktime = 0;
719 m_data_monitor->Hide();
721 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
725 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
728 InitTimer.SetOwner(
this, INIT_TIMER);
730 m_initializing =
false;
733 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
736 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
739 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
742 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
745 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
747 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
756 m_bTimeIsSet =
false;
759 m_bdefer_resize =
false;
762 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
763 COGFilterTable[i] = NAN;
764 SOGFilterTable[i] = NAN;
766 m_last_bGPSValid =
false;
767 m_last_bVelocityValid =
false;
777 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
782 double process_noise_std = 1.0;
783 double measurement_noise_std = 0.5;
785 m_ChartUpdatePeriod = 1;
790 log_callbacks.log_is_active = [&]() {
791 auto log = GetDataMonitor();
792 return log && log->IsVisible();
794 log_callbacks.log_message = [&](
Logline ll) {
795 NmeaLog *monitor = GetDataMonitor();
798 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
801 ais_callbacks.confirm_stop_track = []() {
802 int r = OCPNMessageBox(
804 _(
"This AIS target has Persistent tracking selected by MMSI "
806 "A Persistent track recording will therefore be restarted for this "
808 "Do you instead want to stop Persistent tracking for this target?"),
809 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
810 return r == wxID_YES;
812 ais_callbacks.get_target_mmsi = []() {
813 auto alert_dlg_active =
815 assert(alert_dlg_active);
816 return alert_dlg_active->Get_Dialog_MMSI();
824 wxLogMessage(
" **** Connect stuff");
830 Connect(wxEVT_OCPN_MSG,
831 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
838 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
839 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
847#if defined(__WXGTK__) || defined(__WXQT__)
848 wxIcon app_icon(opencpn);
856 wxDynamicLibrary dllUser32(
"user32.dll");
858 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
859 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
864 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
867 g_sticky_projection = -1;
870 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
871 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
873 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
875 [&](wxCommandEvent) { Refresh(); });
876 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
881 EnableFullScreenView();
883 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
889 FrameTenHzTimer.Stop();
896 wxRouteListNode *node = pRouteList->GetFirst();
899 Route *pRouteDelete = node->GetData();
902 node = node->GetNext();
909 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
915void MyFrame::FreezeCharts() {
918 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
920 if (cc) cc->Freeze();
925void MyFrame::ThawCharts() {
928 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
937 switch (event.type) {
938 case SENC_BUILD_STARTED:
941 case SENC_BUILD_DONE_NOERROR:
943 chart =
event.m_ticket->m_chart;
945 chart->PostInit(FULL_INIT, global_color_scheme);
947 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
949 if (cc) cc->ClearS52PLIBStateHash();
954 delete event.m_ticket;
956 case SENC_BUILD_DONE_ERROR:
964void MyFrame::RebuildChartDatabase() {
965 bool b_SetInitialPoint =
false;
968 ArrayOfCDI ChartDirArray;
969 pConfig->LoadChartDirArray(ChartDirArray);
971 if (ChartDirArray.GetCount()) {
974 if (g_NeedDBUpdate == 1) {
976 _(
"OpenCPN needs to update the chart database from config file "
980 wxICON_INFORMATION | wxOK);
988 _(
"Rebuilding chart database from configuration file entries..."));
992 wxString dummy1 = _(
"Elapsed time : ");
993 wxString dummy2 = _(
"Estimated time : ");
994 wxString dummy3 = _(
"Remaining time : ");
995 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
996 _(
"OpenCPN Chart Update"), line, 100, NULL,
997 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
998 wxPD_REMAINING_TIME);
1001 ChartData->SaveBinary(ChartListFileName);
1011void MyFrame::OnBellsFinished(wxCommandEvent &event) {
1012 int bells = wxMin(m_BellsToPlay, 2);
1013 if (bells <= 0)
return;
1015 wxString soundfile =
"sounds";
1016 appendOSDirSlash(&soundfile);
1017 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
1018 soundfile.Prepend(g_Platform->GetSharedDataDir());
1019 wxLogMessage(
"Using bells sound file: " + soundfile);
1021 OcpnSound *sound = bells_sound[bells - 1];
1022 sound->SetFinishedCallback(onBellsFinishedCB,
this);
1023 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
1024 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
1025 sound->Load(soundfile);
1026 if (!sound->IsOk()) {
1027 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
1031 m_BellsToPlay -= bells;
1034void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
1036void MyFrame::OnMaximize(wxMaximizeEvent &event) {
1043ColorScheme GetColorScheme() {
return global_color_scheme; }
1045ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
1047void MyFrame::ReloadAllVP() {
1048 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1050 if (cc) cc->ReloadVP();
1054void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
1055 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
1058 global_color_scheme = cs;
1059 wxString SchemeName;
1061 case GLOBAL_COLOR_SCHEME_DAY:
1064 case GLOBAL_COLOR_SCHEME_DUSK:
1065 SchemeName =
"DUSK";
1067 case GLOBAL_COLOR_SCHEME_NIGHT:
1068 SchemeName =
"NIGHT";
1075 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
1077 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
1078 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
1079 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1080 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
1081 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
1083 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1112 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1113 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1115 g_pauimgr->Update();
1117 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1120 unsigned Usercolortable_index = 0;
1121 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1122 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1123 if (SchemeName.IsSameAs(*ct->tableName)) {
1124 Usercolortable_index = i;
1129 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1132 pcurrent_user_color_hash =
1133 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1135 SetSystemColors(cs);
1138 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1141 cc->SetColorScheme(cs);
1142 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1143 cc->HideChartInfoWindow();
1144 cc->SetQuiltChartHiLiteIndex(-1);
1150 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1154 g_options->SetColorScheme(cs);
1162 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1165 if (g_pMarkInfoDialog) {
1166 g_pMarkInfoDialog->SetColorScheme(cs);
1169 if (pRoutePropDialog) {
1170 pRoutePropDialog->SetColorScheme(cs);
1175 if (g_pais_query_dialog_active) {
1176 bool b_isshown = g_pais_query_dialog_active->IsShown();
1177 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1178 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1180 g_pais_query_dialog_active->Close();
1183 g_pais_query_dialog_active->
Create(
1184 this, -1, _(
"AIS Target Query"),
1185 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1186 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1187 g_pais_query_dialog_active->UpdateText();
1188 if (b_isshown) g_pais_query_dialog_active->Show();
1191 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1193 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1195 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1197 ApplyGlobalColorSchemetoStatusBar();
1199 UpdateAllToolbars(cs);
1201 if (g_MainToolbar) {
1202 if (g_MainToolbar->GetColorScheme() != cs) {
1204 bool btoolbarFull = g_bmasterToolbarFull;
1206 g_MainToolbar->SetColorScheme(cs);
1210 if (!btoolbarFull) {
1212 RequestNewMasterToolbar();
1213 g_MainToolbar->SetColorScheme(cs);
1214 CollapseGlobalToolbar();
1217 RequestNewMasterToolbar();
1218 g_MainToolbar->SetColorScheme(cs);
1223 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1226void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1227 if (m_pStatusBar != NULL) {
1228 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1229 m_pStatusBar->ClearBackground();
1234 if (g_canvasArray.GetCount() > 0)
1235 return g_canvasArray.Item(0);
1239void MyFrame::CancelAllMouseRoute() {
1241 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1243 if (cc) cc->CancelMouseRoute();
1247void MyFrame::NotifyChildrenResize() {}
1249void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1257 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1260 g_pauimgr->DetachPane(cc);
1265 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1274 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1277 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1278 config_array.Item(i)->canvas = NULL;
1284 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1285 g_canvasArray.RemoveAt(i);
1289 switch (g_canvasConfig) {
1292 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1295 g_canvasArray.Add(cc);
1297 cc = g_canvasArray[0];
1303 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1304 cc->GetglCanvas()->Show();
1307 config_array.Item(0)->canvas = cc;
1311 cc->ApplyCanvasConfig(config_array.Item(0));
1315 cc->ConfigureChartBar();
1316 cc->SetColorScheme(global_color_scheme);
1317 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1318 cc->SetShowGPS(
true);
1320 g_pauimgr->AddPane(cc);
1321 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1322 g_pauimgr->GetPane(cc).Fixed();
1323 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1324 g_pauimgr->GetPane(cc).CenterPane();
1329 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1331 g_canvasArray.Add(cc);
1333 cc = g_canvasArray[0];
1339 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1342 config_array.Item(0)->canvas = cc;
1344 cc->ApplyCanvasConfig(config_array.Item(0));
1347 cc->ConfigureChartBar();
1348 cc->SetColorScheme(global_color_scheme);
1349 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1350 cc->SetShowGPS(
false);
1352 g_pauimgr->AddPane(cc);
1353 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1354 g_pauimgr->GetPane(cc)
1355 .CaptionVisible(
false)
1357 .CloseButton(
false);
1359 g_pauimgr->GetPane(cc).CenterPane();
1362 g_canvasArray.Add(cc);
1366 if (config_array.GetCount() < 2) {
1368 pcc->configIndex = 1;
1372 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1373 config_array.Add(pcc);
1376 config_array.Item(1)->canvas = cc;
1378 cc->ApplyCanvasConfig(config_array.Item(1));
1381 cc->ConfigureChartBar();
1382 cc->SetColorScheme(global_color_scheme);
1383 cc->SetShowGPS(
true);
1386 g_pauimgr->AddPane(cc);
1387 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1388 g_pauimgr->GetPane(cc)
1389 .CaptionVisible(
false)
1391 .CloseButton(
false);
1392 g_pauimgr->GetPane(cc).RightDockable(
true);
1393 g_pauimgr->GetPane(cc).Right();
1396 config_array.Item(1)->canvasSize =
1397 wxSize(GetClientSize().x / 2, GetClientSize().y);
1398 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1403 if (b_useStoredSize) {
1404 int ccw = config_array.Item(1)->canvasSize.x;
1405 int cch = config_array.Item(1)->canvasSize.y;
1408 if (ccw < GetClientSize().x / 10) {
1409 ccw = GetClientSize().x / 2;
1410 cch = GetClientSize().y;
1413 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1414 cc->SetSize(ccw, cch);
1428 if (g_canvasArray.size() > 1)
1432 console->SetColorScheme(global_color_scheme);
1436 if (g_pRouteMan->IsAnyRouteActive()) {
1437 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1443void MyFrame::RequestNewToolbars(
bool bforcenew) {
1444 if (b_inCloseWindow) {
1448 BuildiENCToolbar(bforcenew);
1449 PositionIENCToolbar();
1458void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1459 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1464void MyFrame::SetAllToolbarScale() {
1465 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1468void MyFrame::SetGPSCompassScale() {
1469 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1473 wxPoint screenPoint = ::wxGetMousePosition();
1476 switch (g_canvasConfig) {
1478 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1481 if (canvas->GetScreenRect().Contains(
1485 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1488 if (canvas->GetScreenRect().Contains(
1495 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1498 if (canvas->GetScreenRect().Contains(
1499 canvas->ScreenToClient(screenPoint)))
1507int MyFrame::GetCanvasIndexUnderMouse() {
1508 wxPoint screenPoint = ::wxGetMousePosition();
1511 switch (g_canvasConfig) {
1513 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1516 if (canvas->GetScreenRect().Contains(
1520 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1523 if (canvas->GetScreenRect().Contains(
1530 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1533 if (canvas->GetScreenRect().Contains(
1534 canvas->ScreenToClient(screenPoint)))
1542bool MyFrame::DropMarker(
bool atOwnShip) {
1549 if (!canvas)
return false;
1556 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1558 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1560 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1565 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1566 pRouteManagerDialog->UpdateWptListCtrl();
1571 RefreshAllCanvas(
false);
1576void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1577 if (g_canvasConfig != 0) {
1580 int nTargetGTK = -1;
1582 wxWindow *source = FindFocus();
1588 switch (g_canvasConfig) {
1590 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1593 if (canvas && (canvas == test)) {
1598 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1601 if (canvas && (canvas == test)) {
1609 int nfinalTarget = nTarget;
1611 nfinalTarget = nTargetGTK;
1613 target = ConfigMgr::Get()
1614 .GetCanvasConfigArray()
1619 target->Refresh(
true);
1630void MyFrame::FastClose() {
1632 FrameTenHzTimer.Stop();
1634 FrameTimer1.Start(1);
1638void MyFrame::OnExit(wxCommandEvent &event) {
1642void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1645 if (b_inCloseWindow) {
1655 if (!g_bDeferredInitDone)
return;
1668 if (b_inCompressAllCharts) {
1672 if (bDBUpdateInProgress)
return;
1674 b_inCloseWindow =
true;
1676 ::wxSetCursor(wxCURSOR_WAIT);
1680 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1682 if (cc && cc->IsMeasureActive()) {
1683 cc->CancelMeasureRoute();
1688 SendPreShutdownHookToPlugins();
1692 if (g_pAISTargetList) {
1693 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1694 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1695 g_pauimgr->DetachPane(g_pAISTargetList);
1706 pConfig->SetPath(_T (
"/AUI" ));
1707 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1714 if (g_glTextureManager) {
1715 g_glTextureManager->PurgeJobList();
1717 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1722 SetCursor(wxCURSOR_WAIT);
1724 RefreshAllCanvas(
true);
1730 RestoreScreenBrightness();
1739 if (g_iENCToolbar) {
1740 wxPoint locn = g_iENCToolbar->GetPosition();
1741 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1742 g_iENCToolbarPosY = tbp_incanvas.y;
1743 g_iENCToolbarPosX = tbp_incanvas.x;
1747 g_bframemax = IsMaximized();
1750 FrameTenHzTimer.Stop();
1752 FrameCOGTimer.Stop();
1766 if (g_bAutoAnchorMark) {
1767 bool watching_anchor =
false;
1768 if (pAnchorWatchPoint1)
1769 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1771 if (pAnchorWatchPoint2)
1772 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1775 wxDateTime now = wxDateTime::Now();
1776 wxTimeSpan uptime = now.Subtract(g_start_time);
1778 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1779 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1784 if (g_declutter_anchorage) {
1785 wxRoutePointListNode *node =
1786 pWayPointMan->GetWaypointList()->GetFirst();
1789 if (pr->GetName().StartsWith(
"Anchorage")) {
1790 double a = gLat - pr->m_lat;
1791 double b = gLon - pr->m_lon;
1792 double l = sqrt((a * a) + (b * b));
1795 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1797 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1798 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1804 node = node->GetNext();
1808 wxString name = now.Format();
1809 name.Prepend(_(
"Anchorage created "));
1811 new RoutePoint(gLat, gLon,
"anchorage", name, wxEmptyString);
1815 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1820 pConfig->UpdateSettings();
1824 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1828 NavObj_dB::GetInstance().Close();
1832 pConfig->DeleteGroup(_T (
"/Routes" ));
1833 pConfig->DeleteGroup(_T (
"/Marks" ));
1836 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1837 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1852 if (g_iENCToolbar) {
1859 if (g_pAISTargetList) {
1860 g_pAISTargetList->Disconnect_decoder();
1861 g_pAISTargetList->Destroy();
1868 if (RouteManagerDialog::getInstanceFlag()) {
1869 if (pRouteManagerDialog) {
1870 pRouteManagerDialog->Destroy();
1871 pRouteManagerDialog = NULL;
1885 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1887 if (cc) cc->Destroy();
1890 g_canvasArray.Clear();
1892 g_pauimgr->UnInit();
1907 delete g_pi_manager;
1908 g_pi_manager = NULL;
1911 MyApp &app = wxGetApp();
1912 app.m_comm_bridge.SaveConfig();
1932 auto ®istry = CommDriverRegistry::GetInstance();
1933 registry.CloseAllDrivers();
1936 for (
auto *cp : TheConnectionParams()) {
1941 for (
auto it = pLayerList->begin(); it != pLayerList->end(); ++it) {
1947 ReleaseApiListeners();
1949 g_MainToolbar = NULL;
1950 g_bTempShowMenuBar =
false;
1952#define THREAD_WAIT_SECONDS 5
1958 if (g_bopengl && g_glTextureManager &&
1959 g_glTextureManager->GetRunningJobCount()) {
1960 g_glTextureManager->ClearAllRasterTextures();
1962 wxLogMessage(
"Starting compressor pool drain");
1963 wxDateTime now = wxDateTime::Now();
1964 time_t stall = now.GetTicks();
1965 time_t end = stall + THREAD_WAIT_SECONDS;
1968 while (stall < end) {
1969 wxDateTime later = wxDateTime::Now();
1970 stall = later.GetTicks();
1973 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1974 g_glTextureManager->GetRunningJobCount());
1976 if (!g_glTextureManager->GetRunningJobCount())
break;
1982 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1983 n_comploop, g_glTextureManager->GetRunningJobCount());
1986 delete g_glTextureManager;
1988 uninitIXNetSystem();
1992 wxLogMessage(
"gFrame destroyed.");
1995#ifndef USE_ANDROID_GLES2
1996 qDebug() <<
"Calling OnExit()";
2000 wxTheApp->ExitMainLoop();
2003void MyFrame::OnMove(wxMoveEvent &event) {
2004 auto idx = wxDisplay::GetFromWindow(
this);
2005 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
2006 static_cast<size_t>(idx) < g_monitor_info.size()) {
2007 g_current_monitor = idx;
2013 g_current_monitor_dip_px_ratio =
2014 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
2017 DEBUG_LOG <<
"Moved to " << idx
2018#if wxCHECK_VERSION(3, 1, 6)
2019 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
2020 << wxDisplay(idx).GetPPI().GetY()
2021 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
2023 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
2024 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
2025 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
2026 << wxGetDisplaySizeMM().GetY()
2027 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
2028 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
2029 << g_monitor_info[idx].height_mm <<
"mm "
2030 << g_monitor_info[idx].width_mm <<
"x"
2031 << g_monitor_info[idx].height_mm <<
"mm "
2032 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
2033 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
2034 << g_monitor_info[idx].height_px <<
"px"
2035 << g_monitor_info[idx].scale <<
"%";
2036 if (g_config_display_size_manual) {
2045 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2048 cc->SetMUIBarPosition();
2057 UpdateGPSCompassStatusBoxes();
2067 PositionIENCToolbar();
2073 g_nframewin_posx = GetPosition().x;
2074 g_nframewin_posy = GetPosition().y;
2077void MyFrame::ProcessCanvasResize(
void) {
2078 UpdateGPSCompassStatusBoxes(
true);
2082 PositionIENCToolbar();
2085 TriggerRecaptureTimer();
2089void MyFrame::TriggerRecaptureTimer() {
2090 m_recaptureTimer.Start(
2091 1000, wxTIMER_ONE_SHOT);
2094void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
2096void MyFrame::SetCanvasSizes(wxSize frameSize) {
2097 if (!g_canvasArray.GetCount())
return;
2100 int cccw = frameSize.x;
2101 int ccch = frameSize.y;
2105 switch (g_canvasConfig) {
2109 cc = g_canvasArray.Item(0);
2111 cc->GetSize( &cur_width, &cur_height );
2112 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2113 if( g_pauimgr->GetPane( cc ).IsOk() )
2114 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2116 cc->SetSize( 0, 0, cccw, ccch );
2124 cc = g_canvasArray.Item(1);
2126 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2127 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2129 ccw = wxMin(ccw, cccw * 8 / 10);
2130 ccw = wxMax(ccw, cccw * 2 / 10);
2134 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2141 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2142 g_pauimgr->GetPane(cc).Fixed();
2143 g_pauimgr->Update();
2146 g_pauimgr->GetPane(cc).Resizable();
2158void MyFrame::OnIconize(wxIconizeEvent &event) {
2160 if (g_MainToolbar) {
2161 g_MainToolbar->Show(!event.IsIconized());
2163 if (g_iENCToolbar) {
2164 g_iENCToolbar->Show(!event.IsIconized());
2168 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2170 if (cc && cc->GetMUIBar()) {
2171 if (cc->GetMUIBar()->GetCanvasOptions()) {
2172 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2173 cc->GetMUIBar()->PushCanvasOptions();
2182void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2184void MyFrame::ODoSetSize(
void) {
2186 GetClientSize(&x, &y);
2189 if (m_pStatusBar != NULL) {
2190 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2191 int currentCount = m_pStatusBar->GetFieldsCount();
2192 if (currentCount != m_StatusBarFieldCount) {
2193 if ((currentCount > 0) && (currentCount < 7)) {
2196 int widths[] = {2, 2, 2, 2, 2, 2};
2197 m_pStatusBar->SetStatusWidths(currentCount, widths);
2200 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2203 if (m_StatusBarFieldCount) {
2208 if (m_StatusBarFieldCount > 2) {
2209 int widths[] = {-6, -5, -5, -6, -4};
2210 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2211 }
else if (m_StatusBarFieldCount == 2) {
2212 int cwidth = x * 90 / 100;
2213 int widths[] = {100, 100};
2214 widths[0] = cwidth * 6.4 / 10.0;
2215 widths[1] = cwidth * 3.6 / 10.0;
2216 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2218 int widths[] = {100, 100};
2219 widths[0] = x * 90 / 100;
2220 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2223 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2224 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2225 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2227 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2229 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2237 m_pStatusBar->GetFieldRect(0, stat_box);
2240 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2242 wxFont sys_font = *wxNORMAL_FONT;
2243 int try_font_size = sys_font.GetPointSize();
2246 int min_font_size = 10;
2256 wxFont *statusBarFont =
2257 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2258 int font_size = statusBarFont->GetPointSize();
2260 font_size = wxMin(font_size,
2263 wxMax(font_size, min_font_size);
2266 font_size = statusBarFont->GetPointSize();
2273 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2274 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2276 int min_height = stat_box.height;
2278 m_pStatusBar->SetFont(*pstat_font);
2279 m_pStatusBar->SetForegroundColour(
2280 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2282 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2284 (min_height >> 1) * 2;
2285 m_pStatusBar->SetMinHeight(min_height);
2294 SetCanvasSizes(GetClientSize());
2296 UpdateGPSCompassStatusBoxes(
true);
2298 if (
console) PositionConsole();
2301 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2303 if (cc) cc->FormatPianoKeys();
2307 if (g_MainToolbar) {
2308 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2309 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2310 GetPrimaryCanvas()->GetCompass()->GetRect());
2311 g_MainToolbar->Realize();
2313 if (szBefore != g_MainToolbar->GetToolbarSize())
2314 g_MainToolbar->RefreshToolbar();
2323 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2336 options_lastWindowSize = wxSize(0, 0);
2337 options_lastWindowPos = wxPoint(0, 0);
2344 if (!b_inCloseWindow) {
2345 if (g_options) g_options->Raise();
2347 resizeAndroidPersistents();
2351 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2352 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2355 if (g_pauimgr) g_pauimgr->Update();
2358void MyFrame::PositionConsole(
void) {
2359#if defined(__WXMSW__) || defined(__WXMAC__)
2360 if (NULL == GetPrimaryCanvas())
return;
2362 int ccx, ccy, ccsx, ccsy, consx, consy;
2364 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2367 consoleHost->GetSize(&ccsx, &ccsy);
2368 consoleHost->GetPosition(&ccx, &ccy);
2370 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2371 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2372 consoleHost = GetPrimaryCanvas();
2377 if (consoleHost->GetCompass()) {
2378 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2380 if (compass_rect.y < 100)
2381 yOffset = compass_rect.y + compass_rect.height + 45;
2385 wxSize csz =
console->GetSize();
2389 wxPoint screen_pos =
2390 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2393 if (NULL == GetPrimaryCanvas())
return;
2395 int ccx, ccy, ccsx, ccsy, consx, consy;
2397 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2400 consoleHost->GetSize(&ccsx, &ccsy);
2401 consoleHost->GetPosition(&ccx, &ccy);
2403 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2404 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2405 consoleHost = GetPrimaryCanvas();
2408 int yTopOffset = 60;
2409 int yBottomOffset = 0;
2411 if (consoleHost->GetCompass()) {
2412 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2414 if (compass_rect.y < 100)
2415 yTopOffset = compass_rect.y + compass_rect.height;
2417 if (consoleHost->GetMUIBar()) {
2418 wxRect mui_rect = consoleHost->GetMUIBarRect();
2419 yBottomOffset = ccsy - mui_rect.y;
2423 wxSize csz =
console->GetSize();
2426 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2428 if (consy < yAvail) {
2429 yFinal = (yAvail - consy) / 2;
2430 yFinal += yTopOffset;
2431 }
else if (
console->GetCDI()->IsShown()) {
2432 int cdi_height =
console->GetCDI()->GetSize().y;
2433 int consy_no_cdi = consy - cdi_height;
2434 yFinal = (yAvail - consy_no_cdi) / 2;
2435 yFinal += yTopOffset;
2439 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2444void MyFrame::UpdateAllFonts() {
2453 DestroyPersistentDialogs();
2455 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2460void MyFrame::DestroyPersistentDialogs() {
2461 if (g_pais_query_dialog_active) {
2462 g_pais_query_dialog_active->Hide();
2463 g_pais_query_dialog_active->Destroy();
2464 g_pais_query_dialog_active = NULL;
2467 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2468 pRoutePropDialog->Hide();
2469 pRoutePropDialog->Destroy();
2470 pRoutePropDialog = NULL;
2473 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2474 pTrackPropDialog->Hide();
2475 pTrackPropDialog->Destroy();
2476 pTrackPropDialog = NULL;
2479 if (g_pMarkInfoDialog) {
2480 g_pMarkInfoDialog->Hide();
2481 g_pMarkInfoDialog->Destroy();
2482 g_pMarkInfoDialog = NULL;
2485 if (g_pObjectQueryDialog) {
2486 g_pObjectQueryDialog->Hide();
2487 g_pObjectQueryDialog->Destroy();
2488 g_pObjectQueryDialog = NULL;
2492void MyFrame::RefreshGroupIndices(
void) {
2494 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2496 if (cc) cc->canvasRefreshGroupIndex();
2500void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2501 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2503 switch (event.GetId()) {
2504 case ID_MENU_SCALE_OUT:
2505 DoStackDelta(GetPrimaryCanvas(), 1);
2509 case ID_MENU_SCALE_IN:
2510 DoStackDelta(GetPrimaryCanvas(), -1);
2514 case ID_MENU_ZOOM_IN: {
2515 if (GetFocusCanvas()) {
2516 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2521 case ID_MENU_ZOOM_OUT: {
2522 if (GetFocusCanvas()) {
2523 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2528 case ID_MENU_ROUTE_NEW: {
2529 if (GetFocusCanvas()) {
2530 if (0 == GetFocusCanvas()->m_routeState) {
2531 GetFocusCanvas()->StartRoute();
2533 GetFocusCanvas()->FinishRoute();
2539 case ID_MENU_TOOL_MEASURE: {
2540 GetPrimaryCanvas()->StartMeasureRoute();
2544 case ID_MENU_TOOL_NMEA_DBG_LOG:
2545 m_data_monitor->Show();
2546 m_data_monitor->Raise();
2549 case ID_MENU_TOOL_IO_MONITOR:
2550 m_data_monitor->Show();
2553 case ID_MENU_MARK_BOAT: {
2558 case ID_MENU_MARK_CURSOR: {
2563 case ID_MENU_NAV_FOLLOW: {
2564 if (gFrame->GetPrimaryCanvas())
2565 gFrame->GetPrimaryCanvas()->TogglebFollow();
2569 case ID_MENU_CHART_OUTLINES: {
2570 ToggleChartOutlines(GetFocusCanvas());
2574 case ID_MENU_CHART_QUILTING: {
2575 ToggleQuiltMode(GetFocusCanvas());
2579 case ID_MENU_UI_CHARTBAR: {
2580 ToggleChartBar(GetFocusCanvas());
2584 case ID_MENU_ENC_TEXT:
2586 ToggleENCText(GetFocusCanvas());
2589 case ID_MENU_ENC_LIGHTS: {
2590 ToggleLights(GetFocusCanvas());
2593 case ID_MENU_ENC_SOUNDINGS: {
2594 ToggleSoundings(GetFocusCanvas());
2597 case ID_MENU_ENC_ANCHOR: {
2598 ToggleAnchor(GetFocusCanvas());
2601 case ID_MENU_ENC_DATA_QUALITY: {
2602 ToggleDataQuality(GetFocusCanvas());
2605 case ID_MENU_SHOW_NAVOBJECTS: {
2606 ToggleNavobjects(GetFocusCanvas());
2610 case ID_MENU_AIS_TARGETS: {
2611 ToggleAISDisplay(GetFocusCanvas());
2614 case ID_MENU_AIS_MOORED_TARGETS: {
2615 g_bHideMoored = !g_bHideMoored;
2618 case ID_MENU_AIS_SCALED_TARGETS: {
2619 ToggleAISMinimizeTargets(GetFocusCanvas());
2623 case ID_MENU_AIS_TARGETLIST: {
2624 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2628 case ID_MENU_AIS_TRACKS: {
2629 g_bAISShowTracks = !g_bAISShowTracks;
2630 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2634 case ID_MENU_AIS_CPADIALOG: {
2635 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2636 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2637 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2638 if (g_bAIS_CPA_Alert) {
2639 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2644 case ID_MENU_AIS_CPASOUND: {
2645 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2646 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2650 case ID_MENU_AIS_CPAWARNING: {
2651 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2652 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2656 case wxID_PREFERENCES:
2658 g_MainToolbar->HideTooltip();
2663 case ID_SETTINGS_NEW: {
2668 case ID_SETTINGS_DELETE: {
2670 g_options =
nullptr;
2671 g_pOptions =
nullptr;
2675 case ID_RELOAD_CHARTS: {
2680 case ID_MENU_SETTINGS_BASIC: {
2683 androidDisableFullScreen();
2684 g_MainToolbar->HideTooltip();
2685 DoAndroidPreferences();
2692 case ID_MENU_UI_FULLSCREEN: {
2697 case ID_MENU_SHOW_CURRENTS: {
2698 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2699 GetFocusCanvas()->ReloadVP();
2700 GetFocusCanvas()->Refresh(
false);
2704 case ID_MENU_SHOW_TIDES: {
2705 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2706 GetFocusCanvas()->ReloadVP();
2707 GetFocusCanvas()->Refresh(
false);
2727 case ID_MENU_UI_COLSCHEME:
2728 case ID_COLSCHEME: {
2729 ToggleColorScheme();
2738 case ID_MENU_OQUIT: {
2743 case ID_MENU_ROUTE_MANAGER:
2744 case ID_ROUTEMANAGER: {
2745 pRouteManagerDialog = RouteManagerDialog::getInstance(
2748 if (pRouteManagerDialog->IsShown())
2749 pRouteManagerDialog->Hide();
2751 pRouteManagerDialog->UpdateRouteListCtrl();
2752 pRouteManagerDialog->UpdateTrkListCtrl();
2753 pRouteManagerDialog->UpdateWptListCtrl();
2754 pRouteManagerDialog->UpdateLayListCtrl();
2756 pRouteManagerDialog->Show();
2760 pRouteManagerDialog->Centre();
2761 pRouteManagerDialog->Raise();
2767 case ID_MENU_NAV_TRACK:
2769 if (!g_bTrackActive) {
2771 g_bTrackCarryOver =
true;
2774 g_bTrackCarryOver =
false;
2775 RefreshAllCanvas(
true);
2780 case ID_MENU_CHART_NORTHUP: {
2781 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2784 case ID_MENU_CHART_COGUP: {
2785 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2788 case ID_MENU_CHART_HEADUP: {
2789 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2793 case ID_MENU_MARK_MOB:
2799 case ID_MASTERTOGGLE: {
2800 if (g_MainToolbar) {
2801 wxString tip = _(
"Show Toolbar");
2802 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2803 if (g_MainToolbar->GetToolbar())
2804 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2806 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2809 if (g_bmasterToolbarFull)
2810 m_nMasterToolCountShown =
2811 g_MainToolbar->GetToolCount() -
2814 m_nMasterToolCountShown = 2;
2816 m_nMasterToolCountShown =
2817 g_MainToolbar->GetToolShowCount();
2819 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2827 case ID_CMD_SELECT_CHART_TYPE: {
2828 selectChartDisplay(event.GetExtraLong(), -1);
2832 case ID_CMD_SELECT_CHART_FAMILY: {
2833 selectChartDisplay(-1, event.GetExtraLong());
2837 case ID_CMD_APPLY_SETTINGS: {
2838 applySettingsString(event.GetString());
2840 androidRestoreFullScreen();
2846 case ID_CMD_NULL_REFRESH: {
2851 case ID_CMD_SETVP: {
2852 setStringVP(event.GetString());
2856 case ID_CMD_INVALIDATE: {
2862 case ID_CMD_POST_JSON_TO_PLUGINS: {
2868 int numErrors = reader.
Parse(event.GetString(), &root);
2869 if (numErrors == 0) {
2870 if (root[
"MessageID"].IsString()) {
2871 wxString MsgID = root[
"MessageID"].
AsString();
2882 if (g_iENCToolbar) {
2883 g_iENCToolbar->OnToolLeftClick(event);
2893 g_MainToolbar->HideTooltip();
2895 ArrayOfPlugInToolbarTools tool_array =
2896 g_pi_manager->GetPluginToolbarToolArray();
2897 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2899 if (event.GetId() == pttc->id) {
2900 if (pttc->m_pplugin)
2919 if (g_MainToolbar) g_MainToolbar->Realize();
2922bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2923 bool viz_now = g_bmasterToolbarFull;
2925 g_MainToolbar->HideTooltip();
2926 wxString tip = _(
"Show Toolbar");
2928 tip = _(
"Hide Toolbar");
2929 if (g_MainToolbar->GetToolbar())
2930 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2933 bool toggle =
false;
2934 if (viz && !g_bmasterToolbarFull)
2937 else if (!viz && g_bmasterToolbarFull)
2941 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2944 if (g_bmasterToolbarFull)
2945 m_nMasterToolCountShown =
2946 g_MainToolbar->GetToolCount() -
2949 m_nMasterToolCountShown = 2;
2951 m_nMasterToolCountShown =
2952 g_MainToolbar->GetToolShowCount();
2954 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2960void MyFrame::ScheduleReloadCharts() {
2961 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2962 evt.SetId(ID_RELOAD_CHARTS);
2963 GetEventHandler()->AddPendingEvent(evt);
2966void MyFrame::ScheduleDeleteSettingsDialog() {
2967 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2968 evt.SetId(ID_SETTINGS_DELETE);
2969 GetEventHandler()->AddPendingEvent(evt);
2972void MyFrame::ScheduleSettingsDialog() {
2973 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2974 evt.SetId(ID_SETTINGS);
2975 GetEventHandler()->AddPendingEvent(evt);
2978void MyFrame::ScheduleSettingsDialogNew() {
2979 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2980 evt.SetId(ID_SETTINGS_NEW);
2981 GetEventHandler()->AddPendingEvent(evt);
2984void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2985 UpdateCanvasConfigDescriptors();
2987 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2988 CreateCanvasLayout(
true);
2990 CreateCanvasLayout();
2992 g_pauimgr->Update();
2994 ConfigureStatusBar();
2995 wxSize lastOptSize = options_lastWindowSize;
3000 options_lastWindowSize = lastOptSize;
3004 ScheduleSettingsDialogNew();
3006 ScheduleSettingsDialog();
3011 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3014 int index_hint = -1;
3015 if (i < pathArray.GetCount())
3016 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
3017 cc->canvasChartsRefresh(index_hint);
3018 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
3027 return GetPrimaryCanvas();
3030void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
3031 if (g_bmasterToolbarFull) {
3032#ifndef OCPN_TOOLBAR_ANIMATE
3033 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
3036 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
3037 m_nMasterToolCountShown++;
3038 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3039 g_MainToolbar->Realize();
3040 g_MainToolbar->RefreshToolbar();
3042 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
3044 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3045 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
3046 g_MainToolbar->Realize();
3047 g_MainToolbar->RefreshToolbar();
3050#ifndef OCPN_TOOLBAR_ANIMATE
3051 m_nMasterToolCountShown = 1;
3053 if (m_nMasterToolCountShown > 1) {
3054 m_nMasterToolCountShown--;
3055 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3056 g_MainToolbar->Realize();
3057 g_MainToolbar->RefreshToolbar();
3058 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
3060 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3061 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
3062 g_MainToolbar->Realize();
3063 g_MainToolbar->RefreshToolbar();
3068void MyFrame::InvalidateAllGL() {
3071 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3081void MyFrame::RefreshAllCanvas(
bool bErase) {
3083 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3086 cc->Refresh(bErase);
3091void MyFrame::setStringVP(wxString VPS) {
3096 wxStringTokenizer tkz(VPS,
";");
3098 wxString token = tkz.GetNextToken();
3100 token.ToDouble(&lat);
3102 token = tkz.GetNextToken();
3104 token.ToDouble(&lon);
3106 token = tkz.GetNextToken();
3108 token.ToDouble(&scale_ppm);
3110 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
3113void MyFrame::DoSettingsNew() {
3115 g_options =
nullptr;
3120void MyFrame::DoSettings() {
3124 ApplyGlobalSettings(
true);
3127 bool b_loadHarmonics =
false;
3128 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3131 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3134 if (b_loadHarmonics) LoadHarmonics();
3142 g_bShowChartBar = !g_bShowChartBar;
3144 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3149 if (g_bShowChartBar) {
3151 UpdateControlBar(cc);
3154 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3157void MyFrame::ToggleColorScheme() {
3158 static bool lastIsNight;
3159 ColorScheme s = GetColorScheme();
3162 if (lastIsNight && is == 3)
3165 lastIsNight =
false;
3167 if (lastIsNight) is = 2;
3168 if (is == 3) lastIsNight =
true;
3169 s = (ColorScheme)is;
3170 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3172 SetAndApplyColorScheme(s);
3175void MyFrame::ToggleFullScreen() {
3176 bool to = !IsFullScreen();
3181 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3183 ShowFullScreen(to, style);
3186 UpdateAllToolbars(global_color_scheme);
3188 UpdateControlBar(GetPrimaryCanvas());
3190 TriggerRecaptureTimer();
3193void MyFrame::ActivateMOB(
void) {
3195 wxDateTime mob_time = wxDateTime::Now();
3196 wxString mob_label(_(
"MAN OVERBOARD"));
3197 mob_label += _(
" on ");
3198 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3201 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3202 pWP_MOB->SetShared(
true);
3204 pWP_MOB->SetWaypointArrivalRadius(
3206 pWP_MOB->SetUseSca(
false);
3207 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3208 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3210 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3213 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3216 new RoutePoint(zlat, zlon, g_default_wp_icon,
3217 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3218 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3221 pRouteList->Append(temp_route);
3223 temp_route->AddPoint(pWP_src);
3224 temp_route->AddPoint(pWP_MOB);
3226 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3236 temp_route->SetRouteArrivalRadius(-1.0);
3238 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3242 v[
"GUID"] = temp_route->
m_GUID;
3243 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3244 SendJSONMessageToAllPlugins(msg_id, v);
3247 if (RouteManagerDialog::getInstanceFlag()) {
3248 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3249 pRouteManagerDialog->UpdateRouteListCtrl();
3250 pRouteManagerDialog->UpdateWptListCtrl();
3255 RefreshAllCanvas(
false);
3257 wxString mob_message(_(
"MAN OVERBOARD"));
3258 mob_message += _(
" Time: ");
3259 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3260 mob_message += _(
" Position: ");
3261 mob_message += toSDMM(1, gLat);
3263 mob_message += toSDMM(2, gLon);
3264 wxLogMessage(mob_message);
3266void MyFrame::TrackOn(
void) {
3267 g_bTrackActive =
true;
3270 g_TrackList.push_back(g_pActiveTrack);
3271 NavObj_dB::GetInstance().InsertTrack(g_pActiveTrack);
3272 g_pActiveTrack->Start();
3275 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3277 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3279 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3282 androidSetTrackTool(
true);
3285 if (RouteManagerDialog::getInstanceFlag()) {
3286 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3287 pRouteManagerDialog->UpdateTrkListCtrl();
3288 pRouteManagerDialog->UpdateRouteListCtrl();
3293 wxString name = g_pActiveTrack->GetName();
3294 if (name.IsEmpty()) {
3295 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3300 name = _(
"(Unnamed Track)");
3303 v[
"GUID"] = g_pActiveTrack->m_GUID;
3304 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3305 SendJSONMessageToAllPlugins(msg_id, v);
3306 g_FlushNavobjChangesTimeout =
3310Track *MyFrame::TrackOff(
bool do_add_point) {
3311 Track *return_val = g_pActiveTrack;
3313 if (g_pActiveTrack) {
3315 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3316 v[
"GUID"] = g_pActiveTrack->m_GUID;
3317 SendJSONMessageToAllPlugins(msg_id, v);
3319 g_pActiveTrack->Stop(do_add_point);
3321 if (g_pActiveTrack->GetnPoints() < 2) {
3322 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3323 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3326 if (g_bTrackDaily) {
3327 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3329 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3330 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3331 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3332 return_val = pExtendTrack;
3336 g_pActiveTrack = NULL;
3339 g_bTrackActive =
false;
3341 if (RouteManagerDialog::getInstanceFlag()) {
3342 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3343 pRouteManagerDialog->UpdateTrkListCtrl();
3344 pRouteManagerDialog->UpdateRouteListCtrl();
3348 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3350 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3351 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3354 androidSetTrackTool(
false);
3357 g_FlushNavobjChangesTimeout =
3363bool MyFrame::ShouldRestartTrack(
void) {
3364 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3365 time_t now = wxDateTime::Now().GetTicks();
3366 time_t today = wxDateTime::Today().GetTicks();
3368 switch (g_track_rotate_time_type) {
3370 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3372 case TIME_TYPE_COMPUTER:
3373 rotate_at = g_track_rotate_time;
3377 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3378 rotate_at = g_track_rotate_time + utc_offset;
3381 if (rotate_at > 86400)
3383 else if (rotate_at < 0)
3385 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3386 now - today >= rotate_at) {
3387 if (m_last_track_rotation_ts == 0) {
3388 if (now - today > rotate_at)
3389 m_last_track_rotation_ts = today + rotate_at;
3391 m_last_track_rotation_ts = today + rotate_at - 86400;
3394 m_last_track_rotation_ts = now;
3400void MyFrame::TrackDailyRestart(
void) {
3401 if (!g_pActiveTrack)
return;
3402 Track *pPreviousTrack = TrackOff(
true);
3409 if (pPreviousTrack) {
3410 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3411 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3414 if (RouteManagerDialog::getInstanceFlag()) {
3415 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3416 pRouteManagerDialog->UpdateTrkListCtrl();
3417 pRouteManagerDialog->UpdateRouteListCtrl();
3422void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3424 cc->SetUpMode(mode);
3426 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3427 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3428 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3431 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3436 cc->SetShowENCText(!cc->GetShowENCText());
3438 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3446void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3449 cc->SetENCDisplayCategory(nset);
3451 UpdateGlobalMenuItems();
3462 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3464 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3473 cc->SetShowENCLights(!cc->GetShowENCLights());
3475 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3477 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3485void MyFrame::ToggleRocks(
void )
3491 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3492 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3493 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3494 pOLE->nViz = !pOLE->nViz;
3498 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3499 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3500 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3503 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3507 ps52plib->GenerateStateHash();
3514 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3516 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3518 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3524 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3526 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3528 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3541 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3542 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3547 cc->SetShowAIS(!cc->GetShowAIS());
3548 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3552void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3553 cc->SetAttenAIS(!cc->GetAttenAIS());
3554 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3560 cc->m_bFollow =
true;
3563 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3567 SetChartUpdatePeriod();
3575 cc->m_bFollow =
false;
3577 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3581 SetChartUpdatePeriod();
3584void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3585 cc->SetShowOutlines(!cc->GetShowOutlines());
3587 RefreshAllCanvas(
false);
3591 if (g_bopengl) InvalidateAllGL();
3594 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3597void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3599void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3601 bool enabled = m_pMenuBar->IsEnabled(item_id);
3602 m_pMenuBar->Enable(item_id,
false);
3603 m_pMenuBar->Check(item_id, state);
3604 m_pMenuBar->Enable(item_id, enabled);
3608void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3609 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3610 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3611 g_MainToolbar->Realize();
3615void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3616 wxBitmap *bmpRollover) {
3617 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3618 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3619 g_MainToolbar->Realize();
3623void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3624 wxString rolloverSVGfile,
3625 wxString toggledSVGfile) {
3626 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3627 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3628 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3632void MyFrame::ConfigureStatusBar() {
3634 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3637 UseNativeStatusBar(
false);
3640 if (g_bShowStatusBar) {
3641 if (!m_pStatusBar) {
3643 CreateStatusBar(m_StatusBarFieldCount, 0);
3644 ApplyGlobalColorSchemetoStatusBar();
3649 m_pStatusBar->Destroy();
3650 m_pStatusBar = NULL;
3656void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3657 ConfigureStatusBar();
3659 wxSize lastOptSize = options_lastWindowSize;
3665 options_lastWindowSize = lastOptSize;
3667 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3670wxString _menuText(wxString name, wxString shortcut) {
3674 menutext <<
"\t" << shortcut;
3679void MyFrame::BuildMenuBar(
void) {
3685 bool showMenuBar =
true;
3687 bool showMenuBar = g_bShowMenuBar;
3699 m_pMenuBar =
new wxMenuBar();
3700 RegisterGlobalMenuItems();
3701 SetMenuBar(m_pMenuBar);
3705 UpdateGlobalMenuItems();
3710 m_pMenuBar->Destroy();
3716void MyFrame::RegisterGlobalMenuItems() {
3717 if (!m_pMenuBar)
return;
3719 wxMenu *nav_menu =
new wxMenu();
3720 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3721 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3722 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3723 nav_menu->AppendSeparator();
3724 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3725 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3726 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3727 nav_menu->AppendSeparator();
3729 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3730 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3732 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3733 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3735 nav_menu->AppendSeparator();
3736 nav_menu->Append(ID_MENU_SCALE_IN,
3737 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3738 nav_menu->Append(ID_MENU_SCALE_OUT,
3739 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3741 nav_menu->AppendSeparator();
3742 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3744 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3746 wxMenu *view_menu =
new wxMenu();
3748 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3749 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3750 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3751 _menuText(_(
"Show Chart Outlines"),
"O"));
3753 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3754 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3755 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3756 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3758 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3759 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3761 view_menu->AppendSeparator();
3763 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3764 _menuText(_(
"Show ENC text"),
"T"));
3765 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3766 _menuText(_(
"Show ENC Lights"),
"L"));
3767 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3768 _menuText(_(
"Show ENC Soundings"),
"S"));
3769 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3770 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3771 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3772 _menuText(_(
"Show ENC Data Quality"),
"U"));
3773 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3774 _menuText(_(
"Show Navobjects"),
"V"));
3776 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3777 _menuText(_(
"Show ENC text"),
"Alt-T"));
3778 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3779 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3780 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3781 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3782 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3783 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3784 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3785 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3786 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3787 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3789 view_menu->AppendSeparator();
3790 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3791 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3792 view_menu->AppendSeparator();
3794 view_menu->Append(ID_MENU_UI_COLSCHEME,
3795 _menuText(_(
"Change Color Scheme"),
"C"));
3797 view_menu->Append(ID_MENU_UI_COLSCHEME,
3798 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3801 view_menu->AppendSeparator();
3803 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3804 _menuText(_(
"Toggle Full Screen"),
"F11"));
3806 m_pMenuBar->Append(view_menu, _(
"&View"));
3808 wxMenu *ais_menu =
new wxMenu();
3809 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3810 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3811 _(
"Attenuate less critical AIS targets"));
3812 ais_menu->AppendSeparator();
3813 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3814 _(
"Hide Moored AIS Targets"));
3815 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3816 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3817 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3820 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3821 _menuText(_(
"Show CPA Warnings"),
"W"));
3823 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3824 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3827 ais_menu->AppendSeparator();
3828 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3829 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3831 wxMenu *tools_menu =
new wxMenu();
3832 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3833 _menuText(_(
"Data Monitor"),
"Alt-C"));
3835 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3836 _menuText(_(
"Measure Distance"),
"M"));
3838 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3839 _menuText(_(
"Measure Distance"),
"Alt-M"));
3842 tools_menu->AppendSeparator();
3843 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3844 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3845 tools_menu->AppendSeparator();
3846 tools_menu->Append(ID_MENU_MARK_BOAT,
3847 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3848 tools_menu->Append(ID_MENU_MARK_CURSOR,
3849 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3850 tools_menu->AppendSeparator();
3854 _menuText(_(
"Drop MOB Marker"),
3856 tools_menu->AppendSeparator();
3857 tools_menu->Append(wxID_PREFERENCES,
3858 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3860 tools_menu->Append(ID_MENU_MARK_MOB,
3861 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3862 tools_menu->AppendSeparator();
3863 tools_menu->Append(wxID_PREFERENCES,
3864 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3866 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3869 wxMenu *window_menu =
new wxMenu();
3870 m_pMenuBar->Append(window_menu, _(
"&Window"));
3873 wxMenu *help_menu =
new wxMenu();
3874 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3875 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3876 m_pMenuBar->Append(help_menu, _(
"&Help"));
3879 UpdateGlobalMenuItems();
3882void MyFrame::UpdateGlobalMenuItems() {
3883 if (!m_pMenuBar)
return;
3885 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3886 ->Check(GetPrimaryCanvas()->m_bFollow);
3887 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3888 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3889 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3890 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3891 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3892 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3893 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3894 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3895 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3896 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3897 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3898 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3899 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3900 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3901 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3902 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3903 if (g_bAIS_CPA_Alert) {
3904 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3905 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3907 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3908 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3911 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3912 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3913 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3916 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3917 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3918 ->Check(ps52plib->GetShowSoundings());
3920 bool light_state =
false;
3922 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3924 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3925 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3926 light_state = (pOLE->nViz == 1);
3931 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3932 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3936 DisCat nset = ps52plib->GetDisplayCategory();
3937 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3938 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3939 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3940 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3941 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3942 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3943 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3945 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3946 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3947 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3952void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3953 if (!m_pMenuBar)
return;
3955 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3957 if (cc->GetUpMode() == NORTH_UP_MODE)
3958 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3959 else if (cc->GetUpMode() == COURSE_UP_MODE)
3960 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3962 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3964 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3965 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3966 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3967 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3968 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3969 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3970 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3971 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3972 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3973 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3974 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3975 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3976 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3977 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3978 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3981 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3982 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3985 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3987 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3988 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3993 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3997 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3998 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3999 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
4000 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
4001 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
4002 ->Check(cc->GetShowENCDataQual());
4003 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
4005 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
4006 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
4007 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
4012void MyFrame::InvalidateAllCanvasUndo() {
4014 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4016 if (cc) cc->undo->InvalidateUndo();
4020void MyFrame::SubmergeAllCanvasToolbars(
void) {
4022 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4024 if (cc) cc->SubmergeToolbar();
4028void MyFrame::SurfaceAllCanvasToolbars(
void) {
4029 if (g_bshowToolbar) {
4031 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4033 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
4040void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
4042 if (lon > 180.0) lon -= 360.0;
4047 cc->JumpToPosition(lat, lon,
scale);
4050 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
4054void MyFrame::UpdateCanvasConfigDescriptors() {
4056 for (
unsigned int i = 0;
4057 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
4058 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
4066 cc->DBindex = chart->GetQuiltReferenceChartIndex();
4067 cc->GroupID = chart->m_groupIndex;
4070 cc->
bQuilt = chart->GetQuiltMode();
4077 cc->
bFollow = chart->m_bFollow;
4082 int upmode = chart->GetUpMode();
4083 if (upmode == COURSE_UP_MODE)
4085 else if (upmode == HEAD_UP_MODE)
4092void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
4093 if (!RBBox.GetValid())
return;
4095 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
4096 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
4099 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
4100 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
4108 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4109 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
4111 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4112 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
4114 cc->GetSize(&ww, &wh);
4116 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4118 ppm = wxMin(ppm, 1.0);
4124void MyFrame::PrepareOptionsClose(
options *settings,
4125 int settings_return_value) {
4127 options_lastPage = settings->lastPage;
4132 if (options_lastPage == 1) options_lastPage = 0;
4134 options_subpage = settings->lastSubPage;
4135 options_lastWindowPos = settings->lastWindowPos;
4136 options_lastWindowSize = settings->lastWindowSize;
4139 androidEnableBackButton(
true);
4140 androidEnableOptionsMenu(
true);
4141 androidRestoreFullScreen();
4142 androidEnableRotation();
4147void MyFrame::DoOptionsDialog() {
4148 if (NULL == g_options) {
4149 AbstractPlatform::ShowBusySpinner();
4152 pConfig->SetPath(
"/Settings");
4153 pConfig->Read(
"OptionsSizeX", &sx, -1);
4154 pConfig->Read(
"OptionsSizeY", &sy, -1);
4156 wxWindow *optionsParent =
this;
4158 optionsParent = GetPrimaryCanvas();
4160 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4163 AbstractPlatform::HideBusySpinner();
4167 g_options->SetInitChartDir(*pInit_Chart_Dir);
4170 g_options->SetCurrentDirList(
ChartData->GetChartDirArray());
4171 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4172 g_options->SetWorkDirListPtr(pWorkDirArray);
4175 g_options->SetConfigPtr(pConfig);
4176 g_options->SetInitialSettings();
4178 prev_locale = g_locale;
4179 g_options->SetInitialPage(options_lastPage, options_subpage);
4182 g_options->lastWindowPos = options_lastWindowPos;
4183 if (options_lastWindowPos != wxPoint(0, 0)) {
4184 g_options->Move(options_lastWindowPos);
4185 g_options->SetSize(options_lastWindowSize);
4187 g_options->CenterOnScreen();
4189 if (options_lastWindowSize != wxSize(0, 0)) {
4190 g_options->SetSize(options_lastWindowSize);
4195 androidEnableBackButton(
false);
4196 androidEnableOptionsMenu(
false);
4197 androidDisableFullScreen();
4205 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4208 wxString chart_file_name;
4209 if (cc->GetQuiltMode()) {
4210 int dbi = cc->GetQuiltRefChartdbIndex();
4211 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4213 if (cc->m_singleChart)
4214 chart_file_name = cc->m_singleChart->GetFullPath();
4217 pathArray.Add(chart_file_name);
4223 last_canvasConfig = g_canvasConfig;
4226 g_last_ChartScaleFactor = g_ChartScaleFactor;
4232void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4233 bool b_need_refresh =
false;
4235 if ((rr & VISIT_CHARTS) &&
4236 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4238 UpdateChartDatabaseInplace(*pNewDirArray,
4239 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4242 b_need_refresh =
true;
4246 if (rr & STYLE_CHANGED) {
4249 _(
"Please restart OpenCPN to activate language or style changes."),
4250 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4253 bool b_groupchange =
false;
4254 if (((rr & VISIT_CHARTS) &&
4255 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4256 (rr & GROUPS_CHANGED)) {
4257 b_groupchange = ScrubGroupArray();
4259 RefreshGroupIndices();
4262 if (rr & GROUPS_CHANGED || b_groupchange) {
4263 pConfig->DestroyConfigGroups();
4267 if (rr & TIDES_CHANGED) {
4273 if (rr & S52_CHANGED) {
4274 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4277 pConfig->UpdateSettings();
4279 if (g_pActiveTrack) {
4280 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4284 g_pRouteMan->SetColorScheme(global_color_scheme,
4285 g_Platform->GetDisplayDPmm());
4288 double stuffcog = NAN;
4289 double stuffsog = NAN;
4290 if (!std::isnan(gCog)) stuffcog = gCog;
4291 if (!std::isnan(gSog)) stuffsog = gSog;
4293 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4294 COGFilterTable[i] = stuffcog;
4295 SOGFilterTable[i] = stuffsog;
4298 SetChartUpdatePeriod();
4300 if (rr & GL_CHANGED) {
4304 b_need_refresh =
true;
4307 if (rr & S52_CHANGED) {
4308 b_need_refresh =
true;
4312 if (rr & REBUILD_RASTER_CACHE) {
4313 if (g_glTextureManager) {
4314 GetPrimaryCanvas()->Disable();
4315 g_glTextureManager->BuildCompressedCache();
4316 GetPrimaryCanvas()->Enable();
4321 if (g_config_display_size_manual &&
4329 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4335 g_pi_manager->SendBaseConfigToAllPlugIns();
4336 int rrt = rr & S52_CHANGED;
4337 g_pi_manager->SendS52ConfigToAllPlugIns(
4338 (rrt == S52_CHANGED) ||
4339 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4342 if (g_MainToolbar) {
4343 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4344 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4349 ps52plib->SetScaleFactorExp(
4350 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4351 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4355 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4357 if (cc) cc->ApplyGlobalSettings();
4362 bool ztc = g_bEnableZoomToCursor;
4363 g_bEnableZoomToCursor =
4367 if (!GetPrimaryCanvas()->IsFrozen())
4369 g_bEnableZoomToCursor = ztc;
4372 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4373 if (g_pMarkInfoDialog) {
4374 g_pMarkInfoDialog->Hide();
4375 g_pMarkInfoDialog->Destroy();
4376 g_pMarkInfoDialog = NULL;
4381 SetGPSCompassScale();
4383 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4386 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4387 cc->UpdateCanvasControlBar();
4390 UpdateGPSCompassStatusBoxes();
4392 SetAllToolbarScale();
4393 RequestNewToolbars();
4396 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4399 cc->RebuildCursors();
4404 bool b_masterScaleChange =
false;
4405 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4406 b_masterScaleChange =
true;
4408 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4409 RequestNewMasterToolbar(
true);
4411 bool bMuiChange =
false;
4417 if (b_masterScaleChange || bMuiChange) {
4419 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4422 cc->ProcessNewGUIScale();
4428 if (rr & LOCALE_CHANGED) {
4429 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4431 rr |= NEED_NEW_OPTIONS;
4436 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4440 g_last_ChartScaleFactor = g_ChartScaleFactor;
4442 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4447bool MyFrame::CheckGroup(
int igroup) {
4448 if (igroup == 0)
return true;
4452 if (!pGroup->m_element_array.size())
4455 for (
const auto &elem : pGroup->m_element_array) {
4456 for (
unsigned int ic = 0;
4457 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4459 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4461 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4468bool MyFrame::ScrubGroupArray() {
4473 bool b_change =
false;
4474 unsigned int igroup = 0;
4475 while (igroup < g_pGroupArray->GetCount()) {
4476 bool b_chart_in_element =
false;
4479 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4480 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4482 for (
unsigned int ic = 0;
4483 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4485 wxString chart_full_path = pcte->GetFullSystemPath();
4487 if (chart_full_path.StartsWith(element_root)) {
4488 b_chart_in_element =
true;
4494 if (!b_chart_in_element) {
4495 wxString test_string =
"GSHH";
4496 if (element_root.Upper().Contains(test_string))
4497 b_chart_in_element =
true;
4500 if (!b_chart_in_element)
4502 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4514void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4516 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4518 if (cc && (cc != ccThis)) cc->Refresh();
4523void MyFrame::ChartsRefresh() {
4526 AbstractPlatform::ShowBusySpinner();
4528 bool b_run = FrameTimer1.IsRunning();
4531 FrameTenHzTimer.Stop();
4534 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4537 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4538 if (cc->GetQuiltMode()) {
4539 currentIndex = cc->GetQuiltReferenceChartIndex();
4541 cc->canvasChartsRefresh(currentIndex);
4545 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4546 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4548 AbstractPlatform::HideBusySpinner();
4551void MyFrame::InvalidateAllQuilts() {
4552 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4555 cc->InvalidateQuilt();
4556 cc->SetQuiltRefChart(-1);
4557 cc->m_singleChart = NULL;
4562bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4564 const wxString &ChartListFileName) {
4565 bool b_run = FrameTimer1.IsRunning();
4567 FrameTenHzTimer.Stop();
4569 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4570 FrameCOGTimer.Stop();
4573 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4576 cc->InvalidateQuilt();
4577 cc->SetQuiltRefChart(-1);
4578 cc->m_singleChart = NULL;
4588 AbstractPlatform::ShowBusySpinner();
4590 wxGenericProgressDialog *pprog =
nullptr;
4592 wxString longmsg = _(
"OpenCPN Chart Update");
4594 ".................................................................."
4597 pprog =
new wxGenericProgressDialog();
4600 pprog->SetFont(*qFont);
4602 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100, gFrame,
4603 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4604 wxPD_REMAINING_TIME);
4611 wxLogMessage(
"Starting chart database Update...");
4612 wxString gshhg_chart_loc = gWorldMapLocation;
4613 gWorldMapLocation = wxEmptyString;
4617 ChartData->SaveBinary(ChartListFileName);
4618 wxLogMessage(
"Finished chart database Update");
4620 if (gWorldMapLocation.empty()) {
4624 gWorldMapLocation = gDefaultWorldMapLocation;
4625 gshhg_chart_loc = wxEmptyString;
4628 if (gWorldMapLocation != gshhg_chart_loc) {
4630 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4632 if (cc) cc->ResetWorldBackgroundChart();
4635 gshhsCrossesLandReset();
4640 AbstractPlatform::HideBusySpinner();
4642 pConfig->UpdateChartDirs(DirArray);
4645 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4646 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4648 if (b_runCOGTimer) {
4650 int period_ms = 100;
4652 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4659 cc->ToggleCanvasQuiltMode();
4661 bool cur_mode = cc->GetQuiltMode();
4663 if( !cc->GetQuiltMode() )
4664 cc->SetQuiltMode(
true );
4666 if( cc->GetQuiltMode() ) {
4667 cc->SetQuiltMode(
false );
4668 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4672 if( cur_mode != cc->GetQuiltMode() ){
4678 g_bQuiltEnable = cc->GetQuiltMode();
4682 ps52plib->GenerateStateHash();
4687void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4689void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4691void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4693 cc->DoCanvasStackDelta(direction);
4697void MyFrame::PositionIENCToolbar() {
4699 if (g_iENCToolbar) {
4701 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4703 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4711void MyFrame::OnInitTimer(wxTimerEvent &event) {
4714 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4717 wxLog::FlushActive();
4719 switch (m_iInitCount++) {
4721 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4723 if (g_bInlandEcdis) {
4724 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4725 double range_set = 500.;
4727 range = wxRound(range * 10) / 10.;
4731 else if (range > 2000.)
4733 else if (range > 1600.)
4735 else if (range > 1200.)
4737 else if (range > 800.)
4742 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4746 g_Platform->SetFullscreen(g_bFullscreen);
4749 if (g_NeedDBUpdate > 0) {
4750 RebuildChartDatabase();
4751 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4754 cc->SetGroupIndex(0,
false);
4762 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4763 CHART_FAMILY_RASTER)) {
4766 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4768 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4769 CHART_FAMILY_VECTOR)) {
4772 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4781 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4784 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4786 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4789 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4793 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4794 NavObj_dB::GetInstance().LoadNavObjects();
4797 if (!g_AW1GUID.IsEmpty()) {
4798 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4800 if (!g_AW2GUID.IsEmpty()) {
4801 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4806 appendOSDirSlash(&layerdir);
4807 layerdir.Append(
"layers");
4809 if (wxDir::Exists(layerdir)) {
4811 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4812 wxLogMessage(laymsg);
4813 pConfig->LoadLayers(layerdir);
4820 for (
auto *cp : TheConnectionParams()) {
4823 cp->b_IsSetup = TRUE;
4830 if (m_initializing)
break;
4831 m_initializing =
true;
4832 AbstractPlatform::ShowBusySpinner();
4834 AbstractPlatform::HideBusySpinner();
4836 RequestNewMasterToolbar();
4839 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4841 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4843 wxString perspective;
4844 pConfig->SetPath(_T (
"/AUI" ));
4845 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4852 bool bno_load =
false;
4854 wxArrayString name_array;
4855 wxStringTokenizer st(perspective,
"|;");
4856 while (st.HasMoreTokens()) {
4857 wxString s1 = st.GetNextToken();
4858 if (s1.StartsWith(
"name=")) {
4859 wxString sc = s1.AfterFirst(
'=');
4864 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4865 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4866 wxAuiPaneInfo pane = pane_array_val.Item(i);
4870 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4876 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4880 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4883 g_pauimgr->GetPane(cc).MinSize(10,10);
4890 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4893 wxSize frameSize = GetClientSize();
4894 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4895 int width = wxMax(minSize.x, frameSize.x / 10);
4896 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4899 g_pauimgr->Update();
4903 g_pi_manager->NotifyAuiPlugIns();
4906 g_pi_manager->ShowDeferredBlacklistMessages();
4908 g_pi_manager->CallLateInit();
4910 if (g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4916 if (g_MainToolbar) {
4917 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4918 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4923 m_data_monitor->Move(g_MainToolbar->GetToolbarRect().x +
4924 g_MainToolbar->GetToolbarRect().width,
4925 3 * GetCharHeight());
4927 m_data_monitor->Center();
4935 pConfig->SetPath(
"/Settings");
4936 pConfig->Read(
"OptionsSizeX", &sx, -1);
4937 pConfig->Read(
"OptionsSizeY", &sy, -1);
4939 wxWindow *optionsParent =
this;
4941 optionsParent = GetPrimaryCanvas();
4943 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4946 BuildiENCToolbar(
true);
4953 if (!g_params.empty()) {
4954 for (
size_t n = 0; n < g_params.size(); n++) {
4955 wxString path = g_params[n];
4956 if (::wxFileExists(path)) {
4958 pSet->load_file(path.fn_str());
4961 pSet->LoadAllGPXObjects(
4962 !pSet->IsOpenCPN(), wpt_dups,
4964 LLBBox box = pSet->GetBBox();
4965 if (box.GetValid()) {
4966 CenterView(GetPrimaryCanvas(), box);
4975 InitAppMsgBusListener();
4980 auto loader = PluginLoader::GetInstance();
4981 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4982 if (!b_haveWMM) gVar = g_UserVar;
4989 wxLogMessage(
"OnInitTimer...Last Call");
4991 PositionIENCToolbar();
4993 g_bDeferredInitDone =
true;
4995 GetPrimaryCanvas()->SetFocus();
5002 if (b_reloadForPlugins) {
5007 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
5008 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5010 if (cc) cc->SetFirstAuto(
true);
5018 wxLogMessage(
"OnInitTimer...Finalize Canvases");
5020 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5024 cc->CheckGroupValid();
5029 androidEnableBackButton(
true);
5030 androidEnableRotation();
5031 androidEnableOptionItems(
true);
5035 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
5044 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
5046 wxLog::FlushActive();
5048 RefreshAllCanvas(
true);
5049 wxGetApp().m_usb_watcher.Start();
5055void MyFrame::InitAppMsgBusListener() {
5056 auto &msgbus = AppMsgBus::GetInstance();
5059 AppMsg msg_basic(AppMsg::Type::BasicNavData);
5060 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
5064 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
5065 HandleBasicNavMsg(basicnav_msg);
5069 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
5070 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
5074 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
5075 HandleGPSWatchdogMsg(msg);
5082void MyFrame::ReleaseApiListeners() {}
5087 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
5088 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
5089 server.SetGetRestApiEndpointCb(
5090 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
5091 server.open_file_cb = [](
const std::string &path) {
5092 return wxGetApp().OpenFile(path);
5099void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
5100 if (msg->gps_watchdog <= 0) {
5101 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
5102 bool last_bGPSValid = bGPSValid;
5105 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5110 if (m_fix_start_time.IsValid()) {
5111 wxDateTime now = wxDateTime::Now();
5112 wxTimeSpan span = now - m_fix_start_time;
5113 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
5114 auto ¬eman = NotificationManager::GetInstance();
5115 wxString msg = _(
"GNSS Position fix lost");
5116 noteman.AddNotification(NotificationSeverity::kCritical,
5118 m_fix_start_time = wxInvalidDateTime;
5122 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
5123 bool last_bVelocityValid = bVelocityValid;
5124 bVelocityValid =
false;
5131void MyFrame::CalculateCOGAverage() {
5133 if (!std::isnan(gCog)) {
5136 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5139 double sum = 0., count = 0;
5141 double adder = COGTable[i];
5142 if (std::isnan(adder))
continue;
5144 if (fabs(adder -
g_COGAvg) > 180.) {
5158 else if (sum >= 360.)
5167void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5168 m_fixtime = msg->time;
5169 double hdt_data_interval = 0;
5170 double fix_time_interval = 0;
5172 double msgtime = msg->set_time.tv_sec;
5173 double m1 = msg->set_time.tv_nsec / 1e9;
5176 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5177 ((msg->vflag & POS_VALID) == POS_VALID)) {
5179 if (!m_fix_start_time.IsValid()) {
5180 m_fix_start_time = wxDateTime::Now();
5185 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5188 fix_time_gt_last = fix_time_gt;
5189 uint64_t fix_time_gt_now =
5190 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5191 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5195 double implied_sog = dist / (fix_time_interval / 3600);
5200 gLat_gt_m1 = gLat_gt;
5201 gLon_gt_m1 = gLon_gt;
5205 fix_time_gt = fix_time_gt_now;
5209 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5210 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5211 gCog_gt_m1 = gCog_gt;
5221 if (!std::isnan(gCog_gt_m1)) {
5223 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5230 if ((fix_time_gt - fix_time_gt_last) > .08) {
5235 if (gCog_gt > gCog_gt_m1) {
5236 if ((gCog_gt - gCog_gt_m1) > 180.)
5241 if ((gCog_gt_m1 - gCog_gt) > 180.)
5246 difft = fabs(gCog_gt - gCog_gt_m1);
5247 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5255 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5256 tentative_cog_rate_gt *= 1e9;
5257 cog_rate_gt = tentative_cog_rate_gt;
5265 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5268static double hdt_avg;
5269 double hdt_norm = gHdt;
5270 if(gHdt > 180) hdt_norm -= 360;
5273 hdt_avg += hdt_norm * 0.1;
5275 if( gHdt < 0) gHdt += 360.;
5278 if (!std::isnan(gHdt)) {
5280 uint64_t hdt_time_gt_last = hdt_time_gt;
5281 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5282 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5285 if (hdt_data_interval > .09) {
5287 gHdt_gt_m1 = gHdt_gt;
5290 if (!std::isnan(gHdt_gt_m1)) {
5292 double tentative_hdt_rate_gt =
5293 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5294 tentative_hdt_rate_gt *= 1e9;
5296 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5297 hdt_rate_gt = tentative_hdt_rate_gt;
5305 if (std::isnan(gHdt)) gHdt_gt = NAN;
5308 CalculateCOGAverage();
5315 bool last_bGPSValid = bGPSValid;
5316 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5317 if ((msg->vflag & POS_VALID) == POS_VALID)
5322 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5324 bVelocityValid =
true;
5328void MyFrame::UpdateStatusBar() {
5331 unsigned long uiCurrentTickCount;
5332 m_MMEAeventTime.SetToCurrent();
5333 uiCurrentTickCount =
5334 m_MMEAeventTime.GetMillisecond() / 100;
5335 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5336 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5337 m_ulLastNMEATicktime = uiCurrentTickCount;
5339 if (m_tick_idx++ > 6) m_tick_idx = 0;
5344 if (NULL != GetStatusBar()) {
5347 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5350 wxString s1(tick_buf, wxConvUTF8);
5352 s1 += toSDMM(1, gLat);
5354 s1 += toSDMM(2, gLon);
5356 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5360 if (!std::isnan(gSog))
5361 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(gSog));
5363 sogcog.Printf(
"SOG --- ");
5367 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5369 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5371 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5372 (
int)toMagnetic(gCog), 0x00B0);
5374 cogs.Printf((
"COG ---%c"), 0x00B0);
5376 sogcog.Append(cogs);
5377 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5382void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5383 MemFootTimer.Stop();
5385 int memsize = GetApplicationMemoryUse();
5388 printf(
"Memsize: %d \n", memsize);
5391 if (memsize > (g_MemFootMB * 1000)) {
5395 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5396 unsigned int nCache = pCache->GetCount();
5399 for (
unsigned int i = 0; i < nCache; i++) {
5409 for (
unsigned int i = 0; i < nCache - 1; i++) {
5410 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5412 pcea[i] = pcea[i + 1];
5423 unsigned int idelete = 0;
5424 unsigned int idelete_max = pCache->GetCount();
5427 unsigned int minimum_cache = 1;
5428 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5430 while ((memsize > (g_MemFootMB * 1000)) &&
5431 (pCache->GetCount() > minimum_cache) &&
5432 (idelete < idelete_max)) {
5433 int memsizeb = memsize;
5437 memsize = GetApplicationMemoryUse();
5438 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5446 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5451void MyFrame::CheckToolbarPosition() {
5454 static bool bMaximized;
5456 if (IsMaximized() && !bMaximized) {
5458 if (g_MainToolbar) {
5459 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5460 g_MainToolbar->SetDefaultPosition();
5461 g_MainToolbar->Realize();
5463 PositionIENCToolbar();
5464 }
else if (!IsMaximized() && bMaximized) {
5466 if (g_MainToolbar) {
5467 g_MainToolbar->SetYAuxOffset(0);
5468 g_MainToolbar->SetDockY(-1);
5469 g_MainToolbar->SetDefaultPosition();
5470 g_MainToolbar->Realize();
5472 PositionIENCToolbar();
5477void MyFrame::ProcessUnitTest() {
5478 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5485 cc->m_bFollow =
false;
5486 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5487 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5488 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5491 if (cc->m_groupIndex > 0) {
5492 while (ut_index < ChartData->GetChartTableEntries() &&
5493 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5497 if (ut_index < ChartData->GetChartTableEntries()) {
5501 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5502 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5509 if (cc->GetQuiltMode()) {
5510 if (cc->IsChartQuiltableRef(ut_index))
5511 cc->SelectQuiltRefdbChart(ut_index);
5513 cc->SelectdbChart(ut_index);
5516 if (g_unit_test_1) {
5524 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5525 cte->GetLatMin(), cte->GetLonMax(), NULL,
5529 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5530 cte->GetLatMax(), cte->GetLonMin(), NULL,
5533 cc->GetSize(&ww, &wh);
5534 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5536 ppm = wxMin(ppm, 1.0);
5543 if (ut_index > ut_index_max) exit(0);
5554 bool b_rotate =
false;
5556 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5559 if (!b_rotate && !g_btenhertz)
return;
5561 bool b_update =
false;
5563 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5566 struct timespec now;
5567 clock_gettime(CLOCK_MONOTONIC, &now);
5568 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5569 double diffc = diff / 1e9;
5572 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5573 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5574 if (gCog_tentative < 0.) gCog_tentative += 360.;
5575 gCog = gCog_tentative;
5579 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5580 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5581 double diffc = diff / 1e9;
5582 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5586 if (gSog_gt && !std::isnan(gCog_gt)) {
5587 double delta_t = diffc / 3600;
5588 double distance = gSog_gt * delta_t;
5591 double angr = gCog_gt / 180 * M_PI;
5592 double latr = gLat_gt * M_PI / 180;
5593 double D = distance / 3443;
5594 double sD = sin(D), cD = cos(D);
5595 double sy = sin(latr), cy = cos(latr);
5596 double sa = sin(angr), ca = cos(angr);
5598 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5599 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5609 if (cc) cc->DoCanvasCOGSet();
5620 if (b_rotate || cc->m_bFollow) {
5621 cc->DoCanvasUpdate();
5630 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5633void MyFrame::ProcessQuitFlag() {
5636 wxLogMessage(
"Got quitflag from SIGNAL");
5638 FrameTenHzTimer.Stop();
5645void MyFrame::ProcessDeferredTrackOn() {
5648 if (g_bDeferredStartTrack) {
5649 if (!g_bTrackActive) {
5652 g_bDeferredStartTrack =
false;
5655 g_bDeferredStartTrack =
false;
5660void MyFrame::ProcessAnchorWatch() {
5663 if (pAnchorWatchPoint1) {
5666 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5667 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5668 double d = g_nAWMax;
5669 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5670 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5671 bool toofar =
false;
5672 bool tooclose =
false;
5673 if (d >= 0.0) toofar = (dist * 1852. > d);
5674 if (d < 0.0) tooclose = (dist * 1852 < -d);
5676 if (tooclose || toofar)
5677 AnchorAlertOn1 =
true;
5679 AnchorAlertOn1 =
false;
5681 AnchorAlertOn1 =
false;
5683 if (pAnchorWatchPoint2) {
5686 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5687 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5689 double d = g_nAWMax;
5690 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5691 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5692 bool toofar =
false;
5693 bool tooclose =
false;
5694 if (d >= 0) toofar = (dist * 1852. > d);
5695 if (d < 0) tooclose = (dist * 1852 < -d);
5697 if (tooclose || toofar)
5698 AnchorAlertOn2 =
true;
5700 AnchorAlertOn2 =
false;
5702 AnchorAlertOn2 =
false;
5704 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5705 AnchorAlertOn1 =
true;
5708void MyFrame::SendFixToPlugins() {
5712 GPSData.
kLat = gLat;
5713 GPSData.
kLon = gLon;
5714 GPSData.
kCog = gCog;
5715 GPSData.
kSog = gSog;
5716 GPSData.
kVar = gVar;
5717 GPSData.
kHdm = gHdm;
5718 GPSData.
kHdt = gHdt;
5719 GPSData.
nSats = g_SatsInView;
5721 wxDateTime tCheck((time_t)m_fixtime);
5722 if (tCheck.IsValid()) {
5731 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5734 SendPositionFixToAllPlugIns(&GPSData);
5738void MyFrame::ProcessLogAndBells() {
5741 wxDateTime lognow = wxDateTime::Now();
5742 int hourLOC = lognow.GetHour();
5743 int minuteLOC = lognow.GetMinute();
5745 int minuteUTC = lognow.GetMinute();
5746 int second = lognow.GetSecond();
5748 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5749 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5750 (minuteUTC == 30)) {
5751 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5752 wxString day = lognow.FormatISODate();
5753 wxString utc = lognow.FormatISOTime();
5754 wxString navmsg =
"LOGBOOK: ";
5762 data.Printf(
" GPS Lat %10.5f Lon %10.5f ", gLat, gLon);
5766 if (std::isnan(gCog))
5767 cog.Printf(
"COG ----- ");
5769 cog.Printf(
"COG %10.5f ", gCog);
5772 if (std::isnan(gSog))
5773 sog.Printf(
"SOG ----- ");
5775 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(gSog));
5781 data.Printf(
" DR Lat %10.5f Lon %10.5f", gLat, gLon);
5784 wxLogMessage(navmsg);
5785 g_loglast_time = lognow;
5787 int bells = (hourLOC % 4) * 2;
5788 if (minuteLOC != 0) bells++;
5789 if (!bells) bells = 8;
5791 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5792 m_BellsToPlay = bells;
5793 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5794 wxPostEvent(
this, ev);
5801 CheckToolbarPosition();
5807 if (bDBUpdateInProgress)
return;
5810 FrameTenHzTimer.Stop();
5812 ProcessDeferredTrackOn();
5814 ProcessAnchorWatch();
5815 ProcessLogAndBells();
5817 if (ShouldRestartTrack()) TrackDailyRestart();
5820 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5821 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5822 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5828 if (gSog > 3.0) g_bCruising =
true;
5834 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5836 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5842 bool bnew_view =
false;
5843 if (!g_btenhertz) bnew_view = DoChartUpdate();
5850 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5853 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5856 cc->DrawBlinkObjects();
5859 if (bactiveRouteUpdate) {
5861 if (g_pRouteMan->GetpActiveRoute())
5862 cc->RefreshRect(g_blink_rect,
false);
5866 cc->SetOwnShipState(SHIP_NORMAL);
5868 if (cc->GetQuiltMode()) {
5869 double erf = cc->GetQuiltMaxErrorFactor();
5870 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5872 if (cc->m_singleChart) {
5873 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5874 cc->SetOwnShipState(SHIP_LOWACCURACY);
5878 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5880 if ((bGPSValid != m_last_bGPSValid) ||
5881 (bVelocityValid != m_last_bVelocityValid) ||
5882 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5883 if (!g_bopengl) cc->UpdateShips();
5890 m_last_bGPSValid = bGPSValid;
5891 m_last_bVelocityValid = bVelocityValid;
5896 bool brq_dynamic =
false;
5898 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5899 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5901 if (pic->m_enabled && pic->m_init_state) {
5902 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5909 if (brq_dynamic) bnew_view =
true;
5913 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5916 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5921 if (cc->GetglCanvas()) {
5923 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5926 if (cc->m_bFollow) {
5927 cc->DoCanvasUpdate();
5934 if (std::isnan(gCog)) cc->Refresh(
false);
5947 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5961 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5962 g_pais_query_dialog_active->UpdateText();
5965 if (g_pAISTargetList && (0 == (g_tick % (5))))
5966 g_pAISTargetList->UpdateAISTargetList();
5969 UpdateGPSCompassStatusBoxes();
5974 console->RefreshConsoleData();
5981 if (m_bdefer_resize) {
5982 if (0 == (g_tick % (5))) {
5983 printf(
"___RESIZE\n");
5984 SetSize(m_defer_size);
5985 g_pauimgr->Update();
5986 m_bdefer_resize =
false;
5993 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5995 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5996 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
6000double MyFrame::GetMag(
double a,
double lat,
double lon) {
6001 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
6002 auto loader = PluginLoader::GetInstance();
6003 if (loader && loader->IsPlugInAvailable(
"WMM")) {
6010 wxDateTime now = wxDateTime::Now();
6011 SendJSON_WMM_Var_Request(lat, lon, now);
6012 if (fabs(gQueryVar) < 360.0)
6013 Variance = gQueryVar;
6015 return toMagnetic(a, Variance);
6018bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
6024 v[
"Year"] = date.GetYear();
6025 v[
"Month"] = date.GetMonth();
6026 v[
"Day"] = date.GetDay();
6028 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
6034void MyFrame::TouchAISActive(
void) {
6036 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6038 if (cc) cc->TouchAISToolActive();
6042void MyFrame::UpdateAISTool(
void) {
6043 if (!g_pAIS)
return;
6046 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6048 if (cc) cc->UpdateAISTBTool();
6053void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
6055 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6057 if (cc) cc->SetbTCUpdate(
true);
6060 RefreshAllCanvas(
false);
6065void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
6069 bool b_rotate =
false;
6070 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6072 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
6076 FrameCOGTimer.Stop();
6083 int period_ms = 100;
6085 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
6088void MyFrame::DoCOGSet(
void) {
6090 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6092 if (cc) cc->DoCanvasCOGSet();
6096void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
6102 wxFont oldfont = pdc->GetFont();
6104 pdc->SetFont(*pFont);
6105 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
6106 pdc->SetBackgroundMode(wxTRANSPARENT);
6108 pdc->DrawText(str, x, y + 1);
6109 pdc->DrawText(str, x, y - 1);
6110 pdc->DrawText(str, x + 1, y);
6111 pdc->DrawText(str, x - 1, y);
6113 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
6115 pdc->DrawText(str, x, y);
6117 pdc->SetFont(oldfont);
6121void MyFrame::UpdateRotationState(
double rotation) {
6123 g_bCourseUp =
false;
6125 if (fabs(rotation) > .001) {
6126 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
6127 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
6129 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
6132 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
6133 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
6135 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6139 UpdateGPSCompassStatusBoxes(
true);
6143void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6145 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6147 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6153int MyFrame::GetApplicationMemoryUse(
void) {
6159 wxWindow *fWin = wxWindow::FindFocus();
6161 wxArrayString outputArray;
6162 wxString cmd(
"ps --no-headers -o vsize ");
6163 unsigned long pid = wxGetProcessId();
6165 cmd1.Printf(
"%ld", pid);
6167 wxExecute(cmd, outputArray);
6169 if (outputArray.GetCount()) {
6170 wxString s = outputArray.Item(0);
6172 if (s.ToLong(&vtmp)) memsize = vtmp;
6175 if (fWin) fWin->SetFocus();
6181 PROCESS_MEMORY_COUNTERS pmc;
6183 unsigned long processID = wxGetProcessId();
6185 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6187 if (NULL == hProcess)
return 0;
6189 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6207 memsize = pmc.WorkingSetSize / 1024;
6210 CloseHandle(hProcess);
6217double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6218 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6221void MyFrame::SetChartUpdatePeriod() {
6224 g_ChartUpdatePeriod = 0;
6229 bool bskewdc =
false;
6230 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6233 if (!g_bopengl && !cc->GetVP().b_quilt) {
6234 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6236 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6240 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6242 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6247 cc->UpdateCanvasControlBar();
6250void MyFrame::selectChartDisplay(
int type,
int family) {
6252 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6254 if (cc) cc->selectCanvasChartDisplay(type, family);
6257 UpdateGlobalMenuItems();
6266bool MyFrame::DoChartUpdate(
void) {
6267 bool return_val =
false;
6270 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6272 if (cc) return_val |= cc->DoCanvasUpdate();
6278void MyFrame::MouseEvent(wxMouseEvent &event) {
6280 event.GetPosition(&x, &y);
6285#include <mach/mach.h>
6286#include <mach/message.h>
6287#include <mach/kern_return.h>
6288#include <mach/task_info.h>
6290#include <malloc/malloc.h>
6297#if defined(__linux__)
6298#include "sys/types.h"
6299#include "sys/sysinfo.h"
6302int g_lastMemTick = -1;
6306bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6308 return androidGetMemoryStatus(mem_total, mem_used);
6311#if defined(__linux__)
6315 struct sysinfo sys_info;
6316 if (sysinfo(&sys_info) != -1)
6317 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6331 FILE *file = fopen(
"/proc/self/statm",
"r");
6333 if (fscanf(file,
"%d", mem_used) != 1) {
6334 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6347 PROCESS_MEMORY_COUNTERS pmc;
6349 unsigned long processID = wxGetProcessId();
6352 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6355 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6373 *mem_used = pmc.WorkingSetSize / 1024;
6376 CloseHandle(hProcess);
6380 MEMORYSTATUSEX statex;
6382 statex.dwLength =
sizeof(statex);
6384 GlobalMemoryStatusEx(&statex);
6402 *mem_total = statex.ullTotalPhys / 1024;
6409 if (g_tick != g_lastMemTick) {
6410 malloc_zone_pressure_relief(NULL, 0);
6413 int blocksInUse = 0;
6414 int sizeAllocated = 0;
6416 malloc_statistics_t stats;
6417 stats.blocks_in_use = 0;
6418 stats.size_in_use = 0;
6419 stats.max_size_in_use = 0;
6420 stats.size_allocated = 0;
6421 malloc_zone_statistics(NULL, &stats);
6422 bytesInUse += stats.size_in_use;
6423 blocksInUse += stats.blocks_in_use;
6424 sizeAllocated += stats.size_allocated;
6426 g_memUsed = sizeAllocated >> 10;
6429 g_lastMemTick = g_tick;
6432 if (mem_used) *mem_used = g_memUsed;
6435 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6437 double pagesUsed = 0.0, totalPages = 0.0;
6439 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6440 *mem_total = atol(buf) >> 10;
6448 if (mem_used) *mem_used = 0;
6449 if (mem_total) *mem_total = 0;
6453void MyFrame::DoPrint(
void) {
6455 g_PrintingInProgress =
true;
6458 GetPrimaryCanvas()->GetglCanvas()->Render();
6459 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6469 printer.Initialize(wxLANDSCAPE);
6470 printer.EnablePageNumbers(
false);
6471 printer.Print(
this, &printout);
6489 g_PrintingInProgress =
false;
6492 GetPrimaryCanvas()->SetFocus();
6498 wxString message_ID =
event.GetID();
6499 wxString message_JSONText =
event.GetJSONText();
6507 if (message_ID ==
"WMM_VARIATION_BOAT") {
6515 int numErrors = reader.
Parse(message_JSONText, &root);
6516 if (numErrors > 0) {
6522 wxString decl = root[
"Decl"].
AsString();
6524 decl.ToDouble(&decl_val);
6530 if (message_ID ==
"WMM_VARIATION") {
6538 int numErrors = reader.
Parse(message_JSONText, &root);
6539 if (numErrors > 0) {
6545 wxString decl = root[
"Decl"].
AsString();
6547 decl.ToDouble(&decl_val);
6549 gQueryVar = decl_val;
6552 if (message_ID ==
"GRIB_TIMELINE") {
6555 int numErrors = r.
Parse(message_JSONText, &v);
6557 if (numErrors > 0) {
6558 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6563 wxDateTime oldTimeSource = gTimeSource;
6565 if (v[
"Day"].AsInt() == -1) {
6566 gTimeSource = wxInvalidDateTime;
6567 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6569 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6570 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6571 v[
"Second"].AsInt());
6575 if (oldTimeSource != gTimeSource) {
6577 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6579 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6584 cc->pCwin->Refresh(
false);
6590 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6593 wxString trk_id = wxEmptyString;
6595 int numErrors = reader.
Parse(message_JSONText, &root);
6596 if (numErrors > 0)
return;
6601 v[
"Track_ID"] = trk_id;
6602 for (
Track *ptrack : g_TrackList) {
6603 wxString name = wxEmptyString;
6604 if (ptrack->m_GUID == trk_id) {
6605 name = ptrack->GetName();
6606 if (name.IsEmpty()) {
6612 name = _(
"(Unnamed Track)");
6619 v[
"TotalNodes"] = ptrack->GetnPoints();
6620 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6622 v[
"lat"] = tp->m_lat;
6623 v[
"lon"] = tp->m_lon;
6626 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6627 SendJSONMessageToAllPlugins(msg_id, v);
6633 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6634 SendJSONMessageToAllPlugins(msg_id, v);
6636 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6639 wxString guid = wxEmptyString;
6641 int numErrors = reader.
Parse(message_JSONText, &root);
6642 if (numErrors > 0) {
6650 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6652 wxString name = wxEmptyString;
6654 if ((*it)->m_GUID == guid) {
6655 name = (*it)->m_RouteNameString;
6656 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6662 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6663 itp != (*it)->pRoutePointList->end(); itp++) {
6664 w[i][
"lat"] = (*itp)->m_lat;
6665 w[i][
"lon"] = (*itp)->m_lon;
6666 w[i][
"Name"] = (*itp)->GetName();
6667 w[i][
"Description"] = (*itp)->GetDescription();
6668 w[i][
"GUID"] = (*itp)->m_GUID;
6669 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6670 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6675 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6676 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6677 httpLink->DescrText;
6678 node = node->GetNext();
6684 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6685 SendJSONMessageToAllPlugins(msg_id, v);
6692 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6693 SendJSONMessageToAllPlugins(msg_id, v);
6694 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6699 int numErrors = reader.
Parse(message_JSONText, &root);
6700 if (numErrors > 0)
return;
6703 wxString str = root[
"mode"].
AsString();
6704 if (str ==
"Track") route =
false;
6709 for (RouteList::iterator it = pRouteList->begin();
6710 it != pRouteList->end(); it++) {
6711 wxString name = (*it)->m_RouteNameString;
6712 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6714 v[i][
"error"] =
false;
6715 v[i][
"name"] = name;
6716 v[i][
"GUID"] = (*it)->m_GUID;
6717 v[i][
"active"] = (*it)->IsActive();
6721 for (
Track *ptrack : g_TrackList) {
6722 wxString name = ptrack->GetName();
6723 if (name.IsEmpty()) {
6729 name = _(
"(Unnamed Track)");
6731 v[i][
"error"] =
false;
6732 v[i][
"name"] = name;
6733 v[i][
"GUID"] = ptrack->m_GUID;
6734 v[i][
"active"] = g_pActiveTrack == ptrack;
6738 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6739 SendJSONMessageToAllPlugins(msg_id, v);
6742 v[0][
"error"] =
true;
6743 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6744 SendJSONMessageToAllPlugins(msg_id, v);
6746 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6748 v[0][
"error"] =
true;
6749 if (g_pRouteMan->GetpActiveRoute()) {
6750 if (g_pRouteMan->m_bDataValid) {
6751 v[0][
"error"] =
false;
6752 v[0][
"range"] = g_pRouteMan->GetCurrentRngToActivePoint();
6753 v[0][
"bearing"] = g_pRouteMan->GetCurrentBrgToActivePoint();
6754 v[0][
"XTE"] = g_pRouteMan->GetCurrentXTEToActivePoint();
6755 v[0][
"active_route_GUID"] = g_pRouteMan->GetpActiveRoute()->GetGUID();
6756 v[0][
"active_waypoint_lat"] =
6758 v[0][
"active_waypoint_lon"] =
6762 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6763 SendJSONMessageToAllPlugins(msg_id, v);
6767void MyFrame::FilterCogSog(
void) {
6768 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6770 double cog_last = gCog;
6773 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6774 COGFilterTable[i] = COGFilterTable[i - 1];
6775 COGFilterTable[0] = cog_last;
6778 if (!std::isnan(cog_last)) {
6780 double sum = 0., count = 0;
6781 for (
int i = 0; i < g_COGFilterSec; i++) {
6782 double adder = COGFilterTable[i];
6783 if (std::isnan(adder))
continue;
6785 if (fabs(adder - cog_last) > 180.) {
6786 if ((adder - cog_last) > 0.)
6799 else if (sum >= 360.)
6806 double sog_last = gSog;
6809 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6810 SOGFilterTable[i] = SOGFilterTable[i - 1];
6811 SOGFilterTable[0] = sog_last;
6814 if (!std::isnan(gSog)) {
6815 double sum = 0., count = 0;
6816 for (
int i = 0; i < g_SOGFilterSec; i++) {
6817 if (std::isnan(SOGFilterTable[i]))
continue;
6819 sum += SOGFilterTable[i];
6829void MyFrame::LoadHarmonics() {
6832 ptcmgr->LoadDataSources(TideCurrentDataSet);
6834 bool b_newdataset =
false;
6837 for (
auto a : ptcmgr->GetDataSet()) {
6838 bool b_foundi =
false;
6839 for (
auto b : TideCurrentDataSet) {
6846 b_newdataset =
true;
6851 for (
auto a : TideCurrentDataSet) {
6852 bool b_foundi =
false;
6853 for (
auto b : ptcmgr->GetDataSet()) {
6860 b_newdataset =
true;
6865 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6869void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6870 if (!ptarget)
return;
6873 wxDateTime mob_time = wxDateTime::Now();
6874 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6875 mob_label += _(
" on ");
6876 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6879 mob_label, wxEmptyString);
6880 pWP_MOB->SetShared(
true);
6882 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6884 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6886 pWP_MOB->SetUseSca(
false);
6894 wxString(_(
"Own ship")), wxEmptyString);
6895 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6896 pWP_MOB->SetUseSca(
false);
6897 pAISMOBRoute =
new Route();
6898 pRouteList->Append(pAISMOBRoute);
6900 pAISMOBRoute->AddPoint(pWP_src);
6901 pAISMOBRoute->AddPoint(pWP_MOB);
6903 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6904 pWP_src, pWP_MOB, pAISMOBRoute);
6912 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6914 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6918 v[
"GUID"] = pAISMOBRoute->
m_GUID;
6919 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6920 SendJSONMessageToAllPlugins(msg_id, v);
6923 if (RouteManagerDialog::getInstanceFlag()) {
6924 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6925 pRouteManagerDialog->UpdateRouteListCtrl();
6926 pRouteManagerDialog->UpdateWptListCtrl();
6930 RefreshAllCanvas(
false);
6932 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6933 mob_message += _(
" Time: ");
6934 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6935 mob_message += _(
" Ownship Position: ");
6936 mob_message += toSDMM(1, gLat);
6938 mob_message += toSDMM(2, gLon);
6939 mob_message += _(
" MOB Position: ");
6940 mob_message += toSDMM(1, ptarget->Lat);
6942 mob_message += toSDMM(2, ptarget->Lon);
6943 wxLogMessage(mob_message);
6946void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6947 if (pAISMOBRoute && ptarget) {
6949 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6950 OwnPoint->m_lat = gLat;
6951 OwnPoint->m_lon = gLon;
6953 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6954 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6957 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6958 MOB_Point->m_lat = ptarget->Lat;
6959 MOB_Point->m_lon = ptarget->Lon;
6961 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6962 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6964 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6965 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6968 RefreshAllCanvas(
false);
6971 wxDateTime mob_time = wxDateTime::Now();
6973 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6974 mob_message += _(
" Time: ");
6975 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6976 mob_message += _(
" Ownship Position: ");
6977 mob_message += toSDMM(1, gLat);
6979 mob_message += toSDMM(2, gLon);
6980 mob_message += _(
" MOB Position: ");
6981 mob_message += toSDMM(1, ptarget->Lat);
6983 mob_message += toSDMM(2, ptarget->Lon);
6985 wxLogMessage(mob_message);
6989void MyFrame::applySettingsString(wxString settings) {
6991 int last_UIScaleFactor = g_GUIScaleFactor;
6992 bool previous_expert = g_bUIexpert;
6993 g_last_ChartScaleFactor = g_ChartScaleFactor;
6994 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6997 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
7000 pConfig->UpdateSettings();
7003 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
7005 if (rr & S52_CHANGED) {
7007 ps52plib->FlushSymbolCaches(ChartCtxFactory());
7009 ->ClearCNSYLUPArray();
7010 ps52plib->GenerateStateHash();
7014 ProcessOptionsDialog(rr, pNewDirArray);
7019 bool b_newToolbar =
false;
7021 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
7023 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
7025 if (rr & TOOLBAR_CHANGED) {
7026 b_newToolbar =
true;
7031 if (previous_expert && !g_bUIexpert) {
7032 androidForceFullRepaint();
7036 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
7040 SetGPSCompassScale();
7042 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7044 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
7046 UpdateGPSCompassStatusBoxes(
true);
7049 AbstractPlatform::ShowBusySpinner();
7051 SetAllToolbarScale();
7055 AbstractPlatform::HideBusySpinner();
7057 RequestNewMasterToolbar(
true);
7064 UpdateControlBar(GetPrimaryCanvas());
7070 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
7073#ifdef wxHAS_POWER_EVENTS
7074void MyFrame::OnSuspending(wxPowerEvent &event) {
7078 wxLogMessage(
"System suspend starting...");
7081void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
7084 wxLogMessage(
"System is going to suspend.");
7087void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
7090 wxLogMessage(
"System suspend was cancelled.");
7093int g_last_resume_ticks;
7094void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
7095 wxDateTime now = wxDateTime::Now();
7096 wxLogMessage(
"System resumed from suspend.");
7098 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
7101 wxLogMessage(
"Restarting streams.");
7102 g_last_resume_ticks = now.GetTicks();
7106 g_pMUX->ClearStreams();
7108 g_pMUX->StartAllStreams();
7117 if (IsMaximized()) {
7122 wxSize sz = GetSize();
7123 SetSize(wxSize(sz.x - 1, sz.y));
7135void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
7136 bool btbRebuild =
false;
7138 bool b_reshow =
true;
7139 if (g_MainToolbar) {
7141 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
7142 if ((ff > 0.01f) || bforcenew) {
7143 g_MainToolbar->DestroyToolBar();
7144 delete g_MainToolbar;
7145 g_MainToolbar = NULL;
7151 if (!g_MainToolbar) {
7152 long orient = g_Platform->GetDefaultToolbarOrientation();
7153 wxWindow *toolbarParent =
this;
7155 toolbarParent = GetPrimaryCanvas();
7158 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7159 g_MainToolbar->SetBackGroundColorString(
"GREY3");
7160 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7161 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7162 g_MainToolbar->EnableRolloverBitmaps(
false);
7164 g_MainToolbar->CreateConfigMenu();
7165 g_MainToolbar->SetDefaultPosition();
7167 g_bmasterToolbarFull =
true;
7170 if (g_MainToolbar) {
7171 CreateMasterToolbar();
7175 g_MainToolbar->SetColorScheme(global_color_scheme);
7181 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7182 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7186bool MyFrame::CollapseGlobalToolbar() {
7187 if (g_MainToolbar) {
7188 m_nMasterToolCountShown = 1;
7189 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7190 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7191 g_MainToolbar->Realize();
7192 g_bmasterToolbarFull =
false;
7201 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7208 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
7209 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
7210 tic->m_bRequired =
true;
7212 g_MainToolbar->AddToolItem(tic);
7215 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
7216 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
7217 g_MainToolbar->AddToolItem(tic);
7220 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
7221 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
7222 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
7224 g_MainToolbar->AddToolItem(tic);
7227 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
7228 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
7229 g_MainToolbar->AddToolItem(tic);
7232 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
7233 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
7234 _(
"Enable Tracking"),
"MUI_track");
7235 g_MainToolbar->AddToolItem(tic);
7238 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
7239 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
7240 g_MainToolbar->AddToolItem(tic);
7251 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
7252 _(
"Print Chart"),
"MUI_print");
7253 g_MainToolbar->AddToolItem(tic);
7256 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
7257 _(
"About OpenCPN"),
"MUI_help");
7258 g_MainToolbar->AddToolItem(tic);
7261 AddDefaultPositionPlugInTools();
7265 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
7266 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
7267 g_MainToolbar->AddToolItem(tic);
7270 g_MainToolbar->RebuildToolbar();
7274 g_MainToolbar->Realize();
7277 ArrayOfPlugInToolbarTools tool_array =
7278 g_pi_manager->GetPluginToolbarToolArray();
7279 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7281 if (!pttc->b_viz)
continue;
7283 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7286 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7287 if (g_bTrackActive) {
7288 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7290 g_MainToolbar->Realize();
7295bool MyFrame::CheckAndAddPlugInTool() {
7296 if (!g_pi_manager)
return false;
7301 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7303 if (!tb)
return false;
7305 int n_tools = tb->GetToolsCount();
7309 ArrayOfPlugInToolbarTools tool_array =
7310 g_pi_manager->GetPluginToolbarToolArray();
7312 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7314 if (pttc->position == n_tools) {
7315 wxBitmap *ptool_bmp;
7317 switch (global_color_scheme) {
7318 case GLOBAL_COLOR_SCHEME_DAY:
7319 ptool_bmp = pttc->bitmap_day;
7322 case GLOBAL_COLOR_SCHEME_DUSK:
7323 ptool_bmp = pttc->bitmap_dusk;
7325 case GLOBAL_COLOR_SCHEME_NIGHT:
7326 ptool_bmp = pttc->bitmap_night;
7329 ptool_bmp = pttc->bitmap_day;
7334 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7336 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7337 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7338 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7339 tic->m_bPlugin =
true;
7348 while (CheckAndAddPlugInTool()) {
7354bool MyFrame::AddDefaultPositionPlugInTools() {
7355 if (!g_pi_manager)
return false;
7361 ArrayOfPlugInToolbarTools tool_array =
7362 g_pi_manager->GetPluginToolbarToolArray();
7364 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7368 if (!pttc->b_viz)
continue;
7370 if (pttc->position == -1)
7372 wxBitmap *ptool_bmp;
7374 switch (global_color_scheme) {
7375 case GLOBAL_COLOR_SCHEME_DAY:
7376 ptool_bmp = pttc->bitmap_day;
7378 case GLOBAL_COLOR_SCHEME_DUSK:
7379 ptool_bmp = pttc->bitmap_dusk;
7381 case GLOBAL_COLOR_SCHEME_NIGHT:
7382 ptool_bmp = pttc->bitmap_night;
7385 ptool_bmp = pttc->bitmap_day;
7390 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7392 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7393 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7394 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7395 tic->m_bPlugin =
true;
7397 g_MainToolbar->AddToolItem(tic);
7410wxColour GetGlobalColor(wxString colorName);
7412static const char *usercolors[] = {
7413 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7414 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7415 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7416 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7417 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7418 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7419 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7421 "DILG0; 255;255;255;",
7423 "DILG0; 238;239;242;",
7425 "DILG1; 212;208;200;",
7426 "DILG2; 255;255;255;",
7430 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7431 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7432 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7434 "UDKRD; 124; 16; 0;",
7435 "UARTE; 200; 0; 0;",
7437 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7438 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7439 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7440 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7442 "DASHB; 255;255;255;",
7443 "DASHL; 175;175;175;",
7444 "DASHF; 50; 50; 50;",
7445 "DASHR; 200; 0; 0;",
7447 "DASHN; 200;120; 0;",
7448 "DASH1; 204;204;255;",
7449 "DASH2; 122;131;172;",
7450 "COMP1; 211;211;211;",
7452 "GREY3; 40; 40; 40;",
7453 "BLUE4; 100;100;200;",
7454 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7455 "BLUEBACK; 212;234;238;",
7456 "LANDBACK; 201;185;122;",
7459 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7460 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7461 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7462 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7463 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7464 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7465 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7467 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7468 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7469 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7471 "DILG0; 110;110;110;",
7472 "DILG1; 110;110;110;",
7474 "DILG3; 130;130;130;",
7475 "UITX1; 41; 46; 46;",
7477 "UARTE; 64; 64; 64;",
7479 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7480 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7481 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7482 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7484 "DASHB; 77; 77; 77;",
7485 "DASHL; 54; 54; 54;",
7487 "DASHR; 58; 21; 21;",
7488 "DASHG; 21; 58; 21;",
7489 "DASHN; 100; 50; 0;",
7490 "DASH1; 76; 76;113;",
7491 "DASH2; 48; 52; 72;",
7492 "COMP1; 107;107;107;",
7494 "GREY3; 20; 20; 20;",
7495 "BLUE4; 80; 80;160;",
7496 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7497 "LANDBACK; 201;185;122;",
7499 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7500 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7501 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7502 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7503 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7504 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7505 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7506 "DILG0; 80; 80; 80;",
7507 "DILG1; 80; 80; 80;",
7509 "DILG3; 65; 65; 65;",
7510 "UITX1; 31; 34; 35;",
7512 "UARTE; 64; 64; 64;",
7514 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7515 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7516 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7518 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7519 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7520 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7521 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7524 "DASHL; 20; 20; 20;",
7525 "DASHF; 64; 64; 64;",
7526 "DASHR; 70; 15; 15;",
7527 "DASHG; 15; 70; 15;",
7528 "DASHN; 17; 80; 56;",
7529 "DASH1; 48; 52; 72;",
7530 "DASH2; 36; 36; 53;",
7531 "COMP1; 24; 24; 24;",
7533 "GREY3; 10; 10; 10;",
7534 "BLUE4; 70; 70;140;",
7535 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7536 "LANDBACK; 201;185;122;",
7540int get_static_line(
char *d,
const char **p,
int index,
int n) {
7541 if (!strcmp(p[index],
"*****"))
return 0;
7543 strncpy(d, p[index], n);
7547void InitializeUserColors(
void) {
7548 const char **p = usercolors;
7556 UserColorTableArray =
new wxArrayPtrVoid;
7557 UserColourHashTableArray =
new wxArrayPtrVoid;
7561 ct->tableName =
new wxString(
"DAY");
7562 ct->color =
new wxArrayPtrVoid;
7563 UserColorTableArray->Add((
void *)ct);
7566 ct->tableName =
new wxString(
"DUSK");
7567 ct->color =
new wxArrayPtrVoid;
7568 UserColorTableArray->Add((
void *)ct);
7571 ct->tableName =
new wxString(
"NIGHT");
7572 ct->color =
new wxArrayPtrVoid;
7573 UserColorTableArray->Add((
void *)ct);
7575 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7576 if (!strncmp(buf,
"Table", 5)) {
7577 sscanf(buf,
"Table:%s", TableName);
7579 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7580 ctp = (colTable *)(UserColorTableArray->Item(it));
7581 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7590 while (buf[j] !=
';' && j < 20) {
7596 S52color *c =
new S52color;
7597 strcpy(c->colName, name);
7599 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7612 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7613 wxColorHashMap *phash =
new wxColorHashMap;
7614 UserColourHashTableArray->Add((
void *)phash);
7616 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7618 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7619 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7621 wxColour c(c2->R, c2->G, c2->B);
7622 wxString key(c2->colName, wxConvUTF8);
7629 pcurrent_user_color_hash =
7630 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7633void DeInitializeUserColors(
void) {
7634 if (!UserColorTableArray)
return;
7635 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7636 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7638 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7639 S52color *c = (S52color *)ct->color->Item(j);
7643 delete ct->tableName;
7649 delete UserColorTableArray;
7651 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7652 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7656 delete UserColourHashTableArray;
7663typedef struct _MSW_COLOR_SPEC {
7665 wxString S52_RGB_COLOR;
7669MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7670 {COLOR_MENUTEXT,
"UITX1", 0},
7671 {COLOR_BTNSHADOW,
"UIBCK", 0},
7674void SaveSystemColors() {
7688 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7689 while (pcspec->COLOR_NAME != -1) {
7690 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7695void RestoreSystemColors() {
7696 int element[NCOLORS];
7697 int rgbcolor[NCOLORS];
7700 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7701 while (pcspec->COLOR_NAME != -1) {
7702 element[i] = pcspec->COLOR_NAME;
7703 rgbcolor[i] = pcspec->SysRGB_COLOR;
7709 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7714void SetSystemColors(ColorScheme cs) {
7716 int element[NCOLORS];
7717 int rgbcolor[NCOLORS];
7719 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7720 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7721 while (pcspec->COLOR_NAME != -1) {
7722 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7723 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7724 element[i] = pcspec->COLOR_NAME;
7730 pSetSysColors(i, (
unsigned long *)&element[0],
7731 (
unsigned long *)&rgbcolor[0]);
7735 RestoreSystemColors();
7740wxColor GetDimColor(wxColor c) {
7741 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7742 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7746 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7747 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7749 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7750 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7751 hsv.value = hsv.value * factor;
7752 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7754 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7760double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7761 double const AnchorPointMaxDist)
7764 if (d < AnchorPointMinDist)
7765 return AnchorPointMinDist;
7766 else if (d > AnchorPointMaxDist)
7767 return AnchorPointMaxDist;
7773 if (d > -AnchorPointMinDist)
7774 return -AnchorPointMinDist;
7775 else if (d < -AnchorPointMaxDist)
7776 return -AnchorPointMaxDist;
7783static const WORD MAX_CONSOLE_LINES =
7788void RedirectIOToConsole()
7793 wxIntPtr lStdHandle;
7795 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7805 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7806 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7807 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7811 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7812 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7813 fp = _fdopen(hConHandle,
"w");
7815 setvbuf(stdout, NULL, _IONBF, 0);
7819 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7820 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7821 fp = _fdopen(hConHandle,
"r");
7823 setvbuf(stdin, NULL, _IONBF, 0);
7827 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7828 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7829 fp = _fdopen(hConHandle,
"w");
7831 setvbuf(stderr, NULL, _IONBF, 0);
7843bool TestGLCanvas(wxString prog_dir) {
7845 wxString test_app = prog_dir;
7846 test_app +=
"ocpn_gltest1.exe";
7848 if (::wxFileExists(test_app)) {
7849 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7850 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7851 if (proc_return == 0)
7852 printf(
"GLCanvas OK\n");
7854 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7856 return (proc_return == 0);
7866bool ReloadLocale() {
7871 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7878 FontMgr::Get().SetLocale(g_locale);
7886 if (pRoutePropDialog) {
7887 pRoutePropDialog->Hide();
7888 pRoutePropDialog->Destroy();
7889 pRoutePropDialog = NULL;
7892 if (pRouteManagerDialog) {
7893 pRouteManagerDialog->Hide();
7894 pRouteManagerDialog->Destroy();
7895 pRouteManagerDialog = NULL;
7898 if (console)
console->SetColorScheme(global_color_scheme);
7899 if (g_pais_query_dialog_active) {
7900 g_pais_query_dialog_active->Destroy();
7901 g_pais_query_dialog_active = NULL;
7904 auto alert_dlg_active =
7906 if (alert_dlg_active) {
7907 alert_dlg_active->Destroy();
7908 g_pais_alert_dialog_active =
nullptr;
7911 if (g_pAISTargetList) {
7912 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7913 g_pAISTargetList->Disconnect_decoder();
7914 g_pAISTargetList->Destroy();
7915 g_pAISTargetList = NULL;
7919 if (gFrame->m_pMenuBar) {
7920 gFrame->SetMenuBar(NULL);
7921 gFrame->m_pMenuBar->Destroy();
7922 gFrame->m_pMenuBar = NULL;
7924 gFrame->BuildMenuBar();
7927 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7929 if (cc) cc->CanvasApplyLocale();
7934 wxString perspective;
7935 pConfig->SetPath(_T (
"/AUI" ));
7936 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7950 bool bno_load =
false;
7951 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7953 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7954 wxAuiPaneInfo pane = pane_array_val[i];
7955 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7961 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7963 g_pauimgr->Update();
7966 gFrame->RequestNewToolbars(
true);
7967 gFrame->RequestNewMasterToolbar(
true);
7971extern s57RegistrarMgr *m_pRegistrarMan;
7972extern wxString g_UserPresLibData;
7973extern wxString g_SENCPrefix;
7974extern wxString g_csv_locn;
7990 g_csv_locn = g_Platform->GetSharedDataDir();
7991 g_csv_locn.Append(
"s57data");
7995 appendOSDirSlash(&g_csv_locn);
7996 g_csv_locn.Append(
"s57data");
8001 if (g_SENCPrefix.IsEmpty()) {
8003 appendOSDirSlash(&g_SENCPrefix);
8004 g_SENCPrefix.Append(
"SENC");
8008 wxFileName f(g_SENCPrefix);
8010 g_SENCPrefix = f.GetFullPath();
8012 g_SENCPrefix =
"SENC";
8018 bool b_force_legacy =
false;
8020 if (g_UserPresLibData.IsEmpty()) {
8021 plib_data = g_csv_locn;
8022 appendOSDirSlash(&plib_data);
8023 plib_data.Append(
"S52RAZDS.RLE");
8025 plib_data = g_UserPresLibData;
8026 b_force_legacy =
true;
8029 ps52plib =
new s52plib(plib_data, b_force_legacy);
8044 if (!ps52plib->m_bOK) {
8047 wxStandardPaths &std_path = g_Platform->GetStdPaths();
8049 wxString look_data_dir;
8050 look_data_dir.Append(std_path.GetUserDataDir());
8051 appendOSDirSlash(&look_data_dir);
8052 wxString tentative_SData_Locn = look_data_dir;
8053 look_data_dir.Append(
"s57data");
8055 plib_data = look_data_dir;
8056 appendOSDirSlash(&plib_data);
8057 plib_data.Append(
"S52RAZDS.RLE");
8059 wxLogMessage(
"Looking for s57data in " + look_data_dir);
8060 ps52plib =
new s52plib(plib_data);
8062 if (ps52plib->m_bOK) {
8063 g_csv_locn = look_data_dir;
8072 if (!ps52plib->m_bOK) {
8075 wxString look_data_dir;
8076 look_data_dir = g_Platform->GetSharedDataDir();
8077 look_data_dir.Append(
"s57data");
8079 plib_data = look_data_dir;
8080 appendOSDirSlash(&plib_data);
8081 plib_data.Append(
"S52RAZDS.RLE");
8083 wxLogMessage(
"Looking for s57data in " + look_data_dir);
8084 ps52plib =
new s52plib(plib_data);
8086 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
8089 if (ps52plib->m_bOK) {
8090 wxLogMessage(
"Using s57data in " + g_csv_locn);
8092 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
8097 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
8099 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
8100 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
8101 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
8102 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
8105 pConfig->LoadS57Config();
8106 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
8109 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
8110 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
8112 ps52plib->SetDIPFactor(dip_factor);
8117 ps52plib->SetScaleFactorExp(
8118 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
8119 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
8124 extern bool g_b_EnableVBO;
8125 extern GLenum g_texture_rectangle_format;
8130 wxString renderer = wxString(GL_Caps->Renderer.c_str());
8131 ps52plib->SetGLRendererString(renderer);
8134 ps52plib->SetGLOptions(
8135 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
8136 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
8137 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
8142 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
8151 : wxThread(wxTHREAD_JOINABLE) {
8152 m_filename = filename;
8163 newChart->SetNativeScale(m_scale);
8164 newChart->SetFullExtent(m_ext);
8166 newChart->FindOrCreateSenc(m_filename);
8171 wxString m_filename;
8177static double chart_dist(
int index) {
8183 if (cte.GetBBox().Contains(gLat, gLon))
8188 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8189 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8190 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8193 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8194 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8196 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8202WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8203static int CompareInts(
int n1,
int n2) {
8204 double d1 = chart_dist(n1);
8205 double d2 = chart_dist(n2);
8206 return (
int)(d1 - d2);
8211 wxString chart_path;
8216WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8218#include <wx/arrimpl.cpp>
8221void ParseAllENC(wxWindow *parent) {
8222 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8230 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
8233 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8235 idx_sorted_by_distance.Add(i);
8239 if (count == 0)
return;
8241 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
8247 ArrayOfCompressTargets ct_array;
8248 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8249 int i = idx_sorted_by_distance[j];
8252 double distance = chart_dist(i);
8254 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8257 pct->distance = distance;
8258 pct->chart_path = filename;
8260 ct_array.push_back(pct);
8263 int thread_count = 0;
8266 extern int g_nCPUCount;
8267 if (g_nCPUCount > 0)
8268 thread_count = g_nCPUCount;
8270 thread_count = wxThread::GetCPUCount();
8272 if (thread_count < 1) {
8281 for(
int t = 0; t < thread_count; t++)
8285 wxGenericProgressDialog *prog =
nullptr;
8289 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8290 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8292 prog =
new wxGenericProgressDialog();
8294 prog->SetFont(*qFont);
8296 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8297 count + 1, parent, style);
8306 prog->ShowWindowModal();
8315 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8316 wxString filename = ct_array[j].chart_path;
8317 double distance = ct_array[j].distance;
8318 int index =
ChartData->FinddbIndex(filename);
8319 if (index < 0)
continue;
8322 ext.NLAT = cte.GetLatMax();
8323 ext.SLAT = cte.GetLatMin();
8324 ext.WLON = cte.GetLonMin();
8325 ext.ELON = cte.GetLonMax();
8327 int scale = cte.GetScale();
8330 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8333 if (wxThread::IsMain()) {
8335 wxSize sz = prog->GetSize();
8340 prog->Update(count, msg, &skip);
8352 newChart->SetNativeScale(
scale);
8353 newChart->SetFullExtent(ext);
8354 newChart->DisableBackgroundSENC();
8356 newChart->FindOrCreateSenc(filename,
8360 if (wxThread::IsMain()) {
8361 msg.Printf(_(
"ENC Completed."));
8363 prog->Update(count, msg, &skip);
8373 for (
int t = 0;; t = (t + 1) % thread_count) {
8380 if (!workers[t]->IsAlive()) {
8393#if defined(__WXMSW__) || defined(__WXOSX__)
8400 for(
int t = 0; t<thread_count; t++) {
Class AisDecoder and helpers.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
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 displaying a list of AIS targets.
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.
Dialog for managing CM93 chart offsets.
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)
Set the viewport center point.
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 OperGL 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)
Gets 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()
Dialog for displaying and editing waypoint properties.
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.
Dialog for displaying query results of S57 objects.
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.
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.
Raw messages layer, supports sending and recieving navmsg messages.
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
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
New NMEA Debugger successor main window.
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.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
Miscellaneous globals primarely used by gui layer.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
Multiplexer class and helpers.
Class NotificationManager.
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(void)
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
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.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.