63#if (defined(OCPN_GHC_FILESYSTEM) || \
64 (defined(__clang_major__) && (__clang_major__ < 15)))
66#include <ghc/filesystem.hpp>
67namespace fs = ghc::filesystem;
71namespace fs = std::filesystem;
74using namespace std::literals::chrono_literals;
76#include <wx/apptrait.h>
77#include <wx/arrimpl.cpp>
78#include <wx/artprov.h>
79#include <wx/aui/aui.h>
80#include <wx/clrpicker.h>
81#include <wx/cmdline.h>
85#include <wx/display.h>
90#include <wx/jsonreader.h>
91#include <wx/listctrl.h>
93#include <wx/printdlg.h>
95#include <wx/progdlg.h>
96#include <wx/settings.h>
97#include <wx/stdpaths.h>
98#include <wx/tokenzr.h>
100#include "model/ais_decoder.h"
102#include "model/certificates.h"
104#include "model/comm_bridge.h"
105#include "model/comm_n0183_output.h"
106#include "model/comm_vars.h"
107#include "model/config_vars.h"
108#include "model/instance_check.h"
113#include "model/multiplexer.h"
115#include "model/nav_object_database.h"
116#include "model/navutil_base.h"
118#include "model/own_ship.h"
120#include "model/route.h"
121#include "model/routeman.h"
122#include "model/select.h"
123#include "model/track.h"
127#include "ais_info_gui.h"
128#include "AISTargetAlertDialog.h"
129#include "AISTargetListDialog.h"
130#include "AISTargetQueryDialog.h"
131#include "CanvasConfig.h"
137#include "ConfigMgr.h"
138#include "DetailSlider.h"
141#include "gdal/cpl_csv.h"
142#include "glTexCache.h"
143#include "GoToPositionDialog.h"
147#include "observable.h"
149#include "OCPN_AUIManager.h"
150#include "ocpn_frame.h"
151#include "OCPNPlatform.h"
153#include "rest_server_gui.h"
154#include "route_ctx_factory.h"
155#include "routemanagerdialog.h"
156#include "routeman_gui.h"
157#include "RoutePropDlgImpl.h"
160#include "S57QueryDialog.h"
161#include "safe_mode_gui.h"
162#include "SoundFactory.h"
166#include "TrackPropDlg.h"
170#include "glChartCanvas.h"
174#include "model/macutils.h"
178#include "model/garmin_protocol_mgr.h"
179void RedirectIOToConsole();
182#if defined(__WXMSW__) && defined(__MSVC__LEAK)
183#include "Stackwalker.h"
187#include "crashprint.h"
191#include "androidUTIL.h"
197const char *
const kUsage =
200 opencpn [-p] [-f] [-G] [-g] [-P] [-l <str>] [-u <num>] [-U] [-s] [GPX file ...]
201 opencpn --remote [-R] | -q] | -e] |-o <str>]
203Options for starting opencpn
205 -c, --configdir=<dirpath> Use alternative configuration directory.
206 -p, --portable Run in portable mode.
207 -f, --fullscreen Switch to full screen mode on start.
208 -G, --no_opengl Disable OpenGL video acceleration. This setting will
210 -g, --rebuild_gl_raster_cache Rebuild OpenGL raster cache on start.
211 -D, --rebuild_chart_db Rescan chart directories and rebuild the chart database
212 -P, --parse_all_enc Convert all S-57 charts to OpenCPN's internal format on start.
213 -l, --loglevel=<str> Amount of logging: error, warning, message, info, debug or trace
214 -u, --unit_test_1=<num> Display a slideshow of <num> charts and then exit.
215 Zero or negative <num> specifies no limit.
217 -s, --safe_mode Run without plugins, opengl and other "dangerous" stuff
218 -W, --config_wizard Start with initial configuration wizard
220Options manipulating already started opencpn
221 -r, --remote Execute commands on already running instance
222 -R, --raise Make running OpenCPN visible if hidden
223 -q, --quit Terminate already running opencpn
224 -e, --get_rest_endpoint Print rest server endpoint and exit.
225 -o, --open=<GPX file> Open file in running opencpn
228 GPX file GPX-formatted file with waypoints or routes.
232wxDEFINE_EVENT(EVT_N2K_129029, wxCommandEvent);
233wxDEFINE_EVENT(EVT_N2K_129026, wxCommandEvent);
235wxDEFINE_EVENT(EVT_N0183_RMC, wxCommandEvent);
236wxDEFINE_EVENT(EVT_N0183_HDT, wxCommandEvent);
237wxDEFINE_EVENT(EVT_N0183_HDG, wxCommandEvent);
238wxDEFINE_EVENT(EVT_N0183_HDM, wxCommandEvent);
239wxDEFINE_EVENT(EVT_N0183_VTG, wxCommandEvent);
240wxDEFINE_EVENT(EVT_N0183_GSV, wxCommandEvent);
241wxDEFINE_EVENT(EVT_N0183_GGA, wxCommandEvent);
242wxDEFINE_EVENT(EVT_N0183_GLL, wxCommandEvent);
243wxDEFINE_EVENT(EVT_N0183_AIVDO, wxCommandEvent);
253WX_DEFINE_OBJARRAY(ArrayOfCDI);
258bool g_bUpgradeInProcess;
270int g_restore_stackindex;
271int g_restore_dbindex;
272double g_ChartNotRenderScaleFactor;
274LayerList *pLayerList;
286int g_nbrightness = 100;
288bool bDBUpdateInProgress;
293bool g_bshowToolbar =
true;
294bool g_bexpert =
true;
295bool g_bBasicMenus =
false;
297bool bDrawCurrentValues;
299wxString ChartListFileName;
300wxString gWorldMapLocation, gDefaultWorldMapLocation;
301wxString gWorldShapefileLocation;
302wxString *pInit_Chart_Dir;
304wxString g_SENCPrefix;
305wxString g_UserPresLibData;
306wxString g_VisibleLayers;
307wxString g_InvisibleLayers;
308wxString g_VisiNameinLayers;
309wxString g_InVisiNameinLayers;
311bool g_bcompression_wait;
312bool g_FlushNavobjChanges;
313int g_FlushNavobjChangesTimeout;
315wxString g_uploadConnection;
322int g_mem_total, g_mem_initial;
324bool s_bSetSystemTime;
326static unsigned int malloc_max;
328wxDateTime g_start_time;
329wxDateTime g_loglast_time;
330static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
331std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
333OcpnSound *g_anchorwatch_sound = SoundFactory();
335double AnchorPointMinDist;
336bool AnchorAlertOn1, AnchorAlertOn2;
344bool g_bShowDepthUnits;
348bool g_bShowActiveRouteHighway;
351bool g_bPlayShipsBells;
352bool g_bFullscreenToolbar;
354bool g_bTransparentToolbar;
355bool g_bTransparentToolbarInOpenGLOK;
356int g_nAutoHideToolbar;
357bool g_bAutoHideToolbar;
359bool g_bPermanentMOBIcon;
360bool g_bTempShowMenuBar;
362int g_iNavAidRadarRingsNumberVisible;
363bool g_bNavAidRadarRingsShown;
364float g_fNavAidRadarRingsStep;
365int g_pNavAidRadarRingsStepUnits;
366bool g_bWayPointPreventDragging;
367bool g_bConfirmObjectDelete;
368wxColour g_colourOwnshipRangeRingsColour;
372ColorScheme global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
374wxArrayPtrVoid *UserColourHashTableArray;
375wxColorHashMap *pcurrent_user_color_hash;
384int g_ChartUpdatePeriod;
385int g_SkewCompUpdatePeriod;
387int g_lastClientRectx;
388int g_lastClientRecty;
389int g_lastClientRectw;
390int g_lastClientRecth;
394double g_display_size_mm;
395std::vector<size_t> g_config_display_size_mm;
396bool g_config_display_size_manual;
399int g_ChartScaleFactor;
400float g_MarkScaleFactorExp;
401int g_last_ChartScaleFactor;
402int g_ShipScaleFactor;
403float g_ShipScaleFactorExp;
404int g_ENCSoundingScaleFactor;
405int g_ENCTextScaleFactor;
411s57RegistrarMgr *m_pRegistrarMan;
416#include "model/macutils.h"
425extern bool s_glu_dll_ready;
426extern HINSTANCE s_hGLU_DLL;
432double g_ownship_predictor_minutes;
433double g_ownship_HDTpredictor_miles;
434int g_cog_predictor_style;
435wxString g_cog_predictor_color;
436int g_cog_predictor_endmarker;
437int g_ownship_HDTpredictor_style;
438wxString g_ownship_HDTpredictor_color;
439int g_ownship_HDTpredictor_endmarker;
440int g_ownship_HDTpredictor_width;
442bool g_own_ship_sog_cog_calc;
443int g_own_ship_sog_cog_calc_damp_sec;
448int g_iSoundDeviceIndex;
450int g_S57_dialog_sx, g_S57_dialog_sy;
458bool g_bAutoAnchorMark;
461long gStart_LMT_Offset;
463wxArrayString *pMessageOnceArray;
465bool g_bUseGLL =
true;
496bool g_bsmoothpanzoom;
498bool g_bSmoothRecenter =
true;
500double g_overzoom_emphasis_base;
501bool g_oz_vector_scale;
502double g_plus_minus_zoom_factor;
505bool g_b_legacy_input_filter_behaviour;
512bool g_bFullScreenQuilt =
true;
516ChartGroupArray *g_pGroupArray;
520std::vector<std::string> TideCurrentDataSet;
521wxString g_TCData_Dir;
524bool g_bDeferredInitDone;
525int options_lastPage = 0;
526int options_subpage = 0;
528wxPoint options_lastWindowPos(0, 0);
529wxSize options_lastWindowSize(0, 0);
532bool g_bsimplifiedScalebar;
536bool GetMemoryStatus(
int *mem_total,
int *mem_used);
539int g_nAIS_activity_timer;
541bool g_bEnableZoomToCursor;
544bool g_bDeferredStartTrack;
545bool g_bHighliteTracks;
546wxColour g_colourTrackLineColour;
547wxString g_default_wp_icon;
550double g_TrackIntervalSeconds;
552int g_cm93_zoom_factor;
554bool g_bShowDetailSlider;
555int g_detailslider_dialog_x, g_detailslider_dialog_y;
562bool g_b_overzoom_x =
true;
564int g_OwnShipIconType;
565double g_n_ownship_length_meters;
566double g_n_ownship_beam_meters;
567double g_n_gps_antenna_offset_y;
568double g_n_gps_antenna_offset_x;
569int g_n_ownship_min_mm;
574bool g_bPreserveScaleOnX;
575bool g_CanvasHideNotificationIcon;
578About *g_pAboutDlgLegacy;
580#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
581wxLocale *plocale_def_lang = 0;
593wxString g_localeOverride;
594bool g_b_assume_azerty;
600bool g_bShowStatusBar;
606int g_AisTargetList_count;
607bool g_bAisTargetList_autosort;
612wxAuiDefaultDockArt *g_pauidockart;
614wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
619long g_maintoolbar_orient;
620float g_toolbar_scalefactor;
622float g_compass_scalefactor;
624bool g_bShowCompassWin;
626bool g_benable_rotate;
634double gQueryVar = 361.0;
636char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
638int portaudio_initialized;
640char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
643int g_sticky_projection;
645int n_NavMessageShown;
646wxString g_config_version_string;
648wxString g_CmdSoundString;
666bool b_inCompressAllCharts;
670int g_chart_zoom_modifier_raster;
671int g_chart_zoom_modifier_vector;
673bool g_bAdvanceRouteWaypointOnArrivalOnly;
675bool g_bSpaceDropMark;
677wxArrayString g_locale_catalog_array;
678bool b_reloadForPlugins;
679bool g_btrackContinuous;
681unsigned int g_canvasConfig;
683bool g_bmasterToolbarFull =
true;
685int g_AndroidVersionCode;
690WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
692arrayofCanvasPtr g_canvasArray;
693wxString g_lastAppliedTemplateGUID;
699bool g_disable_main_toolbar;
701bool g_declutter_anchorage;
702bool g_bhide_route_console;
703bool g_bhide_context_menus;
715DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
716 0x6b, 0xba, 0xe7, 0x22, 0xc0);
720#include <wx/msw/msvcrt.h>
724static const long long lNaN = 0xfff8000000000000;
725#define NAN (*(double *)&lNaN)
729void appendOSDirSlash(wxString *pString);
731void InitializeUserColors(
void);
732void DeInitializeUserColors(
void);
733void SetSystemColors(ColorScheme cs);
735static bool LoadAllPlugIns(
bool load_enabled) {
736 g_Platform->ShowBusySpinner();
737 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
738 g_Platform->HideBusySpinner();
746#if defined(__WXGTK__) || defined(__WXQT__)
747#include "bitmaps/opencpn.xpm"
750wxString newPrivateFileName(wxString,
const char *name,
751 [[maybe_unused]]
const char *windowsName) {
752 wxString fname = wxString::FromUTF8(name);
753 wxString filePathAndName;
756 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
757 filePathAndName.Append(wxFileName::GetPathSeparator());
760 wxString fwname = wxString::FromUTF8(windowsName);
761 filePathAndName.Append(fwname);
763 filePathAndName.Append(fname);
766 return filePathAndName;
775BEGIN_EVENT_TABLE(
MyApp, wxApp)
776EVT_ACTIVATE_APP(MyApp::OnActivateApp)
779static
void ActivateRoute(const std::
string &guid) {
780 Route *route = g_pRouteMan->FindRouteByGUID(guid);
782 wxLogMessage(
"Cannot activate guid: no such route");
785 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
791 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
793 point = route->GetPoint(2);
800static void ReverseRoute(
const std::string &guid) {
801 Route *route = g_pRouteMan->FindRouteByGUID(guid);
803 wxLogMessage(
"Cannot activate guid: no such route");
810void MyApp::InitRestListeners() {
811 auto activate_route = [&](wxCommandEvent ev) {
812 auto guid = ev.GetString().ToStdString();
816 auto reverse_route = [&](wxCommandEvent ev) {
817 auto guid = ev.GetString().ToStdString();
823bool MyApp::OpenFile(
const std::string &path) {
825 auto result = nav_objects.load_file(path.c_str());
827 std::string s(_(
"Cannot load route or waypoint file: "));
828 s += std::string(
"\"") + path +
"\"";
829 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
835 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
837 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
838 pRouteManagerDialog->UpdateLists();
839 LLBBox box = nav_objects.GetBBox();
840 if (box.GetValid()) {
841 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
847void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
850 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
851 parser.AddSwitch(
"p",
"portable");
852 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
853 wxCMD_LINE_PARAM_OPTIONAL);
854 parser.AddSwitch(
"f",
"fullscreen");
855 parser.AddSwitch(
"G",
"no_opengl");
856 parser.AddSwitch(
"W",
"config_wizard");
857 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
858 parser.AddSwitch(
"D",
"rebuild_chart_db");
859 parser.AddSwitch(
"P",
"parse_all_enc");
860 parser.AddOption(
"l",
"loglevel");
861 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
862 parser.AddSwitch(
"U",
"unit_test_2");
863 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
864 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
865 parser.AddSwitch(
"s",
"safe_mode");
866 parser.AddSwitch(
"r",
"remote");
867 parser.AddSwitch(
"R",
"raise");
868 parser.AddSwitch(
"q",
"quit");
869 parser.AddSwitch(
"e",
"get_rest_endpoint");
870 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
871 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
877static void ParseLoglevel(wxCmdLineParser &parser) {
878 wxLog::SetLogLevel(wxLOG_Message);
881static void ParseLoglevel(wxCmdLineParser &parser) {
882 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
883 strLevel = strLevel ? strLevel :
"info";
885 if (parser.Found(
"l", &wxLevel)) {
886 strLevel = wxLevel.c_str();
888 wxLogLevel level = OcpnLog::str2level(strLevel);
889 if (level == OcpnLog::LOG_BADLEVEL) {
890 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
893 wxLog::SetLogLevel(level);
898bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
905bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
910 g_unit_test_2 = parser.Found(
"unit_test_2");
911 g_bportable = parser.Found(
"p");
912 g_start_fullscreen = parser.Found(
"fullscreen");
913 g_bdisable_opengl = parser.Found(
"no_opengl");
914 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
915 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
916 g_parse_all_enc = parser.Found(
"parse_all_enc");
917 g_config_wizard = parser.Found(
"config_wizard");
918 if (parser.Found(
"unit_test_1", &number)) {
919 g_unit_test_1 =
static_cast<int>(number);
920 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
922 safe_mode::set_mode(parser.Found(
"safe_mode"));
923 ParseLoglevel(parser);
925 if (parser.Found(
"configdir", &wxstr)) {
926 g_configdir = wxstr.ToStdString();
927 fs::path path(g_configdir);
928 if (!fs::exists(path) || !fs::is_directory(path)) {
929 std::cerr << g_configdir <<
" is not an existing directory.\n";
934 bool has_start_options =
false;
935 static const std::vector<std::string> kStartOptions = {
940 "rebuild_gl_raster_cache",
946 for (
const auto &opt : kStartOptions) {
947 if (parser.Found(opt)) has_start_options =
true;
949 if (has_start_options && parser.Found(
"remote")) {
950 std::cerr <<
"this option is not compatible with --remote\n";
954 bool has_remote_options =
false;
955 static const std::vector<std::string> kRemoteOptions = {
956 "raise",
"quit",
"open",
"get_rest_endpoint"};
957 for (
const auto &opt : kRemoteOptions) {
958 if (parser.Found(opt)) has_remote_options =
true;
960 if (has_remote_options && !parser.Found(
"remote")) {
961 std::cerr <<
"This option requires --remote\n";
965 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
966 g_params.push_back(parser.GetParam(paramNr).ToStdString());
969 if (!parser.Found(
"remote"))
970 m_parsed_cmdline = ParsedCmdline();
971 else if (parser.Found(
"raise"))
972 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
973 else if (parser.Found(
"quit"))
974 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
975 else if (parser.Found(
"get_rest_endpoint"))
976 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
977 else if (parser.Found(
"open", &optarg))
978 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
979 else if (parser.GetParamCount() == 1)
981 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
982 else if (!has_start_options && !has_remote_options) {
984 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
994bool MyApp::OnExceptionInMainLoop() {
995 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
1000void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
1002static wxStopWatch init_sw;
1005 if (m_exitcode != -2)
return m_exitcode;
1006 return wxAppConsole::OnRun();
1017 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1018 setenv(
"GDK_BACKEND",
"x11", 1);
1021 "mesa_glthread",
"false",
1027bool MyApp::OnInit() {
1028 if (!wxApp::OnInit())
return false;
1030 androidEnableBackButton(
false);
1031 androidEnableOptionItems(
false);
1036#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1042 wxBitmap bmp(10, 10, -1);
1044 dc.SelectObject(bmp);
1045 dc.DrawText(_T(
"X"), 0, 0);
1050 g_BasePlatform = g_Platform;
1057 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1061 std::cerr <<
"No remote opencpn found. Giving up.\n";
1066 std::unique_ptr<LocalClientApi> client;
1068 client = LocalClientApi::GetClient();
1070 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1077 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1078 "to respond.\nPlease retry."),
1079 "OpenCPN", wxICON_INFORMATION | wxOK);
1084 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1085 m_parsed_cmdline.arg);
1089 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1098 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1099 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1104 if (!safe_mode::get_mode()) {
1110 OCPNPlatform::Initialize_1();
1115 MyApp::SetAppDisplayName(
"OpenCPN");
1118 wxDateTime x = wxDateTime::UNow();
1119 long seed = x.GetMillisecond();
1120 seed *= x.GetTicks();
1125 setlocale(LC_NUMERIC,
"C");
1127 g_start_time = wxDateTime::Now();
1129 g_loglast_time = g_start_time;
1130 g_loglast_time.MakeGMT();
1131 g_loglast_time.Subtract(
1132 wxTimeSpan(0, 29, 0, 0));
1134 AnchorPointMinDist = 5.0;
1140 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1144 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1145 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1146 wxFONTENCODING_SYSTEM);
1147 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1150 auto ¬eman = NotificationManager::GetInstance();
1151 noteman.ScrubNotificationDirectory(30);
1154 if (!g_Platform->InitializeLogFile()) {
1166 wxLogMessage(_T(
"\n\n________\n"));
1168 wxDateTime now = wxDateTime::Now();
1169 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1170 now.FormatISODate().mb_str().data());
1171 wxLogLevel level = wxLog::GetLogLevel();
1172 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1174 wxString wxver(wxVERSION_STRING);
1175 wxver.Prepend(_T(
"wxWidgets version: "));
1177 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1181 os_name = platforminfo.GetOperatingSystemIdName();
1183 os_name = platforminfo.GetOperatingSystemFamilyName();
1186 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1187 platforminfo.GetPortIdName();
1189 wxLogMessage(wxver + _T(
" ") + platform);
1191 ::wxGetOsVersion(&osMajor, &osMinor);
1192 wxString osVersionMsg;
1193 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1194 wxLogMessage(osVersionMsg);
1196 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1197 g_mem_total / 1024, g_mem_initial / 1024);
1202 if (!detail->osd_names_like.empty())
1203 like0 = detail->osd_names_like[0].c_str();
1204 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1205 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1206 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1208 wxLogMessage(msgplat);
1210 wxString imsg = _T(
"SData_Locn is ");
1211 imsg += g_Platform->GetSharedDataDir();
1215 ::wxInitAllImageHandlers();
1219 prepareAndroidStyleSheets();
1223 pInit_Chart_Dir =
new wxString();
1226 g_pGroupArray =
new ChartGroupArray;
1228 imsg = _T(
"PrivateDataDir is ");
1234 pMessageOnceArray =
new wxArrayString;
1238 new Routeman(RoutePropDlg::GetDlgCtx(), RoutemanGui::GetDlgCtx());
1242 pSelect->SetSelectPixelRadius(12);
1245 pSelectTC =
new Select();
1247 pSelectTC->SetSelectPixelRadius(25);
1250 pSelectAIS =
new Select();
1251 pSelectAIS->SetSelectPixelRadius(12);
1255 g_pais_query_dialog_active = NULL;
1258 g_hostname = ::wxGetHostName();
1259 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1261 androidGetDeviceInfo();
1262 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1263 g_hostname.Replace(
" ",
"-",
true);
1268 wxString p(
"Portable-");
1269 g_hostname = p + g_hostname;
1274 pLayerList =
new LayerList;
1276 pRouteList =
new RouteList;
1279 auto &navobj_db = NavObj_dB::GetInstance();
1286#ifdef PROBE_PORTS__WITH_HELPER
1287 user_user_id = getuid();
1288 file_user_id = geteuid();
1292 bool b_initial_load =
false;
1294 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1295 if (config_test_file_name.FileExists())
1296 wxLogMessage(_T(
"Using existing Config_File: ") +
1297 g_Platform->GetConfigFileName());
1300 wxLogMessage(_T(
"Creating new Config_File: ") +
1301 g_Platform->GetConfigFileName());
1303 b_initial_load =
true;
1306 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1307 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1308 wxLogMessage(_T(
"Cannot create config file directory for ") +
1309 g_Platform->GetConfigFileName());
1314 pConfig = g_Platform->GetConfigObject();
1315 InitBaseConfig(pConfig);
1316 pConfig->LoadMyConfig();
1320 if (b_initial_load) g_Platform->SetDefaultOptions();
1322 g_Platform->applyExpertMode(g_bUIexpert);
1330 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1331 if (!g_StyleManager->IsOK()) {
1332 wxString msg = _(
"Failed to initialize the user interface. ");
1333 msg << _(
"OpenCPN cannot start. ");
1334 msg << _(
"The necessary configuration files were not found. ");
1335 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1336 << _(
" for details.") << _T(
"\n\n");
1337 msg << g_Platform->GetSharedDataDir();
1339 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1340 wxCANCEL | wxICON_ERROR);
1347 if (style) style->chartStatusWindowTransparent =
true;
1351 pWayPointMan = NULL;
1355 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1356 (
int)g_display_size_mm);
1360 if (g_config_display_size_manual &&
1361 g_config_display_size_mm.size() > g_current_monitor &&
1362 g_config_display_size_mm[g_current_monitor] > 0) {
1363 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1365 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1366 (
int)g_display_size_mm);
1371 g_display_size_mm = wxMax(50, g_display_size_mm);
1374 int SelectPixelRadius = 50;
1376 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1377 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1378 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1382 if (!n_NavMessageShown) {
1389#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1392 g_Platform->SetLocaleSearchPrefixes();
1394 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1396 imsg = _T(
"System default Language: ") + def_lang_canonical;
1399 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1400 wxLogMessage(cflmsg);
1402 if (g_locale.IsEmpty()) {
1403 g_locale = def_lang_canonical;
1405 _T(
"Config file language empty, using system default: ") + g_locale;
1406 wxLogMessage(cflmsg);
1410 g_locale = g_Platform->GetAdjustedAppLocale();
1411 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1412 wxLogMessage(cflmsg);
1415 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1417 imsg = _T(
"Opencpn language set to: ");
1424 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1426 wxLogMessage(_T(
"wxLocale support not available"));
1431 if (g_config_wizard || b_initial_load) {
1433 auto res = wiz.Run();
1444 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1445 g_bUpgradeInProcess = (vs != g_config_version_string);
1447 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1450 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1451 wxLogMessage(g_Platform->GetLargeLogMessage());
1456 g_bdisable_opengl =
true;
1460 if (g_bdisable_opengl) g_bopengl =
false;
1462#if defined(__linux__) && !defined(__ANDROID__)
1463 if (g_bSoftwareGL) {
1464 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1477 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1479 wxMin(g_memCacheLimit, 1024 * 1024);
1485 g_memCacheLimit = 0;
1486 if (0 == g_nCacheLimit)
1487 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1492 "chartlist.dat",
"CHRTLIST.DAT");
1496 "mmsitoname.csv",
"MMSINAME.CSV");
1499 if (pInit_Chart_Dir->IsEmpty()) {
1500 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1504 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1506 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1510 InitRestListeners();
1513 gDefaultWorldMapLocation =
"gshhs";
1514 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1515 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1516 if (gWorldMapLocation == wxEmptyString) {
1517 gWorldMapLocation = gDefaultWorldMapLocation;
1522 wxString default_tcdata0 =
1523 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1524 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1525 wxString default_tcdata1 =
1526 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1527 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1529 if (TideCurrentDataSet.empty()) {
1530 TideCurrentDataSet.push_back(
1531 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1532 TideCurrentDataSet.push_back(
1533 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1538 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1539 wxString default_sound =
1540 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1541 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1542 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1547 g_Platform->Initialize_2();
1551 wxSize new_frame_size(-1, -1);
1553 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1555 InitializeUserColors();
1557 auto style = g_StyleManager->GetCurrentStyle();
1558 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1560 PluginLoader::GetInstance()->SetPluginDefaultIcon(bitmap);
1562 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1564 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1565 (g_nframewin_y <= ch))
1566 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1568 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1574 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1575 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1576 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1577 g_bframemax =
false;
1580 g_lastClientRectx = cx;
1581 g_lastClientRecty = cy;
1582 g_lastClientRectw = cw;
1583 g_lastClientRecth = ch;
1586 wxPoint position(0, 0);
1587 wxSize dsize = wxGetDisplaySize();
1590 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1593 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1594 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1599 frame_rect.left = position.x;
1600 frame_rect.top = position.y;
1601 frame_rect.right = position.x + new_frame_size.x;
1602 frame_rect.bottom = position.y + new_frame_size.y;
1606 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1607 position = wxPoint(10, 10);
1612 const wxPoint ptScreen(position.x, position.y);
1613 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1615 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1618 g_nframewin_posx = position.x;
1619 g_nframewin_posy = position.y;
1622 wxSize asz = getAndroidDisplayDimensions();
1627 if ((cw > 200) && (ch > 200))
1628 new_frame_size.Set(cw, ch);
1630 new_frame_size.Set(800, 400);
1634 long app_style = wxDEFAULT_FRAME_STYLE;
1635 app_style |= wxWANTS_CHARS;
1640 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1641 wxString myframe_window_title =
1642 wxString(wxT(
"OpenCPN ") + short_version_name);
1645 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1646 myframe_window_title += g_Platform->GetHomeDir();
1647 myframe_window_title += _T(
"]");
1651 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1652 new_frame_size.x, new_frame_size.y, position.x, position.y);
1655 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1657 wxTheApp->SetTopWindow(gFrame);
1660 g_Platform->Initialize_3();
1667 g_pauidockart =
new wxAuiDefaultDockArt;
1668 g_pauimgr->SetArtProvider(g_pauidockart);
1669 g_pauimgr->SetDockSizeConstraint(.9, .9);
1674 g_pauimgr->SetManagedWindow(gFrame);
1676 gFrame->CreateCanvasLayout();
1680 gFrame->SetChartUpdatePeriod();
1684 gFrame->GetPrimaryCanvas()->SetFocus();
1686 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1688 gFrame->ApplyGlobalSettings(
false);
1690 gFrame->SetAllToolbarScale();
1696 gFrame->SetAndApplyColorScheme(global_color_scheme);
1698 if (g_bframemax) gFrame->Maximize(
true);
1701 if (
g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1702 gFrame->Maximize(
true);
1709 ArrayOfCDI ChartDirArray;
1710 pConfig->LoadChartDirArray(ChartDirArray);
1715 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1718 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1719 if (RegKey.Exists()) {
1721 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1723 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1725 wxStringTokenizer tkz(dirs, _T(
";"));
1726 while (tkz.HasMoreTokens()) {
1727 wxString token = tkz.GetNextToken();
1730 cdi.fullpath = token.Trim();
1731 cdi.magic_number = _T(
"");
1733 ChartDirArray.Add(cdi);
1740 cdi.fullpath = _T(
"charts");
1741 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1742 cdi.magic_number = _T(
"");
1743 ChartDirArray.Add(cdi);
1747 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1757 if (!ChartDirArray.GetCount())
1758 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1762 if (g_NeedDBUpdate == 0 &&
1763 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1768 if (g_restore_dbindex >= 0) {
1769 if (ChartData->GetChartTableEntries() == 0)
1770 g_restore_dbindex = -1;
1772 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1773 g_restore_dbindex = 0;
1777 ChartData->ApplyGroupArray(g_pGroupArray);
1785 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1786 g_GLOptions.m_bTextureCompressionCaching) {
1787 gFrame->ReloadAllVP();
1796 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1806 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1807 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1810 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1811 gps_watchdog_timeout_ticks);
1812 wxLogMessage(dogmsg);
1814 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1822 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1824 pAnchorWatchPoint1 = NULL;
1825 pAnchorWatchPoint2 = NULL;
1829 gFrame->DoChartUpdate();
1834 gFrame->ReloadAllVP();
1836 gFrame->Refresh(
false);
1839 gFrame->GetPrimaryCanvas()->Enable();
1840 gFrame->GetPrimaryCanvas()->SetFocus();
1847 if (!g_bdisable_opengl) {
1851 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1852 gFrame->m_defer_size = gFrame->GetSize();
1853 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1854 g_pauimgr->Update();
1855 gFrame->m_bdefer_resize =
true;
1865 glDeleteTextures(n, texts);
1871 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1876 gFrame->SetSize(getAndroidDisplayDimensions());
1877 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1881 gFrame->GetPrimaryCanvas()->Enable();
1882 gFrame->GetPrimaryCanvas()->SetFocus();
1890 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1893 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1896 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1901 OCPNPlatform::Initialize_4();
1904 androidHideBusyIcon();
1907 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1915 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1916 (g_AndroidVersionCode != androidGetVersionCode())) {
1920 if (!ShowNavWarning()) {
1921 qDebug() <<
"Closing due to NavWarning Cancel";
1927 n_NavMessageShown = 1;
1931 g_AndroidVersionCode = androidGetVersionCode();
1932 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1937 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1938 if (!ShowNavWarning())
return false;
1939 n_NavMessageShown = 1;
1946 g_bHasHwClock =
true;
1947#if defined(__UNIX__) && !defined(__ANDROID__)
1950 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1951 (stat(
"/dev/misc/rtc", &buffer) == 0));
1954 g_config_version_string = vs;
1957 pConfig->UpdateSettings();
1960 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1962 g_pauimgr->Update();
1964 for (
auto *cp : TheConnectionParams()) {
1966 if (cp->GetDSPort().Contains(
"Serial")) {
1967 std::string port(cp->Port.ToStdString());
1975 m_comm_bridge.Initialize();
1977 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1980 if (ipv4_addrs.size()) {
1981 std::string ipAddr = ipv4_addrs[0];
1984 if (data_dir.Last() != wxFileName::GetPathSeparator())
1985 data_dir.Append(wxFileName::GetPathSeparator());
1987 make_certificate(ipAddr, data_dir.ToStdString());
1989 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1990 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
1996int MyApp::OnExit() {
1997 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
1999 m_usb_watcher.Stop();
2002 wxDateTime lognow = wxDateTime::Now();
2004 wxString day = lognow.FormatISODate();
2005 wxString utc = lognow.FormatISOTime();
2006 wxString navmsg = _T(
"LOGBOOK: ");
2010 navmsg += _T(
" UTC ");
2014 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2018 if (std::isnan(gCog))
2019 cog.Printf(_T(
"COG ----- "));
2021 cog.Printf(_T(
"COG %10.5f "), gCog);
2024 if (std::isnan(gSog))
2025 sog.Printf(_T(
"SOG ----- "));
2027 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2034 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2037 wxLogMessage(navmsg);
2038 g_loglast_time = lognow;
2040 if (ptcmgr)
delete ptcmgr;
2042 for (
Track *track : g_TrackList) {
2045 g_TrackList.clear();
2053 delete g_SencThreadManager;
2055 if (g_pGroupArray) {
2056 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2058 delete g_pGroupArray->Item(igroup);
2061 g_pGroupArray->Clear();
2062 delete g_pGroupArray;
2065 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2066 wxLog::FlushActive();
2068 g_Platform->CloseLogFile();
2070 delete pInit_Chart_Dir;
2072 for (
Track *track : g_TrackList) {
2075 g_TrackList.clear();
2078 delete pWayPointMan;
2080 delete pMessageOnceArray;
2082 DeInitializeUserColors();
2086 delete m_pRegistrarMan;
2089 delete g_StyleManager;
2094 if (s_glu_dll_ready) {
2095 FreeLibrary(s_hGLU_DLL);
2104 void RestoreSystemColors(
void);
2105 RestoreSystemColors();
2112#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2113 if (plocale_def_lang)
delete plocale_def_lang;
2116 FontMgr::Shutdown();
2118 g_Platform->OnExit_2();
2125#ifdef LINUX_CRASHRPT
2126void MyApp::OnFatalException() { g_crashprint.Report(); }
2132void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2137 if (eErrClass == CE_Debug)
2138 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2139 else if (eErrClass == CE_Warning)
2140 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2142 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2144 wxString str(msg, wxConvUTF8);
bool g_bresponsive
Flag to control adaptive UI scaling.
Global state for AIS decoder.
Dialog for displaying a list of AIS targets.
Dialog for querying detailed information about an AIS target.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
EventVar reverse_route
Notified with a string GUID when user wants to reverse a route.
EventVar activate_route
Notified with a string GUID when user wants to activate a route.
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Dialog for managing CM93 chart offsets.
ChartCanvas - Main chart display and interaction component.
Manages the chart database and provides access to chart data.
bool LoadBinary(const wxString &filename, ArrayOfCDI &dir_array_check)
Load the chart database from a binary file.
const void Notify()
Notify all listeners, no data supplied.
void ScrubList()
Cleans up stale font entries after a locale change.
static void SeedRandom()
Seed the random generator used by GetUUID().
Common interface for all instance checkers.
virtual bool IsMainInstance()=0
Return true if this process is the primary opencpn instance.
virtual void CleanUp()
Remove all persistent instance state, including possible lock file and defunct opencpn processes.
virtual void OnExit()
Do whatever needed before wxWidget's checks triggers.
virtual void WaitUntilValid()
Wait until this object can be used for example for Dbus connection.
static LocalServerApi & GetInstance()
Dialog for displaying and editing waypoint properties.
void Init(const KeyProvider &kp, std::function< void(ObservedEvt &ev)> action)
Initiate an object yet not listening.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool StartServer(const fs::path &certificate_location) override
Start the server thread.
Represents a waypoint or mark within the navigation system.
static std::function< void(unsigned, const unsigned *)> delete_gl_textures
Horrible Hack (tm).
Represents a navigational route in the navigation system.
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
wxString m_RouteNameString
User-assigned name for the route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for displaying query results of S57 objects.
Manager for S57 chart SENC creation threads.
Window for displaying chart thumbnails.
Represents a track, which is a series of connected track points.
Listen to hardware events and notifies SystemEvents when new devices are plugged in.
OpenGL chart rendering canvas.
Handles crash reporting in wxWidgets applications.
Global variables reflecting command line options and arguments.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
Start/stop mdns service routines.
void check_last_start()
Check if the last start failed, possibly invoke user dialog and set safe mode state.
void clear_check()
Mark last run as successful.
Class NotificationManager.
PLugin remote repositories installation and Uninstall/list operations.
bool CheckDongleAccess(wxWindow *parent)
Runs checks and if required dialogs to make dongle accessible.
bool CheckSerialAccess(wxWindow *parent, const std::string device)
Run checks and possible dialogs to ensure device is accessible.
Access checks for comm devices and dongle.