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"
77#include "model/nav_object_database.h"
78#include "model/navutil_base.h"
80#include "model/own_ship.h"
83#include "model/routeman.h"
84#include "model/select.h"
86#include "model/track.h"
88#include "dialog_alert.h"
92#include "ais_info_gui.h"
93#include "AISTargetAlertDialog.h"
94#include "AISTargetListDialog.h"
95#include "AISTargetQueryDialog.h"
96#include "CanvasConfig.h"
98#include "chart_ctx_factory.h"
102#include "color_handler.h"
106#include "ConfigMgr.h"
111#include "glChartCanvas.h"
112#include "GoToPositionDialog.h"
114#include "iENCToolbar.h"
116#include "load_errors_dlg.h"
119#include "N2KParser.h"
123#include "OCPN_AUIManager.h"
124#include "ocpn_frame.h"
125#include "OCPNPlatform.h"
126#include "OCPN_Sound.h"
128#include "pluginmanager.h"
129#include "print_dialog.h"
130#include "printout_chart.h"
131#include "routemanagerdialog.h"
132#include "routeman_gui.h"
133#include "route_point_gui.h"
134#include "RoutePropDlgImpl.h"
137#include "S57QueryDialog.h"
138#include "SystemCmdSound.h"
142#include "TrackPropDlg.h"
143#include "waypointman_gui.h"
144#include "CanvasOptions.h"
148#include "androidUTIL.h"
154WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
162extern arrayofCanvasPtr g_canvasArray;
175extern About *g_pAboutDlgLegacy;
178extern double vLat, vLon;
179extern wxString g_locale;
180extern ColorScheme global_color_scheme;
185GLenum g_texture_rectangle_format;
188#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
189extern wxLocale *plocale_def_lang;
196extern s52plib *ps52plib;
200extern bool g_b_legacy_input_filter_behaviour;
201extern bool g_bTrackActive;
203extern bool g_bmasterToolbarFull;
204extern int g_nAutoHideToolbar;
205extern bool g_bAutoHideToolbar;
206extern bool g_bshowToolbar;
207extern int g_maintoolbar_x;
208extern int g_maintoolbar_y;
209extern wxString g_toolbarConfig;
210extern float g_toolbar_scalefactor;
211extern float g_compass_scalefactor;
212extern bool g_bShowMenuBar;
213extern bool g_bShowCompassWin;
215extern bool g_benable_rotate;
216extern int g_GUIScaleFactor;
217extern int g_ChartScaleFactor;
218extern int g_last_ChartScaleFactor;
219extern int g_ShipScaleFactor;
220extern float g_ShipScaleFactorExp;
221extern int g_ENCTextScaleFactor;
223extern bool g_bShowTide;
224extern bool g_bShowCurrent;
225extern bool g_bUIexpert;
226extern RouteList *pRouteList;
227extern wxString g_default_wp_icon;
228extern std::vector<std::string> TideCurrentDataSet;
229extern wxString g_TCData_Dir;
231extern char nmea_tick_chars[];
232extern double AnchorPointMinDist;
233extern bool AnchorAlertOn1, AnchorAlertOn2;
234extern wxString g_AW1GUID;
235extern wxString g_AW2GUID;
236extern bool g_bCruising;
237extern double g_COGAvg;
238extern int g_COGAvgSec;
240extern std::vector<Track *> g_TrackList;
241extern double gQueryVar;
242extern int g_ChartUpdatePeriod;
243extern int g_SkewCompUpdatePeriod;
244extern bool g_bCourseUp;
245extern bool g_bLookAhead;
246extern bool g_bskew_comp;
247extern bool g_bPauseTest;
249extern bool g_bPlayShipsBells;
250extern wxDateTime g_loglast_time;
251extern int g_nAWDefault;
253extern bool g_bDeferredStartTrack;
254extern bool bDBUpdateInProgress;
258extern bool g_bDeferredInitDone;
259extern int options_lastPage;
260extern int options_subpage;
261extern bool b_reloadForPlugins;
263extern int g_NeedDBUpdate;
264extern bool g_bFullscreen;
265extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
266extern ChartGroupArray *g_pGroupArray;
267extern bool g_bEnableZoomToCursor;
268extern double g_display_size_mm;
269extern std::vector<size_t> g_config_display_size_mm;
270extern wxString ChartListFileName;
271extern bool g_bFullscreenToolbar;
272extern arrayofCanvasPtr g_canvasArray;
273extern wxString g_lastAppliedTemplateGUID;
274extern wxPoint options_lastWindowPos;
275extern wxSize options_lastWindowSize;
276extern unsigned int g_canvasConfig;
277extern bool g_bFullScreenQuilt;
278extern bool g_bQuiltEnable;
279extern wxString *pInit_Chart_Dir;
280extern bool g_bShowOutlines;
281extern bool g_bTempShowMenuBar;
282extern bool g_bShowStatusBar;
283extern bool g_FlushNavobjChanges;
284extern int g_FlushNavobjChangesTimeout;
285extern bool g_bShowChartBar;
286extern double g_plus_minus_zoom_factor;
287extern int g_nframewin_x;
288extern int g_nframewin_y;
289extern int g_nframewin_posx;
290extern int g_nframewin_posy;
291extern bool g_bframemax;
292extern LayerList *pLayerList;
293extern bool g_bAutoAnchorMark;
294extern wxDateTime g_start_time;
295extern bool g_bcompression_wait;
296extern bool g_bquiting;
297extern bool b_inCloseWindow;
298extern bool b_inCompressAllCharts;
299extern long g_maintoolbar_orient;
300extern wxAuiDefaultDockArt *g_pauidockart;
301extern int g_click_stop;
302extern wxString g_CmdSoundString;
303extern std::vector<OcpnSound *> bells_sound;
304extern char bells_sound_file_name[2][12];
305extern int g_sticky_chart;
306extern int g_sticky_projection;
307extern wxArrayPtrVoid *UserColourHashTableArray;
308extern wxColorHashMap *pcurrent_user_color_hash;
311extern bool g_own_ship_sog_cog_calc;
312extern int g_own_ship_sog_cog_calc_damp_sec;
313extern bool g_bHasHwClock;
314extern bool s_bSetSystemTime;
315extern bool bVelocityValid;
316extern int gHDx_Watchdog;
319extern bool g_bUseGLL;
320extern int g_MemFootMB;
323extern int g_chart_zoom_modifier_vector;
324extern bool g_config_display_size_manual;
325extern bool g_PrintingInProgress;
326extern bool g_disable_main_toolbar;
327extern bool g_btenhertz;
328extern bool g_declutter_anchorage;
333typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
334typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
336SetSysColors_t pSetSysColors;
337GetSysColor_t pGetSysColor;
339void SaveSystemColors(
void);
340void RestoreSystemColors(
void);
345DWORD color_3ddkshadow;
347DWORD color_activecaption;
348DWORD color_gradientactivecaption;
349DWORD color_captiontext;
350DWORD color_windowframe;
351DWORD color_inactiveborder;
356#include <wx/msw/msvcrt.h>
360static const long long lNaN = 0xfff8000000000000;
361#define NAN (*(double *)&lNaN)
364static wxArrayPtrVoid *UserColorTableArray = 0;
367double gLat_gt, gLon_gt;
368double gLat_gt_m1, gLon_gt_m1;
370uint64_t fix_time_gt_last;
372double gSog_gt, gCog_gt, gHdt_gt;
373double gCog_gt_m1, gHdt_gt_m1;
375double cog_rate_gt, hdt_rate_gt;
378void appendOSDirSlash(wxString *pString);
380void InitializeUserColors(
void);
381void DeInitializeUserColors(
void);
382void SetSystemColors(ColorScheme cs);
384static bool LoadAllPlugIns(
bool load_enabled) {
385 AbstractPlatform::ShowBusySpinner();
386 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
387 AbstractPlatform::HideBusySpinner();
391static void LaunchLocalHelp(
void) {
393 androidLaunchHelpView();
395 wxString def_lang_canonical = _T(
"en_US");
398 if (plocale_def_lang)
399 def_lang_canonical = plocale_def_lang->GetCanonicalName();
402 wxString help_locn = g_Platform->GetSharedDataDir() + _T(
"doc/help_");
404 wxString help_try = help_locn + def_lang_canonical + _T(
".html");
406 if (!::wxFileExists(help_try)) {
407 help_try = help_locn + _T(
"en_US") + _T(
".html");
409 if (!::wxFileExists(help_try)) {
410 help_try = help_locn + _T(
"web") + _T(
".html");
413 if (!::wxFileExists(help_try))
return;
416 wxLaunchDefaultBrowser(wxString(_T(
"file:///")) + help_try);
420static void DoHelpDialog(
void) {
425 g_pAboutDlg->SetFocus();
430 if (!g_pAboutDlgLegacy)
431 g_pAboutDlgLegacy =
new About(gFrame, g_Platform->GetSharedDataDir(),
432 [] { LaunchLocalHelp(); });
434 g_pAboutDlgLegacy->SetFocus();
435 g_pAboutDlgLegacy->Show();
444#if defined(__WXGTK__) || defined(__WXQT__)
445#include "bitmaps/opencpn.xpm"
460int g_iENCToolbarPosX;
461int g_iENCToolbarPosY;
463void BuildiENCToolbar(
bool bnew) {
464 if (g_bInlandEcdis) {
467 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
468 wxPoint tbp_incanvas =
471 g_iENCToolbarPosY = tbp_incanvas.y;
472 g_iENCToolbarPosX = tbp_incanvas.x;
474 delete g_iENCToolbar;
479 if (!g_iENCToolbar) {
480 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
484 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
486 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
487 g_iENCToolbarPosY = -1;
490 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
496 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
500 double tool_scale_factor =
501 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
504 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
505 g_iENCToolbar->SetColorScheme(global_color_scheme);
506 g_iENCToolbar->EnableSubmerge(
false);
509 delete g_iENCToolbar;
510 g_iENCToolbar = NULL;
514bool ShowNavWarning() {
517OpenCPN is distributed in the hope that it will be useful, \
518but WITHOUT ANY WARRANTY; without even the implied \
519warranty of MERCHANTABILITY or FITNESS FOR A \
520PARTICULAR PURPOSE.\n\n\
521See the GNU General Public License for more details.\n\n\
522OpenCPN must only be used in conjunction with approved \
523paper charts and traditional methods of navigation.\n\n\
524DO NOT rely upon OpenCPN for safety of life or property.\n\n\
525Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
527 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
530 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
533 msg.Replace(
"\n",
"<br>");
535 std::stringstream html;
536 html <<
"<html><body><p>";
537 html << msg.ToStdString();
538 html <<
"</p></body></html>";
540 std::string title = _(
"Welcome to OpenCPN").ToStdString();
541 std::string action = _(
"Agree").ToStdString();
543 info_dlg.SetInitialSize();
544 info_dlg.AddHtmlContent(html);
545 int agreed = info_dlg.ShowModal();
546 return agreed == wxID_OK;
551 if (chart ==
nullptr)
return false;
554 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
556 if (cc && cc->m_singleChart == chart) {
563#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
566static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
567 const char *prop_name) {
571 unsigned long ret_nitems;
572 unsigned long ret_bytes_after;
573 unsigned char *ret_prop;
575 xa_prop_name = XInternAtom(disp, prop_name, False);
583 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
584 &xa_ret_type, &ret_format, &ret_nitems,
585 &ret_bytes_after, &ret_prop) != Success)
588 if (xa_ret_type != xa_prop_type) {
592 return (
char *)ret_prop;
597static bool isTransparentToolbarInOpenGLOK(
void) {
604 if (!g_bdisable_opengl) {
605 Display *disp = XOpenDisplay(NULL);
607 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
609 "_NET_SUPPORTING_WM_CHECK")) ||
610 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
612 "_WIN_SUPPORTING_WM_CHECK"))) {
615 if ((wm_name = get_X11_property(disp, *sup_window,
616 XInternAtom(disp,
"UTF8_STRING", False),
618 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
621 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
642wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
644BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
645EVT_CLOSE(MyFrame::OnCloseWindow)
646EVT_MENU(wxID_EXIT, MyFrame::OnExit)
647EVT_SIZE(MyFrame::OnSize)
648EVT_MOVE(MyFrame::OnMove)
649EVT_ICONIZE(MyFrame::OnIconize)
650EVT_MENU(-1, MyFrame::OnToolLeftClick)
651EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
653EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
654EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
655EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
657EVT_MAXIMIZE(MyFrame::OnMaximize)
658EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
659 MyFrame::RequestNewToolbarArgEvent)
660EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
662EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
663EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
664EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
666#ifdef wxHAS_POWER_EVENTS
667EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
668EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
669EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
670EVT_POWER_RESUME(MyFrame::OnResume)
681static
void onBellsFinishedCB(
void *ptr) {
682 auto framePtr =
static_cast<MyFrame *
>(ptr);
684 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
685 wxPostEvent(framePtr, ev);
690 auto msg = ev.GetString().ToStdString();
691 auto ¬eman = NotificationManager::GetInstance();
692 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
695static NmeaLog *GetDataMonitor() {
696 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
697 return dynamic_cast<NmeaLog *
>(w);
701MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
702 const wxSize &size,
long style)
703 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
704 comm_overflow_dlg(this),
705 m_connections_dlg(nullptr),
707 g_current_monitor = wxDisplay::GetFromWindow(
this);
713 g_current_monitor_dip_px_ratio =
714 g_monitor_info[g_current_monitor].width_px /
715 g_monitor_info[g_current_monitor].width;
718 m_last_track_rotation_ts = 0;
719 m_ulLastNMEATicktime = 0;
720 m_data_monitor->Hide();
722 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
726 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
729 InitTimer.SetOwner(
this, INIT_TIMER);
731 m_initializing =
false;
734 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
737 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
740 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
743 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
746 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
748 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
757 m_bTimeIsSet =
false;
760 m_bdefer_resize =
false;
763 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
764 COGFilterTable[i] = NAN;
765 SOGFilterTable[i] = NAN;
767 m_last_bGPSValid =
false;
768 m_last_bVelocityValid =
false;
778 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
783 double process_noise_std = 1.0;
784 double measurement_noise_std = 0.5;
786 m_ChartUpdatePeriod = 1;
791 log_callbacks.log_is_active = [&]() {
792 auto log = GetDataMonitor();
793 return log && log->IsVisible();
795 log_callbacks.log_message = [&](
Logline ll) {
796 NmeaLog *monitor = GetDataMonitor();
799 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
802 ais_callbacks.confirm_stop_track = []() {
803 int r = OCPNMessageBox(
805 _(
"This AIS target has Persistent tracking selected by MMSI "
807 "A Persistent track recording will therefore be restarted for this "
809 "Do you instead want to stop Persistent tracking for this target?"),
810 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
811 return r == wxID_YES;
813 ais_callbacks.get_target_mmsi = []() {
814 auto alert_dlg_active =
816 assert(alert_dlg_active);
817 return alert_dlg_active->Get_Dialog_MMSI();
825 wxLogMessage(
" **** Connect stuff");
831 Connect(wxEVT_OCPN_MSG,
832 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
839 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
840 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
848#if defined(__WXGTK__) || defined(__WXQT__)
849 wxIcon app_icon(opencpn);
857 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
859 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
860 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
865 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
868 g_sticky_projection = -1;
871 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
872 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
874 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
876 [&](wxCommandEvent) { Refresh(); });
877 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
882 EnableFullScreenView();
888 FrameTenHzTimer.Stop();
895 wxRouteListNode *node = pRouteList->GetFirst();
898 Route *pRouteDelete = node->GetData();
901 node = node->GetNext();
908 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
916 switch (event.type) {
917 case SENC_BUILD_STARTED:
920 case SENC_BUILD_DONE_NOERROR:
922 chart =
event.m_ticket->m_chart;
924 chart->PostInit(FULL_INIT, global_color_scheme);
926 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
928 if (cc) cc->ClearS52PLIBStateHash();
933 delete event.m_ticket;
935 case SENC_BUILD_DONE_ERROR:
943void MyFrame::RebuildChartDatabase() {
944 bool b_SetInitialPoint =
false;
947 ArrayOfCDI ChartDirArray;
948 pConfig->LoadChartDirArray(ChartDirArray);
950 if (ChartDirArray.GetCount()) {
953 if (g_NeedDBUpdate == 1) {
955 _(
"OpenCPN needs to update the chart database from config file "
959 wxICON_INFORMATION | wxOK);
967 _(
"Rebuilding chart database from configuration file entries..."));
971 wxString dummy1 = _(
"Elapsed time : ");
972 wxString dummy2 = _(
"Estimated time : ");
973 wxString dummy3 = _(
"Remaining time : ");
974 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
975 _(
"OpenCPN Chart Update"), line, 100, NULL,
976 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
977 wxPD_REMAINING_TIME);
979 ChartData->
Create(ChartDirArray, pprog);
980 ChartData->SaveBinary(ChartListFileName);
985 ChartData->ApplyGroupArray(g_pGroupArray);
990void MyFrame::OnBellsFinished(wxCommandEvent &event) {
991 int bells = wxMin(m_BellsToPlay, 2);
992 if (bells <= 0)
return;
994 wxString soundfile = _T(
"sounds");
995 appendOSDirSlash(&soundfile);
996 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
997 soundfile.Prepend(g_Platform->GetSharedDataDir());
998 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
1000 OcpnSound *sound = bells_sound[bells - 1];
1001 sound->SetFinishedCallback(onBellsFinishedCB,
this);
1002 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
1003 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
1004 sound->Load(soundfile);
1005 if (!sound->IsOk()) {
1006 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
1010 m_BellsToPlay -= bells;
1013void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
1015void MyFrame::OnMaximize(wxMaximizeEvent &event) {
1022ColorScheme GetColorScheme() {
return global_color_scheme; }
1024ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
1026void MyFrame::ReloadAllVP() {
1027 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1029 if (cc) cc->ReloadVP();
1033void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
1034 global_color_scheme = cs;
1036 wxString SchemeName;
1038 case GLOBAL_COLOR_SCHEME_DAY:
1039 SchemeName = _T(
"DAY");
1041 case GLOBAL_COLOR_SCHEME_DUSK:
1042 SchemeName = _T(
"DUSK");
1044 case GLOBAL_COLOR_SCHEME_NIGHT:
1045 SchemeName = _T(
"NIGHT");
1048 SchemeName = _T(
"DAY");
1052 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
1054 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
1055 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
1056 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1057 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
1058 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
1060 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1089 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1090 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1092 g_pauimgr->Update();
1094 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1097 unsigned Usercolortable_index = 0;
1098 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1099 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1100 if (SchemeName.IsSameAs(*ct->tableName)) {
1101 Usercolortable_index = i;
1106 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1109 pcurrent_user_color_hash =
1110 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1112 SetSystemColors(cs);
1115 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1118 cc->SetColorScheme(cs);
1119 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1120 cc->HideChartInfoWindow();
1121 cc->SetQuiltChartHiLiteIndex(-1);
1127 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1128 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1131 g_options->SetColorScheme(cs);
1135 console->SetColorScheme(cs);
1139 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1142 if (g_pMarkInfoDialog) {
1143 g_pMarkInfoDialog->SetColorScheme(cs);
1146 if (pRoutePropDialog) {
1147 pRoutePropDialog->SetColorScheme(cs);
1152 if (g_pais_query_dialog_active) {
1153 bool b_isshown = g_pais_query_dialog_active->IsShown();
1154 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1155 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1157 g_pais_query_dialog_active->Close();
1160 g_pais_query_dialog_active->
Create(
1161 this, -1, _(
"AIS Target Query"),
1162 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1163 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1164 g_pais_query_dialog_active->UpdateText();
1165 if (b_isshown) g_pais_query_dialog_active->Show();
1168 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1170 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1172 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1174 ApplyGlobalColorSchemetoStatusBar();
1176 UpdateAllToolbars(cs);
1178 if (g_MainToolbar) {
1179 if (g_MainToolbar->GetColorScheme() != cs) {
1181 bool btoolbarFull = g_bmasterToolbarFull;
1183 g_MainToolbar->SetColorScheme(cs);
1187 if (!btoolbarFull) {
1189 RequestNewMasterToolbar();
1190 g_MainToolbar->SetColorScheme(cs);
1191 CollapseGlobalToolbar();
1194 RequestNewMasterToolbar();
1195 g_MainToolbar->SetColorScheme(cs);
1200 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1203void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1204 if (m_pStatusBar != NULL) {
1205 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1206 m_pStatusBar->ClearBackground();
1211 if (g_canvasArray.GetCount() > 0)
1212 return g_canvasArray.Item(0);
1216void MyFrame::CancelAllMouseRoute() {
1218 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1220 if (cc) cc->CancelMouseRoute();
1224void MyFrame::NotifyChildrenResize() {}
1226void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1228 if (ChartData) ChartData->PurgeCache();
1231 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1234 g_pauimgr->DetachPane(cc);
1239 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1248 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1251 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1252 config_array.Item(i)->canvas = NULL;
1258 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1259 g_canvasArray.RemoveAt(i);
1263 switch (g_canvasConfig) {
1266 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1269 g_canvasArray.Add(cc);
1271 cc = g_canvasArray[0];
1277 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1278 cc->GetglCanvas()->Show();
1281 config_array.Item(0)->canvas = cc;
1285 cc->ApplyCanvasConfig(config_array.Item(0));
1289 cc->ConfigureChartBar();
1290 cc->SetColorScheme(global_color_scheme);
1291 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1292 cc->SetShowGPS(
true);
1294 g_pauimgr->AddPane(cc);
1295 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1296 g_pauimgr->GetPane(cc).Fixed();
1297 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1298 g_pauimgr->GetPane(cc).CenterPane();
1303 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1305 g_canvasArray.Add(cc);
1307 cc = g_canvasArray[0];
1313 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1316 config_array.Item(0)->canvas = cc;
1318 cc->ApplyCanvasConfig(config_array.Item(0));
1321 cc->ConfigureChartBar();
1322 cc->SetColorScheme(global_color_scheme);
1323 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1324 cc->SetShowGPS(
false);
1326 g_pauimgr->AddPane(cc);
1327 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1328 g_pauimgr->GetPane(cc)
1329 .CaptionVisible(
false)
1331 .CloseButton(
false);
1333 g_pauimgr->GetPane(cc).CenterPane();
1336 g_canvasArray.Add(cc);
1340 if (config_array.GetCount() < 2) {
1342 pcc->configIndex = 1;
1346 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1347 config_array.Add(pcc);
1350 config_array.Item(1)->canvas = cc;
1352 cc->ApplyCanvasConfig(config_array.Item(1));
1355 cc->ConfigureChartBar();
1356 cc->SetColorScheme(global_color_scheme);
1357 cc->SetShowGPS(
true);
1360 g_pauimgr->AddPane(cc);
1361 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1362 g_pauimgr->GetPane(cc)
1363 .CaptionVisible(
false)
1365 .CloseButton(
false);
1366 g_pauimgr->GetPane(cc).RightDockable(
true);
1367 g_pauimgr->GetPane(cc).Right();
1370 config_array.Item(1)->canvasSize =
1371 wxSize(GetClientSize().x / 2, GetClientSize().y);
1372 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1377 if (b_useStoredSize) {
1378 int ccw = config_array.Item(1)->canvasSize.x;
1379 int cch = config_array.Item(1)->canvasSize.y;
1382 if (ccw < GetClientSize().x / 10) {
1383 ccw = GetClientSize().x / 2;
1384 cch = GetClientSize().y;
1387 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1388 cc->SetSize(ccw, cch);
1399 g_focusCanvas = GetPrimaryCanvas();
1402void MyFrame::RequestNewToolbars(
bool bforcenew) {
1403 if (b_inCloseWindow) {
1407 BuildiENCToolbar(bforcenew);
1408 PositionIENCToolbar();
1417void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1418 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1423void MyFrame::SetAllToolbarScale() {
1424 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1427void MyFrame::SetGPSCompassScale() {
1428 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1432 wxPoint screenPoint = ::wxGetMousePosition();
1435 switch (g_canvasConfig) {
1437 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1440 if (canvas->GetScreenRect().Contains(
1444 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1447 if (canvas->GetScreenRect().Contains(
1454 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1457 if (canvas->GetScreenRect().Contains(
1458 canvas->ScreenToClient(screenPoint)))
1466int MyFrame::GetCanvasIndexUnderMouse() {
1467 wxPoint screenPoint = ::wxGetMousePosition();
1470 switch (g_canvasConfig) {
1472 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1475 if (canvas->GetScreenRect().Contains(
1479 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1482 if (canvas->GetScreenRect().Contains(
1489 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1492 if (canvas->GetScreenRect().Contains(
1493 canvas->ScreenToClient(screenPoint)))
1501bool MyFrame::DropMarker(
bool atOwnShip) {
1508 if (!canvas)
return false;
1515 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1517 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1519 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1524 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1525 pRouteManagerDialog->UpdateWptListCtrl();
1530 RefreshAllCanvas(
false);
1535void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1536 if (g_canvasConfig != 0) {
1539 int nTargetGTK = -1;
1541 wxWindow *source = FindFocus();
1547 switch (g_canvasConfig) {
1549 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1552 if (canvas && (canvas == test)) {
1557 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1560 if (canvas && (canvas == test)) {
1568 int nfinalTarget = nTarget;
1570 nfinalTarget = nTargetGTK;
1572 target = ConfigMgr::Get()
1573 .GetCanvasConfigArray()
1578 target->Refresh(
true);
1589void MyFrame::FastClose() {
1591 FrameTenHzTimer.Stop();
1593 FrameTimer1.Start(1);
1597void MyFrame::OnExit(wxCommandEvent &event) {
1601void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1604 if (b_inCloseWindow) {
1614 if (!g_bDeferredInitDone)
return;
1627 if (b_inCompressAllCharts) {
1631 if (bDBUpdateInProgress)
return;
1633 b_inCloseWindow =
true;
1635 ::wxSetCursor(wxCURSOR_WAIT);
1639 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1641 if (cc && cc->IsMeasureActive()) {
1642 cc->CancelMeasureRoute();
1647 SendPreShutdownHookToPlugins();
1651 if (g_pAISTargetList) {
1652 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1653 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1654 g_pauimgr->DetachPane(g_pAISTargetList);
1665 pConfig->SetPath(_T (
"/AUI" ));
1666 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1673 if (g_glTextureManager) {
1674 g_glTextureManager->PurgeJobList();
1676 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1681 SetCursor(wxCURSOR_WAIT);
1683 RefreshAllCanvas(
true);
1689 RestoreScreenBrightness();
1698 if (g_iENCToolbar) {
1699 wxPoint locn = g_iENCToolbar->GetPosition();
1700 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1701 g_iENCToolbarPosY = tbp_incanvas.y;
1702 g_iENCToolbarPosX = tbp_incanvas.x;
1706 g_bframemax = IsMaximized();
1709 FrameTenHzTimer.Stop();
1711 FrameCOGTimer.Stop();
1725 if (g_bAutoAnchorMark) {
1726 bool watching_anchor =
false;
1727 if (pAnchorWatchPoint1)
1728 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1730 if (pAnchorWatchPoint2)
1731 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1734 wxDateTime now = wxDateTime::Now();
1735 wxTimeSpan uptime = now.Subtract(g_start_time);
1737 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1738 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1743 if (g_declutter_anchorage) {
1744 wxRoutePointListNode *node =
1745 pWayPointMan->GetWaypointList()->GetFirst();
1748 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1749 double a = gLat - pr->m_lat;
1750 double b = gLon - pr->m_lon;
1751 double l = sqrt((a * a) + (b * b));
1754 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1756 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1757 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1763 node = node->GetNext();
1767 wxString name = now.Format();
1768 name.Prepend(_(
"Anchorage created "));
1770 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1774 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1779 pConfig->UpdateSettings();
1783 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1787 NavObj_dB::GetInstance().Close();
1791 pConfig->DeleteGroup(_T (
"/Routes" ));
1792 pConfig->DeleteGroup(_T (
"/Marks" ));
1795 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1796 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1801 if (g_pCM93OffsetDialog) {
1802 g_pCM93OffsetDialog->Destroy();
1803 g_pCM93OffsetDialog = NULL;
1811 if (g_iENCToolbar) {
1818 if (g_pAISTargetList) {
1819 g_pAISTargetList->Disconnect_decoder();
1820 g_pAISTargetList->Destroy();
1827 if (RouteManagerDialog::getInstanceFlag()) {
1828 if (pRouteManagerDialog) {
1829 pRouteManagerDialog->Destroy();
1830 pRouteManagerDialog = NULL;
1835 if (ChartData) ChartData->PurgeCache();
1841 g_focusCanvas = NULL;
1844 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1846 if (cc) cc->Destroy();
1849 g_canvasArray.Clear();
1851 g_pauimgr->UnInit();
1861 if (ChartData) ChartData->PurgeCachePlugins();
1866 delete g_pi_manager;
1867 g_pi_manager = NULL;
1870 MyApp &app = wxGetApp();
1871 app.m_comm_bridge.SaveConfig();
1891 auto ®istry = CommDriverRegistry::GetInstance();
1892 registry.CloseAllDrivers();
1895 for (
auto *cp : TheConnectionParams()) {
1900 LayerList::iterator it;
1901 while (pLayerList->GetCount()) {
1902 Layer *lay = pLayerList->GetFirst()->GetData();
1907 ReleaseApiListeners();
1909 g_MainToolbar = NULL;
1910 g_bTempShowMenuBar =
false;
1912#define THREAD_WAIT_SECONDS 5
1918 if (g_bopengl && g_glTextureManager &&
1919 g_glTextureManager->GetRunningJobCount()) {
1920 g_glTextureManager->ClearAllRasterTextures();
1922 wxLogMessage(_T(
"Starting compressor pool drain"));
1923 wxDateTime now = wxDateTime::Now();
1924 time_t stall = now.GetTicks();
1925 time_t end = stall + THREAD_WAIT_SECONDS;
1928 while (stall < end) {
1929 wxDateTime later = wxDateTime::Now();
1930 stall = later.GetTicks();
1933 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1934 g_glTextureManager->GetRunningJobCount());
1936 if (!g_glTextureManager->GetRunningJobCount())
break;
1942 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1943 n_comploop, g_glTextureManager->GetRunningJobCount());
1946 delete g_glTextureManager;
1948 uninitIXNetSystem();
1952 wxLogMessage(_T(
"gFrame destroyed."));
1955#ifndef USE_ANDROID_GLES2
1956 qDebug() <<
"Calling OnExit()";
1960 wxTheApp->ExitMainLoop();
1963void MyFrame::OnMove(wxMoveEvent &event) {
1964 auto idx = wxDisplay::GetFromWindow(
this);
1965 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
1966 static_cast<size_t>(idx) < g_monitor_info.size()) {
1967 g_current_monitor = idx;
1973 g_current_monitor_dip_px_ratio =
1974 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
1977 DEBUG_LOG <<
"Moved to " << idx
1978#if wxCHECK_VERSION(3, 1, 6)
1979 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1980 << wxDisplay(idx).GetPPI().GetY()
1981 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1983 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1984 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1985 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1986 << wxGetDisplaySizeMM().GetY()
1987 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1988 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
1989 << g_monitor_info[idx].height_mm <<
"mm "
1990 << g_monitor_info[idx].width_mm <<
"x"
1991 << g_monitor_info[idx].height_mm <<
"mm "
1992 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
1993 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
1994 << g_monitor_info[idx].height_px <<
"px"
1995 << g_monitor_info[idx].scale <<
"%";
1996 if (g_config_display_size_manual) {
1997 if (g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
1998 g_display_size_mm = g_config_display_size_mm[idx];
2001 g_display_size_mm = g_monitor_info[idx].width_mm;
2005 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2008 cc->SetMUIBarPosition();
2017 UpdateGPSCompassStatusBoxes();
2019 if (console && console->IsShown()) PositionConsole();
2027 PositionIENCToolbar();
2033 g_nframewin_posx = GetPosition().x;
2034 g_nframewin_posy = GetPosition().y;
2037void MyFrame::ProcessCanvasResize(
void) {
2038 UpdateGPSCompassStatusBoxes(
true);
2040 if (console && console->IsShown()) PositionConsole();
2042 PositionIENCToolbar();
2045 TriggerRecaptureTimer();
2049void MyFrame::TriggerRecaptureTimer() {
2050 m_recaptureTimer.Start(
2051 1000, wxTIMER_ONE_SHOT);
2054void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
2056void MyFrame::SetCanvasSizes(wxSize frameSize) {
2057 if (!g_canvasArray.GetCount())
return;
2060 int cccw = frameSize.x;
2061 int ccch = frameSize.y;
2065 switch (g_canvasConfig) {
2069 cc = g_canvasArray.Item(0);
2071 cc->GetSize( &cur_width, &cur_height );
2072 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2073 if( g_pauimgr->GetPane( cc ).IsOk() )
2074 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2076 cc->SetSize( 0, 0, cccw, ccch );
2084 cc = g_canvasArray.Item(1);
2086 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2087 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2089 ccw = wxMin(ccw, cccw * 8 / 10);
2090 ccw = wxMax(ccw, cccw * 2 / 10);
2094 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2101 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2102 g_pauimgr->GetPane(cc).Fixed();
2103 g_pauimgr->Update();
2106 g_pauimgr->GetPane(cc).Resizable();
2118void MyFrame::OnIconize(wxIconizeEvent &event) {
2120 if (g_MainToolbar) {
2121 g_MainToolbar->Show(!event.IsIconized());
2123 if (g_iENCToolbar) {
2124 g_iENCToolbar->Show(!event.IsIconized());
2128 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2130 if (cc && cc->GetMUIBar()) {
2131 if (cc->GetMUIBar()->GetCanvasOptions()) {
2132 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2133 cc->GetMUIBar()->PushCanvasOptions();
2142void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2144void MyFrame::ODoSetSize(
void) {
2146 GetClientSize(&x, &y);
2149 if (m_pStatusBar != NULL) {
2150 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2151 int currentCount = m_pStatusBar->GetFieldsCount();
2152 if (currentCount != m_StatusBarFieldCount) {
2153 if ((currentCount > 0) && (currentCount < 7)) {
2156 int widths[] = {2, 2, 2, 2, 2, 2};
2157 m_pStatusBar->SetStatusWidths(currentCount, widths);
2160 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2163 if (m_StatusBarFieldCount) {
2168 if (m_StatusBarFieldCount > 2) {
2169 int widths[] = {-6, -5, -5, -6, -4};
2170 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2171 }
else if (m_StatusBarFieldCount == 2) {
2172 int cwidth = x * 90 / 100;
2173 int widths[] = {100, 100};
2174 widths[0] = cwidth * 6.4 / 10.0;
2175 widths[1] = cwidth * 3.6 / 10.0;
2176 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2178 int widths[] = {100, 100};
2179 widths[0] = x * 90 / 100;
2180 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2183 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2184 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2185 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2187 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2188 _T(
" COG ---\u00B0"));
2189 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2197 m_pStatusBar->GetFieldRect(0, stat_box);
2200 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2202 wxFont sys_font = *wxNORMAL_FONT;
2203 int try_font_size = sys_font.GetPointSize();
2206 int min_font_size = 10;
2216 wxFont *statusBarFont =
2217 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2218 int font_size = statusBarFont->GetPointSize();
2220 font_size = wxMin(font_size,
2223 wxMax(font_size, min_font_size);
2226 font_size = statusBarFont->GetPointSize();
2233 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2234 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2236 int min_height = stat_box.height;
2238 m_pStatusBar->SetFont(*pstat_font);
2239 m_pStatusBar->SetForegroundColour(
2240 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2242 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2244 (min_height >> 1) * 2;
2245 m_pStatusBar->SetMinHeight(min_height);
2254 SetCanvasSizes(GetClientSize());
2256 UpdateGPSCompassStatusBoxes(
true);
2258 if (console) PositionConsole();
2261 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2263 if (cc) cc->FormatPianoKeys();
2267 if (g_MainToolbar) {
2268 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2269 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2270 GetPrimaryCanvas()->GetCompass()->GetRect());
2271 g_MainToolbar->Realize();
2273 if (szBefore != g_MainToolbar->GetToolbarSize())
2274 g_MainToolbar->RefreshToolbar();
2283 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2296 options_lastWindowSize = wxSize(0, 0);
2297 options_lastWindowPos = wxPoint(0, 0);
2304 if (!b_inCloseWindow) {
2305 if (g_options) g_options->Raise();
2307 resizeAndroidPersistents();
2311 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2312 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2315 if (g_pauimgr) g_pauimgr->Update();
2318void MyFrame::PositionConsole(
void) {
2319 if (NULL == GetPrimaryCanvas())
return;
2321 int ccx, ccy, ccsx, ccsy, consx, consy;
2323 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2326 consoleHost->GetSize(&ccsx, &ccsy);
2327 consoleHost->GetPosition(&ccx, &ccy);
2329 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2330 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2331 consoleHost = GetPrimaryCanvas();
2336 if (consoleHost->GetCompass()) {
2337 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2339 if (compass_rect.y < 100)
2340 yOffset = compass_rect.y + compass_rect.height + 45;
2344 console->GetSize(&consx, &consy);
2346 wxPoint screen_pos =
2347 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2348 console->Move(screen_pos);
2351void MyFrame::UpdateAllFonts() {
2353 console->UpdateFonts();
2360 DestroyPersistentDialogs();
2362 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2367void MyFrame::DestroyPersistentDialogs() {
2368 if (g_pais_query_dialog_active) {
2369 g_pais_query_dialog_active->Hide();
2370 g_pais_query_dialog_active->Destroy();
2371 g_pais_query_dialog_active = NULL;
2374 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2375 pRoutePropDialog->Hide();
2376 pRoutePropDialog->Destroy();
2377 pRoutePropDialog = NULL;
2380 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2381 pTrackPropDialog->Hide();
2382 pTrackPropDialog->Destroy();
2383 pTrackPropDialog = NULL;
2386 if (g_pMarkInfoDialog) {
2387 g_pMarkInfoDialog->Hide();
2388 g_pMarkInfoDialog->Destroy();
2389 g_pMarkInfoDialog = NULL;
2392 if (g_pObjectQueryDialog) {
2393 g_pObjectQueryDialog->Hide();
2394 g_pObjectQueryDialog->Destroy();
2395 g_pObjectQueryDialog = NULL;
2399void MyFrame::RefreshGroupIndices(
void) {
2401 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2403 if (cc) cc->canvasRefreshGroupIndex();
2407void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2408 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2410 switch (event.GetId()) {
2411 case ID_MENU_SCALE_OUT:
2412 DoStackDelta(GetPrimaryCanvas(), 1);
2416 case ID_MENU_SCALE_IN:
2417 DoStackDelta(GetPrimaryCanvas(), -1);
2421 case ID_MENU_ZOOM_IN: {
2422 if (GetFocusCanvas()) {
2423 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2428 case ID_MENU_ZOOM_OUT: {
2429 if (GetFocusCanvas()) {
2430 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2435 case ID_MENU_ROUTE_NEW: {
2436 if (GetFocusCanvas()) {
2437 if (0 == GetFocusCanvas()->m_routeState) {
2438 GetFocusCanvas()->StartRoute();
2440 GetFocusCanvas()->FinishRoute();
2446 case ID_MENU_TOOL_MEASURE: {
2447 GetPrimaryCanvas()->StartMeasureRoute();
2451 case ID_MENU_TOOL_NMEA_DBG_LOG:
2452 m_data_monitor->Show();
2453 m_data_monitor->Raise();
2456 case ID_MENU_TOOL_IO_MONITOR:
2457 m_data_monitor->Show();
2460 case ID_MENU_MARK_BOAT: {
2465 case ID_MENU_MARK_CURSOR: {
2470 case ID_MENU_NAV_FOLLOW: {
2471 if (gFrame->GetPrimaryCanvas())
2472 gFrame->GetPrimaryCanvas()->TogglebFollow();
2476 case ID_MENU_CHART_OUTLINES: {
2477 ToggleChartOutlines(GetFocusCanvas());
2481 case ID_MENU_CHART_QUILTING: {
2482 ToggleQuiltMode(GetFocusCanvas());
2486 case ID_MENU_UI_CHARTBAR: {
2487 ToggleChartBar(GetFocusCanvas());
2491 case ID_MENU_ENC_TEXT:
2493 ToggleENCText(GetFocusCanvas());
2496 case ID_MENU_ENC_LIGHTS: {
2497 ToggleLights(GetFocusCanvas());
2500 case ID_MENU_ENC_SOUNDINGS: {
2501 ToggleSoundings(GetFocusCanvas());
2504 case ID_MENU_ENC_ANCHOR: {
2505 ToggleAnchor(GetFocusCanvas());
2508 case ID_MENU_ENC_DATA_QUALITY: {
2509 ToggleDataQuality(GetFocusCanvas());
2512 case ID_MENU_SHOW_NAVOBJECTS: {
2513 ToggleNavobjects(GetFocusCanvas());
2517 case ID_MENU_AIS_TARGETS: {
2518 ToggleAISDisplay(GetFocusCanvas());
2521 case ID_MENU_AIS_MOORED_TARGETS: {
2522 g_bHideMoored = !g_bHideMoored;
2525 case ID_MENU_AIS_SCALED_TARGETS: {
2526 ToggleAISMinimizeTargets(GetFocusCanvas());
2530 case ID_MENU_AIS_TARGETLIST: {
2531 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2535 case ID_MENU_AIS_TRACKS: {
2536 g_bAISShowTracks = !g_bAISShowTracks;
2537 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2541 case ID_MENU_AIS_CPADIALOG: {
2542 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2543 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2544 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2545 if (g_bAIS_CPA_Alert) {
2546 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2551 case ID_MENU_AIS_CPASOUND: {
2552 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2553 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2557 case ID_MENU_AIS_CPAWARNING: {
2558 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2559 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2563 case wxID_PREFERENCES:
2565 g_MainToolbar->HideTooltip();
2570 case ID_SETTINGS_NEW: {
2575 case ID_SETTINGS_DELETE: {
2577 g_options =
nullptr;
2578 g_pOptions =
nullptr;
2582 case ID_MENU_SETTINGS_BASIC: {
2585 androidDisableFullScreen();
2586 g_MainToolbar->HideTooltip();
2587 DoAndroidPreferences();
2594 case ID_MENU_UI_FULLSCREEN: {
2599 case ID_MENU_SHOW_CURRENTS: {
2600 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2601 GetFocusCanvas()->ReloadVP();
2602 GetFocusCanvas()->Refresh(
false);
2606 case ID_MENU_SHOW_TIDES: {
2607 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2608 GetFocusCanvas()->ReloadVP();
2609 GetFocusCanvas()->Refresh(
false);
2629 case ID_MENU_UI_COLSCHEME:
2630 case ID_COLSCHEME: {
2631 ToggleColorScheme();
2640 case ID_MENU_OQUIT: {
2645 case ID_MENU_ROUTE_MANAGER:
2646 case ID_ROUTEMANAGER: {
2647 pRouteManagerDialog = RouteManagerDialog::getInstance(
2650 if (pRouteManagerDialog->IsShown())
2651 pRouteManagerDialog->Hide();
2653 pRouteManagerDialog->UpdateRouteListCtrl();
2654 pRouteManagerDialog->UpdateTrkListCtrl();
2655 pRouteManagerDialog->UpdateWptListCtrl();
2656 pRouteManagerDialog->UpdateLayListCtrl();
2658 pRouteManagerDialog->Show();
2662 pRouteManagerDialog->Centre();
2663 pRouteManagerDialog->Raise();
2669 case ID_MENU_NAV_TRACK:
2671 if (!g_bTrackActive) {
2673 g_bTrackCarryOver =
true;
2676 g_bTrackCarryOver =
false;
2677 RefreshAllCanvas(
true);
2682 case ID_MENU_CHART_NORTHUP: {
2683 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2686 case ID_MENU_CHART_COGUP: {
2687 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2690 case ID_MENU_CHART_HEADUP: {
2691 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2695 case ID_MENU_MARK_MOB:
2701 case ID_MASTERTOGGLE: {
2702 if (g_MainToolbar) {
2703 wxString tip = _(
"Show Toolbar");
2704 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2705 if (g_MainToolbar->GetToolbar())
2706 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2708 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2711 if (g_bmasterToolbarFull)
2712 m_nMasterToolCountShown =
2713 g_MainToolbar->GetToolCount() -
2716 m_nMasterToolCountShown = 2;
2718 m_nMasterToolCountShown =
2719 g_MainToolbar->GetToolShowCount();
2721 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2729 case ID_CMD_SELECT_CHART_TYPE: {
2730 selectChartDisplay(event.GetExtraLong(), -1);
2734 case ID_CMD_SELECT_CHART_FAMILY: {
2735 selectChartDisplay(-1, event.GetExtraLong());
2739 case ID_CMD_APPLY_SETTINGS: {
2740 applySettingsString(event.GetString());
2742 androidRestoreFullScreen();
2748 case ID_CMD_NULL_REFRESH: {
2753 case ID_CMD_SETVP: {
2754 setStringVP(event.GetString());
2758 case ID_CMD_INVALIDATE: {
2764 case ID_CMD_POST_JSON_TO_PLUGINS: {
2770 int numErrors = reader.
Parse(event.GetString(), &root);
2771 if (numErrors == 0) {
2772 if (root[_T(
"MessageID")].IsString()) {
2773 wxString MsgID = root[_T(
"MessageID")].
AsString();
2784 if (g_iENCToolbar) {
2785 g_iENCToolbar->OnToolLeftClick(event);
2795 g_MainToolbar->HideTooltip();
2797 ArrayOfPlugInToolbarTools tool_array =
2798 g_pi_manager->GetPluginToolbarToolArray();
2799 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2801 if (event.GetId() == pttc->id) {
2802 if (pttc->m_pplugin)
2821 if (g_MainToolbar) g_MainToolbar->Realize();
2824bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2825 bool viz_now = g_bmasterToolbarFull;
2827 g_MainToolbar->HideTooltip();
2828 wxString tip = _(
"Show Toolbar");
2830 tip = _(
"Hide Toolbar");
2831 if (g_MainToolbar->GetToolbar())
2832 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2835 bool toggle =
false;
2836 if (viz && !g_bmasterToolbarFull)
2839 else if (!viz && g_bmasterToolbarFull)
2843 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2846 if (g_bmasterToolbarFull)
2847 m_nMasterToolCountShown =
2848 g_MainToolbar->GetToolCount() -
2851 m_nMasterToolCountShown = 2;
2853 m_nMasterToolCountShown =
2854 g_MainToolbar->GetToolShowCount();
2856 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2862void MyFrame::ScheduleDeleteSettingsDialog() {
2863 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2864 evt.SetId(ID_SETTINGS_DELETE);
2865 GetEventHandler()->AddPendingEvent(evt);
2868void MyFrame::ScheduleSettingsDialog() {
2869 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2870 evt.SetId(ID_SETTINGS);
2871 GetEventHandler()->AddPendingEvent(evt);
2874void MyFrame::ScheduleSettingsDialogNew() {
2875 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2876 evt.SetId(ID_SETTINGS_NEW);
2877 GetEventHandler()->AddPendingEvent(evt);
2880void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2881 UpdateCanvasConfigDescriptors();
2883 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2884 CreateCanvasLayout(
true);
2886 CreateCanvasLayout();
2888 g_pauimgr->Update();
2890 ConfigureStatusBar();
2891 wxSize lastOptSize = options_lastWindowSize;
2896 options_lastWindowSize = lastOptSize;
2900 ScheduleSettingsDialogNew();
2902 ScheduleSettingsDialog();
2907 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2910 int index_hint = -1;
2911 if (i < pathArray.GetCount())
2912 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
2913 cc->canvasChartsRefresh(index_hint);
2914 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2920 if ((g_canvasConfig != 0) && g_focusCanvas)
2921 return g_focusCanvas;
2923 return GetPrimaryCanvas();
2926void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2927 if (g_bmasterToolbarFull) {
2928#ifndef OCPN_TOOLBAR_ANIMATE
2929 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
2932 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
2933 m_nMasterToolCountShown++;
2934 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2935 g_MainToolbar->Realize();
2936 g_MainToolbar->RefreshToolbar();
2938 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2940 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2941 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2942 g_MainToolbar->Realize();
2943 g_MainToolbar->RefreshToolbar();
2946#ifndef OCPN_TOOLBAR_ANIMATE
2947 m_nMasterToolCountShown = 1;
2949 if (m_nMasterToolCountShown > 1) {
2950 m_nMasterToolCountShown--;
2951 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2952 g_MainToolbar->Realize();
2953 g_MainToolbar->RefreshToolbar();
2954 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2956 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2957 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2958 g_MainToolbar->Realize();
2959 g_MainToolbar->RefreshToolbar();
2964void MyFrame::InvalidateAllGL() {
2967 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2977void MyFrame::RefreshAllCanvas(
bool bErase) {
2979 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2982 cc->Refresh(bErase);
2987void MyFrame::setStringVP(wxString VPS) {
2992 wxStringTokenizer tkz(VPS, _T(
";"));
2994 wxString token = tkz.GetNextToken();
2996 token.ToDouble(&lat);
2998 token = tkz.GetNextToken();
3000 token.ToDouble(&lon);
3002 token = tkz.GetNextToken();
3004 token.ToDouble(&scale_ppm);
3006 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
3009void MyFrame::DoSettingsNew() {
3011 g_options =
nullptr;
3016void MyFrame::DoSettings() {
3020 ApplyGlobalSettings(
true);
3023 bool b_loadHarmonics =
false;
3024 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3027 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3030 if (b_loadHarmonics) LoadHarmonics();
3038 g_bShowChartBar = !g_bShowChartBar;
3040 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3045 if (g_bShowChartBar) {
3047 UpdateControlBar(cc);
3050 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3053void MyFrame::ToggleColorScheme() {
3054 static bool lastIsNight;
3055 ColorScheme s = GetColorScheme();
3058 if (lastIsNight && is == 3)
3061 lastIsNight =
false;
3063 if (lastIsNight) is = 2;
3064 if (is == 3) lastIsNight =
true;
3065 s = (ColorScheme)is;
3066 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3068 SetAndApplyColorScheme(s);
3071void MyFrame::ToggleFullScreen() {
3072 bool to = !IsFullScreen();
3077 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3079 ShowFullScreen(to, style);
3082 UpdateAllToolbars(global_color_scheme);
3084 UpdateControlBar(GetPrimaryCanvas());
3086 TriggerRecaptureTimer();
3089void MyFrame::ActivateMOB(
void) {
3091 wxDateTime mob_time = wxDateTime::Now();
3092 wxString mob_label(_(
"MAN OVERBOARD"));
3093 mob_label += _(
" on ");
3094 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3097 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3098 pWP_MOB->SetShared(
true);
3100 pWP_MOB->SetWaypointArrivalRadius(
3102 pWP_MOB->SetUseSca(
false);
3103 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3104 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3106 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3109 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3112 new RoutePoint(zlat, zlon, g_default_wp_icon,
3113 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3114 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3117 pRouteList->Append(temp_route);
3119 temp_route->AddPoint(pWP_src);
3120 temp_route->AddPoint(pWP_MOB);
3122 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3132 temp_route->SetRouteArrivalRadius(-1.0);
3134 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3138 v[_T(
"GUID")] = temp_route->
m_GUID;
3139 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
3140 SendJSONMessageToAllPlugins(msg_id, v);
3143 if (RouteManagerDialog::getInstanceFlag()) {
3144 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3145 pRouteManagerDialog->UpdateRouteListCtrl();
3146 pRouteManagerDialog->UpdateWptListCtrl();
3151 RefreshAllCanvas(
false);
3153 wxString mob_message(_(
"MAN OVERBOARD"));
3154 mob_message += _(
" Time: ");
3155 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3156 mob_message += _(
" Position: ");
3157 mob_message += toSDMM(1, gLat);
3158 mob_message += _T(
" ");
3159 mob_message += toSDMM(2, gLon);
3160 wxLogMessage(mob_message);
3162void MyFrame::TrackOn(
void) {
3163 g_bTrackActive =
true;
3166 g_TrackList.push_back(g_pActiveTrack);
3167 NavObj_dB::GetInstance().InsertTrack(g_pActiveTrack);
3168 g_pActiveTrack->Start();
3171 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3173 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3175 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3178 androidSetTrackTool(
true);
3181 if (RouteManagerDialog::getInstanceFlag()) {
3182 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3183 pRouteManagerDialog->UpdateTrkListCtrl();
3184 pRouteManagerDialog->UpdateRouteListCtrl();
3189 wxString name = g_pActiveTrack->GetName();
3190 if (name.IsEmpty()) {
3191 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3196 name = _(
"(Unnamed Track)");
3198 v[_T(
"Name")] = name;
3199 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3200 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3201 SendJSONMessageToAllPlugins(msg_id, v);
3202 g_FlushNavobjChangesTimeout =
3206Track *MyFrame::TrackOff(
bool do_add_point) {
3207 Track *return_val = g_pActiveTrack;
3209 if (g_pActiveTrack) {
3211 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3212 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3213 SendJSONMessageToAllPlugins(msg_id, v);
3215 g_pActiveTrack->Stop(do_add_point);
3217 if (g_pActiveTrack->GetnPoints() < 2) {
3218 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3219 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3222 if (g_bTrackDaily) {
3223 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3225 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3226 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3227 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3228 return_val = pExtendTrack;
3232 g_pActiveTrack = NULL;
3235 g_bTrackActive =
false;
3237 if (RouteManagerDialog::getInstanceFlag()) {
3238 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3239 pRouteManagerDialog->UpdateTrkListCtrl();
3240 pRouteManagerDialog->UpdateRouteListCtrl();
3244 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3246 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3247 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3250 androidSetTrackTool(
false);
3253 g_FlushNavobjChangesTimeout =
3259bool MyFrame::ShouldRestartTrack(
void) {
3260 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3261 time_t now = wxDateTime::Now().GetTicks();
3262 time_t today = wxDateTime::Today().GetTicks();
3264 switch (g_track_rotate_time_type) {
3266 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3268 case TIME_TYPE_COMPUTER:
3269 rotate_at = g_track_rotate_time;
3273 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3274 rotate_at = g_track_rotate_time + utc_offset;
3277 if (rotate_at > 86400)
3279 else if (rotate_at < 0)
3281 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3282 now - today >= rotate_at) {
3283 if (m_last_track_rotation_ts == 0) {
3284 if (now - today > rotate_at)
3285 m_last_track_rotation_ts = today + rotate_at;
3287 m_last_track_rotation_ts = today + rotate_at - 86400;
3290 m_last_track_rotation_ts = now;
3296void MyFrame::TrackDailyRestart(
void) {
3297 if (!g_pActiveTrack)
return;
3298 Track *pPreviousTrack = TrackOff(
true);
3305 if (pPreviousTrack) {
3306 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3307 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3310 if (RouteManagerDialog::getInstanceFlag()) {
3311 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3312 pRouteManagerDialog->UpdateTrkListCtrl();
3313 pRouteManagerDialog->UpdateRouteListCtrl();
3318void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3320 cc->SetUpMode(mode);
3322 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3323 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3324 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3327 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3332 cc->SetShowENCText(!cc->GetShowENCText());
3334 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3342void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3345 cc->SetENCDisplayCategory(nset);
3347 UpdateGlobalMenuItems();
3358 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3360 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3369 cc->SetShowENCLights(!cc->GetShowENCLights());
3371 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3373 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3381void MyFrame::ToggleRocks(
void )
3387 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3388 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3389 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3390 pOLE->nViz = !pOLE->nViz;
3394 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3395 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3396 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3399 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3403 ps52plib->GenerateStateHash();
3410 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3412 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3414 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3420 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3422 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3424 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3437 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3438 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3443 cc->SetShowAIS(!cc->GetShowAIS());
3444 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3448void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3449 cc->SetAttenAIS(!cc->GetAttenAIS());
3450 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3456 cc->m_bFollow =
true;
3459 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3463 SetChartUpdatePeriod();
3471 cc->m_bFollow =
false;
3473 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3477 SetChartUpdatePeriod();
3480void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3481 cc->SetShowOutlines(!cc->GetShowOutlines());
3483 RefreshAllCanvas(
false);
3487 if (g_bopengl) InvalidateAllGL();
3490 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3493void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3495void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3497 bool enabled = m_pMenuBar->IsEnabled(item_id);
3498 m_pMenuBar->Enable(item_id,
false);
3499 m_pMenuBar->Check(item_id, state);
3500 m_pMenuBar->Enable(item_id, enabled);
3504void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3505 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3506 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3507 g_MainToolbar->Realize();
3511void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3512 wxBitmap *bmpRollover) {
3513 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3514 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3515 g_MainToolbar->Realize();
3519void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3520 wxString rolloverSVGfile,
3521 wxString toggledSVGfile) {
3522 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3523 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3524 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3528void MyFrame::ConfigureStatusBar() {
3530 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3533 UseNativeStatusBar(
false);
3536 if (g_bShowStatusBar) {
3537 if (!m_pStatusBar) {
3539 CreateStatusBar(m_StatusBarFieldCount, 0);
3540 ApplyGlobalColorSchemetoStatusBar();
3545 m_pStatusBar->Destroy();
3546 m_pStatusBar = NULL;
3552void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3553 ConfigureStatusBar();
3555 wxSize lastOptSize = options_lastWindowSize;
3561 options_lastWindowSize = lastOptSize;
3563 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3566wxString _menuText(wxString name, wxString shortcut) {
3570 menutext << _T(
"\t") << shortcut;
3575void MyFrame::BuildMenuBar(
void) {
3581 bool showMenuBar =
true;
3583 bool showMenuBar = g_bShowMenuBar;
3595 m_pMenuBar =
new wxMenuBar();
3596 RegisterGlobalMenuItems();
3597 SetMenuBar(m_pMenuBar);
3601 UpdateGlobalMenuItems();
3606 m_pMenuBar->Destroy();
3612void MyFrame::RegisterGlobalMenuItems() {
3613 if (!m_pMenuBar)
return;
3615 wxMenu *nav_menu =
new wxMenu();
3616 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3617 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3618 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3619 nav_menu->AppendSeparator();
3620 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3621 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3622 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3623 nav_menu->AppendSeparator();
3625 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3626 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3628 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3629 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3631 nav_menu->AppendSeparator();
3632 nav_menu->Append(ID_MENU_SCALE_IN,
3633 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3634 nav_menu->Append(ID_MENU_SCALE_OUT,
3635 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3637 nav_menu->AppendSeparator();
3638 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3640 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3642 wxMenu *view_menu =
new wxMenu();
3644 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3645 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3646 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3647 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3649 view_menu->AppendCheckItem(
3650 ID_MENU_CHART_QUILTING,
3651 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3652 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3653 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3655 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3656 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3658 view_menu->AppendSeparator();
3660 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3661 _menuText(_(
"Show ENC text"), _T(
"T")));
3662 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3663 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3664 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3665 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3666 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3667 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3668 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3669 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3670 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3671 _menuText(_(
"Show Navobjects"), _T(
"V")));
3673 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3674 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3675 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3676 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3677 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3678 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3679 view_menu->AppendCheckItem(
3680 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3681 view_menu->AppendCheckItem(
3682 ID_MENU_ENC_DATA_QUALITY,
3683 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3684 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3685 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3687 view_menu->AppendSeparator();
3688 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3689 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3690 view_menu->AppendSeparator();
3692 view_menu->Append(ID_MENU_UI_COLSCHEME,
3693 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3695 view_menu->Append(ID_MENU_UI_COLSCHEME,
3696 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3699 view_menu->AppendSeparator();
3701 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3702 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3704 m_pMenuBar->Append(view_menu, _(
"&View"));
3706 wxMenu *ais_menu =
new wxMenu();
3707 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3708 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3709 _(
"Attenuate less critical AIS targets"));
3710 ais_menu->AppendSeparator();
3711 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3712 _(
"Hide Moored AIS Targets"));
3713 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3714 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3715 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3718 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3719 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3721 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3722 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3725 ais_menu->AppendSeparator();
3726 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3727 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3729 wxMenu *tools_menu =
new wxMenu();
3730 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3731 _menuText(_(
"Data Monitor"),
"Alt-C"));
3733 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3734 _menuText(_(
"Measure Distance"), _T(
"M")));
3736 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3737 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3740 tools_menu->AppendSeparator();
3741 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3742 tools_menu->Append(ID_MENU_ROUTE_NEW,
3743 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3744 tools_menu->AppendSeparator();
3745 tools_menu->Append(ID_MENU_MARK_BOAT,
3746 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3747 tools_menu->Append(ID_MENU_MARK_CURSOR,
3748 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3749 tools_menu->AppendSeparator();
3754 _(
"Drop MOB Marker"),
3755 _T(
"RawCtrl-Space")));
3756 tools_menu->AppendSeparator();
3757 tools_menu->Append(wxID_PREFERENCES,
3758 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3760 tools_menu->Append(ID_MENU_MARK_MOB,
3761 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3762 tools_menu->AppendSeparator();
3763 tools_menu->Append(wxID_PREFERENCES,
3764 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3766 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3769 wxMenu *window_menu =
new wxMenu();
3770 m_pMenuBar->Append(window_menu, _(
"&Window"));
3773 wxMenu *help_menu =
new wxMenu();
3774 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3775 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3776 m_pMenuBar->Append(help_menu, _(
"&Help"));
3779 UpdateGlobalMenuItems();
3782void MyFrame::UpdateGlobalMenuItems() {
3783 if (!m_pMenuBar)
return;
3785 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3786 ->Check(GetPrimaryCanvas()->m_bFollow);
3787 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3788 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3789 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3790 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3791 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3792 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3793 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3794 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3795 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3796 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3797 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3798 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3799 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3800 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3801 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3802 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3803 if (g_bAIS_CPA_Alert) {
3804 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3805 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3807 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3808 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3811 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3812 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3813 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3816 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3817 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3818 ->Check(ps52plib->GetShowSoundings());
3820 bool light_state =
false;
3822 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3824 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3825 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3826 light_state = (pOLE->nViz == 1);
3831 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3832 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3836 DisCat nset = ps52plib->GetDisplayCategory();
3837 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3838 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3839 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3840 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3841 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3842 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3843 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3845 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3846 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3847 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3852void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3853 if (!m_pMenuBar)
return;
3855 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3857 if (cc->GetUpMode() == NORTH_UP_MODE)
3858 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3859 else if (cc->GetUpMode() == COURSE_UP_MODE)
3860 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3862 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3864 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3865 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3866 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3867 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3868 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3869 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3870 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3871 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3872 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3873 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3874 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3875 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3876 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3877 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3878 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3881 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3882 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3885 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3887 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3888 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3893 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3897 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3898 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3899 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3900 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3901 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3902 ->Check(cc->GetShowENCDataQual());
3903 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3905 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3906 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3907 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3912void MyFrame::InvalidateAllCanvasUndo() {
3914 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3916 if (cc) cc->undo->InvalidateUndo();
3920void MyFrame::SubmergeAllCanvasToolbars(
void) {
3922 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3924 if (cc) cc->SubmergeToolbar();
3928void MyFrame::SurfaceAllCanvasToolbars(
void) {
3929 if (g_bshowToolbar) {
3931 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3933 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3940void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3942 if (lon > 180.0) lon -= 360.0;
3947 cc->JumpToPosition(lat, lon,
scale);
3950 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3954void MyFrame::UpdateCanvasConfigDescriptors() {
3956 for (
unsigned int i = 0;
3957 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3958 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3966 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3967 cc->GroupID = chart->m_groupIndex;
3970 cc->
bQuilt = chart->GetQuiltMode();
3977 cc->
bFollow = chart->m_bFollow;
3982 int upmode = chart->GetUpMode();
3983 if (upmode == COURSE_UP_MODE)
3985 else if (upmode == HEAD_UP_MODE)
3992void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3993 if (!RBBox.GetValid())
return;
3995 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3996 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3999 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
4000 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
4008 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4009 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
4011 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4012 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
4014 cc->GetSize(&ww, &wh);
4016 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4018 ppm = wxMin(ppm, 1.0);
4024void MyFrame::PrepareOptionsClose(
options *settings,
4025 int settings_return_value) {
4027 options_lastPage = settings->lastPage;
4032 if (options_lastPage == 1) options_lastPage = 0;
4034 options_subpage = settings->lastSubPage;
4035 options_lastWindowPos = settings->lastWindowPos;
4036 options_lastWindowSize = settings->lastWindowSize;
4039 androidEnableBackButton(
true);
4040 androidEnableOptionsMenu(
true);
4041 androidRestoreFullScreen();
4042 androidEnableRotation();
4046void MyFrame::DoOptionsDialog() {
4047 if (NULL == g_options) {
4048 AbstractPlatform::ShowBusySpinner();
4051 pConfig->SetPath(
"/Settings");
4052 pConfig->Read(
"OptionsSizeX", &sx, -1);
4053 pConfig->Read(
"OptionsSizeY", &sy, -1);
4055 wxWindow *optionsParent =
this;
4057 optionsParent = GetPrimaryCanvas();
4059 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4062 AbstractPlatform::HideBusySpinner();
4066 g_options->SetInitChartDir(*pInit_Chart_Dir);
4069 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
4070 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4071 g_options->SetWorkDirListPtr(pWorkDirArray);
4074 g_options->SetConfigPtr(pConfig);
4075 g_options->SetInitialSettings();
4077 prev_locale = g_locale;
4078 g_options->SetInitialPage(options_lastPage, options_subpage);
4081 g_options->lastWindowPos = options_lastWindowPos;
4082 if (options_lastWindowPos != wxPoint(0, 0)) {
4083 g_options->Move(options_lastWindowPos);
4084 g_options->SetSize(options_lastWindowSize);
4086 g_options->CenterOnScreen();
4088 if (options_lastWindowSize != wxSize(0, 0)) {
4089 g_options->SetSize(options_lastWindowSize);
4094 androidEnableBackButton(
false);
4095 androidEnableOptionsMenu(
false);
4096 androidDisableFullScreen();
4104 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4107 wxString chart_file_name;
4108 if (cc->GetQuiltMode()) {
4109 int dbi = cc->GetQuiltRefChartdbIndex();
4110 chart_file_name = ChartData->GetDBChartFileName(dbi);
4112 if (cc->m_singleChart)
4113 chart_file_name = cc->m_singleChart->GetFullPath();
4116 pathArray.Add(chart_file_name);
4122 last_canvasConfig = g_canvasConfig;
4125 g_last_ChartScaleFactor = g_ChartScaleFactor;
4131void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4132 bool b_need_refresh =
false;
4134 if ((rr & VISIT_CHARTS) &&
4135 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4137 UpdateChartDatabaseInplace(*pNewDirArray,
4138 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4141 b_need_refresh =
true;
4145 if (rr & STYLE_CHANGED) {
4148 _(
"Please restart OpenCPN to activate language or style changes."),
4149 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4152 bool b_groupchange =
false;
4153 if (((rr & VISIT_CHARTS) &&
4154 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4155 (rr & GROUPS_CHANGED)) {
4156 b_groupchange = ScrubGroupArray();
4157 ChartData->ApplyGroupArray(g_pGroupArray);
4158 RefreshGroupIndices();
4161 if (rr & GROUPS_CHANGED || b_groupchange) {
4162 pConfig->DestroyConfigGroups();
4163 pConfig->CreateConfigGroups(g_pGroupArray);
4166 if (rr & TIDES_CHANGED) {
4172 if (rr & S52_CHANGED) {
4173 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4176 pConfig->UpdateSettings();
4178 if (g_pActiveTrack) {
4179 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4183 g_pRouteMan->SetColorScheme(global_color_scheme,
4184 g_Platform->GetDisplayDPmm());
4187 double stuffcog = NAN;
4188 double stuffsog = NAN;
4189 if (!std::isnan(gCog)) stuffcog = gCog;
4190 if (!std::isnan(gSog)) stuffsog = gSog;
4192 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4193 COGFilterTable[i] = stuffcog;
4194 SOGFilterTable[i] = stuffsog;
4197 SetChartUpdatePeriod();
4199 if (rr & GL_CHANGED) {
4203 b_need_refresh =
true;
4206 if (rr & S52_CHANGED) {
4207 b_need_refresh =
true;
4211 if (rr & REBUILD_RASTER_CACHE) {
4212 if (g_glTextureManager) {
4213 GetPrimaryCanvas()->Disable();
4214 g_glTextureManager->BuildCompressedCache();
4215 GetPrimaryCanvas()->Enable();
4220 if (g_config_display_size_manual &&
4221 g_config_display_size_mm.size() > g_current_monitor &&
4222 g_config_display_size_mm[g_current_monitor] > 0) {
4223 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4228 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4234 g_pi_manager->SendBaseConfigToAllPlugIns();
4235 int rrt = rr & S52_CHANGED;
4236 g_pi_manager->SendS52ConfigToAllPlugIns(
4237 (rrt == S52_CHANGED) ||
4238 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4241 if (g_MainToolbar) {
4242 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4243 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4248 ps52plib->SetScaleFactorExp(
4249 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4250 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4254 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4256 if (cc) cc->ApplyGlobalSettings();
4261 bool ztc = g_bEnableZoomToCursor;
4262 g_bEnableZoomToCursor =
4267 g_bEnableZoomToCursor = ztc;
4270 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4271 if (g_pMarkInfoDialog) {
4272 g_pMarkInfoDialog->Hide();
4273 g_pMarkInfoDialog->Destroy();
4274 g_pMarkInfoDialog = NULL;
4279 SetGPSCompassScale();
4281 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4284 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4285 cc->UpdateCanvasControlBar();
4288 UpdateGPSCompassStatusBoxes();
4290 SetAllToolbarScale();
4291 RequestNewToolbars();
4294 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4297 cc->RebuildCursors();
4302 bool b_masterScaleChange =
false;
4303 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4304 b_masterScaleChange =
true;
4306 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4307 RequestNewMasterToolbar(
true);
4309 bool bMuiChange =
false;
4315 if (b_masterScaleChange || bMuiChange) {
4317 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4320 cc->ProcessNewGUIScale();
4326 if (rr & LOCALE_CHANGED) {
4327 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4329 rr |= NEED_NEW_OPTIONS;
4334 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4338 g_last_ChartScaleFactor = g_ChartScaleFactor;
4343bool MyFrame::CheckGroup(
int igroup) {
4344 if (igroup == 0)
return true;
4346 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4348 if (!pGroup->m_element_array.size())
4351 for (
const auto &elem : pGroup->m_element_array) {
4352 for (
unsigned int ic = 0;
4353 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4355 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4357 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4364bool MyFrame::ScrubGroupArray() {
4369 bool b_change =
false;
4370 unsigned int igroup = 0;
4371 while (igroup < g_pGroupArray->GetCount()) {
4372 bool b_chart_in_element =
false;
4373 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4375 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4376 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4378 for (
unsigned int ic = 0;
4379 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4381 wxString chart_full_path = pcte->GetFullSystemPath();
4383 if (chart_full_path.StartsWith(element_root)) {
4384 b_chart_in_element =
true;
4390 if (!b_chart_in_element) {
4391 wxString test_string = _T(
"GSHH");
4392 if (element_root.Upper().Contains(test_string))
4393 b_chart_in_element =
true;
4396 if (!b_chart_in_element)
4398 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4410void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4412 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4414 if (cc && (cc != ccThis)) cc->Refresh();
4419void MyFrame::ChartsRefresh() {
4420 if (!ChartData)
return;
4422 AbstractPlatform::ShowBusySpinner();
4424 bool b_run = FrameTimer1.IsRunning();
4427 FrameTenHzTimer.Stop();
4430 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4433 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4434 if (cc->GetQuiltMode()) {
4435 currentIndex = cc->GetQuiltReferenceChartIndex();
4437 cc->canvasChartsRefresh(currentIndex);
4441 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4442 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4444 AbstractPlatform::HideBusySpinner();
4447void MyFrame::InvalidateAllQuilts() {
4448 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4451 cc->InvalidateQuilt();
4452 cc->SetQuiltRefChart(-1);
4453 cc->m_singleChart = NULL;
4458bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4460 const wxString &ChartListFileName) {
4461 bool b_run = FrameTimer1.IsRunning();
4463 FrameTenHzTimer.Stop();
4465 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4466 FrameCOGTimer.Stop();
4469 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4472 cc->InvalidateQuilt();
4473 cc->SetQuiltRefChart(-1);
4474 cc->m_singleChart = NULL;
4478 ChartData->PurgeCache();
4484 AbstractPlatform::ShowBusySpinner();
4486 wxGenericProgressDialog *pprog =
nullptr;
4488 wxString longmsg = _(
"OpenCPN Chart Update");
4490 _T(
"..................................................................")
4493 pprog = new wxGenericProgressDialog();
4496 pprog->SetFont(*qFont);
4498 pprog->Create(_("OpenCPN
Chart Update"), longmsg, 100, gFrame,
4499 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4500 wxPD_REMAINING_TIME);
4506 wxLogMessage(_T(" "));
4507 wxLogMessage(_T("Starting chart database Update..."));
4508 wxString gshhg_chart_loc = gWorldMapLocation;
4509 gWorldMapLocation = wxEmptyString;
4512 ChartData->Update(DirArray, b_force, pprog);
4513 ChartData->SaveBinary(ChartListFileName);
4514 wxLogMessage(_T("Finished chart database Update"));
4515 wxLogMessage(_T(" "));
4516 if (gWorldMapLocation.empty()) {
4520 gWorldMapLocation = gDefaultWorldMapLocation;
4521 gshhg_chart_loc = wxEmptyString;
4524 if (gWorldMapLocation != gshhg_chart_loc) {
4526 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4528 if (cc) cc->ResetWorldBackgroundChart();
4531 gshhsCrossesLandReset();
4536 AbstractPlatform::HideBusySpinner();
4538 pConfig->UpdateChartDirs(DirArray);
4541 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4542 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4544 if (b_runCOGTimer) {
4546 int period_ms = 100;
4547 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4548 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4555 cc->ToggleCanvasQuiltMode();
4557 bool cur_mode = cc->GetQuiltMode();
4559 if( !cc->GetQuiltMode() )
4560 cc->SetQuiltMode(
true );
4562 if( cc->GetQuiltMode() ) {
4563 cc->SetQuiltMode(
false );
4564 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4568 if( cur_mode != cc->GetQuiltMode() ){
4574 g_bQuiltEnable = cc->GetQuiltMode();
4578 ps52plib->GenerateStateHash();
4583void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4585void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4587void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4589 cc->DoCanvasStackDelta(direction);
4593void MyFrame::PositionIENCToolbar() {
4595 if (g_iENCToolbar) {
4597 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4599 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4607void MyFrame::OnInitTimer(wxTimerEvent &event) {
4610 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4613 wxLog::FlushActive();
4615 switch (m_iInitCount++) {
4617 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4619 if (g_bInlandEcdis) {
4620 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4621 double range_set = 500.;
4623 range = wxRound(range * 10) / 10.;
4627 else if (range > 2000.)
4629 else if (range > 1600.)
4631 else if (range > 1200.)
4633 else if (range > 800.)
4638 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4642 g_Platform->SetFullscreen(g_bFullscreen);
4645 if (g_NeedDBUpdate > 0) {
4646 RebuildChartDatabase();
4647 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4650 cc->SetGroupIndex(0,
false);
4658 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4659 CHART_FAMILY_RASTER)) {
4662 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4664 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4665 CHART_FAMILY_VECTOR)) {
4668 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4677 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4680 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4682 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4685 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4689 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4690 NavObj_dB::GetInstance().LoadNavObjects();
4693 if (!g_AW1GUID.IsEmpty()) {
4694 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4696 if (!g_AW2GUID.IsEmpty()) {
4697 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4702 appendOSDirSlash(&layerdir);
4703 layerdir.Append(_T(
"layers"));
4705 if (wxDir::Exists(layerdir)) {
4707 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4709 wxLogMessage(laymsg);
4710 pConfig->LoadLayers(layerdir);
4718 for (
auto *cp : TheConnectionParams()) {
4721 cp->b_IsSetup = TRUE;
4726 console->SetColorScheme(global_color_scheme);
4730 if (g_pRouteMan->IsAnyRouteActive()) {
4731 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
4738 if (m_initializing)
break;
4739 m_initializing =
true;
4740 AbstractPlatform::ShowBusySpinner();
4742 AbstractPlatform::HideBusySpinner();
4744 RequestNewMasterToolbar();
4747 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4749 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4751 wxString perspective;
4752 pConfig->SetPath(_T (
"/AUI" ));
4753 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4760 bool bno_load =
false;
4762 wxArrayString name_array;
4763 wxStringTokenizer st(perspective, _T(
"|;"));
4764 while (st.HasMoreTokens()) {
4765 wxString s1 = st.GetNextToken();
4766 if (s1.StartsWith(_T(
"name="))) {
4767 wxString sc = s1.AfterFirst(
'=');
4772 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4773 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4774 wxAuiPaneInfo pane = pane_array_val.Item(i);
4778 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4784 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4788 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4791 g_pauimgr->GetPane(cc).MinSize(10,10);
4798 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4801 wxSize frameSize = GetClientSize();
4802 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4803 int width = wxMax(minSize.x, frameSize.x / 10);
4804 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4807 g_pauimgr->Update();
4811 g_pi_manager->NotifyAuiPlugIns();
4814 g_pi_manager->ShowDeferredBlacklistMessages();
4816 g_pi_manager->CallLateInit();
4821 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4822 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4824 if (cc) cc->SetFirstAuto(
true);
4827 b_reloadForPlugins =
true;
4834 if (g_MainToolbar) {
4835 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4836 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4841 m_data_monitor->Move(g_MainToolbar->GetToolbarRect().x +
4842 g_MainToolbar->GetToolbarRect().width,
4843 3 * GetCharHeight());
4845 m_data_monitor->Center();
4853 pConfig->SetPath(
"/Settings");
4854 pConfig->Read(
"OptionsSizeX", &sx, -1);
4855 pConfig->Read(
"OptionsSizeY", &sy, -1);
4857 wxWindow *optionsParent =
this;
4859 optionsParent = GetPrimaryCanvas();
4861 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4864 BuildiENCToolbar(
true);
4871 if (!g_params.empty()) {
4872 for (
size_t n = 0; n < g_params.size(); n++) {
4873 wxString path = g_params[n];
4874 if (::wxFileExists(path)) {
4876 pSet->load_file(path.fn_str());
4879 pSet->LoadAllGPXObjects(
4880 !pSet->IsOpenCPN(), wpt_dups,
4882 LLBBox box = pSet->GetBBox();
4883 if (box.GetValid()) {
4884 CenterView(GetPrimaryCanvas(), box);
4893 InitAppMsgBusListener();
4898 auto loader = PluginLoader::GetInstance();
4899 bool b_haveWMM = loader && loader->IsPlugInAvailable(_T(
"WMM"));
4900 if (!b_haveWMM) gVar = g_UserVar;
4907 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4909 PositionIENCToolbar();
4911 g_bDeferredInitDone =
true;
4913 GetPrimaryCanvas()->SetFocus();
4914 g_focusCanvas = GetPrimaryCanvas();
4920 if (b_reloadForPlugins) {
4925 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4927 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4931 cc->CheckGroupValid();
4936 androidEnableBackButton(
true);
4937 androidEnableRotation();
4938 androidEnableOptionItems(
true);
4942 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
4951 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
4953 wxLog::FlushActive();
4955 RefreshAllCanvas(
true);
4956 wxGetApp().m_usb_watcher.Start();
4962void MyFrame::InitAppMsgBusListener() {
4963 auto &msgbus = AppMsgBus::GetInstance();
4966 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4967 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4971 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4972 HandleBasicNavMsg(basicnav_msg);
4976 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4977 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4981 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4982 HandleGPSWatchdogMsg(msg);
4989void MyFrame::ReleaseApiListeners() {}
4994 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4995 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4996 server.SetGetRestApiEndpointCb(
4997 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4998 server.open_file_cb = [](
const std::string &path) {
4999 return wxGetApp().OpenFile(path);
5006void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
5007 if (msg->gps_watchdog <= 0) {
5008 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
5009 bool last_bGPSValid = bGPSValid;
5012 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5017 if (m_fix_start_time.IsValid()) {
5018 wxDateTime now = wxDateTime::Now();
5019 wxTimeSpan span = now - m_fix_start_time;
5020 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
5021 auto ¬eman = NotificationManager::GetInstance();
5022 wxString msg = _(
"GNSS Position fix lost");
5023 noteman.AddNotification(NotificationSeverity::kCritical,
5025 m_fix_start_time = wxInvalidDateTime;
5029 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
5030 bool last_bVelocityValid = bVelocityValid;
5031 bVelocityValid =
false;
5038void MyFrame::CalculateCOGAverage() {
5040 if (!std::isnan(gCog)) {
5041 if (g_COGAvgSec > 0) {
5043 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5046 double sum = 0., count = 0;
5047 for (
int i = 0; i < g_COGAvgSec; i++) {
5048 double adder = COGTable[i];
5049 if (std::isnan(adder))
continue;
5051 if (fabs(adder - g_COGAvg) > 180.) {
5052 if ((adder - g_COGAvg) > 0.)
5065 else if (sum >= 360.)
5074void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5075 m_fixtime = msg->time;
5076 double hdt_data_interval = 0;
5077 double fix_time_interval = 0;
5079 double msgtime = msg->set_time.tv_sec;
5080 double m1 = msg->set_time.tv_nsec / 1e9;
5083 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5084 ((msg->vflag & POS_VALID) == POS_VALID)) {
5086 if (!m_fix_start_time.IsValid()) {
5087 m_fix_start_time = wxDateTime::Now();
5092 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5095 fix_time_gt_last = fix_time_gt;
5096 uint64_t fix_time_gt_now =
5097 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5098 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5102 double implied_sog = dist / (fix_time_interval / 3600);
5107 gLat_gt_m1 = gLat_gt;
5108 gLon_gt_m1 = gLon_gt;
5112 fix_time_gt = fix_time_gt_now;
5116 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5117 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5118 gCog_gt_m1 = gCog_gt;
5128 if (!std::isnan(gCog_gt_m1)) {
5130 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5137 if ((fix_time_gt - fix_time_gt_last) > .08) {
5142 if (gCog_gt > gCog_gt_m1) {
5143 if ((gCog_gt - gCog_gt_m1) > 180.)
5148 if ((gCog_gt_m1 - gCog_gt) > 180.)
5153 difft = fabs(gCog_gt - gCog_gt_m1);
5154 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5162 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5163 tentative_cog_rate_gt *= 1e9;
5164 cog_rate_gt = tentative_cog_rate_gt;
5172 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5175static double hdt_avg;
5176 double hdt_norm = gHdt;
5177 if(gHdt > 180) hdt_norm -= 360;
5180 hdt_avg += hdt_norm * 0.1;
5182 if( gHdt < 0) gHdt += 360.;
5185 if (!std::isnan(gHdt)) {
5187 uint64_t hdt_time_gt_last = hdt_time_gt;
5188 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5189 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5192 if (hdt_data_interval > .09) {
5194 gHdt_gt_m1 = gHdt_gt;
5197 if (!std::isnan(gHdt_gt_m1)) {
5199 double tentative_hdt_rate_gt =
5200 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5201 tentative_hdt_rate_gt *= 1e9;
5203 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5204 hdt_rate_gt = tentative_hdt_rate_gt;
5212 if (std::isnan(gHdt)) gHdt_gt = NAN;
5215 CalculateCOGAverage();
5222 bool last_bGPSValid = bGPSValid;
5223 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5224 if ((msg->vflag & POS_VALID) == POS_VALID)
5229 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5231 bVelocityValid =
true;
5235void MyFrame::UpdateStatusBar() {
5238 unsigned long uiCurrentTickCount;
5239 m_MMEAeventTime.SetToCurrent();
5240 uiCurrentTickCount =
5241 m_MMEAeventTime.GetMillisecond() / 100;
5242 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5243 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5244 m_ulLastNMEATicktime = uiCurrentTickCount;
5246 if (m_tick_idx++ > 6) m_tick_idx = 0;
5251 if (NULL != GetStatusBar()) {
5254 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5257 wxString s1(tick_buf, wxConvUTF8);
5259 s1 += toSDMM(1, gLat);
5261 s1 += toSDMM(2, gLon);
5263 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5267 if (!std::isnan(gSog))
5268 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5271 sogcog.Printf(_T(
"SOG --- "));
5275 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5277 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5279 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5280 (
int)toMagnetic(gCog), 0x00B0);
5282 cogs.Printf((
"COG ---%c"), 0x00B0);
5284 sogcog.Append(cogs);
5285 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5290void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5291 MemFootTimer.Stop();
5293 int memsize = GetApplicationMemoryUse();
5296 printf(
"Memsize: %d \n", memsize);
5299 if (memsize > (g_MemFootMB * 1000)) {
5301 if (ChartData && cc) {
5303 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5304 unsigned int nCache = pCache->GetCount();
5307 for (
unsigned int i = 0; i < nCache; i++) {
5317 for (
unsigned int i = 0; i < nCache - 1; i++) {
5318 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5320 pcea[i] = pcea[i + 1];
5331 unsigned int idelete = 0;
5332 unsigned int idelete_max = pCache->GetCount();
5335 unsigned int minimum_cache = 1;
5336 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5338 while ((memsize > (g_MemFootMB * 1000)) &&
5339 (pCache->GetCount() > minimum_cache) &&
5340 (idelete < idelete_max)) {
5341 int memsizeb = memsize;
5343 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5345 memsize = GetApplicationMemoryUse();
5346 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5354 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5359void MyFrame::CheckToolbarPosition() {
5362 static bool bMaximized;
5364 if (IsMaximized() && !bMaximized) {
5366 if (g_MainToolbar) {
5367 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5368 g_MainToolbar->SetDefaultPosition();
5369 g_MainToolbar->Realize();
5371 PositionIENCToolbar();
5372 }
else if (!IsMaximized() && bMaximized) {
5374 if (g_MainToolbar) {
5375 g_MainToolbar->SetYAuxOffset(0);
5376 g_MainToolbar->SetDockY(-1);
5377 g_MainToolbar->SetDefaultPosition();
5378 g_MainToolbar->Realize();
5380 PositionIENCToolbar();
5385void MyFrame::ProcessUnitTest() {
5386 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5393 cc->m_bFollow =
false;
5394 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5395 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5396 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5399 if (cc->m_groupIndex > 0) {
5400 while (ut_index < ChartData->GetChartTableEntries() &&
5401 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5405 if (ut_index < ChartData->GetChartTableEntries()) {
5407 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5409 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5410 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5417 if (cc->GetQuiltMode()) {
5418 if (cc->IsChartQuiltableRef(ut_index))
5419 cc->SelectQuiltRefdbChart(ut_index);
5421 cc->SelectdbChart(ut_index);
5424 if (g_unit_test_1) {
5432 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5433 cte->GetLatMin(), cte->GetLonMax(), NULL,
5437 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5438 cte->GetLatMax(), cte->GetLonMin(), NULL,
5441 cc->GetSize(&ww, &wh);
5442 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5444 ppm = wxMin(ppm, 1.0);
5451 if (ut_index > ut_index_max) exit(0);
5462 bool b_rotate =
false;
5464 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5467 if (!b_rotate && !g_btenhertz)
return;
5469 bool b_update =
false;
5471 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5474 struct timespec now;
5475 clock_gettime(CLOCK_MONOTONIC, &now);
5476 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5477 double diffc = diff / 1e9;
5480 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5481 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5482 if (gCog_tentative < 0.) gCog_tentative += 360.;
5483 gCog = gCog_tentative;
5487 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5488 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5489 double diffc = diff / 1e9;
5490 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5494 if (gSog_gt && !std::isnan(gCog_gt)) {
5495 double delta_t = diffc / 3600;
5496 double distance = gSog_gt * delta_t;
5499 double angr = gCog_gt / 180 * M_PI;
5500 double latr = gLat_gt * M_PI / 180;
5501 double D = distance / 3443;
5502 double sD = sin(D), cD = cos(D);
5503 double sy = sin(latr), cy = cos(latr);
5504 double sa = sin(angr), ca = cos(angr);
5506 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5507 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5517 if (cc) cc->DoCanvasCOGSet();
5528 if (b_rotate || cc->m_bFollow) {
5529 cc->DoCanvasUpdate();
5538 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5541void MyFrame::ProcessQuitFlag() {
5544 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5546 FrameTenHzTimer.Stop();
5553void MyFrame::ProcessDeferredTrackOn() {
5556 if (g_bDeferredStartTrack) {
5557 if (!g_bTrackActive) {
5560 g_bDeferredStartTrack =
false;
5563 g_bDeferredStartTrack =
false;
5568void MyFrame::ProcessAnchorWatch() {
5571 if (pAnchorWatchPoint1) {
5574 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5575 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5576 double d = g_nAWMax;
5577 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5578 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5579 bool toofar =
false;
5580 bool tooclose =
false;
5581 if (d >= 0.0) toofar = (dist * 1852. > d);
5582 if (d < 0.0) tooclose = (dist * 1852 < -d);
5584 if (tooclose || toofar)
5585 AnchorAlertOn1 =
true;
5587 AnchorAlertOn1 =
false;
5589 AnchorAlertOn1 =
false;
5591 if (pAnchorWatchPoint2) {
5594 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5595 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5597 double d = g_nAWMax;
5598 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5599 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5600 bool toofar =
false;
5601 bool tooclose =
false;
5602 if (d >= 0) toofar = (dist * 1852. > d);
5603 if (d < 0) tooclose = (dist * 1852 < -d);
5605 if (tooclose || toofar)
5606 AnchorAlertOn2 =
true;
5608 AnchorAlertOn2 =
false;
5610 AnchorAlertOn2 =
false;
5612 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5613 AnchorAlertOn1 =
true;
5616void MyFrame::SendFixToPlugins() {
5620 GPSData.
kLat = gLat;
5621 GPSData.
kLon = gLon;
5622 GPSData.
kCog = gCog;
5623 GPSData.
kSog = gSog;
5624 GPSData.
kVar = gVar;
5625 GPSData.
kHdm = gHdm;
5626 GPSData.
kHdt = gHdt;
5627 GPSData.
nSats = g_SatsInView;
5629 wxDateTime tCheck((time_t)m_fixtime);
5630 if (tCheck.IsValid()) {
5639 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5642 SendPositionFixToAllPlugIns(&GPSData);
5646void MyFrame::ProcessLogAndBells() {
5649 wxDateTime lognow = wxDateTime::Now();
5650 int hourLOC = lognow.GetHour();
5651 int minuteLOC = lognow.GetMinute();
5653 int minuteUTC = lognow.GetMinute();
5654 int second = lognow.GetSecond();
5656 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5657 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5658 (minuteUTC == 30)) {
5659 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5660 wxString day = lognow.FormatISODate();
5661 wxString utc = lognow.FormatISOTime();
5662 wxString navmsg = _T(
"LOGBOOK: ");
5666 navmsg += _T(
" UTC ");
5670 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5674 if (std::isnan(gCog))
5675 cog.Printf(_T(
"COG ----- "));
5677 cog.Printf(_T(
"COG %10.5f "), gCog);
5680 if (std::isnan(gSog))
5681 sog.Printf(_T(
"SOG ----- "));
5683 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5689 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5692 wxLogMessage(navmsg);
5693 g_loglast_time = lognow;
5695 int bells = (hourLOC % 4) * 2;
5696 if (minuteLOC != 0) bells++;
5697 if (!bells) bells = 8;
5699 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5700 m_BellsToPlay = bells;
5701 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5702 wxPostEvent(
this, ev);
5709 CheckToolbarPosition();
5715 if (bDBUpdateInProgress)
return;
5718 FrameTenHzTimer.Stop();
5720 ProcessDeferredTrackOn();
5722 ProcessAnchorWatch();
5723 ProcessLogAndBells();
5725 if (ShouldRestartTrack()) TrackDailyRestart();
5728 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5729 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5730 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5736 if (gSog > 3.0) g_bCruising =
true;
5742 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5743 _T(
" COG ---\u00B0"));
5744 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5750 bool bnew_view =
false;
5751 if (!g_btenhertz) bnew_view = DoChartUpdate();
5756 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5759 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5762 cc->DrawBlinkObjects();
5765 if (bactiveRouteUpdate) {
5767 if (g_pRouteMan->GetpActiveRoute())
5768 cc->RefreshRect(g_blink_rect,
false);
5772 cc->SetOwnShipState(SHIP_NORMAL);
5774 if (cc->GetQuiltMode()) {
5775 double erf = cc->GetQuiltMaxErrorFactor();
5776 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5778 if (cc->m_singleChart) {
5779 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5780 cc->SetOwnShipState(SHIP_LOWACCURACY);
5784 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5786 if ((bGPSValid != m_last_bGPSValid) ||
5787 (bVelocityValid != m_last_bVelocityValid) ||
5788 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5789 if (!g_bopengl) cc->UpdateShips();
5796 m_last_bGPSValid = bGPSValid;
5797 m_last_bVelocityValid = bVelocityValid;
5802 bool brq_dynamic =
false;
5804 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5805 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5807 if (pic->m_enabled && pic->m_init_state) {
5808 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5815 if (brq_dynamic) bnew_view =
true;
5819 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5822 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5827 if (cc->GetglCanvas()) {
5829 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5832 if (cc->m_bFollow) {
5833 cc->DoCanvasUpdate();
5840 if (std::isnan(gCog)) cc->Refresh(
false);
5853 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5867 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5868 g_pais_query_dialog_active->UpdateText();
5871 if (g_pAISTargetList && (0 == (g_tick % (5))))
5872 g_pAISTargetList->UpdateAISTargetList();
5875 UpdateGPSCompassStatusBoxes();
5878 if (console && console->IsShown()) {
5880 console->RefreshConsoleData();
5887 if (m_bdefer_resize) {
5888 if (0 == (g_tick % (5))) {
5889 printf(
"___RESIZE\n");
5890 SetSize(m_defer_size);
5891 g_pauimgr->Update();
5892 m_bdefer_resize =
false;
5899 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5901 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5902 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5906double MyFrame::GetMag(
double a,
double lat,
double lon) {
5907 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5908 auto loader = PluginLoader::GetInstance();
5909 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5916 wxDateTime now = wxDateTime::Now();
5917 SendJSON_WMM_Var_Request(lat, lon, now);
5918 if (fabs(gQueryVar) < 360.0)
5919 Variance = gQueryVar;
5921 return toMagnetic(a, Variance);
5924bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5930 v[_T(
"Year")] = date.GetYear();
5931 v[_T(
"Month")] = date.GetMonth();
5932 v[_T(
"Day")] = date.GetDay();
5934 SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
5940void MyFrame::TouchAISActive(
void) {
5942 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5944 if (cc) cc->TouchAISToolActive();
5948void MyFrame::UpdateAISTool(
void) {
5949 if (!g_pAIS)
return;
5952 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5954 if (cc) cc->UpdateAISTBTool();
5959void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5961 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5963 if (cc) cc->SetbTCUpdate(
true);
5966 RefreshAllCanvas(
false);
5971void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5975 bool b_rotate =
false;
5976 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5978 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5982 FrameCOGTimer.Stop();
5989 int period_ms = 100;
5991 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5994void MyFrame::DoCOGSet(
void) {
5996 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5998 if (cc) cc->DoCanvasCOGSet();
6002void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
6008 wxFont oldfont = pdc->GetFont();
6010 pdc->SetFont(*pFont);
6011 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
6012 pdc->SetBackgroundMode(wxTRANSPARENT);
6014 pdc->DrawText(str, x, y + 1);
6015 pdc->DrawText(str, x, y - 1);
6016 pdc->DrawText(str, x + 1, y);
6017 pdc->DrawText(str, x - 1, y);
6019 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
6021 pdc->DrawText(str, x, y);
6023 pdc->SetFont(oldfont);
6027void MyFrame::UpdateRotationState(
double rotation) {
6029 g_bCourseUp =
false;
6031 if (fabs(rotation) > .001) {
6032 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
6033 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
6035 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
6038 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
6039 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
6041 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6045 UpdateGPSCompassStatusBoxes(
true);
6049void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6051 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6053 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6059int MyFrame::GetApplicationMemoryUse(
void) {
6065 wxWindow *fWin = wxWindow::FindFocus();
6067 wxArrayString outputArray;
6068 wxString cmd(_T(
"ps --no-headers -o vsize "));
6069 unsigned long pid = wxGetProcessId();
6071 cmd1.Printf(_T(
"%ld"), pid);
6073 wxExecute(cmd, outputArray);
6075 if (outputArray.GetCount()) {
6076 wxString s = outputArray.Item(0);
6078 if (s.ToLong(&vtmp)) memsize = vtmp;
6081 if (fWin) fWin->SetFocus();
6087 PROCESS_MEMORY_COUNTERS pmc;
6089 unsigned long processID = wxGetProcessId();
6091 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6093 if (NULL == hProcess)
return 0;
6095 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6113 memsize = pmc.WorkingSetSize / 1024;
6116 CloseHandle(hProcess);
6123double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6124 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6127void MyFrame::SetChartUpdatePeriod() {
6130 g_ChartUpdatePeriod = 0;
6135 bool bskewdc =
false;
6136 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6139 if (!g_bopengl && !cc->GetVP().b_quilt) {
6140 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6142 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6146 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6148 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6153 cc->UpdateCanvasControlBar();
6156void MyFrame::selectChartDisplay(
int type,
int family) {
6158 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6160 if (cc) cc->selectCanvasChartDisplay(type, family);
6163 UpdateGlobalMenuItems();
6172bool MyFrame::DoChartUpdate(
void) {
6173 bool return_val =
false;
6176 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6178 if (cc) return_val |= cc->DoCanvasUpdate();
6184void MyFrame::MouseEvent(wxMouseEvent &event) {
6186 event.GetPosition(&x, &y);
6191#include <mach/mach.h>
6192#include <mach/message.h>
6193#include <mach/kern_return.h>
6194#include <mach/task_info.h>
6196#include <malloc/malloc.h>
6203#if defined(__linux__)
6204#include "sys/types.h"
6205#include "sys/sysinfo.h"
6208int g_lastMemTick = -1;
6212bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6214 return androidGetMemoryStatus(mem_total, mem_used);
6217#if defined(__linux__)
6221 struct sysinfo sys_info;
6222 if (sysinfo(&sys_info) != -1)
6223 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6237 FILE *file = fopen(
"/proc/self/statm",
"r");
6239 if (fscanf(file,
"%d", mem_used) != 1) {
6240 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6253 PROCESS_MEMORY_COUNTERS pmc;
6255 unsigned long processID = wxGetProcessId();
6258 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6261 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6279 *mem_used = pmc.WorkingSetSize / 1024;
6282 CloseHandle(hProcess);
6286 MEMORYSTATUSEX statex;
6288 statex.dwLength =
sizeof(statex);
6290 GlobalMemoryStatusEx(&statex);
6308 *mem_total = statex.ullTotalPhys / 1024;
6315 if (g_tick != g_lastMemTick) {
6316 malloc_zone_pressure_relief(NULL, 0);
6319 int blocksInUse = 0;
6320 int sizeAllocated = 0;
6322 malloc_statistics_t stats;
6323 stats.blocks_in_use = 0;
6324 stats.size_in_use = 0;
6325 stats.max_size_in_use = 0;
6326 stats.size_allocated = 0;
6327 malloc_zone_statistics(NULL, &stats);
6328 bytesInUse += stats.size_in_use;
6329 blocksInUse += stats.blocks_in_use;
6330 sizeAllocated += stats.size_allocated;
6332 g_memUsed = sizeAllocated >> 10;
6335 g_lastMemTick = g_tick;
6338 if (mem_used) *mem_used = g_memUsed;
6341 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6343 double pagesUsed = 0.0, totalPages = 0.0;
6345 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6346 *mem_total = atol(buf) >> 10;
6354 if (mem_used) *mem_used = 0;
6355 if (mem_total) *mem_total = 0;
6359void MyFrame::DoPrint(
void) {
6361 g_PrintingInProgress =
true;
6364 GetPrimaryCanvas()->GetglCanvas()->Render();
6365 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6375 printer.Initialize(wxLANDSCAPE);
6376 printer.EnablePageNumbers(
false);
6377 printer.Print(
this, &printout);
6395 g_PrintingInProgress =
false;
6398 GetPrimaryCanvas()->SetFocus();
6403wxDateTime gTimeSource;
6406 wxString message_ID =
event.GetID();
6407 wxString message_JSONText =
event.GetJSONText();
6415 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6423 int numErrors = reader.
Parse(message_JSONText, &root);
6424 if (numErrors > 0) {
6430 wxString decl = root[_T(
"Decl")].
AsString();
6432 decl.ToDouble(&decl_val);
6438 if (message_ID == _T(
"WMM_VARIATION")) {
6446 int numErrors = reader.
Parse(message_JSONText, &root);
6447 if (numErrors > 0) {
6453 wxString decl = root[_T(
"Decl")].
AsString();
6455 decl.ToDouble(&decl_val);
6457 gQueryVar = decl_val;
6460 if (message_ID == _T(
"GRIB_TIMELINE")) {
6463 r.
Parse(message_JSONText, &v);
6464 if (v[_T(
"Day")].AsInt() == -1)
6465 gTimeSource = wxInvalidDateTime;
6467 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6468 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6469 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6470 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6472 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6475 wxString trk_id = wxEmptyString;
6477 int numErrors = reader.
Parse(message_JSONText, &root);
6478 if (numErrors > 0)
return;
6481 trk_id = root[_T(
"Track_ID")].
AsString();
6484 v[_T(
"Track_ID")] = trk_id;
6485 for (
Track *ptrack : g_TrackList) {
6486 wxString name = wxEmptyString;
6487 if (ptrack->m_GUID == trk_id) {
6488 name = ptrack->GetName();
6489 if (name.IsEmpty()) {
6495 name = _(
"(Unnamed Track)");
6501 v[_T(
"error")] =
false;
6502 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6503 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6505 v[_T(
"lat")] = tp->m_lat;
6506 v[_T(
"lon")] = tp->m_lon;
6507 v[_T(
"NodeNr")] = i;
6509 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6510 SendJSONMessageToAllPlugins(msg_id, v);
6514 v[_T(
"error")] =
true;
6516 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6517 SendJSONMessageToAllPlugins(msg_id, v);
6519 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6522 wxString guid = wxEmptyString;
6524 int numErrors = reader.
Parse(message_JSONText, &root);
6525 if (numErrors > 0) {
6532 v[_T(
"GUID")] = guid;
6533 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6535 wxString name = wxEmptyString;
6537 if ((*it)->m_GUID == guid) {
6538 name = (*it)->m_RouteNameString;
6539 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6541 v[_T(
"Name")] = name;
6542 v[_T(
"error")] =
false;
6545 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6546 itp != (*it)->pRoutePointList->end(); itp++) {
6547 w[i][_T(
"lat")] = (*itp)->m_lat;
6548 w[i][_T(
"lon")] = (*itp)->m_lon;
6549 w[i][_T(
"Name")] = (*itp)->GetName();
6550 w[i][_T(
"Description")] = (*itp)->GetDescription();
6551 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6552 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6553 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6558 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6560 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6561 httpLink->DescrText;
6562 node = node->GetNext();
6567 v[_T(
"waypoints")] = w;
6568 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6569 SendJSONMessageToAllPlugins(msg_id, v);
6574 v[_T(
"error")] =
true;
6576 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6577 SendJSONMessageToAllPlugins(msg_id, v);
6578 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6583 int numErrors = reader.
Parse(message_JSONText, &root);
6584 if (numErrors > 0)
return;
6587 wxString str = root[_T(
"mode")].
AsString();
6588 if (str == _T(
"Track")) route =
false;
6593 for (RouteList::iterator it = pRouteList->begin();
6594 it != pRouteList->end(); it++) {
6595 wxString name = (*it)->m_RouteNameString;
6596 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6598 v[i][_T(
"error")] =
false;
6599 v[i][_T(
"name")] = name;
6600 v[i][_T(
"GUID")] = (*it)->m_GUID;
6601 v[i][_T(
"active")] = (*it)->IsActive();
6605 for (
Track *ptrack : g_TrackList) {
6606 wxString name = ptrack->GetName();
6607 if (name.IsEmpty()) {
6613 name = _(
"(Unnamed Track)");
6615 v[i][_T(
"error")] =
false;
6616 v[i][_T(
"name")] = name;
6617 v[i][_T(
"GUID")] = ptrack->m_GUID;
6618 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6622 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6623 SendJSONMessageToAllPlugins(msg_id, v);
6626 v[0][_T(
"error")] =
true;
6627 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6628 SendJSONMessageToAllPlugins(msg_id, v);
6630 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6632 v[0][_T(
"error")] =
true;
6633 if (g_pRouteMan->GetpActiveRoute()) {
6634 if (g_pRouteMan->m_bDataValid) {
6635 v[0][_T(
"error")] =
false;
6636 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6637 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6638 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6639 v[0][_T(
"active_route_GUID")] =
6640 g_pRouteMan->GetpActiveRoute()->GetGUID();
6641 v[0][_T(
"active_waypoint_lat")] =
6643 v[0][_T(
"active_waypoint_lon")] =
6647 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6648 SendJSONMessageToAllPlugins(msg_id, v);
6652void MyFrame::FilterCogSog(
void) {
6653 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6655 double cog_last = gCog;
6658 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6659 COGFilterTable[i] = COGFilterTable[i - 1];
6660 COGFilterTable[0] = cog_last;
6663 if (!std::isnan(cog_last)) {
6665 double sum = 0., count = 0;
6666 for (
int i = 0; i < g_COGFilterSec; i++) {
6667 double adder = COGFilterTable[i];
6668 if (std::isnan(adder))
continue;
6670 if (fabs(adder - cog_last) > 180.) {
6671 if ((adder - cog_last) > 0.)
6684 else if (sum >= 360.)
6691 double sog_last = gSog;
6694 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6695 SOGFilterTable[i] = SOGFilterTable[i - 1];
6696 SOGFilterTable[0] = sog_last;
6699 if (!std::isnan(gSog)) {
6700 double sum = 0., count = 0;
6701 for (
int i = 0; i < g_SOGFilterSec; i++) {
6702 if (std::isnan(SOGFilterTable[i]))
continue;
6704 sum += SOGFilterTable[i];
6714void MyFrame::LoadHarmonics() {
6717 ptcmgr->LoadDataSources(TideCurrentDataSet);
6719 bool b_newdataset =
false;
6722 for (
auto a : ptcmgr->GetDataSet()) {
6723 bool b_foundi =
false;
6724 for (
auto b : TideCurrentDataSet) {
6731 b_newdataset =
true;
6736 for (
auto a : TideCurrentDataSet) {
6737 bool b_foundi =
false;
6738 for (
auto b : ptcmgr->GetDataSet()) {
6745 b_newdataset =
true;
6750 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6754void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6755 if (!ptarget)
return;
6758 wxDateTime mob_time = wxDateTime::Now();
6759 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6760 mob_label += _(
" on ");
6761 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6764 mob_label, wxEmptyString);
6765 pWP_MOB->SetShared(
true);
6767 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6769 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6771 pWP_MOB->SetUseSca(
false);
6779 wxString(_(
"Own ship")), wxEmptyString);
6780 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6781 pWP_MOB->SetUseSca(
false);
6782 pAISMOBRoute =
new Route();
6783 pRouteList->Append(pAISMOBRoute);
6785 pAISMOBRoute->AddPoint(pWP_src);
6786 pAISMOBRoute->AddPoint(pWP_MOB);
6788 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6789 pWP_src, pWP_MOB, pAISMOBRoute);
6797 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6799 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6803 v[_T(
"GUID")] = pAISMOBRoute->
m_GUID;
6804 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6805 SendJSONMessageToAllPlugins(msg_id, v);
6808 if (RouteManagerDialog::getInstanceFlag()) {
6809 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6810 pRouteManagerDialog->UpdateRouteListCtrl();
6811 pRouteManagerDialog->UpdateWptListCtrl();
6815 RefreshAllCanvas(
false);
6817 wxString mob_message(_(
"AIS MAN OVERBOARD"));
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);
6828 wxLogMessage(mob_message);
6831void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6832 if (pAISMOBRoute && ptarget) {
6834 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6835 OwnPoint->m_lat = gLat;
6836 OwnPoint->m_lon = gLon;
6838 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6839 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6842 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6843 MOB_Point->m_lat = ptarget->Lat;
6844 MOB_Point->m_lon = ptarget->Lon;
6846 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6847 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6849 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6850 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6853 RefreshAllCanvas(
false);
6856 wxDateTime mob_time = wxDateTime::Now();
6858 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6859 mob_message += _(
" Time: ");
6860 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6861 mob_message += _(
" Ownship Position: ");
6862 mob_message += toSDMM(1, gLat);
6863 mob_message += _T(
" ");
6864 mob_message += toSDMM(2, gLon);
6865 mob_message += _(
" MOB Position: ");
6866 mob_message += toSDMM(1, ptarget->Lat);
6867 mob_message += _T(
" ");
6868 mob_message += toSDMM(2, ptarget->Lon);
6870 wxLogMessage(mob_message);
6874void MyFrame::applySettingsString(wxString settings) {
6876 int last_UIScaleFactor = g_GUIScaleFactor;
6877 bool previous_expert = g_bUIexpert;
6878 g_last_ChartScaleFactor = g_ChartScaleFactor;
6879 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6882 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6885 pConfig->UpdateSettings();
6888 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6890 if (rr & S52_CHANGED) {
6892 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6894 ->ClearCNSYLUPArray();
6895 ps52plib->GenerateStateHash();
6899 ProcessOptionsDialog(rr, pNewDirArray);
6904 bool b_newToolbar =
false;
6906 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6908 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6910 if (rr & TOOLBAR_CHANGED) {
6911 b_newToolbar =
true;
6916 if (previous_expert && !g_bUIexpert) {
6917 androidForceFullRepaint();
6921 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6925 SetGPSCompassScale();
6927 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6929 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6931 UpdateGPSCompassStatusBoxes(
true);
6934 AbstractPlatform::ShowBusySpinner();
6936 SetAllToolbarScale();
6940 AbstractPlatform::HideBusySpinner();
6942 RequestNewMasterToolbar(
true);
6949 UpdateControlBar(GetPrimaryCanvas());
6952 if (console) console->Raise();
6955 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6958#ifdef wxHAS_POWER_EVENTS
6959void MyFrame::OnSuspending(wxPowerEvent &event) {
6963 wxLogMessage(_T(
"System suspend starting..."));
6966void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6969 wxLogMessage(_T(
"System is going to suspend."));
6972void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6975 wxLogMessage(_T(
"System suspend was cancelled."));
6978int g_last_resume_ticks;
6979void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6980 wxDateTime now = wxDateTime::Now();
6981 wxLogMessage(_T(
"System resumed from suspend."));
6983 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6986 wxLogMessage(
"Restarting streams.");
6987 g_last_resume_ticks = now.GetTicks();
6991 g_pMUX->ClearStreams();
6993 g_pMUX->StartAllStreams();
7002 if (IsMaximized()) {
7007 wxSize sz = GetSize();
7008 SetSize(wxSize(sz.x - 1, sz.y));
7020void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
7021 bool btbRebuild =
false;
7023 bool b_reshow =
true;
7024 if (g_MainToolbar) {
7026 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
7027 if ((ff > 0.01f) || bforcenew) {
7028 g_MainToolbar->DestroyToolBar();
7029 delete g_MainToolbar;
7030 g_MainToolbar = NULL;
7036 if (!g_MainToolbar) {
7037 long orient = g_Platform->GetDefaultToolbarOrientation();
7038 wxWindow *toolbarParent =
this;
7040 toolbarParent = GetPrimaryCanvas();
7043 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7044 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
7045 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7046 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7047 g_MainToolbar->EnableRolloverBitmaps(
false);
7049 g_MainToolbar->CreateConfigMenu();
7050 g_MainToolbar->SetDefaultPosition();
7052 g_bmasterToolbarFull =
true;
7055 if (g_MainToolbar) {
7056 CreateMasterToolbar();
7060 g_MainToolbar->SetColorScheme(global_color_scheme);
7066 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7067 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7071bool MyFrame::CollapseGlobalToolbar() {
7072 if (g_MainToolbar) {
7073 m_nMasterToolCountShown = 1;
7074 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7075 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7076 g_MainToolbar->Realize();
7077 g_bmasterToolbarFull =
false;
7086 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7093 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7094 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7095 tic->m_bRequired =
true;
7097 g_MainToolbar->AddToolItem(tic);
7100 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7101 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7102 g_MainToolbar->AddToolItem(tic);
7105 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7106 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7107 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7109 g_MainToolbar->AddToolItem(tic);
7112 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7113 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7114 g_MainToolbar->AddToolItem(tic);
7117 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7118 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7119 _(
"Enable Tracking"), _T(
"MUI_track"));
7120 g_MainToolbar->AddToolItem(tic);
7123 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7124 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7125 g_MainToolbar->AddToolItem(tic);
7136 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7137 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7138 g_MainToolbar->AddToolItem(tic);
7141 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7142 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7143 g_MainToolbar->AddToolItem(tic);
7146 AddDefaultPositionPlugInTools();
7150 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7151 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7152 g_MainToolbar->AddToolItem(tic);
7155 g_MainToolbar->RebuildToolbar();
7159 g_MainToolbar->Realize();
7162 ArrayOfPlugInToolbarTools tool_array =
7163 g_pi_manager->GetPluginToolbarToolArray();
7164 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7166 if (!pttc->b_viz)
continue;
7168 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7171 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7172 if (g_bTrackActive) {
7173 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7175 g_MainToolbar->Realize();
7180bool MyFrame::CheckAndAddPlugInTool() {
7181 if (!g_pi_manager)
return false;
7186 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7188 if (!tb)
return false;
7190 int n_tools = tb->GetToolsCount();
7194 ArrayOfPlugInToolbarTools tool_array =
7195 g_pi_manager->GetPluginToolbarToolArray();
7197 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7199 if (pttc->position == n_tools) {
7200 wxBitmap *ptool_bmp;
7202 switch (global_color_scheme) {
7203 case GLOBAL_COLOR_SCHEME_DAY:
7204 ptool_bmp = pttc->bitmap_day;
7207 case GLOBAL_COLOR_SCHEME_DUSK:
7208 ptool_bmp = pttc->bitmap_dusk;
7210 case GLOBAL_COLOR_SCHEME_NIGHT:
7211 ptool_bmp = pttc->bitmap_night;
7214 ptool_bmp = pttc->bitmap_day;
7219 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7221 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7222 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7223 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7224 tic->m_bPlugin =
true;
7233 while (CheckAndAddPlugInTool()) {
7239bool MyFrame::AddDefaultPositionPlugInTools() {
7240 if (!g_pi_manager)
return false;
7246 ArrayOfPlugInToolbarTools tool_array =
7247 g_pi_manager->GetPluginToolbarToolArray();
7249 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7253 if (!pttc->b_viz)
continue;
7255 if (pttc->position == -1)
7257 wxBitmap *ptool_bmp;
7259 switch (global_color_scheme) {
7260 case GLOBAL_COLOR_SCHEME_DAY:
7261 ptool_bmp = pttc->bitmap_day;
7263 case GLOBAL_COLOR_SCHEME_DUSK:
7264 ptool_bmp = pttc->bitmap_dusk;
7266 case GLOBAL_COLOR_SCHEME_NIGHT:
7267 ptool_bmp = pttc->bitmap_night;
7270 ptool_bmp = pttc->bitmap_day;
7275 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7277 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7278 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7279 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7280 tic->m_bPlugin =
true;
7282 g_MainToolbar->AddToolItem(tic);
7295wxColour GetGlobalColor(wxString colorName);
7297static const char *usercolors[] = {
7298 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7299 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7300 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7301 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7302 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7303 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7304 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7306 "DILG0; 255;255;255;",
7308 "DILG0; 238;239;242;",
7310 "DILG1; 212;208;200;",
7311 "DILG2; 255;255;255;",
7315 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7316 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7317 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7319 "UDKRD; 124; 16; 0;",
7320 "UARTE; 200; 0; 0;",
7322 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7323 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7324 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7325 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7327 "DASHB; 255;255;255;",
7328 "DASHL; 175;175;175;",
7329 "DASHF; 50; 50; 50;",
7330 "DASHR; 200; 0; 0;",
7332 "DASHN; 200;120; 0;",
7333 "DASH1; 204;204;255;",
7334 "DASH2; 122;131;172;",
7335 "COMP1; 211;211;211;",
7337 "GREY3; 40; 40; 40;",
7338 "BLUE4; 100;100;200;",
7339 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7340 "BLUEBACK; 212;234;238;",
7341 "LANDBACK; 201;185;122;",
7344 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7345 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7346 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7347 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7348 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7349 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7350 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7352 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7353 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7354 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7356 "DILG0; 110;110;110;",
7357 "DILG1; 110;110;110;",
7359 "DILG3; 130;130;130;",
7360 "UITX1; 41; 46; 46;",
7362 "UARTE; 64; 64; 64;",
7364 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7365 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7366 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7367 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7369 "DASHB; 77; 77; 77;",
7370 "DASHL; 54; 54; 54;",
7372 "DASHR; 58; 21; 21;",
7373 "DASHG; 21; 58; 21;",
7374 "DASHN; 100; 50; 0;",
7375 "DASH1; 76; 76;113;",
7376 "DASH2; 48; 52; 72;",
7377 "COMP1; 107;107;107;",
7379 "GREY3; 20; 20; 20;",
7380 "BLUE4; 80; 80;160;",
7381 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7382 "LANDBACK; 201;185;122;",
7384 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7385 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7386 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7387 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7388 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7389 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7390 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7391 "DILG0; 80; 80; 80;",
7392 "DILG1; 80; 80; 80;",
7394 "DILG3; 65; 65; 65;",
7395 "UITX1; 31; 34; 35;",
7397 "UARTE; 64; 64; 64;",
7399 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7400 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7401 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7403 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7404 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7405 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7406 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7409 "DASHL; 20; 20; 20;",
7410 "DASHF; 64; 64; 64;",
7411 "DASHR; 70; 15; 15;",
7412 "DASHG; 15; 70; 15;",
7413 "DASHN; 17; 80; 56;",
7414 "DASH1; 48; 52; 72;",
7415 "DASH2; 36; 36; 53;",
7416 "COMP1; 24; 24; 24;",
7418 "GREY3; 10; 10; 10;",
7419 "BLUE4; 70; 70;140;",
7420 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7421 "LANDBACK; 201;185;122;",
7425int get_static_line(
char *d,
const char **p,
int index,
int n) {
7426 if (!strcmp(p[index],
"*****"))
return 0;
7428 strncpy(d, p[index], n);
7432void InitializeUserColors(
void) {
7433 const char **p = usercolors;
7441 UserColorTableArray =
new wxArrayPtrVoid;
7442 UserColourHashTableArray =
new wxArrayPtrVoid;
7446 ct->tableName =
new wxString(_T(
"DAY"));
7447 ct->color =
new wxArrayPtrVoid;
7448 UserColorTableArray->Add((
void *)ct);
7451 ct->tableName =
new wxString(_T(
"DUSK"));
7452 ct->color =
new wxArrayPtrVoid;
7453 UserColorTableArray->Add((
void *)ct);
7456 ct->tableName =
new wxString(_T(
"NIGHT"));
7457 ct->color =
new wxArrayPtrVoid;
7458 UserColorTableArray->Add((
void *)ct);
7460 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7461 if (!strncmp(buf,
"Table", 5)) {
7462 sscanf(buf,
"Table:%s", TableName);
7464 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7465 ctp = (colTable *)(UserColorTableArray->Item(it));
7466 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7475 while (buf[j] !=
';' && j < 20) {
7481 S52color *c =
new S52color;
7482 strcpy(c->colName, name);
7484 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7497 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7498 wxColorHashMap *phash =
new wxColorHashMap;
7499 UserColourHashTableArray->Add((
void *)phash);
7501 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7503 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7504 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7506 wxColour c(c2->R, c2->G, c2->B);
7507 wxString key(c2->colName, wxConvUTF8);
7514 pcurrent_user_color_hash =
7515 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7518void DeInitializeUserColors(
void) {
7519 if (!UserColorTableArray)
return;
7520 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7521 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7523 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7524 S52color *c = (S52color *)ct->color->Item(j);
7528 delete ct->tableName;
7534 delete UserColorTableArray;
7536 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7537 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7541 delete UserColourHashTableArray;
7548typedef struct _MSW_COLOR_SPEC {
7550 wxString S52_RGB_COLOR;
7554MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7555 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7556 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7559void SaveSystemColors() {
7573 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7574 while (pcspec->COLOR_NAME != -1) {
7575 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7580void RestoreSystemColors() {
7581 int element[NCOLORS];
7582 int rgbcolor[NCOLORS];
7585 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7586 while (pcspec->COLOR_NAME != -1) {
7587 element[i] = pcspec->COLOR_NAME;
7588 rgbcolor[i] = pcspec->SysRGB_COLOR;
7594 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7599void SetSystemColors(ColorScheme cs) {
7601 int element[NCOLORS];
7602 int rgbcolor[NCOLORS];
7604 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7605 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7606 while (pcspec->COLOR_NAME != -1) {
7607 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7608 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7609 element[i] = pcspec->COLOR_NAME;
7615 pSetSysColors(i, (
unsigned long *)&element[0],
7616 (
unsigned long *)&rgbcolor[0]);
7620 RestoreSystemColors();
7625wxColor GetDimColor(wxColor c) {
7626 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7627 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7631 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7632 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7634 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7635 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7636 hsv.value = hsv.value * factor;
7637 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7639 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7645double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7646 double const AnchorPointMaxDist)
7649 if (d < AnchorPointMinDist)
7650 return AnchorPointMinDist;
7651 else if (d > AnchorPointMaxDist)
7652 return AnchorPointMaxDist;
7658 if (d > -AnchorPointMinDist)
7659 return -AnchorPointMinDist;
7660 else if (d < -AnchorPointMaxDist)
7661 return -AnchorPointMaxDist;
7668static const WORD MAX_CONSOLE_LINES =
7673void RedirectIOToConsole()
7678 wxIntPtr lStdHandle;
7680 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7690 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7691 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7692 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7696 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7697 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7698 fp = _fdopen(hConHandle,
"w");
7700 setvbuf(stdout, NULL, _IONBF, 0);
7704 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7705 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7706 fp = _fdopen(hConHandle,
"r");
7708 setvbuf(stdin, NULL, _IONBF, 0);
7712 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7713 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7714 fp = _fdopen(hConHandle,
"w");
7716 setvbuf(stderr, NULL, _IONBF, 0);
7728bool TestGLCanvas(wxString prog_dir) {
7730 wxString test_app = prog_dir;
7731 test_app += _T(
"ocpn_gltest1.exe");
7733 if (::wxFileExists(test_app)) {
7734 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7735 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7736 if (proc_return == 0)
7737 printf(
"GLCanvas OK\n");
7739 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7741 return (proc_return == 0);
7751bool ReloadLocale() {
7756 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7763 FontMgr::Get().SetLocale(g_locale);
7771 if (pRoutePropDialog) {
7772 pRoutePropDialog->Hide();
7773 pRoutePropDialog->Destroy();
7774 pRoutePropDialog = NULL;
7777 if (pRouteManagerDialog) {
7778 pRouteManagerDialog->Hide();
7779 pRouteManagerDialog->Destroy();
7780 pRouteManagerDialog = NULL;
7783 if (console) console->SetColorScheme(global_color_scheme);
7784 if (g_pais_query_dialog_active) {
7785 g_pais_query_dialog_active->Destroy();
7786 g_pais_query_dialog_active = NULL;
7789 auto alert_dlg_active =
7791 if (alert_dlg_active) {
7792 alert_dlg_active->Destroy();
7793 g_pais_alert_dialog_active =
nullptr;
7796 if (g_pAISTargetList) {
7797 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7798 g_pAISTargetList->Disconnect_decoder();
7799 g_pAISTargetList->Destroy();
7800 g_pAISTargetList = NULL;
7804 if (gFrame->m_pMenuBar) {
7805 gFrame->SetMenuBar(NULL);
7806 gFrame->m_pMenuBar->Destroy();
7807 gFrame->m_pMenuBar = NULL;
7809 gFrame->BuildMenuBar();
7812 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7814 if (cc) cc->CanvasApplyLocale();
7819 wxString perspective;
7820 pConfig->SetPath(_T (
"/AUI" ));
7821 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7835 bool bno_load =
false;
7836 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7838 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7839 wxAuiPaneInfo pane = pane_array_val[i];
7840 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7846 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7848 g_pauimgr->Update();
7851 gFrame->RequestNewToolbars(
true);
7852 gFrame->RequestNewMasterToolbar(
true);
7856extern s57RegistrarMgr *m_pRegistrarMan;
7857extern wxString g_UserPresLibData;
7858extern wxString g_SENCPrefix;
7859extern wxString g_csv_locn;
7875 g_csv_locn = g_Platform->GetSharedDataDir();
7876 g_csv_locn.Append(_T(
"s57data"));
7879 g_csv_locn = _T(
".");
7880 appendOSDirSlash(&g_csv_locn);
7881 g_csv_locn.Append(_T(
"s57data"));
7886 if (g_SENCPrefix.IsEmpty()) {
7888 appendOSDirSlash(&g_SENCPrefix);
7889 g_SENCPrefix.Append(_T(
"SENC"));
7893 wxFileName f(g_SENCPrefix);
7895 g_SENCPrefix = f.GetFullPath();
7897 g_SENCPrefix = _T(
"SENC");
7903 bool b_force_legacy =
false;
7905 if (g_UserPresLibData.IsEmpty()) {
7906 plib_data = g_csv_locn;
7907 appendOSDirSlash(&plib_data);
7908 plib_data.Append(_T(
"S52RAZDS.RLE"));
7910 plib_data = g_UserPresLibData;
7911 b_force_legacy =
true;
7914 ps52plib =
new s52plib(plib_data, b_force_legacy);
7929 if (!ps52plib->m_bOK) {
7932 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7934 wxString look_data_dir;
7935 look_data_dir.Append(std_path.GetUserDataDir());
7936 appendOSDirSlash(&look_data_dir);
7937 wxString tentative_SData_Locn = look_data_dir;
7938 look_data_dir.Append(_T(
"s57data"));
7940 plib_data = look_data_dir;
7941 appendOSDirSlash(&plib_data);
7942 plib_data.Append(_T(
"S52RAZDS.RLE"));
7944 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7945 ps52plib =
new s52plib(plib_data);
7947 if (ps52plib->m_bOK) {
7948 g_csv_locn = look_data_dir;
7957 if (!ps52plib->m_bOK) {
7960 wxString look_data_dir;
7961 look_data_dir = g_Platform->GetSharedDataDir();
7962 look_data_dir.Append(_T(
"s57data"));
7964 plib_data = look_data_dir;
7965 appendOSDirSlash(&plib_data);
7966 plib_data.Append(_T(
"S52RAZDS.RLE"));
7968 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7969 ps52plib =
new s52plib(plib_data);
7971 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7974 if (ps52plib->m_bOK) {
7975 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
7977 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7982 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7984 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7985 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7986 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7987 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7990 pConfig->LoadS57Config();
7991 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7994 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
7995 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
7997 ps52plib->SetDIPFactor(dip_factor);
8002 ps52plib->SetScaleFactorExp(
8003 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
8004 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
8009 extern bool g_b_EnableVBO;
8010 extern GLenum g_texture_rectangle_format;
8015 wxString renderer = wxString(GL_Caps->Renderer.c_str());
8016 ps52plib->SetGLRendererString(renderer);
8019 ps52plib->SetGLOptions(
8020 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
8021 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
8022 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
8028 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
8037 : wxThread(wxTHREAD_JOINABLE) {
8038 m_filename = filename;
8049 newChart->SetNativeScale(m_scale);
8050 newChart->SetFullExtent(m_ext);
8052 newChart->FindOrCreateSenc(m_filename);
8057 wxString m_filename;
8063static double chart_dist(
int index) {
8069 if (cte.GetBBox().Contains(gLat, gLon))
8074 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8075 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8076 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8079 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8080 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8082 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8088WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8089static int CompareInts(
int n1,
int n2) {
8090 double d1 = chart_dist(n1);
8091 double d2 = chart_dist(n2);
8092 return (
int)(d1 - d2);
8097 wxString chart_path;
8102WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8104#include <wx/arrimpl.cpp>
8107void ParseAllENC(wxWindow *parent) {
8108 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8116 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8119 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8121 idx_sorted_by_distance.Add(i);
8125 if (count == 0)
return;
8127 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8133 ArrayOfCompressTargets ct_array;
8134 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8135 int i = idx_sorted_by_distance[j];
8138 double distance = chart_dist(i);
8140 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8143 pct->distance = distance;
8144 pct->chart_path = filename;
8146 ct_array.push_back(pct);
8149 int thread_count = 0;
8152 extern int g_nCPUCount;
8153 if (g_nCPUCount > 0)
8154 thread_count = g_nCPUCount;
8156 thread_count = wxThread::GetCPUCount();
8158 if (thread_count < 1) {
8167 for(
int t = 0; t < thread_count; t++)
8171 wxGenericProgressDialog *prog =
nullptr;
8175 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8176 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8178 prog =
new wxGenericProgressDialog();
8180 prog->SetFont(*qFont);
8182 prog->Create(_(
"OpenCPN ENC Prepare"),
8183 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8193 prog->ShowWindowModal();
8202 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8203 wxString filename = ct_array[j].chart_path;
8204 double distance = ct_array[j].distance;
8205 int index = ChartData->FinddbIndex(filename);
8206 if (index < 0)
continue;
8209 ext.NLAT = cte.GetLatMax();
8210 ext.SLAT = cte.GetLatMin();
8211 ext.WLON = cte.GetLonMin();
8212 ext.ELON = cte.GetLonMax();
8214 int scale = cte.GetScale();
8217 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8220 if (wxThread::IsMain()) {
8222 wxSize sz = prog->GetSize();
8224 msg += _T(
" Chart:");
8227 prog->Update(count, msg, &skip);
8239 newChart->SetNativeScale(
scale);
8240 newChart->SetFullExtent(ext);
8241 newChart->DisableBackgroundSENC();
8243 newChart->FindOrCreateSenc(filename,
8247 if (wxThread::IsMain()) {
8248 msg.Printf(_(
"ENC Completed."));
8250 prog->Update(count, msg, &skip);
8260 for (
int t = 0;; t = (t + 1) % thread_count) {
8267 if (!workers[t]->IsAlive()) {
8280#if defined(__WXMSW__) || defined(__WXOSX__)
8287 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.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
A modal message dialog with confirmation button and cancel button.
Dialog for managing CM93 chart offsets.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Set the viewport center point.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
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.
virtual bool IsVisible() 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 OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.
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.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
Global variables reflecting command line options and arguments.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
The ConnectionsDlg class.
New NMEA Debugger successor main window.
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.
Class NotificationManager.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse(void)
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
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.