32 #include <wx/wxprec.h>
51 #include <X11/Xatom.h>
55 #include <wx/stdpaths.h>
56 #include <wx/tokenzr.h>
57 #include <wx/display.h>
59 #include "model/ais_decoder.h"
61 #include "model/ais_target_data.h"
63 #include "model/comm_drv_factory.h"
64 #include "model/comm_drv_registry.h"
65 #include "model/comm_n0183_output.h"
66 #include "model/comm_navmsg_bus.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"
74 #include "model/logger.h"
75 #include "model/multiplexer.h"
76 #include "model/nav_object_database.h"
77 #include "model/navutil_base.h"
78 #include "model/own_ship.h"
79 #include "model/plugin_loader.h"
80 #include "model/routeman.h"
81 #include "model/select.h"
82 #include "model/sys_events.h"
83 #include "model/track.h"
85 #include "AboutFrameImpl.h"
88 #include "ais_info_gui.h"
89 #include "AISTargetAlertDialog.h"
90 #include "AISTargetListDialog.h"
91 #include "AISTargetQueryDialog.h"
92 #include "CanvasConfig.h"
93 #include "chartbase.h"
94 #include "chart_ctx_factory.h"
98 #include "color_handler.h"
101 #include "ConfigMgr.h"
102 #include "displays.h"
105 #include "glChartCanvas.h"
106 #include "GoToPositionDialog.h"
108 #include "iENCToolbar.h"
111 #include "MarkInfo.h"
113 #include "N2KParser.h"
115 #include "NMEALogWindow.h"
116 #include "ocpn_app.h"
117 #include "OCPN_AUIManager.h"
118 #include "ocpn_frame.h"
119 #include "OCPNPlatform.h"
120 #include "OCPN_Sound.h"
122 #include "pluginmanager.h"
123 #include "routemanagerdialog.h"
124 #include "routeman_gui.h"
125 #include "route_point_gui.h"
126 #include "RoutePropDlgImpl.h"
128 #include "s57chart.h"
129 #include "S57QueryDialog.h"
130 #include "SystemCmdSound.h"
134 #include "TrackPropDlg.h"
135 #include "waypointman_gui.h"
136 #include "CanvasOptions.h"
140 #include "androidUTIL.h"
146 WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
154 extern arrayofCanvasPtr g_canvasArray;
167 extern about *g_pAboutDlgLegacy;
170 extern double vLat, vLon;
171 extern wxString g_locale;
172 extern ColorScheme global_color_scheme;
177 GLenum g_texture_rectangle_format;
180 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
181 extern wxLocale *plocale_def_lang;
188 extern s52plib *ps52plib;
192 extern bool g_b_legacy_input_filter_behaviour;
193 extern bool g_bTrackActive;
195 extern bool g_bmasterToolbarFull;
196 extern int g_nAutoHideToolbar;
197 extern bool g_bAutoHideToolbar;
198 extern bool g_bshowToolbar;
199 extern int g_maintoolbar_x;
200 extern int g_maintoolbar_y;
201 extern wxString g_toolbarConfig;
202 extern float g_toolbar_scalefactor;
203 extern float g_compass_scalefactor;
204 extern bool g_bShowMenuBar;
205 extern bool g_bShowCompassWin;
207 extern bool g_benable_rotate;
208 extern int g_GUIScaleFactor;
209 extern int g_ChartScaleFactor;
210 extern int g_last_ChartScaleFactor;
211 extern int g_ShipScaleFactor;
212 extern float g_ShipScaleFactorExp;
213 extern int g_ENCTextScaleFactor;
215 extern bool g_bShowTide;
216 extern bool g_bShowCurrent;
217 extern bool g_bUIexpert;
218 extern RouteList *pRouteList;
219 extern wxString g_default_wp_icon;
220 extern std::vector<std::string> TideCurrentDataSet;
221 extern wxString g_TCData_Dir;
222 extern TCMgr *ptcmgr;
223 extern char nmea_tick_chars[];
224 extern double AnchorPointMinDist;
225 extern bool AnchorAlertOn1, AnchorAlertOn2;
226 extern wxString g_AW1GUID;
227 extern wxString g_AW2GUID;
228 extern bool g_bCruising;
229 extern double g_COGAvg;
230 extern int g_COGAvgSec;
232 extern std::vector<Track *> g_TrackList;
233 extern double gQueryVar;
234 extern wxPrintData *g_printData;
235 extern wxPageSetupData *g_pageSetupData;
236 extern int g_ChartUpdatePeriod;
237 extern int g_SkewCompUpdatePeriod;
238 extern bool g_bCourseUp;
239 extern bool g_bLookAhead;
240 extern bool g_bskew_comp;
241 extern bool g_bPauseTest;
242 extern bool g_bSleep;
243 extern bool g_bPlayShipsBells;
244 extern wxDateTime g_loglast_time;
245 extern int g_nAWDefault;
247 extern bool g_bDeferredStartTrack;
248 extern bool bDBUpdateInProgress;
252 extern bool g_boptionsactive;
253 extern bool g_bDeferredInitDone;
254 extern int options_lastPage;
255 extern int options_subpage;
256 extern bool b_reloadForPlugins;
258 extern int g_NeedDBUpdate;
259 extern bool g_bFullscreen;
260 extern wxString gWorldMapLocation, gDefaultWorldMapLocation;
261 extern ChartGroupArray *g_pGroupArray;
262 extern bool g_bEnableZoomToCursor;
263 extern double g_display_size_mm;
264 extern std::vector<size_t> g_config_display_size_mm;
265 extern wxString ChartListFileName;
266 extern bool g_bFullscreenToolbar;
267 extern arrayofCanvasPtr g_canvasArray;
268 extern wxString g_lastAppliedTemplateGUID;
269 extern wxPoint options_lastWindowPos;
270 extern wxSize options_lastWindowSize;
271 extern unsigned int g_canvasConfig;
272 extern bool g_bFullScreenQuilt;
273 extern bool g_bQuiltEnable;
274 extern wxString *pInit_Chart_Dir;
275 extern bool g_bShowOutlines;
276 extern bool g_bTempShowMenuBar;
277 extern bool g_bShowStatusBar;
278 extern bool g_FlushNavobjChanges;
279 extern int g_FlushNavobjChangesTimeout;
280 extern bool g_bShowChartBar;
281 extern double g_plus_minus_zoom_factor;
282 extern int g_nframewin_x;
283 extern int g_nframewin_y;
284 extern int g_nframewin_posx;
285 extern int g_nframewin_posy;
286 extern bool g_bframemax;
287 extern LayerList *pLayerList;
288 extern bool g_bAutoAnchorMark;
289 extern wxDateTime g_start_time;
290 extern bool g_bcompression_wait;
291 extern bool g_bquiting;
292 extern bool b_inCloseWindow;
293 extern bool b_inCompressAllCharts;
294 extern long g_maintoolbar_orient;
295 extern wxAuiDefaultDockArt *g_pauidockart;
296 extern int g_click_stop;
297 extern wxString g_CmdSoundString;
298 extern std::vector<OcpnSound *> bells_sound;
299 extern char bells_sound_file_name[2][12];
300 extern int g_sticky_chart;
301 extern int g_sticky_projection;
302 extern wxArrayPtrVoid *UserColourHashTableArray;
303 extern wxColorHashMap *pcurrent_user_color_hash;
306 extern bool g_bfilter_cogsog;
307 extern int g_COGFilterSec;
308 extern int g_SOGFilterSec;
309 extern bool g_own_ship_sog_cog_calc;
310 extern int g_own_ship_sog_cog_calc_damp_sec;
311 extern bool g_bHasHwClock;
312 extern bool s_bSetSystemTime;
313 extern bool bVelocityValid;
314 extern int gHDx_Watchdog;
317 extern bool g_bUseGLL;
318 extern int g_MemFootMB;
320 extern int g_memUsed;
321 extern int g_chart_zoom_modifier_vector;
322 extern bool g_config_display_size_manual;
323 extern bool g_PrintingInProgress;
328 typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
329 typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
331 SetSysColors_t pSetSysColors;
332 GetSysColor_t pGetSysColor;
334 void SaveSystemColors(
void);
335 void RestoreSystemColors(
void);
338 DWORD color_3dhilite;
339 DWORD color_3dshadow;
340 DWORD color_3ddkshadow;
342 DWORD color_activecaption;
343 DWORD color_gradientactivecaption;
344 DWORD color_captiontext;
345 DWORD color_windowframe;
346 DWORD color_inactiveborder;
352 #define _CRTDBG_MAP_ALLOC
355 #define DEBUG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
356 #define new DEBUG_NEW
360 static const long long lNaN = 0xfff8000000000000;
361 #define NAN (*(double *)&lNaN)
364 static wxArrayPtrVoid *UserColorTableArray = 0;
367 void appendOSDirSlash(wxString *pString);
369 void InitializeUserColors(
void);
370 void DeInitializeUserColors(
void);
371 void SetSystemColors(ColorScheme cs);
373 static bool LoadAllPlugIns(
bool load_enabled) {
374 AbstractPlatform::ShowBusySpinner();
375 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled);
376 AbstractPlatform::HideBusySpinner();
384 #if defined(__WXGTK__) || defined(__WXQT__)
385 #include "bitmaps/opencpn.xpm"
400 int g_iENCToolbarPosX;
401 int g_iENCToolbarPosY;
403 void BuildiENCToolbar(
bool bnew) {
404 if (g_bInlandEcdis) {
407 wxPoint locn = g_iENCToolbar->GetToolbarPosition();
408 wxPoint tbp_incanvas = locn;
410 g_iENCToolbarPosY = tbp_incanvas.y;
411 g_iENCToolbarPosX = tbp_incanvas.x;
413 delete g_iENCToolbar;
418 if (!g_iENCToolbar) {
419 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
423 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
424 (g_iENCToolbarPosY < g_maintoolbar_y + g_MainToolbar->GetToolSize().y))
425 g_iENCToolbarPosY = -1;
428 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
433 posn = wxPoint(g_maintoolbar_x + g_MainToolbar->GetToolbarSize().x + 4,
437 double tool_scale_factor =
438 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
441 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
442 g_iENCToolbar->SetColorScheme(global_color_scheme);
443 g_iENCToolbar->EnableSubmerge(
false);
446 delete g_iENCToolbar;
447 g_iENCToolbar = NULL;
451 int ShowNavWarning() {
454 OpenCPN is distributed in the hope that it will be useful, \
455 but WITHOUT ANY WARRANTY; without even the implied \
456 warranty of MERCHANTABILITY or FITNESS FOR A \
457 PARTICULAR PURPOSE.\n\n\
458 See the GNU General Public License for more details.\n\n\
459 OpenCPN must only be used in conjunction with approved \
460 paper charts and traditional methods of navigation.\n\n\
461 DO NOT rely upon OpenCPN for safety of life or property.\n\n\
462 Please click \"OK\" to agree and proceed, \"Cancel\" to quit.\n"));
464 wxString vs = wxString::Format(wxT(
" .. Version %s"), VERSION_FULL);
467 androidShowDisclaimer(_(
"OpenCPN for Android") + vs, msg0);
470 wxColor fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
472 msg1.Printf(_T(
"<html><body><font color=#%02x%02x%02x><hr />"), fg.Red(),
473 fg.Green(), fg.Blue());
475 for (
unsigned int i = 0; i < msg0.Length(); i++) {
482 msg1 << _T(
"<hr /></font></body></html>");
485 gFrame, msg1, _(
"Welcome to OpenCPN") + vs, -1, wxCANCEL | wxOK);
489 return (infoDlg.GetReturnCode());
494 if (chart ==
nullptr)
return false;
497 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
499 if (cc && cc->m_singleChart == chart) {
506 #if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
509 static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
510 const char *prop_name) {
514 unsigned long ret_nitems;
515 unsigned long ret_bytes_after;
516 unsigned char *ret_prop;
518 xa_prop_name = XInternAtom(disp, prop_name, False);
526 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
527 &xa_ret_type, &ret_format, &ret_nitems,
528 &ret_bytes_after, &ret_prop) != Success)
531 if (xa_ret_type != xa_prop_type) {
535 return (
char *)ret_prop;
540 static bool isTransparentToolbarInOpenGLOK(
void) {
547 if (!g_bdisable_opengl) {
548 Display *disp = XOpenDisplay(NULL);
550 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
552 "_NET_SUPPORTING_WM_CHECK")) ||
553 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
555 "_WIN_SUPPORTING_WM_CHECK"))) {
558 if ((wm_name = get_X11_property(disp, *sup_window,
559 XInternAtom(disp,
"UTF8_STRING", False),
561 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
564 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
587 BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
588 EVT_CLOSE(MyFrame::OnCloseWindow)
589 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
590 EVT_SIZE(MyFrame::OnSize)
591 EVT_MOVE(MyFrame::OnMove)
592 EVT_ICONIZE(MyFrame::OnIconize)
593 EVT_MENU(-1, MyFrame::OnToolLeftClick)
594 EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
596 EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
597 EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
598 EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
599 EVT_MAXIMIZE(MyFrame::OnMaximize)
600 EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
601 MyFrame::RequestNewToolbarArgEvent)
602 EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
604 EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
605 EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
606 EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
608 #ifdef wxHAS_POWER_EVENTS
609 EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
610 EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
611 EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
612 EVT_POWER_RESUME(MyFrame::OnResume)
623 static
void onBellsFinishedCB(
void *ptr) {
624 auto framePtr =
static_cast<MyFrame *
>(ptr);
626 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
627 wxPostEvent(framePtr, ev);
632 MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
633 const wxSize &size,
long style)
634 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
635 comm_overflow_dlg(this) {
637 g_current_monitor = wxDisplay::GetFromWindow(
this);
642 g_current_monitor_dip_px_ratio = g_monitor_info[g_current_monitor].width_px / g_monitor_info[g_current_monitor].width;
645 m_last_track_rotation_ts = 0;
646 m_ulLastNMEATicktime = 0;
649 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
653 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
656 InitTimer.SetOwner(
this, INIT_TIMER);
658 m_initializing =
false;
661 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
664 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
667 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
670 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
673 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
682 m_bTimeIsSet =
false;
685 m_bdefer_resize =
false;
688 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
689 COGFilterTable[i] = NAN;
690 SOGFilterTable[i] = NAN;
692 m_last_bGPSValid =
false;
693 m_last_bVelocityValid =
false;
701 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
705 m_ChartUpdatePeriod = 1;
710 log_callbacks.log_is_active = []() {
return NMEALogWindow::GetInstance().
Active(); };
711 log_callbacks.log_message = [](
const std::string& s) {
712 NMEALogWindow::GetInstance().
Add(s); };
713 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
716 ais_callbacks.confirm_stop_track = []() {
717 int r = OCPNMessageBox(NULL,
718 _(
"This AIS target has Persistent tracking selected by MMSI properties\n"
719 "A Persistent track recording will therefore be restarted for this target.\n\n"
720 "Do you instead want to stop Persistent tracking for this target?"),
721 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
722 return r == wxID_YES;
724 ais_callbacks.get_target_mmsi = []() {
725 auto alert_dlg_active =
727 assert(alert_dlg_active);
728 return alert_dlg_active->Get_Dialog_MMSI();
737 wxLogMessage(
" **** Connect stuff");
743 Connect(wxEVT_OCPN_MSG,
744 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
751 Connect(wxEVT_OCPN_BUILDSENCTHREAD,
752 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
760 #if defined(__WXGTK__) || defined(__WXQT__)
761 wxIcon app_icon(opencpn);
769 wxDynamicLibrary dllUser32(_T(
"user32.dll"));
771 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(wxT(
"SetSysColors"));
772 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(wxT(
"GetSysColor"));
777 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
780 g_sticky_projection = -1;
783 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
784 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
786 assert(g_pRouteMan != 0 &&
"g_pRouteMan not available");
788 [&](wxCommandEvent) { Refresh(); });
793 EnableFullScreenView();
797 MyFrame::~MyFrame() {
805 wxRouteListNode *node = pRouteList->GetFirst();
808 Route *pRouteDelete = node->GetData();
811 node = node->GetNext();
818 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
826 switch (event.type) {
827 case SENC_BUILD_STARTED:
830 case SENC_BUILD_DONE_NOERROR:
832 chart =
event.m_ticket->m_chart;
834 chart->PostInit(FULL_INIT, global_color_scheme);
836 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
838 if (cc) cc->ClearS52PLIBStateHash();
843 delete event.m_ticket;
845 case SENC_BUILD_DONE_ERROR:
853 void MyFrame::RebuildChartDatabase() {
854 bool b_SetInitialPoint =
false;
857 ArrayOfCDI ChartDirArray;
858 pConfig->LoadChartDirArray(ChartDirArray);
860 if (ChartDirArray.GetCount()) {
863 if(g_NeedDBUpdate == 1) {
865 _(
"OpenCPN needs to update the chart database from config file "
869 wxICON_INFORMATION | wxOK);
877 _(
"Rebuilding chart database from configuration file entries..."));
881 wxString dummy1 = _(
"Elapsed time : ");
882 wxString dummy2 = _(
"Estimated time : ");
883 wxString dummy3 = _(
"Remaining time : ");
884 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
885 _(
"OpenCPN Chart Update"), line, 100, NULL,
886 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
887 wxPD_REMAINING_TIME);
889 ChartData->Create(ChartDirArray, pprog);
890 ChartData->SaveBinary(ChartListFileName);
895 ChartData->ApplyGroupArray(g_pGroupArray);
900 void MyFrame::OnBellsFinished(wxCommandEvent &event) {
901 int bells = wxMin(m_BellsToPlay, 2);
902 if (bells <= 0)
return;
904 wxString soundfile = _T(
"sounds");
905 appendOSDirSlash(&soundfile);
906 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
907 soundfile.Prepend(g_Platform->GetSharedDataDir());
908 wxLogMessage(_T(
"Using bells sound file: ") + soundfile);
910 OcpnSound *sound = bells_sound[bells - 1];
911 sound->SetFinishedCallback(onBellsFinishedCB,
this);
912 auto cmd_sound =
dynamic_cast<SystemCmdSound *
>(sound);
913 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
914 sound->Load(soundfile);
915 if (!sound->IsOk()) {
916 wxLogMessage(_T(
"Failed to load bells sound file: ") + soundfile);
920 m_BellsToPlay -= bells;
923 void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
925 void MyFrame::OnMaximize(wxMaximizeEvent &event) {
932 ColorScheme GetColorScheme() {
return global_color_scheme; }
934 ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
936 void MyFrame::ReloadAllVP() {
937 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
939 if (cc) cc->ReloadVP();
943 void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
944 global_color_scheme = cs;
948 case GLOBAL_COLOR_SCHEME_DAY:
949 SchemeName = _T(
"DAY");
951 case GLOBAL_COLOR_SCHEME_DUSK:
952 SchemeName = _T(
"DUSK");
954 case GLOBAL_COLOR_SCHEME_NIGHT:
955 SchemeName = _T(
"NIGHT");
958 SchemeName = _T(
"DAY");
962 g_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
964 g_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
965 g_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
966 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
967 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
968 g_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
970 g_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
999 g_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
1000 g_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
1002 g_pauimgr->Update();
1004 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
1007 unsigned Usercolortable_index = 0;
1008 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
1009 colTable *ct = (colTable *)UserColorTableArray->Item(i);
1010 if (SchemeName.IsSameAs(*ct->tableName)) {
1011 Usercolortable_index = i;
1016 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
1019 pcurrent_user_color_hash =
1020 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
1022 SetSystemColors(cs);
1025 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1028 cc->SetColorScheme(cs);
1029 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1030 cc->HideChartInfoWindow();
1031 cc->SetQuiltChartHiLiteIndex(-1);
1037 g_Platform->GetDisplayDPmm());
1038 if (ChartData) ChartData->ApplyColorSchemeToCachedCharts(cs);
1041 g_options->SetColorScheme(cs);
1045 console->SetColorScheme(cs);
1049 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1052 if (g_pMarkInfoDialog) {
1053 g_pMarkInfoDialog->SetColorScheme(cs);
1056 if (pRoutePropDialog) {
1057 pRoutePropDialog->SetColorScheme(cs);
1062 if (g_pais_query_dialog_active) {
1063 bool b_isshown = g_pais_query_dialog_active->IsShown();
1064 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1065 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1067 g_pais_query_dialog_active->Close();
1070 g_pais_query_dialog_active->
Create(
1071 this, -1, _(
"AIS Target Query"),
1072 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1073 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1074 g_pais_query_dialog_active->UpdateText();
1075 if (b_isshown) g_pais_query_dialog_active->Show();
1078 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1080 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1082 if (g_pObjectQueryDialog) g_pObjectQueryDialog->SetColorScheme();
1084 ApplyGlobalColorSchemetoStatusBar();
1086 UpdateAllToolbars(cs);
1088 if (g_MainToolbar) {
1089 if (g_MainToolbar->GetColorScheme() != cs) {
1091 bool btoolbarFull = g_bmasterToolbarFull;
1093 g_MainToolbar->SetColorScheme(cs);
1097 if (!btoolbarFull) {
1099 RequestNewMasterToolbar();
1100 g_MainToolbar->SetColorScheme(cs);
1101 CollapseGlobalToolbar();
1104 RequestNewMasterToolbar();
1105 g_MainToolbar->SetColorScheme(cs);
1110 if (g_pi_manager) g_pi_manager->SetColorSchemeForAllPlugIns(cs);
1113 void MyFrame::ApplyGlobalColorSchemetoStatusBar(
void) {
1114 if (m_pStatusBar != NULL) {
1115 m_pStatusBar->SetBackgroundColour(GetGlobalColor(_T(
"UIBDR")));
1116 m_pStatusBar->ClearBackground();
1121 if (g_canvasArray.GetCount() > 0)
1122 return g_canvasArray.Item(0);
1126 void MyFrame::CancelAllMouseRoute() {
1128 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1130 if (cc) cc->CancelMouseRoute();
1134 void MyFrame::NotifyChildrenResize() {}
1136 void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1138 if (ChartData) ChartData->PurgeCache();
1141 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1144 g_pauimgr->DetachPane(cc);
1149 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1158 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1161 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1162 config_array.Item(i)->canvas = NULL;
1168 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1169 g_canvasArray.RemoveAt(i);
1173 switch (g_canvasConfig) {
1176 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1178 g_canvasArray.Add(cc);
1180 cc = g_canvasArray[0];
1186 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1187 cc->GetglCanvas()->Show();
1190 config_array.Item(0)->canvas = cc;
1192 cc->SetDisplaySizeMM(g_display_size_mm);
1194 cc->ApplyCanvasConfig(config_array.Item(0));
1198 cc->ConfigureChartBar();
1199 cc->SetColorScheme(global_color_scheme);
1200 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1201 cc->SetShowGPS(
true);
1203 g_pauimgr->AddPane(cc);
1204 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1205 g_pauimgr->GetPane(cc).Fixed();
1206 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1207 g_pauimgr->GetPane(cc).CenterPane();
1212 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1214 g_canvasArray.Add(cc);
1216 cc = g_canvasArray[0];
1222 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1225 config_array.Item(0)->canvas = cc;
1227 cc->ApplyCanvasConfig(config_array.Item(0));
1229 cc->SetDisplaySizeMM(g_display_size_mm);
1230 cc->ConfigureChartBar();
1231 cc->SetColorScheme(global_color_scheme);
1232 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1233 cc->SetShowGPS(
false);
1235 g_pauimgr->AddPane(cc);
1236 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas"));
1237 g_pauimgr->GetPane(cc)
1238 .CaptionVisible(
false)
1240 .CloseButton(
false);
1242 g_pauimgr->GetPane(cc).CenterPane();
1245 g_canvasArray.Add(cc);
1249 if (config_array.GetCount() < 2) {
1251 pcc->configIndex = 1;
1255 pcc->canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1256 config_array.Add(pcc);
1259 config_array.Item(1)->canvas = cc;
1261 cc->ApplyCanvasConfig(config_array.Item(1));
1263 cc->SetDisplaySizeMM(g_display_size_mm);
1264 cc->ConfigureChartBar();
1265 cc->SetColorScheme(global_color_scheme);
1266 cc->SetShowGPS(
true);
1268 g_pauimgr->AddPane(cc);
1269 g_pauimgr->GetPane(cc).Name(_T(
"ChartCanvas2"));
1270 g_pauimgr->GetPane(cc)
1271 .CaptionVisible(
false)
1273 .CloseButton(
false);
1274 g_pauimgr->GetPane(cc).RightDockable(
true);
1275 g_pauimgr->GetPane(cc).Right();
1278 config_array.Item(1)->canvasSize =
1279 wxSize(GetClientSize().x / 2, GetClientSize().y);
1280 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1285 if (b_useStoredSize) {
1286 int ccw = config_array.Item(1)->canvasSize.x;
1287 int cch = config_array.Item(1)->canvasSize.y;
1290 if (ccw < GetClientSize().x / 10) {
1291 ccw = GetClientSize().x / 2;
1292 cch = GetClientSize().y;
1295 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1296 cc->SetSize(ccw, cch);
1307 g_focusCanvas = GetPrimaryCanvas();
1310 void MyFrame::RequestNewToolbars(
bool bforcenew) {
1311 if (b_inCloseWindow) {
1315 BuildiENCToolbar(bforcenew);
1316 PositionIENCToolbar();
1325 void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1326 if (g_iENCToolbar) g_iENCToolbar->SetColorScheme(cs);
1331 void MyFrame::SetAllToolbarScale() {
1332 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1335 void MyFrame::SetGPSCompassScale() {
1336 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1340 wxPoint screenPoint = ::wxGetMousePosition();
1343 switch (g_canvasConfig) {
1345 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1348 if (canvas->GetScreenRect().Contains(
1352 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1355 if (canvas->GetScreenRect().Contains(
1362 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1365 if (canvas->GetScreenRect().Contains(
1366 canvas->ScreenToClient(screenPoint)))
1374 int MyFrame::GetCanvasIndexUnderMouse() {
1375 wxPoint screenPoint = ::wxGetMousePosition();
1378 switch (g_canvasConfig) {
1380 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1383 if (canvas->GetScreenRect().Contains(
1387 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1390 if (canvas->GetScreenRect().Contains(
1397 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1400 if (canvas->GetScreenRect().Contains(
1401 canvas->ScreenToClient(screenPoint)))
1409 bool MyFrame::DropMarker(
bool atOwnShip) {
1416 if (!canvas)
return false;
1418 lat = canvas->m_cursor_lat;
1419 lon = canvas->m_cursor_lon;
1423 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1424 pWP->m_bIsolatedMark =
true;
1425 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1426 pConfig->AddNewWayPoint(pWP, -1);
1430 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1431 pRouteManagerDialog->UpdateWptListCtrl();
1436 RefreshAllCanvas(
false);
1441 void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1442 if (g_canvasConfig != 0) {
1445 int nTargetGTK = -1;
1447 wxWindow *source = FindFocus();
1453 switch (g_canvasConfig) {
1455 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1458 if (canvas && (canvas == test)) {
1463 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1466 if (canvas && (canvas == test)) {
1474 int nfinalTarget = nTarget;
1476 nfinalTarget = nTargetGTK;
1478 target = ConfigMgr::Get().GetCanvasConfigArray().Item(nfinalTarget)->canvas;
1480 wxWindow *win = wxDynamicCast(target, wxWindow);
1482 target->Refresh(
true);
1493 void MyFrame::FastClose() {
1496 FrameTimer1.Start(1);
1500 void MyFrame::OnExit(wxCommandEvent &event) {
1504 void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1507 if (b_inCloseWindow) {
1517 if (!g_bDeferredInitDone)
return;
1530 if (b_inCompressAllCharts) {
1534 if (bDBUpdateInProgress)
return;
1536 b_inCloseWindow =
true;
1538 ::wxSetCursor(wxCURSOR_WAIT);
1542 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1544 if (cc && cc->IsMeasureActive()) {
1545 cc->CancelMeasureRoute();
1551 if (g_pAISTargetList) {
1552 wxAuiPaneInfo &pane = g_pauimgr->GetPane(g_pAISTargetList);
1553 g_AisTargetList_perspective = g_pauimgr->SavePaneInfo(pane);
1554 g_pauimgr->DetachPane(g_pAISTargetList);
1565 pConfig->SetPath(_T (
"/AUI" ));
1566 pConfig->Write(_T (
"AUIPerspective" ), g_pauimgr->SavePerspective());
1573 if (g_glTextureManager) {
1574 g_glTextureManager->PurgeJobList();
1576 if (g_glTextureManager->GetRunningJobCount()) g_bcompression_wait =
true;
1581 SetCursor(wxCURSOR_WAIT);
1583 RefreshAllCanvas(
true);
1589 RestoreScreenBrightness();
1597 if (g_iENCToolbar) {
1598 wxPoint locn = g_iENCToolbar->GetPosition();
1599 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1600 g_iENCToolbarPosY = tbp_incanvas.y;
1601 g_iENCToolbarPosX = tbp_incanvas.x;
1605 g_bframemax = IsMaximized();
1608 FrameCOGTimer.Stop();
1622 if (g_bAutoAnchorMark) {
1623 bool watching_anchor =
false;
1624 if (pAnchorWatchPoint1)
1625 watching_anchor = (pAnchorWatchPoint1->GetIconName().StartsWith(
1627 if (pAnchorWatchPoint2)
1628 watching_anchor |= (pAnchorWatchPoint2->GetIconName().StartsWith(
1631 wxDateTime now = wxDateTime::Now();
1632 wxTimeSpan uptime = now.Subtract(g_start_time);
1634 if (!watching_anchor && (g_bCruising) && (gSog < 0.5) &&
1635 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1640 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
1643 if (pr->GetName().StartsWith(_T(
"Anchorage"))) {
1644 double a = gLat - pr->m_lat;
1645 double b = gLon - pr->m_lon;
1646 double l = sqrt((a * a) + (b * b));
1649 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1650 pConfig->DeleteWayPoint(pr);
1651 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1657 node = node->GetNext();
1660 wxString name = now.Format();
1661 name.Prepend(_(
"Anchorage created "));
1663 new RoutePoint(gLat, gLon, _T(
"anchorage"), name, wxEmptyString);
1664 pWP->m_bShowName =
false;
1665 pWP->m_bIsolatedMark =
true;
1667 pConfig->AddNewWayPoint(pWP, -1);
1672 pConfig->UpdateSettings();
1675 auto plugin_loader = PluginLoader::getInstance();
1676 if (plugin_loader) {
1677 plugin_loader->DeactivateAllPlugIns();
1680 wxLogMessage(_T(
"opencpn::MyFrame exiting cleanly."));
1684 pConfig->UpdateNavObj();
1686 pConfig->m_pNavObjectChangesSet->reset();
1690 pConfig->DeleteGroup(_T (
"/Routes" ));
1691 pConfig->DeleteGroup(_T (
"/Marks" ));
1695 delete g_pageSetupData;
1697 if (g_pAboutDlg) g_pAboutDlg->Destroy();
1698 if (g_pAboutDlgLegacy) g_pAboutDlgLegacy->Destroy();
1703 if (g_pCM93OffsetDialog) {
1704 g_pCM93OffsetDialog->Destroy();
1705 g_pCM93OffsetDialog = NULL;
1713 if (g_iENCToolbar) {
1720 if (g_pAISTargetList) {
1721 g_pAISTargetList->Disconnect_decoder();
1722 g_pAISTargetList->Destroy();
1729 if (RouteManagerDialog::getInstanceFlag()) {
1730 if (pRouteManagerDialog) {
1731 pRouteManagerDialog->Destroy();
1732 pRouteManagerDialog = NULL;
1737 if (ChartData) ChartData->PurgeCache();
1743 g_focusCanvas = NULL;
1746 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1748 if (cc) cc->Destroy();
1751 g_canvasArray.Clear();
1753 g_pauimgr->UnInit();
1763 if (ChartData) ChartData->PurgeCachePlugins();
1765 if (PluginLoader::getInstance())
1766 PluginLoader::getInstance()->UnLoadAllPlugIns();
1769 delete g_pi_manager;
1770 g_pi_manager = NULL;
1773 MyApp& app = wxGetApp();
1774 app.m_comm_bridge.SaveConfig();
1795 auto& registry = CommDriverRegistry::GetInstance();
1796 registry.CloseAllDrivers();
1799 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1803 delete TheConnectionParams();
1806 LayerList::iterator it;
1807 while (pLayerList->GetCount()) {
1808 Layer *lay = pLayerList->GetFirst()->GetData();
1813 NMEALogWindow::Shutdown();
1815 ReleaseApiListeners();
1817 g_MainToolbar = NULL;
1818 g_bTempShowMenuBar =
false;
1820 #define THREAD_WAIT_SECONDS 5
1826 if (g_bopengl && g_glTextureManager &&
1827 g_glTextureManager->GetRunningJobCount()) {
1828 g_glTextureManager->ClearAllRasterTextures();
1830 wxLogMessage(_T(
"Starting compressor pool drain"));
1831 wxDateTime now = wxDateTime::Now();
1832 time_t stall = now.GetTicks();
1833 time_t end = stall + THREAD_WAIT_SECONDS;
1836 while (stall < end) {
1837 wxDateTime later = wxDateTime::Now();
1838 stall = later.GetTicks();
1841 msg.Printf(_T(
"Time: %d Job Count: %d"), n_comploop,
1842 g_glTextureManager->GetRunningJobCount());
1844 if (!g_glTextureManager->GetRunningJobCount())
break;
1850 fmsg.Printf(_T(
"Finished compressor pool drain..Time: %d Job Count: %d"),
1851 n_comploop, g_glTextureManager->GetRunningJobCount());
1854 delete g_glTextureManager;
1856 uninitIXNetSystem();
1860 wxLogMessage(_T(
"gFrame destroyed."));
1863 #ifndef USE_ANDROID_GLES2
1864 qDebug() <<
"Calling OnExit()";
1868 wxTheApp->ExitMainLoop();
1871 void MyFrame::OnMove(wxMoveEvent &event) {
1872 auto idx = wxDisplay::GetFromWindow(
this);
1873 if (idx != wxNOT_FOUND && g_current_monitor !=
static_cast<size_t>(idx) &&
static_cast<size_t>(idx) < g_monitor_info.size()) {
1874 g_current_monitor = idx;
1879 g_current_monitor_dip_px_ratio = g_monitor_info[idx].width_px / g_monitor_info[idx].width;
1882 DEBUG_LOG <<
"Moved to " << idx
1883 #if wxCHECK_VERSION(3, 1, 6)
1884 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x" << wxDisplay(idx).GetPPI().GetY()
1885 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1887 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth() <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1888 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x" << wxGetDisplaySizeMM().GetY()
1889 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1890 <<
" Real: " << g_monitor_info[idx].width_mm <<
"x" << g_monitor_info[idx].height_mm <<
"mm "
1891 << g_monitor_info[idx].width_mm <<
"x" << g_monitor_info[idx].height_mm <<
"mm "
1892 << g_monitor_info[idx].width <<
"x" << g_monitor_info[idx].height <<
"DIP "
1893 << g_monitor_info[idx].width_px <<
"x" << g_monitor_info[idx].height_px <<
"px"
1894 << g_monitor_info[idx].scale <<
"%";
1895 if(g_config_display_size_manual) {
1896 if(g_config_display_size_mm.size() >
static_cast<size_t>(idx)) {
1897 g_display_size_mm = g_config_display_size_mm[idx];
1900 g_display_size_mm = g_monitor_info[idx].width_mm;
1904 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1907 cc->SetMUIBarPosition();
1908 cc->SetDisplaySizeMM(g_display_size_mm);
1916 UpdateGPSCompassStatusBoxes();
1918 if (console && console->IsShown()) PositionConsole();
1926 PositionIENCToolbar();
1932 g_nframewin_posx = GetPosition().x;
1933 g_nframewin_posy = GetPosition().y;
1936 void MyFrame::ProcessCanvasResize(
void) {
1937 UpdateGPSCompassStatusBoxes(
true);
1939 if (console && console->IsShown()) PositionConsole();
1941 PositionIENCToolbar();
1944 TriggerRecaptureTimer();
1948 void MyFrame::TriggerRecaptureTimer() {
1949 m_recaptureTimer.Start(
1950 1000, wxTIMER_ONE_SHOT);
1953 void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { Raise(); }
1955 void MyFrame::SetCanvasSizes(wxSize frameSize) {
1956 if (!g_canvasArray.GetCount())
return;
1959 int cccw = frameSize.x;
1960 int ccch = frameSize.y;
1964 switch (g_canvasConfig) {
1968 cc = g_canvasArray.Item(0);
1970 cc->GetSize( &cur_width, &cur_height );
1971 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1972 if( g_pauimgr->GetPane( cc ).IsOk() )
1973 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1975 cc->SetSize( 0, 0, cccw, ccch );
1983 cc = g_canvasArray.Item(1);
1985 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1986 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1988 ccw = wxMin(ccw, cccw * 8 / 10);
1989 ccw = wxMax(ccw, cccw * 2 / 10);
1993 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
2000 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2001 g_pauimgr->GetPane(cc).Fixed();
2002 g_pauimgr->Update();
2005 g_pauimgr->GetPane(cc).Resizable();
2017 void MyFrame::OnIconize(wxIconizeEvent &event) {
2019 if (g_MainToolbar) {
2020 g_MainToolbar->Show(!event.IsIconized());
2022 if (g_iENCToolbar) {
2023 g_iENCToolbar->Show(!event.IsIconized());
2027 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2029 if (cc && cc->GetMUIBar()) {
2030 if (cc->GetMUIBar()->GetCanvasOptions()) {
2031 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2032 cc->GetMUIBar()->PushCanvasOptions();
2041 void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2043 void MyFrame::ODoSetSize(
void) {
2045 GetClientSize(&x, &y);
2048 if (m_pStatusBar != NULL) {
2049 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2050 int currentCount = m_pStatusBar->GetFieldsCount();
2051 if (currentCount != m_StatusBarFieldCount) {
2052 if ((currentCount > 0) && (currentCount < 7)) {
2055 int widths[] = {2, 2, 2, 2, 2, 2};
2056 m_pStatusBar->SetStatusWidths(currentCount, widths);
2059 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2062 if (m_StatusBarFieldCount) {
2067 if (m_StatusBarFieldCount > 2) {
2068 int widths[] = {-6, -5, -5, -6, -4};
2069 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2070 }
else if (m_StatusBarFieldCount == 2) {
2071 int cwidth = x * 90 / 100;
2072 int widths[] = {100, 100};
2073 widths[0] = cwidth * 6.4 / 10.0;
2074 widths[1] = cwidth * 3.6 / 10.0;
2075 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2077 int widths[] = {100, 100};
2078 widths[0] = x * 90 / 100;
2079 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2082 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2083 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2084 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2086 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
2087 _T(
" COG ---\u00B0"));
2088 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2096 m_pStatusBar->GetFieldRect(0, stat_box);
2099 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2101 wxFont sys_font = *wxNORMAL_FONT;
2102 int try_font_size = sys_font.GetPointSize();
2105 int min_font_size = 10;
2115 wxFont *statusBarFont =
2116 FontMgr::Get().GetFont(_(
"StatusBar"), try_font_size);
2117 int font_size = statusBarFont->GetPointSize();
2119 font_size = wxMin(font_size,
2122 wxMax(font_size, min_font_size);
2125 font_size = statusBarFont->GetPointSize();
2129 font_size /= OCPN_GetDisplayContentScaleFactor();
2131 wxFont *pstat_font = FontMgr::Get().FindOrCreateFont(
2132 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2133 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2135 int min_height = stat_box.height;
2137 m_pStatusBar->SetFont(*pstat_font);
2138 m_pStatusBar->SetForegroundColour(
2139 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2141 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2143 (min_height >> 1) * 2;
2144 m_pStatusBar->SetMinHeight(min_height);
2153 SetCanvasSizes(GetClientSize());
2155 UpdateGPSCompassStatusBoxes(
true);
2157 if (console) PositionConsole();
2160 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2162 if (cc) cc->FormatPianoKeys();
2166 if (g_MainToolbar) {
2167 wxSize szBefore = g_MainToolbar->GetToolbarSize();
2168 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2169 GetPrimaryCanvas()->GetCompass()->GetRect());
2170 g_MainToolbar->Realize();
2172 if (szBefore != g_MainToolbar->GetToolbarSize())
2173 g_MainToolbar->RefreshToolbar();
2182 if (g_pi_manager) g_pi_manager->SendResizeEventToAllPlugIns(x, y);
2195 options_lastWindowSize = wxSize(0, 0);
2196 options_lastWindowPos = wxPoint(0, 0);
2203 if (!b_inCloseWindow) {
2204 if (g_options) g_options->Raise();
2206 resizeAndroidPersistents();
2211 if (g_pauimgr) g_pauimgr->Update();
2214 void MyFrame::PositionConsole(
void) {
2215 if (NULL == GetPrimaryCanvas())
return;
2217 int ccx, ccy, ccsx, ccsy, consx, consy;
2219 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2222 consoleHost->GetSize(&ccsx, &ccsy);
2223 consoleHost->GetPosition(&ccx, &ccy);
2225 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2226 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2227 consoleHost = GetPrimaryCanvas();
2232 if(consoleHost->GetCompass()){
2233 wxRect compass_rect = consoleHost->GetCompass()->GetRect();
2235 if(compass_rect.y < 100)
2236 yOffset = compass_rect.y + compass_rect.height + 45;
2240 console->GetSize(&consx, &consy);
2242 wxPoint screen_pos =
2243 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2244 console->Move(screen_pos);
2247 void MyFrame::UpdateAllFonts() {
2249 console->UpdateFonts();
2256 DestroyPersistentDialogs();
2258 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2263 void MyFrame::DestroyPersistentDialogs() {
2264 if (g_pais_query_dialog_active) {
2265 g_pais_query_dialog_active->Hide();
2266 g_pais_query_dialog_active->Destroy();
2267 g_pais_query_dialog_active = NULL;
2270 if (RoutePropDlgImpl::getInstanceFlag() && pRoutePropDialog) {
2271 pRoutePropDialog->Hide();
2272 pRoutePropDialog->Destroy();
2273 pRoutePropDialog = NULL;
2276 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog) {
2277 pTrackPropDialog->Hide();
2278 pTrackPropDialog->Destroy();
2279 pTrackPropDialog = NULL;
2282 if (g_pMarkInfoDialog) {
2283 g_pMarkInfoDialog->Hide();
2284 g_pMarkInfoDialog->Destroy();
2285 g_pMarkInfoDialog = NULL;
2288 if (g_pObjectQueryDialog) {
2289 g_pObjectQueryDialog->Hide();
2290 g_pObjectQueryDialog->Destroy();
2291 g_pObjectQueryDialog = NULL;
2295 void MyFrame::RefreshGroupIndices(
void) {
2297 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2299 if (cc) cc->canvasRefreshGroupIndex();
2303 void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2304 if (g_MainToolbar) g_MainToolbar->HideTooltip();
2307 switch (event.GetId()) {
2308 case ID_MENU_SCALE_OUT:
2309 DoStackDelta(GetPrimaryCanvas(), 1);
2313 case ID_MENU_SCALE_IN:
2314 DoStackDelta(GetPrimaryCanvas(), -1);
2318 case ID_MENU_ZOOM_IN: {
2319 if (GetFocusCanvas()) {
2320 GetFocusCanvas()->ZoomCanvas(g_plus_minus_zoom_factor,
false);
2325 case ID_MENU_ZOOM_OUT: {
2326 if (GetFocusCanvas()) {
2327 GetFocusCanvas()->ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2332 case ID_MENU_ROUTE_NEW: {
2333 if (GetFocusCanvas()) {
2334 if (0 == GetFocusCanvas()->m_routeState) {
2335 GetFocusCanvas()->StartRoute();
2337 GetFocusCanvas()->FinishRoute();
2343 case ID_MENU_TOOL_MEASURE: {
2344 GetPrimaryCanvas()->StartMeasureRoute();
2348 case ID_MENU_MARK_BOAT: {
2353 case ID_MENU_MARK_CURSOR: {
2358 case ID_MENU_NAV_FOLLOW: {
2359 if (gFrame->GetPrimaryCanvas())
2360 gFrame->GetPrimaryCanvas()->TogglebFollow();
2364 case ID_MENU_CHART_OUTLINES: {
2365 ToggleChartOutlines(GetFocusCanvas());
2369 case ID_MENU_CHART_QUILTING: {
2370 ToggleQuiltMode(GetFocusCanvas());
2374 case ID_MENU_UI_CHARTBAR: {
2375 ToggleChartBar(GetFocusCanvas());
2379 case ID_MENU_ENC_TEXT:
2381 ToggleENCText(GetFocusCanvas());
2384 case ID_MENU_ENC_LIGHTS: {
2385 ToggleLights(GetFocusCanvas());
2388 case ID_MENU_ENC_SOUNDINGS: {
2389 ToggleSoundings(GetFocusCanvas());
2392 case ID_MENU_ENC_ANCHOR: {
2393 ToggleAnchor(GetFocusCanvas());
2396 case ID_MENU_ENC_DATA_QUALITY: {
2397 ToggleDataQuality(GetFocusCanvas());
2400 case ID_MENU_SHOW_NAVOBJECTS: {
2401 ToggleNavobjects(GetFocusCanvas());
2405 case ID_MENU_AIS_TARGETS: {
2406 ToggleAISDisplay(GetFocusCanvas());
2409 case ID_MENU_AIS_MOORED_TARGETS: {
2410 g_bHideMoored = !g_bHideMoored;
2413 case ID_MENU_AIS_SCALED_TARGETS: {
2414 ToggleAISMinimizeTargets(GetFocusCanvas());
2418 case ID_MENU_AIS_TARGETLIST: {
2419 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2423 case ID_MENU_AIS_TRACKS: {
2424 g_bAISShowTracks = !g_bAISShowTracks;
2425 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2429 case ID_MENU_AIS_CPADIALOG: {
2430 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2431 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2432 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2433 if (g_bAIS_CPA_Alert){
2434 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2439 case ID_MENU_AIS_CPASOUND: {
2440 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2441 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2445 case ID_MENU_AIS_CPAWARNING: {
2446 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2447 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2451 case wxID_PREFERENCES:
2453 g_MainToolbar->HideTooltip();
2458 case ID_MENU_SETTINGS_BASIC: {
2461 androidDisableFullScreen();
2462 g_MainToolbar->HideTooltip();
2463 DoAndroidPreferences();
2470 case ID_MENU_UI_FULLSCREEN: {
2475 case ID_MENU_SHOW_CURRENTS: {
2476 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2477 GetFocusCanvas()->ReloadVP();
2478 GetFocusCanvas()->Refresh(
false);
2482 case ID_MENU_SHOW_TIDES: {
2483 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2484 GetFocusCanvas()->ReloadVP();
2485 GetFocusCanvas()->Refresh(
false);
2491 g_Platform->DoHelpDialog();
2496 g_Platform->LaunchLocalHelp();
2505 case ID_MENU_UI_COLSCHEME:
2506 case ID_COLSCHEME: {
2507 ToggleColorScheme();
2516 case ID_MENU_OQUIT: {
2521 case ID_MENU_ROUTE_MANAGER:
2522 case ID_ROUTEMANAGER: {
2523 pRouteManagerDialog = RouteManagerDialog::getInstance(
2526 if (pRouteManagerDialog->IsShown())
2527 pRouteManagerDialog->Hide();
2529 pRouteManagerDialog->UpdateRouteListCtrl();
2530 pRouteManagerDialog->UpdateTrkListCtrl();
2531 pRouteManagerDialog->UpdateWptListCtrl();
2532 pRouteManagerDialog->UpdateLayListCtrl();
2534 pRouteManagerDialog->Show();
2538 pRouteManagerDialog->Centre();
2539 pRouteManagerDialog->Raise();
2545 case ID_MENU_NAV_TRACK:
2547 if (!g_bTrackActive) {
2549 g_bTrackCarryOver =
true;
2552 if (pConfig && pConfig->IsChangesFileDirty()) {
2553 pConfig->UpdateNavObj(
true);
2555 g_bTrackCarryOver =
false;
2556 RefreshAllCanvas(
true);
2561 case ID_MENU_CHART_NORTHUP: {
2562 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2565 case ID_MENU_CHART_COGUP: {
2566 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2569 case ID_MENU_CHART_HEADUP: {
2570 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2574 case ID_MENU_MARK_MOB:
2580 case ID_MASTERTOGGLE: {
2581 if (g_MainToolbar) {
2582 wxString tip = _(
"Show Toolbar");
2583 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2584 if (g_MainToolbar->GetToolbar())
2585 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2587 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2590 if (g_bmasterToolbarFull)
2591 m_nMasterToolCountShown =
2592 g_MainToolbar->GetToolCount() -
2595 m_nMasterToolCountShown = 2;
2597 m_nMasterToolCountShown =
2598 g_MainToolbar->GetToolShowCount();
2600 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2608 case ID_CMD_SELECT_CHART_TYPE: {
2609 selectChartDisplay(event.GetExtraLong(), -1);
2613 case ID_CMD_SELECT_CHART_FAMILY: {
2614 selectChartDisplay(-1, event.GetExtraLong());
2618 case ID_CMD_APPLY_SETTINGS: {
2619 applySettingsString(event.GetString());
2621 androidRestoreFullScreen();
2627 case ID_CMD_NULL_REFRESH: {
2632 case ID_CMD_SETVP: {
2633 setStringVP(event.GetString());
2637 case ID_CMD_INVALIDATE: {
2643 case ID_CMD_POST_JSON_TO_PLUGINS: {
2647 wxJSONReader reader;
2649 int numErrors = reader.Parse(event.GetString(), &root);
2650 if (numErrors == 0) {
2651 if (root[_T(
"MessageID")].IsString()) {
2652 wxString MsgID = root[_T(
"MessageID")].AsString();
2653 SendPluginMessage(MsgID, event.GetString());
2663 if (g_iENCToolbar ){
2664 g_iENCToolbar->OnToolLeftClick(event);
2674 g_MainToolbar->HideTooltip();
2676 ArrayOfPlugInToolbarTools tool_array =
2677 g_pi_manager->GetPluginToolbarToolArray();
2678 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2680 if (event.GetId() == pttc->id) {
2681 if (pttc->m_pplugin)
2682 pttc->m_pplugin->OnToolbarToolCallback(pttc->id);
2701 g_MainToolbar->Realize();
2706 bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2707 bool viz_now = g_bmasterToolbarFull;
2709 g_MainToolbar->HideTooltip();
2710 wxString tip = _(
"Show Toolbar");
2712 tip = _(
"Hide Toolbar");
2713 if (g_MainToolbar->GetToolbar())
2714 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2717 bool toggle =
false;
2718 if (viz && !g_bmasterToolbarFull)
2721 else if (!viz && g_bmasterToolbarFull)
2725 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2728 if (g_bmasterToolbarFull)
2729 m_nMasterToolCountShown =
2730 g_MainToolbar->GetToolCount() -
2733 m_nMasterToolCountShown = 2;
2735 m_nMasterToolCountShown =
2736 g_MainToolbar->GetToolShowCount();
2738 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2744 void MyFrame::ScheduleSettingsDialog() {
2745 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2746 evt.SetId(ID_SETTINGS );
2747 GetEventHandler()->AddPendingEvent(evt);
2751 if ((g_canvasConfig != 0) && g_focusCanvas)
2752 return g_focusCanvas;
2754 return GetPrimaryCanvas();
2757 void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2758 if (g_bmasterToolbarFull) {
2759 #ifndef OCPN_TOOLBAR_ANIMATE
2760 m_nMasterToolCountShown = (int)g_MainToolbar->GetToolCount();
2763 if (m_nMasterToolCountShown < (
int)g_MainToolbar->GetToolCount()) {
2764 m_nMasterToolCountShown++;
2765 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2766 g_MainToolbar->Realize();
2767 g_MainToolbar->RefreshToolbar();
2769 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2771 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2772 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2773 g_MainToolbar->Realize();
2774 g_MainToolbar->RefreshToolbar();
2777 #ifndef OCPN_TOOLBAR_ANIMATE
2778 m_nMasterToolCountShown = 1;
2780 if (m_nMasterToolCountShown > 1) {
2781 m_nMasterToolCountShown--;
2782 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2783 g_MainToolbar->Realize();
2784 g_MainToolbar->RefreshToolbar();
2785 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2787 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
2788 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
2789 g_MainToolbar->Realize();
2790 g_MainToolbar->RefreshToolbar();
2795 void MyFrame::InvalidateAllGL() {
2798 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2808 void MyFrame::RefreshAllCanvas(
bool bErase) {
2810 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2813 cc->Refresh(bErase);
2818 void MyFrame::setStringVP(wxString VPS) {
2823 wxStringTokenizer tkz(VPS, _T(
";"));
2825 wxString token = tkz.GetNextToken();
2827 token.ToDouble(&lat);
2829 token = tkz.GetNextToken();
2831 token.ToDouble(&lon);
2833 token = tkz.GetNextToken();
2834 double scale_ppm = cc->GetVP().view_scale_ppm;
2835 token.ToDouble(&scale_ppm);
2837 cc->SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2840 void MyFrame::DoSettings() {
2841 if (g_boptionsactive)
return;
2843 bool bnewtoolbar = !(DoOptionsDialog() == 0);
2846 ApplyGlobalSettings(bnewtoolbar);
2849 bool b_loadHarmonics =
false;
2850 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2853 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2856 if (b_loadHarmonics) LoadHarmonics();
2864 g_bShowChartBar = !g_bShowChartBar;
2866 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2871 if (g_bShowChartBar) {
2873 UpdateControlBar(cc);
2876 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2879 void MyFrame::ToggleColorScheme() {
2880 static bool lastIsNight;
2881 ColorScheme s = GetColorScheme();
2884 if (lastIsNight && is == 3)
2887 lastIsNight =
false;
2889 if (lastIsNight) is = 2;
2890 if (is == 3) lastIsNight =
true;
2891 s = (ColorScheme)is;
2892 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
2894 SetAndApplyColorScheme(s);
2897 void MyFrame::ToggleFullScreen() {
2898 bool to = !IsFullScreen();
2903 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
2905 ShowFullScreen(to, style);
2908 UpdateAllToolbars(global_color_scheme);
2910 UpdateControlBar(GetPrimaryCanvas());
2912 TriggerRecaptureTimer();
2915 void MyFrame::ActivateMOB(
void) {
2917 wxDateTime mob_time = wxDateTime::Now();
2918 wxString mob_label(_(
"MAN OVERBOARD"));
2919 mob_label += _(
" at ");
2920 mob_label += mob_time.FormatTime();
2921 mob_label += _(
" on ");
2922 mob_label += mob_time.FormatISODate();
2925 new RoutePoint(gLat, gLon, _T (
"mob" ), mob_label, wxEmptyString);
2926 pWP_MOB->SetShared(
true);
2927 pWP_MOB->m_bIsolatedMark =
true;
2928 pWP_MOB->SetWaypointArrivalRadius(
2930 pWP_MOB->SetUseSca(
false);
2931 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_MOB);
2932 pConfig->AddNewWayPoint(pWP_MOB, -1);
2934 if (bGPSValid && !std::isnan(gCog) && !std::isnan(gSog)) {
2937 ll_gc_ll(gLat, gLon, gCog, 1.0, &zlat, &zlon);
2940 new RoutePoint(zlat, zlon, g_default_wp_icon,
2941 wxString(_(
"1.0 NM along COG")), wxEmptyString);
2942 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
2945 pRouteList->Append(temp_route);
2947 temp_route->AddPoint(pWP_src);
2948 temp_route->AddPoint(pWP_MOB);
2950 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src, pWP_MOB,
2953 temp_route->m_RouteNameString = _(
"Temporary MOB Route");
2954 temp_route->m_RouteStartString = _(
"Assumed 1 Mile Point");
2956 temp_route->m_RouteEndString = mob_label;
2958 temp_route->m_bDeleteOnArrival =
false;
2960 temp_route->SetRouteArrivalRadius(-1.0);
2962 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
2963 g_pRouteMan->ActivateRoute(temp_route, pWP_MOB);
2966 v[_T(
"GUID")] = temp_route->m_GUID;
2967 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
2968 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
2971 if (RouteManagerDialog::getInstanceFlag()) {
2972 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
2973 pRouteManagerDialog->UpdateRouteListCtrl();
2974 pRouteManagerDialog->UpdateWptListCtrl();
2979 RefreshAllCanvas(
false);
2981 wxString mob_message(_(
"MAN OVERBOARD"));
2982 mob_message += _(
" Time: ");
2983 mob_message += mob_time.Format();
2984 mob_message += _(
" Position: ");
2985 mob_message += toSDMM(1, gLat);
2986 mob_message += _T(
" ");
2987 mob_message += toSDMM(2, gLon);
2988 wxLogMessage(mob_message);
2990 void MyFrame::TrackOn(
void) {
2991 g_bTrackActive =
true;
2994 g_TrackList.push_back(g_pActiveTrack);
2995 if (pConfig) pConfig->AddNewTrack(g_pActiveTrack);
2997 g_pActiveTrack->Start();
3000 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3002 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3004 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3007 androidSetTrackTool(
true);
3010 if (RouteManagerDialog::getInstanceFlag()) {
3011 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3012 pRouteManagerDialog->UpdateTrkListCtrl();
3013 pRouteManagerDialog->UpdateRouteListCtrl();
3019 now = now.Now().ToUTC();
3020 wxString name = g_pActiveTrack->GetName();
3021 if (name.IsEmpty()) {
3022 TrackPoint *tp = g_pActiveTrack->GetPoint(0);
3023 if (tp->GetCreateTime().IsValid())
3024 name = tp->GetCreateTime().FormatISODate() + _T(
" ") +
3025 tp->GetCreateTime().FormatISOTime();
3027 name = _(
"(Unnamed Track)");
3029 v[_T(
"Name")] = name;
3030 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3031 wxString msg_id(_T(
"OCPN_TRK_ACTIVATED"));
3032 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
3033 g_FlushNavobjChangesTimeout =
3037 Track *MyFrame::TrackOff(
bool do_add_point) {
3038 Track *return_val = g_pActiveTrack;
3040 if (g_pActiveTrack) {
3042 wxString msg_id(_T(
"OCPN_TRK_DEACTIVATED"));
3043 v[_T(
"GUID")] = g_pActiveTrack->m_GUID;
3044 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
3046 g_pActiveTrack->Stop(do_add_point);
3048 if (g_pActiveTrack->GetnPoints() < 2) {
3049 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3052 if (g_bTrackDaily) {
3053 Track *pExtendTrack = g_pActiveTrack->DoExtendDaily();
3055 RoutemanGui(*g_pRouteMan).DeleteTrack(g_pActiveTrack);
3056 return_val = pExtendTrack;
3060 g_pActiveTrack = NULL;
3063 g_bTrackActive =
false;
3065 if (RouteManagerDialog::getInstanceFlag()) {
3066 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3067 pRouteManagerDialog->UpdateTrkListCtrl();
3068 pRouteManagerDialog->UpdateRouteListCtrl();
3072 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3074 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3075 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3078 androidSetTrackTool(
false);
3081 g_FlushNavobjChangesTimeout =
3087 bool MyFrame::ShouldRestartTrack(
void) {
3088 if (!g_pActiveTrack || !g_bTrackDaily)
return false;
3089 time_t now = wxDateTime::Now().GetTicks();
3090 time_t today = wxDateTime::Today().GetTicks();
3092 switch (g_track_rotate_time_type) {
3094 rotate_at = g_track_rotate_time + wxRound(gLon * 3600. / 15.);
3096 case TIME_TYPE_COMPUTER:
3097 rotate_at = g_track_rotate_time;
3101 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3102 rotate_at = g_track_rotate_time + utc_offset;
3105 if (rotate_at > 86400)
3107 else if (rotate_at < 0)
3109 if (now >= m_last_track_rotation_ts + 86400 - 3600 &&
3110 now - today >= rotate_at) {
3111 if (m_last_track_rotation_ts == 0) {
3112 if (now - today > rotate_at)
3113 m_last_track_rotation_ts = today + rotate_at;
3115 m_last_track_rotation_ts = today + rotate_at - 86400;
3118 m_last_track_rotation_ts = now;
3124 void MyFrame::TrackDailyRestart(
void) {
3125 if (!g_pActiveTrack)
return;
3127 Track *pPreviousTrack = TrackOff(
true);
3128 if (pConfig && pConfig->IsChangesFileDirty()) {
3129 pConfig->UpdateNavObj(
true);
3138 if (pPreviousTrack) {
3139 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3140 g_pActiveTrack->AdjustCurrentTrackPoint(pMidnightPoint);
3143 if (RouteManagerDialog::getInstanceFlag()) {
3144 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3145 pRouteManagerDialog->UpdateTrkListCtrl();
3146 pRouteManagerDialog->UpdateRouteListCtrl();
3151 void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3153 cc->SetUpMode(mode);
3155 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3156 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3157 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3160 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3165 cc->SetShowENCText(!cc->GetShowENCText());
3167 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3175 void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3178 cc->SetENCDisplayCategory(nset);
3180 UpdateGlobalMenuItems();
3191 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3193 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3202 cc->SetShowENCLights(!cc->GetShowENCLights());
3204 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3206 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns(
true);
3214 void MyFrame::ToggleRocks(
void )
3220 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3221 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3222 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3223 pOLE->nViz = !pOLE->nViz;
3227 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3228 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3229 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3232 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3236 ps52plib->GenerateStateHash();
3243 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3245 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3247 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3252 void MyFrame::ToggleDataQuality(
ChartCanvas *cc) {
3253 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3255 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3257 if (g_pi_manager) g_pi_manager->SendS52ConfigToAllPlugIns();
3270 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3271 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3276 cc->SetShowAIS(!cc->GetShowAIS());
3277 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3281 void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3282 cc->SetAttenAIS(!cc->GetAttenAIS());
3283 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3288 JumpToPosition(cc, gLat, gLon, cc->GetVPScale());
3289 cc->m_bFollow =
true;
3292 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3296 SetChartUpdatePeriod();
3304 cc->m_bFollow =
false;
3306 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3310 SetChartUpdatePeriod();
3313 void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3314 cc->SetShowOutlines(!cc->GetShowOutlines());
3316 RefreshAllCanvas(
false);
3320 if (g_bopengl) InvalidateAllGL();
3323 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3326 void MyFrame::ToggleTestPause(
void) { g_bPauseTest = !g_bPauseTest; }
3328 void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3330 bool enabled = m_pMenuBar->IsEnabled(item_id);
3331 m_pMenuBar->Enable(item_id,
false);
3332 m_pMenuBar->Check(item_id, state);
3333 m_pMenuBar->Enable(item_id, enabled);
3337 void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3338 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3339 g_MainToolbar->GetToolbar()->ToggleTool(tool_id, state);
3340 g_MainToolbar->Realize();
3344 void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3345 wxBitmap *bmpRollover) {
3346 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3347 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3348 g_MainToolbar->Realize();
3352 void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3353 wxString rolloverSVGfile,
3354 wxString toggledSVGfile) {
3355 if (g_MainToolbar && g_MainToolbar->GetToolbar()) {
3356 g_MainToolbar->GetToolbar()->SetToolBitmapsSVG(
3357 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3361 void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3363 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3366 UseNativeStatusBar(
false);
3369 if (g_bShowStatusBar) {
3370 if (!m_pStatusBar) {
3372 CreateStatusBar(m_StatusBarFieldCount, 0);
3373 ApplyGlobalColorSchemetoStatusBar();
3378 m_pStatusBar->Destroy();
3379 m_pStatusBar = NULL;
3384 wxSize lastOptSize = options_lastWindowSize;
3390 options_lastWindowSize = lastOptSize;
3392 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3395 wxString _menuText(wxString name, wxString shortcut) {
3399 menutext << _T(
"\t") << shortcut;
3404 void MyFrame::BuildMenuBar(
void) {
3410 bool showMenuBar =
true;
3412 bool showMenuBar = g_bShowMenuBar;
3424 m_pMenuBar =
new wxMenuBar();
3425 RegisterGlobalMenuItems();
3426 SetMenuBar(m_pMenuBar);
3430 UpdateGlobalMenuItems();
3435 m_pMenuBar->Destroy();
3441 void MyFrame::RegisterGlobalMenuItems() {
3442 if (!m_pMenuBar)
return;
3444 wxMenu *nav_menu =
new wxMenu();
3445 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3446 _menuText(_(
"Auto Follow"), _T(
"Ctrl-A")));
3447 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3448 nav_menu->AppendSeparator();
3449 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3450 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3451 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3452 nav_menu->AppendSeparator();
3454 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"+")));
3455 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"-")));
3457 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"), _T(
"Alt-+")));
3458 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"), _T(
"Alt--")));
3460 nav_menu->AppendSeparator();
3461 nav_menu->Append(ID_MENU_SCALE_IN,
3462 _menuText(_(
"Larger Scale Chart"), _T(
"Ctrl-Left")));
3463 nav_menu->Append(ID_MENU_SCALE_OUT,
3464 _menuText(_(
"Smaller Scale Chart"), _T(
"Ctrl-Right")));
3466 nav_menu->AppendSeparator();
3467 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"), _T(
"Ctrl-Q")));
3469 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3471 wxMenu *view_menu =
new wxMenu();
3473 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3474 _menuText(_(
"Enable Chart Quilting"), _T(
"Q")));
3475 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3476 _menuText(_(
"Show Chart Outlines"), _T(
"O")));
3478 view_menu->AppendCheckItem(
3479 ID_MENU_CHART_QUILTING,
3480 _menuText(_(
"Enable Chart Quilting"), _T(
"Alt-Q")));
3481 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3482 _menuText(_(
"Show Chart Outlines"), _T(
"Alt-O")));
3484 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3485 _menuText(_(
"Show Chart Bar"), _T(
"Ctrl-B")));
3487 view_menu->AppendSeparator();
3489 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3490 _menuText(_(
"Show ENC text"), _T(
"T")));
3491 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3492 _menuText(_(
"Show ENC Lights"), _T(
"L")));
3493 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3494 _menuText(_(
"Show ENC Soundings"), _T(
"S")));
3495 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3496 _menuText(_(
"Show ENC Anchoring Info"), _T(
"A")));
3497 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3498 _menuText(_(
"Show ENC Data Quality"), _T(
"U")));
3499 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3500 _menuText(_(
"Show Navobjects"), _T(
"V")));
3502 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3503 _menuText(_(
"Show ENC text"), _T(
"Alt-T")));
3504 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3505 _menuText(_(
"Show ENC Lights"), _T(
"Alt-L")));
3506 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3507 _menuText(_(
"Show ENC Soundings"), _T(
"Alt-S")));
3508 view_menu->AppendCheckItem(
3509 ID_MENU_ENC_ANCHOR, _menuText(_(
"Show ENC Anchoring Info"), _T(
"Alt-A")));
3510 view_menu->AppendCheckItem(
3511 ID_MENU_ENC_DATA_QUALITY,
3512 _menuText(_(
"Show ENC Data Quality"), _T(
"Alt-U")));
3513 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3514 _menuText(_(
"Show Navobjects"), _T(
"Alt-V")));
3516 view_menu->AppendSeparator();
3517 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3518 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3519 view_menu->AppendSeparator();
3521 view_menu->Append(ID_MENU_UI_COLSCHEME,
3522 _menuText(_(
"Change Color Scheme"), _T(
"C")));
3524 view_menu->Append(ID_MENU_UI_COLSCHEME,
3525 _menuText(_(
"Change Color Scheme"), _T(
"Alt-C")));
3528 view_menu->AppendSeparator();
3530 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3531 _menuText(_(
"Toggle Full Screen"), _T(
"F11")));
3533 m_pMenuBar->Append(view_menu, _(
"&View"));
3535 wxMenu *ais_menu =
new wxMenu();
3536 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3537 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3538 _(
"Attenuate less critical AIS targets"));
3539 ais_menu->AppendSeparator();
3540 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3541 _(
"Hide Moored AIS Targets"));
3542 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3543 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3544 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3547 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3548 _menuText(_(
"Show CPA Warnings"), _T(
"W")));
3550 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3551 _menuText(_(
"Show CPA Warnings"), _T(
"Alt-W")));
3554 ais_menu->AppendSeparator();
3555 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") + _T(
"..."));
3556 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3558 wxMenu *tools_menu =
new wxMenu();
3560 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3561 _menuText(_(
"Measure Distance"), _T(
"M")));
3563 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3564 _menuText(_(
"Measure Distance"), _T(
"Alt-M")));
3567 tools_menu->AppendSeparator();
3568 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3569 tools_menu->Append(ID_MENU_ROUTE_NEW,
3570 _menuText(_(
"Create Route"), _T(
"Ctrl-R")));
3571 tools_menu->AppendSeparator();
3572 tools_menu->Append(ID_MENU_MARK_BOAT,
3573 _menuText(_(
"Drop Mark at Boat"), _T(
"Ctrl-O")));
3574 tools_menu->Append(ID_MENU_MARK_CURSOR,
3575 _menuText(_(
"Drop Mark at Cursor"), _T(
"Ctrl-M")));
3576 tools_menu->AppendSeparator();
3581 _(
"Drop MOB Marker"),
3582 _T(
"RawCtrl-Space")));
3583 tools_menu->AppendSeparator();
3584 tools_menu->Append(wxID_PREFERENCES,
3585 _menuText(_(
"Preferences") + _T(
"..."), _T(
"Ctrl-,")));
3587 tools_menu->Append(ID_MENU_MARK_MOB,
3588 _menuText(_(
"Drop MOB Marker"), _T(
"Ctrl-Space")));
3589 tools_menu->AppendSeparator();
3590 tools_menu->Append(wxID_PREFERENCES,
3591 _menuText(_(
"Options") + _T(
"..."), _T(
"Ctrl-,")));
3593 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3596 wxMenu *window_menu =
new wxMenu();
3597 m_pMenuBar->Append(window_menu, _(
"&Window"));
3600 wxMenu *help_menu =
new wxMenu();
3601 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3602 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3603 m_pMenuBar->Append(help_menu, _(
"&Help"));
3606 UpdateGlobalMenuItems();
3609 void MyFrame::UpdateGlobalMenuItems() {
3610 if (!m_pMenuBar)
return;
3612 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3613 ->Check(GetPrimaryCanvas()->m_bFollow);
3614 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3615 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3616 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3617 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3618 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3619 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3620 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3621 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3622 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3623 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3624 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3625 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3626 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3627 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3628 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3629 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3630 if (g_bAIS_CPA_Alert) {
3631 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3632 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3635 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3636 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3639 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3640 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3641 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3644 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3645 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3646 ->Check(ps52plib->GetShowSoundings());
3648 bool light_state =
false;
3650 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3652 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3653 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3654 light_state = (pOLE->nViz == 1);
3659 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3660 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3664 DisCat nset = ps52plib->GetDisplayCategory();
3665 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3666 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3667 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3668 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3669 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3670 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3671 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3673 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3674 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3675 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3680 void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3681 if (!m_pMenuBar)
return;
3683 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3685 if (cc->GetUpMode() == NORTH_UP_MODE)
3686 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3687 else if (cc->GetUpMode() == COURSE_UP_MODE)
3688 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3690 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3692 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3693 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3694 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3695 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3696 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3697 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3698 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3699 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3700 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3701 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3702 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3703 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3704 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3705 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3706 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3709 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3710 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3713 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3715 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3716 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3721 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3725 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3726 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3727 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3728 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3729 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3730 ->Check(cc->GetShowENCDataQual());
3731 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3733 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3734 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3735 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3740 void MyFrame::InvalidateAllCanvasUndo() {
3742 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3744 if (cc) cc->undo->InvalidateUndo();
3748 void MyFrame::SubmergeAllCanvasToolbars(
void) {
3750 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3752 if (cc) cc->SubmergeToolbar();
3756 void MyFrame::SurfaceAllCanvasToolbars(
void) {
3757 if (g_bshowToolbar) {
3759 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3761 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3768 void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3770 if (lon > 180.0) lon -= 360.0;
3775 cc->JumpToPosition(lat, lon,
scale);
3778 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3782 void MyFrame::UpdateCanvasConfigDescriptors() {
3784 for (
unsigned int i = 0; i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3785 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3789 cc->iLat = chart->GetVP().clat;
3790 cc->iLon = chart->GetVP().clon;
3791 cc->iRotation = chart->GetVP().rotation;
3792 cc->iScale = chart->GetVP().view_scale_ppm;
3793 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3794 cc->GroupID = chart->m_groupIndex;
3795 cc->canvasSize = chart->GetSize();
3797 cc->bQuilt = chart->GetQuiltMode();
3798 cc->bShowTides = chart->GetbShowTide();
3799 cc->bShowCurrents = chart->GetbShowCurrent();
3800 cc->bShowGrid = chart->GetShowGrid();
3801 cc->bShowOutlines = chart->GetShowOutlines();
3802 cc->bShowDepthUnits = chart->GetShowDepthUnits();
3804 cc->bFollow = chart->m_bFollow;
3805 cc->bLookahead = chart->m_bLookAhead;
3806 cc->bCourseUp =
false;
3807 cc->bHeadUp =
false;;
3808 int upmode = chart->GetUpMode();
3809 if (upmode == COURSE_UP_MODE)
3810 cc->bCourseUp =
true;
3811 else if (upmode == HEAD_UP_MODE)
3818 void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3819 if (!RBBox.GetValid())
return;
3821 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3822 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3825 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3826 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3828 ppm = cc->GetVPScale();
3834 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3835 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3837 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3838 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3840 cc->GetSize(&ww, &wh);
3842 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3844 ppm = wxMin(ppm, 1.0);
3847 JumpToPosition(cc, clat, clon, ppm);
3850 int MyFrame::DoOptionsDialog() {
3851 if (g_boptionsactive)
return 0;
3853 g_boptionsactive =
true;
3854 g_last_ChartScaleFactor = g_ChartScaleFactor;
3856 if (NULL == g_options) {
3857 AbstractPlatform::ShowBusySpinner();
3860 pConfig->SetPath(
"/Settings");
3861 pConfig->Read(
"OptionsSizeX", &sx, -1);
3862 pConfig->Read(
"OptionsSizeY", &sy, -1);
3864 wxWindow *optionsParent =
this;
3866 optionsParent = GetPrimaryCanvas();
3869 new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1), wxSize(sx, sy));
3871 AbstractPlatform::HideBusySpinner();
3875 g_options->SetInitChartDir(*pInit_Chart_Dir);
3878 g_options->SetCurrentDirList(ChartData->GetChartDirArray());
3879 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
3880 g_options->SetWorkDirListPtr(pWorkDirArray);
3883 g_options->SetConfigPtr(pConfig);
3885 g_options->SetInitialSettings();
3887 prev_locale = g_locale;
3891 if (g_MainToolbar && g_MainToolbar->IsShown()) {
3892 wxRect bx_rect = g_options->GetScreenRect();
3893 wxRect tb_rect = g_MainToolbar->GetScreenRect();
3894 if (tb_rect.Intersects(bx_rect)) b_sub =
true;
3896 if (b_sub) g_MainToolbar->Submerge();
3900 #if defined(__WXOSX__) || defined(__WXQT__)
3901 bool b_restoreAIS =
false;
3902 if (g_pAISTargetList && g_pAISTargetList->IsShown()) {
3903 b_restoreAIS =
true;
3904 g_pAISTargetList->Shutdown();
3905 g_pAISTargetList = NULL;
3911 g_MainToolbar->Submerge();
3914 g_options->SetInitialPage(options_lastPage, options_subpage);
3917 g_options->lastWindowPos = options_lastWindowPos;
3918 if (options_lastWindowPos != wxPoint(0, 0)) {
3919 g_options->Move(options_lastWindowPos);
3920 g_options->SetSize(options_lastWindowSize);
3922 g_options->CenterOnScreen();
3924 if (options_lastWindowSize != wxSize(0, 0)) {
3925 g_options->SetSize(options_lastWindowSize);
3931 if (options_lastWindowSize != wxSize(0, 0))
3932 g_options->SetSize(options_lastWindowSize.x - 1, options_lastWindowSize.y);
3937 if (g_MainToolbar) g_MainToolbar->DisableTooltips();
3940 androidEnableBackButton(
false);
3941 androidEnableOptionsMenu(
false);
3942 androidDisableFullScreen();
3946 unsigned int last_canvasConfig = g_canvasConfig;
3947 wxSize cc1SizeBefore;
3948 if (g_canvasConfig > 0) {
3949 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
3950 if (cc) cc1SizeBefore = g_canvasArray.Item(0)->GetSize();
3955 wxArrayString pathArray;
3956 double restoreScale[4];
3959 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3962 wxString chart_file_name;
3963 if (cc->GetQuiltMode()) {
3964 int dbi = cc->GetQuiltRefChartdbIndex();
3965 chart_file_name = ChartData->GetDBChartFileName(dbi);
3967 if (cc->m_singleChart)
3968 chart_file_name = cc->m_singleChart->GetFullPath();
3971 pathArray.Add(chart_file_name);
3972 restoreScale[i] = cc->GetVPScale();
3976 int rr = g_options->ShowModal();
3979 androidEnableBackButton(
true);
3980 androidEnableOptionsMenu(
true);
3981 androidRestoreFullScreen();
3982 androidEnableRotation();
3985 if (g_MainToolbar) g_MainToolbar->EnableTooltips();
3987 options_lastPage = g_options->lastPage;
3992 if (options_lastPage == 1) options_lastPage = 0;
3995 options_subpage = g_options->lastSubPage;
3997 options_lastWindowPos = g_options->lastWindowPos;
3998 options_lastWindowSize = g_options->lastWindowSize;
4002 g_MainToolbar->SetDockX(-1);
4003 g_MainToolbar->SetDockY(-1);
4007 GetPrimaryCanvas()->SetFocus();
4014 bool ret_val =
false;
4015 rr = g_options->GetReturnCode();
4017 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
4019 bool b_refresh =
true;
4022 bool ccRightSizeChanged =
false;
4023 if( g_canvasConfig > 0 ){
4026 wxSize cc1Size = cc->canvasSize;
4027 if(cc1Size.x != cc1SizeBefore.x)
4028 ccRightSizeChanged =
true;
4033 if ((g_canvasConfig != last_canvasConfig) || (rr & GL_CHANGED)) {
4034 DestroyPersistentDialogs();
4036 UpdateCanvasConfigDescriptors();
4038 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
4039 CreateCanvasLayout(
true);
4041 CreateCanvasLayout();
4045 g_pauimgr->Update();
4052 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4054 if (cc) cc->CreateMUIBar();
4057 rr |= GENERIC_CHANGED;
4079 if (rr & CONFIG_CHANGED) {
4082 for (
unsigned int i = 0; i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
4083 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
4087 chartCanvas->ApplyCanvasConfig(cc);
4094 bDBUpdateInProgress =
true;
4095 b_refresh |= ProcessOptionsDialog(rr, g_options->GetWorkDirListPtr());
4096 ChartData->GetChartDirArray() =
4097 *(g_options->GetWorkDirListPtr());
4099 bDBUpdateInProgress =
false;
4103 delete pWorkDirArray;
4109 SetGPSCompassScale();
4111 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4114 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4115 cc->UpdateCanvasControlBar();
4118 UpdateGPSCompassStatusBoxes();
4120 SetAllToolbarScale();
4121 RequestNewToolbars();
4125 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4128 cc->RebuildCursors();
4133 bool b_masterScaleChange =
false;
4134 if (fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4135 b_masterScaleChange =
true;
4137 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4138 RequestNewMasterToolbar(
true);
4140 bool bMuiChange =
false;
4146 if (b_masterScaleChange || bMuiChange) {
4148 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4151 cc->ProcessNewGUIScale();
4156 if (g_MainToolbar) {
4157 if (IsFullScreen() && !g_bFullscreenToolbar) g_MainToolbar->Submerge();
4160 #if defined(__WXOSX__) || defined(__WXQT__)
4163 g_pAISTargetList->UpdateAISTargetList();
4167 if (console && console->IsShown()) console->Raise();
4169 auto alert_dlg_active =
4171 if (alert_dlg_active) alert_dlg_active->Raise();
4173 if (NMEALogWindow::GetInstance().Active())
4174 NMEALogWindow::GetInstance().GetTTYWindow()->Raise();
4177 if (g_pi_manager) g_pi_manager->NotifyAuiPlugIns();
4182 if ((rr & FONT_CHANGED) || (rr & NEED_NEW_OPTIONS)) {
4189 if (g_pMarkInfoDialog) {
4190 g_pMarkInfoDialog->Hide();
4191 g_pMarkInfoDialog->Destroy();
4192 g_pMarkInfoDialog = NULL;
4196 if (rr & LOCALE_CHANGED) {
4197 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4207 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4210 int index_hint = -1;
4211 if (i < pathArray.GetCount())
4212 index_hint = ChartData->FinddbIndex(pathArray.Item(i));
4213 cc->canvasChartsRefresh(index_hint);
4214 if (index_hint != -1) cc->SetVPScale(restoreScale[i]);
4219 g_boptionsactive =
false;
4222 if (rr & CONFIG_CHANGED) {
4223 options_subpage = 3;
4224 ScheduleSettingsDialog();
4226 options_subpage = 0;
4231 bool MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4232 bool b_need_refresh =
false;
4234 if ((rr & VISIT_CHARTS) &&
4235 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4237 UpdateChartDatabaseInplace(*pNewDirArray,
4238 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4241 b_need_refresh =
true;
4245 if (rr & STYLE_CHANGED) {
4248 _(
"Please restart OpenCPN to activate language or style changes."),
4249 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4252 bool b_groupchange =
false;
4253 if (((rr & VISIT_CHARTS) &&
4254 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4255 (rr & GROUPS_CHANGED)) {
4256 b_groupchange = ScrubGroupArray();
4257 ChartData->ApplyGroupArray(g_pGroupArray);
4258 RefreshGroupIndices();
4261 if (rr & GROUPS_CHANGED || b_groupchange) {
4262 pConfig->DestroyConfigGroups();
4263 pConfig->CreateConfigGroups(g_pGroupArray);
4266 if (rr & TIDES_CHANGED) {
4272 if (rr & S52_CHANGED) {
4273 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4276 pConfig->UpdateSettings();
4278 if (g_pActiveTrack) {
4279 g_pActiveTrack->SetPrecision(g_nTrackPrecision);
4293 if( !std::isnan(gCog) ) stuff = gCog;
4294 if( g_COGAvgSec > 0 ) {
4295 for(
int i = 0; i < g_COGAvgSec; i++ )
4296 COGTable[i] = stuff;
4306 g_pRouteMan->SetColorScheme(global_color_scheme,
4307 g_Platform->GetDisplayDPmm());
4310 double stuffcog = NAN;
4311 double stuffsog = NAN;
4312 if (!std::isnan(gCog)) stuffcog = gCog;
4313 if (!std::isnan(gSog)) stuffsog = gSog;
4315 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4316 COGFilterTable[i] = stuffcog;
4317 SOGFilterTable[i] = stuffsog;
4320 SetChartUpdatePeriod();
4322 if (rr & GL_CHANGED) {
4326 b_need_refresh =
true;
4329 if (rr & S52_CHANGED) {
4330 b_need_refresh =
true;
4334 if (rr & REBUILD_RASTER_CACHE) {
4335 if (g_glTextureManager) {
4336 GetPrimaryCanvas()->Disable();
4337 g_glTextureManager->BuildCompressedCache();
4338 GetPrimaryCanvas()->Enable();
4343 if (g_config_display_size_manual && g_config_display_size_mm.size() > g_current_monitor && g_config_display_size_mm[g_current_monitor] > 0) {
4344 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
4346 g_display_size_mm = wxMax(50, g_Platform->GetDisplaySizeMM());
4349 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4351 if (cc) cc->SetDisplaySizeMM(g_display_size_mm);
4355 g_pi_manager->SendBaseConfigToAllPlugIns();
4356 int rrt = rr & S52_CHANGED;
4357 g_pi_manager->SendS52ConfigToAllPlugIns(
4358 (rrt == S52_CHANGED) ||
4359 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4362 if (g_MainToolbar) {
4363 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4364 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4369 ps52plib->SetScaleFactorExp(g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4370 ps52plib-> SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4374 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4376 if (cc) cc->ApplyGlobalSettings();
4383 int index_hint = ChartData->FinddbIndex( chart_file_name );
4384 if( -1 == index_hint )
4393 bool ztc = g_bEnableZoomToCursor;
4394 g_bEnableZoomToCursor =
4398 GetPrimaryCanvas()->DoZoomCanvas(1.0001);
4400 g_bEnableZoomToCursor = ztc;
4402 g_last_ChartScaleFactor = g_ChartScaleFactor;
4404 return b_need_refresh;
4407 bool MyFrame::CheckGroup(
int igroup) {
4408 if (igroup == 0)
return true;
4410 ChartGroup *pGroup = g_pGroupArray->Item(igroup - 1);
4412 if (!pGroup->m_element_array.size())
4415 for (
const auto &elem : pGroup->m_element_array) {
4416 for (
unsigned int ic = 0;
4417 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4419 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4421 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4428 bool MyFrame::ScrubGroupArray() {
4433 bool b_change =
false;
4434 unsigned int igroup = 0;
4435 while (igroup < g_pGroupArray->GetCount()) {
4436 bool b_chart_in_element =
false;
4437 ChartGroup *pGroup = g_pGroupArray->Item(igroup);
4439 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4440 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4442 for (
unsigned int ic = 0;
4443 ic < (
unsigned int)ChartData->GetChartTableEntries(); ic++) {
4445 wxString chart_full_path = pcte->GetFullSystemPath();
4447 if (chart_full_path.StartsWith(element_root)) {
4448 b_chart_in_element =
true;
4454 if (!b_chart_in_element) {
4455 wxString test_string = _T(
"GSHH");
4456 if (element_root.Upper().Contains(test_string))
4457 b_chart_in_element =
true;
4460 if (!b_chart_in_element)
4462 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4474 void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4476 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4478 if (cc && (cc != ccThis)) cc->Refresh();
4483 void MyFrame::ChartsRefresh() {
4484 if (!ChartData)
return;
4486 AbstractPlatform::ShowBusySpinner();
4488 bool b_run = FrameTimer1.IsRunning();
4493 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4496 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4497 if (cc->GetQuiltMode()) {
4498 currentIndex = cc->GetQuiltReferenceChartIndex();
4500 cc->canvasChartsRefresh(currentIndex);
4504 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4506 AbstractPlatform::HideBusySpinner();
4509 void MyFrame::InvalidateAllQuilts() {
4510 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4513 cc->InvalidateQuilt();
4514 cc->SetQuiltRefChart(-1);
4515 cc->m_singleChart = NULL;
4520 bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4522 const wxString &ChartListFileName) {
4523 bool b_run = FrameTimer1.IsRunning();
4525 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4526 FrameCOGTimer.Stop();
4529 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4532 cc->InvalidateQuilt();
4533 cc->SetQuiltRefChart(-1);
4534 cc->m_singleChart = NULL;
4538 ChartData->PurgeCache();
4544 AbstractPlatform::ShowBusySpinner();
4546 wxGenericProgressDialog *pprog =
nullptr;
4548 wxString longmsg = _(
"OpenCPN Chart Update");
4550 _T(
"..................................................................")
4553 pprog = new wxGenericProgressDialog();
4555 wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
4556 pprog->SetFont(*qFont);
4558 pprog->Create(_("OpenCPN Chart Update"), longmsg, 100, gFrame,
4559 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4560 wxPD_REMAINING_TIME);
4566 wxLogMessage(_T(" "));
4567 wxLogMessage(_T("Starting chart database Update..."));
4568 wxString gshhg_chart_loc = gWorldMapLocation;
4569 gWorldMapLocation = wxEmptyString;
4570 ChartData->Update(DirArray, b_force, pprog);
4571 ChartData->SaveBinary(ChartListFileName);
4572 wxLogMessage(_T("Finished chart database Update"));
4573 wxLogMessage(_T(" "));
4574 if (gWorldMapLocation.empty()) {
4578 gWorldMapLocation = gDefaultWorldMapLocation;
4579 gshhg_chart_loc = wxEmptyString;
4582 if (gWorldMapLocation != gshhg_chart_loc) {
4584 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4586 if (cc) cc->ResetWorldBackgroundChart();
4592 AbstractPlatform::HideBusySpinner();
4594 pConfig->UpdateChartDirs(DirArray);
4597 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4598 if (b_runCOGTimer) {
4600 int period_ms = 100;
4601 if (g_COGAvgSec > 0) period_ms = g_COGAvgSec * 1000;
4602 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4609 cc->ToggleCanvasQuiltMode();
4611 bool cur_mode = cc->GetQuiltMode();
4613 if( !cc->GetQuiltMode() )
4614 cc->SetQuiltMode(
true );
4616 if( cc->GetQuiltMode() ) {
4617 cc->SetQuiltMode(
false );
4618 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4622 if( cur_mode != cc->GetQuiltMode() ){
4628 g_bQuiltEnable = cc->GetQuiltMode();
4632 ps52plib->GenerateStateHash();
4637 void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4639 void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4641 void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4643 cc->DoCanvasStackDelta(direction);
4647 void MyFrame::PositionIENCToolbar() {
4649 if (g_iENCToolbar) {
4651 posn.x = (GetPrimaryCanvas()->GetSize().x - g_iENCToolbar->GetSize().x) / 2;
4653 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4661 void MyFrame::OnInitTimer(wxTimerEvent &event) {
4664 msg.Printf(_T(
"OnInitTimer...%d"), m_iInitCount);
4667 wxLog::FlushActive();
4669 switch (m_iInitCount++) {
4671 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4673 if (g_bInlandEcdis) {
4674 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4675 double range_set = 500.;
4677 range = wxRound(range * 10) / 10.;
4681 else if (range > 2000.)
4683 else if (range > 1600.)
4685 else if (range > 1200.)
4687 else if (range > 800.)
4692 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4696 g_Platform->SetFullscreen(g_bFullscreen);
4699 if (g_NeedDBUpdate > 0) {
4700 RebuildChartDatabase();
4701 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4704 cc->SetGroupIndex(0,
false);
4712 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4713 CHART_FAMILY_RASTER)) {
4716 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4718 if (ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4719 CHART_FAMILY_VECTOR)) {
4722 gFrame->ClearbFollow(gFrame->GetPrimaryCanvas());
4731 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4733 WayPointmanGui(*pWayPointMan).SetColorScheme(global_color_scheme,
4734 g_Platform->GetDisplayDPmm());
4736 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4739 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4743 pConfig->LoadNavObjects();
4745 if (!g_AW1GUID.IsEmpty()) {
4746 pAnchorWatchPoint1 = pWayPointMan->FindRoutePointByGUID(g_AW1GUID);
4748 if (!g_AW2GUID.IsEmpty()) {
4749 pAnchorWatchPoint2 = pWayPointMan->FindRoutePointByGUID(g_AW2GUID);
4754 appendOSDirSlash(&layerdir);
4755 layerdir.Append(_T(
"layers"));
4757 if (wxDir::Exists(layerdir)) {
4759 laymsg.Printf(wxT(
"Getting .gpx layer files from: %s"),
4761 wxLogMessage(laymsg);
4762 pConfig->LoadLayers(layerdir);
4770 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
4773 auto driver = MakeCommDriver(cp);
4774 cp->b_IsSetup = TRUE;
4779 console->SetColorScheme(global_color_scheme);
4783 if (g_pRouteMan->IsAnyRouteActive()){
4784 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
4791 if (m_initializing)
break;
4792 m_initializing =
true;
4793 AbstractPlatform::ShowBusySpinner();
4795 AbstractPlatform::HideBusySpinner();
4797 RequestNewMasterToolbar();
4800 if (pWayPointMan)
WayPointmanGui(*pWayPointMan).ReloadRoutepointIcons();
4802 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
false);
4804 wxString perspective;
4805 pConfig->SetPath(_T (
"/AUI" ));
4806 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
4813 bool bno_load =
false;
4815 wxArrayString name_array;
4816 wxStringTokenizer st(perspective, _T(
"|;"));
4817 while (st.HasMoreTokens()) {
4818 wxString s1 = st.GetNextToken();
4819 if (s1.StartsWith(_T(
"name="))) {
4820 wxString sc = s1.AfterFirst(
'=');
4825 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
4826 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
4827 wxAuiPaneInfo pane = pane_array_val.Item(i);
4831 if (name_array.Index(pane.name) == wxNOT_FOUND) {
4837 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
4841 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4844 g_pauimgr->GetPane(cc).MinSize(10,10);
4851 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4854 wxSize frameSize = GetClientSize();
4855 wxSize minSize = g_pauimgr->GetPane(cc).min_size;
4856 int width = wxMax(minSize.x, frameSize.x / 10);
4857 g_pauimgr->GetPane(cc).MinSize(frameSize.x * 1 / 5, frameSize.y);
4860 g_pauimgr->Update();
4864 g_pi_manager->NotifyAuiPlugIns();
4867 g_pi_manager ->ShowDeferredBlacklistMessages();
4869 g_pi_manager->CallLateInit();
4874 if (g_pi_manager->IsAnyPlugInChartEnabled()) {
4875 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4877 if (cc) cc->SetFirstAuto(
true);
4880 b_reloadForPlugins =
true;
4887 if (g_MainToolbar) {
4888 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
4889 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
4895 for(
unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
4897 cc->RequestNewCanvasToolbar(
true );
4899 if(cc && cc->GetToolbarEnable()){
4900 cc->GetToolbar()->SetAutoHide(g_bAutoHideToolbar);
4901 cc->GetToolbar()->SetAutoHideTimer(g_nAutoHideToolbar);
4911 pConfig->SetPath(
"/Settings");
4912 pConfig->Read(
"OptionsSizeX", &sx, -1);
4913 pConfig->Read(
"OptionsSizeY", &sy, -1);
4915 wxWindow *optionsParent =
this;
4917 optionsParent = GetPrimaryCanvas();
4920 new options(optionsParent, -1, _(
"Options"), wxPoint(-1, -1), wxSize(sx, sy));
4922 BuildiENCToolbar(
true);
4929 if (!g_params.empty()) {
4930 for (
size_t n = 0; n < g_params.size(); n++) {
4931 wxString path = g_params[n];
4932 if (::wxFileExists(path)) {
4934 pSet->load_file(path.fn_str());
4937 pSet->LoadAllGPXObjects(
4938 !pSet->IsOpenCPN(), wpt_dups,
4940 LLBBox box = pSet->GetBBox();
4941 if (box.GetValid()) {
4942 CenterView(GetPrimaryCanvas(), box);
4951 InitAppMsgBusListener();
4959 wxLogMessage(_T(
"OnInitTimer...Last Call"));
4961 PositionIENCToolbar();
4963 g_bDeferredInitDone =
true;
4965 GetPrimaryCanvas()->SetFocus();
4966 g_focusCanvas = GetPrimaryCanvas();
4972 if (b_reloadForPlugins) {
4977 wxLogMessage(_T(
"OnInitTimer...Finalize Canvases"));
4979 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4983 cc->CheckGroupValid();
4988 androidEnableBackButton(
true);
4989 androidEnableRotation();
4990 androidEnableOptionItems(
true);
4994 if (g_MainToolbar) g_MainToolbar->EnableTool(ID_SETTINGS,
true);
5004 if (!g_bDeferredInitDone) InitTimer.Start(100, wxTIMER_ONE_SHOT);
5006 wxLog::FlushActive();
5008 RefreshAllCanvas(
true);
5009 wxGetApp().m_usb_watcher.Start();
5015 void MyFrame::InitAppMsgBusListener() {
5016 auto &msgbus = AppMsgBus::GetInstance();
5019 AppMsg msg_basic(AppMsg::Type::BasicNavData);
5020 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
5023 auto ptr = ev.GetSharedPtr();
5024 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
5025 HandleBasicNavMsg( basicnav_msg );
5029 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
5030 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
5033 auto ptr = ev.GetSharedPtr();
5034 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
5035 HandleGPSWatchdogMsg(msg);
5043 void MyFrame::ReleaseApiListeners() {}
5048 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt){ Raise(); });
5049 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt){ FastClose(); });
5050 server.SetGetRestApiEndpointCb(
5051 [&]{
return wxGetApp().m_rest_server.GetEndpoint(); });
5052 server.open_file_cb =
5053 [](
const std::string& path) {
return wxGetApp().OpenFile(path); };
5060 void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
5062 if (msg->gps_watchdog <= 0){
5063 if (msg->wd_source == GPSWatchdogMsg::WDSource::position){
5064 bool last_bGPSValid = bGPSValid;
5067 if (last_bGPSValid != bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5069 else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity){
5070 bool last_bVelocityValid = bVelocityValid;
5071 bVelocityValid =
false;
5078 void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5079 m_fixtime = msg->time;
5082 if (!std::isnan(gCog)) {
5083 if (g_COGAvgSec > 0) {
5085 for (
int i = g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5088 double sum = 0., count = 0;
5089 for (
int i = 0; i < g_COGAvgSec; i++) {
5090 double adder = COGTable[i];
5091 if (std::isnan(adder))
continue;
5093 if (fabs(adder - g_COGAvg) > 180.) {
5094 if ((adder - g_COGAvg) > 0.)
5107 else if (sum >= 360.)
5119 if (gSog > 3.0) g_bCruising =
true;
5126 bool last_bGPSValid = bGPSValid;
5127 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5128 if ((msg->vflag & POS_VALID) == POS_VALID)
5133 if (last_bGPSValid != bGPSValid)
5134 UpdateGPSCompassStatusBoxes(
true);
5136 bVelocityValid =
true;
5140 #ifdef ocpnUPDATE_SYSTEM_TIME
5144 if (!m_bTimeIsSet) {
5145 if (!s_bSetSystemTime) {
5146 m_bTimeIsSet =
true;
5149 wxDateTime Fix_Time(wxDateTime::Now());
5151 if (6 == sfixtime.Len() ||
5152 6 == sfixtime.find(
'.')) {
5155 a = sfixtime.Mid(0, 2);
5156 if (a.ToLong(&b)) Fix_Time.SetHour((wxDateTime::wxDateTime_t)b);
5157 a = sfixtime.Mid(2, 2);
5158 if (a.ToLong(&b)) Fix_Time.SetMinute((wxDateTime::wxDateTime_t)b);
5159 a = sfixtime.Mid(4, 2);
5160 if (a.ToLong(&b)) Fix_Time.SetSecond((wxDateTime::wxDateTime_t)b);
5164 time_t TimeOff = Fix_Time.GetTicks() - wxDateTime::Now().GetTicks();
5166 if (g_bHasHwClock) {
5169 if ((abs(TimeOff) > 20) && (abs(TimeOff) < 7200)) {
5171 msg.Printf(_T(
"Setting system time, delta t is %d seconds"), TimeOff);
5175 Fix_Time = Fix_Time.ToGMT();
5178 const wxDateTime::Tm tm(Fix_Time.GetTm());
5180 stm.wYear = (WXWORD)tm.year;
5181 stm.wMonth = (WXWORD)(tm.mon - wxDateTime::Jan + 1);
5184 stm.wHour = Fix_Time.GetHour();
5185 stm.wMinute = tm.min;
5186 stm.wSecond = tm.sec;
5187 stm.wMilliseconds = 0;
5189 ::SetSystemTime(&stm);
5195 wxString CommandStr(
"sudo /bin/date +%T --utc --set=\"");
5196 CommandStr.Append(Fix_Time.Format(
"%T"));
5197 CommandStr.Append(
"\"");
5198 msg.Printf(_T(
"Linux command is:"));
5201 wxExecute(CommandStr, wxEXEC_ASYNC);
5204 m_bTimeIsSet =
true;
5206 if (gRmcDate.Len() == 6) {
5207 #if !defined(__WXMSW__)
5210 Fix_Time.SetMonth((wxDateTime::Month)2);
5211 a = gRmcDate.Mid(0, 2);
5212 if (a.ToLong(&b)) Fix_Time.SetDay(b);
5213 a = gRmcDate.Mid(2, 2);
5214 if (a.ToLong(&b)) Fix_Time.SetMonth((wxDateTime::Month)(b - 1));
5215 a = gRmcDate.Mid(4, 2);
5217 Fix_Time.SetYear(b + 2000);
5219 wxString CommandStr(
"sudo /bin/date --utc --set=\"");
5220 CommandStr.Append(Fix_Time.Format(
"%D %T\""));
5221 msg.Printf(_T(
"Set Date/Time, Linux command is: %s"), CommandStr);
5223 wxExecute(CommandStr, wxEXEC_ASYNC);
5225 m_bTimeIsSet =
true;
5234 void MyFrame::UpdateStatusBar() {
5237 unsigned long uiCurrentTickCount;
5238 m_MMEAeventTime.SetToCurrent();
5239 uiCurrentTickCount =
5240 m_MMEAeventTime.GetMillisecond() / 100;
5241 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5242 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5243 m_ulLastNMEATicktime = uiCurrentTickCount;
5245 if (m_tick_idx++ > 6) m_tick_idx = 0;
5250 if (NULL != GetStatusBar()) {
5253 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5256 wxString s1(tick_buf, wxConvUTF8);
5258 s1 += toSDMM(1, gLat);
5260 s1 += toSDMM(2, gLon);
5262 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5266 if (!std::isnan(gSog))
5267 sogcog.Printf(_T(
"SOG %2.2f ") + getUsrSpeedUnit() + _T(
" "),
5270 sogcog.Printf(_T(
"SOG --- "));
5274 if (!std::isnan(gCog) && !std::isnan(gSog) && (gSog > 0.05)) {
5276 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)gCog, 0x00B0);
5278 cogs << wxString::Format(wxString(
"COG %03d%c(M) "), (
int)toMagnetic(gCog),
5281 cogs.Printf((
"COG ---%c"), 0x00B0);
5283 sogcog.Append(cogs);
5284 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5291 void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5292 MemFootTimer.Stop();
5294 int memsize = GetApplicationMemoryUse();
5297 printf(
"Memsize: %d \n", memsize);
5300 if (memsize > (g_MemFootMB * 1000)) {
5302 if (ChartData && cc) {
5304 wxArrayPtrVoid *pCache = ChartData->GetChartCache();
5305 unsigned int nCache = pCache->GetCount();
5308 for (
unsigned int i = 0; i < nCache; i++) {
5318 for (
unsigned int i = 0; i < nCache - 1; i++) {
5319 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5321 pcea[i] = pcea[i + 1];
5332 unsigned int idelete = 0;
5333 unsigned int idelete_max = pCache->GetCount();
5336 unsigned int minimum_cache = 1;
5337 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5339 while ((memsize > (g_MemFootMB * 1000)) &&
5340 (pCache->GetCount() > minimum_cache) &&
5341 (idelete < idelete_max)) {
5342 int memsizeb = memsize;
5344 ChartData->DeleteCacheChart((
ChartBase *)pcea[idelete].pChart);
5346 memsize = GetApplicationMemoryUse();
5347 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5355 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5360 void MyFrame::CheckToolbarPosition() {
5363 static bool bMaximized;
5365 if (IsMaximized() && !bMaximized) {
5367 if (g_MainToolbar) {
5368 g_MainToolbar->SetYAuxOffset(g_MainToolbar->GetToolSize().y * 15 / 10);
5369 g_MainToolbar->SetDefaultPosition();
5370 g_MainToolbar->Realize();
5372 PositionIENCToolbar();
5373 }
else if (!IsMaximized() && bMaximized) {
5375 if (g_MainToolbar) {
5376 g_MainToolbar->SetYAuxOffset(0);
5377 g_MainToolbar->SetDockY(-1);
5378 g_MainToolbar->SetDefaultPosition();
5379 g_MainToolbar->Realize();
5381 PositionIENCToolbar();
5387 CheckToolbarPosition();
5389 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5396 cc->m_bFollow =
false;
5397 if (g_MainToolbar && g_MainToolbar->GetToolbar())
5398 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5399 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5402 if (cc->m_groupIndex > 0) {
5403 while (ut_index < ChartData->GetChartTableEntries() &&
5404 !ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5408 if (ut_index < ChartData->GetChartTableEntries()) {
5410 const ChartTableEntry *cte = &ChartData->GetChartTableEntry(ut_index);
5412 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5413 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5418 cc->SetViewPoint(clat, clon);
5420 if (cc->GetQuiltMode()) {
5421 if (cc->IsChartQuiltableRef(ut_index))
5422 cc->SelectQuiltRefdbChart(ut_index);
5424 cc->SelectdbChart(ut_index);
5427 if (g_unit_test_1) {
5428 ppm = cc->GetCanvasScaleFactor() / cte->GetScale();
5435 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5436 cte->GetLatMin(), cte->GetLonMax(), NULL,
5440 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5441 cte->GetLatMax(), cte->GetLonMin(), NULL,
5444 cc->GetSize(&ww, &wh);
5445 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5447 ppm = wxMin(ppm, 1.0);
5449 cc->SetVPScale(ppm);
5454 if (ut_index > ut_index_max) exit(0);
5464 wxLogMessage(_T(
"Got quitflag from SIGNAL"));
5470 if (bDBUpdateInProgress)
return;
5476 if (g_bDeferredStartTrack) {
5477 if (!g_bTrackActive) {
5480 g_bDeferredStartTrack =
false;
5483 g_bDeferredStartTrack =
false;
5491 GPSData.kLat = gLat;
5492 GPSData.kLon = gLon;
5493 GPSData.kCog = gCog;
5494 GPSData.kSog = gSog;
5495 GPSData.kVar = gVar;
5496 GPSData.kHdm = gHdm;
5497 GPSData.kHdt = gHdt;
5498 GPSData.nSats = g_SatsInView;
5500 wxDateTime tCheck((time_t)m_fixtime);
5502 if (tCheck.IsValid())
5503 GPSData.FixTime = m_fixtime;
5505 GPSData.FixTime = wxDateTime::Now().GetTicks();
5507 g_pi_manager->SendPositionFixToAllPlugIns(&GPSData);
5512 if (pAnchorWatchPoint1) {
5515 DistanceBearingMercator(pAnchorWatchPoint1->m_lat,
5516 pAnchorWatchPoint1->m_lon, gLat, gLon, &brg, &dist);
5517 double d = g_nAWMax;
5518 (pAnchorWatchPoint1->GetName()).ToDouble(&d);
5519 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5520 bool toofar =
false;
5521 bool tooclose =
false;
5522 if (d >= 0.0) toofar = (dist * 1852. > d);
5523 if (d < 0.0) tooclose = (dist * 1852 < -d);
5525 if (tooclose || toofar)
5526 AnchorAlertOn1 =
true;
5528 AnchorAlertOn1 =
false;
5530 AnchorAlertOn1 =
false;
5532 if (pAnchorWatchPoint2) {
5535 DistanceBearingMercator(pAnchorWatchPoint2->m_lat,
5536 pAnchorWatchPoint2->m_lon, gLat, gLon, &brg, &dist);
5538 double d = g_nAWMax;
5539 (pAnchorWatchPoint2->GetName()).ToDouble(&d);
5540 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5541 bool toofar =
false;
5542 bool tooclose =
false;
5543 if (d >= 0) toofar = (dist * 1852. > d);
5544 if (d < 0) tooclose = (dist * 1852 < -d);
5546 if (tooclose || toofar)
5547 AnchorAlertOn2 =
true;
5549 AnchorAlertOn2 =
false;
5551 AnchorAlertOn2 =
false;
5553 if ((pAnchorWatchPoint1 || pAnchorWatchPoint2) && !bGPSValid)
5554 AnchorAlertOn1 =
true;
5559 wxDateTime lognow = wxDateTime::Now();
5560 int hourLOC = lognow.GetHour();
5561 int minuteLOC = lognow.GetMinute();
5563 int minuteUTC = lognow.GetMinute();
5564 int second = lognow.GetSecond();
5566 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5567 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5568 (minuteUTC == 30)) {
5569 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5570 wxString day = lognow.FormatISODate();
5571 wxString utc = lognow.FormatISOTime();
5572 wxString navmsg = _T(
"LOGBOOK: ");
5576 navmsg += _T(
" UTC ");
5580 data.Printf(_T(
" GPS Lat %10.5f Lon %10.5f "), gLat, gLon);
5584 if (std::isnan(gCog))
5585 cog.Printf(_T(
"COG ----- "));
5587 cog.Printf(_T(
"COG %10.5f "), gCog);
5590 if (std::isnan(gSog))
5591 sog.Printf(_T(
"SOG ----- "));
5593 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
5599 data.Printf(_T(
" DR Lat %10.5f Lon %10.5f"), gLat, gLon);
5602 wxLogMessage(navmsg);
5603 g_loglast_time = lognow;
5605 int bells = (hourLOC % 4) * 2;
5606 if (minuteLOC != 0) bells++;
5607 if (!bells) bells = 8;
5609 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5610 m_BellsToPlay = bells;
5611 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5612 wxPostEvent(
this, ev);
5617 if (ShouldRestartTrack()) TrackDailyRestart();
5620 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5621 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5629 wxString sogcog(_T(
"SOG --- ") + getUsrSpeedUnit() + +_T(
" ") +
5630 _T(
" COG ---\u00B0"));
5631 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5639 #if !defined(__WXGTK__) && !defined(__WXQT__)
5641 double cursor_lat, cursor_lon;
5642 GetPrimaryCanvas()->GetCursorLatLon( &cursor_lat, &cursor_lon );
5643 GetPrimaryCanvas()->SetCursorStatus(cursor_lat, cursor_lon);
5649 bool bnew_view =
false;
5653 if ( (0 != g_ChartUpdatePeriod)) {
5654 if (0 == m_ChartUpdatePeriod--) {
5655 bnew_view = DoChartUpdate();
5656 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
5664 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5667 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5670 cc->DrawBlinkObjects();
5673 if (bactiveRouteUpdate) {
5675 if (g_pRouteMan->GetpActiveRoute())
5676 cc->RefreshRect(g_blink_rect,
false);
5680 cc->SetOwnShipState(SHIP_NORMAL);
5682 if (cc->GetQuiltMode()) {
5683 double erf = cc->GetQuiltMaxErrorFactor();
5684 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5686 if (cc->m_singleChart) {
5687 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5688 cc->SetOwnShipState(SHIP_LOWACCURACY);
5692 if (!bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5694 if ((bGPSValid != m_last_bGPSValid) ||
5695 (bVelocityValid != m_last_bVelocityValid)) {
5696 if (!g_bopengl) cc->UpdateShips();
5703 m_last_bGPSValid = bGPSValid;
5704 m_last_bVelocityValid = bVelocityValid;
5708 bool brq_dynamic =
false;
5710 auto *pplugin_array = PluginLoader::getInstance()->GetPlugInArray();
5711 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5713 if (pic->m_enabled && pic->m_init_state) {
5714 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5721 if (brq_dynamic) bnew_view =
true;
5725 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5728 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5733 if (cc->GetglCanvas()) {
5734 if (m_fixtime - cc->GetglCanvas()->m_last_render_time > 0)
5738 if (AnyAISTargetsOnscreen(cc, cc->GetVP())) bnew_view =
true;
5751 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5765 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5766 g_pais_query_dialog_active->UpdateText();
5769 if (g_pAISTargetList && (0 == (g_tick % (5))))
5770 g_pAISTargetList->UpdateAISTargetList();
5773 UpdateGPSCompassStatusBoxes();
5776 if (console && console->IsShown()) {
5778 console->RefreshConsoleData();
5785 if (m_bdefer_resize) {
5786 if (0 == (g_tick % (5))) {
5787 printf(
"___RESIZE\n");
5788 SetSize(m_defer_size);
5789 g_pauimgr->Update();
5790 m_bdefer_resize =
false;
5798 if (((g_tick % g_FlushNavobjChangesTimeout) == 0) || g_FlushNavobjChanges) {
5799 if (pConfig && pConfig->IsChangesFileDirty()) {
5800 androidShowBusyIcon();
5801 wxStopWatch update_sw;
5802 pConfig->UpdateNavObj(
true);
5803 wxString msg = wxString::Format(
5804 _T(
"OpenCPN periodic navobj update took %ld ms."), update_sw.Time());
5806 qDebug() << msg.mb_str();
5807 g_FlushNavobjChanges =
false;
5808 androidHideBusyIcon();
5817 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5819 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5822 double MyFrame::GetMag(
double a,
double lat,
double lon) {
5823 double Variance = std::isnan(gVar) ? g_UserVar : gVar;
5824 auto loader = PluginLoader::getInstance();
5825 if (loader && loader->IsPlugInAvailable(_T(
"WMM"))) {
5832 wxDateTime now = wxDateTime::Now();
5833 SendJSON_WMM_Var_Request(lat, lon, now);
5834 if (fabs(gQueryVar) < 360.0)
5835 Variance = gQueryVar;
5837 return toMagnetic(a, Variance);
5840 bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5846 v[_T(
"Year")] = date.GetYear();
5847 v[_T(
"Month")] = date.GetMonth();
5848 v[_T(
"Day")] = date.GetDay();
5850 g_pi_manager->SendJSONMessageToAllPlugins(_T(
"WMM_VARIATION_REQUEST"), v);
5856 void MyFrame::TouchAISActive(
void) {
5858 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5860 if (cc) cc->TouchAISToolActive();
5864 void MyFrame::UpdateAISTool(
void) {
5865 if (!g_pAIS)
return;
5868 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5870 if (cc) cc->UpdateAISTBTool();
5875 void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5877 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5879 if (cc) cc->SetbTCUpdate(
true);
5882 RefreshAllCanvas(
false);
5887 void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5889 bool b_rotate =
false;
5890 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5892 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5896 FrameCOGTimer.Stop();
5903 int period_ms = 100;
5905 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5908 void MyFrame::DoCOGSet(
void) {
5910 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5912 if (cc) cc->DoCanvasCOGSet();
5916 void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5922 wxFont oldfont = pdc->GetFont();
5924 pdc->SetFont(*pFont);
5925 pdc->SetTextForeground(GetGlobalColor(_T(
"CHGRF")));
5926 pdc->SetBackgroundMode(wxTRANSPARENT);
5928 pdc->DrawText(str, x, y + 1);
5929 pdc->DrawText(str, x, y - 1);
5930 pdc->DrawText(str, x + 1, y);
5931 pdc->DrawText(str, x - 1, y);
5933 pdc->SetTextForeground(GetGlobalColor(_T(
"CHBLK")));
5935 pdc->DrawText(str, x, y);
5937 pdc->SetFont(oldfont);
5941 void MyFrame::UpdateRotationState(
double rotation) {
5943 g_bCourseUp =
false;
5945 if (fabs(rotation) > .001) {
5946 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5947 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5949 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5952 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5953 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5955 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5959 UpdateGPSCompassStatusBoxes(
true);
5963 void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5965 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5967 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5973 int MyFrame::GetApplicationMemoryUse(
void) {
5979 wxWindow *fWin = wxWindow::FindFocus();
5981 wxArrayString outputArray;
5982 wxString cmd(_T(
"ps --no-headers -o vsize "));
5983 unsigned long pid = wxGetProcessId();
5985 cmd1.Printf(_T(
"%ld"), pid);
5987 wxExecute(cmd, outputArray);
5989 if (outputArray.GetCount()) {
5990 wxString s = outputArray.Item(0);
5992 if (s.ToLong(&vtmp)) memsize = vtmp;
5995 if (fWin) fWin->SetFocus();
6001 PROCESS_MEMORY_COUNTERS pmc;
6003 unsigned long processID = wxGetProcessId();
6005 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6007 if (NULL == hProcess)
return 0;
6009 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6027 memsize = pmc.WorkingSetSize / 1024;
6030 CloseHandle(hProcess);
6037 double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6038 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6041 void MyFrame::SetChartUpdatePeriod() {
6044 g_ChartUpdatePeriod = 0;
6049 bool bskewdc =
false;
6050 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6053 if (!g_bopengl && !cc->GetVP().b_quilt) {
6054 if (fabs(cc->GetVP().skew) > 0.0001) bskewdc =
true;
6056 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6060 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6062 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6067 cc->UpdateCanvasControlBar();
6070 void MyFrame::selectChartDisplay(
int type,
int family) {
6072 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6074 if (cc) cc->selectCanvasChartDisplay(type, family);
6077 UpdateGlobalMenuItems();
6086 bool MyFrame::DoChartUpdate(
void) {
6087 bool return_val =
false;
6090 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6092 if (cc) return_val |= cc->DoCanvasUpdate();
6098 void MyFrame::MouseEvent(wxMouseEvent &event) {
6100 event.GetPosition(&x, &y);
6105 #include <mach/mach.h>
6106 #include <mach/message.h>
6107 #include <mach/kern_return.h>
6108 #include <mach/task_info.h>
6110 #include <malloc/malloc.h>
6117 #if defined(__linux__)
6118 #include "sys/types.h"
6119 #include "sys/sysinfo.h"
6122 int g_lastMemTick = -1;
6126 bool GetMemoryStatus(
int *mem_total,
int *mem_used) {
6128 return androidGetMemoryStatus(mem_total, mem_used);
6131 #if defined(__linux__)
6135 struct sysinfo sys_info;
6136 if (sysinfo(&sys_info) != -1)
6137 *mem_total = ((uint64_t)sys_info.totalram * sys_info.mem_unit) / 1024;
6151 FILE *file = fopen(
"/proc/self/statm",
"r");
6153 if (fscanf(file,
"%d", mem_used) != 1) {
6154 wxLogWarning(
"Cannot parse /proc/self/statm (!)");
6167 PROCESS_MEMORY_COUNTERS pmc;
6169 unsigned long processID = wxGetProcessId();
6172 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6175 if (hProcess && GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6193 *mem_used = pmc.WorkingSetSize / 1024;
6196 CloseHandle(hProcess);
6200 MEMORYSTATUSEX statex;
6202 statex.dwLength =
sizeof(statex);
6204 GlobalMemoryStatusEx(&statex);
6222 *mem_total = statex.ullTotalPhys / 1024;
6229 if (g_tick != g_lastMemTick) {
6230 malloc_zone_pressure_relief(NULL, 0);
6233 int blocksInUse = 0;
6234 int sizeAllocated = 0;
6236 malloc_statistics_t stats;
6237 stats.blocks_in_use = 0;
6238 stats.size_in_use = 0;
6239 stats.max_size_in_use = 0;
6240 stats.size_allocated = 0;
6241 malloc_zone_statistics(NULL, &stats);
6242 bytesInUse += stats.size_in_use;
6243 blocksInUse += stats.blocks_in_use;
6244 sizeAllocated += stats.size_allocated;
6246 g_memUsed = sizeAllocated >> 10;
6249 g_lastMemTick = g_tick;
6252 if (mem_used) *mem_used = g_memUsed;
6255 FILE *fpIn = popen(
"sysctl -n hw.memsize",
"r");
6257 double pagesUsed = 0.0, totalPages = 0.0;
6259 if (fgets(buf,
sizeof(buf), fpIn) != NULL) {
6260 *mem_total = atol(buf) >> 10;
6268 if (mem_used) *mem_used = 0;
6269 if (mem_total) *mem_total = 0;
6273 void MyFrame::DoPrint(
void) {
6275 g_PrintingInProgress =
true;
6278 GetPrimaryCanvas()->GetglCanvas()->Render();
6279 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6284 if (NULL == g_printData) {
6285 g_printData =
new wxPrintData;
6286 g_printData->SetOrientation(wxLANDSCAPE);
6287 g_pageSetupData =
new wxPageSetupDialogData;
6290 wxPrintDialogData printDialogData(*g_printData);
6291 printDialogData.EnablePageNumbers(
false);
6293 wxPrinter printer(&printDialogData);
6300 if (g_bopengl) printout.GenerateGLbmp();
6302 if (!printer.Print(
this, &printout,
true)) {
6303 if (wxPrinter::GetLastError() == wxPRINTER_ERROR)
6304 OCPNMessageBox(NULL,
6305 _(
"There was a problem printing.\nPerhaps your current "
6306 "printer is not set correctly?"),
6307 _T(
"OpenCPN"), wxOK);
6311 (*g_printData) = printer.GetPrintDialogData().GetPrintData();
6330 g_PrintingInProgress =
false;
6333 GetPrimaryCanvas()->SetFocus();
6338 wxDateTime gTimeSource;
6341 wxString message_ID =
event.GetID();
6342 wxString message_JSONText =
event.GetJSONText();
6350 if (message_ID == _T(
"WMM_VARIATION_BOAT")) {
6354 wxJSONReader reader;
6358 int numErrors = reader.Parse(message_JSONText, &root);
6359 if (numErrors > 0) {
6365 wxString decl = root[_T(
"Decl")].AsString();
6367 decl.ToDouble(&decl_val);
6373 if (message_ID == _T(
"WMM_VARIATION")) {
6377 wxJSONReader reader;
6381 int numErrors = reader.Parse(message_JSONText, &root);
6382 if (numErrors > 0) {
6388 wxString decl = root[_T(
"Decl")].AsString();
6390 decl.ToDouble(&decl_val);
6392 gQueryVar = decl_val;
6395 if (message_ID == _T(
"GRIB_TIMELINE")) {
6398 r.Parse(message_JSONText, &v);
6399 if (v[_T(
"Day")].AsInt() == -1)
6400 gTimeSource = wxInvalidDateTime;
6402 gTimeSource.Set(v[_T(
"Day")].AsInt(),
6403 (wxDateTime::Month)v[_T(
"Month")].AsInt(),
6404 v[_T(
"Year")].AsInt(), v[_T(
"Hour")].AsInt(),
6405 v[_T(
"Minute")].AsInt(), v[_T(
"Second")].AsInt());
6407 if (message_ID == _T(
"OCPN_TRACK_REQUEST")) {
6409 wxJSONReader reader;
6410 wxString trk_id = wxEmptyString;
6412 int numErrors = reader.Parse(message_JSONText, &root);
6413 if (numErrors > 0)
return;
6415 if (root.HasMember(_T(
"Track_ID")))
6416 trk_id = root[_T(
"Track_ID")].AsString();
6419 v[_T(
"Track_ID")] = trk_id;
6420 for (
Track *ptrack : g_TrackList) {
6421 wxString name = wxEmptyString;
6422 if (ptrack->m_GUID == trk_id) {
6423 name = ptrack->GetName();
6424 if (name.IsEmpty()) {
6426 if (rp && rp->GetCreateTime().IsValid())
6427 name = rp->GetCreateTime().FormatISODate() + _T(
" ") +
6428 rp->GetCreateTime().FormatISOTime();
6430 name = _(
"(Unnamed Track)");
6436 v[_T(
"error")] =
false;
6437 v[_T(
"TotalNodes")] = ptrack->GetnPoints();
6438 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6440 v[_T(
"lat")] = tp->m_lat;
6441 v[_T(
"lon")] = tp->m_lon;
6442 v[_T(
"NodeNr")] = i;
6444 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6445 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6449 v[_T(
"error")] =
true;
6451 wxString msg_id(_T(
"OCPN_TRACKPOINTS_COORDS"));
6452 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6454 }
else if (message_ID == _T(
"OCPN_ROUTE_REQUEST")) {
6456 wxJSONReader reader;
6457 wxString guid = wxEmptyString;
6459 int numErrors = reader.Parse(message_JSONText, &root);
6460 if (numErrors > 0) {
6464 if (root.HasMember(_T(
"GUID"))) guid = root[_T(
"GUID")].AsString();
6467 v[_T(
"GUID")] = guid;
6468 for (RouteList::iterator it = pRouteList->begin(); it != pRouteList->end();
6470 wxString name = wxEmptyString;
6472 if ((*it)->m_GUID == guid) {
6473 name = (*it)->m_RouteNameString;
6474 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6476 v[_T(
"Name")] = name;
6477 v[_T(
"error")] =
false;
6480 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6481 itp != (*it)->pRoutePointList->end(); itp++) {
6482 w[i][_T(
"lat")] = (*itp)->m_lat;
6483 w[i][_T(
"lon")] = (*itp)->m_lon;
6484 w[i][_T(
"Name")] = (*itp)->GetName();
6485 w[i][_T(
"Description")] = (*itp)->GetDescription();
6486 w[i][_T(
"GUID")] = (*itp)->m_GUID;
6487 w[i][_T(
"ArrivalRadius")] = (*itp)->GetWaypointArrivalRadius();
6488 wxHyperlinkListNode *node = (*itp)->m_HyperlinkList->GetFirst();
6493 v[i][_T(
"WPLink") + wxString::Format(_T(
"%d"), n)] =
6495 v[i][_T(
"WPLinkDesciption") + wxString::Format(_T(
"%d"), n++)] =
6496 httpLink->DescrText;
6497 node = node->GetNext();
6502 v[_T(
"waypoints")] = w;
6503 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6504 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6509 v[_T(
"error")] =
true;
6511 wxString msg_id(_T(
"OCPN_ROUTE_RESPONSE"));
6512 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6513 }
else if (message_ID == _T(
"OCPN_ROUTELIST_REQUEST")) {
6515 wxJSONReader reader;
6518 int numErrors = reader.Parse(message_JSONText, &root);
6519 if (numErrors > 0)
return;
6521 if (root.HasMember(_T(
"mode"))) {
6522 wxString str = root[_T(
"mode")].AsString();
6523 if (str == _T(
"Track")) route =
false;
6528 for (RouteList::iterator it = pRouteList->begin();
6529 it != pRouteList->end(); it++) {
6530 wxString name = (*it)->m_RouteNameString;
6531 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6533 v[i][_T(
"error")] =
false;
6534 v[i][_T(
"name")] = name;
6535 v[i][_T(
"GUID")] = (*it)->m_GUID;
6536 v[i][_T(
"active")] = (*it)->IsActive();
6540 for (
Track *ptrack : g_TrackList) {
6541 wxString name = ptrack->GetName();
6542 if (name.IsEmpty()) {
6544 if (tp && tp->GetCreateTime().IsValid())
6545 name = tp->GetCreateTime().FormatISODate() + _T(
" ") +
6546 tp->GetCreateTime().FormatISOTime();
6548 name = _(
"(Unnamed Track)");
6550 v[i][_T(
"error")] =
false;
6551 v[i][_T(
"name")] = name;
6552 v[i][_T(
"GUID")] = ptrack->m_GUID;
6553 v[i][_T(
"active")] = g_pActiveTrack == ptrack;
6557 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6558 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6561 v[0][_T(
"error")] =
true;
6562 wxString msg_id(_T(
"OCPN_ROUTELIST_RESPONSE"));
6563 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6565 }
else if (message_ID == _T(
"OCPN_ACTIVE_ROUTELEG_REQUEST")) {
6567 v[0][_T(
"error")] =
true;
6568 if (g_pRouteMan->GetpActiveRoute()) {
6569 if (g_pRouteMan->m_bDataValid) {
6570 v[0][_T(
"error")] =
false;
6571 v[0][_T(
"range")] = g_pRouteMan->GetCurrentRngToActivePoint();
6572 v[0][_T(
"bearing")] = g_pRouteMan->GetCurrentBrgToActivePoint();
6573 v[0][_T(
"XTE")] = g_pRouteMan->GetCurrentXTEToActivePoint();
6574 v[0][_T(
"active_route_GUID")] =
6575 g_pRouteMan->GetpActiveRoute()->GetGUID();
6576 v[0][_T(
"active_waypoint_lat")] =
6577 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLatitude();
6578 v[0][_T(
"active_waypoint_lon")] =
6579 g_pRouteMan->GetpActiveRoute()->m_pRouteActivePoint->GetLongitude();
6582 wxString msg_id(_T(
"OCPN_ACTIVE_ROUTELEG_RESPONSE"));
6583 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6587 void MyFrame::FilterCogSog(
void) {
6588 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6590 double cog_last = gCog;
6593 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6594 COGFilterTable[i] = COGFilterTable[i - 1];
6595 COGFilterTable[0] = cog_last;
6598 if (!std::isnan(cog_last)) {
6600 double sum = 0., count = 0;
6601 for (
int i = 0; i < g_COGFilterSec; i++) {
6602 double adder = COGFilterTable[i];
6603 if (std::isnan(adder))
continue;
6605 if (fabs(adder - cog_last) > 180.) {
6606 if ((adder - cog_last) > 0.)
6619 else if (sum >= 360.)
6626 double sog_last = gSog;
6629 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6630 SOGFilterTable[i] = SOGFilterTable[i - 1];
6631 SOGFilterTable[0] = sog_last;
6634 if (!std::isnan(gSog)) {
6635 double sum = 0., count = 0;
6636 for (
int i = 0; i < g_SOGFilterSec; i++) {
6637 if (std::isnan(SOGFilterTable[i]))
continue;
6639 sum += SOGFilterTable[i];
6649 void MyFrame::LoadHarmonics() {
6652 ptcmgr->LoadDataSources(TideCurrentDataSet);
6654 bool b_newdataset =
false;
6657 for (
auto a : ptcmgr->GetDataSet()) {
6658 bool b_foundi =
false;
6659 for (
auto b : TideCurrentDataSet) {
6666 b_newdataset =
true;
6671 for (
auto a : TideCurrentDataSet) {
6672 bool b_foundi =
false;
6673 for (
auto b : ptcmgr->GetDataSet()) {
6680 b_newdataset =
true;
6685 if (b_newdataset) ptcmgr->LoadDataSources(TideCurrentDataSet);
6689 void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6690 if (!ptarget)
return;
6693 wxDateTime mob_time = wxDateTime::Now();
6694 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6695 mob_label += _(
" at ");
6696 mob_label += mob_time.FormatTime();
6697 mob_label += _(
" on ");
6698 mob_label += mob_time.FormatISODate();
6701 mob_label, wxEmptyString);
6702 pWP_MOB->SetShared(
true);
6703 pWP_MOB->m_bIsolatedMark =
true;
6704 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6705 pConfig->AddNewWayPoint(pWP_MOB, -1);
6706 pWP_MOB->SetUseSca(
false);
6714 wxString(_(
"Own ship")), wxEmptyString);
6715 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
6716 pWP_MOB->SetUseSca(
false);
6717 pAISMOBRoute =
new Route();
6718 pRouteList->Append(pAISMOBRoute);
6720 pAISMOBRoute->AddPoint(pWP_src);
6721 pAISMOBRoute->AddPoint(pWP_MOB);
6723 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon, gLat, gLon,
6724 pWP_src, pWP_MOB, pAISMOBRoute);
6726 pAISMOBRoute->m_RouteNameString = _(
"Temporary AISMOB Route");
6727 pAISMOBRoute->m_RouteStartString = _(
"Present own ship");
6728 pAISMOBRoute->m_RouteEndString = mob_label;
6730 pAISMOBRoute->m_bDeleteOnArrival =
false;
6732 pAISMOBRoute->SetRouteArrivalRadius(-1.0);
6734 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
6738 v[_T(
"GUID")] = pAISMOBRoute->m_GUID;
6739 wxString msg_id(_T(
"OCPN_MAN_OVERBOARD"));
6740 g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
6743 if (RouteManagerDialog::getInstanceFlag()) {
6744 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6745 pRouteManagerDialog->UpdateRouteListCtrl();
6746 pRouteManagerDialog->UpdateWptListCtrl();
6750 RefreshAllCanvas(
false);
6752 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6753 mob_message += _(
" Time: ");
6754 mob_message += mob_time.Format();
6755 mob_message += _(
" Ownship Position: ");
6756 mob_message += toSDMM(1, gLat);
6757 mob_message += _T(
" ");
6758 mob_message += toSDMM(2, gLon);
6759 mob_message += _(
" MOB Position: ");
6760 mob_message += toSDMM(1, ptarget->Lat);
6761 mob_message += _T(
" ");
6762 mob_message += toSDMM(2, ptarget->Lon);
6763 wxLogMessage(mob_message);
6766 void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6767 if (pAISMOBRoute && ptarget) {
6769 RoutePoint *OwnPoint = pAISMOBRoute->GetPoint(1);
6770 OwnPoint->m_lat = gLat;
6771 OwnPoint->m_lon = gLon;
6773 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6774 pSelect->AddSelectableRoutePoint(gLat, gLon, OwnPoint);
6777 RoutePoint *MOB_Point = pAISMOBRoute->GetPoint(2);
6778 MOB_Point->m_lat = ptarget->Lat;
6779 MOB_Point->m_lon = ptarget->Lon;
6781 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6782 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6784 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6785 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6788 RefreshAllCanvas(
false);
6791 wxDateTime mob_time = wxDateTime::Now();
6793 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6794 mob_message += _(
" Time: ");
6795 mob_message += mob_time.Format();
6796 mob_message += _(
" Ownship Position: ");
6797 mob_message += toSDMM(1, gLat);
6798 mob_message += _T(
" ");
6799 mob_message += toSDMM(2, gLon);
6800 mob_message += _(
" MOB Position: ");
6801 mob_message += toSDMM(1, ptarget->Lat);
6802 mob_message += _T(
" ");
6803 mob_message += toSDMM(2, ptarget->Lon);
6805 wxLogMessage(mob_message);
6809 void MyFrame::applySettingsString(wxString settings) {
6811 int last_UIScaleFactor = g_GUIScaleFactor;
6812 bool previous_expert = g_bUIexpert;
6813 g_last_ChartScaleFactor = g_ChartScaleFactor;
6814 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6817 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6820 pConfig->UpdateSettings();
6823 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6825 if (rr & S52_CHANGED) {
6827 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6829 ->ClearCNSYLUPArray();
6830 ps52plib->GenerateStateHash();
6834 ProcessOptionsDialog(rr, pNewDirArray);
6839 bool b_newToolbar =
false;
6841 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6843 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6845 if (rr & TOOLBAR_CHANGED) b_newToolbar =
true;
6850 if (previous_expert && !g_bUIexpert) {
6851 androidForceFullRepaint();
6855 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6859 SetGPSCompassScale();
6861 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6863 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6865 UpdateGPSCompassStatusBoxes(
true);
6868 AbstractPlatform::ShowBusySpinner();
6870 SetAllToolbarScale();
6874 AbstractPlatform::HideBusySpinner();
6876 RequestNewMasterToolbar(
true);
6883 UpdateControlBar(GetPrimaryCanvas());
6886 if (console) console->Raise();
6890 if (NMEALogWindow::GetInstance().Active())
6891 NMEALogWindow::GetInstance().GetTTYWindow()->Raise();
6894 #ifdef wxHAS_POWER_EVENTS
6895 void MyFrame::OnSuspending(wxPowerEvent &event) {
6899 wxLogMessage(_T(
"System suspend starting..."));
6902 void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6905 wxLogMessage(_T(
"System is going to suspend."));
6908 void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6911 wxLogMessage(_T(
"System suspend was cancelled."));
6914 int g_last_resume_ticks;
6915 void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6916 wxDateTime now = wxDateTime::Now();
6917 wxLogMessage(_T(
"System resumed from suspend."));
6920 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6923 wxLogMessage(
"Restarting streams.");
6924 g_last_resume_ticks = now.GetTicks();
6928 g_pMUX->ClearStreams();
6930 g_pMUX->StartAllStreams();
6939 if (IsMaximized()) {
6944 wxSize sz = GetSize();
6945 SetSize(wxSize(sz.x - 1, sz.y));
6957 void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6958 bool btbRebuild =
false;
6960 bool b_reshow =
true;
6961 if (g_MainToolbar) {
6963 float ff = fabs(g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6964 if ((ff > 0.01f) || bforcenew) {
6965 g_MainToolbar->DestroyToolBar();
6966 delete g_MainToolbar;
6967 g_MainToolbar = NULL;
6973 if (!g_MainToolbar) {
6974 long orient = g_Platform->GetDefaultToolbarOrientation();
6975 wxWindow *toolbarParent =
this;
6977 toolbarParent = GetPrimaryCanvas();
6980 g_toolbar_scalefactor);
6981 g_MainToolbar->SetBackGroundColorString(_T(
"GREY3"));
6982 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6983 g_MainToolbar->SetToolConfigString(g_toolbarConfig);
6984 g_MainToolbar->EnableRolloverBitmaps(
false);
6986 g_MainToolbar->CreateConfigMenu();
6987 g_MainToolbar->SetDefaultPosition();
6989 g_bmasterToolbarFull =
true;
6992 if (g_MainToolbar) {
6993 CreateMasterToolbar();
6996 g_MainToolbar->SetColorScheme(global_color_scheme);
7002 g_MainToolbar->SetAutoHide(g_bAutoHideToolbar);
7003 g_MainToolbar->SetAutoHideTimer(g_nAutoHideToolbar);
7007 bool MyFrame::CollapseGlobalToolbar() {
7008 if (g_MainToolbar) {
7009 m_nMasterToolCountShown = 1;
7010 g_MainToolbar->SetToolShowCount(m_nMasterToolCountShown);
7011 g_MainToolbar->GetToolbar()->InvalidateBitmaps();
7012 g_MainToolbar->Realize();
7013 g_bmasterToolbarFull =
false;
7022 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7029 ID_MASTERTOGGLE, style->GetToolIcon(_T(
"MUI_menu"), TOOLICON_NORMAL),
7030 wxITEM_NORMAL, _(
"Hide Toolbar"), _T(
"MUI_menu"));
7031 tic->m_bRequired =
true;
7033 g_MainToolbar->AddToolItem(tic);
7036 ID_SETTINGS, style->GetToolIcon(_T(
"MUI_settings"), TOOLICON_NORMAL),
7037 wxITEM_NORMAL, _(
"Options"), _T(
"MUI_settings"));
7038 g_MainToolbar->AddToolItem(tic);
7041 ID_MENU_ROUTE_NEW, style->GetToolIcon(_T(
"MUI_route"), TOOLICON_NORMAL),
7042 style->GetToolIcon(_T(
"MUI_route"), TOOLICON_TOGGLED), wxITEM_CHECK,
7043 wxString(_(
"Create Route")) << _T(
" (Ctrl-R)"), _T(
"MUI_route"));
7045 g_MainToolbar->AddToolItem(tic);
7048 ID_ROUTEMANAGER, style->GetToolIcon(_T(
"MUI_RMD"), TOOLICON_NORMAL),
7049 wxITEM_NORMAL, _(
"Route & Mark Manager"), _T(
"MUI_RMD"));
7050 g_MainToolbar->AddToolItem(tic);
7053 ID_TRACK, style->GetToolIcon(_T(
"MUI_track"), TOOLICON_NORMAL),
7054 style->GetToolIcon(_T(
"MUI_track"), TOOLICON_TOGGLED), wxITEM_CHECK,
7055 _(
"Enable Tracking"), _T(
"MUI_track"));
7056 g_MainToolbar->AddToolItem(tic);
7059 ID_COLSCHEME, style->GetToolIcon(_T(
"MUI_colorscheme"), TOOLICON_NORMAL),
7060 wxITEM_NORMAL, _(
"Change Color Scheme"), _T(
"MUI_colorscheme"));
7061 g_MainToolbar->AddToolItem(tic);
7072 ID_PRINT, style->GetToolIcon(_T(
"MUI_print"), TOOLICON_NORMAL),
7073 wxITEM_NORMAL, _(
"Print Chart"), _T(
"MUI_print"));
7074 g_MainToolbar->AddToolItem(tic);
7077 ID_ABOUT, style->GetToolIcon(_T(
"MUI_help"), TOOLICON_NORMAL),
7078 wxITEM_NORMAL, _(
"About OpenCPN"), _T(
"MUI_help"));
7079 g_MainToolbar->AddToolItem(tic);
7082 AddDefaultPositionPlugInTools();
7086 ID_MOB, style->GetToolIcon(_T(
"mob_btn"), TOOLICON_NORMAL), wxITEM_NORMAL,
7087 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"), _T(
"mob_btn"));
7088 g_MainToolbar->AddToolItem(tic);
7091 g_MainToolbar->RebuildToolbar();
7095 g_MainToolbar->Realize();
7098 ArrayOfPlugInToolbarTools tool_array =
7099 g_pi_manager->GetPluginToolbarToolArray();
7100 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7102 if (!pttc->b_viz)
continue;
7104 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
7107 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
7108 if (g_bTrackActive) {
7109 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
7111 g_MainToolbar->Realize();
7116 bool MyFrame::CheckAndAddPlugInTool() {
7117 if (!g_pi_manager)
return false;
7122 if (g_MainToolbar) tb = g_MainToolbar->GetToolbar();
7124 if (!tb)
return false;
7126 int n_tools = tb->GetToolsCount();
7130 ArrayOfPlugInToolbarTools tool_array =
7131 g_pi_manager->GetPluginToolbarToolArray();
7133 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7135 if (pttc->position == n_tools) {
7136 wxBitmap *ptool_bmp;
7138 switch (global_color_scheme) {
7139 case GLOBAL_COLOR_SCHEME_DAY:
7140 ptool_bmp = pttc->bitmap_day;
7143 case GLOBAL_COLOR_SCHEME_DUSK:
7144 ptool_bmp = pttc->bitmap_dusk;
7146 case GLOBAL_COLOR_SCHEME_NIGHT:
7147 ptool_bmp = pttc->bitmap_night;
7150 ptool_bmp = pttc->bitmap_day;
7155 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7157 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7158 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7159 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7160 tic->m_bPlugin =
true;
7169 while (CheckAndAddPlugInTool()) {
7175 bool MyFrame::AddDefaultPositionPlugInTools() {
7176 if (!g_pi_manager)
return false;
7182 ArrayOfPlugInToolbarTools tool_array =
7183 g_pi_manager->GetPluginToolbarToolArray();
7185 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7189 if (!pttc->b_viz)
continue;
7191 if (pttc->position == -1)
7193 wxBitmap *ptool_bmp;
7195 switch (global_color_scheme) {
7196 case GLOBAL_COLOR_SCHEME_DAY:
7197 ptool_bmp = pttc->bitmap_day;
7199 case GLOBAL_COLOR_SCHEME_DUSK:
7200 ptool_bmp = pttc->bitmap_dusk;
7202 case GLOBAL_COLOR_SCHEME_NIGHT:
7203 ptool_bmp = pttc->bitmap_night;
7206 ptool_bmp = pttc->bitmap_day;
7211 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp, _T(
""));
7213 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7214 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7215 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7216 tic->m_bPlugin =
true;
7218 g_MainToolbar->AddToolItem(tic);
7231 wxColour GetGlobalColor(wxString colorName);
7233 static const char *usercolors[] = {
7235 "GREEN1;120;255;120;",
7236 "GREEN2; 45;150; 45;",
7237 "GREEN3;200;220;200;",
7238 "GREEN4; 0;255; 0;",
7239 "BLUE1; 170;170;255;",
7240 "BLUE2; 45; 45;170;",
7242 "GREY1; 200;200;200;",
7243 "GREY2; 230;230;230;",
7244 "RED1; 220;200;200;",
7246 "UWHIT; 255;255;255;",
7249 "YELO1; 243;229; 47;",
7250 "YELO2; 128; 80; 0;",
7251 "TEAL1; 0;128;128;",
7252 "GREEN5;170;254; 0;",
7253 "COMPT; 245;247;244",
7255 "DILG0; 255;255;255;",
7257 "DILG0; 238;239;242;",
7259 "DILG1; 212;208;200;",
7260 "DILG2; 255;255;255;",
7264 "CHGRF; 163; 180; 183;",
7265 "UINFM; 197; 69; 195;",
7266 "UINFG; 104; 228; 86;",
7267 "UINFF; 125; 137; 140;",
7268 "UINFR; 241; 84; 105;",
7270 "CHYLW; 244; 218; 72;",
7271 "CHWHT; 212; 234; 238;",
7273 "UDKRD; 124; 16; 0;",
7274 "UARTE; 200; 0; 0;",
7276 "NODTA; 163; 180; 183;",
7278 "SNDG1; 125; 137; 140;",
7280 "SCLBR; 235; 125; 54;",
7281 "UIBDR; 125; 137; 140;",
7282 "UINFB; 58; 120; 240;",
7284 "UINFO; 235; 125; 54;",
7285 "PLRTE; 220; 64; 37;",
7286 "CHMGD; 197; 69; 195;",
7287 "UIBCK; 212; 234; 238;",
7289 "DASHB; 255;255;255;",
7290 "DASHL; 175;175;175;",
7291 "DASHF; 50; 50; 50;",
7292 "DASHR; 200; 0; 0;",
7294 "DASHN; 200;120; 0;",
7295 "DASH1; 204;204;255;",
7296 "DASH2; 122;131;172;",
7297 "COMP1; 211;211;211;",
7299 "GREY3; 40; 40; 40;",
7300 "BLUE4; 100;100;200;",
7301 "VIO01; 171; 33;141;",
7302 "VIO02; 209;115;213;",
7305 "GREEN1; 60;128; 60;",
7306 "GREEN2; 22; 75; 22;",
7307 "GREEN3; 80;100; 80;",
7308 "GREEN4; 0;128; 0;",
7309 "BLUE1; 80; 80;160;",
7310 "BLUE2; 30; 30;120;",
7312 "GREY1; 100;100;100;",
7313 "GREY2; 128;128;128;",
7314 "RED1; 150;100;100;",
7316 "UWHIT; 255;255;255;",
7317 "URED; 120; 54; 11;",
7318 "UGREN; 35;110; 20;",
7319 "YELO1; 120;115; 24;",
7320 "YELO2; 64; 40; 0;",
7321 "TEAL1; 0; 64; 64;",
7322 "GREEN5; 85;128; 0;",
7323 "COMPT; 124;126;121",
7325 "CHGRF; 41; 46; 46;",
7326 "UINFM; 58; 20; 57;",
7327 "UINFG; 35; 76; 29;",
7328 "UINFF; 41; 46; 46;",
7329 "UINFR; 80; 28; 35;",
7330 "SHIPS; 71; 78; 79;",
7331 "CHYLW; 81; 73; 24;",
7332 "CHWHT; 71; 78; 79;",
7334 "DILG0; 110;110;110;",
7335 "DILG1; 110;110;110;",
7337 "DILG3; 130;130;130;",
7338 "UITX1; 41; 46; 46;",
7340 "UARTE; 64; 64; 64;",
7342 "NODTA; 41; 46; 46;",
7343 "CHBLK; 54; 60; 61;",
7344 "SNDG1; 41; 46; 46;",
7345 "SNDG2; 71; 78; 79;",
7346 "SCLBR; 75; 38; 19;",
7347 "UIBDR; 54; 60; 61;",
7348 "UINFB; 19; 40; 80;",
7349 "UINFD; 71; 78; 79;",
7350 "UINFO; 75; 38; 19;",
7351 "PLRTE; 73; 21; 12;",
7352 "CHMGD; 74; 58; 81;",
7355 "DASHB; 77; 77; 77;",
7356 "DASHL; 54; 54; 54;",
7358 "DASHR; 58; 21; 21;",
7359 "DASHG; 21; 58; 21;",
7360 "DASHN; 100; 50; 0;",
7361 "DASH1; 76; 76;113;",
7362 "DASH2; 48; 52; 72;",
7363 "COMP1; 107;107;107;",
7365 "GREY3; 20; 20; 20;",
7366 "BLUE4; 80; 80;160;",
7367 "VIO01; 128; 25;108;",
7368 "VIO02; 171; 33;141;",
7371 "GREEN1; 30; 80; 30;",
7372 "GREEN2; 15; 60; 15;",
7373 "GREEN3; 12; 23; 9;",
7374 "GREEN4; 0; 64; 0;",
7375 "BLUE1; 60; 60;100;",
7376 "BLUE2; 22; 22; 85;",
7378 "GREY1; 48; 48; 48;",
7379 "GREY2; 32; 32; 32;",
7380 "RED1; 100; 50; 50;",
7381 "UWHIT; 255;255;255;",
7384 "UGREN; 17; 55; 10;",
7385 "YELO1; 60; 65; 12;",
7386 "YELO2; 32; 20; 0;",
7387 "TEAL1; 0; 32; 32;",
7388 "GREEN5; 44; 64; 0;",
7389 "COMPT; 48; 49; 51",
7390 "DILG0; 80; 80; 80;",
7391 "DILG1; 80; 80; 80;",
7393 "DILG3; 65; 65; 65;",
7394 "UITX1; 31; 34; 35;",
7396 "UARTE; 64; 64; 64;",
7398 "CHGRF; 16; 18; 18;",
7399 "UINFM; 52; 18; 52;",
7400 "UINFG; 22; 24; 7;",
7401 "UINFF; 31; 34; 35;",
7402 "UINFR; 59; 17; 10;",
7403 "SHIPS; 37; 41; 41;",
7404 "CHYLW; 31; 33; 10;",
7405 "CHWHT; 37; 41; 41;",
7408 "CHBLK; 31; 34; 35;",
7409 "SNDG1; 31; 34; 35;",
7410 "SNDG2; 43; 48; 48;",
7411 "SCLBR; 52; 28; 12;",
7412 "UIBDR; 31; 34; 35;",
7413 "UINFB; 21; 29; 69;",
7414 "UINFD; 43; 48; 58;",
7415 "UINFO; 52; 28; 12;",
7416 "PLRTE; 66; 19; 11;",
7417 "CHMGD; 52; 18; 52;",
7421 "DASHL; 20; 20; 20;",
7422 "DASHF; 64; 64; 64;",
7423 "DASHR; 70; 15; 15;",
7424 "DASHG; 15; 70; 15;",
7425 "DASHN; 17; 80; 56;",
7426 "DASH1; 48; 52; 72;",
7427 "DASH2; 36; 36; 53;",
7428 "COMP1; 24; 24; 24;",
7430 "GREY3; 10; 10; 10;",
7431 "BLUE4; 70; 70;140;",
7432 "VIO01; 85; 16; 72;",
7433 "VIO02; 128; 25;108;",
7437 int get_static_line(
char *d,
const char **p,
int index,
int n) {
7438 if (!strcmp(p[index],
"*****"))
return 0;
7440 strncpy(d, p[index], n);
7444 void InitializeUserColors(
void) {
7445 const char **p = usercolors;
7453 UserColorTableArray =
new wxArrayPtrVoid;
7454 UserColourHashTableArray =
new wxArrayPtrVoid;
7458 ct->tableName =
new wxString(_T(
"DAY"));
7459 ct->color =
new wxArrayPtrVoid;
7460 UserColorTableArray->Add((
void *)ct);
7463 ct->tableName =
new wxString(_T(
"DUSK"));
7464 ct->color =
new wxArrayPtrVoid;
7465 UserColorTableArray->Add((
void *)ct);
7468 ct->tableName =
new wxString(_T(
"NIGHT"));
7469 ct->color =
new wxArrayPtrVoid;
7470 UserColorTableArray->Add((
void *)ct);
7472 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7473 if (!strncmp(buf,
"Table", 5)) {
7474 sscanf(buf,
"Table:%s", TableName);
7476 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7477 ctp = (colTable *)(UserColorTableArray->Item(it));
7478 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7487 while (buf[j] !=
';' && j < 20) {
7493 S52color *c =
new S52color;
7494 strcpy(c->colName, name);
7496 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7509 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7510 wxColorHashMap *phash =
new wxColorHashMap;
7511 UserColourHashTableArray->Add((
void *)phash);
7513 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7515 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7516 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7518 wxColour c(c2->R, c2->G, c2->B);
7519 wxString key(c2->colName, wxConvUTF8);
7526 pcurrent_user_color_hash =
7527 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7530 void DeInitializeUserColors(
void) {
7531 if (!UserColorTableArray)
return;
7532 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7533 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7535 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7536 S52color *c = (S52color *)ct->color->Item(j);
7540 delete ct->tableName;
7546 delete UserColorTableArray;
7548 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7549 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7553 delete UserColourHashTableArray;
7560 typedef struct _MSW_COLOR_SPEC {
7562 wxString S52_RGB_COLOR;
7566 MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU, _T(
"UIBCK"), 0},
7567 {COLOR_MENUTEXT, _T(
"UITX1"), 0},
7568 {COLOR_BTNSHADOW, _T(
"UIBCK"), 0},
7571 void SaveSystemColors() {
7585 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7586 while (pcspec->COLOR_NAME != -1) {
7587 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7592 void RestoreSystemColors() {
7593 int element[NCOLORS];
7594 int rgbcolor[NCOLORS];
7597 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7598 while (pcspec->COLOR_NAME != -1) {
7599 element[i] = pcspec->COLOR_NAME;
7600 rgbcolor[i] = pcspec->SysRGB_COLOR;
7606 pSetSysColors(i, (
unsigned long *)&element[0], (
unsigned long *)&rgbcolor[0]);
7611 void SetSystemColors(ColorScheme cs) {
7613 int element[NCOLORS];
7614 int rgbcolor[NCOLORS];
7616 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7617 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7618 while (pcspec->COLOR_NAME != -1) {
7619 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7620 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7621 element[i] = pcspec->COLOR_NAME;
7627 pSetSysColors(i, (
unsigned long *)&element[0],
7628 (
unsigned long *)&rgbcolor[0]);
7632 RestoreSystemColors();
7637 wxColor GetDimColor(wxColor c) {
7638 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7639 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7643 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7644 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7646 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7647 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7648 hsv.value = hsv.value * factor;
7649 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7651 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7658 double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7659 double const AnchorPointMaxDist)
7662 if (d < AnchorPointMinDist)
7663 return AnchorPointMinDist;
7664 else if (d > AnchorPointMaxDist)
7665 return AnchorPointMaxDist;
7671 if (d > -AnchorPointMinDist)
7672 return -AnchorPointMinDist;
7673 else if (d < -AnchorPointMaxDist)
7674 return -AnchorPointMaxDist;
7681 static const WORD MAX_CONSOLE_LINES =
7686 void RedirectIOToConsole()
7691 wxIntPtr lStdHandle;
7693 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7703 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7704 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7705 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7709 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7710 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7711 fp = _fdopen(hConHandle,
"w");
7713 setvbuf(stdout, NULL, _IONBF, 0);
7717 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7718 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7719 fp = _fdopen(hConHandle,
"r");
7721 setvbuf(stdin, NULL, _IONBF, 0);
7725 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7726 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7727 fp = _fdopen(hConHandle,
"w");
7729 setvbuf(stderr, NULL, _IONBF, 0);
7741 bool TestGLCanvas(wxString prog_dir) {
7743 wxString test_app = prog_dir;
7744 test_app += _T(
"ocpn_gltest1.exe");
7746 if (::wxFileExists(test_app)) {
7747 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7748 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7749 if (proc_return == 0)
7750 printf(
"GLCanvas OK\n");
7752 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7754 return (proc_return == 0);
7764 OCPN_ThreadMessageEvent::OCPN_ThreadMessageEvent(wxEventType commandType,
7766 : wxEvent(id, commandType) {}
7768 OCPN_ThreadMessageEvent::~OCPN_ThreadMessageEvent() {}
7770 wxEvent *OCPN_ThreadMessageEvent::Clone()
const {
7772 newevent->m_string = this->m_string;
7811 #include <objbase.h>
7812 #include <initguid.h>
7813 #include <Setupapi.h>
7815 #include "EnumSerial.h"
7819 #ifndef GUID_CLASS_COMPORT
7820 DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, \
7821 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
7826 SSerInfo() : bUsbDevice(FALSE) {}
7828 CString strPortName;
7829 CString strFriendlyName;
7831 CString strPortDesc;
7839 void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi);
7840 void EnumPortsWNt4(CArray<SSerInfo,SSerInfo&> &asi);
7841 void EnumPortsW9x(CArray<SSerInfo,SSerInfo&> &asi);
7842 void SearchPnpKeyW9x(HKEY hkPnp, BOOL bUsbDevice,
7843 CArray<SSerInfo,SSerInfo&> &asi);
7852 void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts)
7860 vi.dwOSVersionInfoSize =
sizeof(vi);
7861 if (!::GetVersionEx(&vi)) {
7863 str.Format(
"Could not get OS version. (err=%lx)",
7868 if (vi.dwMajorVersion < 5) {
7869 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
7880 for (
int ii=0; ii<asi.GetSize(); ii++)
7882 SSerInfo& rsi = asi[ii];
7883 if (bIgnoreBusyPorts) {
7885 HANDLE hCom = CreateFile(rsi.strDevPath,
7886 GENERIC_READ | GENERIC_WRITE,
7893 if (hCom == INVALID_HANDLE_VALUE) {
7901 ::CloseHandle(hCom);
7907 if (rsi.strFriendlyName.IsEmpty())
7908 rsi.strFriendlyName = rsi.strPortName;
7912 if (rsi.strPortDesc.IsEmpty()) {
7915 rsi.strPortDesc = rsi.strFriendlyName;
7916 int startdex = rsi.strPortDesc.Find(
" (");
7917 int enddex = rsi.strPortDesc.Find(
")");
7918 if (startdex > 0 && enddex ==
7919 (rsi.strPortDesc.GetLength()-1))
7920 rsi.strPortDesc = rsi.strPortDesc.Left(startdex);
7927 void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi)
7932 GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT;
7934 HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
7935 SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
7938 hDevInfo = SetupDiGetClassDevs( guidDev,
7941 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
7944 if(hDevInfo == INVALID_HANDLE_VALUE)
7946 strErr.Format(
"SetupDiGetClassDevs failed. (err=%lx)",
7953 SP_DEVICE_INTERFACE_DATA ifcData;
7954 DWORD dwDetDataSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
7955 pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)
new char[dwDetDataSize];
7958 ifcData.cbSize =
sizeof(SP_DEVICE_INTERFACE_DATA);
7959 pDetData->cbSize =
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
7960 for (DWORD ii=0; bOk; ii++) {
7961 bOk = SetupDiEnumDeviceInterfaces(hDevInfo,
7962 NULL, guidDev, ii, &ifcData);
7965 SP_DEVINFO_DATA devdata = {
sizeof(SP_DEVINFO_DATA)};
7966 bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
7967 &ifcData, pDetData, dwDetDataSize, NULL, &devdata);
7969 CString strDevPath(pDetData->DevicePath);
7973 BOOL bSuccess = SetupDiGetDeviceRegistryProperty(
7974 hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
7975 (PBYTE)fname,
sizeof(fname), NULL);
7976 bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(
7977 hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
7978 (PBYTE)desc,
sizeof(desc), NULL);
7979 BOOL bUsbDevice = FALSE;
7981 if (SetupDiGetDeviceRegistryProperty(
7982 hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,
7983 (PBYTE)locinfo,
sizeof(locinfo), NULL))
7991 bUsbDevice = (strncmp(locinfo,
"USB", 3)==0);
7996 si.strDevPath = strDevPath;
7997 si.strFriendlyName = fname;
7998 si.strPortDesc = desc;
7999 si.bUsbDevice = bUsbDevice;
8005 strErr.Format(
"SetupDiGetDeviceInterfaceDetail failed. (err=%lx)",
8011 DWORD err = GetLastError();
8012 if (err != ERROR_NO_MORE_ITEMS) {
8013 strErr.Format(
"SetupDiEnumDeviceInterfaces failed. (err=%lx)", err);
8019 catch (CString strCatchErr) {
8020 strErr = strCatchErr;
8023 if (pDetData != NULL)
8024 delete [] (
char*)pDetData;
8025 if (hDevInfo != INVALID_HANDLE_VALUE)
8026 SetupDiDestroyDeviceInfoList(hDevInfo);
8028 if (!strErr.IsEmpty())
8032 void EnumPortsWNt4(CArray<SSerInfo,SSerInfo&> &asi)
8038 for (
int ii=1; ii<=16; ii++) {
8040 strPort.Format(
"COM%d",ii);
8041 si.strDevPath = CString(
"\\\\.\\") + strPort;
8042 si.strPortName = strPort;
8047 void EnumPortsW9x(CArray<SSerInfo,SSerInfo&> &asi)
8056 HKEY hkSubEnum = NULL;
8057 HKEY hkSubSubEnum = NULL;
8060 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Enum", 0, KEY_READ,
8061 &hkEnum) != ERROR_SUCCESS)
8062 throw CString(
"Could not read from HKLM\\Enum");
8065 char acSubEnum[128];
8066 DWORD dwSubEnumIndex = 0;
8067 DWORD dwSize =
sizeof(acSubEnum);
8068 while (RegEnumKeyEx(hkEnum, dwSubEnumIndex++, acSubEnum, &dwSize,
8069 NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
8071 HKEY hkSubEnum = NULL;
8072 if (RegOpenKeyEx(hkEnum, acSubEnum, 0, KEY_READ,
8073 &hkSubEnum) != ERROR_SUCCESS)
8074 throw CString(
"Could not read from HKLM\\Enum\\")+acSubEnum;
8078 BOOL bUsbDevice = (strcmp(acSubEnum,
"USBPORTS")==0);
8079 char acSubSubEnum[128];
8080 dwSize =
sizeof(acSubSubEnum);
8081 DWORD dwSubSubEnumIndex = 0;
8082 while (RegEnumKeyEx(hkSubEnum, dwSubSubEnumIndex++, acSubSubEnum,
8083 &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
8085 BOOL bMatch = (strcmp(acSubSubEnum,
"*PNP0500")==0 ||
8086 strcmp(acSubSubEnum,
"*PNP0501")==0 ||
8089 HKEY hkSubSubEnum = NULL;
8090 if (RegOpenKeyEx(hkSubEnum, acSubSubEnum, 0, KEY_READ,
8091 &hkSubSubEnum) != ERROR_SUCCESS)
8092 throw CString(
"Could not read from HKLM\\Enum\\") +
8093 acSubEnum +
"\\" + acSubSubEnum;
8094 SearchPnpKeyW9x(hkSubSubEnum, bUsbDevice, asi);
8095 RegCloseKey(hkSubSubEnum);
8096 hkSubSubEnum = NULL;
8099 dwSize =
sizeof(acSubSubEnum);
8102 RegCloseKey(hkSubEnum);
8104 dwSize =
sizeof(acSubEnum);
8107 catch (CString strError) {
8109 RegCloseKey(hkEnum);
8110 if (hkSubEnum != NULL)
8111 RegCloseKey(hkSubEnum);
8112 if (hkSubSubEnum != NULL)
8113 RegCloseKey(hkSubSubEnum);
8117 RegCloseKey(hkEnum);
8120 void SearchPnpKeyW9x(HKEY hkPnp, BOOL bUsbDevice,
8121 CArray<SSerInfo,SSerInfo&> &asi)
8126 HKEY hkSubPnp = NULL;
8131 DWORD dwSubPnpIndex = 0;
8132 DWORD dwSize =
sizeof(acSubPnp);
8133 while (RegEnumKeyEx(hkPnp, dwSubPnpIndex++, acSubPnp, &dwSize,
8134 NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
8136 HKEY hkSubPnp = NULL;
8137 if (RegOpenKeyEx(hkPnp, acSubPnp, 0, KEY_READ,
8138 &hkSubPnp) != ERROR_SUCCESS)
8139 throw CString(
"Could not read from HKLM\\Enum\\...\\")
8144 dwSize =
sizeof(acValue);
8145 if (RegQueryValueEx(hkSubPnp,
"PORTNAME", NULL, NULL, (BYTE*)acValue,
8146 &dwSize) == ERROR_SUCCESS)
8148 CString strPortName(acValue);
8151 CString strFriendlyName;
8152 dwSize =
sizeof(acValue);
8153 if (RegQueryValueEx(hkSubPnp,
"FRIENDLYNAME", NULL, NULL, (BYTE*)acValue,
8154 &dwSize) == ERROR_SUCCESS)
8155 strFriendlyName = acValue;
8159 si.strDevPath = CString(
"\\\\.\\") + strPortName;
8160 si.strPortName = strPortName;
8161 si.strFriendlyName = strFriendlyName;
8162 si.bUsbDevice = bUsbDevice;
8166 for (
int ii=0; ii<asi.GetSize() && !bDup; ii++)
8168 if (asi[ii].strPortName == strPortName) {
8179 RegCloseKey(hkSubPnp);
8181 dwSize =
sizeof(acSubPnp);
8184 catch (CString strError) {
8185 if (hkSubPnp != NULL)
8186 RegCloseKey(hkSubPnp);
8193 bool ReloadLocale() {
8198 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
8204 void ApplyLocale() {
8205 FontMgr::Get().SetLocale(g_locale);
8206 FontMgr::Get().ScrubList();
8213 if (pRoutePropDialog) {
8214 pRoutePropDialog->Hide();
8215 pRoutePropDialog->Destroy();
8216 pRoutePropDialog = NULL;
8219 if (pRouteManagerDialog) {
8220 pRouteManagerDialog->Hide();
8221 pRouteManagerDialog->Destroy();
8222 pRouteManagerDialog = NULL;
8225 if (console) console->SetColorScheme(global_color_scheme);
8226 if (g_pais_query_dialog_active) {
8227 g_pais_query_dialog_active->Destroy();
8228 g_pais_query_dialog_active = NULL;
8231 auto alert_dlg_active =
8233 if (alert_dlg_active) {
8234 alert_dlg_active->Destroy();
8235 g_pais_alert_dialog_active =
nullptr;
8238 if (g_pAISTargetList) {
8239 if (g_pauimgr) g_pauimgr->DetachPane(g_pAISTargetList);
8240 g_pAISTargetList->Disconnect_decoder();
8241 g_pAISTargetList->Destroy();
8242 g_pAISTargetList = NULL;
8246 if (gFrame->m_pMenuBar) {
8247 gFrame->SetMenuBar(NULL);
8248 gFrame->m_pMenuBar->Destroy();
8249 gFrame->m_pMenuBar = NULL;
8251 gFrame->BuildMenuBar();
8254 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
8256 if (cc) cc->CanvasApplyLocale();
8261 wxString perspective;
8262 pConfig->SetPath(_T (
"/AUI" ));
8263 pConfig->Read(_T (
"AUIPerspective" ), &perspective);
8268 PluginLoader::getInstance()->DeactivateAllPlugIns();
8269 PluginLoader::getInstance()->UpdatePlugIns();
8277 bool bno_load =
false;
8278 wxAuiPaneInfoArray pane_array_val = g_pauimgr->GetAllPanes();
8280 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
8281 wxAuiPaneInfo pane = pane_array_val[i];
8282 if (perspective.Find(pane.name) == wxNOT_FOUND) {
8288 if (!bno_load) g_pauimgr->LoadPerspective(perspective,
false);
8290 g_pauimgr->Update();
8293 gFrame->RequestNewToolbars(
true);
8294 gFrame->RequestNewMasterToolbar(
true);
8298 extern s57RegistrarMgr *m_pRegistrarMan;
8299 extern wxString g_UserPresLibData;
8300 extern wxString g_SENCPrefix;
8301 extern wxString g_csv_locn;
8317 g_csv_locn = g_Platform->GetSharedDataDir();
8318 g_csv_locn.Append(_T(
"s57data"));
8321 g_csv_locn = _T(
".");
8322 appendOSDirSlash(&g_csv_locn);
8323 g_csv_locn.Append(_T(
"s57data"));
8328 if (g_SENCPrefix.IsEmpty()) {
8330 appendOSDirSlash(&g_SENCPrefix);
8331 g_SENCPrefix.Append(_T(
"SENC"));
8335 wxFileName f(g_SENCPrefix);
8337 g_SENCPrefix = f.GetFullPath();
8339 g_SENCPrefix = _T(
"SENC");
8345 bool b_force_legacy =
false;
8347 if (g_UserPresLibData.IsEmpty()) {
8348 plib_data = g_csv_locn;
8349 appendOSDirSlash(&plib_data);
8350 plib_data.Append(_T(
"S52RAZDS.RLE"));
8352 plib_data = g_UserPresLibData;
8353 b_force_legacy =
true;
8356 ps52plib =
new s52plib(plib_data, b_force_legacy);
8371 if (!ps52plib->m_bOK) {
8374 wxStandardPaths &std_path = g_Platform->GetStdPaths();
8376 wxString look_data_dir;
8377 look_data_dir.Append(std_path.GetUserDataDir());
8378 appendOSDirSlash(&look_data_dir);
8379 wxString tentative_SData_Locn = look_data_dir;
8380 look_data_dir.Append(_T(
"s57data"));
8382 plib_data = look_data_dir;
8383 appendOSDirSlash(&plib_data);
8384 plib_data.Append(_T(
"S52RAZDS.RLE"));
8386 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
8387 ps52plib =
new s52plib(plib_data);
8389 if (ps52plib->m_bOK) {
8390 g_csv_locn = look_data_dir;
8399 if (!ps52plib->m_bOK) {
8402 wxString look_data_dir;
8403 look_data_dir = g_Platform->GetSharedDataDir();
8404 look_data_dir.Append(_T(
"s57data"));
8406 plib_data = look_data_dir;
8407 appendOSDirSlash(&plib_data);
8408 plib_data.Append(_T(
"S52RAZDS.RLE"));
8410 wxLogMessage(_T(
"Looking for s57data in ") + look_data_dir);
8411 ps52plib =
new s52plib(plib_data);
8413 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
8416 if (ps52plib->m_bOK) {
8417 wxLogMessage(_T(
"Using s57data in ") + g_csv_locn);
8419 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
8424 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
8426 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
8427 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
8428 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
8429 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
8432 pConfig->LoadS57Config();
8433 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
8436 ps52plib->SetDisplayWidth(g_monitor_info[g_current_monitor].width);
8437 ps52plib->SetPPMM(g_BasePlatform->GetDisplayDPmm());
8438 double dip_factor = g_BasePlatform->GetDisplayDIPMult(gFrame);
8439 ps52plib->SetDIPFactor(dip_factor);
8440 ps52plib->SetContentScaleFactor(OCPN_GetDisplayContentScaleFactor());
8444 ps52plib->SetScaleFactorExp(g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
8445 ps52plib-> SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
8450 extern bool g_b_EnableVBO;
8451 extern GLenum g_texture_rectangle_format;
8456 wxString renderer = wxString(GL_Caps->Renderer.c_str());
8457 ps52plib->SetGLRendererString(renderer);
8460 ps52plib->SetGLOptions(
8461 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
8462 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
8463 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
8470 _T(
" S52PLIB Initialization failed, disabling Vector charts."));
8479 : wxThread(wxTHREAD_JOINABLE) {
8480 m_filename = filename;
8491 newChart->SetNativeScale(m_scale);
8492 newChart->SetFullExtent(m_ext);
8494 newChart->FindOrCreateSenc(m_filename);
8499 wxString m_filename;
8505 static double chart_dist(
int index) {
8511 if (cte.GetBBox().Contains(gLat, gLon))
8516 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
8517 d = DistGreatCircle(cte.GetLatMax(), clon, gLat, gLon);
8518 t = DistGreatCircle(cte.GetLatMin(), clon, gLat, gLon);
8521 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
8522 t = DistGreatCircle(clat, cte.GetLonMin(), gLat, gLon);
8524 t = DistGreatCircle(clat, cte.GetLonMax(), gLat, gLon);
8530 WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
8531 static int CompareInts(
int n1,
int n2) {
8532 double d1 = chart_dist(n1);
8533 double d2 = chart_dist(n2);
8534 return (
int)(d1 - d2);
8539 wxString chart_path;
8544 WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
8546 #include <wx/arrimpl.cpp>
8549 void ParseAllENC(wxWindow *parent) {
8550 MySortedArrayInt idx_sorted_by_distance(CompareInts);
8558 for (
int i = 0; i < ChartData->GetChartTableEntries(); i++) {
8561 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
8563 idx_sorted_by_distance.Add(i);
8567 if (count == 0)
return;
8569 wxLogMessage(wxString::Format(_T(
"ParseAllENC() count = %d"), count));
8575 ArrayOfCompressTargets ct_array;
8576 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
8577 int i = idx_sorted_by_distance[j];
8580 double distance = chart_dist(i);
8582 wxString filename(cte.GetpFullPath(), wxConvUTF8);
8585 pct->distance = distance;
8586 pct->chart_path = filename;
8588 ct_array.push_back(pct);
8591 int thread_count = 0;
8594 extern int g_nCPUCount;
8595 if (g_nCPUCount > 0)
8596 thread_count = g_nCPUCount;
8598 thread_count = wxThread::GetCPUCount();
8600 if (thread_count < 1) {
8609 for(
int t = 0; t < thread_count; t++)
8613 wxGenericProgressDialog *prog =
nullptr;
8614 wxSize csz = GetOCPNCanvasWindow()->GetClientSize();
8617 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8618 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8620 prog =
new wxGenericProgressDialog();
8621 wxFont *qFont = GetOCPNScaledFont(_(
"Dialog"));
8622 prog->SetFont(*qFont);
8624 prog->Create(_(
"OpenCPN ENC Prepare"),
8625 _T(
"Longgggggggggggggggggggggggggggg"), count + 1, parent,
8635 prog->ShowWindowModal();
8644 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8645 wxString filename = ct_array[j].chart_path;
8646 double distance = ct_array[j].distance;
8647 int index = ChartData->FinddbIndex(filename);
8648 if (index < 0)
continue;
8651 ext.NLAT = cte.GetLatMax();
8652 ext.SLAT = cte.GetLatMin();
8653 ext.WLON = cte.GetLonMin();
8654 ext.ELON = cte.GetLonMax();
8656 int scale = cte.GetScale();
8659 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8662 if (wxThread::IsMain()) {
8664 wxSize sz = prog->GetSize();
8666 msg += _T(
" Chart:");
8669 prog->Update(count, msg, &skip);
8681 newChart->SetNativeScale(
scale);
8682 newChart->SetFullExtent(ext);
8683 newChart->DisableBackgroundSENC();
8685 newChart->FindOrCreateSenc(filename,
8689 if (wxThread::IsMain()) {
8690 msg.Printf(_(
"ENC Completed."));
8692 prog->Update(count, msg, &skip);
8702 for (
int t = 0;; t = (t + 1) % thread_count) {
8709 if (!workers[t]->IsAlive()) {
8722 #if defined(__WXMSW__) || defined(__WXOSX__)
8729 for(
int t = 0; t<thread_count; t++) {
Global state for AIS decoder.
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.
const void Notify()
Notify all listeners, no data supplied.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
void OnFrameTimer1(wxTimerEvent &event)
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
bool Active() const
Return true if log is visible i.
void Add(const wxString &s)
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.
Adds a std::shared<void> element to wxCommandEvent.
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.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
EventVar evt_resume
Notified when resuming from hibernate.
Global variables reflecting command line options and arguments.
Hooks int gui available in model.
General purpose GUI support.
Handle dialog reporting plugin load errors.
The local API has a server side handling commands and a client part issuing commands.
wxDEFINE_EVENT(REST_IO_EVT, ObservedEvt)
Event from IO thread to main.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.