54#include <wx/stdpaths.h>
55#include <wx/tokenzr.h>
56#include <wx/display.h>
57#include <wx/jsonreader.h>
59#include "model/ais_decoder.h"
61#include "model/ais_target_data.h"
63#include "model/comm_drv_factory.h"
65#include "model/comm_n0183_output.h"
67#include "model/comm_vars.h"
68#include "model/config_vars.h"
69#include "model/cutil.h"
70#include "model/georef.h"
72#include "model/idents.h"
75#include "model/multiplexer.h"
76#include "model/nav_object_database.h"
77#include "model/navutil_base.h"
79#include "model/own_ship.h"
82#include "model/routeman.h"
83#include "model/select.h"
85#include "model/track.h"
87#include "dialog_alert.h"
91#include "ais_info_gui.h"
92#include "AISTargetAlertDialog.h"
93#include "AISTargetListDialog.h"
94#include "AISTargetQueryDialog.h"
95#include "CanvasConfig.h"
97#include "chart_ctx_factory.h"
101#include "color_handler.h"
104#include "connections_dlg.h"
105#include "ConfigMgr.h"
110#include "glChartCanvas.h"
111#include "GoToPositionDialog.h"
113#include "iENCToolbar.h"
115#include "load_errors_dlg.h"
118#include "N2KParser.h"
122#include "OCPN_AUIManager.h"
123#include "ocpn_frame.h"
124#include "OCPNPlatform.h"
125#include "OCPN_Sound.h"
127#include "pluginmanager.h"
128#include "print_dialog.h"
129#include "printout_chart.h"
130#include "routemanagerdialog.h"
131#include "routeman_gui.h"
132#include "route_point_gui.h"
133#include "RoutePropDlgImpl.h"
136#include "S57QueryDialog.h"
137#include "SystemCmdSound.h"
141#include "TrackPropDlg.h"
142#include "waypointman_gui.h"
143#include "CanvasOptions.h"
147#include "androidUTIL.h"
153WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
161extern arrayofCanvasPtr g_canvasArray;
174extern About *g_pAboutDlgLegacy;
177extern double vLat, vLon;
178extern wxString g_locale;
179extern ColorScheme global_color_scheme;
184GLenum g_texture_rectangle_format;
187#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
188extern wxLocale *plocale_def_lang;
195extern s52plib *ps52plib;
199extern bool g_b_legacy_input_filter_behaviour;
200extern bool g_bTrackActive;
202extern bool g_bmasterToolbarFull;
203extern int g_nAutoHideToolbar;
204extern bool g_bAutoHideToolbar;
205extern bool g_bshowToolbar;
206extern int g_maintoolbar_x;
207extern int g_maintoolbar_y;
208extern wxString g_toolbarConfig;
209extern float g_toolbar_scalefactor;
210extern float g_compass_scalefactor;
211extern bool g_bShowMenuBar;
212extern bool g_bShowCompassWin;
214extern bool g_benable_rotate;
215extern int g_GUIScaleFactor;
216extern int g_ChartScaleFactor;
217extern int g_last_ChartScaleFactor;
218extern int g_ShipScaleFactor;
219extern float g_ShipScaleFactorExp;
220extern int g_ENCTextScaleFactor;
222extern bool g_bShowTide;
223extern bool g_bShowCurrent;
224extern bool g_bUIexpert;
225extern RouteList *pRouteList;
226extern wxString g_default_wp_icon;
227extern std::vector<std::string> TideCurrentDataSet;
228extern wxString g_TCData_Dir;
230extern char nmea_tick_chars[];
231extern double AnchorPointMinDist;
232extern bool AnchorAlertOn1, AnchorAlertOn2;
233extern wxString g_AW1GUID;
234extern wxString g_AW2GUID;
235extern bool g_bCruising;
236extern double g_COGAvg;
237extern int g_COGAvgSec;
239extern std::vector<Track *> g_TrackList;
240extern double gQueryVar;
241extern int g_ChartUpdatePeriod;
242extern int g_SkewCompUpdatePeriod;
243extern bool g_bCourseUp;
244extern bool g_bLookAhead;
245extern bool g_bskew_comp;
246extern bool g_bPauseTest;
248extern bool g_bPlayShipsBells;
249extern wxDateTime g_loglast_time;
250extern int g_nAWDefault;
252extern bool g_bDeferredStartTrack;
253extern bool bDBUpdateInProgress;
257extern bool g_bDeferredInitDone;
258extern int options_lastPage;
259extern int options_subpage;
260extern bool b_reloadForPlugins;
262extern int g_NeedDBUpdate;
263extern bool g_bFullscreen;
264extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
265extern ChartGroupArray *g_pGroupArray;
266extern bool g_bEnableZoomToCursor;
267extern double g_display_size_mm;
268extern std::vector<size_t> g_config_display_size_mm;
269extern wxString ChartListFileName;
270extern bool g_bFullscreenToolbar;
271extern arrayofCanvasPtr g_canvasArray;
272extern wxString g_lastAppliedTemplateGUID;
273extern wxPoint options_lastWindowPos;
274extern wxSize options_lastWindowSize;
275extern unsigned int g_canvasConfig;
276extern bool g_bFullScreenQuilt;
277extern bool g_bQuiltEnable;
278extern wxString *pInit_Chart_Dir;
279extern bool g_bShowOutlines;
280extern bool g_bTempShowMenuBar;
281extern bool g_bShowStatusBar;
282extern bool g_FlushNavobjChanges;
283extern int g_FlushNavobjChangesTimeout;
284extern bool g_bShowChartBar;
285extern double g_plus_minus_zoom_factor;
286extern int g_nframewin_x;
287extern int g_nframewin_y;
288extern int g_nframewin_posx;
289extern int g_nframewin_posy;
290extern bool g_bframemax;
291extern LayerList *pLayerList;
292extern bool g_bAutoAnchorMark;
293extern wxDateTime g_start_time;
294extern bool g_bcompression_wait;
295extern bool g_bquiting;
296extern bool b_inCloseWindow;
297extern bool b_inCompressAllCharts;
298extern long g_maintoolbar_orient;
299extern wxAuiDefaultDockArt *g_pauidockart;
300extern int g_click_stop;
301extern wxString g_CmdSoundString;
302extern std::vector<OcpnSound *> bells_sound;
303extern char bells_sound_file_name[2][12];
304extern int g_sticky_chart;
305extern int g_sticky_projection;
306extern wxArrayPtrVoid *UserColourHashTableArray;
307extern wxColorHashMap *pcurrent_user_color_hash;
310extern bool g_own_ship_sog_cog_calc;
311extern int g_own_ship_sog_cog_calc_damp_sec;
312extern bool g_bHasHwClock;
313extern bool s_bSetSystemTime;
314extern bool bVelocityValid;
315extern int gHDx_Watchdog;
318extern bool g_bUseGLL;
319extern int g_MemFootMB;
322extern int g_chart_zoom_modifier_vector;
323extern bool g_config_display_size_manual;
324extern bool g_PrintingInProgress;
325extern bool g_disable_main_toolbar;
326extern bool g_btenhertz;
331typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
332typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
334SetSysColors_t pSetSysColors;
335GetSysColor_t pGetSysColor;
337void SaveSystemColors(
void);
338void RestoreSystemColors(
void);
343DWORD color_3ddkshadow;
345DWORD color_activecaption;
346DWORD color_gradientactivecaption;
347DWORD color_captiontext;
348DWORD color_windowframe;
349DWORD color_inactiveborder;
354#include <wx/msw/msvcrt.h>
358static const long long lNaN = 0xfff8000000000000;
359#define NAN (*(double *)&lNaN)
362static wxArrayPtrVoid *UserColorTableArray = 0;
365double gLat_gt, gLon_gt;
366double gLat_gt_m1, gLon_gt_m1;
368uint64_t fix_time_gt_last;
370double gSog_gt, gCog_gt, gHdt_gt;
371double gCog_gt_m1, gHdt_gt_m1;
373double cog_rate_gt, hdt_rate_gt;
376void appendOSDirSlash(wxString *pString);
378void InitializeUserColors(
void);
379void DeInitializeUserColors(
void);
380void SetSystemColors(ColorScheme cs);
382static bool LoadAllPlugIns(
bool load_enabled) {
383 AbstractPlatform::ShowBusySpinner();
384 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
385 AbstractPlatform::HideBusySpinner();
389static void LaunchLocalHelp(
void) {
391 androidLaunchHelpView();
393 wxString def_lang_canonical = _T(
"en_US");
396 if (plocale_def_lang)
397 def_lang_canonical = plocale_def_lang->GetCanonicalName();
400 wxString help_locn = g_Platform->GetSharedDataDir() + _T(
"doc/help_");
402 wxString help_try = help_locn + def_lang_canonical + _T(
".html");
404 if (!::wxFileExists(help_try)) {
405 help_try = help_locn + _T(
"en_US") + _T(
".html");
407 if (!::wxFileExists(help_try)) {
408 help_try = help_locn + _T(
"web") + _T(
".html");
411 if (!::wxFileExists(help_try))
return;
414 wxLaunchDefaultBrowser(wxString(_T(
"file:///")) + help_try);
418static void DoHelpDialog(
void) {
423 g_pAboutDlg->SetFocus();
428 if (!g_pAboutDlgLegacy)
429 g_pAboutDlgLegacy =
new About(gFrame, g_Platform->GetSharedDataDir(),
430 [] { LaunchLocalHelp(); });
432 g_pAboutDlgLegacy->SetFocus();
433 g_pAboutDlgLegacy->Show();
442#if defined(__WXGTK__) || defined(__WXQT__)
443#include "bitmaps/opencpn.xpm"
458int g_iENCToolbarPosX;
459int g_iENCToolbarPosY;
461void BuildiENCToolbar(
bool bnew) {
462 if (g_bInlandEcdis) {
465 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
466 wxPoint tbp_incanvas =
469 g_iENCToolbarPosY = tbp_incanvas.y;
470 g_iENCToolbarPosX = tbp_incanvas.x;
472 delete g_iENCToolbar;
477 if (!g_iENCToolbar) {
478 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
482 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
484 g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
485 g_iENCToolbarPosY = -1;
488 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
494 wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
498 double tool_scale_factor =
499 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
502 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
503 g_iENCToolbar->SetColorScheme(global_color_scheme);
504 g_iENCToolbar->EnableSubmerge(
false);
507 delete g_iENCToolbar;
508 g_iENCToolbar = NULL;
512bool ShowNavWarning() {
515OpenCPN is distributed in the hope that it will be useful, \
516but WITHOUT ANY WARRANTY; without even the implied \
517warranty of MERCHANTABILITY or FITNESS FOR A \
518PARTICULAR PURPOSE.\n\n\
519See the GNU General Public License for more details.\n\n\
520OpenCPN must only be used in conjunction with approved \
521paper charts and traditional methods of navigation.\n\n\
522DO NOT rely upon OpenCPN for safety of life or property.\n\n\
523Please click \"Agree\" and proceed, or \"Cancel\" to quit.\n"));
525 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
528 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg);
531 msg.Replace(
"\n",
"<br>");
533 std::stringstream html;
534 html <<
"<html><body><p>";
535 html << msg.ToStdString();
536 html <<
"</p></body></html>";
538 std::string title = _(
"Welcome to OpenCPN").ToStdString();
539 std::string action = _(
"Agree").ToStdString();
541 info_dlg.SetInitialSize();
542 info_dlg.AddHtmlContent(html);
543 int agreed = info_dlg.ShowModal();
544 return agreed == wxID_OK;
549 if (chart ==
nullptr)
return false;
552 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
554 if (cc && cc->m_singleChart == chart) {
561#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
564static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
565 const char *prop_name) {
569 unsigned long ret_nitems;
570 unsigned long ret_bytes_after;
571 unsigned char *ret_prop;
573 xa_prop_name = XInternAtom(disp, prop_name, False);
581 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
582 &xa_ret_type, &ret_format, &ret_nitems,
583 &ret_bytes_after, &ret_prop) != Success)
586 if (xa_ret_type != xa_prop_type) {
590 return (
char *)ret_prop;
595static bool isTransparentToolbarInOpenGLOK(
void) {
602 if (!g_bdisable_opengl) {
603 Display *disp = XOpenDisplay(NULL);
605 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
607 "_NET_SUPPORTING_WM_CHECK")) ||
608 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
610 "_WIN_SUPPORTING_WM_CHECK"))) {
613 if ((wm_name = get_X11_property(disp, *sup_window,
614 XInternAtom(disp,
"UTF8_STRING", False),
616 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
619 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
640wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
642BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
643EVT_CLOSE(MyFrame::OnCloseWindow)
644EVT_MENU(wxID_EXIT, MyFrame::OnExit)
645EVT_SIZE(MyFrame::OnSize)
646EVT_MOVE(MyFrame::OnMove)
647EVT_ICONIZE(MyFrame::OnIconize)
648EVT_MENU(-1, MyFrame::OnToolLeftClick)
649EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
650EVT_TIMER(FRAME_TIMER_1, MyFrame::OnFrameTimer1)
651EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
652EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
653EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
654EVT_TIMER(FRANE_TENHZ_TIMER, MyFrame::OnFrameTenHzTimer)
655EVT_MAXIMIZE(MyFrame::OnMaximize)
656EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
657 MyFrame::RequestNewToolbarArgEvent)
658EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
660EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
661EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
662EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
664#ifdef wxHAS_POWER_EVENTS
665EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
666EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
667EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
668EVT_POWER_RESUME(MyFrame::OnResume)
679static
void onBellsFinishedCB(
void *ptr) {
680 auto framePtr =
static_cast<MyFrame *
>(ptr);
682 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
683 wxPostEvent(framePtr, ev);
688 auto msg = ev.GetString().ToStdString();
689 auto ¬eman = NotificationManager::GetInstance();
690 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
693static NmeaLog *GetDataMonitor() {
694 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
695 return dynamic_cast<NmeaLog *
>(w);
699MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
700 const wxSize &size,
long style)
701 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
702 comm_overflow_dlg(this),
703 m_connections_dlg(nullptr),
705 g_current_monitor = wxDisplay::GetFromWindow(
this);
711 g_current_monitor_dip_px_ratio =
712 g_monitor_info[g_current_monitor].width_px /
713 g_monitor_info[g_current_monitor].width;
716 m_last_track_rotation_ts = 0;
717 m_ulLastNMEATicktime = 0;
718 m_data_monitor->Hide();
720 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
724 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
727 InitTimer.SetOwner(
this, INIT_TIMER);
729 m_initializing =
false;
732 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
735 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
738 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
741 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
744 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
746 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
755 m_bTimeIsSet =
false;
758 m_bdefer_resize =
false;
761 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
762 COGFilterTable[i] = NAN;
763 SOGFilterTable[i] = NAN;
765 m_last_bGPSValid =
false;
766 m_last_bVelocityValid =
false;
776 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
781 double process_noise_std = 1.0;
782 double measurement_noise_std = 0.5;
784 m_ChartUpdatePeriod = 1;
789 log_callbacks.log_is_active = [&]() {
790 auto log = GetDataMonitor();
791 return log && log->IsVisible();
793 log_callbacks.log_message = [&](
Logline ll) {
794 NmeaLog *monitor = GetDataMonitor();
797 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
800 ais_callbacks.confirm_stop_track = []() {
801 int r = OCPNMessageBox(
803 _(
"This AIS target has Persistent tracking selected by MMSI "
805 "A Persistent track recording will therefore be restarted for this "
807 "Do you instead want to stop Persistent tracking for this target?"),
808 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
809 return r == wxID_YES;
811 ais_callbacks.get_target_mmsi = []() {
812 auto alert_dlg_active =
814 assert(alert_dlg_active);
815 return alert_dlg_active->Get_Dialog_MMSI();
823 wxLogMessage(
" **** Connect stuff");
829 Connect(wxEVT_OCPN_MSG,
830 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
837 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
838 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
846#if defined(__WXGTK__) || defined(__WXQT__)
847 wxIcon app_icon(opencpn);
855 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
857 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
858 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
863 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
866 g_sticky_projection = -1;
869 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
870 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
872 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
874 [&](wxCommandEvent) { Refresh(); });
875 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
880 EnableFullScreenView();
886 FrameTenHzTimer.Stop();
893 wxRouteListNode *node = pRouteList->GetFirst();
896 Route *pRouteDelete = node->GetData();
899 node = node->GetNext();
906 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
914 switch (event.type) {
915 case SENC_BUILD_STARTED:
918 case SENC_BUILD_DONE_NOERROR:
920 chart =
event.m_ticket->m_chart;
922 chart->PostInit(FULL_INIT, global_color_scheme);
924 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
926 if (cc) cc->ClearS52PLIBStateHash();
931 delete event.m_ticket;
933 case SENC_BUILD_DONE_ERROR:
941void MyFrame::RebuildChartDatabase() {
942 bool b_SetInitialPoint =
false;
945 ArrayOfCDI ChartDirArray;
946 pConfig->LoadChartDirArray(ChartDirArray);
948 if (ChartDirArray.GetCount()) {
951 if (g_NeedDBUpdate == 1) {
953 _(
"OpenCPN needs to update the chart database from config file "
957 wxICON_INFORMATION | wxOK);
965 _(
"Rebuilding chart database from configuration file entries..."));
969 wxString dummy1 = _(
"Elapsed time : ");
970 wxString dummy2 = _(
"Estimated time : ");
971 wxString dummy3 = _(
"Remaining time : ");
972 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
973 _(
"OpenCPN Chart Update"), line, 100, NULL,
974 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
975 wxPD_REMAINING_TIME);
977 ChartData->
Create(ChartDirArray, pprog);
978 ChartData->SaveBinary(ChartListFileName);
983 ChartData->ApplyGroupArray(g_pGroupArray);
988void MyFrame::OnBellsFinished(wxCommandEvent &event) {
989 int bells = wxMin(m_BellsToPlay, 2);
990 if (bells <= 0)
return;
992 wxString soundfile = _T(
"sounds");
993 appendOSDirSlash(&soundfile);
994 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
995 soundfile.Prepend(g_Platform->GetSharedDataDir());
996 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
998 OcpnSound *sound = bells_sound[bells - 1];
999 sound->SetFinishedCallback(onBellsFinishedCB,
this);
1000 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
1001 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
1002 sound->Load(soundfile);
1003 if (!sound->IsOk()) {
1004 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
1008 m_BellsToPlay -= bells;
1011void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
1013void MyFrame::OnMaximize(wxMaximizeEvent &event) {
1020ColorScheme GetColorScheme() {
return global_color_scheme; }
1022ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
1024void MyFrame::ReloadAllVP() {
1025 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1027 if (cc) cc->ReloadVP();
1031void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
1032 global_color_scheme = cs;
1034 wxString SchemeName;
1036 case GLOBAL_COLOR_SCHEME_DAY:
1037 SchemeName = _T(
"DAY");
1039 case GLOBAL_COLOR_SCHEME_DUSK:
1040 SchemeName = _T(
"DUSK");
1042 case GLOBAL_COLOR_SCHEME_NIGHT:
1043 SchemeName = _T(
"NIGHT");
1046 SchemeName = _T(
"DAY");
1050 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
1052 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
1053 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
1054 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1055 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
1056 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
1058 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
1087 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1088 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1090 g_pauimgr->Update();
1092 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1095 unsigned Usercolortable_index = 0;
1096 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1097 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1098 if (SchemeName.IsSameAs(*ct->tableName)) {
1099 Usercolortable_index = i;
1104 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1107 pcurrent_user_color_hash =
1108 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1110 SetSystemColors(cs);
1113 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1116 cc->SetColorScheme(cs);
1117 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1118 cc->HideChartInfoWindow();
1119 cc->SetQuiltChartHiLiteIndex(-1);
1125 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1126 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1129 g_options->SetColorScheme(cs);
1133 console->SetColorScheme(cs);
1137 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1140 if (g_pMarkInfoDialog) {
1141 g_pMarkInfoDialog->SetColorScheme(cs);
1144 if (pRoutePropDialog) {
1145 pRoutePropDialog->SetColorScheme(cs);
1150 if (g_pais_query_dialog_active) {
1151 bool b_isshown = g_pais_query_dialog_active->IsShown();
1152 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1153 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1155 g_pais_query_dialog_active->Close();
1158 g_pais_query_dialog_active->
Create(
1159 this, -1, _(
"AIS Target Query"),
1160 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1161 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1162 g_pais_query_dialog_active->UpdateText();
1163 if (b_isshown) g_pais_query_dialog_active->Show();
1166 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1168 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1170 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1172 ApplyGlobalColorSchemetoStatusBar();
1174 UpdateAllToolbars(cs);
1176 if (g_MainToolbar) {
1177 if (g_MainToolbar->GetColorScheme() != cs) {
1179 bool btoolbarFull = g_bmasterToolbarFull;
1181 g_MainToolbar->SetColorScheme(cs);
1185 if (!btoolbarFull) {
1187 RequestNewMasterToolbar();
1188 g_MainToolbar->SetColorScheme(cs);
1189 CollapseGlobalToolbar();
1192 RequestNewMasterToolbar();
1193 g_MainToolbar->SetColorScheme(cs);
1198 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1201void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1202 if (m_pStatusBar != NULL) {
1203 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1204 m_pStatusBar->ClearBackground();
1209 if (g_canvasArray.GetCount() > 0)
1210 return g_canvasArray.Item(0);
1214void MyFrame::CancelAllMouseRoute() {
1216 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1218 if (cc) cc->CancelMouseRoute();
1222void MyFrame::NotifyChildrenResize() {}
1224void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1226 if (ChartData) ChartData->PurgeCache();
1229 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1232 g_pauimgr->DetachPane(cc);
1237 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1246 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1249 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1250 config_array.Item(i)->canvas = NULL;
1256 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1257 g_canvasArray.RemoveAt(i);
1261 switch (g_canvasConfig) {
1264 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1267 g_canvasArray.Add(cc);
1269 cc = g_canvasArray[0];
1275 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1276 cc->GetglCanvas()->Show();
1279 config_array.Item(0)->canvas = cc;
1283 cc->ApplyCanvasConfig(config_array.Item(0));
1287 cc->ConfigureChartBar();
1288 cc->SetColorScheme(global_color_scheme);
1289 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1290 cc->SetShowGPS(
true);
1292 g_pauimgr->AddPane(cc);
1293 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1294 g_pauimgr->GetPane(cc).Fixed();
1295 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1296 g_pauimgr->GetPane(cc).CenterPane();
1301 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1303 g_canvasArray.Add(cc);
1305 cc = g_canvasArray[0];
1311 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1314 config_array.Item(0)->canvas = cc;
1316 cc->ApplyCanvasConfig(config_array.Item(0));
1319 cc->ConfigureChartBar();
1320 cc->SetColorScheme(global_color_scheme);
1321 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1322 cc->SetShowGPS(
false);
1324 g_pauimgr->AddPane(cc);
1325 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1326 g_pauimgr->GetPane(cc)
1327 .CaptionVisible(
false)
1329 .CloseButton(
false);
1331 g_pauimgr->GetPane(cc).CenterPane();
1334 g_canvasArray.Add(cc);
1338 if (config_array.GetCount() < 2) {
1340 pcc->configIndex = 1;
1344 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1345 config_array.Add(pcc);
1348 config_array.Item(1)->canvas = cc;
1350 cc->ApplyCanvasConfig(config_array.Item(1));
1353 cc->ConfigureChartBar();
1354 cc->SetColorScheme(global_color_scheme);
1355 cc->SetShowGPS(
true);
1358 g_pauimgr->AddPane(cc);
1359 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1360 g_pauimgr->GetPane(cc)
1361 .CaptionVisible(
false)
1363 .CloseButton(
false);
1364 g_pauimgr->GetPane(cc).RightDockable(
true);
1365 g_pauimgr->GetPane(cc).Right();
1368 config_array.Item(1)->canvasSize =
1369 wxSize(GetClientSize().x / 2, GetClientSize().y);
1370 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1375 if (b_useStoredSize) {
1376 int ccw = config_array.Item(1)->canvasSize.x;
1377 int cch = config_array.Item(1)->canvasSize.y;
1380 if (ccw < GetClientSize().x / 10) {
1381 ccw = GetClientSize().x / 2;
1382 cch = GetClientSize().y;
1385 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1386 cc->SetSize(ccw, cch);
1397 g_focusCanvas = GetPrimaryCanvas();
1400void MyFrame::RequestNewToolbars(
bool bforcenew) {
1401 if (b_inCloseWindow) {
1405 BuildiENCToolbar(bforcenew);
1406 PositionIENCToolbar();
1415void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1416 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1421void MyFrame::SetAllToolbarScale() {
1422 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1425void MyFrame::SetGPSCompassScale() {
1426 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1430 wxPoint screenPoint = ::wxGetMousePosition();
1433 switch (g_canvasConfig) {
1435 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1438 if (canvas->GetScreenRect().Contains(
1442 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1445 if (canvas->GetScreenRect().Contains(
1452 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1455 if (canvas->GetScreenRect().Contains(
1456 canvas->ScreenToClient(screenPoint)))
1464int MyFrame::GetCanvasIndexUnderMouse() {
1465 wxPoint screenPoint = ::wxGetMousePosition();
1468 switch (g_canvasConfig) {
1470 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1473 if (canvas->GetScreenRect().Contains(
1477 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1480 if (canvas->GetScreenRect().Contains(
1487 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1490 if (canvas->GetScreenRect().Contains(
1491 canvas->ScreenToClient(screenPoint)))
1499bool MyFrame::DropMarker(
bool atOwnShip) {
1506 if (!canvas)
return false;
1513 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1515 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1516 pConfig->AddNewWayPoint(pWP, -1);
1520 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1521 pRouteManagerDialog->UpdateWptListCtrl();
1526 RefreshAllCanvas(
false);
1531void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1532 if (g_canvasConfig != 0) {
1535 int nTargetGTK = -1;
1537 wxWindow *source = FindFocus();
1543 switch (g_canvasConfig) {
1545 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1548 if (canvas && (canvas == test)) {
1553 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1556 if (canvas && (canvas == test)) {
1564 int nfinalTarget = nTarget;
1566 nfinalTarget = nTargetGTK;
1568 target = ConfigMgr::Get()
1569 .GetCanvasConfigArray()
1574 target->Refresh(
true);
1585void MyFrame::FastClose() {
1587 FrameTenHzTimer.Stop();
1589 FrameTimer1.Start(1);
1593void MyFrame::OnExit(wxCommandEvent &event) {
1597void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1600 if (b_inCloseWindow) {
1610 if (!g_bDeferredInitDone)
return;
1623 if (b_inCompressAllCharts) {
1627 if (bDBUpdateInProgress)
return;
1629 b_inCloseWindow =
true;
1631 ::wxSetCursor(wxCURSOR_WAIT);
1635 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1637 if (cc && cc->IsMeasureActive()) {
1638 cc->CancelMeasureRoute();
1643 SendPreShutdownHookToPlugins();
1647 if (g_pAISTargetList) {
1648 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1649 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1650 g_pauimgr->DetachPane(g_pAISTargetList);
1661 pConfig->SetPath(_T (
"/AUI" ));
1662 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1669 if (g_glTextureManager) {
1670 g_glTextureManager->PurgeJobList();
1672 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1677 SetCursor(wxCURSOR_WAIT);
1679 RefreshAllCanvas(
true);
1685 RestoreScreenBrightness();
1694 if (g_iENCToolbar) {
1695 wxPoint locn = g_iENCToolbar->GetPosition();
1696 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1697 g_iENCToolbarPosY = tbp_incanvas.y;
1698 g_iENCToolbarPosX = tbp_incanvas.x;
1702 g_bframemax = IsMaximized();
1705 FrameTenHzTimer.Stop();
1707 FrameCOGTimer.Stop();
1721 if (g_bAutoAnchorMark) {
1722 bool watching_anchor =
false;
1723 if (pAnchorWatchPoint1)
1724 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1726 if (pAnchorWatchPoint2)
1727 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1730 wxDateTime now = wxDateTime::Now();
1731 wxTimeSpan uptime = now.Subtract(g_start_time);
1733 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1734 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1739 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1742 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1743 double a = gLat - pr->m_lat;
1744 double b = gLon - pr->m_lon;
1745 double l = sqrt((a * a) + (b * b));
1748 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1749 pConfig->DeleteWayPoint(pr);
1750 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1756 node = node->GetNext();
1759 wxString name = now.Format();
1760 name.Prepend(_(
"Anchorage created "));
1762 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1763 pWP->m_bShowName =
false;
1766 pConfig->AddNewWayPoint(pWP, -1);
1771 pConfig->UpdateSettings();
1774 PluginLoader::GetInstance()->DeactivateAllPlugIns();
1775 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1779 pConfig->UpdateNavObj();
1781 pConfig->m_pNavObjectChangesSet->reset();
1785 pConfig->DeleteGroup(_T (
"/Routes" ));
1786 pConfig->DeleteGroup(_T (
"/Marks" ));
1789 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1790 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1795 if (g_pCM93OffsetDialog) {
1796 g_pCM93OffsetDialog->Destroy();
1797 g_pCM93OffsetDialog = NULL;
1805 if (g_iENCToolbar) {
1812 if (g_pAISTargetList) {
1813 g_pAISTargetList->Disconnect_decoder();
1814 g_pAISTargetList->Destroy();
1821 if (RouteManagerDialog::getInstanceFlag()) {
1822 if (pRouteManagerDialog) {
1823 pRouteManagerDialog->Destroy();
1824 pRouteManagerDialog = NULL;
1829 if (ChartData) ChartData->PurgeCache();
1835 g_focusCanvas = NULL;
1838 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1840 if (cc) cc->Destroy();
1843 g_canvasArray.Clear();
1845 g_pauimgr->UnInit();
1855 if (ChartData) ChartData->PurgeCachePlugins();
1857 PluginLoader::GetInstance()->UnLoadAllPlugIns();
1860 delete g_pi_manager;
1861 g_pi_manager = NULL;
1864 MyApp &app = wxGetApp();
1865 app.m_comm_bridge.SaveConfig();
1885 auto ®istry = CommDriverRegistry::GetInstance();
1886 registry.CloseAllDrivers();
1889 for (
auto *cp : TheConnectionParams()) {
1894 LayerList::iterator it;
1895 while (pLayerList->GetCount()) {
1896 Layer *lay = pLayerList->GetFirst()->GetData();
1901 ReleaseApiListeners();
1903 g_MainToolbar = NULL;
1904 g_bTempShowMenuBar =
false;
1906#define THREAD_WAIT_SECONDS 5
1912 if (g_bopengl && g_glTextureManager &&
1913 g_glTextureManager->GetRunningJobCount()) {
1914 g_glTextureManager->ClearAllRasterTextures();
1916 wxLogMessage(_T(
"Starting compressor pool drain"));
1917 wxDateTime now = wxDateTime::Now();
1918 time_t stall = now.GetTicks();
1919 time_t end = stall + THREAD_WAIT_SECONDS;
1922 while (stall < end) {
1923 wxDateTime later = wxDateTime::Now();
1924 stall = later.GetTicks();
1927 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1928 g_glTextureManager->GetRunningJobCount());
1930 if (!g_glTextureManager->GetRunningJobCount())
break;
1936 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1937 n_comploop, g_glTextureManager->GetRunningJobCount());
1940 delete g_glTextureManager;
1942 uninitIXNetSystem();
1946 wxLogMessage(_T(
"gFrame destroyed."));
1949#ifndef USE_ANDROID_GLES2
1950 qDebug() <<
"Calling OnExit()";
1954 wxTheApp->ExitMainLoop();
1957void MyFrame::OnMove(wxMoveEvent &event) {
1958 auto idx = wxDisplay::GetFromWindow(
this);
1959 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
1960 static_cast<size_t>(idx) < g_monitor_info.size()) {
1961 g_current_monitor = idx;
1967 g_current_monitor_dip_px_ratio =
1968 g_monitor_info[idx].width_px / g_monitor_info[idx].width;
1971 DEBUG_LOG <<
"Moved to " << idx
1972#if wxCHECK_VERSION(3, 1, 6)
1973 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1974 << wxDisplay(idx).GetPPI().GetY()
1975 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1977 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1978 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1979 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1980 << wxGetDisplaySizeMM().GetY()
1981 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1982 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x"
1983 << g_monitor_info[idx].height_mm <<
"mm "
1984 << g_monitor_info[idx].width_mm <<
"x"
1985 << g_monitor_info[idx].height_mm <<
"mm "
1986 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height
1987 <<
"DIP " << g_monitor_info[idx].width_px <<
"x"
1988 << g_monitor_info[idx].height_px <<
"px"
1989 << g_monitor_info[idx].scale <<
"%";
1990 if (g_config_display_size_manual) {
1991 if (g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
1992 g_display_size_mm = g_config_display_size_mm[idx];
1995 g_display_size_mm = g_monitor_info[idx].width_mm;
1999 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2002 cc->SetMUIBarPosition();
2011 UpdateGPSCompassStatusBoxes();
2013 if (console && console->IsShown()) PositionConsole();
2021 PositionIENCToolbar();
2027 g_nframewin_posx = GetPosition().x;
2028 g_nframewin_posy = GetPosition().y;
2031void MyFrame::ProcessCanvasResize(
void) {
2032 UpdateGPSCompassStatusBoxes(
true);
2034 if (console && console->IsShown()) PositionConsole();
2036 PositionIENCToolbar();
2039 TriggerRecaptureTimer();
2043void MyFrame::TriggerRecaptureTimer() {
2044 m_recaptureTimer.Start(
2045 1000, wxTIMER_ONE_SHOT);
2048void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
2050void MyFrame::SetCanvasSizes(wxSize frameSize) {
2051 if (!g_canvasArray.GetCount())
return;
2054 int cccw = frameSize.x;
2055 int ccch = frameSize.y;
2059 switch (g_canvasConfig) {
2063 cc = g_canvasArray.Item(0);
2065 cc->GetSize( &cur_width, &cur_height );
2066 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
2067 if( g_pauimgr->GetPane( cc ).IsOk() )
2068 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
2070 cc->SetSize( 0, 0, cccw, ccch );
2078 cc = g_canvasArray.Item(1);
2080 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
2081 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
2083 ccw = wxMin(ccw, cccw * 8 / 10);
2084 ccw = wxMax(ccw, cccw * 2 / 10);
2088 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2095 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2096 g_pauimgr->GetPane(cc).Fixed();
2097 g_pauimgr->Update();
2100 g_pauimgr->GetPane(cc).Resizable();
2112void MyFrame::OnIconize(wxIconizeEvent &event) {
2114 if (g_MainToolbar) {
2115 g_MainToolbar->Show(!event.IsIconized());
2117 if (g_iENCToolbar) {
2118 g_iENCToolbar->Show(!event.IsIconized());
2122 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2124 if (cc && cc->GetMUIBar()) {
2125 if (cc->GetMUIBar()->GetCanvasOptions()) {
2126 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2127 cc->GetMUIBar()->PushCanvasOptions();
2136void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2138void MyFrame::ODoSetSize(
void) {
2140 GetClientSize(&x, &y);
2143 if (m_pStatusBar != NULL) {
2144 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2145 int currentCount = m_pStatusBar->GetFieldsCount();
2146 if (currentCount != m_StatusBarFieldCount) {
2147 if ((currentCount > 0) && (currentCount < 7)) {
2150 int widths[] = {2, 2, 2, 2, 2, 2};
2151 m_pStatusBar->SetStatusWidths(currentCount, widths);
2154 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2157 if (m_StatusBarFieldCount) {
2162 if (m_StatusBarFieldCount > 2) {
2163 int widths[] = {-6, -5, -5, -6, -4};
2164 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2165 }
else if (m_StatusBarFieldCount == 2) {
2166 int cwidth = x * 90 / 100;
2167 int widths[] = {100, 100};
2168 widths[0] = cwidth * 6.4 / 10.0;
2169 widths[1] = cwidth * 3.6 / 10.0;
2170 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2172 int widths[] = {100, 100};
2173 widths[0] = x * 90 / 100;
2174 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2177 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2178 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2179 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2181 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2182 _T(
" COG ---\u00B0"));
2183 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2191 m_pStatusBar->GetFieldRect(0, stat_box);
2194 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2196 wxFont sys_font = *wxNORMAL_FONT;
2197 int try_font_size = sys_font.GetPointSize();
2200 int min_font_size = 10;
2210 wxFont *statusBarFont =
2211 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2212 int font_size = statusBarFont->GetPointSize();
2214 font_size = wxMin(font_size,
2217 wxMax(font_size, min_font_size);
2220 font_size = statusBarFont->GetPointSize();
2227 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2228 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2230 int min_height = stat_box.height;
2232 m_pStatusBar->SetFont(*pstat_font);
2233 m_pStatusBar->SetForegroundColour(
2234 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2236 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2238 (min_height >> 1) * 2;
2239 m_pStatusBar->SetMinHeight(min_height);
2248 SetCanvasSizes(GetClientSize());
2250 UpdateGPSCompassStatusBoxes(
true);
2252 if (console) PositionConsole();
2255 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2257 if (cc) cc->FormatPianoKeys();
2261 if (g_MainToolbar) {
2262 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2263 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2264 GetPrimaryCanvas()->GetCompass()->GetRect());
2265 g_MainToolbar->Realize();
2267 if (szBefore != g_MainToolbar->GetToolbarSize())
2268 g_MainToolbar->RefreshToolbar();
2277 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2290 options_lastWindowSize = wxSize(0, 0);
2291 options_lastWindowPos = wxPoint(0, 0);
2298 if (!b_inCloseWindow) {
2299 if (g_options) g_options->Raise();
2301 resizeAndroidPersistents();
2306 if (g_pauimgr) g_pauimgr->Update();
2309void MyFrame::PositionConsole(
void) {
2310 if (NULL == GetPrimaryCanvas())
return;
2312 int ccx, ccy, ccsx, ccsy, consx, consy;
2314 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2317 consoleHost->GetSize(&ccsx, &ccsy);
2318 consoleHost->GetPosition(&ccx, &ccy);
2320 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2321 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2322 consoleHost = GetPrimaryCanvas();
2327 if (consoleHost->GetCompass()) {
2328 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2330 if (compass_rect.y < 100)
2331 yOffset = compass_rect.y + compass_rect.height + 45;
2335 console->GetSize(&consx, &consy);
2337 wxPoint screen_pos =
2338 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2339 console->Move(screen_pos);
2342void MyFrame::UpdateAllFonts() {
2344 console->UpdateFonts();
2351 DestroyPersistentDialogs();
2353 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2358void MyFrame::DestroyPersistentDialogs() {
2359 if (g_pais_query_dialog_active) {
2360 g_pais_query_dialog_active->Hide();
2361 g_pais_query_dialog_active->Destroy();
2362 g_pais_query_dialog_active = NULL;
2365 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2366 pRoutePropDialog->Hide();
2367 pRoutePropDialog->Destroy();
2368 pRoutePropDialog = NULL;
2371 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2372 pTrackPropDialog->Hide();
2373 pTrackPropDialog->Destroy();
2374 pTrackPropDialog = NULL;
2377 if (g_pMarkInfoDialog) {
2378 g_pMarkInfoDialog->Hide();
2379 g_pMarkInfoDialog->Destroy();
2380 g_pMarkInfoDialog = NULL;
2383 if (g_pObjectQueryDialog) {
2384 g_pObjectQueryDialog->Hide();
2385 g_pObjectQueryDialog->Destroy();
2386 g_pObjectQueryDialog = NULL;
2390void MyFrame::RefreshGroupIndices(
void) {
2392 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2394 if (cc) cc->canvasRefreshGroupIndex();
2398void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2399 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2401 switch (event.GetId()) {
2402 case ID_MENU_SCALE_OUT:
2403 DoStackDelta(GetPrimaryCanvas(), 1);
2407 case ID_MENU_SCALE_IN:
2408 DoStackDelta(GetPrimaryCanvas(), -1);
2412 case ID_MENU_ZOOM_IN: {
2413 if (GetFocusCanvas()) {
2414 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2419 case ID_MENU_ZOOM_OUT: {
2420 if (GetFocusCanvas()) {
2421 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2426 case ID_MENU_ROUTE_NEW: {
2427 if (GetFocusCanvas()) {
2428 if (0 == GetFocusCanvas()->m_routeState) {
2429 GetFocusCanvas()->StartRoute();
2431 GetFocusCanvas()->FinishRoute();
2437 case ID_MENU_TOOL_MEASURE: {
2438 GetPrimaryCanvas()->StartMeasureRoute();
2442 case ID_MENU_TOOL_NMEA_DBG_LOG:
2443 m_data_monitor->Show();
2444 m_data_monitor->Raise();
2447 case ID_MENU_TOOL_IO_MONITOR:
2448 m_data_monitor->Show();
2451 case ID_MENU_MARK_BOAT: {
2456 case ID_MENU_MARK_CURSOR: {
2461 case ID_MENU_NAV_FOLLOW: {
2462 if (gFrame->GetPrimaryCanvas())
2463 gFrame->GetPrimaryCanvas()->TogglebFollow();
2467 case ID_MENU_CHART_OUTLINES: {
2468 ToggleChartOutlines(GetFocusCanvas());
2472 case ID_MENU_CHART_QUILTING: {
2473 ToggleQuiltMode(GetFocusCanvas());
2477 case ID_MENU_UI_CHARTBAR: {
2478 ToggleChartBar(GetFocusCanvas());
2482 case ID_MENU_ENC_TEXT:
2484 ToggleENCText(GetFocusCanvas());
2487 case ID_MENU_ENC_LIGHTS: {
2488 ToggleLights(GetFocusCanvas());
2491 case ID_MENU_ENC_SOUNDINGS: {
2492 ToggleSoundings(GetFocusCanvas());
2495 case ID_MENU_ENC_ANCHOR: {
2496 ToggleAnchor(GetFocusCanvas());
2499 case ID_MENU_ENC_DATA_QUALITY: {
2500 ToggleDataQuality(GetFocusCanvas());
2503 case ID_MENU_SHOW_NAVOBJECTS: {
2504 ToggleNavobjects(GetFocusCanvas());
2508 case ID_MENU_AIS_TARGETS: {
2509 ToggleAISDisplay(GetFocusCanvas());
2512 case ID_MENU_AIS_MOORED_TARGETS: {
2513 g_bHideMoored = !g_bHideMoored;
2516 case ID_MENU_AIS_SCALED_TARGETS: {
2517 ToggleAISMinimizeTargets(GetFocusCanvas());
2521 case ID_MENU_AIS_TARGETLIST: {
2522 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2526 case ID_MENU_AIS_TRACKS: {
2527 g_bAISShowTracks = !g_bAISShowTracks;
2528 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2532 case ID_MENU_AIS_CPADIALOG: {
2533 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2534 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2535 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2536 if (g_bAIS_CPA_Alert) {
2537 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2542 case ID_MENU_AIS_CPASOUND: {
2543 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2544 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2548 case ID_MENU_AIS_CPAWARNING: {
2549 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2550 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2554 case wxID_PREFERENCES:
2556 g_MainToolbar->HideTooltip();
2561 case ID_SETTINGS_NEW: {
2566 case ID_SETTINGS_DELETE: {
2568 g_options =
nullptr;
2572 case ID_MENU_SETTINGS_BASIC: {
2575 androidDisableFullScreen();
2576 g_MainToolbar->HideTooltip();
2577 DoAndroidPreferences();
2584 case ID_MENU_UI_FULLSCREEN: {
2589 case ID_MENU_SHOW_CURRENTS: {
2590 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2591 GetFocusCanvas()->ReloadVP();
2592 GetFocusCanvas()->Refresh(
false);
2596 case ID_MENU_SHOW_TIDES: {
2597 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2598 GetFocusCanvas()->ReloadVP();
2599 GetFocusCanvas()->Refresh(
false);
2619 case ID_MENU_UI_COLSCHEME:
2620 case ID_COLSCHEME: {
2621 ToggleColorScheme();
2630 case ID_MENU_OQUIT: {
2635 case ID_MENU_ROUTE_MANAGER:
2636 case ID_ROUTEMANAGER: {
2637 pRouteManagerDialog = RouteManagerDialog::getInstance(
2640 if (pRouteManagerDialog->IsShown())
2641 pRouteManagerDialog->Hide();
2643 pRouteManagerDialog->UpdateRouteListCtrl();
2644 pRouteManagerDialog->UpdateTrkListCtrl();
2645 pRouteManagerDialog->UpdateWptListCtrl();
2646 pRouteManagerDialog->UpdateLayListCtrl();
2648 pRouteManagerDialog->Show();
2652 pRouteManagerDialog->Centre();
2653 pRouteManagerDialog->Raise();
2659 case ID_MENU_NAV_TRACK:
2661 if (!g_bTrackActive) {
2663 g_bTrackCarryOver =
true;
2666 if (pConfig && pConfig->IsChangesFileDirty()) {
2667 pConfig->UpdateNavObj(
true);
2669 g_bTrackCarryOver =
false;
2670 RefreshAllCanvas(
true);
2675 case ID_MENU_CHART_NORTHUP: {
2676 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2679 case ID_MENU_CHART_COGUP: {
2680 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2683 case ID_MENU_CHART_HEADUP: {
2684 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2688 case ID_MENU_MARK_MOB:
2694 case ID_MASTERTOGGLE: {
2695 if (g_MainToolbar) {
2696 wxString tip = _(
"Show Toolbar");
2697 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2698 if (g_MainToolbar->GetToolbar())
2699 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2701 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2704 if (g_bmasterToolbarFull)
2705 m_nMasterToolCountShown =
2706 g_MainToolbar->GetToolCount() -
2709 m_nMasterToolCountShown = 2;
2711 m_nMasterToolCountShown =
2712 g_MainToolbar->GetToolShowCount();
2714 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2722 case ID_CMD_SELECT_CHART_TYPE: {
2723 selectChartDisplay(event.GetExtraLong(), -1);
2727 case ID_CMD_SELECT_CHART_FAMILY: {
2728 selectChartDisplay(-1, event.GetExtraLong());
2732 case ID_CMD_APPLY_SETTINGS: {
2733 applySettingsString(event.GetString());
2735 androidRestoreFullScreen();
2741 case ID_CMD_NULL_REFRESH: {
2746 case ID_CMD_SETVP: {
2747 setStringVP(event.GetString());
2751 case ID_CMD_INVALIDATE: {
2757 case ID_CMD_POST_JSON_TO_PLUGINS: {
2763 int numErrors = reader.
Parse(event.GetString(), &root);
2764 if (numErrors == 0) {
2765 if (root[_T(
"MessageID")].IsString()) {
2766 wxString MsgID = root[_T(
"MessageID")].
AsString();
2777 if (g_iENCToolbar) {
2778 g_iENCToolbar->OnToolLeftClick(event);
2788 g_MainToolbar->HideTooltip();
2790 ArrayOfPlugInToolbarTools tool_array =
2791 g_pi_manager->GetPluginToolbarToolArray();
2792 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2794 if (event.GetId() == pttc->id) {
2795 if (pttc->m_pplugin)
2814 if (g_MainToolbar) g_MainToolbar->Realize();
2817bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2818 bool viz_now = g_bmasterToolbarFull;
2820 g_MainToolbar->HideTooltip();
2821 wxString tip = _(
"Show Toolbar");
2823 tip = _(
"Hide Toolbar");
2824 if (g_MainToolbar->GetToolbar())
2825 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2828 bool toggle =
false;
2829 if (viz && !g_bmasterToolbarFull)
2832 else if (!viz && g_bmasterToolbarFull)
2836 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2839 if (g_bmasterToolbarFull)
2840 m_nMasterToolCountShown =
2841 g_MainToolbar->GetToolCount() -
2844 m_nMasterToolCountShown = 2;
2846 m_nMasterToolCountShown =
2847 g_MainToolbar->GetToolShowCount();
2849 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2855void MyFrame::ScheduleDeleteSettingsDialog() {
2856 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2857 evt.SetId(ID_SETTINGS_DELETE);
2858 GetEventHandler()->AddPendingEvent(evt);
2861void MyFrame::ScheduleSettingsDialog() {
2862 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2863 evt.SetId(ID_SETTINGS);
2864 GetEventHandler()->AddPendingEvent(evt);
2867void MyFrame::ScheduleSettingsDialogNew() {
2868 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2869 evt.SetId(ID_SETTINGS_NEW);
2870 GetEventHandler()->AddPendingEvent(evt);
2873void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2874 UpdateCanvasConfigDescriptors();
2876 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2877 CreateCanvasLayout(
true);
2879 CreateCanvasLayout();
2881 g_pauimgr->Update();
2883 ConfigureStatusBar();
2884 wxSize lastOptSize = options_lastWindowSize;
2889 options_lastWindowSize = lastOptSize;
2893 ScheduleSettingsDialogNew();
2895 ScheduleSettingsDialog();
2900 if ((g_canvasConfig != 0) && g_focusCanvas)
2901 return g_focusCanvas;
2903 return GetPrimaryCanvas();
2906void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2907 if (g_bmasterToolbarFull) {
2908#ifndef OCPN_TOOLBAR_ANIMATE
2909 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
2912 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
2913 m_nMasterToolCountShown++;
2914 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2915 g_MainToolbar->Realize();
2916 g_MainToolbar->RefreshToolbar();
2918 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2920 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2921 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2922 g_MainToolbar->Realize();
2923 g_MainToolbar->RefreshToolbar();
2926#ifndef OCPN_TOOLBAR_ANIMATE
2927 m_nMasterToolCountShown = 1;
2929 if (m_nMasterToolCountShown > 1) {
2930 m_nMasterToolCountShown--;
2931 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2932 g_MainToolbar->Realize();
2933 g_MainToolbar->RefreshToolbar();
2934 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2936 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2937 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2938 g_MainToolbar->Realize();
2939 g_MainToolbar->RefreshToolbar();
2944void MyFrame::InvalidateAllGL() {
2947 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2957void MyFrame::RefreshAllCanvas(
bool bErase) {
2959 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2962 cc->Refresh(bErase);
2967void MyFrame::setStringVP(wxString VPS) {
2972 wxStringTokenizer tkz(VPS, _T(
";"));
2974 wxString token = tkz.GetNextToken();
2976 token.ToDouble(&lat);
2978 token = tkz.GetNextToken();
2980 token.ToDouble(&lon);
2982 token = tkz.GetNextToken();
2984 token.ToDouble(&scale_ppm);
2986 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2989void MyFrame::DoSettingsNew() {
2991 g_options =
nullptr;
2996void MyFrame::DoSettings() {
3000 ApplyGlobalSettings(
true);
3003 bool b_loadHarmonics =
false;
3004 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3007 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3010 if (b_loadHarmonics) LoadHarmonics();
3018 g_bShowChartBar = !g_bShowChartBar;
3020 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3025 if (g_bShowChartBar) {
3027 UpdateControlBar(cc);
3030 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3033void MyFrame::ToggleColorScheme() {
3034 static bool lastIsNight;
3035 ColorScheme s = GetColorScheme();
3038 if (lastIsNight && is == 3)
3041 lastIsNight =
false;
3043 if (lastIsNight) is = 2;
3044 if (is == 3) lastIsNight =
true;
3045 s = (ColorScheme)is;
3046 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3048 SetAndApplyColorScheme(s);
3051void MyFrame::ToggleFullScreen() {
3052 bool to = !IsFullScreen();
3057 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3059 ShowFullScreen(to, style);
3062 UpdateAllToolbars(global_color_scheme);
3064 UpdateControlBar(GetPrimaryCanvas());
3066 TriggerRecaptureTimer();
3069void MyFrame::ActivateMOB(
void) {
3071 wxDateTime mob_time = wxDateTime::Now();
3072 wxString mob_label(_(
"MAN OVERBOARD"));
3073 mob_label += _(
" on ");
3074 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3077 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
3078 pWP_MOB->SetShared(
true);
3080 pWP_MOB->SetWaypointArrivalRadius(
3082 pWP_MOB->SetUseSca(
false);
3083 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
3084 pConfig->AddNewWayPoint(pWP_MOB, -1);
3086 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
3089 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
3092 new RoutePoint(zlat, zlon, g_default_wp_icon,
3093 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3094 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3097 pRouteList->Append(temp_route);
3099 temp_route->AddPoint(pWP_src);
3100 temp_route->AddPoint(pWP_MOB);
3102 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
3112 temp_route->SetRouteArrivalRadius(-1.0);
3114 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
3118 v[_T(
"GUID")] = temp_route->
m_GUID;
3119 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
3120 SendJSONMessageToAllPlugins(msg_id, v);
3123 if (RouteManagerDialog::getInstanceFlag()) {
3124 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3125 pRouteManagerDialog->UpdateRouteListCtrl();
3126 pRouteManagerDialog->UpdateWptListCtrl();
3131 RefreshAllCanvas(
false);
3133 wxString mob_message(_(
"MAN OVERBOARD"));
3134 mob_message += _(
" Time: ");
3135 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3136 mob_message += _(
" Position: ");
3137 mob_message += toSDMM(1, gLat);
3138 mob_message += _T(
" ");
3139 mob_message += toSDMM(2, gLon);
3140 wxLogMessage(mob_message);
3142void MyFrame::TrackOn(
void) {
3143 g_bTrackActive =
true;
3146 g_TrackList.push_back(g_pActiveTrack);
3147 if (pConfig) pConfig->AddNewTrack(g_pActiveTrack);
3149 g_pActiveTrack->Start();
3152 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3154 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3156 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3159 androidSetTrackTool(
true);
3162 if (RouteManagerDialog::getInstanceFlag()) {
3163 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3164 pRouteManagerDialog->UpdateTrkListCtrl();
3165 pRouteManagerDialog->UpdateRouteListCtrl();
3170 wxString name = g_pActiveTrack->GetName();
3171 if (name.IsEmpty()) {
3172 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3177 name = _(
"(Unnamed Track)");
3179 v[_T(
"Name")] = name;
3180 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3181 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3182 SendJSONMessageToAllPlugins(msg_id, v);
3183 g_FlushNavobjChangesTimeout =
3187Track *MyFrame::TrackOff(
bool do_add_point) {
3188 Track *return_val = g_pActiveTrack;
3190 if (g_pActiveTrack) {
3192 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3193 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3194 SendJSONMessageToAllPlugins(msg_id, v);
3196 g_pActiveTrack->Stop(do_add_point);
3198 if (g_pActiveTrack->GetnPoints() < 2) {
3199 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3202 if (g_bTrackDaily) {
3203 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3205 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3206 return_val = pExtendTrack;
3210 g_pActiveTrack = NULL;
3213 g_bTrackActive =
false;
3215 if (RouteManagerDialog::getInstanceFlag()) {
3216 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3217 pRouteManagerDialog->UpdateTrkListCtrl();
3218 pRouteManagerDialog->UpdateRouteListCtrl();
3222 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3224 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3225 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3228 androidSetTrackTool(
false);
3231 g_FlushNavobjChangesTimeout =
3237bool MyFrame::ShouldRestartTrack(
void) {
3238 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3239 time_t now = wxDateTime::Now().GetTicks();
3240 time_t today = wxDateTime::Today().GetTicks();
3242 switch (g_track_rotate_time_type) {
3244 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3246 case TIME_TYPE_COMPUTER:
3247 rotate_at = g_track_rotate_time;
3251 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3252 rotate_at = g_track_rotate_time + utc_offset;
3255 if (rotate_at > 86400)
3257 else if (rotate_at < 0)
3259 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3260 now - today >= rotate_at) {
3261 if (m_last_track_rotation_ts == 0) {
3262 if (now - today > rotate_at)
3263 m_last_track_rotation_ts = today + rotate_at;
3265 m_last_track_rotation_ts = today + rotate_at - 86400;
3268 m_last_track_rotation_ts = now;
3274void MyFrame::TrackDailyRestart(
void) {
3275 if (!g_pActiveTrack)
return;
3277 Track *pPreviousTrack = TrackOff(
true);
3278 if (pConfig && pConfig->IsChangesFileDirty()) {
3279 pConfig->UpdateNavObj(
true);
3288 if (pPreviousTrack) {
3289 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3290 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3293 if (RouteManagerDialog::getInstanceFlag()) {
3294 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3295 pRouteManagerDialog->UpdateTrkListCtrl();
3296 pRouteManagerDialog->UpdateRouteListCtrl();
3301void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3303 cc->SetUpMode(mode);
3305 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3306 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3307 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3310 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3315 cc->SetShowENCText(!cc->GetShowENCText());
3317 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3325void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3328 cc->SetENCDisplayCategory(nset);
3330 UpdateGlobalMenuItems();
3341 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3343 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3352 cc->SetShowENCLights(!cc->GetShowENCLights());
3354 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3356 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3364void MyFrame::ToggleRocks(
void )
3370 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3371 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3372 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3373 pOLE->nViz = !pOLE->nViz;
3377 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3378 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3379 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3382 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3386 ps52plib->GenerateStateHash();
3393 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3395 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3397 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3403 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3405 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3407 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3420 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3421 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3426 cc->SetShowAIS(!cc->GetShowAIS());
3427 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3431void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3432 cc->SetAttenAIS(!cc->GetAttenAIS());
3433 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3439 cc->m_bFollow =
true;
3442 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3446 SetChartUpdatePeriod();
3454 cc->m_bFollow =
false;
3456 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3460 SetChartUpdatePeriod();
3463void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3464 cc->SetShowOutlines(!cc->GetShowOutlines());
3466 RefreshAllCanvas(
false);
3470 if (g_bopengl) InvalidateAllGL();
3473 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3476void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3478void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3480 bool enabled = m_pMenuBar->IsEnabled(item_id);
3481 m_pMenuBar->Enable(item_id,
false);
3482 m_pMenuBar->Check(item_id, state);
3483 m_pMenuBar->Enable(item_id, enabled);
3487void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3488 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3489 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3490 g_MainToolbar->Realize();
3494void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3495 wxBitmap *bmpRollover) {
3496 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3497 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3498 g_MainToolbar->Realize();
3502void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3503 wxString rolloverSVGfile,
3504 wxString toggledSVGfile) {
3505 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3506 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3507 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3511void MyFrame::ConfigureStatusBar() {
3513 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3516 UseNativeStatusBar(
false);
3519 if (g_bShowStatusBar) {
3520 if (!m_pStatusBar) {
3522 CreateStatusBar(m_StatusBarFieldCount, 0);
3523 ApplyGlobalColorSchemetoStatusBar();
3528 m_pStatusBar->Destroy();
3529 m_pStatusBar = NULL;
3535void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3536 ConfigureStatusBar();
3538 wxSize lastOptSize = options_lastWindowSize;
3544 options_lastWindowSize = lastOptSize;
3546 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3549wxString _menuText(wxString name, wxString shortcut) {
3553 menutext << _T(
"\t") << shortcut;
3558void MyFrame::BuildMenuBar(
void) {
3564 bool showMenuBar =
true;
3566 bool showMenuBar = g_bShowMenuBar;
3578 m_pMenuBar =
new wxMenuBar();
3579 RegisterGlobalMenuItems();
3580 SetMenuBar(m_pMenuBar);
3584 UpdateGlobalMenuItems();
3589 m_pMenuBar->Destroy();
3595void MyFrame::RegisterGlobalMenuItems() {
3596 if (!m_pMenuBar)
return;
3598 wxMenu *nav_menu =
new wxMenu();
3599 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3600 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3601 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3602 nav_menu->AppendSeparator();
3603 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3604 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3605 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3606 nav_menu->AppendSeparator();
3608 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3609 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3611 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3612 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3614 nav_menu->AppendSeparator();
3615 nav_menu->Append(ID_MENU_SCALE_IN,
3616 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3617 nav_menu->Append(ID_MENU_SCALE_OUT,
3618 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3620 nav_menu->AppendSeparator();
3621 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3623 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3625 wxMenu *view_menu =
new wxMenu();
3627 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3628 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3629 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3630 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3632 view_menu->AppendCheckItem(
3633 ID_MENU_CHART_QUILTING,
3634 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3635 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3636 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3638 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3639 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3641 view_menu->AppendSeparator();
3643 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3644 _menuText(_(
"Show ENC text"), _T(
"T")));
3645 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3646 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3647 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3648 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3649 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3650 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3651 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3652 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3653 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3654 _menuText(_(
"Show Navobjects"), _T(
"V")));
3656 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3657 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3658 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3659 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3660 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3661 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3662 view_menu->AppendCheckItem(
3663 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3664 view_menu->AppendCheckItem(
3665 ID_MENU_ENC_DATA_QUALITY,
3666 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3667 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3668 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3670 view_menu->AppendSeparator();
3671 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3672 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3673 view_menu->AppendSeparator();
3675 view_menu->Append(ID_MENU_UI_COLSCHEME,
3676 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3678 view_menu->Append(ID_MENU_UI_COLSCHEME,
3679 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3682 view_menu->AppendSeparator();
3684 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3685 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3687 m_pMenuBar->Append(view_menu, _(
"&View"));
3689 wxMenu *ais_menu =
new wxMenu();
3690 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3691 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3692 _(
"Attenuate less critical AIS targets"));
3693 ais_menu->AppendSeparator();
3694 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3695 _(
"Hide Moored AIS Targets"));
3696 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3697 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3698 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3701 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3702 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3704 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3705 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3708 ais_menu->AppendSeparator();
3709 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3710 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3712 wxMenu *tools_menu =
new wxMenu();
3713 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3714 _menuText(_(
"Data Monitor"),
"Alt-C"));
3716 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3717 _menuText(_(
"Measure Distance"), _T(
"M")));
3719 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3720 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3723 tools_menu->AppendSeparator();
3724 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3725 tools_menu->Append(ID_MENU_ROUTE_NEW,
3726 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3727 tools_menu->AppendSeparator();
3728 tools_menu->Append(ID_MENU_MARK_BOAT,
3729 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3730 tools_menu->Append(ID_MENU_MARK_CURSOR,
3731 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3732 tools_menu->AppendSeparator();
3737 _(
"Drop MOB Marker"),
3738 _T(
"RawCtrl-Space")));
3739 tools_menu->AppendSeparator();
3740 tools_menu->Append(wxID_PREFERENCES,
3741 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3743 tools_menu->Append(ID_MENU_MARK_MOB,
3744 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3745 tools_menu->AppendSeparator();
3746 tools_menu->Append(wxID_PREFERENCES,
3747 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3749 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3752 wxMenu *window_menu =
new wxMenu();
3753 m_pMenuBar->Append(window_menu, _(
"&Window"));
3756 wxMenu *help_menu =
new wxMenu();
3757 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3758 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3759 m_pMenuBar->Append(help_menu, _(
"&Help"));
3762 UpdateGlobalMenuItems();
3765void MyFrame::UpdateGlobalMenuItems() {
3766 if (!m_pMenuBar)
return;
3768 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3769 ->Check(GetPrimaryCanvas()->m_bFollow);
3770 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3771 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3772 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3773 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3774 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3775 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3776 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3777 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3778 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3779 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3780 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3781 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3782 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3783 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3784 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3785 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3786 if (g_bAIS_CPA_Alert) {
3787 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3788 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3790 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3791 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3794 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3795 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3796 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3799 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3800 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3801 ->Check(ps52plib->GetShowSoundings());
3803 bool light_state =
false;
3805 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3807 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3808 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3809 light_state = (pOLE->nViz == 1);
3814 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3815 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3819 DisCat nset = ps52plib->GetDisplayCategory();
3820 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3821 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3822 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3823 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3824 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3825 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3826 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3828 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3829 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3830 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3835void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3836 if (!m_pMenuBar)
return;
3838 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3840 if (cc->GetUpMode() == NORTH_UP_MODE)
3841 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3842 else if (cc->GetUpMode() == COURSE_UP_MODE)
3843 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3845 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3847 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3848 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3849 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3850 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3851 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3852 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3853 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3854 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3855 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3856 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3857 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3858 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3859 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3860 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3861 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3864 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3865 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3868 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3870 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3871 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3876 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3880 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3881 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3882 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3883 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3884 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3885 ->Check(cc->GetShowENCDataQual());
3886 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3888 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3889 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3890 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3895void MyFrame::InvalidateAllCanvasUndo() {
3897 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3899 if (cc) cc->undo->InvalidateUndo();
3903void MyFrame::SubmergeAllCanvasToolbars(
void) {
3905 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3907 if (cc) cc->SubmergeToolbar();
3911void MyFrame::SurfaceAllCanvasToolbars(
void) {
3912 if (g_bshowToolbar) {
3914 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3916 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3923void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3925 if (lon > 180.0) lon -= 360.0;
3930 cc->JumpToPosition(lat, lon,
scale);
3933 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3937void MyFrame::UpdateCanvasConfigDescriptors() {
3939 for (
unsigned int i = 0;
3940 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3941 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3949 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3950 cc->GroupID = chart->m_groupIndex;
3953 cc->
bQuilt = chart->GetQuiltMode();
3960 cc->
bFollow = chart->m_bFollow;
3965 int upmode = chart->GetUpMode();
3966 if (upmode == COURSE_UP_MODE)
3968 else if (upmode == HEAD_UP_MODE)
3975void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3976 if (!RBBox.GetValid())
return;
3978 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3979 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3982 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3983 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3991 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3992 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3994 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3995 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3997 cc->GetSize(&ww, &wh);
3999 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4001 ppm = wxMin(ppm, 1.0);
4007void MyFrame::PrepareOptionsClose(
options *settings,
4008 int settings_return_value) {
4010 options_lastPage = settings->lastPage;
4015 if (options_lastPage == 1) options_lastPage = 0;
4017 options_subpage = settings->lastSubPage;
4018 options_lastWindowPos = settings->lastWindowPos;
4019 options_lastWindowSize = settings->lastWindowSize;
4022 androidEnableBackButton(
true);
4023 androidEnableOptionsMenu(
true);
4024 androidRestoreFullScreen();
4025 androidEnableRotation();
4034 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4037 int index_hint = -1;
4038 if (i < pathArray.GetCount())
4039 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
4040 cc->canvasChartsRefresh(index_hint);
4041 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
4048void MyFrame::DoOptionsDialog() {
4049 if (NULL == g_options) {
4050 AbstractPlatform::ShowBusySpinner();
4053 pConfig->SetPath(
"/Settings");
4054 pConfig->Read(
"OptionsSizeX", &sx, -1);
4055 pConfig->Read(
"OptionsSizeY", &sy, -1);
4057 wxWindow *optionsParent =
this;
4059 optionsParent = GetPrimaryCanvas();
4061 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4064 AbstractPlatform::HideBusySpinner();
4068 g_options->SetInitChartDir(*pInit_Chart_Dir);
4071 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
4072 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4073 g_options->SetWorkDirListPtr(pWorkDirArray);
4076 g_options->SetConfigPtr(pConfig);
4077 g_options->SetInitialSettings();
4079 prev_locale = g_locale;
4080 g_options->SetInitialPage(options_lastPage, options_subpage);
4083 g_options->lastWindowPos = options_lastWindowPos;
4084 if (options_lastWindowPos != wxPoint(0, 0)) {
4085 g_options->Move(options_lastWindowPos);
4086 g_options->SetSize(options_lastWindowSize);
4088 g_options->CenterOnScreen();
4090 if (options_lastWindowSize != wxSize(0, 0)) {
4091 g_options->SetSize(options_lastWindowSize);
4096 androidEnableBackButton(
false);
4097 androidEnableOptionsMenu(
false);
4098 androidDisableFullScreen();
4105 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4108 wxString chart_file_name;
4109 if (cc->GetQuiltMode()) {
4110 int dbi = cc->GetQuiltRefChartdbIndex();
4111 chart_file_name = ChartData->GetDBChartFileName(dbi);
4113 if (cc->m_singleChart)
4114 chart_file_name = cc->m_singleChart->GetFullPath();
4117 pathArray.Add(chart_file_name);
4123 last_canvasConfig = g_canvasConfig;
4126 g_last_ChartScaleFactor = g_ChartScaleFactor;
4132void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4133 bool b_need_refresh =
false;
4135 if ((rr & VISIT_CHARTS) &&
4136 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4138 UpdateChartDatabaseInplace(*pNewDirArray,
4139 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4142 b_need_refresh =
true;
4146 if (rr & STYLE_CHANGED) {
4149 _(
"Please restart OpenCPN to activate language or style changes."),
4150 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4153 bool b_groupchange =
false;
4154 if (((rr & VISIT_CHARTS) &&
4155 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4156 (rr & GROUPS_CHANGED)) {
4157 b_groupchange = ScrubGroupArray();
4158 ChartData->ApplyGroupArray(g_pGroupArray);
4159 RefreshGroupIndices();
4162 if (rr & GROUPS_CHANGED || b_groupchange) {
4163 pConfig->DestroyConfigGroups();
4164 pConfig->CreateConfigGroups(g_pGroupArray);
4167 if (rr & TIDES_CHANGED) {
4173 if (rr & S52_CHANGED) {
4174 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4177 pConfig->UpdateSettings();
4179 if (g_pActiveTrack) {
4180 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4184 g_pRouteMan->SetColorScheme(global_color_scheme,
4185 g_Platform->GetDisplayDPmm());
4188 double stuffcog = NAN;
4189 double stuffsog = NAN;
4190 if (!std::isnan(gCog)) stuffcog = gCog;
4191 if (!std::isnan(gSog)) stuffsog = gSog;
4193 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4194 COGFilterTable[i] = stuffcog;
4195 SOGFilterTable[i] = stuffsog;
4198 SetChartUpdatePeriod();
4200 if (rr & GL_CHANGED) {
4204 b_need_refresh =
true;
4207 if (rr & S52_CHANGED) {
4208 b_need_refresh =
true;
4212 if (rr & REBUILD_RASTER_CACHE) {
4213 if (g_glTextureManager) {
4214 GetPrimaryCanvas()->Disable();
4215 g_glTextureManager->BuildCompressedCache();
4216 GetPrimaryCanvas()->Enable();
4221 if (g_config_display_size_manual &&
4222 g_config_display_size_mm.size() > g_current_monitor &&
4223 g_config_display_size_mm[g_current_monitor] > 0) {
4224 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4229 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4235 g_pi_manager->SendBaseConfigToAllPlugIns();
4236 int rrt = rr & S52_CHANGED;
4237 g_pi_manager->SendS52ConfigToAllPlugIns(
4238 (rrt == S52_CHANGED) ||
4239 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4242 if (g_MainToolbar) {
4243 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4244 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4249 ps52plib->SetScaleFactorExp(
4250 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4251 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4255 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4257 if (cc) cc->ApplyGlobalSettings();
4264 int index_hint = ChartData->FinddbIndex( chart_file_name );
4265 if( -1 == index_hint )
4273 bool ztc = g_bEnableZoomToCursor;
4274 g_bEnableZoomToCursor =
4279 g_bEnableZoomToCursor = ztc;
4282 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4283 if (g_pMarkInfoDialog) {
4284 g_pMarkInfoDialog->Hide();
4285 g_pMarkInfoDialog->Destroy();
4286 g_pMarkInfoDialog = NULL;
4291 SetGPSCompassScale();
4293 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4296 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4297 cc->UpdateCanvasControlBar();
4300 UpdateGPSCompassStatusBoxes();
4302 SetAllToolbarScale();
4303 RequestNewToolbars();
4306 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4309 cc->RebuildCursors();
4314 bool b_masterScaleChange =
false;
4315 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4316 b_masterScaleChange =
true;
4318 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4319 RequestNewMasterToolbar(
true);
4321 bool bMuiChange =
false;
4327 if (b_masterScaleChange || bMuiChange) {
4329 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4332 cc->ProcessNewGUIScale();
4338 if (rr & LOCALE_CHANGED) {
4339 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4341 rr |= NEED_NEW_OPTIONS;
4346 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4350 g_last_ChartScaleFactor = g_ChartScaleFactor;
4355bool MyFrame::CheckGroup(
int igroup) {
4356 if (igroup == 0)
return true;
4358 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4360 if (!pGroup->m_element_array.size())
4363 for (
const auto &elem : pGroup->m_element_array) {
4364 for (
unsigned int ic = 0;
4365 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4367 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4369 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4376bool MyFrame::ScrubGroupArray() {
4381 bool b_change =
false;
4382 unsigned int igroup = 0;
4383 while (igroup < g_pGroupArray->GetCount()) {
4384 bool b_chart_in_element =
false;
4385 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4387 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4388 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4390 for (
unsigned int ic = 0;
4391 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4393 wxString chart_full_path = pcte->GetFullSystemPath();
4395 if (chart_full_path.StartsWith(element_root)) {
4396 b_chart_in_element =
true;
4402 if (!b_chart_in_element) {
4403 wxString test_string = _T(
"GSHH");
4404 if (element_root.Upper().Contains(test_string))
4405 b_chart_in_element =
true;
4408 if (!b_chart_in_element)
4410 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4422void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4424 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4426 if (cc && (cc != ccThis)) cc->Refresh();
4431void MyFrame::ChartsRefresh() {
4432 if (!ChartData)
return;
4434 AbstractPlatform::ShowBusySpinner();
4436 bool b_run = FrameTimer1.IsRunning();
4439 FrameTenHzTimer.Stop();
4442 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4445 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4446 if (cc->GetQuiltMode()) {
4447 currentIndex = cc->GetQuiltReferenceChartIndex();
4449 cc->canvasChartsRefresh(currentIndex);
4453 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4454 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4456 AbstractPlatform::HideBusySpinner();
4459void MyFrame::InvalidateAllQuilts() {
4460 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4463 cc->InvalidateQuilt();
4464 cc->SetQuiltRefChart(-1);
4465 cc->m_singleChart = NULL;
4470bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4472 const wxString &ChartListFileName) {
4473 bool b_run = FrameTimer1.IsRunning();
4475 FrameTenHzTimer.Stop();
4477 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4478 FrameCOGTimer.Stop();
4481 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4484 cc->InvalidateQuilt();
4485 cc->SetQuiltRefChart(-1);
4486 cc->m_singleChart = NULL;
4490 ChartData->PurgeCache();
4496 AbstractPlatform::ShowBusySpinner();
4498 wxGenericProgressDialog *pprog =
nullptr;
4500 wxString longmsg = _(
"OpenCPN Chart Update");
4502 _T(
"..................................................................")
4505 pprog = new wxGenericProgressDialog();
4508 pprog->SetFont(*qFont);
4510 pprog->Create(_("OpenCPN
Chart Update"), longmsg, 100, gFrame,
4511 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4512 wxPD_REMAINING_TIME);
4518 wxLogMessage(_T(" "));
4519 wxLogMessage(_T("Starting chart database Update..."));
4520 wxString gshhg_chart_loc = gWorldMapLocation;
4521 gWorldMapLocation = wxEmptyString;
4524 ChartData->Update(DirArray, b_force, pprog);
4525 ChartData->SaveBinary(ChartListFileName);
4526 wxLogMessage(_T("Finished chart database Update"));
4527 wxLogMessage(_T(" "));
4528 if (gWorldMapLocation.empty()) {
4532 gWorldMapLocation = gDefaultWorldMapLocation;
4533 gshhg_chart_loc = wxEmptyString;
4536 if (gWorldMapLocation != gshhg_chart_loc) {
4538 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4540 if (cc) cc->ResetWorldBackgroundChart();
4543 gshhsCrossesLandReset();
4548 AbstractPlatform::HideBusySpinner();
4550 pConfig->UpdateChartDirs(DirArray);
4553 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4554 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4556 if (b_runCOGTimer) {
4558 int period_ms = 100;
4559 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4560 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4567 cc->ToggleCanvasQuiltMode();
4569 bool cur_mode = cc->GetQuiltMode();
4571 if( !cc->GetQuiltMode() )
4572 cc->SetQuiltMode(
true );
4574 if( cc->GetQuiltMode() ) {
4575 cc->SetQuiltMode(
false );
4576 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4580 if( cur_mode != cc->GetQuiltMode() ){
4586 g_bQuiltEnable = cc->GetQuiltMode();
4590 ps52plib->GenerateStateHash();
4595void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4597void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4599void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4601 cc->DoCanvasStackDelta(direction);
4605void MyFrame::PositionIENCToolbar() {
4607 if (g_iENCToolbar) {
4609 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4611 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4619void MyFrame::OnInitTimer(wxTimerEvent &event) {
4622 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4625 wxLog::FlushActive();
4627 switch (m_iInitCount++) {
4629 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4631 if (g_bInlandEcdis) {
4632 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4633 double range_set = 500.;
4635 range = wxRound(range * 10) / 10.;
4639 else if (range > 2000.)
4641 else if (range > 1600.)
4643 else if (range > 1200.)
4645 else if (range > 800.)
4650 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4654 g_Platform->SetFullscreen(g_bFullscreen);
4657 if (g_NeedDBUpdate > 0) {
4658 RebuildChartDatabase();
4659 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4662 cc->SetGroupIndex(0,
false);
4670 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4671 CHART_FAMILY_RASTER)) {
4674 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4676 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4677 CHART_FAMILY_VECTOR)) {
4680 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4689 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4692 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4694 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4697 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4701 pConfig->LoadNavObjects();
4703 if (!g_AW1GUID.IsEmpty()) {
4704 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4706 if (!g_AW2GUID.IsEmpty()) {
4707 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4712 appendOSDirSlash(&layerdir);
4713 layerdir.Append(_T(
"layers"));
4715 if (wxDir::Exists(layerdir)) {
4717 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4719 wxLogMessage(laymsg);
4720 pConfig->LoadLayers(layerdir);
4728 for (
auto *cp : TheConnectionParams()) {
4731 cp->b_IsSetup = TRUE;
4736 console->SetColorScheme(global_color_scheme);
4740 if (g_pRouteMan->IsAnyRouteActive()) {
4741 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
4748 if (m_initializing)
break;
4749 m_initializing =
true;
4750 AbstractPlatform::ShowBusySpinner();
4752 AbstractPlatform::HideBusySpinner();
4754 RequestNewMasterToolbar();
4757 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4759 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4761 wxString perspective;
4762 pConfig->SetPath(_T (
"/AUI" ));
4763 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4770 bool bno_load =
false;
4772 wxArrayString name_array;
4773 wxStringTokenizer st(perspective, _T(
"|;"));
4774 while (st.HasMoreTokens()) {
4775 wxString s1 = st.GetNextToken();
4776 if (s1.StartsWith(_T(
"name="))) {
4777 wxString sc = s1.AfterFirst(
'=');
4782 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4783 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4784 wxAuiPaneInfo pane = pane_array_val.Item(i);
4788 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4794 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4798 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4801 g_pauimgr->GetPane(cc).MinSize(10,10);
4808 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4811 wxSize frameSize = GetClientSize();
4812 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4813 int width = wxMax(minSize.x, frameSize.x / 10);
4814 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4817 g_pauimgr->Update();
4821 g_pi_manager->NotifyAuiPlugIns();
4824 g_pi_manager->ShowDeferredBlacklistMessages();
4826 g_pi_manager->CallLateInit();
4831 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4832 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4834 if (cc) cc->SetFirstAuto(
true);
4837 b_reloadForPlugins =
true;
4844 if (g_MainToolbar) {
4845 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4846 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4852 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4854 cc->RequestNewCanvasToolbar(
true );
4856 if(cc && cc->GetToolbarEnable()){
4857 cc->GetToolbar()->SetAutoHide(g_bAutoHideToolbar);
4858 cc->GetToolbar()->SetAutoHideTimer(g_nAutoHideToolbar);
4868 pConfig->SetPath(
"/Settings");
4869 pConfig->Read(
"OptionsSizeX", &sx, -1);
4870 pConfig->Read(
"OptionsSizeY", &sy, -1);
4872 wxWindow *optionsParent =
this;
4874 optionsParent = GetPrimaryCanvas();
4876 g_options =
new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1),
4879 BuildiENCToolbar(
true);
4886 if (!g_params.empty()) {
4887 for (
size_t n = 0; n < g_params.size(); n++) {
4888 wxString path = g_params[n];
4889 if (::wxFileExists(path)) {
4891 pSet->load_file(path.fn_str());
4894 pSet->LoadAllGPXObjects(
4895 !pSet->IsOpenCPN(), wpt_dups,
4897 LLBBox box = pSet->GetBBox();
4898 if (box.GetValid()) {
4899 CenterView(GetPrimaryCanvas(), box);
4908 InitAppMsgBusListener();
4916 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4918 PositionIENCToolbar();
4920 g_bDeferredInitDone =
true;
4922 GetPrimaryCanvas()->SetFocus();
4923 g_focusCanvas = GetPrimaryCanvas();
4929 if (b_reloadForPlugins) {
4934 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4936 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4940 cc->CheckGroupValid();
4945 androidEnableBackButton(
true);
4946 androidEnableRotation();
4947 androidEnableOptionItems(
true);
4951 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
4960 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
4962 wxLog::FlushActive();
4964 RefreshAllCanvas(
true);
4965 wxGetApp().m_usb_watcher.Start();
4971void MyFrame::InitAppMsgBusListener() {
4972 auto &msgbus = AppMsgBus::GetInstance();
4975 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4976 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4980 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4981 HandleBasicNavMsg(basicnav_msg);
4985 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4986 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4990 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4991 HandleGPSWatchdogMsg(msg);
4998void MyFrame::ReleaseApiListeners() {}
5003 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
5004 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
5005 server.SetGetRestApiEndpointCb(
5006 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
5007 server.open_file_cb = [](
const std::string &path) {
5008 return wxGetApp().OpenFile(path);
5015void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
5016 if (msg->gps_watchdog <= 0) {
5017 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
5018 bool last_bGPSValid = bGPSValid;
5021 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5026 if (m_fix_start_time.IsValid()) {
5027 wxDateTime now = wxDateTime::Now();
5028 wxTimeSpan span = now - m_fix_start_time;
5029 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
5030 auto ¬eman = NotificationManager::GetInstance();
5031 std::string msg =
"GNSS Position fix lost";
5032 noteman.AddNotification(NotificationSeverity::kCritical, msg);
5033 m_fix_start_time = wxInvalidDateTime;
5037 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
5038 bool last_bVelocityValid = bVelocityValid;
5039 bVelocityValid =
false;
5046void MyFrame::CalculateCOGAverage() {
5048 if (!std::isnan(gCog)) {
5049 if (g_COGAvgSec > 0) {
5051 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5054 double sum = 0., count = 0;
5055 for (
int i = 0; i < g_COGAvgSec; i++) {
5056 double adder = COGTable[i];
5057 if (std::isnan(adder))
continue;
5059 if (fabs(adder - g_COGAvg) > 180.) {
5060 if ((adder - g_COGAvg) > 0.)
5073 else if (sum >= 360.)
5082void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5083 m_fixtime = msg->time;
5084 double hdt_data_interval = 0;
5085 double fix_time_interval = 0;
5087 double msgtime = msg->set_time.tv_sec;
5088 double m1 = msg->set_time.tv_nsec / 1e9;
5091 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5092 ((msg->vflag & POS_VALID) == POS_VALID)) {
5094 if (!m_fix_start_time.IsValid()) {
5095 m_fix_start_time = wxDateTime::Now();
5100 DistanceBearingMercator(gLat, gLon, gLat_gt, gLon_gt, &brg, &dist);
5103 fix_time_gt_last = fix_time_gt;
5104 uint64_t fix_time_gt_now =
5105 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5106 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5110 double implied_sog = dist / (fix_time_interval / 3600);
5115 gLat_gt_m1 = gLat_gt;
5116 gLon_gt_m1 = gLon_gt;
5120 fix_time_gt = fix_time_gt_now;
5124 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5125 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5126 gCog_gt_m1 = gCog_gt;
5136 if (!std::isnan(gCog_gt_m1)) {
5138 if ((fabs(gSog - implied_sog) / gSog) > 0.5) {
5145 if ((fix_time_gt - fix_time_gt_last) > .08) {
5150 if (gCog_gt > gCog_gt_m1) {
5151 if ((gCog_gt - gCog_gt_m1) > 180.)
5156 if ((gCog_gt_m1 - gCog_gt) > 180.)
5161 difft = fabs(gCog_gt - gCog_gt_m1);
5162 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5170 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5171 tentative_cog_rate_gt *= 1e9;
5172 cog_rate_gt = tentative_cog_rate_gt;
5180 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5183static double hdt_avg;
5184 double hdt_norm = gHdt;
5185 if(gHdt > 180) hdt_norm -= 360;
5188 hdt_avg += hdt_norm * 0.1;
5190 if( gHdt < 0) gHdt += 360.;
5193 if (!std::isnan(gHdt)) {
5195 uint64_t hdt_time_gt_last = hdt_time_gt;
5196 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5197 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5200 if (hdt_data_interval > .09) {
5202 gHdt_gt_m1 = gHdt_gt;
5205 if (!std::isnan(gHdt_gt_m1)) {
5207 double tentative_hdt_rate_gt =
5208 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5209 tentative_hdt_rate_gt *= 1e9;
5211 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5212 hdt_rate_gt = tentative_hdt_rate_gt;
5220 if (std::isnan(gHdt)) gHdt_gt = NAN;
5223 CalculateCOGAverage();
5230 bool last_bGPSValid = bGPSValid;
5231 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5232 if ((msg->vflag & POS_VALID) == POS_VALID)
5237 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5239 bVelocityValid =
true;
5243void MyFrame::UpdateStatusBar() {
5246 unsigned long uiCurrentTickCount;
5247 m_MMEAeventTime.SetToCurrent();
5248 uiCurrentTickCount =
5249 m_MMEAeventTime.GetMillisecond() / 100;
5250 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5251 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5252 m_ulLastNMEATicktime = uiCurrentTickCount;
5254 if (m_tick_idx++ > 6) m_tick_idx = 0;
5259 if (NULL != GetStatusBar()) {
5262 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5265 wxString s1(tick_buf, wxConvUTF8);
5267 s1 += toSDMM(1, gLat);
5269 s1 += toSDMM(2, gLon);
5271 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5275 if (!std::isnan(gSog))
5276 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5279 sogcog.Printf(_T(
"SOG --- "));
5283 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5285 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5287 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5288 (
int)toMagnetic(gCog), 0x00B0);
5290 cogs.Printf((
"COG ---%c"), 0x00B0);
5292 sogcog.Append(cogs);
5293 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5298void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5299 MemFootTimer.Stop();
5301 int memsize = GetApplicationMemoryUse();
5304 printf(
"Memsize: %d \n", memsize);
5307 if (memsize > (g_MemFootMB * 1000)) {
5309 if (ChartData && cc) {
5311 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5312 unsigned int nCache = pCache->GetCount();
5315 for (
unsigned int i = 0; i < nCache; i++) {
5325 for (
unsigned int i = 0; i < nCache - 1; i++) {
5326 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5328 pcea[i] = pcea[i + 1];
5339 unsigned int idelete = 0;
5340 unsigned int idelete_max = pCache->GetCount();
5343 unsigned int minimum_cache = 1;
5344 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5346 while ((memsize > (g_MemFootMB * 1000)) &&
5347 (pCache->GetCount() > minimum_cache) &&
5348 (idelete < idelete_max)) {
5349 int memsizeb = memsize;
5351 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5353 memsize = GetApplicationMemoryUse();
5354 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5362 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5367void MyFrame::CheckToolbarPosition() {
5370 static bool bMaximized;
5372 if (IsMaximized() && !bMaximized) {
5374 if (g_MainToolbar) {
5375 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5376 g_MainToolbar->SetDefaultPosition();
5377 g_MainToolbar->Realize();
5379 PositionIENCToolbar();
5380 }
else if (!IsMaximized() && bMaximized) {
5382 if (g_MainToolbar) {
5383 g_MainToolbar->SetYAuxOffset(0);
5384 g_MainToolbar->SetDockY(-1);
5385 g_MainToolbar->SetDefaultPosition();
5386 g_MainToolbar->Realize();
5388 PositionIENCToolbar();
5393void MyFrame::ProcessUnitTest() {
5394 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5401 cc->m_bFollow =
false;
5402 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5403 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5404 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5407 if (cc->m_groupIndex > 0) {
5408 while (ut_index < ChartData->GetChartTableEntries() &&
5409 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5413 if (ut_index < ChartData->GetChartTableEntries()) {
5415 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5417 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5418 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5425 if (cc->GetQuiltMode()) {
5426 if (cc->IsChartQuiltableRef(ut_index))
5427 cc->SelectQuiltRefdbChart(ut_index);
5429 cc->SelectdbChart(ut_index);
5432 if (g_unit_test_1) {
5440 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5441 cte->GetLatMin(), cte->GetLonMax(), NULL,
5445 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5446 cte->GetLatMax(), cte->GetLonMin(), NULL,
5449 cc->GetSize(&ww, &wh);
5450 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5452 ppm = wxMin(ppm, 1.0);
5459 if (ut_index > ut_index_max) exit(0);
5468void MyFrame::OnFrameTenHzTimer(wxTimerEvent &event) {
5470 bool b_rotate =
false;
5472 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5475 if (!b_rotate && !g_btenhertz)
return;
5477 bool b_update =
false;
5479 if (!std::isnan(gCog) && !std::isnan(gSog)) {
5482 struct timespec now;
5483 clock_gettime(CLOCK_MONOTONIC, &now);
5484 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5485 double diffc = diff / 1e9;
5488 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5489 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5490 if (gCog_tentative < 0.) gCog_tentative += 360.;
5491 gCog = gCog_tentative;
5495 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5496 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5497 double diffc = diff / 1e9;
5498 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5502 if (gSog_gt && !std::isnan(gCog_gt)) {
5503 double delta_t = diffc / 3600;
5504 double distance = gSog_gt * delta_t;
5507 double angr = gCog_gt / 180 * M_PI;
5508 double latr = gLat_gt * M_PI / 180;
5509 double D = distance / 3443;
5510 double sD = sin(D), cD = cos(D);
5511 double sy = sin(latr), cy = cos(latr);
5512 double sa = sin(angr), ca = cos(angr);
5514 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5515 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5525 if (cc) cc->DoCanvasCOGSet();
5536 if (b_rotate || cc->m_bFollow) {
5537 cc->DoCanvasUpdate();
5546 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5549void MyFrame::ProcessQuitFlag() {
5552 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5554 FrameTenHzTimer.Stop();
5561void MyFrame::ProcessDeferredTrackOn() {
5564 if (g_bDeferredStartTrack) {
5565 if (!g_bTrackActive) {
5568 g_bDeferredStartTrack =
false;
5571 g_bDeferredStartTrack =
false;
5576void MyFrame::ProcessAnchorWatch() {
5579 if (pAnchorWatchPoint1) {
5582 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5583 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5584 double d = g_nAWMax;
5585 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5586 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5587 bool toofar =
false;
5588 bool tooclose =
false;
5589 if (d >= 0.0) toofar = (dist * 1852. > d);
5590 if (d < 0.0) tooclose = (dist * 1852 < -d);
5592 if (tooclose || toofar)
5593 AnchorAlertOn1 =
true;
5595 AnchorAlertOn1 =
false;
5597 AnchorAlertOn1 =
false;
5599 if (pAnchorWatchPoint2) {
5602 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5603 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5605 double d = g_nAWMax;
5606 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5607 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5608 bool toofar =
false;
5609 bool tooclose =
false;
5610 if (d >= 0) toofar = (dist * 1852. > d);
5611 if (d < 0) tooclose = (dist * 1852 < -d);
5613 if (tooclose || toofar)
5614 AnchorAlertOn2 =
true;
5616 AnchorAlertOn2 =
false;
5618 AnchorAlertOn2 =
false;
5620 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5621 AnchorAlertOn1 =
true;
5624void MyFrame::SendFixToPlugins() {
5628 GPSData.
kLat = gLat;
5629 GPSData.
kLon = gLon;
5630 GPSData.
kCog = gCog;
5631 GPSData.
kSog = gSog;
5632 GPSData.
kVar = gVar;
5633 GPSData.
kHdm = gHdm;
5634 GPSData.
kHdt = gHdt;
5635 GPSData.
nSats = g_SatsInView;
5637 wxDateTime tCheck((time_t)m_fixtime);
5638 if (tCheck.IsValid()) {
5647 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5650 SendPositionFixToAllPlugIns(&GPSData);
5654void MyFrame::ProcessLogAndBells() {
5657 wxDateTime lognow = wxDateTime::Now();
5658 int hourLOC = lognow.GetHour();
5659 int minuteLOC = lognow.GetMinute();
5661 int minuteUTC = lognow.GetMinute();
5662 int second = lognow.GetSecond();
5664 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5665 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5666 (minuteUTC == 30)) {
5667 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5668 wxString day = lognow.FormatISODate();
5669 wxString utc = lognow.FormatISOTime();
5670 wxString navmsg = _T(
"LOGBOOK: ");
5674 navmsg += _T(
" UTC ");
5678 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5682 if (std::isnan(gCog))
5683 cog.Printf(_T(
"COG ----- "));
5685 cog.Printf(_T(
"COG %10.5f "), gCog);
5688 if (std::isnan(gSog))
5689 sog.Printf(_T(
"SOG ----- "));
5691 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5697 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5700 wxLogMessage(navmsg);
5701 g_loglast_time = lognow;
5703 int bells = (hourLOC % 4) * 2;
5704 if (minuteLOC != 0) bells++;
5705 if (!bells) bells = 8;
5707 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5708 m_BellsToPlay = bells;
5709 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5710 wxPostEvent(
this, ev);
5716void MyFrame::OnFrameTimer1(wxTimerEvent &event) {
5717 CheckToolbarPosition();
5723 if (bDBUpdateInProgress)
return;
5726 FrameTenHzTimer.Stop();
5728 ProcessDeferredTrackOn();
5730 ProcessAnchorWatch();
5731 ProcessLogAndBells();
5733 if (ShouldRestartTrack()) TrackDailyRestart();
5736 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5737 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5738 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5744 if (gSog > 3.0) g_bCruising =
true;
5750 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5751 _T(
" COG ---\u00B0"));
5752 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5758 bool bnew_view =
false;
5759 if (!g_btenhertz) bnew_view = DoChartUpdate();
5764 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5767 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5770 cc->DrawBlinkObjects();
5773 if (bactiveRouteUpdate) {
5775 if (g_pRouteMan->GetpActiveRoute())
5776 cc->RefreshRect(g_blink_rect,
false);
5780 cc->SetOwnShipState(SHIP_NORMAL);
5782 if (cc->GetQuiltMode()) {
5783 double erf = cc->GetQuiltMaxErrorFactor();
5784 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5786 if (cc->m_singleChart) {
5787 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5788 cc->SetOwnShipState(SHIP_LOWACCURACY);
5792 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5794 if ((bGPSValid != m_last_bGPSValid) ||
5795 (bVelocityValid != m_last_bVelocityValid) ||
5796 (!isnan(gHdt) && (gHdt != m_last_hdt))) {
5797 if (!g_bopengl) cc->UpdateShips();
5804 m_last_bGPSValid = bGPSValid;
5805 m_last_bVelocityValid = bVelocityValid;
5810 bool brq_dynamic =
false;
5812 auto *pplugin_array = PluginLoader::GetInstance()->GetPlugInArray();
5813 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5815 if (pic->m_enabled && pic->m_init_state) {
5816 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5823 if (brq_dynamic) bnew_view =
true;
5827 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5830 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5835 if (cc->GetglCanvas()) {
5837 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5840 if (cc->m_bFollow) {
5841 cc->DoCanvasUpdate();
5848 if (std::isnan(gCog)) cc->Refresh(
false);
5861 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5875 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5876 g_pais_query_dialog_active->UpdateText();
5879 if (g_pAISTargetList && (0 == (g_tick % (5))))
5880 g_pAISTargetList->UpdateAISTargetList();
5883 UpdateGPSCompassStatusBoxes();
5886 if (console && console->IsShown()) {
5888 console->RefreshConsoleData();
5895 if (m_bdefer_resize) {
5896 if (0 == (g_tick % (5))) {
5897 printf(
"___RESIZE\n");
5898 SetSize(m_defer_size);
5899 g_pauimgr->Update();
5900 m_bdefer_resize =
false;
5908 if (((g_tick % g_FlushNavobjChangesTimeout) == 0) || g_FlushNavobjChanges) {
5909 if (pConfig && pConfig->IsChangesFileDirty()) {
5910 androidShowBusyIcon();
5911 wxStopWatch update_sw;
5912 pConfig->UpdateNavObj(
true);
5913 wxString msg = wxString::Format(
5914 _T(
"OpenCPN periodic navobj update took %ld ms."), update_sw.Time());
5916 qDebug() << msg.mb_str();
5917 g_FlushNavobjChanges =
false;
5918 androidHideBusyIcon();
5927 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5929 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5930 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5934double MyFrame::GetMag(
double a,
double lat,
double lon) {
5935 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5936 auto loader = PluginLoader::GetInstance();
5937 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5944 wxDateTime now = wxDateTime::Now();
5945 SendJSON_WMM_Var_Request(lat, lon, now);
5946 if (fabs(gQueryVar) < 360.0)
5947 Variance = gQueryVar;
5949 return toMagnetic(a, Variance);
5952bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5958 v[_T(
"Year")] = date.GetYear();
5959 v[_T(
"Month")] = date.GetMonth();
5960 v[_T(
"Day")] = date.GetDay();
5962 SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
5968void MyFrame::TouchAISActive(
void) {
5970 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5972 if (cc) cc->TouchAISToolActive();
5976void MyFrame::UpdateAISTool(
void) {
5977 if (!g_pAIS)
return;
5980 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5982 if (cc) cc->UpdateAISTBTool();
5987void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5989 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5991 if (cc) cc->SetbTCUpdate(
true);
5994 RefreshAllCanvas(
false);
5999void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
6003 bool b_rotate =
false;
6004 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6006 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
6010 FrameCOGTimer.Stop();
6017 int period_ms = 100;
6019 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
6022void MyFrame::DoCOGSet(
void) {
6024 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6026 if (cc) cc->DoCanvasCOGSet();
6030void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
6036 wxFont oldfont = pdc->GetFont();
6038 pdc->SetFont(*pFont);
6039 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
6040 pdc->SetBackgroundMode(wxTRANSPARENT);
6042 pdc->DrawText(str, x, y + 1);
6043 pdc->DrawText(str, x, y - 1);
6044 pdc->DrawText(str, x + 1, y);
6045 pdc->DrawText(str, x - 1, y);
6047 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
6049 pdc->DrawText(str, x, y);
6051 pdc->SetFont(oldfont);
6055void MyFrame::UpdateRotationState(
double rotation) {
6057 g_bCourseUp =
false;
6059 if (fabs(rotation) > .001) {
6060 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
6061 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
6063 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
6066 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
6067 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
6069 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
6073 UpdateGPSCompassStatusBoxes(
true);
6077void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
6079 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6081 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
6087int MyFrame::GetApplicationMemoryUse(
void) {
6093 wxWindow *fWin = wxWindow::FindFocus();
6095 wxArrayString outputArray;
6096 wxString cmd(_T(
"ps --no-headers -o vsize "));
6097 unsigned long pid = wxGetProcessId();
6099 cmd1.Printf(_T(
"%ld"), pid);
6101 wxExecute(cmd, outputArray);
6103 if (outputArray.GetCount()) {
6104 wxString s = outputArray.Item(0);
6106 if (s.ToLong(&vtmp)) memsize = vtmp;
6109 if (fWin) fWin->SetFocus();
6115 PROCESS_MEMORY_COUNTERS pmc;
6117 unsigned long processID = wxGetProcessId();
6119 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6121 if (NULL == hProcess)
return 0;
6123 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6141 memsize = pmc.WorkingSetSize / 1024;
6144 CloseHandle(hProcess);
6151double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6152 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6155void MyFrame::SetChartUpdatePeriod() {
6158 g_ChartUpdatePeriod = 0;
6163 bool bskewdc =
false;
6164 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6167 if (!g_bopengl && !cc->GetVP().b_quilt) {
6168 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6170 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6174 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6176 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6181 cc->UpdateCanvasControlBar();
6184void MyFrame::selectChartDisplay(
int type,
int family) {
6186 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6188 if (cc) cc->selectCanvasChartDisplay(type, family);
6191 UpdateGlobalMenuItems();
6200bool MyFrame::DoChartUpdate(
void) {
6201 bool return_val =
false;
6204 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6206 if (cc) return_val |= cc->DoCanvasUpdate();
6212void MyFrame::MouseEvent(wxMouseEvent &event) {
6214 event.GetPosition(&x, &y);
6219#include <mach/mach.h>
6220#include <mach/message.h>
6221#include <mach/kern_return.h>
6222#include <mach/task_info.h>
6224#include <malloc/malloc.h>
6231#if defined(__linux__)
6232#include "sys/types.h"
6233#include "sys/sysinfo.h"
6236int g_lastMemTick = -1;
6240bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6242 return androidGetMemoryStatus(mem_total, mem_used);
6245#if defined(__linux__)
6249 struct sysinfo sys_info;
6250 if (sysinfo(&sys_info) != -1)
6251 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6265 FILE *file = fopen(
"/proc/self/statm",
"r");
6267 if (fscanf(file,
"%d", mem_used) != 1) {
6268 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6281 PROCESS_MEMORY_COUNTERS pmc;
6283 unsigned long processID = wxGetProcessId();
6286 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6289 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6307 *mem_used = pmc.WorkingSetSize / 1024;
6310 CloseHandle(hProcess);
6314 MEMORYSTATUSEX statex;
6316 statex.dwLength =
sizeof(statex);
6318 GlobalMemoryStatusEx(&statex);
6336 *mem_total = statex.ullTotalPhys / 1024;
6343 if (g_tick != g_lastMemTick) {
6344 malloc_zone_pressure_relief(NULL, 0);
6347 int blocksInUse = 0;
6348 int sizeAllocated = 0;
6350 malloc_statistics_t stats;
6351 stats.blocks_in_use = 0;
6352 stats.size_in_use = 0;
6353 stats.max_size_in_use = 0;
6354 stats.size_allocated = 0;
6355 malloc_zone_statistics(NULL, &stats);
6356 bytesInUse += stats.size_in_use;
6357 blocksInUse += stats.blocks_in_use;
6358 sizeAllocated += stats.size_allocated;
6360 g_memUsed = sizeAllocated >> 10;
6363 g_lastMemTick = g_tick;
6366 if (mem_used) *mem_used = g_memUsed;
6369 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6371 double pagesUsed = 0.0, totalPages = 0.0;
6373 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6374 *mem_total = atol(buf) >> 10;
6382 if (mem_used) *mem_used = 0;
6383 if (mem_total) *mem_total = 0;
6387void MyFrame::DoPrint(
void) {
6389 g_PrintingInProgress =
true;
6392 GetPrimaryCanvas()->GetglCanvas()->Render();
6393 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6403 printer.Initialize(wxLANDSCAPE);
6404 printer.EnablePageNumbers(
false);
6405 printer.Print(
this, &printout);
6423 g_PrintingInProgress =
false;
6426 GetPrimaryCanvas()->SetFocus();
6431wxDateTime gTimeSource;
6434 wxString message_ID =
event.GetID();
6435 wxString message_JSONText =
event.GetJSONText();
6443 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6451 int numErrors = reader.
Parse(message_JSONText, &root);
6452 if (numErrors > 0) {
6458 wxString decl = root[_T(
"Decl")].
AsString();
6460 decl.ToDouble(&decl_val);
6466 if (message_ID == _T(
"WMM_VARIATION")) {
6474 int numErrors = reader.
Parse(message_JSONText, &root);
6475 if (numErrors > 0) {
6481 wxString decl = root[_T(
"Decl")].
AsString();
6483 decl.ToDouble(&decl_val);
6485 gQueryVar = decl_val;
6488 if (message_ID == _T(
"GRIB_TIMELINE")) {
6491 r.
Parse(message_JSONText, &v);
6492 if (v[_T(
"Day")].AsInt() == -1)
6493 gTimeSource = wxInvalidDateTime;
6495 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6496 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6497 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6498 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6500 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6503 wxString trk_id = wxEmptyString;
6505 int numErrors = reader.
Parse(message_JSONText, &root);
6506 if (numErrors > 0)
return;
6509 trk_id = root[_T(
"Track_ID")].
AsString();
6512 v[_T(
"Track_ID")] = trk_id;
6513 for (
Track *ptrack : g_TrackList) {
6514 wxString name = wxEmptyString;
6515 if (ptrack->m_GUID == trk_id) {
6516 name = ptrack->GetName();
6517 if (name.IsEmpty()) {
6523 name = _(
"(Unnamed Track)");
6529 v[_T(
"error")] =
false;
6530 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6531 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6533 v[_T(
"lat")] = tp->m_lat;
6534 v[_T(
"lon")] = tp->m_lon;
6535 v[_T(
"NodeNr")] = i;
6537 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6538 SendJSONMessageToAllPlugins(msg_id, v);
6542 v[_T(
"error")] =
true;
6544 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6545 SendJSONMessageToAllPlugins(msg_id, v);
6547 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6550 wxString guid = wxEmptyString;
6552 int numErrors = reader.
Parse(message_JSONText, &root);
6553 if (numErrors > 0) {
6560 v[_T(
"GUID")] = guid;
6561 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6563 wxString name = wxEmptyString;
6565 if ((*it)->m_GUID == guid) {
6566 name = (*it)->m_RouteNameString;
6567 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6569 v[_T(
"Name")] = name;
6570 v[_T(
"error")] =
false;
6573 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6574 itp != (*it)->pRoutePointList->end(); itp++) {
6575 w[i][_T(
"lat")] = (*itp)->m_lat;
6576 w[i][_T(
"lon")] = (*itp)->m_lon;
6577 w[i][_T(
"Name")] = (*itp)->GetName();
6578 w[i][_T(
"Description")] = (*itp)->GetDescription();
6579 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6580 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6581 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6586 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6588 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6589 httpLink->DescrText;
6590 node = node->GetNext();
6595 v[_T(
"waypoints")] = w;
6596 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6597 SendJSONMessageToAllPlugins(msg_id, v);
6602 v[_T(
"error")] =
true;
6604 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6605 SendJSONMessageToAllPlugins(msg_id, v);
6606 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6611 int numErrors = reader.
Parse(message_JSONText, &root);
6612 if (numErrors > 0)
return;
6615 wxString str = root[_T(
"mode")].
AsString();
6616 if (str == _T(
"Track")) route =
false;
6621 for (RouteList::iterator it = pRouteList->begin();
6622 it != pRouteList->end(); it++) {
6623 wxString name = (*it)->m_RouteNameString;
6624 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6626 v[i][_T(
"error")] =
false;
6627 v[i][_T(
"name")] = name;
6628 v[i][_T(
"GUID")] = (*it)->m_GUID;
6629 v[i][_T(
"active")] = (*it)->IsActive();
6633 for (
Track *ptrack : g_TrackList) {
6634 wxString name = ptrack->GetName();
6635 if (name.IsEmpty()) {
6641 name = _(
"(Unnamed Track)");
6643 v[i][_T(
"error")] =
false;
6644 v[i][_T(
"name")] = name;
6645 v[i][_T(
"GUID")] = ptrack->m_GUID;
6646 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6650 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6651 SendJSONMessageToAllPlugins(msg_id, v);
6654 v[0][_T(
"error")] =
true;
6655 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6656 SendJSONMessageToAllPlugins(msg_id, v);
6658 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6660 v[0][_T(
"error")] =
true;
6661 if (g_pRouteMan->GetpActiveRoute()) {
6662 if (g_pRouteMan->m_bDataValid) {
6663 v[0][_T(
"error")] =
false;
6664 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6665 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6666 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6667 v[0][_T(
"active_route_GUID")] =
6668 g_pRouteMan->GetpActiveRoute()->GetGUID();
6669 v[0][_T(
"active_waypoint_lat")] =
6671 v[0][_T(
"active_waypoint_lon")] =
6675 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6676 SendJSONMessageToAllPlugins(msg_id, v);
6680void MyFrame::FilterCogSog(
void) {
6681 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6683 double cog_last = gCog;
6686 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6687 COGFilterTable[i] = COGFilterTable[i - 1];
6688 COGFilterTable[0] = cog_last;
6691 if (!std::isnan(cog_last)) {
6693 double sum = 0., count = 0;
6694 for (
int i = 0; i < g_COGFilterSec; i++) {
6695 double adder = COGFilterTable[i];
6696 if (std::isnan(adder))
continue;
6698 if (fabs(adder - cog_last) > 180.) {
6699 if ((adder - cog_last) > 0.)
6712 else if (sum >= 360.)
6719 double sog_last = gSog;
6722 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6723 SOGFilterTable[i] = SOGFilterTable[i - 1];
6724 SOGFilterTable[0] = sog_last;
6727 if (!std::isnan(gSog)) {
6728 double sum = 0., count = 0;
6729 for (
int i = 0; i < g_SOGFilterSec; i++) {
6730 if (std::isnan(SOGFilterTable[i]))
continue;
6732 sum += SOGFilterTable[i];
6742void MyFrame::LoadHarmonics() {
6745 ptcmgr->LoadDataSources(TideCurrentDataSet);
6747 bool b_newdataset =
false;
6750 for (
auto a : ptcmgr->GetDataSet()) {
6751 bool b_foundi =
false;
6752 for (
auto b : TideCurrentDataSet) {
6759 b_newdataset =
true;
6764 for (
auto a : TideCurrentDataSet) {
6765 bool b_foundi =
false;
6766 for (
auto b : ptcmgr->GetDataSet()) {
6773 b_newdataset =
true;
6778 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6782void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6783 if (!ptarget)
return;
6786 wxDateTime mob_time = wxDateTime::Now();
6787 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6788 mob_label += _(
" on ");
6789 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6792 mob_label, wxEmptyString);
6793 pWP_MOB->SetShared(
true);
6795 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6796 pConfig->AddNewWayPoint(pWP_MOB, -1);
6797 pWP_MOB->SetUseSca(
false);
6805 wxString(_(
"Own ship")), wxEmptyString);
6806 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6807 pWP_MOB->SetUseSca(
false);
6808 pAISMOBRoute =
new Route();
6809 pRouteList->Append(pAISMOBRoute);
6811 pAISMOBRoute->AddPoint(pWP_src);
6812 pAISMOBRoute->AddPoint(pWP_MOB);
6814 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6815 pWP_src, pWP_MOB, pAISMOBRoute);
6823 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6825 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6829 v[_T(
"GUID")] = pAISMOBRoute->
m_GUID;
6830 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6831 SendJSONMessageToAllPlugins(msg_id, v);
6834 if (RouteManagerDialog::getInstanceFlag()) {
6835 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6836 pRouteManagerDialog->UpdateRouteListCtrl();
6837 pRouteManagerDialog->UpdateWptListCtrl();
6841 RefreshAllCanvas(
false);
6843 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6844 mob_message += _(
" Time: ");
6845 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6846 mob_message += _(
" Ownship Position: ");
6847 mob_message += toSDMM(1, gLat);
6848 mob_message += _T(
" ");
6849 mob_message += toSDMM(2, gLon);
6850 mob_message += _(
" MOB Position: ");
6851 mob_message += toSDMM(1, ptarget->Lat);
6852 mob_message += _T(
" ");
6853 mob_message += toSDMM(2, ptarget->Lon);
6854 wxLogMessage(mob_message);
6857void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6858 if (pAISMOBRoute && ptarget) {
6860 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6861 OwnPoint->m_lat = gLat;
6862 OwnPoint->m_lon = gLon;
6864 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6865 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6868 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6869 MOB_Point->m_lat = ptarget->Lat;
6870 MOB_Point->m_lon = ptarget->Lon;
6872 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6873 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6875 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6876 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6879 RefreshAllCanvas(
false);
6882 wxDateTime mob_time = wxDateTime::Now();
6884 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6885 mob_message += _(
" Time: ");
6886 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6887 mob_message += _(
" Ownship Position: ");
6888 mob_message += toSDMM(1, gLat);
6889 mob_message += _T(
" ");
6890 mob_message += toSDMM(2, gLon);
6891 mob_message += _(
" MOB Position: ");
6892 mob_message += toSDMM(1, ptarget->Lat);
6893 mob_message += _T(
" ");
6894 mob_message += toSDMM(2, ptarget->Lon);
6896 wxLogMessage(mob_message);
6900void MyFrame::applySettingsString(wxString settings) {
6902 int last_UIScaleFactor = g_GUIScaleFactor;
6903 bool previous_expert = g_bUIexpert;
6904 g_last_ChartScaleFactor = g_ChartScaleFactor;
6905 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6908 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6911 pConfig->UpdateSettings();
6914 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6916 if (rr & S52_CHANGED) {
6918 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6920 ->ClearCNSYLUPArray();
6921 ps52plib->GenerateStateHash();
6925 ProcessOptionsDialog(rr, pNewDirArray);
6930 bool b_newToolbar =
false;
6932 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6934 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6936 if (rr & TOOLBAR_CHANGED) {
6937 b_newToolbar =
true;
6942 if (previous_expert && !g_bUIexpert) {
6943 androidForceFullRepaint();
6947 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6951 SetGPSCompassScale();
6953 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6955 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6957 UpdateGPSCompassStatusBoxes(
true);
6960 AbstractPlatform::ShowBusySpinner();
6962 SetAllToolbarScale();
6966 AbstractPlatform::HideBusySpinner();
6968 RequestNewMasterToolbar(
true);
6975 UpdateControlBar(GetPrimaryCanvas());
6978 if (console) console->Raise();
6981 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6984#ifdef wxHAS_POWER_EVENTS
6985void MyFrame::OnSuspending(wxPowerEvent &event) {
6989 wxLogMessage(_T(
"System suspend starting..."));
6992void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6995 wxLogMessage(_T(
"System is going to suspend."));
6998void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
7001 wxLogMessage(_T(
"System suspend was cancelled."));
7004int g_last_resume_ticks;
7005void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
7006 wxDateTime now = wxDateTime::Now();
7007 wxLogMessage(_T(
"System resumed from suspend."));
7009 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
7012 wxLogMessage(
"Restarting streams.");
7013 g_last_resume_ticks = now.GetTicks();
7017 g_pMUX->ClearStreams();
7019 g_pMUX->StartAllStreams();
7028 if (IsMaximized()) {
7033 wxSize sz = GetSize();
7034 SetSize(wxSize(sz.x - 1, sz.y));
7046void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
7047 bool btbRebuild =
false;
7049 bool b_reshow =
true;
7050 if (g_MainToolbar) {
7052 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
7053 if ((ff > 0.01f) || bforcenew) {
7054 g_MainToolbar->DestroyToolBar();
7055 delete g_MainToolbar;
7056 g_MainToolbar = NULL;
7062 if (!g_MainToolbar) {
7063 long orient = g_Platform->GetDefaultToolbarOrientation();
7064 wxWindow *toolbarParent =
this;
7066 toolbarParent = GetPrimaryCanvas();
7069 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
7070 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
7071 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
7072 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
7073 g_MainToolbar->EnableRolloverBitmaps(
false);
7075 g_MainToolbar->CreateConfigMenu();
7076 g_MainToolbar->SetDefaultPosition();
7078 g_bmasterToolbarFull =
true;
7081 if (g_MainToolbar) {
7082 CreateMasterToolbar();
7086 g_MainToolbar->SetColorScheme(global_color_scheme);
7092 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7093 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7097bool MyFrame::CollapseGlobalToolbar() {
7098 if (g_MainToolbar) {
7099 m_nMasterToolCountShown = 1;
7100 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7101 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7102 g_MainToolbar->Realize();
7103 g_bmasterToolbarFull =
false;
7112 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7119 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7120 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7121 tic->m_bRequired =
true;
7123 g_MainToolbar->AddToolItem(tic);
7126 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7127 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7128 g_MainToolbar->AddToolItem(tic);
7131 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7132 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7133 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7135 g_MainToolbar->AddToolItem(tic);
7138 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7139 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7140 g_MainToolbar->AddToolItem(tic);
7143 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7144 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7145 _(
"Enable Tracking"), _T(
"MUI_track"));
7146 g_MainToolbar->AddToolItem(tic);
7149 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7150 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7151 g_MainToolbar->AddToolItem(tic);
7162 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7163 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7164 g_MainToolbar->AddToolItem(tic);
7167 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7168 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7169 g_MainToolbar->AddToolItem(tic);
7172 AddDefaultPositionPlugInTools();
7176 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7177 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7178 g_MainToolbar->AddToolItem(tic);
7181 g_MainToolbar->RebuildToolbar();
7185 g_MainToolbar->Realize();
7188 ArrayOfPlugInToolbarTools tool_array =
7189 g_pi_manager->GetPluginToolbarToolArray();
7190 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7192 if (!pttc->b_viz)
continue;
7194 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7197 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7198 if (g_bTrackActive) {
7199 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7201 g_MainToolbar->Realize();
7206bool MyFrame::CheckAndAddPlugInTool() {
7207 if (!g_pi_manager)
return false;
7212 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7214 if (!tb)
return false;
7216 int n_tools = tb->GetToolsCount();
7220 ArrayOfPlugInToolbarTools tool_array =
7221 g_pi_manager->GetPluginToolbarToolArray();
7223 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7225 if (pttc->position == n_tools) {
7226 wxBitmap *ptool_bmp;
7228 switch (global_color_scheme) {
7229 case GLOBAL_COLOR_SCHEME_DAY:
7230 ptool_bmp = pttc->bitmap_day;
7233 case GLOBAL_COLOR_SCHEME_DUSK:
7234 ptool_bmp = pttc->bitmap_dusk;
7236 case GLOBAL_COLOR_SCHEME_NIGHT:
7237 ptool_bmp = pttc->bitmap_night;
7240 ptool_bmp = pttc->bitmap_day;
7245 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7247 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7248 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7249 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7250 tic->m_bPlugin =
true;
7259 while (CheckAndAddPlugInTool()) {
7265bool MyFrame::AddDefaultPositionPlugInTools() {
7266 if (!g_pi_manager)
return false;
7272 ArrayOfPlugInToolbarTools tool_array =
7273 g_pi_manager->GetPluginToolbarToolArray();
7275 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7279 if (!pttc->b_viz)
continue;
7281 if (pttc->position == -1)
7283 wxBitmap *ptool_bmp;
7285 switch (global_color_scheme) {
7286 case GLOBAL_COLOR_SCHEME_DAY:
7287 ptool_bmp = pttc->bitmap_day;
7289 case GLOBAL_COLOR_SCHEME_DUSK:
7290 ptool_bmp = pttc->bitmap_dusk;
7292 case GLOBAL_COLOR_SCHEME_NIGHT:
7293 ptool_bmp = pttc->bitmap_night;
7296 ptool_bmp = pttc->bitmap_day;
7301 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7303 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7304 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7305 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7306 tic->m_bPlugin =
true;
7308 g_MainToolbar->AddToolItem(tic);
7321wxColour GetGlobalColor(wxString colorName);
7323static const char *usercolors[] = {
7324 "Table:DAY",
"GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
7325 "GREEN3;200;220;200;",
"GREEN4; 0;255; 0;",
"BLUE1; 170;170;255;",
7326 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7327 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"UBLCK; 0; 0; 0;",
7328 "UWHIT; 255;255;255;",
"URED; 255; 0; 0;",
"UGREN; 0;255; 0;",
7329 "YELO1; 243;229; 47;",
"YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7330 "GREEN5;170;254; 0;",
"COMPT; 245;247;244",
7332 "DILG0; 255;255;255;",
7334 "DILG0; 238;239;242;",
7336 "DILG1; 212;208;200;",
7337 "DILG2; 255;255;255;",
7341 "CHGRF; 163; 180; 183;",
"UINFM; 197; 69; 195;",
"UINFG; 104; 228; 86;",
7342 "UINFF; 125; 137; 140;",
"UINFR; 241; 84; 105;",
"SHIPS; 7; 7; 7;",
7343 "CHYLW; 244; 218; 72;",
"CHWHT; 212; 234; 238;",
7345 "UDKRD; 124; 16; 0;",
7346 "UARTE; 200; 0; 0;",
7348 "NODTA; 163; 180; 183;",
"CHBLK; 7; 7; 7;",
"SNDG1; 125; 137; 140;",
7349 "SNDG2; 7; 7; 7;",
"SCLBR; 235; 125; 54;",
"UIBDR; 125; 137; 140;",
7350 "UINFB; 58; 120; 240;",
"UINFD; 7; 7; 7;",
"UINFO; 235; 125; 54;",
7351 "PLRTE; 220; 64; 37;",
"CHMGD; 197; 69; 195;",
"UIBCK; 212; 234; 238;",
7353 "DASHB; 255;255;255;",
7354 "DASHL; 175;175;175;",
7355 "DASHF; 50; 50; 50;",
7356 "DASHR; 200; 0; 0;",
7358 "DASHN; 200;120; 0;",
7359 "DASH1; 204;204;255;",
7360 "DASH2; 122;131;172;",
7361 "COMP1; 211;211;211;",
7363 "GREY3; 40; 40; 40;",
7364 "BLUE4; 100;100;200;",
7365 "VIO01; 171; 33;141;",
"VIO02; 209;115;213;",
7366 "BLUEBACK; 212;234;238;",
7367 "LANDBACK; 201;185;122;",
7370 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7371 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7372 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7373 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7374 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7375 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7376 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7378 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7379 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7380 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7382 "DILG0; 110;110;110;",
7383 "DILG1; 110;110;110;",
7385 "DILG3; 130;130;130;",
7386 "UITX1; 41; 46; 46;",
7388 "UARTE; 64; 64; 64;",
7390 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7391 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7392 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7393 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7395 "DASHB; 77; 77; 77;",
7396 "DASHL; 54; 54; 54;",
7398 "DASHR; 58; 21; 21;",
7399 "DASHG; 21; 58; 21;",
7400 "DASHN; 100; 50; 0;",
7401 "DASH1; 76; 76;113;",
7402 "DASH2; 48; 52; 72;",
7403 "COMP1; 107;107;107;",
7405 "GREY3; 20; 20; 20;",
7406 "BLUE4; 80; 80;160;",
7407 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7408 "LANDBACK; 201;185;122;",
7410 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7411 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7412 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7413 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7414 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7415 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7416 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7417 "DILG0; 80; 80; 80;",
7418 "DILG1; 80; 80; 80;",
7420 "DILG3; 65; 65; 65;",
7421 "UITX1; 31; 34; 35;",
7423 "UARTE; 64; 64; 64;",
7425 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7426 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7427 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7429 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7430 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7431 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7432 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7435 "DASHL; 20; 20; 20;",
7436 "DASHF; 64; 64; 64;",
7437 "DASHR; 70; 15; 15;",
7438 "DASHG; 15; 70; 15;",
7439 "DASHN; 17; 80; 56;",
7440 "DASH1; 48; 52; 72;",
7441 "DASH2; 36; 36; 53;",
7442 "COMP1; 24; 24; 24;",
7444 "GREY3; 10; 10; 10;",
7445 "BLUE4; 70; 70;140;",
7446 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7447 "LANDBACK; 201;185;122;",
7451int get_static_line(
char *d,
const char **p,
int index,
int n) {
7452 if (!strcmp(p[index],
"*****"))
return 0;
7454 strncpy(d, p[index], n);
7458void InitializeUserColors(
void) {
7459 const char **p = usercolors;
7467 UserColorTableArray =
new wxArrayPtrVoid;
7468 UserColourHashTableArray =
new wxArrayPtrVoid;
7472 ct->tableName =
new wxString(_T(
"DAY"));
7473 ct->color =
new wxArrayPtrVoid;
7474 UserColorTableArray->Add((
void *)ct);
7477 ct->tableName =
new wxString(_T(
"DUSK"));
7478 ct->color =
new wxArrayPtrVoid;
7479 UserColorTableArray->Add((
void *)ct);
7482 ct->tableName =
new wxString(_T(
"NIGHT"));
7483 ct->color =
new wxArrayPtrVoid;
7484 UserColorTableArray->Add((
void *)ct);
7486 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7487 if (!strncmp(buf,
"Table", 5)) {
7488 sscanf(buf,
"Table:%s", TableName);
7490 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7491 ctp = (colTable *)(UserColorTableArray->Item(it));
7492 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7501 while (buf[j] !=
';' && j < 20) {
7507 S52color *c =
new S52color;
7508 strcpy(c->colName, name);
7510 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7523 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7524 wxColorHashMap *phash =
new wxColorHashMap;
7525 UserColourHashTableArray->Add((
void *)phash);
7527 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7529 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7530 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7532 wxColour c(c2->R, c2->G, c2->B);
7533 wxString key(c2->colName, wxConvUTF8);
7540 pcurrent_user_color_hash =
7541 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7544void DeInitializeUserColors(
void) {
7545 if (!UserColorTableArray)
return;
7546 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7547 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7549 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7550 S52color *c = (S52color *)ct->color->Item(j);
7554 delete ct->tableName;
7560 delete UserColorTableArray;
7562 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7563 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7567 delete UserColourHashTableArray;
7574typedef struct _MSW_COLOR_SPEC {
7576 wxString S52_RGB_COLOR;
7580MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7581 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7582 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7585void SaveSystemColors() {
7599 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7600 while (pcspec->COLOR_NAME != -1) {
7601 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7606void RestoreSystemColors() {
7607 int element[NCOLORS];
7608 int rgbcolor[NCOLORS];
7611 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7612 while (pcspec->COLOR_NAME != -1) {
7613 element[i] = pcspec->COLOR_NAME;
7614 rgbcolor[i] = pcspec->SysRGB_COLOR;
7620 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7625void SetSystemColors(ColorScheme cs) {
7627 int element[NCOLORS];
7628 int rgbcolor[NCOLORS];
7630 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7631 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7632 while (pcspec->COLOR_NAME != -1) {
7633 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7634 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7635 element[i] = pcspec->COLOR_NAME;
7641 pSetSysColors(i, (
unsigned long *)&element[0],
7642 (
unsigned long *)&rgbcolor[0]);
7646 RestoreSystemColors();
7651wxColor GetDimColor(wxColor c) {
7652 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7653 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7657 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7658 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7660 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7661 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7662 hsv.value = hsv.value * factor;
7663 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7665 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7671double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7672 double const AnchorPointMaxDist)
7675 if (d < AnchorPointMinDist)
7676 return AnchorPointMinDist;
7677 else if (d > AnchorPointMaxDist)
7678 return AnchorPointMaxDist;
7684 if (d > -AnchorPointMinDist)
7685 return -AnchorPointMinDist;
7686 else if (d < -AnchorPointMaxDist)
7687 return -AnchorPointMaxDist;
7694static const WORD MAX_CONSOLE_LINES =
7699void RedirectIOToConsole()
7704 wxIntPtr lStdHandle;
7706 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7716 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7717 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7718 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7722 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7723 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7724 fp = _fdopen(hConHandle,
"w");
7726 setvbuf(stdout, NULL, _IONBF, 0);
7730 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7731 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7732 fp = _fdopen(hConHandle,
"r");
7734 setvbuf(stdin, NULL, _IONBF, 0);
7738 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7739 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7740 fp = _fdopen(hConHandle,
"w");
7742 setvbuf(stderr, NULL, _IONBF, 0);
7754bool TestGLCanvas(wxString prog_dir) {
7756 wxString test_app = prog_dir;
7757 test_app += _T(
"ocpn_gltest1.exe");
7759 if (::wxFileExists(test_app)) {
7760 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7761 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7762 if (proc_return == 0)
7763 printf(
"GLCanvas OK\n");
7765 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7767 return (proc_return == 0);
7777bool ReloadLocale() {
7782 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7789 FontMgr::Get().SetLocale(g_locale);
7797 if (pRoutePropDialog) {
7798 pRoutePropDialog->Hide();
7799 pRoutePropDialog->Destroy();
7800 pRoutePropDialog = NULL;
7803 if (pRouteManagerDialog) {
7804 pRouteManagerDialog->Hide();
7805 pRouteManagerDialog->Destroy();
7806 pRouteManagerDialog = NULL;
7809 if (console) console->SetColorScheme(global_color_scheme);
7810 if (g_pais_query_dialog_active) {
7811 g_pais_query_dialog_active->Destroy();
7812 g_pais_query_dialog_active = NULL;
7815 auto alert_dlg_active =
7817 if (alert_dlg_active) {
7818 alert_dlg_active->Destroy();
7819 g_pais_alert_dialog_active =
nullptr;
7822 if (g_pAISTargetList) {
7823 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
7824 g_pAISTargetList->Disconnect_decoder();
7825 g_pAISTargetList->Destroy();
7826 g_pAISTargetList = NULL;
7830 if (gFrame->m_pMenuBar) {
7831 gFrame->SetMenuBar(NULL);
7832 gFrame->m_pMenuBar->Destroy();
7833 gFrame->m_pMenuBar = NULL;
7835 gFrame->BuildMenuBar();
7838 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7840 if (cc) cc->CanvasApplyLocale();
7845 wxString perspective;
7846 pConfig->SetPath(_T (
"/AUI" ));
7847 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
7852 PluginLoader::GetInstance()->DeactivateAllPlugIns();
7853 PluginLoader::GetInstance()->UpdatePlugIns();
7861 bool bno_load =
false;
7862 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
7864 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7865 wxAuiPaneInfo pane = pane_array_val[i];
7866 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7872 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
7874 g_pauimgr->Update();
7877 gFrame->RequestNewToolbars(
true);
7878 gFrame->RequestNewMasterToolbar(
true);
7882extern s57RegistrarMgr *m_pRegistrarMan;
7883extern wxString g_UserPresLibData;
7884extern wxString g_SENCPrefix;
7885extern wxString g_csv_locn;
7901 g_csv_locn = g_Platform->GetSharedDataDir();
7902 g_csv_locn.Append(_T(
"s57data"));
7905 g_csv_locn = _T(
".");
7906 appendOSDirSlash(&g_csv_locn);
7907 g_csv_locn.Append(_T(
"s57data"));
7912 if (g_SENCPrefix.IsEmpty()) {
7914 appendOSDirSlash(&g_SENCPrefix);
7915 g_SENCPrefix.Append(_T(
"SENC"));
7919 wxFileName f(g_SENCPrefix);
7921 g_SENCPrefix = f.GetFullPath();
7923 g_SENCPrefix = _T(
"SENC");
7929 bool b_force_legacy =
false;
7931 if (g_UserPresLibData.IsEmpty()) {
7932 plib_data = g_csv_locn;
7933 appendOSDirSlash(&plib_data);
7934 plib_data.Append(_T(
"S52RAZDS.RLE"));
7936 plib_data = g_UserPresLibData;
7937 b_force_legacy =
true;
7940 ps52plib =
new s52plib(plib_data, b_force_legacy);
7955 if (!ps52plib->m_bOK) {
7958 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7960 wxString look_data_dir;
7961 look_data_dir.Append(std_path.GetUserDataDir());
7962 appendOSDirSlash(&look_data_dir);
7963 wxString tentative_SData_Locn = look_data_dir;
7964 look_data_dir.Append(_T(
"s57data"));
7966 plib_data = look_data_dir;
7967 appendOSDirSlash(&plib_data);
7968 plib_data.Append(_T(
"S52RAZDS.RLE"));
7970 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7971 ps52plib =
new s52plib(plib_data);
7973 if (ps52plib->m_bOK) {
7974 g_csv_locn = look_data_dir;
7983 if (!ps52plib->m_bOK) {
7986 wxString look_data_dir;
7987 look_data_dir = g_Platform->GetSharedDataDir();
7988 look_data_dir.Append(_T(
"s57data"));
7990 plib_data = look_data_dir;
7991 appendOSDirSlash(&plib_data);
7992 plib_data.Append(_T(
"S52RAZDS.RLE"));
7994 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
7995 ps52plib =
new s52plib(plib_data);
7997 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
8000 if (ps52plib->m_bOK) {
8001 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
8003 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
8008 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
8010 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
8011 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
8012 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
8013 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
8016 pConfig->LoadS57Config();
8017 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
8020 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
8021 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
8023 ps52plib->SetDIPFactor(dip_factor);
8028 ps52plib->SetScaleFactorExp(
8029 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
8030 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
8035 extern bool g_b_EnableVBO;
8036 extern GLenum g_texture_rectangle_format;
8041 wxString renderer = wxString(GL_Caps->Renderer.c_str());
8042 ps52plib->SetGLRendererString(renderer);
8045 ps52plib->SetGLOptions(
8046 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
8047 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
8048 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
8054 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
8063 : wxThread(wxTHREAD_JOINABLE) {
8064 m_filename = filename;
8075 newChart->SetNativeScale(m_scale);
8076 newChart->SetFullExtent(m_ext);
8078 newChart->FindOrCreateSenc(m_filename);
8083 wxString m_filename;
8089static double chart_dist(
int index) {
8095 if (cte.GetBBox().Contains(gLat, gLon))
8100 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8101 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8102 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8105 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8106 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8108 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8114WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8115static int CompareInts(
int n1,
int n2) {
8116 double d1 = chart_dist(n1);
8117 double d2 = chart_dist(n2);
8118 return (
int)(d1 - d2);
8123 wxString chart_path;
8128WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8130#include <wx/arrimpl.cpp>
8133void ParseAllENC(wxWindow *parent) {
8134 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8142 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8145 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8147 idx_sorted_by_distance.Add(i);
8151 if (count == 0)
return;
8153 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8159 ArrayOfCompressTargets ct_array;
8160 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8161 int i = idx_sorted_by_distance[j];
8164 double distance = chart_dist(i);
8166 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8169 pct->distance = distance;
8170 pct->chart_path = filename;
8172 ct_array.push_back(pct);
8175 int thread_count = 0;
8178 extern int g_nCPUCount;
8179 if (g_nCPUCount > 0)
8180 thread_count = g_nCPUCount;
8182 thread_count = wxThread::GetCPUCount();
8184 if (thread_count < 1) {
8193 for(
int t = 0; t < thread_count; t++)
8197 wxGenericProgressDialog *prog =
nullptr;
8201 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8202 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8204 prog =
new wxGenericProgressDialog();
8206 prog->SetFont(*qFont);
8208 prog->Create(_(
"OpenCPN ENC Prepare"),
8209 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8219 prog->ShowWindowModal();
8228 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8229 wxString filename = ct_array[j].chart_path;
8230 double distance = ct_array[j].distance;
8231 int index = ChartData->FinddbIndex(filename);
8232 if (index < 0)
continue;
8235 ext.NLAT = cte.GetLatMax();
8236 ext.SLAT = cte.GetLatMin();
8237 ext.WLON = cte.GetLonMin();
8238 ext.ELON = cte.GetLonMax();
8240 int scale = cte.GetScale();
8243 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8246 if (wxThread::IsMain()) {
8248 wxSize sz = prog->GetSize();
8250 msg += _T(
" Chart:");
8253 prog->Update(count, msg, &skip);
8265 newChart->SetNativeScale(
scale);
8266 newChart->SetFullExtent(ext);
8267 newChart->DisableBackgroundSENC();
8269 newChart->FindOrCreateSenc(filename,
8273 if (wxThread::IsMain()) {
8274 msg.Printf(_(
"ENC Completed."));
8276 prog->Update(count, msg, &skip);
8286 for (
int t = 0;; t = (t + 1) % thread_count) {
8293 if (!workers[t]->IsAlive()) {
8306#if defined(__WXMSW__) || defined(__WXOSX__)
8313 for(
int t = 0; t<thread_count; t++) {
Global state for AIS decoder.
Dialog for displaying AIS target alerts.
Dialog for displaying a list of AIS targets.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
A modal message dialog with confirmation button and cancel button.
Dialog for managing CM93 chart offsets.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void DoZoomCanvas(double factor, bool can_zoom_to_cursor=true)
Internal function that implements the actual zoom operation.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Set the viewport center point.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OperGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Primary navigation console display for route and vessel tracking.
Overall logging handler, outputs to screen and log file.
virtual bool IsVisible() const override
Return true if log is visible i.
const void Notify()
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Represents a layer of chart objects in OpenCPN.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
virtual bool IsVisible() const =0
Return true if log is visible i.
virtual void Add(const Logline &l)=0
Add an formatted string to log output.
void Init(const KeyProvider &kp, std::function< void(ObservedEvt &ev)> action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
Global variables reflecting command line options and arguments.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
New NMEA Debugger successor main window.
Hooks into gui available in model.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
Class NotificationManager.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse(void)
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.