54#include <wx/stdpaths.h>
55#include <wx/tokenzr.h>
56#include <wx/display.h>
57#include <wx/jsonreader.h>
59#include "model/ais_decoder.h"
61#include "model/ais_target_data.h"
63#include "model/comm_drv_factory.h"
65#include "model/comm_n0183_output.h"
67#include "model/comm_vars.h"
68#include "model/config_vars.h"
69#include "model/cutil.h"
70#include "model/georef.h"
72#include "model/idents.h"
75#include "model/multiplexer.h"
76#include "model/nav_object_database.h"
77#include "model/navutil_base.h"
78#include "model/own_ship.h"
80#include "model/plugin_loader.h"
81#include "model/routeman.h"
82#include "model/select.h"
84#include "model/track.h"
86#include "dialog_alert.h"
87#include "AboutFrameImpl.h"
90#include "ais_info_gui.h"
91#include "AISTargetAlertDialog.h"
92#include "AISTargetListDialog.h"
93#include "AISTargetQueryDialog.h"
94#include "CanvasConfig.h"
96#include "chart_ctx_factory.h"
100#include "color_handler.h"
103#include "connections_dlg.h"
104#include "ConfigMgr.h"
109#include "glChartCanvas.h"
110#include "GoToPositionDialog.h"
112#include "iENCToolbar.h"
114#include "load_errors_dlg.h"
117#include "N2KParser.h"
121#include "OCPN_AUIManager.h"
122#include "ocpn_frame.h"
123#include "OCPNPlatform.h"
124#include "OCPN_Sound.h"
126#include "pluginmanager.h"
127#include "print_dialog.h"
128#include "printout_chart.h"
129#include "routemanagerdialog.h"
130#include "routeman_gui.h"
131#include "route_point_gui.h"
132#include "RoutePropDlgImpl.h"
135#include "S57QueryDialog.h"
136#include "SystemCmdSound.h"
140#include "TrackPropDlg.h"
141#include "waypointman_gui.h"
142#include "CanvasOptions.h"
146#include "androidUTIL.h"
152WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
160extern arrayofCanvasPtr g_canvasArray;
173extern about *g_pAboutDlgLegacy;
176extern double vLat, vLon;
177extern wxString g_locale;
178extern ColorScheme global_color_scheme;
183GLenum g_texture_rectangle_format;
186#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
187extern wxLocale *plocale_def_lang;
194extern s52plib *ps52plib;
198extern bool g_b_legacy_input_filter_behaviour;
199extern bool g_bTrackActive;
201extern bool g_bmasterToolbarFull;
202extern int g_nAutoHideToolbar;
203extern bool g_bAutoHideToolbar;
204extern bool g_bshowToolbar;
205extern int g_maintoolbar_x;
206extern int g_maintoolbar_y;
207extern wxString g_toolbarConfig;
208extern float g_toolbar_scalefactor;
209extern float g_compass_scalefactor;
210extern bool g_bShowMenuBar;
211extern bool g_bShowCompassWin;
213extern bool g_benable_rotate;
214extern int g_GUIScaleFactor;
215extern int g_ChartScaleFactor;
216extern int g_last_ChartScaleFactor;
217extern int g_ShipScaleFactor;
218extern float g_ShipScaleFactorExp;
219extern int g_ENCTextScaleFactor;
221extern bool g_bShowTide;
222extern bool g_bShowCurrent;
223extern bool g_bUIexpert;
224extern RouteList *pRouteList;
225extern wxString g_default_wp_icon;
226extern std::vector<std::string> TideCurrentDataSet;
227extern wxString g_TCData_Dir;
229extern char nmea_tick_chars[];
230extern double AnchorPointMinDist;
231extern bool AnchorAlertOn1, AnchorAlertOn2;
232extern wxString g_AW1GUID;
233extern wxString g_AW2GUID;
234extern bool g_bCruising;
235extern double g_COGAvg;
236extern int g_COGAvgSec;
238extern std::vector<Track *> g_TrackList;
239extern double gQueryVar;
240extern int g_ChartUpdatePeriod;
241extern int g_SkewCompUpdatePeriod;
242extern bool g_bCourseUp;
243extern bool g_bLookAhead;
244extern bool g_bskew_comp;
245extern bool g_bPauseTest;
247extern bool g_bPlayShipsBells;
248extern wxDateTime g_loglast_time;
249extern int g_nAWDefault;
251extern bool g_bDeferredStartTrack;
252extern bool bDBUpdateInProgress;
256extern bool g_bDeferredInitDone;
257extern int options_lastPage;
258extern int options_subpage;
259extern bool b_reloadForPlugins;
261extern int g_NeedDBUpdate;
262extern bool g_bFullscreen;
263extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
264extern ChartGroupArray *g_pGroupArray;
265extern bool g_bEnableZoomToCursor;
266extern double g_display_size_mm;
267extern std::vector<size_t> g_config_display_size_mm;
268extern wxString ChartListFileName;
269extern bool g_bFullscreenToolbar;
270extern arrayofCanvasPtr g_canvasArray;
271extern wxString g_lastAppliedTemplateGUID;
272extern wxPoint options_lastWindowPos;
273extern wxSize options_lastWindowSize;
274extern unsigned int g_canvasConfig;
275extern bool g_bFullScreenQuilt;
276extern bool g_bQuiltEnable;
277extern wxString *pInit_Chart_Dir;
278extern bool g_bShowOutlines;
279extern bool g_bTempShowMenuBar;
280extern bool g_bShowStatusBar;
281extern bool g_FlushNavobjChanges;
282extern int g_FlushNavobjChangesTimeout;
283extern bool g_bShowChartBar;
284extern double g_plus_minus_zoom_factor;
285extern int g_nframewin_x;
286extern int g_nframewin_y;
287extern int g_nframewin_posx;
288extern int g_nframewin_posy;
289extern bool g_bframemax;
290extern LayerList *pLayerList;
291extern bool g_bAutoAnchorMark;
292extern wxDateTime g_start_time;
293extern bool g_bcompression_wait;
294extern bool g_bquiting;
295extern bool b_inCloseWindow;
296extern bool b_inCompressAllCharts;
297extern long g_maintoolbar_orient;
298extern wxAuiDefaultDockArt *g_pauidockart;
299extern int g_click_stop;
300extern wxString g_CmdSoundString;
301extern std::vector<OcpnSound *> bells_sound;
302extern char bells_sound_file_name[2][12];
303extern int g_sticky_chart;
304extern int g_sticky_projection;
305extern wxArrayPtrVoid *UserColourHashTableArray;
306extern wxColorHashMap *pcurrent_user_color_hash;
309extern bool g_own_ship_sog_cog_calc;
310extern int g_own_ship_sog_cog_calc_damp_sec;
311extern bool g_bHasHwClock;
312extern bool s_bSetSystemTime;
313extern bool bVelocityValid;
314extern int gHDx_Watchdog;
317extern bool g_bUseGLL;
318extern int g_MemFootMB;
321extern int g_chart_zoom_modifier_vector;
322extern bool g_config_display_size_manual;
323extern bool g_PrintingInProgress;
324extern bool g_disable_main_toolbar;
325extern bool g_btenhertz;
330typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
331typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
333SetSysColors_t pSetSysColors;
334GetSysColor_t pGetSysColor;
336void SaveSystemColors(
void);
337void RestoreSystemColors(
void);
342DWORD color_3ddkshadow;
344DWORD color_activecaption;
345DWORD color_gradientactivecaption;
346DWORD color_captiontext;
347DWORD color_windowframe;
348DWORD color_inactiveborder;
353#include <wx/msw/msvcrt.h>
357static const long long lNaN = 0xfff8000000000000;
358#define NAN (*(double *)&lNaN)
361static wxArrayPtrVoid *UserColorTableArray = 0;
364double gLat_gt, gLon_gt;
365double gLat_gt_m1, gLon_gt_m1;
367uint64_t fix_time_gt_last;
369double gSog_gt, gCog_gt, gHdt_gt;
370double gCog_gt_m1, gHdt_gt_m1;
372double cog_rate_gt, hdt_rate_gt;
375void appendOSDirSlash(wxString *pString);
377void InitializeUserColors(
void);
378void DeInitializeUserColors(
void);
379void SetSystemColors(ColorScheme cs);
381static bool LoadAllPlugIns(
bool load_enabled) {
382 AbstractPlatform::ShowBusySpinner();
383 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled);
384 AbstractPlatform::HideBusySpinner();
392#if defined(__WXGTK__) || defined(__WXQT__)
393#include "bitmaps/opencpn.xpm"
408int g_iENCToolbarPosX;
409int g_iENCToolbarPosY;
411void BuildiENCToolbar(
bool bnew) {
412 if (g_bInlandEcdis) {
415 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
416 wxPoint tbp_incanvas =
419 g_iENCToolbarPosY = tbp_incanvas.y;
420 g_iENCToolbarPosX = tbp_incanvas.x;
422 delete g_iENCToolbar;
427 if (!g_iENCToolbar) {
428 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
432 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
434 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
435 g_iENCToolbarPosY = -1;
438 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
444 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
448 double tool_scale_factor =
449 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
452 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
453 g_iENCToolbar->SetColorScheme(global_color_scheme);
454 g_iENCToolbar->EnableSubmerge(
false);
457 delete g_iENCToolbar;
458 g_iENCToolbar = NULL;
462bool ShowNavWarning() {
465OpenCPN is distributed in the hope that it will be useful, \
466but WITHOUT ANY WARRANTY; without even the implied \
467warranty of MERCHANTABILITY or FITNESS FOR A \
468PARTICULAR PURPOSE.\n\n\
469See the GNU General Public License for more details.\n\n\
470OpenCPN must only be used in conjunction with approved \
471paper charts and traditional methods of navigation.\n\n\
472DO NOT rely upon OpenCPN for safety of life or property.\n\n\
473Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
475 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
478 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
481 msg.Replace(
"\n",
"<br>");
483 std::stringstream html;
484 html <<
"<html><body><p>";
485 html << msg.ToStdString();
486 html <<
"</p></body></html>";
488 std::string title = _(
"Welcome to OpenCPN").ToStdString();
489 std::string action = _(
"Agree").ToStdString();
491 info_dlg.SetInitialSize();
492 info_dlg.AddHtmlContent(html);
493 int agreed = info_dlg.ShowModal();
494 return agreed == wxID_OK;
499 if (chart ==
nullptr)
return false;
502 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
504 if (cc && cc->m_singleChart == chart) {
511#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
514static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
515 const char *prop_name) {
519 unsigned long ret_nitems;
520 unsigned long ret_bytes_after;
521 unsigned char *ret_prop;
523 xa_prop_name = XInternAtom(disp, prop_name, False);
531 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
532 &xa_ret_type, &ret_format, &ret_nitems,
533 &ret_bytes_after, &ret_prop) != Success)
536 if (xa_ret_type != xa_prop_type) {
540 return (
char *)ret_prop;
545static bool isTransparentToolbarInOpenGLOK(
void) {
552 if (!g_bdisable_opengl) {
553 Display *disp = XOpenDisplay(NULL);
555 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
557 "_NET_SUPPORTING_WM_CHECK")) ||
558 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
560 "_WIN_SUPPORTING_WM_CHECK"))) {
563 if ((wm_name = get_X11_property(disp, *sup_window,
564 XInternAtom(disp,
"UTF8_STRING", False),
566 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
569 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
590wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
592BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
593EVT_CLOSE(MyFrame::OnCloseWindow)
594EVT_MENU(wxID_EXIT, MyFrame::OnExit)
595EVT_SIZE(MyFrame::OnSize)
596EVT_MOVE(MyFrame::OnMove)
597EVT_ICONIZE(MyFrame::OnIconize)
598EVT_MENU(-1, MyFrame::OnToolLeftClick)
599EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
600EVT_TIMER(FRAME_TIMER_1, MyFrame::OnFrameTimer1)
601EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
602EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
603EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
604EVT_TIMER(FRANE_TENHZ_TIMER, MyFrame::OnFrameTenHzTimer)
605EVT_MAXIMIZE(MyFrame::OnMaximize)
606EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
607 MyFrame::RequestNewToolbarArgEvent)
608EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
610EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
611EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
612EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
614#ifdef wxHAS_POWER_EVENTS
615EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
616EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
617EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
618EVT_POWER_RESUME(MyFrame::OnResume)
629static
void onBellsFinishedCB(
void *ptr) {
630 auto framePtr =
static_cast<MyFrame *
>(ptr);
632 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
633 wxPostEvent(framePtr, ev);
638 auto msg = ev.GetString().ToStdString();
639 OCPNMessageBox(
GetTopWindow(), msg, _(
"Communication Error"));
642static NmeaLog *GetDataMonitor() {
643 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
644 return dynamic_cast<NmeaLog *
>(w);
648MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
649 const wxSize &size,
long style,
DataMonitor *data_monitor)
650 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
651 comm_overflow_dlg(this),
652 m_connections_dlg(nullptr),
653 m_data_monitor(data_monitor) {
654 g_current_monitor = wxDisplay::GetFromWindow(
this);
660 g_current_monitor_dip_px_ratio =
661 g_monitor_info[g_current_monitor].width_px /
662 g_monitor_info[g_current_monitor].width;
665 m_last_track_rotation_ts = 0;
666 m_ulLastNMEATicktime = 0;
667 m_data_monitor->Hide();
669 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
673 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
676 InitTimer.SetOwner(
this, INIT_TIMER);
678 m_initializing =
false;
681 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
684 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
687 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
690 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
693 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
695 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
704 m_bTimeIsSet =
false;
707 m_bdefer_resize =
false;
710 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
711 COGFilterTable[i] = NAN;
712 SOGFilterTable[i] = NAN;
714 m_last_bGPSValid =
false;
715 m_last_bVelocityValid =
false;
725 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
730 double process_noise_std = 1.0;
731 double measurement_noise_std = 0.5;
733 m_ChartUpdatePeriod = 1;
738 log_callbacks.log_is_active = [&]() {
739 auto log = GetDataMonitor();
740 return log && log->IsActive();
742 log_callbacks.log_message = [&](
Logline ll) {
743 NmeaLog *monitor = GetDataMonitor();
744 if (monitor && monitor->
IsActive()) monitor->
Add(ll);
746 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
749 ais_callbacks.confirm_stop_track = []() {
750 int r = OCPNMessageBox(
752 _(
"This AIS target has Persistent tracking selected by MMSI "
754 "A Persistent track recording will therefore be restarted for this "
756 "Do you instead want to stop Persistent tracking for this target?"),
757 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
758 return r == wxID_YES;
760 ais_callbacks.get_target_mmsi = []() {
761 auto alert_dlg_active =
763 assert(alert_dlg_active);
764 return alert_dlg_active->Get_Dialog_MMSI();
772 wxLogMessage(
" **** Connect stuff");
778 Connect(wxEVT_OCPN_MSG,
779 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
786 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
787 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
795#if defined(__WXGTK__) || defined(__WXQT__)
796 wxIcon app_icon(opencpn);
804 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
806 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
807 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
812 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
815 g_sticky_projection = -1;
818 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
819 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
821 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
823 [&](wxCommandEvent) { Refresh(); });
824 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
829 EnableFullScreenView();
835 FrameTenHzTimer.Stop();
842 wxRouteListNode *node = pRouteList->GetFirst();
845 Route *pRouteDelete = node->GetData();
848 node = node->GetNext();
855 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
863 switch (event.type) {
864 case SENC_BUILD_STARTED:
867 case SENC_BUILD_DONE_NOERROR:
869 chart =
event.m_ticket->m_chart;
871 chart->PostInit(FULL_INIT, global_color_scheme);
873 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
875 if (cc) cc->ClearS52PLIBStateHash();
880 delete event.m_ticket;
882 case SENC_BUILD_DONE_ERROR:
890void MyFrame::RebuildChartDatabase() {
891 bool b_SetInitialPoint =
false;
894 ArrayOfCDI ChartDirArray;
895 pConfig->LoadChartDirArray(ChartDirArray);
897 if (ChartDirArray.GetCount()) {
900 if (g_NeedDBUpdate == 1) {
902 _(
"OpenCPN needs to update the chart database from config file "
906 wxICON_INFORMATION | wxOK);
914 _(
"Rebuilding chart database from configuration file entries..."));
918 wxString dummy1 = _(
"Elapsed time : ");
919 wxString dummy2 = _(
"Estimated time : ");
920 wxString dummy3 = _(
"Remaining time : ");
921 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
922 _(
"OpenCPN Chart Update"), line, 100, NULL,
923 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
924 wxPD_REMAINING_TIME);
926 ChartData->
Create(ChartDirArray, pprog);
927 ChartData->SaveBinary(ChartListFileName);
932 ChartData->ApplyGroupArray(g_pGroupArray);
937void MyFrame::OnBellsFinished(wxCommandEvent &event) {
938 int bells = wxMin(m_BellsToPlay, 2);
939 if (bells <= 0)
return;
941 wxString soundfile = _T(
"sounds");
942 appendOSDirSlash(&soundfile);
943 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
944 soundfile.Prepend(g_Platform->GetSharedDataDir());
945 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
947 OcpnSound *sound = bells_sound[bells - 1];
948 sound->SetFinishedCallback(onBellsFinishedCB,
this);
949 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
950 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
951 sound->Load(soundfile);
952 if (!sound->IsOk()) {
953 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
957 m_BellsToPlay -= bells;
960void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
962void MyFrame::OnMaximize(wxMaximizeEvent &event) {
969ColorScheme GetColorScheme() {
return global_color_scheme; }
971ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
973void MyFrame::ReloadAllVP() {
974 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
976 if (cc) cc->ReloadVP();
980void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
981 global_color_scheme = cs;
985 case GLOBAL_COLOR_SCHEME_DAY:
986 SchemeName = _T(
"DAY");
988 case GLOBAL_COLOR_SCHEME_DUSK:
989 SchemeName = _T(
"DUSK");
991 case GLOBAL_COLOR_SCHEME_NIGHT:
992 SchemeName = _T(
"NIGHT");
995 SchemeName = _T(
"DAY");
999 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
1001 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
1002 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
1003 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1004 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
1005 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
1007 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1036 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1037 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1039 g_pauimgr->Update();
1041 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1044 unsigned Usercolortable_index = 0;
1045 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1046 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1047 if (SchemeName.IsSameAs(*ct->tableName)) {
1048 Usercolortable_index = i;
1053 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1056 pcurrent_user_color_hash =
1057 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1059 SetSystemColors(cs);
1062 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1065 cc->SetColorScheme(cs);
1066 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1067 cc->HideChartInfoWindow();
1068 cc->SetQuiltChartHiLiteIndex(-1);
1074 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1075 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1078 g_options->SetColorScheme(cs);
1082 console->SetColorScheme(cs);
1086 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1089 if (g_pMarkInfoDialog) {
1090 g_pMarkInfoDialog->SetColorScheme(cs);
1093 if (pRoutePropDialog) {
1094 pRoutePropDialog->SetColorScheme(cs);
1099 if (g_pais_query_dialog_active) {
1100 bool b_isshown = g_pais_query_dialog_active->IsShown();
1101 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1102 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1104 g_pais_query_dialog_active->Close();
1107 g_pais_query_dialog_active->
Create(
1108 this, -1, _(
"AIS Target Query"),
1109 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1110 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1111 g_pais_query_dialog_active->UpdateText();
1112 if (b_isshown) g_pais_query_dialog_active->Show();
1115 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1117 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1119 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1121 ApplyGlobalColorSchemetoStatusBar();
1123 UpdateAllToolbars(cs);
1125 if (g_MainToolbar) {
1126 if (g_MainToolbar->GetColorScheme() != cs) {
1128 bool btoolbarFull = g_bmasterToolbarFull;
1130 g_MainToolbar->SetColorScheme(cs);
1134 if (!btoolbarFull) {
1136 RequestNewMasterToolbar();
1137 g_MainToolbar->SetColorScheme(cs);
1138 CollapseGlobalToolbar();
1141 RequestNewMasterToolbar();
1142 g_MainToolbar->SetColorScheme(cs);
1147 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1150void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1151 if (m_pStatusBar != NULL) {
1152 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1153 m_pStatusBar->ClearBackground();
1158 if (g_canvasArray.GetCount() > 0)
1159 return g_canvasArray.Item(0);
1163void MyFrame::CancelAllMouseRoute() {
1165 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1167 if (cc) cc->CancelMouseRoute();
1171void MyFrame::NotifyChildrenResize() {}
1173void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1175 if (ChartData) ChartData->PurgeCache();
1178 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1181 g_pauimgr->DetachPane(cc);
1186 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1195 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1198 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1199 config_array.Item(i)->canvas = NULL;
1205 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1206 g_canvasArray.RemoveAt(i);
1210 switch (g_canvasConfig) {
1213 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1216 g_canvasArray.Add(cc);
1218 cc = g_canvasArray[0];
1224 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1225 cc->GetglCanvas()->Show();
1228 config_array.Item(0)->canvas = cc;
1232 cc->ApplyCanvasConfig(config_array.Item(0));
1236 cc->ConfigureChartBar();
1237 cc->SetColorScheme(global_color_scheme);
1238 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1239 cc->SetShowGPS(
true);
1241 g_pauimgr->AddPane(cc);
1242 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1243 g_pauimgr->GetPane(cc).Fixed();
1244 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1245 g_pauimgr->GetPane(cc).CenterPane();
1250 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1252 g_canvasArray.Add(cc);
1254 cc = g_canvasArray[0];
1260 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1263 config_array.Item(0)->canvas = cc;
1265 cc->ApplyCanvasConfig(config_array.Item(0));
1268 cc->ConfigureChartBar();
1269 cc->SetColorScheme(global_color_scheme);
1270 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1271 cc->SetShowGPS(
false);
1273 g_pauimgr->AddPane(cc);
1274 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1275 g_pauimgr->GetPane(cc)
1276 .CaptionVisible(
false)
1278 .CloseButton(
false);
1280 g_pauimgr->GetPane(cc).CenterPane();
1283 g_canvasArray.Add(cc);
1287 if (config_array.GetCount() < 2) {
1289 pcc->configIndex = 1;
1293 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1294 config_array.Add(pcc);
1297 config_array.Item(1)->canvas = cc;
1299 cc->ApplyCanvasConfig(config_array.Item(1));
1302 cc->ConfigureChartBar();
1303 cc->SetColorScheme(global_color_scheme);
1304 cc->SetShowGPS(
true);
1307 g_pauimgr->AddPane(cc);
1308 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1309 g_pauimgr->GetPane(cc)
1310 .CaptionVisible(
false)
1312 .CloseButton(
false);
1313 g_pauimgr->GetPane(cc).RightDockable(
true);
1314 g_pauimgr->GetPane(cc).Right();
1317 config_array.Item(1)->canvasSize =
1318 wxSize(GetClientSize().x / 2, GetClientSize().y);
1319 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1324 if (b_useStoredSize) {
1325 int ccw = config_array.Item(1)->canvasSize.x;
1326 int cch = config_array.Item(1)->canvasSize.y;
1329 if (ccw < GetClientSize().x / 10) {
1330 ccw = GetClientSize().x / 2;
1331 cch = GetClientSize().y;
1334 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1335 cc->SetSize(ccw, cch);
1346 g_focusCanvas = GetPrimaryCanvas();
1349void MyFrame::RequestNewToolbars(
bool bforcenew) {
1350 if (b_inCloseWindow) {
1354 BuildiENCToolbar(bforcenew);
1355 PositionIENCToolbar();
1364void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1365 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1370void MyFrame::SetAllToolbarScale() {
1371 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1374void MyFrame::SetGPSCompassScale() {
1375 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1379 wxPoint screenPoint = ::wxGetMousePosition();
1382 switch (g_canvasConfig) {
1384 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1387 if (canvas->GetScreenRect().Contains(
1391 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1394 if (canvas->GetScreenRect().Contains(
1401 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1404 if (canvas->GetScreenRect().Contains(
1405 canvas->ScreenToClient(screenPoint)))
1413int MyFrame::GetCanvasIndexUnderMouse() {
1414 wxPoint screenPoint = ::wxGetMousePosition();
1417 switch (g_canvasConfig) {
1419 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1422 if (canvas->GetScreenRect().Contains(
1426 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1429 if (canvas->GetScreenRect().Contains(
1436 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1439 if (canvas->GetScreenRect().Contains(
1440 canvas->ScreenToClient(screenPoint)))
1448bool MyFrame::DropMarker(
bool atOwnShip) {
1455 if (!canvas)
return false;
1462 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1464 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1465 pConfig->AddNewWayPoint(pWP, -1);
1469 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1470 pRouteManagerDialog->UpdateWptListCtrl();
1475 RefreshAllCanvas(
false);
1480void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1481 if (g_canvasConfig != 0) {
1484 int nTargetGTK = -1;
1486 wxWindow *source = FindFocus();
1492 switch (g_canvasConfig) {
1494 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1497 if (canvas && (canvas == test)) {
1502 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1505 if (canvas && (canvas == test)) {
1513 int nfinalTarget = nTarget;
1515 nfinalTarget = nTargetGTK;
1517 target = ConfigMgr::Get()
1518 .GetCanvasConfigArray()
1523 target->Refresh(
true);
1534void MyFrame::FastClose() {
1536 FrameTenHzTimer.Stop();
1538 FrameTimer1.Start(1);
1542void MyFrame::OnExit(wxCommandEvent &event) {
1546void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1549 if (b_inCloseWindow) {
1559 if (!g_bDeferredInitDone)
return;
1572 if (b_inCompressAllCharts) {
1576 if (bDBUpdateInProgress)
return;
1578 b_inCloseWindow =
true;
1580 ::wxSetCursor(wxCURSOR_WAIT);
1584 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1586 if (cc && cc->IsMeasureActive()) {
1587 cc->CancelMeasureRoute();
1592 SendPreShutdownHookToPlugins();
1596 if (g_pAISTargetList) {
1597 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1598 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1599 g_pauimgr->DetachPane(g_pAISTargetList);
1610 pConfig->SetPath(_T (
"/AUI" ));
1611 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1618 if (g_glTextureManager) {
1619 g_glTextureManager->PurgeJobList();
1621 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1626 SetCursor(wxCURSOR_WAIT);
1628 RefreshAllCanvas(
true);
1634 RestoreScreenBrightness();
1643 if (g_iENCToolbar) {
1644 wxPoint locn = g_iENCToolbar->GetPosition();
1645 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1646 g_iENCToolbarPosY = tbp_incanvas.y;
1647 g_iENCToolbarPosX = tbp_incanvas.x;
1651 g_bframemax = IsMaximized();
1654 FrameTenHzTimer.Stop();
1656 FrameCOGTimer.Stop();
1670 if (g_bAutoAnchorMark) {
1671 bool watching_anchor =
false;
1672 if (pAnchorWatchPoint1)
1673 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1675 if (pAnchorWatchPoint2)
1676 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1679 wxDateTime now = wxDateTime::Now();
1680 wxTimeSpan uptime = now.Subtract(g_start_time);
1682 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1683 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1688 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1691 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1692 double a = gLat - pr->m_lat;
1693 double b = gLon - pr->m_lon;
1694 double l = sqrt((a * a) + (b * b));
1697 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1698 pConfig->DeleteWayPoint(pr);
1699 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1705 node = node->GetNext();
1708 wxString name = now.Format();
1709 name.Prepend(_(
"Anchorage created "));
1711 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1712 pWP->m_bShowName =
false;
1715 pConfig->AddNewWayPoint(pWP, -1);
1720 pConfig->UpdateSettings();
1723 auto plugin_loader = PluginLoader::getInstance();
1724 if (plugin_loader) {
1725 plugin_loader->DeactivateAllPlugIns();
1728 wxLogMessage(_T(
"opencpn::MyFrame exiting cleanly."));
1732 pConfig->UpdateNavObj();
1734 pConfig->m_pNavObjectChangesSet->reset();
1738 pConfig->DeleteGroup(_T (
"/Routes" ));
1739 pConfig->DeleteGroup(_T (
"/Marks" ));
1742 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1743 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1748 if (g_pCM93OffsetDialog) {
1749 g_pCM93OffsetDialog->Destroy();
1750 g_pCM93OffsetDialog = NULL;
1758 if (g_iENCToolbar) {
1765 if (g_pAISTargetList) {
1766 g_pAISTargetList->Disconnect_decoder();
1767 g_pAISTargetList->Destroy();
1774 if (RouteManagerDialog::getInstanceFlag()) {
1775 if (pRouteManagerDialog) {
1776 pRouteManagerDialog->Destroy();
1777 pRouteManagerDialog = NULL;
1782 if (ChartData) ChartData->PurgeCache();
1788 g_focusCanvas = NULL;
1791 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1793 if (cc) cc->Destroy();
1796 g_canvasArray.Clear();
1798 g_pauimgr->UnInit();
1808 if (ChartData) ChartData->PurgeCachePlugins();
1810 if (PluginLoader::getInstance())
1811 PluginLoader::getInstance()->UnLoadAllPlugIns();
1814 delete g_pi_manager;
1815 g_pi_manager = NULL;
1818 MyApp &app = wxGetApp();
1819 app.m_comm_bridge.SaveConfig();
1839 auto ®istry = CommDriverRegistry::GetInstance();
1840 registry.CloseAllDrivers();
1843 for (
auto *cp : TheConnectionParams()) {
1848 LayerList::iterator it;
1849 while (pLayerList->GetCount()) {
1850 Layer *lay = pLayerList->GetFirst()->GetData();
1855 ReleaseApiListeners();
1857 g_MainToolbar = NULL;
1858 g_bTempShowMenuBar =
false;
1860#define THREAD_WAIT_SECONDS 5
1866 if (g_bopengl && g_glTextureManager &&
1867 g_glTextureManager->GetRunningJobCount()) {
1868 g_glTextureManager->ClearAllRasterTextures();
1870 wxLogMessage(_T(
"Starting compressor pool drain"));
1871 wxDateTime now = wxDateTime::Now();
1872 time_t stall = now.GetTicks();
1873 time_t end = stall + THREAD_WAIT_SECONDS;
1876 while (stall < end) {
1877 wxDateTime later = wxDateTime::Now();
1878 stall = later.GetTicks();
1881 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1882 g_glTextureManager->GetRunningJobCount());
1884 if (!g_glTextureManager->GetRunningJobCount())
break;
1890 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1891 n_comploop, g_glTextureManager->GetRunningJobCount());
1894 delete g_glTextureManager;
1896 uninitIXNetSystem();
1900 wxLogMessage(_T(
"gFrame destroyed."));
1903#ifndef USE_ANDROID_GLES2
1904 qDebug() <<
"Calling OnExit()";
1908 wxTheApp->ExitMainLoop();
1911void MyFrame::OnMove(wxMoveEvent &event) {
1912 auto idx = wxDisplay::GetFromWindow(
this);
1913 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
1914 static_cast<size_t>(idx) < g_monitor_info.size()) {
1915 g_current_monitor = idx;
1921 g_current_monitor_dip_px_ratio =
1922 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
1925 DEBUG_LOG <<
"Moved to " << idx
1926#if wxCHECK_VERSION(3, 1, 6)
1927 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1928 << wxDisplay(idx).GetPPI().GetY()
1929 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1931 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1932 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1933 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1934 << wxGetDisplaySizeMM().GetY()
1935 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1936 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
1937 << g_monitor_info[idx].height_mm <<
"mm "
1938 << g_monitor_info[idx].width_mm <<
"x"
1939 << g_monitor_info[idx].height_mm <<
"mm "
1940 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
1941 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
1942 << g_monitor_info[idx].height_px <<
"px"
1943 << g_monitor_info[idx].scale <<
"%";
1944 if (g_config_display_size_manual) {
1945 if (g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
1946 g_display_size_mm = g_config_display_size_mm[idx];
1949 g_display_size_mm = g_monitor_info[idx].width_mm;
1953 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1956 cc->SetMUIBarPosition();
1965 UpdateGPSCompassStatusBoxes();
1967 if (console && console->IsShown()) PositionConsole();
1975 PositionIENCToolbar();
1981 g_nframewin_posx = GetPosition().x;
1982 g_nframewin_posy = GetPosition().y;
1985void MyFrame::ProcessCanvasResize(
void) {
1986 UpdateGPSCompassStatusBoxes(
true);
1988 if (console && console->IsShown()) PositionConsole();
1990 PositionIENCToolbar();
1993 TriggerRecaptureTimer();
1997void MyFrame::TriggerRecaptureTimer() {
1998 m_recaptureTimer.Start(
1999 1000, wxTIMER_ONE_SHOT);
2002void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
2004void MyFrame::SetCanvasSizes(wxSize frameSize) {
2005 if (!g_canvasArray.GetCount())
return;
2008 int cccw = frameSize.x;
2009 int ccch = frameSize.y;
2013 switch (g_canvasConfig) {
2017 cc = g_canvasArray.Item(0);
2019 cc->GetSize( &cur_width, &cur_height );
2020 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2021 if( g_pauimgr->GetPane( cc ).IsOk() )
2022 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2024 cc->SetSize( 0, 0, cccw, ccch );
2032 cc = g_canvasArray.Item(1);
2034 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2035 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2037 ccw = wxMin(ccw, cccw * 8 / 10);
2038 ccw = wxMax(ccw, cccw * 2 / 10);
2042 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2049 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2050 g_pauimgr->GetPane(cc).Fixed();
2051 g_pauimgr->Update();
2054 g_pauimgr->GetPane(cc).Resizable();
2066void MyFrame::OnIconize(wxIconizeEvent &event) {
2068 if (g_MainToolbar) {
2069 g_MainToolbar->Show(!event.IsIconized());
2071 if (g_iENCToolbar) {
2072 g_iENCToolbar->Show(!event.IsIconized());
2076 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2078 if (cc && cc->GetMUIBar()) {
2079 if (cc->GetMUIBar()->GetCanvasOptions()) {
2080 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2081 cc->GetMUIBar()->PushCanvasOptions();
2090void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2092void MyFrame::ODoSetSize(
void) {
2094 GetClientSize(&x, &y);
2097 if (m_pStatusBar != NULL) {
2098 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2099 int currentCount = m_pStatusBar->GetFieldsCount();
2100 if (currentCount != m_StatusBarFieldCount) {
2101 if ((currentCount > 0) && (currentCount < 7)) {
2104 int widths[] = {2, 2, 2, 2, 2, 2};
2105 m_pStatusBar->SetStatusWidths(currentCount, widths);
2108 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2111 if (m_StatusBarFieldCount) {
2116 if (m_StatusBarFieldCount > 2) {
2117 int widths[] = {-6, -5, -5, -6, -4};
2118 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2119 }
else if (m_StatusBarFieldCount == 2) {
2120 int cwidth = x * 90 / 100;
2121 int widths[] = {100, 100};
2122 widths[0] = cwidth * 6.4 / 10.0;
2123 widths[1] = cwidth * 3.6 / 10.0;
2124 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2126 int widths[] = {100, 100};
2127 widths[0] = x * 90 / 100;
2128 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2131 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2132 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2133 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2135 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2136 _T(
" COG ---\u00B0"));
2137 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2145 m_pStatusBar->GetFieldRect(0, stat_box);
2148 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2150 wxFont sys_font = *wxNORMAL_FONT;
2151 int try_font_size = sys_font.GetPointSize();
2154 int min_font_size = 10;
2164 wxFont *statusBarFont =
2165 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2166 int font_size = statusBarFont->GetPointSize();
2168 font_size = wxMin(font_size,
2171 wxMax(font_size, min_font_size);
2174 font_size = statusBarFont->GetPointSize();
2181 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2182 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2184 int min_height = stat_box.height;
2186 m_pStatusBar->SetFont(*pstat_font);
2187 m_pStatusBar->SetForegroundColour(
2188 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2190 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2192 (min_height >> 1) * 2;
2193 m_pStatusBar->SetMinHeight(min_height);
2202 SetCanvasSizes(GetClientSize());
2204 UpdateGPSCompassStatusBoxes(
true);
2206 if (console) PositionConsole();
2209 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2211 if (cc) cc->FormatPianoKeys();
2215 if (g_MainToolbar) {
2216 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2217 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2218 GetPrimaryCanvas()->GetCompass()->GetRect());
2219 g_MainToolbar->Realize();
2221 if (szBefore != g_MainToolbar->GetToolbarSize())
2222 g_MainToolbar->RefreshToolbar();
2231 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2244 options_lastWindowSize = wxSize(0, 0);
2245 options_lastWindowPos = wxPoint(0, 0);
2252 if (!b_inCloseWindow) {
2253 if (g_options) g_options->Raise();
2255 resizeAndroidPersistents();
2260 if (g_pauimgr) g_pauimgr->Update();
2263void MyFrame::PositionConsole(
void) {
2264 if (NULL == GetPrimaryCanvas())
return;
2266 int ccx, ccy, ccsx, ccsy, consx, consy;
2268 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2271 consoleHost->GetSize(&ccsx, &ccsy);
2272 consoleHost->GetPosition(&ccx, &ccy);
2274 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2275 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2276 consoleHost = GetPrimaryCanvas();
2281 if (consoleHost->GetCompass()) {
2282 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2284 if (compass_rect.y < 100)
2285 yOffset = compass_rect.y + compass_rect.height + 45;
2289 console->GetSize(&consx, &consy);
2291 wxPoint screen_pos =
2292 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2293 console->Move(screen_pos);
2296void MyFrame::UpdateAllFonts() {
2298 console->UpdateFonts();
2305 DestroyPersistentDialogs();
2307 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2312void MyFrame::DestroyPersistentDialogs() {
2313 if (g_pais_query_dialog_active) {
2314 g_pais_query_dialog_active->Hide();
2315 g_pais_query_dialog_active->Destroy();
2316 g_pais_query_dialog_active = NULL;
2319 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2320 pRoutePropDialog->Hide();
2321 pRoutePropDialog->Destroy();
2322 pRoutePropDialog = NULL;
2325 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2326 pTrackPropDialog->Hide();
2327 pTrackPropDialog->Destroy();
2328 pTrackPropDialog = NULL;
2331 if (g_pMarkInfoDialog) {
2332 g_pMarkInfoDialog->Hide();
2333 g_pMarkInfoDialog->Destroy();
2334 g_pMarkInfoDialog = NULL;
2337 if (g_pObjectQueryDialog) {
2338 g_pObjectQueryDialog->Hide();
2339 g_pObjectQueryDialog->Destroy();
2340 g_pObjectQueryDialog = NULL;
2344void MyFrame::RefreshGroupIndices(
void) {
2346 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2348 if (cc) cc->canvasRefreshGroupIndex();
2352void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2353 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2355 switch (event.GetId()) {
2356 case ID_MENU_SCALE_OUT:
2357 DoStackDelta(GetPrimaryCanvas(), 1);
2361 case ID_MENU_SCALE_IN:
2362 DoStackDelta(GetPrimaryCanvas(), -1);
2366 case ID_MENU_ZOOM_IN: {
2367 if (GetFocusCanvas()) {
2368 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2373 case ID_MENU_ZOOM_OUT: {
2374 if (GetFocusCanvas()) {
2375 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2380 case ID_MENU_ROUTE_NEW: {
2381 if (GetFocusCanvas()) {
2382 if (0 == GetFocusCanvas()->m_routeState) {
2383 GetFocusCanvas()->StartRoute();
2385 GetFocusCanvas()->FinishRoute();
2391 case ID_MENU_TOOL_MEASURE: {
2392 GetPrimaryCanvas()->StartMeasureRoute();
2396 case ID_MENU_TOOL_NMEA_DBG_LOG:
2397 m_data_monitor->Show();
2400 case ID_MENU_TOOL_IO_MONITOR:
2401 m_data_monitor->Show();
2404 case ID_MENU_MARK_BOAT: {
2409 case ID_MENU_MARK_CURSOR: {
2414 case ID_MENU_NAV_FOLLOW: {
2415 if (gFrame->GetPrimaryCanvas())
2416 gFrame->GetPrimaryCanvas()->TogglebFollow();
2420 case ID_MENU_CHART_OUTLINES: {
2421 ToggleChartOutlines(GetFocusCanvas());
2425 case ID_MENU_CHART_QUILTING: {
2426 ToggleQuiltMode(GetFocusCanvas());
2430 case ID_MENU_UI_CHARTBAR: {
2431 ToggleChartBar(GetFocusCanvas());
2435 case ID_MENU_ENC_TEXT:
2437 ToggleENCText(GetFocusCanvas());
2440 case ID_MENU_ENC_LIGHTS: {
2441 ToggleLights(GetFocusCanvas());
2444 case ID_MENU_ENC_SOUNDINGS: {
2445 ToggleSoundings(GetFocusCanvas());
2448 case ID_MENU_ENC_ANCHOR: {
2449 ToggleAnchor(GetFocusCanvas());
2452 case ID_MENU_ENC_DATA_QUALITY: {
2453 ToggleDataQuality(GetFocusCanvas());
2456 case ID_MENU_SHOW_NAVOBJECTS: {
2457 ToggleNavobjects(GetFocusCanvas());
2461 case ID_MENU_AIS_TARGETS: {
2462 ToggleAISDisplay(GetFocusCanvas());
2465 case ID_MENU_AIS_MOORED_TARGETS: {
2466 g_bHideMoored = !g_bHideMoored;
2469 case ID_MENU_AIS_SCALED_TARGETS: {
2470 ToggleAISMinimizeTargets(GetFocusCanvas());
2474 case ID_MENU_AIS_TARGETLIST: {
2475 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2479 case ID_MENU_AIS_TRACKS: {
2480 g_bAISShowTracks = !g_bAISShowTracks;
2481 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2485 case ID_MENU_AIS_CPADIALOG: {
2486 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2487 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2488 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2489 if (g_bAIS_CPA_Alert) {
2490 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2495 case ID_MENU_AIS_CPASOUND: {
2496 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2497 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2501 case ID_MENU_AIS_CPAWARNING: {
2502 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2503 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2507 case wxID_PREFERENCES:
2509 g_MainToolbar->HideTooltip();
2514 case ID_SETTINGS_NEW: {
2519 case ID_SETTINGS_DELETE: {
2521 g_options =
nullptr;
2525 case ID_MENU_SETTINGS_BASIC: {
2528 androidDisableFullScreen();
2529 g_MainToolbar->HideTooltip();
2530 DoAndroidPreferences();
2537 case ID_MENU_UI_FULLSCREEN: {
2542 case ID_MENU_SHOW_CURRENTS: {
2543 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2544 GetFocusCanvas()->ReloadVP();
2545 GetFocusCanvas()->Refresh(
false);
2549 case ID_MENU_SHOW_TIDES: {
2550 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2551 GetFocusCanvas()->ReloadVP();
2552 GetFocusCanvas()->Refresh(
false);
2558 g_Platform->DoHelpDialog();
2563 g_Platform->LaunchLocalHelp();
2572 case ID_MENU_UI_COLSCHEME:
2573 case ID_COLSCHEME: {
2574 ToggleColorScheme();
2583 case ID_MENU_OQUIT: {
2588 case ID_MENU_ROUTE_MANAGER:
2589 case ID_ROUTEMANAGER: {
2590 pRouteManagerDialog = RouteManagerDialog::getInstance(
2593 if (pRouteManagerDialog->IsShown())
2594 pRouteManagerDialog->Hide();
2596 pRouteManagerDialog->UpdateRouteListCtrl();
2597 pRouteManagerDialog->UpdateTrkListCtrl();
2598 pRouteManagerDialog->UpdateWptListCtrl();
2599 pRouteManagerDialog->UpdateLayListCtrl();
2601 pRouteManagerDialog->Show();
2605 pRouteManagerDialog->Centre();
2606 pRouteManagerDialog->Raise();
2612 case ID_MENU_NAV_TRACK:
2614 if (!g_bTrackActive) {
2616 g_bTrackCarryOver =
true;
2619 if (pConfig && pConfig->IsChangesFileDirty()) {
2620 pConfig->UpdateNavObj(
true);
2622 g_bTrackCarryOver =
false;
2623 RefreshAllCanvas(
true);
2628 case ID_MENU_CHART_NORTHUP: {
2629 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2632 case ID_MENU_CHART_COGUP: {
2633 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2636 case ID_MENU_CHART_HEADUP: {
2637 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2641 case ID_MENU_MARK_MOB:
2647 case ID_MASTERTOGGLE: {
2648 if (g_MainToolbar) {
2649 wxString tip = _(
"Show Toolbar");
2650 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2651 if (g_MainToolbar->GetToolbar())
2652 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2654 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2657 if (g_bmasterToolbarFull)
2658 m_nMasterToolCountShown =
2659 g_MainToolbar->GetToolCount() -
2662 m_nMasterToolCountShown = 2;
2664 m_nMasterToolCountShown =
2665 g_MainToolbar->GetToolShowCount();
2667 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2675 case ID_CMD_SELECT_CHART_TYPE: {
2676 selectChartDisplay(event.GetExtraLong(), -1);
2680 case ID_CMD_SELECT_CHART_FAMILY: {
2681 selectChartDisplay(-1, event.GetExtraLong());
2685 case ID_CMD_APPLY_SETTINGS: {
2686 applySettingsString(event.GetString());
2688 androidRestoreFullScreen();
2694 case ID_CMD_NULL_REFRESH: {
2699 case ID_CMD_SETVP: {
2700 setStringVP(event.GetString());
2704 case ID_CMD_INVALIDATE: {
2710 case ID_CMD_POST_JSON_TO_PLUGINS: {
2716 int numErrors = reader.
Parse(event.GetString(), &root);
2717 if (numErrors == 0) {
2718 if (root[_T(
"MessageID")].IsString()) {
2719 wxString MsgID = root[_T(
"MessageID")].
AsString();
2730 if (g_iENCToolbar) {
2731 g_iENCToolbar->OnToolLeftClick(event);
2741 g_MainToolbar->HideTooltip();
2743 ArrayOfPlugInToolbarTools tool_array =
2744 g_pi_manager->GetPluginToolbarToolArray();
2745 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2747 if (event.GetId() == pttc->id) {
2748 if (pttc->m_pplugin)
2767 if (g_MainToolbar) g_MainToolbar->Realize();
2770bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2771 bool viz_now = g_bmasterToolbarFull;
2773 g_MainToolbar->HideTooltip();
2774 wxString tip = _(
"Show Toolbar");
2776 tip = _(
"Hide Toolbar");
2777 if (g_MainToolbar->GetToolbar())
2778 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2781 bool toggle =
false;
2782 if (viz && !g_bmasterToolbarFull)
2785 else if (!viz && g_bmasterToolbarFull)
2789 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2792 if (g_bmasterToolbarFull)
2793 m_nMasterToolCountShown =
2794 g_MainToolbar->GetToolCount() -
2797 m_nMasterToolCountShown = 2;
2799 m_nMasterToolCountShown =
2800 g_MainToolbar->GetToolShowCount();
2802 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2808void MyFrame::ScheduleDeleteSettingsDialog() {
2809 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2810 evt.SetId(ID_SETTINGS_DELETE);
2811 GetEventHandler()->AddPendingEvent(evt);
2814void MyFrame::ScheduleSettingsDialog() {
2815 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2816 evt.SetId(ID_SETTINGS);
2817 GetEventHandler()->AddPendingEvent(evt);
2820void MyFrame::ScheduleSettingsDialogNew() {
2821 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2822 evt.SetId(ID_SETTINGS_NEW);
2823 GetEventHandler()->AddPendingEvent(evt);
2826void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2827 UpdateCanvasConfigDescriptors();
2829 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2830 CreateCanvasLayout(
true);
2832 CreateCanvasLayout();
2834 g_pauimgr->Update();
2836 ConfigureStatusBar();
2837 wxSize lastOptSize = options_lastWindowSize;
2842 options_lastWindowSize = lastOptSize;
2846 ScheduleSettingsDialogNew();
2848 ScheduleSettingsDialog();
2853 if ((g_canvasConfig != 0) && g_focusCanvas)
2854 return g_focusCanvas;
2856 return GetPrimaryCanvas();
2859void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2860 if (g_bmasterToolbarFull) {
2861#ifndef OCPN_TOOLBAR_ANIMATE
2862 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
2865 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
2866 m_nMasterToolCountShown++;
2867 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2868 g_MainToolbar->Realize();
2869 g_MainToolbar->RefreshToolbar();
2871 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2873 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2874 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2875 g_MainToolbar->Realize();
2876 g_MainToolbar->RefreshToolbar();
2879#ifndef OCPN_TOOLBAR_ANIMATE
2880 m_nMasterToolCountShown = 1;
2882 if (m_nMasterToolCountShown > 1) {
2883 m_nMasterToolCountShown--;
2884 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2885 g_MainToolbar->Realize();
2886 g_MainToolbar->RefreshToolbar();
2887 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2889 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2890 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2891 g_MainToolbar->Realize();
2892 g_MainToolbar->RefreshToolbar();
2897void MyFrame::InvalidateAllGL() {
2900 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2910void MyFrame::RefreshAllCanvas(
bool bErase) {
2912 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2915 cc->Refresh(bErase);
2920void MyFrame::setStringVP(wxString VPS) {
2925 wxStringTokenizer tkz(VPS, _T(
";"));
2927 wxString token = tkz.GetNextToken();
2929 token.ToDouble(&lat);
2931 token = tkz.GetNextToken();
2933 token.ToDouble(&lon);
2935 token = tkz.GetNextToken();
2937 token.ToDouble(&scale_ppm);
2939 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2942void MyFrame::DoSettingsNew() {
2944 g_options =
nullptr;
2949void MyFrame::DoSettings() {
2953 ApplyGlobalSettings(
true);
2956 bool b_loadHarmonics =
false;
2957 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2960 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2963 if (b_loadHarmonics) LoadHarmonics();
2971 g_bShowChartBar = !g_bShowChartBar;
2973 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2978 if (g_bShowChartBar) {
2980 UpdateControlBar(cc);
2983 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2986void MyFrame::ToggleColorScheme() {
2987 static bool lastIsNight;
2988 ColorScheme s = GetColorScheme();
2991 if (lastIsNight && is == 3)
2994 lastIsNight =
false;
2996 if (lastIsNight) is = 2;
2997 if (is == 3) lastIsNight =
true;
2998 s = (ColorScheme)is;
2999 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3001 SetAndApplyColorScheme(s);
3004void MyFrame::ToggleFullScreen() {
3005 bool to = !IsFullScreen();
3010 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3012 ShowFullScreen(to, style);
3015 UpdateAllToolbars(global_color_scheme);
3017 UpdateControlBar(GetPrimaryCanvas());
3019 TriggerRecaptureTimer();
3022void MyFrame::ActivateMOB(
void) {
3024 wxDateTime mob_time = wxDateTime::Now();
3025 wxString mob_label(_(
"MAN OVERBOARD"));
3026 mob_label += _(
" on ");
3027 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3030 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3031 pWP_MOB->SetShared(
true);
3033 pWP_MOB->SetWaypointArrivalRadius(
3035 pWP_MOB->SetUseSca(
false);
3036 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3037 pConfig->AddNewWayPoint(pWP_MOB, -1);
3039 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3042 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3045 new RoutePoint(zlat, zlon, g_default_wp_icon,
3046 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3047 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3050 pRouteList->Append(temp_route);
3052 temp_route->AddPoint(pWP_src);
3053 temp_route->AddPoint(pWP_MOB);
3055 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3058 temp_route->m_RouteNameString = _(
"Temporary MOB Route");
3059 temp_route->m_RouteStartString = _(
"Assumed 1 Mile Point");
3061 temp_route->m_RouteEndString = mob_label;
3063 temp_route->m_bDeleteOnArrival =
false;
3065 temp_route->SetRouteArrivalRadius(-1.0);
3067 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3071 v[_T(
"GUID")] = temp_route->m_GUID;
3072 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
3073 SendJSONMessageToAllPlugins(msg_id, v);
3076 if (RouteManagerDialog::getInstanceFlag()) {
3077 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3078 pRouteManagerDialog->UpdateRouteListCtrl();
3079 pRouteManagerDialog->UpdateWptListCtrl();
3084 RefreshAllCanvas(
false);
3086 wxString mob_message(_(
"MAN OVERBOARD"));
3087 mob_message += _(
" Time: ");
3088 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3089 mob_message += _(
" Position: ");
3090 mob_message += toSDMM(1, gLat);
3091 mob_message += _T(
" ");
3092 mob_message += toSDMM(2, gLon);
3093 wxLogMessage(mob_message);
3095void MyFrame::TrackOn(
void) {
3096 g_bTrackActive =
true;
3099 g_TrackList.push_back(g_pActiveTrack);
3100 if (pConfig) pConfig->AddNewTrack(g_pActiveTrack);
3102 g_pActiveTrack->Start();
3105 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3107 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3109 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3112 androidSetTrackTool(
true);
3115 if (RouteManagerDialog::getInstanceFlag()) {
3116 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3117 pRouteManagerDialog->UpdateTrkListCtrl();
3118 pRouteManagerDialog->UpdateRouteListCtrl();
3123 wxString name = g_pActiveTrack->GetName();
3124 if (name.IsEmpty()) {
3125 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3130 name = _(
"(Unnamed Track)");
3132 v[_T(
"Name")] = name;
3133 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3134 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3135 SendJSONMessageToAllPlugins(msg_id, v);
3136 g_FlushNavobjChangesTimeout =
3140Track *MyFrame::TrackOff(
bool do_add_point) {
3141 Track *return_val = g_pActiveTrack;
3143 if (g_pActiveTrack) {
3145 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3146 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3147 SendJSONMessageToAllPlugins(msg_id, v);
3149 g_pActiveTrack->Stop(do_add_point);
3151 if (g_pActiveTrack->GetnPoints() < 2) {
3152 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3155 if (g_bTrackDaily) {
3156 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3158 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3159 return_val = pExtendTrack;
3163 g_pActiveTrack = NULL;
3166 g_bTrackActive =
false;
3168 if (RouteManagerDialog::getInstanceFlag()) {
3169 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3170 pRouteManagerDialog->UpdateTrkListCtrl();
3171 pRouteManagerDialog->UpdateRouteListCtrl();
3175 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3177 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3178 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3181 androidSetTrackTool(
false);
3184 g_FlushNavobjChangesTimeout =
3190bool MyFrame::ShouldRestartTrack(
void) {
3191 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3192 time_t now = wxDateTime::Now().GetTicks();
3193 time_t today = wxDateTime::Today().GetTicks();
3195 switch (g_track_rotate_time_type) {
3197 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3199 case TIME_TYPE_COMPUTER:
3200 rotate_at = g_track_rotate_time;
3204 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3205 rotate_at = g_track_rotate_time + utc_offset;
3208 if (rotate_at > 86400)
3210 else if (rotate_at < 0)
3212 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3213 now - today >= rotate_at) {
3214 if (m_last_track_rotation_ts == 0) {
3215 if (now - today > rotate_at)
3216 m_last_track_rotation_ts = today + rotate_at;
3218 m_last_track_rotation_ts = today + rotate_at - 86400;
3221 m_last_track_rotation_ts = now;
3227void MyFrame::TrackDailyRestart(
void) {
3228 if (!g_pActiveTrack)
return;
3230 Track *pPreviousTrack = TrackOff(
true);
3231 if (pConfig && pConfig->IsChangesFileDirty()) {
3232 pConfig->UpdateNavObj(
true);
3241 if (pPreviousTrack) {
3242 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3243 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3246 if (RouteManagerDialog::getInstanceFlag()) {
3247 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3248 pRouteManagerDialog->UpdateTrkListCtrl();
3249 pRouteManagerDialog->UpdateRouteListCtrl();
3254void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3256 cc->SetUpMode(mode);
3258 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3259 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3260 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3263 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3268 cc->SetShowENCText(!cc->GetShowENCText());
3270 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3278void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3281 cc->SetENCDisplayCategory(nset);
3283 UpdateGlobalMenuItems();
3294 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3296 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3305 cc->SetShowENCLights(!cc->GetShowENCLights());
3307 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3309 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3317void MyFrame::ToggleRocks(
void )
3323 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3324 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3325 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3326 pOLE->nViz = !pOLE->nViz;
3330 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3331 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3332 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3335 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3339 ps52plib->GenerateStateHash();
3346 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3348 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3350 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3356 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3358 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3360 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3373 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3374 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3379 cc->SetShowAIS(!cc->GetShowAIS());
3380 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3384void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3385 cc->SetAttenAIS(!cc->GetAttenAIS());
3386 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3392 cc->m_bFollow =
true;
3395 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3399 SetChartUpdatePeriod();
3407 cc->m_bFollow =
false;
3409 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3413 SetChartUpdatePeriod();
3416void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3417 cc->SetShowOutlines(!cc->GetShowOutlines());
3419 RefreshAllCanvas(
false);
3423 if (g_bopengl) InvalidateAllGL();
3426 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3429void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3431void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3433 bool enabled = m_pMenuBar->IsEnabled(item_id);
3434 m_pMenuBar->Enable(item_id,
false);
3435 m_pMenuBar->Check(item_id, state);
3436 m_pMenuBar->Enable(item_id, enabled);
3440void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3441 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3442 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3443 g_MainToolbar->Realize();
3447void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3448 wxBitmap *bmpRollover) {
3449 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3450 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3451 g_MainToolbar->Realize();
3455void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3456 wxString rolloverSVGfile,
3457 wxString toggledSVGfile) {
3458 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3459 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3460 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3464void MyFrame::ConfigureStatusBar() {
3466 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3469 UseNativeStatusBar(
false);
3472 if (g_bShowStatusBar) {
3473 if (!m_pStatusBar) {
3475 CreateStatusBar(m_StatusBarFieldCount, 0);
3476 ApplyGlobalColorSchemetoStatusBar();
3481 m_pStatusBar->Destroy();
3482 m_pStatusBar = NULL;
3488void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3489 ConfigureStatusBar();
3491 wxSize lastOptSize = options_lastWindowSize;
3497 options_lastWindowSize = lastOptSize;
3499 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3502wxString _menuText(wxString name, wxString shortcut) {
3506 menutext << _T(
"\t") << shortcut;
3511void MyFrame::BuildMenuBar(
void) {
3517 bool showMenuBar =
true;
3519 bool showMenuBar = g_bShowMenuBar;
3531 m_pMenuBar =
new wxMenuBar();
3532 RegisterGlobalMenuItems();
3533 SetMenuBar(m_pMenuBar);
3537 UpdateGlobalMenuItems();
3542 m_pMenuBar->Destroy();
3548void MyFrame::RegisterGlobalMenuItems() {
3549 if (!m_pMenuBar)
return;
3551 wxMenu *nav_menu =
new wxMenu();
3552 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3553 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3554 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3555 nav_menu->AppendSeparator();
3556 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3557 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3558 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3559 nav_menu->AppendSeparator();
3561 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3562 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3564 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3565 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3567 nav_menu->AppendSeparator();
3568 nav_menu->Append(ID_MENU_SCALE_IN,
3569 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3570 nav_menu->Append(ID_MENU_SCALE_OUT,
3571 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3573 nav_menu->AppendSeparator();
3574 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3576 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3578 wxMenu *view_menu =
new wxMenu();
3580 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3581 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3582 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3583 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3585 view_menu->AppendCheckItem(
3586 ID_MENU_CHART_QUILTING,
3587 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3588 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3589 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3591 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3592 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3594 view_menu->AppendSeparator();
3596 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3597 _menuText(_(
"Show ENC text"), _T(
"T")));
3598 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3599 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3600 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3601 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3602 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3603 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3604 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3605 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3606 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3607 _menuText(_(
"Show Navobjects"), _T(
"V")));
3609 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3610 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3611 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3612 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3613 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3614 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3615 view_menu->AppendCheckItem(
3616 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3617 view_menu->AppendCheckItem(
3618 ID_MENU_ENC_DATA_QUALITY,
3619 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3620 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3621 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3623 view_menu->AppendSeparator();
3624 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3625 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3626 view_menu->AppendSeparator();
3628 view_menu->Append(ID_MENU_UI_COLSCHEME,
3629 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3631 view_menu->Append(ID_MENU_UI_COLSCHEME,
3632 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3635 view_menu->AppendSeparator();
3637 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3638 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3640 m_pMenuBar->Append(view_menu, _(
"&View"));
3642 wxMenu *ais_menu =
new wxMenu();
3643 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3644 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3645 _(
"Attenuate less critical AIS targets"));
3646 ais_menu->AppendSeparator();
3647 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3648 _(
"Hide Moored AIS Targets"));
3649 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3650 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3651 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3655 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3657 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3658 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3661 ais_menu->AppendSeparator();
3662 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3663 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3665 wxMenu *tools_menu =
new wxMenu();
3666 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3667 _menuText(_(
"Data Monitor"),
"Alt-C"));
3669 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3670 _menuText(_(
"Measure Distance"), _T(
"M")));
3672 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3673 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3676 tools_menu->AppendSeparator();
3677 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3678 tools_menu->Append(ID_MENU_ROUTE_NEW,
3679 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3680 tools_menu->AppendSeparator();
3681 tools_menu->Append(ID_MENU_MARK_BOAT,
3682 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3683 tools_menu->Append(ID_MENU_MARK_CURSOR,
3684 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3685 tools_menu->AppendSeparator();
3690 _(
"Drop MOB Marker"),
3691 _T(
"RawCtrl-Space")));
3692 tools_menu->AppendSeparator();
3693 tools_menu->Append(wxID_PREFERENCES,
3694 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3696 tools_menu->Append(ID_MENU_MARK_MOB,
3697 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3698 tools_menu->AppendSeparator();
3699 tools_menu->Append(wxID_PREFERENCES,
3700 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3702 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3705 wxMenu *window_menu =
new wxMenu();
3706 m_pMenuBar->Append(window_menu, _(
"&Window"));
3709 wxMenu *help_menu =
new wxMenu();
3710 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3711 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3712 m_pMenuBar->Append(help_menu, _(
"&Help"));
3715 UpdateGlobalMenuItems();
3718void MyFrame::UpdateGlobalMenuItems() {
3719 if (!m_pMenuBar)
return;
3721 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3722 ->Check(GetPrimaryCanvas()->m_bFollow);
3723 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3724 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3725 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3726 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3727 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3728 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3729 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3730 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3731 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3732 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3733 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3734 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3735 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3736 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3737 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3738 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3739 if (g_bAIS_CPA_Alert) {
3740 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3741 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3744 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3748 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3749 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3752 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3753 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3754 ->Check(ps52plib->GetShowSoundings());
3756 bool light_state =
false;
3758 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3760 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3761 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3762 light_state = (pOLE->nViz == 1);
3767 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3768 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3772 DisCat nset = ps52plib->GetDisplayCategory();
3773 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3774 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3775 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3776 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3777 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3778 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3779 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3781 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3782 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3783 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3788void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3789 if (!m_pMenuBar)
return;
3791 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3793 if (cc->GetUpMode() == NORTH_UP_MODE)
3794 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3795 else if (cc->GetUpMode() == COURSE_UP_MODE)
3796 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3798 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3800 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3801 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3802 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3803 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3804 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3805 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3806 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3807 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3808 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3809 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3810 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3811 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3812 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3813 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3814 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3817 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3818 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3821 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3823 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3824 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3829 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3833 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3834 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3835 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3836 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3837 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3838 ->Check(cc->GetShowENCDataQual());
3839 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3841 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3842 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3843 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3848void MyFrame::InvalidateAllCanvasUndo() {
3850 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3852 if (cc) cc->undo->InvalidateUndo();
3856void MyFrame::SubmergeAllCanvasToolbars(
void) {
3858 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3860 if (cc) cc->SubmergeToolbar();
3864void MyFrame::SurfaceAllCanvasToolbars(
void) {
3865 if (g_bshowToolbar) {
3867 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3869 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3876void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3878 if (lon > 180.0) lon -= 360.0;
3883 cc->JumpToPosition(lat, lon,
scale);
3886 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3890void MyFrame::UpdateCanvasConfigDescriptors() {
3892 for (
unsigned int i = 0;
3893 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3894 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3902 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3903 cc->GroupID = chart->m_groupIndex;
3906 cc->
bQuilt = chart->GetQuiltMode();
3913 cc->
bFollow = chart->m_bFollow;
3918 int upmode = chart->GetUpMode();
3919 if (upmode == COURSE_UP_MODE)
3921 else if (upmode == HEAD_UP_MODE)
3928void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3929 if (!RBBox.GetValid())
return;
3931 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3932 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3935 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3936 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3944 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3945 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3947 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3948 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3950 cc->GetSize(&ww, &wh);
3952 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3954 ppm = wxMin(ppm, 1.0);
3960void MyFrame::PrepareOptionsClose(
options *settings,
3961 int settings_return_value) {
3963 options_lastPage = settings->lastPage;
3968 if (options_lastPage == 1) options_lastPage = 0;
3970 options_subpage = settings->lastSubPage;
3971 options_lastWindowPos = settings->lastWindowPos;
3972 options_lastWindowSize = settings->lastWindowSize;
3975 androidEnableBackButton(
true);
3976 androidEnableOptionsMenu(
true);
3977 androidRestoreFullScreen();
3978 androidEnableRotation();
3987 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3990 int index_hint = -1;
3991 if (i < pathArray.GetCount())
3992 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
3993 cc->canvasChartsRefresh(index_hint);
3994 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
4001void MyFrame::DoOptionsDialog() {
4002 if (NULL == g_options) {
4003 AbstractPlatform::ShowBusySpinner();
4006 pConfig->SetPath(
"/Settings");
4007 pConfig->Read(
"OptionsSizeX", &sx, -1);
4008 pConfig->Read(
"OptionsSizeY", &sy, -1);
4010 wxWindow *optionsParent =
this;
4012 optionsParent = GetPrimaryCanvas();
4014 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4017 AbstractPlatform::HideBusySpinner();
4021 g_options->SetInitChartDir(*pInit_Chart_Dir);
4024 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
4025 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4026 g_options->SetWorkDirListPtr(pWorkDirArray);
4029 g_options->SetConfigPtr(pConfig);
4030 g_options->SetInitialSettings();
4032 prev_locale = g_locale;
4033 g_options->SetInitialPage(options_lastPage, options_subpage);
4036 g_options->lastWindowPos = options_lastWindowPos;
4037 if (options_lastWindowPos != wxPoint(0, 0)) {
4038 g_options->Move(options_lastWindowPos);
4039 g_options->SetSize(options_lastWindowSize);
4041 g_options->CenterOnScreen();
4043 if (options_lastWindowSize != wxSize(0, 0)) {
4044 g_options->SetSize(options_lastWindowSize);
4049 androidEnableBackButton(
false);
4050 androidEnableOptionsMenu(
false);
4051 androidDisableFullScreen();
4058 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4061 wxString chart_file_name;
4062 if (cc->GetQuiltMode()) {
4063 int dbi = cc->GetQuiltRefChartdbIndex();
4064 chart_file_name = ChartData->GetDBChartFileName(dbi);
4066 if (cc->m_singleChart)
4067 chart_file_name = cc->m_singleChart->GetFullPath();
4070 pathArray.Add(chart_file_name);
4076 last_canvasConfig = g_canvasConfig;
4079 g_last_ChartScaleFactor = g_ChartScaleFactor;
4085void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4086 bool b_need_refresh =
false;
4088 if ((rr & VISIT_CHARTS) &&
4089 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4091 UpdateChartDatabaseInplace(*pNewDirArray,
4092 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4095 b_need_refresh =
true;
4099 if (rr & STYLE_CHANGED) {
4102 _(
"Please restart OpenCPN to activate language or style changes."),
4103 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4106 bool b_groupchange =
false;
4107 if (((rr & VISIT_CHARTS) &&
4108 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4109 (rr & GROUPS_CHANGED)) {
4110 b_groupchange = ScrubGroupArray();
4111 ChartData->ApplyGroupArray(g_pGroupArray);
4112 RefreshGroupIndices();
4115 if (rr & GROUPS_CHANGED || b_groupchange) {
4116 pConfig->DestroyConfigGroups();
4117 pConfig->CreateConfigGroups(g_pGroupArray);
4120 if (rr & TIDES_CHANGED) {
4126 if (rr & S52_CHANGED) {
4127 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4130 pConfig->UpdateSettings();
4132 if (g_pActiveTrack) {
4133 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4137 g_pRouteMan->SetColorScheme(global_color_scheme,
4138 g_Platform->GetDisplayDPmm());
4141 double stuffcog = NAN;
4142 double stuffsog = NAN;
4143 if (!std::isnan(gCog)) stuffcog = gCog;
4144 if (!std::isnan(gSog)) stuffsog = gSog;
4146 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4147 COGFilterTable[i] = stuffcog;
4148 SOGFilterTable[i] = stuffsog;
4151 SetChartUpdatePeriod();
4153 if (rr & GL_CHANGED) {
4157 b_need_refresh =
true;
4160 if (rr & S52_CHANGED) {
4161 b_need_refresh =
true;
4165 if (rr & REBUILD_RASTER_CACHE) {
4166 if (g_glTextureManager) {
4167 GetPrimaryCanvas()->Disable();
4168 g_glTextureManager->BuildCompressedCache();
4169 GetPrimaryCanvas()->Enable();
4174 if (g_config_display_size_manual &&
4175 g_config_display_size_mm.size() > g_current_monitor &&
4176 g_config_display_size_mm[g_current_monitor] > 0) {
4177 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4182 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4188 g_pi_manager->SendBaseConfigToAllPlugIns();
4189 int rrt = rr & S52_CHANGED;
4190 g_pi_manager->SendS52ConfigToAllPlugIns(
4191 (rrt == S52_CHANGED) ||
4192 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4195 if (g_MainToolbar) {
4196 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4197 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4202 ps52plib->SetScaleFactorExp(
4203 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4204 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4208 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4210 if (cc) cc->ApplyGlobalSettings();
4217 int index_hint = ChartData->FinddbIndex( chart_file_name );
4218 if( -1 == index_hint )
4226 bool ztc = g_bEnableZoomToCursor;
4227 g_bEnableZoomToCursor =
4232 g_bEnableZoomToCursor = ztc;
4235 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4236 if (g_pMarkInfoDialog) {
4237 g_pMarkInfoDialog->Hide();
4238 g_pMarkInfoDialog->Destroy();
4239 g_pMarkInfoDialog = NULL;
4244 SetGPSCompassScale();
4246 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4249 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4250 cc->UpdateCanvasControlBar();
4253 UpdateGPSCompassStatusBoxes();
4255 SetAllToolbarScale();
4256 RequestNewToolbars();
4259 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4262 cc->RebuildCursors();
4267 bool b_masterScaleChange =
false;
4268 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4269 b_masterScaleChange =
true;
4271 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4272 RequestNewMasterToolbar(
true);
4274 bool bMuiChange =
false;
4280 if (b_masterScaleChange || bMuiChange) {
4282 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4285 cc->ProcessNewGUIScale();
4291 if (rr & LOCALE_CHANGED) {
4292 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4294 rr |= NEED_NEW_OPTIONS;
4299 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4303 g_last_ChartScaleFactor = g_ChartScaleFactor;
4308bool MyFrame::CheckGroup(
int igroup) {
4309 if (igroup == 0)
return true;
4311 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4313 if (!pGroup->m_element_array.size())
4316 for (
const auto &elem : pGroup->m_element_array) {
4317 for (
unsigned int ic = 0;
4318 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4320 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4322 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4329bool MyFrame::ScrubGroupArray() {
4334 bool b_change =
false;
4335 unsigned int igroup = 0;
4336 while (igroup < g_pGroupArray->GetCount()) {
4337 bool b_chart_in_element =
false;
4338 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4340 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4341 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4343 for (
unsigned int ic = 0;
4344 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4346 wxString chart_full_path = pcte->GetFullSystemPath();
4348 if (chart_full_path.StartsWith(element_root)) {
4349 b_chart_in_element =
true;
4355 if (!b_chart_in_element) {
4356 wxString test_string = _T(
"GSHH");
4357 if (element_root.Upper().Contains(test_string))
4358 b_chart_in_element =
true;
4361 if (!b_chart_in_element)
4363 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4375void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4377 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4379 if (cc && (cc != ccThis)) cc->Refresh();
4384void MyFrame::ChartsRefresh() {
4385 if (!ChartData)
return;
4387 AbstractPlatform::ShowBusySpinner();
4389 bool b_run = FrameTimer1.IsRunning();
4392 FrameTenHzTimer.Stop();
4395 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4398 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4399 if (cc->GetQuiltMode()) {
4400 currentIndex = cc->GetQuiltReferenceChartIndex();
4402 cc->canvasChartsRefresh(currentIndex);
4406 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4407 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4409 AbstractPlatform::HideBusySpinner();
4412void MyFrame::InvalidateAllQuilts() {
4413 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4416 cc->InvalidateQuilt();
4417 cc->SetQuiltRefChart(-1);
4418 cc->m_singleChart = NULL;
4423bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4425 const wxString &ChartListFileName) {
4426 bool b_run = FrameTimer1.IsRunning();
4428 FrameTenHzTimer.Stop();
4430 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4431 FrameCOGTimer.Stop();
4434 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4437 cc->InvalidateQuilt();
4438 cc->SetQuiltRefChart(-1);
4439 cc->m_singleChart = NULL;
4443 ChartData->PurgeCache();
4449 AbstractPlatform::ShowBusySpinner();
4451 wxGenericProgressDialog *pprog =
nullptr;
4453 wxString longmsg = _(
"OpenCPN Chart Update");
4455 _T(
"..................................................................")
4458 pprog = new wxGenericProgressDialog();
4461 pprog->SetFont(*qFont);
4463 pprog->Create(_("OpenCPN
Chart Update"), longmsg, 100, gFrame,
4464 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4465 wxPD_REMAINING_TIME);
4471 wxLogMessage(_T(" "));
4472 wxLogMessage(_T("Starting chart database Update..."));
4473 wxString gshhg_chart_loc = gWorldMapLocation;
4474 gWorldMapLocation = wxEmptyString;
4477 ChartData->Update(DirArray, b_force, pprog);
4478 ChartData->SaveBinary(ChartListFileName);
4479 wxLogMessage(_T("Finished chart database Update"));
4480 wxLogMessage(_T(" "));
4481 if (gWorldMapLocation.empty()) {
4485 gWorldMapLocation = gDefaultWorldMapLocation;
4486 gshhg_chart_loc = wxEmptyString;
4489 if (gWorldMapLocation != gshhg_chart_loc) {
4491 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4493 if (cc) cc->ResetWorldBackgroundChart();
4496 gshhsCrossesLandReset();
4501 AbstractPlatform::HideBusySpinner();
4503 pConfig->UpdateChartDirs(DirArray);
4506 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4507 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4509 if (b_runCOGTimer) {
4511 int period_ms = 100;
4512 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4513 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4520 cc->ToggleCanvasQuiltMode();
4522 bool cur_mode = cc->GetQuiltMode();
4524 if( !cc->GetQuiltMode() )
4525 cc->SetQuiltMode(
true );
4527 if( cc->GetQuiltMode() ) {
4528 cc->SetQuiltMode(
false );
4529 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4533 if( cur_mode != cc->GetQuiltMode() ){
4539 g_bQuiltEnable = cc->GetQuiltMode();
4543 ps52plib->GenerateStateHash();
4548void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4550void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4552void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4554 cc->DoCanvasStackDelta(direction);
4558void MyFrame::PositionIENCToolbar() {
4560 if (g_iENCToolbar) {
4562 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4564 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4572void MyFrame::OnInitTimer(wxTimerEvent &event) {
4575 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4578 wxLog::FlushActive();
4580 switch (m_iInitCount++) {
4582 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4584 if (g_bInlandEcdis) {
4585 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4586 double range_set = 500.;
4588 range = wxRound(range * 10) / 10.;
4592 else if (range > 2000.)
4594 else if (range > 1600.)
4596 else if (range > 1200.)
4598 else if (range > 800.)
4603 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4607 g_Platform->SetFullscreen(g_bFullscreen);
4610 if (g_NeedDBUpdate > 0) {
4611 RebuildChartDatabase();
4612 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4615 cc->SetGroupIndex(0,
false);
4623 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4624 CHART_FAMILY_RASTER)) {
4627 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4629 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4630 CHART_FAMILY_VECTOR)) {
4633 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4642 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4645 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4647 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4650 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4654 pConfig->LoadNavObjects();
4656 if (!g_AW1GUID.IsEmpty()) {
4657 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4659 if (!g_AW2GUID.IsEmpty()) {
4660 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4665 appendOSDirSlash(&layerdir);
4666 layerdir.Append(_T(
"layers"));
4668 if (wxDir::Exists(layerdir)) {
4670 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4672 wxLogMessage(laymsg);
4673 pConfig->LoadLayers(layerdir);
4681 for (
auto *cp : TheConnectionParams()) {
4684 cp->b_IsSetup = TRUE;
4689 console->SetColorScheme(global_color_scheme);
4693 if (g_pRouteMan->IsAnyRouteActive()) {
4694 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
4701 if (m_initializing)
break;
4702 m_initializing =
true;
4703 AbstractPlatform::ShowBusySpinner();
4705 AbstractPlatform::HideBusySpinner();
4707 RequestNewMasterToolbar();
4710 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4712 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4714 wxString perspective;
4715 pConfig->SetPath(_T (
"/AUI" ));
4716 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4723 bool bno_load =
false;
4725 wxArrayString name_array;
4726 wxStringTokenizer st(perspective, _T(
"|;"));
4727 while (st.HasMoreTokens()) {
4728 wxString s1 = st.GetNextToken();
4729 if (s1.StartsWith(_T(
"name="))) {
4730 wxString sc = s1.AfterFirst(
'=');
4735 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4736 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4737 wxAuiPaneInfo pane = pane_array_val.Item(i);
4741 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4747 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4751 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4754 g_pauimgr->GetPane(cc).MinSize(10,10);
4761 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4764 wxSize frameSize = GetClientSize();
4765 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4766 int width = wxMax(minSize.x, frameSize.x / 10);
4767 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4770 g_pauimgr->Update();
4774 g_pi_manager->NotifyAuiPlugIns();
4777 g_pi_manager->ShowDeferredBlacklistMessages();
4779 g_pi_manager->CallLateInit();
4784 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4785 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4787 if (cc) cc->SetFirstAuto(
true);
4790 b_reloadForPlugins =
true;
4797 if (g_MainToolbar) {
4798 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4799 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4805 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4807 cc->RequestNewCanvasToolbar(
true );
4809 if(cc && cc->GetToolbarEnable()){
4810 cc->GetToolbar()->SetAutoHide(g_bAutoHideToolbar);
4811 cc->GetToolbar()->SetAutoHideTimer(g_nAutoHideToolbar);
4821 pConfig->SetPath(
"/Settings");
4822 pConfig->Read(
"OptionsSizeX", &sx, -1);
4823 pConfig->Read(
"OptionsSizeY", &sy, -1);
4825 wxWindow *optionsParent =
this;
4827 optionsParent = GetPrimaryCanvas();
4829 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4832 BuildiENCToolbar(
true);
4839 if (!g_params.empty()) {
4840 for (
size_t n = 0; n < g_params.size(); n++) {
4841 wxString path = g_params[n];
4842 if (::wxFileExists(path)) {
4844 pSet->load_file(path.fn_str());
4847 pSet->LoadAllGPXObjects(
4848 !pSet->IsOpenCPN(), wpt_dups,
4850 LLBBox box = pSet->GetBBox();
4851 if (box.GetValid()) {
4852 CenterView(GetPrimaryCanvas(), box);
4861 InitAppMsgBusListener();
4869 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4871 PositionIENCToolbar();
4873 g_bDeferredInitDone =
true;
4875 GetPrimaryCanvas()->SetFocus();
4876 g_focusCanvas = GetPrimaryCanvas();
4882 if (b_reloadForPlugins) {
4887 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4889 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4893 cc->CheckGroupValid();
4898 androidEnableBackButton(
true);
4899 androidEnableRotation();
4900 androidEnableOptionItems(
true);
4904 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
4913 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
4915 wxLog::FlushActive();
4917 RefreshAllCanvas(
true);
4918 wxGetApp().m_usb_watcher.Start();
4924void MyFrame::InitAppMsgBusListener() {
4925 auto &msgbus = AppMsgBus::GetInstance();
4928 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4929 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4933 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4934 HandleBasicNavMsg(basicnav_msg);
4938 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4939 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4943 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4944 HandleGPSWatchdogMsg(msg);
4951void MyFrame::ReleaseApiListeners() {}
4956 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4957 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4958 server.SetGetRestApiEndpointCb(
4959 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4960 server.open_file_cb = [](
const std::string &path) {
4961 return wxGetApp().OpenFile(path);
4968void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4969 if (msg->gps_watchdog <= 0) {
4970 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4971 bool last_bGPSValid = bGPSValid;
4974 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4975 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4976 bool last_bVelocityValid = bVelocityValid;
4977 bVelocityValid =
false;
4984void MyFrame::CalculateCOGAverage() {
4986 if (!std::isnan(gCog)) {
4987 if (g_COGAvgSec > 0) {
4989 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4992 double sum = 0., count = 0;
4993 for (
int i = 0; i < g_COGAvgSec; i++) {
4994 double adder = COGTable[i];
4995 if (std::isnan(adder))
continue;
4997 if (fabs(adder - g_COGAvg) > 180.) {
4998 if ((adder - g_COGAvg) > 0.)
5011 else if (sum >= 360.)
5020void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5021 m_fixtime = msg->time;
5022 double hdt_data_interval = 0;
5023 double fix_time_interval = 0;
5025 double msgtime = msg->set_time.tv_sec;
5026 double m1 = msg->set_time.tv_nsec / 1e9;
5029 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5030 ((msg->vflag & POS_VALID) == POS_VALID)) {
5033 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5036 fix_time_gt_last = fix_time_gt;
5037 uint64_t fix_time_gt_now =
5038 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5039 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5043 double implied_sog = dist / (fix_time_interval / 3600);
5048 gLat_gt_m1 = gLat_gt;
5049 gLon_gt_m1 = gLon_gt;
5053 fix_time_gt = fix_time_gt_now;
5057 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5058 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5059 gCog_gt_m1 = gCog_gt;
5069 if (!std::isnan(gCog_gt_m1)) {
5071 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5078 if ((fix_time_gt - fix_time_gt_last) > .08) {
5083 if (gCog_gt > gCog_gt_m1) {
5084 if ((gCog_gt - gCog_gt_m1) > 180.)
5089 if ((gCog_gt_m1 - gCog_gt) > 180.)
5094 difft = fabs(gCog_gt - gCog_gt_m1);
5095 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5103 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5104 tentative_cog_rate_gt *= 1e9;
5105 cog_rate_gt = tentative_cog_rate_gt;
5113 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5116static double hdt_avg;
5117 double hdt_norm = gHdt;
5118 if(gHdt > 180) hdt_norm -= 360;
5121 hdt_avg += hdt_norm * 0.1;
5123 if( gHdt < 0) gHdt += 360.;
5126 if (!std::isnan(gHdt)) {
5128 uint64_t hdt_time_gt_last = hdt_time_gt;
5129 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5130 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5133 if (hdt_data_interval > .09) {
5135 gHdt_gt_m1 = gHdt_gt;
5138 if (!std::isnan(gHdt_gt_m1)) {
5140 double tentative_hdt_rate_gt =
5141 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5142 tentative_hdt_rate_gt *= 1e9;
5144 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5145 hdt_rate_gt = tentative_hdt_rate_gt;
5153 if (std::isnan(gHdt)) gHdt_gt = NAN;
5156 CalculateCOGAverage();
5163 bool last_bGPSValid = bGPSValid;
5164 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5165 if ((msg->vflag & POS_VALID) == POS_VALID)
5170 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5172 bVelocityValid =
true;
5176void MyFrame::UpdateStatusBar() {
5179 unsigned long uiCurrentTickCount;
5180 m_MMEAeventTime.SetToCurrent();
5181 uiCurrentTickCount =
5182 m_MMEAeventTime.GetMillisecond() / 100;
5183 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5184 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5185 m_ulLastNMEATicktime = uiCurrentTickCount;
5187 if (m_tick_idx++ > 6) m_tick_idx = 0;
5192 if (NULL != GetStatusBar()) {
5195 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5198 wxString s1(tick_buf, wxConvUTF8);
5200 s1 += toSDMM(1, gLat);
5202 s1 += toSDMM(2, gLon);
5204 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5208 if (!std::isnan(gSog))
5209 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5212 sogcog.Printf(_T(
"SOG --- "));
5216 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5218 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5220 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5221 (
int)toMagnetic(gCog), 0x00B0);
5223 cogs.Printf((
"COG ---%c"), 0x00B0);
5225 sogcog.Append(cogs);
5226 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5231void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5232 MemFootTimer.Stop();
5234 int memsize = GetApplicationMemoryUse();
5237 printf(
"Memsize: %d \n", memsize);
5240 if (memsize > (g_MemFootMB * 1000)) {
5242 if (ChartData && cc) {
5244 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5245 unsigned int nCache = pCache->GetCount();
5248 for (
unsigned int i = 0; i < nCache; i++) {
5258 for (
unsigned int i = 0; i < nCache - 1; i++) {
5259 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5261 pcea[i] = pcea[i + 1];
5272 unsigned int idelete = 0;
5273 unsigned int idelete_max = pCache->GetCount();
5276 unsigned int minimum_cache = 1;
5277 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5279 while ((memsize > (g_MemFootMB * 1000)) &&
5280 (pCache->GetCount() > minimum_cache) &&
5281 (idelete < idelete_max)) {
5282 int memsizeb = memsize;
5284 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5286 memsize = GetApplicationMemoryUse();
5287 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5295 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5300void MyFrame::CheckToolbarPosition() {
5303 static bool bMaximized;
5305 if (IsMaximized() && !bMaximized) {
5307 if (g_MainToolbar) {
5308 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5309 g_MainToolbar->SetDefaultPosition();
5310 g_MainToolbar->Realize();
5312 PositionIENCToolbar();
5313 }
else if (!IsMaximized() && bMaximized) {
5315 if (g_MainToolbar) {
5316 g_MainToolbar->SetYAuxOffset(0);
5317 g_MainToolbar->SetDockY(-1);
5318 g_MainToolbar->SetDefaultPosition();
5319 g_MainToolbar->Realize();
5321 PositionIENCToolbar();
5326void MyFrame::ProcessUnitTest() {
5327 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5334 cc->m_bFollow =
false;
5335 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5336 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5337 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5340 if (cc->m_groupIndex > 0) {
5341 while (ut_index < ChartData->GetChartTableEntries() &&
5342 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5346 if (ut_index < ChartData->GetChartTableEntries()) {
5348 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5350 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5351 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5358 if (cc->GetQuiltMode()) {
5359 if (cc->IsChartQuiltableRef(ut_index))
5360 cc->SelectQuiltRefdbChart(ut_index);
5362 cc->SelectdbChart(ut_index);
5365 if (g_unit_test_1) {
5373 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5374 cte->GetLatMin(), cte->GetLonMax(), NULL,
5378 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5379 cte->GetLatMax(), cte->GetLonMin(), NULL,
5382 cc->GetSize(&ww, &wh);
5383 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5385 ppm = wxMin(ppm, 1.0);
5392 if (ut_index > ut_index_max) exit(0);
5401void MyFrame::OnFrameTenHzTimer(wxTimerEvent &event) {
5403 bool b_rotate =
false;
5405 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5408 if (!b_rotate && !g_btenhertz)
return;
5410 bool b_update =
false;
5412 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5415 struct timespec now;
5416 clock_gettime(CLOCK_MONOTONIC, &now);
5417 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5418 double diffc = diff / 1e9;
5421 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5422 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5423 if (gCog_tentative < 0.) gCog_tentative += 360.;
5424 gCog = gCog_tentative;
5428 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5429 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5430 double diffc = diff / 1e9;
5431 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5435 if (gSog_gt && !std::isnan(gCog_gt)) {
5436 double delta_t = diffc / 3600;
5437 double distance = gSog_gt * delta_t;
5440 double angr = gCog_gt / 180 * M_PI;
5441 double latr = gLat_gt * M_PI / 180;
5442 double D = distance / 3443;
5443 double sD = sin(D), cD = cos(D);
5444 double sy = sin(latr), cy = cos(latr);
5445 double sa = sin(angr), ca = cos(angr);
5447 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5448 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5458 if (cc) cc->DoCanvasCOGSet();
5469 if (b_rotate || cc->m_bFollow) {
5470 cc->DoCanvasUpdate();
5479 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5482void MyFrame::ProcessQuitFlag() {
5485 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5487 FrameTenHzTimer.Stop();
5494void MyFrame::ProcessDeferredTrackOn() {
5497 if (g_bDeferredStartTrack) {
5498 if (!g_bTrackActive) {
5501 g_bDeferredStartTrack =
false;
5504 g_bDeferredStartTrack =
false;
5509void MyFrame::ProcessAnchorWatch() {
5512 if (pAnchorWatchPoint1) {
5515 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5516 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5517 double d = g_nAWMax;
5518 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5519 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5520 bool toofar =
false;
5521 bool tooclose =
false;
5522 if (d >= 0.0) toofar = (dist * 1852. > d);
5523 if (d < 0.0) tooclose = (dist * 1852 < -d);
5525 if (tooclose || toofar)
5526 AnchorAlertOn1 =
true;
5528 AnchorAlertOn1 =
false;
5530 AnchorAlertOn1 =
false;
5532 if (pAnchorWatchPoint2) {
5535 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5536 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5538 double d = g_nAWMax;
5539 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5540 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5541 bool toofar =
false;
5542 bool tooclose =
false;
5543 if (d >= 0) toofar = (dist * 1852. > d);
5544 if (d < 0) tooclose = (dist * 1852 < -d);
5546 if (tooclose || toofar)
5547 AnchorAlertOn2 =
true;
5549 AnchorAlertOn2 =
false;
5551 AnchorAlertOn2 =
false;
5553 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5554 AnchorAlertOn1 =
true;
5557void MyFrame::SendFixToPlugins() {
5561 GPSData.
kLat = gLat;
5562 GPSData.
kLon = gLon;
5563 GPSData.
kCog = gCog;
5564 GPSData.
kSog = gSog;
5565 GPSData.
kVar = gVar;
5566 GPSData.
kHdm = gHdm;
5567 GPSData.
kHdt = gHdt;
5568 GPSData.
nSats = g_SatsInView;
5570 wxDateTime tCheck((time_t)m_fixtime);
5571 if (tCheck.IsValid()) {
5580 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5583 SendPositionFixToAllPlugIns(&GPSData);
5587void MyFrame::ProcessLogAndBells() {
5590 wxDateTime lognow = wxDateTime::Now();
5591 int hourLOC = lognow.GetHour();
5592 int minuteLOC = lognow.GetMinute();
5594 int minuteUTC = lognow.GetMinute();
5595 int second = lognow.GetSecond();
5597 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5598 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5599 (minuteUTC == 30)) {
5600 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5601 wxString day = lognow.FormatISODate();
5602 wxString utc = lognow.FormatISOTime();
5603 wxString navmsg = _T(
"LOGBOOK: ");
5607 navmsg += _T(
" UTC ");
5611 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5615 if (std::isnan(gCog))
5616 cog.Printf(_T(
"COG ----- "));
5618 cog.Printf(_T(
"COG %10.5f "), gCog);
5621 if (std::isnan(gSog))
5622 sog.Printf(_T(
"SOG ----- "));
5624 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5630 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5633 wxLogMessage(navmsg);
5634 g_loglast_time = lognow;
5636 int bells = (hourLOC % 4) * 2;
5637 if (minuteLOC != 0) bells++;
5638 if (!bells) bells = 8;
5640 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5641 m_BellsToPlay = bells;
5642 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5643 wxPostEvent(
this, ev);
5649void MyFrame::OnFrameTimer1(wxTimerEvent &event) {
5650 CheckToolbarPosition();
5656 if (bDBUpdateInProgress)
return;
5659 FrameTenHzTimer.Stop();
5661 ProcessDeferredTrackOn();
5663 ProcessAnchorWatch();
5664 ProcessLogAndBells();
5666 if (ShouldRestartTrack()) TrackDailyRestart();
5669 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5670 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5671 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5677 if (gSog > 3.0) g_bCruising =
true;
5683 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5684 _T(
" COG ---\u00B0"));
5685 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5691 bool bnew_view =
false;
5692 if (!g_btenhertz) bnew_view = DoChartUpdate();
5697 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5700 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5703 cc->DrawBlinkObjects();
5706 if (bactiveRouteUpdate) {
5708 if (g_pRouteMan->GetpActiveRoute())
5709 cc->RefreshRect(g_blink_rect,
false);
5713 cc->SetOwnShipState(SHIP_NORMAL);
5715 if (cc->GetQuiltMode()) {
5716 double erf = cc->GetQuiltMaxErrorFactor();
5717 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5719 if (cc->m_singleChart) {
5720 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5721 cc->SetOwnShipState(SHIP_LOWACCURACY);
5725 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5727 if ((bGPSValid != m_last_bGPSValid) ||
5728 (bVelocityValid != m_last_bVelocityValid) ||
5729 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5730 if (!g_bopengl) cc->UpdateShips();
5737 m_last_bGPSValid = bGPSValid;
5738 m_last_bVelocityValid = bVelocityValid;
5743 bool brq_dynamic =
false;
5745 auto *pplugin_array = PluginLoader::getInstance()->GetPlugInArray();
5746 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5748 if (pic->m_enabled && pic->m_init_state) {
5749 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5756 if (brq_dynamic) bnew_view =
true;
5760 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5763 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5768 if (cc->GetglCanvas()) {
5770 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5773 if (cc->m_bFollow) {
5774 cc->DoCanvasUpdate();
5781 if (std::isnan(gCog)) cc->Refresh(
false);
5794 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5808 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5809 g_pais_query_dialog_active->UpdateText();
5812 if (g_pAISTargetList && (0 == (g_tick % (5))))
5813 g_pAISTargetList->UpdateAISTargetList();
5816 UpdateGPSCompassStatusBoxes();
5819 if (console && console->IsShown()) {
5821 console->RefreshConsoleData();
5828 if (m_bdefer_resize) {
5829 if (0 == (g_tick % (5))) {
5830 printf(
"___RESIZE\n");
5831 SetSize(m_defer_size);
5832 g_pauimgr->Update();
5833 m_bdefer_resize =
false;
5841 if (((g_tick % g_FlushNavobjChangesTimeout) == 0) || g_FlushNavobjChanges) {
5842 if (pConfig && pConfig->IsChangesFileDirty()) {
5843 androidShowBusyIcon();
5844 wxStopWatch update_sw;
5845 pConfig->UpdateNavObj(
true);
5846 wxString msg = wxString::Format(
5847 _T(
"OpenCPN periodic navobj update took %ld ms."), update_sw.Time());
5849 qDebug() << msg.mb_str();
5850 g_FlushNavobjChanges =
false;
5851 androidHideBusyIcon();
5860 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5862 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5863 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5867double MyFrame::GetMag(
double a,
double lat,
double lon) {
5868 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5869 auto loader = PluginLoader::getInstance();
5870 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5877 wxDateTime now = wxDateTime::Now();
5878 SendJSON_WMM_Var_Request(lat, lon, now);
5879 if (fabs(gQueryVar) < 360.0)
5880 Variance = gQueryVar;
5882 return toMagnetic(a, Variance);
5885bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5891 v[_T(
"Year")] = date.GetYear();
5892 v[_T(
"Month")] = date.GetMonth();
5893 v[_T(
"Day")] = date.GetDay();
5895 SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
5901void MyFrame::TouchAISActive(
void) {
5903 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5905 if (cc) cc->TouchAISToolActive();
5909void MyFrame::UpdateAISTool(
void) {
5910 if (!g_pAIS)
return;
5913 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5915 if (cc) cc->UpdateAISTBTool();
5920void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5922 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5924 if (cc) cc->SetbTCUpdate(
true);
5927 RefreshAllCanvas(
false);
5932void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5936 bool b_rotate =
false;
5937 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5939 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5943 FrameCOGTimer.Stop();
5950 int period_ms = 100;
5952 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5955void MyFrame::DoCOGSet(
void) {
5957 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5959 if (cc) cc->DoCanvasCOGSet();
5963void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5969 wxFont oldfont = pdc->GetFont();
5971 pdc->SetFont(*pFont);
5972 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
5973 pdc->SetBackgroundMode(wxTRANSPARENT);
5975 pdc->DrawText(str, x, y + 1);
5976 pdc->DrawText(str, x, y - 1);
5977 pdc->DrawText(str, x + 1, y);
5978 pdc->DrawText(str, x - 1, y);
5980 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
5982 pdc->DrawText(str, x, y);
5984 pdc->SetFont(oldfont);
5988void MyFrame::UpdateRotationState(
double rotation) {
5990 g_bCourseUp =
false;
5992 if (fabs(rotation) > .001) {
5993 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5994 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5996 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5999 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
6000 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
6002 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6006 UpdateGPSCompassStatusBoxes(
true);
6010void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6012 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6014 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6020int MyFrame::GetApplicationMemoryUse(
void) {
6026 wxWindow *fWin = wxWindow::FindFocus();
6028 wxArrayString outputArray;
6029 wxString cmd(_T(
"ps --no-headers -o vsize "));
6030 unsigned long pid = wxGetProcessId();
6032 cmd1.Printf(_T(
"%ld"), pid);
6034 wxExecute(cmd, outputArray);
6036 if (outputArray.GetCount()) {
6037 wxString s = outputArray.Item(0);
6039 if (s.ToLong(&vtmp)) memsize = vtmp;
6042 if (fWin) fWin->SetFocus();
6048 PROCESS_MEMORY_COUNTERS pmc;
6050 unsigned long processID = wxGetProcessId();
6052 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6054 if (NULL == hProcess)
return 0;
6056 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6074 memsize = pmc.WorkingSetSize / 1024;
6077 CloseHandle(hProcess);
6084double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6085 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6088void MyFrame::SetChartUpdatePeriod() {
6091 g_ChartUpdatePeriod = 0;
6096 bool bskewdc =
false;
6097 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6100 if (!g_bopengl && !cc->GetVP().b_quilt) {
6101 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6103 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6107 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6109 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6114 cc->UpdateCanvasControlBar();
6117void MyFrame::selectChartDisplay(
int type,
int family) {
6119 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6121 if (cc) cc->selectCanvasChartDisplay(type, family);
6124 UpdateGlobalMenuItems();
6133bool MyFrame::DoChartUpdate(
void) {
6134 bool return_val =
false;
6137 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6139 if (cc) return_val |= cc->DoCanvasUpdate();
6145void MyFrame::MouseEvent(wxMouseEvent &event) {
6147 event.GetPosition(&x, &y);
6152#include <mach/mach.h>
6153#include <mach/message.h>
6154#include <mach/kern_return.h>
6155#include <mach/task_info.h>
6157#include <malloc/malloc.h>
6164#if defined(__linux__)
6165#include "sys/types.h"
6166#include "sys/sysinfo.h"
6169int g_lastMemTick = -1;
6173bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6175 return androidGetMemoryStatus(mem_total, mem_used);
6178#if defined(__linux__)
6182 struct sysinfo sys_info;
6183 if (sysinfo(&sys_info) != -1)
6184 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6198 FILE *file = fopen(
"/proc/self/statm",
"r");
6200 if (fscanf(file,
"%d", mem_used) != 1) {
6201 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6214 PROCESS_MEMORY_COUNTERS pmc;
6216 unsigned long processID = wxGetProcessId();
6219 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6222 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6240 *mem_used = pmc.WorkingSetSize / 1024;
6243 CloseHandle(hProcess);
6247 MEMORYSTATUSEX statex;
6249 statex.dwLength =
sizeof(statex);
6251 GlobalMemoryStatusEx(&statex);
6269 *mem_total = statex.ullTotalPhys / 1024;
6276 if (g_tick != g_lastMemTick) {
6277 malloc_zone_pressure_relief(NULL, 0);
6280 int blocksInUse = 0;
6281 int sizeAllocated = 0;
6283 malloc_statistics_t stats;
6284 stats.blocks_in_use = 0;
6285 stats.size_in_use = 0;
6286 stats.max_size_in_use = 0;
6287 stats.size_allocated = 0;
6288 malloc_zone_statistics(NULL, &stats);
6289 bytesInUse += stats.size_in_use;
6290 blocksInUse += stats.blocks_in_use;
6291 sizeAllocated += stats.size_allocated;
6293 g_memUsed = sizeAllocated >> 10;
6296 g_lastMemTick = g_tick;
6299 if (mem_used) *mem_used = g_memUsed;
6302 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6304 double pagesUsed = 0.0, totalPages = 0.0;
6306 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6307 *mem_total = atol(buf) >> 10;
6315 if (mem_used) *mem_used = 0;
6316 if (mem_total) *mem_total = 0;
6320void MyFrame::DoPrint(
void) {
6322 g_PrintingInProgress =
true;
6325 GetPrimaryCanvas()->GetglCanvas()->Render();
6326 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6336 printer.Initialize(wxLANDSCAPE);
6337 printer.EnablePageNumbers(
false);
6338 printer.Print(
this, &printout);
6356 g_PrintingInProgress =
false;
6359 GetPrimaryCanvas()->SetFocus();
6364wxDateTime gTimeSource;
6367 wxString message_ID =
event.GetID();
6368 wxString message_JSONText =
event.GetJSONText();
6376 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6384 int numErrors = reader.
Parse(message_JSONText, &root);
6385 if (numErrors > 0) {
6391 wxString decl = root[_T(
"Decl")].
AsString();
6393 decl.ToDouble(&decl_val);
6399 if (message_ID == _T(
"WMM_VARIATION")) {
6407 int numErrors = reader.
Parse(message_JSONText, &root);
6408 if (numErrors > 0) {
6414 wxString decl = root[_T(
"Decl")].
AsString();
6416 decl.ToDouble(&decl_val);
6418 gQueryVar = decl_val;
6421 if (message_ID == _T(
"GRIB_TIMELINE")) {
6424 r.
Parse(message_JSONText, &v);
6425 if (v[_T(
"Day")].AsInt() == -1)
6426 gTimeSource = wxInvalidDateTime;
6428 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6429 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6430 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6431 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6433 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6436 wxString trk_id = wxEmptyString;
6438 int numErrors = reader.
Parse(message_JSONText, &root);
6439 if (numErrors > 0)
return;
6442 trk_id = root[_T(
"Track_ID")].
AsString();
6445 v[_T(
"Track_ID")] = trk_id;
6446 for (
Track *ptrack : g_TrackList) {
6447 wxString name = wxEmptyString;
6448 if (ptrack->m_GUID == trk_id) {
6449 name = ptrack->GetName();
6450 if (name.IsEmpty()) {
6456 name = _(
"(Unnamed Track)");
6462 v[_T(
"error")] =
false;
6463 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6464 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6466 v[_T(
"lat")] = tp->m_lat;
6467 v[_T(
"lon")] = tp->m_lon;
6468 v[_T(
"NodeNr")] = i;
6470 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6471 SendJSONMessageToAllPlugins(msg_id, v);
6475 v[_T(
"error")] =
true;
6477 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6478 SendJSONMessageToAllPlugins(msg_id, v);
6480 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6483 wxString guid = wxEmptyString;
6485 int numErrors = reader.
Parse(message_JSONText, &root);
6486 if (numErrors > 0) {
6493 v[_T(
"GUID")] = guid;
6494 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6496 wxString name = wxEmptyString;
6498 if ((*it)->m_GUID == guid) {
6499 name = (*it)->m_RouteNameString;
6500 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6502 v[_T(
"Name")] = name;
6503 v[_T(
"error")] =
false;
6506 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6507 itp != (*it)->pRoutePointList->end(); itp++) {
6508 w[i][_T(
"lat")] = (*itp)->m_lat;
6509 w[i][_T(
"lon")] = (*itp)->m_lon;
6510 w[i][_T(
"Name")] = (*itp)->GetName();
6511 w[i][_T(
"Description")] = (*itp)->GetDescription();
6512 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6513 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6514 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6519 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6521 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6522 httpLink->DescrText;
6523 node = node->GetNext();
6528 v[_T(
"waypoints")] = w;
6529 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6530 SendJSONMessageToAllPlugins(msg_id, v);
6535 v[_T(
"error")] =
true;
6537 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6538 SendJSONMessageToAllPlugins(msg_id, v);
6539 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6544 int numErrors = reader.
Parse(message_JSONText, &root);
6545 if (numErrors > 0)
return;
6548 wxString str = root[_T(
"mode")].
AsString();
6549 if (str == _T(
"Track")) route =
false;
6554 for (RouteList::iterator it = pRouteList->begin();
6555 it != pRouteList->end(); it++) {
6556 wxString name = (*it)->m_RouteNameString;
6557 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6559 v[i][_T(
"error")] =
false;
6560 v[i][_T(
"name")] = name;
6561 v[i][_T(
"GUID")] = (*it)->m_GUID;
6562 v[i][_T(
"active")] = (*it)->IsActive();
6566 for (
Track *ptrack : g_TrackList) {
6567 wxString name = ptrack->GetName();
6568 if (name.IsEmpty()) {
6574 name = _(
"(Unnamed Track)");
6576 v[i][_T(
"error")] =
false;
6577 v[i][_T(
"name")] = name;
6578 v[i][_T(
"GUID")] = ptrack->m_GUID;
6579 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6583 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6584 SendJSONMessageToAllPlugins(msg_id, v);
6587 v[0][_T(
"error")] =
true;
6588 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6589 SendJSONMessageToAllPlugins(msg_id, v);
6591 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6593 v[0][_T(
"error")] =
true;
6594 if (g_pRouteMan->GetpActiveRoute()) {
6595 if (g_pRouteMan->m_bDataValid) {
6596 v[0][_T(
"error")] =
false;
6597 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6598 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6599 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6600 v[0][_T(
"active_route_GUID")] =
6601 g_pRouteMan->GetpActiveRoute()->GetGUID();
6602 v[0][_T(
"active_waypoint_lat")] =
6603 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLatitude();
6604 v[0][_T(
"active_waypoint_lon")] =
6605 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLongitude();
6608 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6609 SendJSONMessageToAllPlugins(msg_id, v);
6613void MyFrame::FilterCogSog(
void) {
6614 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6616 double cog_last = gCog;
6619 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6620 COGFilterTable[i] = COGFilterTable[i - 1];
6621 COGFilterTable[0] = cog_last;
6624 if (!std::isnan(cog_last)) {
6626 double sum = 0., count = 0;
6627 for (
int i = 0; i < g_COGFilterSec; i++) {
6628 double adder = COGFilterTable[i];
6629 if (std::isnan(adder))
continue;
6631 if (fabs(adder - cog_last) > 180.) {
6632 if ((adder - cog_last) > 0.)
6645 else if (sum >= 360.)
6652 double sog_last = gSog;
6655 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6656 SOGFilterTable[i] = SOGFilterTable[i - 1];
6657 SOGFilterTable[0] = sog_last;
6660 if (!std::isnan(gSog)) {
6661 double sum = 0., count = 0;
6662 for (
int i = 0; i < g_SOGFilterSec; i++) {
6663 if (std::isnan(SOGFilterTable[i]))
continue;
6665 sum += SOGFilterTable[i];
6675void MyFrame::LoadHarmonics() {
6678 ptcmgr->LoadDataSources(TideCurrentDataSet);
6680 bool b_newdataset =
false;
6683 for (
auto a : ptcmgr->GetDataSet()) {
6684 bool b_foundi =
false;
6685 for (
auto b : TideCurrentDataSet) {
6692 b_newdataset =
true;
6697 for (
auto a : TideCurrentDataSet) {
6698 bool b_foundi =
false;
6699 for (
auto b : ptcmgr->GetDataSet()) {
6706 b_newdataset =
true;
6711 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6715void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6716 if (!ptarget)
return;
6719 wxDateTime mob_time = wxDateTime::Now();
6720 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6721 mob_label += _(
" on ");
6722 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6725 mob_label, wxEmptyString);
6726 pWP_MOB->SetShared(
true);
6728 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6729 pConfig->AddNewWayPoint(pWP_MOB, -1);
6730 pWP_MOB->SetUseSca(
false);
6738 wxString(_(
"Own ship")), wxEmptyString);
6739 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6740 pWP_MOB->SetUseSca(
false);
6741 pAISMOBRoute =
new Route();
6742 pRouteList->Append(pAISMOBRoute);
6744 pAISMOBRoute->AddPoint(pWP_src);
6745 pAISMOBRoute->AddPoint(pWP_MOB);
6747 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6748 pWP_src, pWP_MOB, pAISMOBRoute);
6750 pAISMOBRoute->m_RouteNameString = _(
"Temporary AISMOB Route");
6751 pAISMOBRoute->m_RouteStartString = _(
"Present own ship");
6752 pAISMOBRoute->m_RouteEndString = mob_label;
6754 pAISMOBRoute->m_bDeleteOnArrival =
false;
6756 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6758 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6762 v[_T(
"GUID")] = pAISMOBRoute->m_GUID;
6763 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6764 SendJSONMessageToAllPlugins(msg_id, v);
6767 if (RouteManagerDialog::getInstanceFlag()) {
6768 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6769 pRouteManagerDialog->UpdateRouteListCtrl();
6770 pRouteManagerDialog->UpdateWptListCtrl();
6774 RefreshAllCanvas(
false);
6776 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6777 mob_message += _(
" Time: ");
6778 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6779 mob_message += _(
" Ownship Position: ");
6780 mob_message += toSDMM(1, gLat);
6781 mob_message += _T(
" ");
6782 mob_message += toSDMM(2, gLon);
6783 mob_message += _(
" MOB Position: ");
6784 mob_message += toSDMM(1, ptarget->Lat);
6785 mob_message += _T(
" ");
6786 mob_message += toSDMM(2, ptarget->Lon);
6787 wxLogMessage(mob_message);
6790void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6791 if (pAISMOBRoute && ptarget) {
6793 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6794 OwnPoint->m_lat = gLat;
6795 OwnPoint->m_lon = gLon;
6797 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6798 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6801 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6802 MOB_Point->m_lat = ptarget->Lat;
6803 MOB_Point->m_lon = ptarget->Lon;
6805 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6806 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6808 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6809 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6812 RefreshAllCanvas(
false);
6815 wxDateTime mob_time = wxDateTime::Now();
6817 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6818 mob_message += _(
" Time: ");
6819 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6820 mob_message += _(
" Ownship Position: ");
6821 mob_message += toSDMM(1, gLat);
6822 mob_message += _T(
" ");
6823 mob_message += toSDMM(2, gLon);
6824 mob_message += _(
" MOB Position: ");
6825 mob_message += toSDMM(1, ptarget->Lat);
6826 mob_message += _T(
" ");
6827 mob_message += toSDMM(2, ptarget->Lon);
6829 wxLogMessage(mob_message);
6833void MyFrame::applySettingsString(wxString settings) {
6835 int last_UIScaleFactor = g_GUIScaleFactor;
6836 bool previous_expert = g_bUIexpert;
6837 g_last_ChartScaleFactor = g_ChartScaleFactor;
6838 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6841 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6844 pConfig->UpdateSettings();
6847 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6849 if (rr & S52_CHANGED) {
6851 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6853 ->ClearCNSYLUPArray();
6854 ps52plib->GenerateStateHash();
6858 ProcessOptionsDialog(rr, pNewDirArray);
6863 bool b_newToolbar =
false;
6865 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6867 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6869 if (rr & TOOLBAR_CHANGED) {
6870 b_newToolbar =
true;
6875 if (previous_expert && !g_bUIexpert) {
6876 androidForceFullRepaint();
6880 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6884 SetGPSCompassScale();
6886 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6888 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6890 UpdateGPSCompassStatusBoxes(
true);
6893 AbstractPlatform::ShowBusySpinner();
6895 SetAllToolbarScale();
6899 AbstractPlatform::HideBusySpinner();
6901 RequestNewMasterToolbar(
true);
6908 UpdateControlBar(GetPrimaryCanvas());
6911 if (console) console->Raise();
6914 if (m_data_monitor->
IsActive()) m_data_monitor->Raise();
6917#ifdef wxHAS_POWER_EVENTS
6918void MyFrame::OnSuspending(wxPowerEvent &event) {
6922 wxLogMessage(_T(
"System suspend starting..."));
6925void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6928 wxLogMessage(_T(
"System is going to suspend."));
6931void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6934 wxLogMessage(_T(
"System suspend was cancelled."));
6937int g_last_resume_ticks;
6938void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6939 wxDateTime now = wxDateTime::Now();
6940 wxLogMessage(_T(
"System resumed from suspend."));
6942 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6945 wxLogMessage(
"Restarting streams.");
6946 g_last_resume_ticks = now.GetTicks();
6950 g_pMUX->ClearStreams();
6952 g_pMUX->StartAllStreams();
6961 if (IsMaximized()) {
6966 wxSize sz = GetSize();
6967 SetSize(wxSize(sz.x - 1, sz.y));
6979void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6980 bool btbRebuild =
false;
6982 bool b_reshow =
true;
6983 if (g_MainToolbar) {
6985 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6986 if ((ff > 0.01f) || bforcenew) {
6987 g_MainToolbar->DestroyToolBar();
6988 delete g_MainToolbar;
6989 g_MainToolbar = NULL;
6995 if (!g_MainToolbar) {
6996 long orient = g_Platform->GetDefaultToolbarOrientation();
6997 wxWindow *toolbarParent =
this;
6999 toolbarParent = GetPrimaryCanvas();
7002 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7003 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
7004 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7005 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7006 g_MainToolbar->EnableRolloverBitmaps(
false);
7008 g_MainToolbar->CreateConfigMenu();
7009 g_MainToolbar->SetDefaultPosition();
7011 g_bmasterToolbarFull =
true;
7014 if (g_MainToolbar) {
7015 CreateMasterToolbar();
7019 g_MainToolbar->SetColorScheme(global_color_scheme);
7025 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7026 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7030bool MyFrame::CollapseGlobalToolbar() {
7031 if (g_MainToolbar) {
7032 m_nMasterToolCountShown = 1;
7033 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7034 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7035 g_MainToolbar->Realize();
7036 g_bmasterToolbarFull =
false;
7045 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7052 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7053 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7054 tic->m_bRequired =
true;
7056 g_MainToolbar->AddToolItem(tic);
7059 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7060 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7061 g_MainToolbar->AddToolItem(tic);
7064 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7065 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7066 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7068 g_MainToolbar->AddToolItem(tic);
7071 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7072 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7073 g_MainToolbar->AddToolItem(tic);
7076 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7077 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7078 _(
"Enable Tracking"), _T(
"MUI_track"));
7079 g_MainToolbar->AddToolItem(tic);
7082 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7083 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7084 g_MainToolbar->AddToolItem(tic);
7095 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7096 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7097 g_MainToolbar->AddToolItem(tic);
7100 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7101 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7102 g_MainToolbar->AddToolItem(tic);
7105 AddDefaultPositionPlugInTools();
7109 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7110 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7111 g_MainToolbar->AddToolItem(tic);
7114 g_MainToolbar->RebuildToolbar();
7118 g_MainToolbar->Realize();
7121 ArrayOfPlugInToolbarTools tool_array =
7122 g_pi_manager->GetPluginToolbarToolArray();
7123 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7125 if (!pttc->b_viz)
continue;
7127 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7130 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7131 if (g_bTrackActive) {
7132 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7134 g_MainToolbar->Realize();
7139bool MyFrame::CheckAndAddPlugInTool() {
7140 if (!g_pi_manager)
return false;
7145 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7147 if (!tb)
return false;
7149 int n_tools = tb->GetToolsCount();
7153 ArrayOfPlugInToolbarTools tool_array =
7154 g_pi_manager->GetPluginToolbarToolArray();
7156 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7158 if (pttc->position == n_tools) {
7159 wxBitmap *ptool_bmp;
7161 switch (global_color_scheme) {
7162 case GLOBAL_COLOR_SCHEME_DAY:
7163 ptool_bmp = pttc->bitmap_day;
7166 case GLOBAL_COLOR_SCHEME_DUSK:
7167 ptool_bmp = pttc->bitmap_dusk;
7169 case GLOBAL_COLOR_SCHEME_NIGHT:
7170 ptool_bmp = pttc->bitmap_night;
7173 ptool_bmp = pttc->bitmap_day;
7178 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7180 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7181 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7182 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7183 tic->m_bPlugin =
true;
7192 while (CheckAndAddPlugInTool()) {
7198bool MyFrame::AddDefaultPositionPlugInTools() {
7199 if (!g_pi_manager)
return false;
7205 ArrayOfPlugInToolbarTools tool_array =
7206 g_pi_manager->GetPluginToolbarToolArray();
7208 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7212 if (!pttc->b_viz)
continue;
7214 if (pttc->position == -1)
7216 wxBitmap *ptool_bmp;
7218 switch (global_color_scheme) {
7219 case GLOBAL_COLOR_SCHEME_DAY:
7220 ptool_bmp = pttc->bitmap_day;
7222 case GLOBAL_COLOR_SCHEME_DUSK:
7223 ptool_bmp = pttc->bitmap_dusk;
7225 case GLOBAL_COLOR_SCHEME_NIGHT:
7226 ptool_bmp = pttc->bitmap_night;
7229 ptool_bmp = pttc->bitmap_day;
7234 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7236 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7237 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7238 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7239 tic->m_bPlugin =
true;
7241 g_MainToolbar->AddToolItem(tic);
7254wxColour GetGlobalColor(wxString colorName);
7256static const char *usercolors[] = {
7257 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7258 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7259 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7260 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7261 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7262 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7263 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7265 "DILG0; 255;255;255;",
7267 "DILG0; 238;239;242;",
7269 "DILG1; 212;208;200;",
7270 "DILG2; 255;255;255;",
7274 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7275 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7276 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7278 "UDKRD; 124; 16; 0;",
7279 "UARTE; 200; 0; 0;",
7281 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7282 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7283 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7284 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7286 "DASHB; 255;255;255;",
7287 "DASHL; 175;175;175;",
7288 "DASHF; 50; 50; 50;",
7289 "DASHR; 200; 0; 0;",
7291 "DASHN; 200;120; 0;",
7292 "DASH1; 204;204;255;",
7293 "DASH2; 122;131;172;",
7294 "COMP1; 211;211;211;",
7296 "GREY3; 40; 40; 40;",
7297 "BLUE4; 100;100;200;",
7298 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7299 "BLUEBACK; 212;234;238;",
7300 "LANDBACK; 201;185;122;",
7303 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7304 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7305 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7306 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7307 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7308 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7309 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7311 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7312 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7313 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7315 "DILG0; 110;110;110;",
7316 "DILG1; 110;110;110;",
7318 "DILG3; 130;130;130;",
7319 "UITX1; 41; 46; 46;",
7321 "UARTE; 64; 64; 64;",
7323 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7324 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7325 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7326 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7328 "DASHB; 77; 77; 77;",
7329 "DASHL; 54; 54; 54;",
7331 "DASHR; 58; 21; 21;",
7332 "DASHG; 21; 58; 21;",
7333 "DASHN; 100; 50; 0;",
7334 "DASH1; 76; 76;113;",
7335 "DASH2; 48; 52; 72;",
7336 "COMP1; 107;107;107;",
7338 "GREY3; 20; 20; 20;",
7339 "BLUE4; 80; 80;160;",
7340 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7341 "LANDBACK; 201;185;122;",
7343 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7344 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7345 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7346 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7347 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7348 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7349 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7350 "DILG0; 80; 80; 80;",
7351 "DILG1; 80; 80; 80;",
7353 "DILG3; 65; 65; 65;",
7354 "UITX1; 31; 34; 35;",
7356 "UARTE; 64; 64; 64;",
7358 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7359 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7360 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7362 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7363 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7364 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7365 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7368 "DASHL; 20; 20; 20;",
7369 "DASHF; 64; 64; 64;",
7370 "DASHR; 70; 15; 15;",
7371 "DASHG; 15; 70; 15;",
7372 "DASHN; 17; 80; 56;",
7373 "DASH1; 48; 52; 72;",
7374 "DASH2; 36; 36; 53;",
7375 "COMP1; 24; 24; 24;",
7377 "GREY3; 10; 10; 10;",
7378 "BLUE4; 70; 70;140;",
7379 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7380 "LANDBACK; 201;185;122;",
7384int get_static_line(
char *d,
const char **p,
int index,
int n) {
7385 if (!strcmp(p[index],
"*****"))
return 0;
7387 strncpy(d, p[index], n);
7391void InitializeUserColors(
void) {
7392 const char **p = usercolors;
7400 UserColorTableArray =
new wxArrayPtrVoid;
7401 UserColourHashTableArray =
new wxArrayPtrVoid;
7405 ct->tableName =
new wxString(_T(
"DAY"));
7406 ct->color =
new wxArrayPtrVoid;
7407 UserColorTableArray->Add((
void *)ct);
7410 ct->tableName =
new wxString(_T(
"DUSK"));
7411 ct->color =
new wxArrayPtrVoid;
7412 UserColorTableArray->Add((
void *)ct);
7415 ct->tableName =
new wxString(_T(
"NIGHT"));
7416 ct->color =
new wxArrayPtrVoid;
7417 UserColorTableArray->Add((
void *)ct);
7419 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7420 if (!strncmp(buf,
"Table", 5)) {
7421 sscanf(buf,
"Table:%s", TableName);
7423 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7424 ctp = (colTable *)(UserColorTableArray->Item(it));
7425 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7434 while (buf[j] !=
';' && j < 20) {
7440 S52color *c =
new S52color;
7441 strcpy(c->colName, name);
7443 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7456 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7457 wxColorHashMap *phash =
new wxColorHashMap;
7458 UserColourHashTableArray->Add((
void *)phash);
7460 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7462 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7463 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7465 wxColour c(c2->R, c2->G, c2->B);
7466 wxString key(c2->colName, wxConvUTF8);
7473 pcurrent_user_color_hash =
7474 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7477void DeInitializeUserColors(
void) {
7478 if (!UserColorTableArray)
return;
7479 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7480 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7482 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7483 S52color *c = (S52color *)ct->color->Item(j);
7487 delete ct->tableName;
7493 delete UserColorTableArray;
7495 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7496 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7500 delete UserColourHashTableArray;
7507typedef struct _MSW_COLOR_SPEC {
7509 wxString S52_RGB_COLOR;
7513MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7514 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7515 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7518void SaveSystemColors() {
7532 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7533 while (pcspec->COLOR_NAME != -1) {
7534 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7539void RestoreSystemColors() {
7540 int element[NCOLORS];
7541 int rgbcolor[NCOLORS];
7544 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7545 while (pcspec->COLOR_NAME != -1) {
7546 element[i] = pcspec->COLOR_NAME;
7547 rgbcolor[i] = pcspec->SysRGB_COLOR;
7553 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7558void SetSystemColors(ColorScheme cs) {
7560 int element[NCOLORS];
7561 int rgbcolor[NCOLORS];
7563 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7564 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7565 while (pcspec->COLOR_NAME != -1) {
7566 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7567 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7568 element[i] = pcspec->COLOR_NAME;
7574 pSetSysColors(i, (
unsigned long *)&element[0],
7575 (
unsigned long *)&rgbcolor[0]);
7579 RestoreSystemColors();
7584wxColor GetDimColor(wxColor c) {
7585 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7586 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7590 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7591 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7593 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7594 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7595 hsv.value = hsv.value * factor;
7596 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7598 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7604double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7605 double const AnchorPointMaxDist)
7608 if (d < AnchorPointMinDist)
7609 return AnchorPointMinDist;
7610 else if (d > AnchorPointMaxDist)
7611 return AnchorPointMaxDist;
7617 if (d > -AnchorPointMinDist)
7618 return -AnchorPointMinDist;
7619 else if (d < -AnchorPointMaxDist)
7620 return -AnchorPointMaxDist;
7627static const WORD MAX_CONSOLE_LINES =
7632void RedirectIOToConsole()
7637 wxIntPtr lStdHandle;
7639 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7649 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7650 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7651 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7655 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7656 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7657 fp = _fdopen(hConHandle,
"w");
7659 setvbuf(stdout, NULL, _IONBF, 0);
7663 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7664 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7665 fp = _fdopen(hConHandle,
"r");
7667 setvbuf(stdin, NULL, _IONBF, 0);
7671 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7672 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7673 fp = _fdopen(hConHandle,
"w");
7675 setvbuf(stderr, NULL, _IONBF, 0);
7687bool TestGLCanvas(wxString prog_dir) {
7689 wxString test_app = prog_dir;
7690 test_app += _T(
"ocpn_gltest1.exe");
7692 if (::wxFileExists(test_app)) {
7693 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7694 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7695 if (proc_return == 0)
7696 printf(
"GLCanvas OK\n");
7698 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7700 return (proc_return == 0);
7710bool ReloadLocale() {
7715 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7722 FontMgr::Get().SetLocale(g_locale);
7730 if (pRoutePropDialog) {
7731 pRoutePropDialog->Hide();
7732 pRoutePropDialog->Destroy();
7733 pRoutePropDialog = NULL;
7736 if (pRouteManagerDialog) {
7737 pRouteManagerDialog->Hide();
7738 pRouteManagerDialog->Destroy();
7739 pRouteManagerDialog = NULL;
7742 if (console) console->SetColorScheme(global_color_scheme);
7743 if (g_pais_query_dialog_active) {
7744 g_pais_query_dialog_active->Destroy();
7745 g_pais_query_dialog_active = NULL;
7748 auto alert_dlg_active =
7750 if (alert_dlg_active) {
7751 alert_dlg_active->Destroy();
7752 g_pais_alert_dialog_active =
nullptr;
7755 if (g_pAISTargetList) {
7756 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7757 g_pAISTargetList->Disconnect_decoder();
7758 g_pAISTargetList->Destroy();
7759 g_pAISTargetList = NULL;
7763 if (gFrame->m_pMenuBar) {
7764 gFrame->SetMenuBar(NULL);
7765 gFrame->m_pMenuBar->Destroy();
7766 gFrame->m_pMenuBar = NULL;
7768 gFrame->BuildMenuBar();
7771 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7773 if (cc) cc->CanvasApplyLocale();
7778 wxString perspective;
7779 pConfig->SetPath(_T (
"/AUI" ));
7780 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7785 PluginLoader::getInstance()->DeactivateAllPlugIns();
7786 PluginLoader::getInstance()->UpdatePlugIns();
7794 bool bno_load =
false;
7795 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7797 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7798 wxAuiPaneInfo pane = pane_array_val[i];
7799 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7805 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7807 g_pauimgr->Update();
7810 gFrame->RequestNewToolbars(
true);
7811 gFrame->RequestNewMasterToolbar(
true);
7815extern s57RegistrarMgr *m_pRegistrarMan;
7816extern wxString g_UserPresLibData;
7817extern wxString g_SENCPrefix;
7818extern wxString g_csv_locn;
7834 g_csv_locn = g_Platform->GetSharedDataDir();
7835 g_csv_locn.Append(_T(
"s57data"));
7838 g_csv_locn = _T(
".");
7839 appendOSDirSlash(&g_csv_locn);
7840 g_csv_locn.Append(_T(
"s57data"));
7845 if (g_SENCPrefix.IsEmpty()) {
7847 appendOSDirSlash(&g_SENCPrefix);
7848 g_SENCPrefix.Append(_T(
"SENC"));
7852 wxFileName f(g_SENCPrefix);
7854 g_SENCPrefix = f.GetFullPath();
7856 g_SENCPrefix = _T(
"SENC");
7862 bool b_force_legacy =
false;
7864 if (g_UserPresLibData.IsEmpty()) {
7865 plib_data = g_csv_locn;
7866 appendOSDirSlash(&plib_data);
7867 plib_data.Append(_T(
"S52RAZDS.RLE"));
7869 plib_data = g_UserPresLibData;
7870 b_force_legacy =
true;
7873 ps52plib =
new s52plib(plib_data, b_force_legacy);
7888 if (!ps52plib->m_bOK) {
7891 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7893 wxString look_data_dir;
7894 look_data_dir.Append(std_path.GetUserDataDir());
7895 appendOSDirSlash(&look_data_dir);
7896 wxString tentative_SData_Locn = look_data_dir;
7897 look_data_dir.Append(_T(
"s57data"));
7899 plib_data = look_data_dir;
7900 appendOSDirSlash(&plib_data);
7901 plib_data.Append(_T(
"S52RAZDS.RLE"));
7903 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7904 ps52plib =
new s52plib(plib_data);
7906 if (ps52plib->m_bOK) {
7907 g_csv_locn = look_data_dir;
7916 if (!ps52plib->m_bOK) {
7919 wxString look_data_dir;
7920 look_data_dir = g_Platform->GetSharedDataDir();
7921 look_data_dir.Append(_T(
"s57data"));
7923 plib_data = look_data_dir;
7924 appendOSDirSlash(&plib_data);
7925 plib_data.Append(_T(
"S52RAZDS.RLE"));
7927 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7928 ps52plib =
new s52plib(plib_data);
7930 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7933 if (ps52plib->m_bOK) {
7934 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
7936 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7941 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7943 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7944 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7945 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7946 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7949 pConfig->LoadS57Config();
7950 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7953 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
7954 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
7956 ps52plib->SetDIPFactor(dip_factor);
7961 ps52plib->SetScaleFactorExp(
7962 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7963 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7968 extern bool g_b_EnableVBO;
7969 extern GLenum g_texture_rectangle_format;
7974 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7975 ps52plib->SetGLRendererString(renderer);
7978 ps52plib->SetGLOptions(
7979 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7980 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7981 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7987 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
7996 : wxThread(wxTHREAD_JOINABLE) {
7997 m_filename = filename;
8008 newChart->SetNativeScale(m_scale);
8009 newChart->SetFullExtent(m_ext);
8011 newChart->FindOrCreateSenc(m_filename);
8016 wxString m_filename;
8022static double chart_dist(
int index) {
8028 if (cte.GetBBox().Contains(gLat, gLon))
8033 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8034 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8035 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8038 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8039 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8041 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8047WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8048static int CompareInts(
int n1,
int n2) {
8049 double d1 = chart_dist(n1);
8050 double d2 = chart_dist(n2);
8051 return (
int)(d1 - d2);
8056 wxString chart_path;
8061WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8063#include <wx/arrimpl.cpp>
8066void ParseAllENC(wxWindow *parent) {
8067 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8075 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8078 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8080 idx_sorted_by_distance.Add(i);
8084 if (count == 0)
return;
8086 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8092 ArrayOfCompressTargets ct_array;
8093 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8094 int i = idx_sorted_by_distance[j];
8097 double distance = chart_dist(i);
8099 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8102 pct->distance = distance;
8103 pct->chart_path = filename;
8105 ct_array.push_back(pct);
8108 int thread_count = 0;
8111 extern int g_nCPUCount;
8112 if (g_nCPUCount > 0)
8113 thread_count = g_nCPUCount;
8115 thread_count = wxThread::GetCPUCount();
8117 if (thread_count < 1) {
8126 for(
int t = 0; t < thread_count; t++)
8130 wxGenericProgressDialog *prog =
nullptr;
8134 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8135 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8137 prog =
new wxGenericProgressDialog();
8139 prog->SetFont(*qFont);
8141 prog->Create(_(
"OpenCPN ENC Prepare"),
8142 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8152 prog->ShowWindowModal();
8161 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8162 wxString filename = ct_array[j].chart_path;
8163 double distance = ct_array[j].distance;
8164 int index = ChartData->FinddbIndex(filename);
8165 if (index < 0)
continue;
8168 ext.NLAT = cte.GetLatMax();
8169 ext.SLAT = cte.GetLatMin();
8170 ext.WLON = cte.GetLonMin();
8171 ext.ELON = cte.GetLonMax();
8173 int scale = cte.GetScale();
8176 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8179 if (wxThread::IsMain()) {
8181 wxSize sz = prog->GetSize();
8183 msg += _T(
" Chart:");
8186 prog->Update(count, msg, &skip);
8198 newChart->SetNativeScale(
scale);
8199 newChart->SetFullExtent(ext);
8200 newChart->DisableBackgroundSENC();
8202 newChart->FindOrCreateSenc(filename,
8206 if (wxThread::IsMain()) {
8207 msg.Printf(_(
"ENC Completed."));
8209 prog->Update(count, msg, &skip);
8219 for (
int t = 0;; t = (t + 1) % thread_count) {
8226 if (!workers[t]->IsAlive()) {
8239#if defined(__WXMSW__) || defined(__WXOSX__)
8246 for(
int t = 0; t<thread_count; t++) {
Global state for AIS decoder.
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.
Implements the AboutFrame class with additional functionality.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
A modal message dialog with a cancel and confirmation 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 DoZoomCanvas(double factor, bool can_zoom_to_cursor=true)
Internal function that implements the actual zoom operation.
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.
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...
Primary navigation console display for route and vessel tracking.
Overall logging handler, outputs to screen and log file.
bool IsActive() const override
Return true if log is visible i.
const void Notify()
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.
Represents a layer of chart objects in OpenCPN.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
virtual bool IsActive() const =0
Return true if log is visible i.
virtual void Add(const Logline &l)=0
Add an formatted string to log output.
void Init(const KeyProvider &kp, 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.
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.
Represents a navigational route in the navigation system.
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.
Represents the About dialog for OpenCPN.
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.
Global variables reflecting command line options and arguments.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
New NMEA Debugger successor main window.
wxWindow * GetTopWindow()
Return the top level window a k a gFrame.
Hooks into gui available in model.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
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.
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.