52#include <wx/stdpaths.h>
53#include <wx/tokenzr.h>
54#include <wx/display.h>
55#include <wx/jsonreader.h>
59#include "model/ais_target_data.h"
60#include "model/autopilot_output.h"
64#include "model/comm_n0183_output.h"
66#include "model/comm_vars.h"
67#include "model/config_vars.h"
68#include "model/cutil.h"
69#include "model/georef.h"
72#include "model/idents.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"
87#include "model/track.h"
89#include "dialog_alert.h"
93#include "ais_info_gui.h"
94#include "AISTargetAlertDialog.h"
95#include "AISTargetListDialog.h"
96#include "AISTargetQueryDialog.h"
97#include "CanvasConfig.h"
99#include "chart_ctx_factory.h"
104#include "color_handler.h"
108#include "ConfigMgr.h"
113#include "glChartCanvas.h"
114#include "GoToPositionDialog.h"
116#include "iENCToolbar.h"
118#include "load_errors_dlg.h"
121#include "N2KParser.h"
125#include "OCPN_AUIManager.h"
126#include "ocpn_frame.h"
127#include "OCPNPlatform.h"
128#include "OCPN_Sound.h"
131#include "print_dialog.h"
132#include "printout_chart.h"
133#include "routemanagerdialog.h"
134#include "routeman_gui.h"
135#include "route_point_gui.h"
136#include "RoutePropDlgImpl.h"
139#include "S57QueryDialog.h"
140#include "SystemCmdSound.h"
144#include "TrackPropDlg.h"
145#include "waypointman_gui.h"
146#include "CanvasOptions.h"
150#include "androidUTIL.h"
156WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
164extern arrayofCanvasPtr g_canvasArray;
177extern About *g_pAboutDlgLegacy;
180extern double vLat, vLon;
181extern wxString g_locale;
182extern ColorScheme global_color_scheme;
187GLenum g_texture_rectangle_format;
190#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
191extern wxLocale *plocale_def_lang;
198extern s52plib *ps52plib;
202extern bool g_b_legacy_input_filter_behaviour;
203extern bool g_bTrackActive;
205extern bool g_bmasterToolbarFull;
206extern int g_nAutoHideToolbar;
207extern bool g_bAutoHideToolbar;
208extern bool g_bshowToolbar;
209extern int g_maintoolbar_x;
210extern int g_maintoolbar_y;
211extern wxString g_toolbarConfig;
212extern float g_toolbar_scalefactor;
213extern float g_compass_scalefactor;
214extern bool g_bShowMenuBar;
215extern bool g_bShowCompassWin;
217extern bool g_benable_rotate;
218extern int g_GUIScaleFactor;
219extern int g_ChartScaleFactor;
220extern int g_last_ChartScaleFactor;
221extern int g_ShipScaleFactor;
222extern float g_ShipScaleFactorExp;
223extern int g_ENCTextScaleFactor;
225extern bool g_bShowTide;
226extern bool g_bShowCurrent;
227extern bool g_bUIexpert;
228extern RouteList *pRouteList;
229extern wxString g_default_wp_icon;
230extern std::vector<std::string> TideCurrentDataSet;
231extern wxString g_TCData_Dir;
233extern char nmea_tick_chars[];
234extern double AnchorPointMinDist;
235extern bool AnchorAlertOn1, AnchorAlertOn2;
236extern wxString g_AW1GUID;
237extern wxString g_AW2GUID;
238extern bool g_bCruising;
239extern double g_COGAvg;
240extern int g_COGAvgSec;
242extern std::vector<Track *> g_TrackList;
243extern double gQueryVar;
244extern int g_ChartUpdatePeriod;
245extern int g_SkewCompUpdatePeriod;
246extern bool g_bCourseUp;
247extern bool g_bLookAhead;
248extern bool g_bskew_comp;
249extern bool g_bPauseTest;
251extern bool g_bPlayShipsBells;
252extern wxDateTime g_loglast_time;
253extern int g_nAWDefault;
255extern bool g_bDeferredStartTrack;
256extern bool bDBUpdateInProgress;
260extern bool g_bDeferredInitDone;
261extern int options_lastPage;
262extern int options_subpage;
263extern bool b_reloadForPlugins;
265extern int g_NeedDBUpdate;
266extern bool g_bFullscreen;
267extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
268extern ChartGroupArray *g_pGroupArray;
269extern bool g_bEnableZoomToCursor;
270extern double g_display_size_mm;
271extern std::vector<size_t> g_config_display_size_mm;
272extern wxString ChartListFileName;
273extern bool g_bFullscreenToolbar;
274extern arrayofCanvasPtr g_canvasArray;
275extern wxString g_lastAppliedTemplateGUID;
276extern wxPoint options_lastWindowPos;
277extern wxSize options_lastWindowSize;
278extern unsigned int g_canvasConfig;
279extern bool g_bFullScreenQuilt;
280extern bool g_bQuiltEnable;
281extern wxString *pInit_Chart_Dir;
282extern bool g_bShowOutlines;
283extern bool g_bTempShowMenuBar;
284extern bool g_bShowStatusBar;
285extern bool g_FlushNavobjChanges;
286extern int g_FlushNavobjChangesTimeout;
287extern bool g_bShowChartBar;
288extern double g_plus_minus_zoom_factor;
289extern int g_nframewin_x;
290extern int g_nframewin_y;
291extern int g_nframewin_posx;
292extern int g_nframewin_posy;
293extern bool g_bframemax;
294extern LayerList *pLayerList;
295extern bool g_bAutoAnchorMark;
296extern wxDateTime g_start_time;
297extern bool g_bcompression_wait;
298extern bool g_bquiting;
299extern bool b_inCloseWindow;
300extern bool b_inCompressAllCharts;
301extern long g_maintoolbar_orient;
302extern wxAuiDefaultDockArt *g_pauidockart;
303extern int g_click_stop;
304extern wxString g_CmdSoundString;
305extern std::vector<OcpnSound *> bells_sound;
306extern char bells_sound_file_name[2][12];
307extern int g_sticky_chart;
308extern int g_sticky_projection;
309extern wxArrayPtrVoid *UserColourHashTableArray;
310extern wxColorHashMap *pcurrent_user_color_hash;
313extern bool g_own_ship_sog_cog_calc;
314extern int g_own_ship_sog_cog_calc_damp_sec;
315extern bool g_bHasHwClock;
316extern bool s_bSetSystemTime;
317extern bool bVelocityValid;
318extern int gHDx_Watchdog;
321extern bool g_bUseGLL;
322extern int g_MemFootMB;
325extern int g_chart_zoom_modifier_vector;
326extern bool g_config_display_size_manual;
327extern bool g_PrintingInProgress;
328extern bool g_disable_main_toolbar;
329extern bool g_btenhertz;
330extern bool g_declutter_anchorage;
335typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
336typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
338SetSysColors_t pSetSysColors;
339GetSysColor_t pGetSysColor;
341void SaveSystemColors(
void);
342void RestoreSystemColors(
void);
347DWORD color_3ddkshadow;
349DWORD color_activecaption;
350DWORD color_gradientactivecaption;
351DWORD color_captiontext;
352DWORD color_windowframe;
353DWORD color_inactiveborder;
358#include <wx/msw/msvcrt.h>
362static const long long lNaN = 0xfff8000000000000;
363#define NAN (*(double *)&lNaN)
366static wxArrayPtrVoid *UserColorTableArray = 0;
369double gLat_gt, gLon_gt;
370double gLat_gt_m1, gLon_gt_m1;
372uint64_t fix_time_gt_last;
374double gSog_gt, gCog_gt, gHdt_gt;
375double gCog_gt_m1, gHdt_gt_m1;
377double cog_rate_gt, hdt_rate_gt;
380void appendOSDirSlash(wxString *pString);
382void InitializeUserColors(
void);
383void DeInitializeUserColors(
void);
384void SetSystemColors(ColorScheme cs);
386static bool LoadAllPlugIns(
bool load_enabled) {
387 AbstractPlatform::ShowBusySpinner();
388 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
389 AbstractPlatform::HideBusySpinner();
393static void LaunchLocalHelp(
void) {
395 androidLaunchHelpView();
397 wxString def_lang_canonical = _T(
"en_US");
400 if (plocale_def_lang)
401 def_lang_canonical = plocale_def_lang->GetCanonicalName();
404 wxString help_locn = g_Platform->GetSharedDataDir() + _T(
"doc/help_");
406 wxString help_try = help_locn + def_lang_canonical + _T(
".html");
408 if (!::wxFileExists(help_try)) {
409 help_try = help_locn + _T(
"en_US") + _T(
".html");
411 if (!::wxFileExists(help_try)) {
412 help_try = help_locn + _T(
"web") + _T(
".html");
415 if (!::wxFileExists(help_try))
return;
418 wxLaunchDefaultBrowser(wxString(_T(
"file:///")) + help_try);
422static void DoHelpDialog(
void) {
427 g_pAboutDlg->SetFocus();
432 if (!g_pAboutDlgLegacy)
433 g_pAboutDlgLegacy =
new About(gFrame, g_Platform->GetSharedDataDir(),
434 [] { LaunchLocalHelp(); });
436 g_pAboutDlgLegacy->SetFocus();
437 g_pAboutDlgLegacy->Show();
446#if defined(__WXGTK__) || defined(__WXQT__)
447#include "bitmaps/opencpn.xpm"
462int g_iENCToolbarPosX;
463int g_iENCToolbarPosY;
465void BuildiENCToolbar(
bool bnew) {
466 if (g_bInlandEcdis) {
469 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
470 wxPoint tbp_incanvas =
473 g_iENCToolbarPosY = tbp_incanvas.y;
474 g_iENCToolbarPosX = tbp_incanvas.x;
476 delete g_iENCToolbar;
481 if (!g_iENCToolbar) {
482 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
486 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
488 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
489 g_iENCToolbarPosY = -1;
492 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
498 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
502 double tool_scale_factor =
503 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
506 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
507 g_iENCToolbar->SetColorScheme(global_color_scheme);
508 g_iENCToolbar->EnableSubmerge(
false);
511 delete g_iENCToolbar;
512 g_iENCToolbar = NULL;
516bool ShowNavWarning() {
519OpenCPN is distributed in the hope that it will be useful, \
520but WITHOUT ANY WARRANTY; without even the implied \
521warranty of MERCHANTABILITY or FITNESS FOR A \
522PARTICULAR PURPOSE.\n\n\
523See the GNU General Public License for more details.\n\n\
524OpenCPN must only be used in conjunction with approved \
525paper charts and traditional methods of navigation.\n\n\
526DO NOT rely upon OpenCPN for safety of life or property.\n\n\
527Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
529 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
532 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
535 msg.Replace(
"\n",
"<br>");
537 std::stringstream html;
538 html <<
"<html><body><p>";
539 html << msg.ToStdString();
540 html <<
"</p></body></html>";
542 std::string title = _(
"Welcome to OpenCPN").ToStdString();
543 std::string action = _(
"Agree").ToStdString();
545 info_dlg.SetInitialSize();
546 info_dlg.AddHtmlContent(html);
547 int agreed = info_dlg.ShowModal();
548 return agreed == wxID_OK;
553 if (chart ==
nullptr)
return false;
556 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
558 if (cc && cc->m_singleChart == chart) {
565#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
568static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
569 const char *prop_name) {
573 unsigned long ret_nitems;
574 unsigned long ret_bytes_after;
575 unsigned char *ret_prop;
577 xa_prop_name = XInternAtom(disp, prop_name, False);
585 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
586 &xa_ret_type, &ret_format, &ret_nitems,
587 &ret_bytes_after, &ret_prop) != Success)
590 if (xa_ret_type != xa_prop_type) {
594 return (
char *)ret_prop;
599static bool isTransparentToolbarInOpenGLOK(
void) {
606 if (!g_bdisable_opengl) {
607 Display *disp = XOpenDisplay(NULL);
609 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
611 "_NET_SUPPORTING_WM_CHECK")) ||
612 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
614 "_WIN_SUPPORTING_WM_CHECK"))) {
617 if ((wm_name = get_X11_property(disp, *sup_window,
618 XInternAtom(disp,
"UTF8_STRING", False),
620 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
623 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
644wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
646BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
647EVT_CLOSE(MyFrame::OnCloseWindow)
648EVT_MENU(wxID_EXIT, MyFrame::OnExit)
649EVT_SIZE(MyFrame::OnSize)
650EVT_MOVE(MyFrame::OnMove)
651EVT_ICONIZE(MyFrame::OnIconize)
652EVT_MENU(-1, MyFrame::OnToolLeftClick)
653EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
655EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
656EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
657EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
659EVT_MAXIMIZE(MyFrame::OnMaximize)
660EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
661 MyFrame::RequestNewToolbarArgEvent)
662EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
664EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
665EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
666EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
668#ifdef wxHAS_POWER_EVENTS
669EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
670EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
671EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
672EVT_POWER_RESUME(MyFrame::OnResume)
683static
void onBellsFinishedCB(
void *ptr) {
684 auto framePtr =
static_cast<MyFrame *
>(ptr);
686 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
687 wxPostEvent(framePtr, ev);
692 auto msg = ev.GetString().ToStdString();
693 auto ¬eman = NotificationManager::GetInstance();
694 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
697static NmeaLog *GetDataMonitor() {
698 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
699 return dynamic_cast<NmeaLog *
>(w);
703MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
704 const wxSize &size,
long style)
705 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
706 comm_overflow_dlg(this),
707 m_connections_dlg(nullptr),
709 g_current_monitor = wxDisplay::GetFromWindow(
this);
715 g_current_monitor_dip_px_ratio =
716 g_monitor_info[g_current_monitor].width_px /
717 g_monitor_info[g_current_monitor].width;
720 m_last_track_rotation_ts = 0;
721 m_ulLastNMEATicktime = 0;
722 m_data_monitor->Hide();
724 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
728 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
731 InitTimer.SetOwner(
this, INIT_TIMER);
733 m_initializing =
false;
736 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
739 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
742 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
745 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
748 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
750 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
759 m_bTimeIsSet =
false;
762 m_bdefer_resize =
false;
765 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
766 COGFilterTable[i] = NAN;
767 SOGFilterTable[i] = NAN;
769 m_last_bGPSValid =
false;
770 m_last_bVelocityValid =
false;
780 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
785 double process_noise_std = 1.0;
786 double measurement_noise_std = 0.5;
788 m_ChartUpdatePeriod = 1;
793 log_callbacks.log_is_active = [&]() {
794 auto log = GetDataMonitor();
795 return log && log->IsVisible();
797 log_callbacks.log_message = [&](
Logline ll) {
798 NmeaLog *monitor = GetDataMonitor();
801 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
804 ais_callbacks.confirm_stop_track = []() {
805 int r = OCPNMessageBox(
807 _(
"This AIS target has Persistent tracking selected by MMSI "
809 "A Persistent track recording will therefore be restarted for this "
811 "Do you instead want to stop Persistent tracking for this target?"),
812 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
813 return r == wxID_YES;
815 ais_callbacks.get_target_mmsi = []() {
816 auto alert_dlg_active =
818 assert(alert_dlg_active);
819 return alert_dlg_active->Get_Dialog_MMSI();
827 wxLogMessage(
" **** Connect stuff");
833 Connect(wxEVT_OCPN_MSG,
834 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
841 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
842 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
850#if defined(__WXGTK__) || defined(__WXQT__)
851 wxIcon app_icon(opencpn);
859 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
861 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
862 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
867 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
870 g_sticky_projection = -1;
873 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
874 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
876 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
878 [&](wxCommandEvent) { Refresh(); });
879 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
884 EnableFullScreenView();
886 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
892 FrameTenHzTimer.Stop();
899 wxRouteListNode *node = pRouteList->GetFirst();
902 Route *pRouteDelete = node->GetData();
905 node = node->GetNext();
912 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
920 switch (event.type) {
921 case SENC_BUILD_STARTED:
924 case SENC_BUILD_DONE_NOERROR:
926 chart =
event.m_ticket->m_chart;
928 chart->PostInit(FULL_INIT, global_color_scheme);
930 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
932 if (cc) cc->ClearS52PLIBStateHash();
937 delete event.m_ticket;
939 case SENC_BUILD_DONE_ERROR:
947void MyFrame::RebuildChartDatabase() {
948 bool b_SetInitialPoint =
false;
951 ArrayOfCDI ChartDirArray;
952 pConfig->LoadChartDirArray(ChartDirArray);
954 if (ChartDirArray.GetCount()) {
957 if (g_NeedDBUpdate == 1) {
959 _(
"OpenCPN needs to update the chart database from config file "
963 wxICON_INFORMATION | wxOK);
971 _(
"Rebuilding chart database from configuration file entries..."));
975 wxString dummy1 = _(
"Elapsed time : ");
976 wxString dummy2 = _(
"Estimated time : ");
977 wxString dummy3 = _(
"Remaining time : ");
978 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
979 _(
"OpenCPN Chart Update"), line, 100, NULL,
980 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
981 wxPD_REMAINING_TIME);
983 ChartData->
Create(ChartDirArray, pprog);
984 ChartData->SaveBinary(ChartListFileName);
989 ChartData->ApplyGroupArray(g_pGroupArray);
994void MyFrame::OnBellsFinished(wxCommandEvent &event) {
995 int bells = wxMin(m_BellsToPlay, 2);
996 if (bells <= 0)
return;
998 wxString soundfile = _T(
"sounds");
999 appendOSDirSlash(&soundfile);
1000 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
1001 soundfile.Prepend(g_Platform->GetSharedDataDir());
1002 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
1004 OcpnSound *sound = bells_sound[bells - 1];
1005 sound->SetFinishedCallback(onBellsFinishedCB,
this);
1006 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
1007 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
1008 sound->Load(soundfile);
1009 if (!sound->IsOk()) {
1010 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
1014 m_BellsToPlay -= bells;
1017void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
1019void MyFrame::OnMaximize(wxMaximizeEvent &event) {
1026ColorScheme GetColorScheme() {
return global_color_scheme; }
1028ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
1030void MyFrame::ReloadAllVP() {
1031 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1033 if (cc) cc->ReloadVP();
1037void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
1038 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
1041 global_color_scheme = cs;
1042 wxString SchemeName;
1044 case GLOBAL_COLOR_SCHEME_DAY:
1045 SchemeName = _T(
"DAY");
1047 case GLOBAL_COLOR_SCHEME_DUSK:
1048 SchemeName = _T(
"DUSK");
1050 case GLOBAL_COLOR_SCHEME_NIGHT:
1051 SchemeName = _T(
"NIGHT");
1054 SchemeName = _T(
"DAY");
1058 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
1060 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
1061 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
1062 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1063 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
1064 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
1066 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1095 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1096 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1098 g_pauimgr->Update();
1100 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1103 unsigned Usercolortable_index = 0;
1104 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1105 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1106 if (SchemeName.IsSameAs(*ct->tableName)) {
1107 Usercolortable_index = i;
1112 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1115 pcurrent_user_color_hash =
1116 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1118 SetSystemColors(cs);
1121 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1124 cc->SetColorScheme(cs);
1125 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1126 cc->HideChartInfoWindow();
1127 cc->SetQuiltChartHiLiteIndex(-1);
1133 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1134 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1137 g_options->SetColorScheme(cs);
1141 console->SetColorScheme(cs);
1145 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1148 if (g_pMarkInfoDialog) {
1149 g_pMarkInfoDialog->SetColorScheme(cs);
1152 if (pRoutePropDialog) {
1153 pRoutePropDialog->SetColorScheme(cs);
1158 if (g_pais_query_dialog_active) {
1159 bool b_isshown = g_pais_query_dialog_active->IsShown();
1160 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1161 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1163 g_pais_query_dialog_active->Close();
1166 g_pais_query_dialog_active->
Create(
1167 this, -1, _(
"AIS Target Query"),
1168 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1169 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1170 g_pais_query_dialog_active->UpdateText();
1171 if (b_isshown) g_pais_query_dialog_active->Show();
1174 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1176 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1178 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1180 ApplyGlobalColorSchemetoStatusBar();
1182 UpdateAllToolbars(cs);
1184 if (g_MainToolbar) {
1185 if (g_MainToolbar->GetColorScheme() != cs) {
1187 bool btoolbarFull = g_bmasterToolbarFull;
1189 g_MainToolbar->SetColorScheme(cs);
1193 if (!btoolbarFull) {
1195 RequestNewMasterToolbar();
1196 g_MainToolbar->SetColorScheme(cs);
1197 CollapseGlobalToolbar();
1200 RequestNewMasterToolbar();
1201 g_MainToolbar->SetColorScheme(cs);
1206 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1209void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1210 if (m_pStatusBar != NULL) {
1211 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1212 m_pStatusBar->ClearBackground();
1217 if (g_canvasArray.GetCount() > 0)
1218 return g_canvasArray.Item(0);
1222void MyFrame::CancelAllMouseRoute() {
1224 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1226 if (cc) cc->CancelMouseRoute();
1230void MyFrame::NotifyChildrenResize() {}
1232void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1234 if (ChartData) ChartData->PurgeCache();
1237 if (console) console->Show(
false);
1240 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1243 g_pauimgr->DetachPane(cc);
1248 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1257 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1260 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1261 config_array.Item(i)->canvas = NULL;
1267 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1268 g_canvasArray.RemoveAt(i);
1272 switch (g_canvasConfig) {
1275 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1278 g_canvasArray.Add(cc);
1280 cc = g_canvasArray[0];
1286 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1287 cc->GetglCanvas()->Show();
1290 config_array.Item(0)->canvas = cc;
1294 cc->ApplyCanvasConfig(config_array.Item(0));
1298 cc->ConfigureChartBar();
1299 cc->SetColorScheme(global_color_scheme);
1300 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1301 cc->SetShowGPS(
true);
1303 g_pauimgr->AddPane(cc);
1304 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1305 g_pauimgr->GetPane(cc).Fixed();
1306 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1307 g_pauimgr->GetPane(cc).CenterPane();
1312 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1314 g_canvasArray.Add(cc);
1316 cc = g_canvasArray[0];
1322 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1325 config_array.Item(0)->canvas = cc;
1327 cc->ApplyCanvasConfig(config_array.Item(0));
1330 cc->ConfigureChartBar();
1331 cc->SetColorScheme(global_color_scheme);
1332 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1333 cc->SetShowGPS(
false);
1335 g_pauimgr->AddPane(cc);
1336 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1337 g_pauimgr->GetPane(cc)
1338 .CaptionVisible(
false)
1340 .CloseButton(
false);
1342 g_pauimgr->GetPane(cc).CenterPane();
1345 g_canvasArray.Add(cc);
1349 if (config_array.GetCount() < 2) {
1351 pcc->configIndex = 1;
1355 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1356 config_array.Add(pcc);
1359 config_array.Item(1)->canvas = cc;
1361 cc->ApplyCanvasConfig(config_array.Item(1));
1364 cc->ConfigureChartBar();
1365 cc->SetColorScheme(global_color_scheme);
1366 cc->SetShowGPS(
true);
1369 g_pauimgr->AddPane(cc);
1370 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1371 g_pauimgr->GetPane(cc)
1372 .CaptionVisible(
false)
1374 .CloseButton(
false);
1375 g_pauimgr->GetPane(cc).RightDockable(
true);
1376 g_pauimgr->GetPane(cc).Right();
1379 config_array.Item(1)->canvasSize =
1380 wxSize(GetClientSize().x / 2, GetClientSize().y);
1381 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1386 if (b_useStoredSize) {
1387 int ccw = config_array.Item(1)->canvasSize.x;
1388 int cch = config_array.Item(1)->canvasSize.y;
1391 if (ccw < GetClientSize().x / 10) {
1392 ccw = GetClientSize().x / 2;
1393 cch = GetClientSize().y;
1396 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1397 cc->SetSize(ccw, cch);
1408 g_focusCanvas = GetPrimaryCanvas();
1411 if (g_canvasArray.size() > 1)
1412 console =
new APConsole(g_canvasArray.Item(1));
1414 console =
new APConsole(g_canvasArray.Item(0));
1415 console->SetColorScheme(global_color_scheme);
1419 if (g_pRouteMan->IsAnyRouteActive()) {
1420 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1426void MyFrame::RequestNewToolbars(
bool bforcenew) {
1427 if (b_inCloseWindow) {
1431 BuildiENCToolbar(bforcenew);
1432 PositionIENCToolbar();
1441void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1442 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1447void MyFrame::SetAllToolbarScale() {
1448 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1451void MyFrame::SetGPSCompassScale() {
1452 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1456 wxPoint screenPoint = ::wxGetMousePosition();
1459 switch (g_canvasConfig) {
1461 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1464 if (canvas->GetScreenRect().Contains(
1468 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1471 if (canvas->GetScreenRect().Contains(
1478 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1481 if (canvas->GetScreenRect().Contains(
1482 canvas->ScreenToClient(screenPoint)))
1490int MyFrame::GetCanvasIndexUnderMouse() {
1491 wxPoint screenPoint = ::wxGetMousePosition();
1494 switch (g_canvasConfig) {
1496 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1499 if (canvas->GetScreenRect().Contains(
1503 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1506 if (canvas->GetScreenRect().Contains(
1513 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1516 if (canvas->GetScreenRect().Contains(
1517 canvas->ScreenToClient(screenPoint)))
1525bool MyFrame::DropMarker(
bool atOwnShip) {
1532 if (!canvas)
return false;
1539 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1541 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1543 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1548 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1549 pRouteManagerDialog->UpdateWptListCtrl();
1554 RefreshAllCanvas(
false);
1559void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1560 if (g_canvasConfig != 0) {
1563 int nTargetGTK = -1;
1565 wxWindow *source = FindFocus();
1571 switch (g_canvasConfig) {
1573 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1576 if (canvas && (canvas == test)) {
1581 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1584 if (canvas && (canvas == test)) {
1592 int nfinalTarget = nTarget;
1594 nfinalTarget = nTargetGTK;
1596 target = ConfigMgr::Get()
1597 .GetCanvasConfigArray()
1602 target->Refresh(
true);
1613void MyFrame::FastClose() {
1615 FrameTenHzTimer.Stop();
1617 FrameTimer1.Start(1);
1621void MyFrame::OnExit(wxCommandEvent &event) {
1625void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1628 if (b_inCloseWindow) {
1638 if (!g_bDeferredInitDone)
return;
1651 if (b_inCompressAllCharts) {
1655 if (bDBUpdateInProgress)
return;
1657 b_inCloseWindow =
true;
1659 ::wxSetCursor(wxCURSOR_WAIT);
1663 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1665 if (cc && cc->IsMeasureActive()) {
1666 cc->CancelMeasureRoute();
1671 SendPreShutdownHookToPlugins();
1675 if (g_pAISTargetList) {
1676 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1677 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1678 g_pauimgr->DetachPane(g_pAISTargetList);
1689 pConfig->SetPath(_T (
"/AUI" ));
1690 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1697 if (g_glTextureManager) {
1698 g_glTextureManager->PurgeJobList();
1700 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1705 SetCursor(wxCURSOR_WAIT);
1707 RefreshAllCanvas(
true);
1713 RestoreScreenBrightness();
1722 if (g_iENCToolbar) {
1723 wxPoint locn = g_iENCToolbar->GetPosition();
1724 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1725 g_iENCToolbarPosY = tbp_incanvas.y;
1726 g_iENCToolbarPosX = tbp_incanvas.x;
1730 g_bframemax = IsMaximized();
1733 FrameTenHzTimer.Stop();
1735 FrameCOGTimer.Stop();
1749 if (g_bAutoAnchorMark) {
1750 bool watching_anchor =
false;
1751 if (pAnchorWatchPoint1)
1752 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1754 if (pAnchorWatchPoint2)
1755 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1758 wxDateTime now = wxDateTime::Now();
1759 wxTimeSpan uptime = now.Subtract(g_start_time);
1761 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1762 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1767 if (g_declutter_anchorage) {
1768 wxRoutePointListNode *node =
1769 pWayPointMan->GetWaypointList()->GetFirst();
1772 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1773 double a = gLat - pr->m_lat;
1774 double b = gLon - pr->m_lon;
1775 double l = sqrt((a * a) + (b * b));
1778 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1780 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1781 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1787 node = node->GetNext();
1791 wxString name = now.Format();
1792 name.Prepend(_(
"Anchorage created "));
1794 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1798 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1803 pConfig->UpdateSettings();
1807 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1811 NavObj_dB::GetInstance().Close();
1815 pConfig->DeleteGroup(_T (
"/Routes" ));
1816 pConfig->DeleteGroup(_T (
"/Marks" ));
1819 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1820 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1825 if (g_pCM93OffsetDialog) {
1826 g_pCM93OffsetDialog->Destroy();
1827 g_pCM93OffsetDialog = NULL;
1835 if (g_iENCToolbar) {
1842 if (g_pAISTargetList) {
1843 g_pAISTargetList->Disconnect_decoder();
1844 g_pAISTargetList->Destroy();
1851 if (RouteManagerDialog::getInstanceFlag()) {
1852 if (pRouteManagerDialog) {
1853 pRouteManagerDialog->Destroy();
1854 pRouteManagerDialog = NULL;
1859 if (ChartData) ChartData->PurgeCache();
1865 g_focusCanvas = NULL;
1868 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1870 if (cc) cc->Destroy();
1873 g_canvasArray.Clear();
1875 g_pauimgr->UnInit();
1885 if (ChartData) ChartData->PurgeCachePlugins();
1890 delete g_pi_manager;
1891 g_pi_manager = NULL;
1894 MyApp &app = wxGetApp();
1895 app.m_comm_bridge.SaveConfig();
1915 auto ®istry = CommDriverRegistry::GetInstance();
1916 registry.CloseAllDrivers();
1919 for (
auto *cp : TheConnectionParams()) {
1924 LayerList::iterator it;
1925 while (pLayerList->GetCount()) {
1926 Layer *lay = pLayerList->GetFirst()->GetData();
1931 ReleaseApiListeners();
1933 g_MainToolbar = NULL;
1934 g_bTempShowMenuBar =
false;
1936#define THREAD_WAIT_SECONDS 5
1942 if (g_bopengl && g_glTextureManager &&
1943 g_glTextureManager->GetRunningJobCount()) {
1944 g_glTextureManager->ClearAllRasterTextures();
1946 wxLogMessage(_T(
"Starting compressor pool drain"));
1947 wxDateTime now = wxDateTime::Now();
1948 time_t stall = now.GetTicks();
1949 time_t end = stall + THREAD_WAIT_SECONDS;
1952 while (stall < end) {
1953 wxDateTime later = wxDateTime::Now();
1954 stall = later.GetTicks();
1957 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1958 g_glTextureManager->GetRunningJobCount());
1960 if (!g_glTextureManager->GetRunningJobCount())
break;
1966 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1967 n_comploop, g_glTextureManager->GetRunningJobCount());
1970 delete g_glTextureManager;
1972 uninitIXNetSystem();
1976 wxLogMessage(_T(
"gFrame destroyed."));
1979#ifndef USE_ANDROID_GLES2
1980 qDebug() <<
"Calling OnExit()";
1984 wxTheApp->ExitMainLoop();
1987void MyFrame::OnMove(wxMoveEvent &event) {
1988 auto idx = wxDisplay::GetFromWindow(
this);
1989 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
1990 static_cast<size_t>(idx) < g_monitor_info.size()) {
1991 g_current_monitor = idx;
1997 g_current_monitor_dip_px_ratio =
1998 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
2001 DEBUG_LOG <<
"Moved to " << idx
2002#if wxCHECK_VERSION(3, 1, 6)
2003 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
2004 << wxDisplay(idx).GetPPI().GetY()
2005 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
2007 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
2008 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
2009 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
2010 << wxGetDisplaySizeMM().GetY()
2011 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
2012 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
2013 << g_monitor_info[idx].height_mm <<
"mm "
2014 << g_monitor_info[idx].width_mm <<
"x"
2015 << g_monitor_info[idx].height_mm <<
"mm "
2016 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
2017 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
2018 << g_monitor_info[idx].height_px <<
"px"
2019 << g_monitor_info[idx].scale <<
"%";
2020 if (g_config_display_size_manual) {
2021 if (g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
2022 g_display_size_mm = g_config_display_size_mm[idx];
2025 g_display_size_mm = g_monitor_info[idx].width_mm;
2029 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2032 cc->SetMUIBarPosition();
2041 UpdateGPSCompassStatusBoxes();
2043 if (console && console->IsShown()) PositionConsole();
2051 PositionIENCToolbar();
2057 g_nframewin_posx = GetPosition().x;
2058 g_nframewin_posy = GetPosition().y;
2061void MyFrame::ProcessCanvasResize(
void) {
2062 UpdateGPSCompassStatusBoxes(
true);
2064 if (console && console->IsShown()) PositionConsole();
2066 PositionIENCToolbar();
2069 TriggerRecaptureTimer();
2073void MyFrame::TriggerRecaptureTimer() {
2074 m_recaptureTimer.Start(
2075 1000, wxTIMER_ONE_SHOT);
2078void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
2080void MyFrame::SetCanvasSizes(wxSize frameSize) {
2081 if (!g_canvasArray.GetCount())
return;
2084 int cccw = frameSize.x;
2085 int ccch = frameSize.y;
2089 switch (g_canvasConfig) {
2093 cc = g_canvasArray.Item(0);
2095 cc->GetSize( &cur_width, &cur_height );
2096 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2097 if( g_pauimgr->GetPane( cc ).IsOk() )
2098 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2100 cc->SetSize( 0, 0, cccw, ccch );
2108 cc = g_canvasArray.Item(1);
2110 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2111 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2113 ccw = wxMin(ccw, cccw * 8 / 10);
2114 ccw = wxMax(ccw, cccw * 2 / 10);
2118 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2125 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2126 g_pauimgr->GetPane(cc).Fixed();
2127 g_pauimgr->Update();
2130 g_pauimgr->GetPane(cc).Resizable();
2142void MyFrame::OnIconize(wxIconizeEvent &event) {
2144 if (g_MainToolbar) {
2145 g_MainToolbar->Show(!event.IsIconized());
2147 if (g_iENCToolbar) {
2148 g_iENCToolbar->Show(!event.IsIconized());
2152 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2154 if (cc && cc->GetMUIBar()) {
2155 if (cc->GetMUIBar()->GetCanvasOptions()) {
2156 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2157 cc->GetMUIBar()->PushCanvasOptions();
2166void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2168void MyFrame::ODoSetSize(
void) {
2170 GetClientSize(&x, &y);
2173 if (m_pStatusBar != NULL) {
2174 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2175 int currentCount = m_pStatusBar->GetFieldsCount();
2176 if (currentCount != m_StatusBarFieldCount) {
2177 if ((currentCount > 0) && (currentCount < 7)) {
2180 int widths[] = {2, 2, 2, 2, 2, 2};
2181 m_pStatusBar->SetStatusWidths(currentCount, widths);
2184 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2187 if (m_StatusBarFieldCount) {
2192 if (m_StatusBarFieldCount > 2) {
2193 int widths[] = {-6, -5, -5, -6, -4};
2194 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2195 }
else if (m_StatusBarFieldCount == 2) {
2196 int cwidth = x * 90 / 100;
2197 int widths[] = {100, 100};
2198 widths[0] = cwidth * 6.4 / 10.0;
2199 widths[1] = cwidth * 3.6 / 10.0;
2200 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2202 int widths[] = {100, 100};
2203 widths[0] = x * 90 / 100;
2204 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2207 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2208 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2209 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2211 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2212 _T(
" COG ---\u00B0"));
2213 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2221 m_pStatusBar->GetFieldRect(0, stat_box);
2224 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2226 wxFont sys_font = *wxNORMAL_FONT;
2227 int try_font_size = sys_font.GetPointSize();
2230 int min_font_size = 10;
2240 wxFont *statusBarFont =
2241 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2242 int font_size = statusBarFont->GetPointSize();
2244 font_size = wxMin(font_size,
2247 wxMax(font_size, min_font_size);
2250 font_size = statusBarFont->GetPointSize();
2257 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2258 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2260 int min_height = stat_box.height;
2262 m_pStatusBar->SetFont(*pstat_font);
2263 m_pStatusBar->SetForegroundColour(
2264 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2266 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2268 (min_height >> 1) * 2;
2269 m_pStatusBar->SetMinHeight(min_height);
2278 SetCanvasSizes(GetClientSize());
2280 UpdateGPSCompassStatusBoxes(
true);
2282 if (console) PositionConsole();
2285 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2287 if (cc) cc->FormatPianoKeys();
2291 if (g_MainToolbar) {
2292 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2293 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2294 GetPrimaryCanvas()->GetCompass()->GetRect());
2295 g_MainToolbar->Realize();
2297 if (szBefore != g_MainToolbar->GetToolbarSize())
2298 g_MainToolbar->RefreshToolbar();
2307 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2320 options_lastWindowSize = wxSize(0, 0);
2321 options_lastWindowPos = wxPoint(0, 0);
2328 if (!b_inCloseWindow) {
2329 if (g_options) g_options->Raise();
2331 resizeAndroidPersistents();
2335 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2336 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2339 if (g_pauimgr) g_pauimgr->Update();
2342void MyFrame::PositionConsole(
void) {
2343#if defined(__WXMSW__) || defined(__WXMAC__)
2344 if (NULL == GetPrimaryCanvas())
return;
2346 int ccx, ccy, ccsx, ccsy, consx, consy;
2348 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2351 consoleHost->GetSize(&ccsx, &ccsy);
2352 consoleHost->GetPosition(&ccx, &ccy);
2354 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2355 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2356 consoleHost = GetPrimaryCanvas();
2361 if (consoleHost->GetCompass()) {
2362 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2364 if (compass_rect.y < 100)
2365 yOffset = compass_rect.y + compass_rect.height + 45;
2369 wxSize csz = console->GetSize();
2373 wxPoint screen_pos =
2374 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2375 console->Move(screen_pos);
2377 if (NULL == GetPrimaryCanvas())
return;
2379 int ccx, ccy, ccsx, ccsy, consx, consy;
2381 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2384 consoleHost->GetSize(&ccsx, &ccsy);
2385 consoleHost->GetPosition(&ccx, &ccy);
2387 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2388 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2389 consoleHost = GetPrimaryCanvas();
2392 int yTopOffset = 60;
2393 int yBottomOffset = 0;
2395 if (consoleHost->GetCompass()) {
2396 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2398 if (compass_rect.y < 100)
2399 yTopOffset = compass_rect.y + compass_rect.height;
2401 if (consoleHost->GetMUIBar()) {
2402 wxRect mui_rect = consoleHost->GetMUIBarRect();
2403 yBottomOffset = ccsy - mui_rect.y;
2407 wxSize csz = console->GetSize();
2410 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2412 if (consy < yAvail) {
2413 yFinal = (yAvail - consy) / 2;
2414 yFinal += yTopOffset;
2415 }
else if (console->GetCDI()->IsShown()) {
2416 int cdi_height = console->GetCDI()->GetSize().y;
2417 int consy_no_cdi = consy - cdi_height;
2418 yFinal = (yAvail - consy_no_cdi) / 2;
2419 yFinal += yTopOffset;
2420 console->ToggleShowHighway();
2423 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2424 console->Move(in_canvas_pos);
2428void MyFrame::UpdateAllFonts() {
2430 console->UpdateFonts();
2437 DestroyPersistentDialogs();
2439 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2444void MyFrame::DestroyPersistentDialogs() {
2445 if (g_pais_query_dialog_active) {
2446 g_pais_query_dialog_active->Hide();
2447 g_pais_query_dialog_active->Destroy();
2448 g_pais_query_dialog_active = NULL;
2451 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2452 pRoutePropDialog->Hide();
2453 pRoutePropDialog->Destroy();
2454 pRoutePropDialog = NULL;
2457 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2458 pTrackPropDialog->Hide();
2459 pTrackPropDialog->Destroy();
2460 pTrackPropDialog = NULL;
2463 if (g_pMarkInfoDialog) {
2464 g_pMarkInfoDialog->Hide();
2465 g_pMarkInfoDialog->Destroy();
2466 g_pMarkInfoDialog = NULL;
2469 if (g_pObjectQueryDialog) {
2470 g_pObjectQueryDialog->Hide();
2471 g_pObjectQueryDialog->Destroy();
2472 g_pObjectQueryDialog = NULL;
2476void MyFrame::RefreshGroupIndices(
void) {
2478 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2480 if (cc) cc->canvasRefreshGroupIndex();
2484void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2485 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2487 switch (event.GetId()) {
2488 case ID_MENU_SCALE_OUT:
2489 DoStackDelta(GetPrimaryCanvas(), 1);
2493 case ID_MENU_SCALE_IN:
2494 DoStackDelta(GetPrimaryCanvas(), -1);
2498 case ID_MENU_ZOOM_IN: {
2499 if (GetFocusCanvas()) {
2500 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2505 case ID_MENU_ZOOM_OUT: {
2506 if (GetFocusCanvas()) {
2507 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2512 case ID_MENU_ROUTE_NEW: {
2513 if (GetFocusCanvas()) {
2514 if (0 == GetFocusCanvas()->m_routeState) {
2515 GetFocusCanvas()->StartRoute();
2517 GetFocusCanvas()->FinishRoute();
2523 case ID_MENU_TOOL_MEASURE: {
2524 GetPrimaryCanvas()->StartMeasureRoute();
2528 case ID_MENU_TOOL_NMEA_DBG_LOG:
2529 m_data_monitor->Show();
2530 m_data_monitor->Raise();
2533 case ID_MENU_TOOL_IO_MONITOR:
2534 m_data_monitor->Show();
2537 case ID_MENU_MARK_BOAT: {
2542 case ID_MENU_MARK_CURSOR: {
2547 case ID_MENU_NAV_FOLLOW: {
2548 if (gFrame->GetPrimaryCanvas())
2549 gFrame->GetPrimaryCanvas()->TogglebFollow();
2553 case ID_MENU_CHART_OUTLINES: {
2554 ToggleChartOutlines(GetFocusCanvas());
2558 case ID_MENU_CHART_QUILTING: {
2559 ToggleQuiltMode(GetFocusCanvas());
2563 case ID_MENU_UI_CHARTBAR: {
2564 ToggleChartBar(GetFocusCanvas());
2568 case ID_MENU_ENC_TEXT:
2570 ToggleENCText(GetFocusCanvas());
2573 case ID_MENU_ENC_LIGHTS: {
2574 ToggleLights(GetFocusCanvas());
2577 case ID_MENU_ENC_SOUNDINGS: {
2578 ToggleSoundings(GetFocusCanvas());
2581 case ID_MENU_ENC_ANCHOR: {
2582 ToggleAnchor(GetFocusCanvas());
2585 case ID_MENU_ENC_DATA_QUALITY: {
2586 ToggleDataQuality(GetFocusCanvas());
2589 case ID_MENU_SHOW_NAVOBJECTS: {
2590 ToggleNavobjects(GetFocusCanvas());
2594 case ID_MENU_AIS_TARGETS: {
2595 ToggleAISDisplay(GetFocusCanvas());
2598 case ID_MENU_AIS_MOORED_TARGETS: {
2599 g_bHideMoored = !g_bHideMoored;
2602 case ID_MENU_AIS_SCALED_TARGETS: {
2603 ToggleAISMinimizeTargets(GetFocusCanvas());
2607 case ID_MENU_AIS_TARGETLIST: {
2608 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2612 case ID_MENU_AIS_TRACKS: {
2613 g_bAISShowTracks = !g_bAISShowTracks;
2614 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2618 case ID_MENU_AIS_CPADIALOG: {
2619 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2620 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2621 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2622 if (g_bAIS_CPA_Alert) {
2623 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2628 case ID_MENU_AIS_CPASOUND: {
2629 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2630 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2634 case ID_MENU_AIS_CPAWARNING: {
2635 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2636 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2640 case wxID_PREFERENCES:
2642 g_MainToolbar->HideTooltip();
2647 case ID_SETTINGS_NEW: {
2652 case ID_SETTINGS_DELETE: {
2654 g_options =
nullptr;
2655 g_pOptions =
nullptr;
2659 case ID_MENU_SETTINGS_BASIC: {
2662 androidDisableFullScreen();
2663 g_MainToolbar->HideTooltip();
2664 DoAndroidPreferences();
2671 case ID_MENU_UI_FULLSCREEN: {
2676 case ID_MENU_SHOW_CURRENTS: {
2677 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2678 GetFocusCanvas()->ReloadVP();
2679 GetFocusCanvas()->Refresh(
false);
2683 case ID_MENU_SHOW_TIDES: {
2684 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2685 GetFocusCanvas()->ReloadVP();
2686 GetFocusCanvas()->Refresh(
false);
2706 case ID_MENU_UI_COLSCHEME:
2707 case ID_COLSCHEME: {
2708 ToggleColorScheme();
2717 case ID_MENU_OQUIT: {
2722 case ID_MENU_ROUTE_MANAGER:
2723 case ID_ROUTEMANAGER: {
2724 pRouteManagerDialog = RouteManagerDialog::getInstance(
2727 if (pRouteManagerDialog->IsShown())
2728 pRouteManagerDialog->Hide();
2730 pRouteManagerDialog->UpdateRouteListCtrl();
2731 pRouteManagerDialog->UpdateTrkListCtrl();
2732 pRouteManagerDialog->UpdateWptListCtrl();
2733 pRouteManagerDialog->UpdateLayListCtrl();
2735 pRouteManagerDialog->Show();
2739 pRouteManagerDialog->Centre();
2740 pRouteManagerDialog->Raise();
2746 case ID_MENU_NAV_TRACK:
2748 if (!g_bTrackActive) {
2750 g_bTrackCarryOver =
true;
2753 g_bTrackCarryOver =
false;
2754 RefreshAllCanvas(
true);
2759 case ID_MENU_CHART_NORTHUP: {
2760 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2763 case ID_MENU_CHART_COGUP: {
2764 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2767 case ID_MENU_CHART_HEADUP: {
2768 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2772 case ID_MENU_MARK_MOB:
2778 case ID_MASTERTOGGLE: {
2779 if (g_MainToolbar) {
2780 wxString tip = _(
"Show Toolbar");
2781 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2782 if (g_MainToolbar->GetToolbar())
2783 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2785 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2788 if (g_bmasterToolbarFull)
2789 m_nMasterToolCountShown =
2790 g_MainToolbar->GetToolCount() -
2793 m_nMasterToolCountShown = 2;
2795 m_nMasterToolCountShown =
2796 g_MainToolbar->GetToolShowCount();
2798 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2806 case ID_CMD_SELECT_CHART_TYPE: {
2807 selectChartDisplay(event.GetExtraLong(), -1);
2811 case ID_CMD_SELECT_CHART_FAMILY: {
2812 selectChartDisplay(-1, event.GetExtraLong());
2816 case ID_CMD_APPLY_SETTINGS: {
2817 applySettingsString(event.GetString());
2819 androidRestoreFullScreen();
2825 case ID_CMD_NULL_REFRESH: {
2830 case ID_CMD_SETVP: {
2831 setStringVP(event.GetString());
2835 case ID_CMD_INVALIDATE: {
2841 case ID_CMD_POST_JSON_TO_PLUGINS: {
2847 int numErrors = reader.
Parse(event.GetString(), &root);
2848 if (numErrors == 0) {
2849 if (root[_T(
"MessageID")].IsString()) {
2850 wxString MsgID = root[_T(
"MessageID")].
AsString();
2861 if (g_iENCToolbar) {
2862 g_iENCToolbar->OnToolLeftClick(event);
2872 g_MainToolbar->HideTooltip();
2874 ArrayOfPlugInToolbarTools tool_array =
2875 g_pi_manager->GetPluginToolbarToolArray();
2876 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2878 if (event.GetId() == pttc->id) {
2879 if (pttc->m_pplugin)
2898 if (g_MainToolbar) g_MainToolbar->Realize();
2901bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2902 bool viz_now = g_bmasterToolbarFull;
2904 g_MainToolbar->HideTooltip();
2905 wxString tip = _(
"Show Toolbar");
2907 tip = _(
"Hide Toolbar");
2908 if (g_MainToolbar->GetToolbar())
2909 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2912 bool toggle =
false;
2913 if (viz && !g_bmasterToolbarFull)
2916 else if (!viz && g_bmasterToolbarFull)
2920 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2923 if (g_bmasterToolbarFull)
2924 m_nMasterToolCountShown =
2925 g_MainToolbar->GetToolCount() -
2928 m_nMasterToolCountShown = 2;
2930 m_nMasterToolCountShown =
2931 g_MainToolbar->GetToolShowCount();
2933 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2939void MyFrame::ScheduleDeleteSettingsDialog() {
2940 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2941 evt.SetId(ID_SETTINGS_DELETE);
2942 GetEventHandler()->AddPendingEvent(evt);
2945void MyFrame::ScheduleSettingsDialog() {
2946 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2947 evt.SetId(ID_SETTINGS);
2948 GetEventHandler()->AddPendingEvent(evt);
2951void MyFrame::ScheduleSettingsDialogNew() {
2952 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2953 evt.SetId(ID_SETTINGS_NEW);
2954 GetEventHandler()->AddPendingEvent(evt);
2957void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2958 UpdateCanvasConfigDescriptors();
2960 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2961 CreateCanvasLayout(
true);
2963 CreateCanvasLayout();
2965 g_pauimgr->Update();
2967 ConfigureStatusBar();
2968 wxSize lastOptSize = options_lastWindowSize;
2973 options_lastWindowSize = lastOptSize;
2977 ScheduleSettingsDialogNew();
2979 ScheduleSettingsDialog();
2984 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2987 int index_hint = -1;
2988 if (i < pathArray.GetCount())
2989 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
2990 cc->canvasChartsRefresh(index_hint);
2991 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2997 if ((g_canvasConfig != 0) && g_focusCanvas)
2998 return g_focusCanvas;
3000 return GetPrimaryCanvas();
3003void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
3004 if (g_bmasterToolbarFull) {
3005#ifndef OCPN_TOOLBAR_ANIMATE
3006 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
3009 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
3010 m_nMasterToolCountShown++;
3011 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3012 g_MainToolbar->Realize();
3013 g_MainToolbar->RefreshToolbar();
3015 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
3017 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3018 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
3019 g_MainToolbar->Realize();
3020 g_MainToolbar->RefreshToolbar();
3023#ifndef OCPN_TOOLBAR_ANIMATE
3024 m_nMasterToolCountShown = 1;
3026 if (m_nMasterToolCountShown > 1) {
3027 m_nMasterToolCountShown--;
3028 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3029 g_MainToolbar->Realize();
3030 g_MainToolbar->RefreshToolbar();
3031 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
3033 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
3034 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
3035 g_MainToolbar->Realize();
3036 g_MainToolbar->RefreshToolbar();
3041void MyFrame::InvalidateAllGL() {
3044 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3054void MyFrame::RefreshAllCanvas(
bool bErase) {
3056 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3059 cc->Refresh(bErase);
3064void MyFrame::setStringVP(wxString VPS) {
3069 wxStringTokenizer tkz(VPS, _T(
";"));
3071 wxString token = tkz.GetNextToken();
3073 token.ToDouble(&lat);
3075 token = tkz.GetNextToken();
3077 token.ToDouble(&lon);
3079 token = tkz.GetNextToken();
3081 token.ToDouble(&scale_ppm);
3083 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
3086void MyFrame::DoSettingsNew() {
3088 g_options =
nullptr;
3093void MyFrame::DoSettings() {
3097 ApplyGlobalSettings(
true);
3100 bool b_loadHarmonics =
false;
3101 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3104 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3107 if (b_loadHarmonics) LoadHarmonics();
3115 g_bShowChartBar = !g_bShowChartBar;
3117 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3122 if (g_bShowChartBar) {
3124 UpdateControlBar(cc);
3127 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3130void MyFrame::ToggleColorScheme() {
3131 static bool lastIsNight;
3132 ColorScheme s = GetColorScheme();
3135 if (lastIsNight && is == 3)
3138 lastIsNight =
false;
3140 if (lastIsNight) is = 2;
3141 if (is == 3) lastIsNight =
true;
3142 s = (ColorScheme)is;
3143 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3145 SetAndApplyColorScheme(s);
3148void MyFrame::ToggleFullScreen() {
3149 bool to = !IsFullScreen();
3154 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3156 ShowFullScreen(to, style);
3159 UpdateAllToolbars(global_color_scheme);
3161 UpdateControlBar(GetPrimaryCanvas());
3163 TriggerRecaptureTimer();
3166void MyFrame::ActivateMOB(
void) {
3168 wxDateTime mob_time = wxDateTime::Now();
3169 wxString mob_label(_(
"MAN OVERBOARD"));
3170 mob_label += _(
" on ");
3171 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3174 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3175 pWP_MOB->SetShared(
true);
3177 pWP_MOB->SetWaypointArrivalRadius(
3179 pWP_MOB->SetUseSca(
false);
3180 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3181 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3183 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3186 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3189 new RoutePoint(zlat, zlon, g_default_wp_icon,
3190 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3191 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3194 pRouteList->Append(temp_route);
3196 temp_route->AddPoint(pWP_src);
3197 temp_route->AddPoint(pWP_MOB);
3199 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3209 temp_route->SetRouteArrivalRadius(-1.0);
3211 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3215 v[_T(
"GUID")] = temp_route->
m_GUID;
3216 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
3217 SendJSONMessageToAllPlugins(msg_id, v);
3220 if (RouteManagerDialog::getInstanceFlag()) {
3221 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3222 pRouteManagerDialog->UpdateRouteListCtrl();
3223 pRouteManagerDialog->UpdateWptListCtrl();
3228 RefreshAllCanvas(
false);
3230 wxString mob_message(_(
"MAN OVERBOARD"));
3231 mob_message += _(
" Time: ");
3232 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3233 mob_message += _(
" Position: ");
3234 mob_message += toSDMM(1, gLat);
3235 mob_message += _T(
" ");
3236 mob_message += toSDMM(2, gLon);
3237 wxLogMessage(mob_message);
3239void MyFrame::TrackOn(
void) {
3240 g_bTrackActive =
true;
3243 g_TrackList.push_back(g_pActiveTrack);
3244 NavObj_dB::GetInstance().InsertTrack(g_pActiveTrack);
3245 g_pActiveTrack->Start();
3248 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3250 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3252 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3255 androidSetTrackTool(
true);
3258 if (RouteManagerDialog::getInstanceFlag()) {
3259 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3260 pRouteManagerDialog->UpdateTrkListCtrl();
3261 pRouteManagerDialog->UpdateRouteListCtrl();
3266 wxString name = g_pActiveTrack->GetName();
3267 if (name.IsEmpty()) {
3268 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3273 name = _(
"(Unnamed Track)");
3275 v[_T(
"Name")] = name;
3276 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3277 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3278 SendJSONMessageToAllPlugins(msg_id, v);
3279 g_FlushNavobjChangesTimeout =
3283Track *MyFrame::TrackOff(
bool do_add_point) {
3284 Track *return_val = g_pActiveTrack;
3286 if (g_pActiveTrack) {
3288 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3289 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3290 SendJSONMessageToAllPlugins(msg_id, v);
3292 g_pActiveTrack->Stop(do_add_point);
3294 if (g_pActiveTrack->GetnPoints() < 2) {
3295 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3296 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3299 if (g_bTrackDaily) {
3300 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3302 NavObj_dB::GetInstance().DeleteTrack(g_pActiveTrack);
3303 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3304 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3305 return_val = pExtendTrack;
3309 g_pActiveTrack = NULL;
3312 g_bTrackActive =
false;
3314 if (RouteManagerDialog::getInstanceFlag()) {
3315 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3316 pRouteManagerDialog->UpdateTrkListCtrl();
3317 pRouteManagerDialog->UpdateRouteListCtrl();
3321 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3323 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3324 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3327 androidSetTrackTool(
false);
3330 g_FlushNavobjChangesTimeout =
3336bool MyFrame::ShouldRestartTrack(
void) {
3337 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3338 time_t now = wxDateTime::Now().GetTicks();
3339 time_t today = wxDateTime::Today().GetTicks();
3341 switch (g_track_rotate_time_type) {
3343 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3345 case TIME_TYPE_COMPUTER:
3346 rotate_at = g_track_rotate_time;
3350 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3351 rotate_at = g_track_rotate_time + utc_offset;
3354 if (rotate_at > 86400)
3356 else if (rotate_at < 0)
3358 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3359 now - today >= rotate_at) {
3360 if (m_last_track_rotation_ts == 0) {
3361 if (now - today > rotate_at)
3362 m_last_track_rotation_ts = today + rotate_at;
3364 m_last_track_rotation_ts = today + rotate_at - 86400;
3367 m_last_track_rotation_ts = now;
3373void MyFrame::TrackDailyRestart(
void) {
3374 if (!g_pActiveTrack)
return;
3375 Track *pPreviousTrack = TrackOff(
true);
3382 if (pPreviousTrack) {
3383 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3384 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3387 if (RouteManagerDialog::getInstanceFlag()) {
3388 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3389 pRouteManagerDialog->UpdateTrkListCtrl();
3390 pRouteManagerDialog->UpdateRouteListCtrl();
3395void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3397 cc->SetUpMode(mode);
3399 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3400 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3401 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3404 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3409 cc->SetShowENCText(!cc->GetShowENCText());
3411 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3419void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3422 cc->SetENCDisplayCategory(nset);
3424 UpdateGlobalMenuItems();
3435 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3437 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3446 cc->SetShowENCLights(!cc->GetShowENCLights());
3448 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3450 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3458void MyFrame::ToggleRocks(
void )
3464 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3465 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3466 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3467 pOLE->nViz = !pOLE->nViz;
3471 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3472 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3473 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3476 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3480 ps52plib->GenerateStateHash();
3487 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3489 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3491 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3497 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3499 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3501 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3514 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3515 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3520 cc->SetShowAIS(!cc->GetShowAIS());
3521 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3525void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3526 cc->SetAttenAIS(!cc->GetAttenAIS());
3527 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3533 cc->m_bFollow =
true;
3536 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3540 SetChartUpdatePeriod();
3548 cc->m_bFollow =
false;
3550 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3554 SetChartUpdatePeriod();
3557void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3558 cc->SetShowOutlines(!cc->GetShowOutlines());
3560 RefreshAllCanvas(
false);
3564 if (g_bopengl) InvalidateAllGL();
3567 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3570void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3572void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3574 bool enabled = m_pMenuBar->IsEnabled(item_id);
3575 m_pMenuBar->Enable(item_id,
false);
3576 m_pMenuBar->Check(item_id, state);
3577 m_pMenuBar->Enable(item_id, enabled);
3581void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3582 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3583 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3584 g_MainToolbar->Realize();
3588void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3589 wxBitmap *bmpRollover) {
3590 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3591 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3592 g_MainToolbar->Realize();
3596void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3597 wxString rolloverSVGfile,
3598 wxString toggledSVGfile) {
3599 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3600 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3601 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3605void MyFrame::ConfigureStatusBar() {
3607 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3610 UseNativeStatusBar(
false);
3613 if (g_bShowStatusBar) {
3614 if (!m_pStatusBar) {
3616 CreateStatusBar(m_StatusBarFieldCount, 0);
3617 ApplyGlobalColorSchemetoStatusBar();
3622 m_pStatusBar->Destroy();
3623 m_pStatusBar = NULL;
3629void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3630 ConfigureStatusBar();
3632 wxSize lastOptSize = options_lastWindowSize;
3638 options_lastWindowSize = lastOptSize;
3640 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3643wxString _menuText(wxString name, wxString shortcut) {
3647 menutext << _T(
"\t") << shortcut;
3652void MyFrame::BuildMenuBar(
void) {
3658 bool showMenuBar =
true;
3660 bool showMenuBar = g_bShowMenuBar;
3672 m_pMenuBar =
new wxMenuBar();
3673 RegisterGlobalMenuItems();
3674 SetMenuBar(m_pMenuBar);
3678 UpdateGlobalMenuItems();
3683 m_pMenuBar->Destroy();
3689void MyFrame::RegisterGlobalMenuItems() {
3690 if (!m_pMenuBar)
return;
3692 wxMenu *nav_menu =
new wxMenu();
3693 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3694 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3695 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3696 nav_menu->AppendSeparator();
3697 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3698 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3699 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3700 nav_menu->AppendSeparator();
3702 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3703 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3705 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3706 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3708 nav_menu->AppendSeparator();
3709 nav_menu->Append(ID_MENU_SCALE_IN,
3710 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3711 nav_menu->Append(ID_MENU_SCALE_OUT,
3712 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3714 nav_menu->AppendSeparator();
3715 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3717 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3719 wxMenu *view_menu =
new wxMenu();
3721 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3722 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3723 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3724 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3726 view_menu->AppendCheckItem(
3727 ID_MENU_CHART_QUILTING,
3728 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3729 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3730 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3732 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3733 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3735 view_menu->AppendSeparator();
3737 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3738 _menuText(_(
"Show ENC text"), _T(
"T")));
3739 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3740 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3741 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3742 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3743 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3744 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3745 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3746 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3747 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3748 _menuText(_(
"Show Navobjects"), _T(
"V")));
3750 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3751 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3752 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3753 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3754 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3755 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3756 view_menu->AppendCheckItem(
3757 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3758 view_menu->AppendCheckItem(
3759 ID_MENU_ENC_DATA_QUALITY,
3760 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3761 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3762 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3764 view_menu->AppendSeparator();
3765 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3766 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3767 view_menu->AppendSeparator();
3769 view_menu->Append(ID_MENU_UI_COLSCHEME,
3770 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3772 view_menu->Append(ID_MENU_UI_COLSCHEME,
3773 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3776 view_menu->AppendSeparator();
3778 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3779 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3781 m_pMenuBar->Append(view_menu, _(
"&View"));
3783 wxMenu *ais_menu =
new wxMenu();
3784 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3785 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3786 _(
"Attenuate less critical AIS targets"));
3787 ais_menu->AppendSeparator();
3788 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3789 _(
"Hide Moored AIS Targets"));
3790 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3791 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3792 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3795 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3796 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3798 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3799 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3802 ais_menu->AppendSeparator();
3803 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3804 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3806 wxMenu *tools_menu =
new wxMenu();
3807 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3808 _menuText(_(
"Data Monitor"),
"Alt-C"));
3810 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3811 _menuText(_(
"Measure Distance"), _T(
"M")));
3813 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3814 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3817 tools_menu->AppendSeparator();
3818 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3819 tools_menu->Append(ID_MENU_ROUTE_NEW,
3820 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3821 tools_menu->AppendSeparator();
3822 tools_menu->Append(ID_MENU_MARK_BOAT,
3823 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3824 tools_menu->Append(ID_MENU_MARK_CURSOR,
3825 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3826 tools_menu->AppendSeparator();
3831 _(
"Drop MOB Marker"),
3832 _T(
"RawCtrl-Space")));
3833 tools_menu->AppendSeparator();
3834 tools_menu->Append(wxID_PREFERENCES,
3835 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3837 tools_menu->Append(ID_MENU_MARK_MOB,
3838 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3839 tools_menu->AppendSeparator();
3840 tools_menu->Append(wxID_PREFERENCES,
3841 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3843 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3846 wxMenu *window_menu =
new wxMenu();
3847 m_pMenuBar->Append(window_menu, _(
"&Window"));
3850 wxMenu *help_menu =
new wxMenu();
3851 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3852 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3853 m_pMenuBar->Append(help_menu, _(
"&Help"));
3856 UpdateGlobalMenuItems();
3859void MyFrame::UpdateGlobalMenuItems() {
3860 if (!m_pMenuBar)
return;
3862 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3863 ->Check(GetPrimaryCanvas()->m_bFollow);
3864 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3865 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3866 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3867 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3868 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3869 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3870 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3871 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3872 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3873 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3874 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3875 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3876 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3877 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3878 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3879 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3880 if (g_bAIS_CPA_Alert) {
3881 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3882 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3884 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3885 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3888 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3889 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3890 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3893 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3894 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3895 ->Check(ps52plib->GetShowSoundings());
3897 bool light_state =
false;
3899 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3901 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3902 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3903 light_state = (pOLE->nViz == 1);
3908 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3909 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3913 DisCat nset = ps52plib->GetDisplayCategory();
3914 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3915 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3916 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3917 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3918 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3919 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3920 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3922 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3923 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3924 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3929void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3930 if (!m_pMenuBar)
return;
3932 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3934 if (cc->GetUpMode() == NORTH_UP_MODE)
3935 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3936 else if (cc->GetUpMode() == COURSE_UP_MODE)
3937 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3939 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3941 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3942 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3943 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3944 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3945 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3946 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3947 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3948 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3949 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3950 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3951 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3952 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3953 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3954 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3955 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3958 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3959 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3962 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3964 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3965 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3970 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3974 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3975 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3976 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3977 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3978 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3979 ->Check(cc->GetShowENCDataQual());
3980 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3982 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3983 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3984 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3989void MyFrame::InvalidateAllCanvasUndo() {
3991 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3993 if (cc) cc->undo->InvalidateUndo();
3997void MyFrame::SubmergeAllCanvasToolbars(
void) {
3999 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4001 if (cc) cc->SubmergeToolbar();
4005void MyFrame::SurfaceAllCanvasToolbars(
void) {
4006 if (g_bshowToolbar) {
4008 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4010 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
4017void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
4019 if (lon > 180.0) lon -= 360.0;
4024 cc->JumpToPosition(lat, lon,
scale);
4027 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
4031void MyFrame::UpdateCanvasConfigDescriptors() {
4033 for (
unsigned int i = 0;
4034 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
4035 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
4043 cc->DBindex = chart->GetQuiltReferenceChartIndex();
4044 cc->GroupID = chart->m_groupIndex;
4047 cc->
bQuilt = chart->GetQuiltMode();
4054 cc->
bFollow = chart->m_bFollow;
4059 int upmode = chart->GetUpMode();
4060 if (upmode == COURSE_UP_MODE)
4062 else if (upmode == HEAD_UP_MODE)
4069void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
4070 if (!RBBox.GetValid())
return;
4072 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
4073 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
4076 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
4077 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
4085 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4086 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
4088 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4089 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
4091 cc->GetSize(&ww, &wh);
4093 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4095 ppm = wxMin(ppm, 1.0);
4101void MyFrame::PrepareOptionsClose(
options *settings,
4102 int settings_return_value) {
4104 options_lastPage = settings->lastPage;
4109 if (options_lastPage == 1) options_lastPage = 0;
4111 options_subpage = settings->lastSubPage;
4112 options_lastWindowPos = settings->lastWindowPos;
4113 options_lastWindowSize = settings->lastWindowSize;
4116 androidEnableBackButton(
true);
4117 androidEnableOptionsMenu(
true);
4118 androidRestoreFullScreen();
4119 androidEnableRotation();
4123void MyFrame::DoOptionsDialog() {
4124 if (NULL == g_options) {
4125 AbstractPlatform::ShowBusySpinner();
4128 pConfig->SetPath(
"/Settings");
4129 pConfig->Read(
"OptionsSizeX", &sx, -1);
4130 pConfig->Read(
"OptionsSizeY", &sy, -1);
4132 wxWindow *optionsParent =
this;
4134 optionsParent = GetPrimaryCanvas();
4136 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4139 AbstractPlatform::HideBusySpinner();
4143 g_options->SetInitChartDir(*pInit_Chart_Dir);
4146 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
4147 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4148 g_options->SetWorkDirListPtr(pWorkDirArray);
4151 g_options->SetConfigPtr(pConfig);
4152 g_options->SetInitialSettings();
4154 prev_locale = g_locale;
4155 g_options->SetInitialPage(options_lastPage, options_subpage);
4158 g_options->lastWindowPos = options_lastWindowPos;
4159 if (options_lastWindowPos != wxPoint(0, 0)) {
4160 g_options->Move(options_lastWindowPos);
4161 g_options->SetSize(options_lastWindowSize);
4163 g_options->CenterOnScreen();
4165 if (options_lastWindowSize != wxSize(0, 0)) {
4166 g_options->SetSize(options_lastWindowSize);
4171 androidEnableBackButton(
false);
4172 androidEnableOptionsMenu(
false);
4173 androidDisableFullScreen();
4181 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4184 wxString chart_file_name;
4185 if (cc->GetQuiltMode()) {
4186 int dbi = cc->GetQuiltRefChartdbIndex();
4187 chart_file_name = ChartData->GetDBChartFileName(dbi);
4189 if (cc->m_singleChart)
4190 chart_file_name = cc->m_singleChart->GetFullPath();
4193 pathArray.Add(chart_file_name);
4199 last_canvasConfig = g_canvasConfig;
4202 g_last_ChartScaleFactor = g_ChartScaleFactor;
4208void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4209 bool b_need_refresh =
false;
4211 if ((rr & VISIT_CHARTS) &&
4212 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4214 UpdateChartDatabaseInplace(*pNewDirArray,
4215 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4218 b_need_refresh =
true;
4222 if (rr & STYLE_CHANGED) {
4225 _(
"Please restart OpenCPN to activate language or style changes."),
4226 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4229 bool b_groupchange =
false;
4230 if (((rr & VISIT_CHARTS) &&
4231 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4232 (rr & GROUPS_CHANGED)) {
4233 b_groupchange = ScrubGroupArray();
4234 ChartData->ApplyGroupArray(g_pGroupArray);
4235 RefreshGroupIndices();
4238 if (rr & GROUPS_CHANGED || b_groupchange) {
4239 pConfig->DestroyConfigGroups();
4240 pConfig->CreateConfigGroups(g_pGroupArray);
4243 if (rr & TIDES_CHANGED) {
4249 if (rr & S52_CHANGED) {
4250 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4253 pConfig->UpdateSettings();
4255 if (g_pActiveTrack) {
4256 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4260 g_pRouteMan->SetColorScheme(global_color_scheme,
4261 g_Platform->GetDisplayDPmm());
4264 double stuffcog = NAN;
4265 double stuffsog = NAN;
4266 if (!std::isnan(gCog)) stuffcog = gCog;
4267 if (!std::isnan(gSog)) stuffsog = gSog;
4269 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4270 COGFilterTable[i] = stuffcog;
4271 SOGFilterTable[i] = stuffsog;
4274 SetChartUpdatePeriod();
4276 if (rr & GL_CHANGED) {
4280 b_need_refresh =
true;
4283 if (rr & S52_CHANGED) {
4284 b_need_refresh =
true;
4288 if (rr & REBUILD_RASTER_CACHE) {
4289 if (g_glTextureManager) {
4290 GetPrimaryCanvas()->Disable();
4291 g_glTextureManager->BuildCompressedCache();
4292 GetPrimaryCanvas()->Enable();
4297 if (g_config_display_size_manual &&
4298 g_config_display_size_mm.size() > g_current_monitor &&
4299 g_config_display_size_mm[g_current_monitor] > 0) {
4300 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4305 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4311 g_pi_manager->SendBaseConfigToAllPlugIns();
4312 int rrt = rr & S52_CHANGED;
4313 g_pi_manager->SendS52ConfigToAllPlugIns(
4314 (rrt == S52_CHANGED) ||
4315 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4318 if (g_MainToolbar) {
4319 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4320 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4325 ps52plib->SetScaleFactorExp(
4326 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4327 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4331 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4333 if (cc) cc->ApplyGlobalSettings();
4338 bool ztc = g_bEnableZoomToCursor;
4339 g_bEnableZoomToCursor =
4344 g_bEnableZoomToCursor = ztc;
4347 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4348 if (g_pMarkInfoDialog) {
4349 g_pMarkInfoDialog->Hide();
4350 g_pMarkInfoDialog->Destroy();
4351 g_pMarkInfoDialog = NULL;
4356 SetGPSCompassScale();
4358 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4361 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4362 cc->UpdateCanvasControlBar();
4365 UpdateGPSCompassStatusBoxes();
4367 SetAllToolbarScale();
4368 RequestNewToolbars();
4371 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4374 cc->RebuildCursors();
4379 bool b_masterScaleChange =
false;
4380 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4381 b_masterScaleChange =
true;
4383 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4384 RequestNewMasterToolbar(
true);
4386 bool bMuiChange =
false;
4392 if (b_masterScaleChange || bMuiChange) {
4394 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4397 cc->ProcessNewGUIScale();
4403 if (rr & LOCALE_CHANGED) {
4404 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4406 rr |= NEED_NEW_OPTIONS;
4411 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4415 g_last_ChartScaleFactor = g_ChartScaleFactor;
4420bool MyFrame::CheckGroup(
int igroup) {
4421 if (igroup == 0)
return true;
4423 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4425 if (!pGroup->m_element_array.size())
4428 for (
const auto &elem : pGroup->m_element_array) {
4429 for (
unsigned int ic = 0;
4430 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4432 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4434 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4441bool MyFrame::ScrubGroupArray() {
4446 bool b_change =
false;
4447 unsigned int igroup = 0;
4448 while (igroup < g_pGroupArray->GetCount()) {
4449 bool b_chart_in_element =
false;
4450 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4452 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4453 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4455 for (
unsigned int ic = 0;
4456 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4458 wxString chart_full_path = pcte->GetFullSystemPath();
4460 if (chart_full_path.StartsWith(element_root)) {
4461 b_chart_in_element =
true;
4467 if (!b_chart_in_element) {
4468 wxString test_string = _T(
"GSHH");
4469 if (element_root.Upper().Contains(test_string))
4470 b_chart_in_element =
true;
4473 if (!b_chart_in_element)
4475 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4487void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4489 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4491 if (cc && (cc != ccThis)) cc->Refresh();
4496void MyFrame::ChartsRefresh() {
4497 if (!ChartData)
return;
4499 AbstractPlatform::ShowBusySpinner();
4501 bool b_run = FrameTimer1.IsRunning();
4504 FrameTenHzTimer.Stop();
4507 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4510 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4511 if (cc->GetQuiltMode()) {
4512 currentIndex = cc->GetQuiltReferenceChartIndex();
4514 cc->canvasChartsRefresh(currentIndex);
4518 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4519 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4521 AbstractPlatform::HideBusySpinner();
4524void MyFrame::InvalidateAllQuilts() {
4525 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4528 cc->InvalidateQuilt();
4529 cc->SetQuiltRefChart(-1);
4530 cc->m_singleChart = NULL;
4535bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4537 const wxString &ChartListFileName) {
4538 bool b_run = FrameTimer1.IsRunning();
4540 FrameTenHzTimer.Stop();
4542 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4543 FrameCOGTimer.Stop();
4546 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4549 cc->InvalidateQuilt();
4550 cc->SetQuiltRefChart(-1);
4551 cc->m_singleChart = NULL;
4555 ChartData->PurgeCache();
4561 AbstractPlatform::ShowBusySpinner();
4563 wxGenericProgressDialog *pprog =
nullptr;
4565 wxString longmsg = _(
"OpenCPN Chart Update");
4567 _T(
"..................................................................")
4570 pprog = new wxGenericProgressDialog();
4573 pprog->SetFont(*qFont);
4575 pprog->Create(_("OpenCPN
Chart Update"), longmsg, 100, gFrame,
4576 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4577 wxPD_REMAINING_TIME);
4583 wxLogMessage(_T(" "));
4584 wxLogMessage(_T("Starting chart database Update..."));
4585 wxString gshhg_chart_loc = gWorldMapLocation;
4586 gWorldMapLocation = wxEmptyString;
4589 ChartData->Update(DirArray, b_force, pprog);
4590 ChartData->SaveBinary(ChartListFileName);
4591 wxLogMessage(_T("Finished chart database Update"));
4592 wxLogMessage(_T(" "));
4593 if (gWorldMapLocation.empty()) {
4597 gWorldMapLocation = gDefaultWorldMapLocation;
4598 gshhg_chart_loc = wxEmptyString;
4601 if (gWorldMapLocation != gshhg_chart_loc) {
4603 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4605 if (cc) cc->ResetWorldBackgroundChart();
4608 gshhsCrossesLandReset();
4613 AbstractPlatform::HideBusySpinner();
4615 pConfig->UpdateChartDirs(DirArray);
4618 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4619 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4621 if (b_runCOGTimer) {
4623 int period_ms = 100;
4624 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4625 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4632 cc->ToggleCanvasQuiltMode();
4634 bool cur_mode = cc->GetQuiltMode();
4636 if( !cc->GetQuiltMode() )
4637 cc->SetQuiltMode(
true );
4639 if( cc->GetQuiltMode() ) {
4640 cc->SetQuiltMode(
false );
4641 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4645 if( cur_mode != cc->GetQuiltMode() ){
4651 g_bQuiltEnable = cc->GetQuiltMode();
4655 ps52plib->GenerateStateHash();
4660void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4662void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4664void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4666 cc->DoCanvasStackDelta(direction);
4670void MyFrame::PositionIENCToolbar() {
4672 if (g_iENCToolbar) {
4674 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4676 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4684void MyFrame::OnInitTimer(wxTimerEvent &event) {
4687 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4690 wxLog::FlushActive();
4692 switch (m_iInitCount++) {
4694 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4696 if (g_bInlandEcdis) {
4697 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4698 double range_set = 500.;
4700 range = wxRound(range * 10) / 10.;
4704 else if (range > 2000.)
4706 else if (range > 1600.)
4708 else if (range > 1200.)
4710 else if (range > 800.)
4715 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4719 g_Platform->SetFullscreen(g_bFullscreen);
4722 if (g_NeedDBUpdate > 0) {
4723 RebuildChartDatabase();
4724 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4727 cc->SetGroupIndex(0,
false);
4735 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4736 CHART_FAMILY_RASTER)) {
4739 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4741 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4742 CHART_FAMILY_VECTOR)) {
4745 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4754 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4757 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4759 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4762 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4766 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4767 NavObj_dB::GetInstance().LoadNavObjects();
4770 if (!g_AW1GUID.IsEmpty()) {
4771 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4773 if (!g_AW2GUID.IsEmpty()) {
4774 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4779 appendOSDirSlash(&layerdir);
4780 layerdir.Append(_T(
"layers"));
4782 if (wxDir::Exists(layerdir)) {
4784 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4786 wxLogMessage(laymsg);
4787 pConfig->LoadLayers(layerdir);
4795 for (
auto *cp : TheConnectionParams()) {
4798 cp->b_IsSetup = TRUE;
4804 if (m_initializing)
break;
4805 m_initializing =
true;
4806 AbstractPlatform::ShowBusySpinner();
4808 AbstractPlatform::HideBusySpinner();
4810 RequestNewMasterToolbar();
4813 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4815 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4817 wxString perspective;
4818 pConfig->SetPath(_T (
"/AUI" ));
4819 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4826 bool bno_load =
false;
4828 wxArrayString name_array;
4829 wxStringTokenizer st(perspective, _T(
"|;"));
4830 while (st.HasMoreTokens()) {
4831 wxString s1 = st.GetNextToken();
4832 if (s1.StartsWith(_T(
"name="))) {
4833 wxString sc = s1.AfterFirst(
'=');
4838 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4839 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4840 wxAuiPaneInfo pane = pane_array_val.Item(i);
4844 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4850 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4854 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4857 g_pauimgr->GetPane(cc).MinSize(10,10);
4864 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4867 wxSize frameSize = GetClientSize();
4868 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4869 int width = wxMax(minSize.x, frameSize.x / 10);
4870 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4873 g_pauimgr->Update();
4877 g_pi_manager->NotifyAuiPlugIns();
4880 g_pi_manager->ShowDeferredBlacklistMessages();
4882 g_pi_manager->CallLateInit();
4884 if (g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4890 if (g_MainToolbar) {
4891 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4892 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4897 m_data_monitor->Move(g_MainToolbar->GetToolbarRect().x +
4898 g_MainToolbar->GetToolbarRect().width,
4899 3 * GetCharHeight());
4901 m_data_monitor->Center();
4909 pConfig->SetPath(
"/Settings");
4910 pConfig->Read(
"OptionsSizeX", &sx, -1);
4911 pConfig->Read(
"OptionsSizeY", &sy, -1);
4913 wxWindow *optionsParent =
this;
4915 optionsParent = GetPrimaryCanvas();
4917 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4920 BuildiENCToolbar(
true);
4927 if (!g_params.empty()) {
4928 for (
size_t n = 0; n < g_params.size(); n++) {
4929 wxString path = g_params[n];
4930 if (::wxFileExists(path)) {
4932 pSet->load_file(path.fn_str());
4935 pSet->LoadAllGPXObjects(
4936 !pSet->IsOpenCPN(), wpt_dups,
4938 LLBBox box = pSet->GetBBox();
4939 if (box.GetValid()) {
4940 CenterView(GetPrimaryCanvas(), box);
4949 InitAppMsgBusListener();
4954 auto loader = PluginLoader::GetInstance();
4955 bool b_haveWMM = loader && loader->IsPlugInAvailable(_T(
"WMM"));
4956 if (!b_haveWMM) gVar = g_UserVar;
4963 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4965 PositionIENCToolbar();
4967 g_bDeferredInitDone =
true;
4969 GetPrimaryCanvas()->SetFocus();
4970 g_focusCanvas = GetPrimaryCanvas();
4976 if (b_reloadForPlugins) {
4981 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4982 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4984 if (cc) cc->SetFirstAuto(
true);
4992 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4994 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4998 cc->CheckGroupValid();
5003 androidEnableBackButton(
true);
5004 androidEnableRotation();
5005 androidEnableOptionItems(
true);
5009 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
5018 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
5020 wxLog::FlushActive();
5022 RefreshAllCanvas(
true);
5023 wxGetApp().m_usb_watcher.Start();
5029void MyFrame::InitAppMsgBusListener() {
5030 auto &msgbus = AppMsgBus::GetInstance();
5033 AppMsg msg_basic(AppMsg::Type::BasicNavData);
5034 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
5038 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
5039 HandleBasicNavMsg(basicnav_msg);
5043 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
5044 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
5048 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
5049 HandleGPSWatchdogMsg(msg);
5056void MyFrame::ReleaseApiListeners() {}
5061 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
5062 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
5063 server.SetGetRestApiEndpointCb(
5064 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
5065 server.open_file_cb = [](
const std::string &path) {
5066 return wxGetApp().OpenFile(path);
5073void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
5074 if (msg->gps_watchdog <= 0) {
5075 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
5076 bool last_bGPSValid = bGPSValid;
5079 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5084 if (m_fix_start_time.IsValid()) {
5085 wxDateTime now = wxDateTime::Now();
5086 wxTimeSpan span = now - m_fix_start_time;
5087 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
5088 auto ¬eman = NotificationManager::GetInstance();
5089 wxString msg = _(
"GNSS Position fix lost");
5090 noteman.AddNotification(NotificationSeverity::kCritical,
5092 m_fix_start_time = wxInvalidDateTime;
5096 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
5097 bool last_bVelocityValid = bVelocityValid;
5098 bVelocityValid =
false;
5105void MyFrame::CalculateCOGAverage() {
5107 if (!std::isnan(gCog)) {
5108 if (g_COGAvgSec > 0) {
5110 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5113 double sum = 0., count = 0;
5114 for (
int i = 0; i < g_COGAvgSec; i++) {
5115 double adder = COGTable[i];
5116 if (std::isnan(adder))
continue;
5118 if (fabs(adder - g_COGAvg) > 180.) {
5119 if ((adder - g_COGAvg) > 0.)
5132 else if (sum >= 360.)
5141void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5142 m_fixtime = msg->time;
5143 double hdt_data_interval = 0;
5144 double fix_time_interval = 0;
5146 double msgtime = msg->set_time.tv_sec;
5147 double m1 = msg->set_time.tv_nsec / 1e9;
5150 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5151 ((msg->vflag & POS_VALID) == POS_VALID)) {
5153 if (!m_fix_start_time.IsValid()) {
5154 m_fix_start_time = wxDateTime::Now();
5159 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5162 fix_time_gt_last = fix_time_gt;
5163 uint64_t fix_time_gt_now =
5164 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5165 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5169 double implied_sog = dist / (fix_time_interval / 3600);
5174 gLat_gt_m1 = gLat_gt;
5175 gLon_gt_m1 = gLon_gt;
5179 fix_time_gt = fix_time_gt_now;
5183 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5184 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5185 gCog_gt_m1 = gCog_gt;
5195 if (!std::isnan(gCog_gt_m1)) {
5197 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5204 if ((fix_time_gt - fix_time_gt_last) > .08) {
5209 if (gCog_gt > gCog_gt_m1) {
5210 if ((gCog_gt - gCog_gt_m1) > 180.)
5215 if ((gCog_gt_m1 - gCog_gt) > 180.)
5220 difft = fabs(gCog_gt - gCog_gt_m1);
5221 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5229 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5230 tentative_cog_rate_gt *= 1e9;
5231 cog_rate_gt = tentative_cog_rate_gt;
5239 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5242static double hdt_avg;
5243 double hdt_norm = gHdt;
5244 if(gHdt > 180) hdt_norm -= 360;
5247 hdt_avg += hdt_norm * 0.1;
5249 if( gHdt < 0) gHdt += 360.;
5252 if (!std::isnan(gHdt)) {
5254 uint64_t hdt_time_gt_last = hdt_time_gt;
5255 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5256 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5259 if (hdt_data_interval > .09) {
5261 gHdt_gt_m1 = gHdt_gt;
5264 if (!std::isnan(gHdt_gt_m1)) {
5266 double tentative_hdt_rate_gt =
5267 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5268 tentative_hdt_rate_gt *= 1e9;
5270 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5271 hdt_rate_gt = tentative_hdt_rate_gt;
5279 if (std::isnan(gHdt)) gHdt_gt = NAN;
5282 CalculateCOGAverage();
5289 bool last_bGPSValid = bGPSValid;
5290 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5291 if ((msg->vflag & POS_VALID) == POS_VALID)
5296 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5298 bVelocityValid =
true;
5302void MyFrame::UpdateStatusBar() {
5305 unsigned long uiCurrentTickCount;
5306 m_MMEAeventTime.SetToCurrent();
5307 uiCurrentTickCount =
5308 m_MMEAeventTime.GetMillisecond() / 100;
5309 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5310 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5311 m_ulLastNMEATicktime = uiCurrentTickCount;
5313 if (m_tick_idx++ > 6) m_tick_idx = 0;
5318 if (NULL != GetStatusBar()) {
5321 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5324 wxString s1(tick_buf, wxConvUTF8);
5326 s1 += toSDMM(1, gLat);
5328 s1 += toSDMM(2, gLon);
5330 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5334 if (!std::isnan(gSog))
5335 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5338 sogcog.Printf(_T(
"SOG --- "));
5342 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5344 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5346 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5347 (
int)toMagnetic(gCog), 0x00B0);
5349 cogs.Printf((
"COG ---%c"), 0x00B0);
5351 sogcog.Append(cogs);
5352 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5357void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5358 MemFootTimer.Stop();
5360 int memsize = GetApplicationMemoryUse();
5363 printf(
"Memsize: %d \n", memsize);
5366 if (memsize > (g_MemFootMB * 1000)) {
5368 if (ChartData && cc) {
5370 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5371 unsigned int nCache = pCache->GetCount();
5374 for (
unsigned int i = 0; i < nCache; i++) {
5384 for (
unsigned int i = 0; i < nCache - 1; i++) {
5385 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5387 pcea[i] = pcea[i + 1];
5398 unsigned int idelete = 0;
5399 unsigned int idelete_max = pCache->GetCount();
5402 unsigned int minimum_cache = 1;
5403 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5405 while ((memsize > (g_MemFootMB * 1000)) &&
5406 (pCache->GetCount() > minimum_cache) &&
5407 (idelete < idelete_max)) {
5408 int memsizeb = memsize;
5410 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5412 memsize = GetApplicationMemoryUse();
5413 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5421 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5426void MyFrame::CheckToolbarPosition() {
5429 static bool bMaximized;
5431 if (IsMaximized() && !bMaximized) {
5433 if (g_MainToolbar) {
5434 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5435 g_MainToolbar->SetDefaultPosition();
5436 g_MainToolbar->Realize();
5438 PositionIENCToolbar();
5439 }
else if (!IsMaximized() && bMaximized) {
5441 if (g_MainToolbar) {
5442 g_MainToolbar->SetYAuxOffset(0);
5443 g_MainToolbar->SetDockY(-1);
5444 g_MainToolbar->SetDefaultPosition();
5445 g_MainToolbar->Realize();
5447 PositionIENCToolbar();
5452void MyFrame::ProcessUnitTest() {
5453 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5460 cc->m_bFollow =
false;
5461 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5462 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5463 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5466 if (cc->m_groupIndex > 0) {
5467 while (ut_index < ChartData->GetChartTableEntries() &&
5468 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5472 if (ut_index < ChartData->GetChartTableEntries()) {
5474 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5476 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5477 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5484 if (cc->GetQuiltMode()) {
5485 if (cc->IsChartQuiltableRef(ut_index))
5486 cc->SelectQuiltRefdbChart(ut_index);
5488 cc->SelectdbChart(ut_index);
5491 if (g_unit_test_1) {
5499 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5500 cte->GetLatMin(), cte->GetLonMax(), NULL,
5504 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5505 cte->GetLatMax(), cte->GetLonMin(), NULL,
5508 cc->GetSize(&ww, &wh);
5509 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5511 ppm = wxMin(ppm, 1.0);
5518 if (ut_index > ut_index_max) exit(0);
5529 bool b_rotate =
false;
5531 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5534 if (!b_rotate && !g_btenhertz)
return;
5536 bool b_update =
false;
5538 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5541 struct timespec now;
5542 clock_gettime(CLOCK_MONOTONIC, &now);
5543 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5544 double diffc = diff / 1e9;
5547 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5548 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5549 if (gCog_tentative < 0.) gCog_tentative += 360.;
5550 gCog = gCog_tentative;
5554 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5555 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5556 double diffc = diff / 1e9;
5557 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5561 if (gSog_gt && !std::isnan(gCog_gt)) {
5562 double delta_t = diffc / 3600;
5563 double distance = gSog_gt * delta_t;
5566 double angr = gCog_gt / 180 * M_PI;
5567 double latr = gLat_gt * M_PI / 180;
5568 double D = distance / 3443;
5569 double sD = sin(D), cD = cos(D);
5570 double sy = sin(latr), cy = cos(latr);
5571 double sa = sin(angr), ca = cos(angr);
5573 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5574 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5584 if (cc) cc->DoCanvasCOGSet();
5595 if (b_rotate || cc->m_bFollow) {
5596 cc->DoCanvasUpdate();
5605 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5608void MyFrame::ProcessQuitFlag() {
5611 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5613 FrameTenHzTimer.Stop();
5620void MyFrame::ProcessDeferredTrackOn() {
5623 if (g_bDeferredStartTrack) {
5624 if (!g_bTrackActive) {
5627 g_bDeferredStartTrack =
false;
5630 g_bDeferredStartTrack =
false;
5635void MyFrame::ProcessAnchorWatch() {
5638 if (pAnchorWatchPoint1) {
5641 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5642 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5643 double d = g_nAWMax;
5644 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5645 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5646 bool toofar =
false;
5647 bool tooclose =
false;
5648 if (d >= 0.0) toofar = (dist * 1852. > d);
5649 if (d < 0.0) tooclose = (dist * 1852 < -d);
5651 if (tooclose || toofar)
5652 AnchorAlertOn1 =
true;
5654 AnchorAlertOn1 =
false;
5656 AnchorAlertOn1 =
false;
5658 if (pAnchorWatchPoint2) {
5661 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5662 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5664 double d = g_nAWMax;
5665 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5666 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5667 bool toofar =
false;
5668 bool tooclose =
false;
5669 if (d >= 0) toofar = (dist * 1852. > d);
5670 if (d < 0) tooclose = (dist * 1852 < -d);
5672 if (tooclose || toofar)
5673 AnchorAlertOn2 =
true;
5675 AnchorAlertOn2 =
false;
5677 AnchorAlertOn2 =
false;
5679 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5680 AnchorAlertOn1 =
true;
5683void MyFrame::SendFixToPlugins() {
5687 GPSData.
kLat = gLat;
5688 GPSData.
kLon = gLon;
5689 GPSData.
kCog = gCog;
5690 GPSData.
kSog = gSog;
5691 GPSData.
kVar = gVar;
5692 GPSData.
kHdm = gHdm;
5693 GPSData.
kHdt = gHdt;
5694 GPSData.
nSats = g_SatsInView;
5696 wxDateTime tCheck((time_t)m_fixtime);
5697 if (tCheck.IsValid()) {
5706 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5709 SendPositionFixToAllPlugIns(&GPSData);
5713void MyFrame::ProcessLogAndBells() {
5716 wxDateTime lognow = wxDateTime::Now();
5717 int hourLOC = lognow.GetHour();
5718 int minuteLOC = lognow.GetMinute();
5720 int minuteUTC = lognow.GetMinute();
5721 int second = lognow.GetSecond();
5723 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5724 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5725 (minuteUTC == 30)) {
5726 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5727 wxString day = lognow.FormatISODate();
5728 wxString utc = lognow.FormatISOTime();
5729 wxString navmsg = _T(
"LOGBOOK: ");
5733 navmsg += _T(
" UTC ");
5737 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5741 if (std::isnan(gCog))
5742 cog.Printf(_T(
"COG ----- "));
5744 cog.Printf(_T(
"COG %10.5f "), gCog);
5747 if (std::isnan(gSog))
5748 sog.Printf(_T(
"SOG ----- "));
5750 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5756 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5759 wxLogMessage(navmsg);
5760 g_loglast_time = lognow;
5762 int bells = (hourLOC % 4) * 2;
5763 if (minuteLOC != 0) bells++;
5764 if (!bells) bells = 8;
5766 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5767 m_BellsToPlay = bells;
5768 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5769 wxPostEvent(
this, ev);
5776 CheckToolbarPosition();
5782 if (bDBUpdateInProgress)
return;
5785 FrameTenHzTimer.Stop();
5787 ProcessDeferredTrackOn();
5789 ProcessAnchorWatch();
5790 ProcessLogAndBells();
5792 if (ShouldRestartTrack()) TrackDailyRestart();
5795 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5796 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5797 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5803 if (gSog > 3.0) g_bCruising =
true;
5809 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5810 _T(
" COG ---\u00B0"));
5811 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5817 bool bnew_view =
false;
5818 if (!g_btenhertz) bnew_view = DoChartUpdate();
5822 if (g_always_send_rmb_rmc) SendNoRouteRmbRmc(*g_pRouteMan);
5825 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5828 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5831 cc->DrawBlinkObjects();
5834 if (bactiveRouteUpdate) {
5836 if (g_pRouteMan->GetpActiveRoute())
5837 cc->RefreshRect(g_blink_rect,
false);
5841 cc->SetOwnShipState(SHIP_NORMAL);
5843 if (cc->GetQuiltMode()) {
5844 double erf = cc->GetQuiltMaxErrorFactor();
5845 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5847 if (cc->m_singleChart) {
5848 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5849 cc->SetOwnShipState(SHIP_LOWACCURACY);
5853 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5855 if ((bGPSValid != m_last_bGPSValid) ||
5856 (bVelocityValid != m_last_bVelocityValid) ||
5857 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5858 if (!g_bopengl) cc->UpdateShips();
5865 m_last_bGPSValid = bGPSValid;
5866 m_last_bVelocityValid = bVelocityValid;
5871 bool brq_dynamic =
false;
5873 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5874 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5876 if (pic->m_enabled && pic->m_init_state) {
5877 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5884 if (brq_dynamic) bnew_view =
true;
5888 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5891 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5896 if (cc->GetglCanvas()) {
5898 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5901 if (cc->m_bFollow) {
5902 cc->DoCanvasUpdate();
5909 if (std::isnan(gCog)) cc->Refresh(
false);
5922 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5936 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5937 g_pais_query_dialog_active->UpdateText();
5940 if (g_pAISTargetList && (0 == (g_tick % (5))))
5941 g_pAISTargetList->UpdateAISTargetList();
5944 UpdateGPSCompassStatusBoxes();
5947 if (console && console->IsShown()) {
5949 console->RefreshConsoleData();
5956 if (m_bdefer_resize) {
5957 if (0 == (g_tick % (5))) {
5958 printf(
"___RESIZE\n");
5959 SetSize(m_defer_size);
5960 g_pauimgr->Update();
5961 m_bdefer_resize =
false;
5968 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5970 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5971 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5975double MyFrame::GetMag(
double a,
double lat,
double lon) {
5976 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5977 auto loader = PluginLoader::GetInstance();
5978 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5985 wxDateTime now = wxDateTime::Now();
5986 SendJSON_WMM_Var_Request(lat, lon, now);
5987 if (fabs(gQueryVar) < 360.0)
5988 Variance = gQueryVar;
5990 return toMagnetic(a, Variance);
5993bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5999 v[_T(
"Year")] = date.GetYear();
6000 v[_T(
"Month")] = date.GetMonth();
6001 v[_T(
"Day")] = date.GetDay();
6003 SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
6009void MyFrame::TouchAISActive(
void) {
6011 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6013 if (cc) cc->TouchAISToolActive();
6017void MyFrame::UpdateAISTool(
void) {
6018 if (!g_pAIS)
return;
6021 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6023 if (cc) cc->UpdateAISTBTool();
6028void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
6030 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6032 if (cc) cc->SetbTCUpdate(
true);
6035 RefreshAllCanvas(
false);
6040void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
6044 bool b_rotate =
false;
6045 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6047 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
6051 FrameCOGTimer.Stop();
6058 int period_ms = 100;
6060 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
6063void MyFrame::DoCOGSet(
void) {
6065 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6067 if (cc) cc->DoCanvasCOGSet();
6071void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
6077 wxFont oldfont = pdc->GetFont();
6079 pdc->SetFont(*pFont);
6080 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
6081 pdc->SetBackgroundMode(wxTRANSPARENT);
6083 pdc->DrawText(str, x, y + 1);
6084 pdc->DrawText(str, x, y - 1);
6085 pdc->DrawText(str, x + 1, y);
6086 pdc->DrawText(str, x - 1, y);
6088 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
6090 pdc->DrawText(str, x, y);
6092 pdc->SetFont(oldfont);
6096void MyFrame::UpdateRotationState(
double rotation) {
6098 g_bCourseUp =
false;
6100 if (fabs(rotation) > .001) {
6101 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
6102 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
6104 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
6107 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
6108 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
6110 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6114 UpdateGPSCompassStatusBoxes(
true);
6118void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6120 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6122 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6128int MyFrame::GetApplicationMemoryUse(
void) {
6134 wxWindow *fWin = wxWindow::FindFocus();
6136 wxArrayString outputArray;
6137 wxString cmd(_T(
"ps --no-headers -o vsize "));
6138 unsigned long pid = wxGetProcessId();
6140 cmd1.Printf(_T(
"%ld"), pid);
6142 wxExecute(cmd, outputArray);
6144 if (outputArray.GetCount()) {
6145 wxString s = outputArray.Item(0);
6147 if (s.ToLong(&vtmp)) memsize = vtmp;
6150 if (fWin) fWin->SetFocus();
6156 PROCESS_MEMORY_COUNTERS pmc;
6158 unsigned long processID = wxGetProcessId();
6160 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6162 if (NULL == hProcess)
return 0;
6164 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6182 memsize = pmc.WorkingSetSize / 1024;
6185 CloseHandle(hProcess);
6192double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6193 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6196void MyFrame::SetChartUpdatePeriod() {
6199 g_ChartUpdatePeriod = 0;
6204 bool bskewdc =
false;
6205 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6208 if (!g_bopengl && !cc->GetVP().b_quilt) {
6209 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6211 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6215 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6217 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6222 cc->UpdateCanvasControlBar();
6225void MyFrame::selectChartDisplay(
int type,
int family) {
6227 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6229 if (cc) cc->selectCanvasChartDisplay(type, family);
6232 UpdateGlobalMenuItems();
6241bool MyFrame::DoChartUpdate(
void) {
6242 bool return_val =
false;
6245 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6247 if (cc) return_val |= cc->DoCanvasUpdate();
6253void MyFrame::MouseEvent(wxMouseEvent &event) {
6255 event.GetPosition(&x, &y);
6260#include <mach/mach.h>
6261#include <mach/message.h>
6262#include <mach/kern_return.h>
6263#include <mach/task_info.h>
6265#include <malloc/malloc.h>
6272#if defined(__linux__)
6273#include "sys/types.h"
6274#include "sys/sysinfo.h"
6277int g_lastMemTick = -1;
6281bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6283 return androidGetMemoryStatus(mem_total, mem_used);
6286#if defined(__linux__)
6290 struct sysinfo sys_info;
6291 if (sysinfo(&sys_info) != -1)
6292 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6306 FILE *file = fopen(
"/proc/self/statm",
"r");
6308 if (fscanf(file,
"%d", mem_used) != 1) {
6309 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6322 PROCESS_MEMORY_COUNTERS pmc;
6324 unsigned long processID = wxGetProcessId();
6327 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6330 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6348 *mem_used = pmc.WorkingSetSize / 1024;
6351 CloseHandle(hProcess);
6355 MEMORYSTATUSEX statex;
6357 statex.dwLength =
sizeof(statex);
6359 GlobalMemoryStatusEx(&statex);
6377 *mem_total = statex.ullTotalPhys / 1024;
6384 if (g_tick != g_lastMemTick) {
6385 malloc_zone_pressure_relief(NULL, 0);
6388 int blocksInUse = 0;
6389 int sizeAllocated = 0;
6391 malloc_statistics_t stats;
6392 stats.blocks_in_use = 0;
6393 stats.size_in_use = 0;
6394 stats.max_size_in_use = 0;
6395 stats.size_allocated = 0;
6396 malloc_zone_statistics(NULL, &stats);
6397 bytesInUse += stats.size_in_use;
6398 blocksInUse += stats.blocks_in_use;
6399 sizeAllocated += stats.size_allocated;
6401 g_memUsed = sizeAllocated >> 10;
6404 g_lastMemTick = g_tick;
6407 if (mem_used) *mem_used = g_memUsed;
6410 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6412 double pagesUsed = 0.0, totalPages = 0.0;
6414 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6415 *mem_total = atol(buf) >> 10;
6423 if (mem_used) *mem_used = 0;
6424 if (mem_total) *mem_total = 0;
6428void MyFrame::DoPrint(
void) {
6430 g_PrintingInProgress =
true;
6433 GetPrimaryCanvas()->GetglCanvas()->Render();
6434 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6444 printer.Initialize(wxLANDSCAPE);
6445 printer.EnablePageNumbers(
false);
6446 printer.Print(
this, &printout);
6464 g_PrintingInProgress =
false;
6467 GetPrimaryCanvas()->SetFocus();
6472wxDateTime gTimeSource;
6475 wxString message_ID =
event.GetID();
6476 wxString message_JSONText =
event.GetJSONText();
6484 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6492 int numErrors = reader.
Parse(message_JSONText, &root);
6493 if (numErrors > 0) {
6499 wxString decl = root[_T(
"Decl")].
AsString();
6501 decl.ToDouble(&decl_val);
6507 if (message_ID == _T(
"WMM_VARIATION")) {
6515 int numErrors = reader.
Parse(message_JSONText, &root);
6516 if (numErrors > 0) {
6522 wxString decl = root[_T(
"Decl")].
AsString();
6524 decl.ToDouble(&decl_val);
6526 gQueryVar = decl_val;
6529 if (message_ID == _T(
"GRIB_TIMELINE")) {
6532 int numErrors = r.
Parse(message_JSONText, &v);
6534 if (numErrors > 0) {
6535 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6540 wxDateTime oldTimeSource = gTimeSource;
6542 if (v[_T(
"Day")].AsInt() == -1) {
6543 gTimeSource = wxInvalidDateTime;
6544 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6546 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6547 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6548 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6549 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6553 if (oldTimeSource != gTimeSource) {
6555 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6557 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6562 cc->pCwin->Refresh(
false);
6568 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6571 wxString trk_id = wxEmptyString;
6573 int numErrors = reader.
Parse(message_JSONText, &root);
6574 if (numErrors > 0)
return;
6577 trk_id = root[_T(
"Track_ID")].
AsString();
6580 v[_T(
"Track_ID")] = trk_id;
6581 for (
Track *ptrack : g_TrackList) {
6582 wxString name = wxEmptyString;
6583 if (ptrack->m_GUID == trk_id) {
6584 name = ptrack->GetName();
6585 if (name.IsEmpty()) {
6591 name = _(
"(Unnamed Track)");
6597 v[_T(
"error")] =
false;
6598 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6599 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6601 v[_T(
"lat")] = tp->m_lat;
6602 v[_T(
"lon")] = tp->m_lon;
6603 v[_T(
"NodeNr")] = i;
6605 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6606 SendJSONMessageToAllPlugins(msg_id, v);
6610 v[_T(
"error")] =
true;
6612 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6613 SendJSONMessageToAllPlugins(msg_id, v);
6615 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6618 wxString guid = wxEmptyString;
6620 int numErrors = reader.
Parse(message_JSONText, &root);
6621 if (numErrors > 0) {
6628 v[_T(
"GUID")] = guid;
6629 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6631 wxString name = wxEmptyString;
6633 if ((*it)->m_GUID == guid) {
6634 name = (*it)->m_RouteNameString;
6635 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6637 v[_T(
"Name")] = name;
6638 v[_T(
"error")] =
false;
6641 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6642 itp != (*it)->pRoutePointList->end(); itp++) {
6643 w[i][_T(
"lat")] = (*itp)->m_lat;
6644 w[i][_T(
"lon")] = (*itp)->m_lon;
6645 w[i][_T(
"Name")] = (*itp)->GetName();
6646 w[i][_T(
"Description")] = (*itp)->GetDescription();
6647 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6648 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6649 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6654 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6656 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6657 httpLink->DescrText;
6658 node = node->GetNext();
6663 v[_T(
"waypoints")] = w;
6664 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6665 SendJSONMessageToAllPlugins(msg_id, v);
6670 v[_T(
"error")] =
true;
6672 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6673 SendJSONMessageToAllPlugins(msg_id, v);
6674 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6679 int numErrors = reader.
Parse(message_JSONText, &root);
6680 if (numErrors > 0)
return;
6683 wxString str = root[_T(
"mode")].
AsString();
6684 if (str == _T(
"Track")) route =
false;
6689 for (RouteList::iterator it = pRouteList->begin();
6690 it != pRouteList->end(); it++) {
6691 wxString name = (*it)->m_RouteNameString;
6692 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6694 v[i][_T(
"error")] =
false;
6695 v[i][_T(
"name")] = name;
6696 v[i][_T(
"GUID")] = (*it)->m_GUID;
6697 v[i][_T(
"active")] = (*it)->IsActive();
6701 for (
Track *ptrack : g_TrackList) {
6702 wxString name = ptrack->GetName();
6703 if (name.IsEmpty()) {
6709 name = _(
"(Unnamed Track)");
6711 v[i][_T(
"error")] =
false;
6712 v[i][_T(
"name")] = name;
6713 v[i][_T(
"GUID")] = ptrack->m_GUID;
6714 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6718 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6719 SendJSONMessageToAllPlugins(msg_id, v);
6722 v[0][_T(
"error")] =
true;
6723 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6724 SendJSONMessageToAllPlugins(msg_id, v);
6726 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6728 v[0][_T(
"error")] =
true;
6729 if (g_pRouteMan->GetpActiveRoute()) {
6730 if (g_pRouteMan->m_bDataValid) {
6731 v[0][_T(
"error")] =
false;
6732 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6733 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6734 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6735 v[0][_T(
"active_route_GUID")] =
6736 g_pRouteMan->GetpActiveRoute()->GetGUID();
6737 v[0][_T(
"active_waypoint_lat")] =
6739 v[0][_T(
"active_waypoint_lon")] =
6743 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6744 SendJSONMessageToAllPlugins(msg_id, v);
6748void MyFrame::FilterCogSog(
void) {
6749 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6751 double cog_last = gCog;
6754 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6755 COGFilterTable[i] = COGFilterTable[i - 1];
6756 COGFilterTable[0] = cog_last;
6759 if (!std::isnan(cog_last)) {
6761 double sum = 0., count = 0;
6762 for (
int i = 0; i < g_COGFilterSec; i++) {
6763 double adder = COGFilterTable[i];
6764 if (std::isnan(adder))
continue;
6766 if (fabs(adder - cog_last) > 180.) {
6767 if ((adder - cog_last) > 0.)
6780 else if (sum >= 360.)
6787 double sog_last = gSog;
6790 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6791 SOGFilterTable[i] = SOGFilterTable[i - 1];
6792 SOGFilterTable[0] = sog_last;
6795 if (!std::isnan(gSog)) {
6796 double sum = 0., count = 0;
6797 for (
int i = 0; i < g_SOGFilterSec; i++) {
6798 if (std::isnan(SOGFilterTable[i]))
continue;
6800 sum += SOGFilterTable[i];
6810void MyFrame::LoadHarmonics() {
6813 ptcmgr->LoadDataSources(TideCurrentDataSet);
6815 bool b_newdataset =
false;
6818 for (
auto a : ptcmgr->GetDataSet()) {
6819 bool b_foundi =
false;
6820 for (
auto b : TideCurrentDataSet) {
6827 b_newdataset =
true;
6832 for (
auto a : TideCurrentDataSet) {
6833 bool b_foundi =
false;
6834 for (
auto b : ptcmgr->GetDataSet()) {
6841 b_newdataset =
true;
6846 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6850void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6851 if (!ptarget)
return;
6854 wxDateTime mob_time = wxDateTime::Now();
6855 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6856 mob_label += _(
" on ");
6857 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6860 mob_label, wxEmptyString);
6861 pWP_MOB->SetShared(
true);
6863 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6865 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6867 pWP_MOB->SetUseSca(
false);
6875 wxString(_(
"Own ship")), wxEmptyString);
6876 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6877 pWP_MOB->SetUseSca(
false);
6878 pAISMOBRoute =
new Route();
6879 pRouteList->Append(pAISMOBRoute);
6881 pAISMOBRoute->AddPoint(pWP_src);
6882 pAISMOBRoute->AddPoint(pWP_MOB);
6884 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6885 pWP_src, pWP_MOB, pAISMOBRoute);
6893 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6895 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6899 v[_T(
"GUID")] = pAISMOBRoute->
m_GUID;
6900 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6901 SendJSONMessageToAllPlugins(msg_id, v);
6904 if (RouteManagerDialog::getInstanceFlag()) {
6905 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6906 pRouteManagerDialog->UpdateRouteListCtrl();
6907 pRouteManagerDialog->UpdateWptListCtrl();
6911 RefreshAllCanvas(
false);
6913 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6914 mob_message += _(
" Time: ");
6915 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6916 mob_message += _(
" Ownship Position: ");
6917 mob_message += toSDMM(1, gLat);
6918 mob_message += _T(
" ");
6919 mob_message += toSDMM(2, gLon);
6920 mob_message += _(
" MOB Position: ");
6921 mob_message += toSDMM(1, ptarget->Lat);
6922 mob_message += _T(
" ");
6923 mob_message += toSDMM(2, ptarget->Lon);
6924 wxLogMessage(mob_message);
6927void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6928 if (pAISMOBRoute && ptarget) {
6930 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6931 OwnPoint->m_lat = gLat;
6932 OwnPoint->m_lon = gLon;
6934 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6935 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6938 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6939 MOB_Point->m_lat = ptarget->Lat;
6940 MOB_Point->m_lon = ptarget->Lon;
6942 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6943 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6945 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6946 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6949 RefreshAllCanvas(
false);
6952 wxDateTime mob_time = wxDateTime::Now();
6954 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6955 mob_message += _(
" Time: ");
6956 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6957 mob_message += _(
" Ownship Position: ");
6958 mob_message += toSDMM(1, gLat);
6959 mob_message += _T(
" ");
6960 mob_message += toSDMM(2, gLon);
6961 mob_message += _(
" MOB Position: ");
6962 mob_message += toSDMM(1, ptarget->Lat);
6963 mob_message += _T(
" ");
6964 mob_message += toSDMM(2, ptarget->Lon);
6966 wxLogMessage(mob_message);
6970void MyFrame::applySettingsString(wxString settings) {
6972 int last_UIScaleFactor = g_GUIScaleFactor;
6973 bool previous_expert = g_bUIexpert;
6974 g_last_ChartScaleFactor = g_ChartScaleFactor;
6975 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6978 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6981 pConfig->UpdateSettings();
6984 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6986 if (rr & S52_CHANGED) {
6988 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6990 ->ClearCNSYLUPArray();
6991 ps52plib->GenerateStateHash();
6995 ProcessOptionsDialog(rr, pNewDirArray);
7000 bool b_newToolbar =
false;
7002 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
7004 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
7006 if (rr & TOOLBAR_CHANGED) {
7007 b_newToolbar =
true;
7012 if (previous_expert && !g_bUIexpert) {
7013 androidForceFullRepaint();
7017 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
7021 SetGPSCompassScale();
7023 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7025 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
7027 UpdateGPSCompassStatusBoxes(
true);
7030 AbstractPlatform::ShowBusySpinner();
7032 SetAllToolbarScale();
7036 AbstractPlatform::HideBusySpinner();
7038 RequestNewMasterToolbar(
true);
7045 UpdateControlBar(GetPrimaryCanvas());
7048 if (console) console->Raise();
7051 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
7054#ifdef wxHAS_POWER_EVENTS
7055void MyFrame::OnSuspending(wxPowerEvent &event) {
7059 wxLogMessage(_T(
"System suspend starting..."));
7062void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
7065 wxLogMessage(_T(
"System is going to suspend."));
7068void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
7071 wxLogMessage(_T(
"System suspend was cancelled."));
7074int g_last_resume_ticks;
7075void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
7076 wxDateTime now = wxDateTime::Now();
7077 wxLogMessage(_T(
"System resumed from suspend."));
7079 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
7082 wxLogMessage(
"Restarting streams.");
7083 g_last_resume_ticks = now.GetTicks();
7087 g_pMUX->ClearStreams();
7089 g_pMUX->StartAllStreams();
7098 if (IsMaximized()) {
7103 wxSize sz = GetSize();
7104 SetSize(wxSize(sz.x - 1, sz.y));
7116void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
7117 bool btbRebuild =
false;
7119 bool b_reshow =
true;
7120 if (g_MainToolbar) {
7122 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
7123 if ((ff > 0.01f) || bforcenew) {
7124 g_MainToolbar->DestroyToolBar();
7125 delete g_MainToolbar;
7126 g_MainToolbar = NULL;
7132 if (!g_MainToolbar) {
7133 long orient = g_Platform->GetDefaultToolbarOrientation();
7134 wxWindow *toolbarParent =
this;
7136 toolbarParent = GetPrimaryCanvas();
7139 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7140 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
7141 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7142 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7143 g_MainToolbar->EnableRolloverBitmaps(
false);
7145 g_MainToolbar->CreateConfigMenu();
7146 g_MainToolbar->SetDefaultPosition();
7148 g_bmasterToolbarFull =
true;
7151 if (g_MainToolbar) {
7152 CreateMasterToolbar();
7156 g_MainToolbar->SetColorScheme(global_color_scheme);
7162 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7163 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7167bool MyFrame::CollapseGlobalToolbar() {
7168 if (g_MainToolbar) {
7169 m_nMasterToolCountShown = 1;
7170 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7171 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7172 g_MainToolbar->Realize();
7173 g_bmasterToolbarFull =
false;
7182 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7189 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7190 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7191 tic->m_bRequired =
true;
7193 g_MainToolbar->AddToolItem(tic);
7196 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7197 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7198 g_MainToolbar->AddToolItem(tic);
7201 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7202 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7203 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7205 g_MainToolbar->AddToolItem(tic);
7208 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7209 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7210 g_MainToolbar->AddToolItem(tic);
7213 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7214 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7215 _(
"Enable Tracking"), _T(
"MUI_track"));
7216 g_MainToolbar->AddToolItem(tic);
7219 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7220 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7221 g_MainToolbar->AddToolItem(tic);
7232 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7233 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7234 g_MainToolbar->AddToolItem(tic);
7237 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7238 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7239 g_MainToolbar->AddToolItem(tic);
7242 AddDefaultPositionPlugInTools();
7246 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7247 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7248 g_MainToolbar->AddToolItem(tic);
7251 g_MainToolbar->RebuildToolbar();
7255 g_MainToolbar->Realize();
7258 ArrayOfPlugInToolbarTools tool_array =
7259 g_pi_manager->GetPluginToolbarToolArray();
7260 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7262 if (!pttc->b_viz)
continue;
7264 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7267 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7268 if (g_bTrackActive) {
7269 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7271 g_MainToolbar->Realize();
7276bool MyFrame::CheckAndAddPlugInTool() {
7277 if (!g_pi_manager)
return false;
7282 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7284 if (!tb)
return false;
7286 int n_tools = tb->GetToolsCount();
7290 ArrayOfPlugInToolbarTools tool_array =
7291 g_pi_manager->GetPluginToolbarToolArray();
7293 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7295 if (pttc->position == n_tools) {
7296 wxBitmap *ptool_bmp;
7298 switch (global_color_scheme) {
7299 case GLOBAL_COLOR_SCHEME_DAY:
7300 ptool_bmp = pttc->bitmap_day;
7303 case GLOBAL_COLOR_SCHEME_DUSK:
7304 ptool_bmp = pttc->bitmap_dusk;
7306 case GLOBAL_COLOR_SCHEME_NIGHT:
7307 ptool_bmp = pttc->bitmap_night;
7310 ptool_bmp = pttc->bitmap_day;
7315 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7317 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7318 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7319 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7320 tic->m_bPlugin =
true;
7329 while (CheckAndAddPlugInTool()) {
7335bool MyFrame::AddDefaultPositionPlugInTools() {
7336 if (!g_pi_manager)
return false;
7342 ArrayOfPlugInToolbarTools tool_array =
7343 g_pi_manager->GetPluginToolbarToolArray();
7345 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7349 if (!pttc->b_viz)
continue;
7351 if (pttc->position == -1)
7353 wxBitmap *ptool_bmp;
7355 switch (global_color_scheme) {
7356 case GLOBAL_COLOR_SCHEME_DAY:
7357 ptool_bmp = pttc->bitmap_day;
7359 case GLOBAL_COLOR_SCHEME_DUSK:
7360 ptool_bmp = pttc->bitmap_dusk;
7362 case GLOBAL_COLOR_SCHEME_NIGHT:
7363 ptool_bmp = pttc->bitmap_night;
7366 ptool_bmp = pttc->bitmap_day;
7371 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7373 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7374 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7375 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7376 tic->m_bPlugin =
true;
7378 g_MainToolbar->AddToolItem(tic);
7391wxColour GetGlobalColor(wxString colorName);
7393static const char *usercolors[] = {
7394 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7395 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7396 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7397 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7398 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7399 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7400 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7402 "DILG0; 255;255;255;",
7404 "DILG0; 238;239;242;",
7406 "DILG1; 212;208;200;",
7407 "DILG2; 255;255;255;",
7411 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7412 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7413 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7415 "UDKRD; 124; 16; 0;",
7416 "UARTE; 200; 0; 0;",
7418 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7419 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7420 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7421 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7423 "DASHB; 255;255;255;",
7424 "DASHL; 175;175;175;",
7425 "DASHF; 50; 50; 50;",
7426 "DASHR; 200; 0; 0;",
7428 "DASHN; 200;120; 0;",
7429 "DASH1; 204;204;255;",
7430 "DASH2; 122;131;172;",
7431 "COMP1; 211;211;211;",
7433 "GREY3; 40; 40; 40;",
7434 "BLUE4; 100;100;200;",
7435 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7436 "BLUEBACK; 212;234;238;",
7437 "LANDBACK; 201;185;122;",
7440 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7441 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7442 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7443 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7444 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7445 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7446 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7448 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7449 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7450 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7452 "DILG0; 110;110;110;",
7453 "DILG1; 110;110;110;",
7455 "DILG3; 130;130;130;",
7456 "UITX1; 41; 46; 46;",
7458 "UARTE; 64; 64; 64;",
7460 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7461 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7462 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7463 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7465 "DASHB; 77; 77; 77;",
7466 "DASHL; 54; 54; 54;",
7468 "DASHR; 58; 21; 21;",
7469 "DASHG; 21; 58; 21;",
7470 "DASHN; 100; 50; 0;",
7471 "DASH1; 76; 76;113;",
7472 "DASH2; 48; 52; 72;",
7473 "COMP1; 107;107;107;",
7475 "GREY3; 20; 20; 20;",
7476 "BLUE4; 80; 80;160;",
7477 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7478 "LANDBACK; 201;185;122;",
7480 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7481 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7482 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7483 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7484 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7485 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7486 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7487 "DILG0; 80; 80; 80;",
7488 "DILG1; 80; 80; 80;",
7490 "DILG3; 65; 65; 65;",
7491 "UITX1; 31; 34; 35;",
7493 "UARTE; 64; 64; 64;",
7495 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7496 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7497 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7499 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7500 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7501 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7502 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7505 "DASHL; 20; 20; 20;",
7506 "DASHF; 64; 64; 64;",
7507 "DASHR; 70; 15; 15;",
7508 "DASHG; 15; 70; 15;",
7509 "DASHN; 17; 80; 56;",
7510 "DASH1; 48; 52; 72;",
7511 "DASH2; 36; 36; 53;",
7512 "COMP1; 24; 24; 24;",
7514 "GREY3; 10; 10; 10;",
7515 "BLUE4; 70; 70;140;",
7516 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7517 "LANDBACK; 201;185;122;",
7521int get_static_line(
char *d,
const char **p,
int index,
int n) {
7522 if (!strcmp(p[index],
"*****"))
return 0;
7524 strncpy(d, p[index], n);
7528void InitializeUserColors(
void) {
7529 const char **p = usercolors;
7537 UserColorTableArray =
new wxArrayPtrVoid;
7538 UserColourHashTableArray =
new wxArrayPtrVoid;
7542 ct->tableName =
new wxString(_T(
"DAY"));
7543 ct->color =
new wxArrayPtrVoid;
7544 UserColorTableArray->Add((
void *)ct);
7547 ct->tableName =
new wxString(_T(
"DUSK"));
7548 ct->color =
new wxArrayPtrVoid;
7549 UserColorTableArray->Add((
void *)ct);
7552 ct->tableName =
new wxString(_T(
"NIGHT"));
7553 ct->color =
new wxArrayPtrVoid;
7554 UserColorTableArray->Add((
void *)ct);
7556 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7557 if (!strncmp(buf,
"Table", 5)) {
7558 sscanf(buf,
"Table:%s", TableName);
7560 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7561 ctp = (colTable *)(UserColorTableArray->Item(it));
7562 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7571 while (buf[j] !=
';' && j < 20) {
7577 S52color *c =
new S52color;
7578 strcpy(c->colName, name);
7580 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7593 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7594 wxColorHashMap *phash =
new wxColorHashMap;
7595 UserColourHashTableArray->Add((
void *)phash);
7597 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7599 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7600 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7602 wxColour c(c2->R, c2->G, c2->B);
7603 wxString key(c2->colName, wxConvUTF8);
7610 pcurrent_user_color_hash =
7611 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7614void DeInitializeUserColors(
void) {
7615 if (!UserColorTableArray)
return;
7616 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7617 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7619 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7620 S52color *c = (S52color *)ct->color->Item(j);
7624 delete ct->tableName;
7630 delete UserColorTableArray;
7632 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7633 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7637 delete UserColourHashTableArray;
7644typedef struct _MSW_COLOR_SPEC {
7646 wxString S52_RGB_COLOR;
7650MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7651 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7652 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7655void SaveSystemColors() {
7669 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7670 while (pcspec->COLOR_NAME != -1) {
7671 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7676void RestoreSystemColors() {
7677 int element[NCOLORS];
7678 int rgbcolor[NCOLORS];
7681 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7682 while (pcspec->COLOR_NAME != -1) {
7683 element[i] = pcspec->COLOR_NAME;
7684 rgbcolor[i] = pcspec->SysRGB_COLOR;
7690 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7695void SetSystemColors(ColorScheme cs) {
7697 int element[NCOLORS];
7698 int rgbcolor[NCOLORS];
7700 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7701 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7702 while (pcspec->COLOR_NAME != -1) {
7703 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7704 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7705 element[i] = pcspec->COLOR_NAME;
7711 pSetSysColors(i, (
unsigned long *)&element[0],
7712 (
unsigned long *)&rgbcolor[0]);
7716 RestoreSystemColors();
7721wxColor GetDimColor(wxColor c) {
7722 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7723 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7727 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7728 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7730 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7731 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7732 hsv.value = hsv.value * factor;
7733 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7735 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7741double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7742 double const AnchorPointMaxDist)
7745 if (d < AnchorPointMinDist)
7746 return AnchorPointMinDist;
7747 else if (d > AnchorPointMaxDist)
7748 return AnchorPointMaxDist;
7754 if (d > -AnchorPointMinDist)
7755 return -AnchorPointMinDist;
7756 else if (d < -AnchorPointMaxDist)
7757 return -AnchorPointMaxDist;
7764static const WORD MAX_CONSOLE_LINES =
7769void RedirectIOToConsole()
7774 wxIntPtr lStdHandle;
7776 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7786 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7787 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7788 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7792 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7793 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7794 fp = _fdopen(hConHandle,
"w");
7796 setvbuf(stdout, NULL, _IONBF, 0);
7800 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7801 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7802 fp = _fdopen(hConHandle,
"r");
7804 setvbuf(stdin, NULL, _IONBF, 0);
7808 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7809 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7810 fp = _fdopen(hConHandle,
"w");
7812 setvbuf(stderr, NULL, _IONBF, 0);
7824bool TestGLCanvas(wxString prog_dir) {
7826 wxString test_app = prog_dir;
7827 test_app += _T(
"ocpn_gltest1.exe");
7829 if (::wxFileExists(test_app)) {
7830 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7831 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7832 if (proc_return == 0)
7833 printf(
"GLCanvas OK\n");
7835 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7837 return (proc_return == 0);
7847bool ReloadLocale() {
7852 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7859 FontMgr::Get().SetLocale(g_locale);
7867 if (pRoutePropDialog) {
7868 pRoutePropDialog->Hide();
7869 pRoutePropDialog->Destroy();
7870 pRoutePropDialog = NULL;
7873 if (pRouteManagerDialog) {
7874 pRouteManagerDialog->Hide();
7875 pRouteManagerDialog->Destroy();
7876 pRouteManagerDialog = NULL;
7879 if (console) console->SetColorScheme(global_color_scheme);
7880 if (g_pais_query_dialog_active) {
7881 g_pais_query_dialog_active->Destroy();
7882 g_pais_query_dialog_active = NULL;
7885 auto alert_dlg_active =
7887 if (alert_dlg_active) {
7888 alert_dlg_active->Destroy();
7889 g_pais_alert_dialog_active =
nullptr;
7892 if (g_pAISTargetList) {
7893 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7894 g_pAISTargetList->Disconnect_decoder();
7895 g_pAISTargetList->Destroy();
7896 g_pAISTargetList = NULL;
7900 if (gFrame->m_pMenuBar) {
7901 gFrame->SetMenuBar(NULL);
7902 gFrame->m_pMenuBar->Destroy();
7903 gFrame->m_pMenuBar = NULL;
7905 gFrame->BuildMenuBar();
7908 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7910 if (cc) cc->CanvasApplyLocale();
7915 wxString perspective;
7916 pConfig->SetPath(_T (
"/AUI" ));
7917 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7931 bool bno_load =
false;
7932 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7934 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7935 wxAuiPaneInfo pane = pane_array_val[i];
7936 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7942 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7944 g_pauimgr->Update();
7947 gFrame->RequestNewToolbars(
true);
7948 gFrame->RequestNewMasterToolbar(
true);
7952extern s57RegistrarMgr *m_pRegistrarMan;
7953extern wxString g_UserPresLibData;
7954extern wxString g_SENCPrefix;
7955extern wxString g_csv_locn;
7971 g_csv_locn = g_Platform->GetSharedDataDir();
7972 g_csv_locn.Append(_T(
"s57data"));
7975 g_csv_locn = _T(
".");
7976 appendOSDirSlash(&g_csv_locn);
7977 g_csv_locn.Append(_T(
"s57data"));
7982 if (g_SENCPrefix.IsEmpty()) {
7984 appendOSDirSlash(&g_SENCPrefix);
7985 g_SENCPrefix.Append(_T(
"SENC"));
7989 wxFileName f(g_SENCPrefix);
7991 g_SENCPrefix = f.GetFullPath();
7993 g_SENCPrefix = _T(
"SENC");
7999 bool b_force_legacy =
false;
8001 if (g_UserPresLibData.IsEmpty()) {
8002 plib_data = g_csv_locn;
8003 appendOSDirSlash(&plib_data);
8004 plib_data.Append(_T(
"S52RAZDS.RLE"));
8006 plib_data = g_UserPresLibData;
8007 b_force_legacy =
true;
8010 ps52plib =
new s52plib(plib_data, b_force_legacy);
8025 if (!ps52plib->m_bOK) {
8028 wxStandardPaths &std_path = g_Platform->GetStdPaths();
8030 wxString look_data_dir;
8031 look_data_dir.Append(std_path.GetUserDataDir());
8032 appendOSDirSlash(&look_data_dir);
8033 wxString tentative_SData_Locn = look_data_dir;
8034 look_data_dir.Append(_T(
"s57data"));
8036 plib_data = look_data_dir;
8037 appendOSDirSlash(&plib_data);
8038 plib_data.Append(_T(
"S52RAZDS.RLE"));
8040 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
8041 ps52plib =
new s52plib(plib_data);
8043 if (ps52plib->m_bOK) {
8044 g_csv_locn = look_data_dir;
8053 if (!ps52plib->m_bOK) {
8056 wxString look_data_dir;
8057 look_data_dir = g_Platform->GetSharedDataDir();
8058 look_data_dir.Append(_T(
"s57data"));
8060 plib_data = look_data_dir;
8061 appendOSDirSlash(&plib_data);
8062 plib_data.Append(_T(
"S52RAZDS.RLE"));
8064 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
8065 ps52plib =
new s52plib(plib_data);
8067 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
8070 if (ps52plib->m_bOK) {
8071 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
8073 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
8078 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
8080 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
8081 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
8082 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
8083 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
8086 pConfig->LoadS57Config();
8087 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
8090 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
8091 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
8093 ps52plib->SetDIPFactor(dip_factor);
8098 ps52plib->SetScaleFactorExp(
8099 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
8100 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
8105 extern bool g_b_EnableVBO;
8106 extern GLenum g_texture_rectangle_format;
8111 wxString renderer = wxString(GL_Caps->Renderer.c_str());
8112 ps52plib->SetGLRendererString(renderer);
8115 ps52plib->SetGLOptions(
8116 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
8117 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
8118 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
8124 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
8133 : wxThread(wxTHREAD_JOINABLE) {
8134 m_filename = filename;
8145 newChart->SetNativeScale(m_scale);
8146 newChart->SetFullExtent(m_ext);
8148 newChart->FindOrCreateSenc(m_filename);
8153 wxString m_filename;
8159static double chart_dist(
int index) {
8165 if (cte.GetBBox().Contains(gLat, gLon))
8170 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8171 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8172 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8175 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8176 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8178 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8184WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8185static int CompareInts(
int n1,
int n2) {
8186 double d1 = chart_dist(n1);
8187 double d2 = chart_dist(n2);
8188 return (
int)(d1 - d2);
8193 wxString chart_path;
8198WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8200#include <wx/arrimpl.cpp>
8203void ParseAllENC(wxWindow *parent) {
8204 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8212 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8215 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8217 idx_sorted_by_distance.Add(i);
8221 if (count == 0)
return;
8223 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8229 ArrayOfCompressTargets ct_array;
8230 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8231 int i = idx_sorted_by_distance[j];
8234 double distance = chart_dist(i);
8236 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8239 pct->distance = distance;
8240 pct->chart_path = filename;
8242 ct_array.push_back(pct);
8245 int thread_count = 0;
8248 extern int g_nCPUCount;
8249 if (g_nCPUCount > 0)
8250 thread_count = g_nCPUCount;
8252 thread_count = wxThread::GetCPUCount();
8254 if (thread_count < 1) {
8263 for(
int t = 0; t < thread_count; t++)
8267 wxGenericProgressDialog *prog =
nullptr;
8271 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8272 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8274 prog =
new wxGenericProgressDialog();
8276 prog->SetFont(*qFont);
8278 prog->Create(_(
"OpenCPN ENC Prepare"),
8279 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8289 prog->ShowWindowModal();
8298 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8299 wxString filename = ct_array[j].chart_path;
8300 double distance = ct_array[j].distance;
8301 int index = ChartData->FinddbIndex(filename);
8302 if (index < 0)
continue;
8305 ext.NLAT = cte.GetLatMax();
8306 ext.SLAT = cte.GetLatMin();
8307 ext.WLON = cte.GetLonMin();
8308 ext.ELON = cte.GetLonMax();
8310 int scale = cte.GetScale();
8313 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8316 if (wxThread::IsMain()) {
8318 wxSize sz = prog->GetSize();
8320 msg += _T(
" Chart:");
8323 prog->Update(count, msg, &skip);
8335 newChart->SetNativeScale(
scale);
8336 newChart->SetFullExtent(ext);
8337 newChart->DisableBackgroundSENC();
8339 newChart->FindOrCreateSenc(filename,
8343 if (wxThread::IsMain()) {
8344 msg.Printf(_(
"ENC Completed."));
8346 prog->Update(count, msg, &skip);
8356 for (
int t = 0;; t = (t + 1) % thread_count) {
8363 if (!workers[t]->IsAlive()) {
8376#if defined(__WXMSW__) || defined(__WXOSX__)
8383 for(
int t = 0; t<thread_count; t++) {
Class AisDecoder and helpers.
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...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
Represents a layer of chart objects in OpenCPN.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
Global variables reflecting command line options and arguments.
void MakeCommDriver(const ConnectionParams *params)
Create and register a driver for given connection.
Communication drivers factory and support.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
The ConnectionsDlg class.
New NMEA Debugger successor main window.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
Multiplexer class and helpers.
Class NotificationManager.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse(void)
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.