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;
713DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
714 0x6b, 0xba, 0xe7, 0x22, 0xc0);
718#include <wx/msw/msvcrt.h>
722static const long long lNaN = 0xfff8000000000000;
723#define NAN (*(double *)&lNaN)
727void appendOSDirSlash(wxString *pString);
729void InitializeUserColors(
void);
730void DeInitializeUserColors(
void);
731void SetSystemColors(ColorScheme cs);
733static bool LoadAllPlugIns(
bool load_enabled) {
734 g_Platform->ShowBusySpinner();
735 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
736 g_Platform->HideBusySpinner();
744#if defined(__WXGTK__) || defined(__WXQT__)
745#include "bitmaps/opencpn.xpm"
748wxString newPrivateFileName(wxString,
const char *name,
749 [[maybe_unused]]
const char *windowsName) {
750 wxString fname = wxString::FromUTF8(name);
751 wxString filePathAndName;
754 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
755 filePathAndName.Append(wxFileName::GetPathSeparator());
758 wxString fwname = wxString::FromUTF8(windowsName);
759 filePathAndName.Append(fwname);
761 filePathAndName.Append(fname);
764 return filePathAndName;
773BEGIN_EVENT_TABLE(
MyApp, wxApp)
774EVT_ACTIVATE_APP(MyApp::OnActivateApp)
777static
void ActivateRoute(const std::
string &guid) {
778 Route *route = g_pRouteMan->FindRouteByGUID(guid);
780 wxLogMessage(
"Cannot activate guid: no such route");
783 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
789 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
791 point = route->GetPoint(2);
798static void ReverseRoute(
const std::string &guid) {
799 Route *route = g_pRouteMan->FindRouteByGUID(guid);
801 wxLogMessage(
"Cannot activate guid: no such route");
808void MyApp::InitRestListeners() {
809 auto activate_route = [&](wxCommandEvent ev) {
810 auto guid = ev.GetString().ToStdString();
814 auto reverse_route = [&](wxCommandEvent ev) {
815 auto guid = ev.GetString().ToStdString();
821bool MyApp::OpenFile(
const std::string &path) {
823 auto result = nav_objects.load_file(path.c_str());
825 std::string s(_(
"Cannot load route or waypoint file: "));
826 s += std::string(
"\"") + path +
"\"";
827 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
833 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
835 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
836 pRouteManagerDialog->UpdateLists();
837 LLBBox box = nav_objects.GetBBox();
838 if (box.GetValid()) {
839 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
845void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
848 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
849 parser.AddSwitch(
"p",
"portable");
850 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
851 wxCMD_LINE_PARAM_OPTIONAL);
852 parser.AddSwitch(
"f",
"fullscreen");
853 parser.AddSwitch(
"G",
"no_opengl");
854 parser.AddSwitch(
"W",
"config_wizard");
855 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
856 parser.AddSwitch(
"D",
"rebuild_chart_db");
857 parser.AddSwitch(
"P",
"parse_all_enc");
858 parser.AddOption(
"l",
"loglevel");
859 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
860 parser.AddSwitch(
"U",
"unit_test_2");
861 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
862 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
863 parser.AddSwitch(
"s",
"safe_mode");
864 parser.AddSwitch(
"r",
"remote");
865 parser.AddSwitch(
"R",
"raise");
866 parser.AddSwitch(
"q",
"quit");
867 parser.AddSwitch(
"e",
"get_rest_endpoint");
868 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
869 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
875static void ParseLoglevel(wxCmdLineParser &parser) {
876 wxLog::SetLogLevel(wxLOG_Message);
879static void ParseLoglevel(wxCmdLineParser &parser) {
880 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
881 strLevel = strLevel ? strLevel :
"info";
883 if (parser.Found(
"l", &wxLevel)) {
884 strLevel = wxLevel.c_str();
886 wxLogLevel level = OcpnLog::str2level(strLevel);
887 if (level == OcpnLog::LOG_BADLEVEL) {
888 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
891 wxLog::SetLogLevel(level);
896bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
903bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
908 g_unit_test_2 = parser.Found(
"unit_test_2");
909 g_bportable = parser.Found(
"p");
910 g_start_fullscreen = parser.Found(
"fullscreen");
911 g_bdisable_opengl = parser.Found(
"no_opengl");
912 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
913 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
914 g_parse_all_enc = parser.Found(
"parse_all_enc");
915 g_config_wizard = parser.Found(
"config_wizard");
916 if (parser.Found(
"unit_test_1", &number)) {
917 g_unit_test_1 =
static_cast<int>(number);
918 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
920 safe_mode::set_mode(parser.Found(
"safe_mode"));
921 ParseLoglevel(parser);
923 if (parser.Found(
"configdir", &wxstr)) {
924 g_configdir = wxstr.ToStdString();
925 fs::path path(g_configdir);
926 if (!fs::exists(path) || !fs::is_directory(path)) {
927 std::cerr << g_configdir <<
" is not an existing directory.\n";
932 bool has_start_options =
false;
933 static const std::vector<std::string> kStartOptions = {
938 "rebuild_gl_raster_cache",
944 for (
const auto &opt : kStartOptions) {
945 if (parser.Found(opt)) has_start_options =
true;
947 if (has_start_options && parser.Found(
"remote")) {
948 std::cerr <<
"this option is not compatible with --remote\n";
952 bool has_remote_options =
false;
953 static const std::vector<std::string> kRemoteOptions = {
954 "raise",
"quit",
"open",
"get_rest_endpoint"};
955 for (
const auto &opt : kRemoteOptions) {
956 if (parser.Found(opt)) has_remote_options =
true;
958 if (has_remote_options && !parser.Found(
"remote")) {
959 std::cerr <<
"This option requires --remote\n";
963 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
964 g_params.push_back(parser.GetParam(paramNr).ToStdString());
967 if (!parser.Found(
"remote"))
968 m_parsed_cmdline = ParsedCmdline();
969 else if (parser.Found(
"raise"))
970 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
971 else if (parser.Found(
"quit"))
972 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
973 else if (parser.Found(
"get_rest_endpoint"))
974 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
975 else if (parser.Found(
"open", &optarg))
976 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
977 else if (parser.GetParamCount() == 1)
979 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
980 else if (!has_start_options && !has_remote_options) {
982 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
992bool MyApp::OnExceptionInMainLoop() {
993 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
998void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
1000static wxStopWatch init_sw;
1003 if (m_exitcode != -2)
return m_exitcode;
1004 return wxAppConsole::OnRun();
1015 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1016 setenv(
"GDK_BACKEND",
"x11", 1);
1019 "mesa_glthread",
"false",
1025bool MyApp::OnInit() {
1026 if (!wxApp::OnInit())
return false;
1028 androidEnableBackButton(
false);
1029 androidEnableOptionItems(
false);
1034#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1040 wxBitmap bmp(10, 10, -1);
1042 dc.SelectObject(bmp);
1043 dc.DrawText(_T(
"X"), 0, 0);
1048 g_BasePlatform = g_Platform;
1055 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1059 std::cerr <<
"No remote opencpn found. Giving up.\n";
1064 std::unique_ptr<LocalClientApi> client;
1066 client = LocalClientApi::GetClient();
1068 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1075 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1076 "to respond.\nPlease retry."),
1077 "OpenCPN", wxICON_INFORMATION | wxOK);
1082 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1083 m_parsed_cmdline.arg);
1087 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1096 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1097 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1102 if (!safe_mode::get_mode()) {
1108 OCPNPlatform::Initialize_1();
1113 MyApp::SetAppDisplayName(
"OpenCPN");
1116 wxDateTime x = wxDateTime::UNow();
1117 long seed = x.GetMillisecond();
1118 seed *= x.GetTicks();
1123 setlocale(LC_NUMERIC,
"C");
1125 g_start_time = wxDateTime::Now();
1127 g_loglast_time = g_start_time;
1128 g_loglast_time.MakeGMT();
1129 g_loglast_time.Subtract(
1130 wxTimeSpan(0, 29, 0, 0));
1132 AnchorPointMinDist = 5.0;
1138 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1142 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1143 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1144 wxFONTENCODING_SYSTEM);
1145 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1148 auto ¬eman = NotificationManager::GetInstance();
1149 noteman.ScrubNotificationDirectory(30);
1152 if (!g_Platform->InitializeLogFile()) {
1164 wxLogMessage(_T(
"\n\n________\n"));
1166 wxDateTime now = wxDateTime::Now();
1167 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1168 now.FormatISODate().mb_str().data());
1169 wxLogLevel level = wxLog::GetLogLevel();
1170 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1172 wxString wxver(wxVERSION_STRING);
1173 wxver.Prepend(_T(
"wxWidgets version: "));
1175 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1179 os_name = platforminfo.GetOperatingSystemIdName();
1181 os_name = platforminfo.GetOperatingSystemFamilyName();
1184 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1185 platforminfo.GetPortIdName();
1187 wxLogMessage(wxver + _T(
" ") + platform);
1189 ::wxGetOsVersion(&osMajor, &osMinor);
1190 wxString osVersionMsg;
1191 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1192 wxLogMessage(osVersionMsg);
1194 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1195 g_mem_total / 1024, g_mem_initial / 1024);
1200 if (!detail->osd_names_like.empty())
1201 like0 = detail->osd_names_like[0].c_str();
1202 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1203 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1204 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1206 wxLogMessage(msgplat);
1208 wxString imsg = _T(
"SData_Locn is ");
1209 imsg += g_Platform->GetSharedDataDir();
1213 ::wxInitAllImageHandlers();
1217 prepareAndroidStyleSheets();
1221 pInit_Chart_Dir =
new wxString();
1224 g_pGroupArray =
new ChartGroupArray;
1226 imsg = _T(
"PrivateDataDir is ");
1232 pMessageOnceArray =
new wxArrayString;
1236 new Routeman(RoutePropDlg::GetDlgCtx(), RoutemanGui::GetDlgCtx());
1240 pSelect->SetSelectPixelRadius(12);
1243 pSelectTC =
new Select();
1245 pSelectTC->SetSelectPixelRadius(25);
1248 pSelectAIS =
new Select();
1249 pSelectAIS->SetSelectPixelRadius(12);
1253 g_pais_query_dialog_active = NULL;
1256 g_hostname = ::wxGetHostName();
1257 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1259 androidGetDeviceInfo();
1260 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1261 g_hostname.Replace(
" ",
"-",
true);
1266 wxString p(
"Portable-");
1267 g_hostname = p + g_hostname;
1272 pLayerList =
new LayerList;
1274 pRouteList =
new RouteList;
1277 auto &navobj_db = NavObj_dB::GetInstance();
1284#ifdef PROBE_PORTS__WITH_HELPER
1285 user_user_id = getuid();
1286 file_user_id = geteuid();
1290 bool b_initial_load =
false;
1292 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1293 if (config_test_file_name.FileExists())
1294 wxLogMessage(_T(
"Using existing Config_File: ") +
1295 g_Platform->GetConfigFileName());
1298 wxLogMessage(_T(
"Creating new Config_File: ") +
1299 g_Platform->GetConfigFileName());
1301 b_initial_load =
true;
1304 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1305 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1306 wxLogMessage(_T(
"Cannot create config file directory for ") +
1307 g_Platform->GetConfigFileName());
1312 pConfig = g_Platform->GetConfigObject();
1313 InitBaseConfig(pConfig);
1314 pConfig->LoadMyConfig();
1318 if (b_initial_load) g_Platform->SetDefaultOptions();
1320 g_Platform->applyExpertMode(g_bUIexpert);
1328 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1329 if (!g_StyleManager->IsOK()) {
1330 wxString msg = _(
"Failed to initialize the user interface. ");
1331 msg << _(
"OpenCPN cannot start. ");
1332 msg << _(
"The necessary configuration files were not found. ");
1333 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1334 << _(
" for details.") << _T(
"\n\n");
1335 msg << g_Platform->GetSharedDataDir();
1337 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1338 wxCANCEL | wxICON_ERROR);
1345 if (style) style->chartStatusWindowTransparent =
true;
1349 pWayPointMan = NULL;
1353 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1354 (
int)g_display_size_mm);
1358 if (g_config_display_size_manual &&
1359 g_config_display_size_mm.size() > g_current_monitor &&
1360 g_config_display_size_mm[g_current_monitor] > 0) {
1361 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1363 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1364 (
int)g_display_size_mm);
1369 g_display_size_mm = wxMax(50, g_display_size_mm);
1372 int SelectPixelRadius = 50;
1374 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1375 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1376 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1380 if (!n_NavMessageShown) {
1387#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1390 g_Platform->SetLocaleSearchPrefixes();
1392 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1394 imsg = _T(
"System default Language: ") + def_lang_canonical;
1397 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1398 wxLogMessage(cflmsg);
1400 if (g_locale.IsEmpty()) {
1401 g_locale = def_lang_canonical;
1403 _T(
"Config file language empty, using system default: ") + g_locale;
1404 wxLogMessage(cflmsg);
1408 g_locale = g_Platform->GetAdjustedAppLocale();
1409 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1410 wxLogMessage(cflmsg);
1413 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1415 imsg = _T(
"Opencpn language set to: ");
1422 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1424 wxLogMessage(_T(
"wxLocale support not available"));
1429 if (g_config_wizard || b_initial_load) {
1431 auto res = wiz.Run();
1442 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1443 g_bUpgradeInProcess = (vs != g_config_version_string);
1445 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1448 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1449 wxLogMessage(g_Platform->GetLargeLogMessage());
1454 g_bdisable_opengl =
true;
1458 if (g_bdisable_opengl) g_bopengl =
false;
1460#if defined(__linux__) && !defined(__ANDROID__)
1461 if (g_bSoftwareGL) {
1462 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1475 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1477 wxMin(g_memCacheLimit, 1024 * 1024);
1483 g_memCacheLimit = 0;
1484 if (0 == g_nCacheLimit)
1485 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1490 "chartlist.dat",
"CHRTLIST.DAT");
1494 "mmsitoname.csv",
"MMSINAME.CSV");
1497 if (pInit_Chart_Dir->IsEmpty()) {
1498 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1502 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1504 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1508 InitRestListeners();
1511 gDefaultWorldMapLocation =
"gshhs";
1512 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1513 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1514 if (gWorldMapLocation == wxEmptyString) {
1515 gWorldMapLocation = gDefaultWorldMapLocation;
1520 wxString default_tcdata0 =
1521 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1522 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1523 wxString default_tcdata1 =
1524 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1525 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1527 if (TideCurrentDataSet.empty()) {
1528 TideCurrentDataSet.push_back(
1529 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1530 TideCurrentDataSet.push_back(
1531 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1536 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1537 wxString default_sound =
1538 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1539 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1540 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1545 g_Platform->Initialize_2();
1549 wxSize new_frame_size(-1, -1);
1551 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1553 InitializeUserColors();
1555 auto style = g_StyleManager->GetCurrentStyle();
1556 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1558 PluginLoader::GetInstance()->SetPluginDefaultIcon(bitmap);
1560 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1562 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1563 (g_nframewin_y <= ch))
1564 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1566 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1572 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1573 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1574 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1575 g_bframemax =
false;
1578 g_lastClientRectx = cx;
1579 g_lastClientRecty = cy;
1580 g_lastClientRectw = cw;
1581 g_lastClientRecth = ch;
1584 wxPoint position(0, 0);
1585 wxSize dsize = wxGetDisplaySize();
1588 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1591 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1592 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1597 frame_rect.left = position.x;
1598 frame_rect.top = position.y;
1599 frame_rect.right = position.x + new_frame_size.x;
1600 frame_rect.bottom = position.y + new_frame_size.y;
1604 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1605 position = wxPoint(10, 10);
1610 const wxPoint ptScreen(position.x, position.y);
1611 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1613 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1616 g_nframewin_posx = position.x;
1617 g_nframewin_posy = position.y;
1620 wxSize asz = getAndroidDisplayDimensions();
1625 if ((cw > 200) && (ch > 200))
1626 new_frame_size.Set(cw, ch);
1628 new_frame_size.Set(800, 400);
1632 long app_style = wxDEFAULT_FRAME_STYLE;
1633 app_style |= wxWANTS_CHARS;
1638 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1639 wxString myframe_window_title =
1640 wxString(wxT(
"OpenCPN ") + short_version_name);
1643 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1644 myframe_window_title += g_Platform->GetHomeDir();
1645 myframe_window_title += _T(
"]");
1649 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1650 new_frame_size.x, new_frame_size.y, position.x, position.y);
1653 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1655 wxTheApp->SetTopWindow(gFrame);
1658 g_Platform->Initialize_3();
1665 g_pauidockart =
new wxAuiDefaultDockArt;
1666 g_pauimgr->SetArtProvider(g_pauidockart);
1667 g_pauimgr->SetDockSizeConstraint(.9, .9);
1672 g_pauimgr->SetManagedWindow(gFrame);
1674 gFrame->CreateCanvasLayout();
1678 gFrame->SetChartUpdatePeriod();
1682 gFrame->GetPrimaryCanvas()->SetFocus();
1684 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1686 gFrame->ApplyGlobalSettings(
false);
1688 gFrame->SetAllToolbarScale();
1694 gFrame->SetAndApplyColorScheme(global_color_scheme);
1696 if (g_bframemax) gFrame->Maximize(
true);
1699 if (
g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1700 gFrame->Maximize(
true);
1707 ArrayOfCDI ChartDirArray;
1708 pConfig->LoadChartDirArray(ChartDirArray);
1713 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1716 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1717 if (RegKey.Exists()) {
1719 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1721 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1723 wxStringTokenizer tkz(dirs, _T(
";"));
1724 while (tkz.HasMoreTokens()) {
1725 wxString token = tkz.GetNextToken();
1728 cdi.fullpath = token.Trim();
1729 cdi.magic_number = _T(
"");
1731 ChartDirArray.Add(cdi);
1738 cdi.fullpath = _T(
"charts");
1739 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1740 cdi.magic_number = _T(
"");
1741 ChartDirArray.Add(cdi);
1745 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1755 if (!ChartDirArray.GetCount())
1756 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1760 if (g_NeedDBUpdate == 0 &&
1761 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1766 if (g_restore_dbindex >= 0) {
1767 if (ChartData->GetChartTableEntries() == 0)
1768 g_restore_dbindex = -1;
1770 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1771 g_restore_dbindex = 0;
1775 ChartData->ApplyGroupArray(g_pGroupArray);
1783 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1784 g_GLOptions.m_bTextureCompressionCaching) {
1785 gFrame->ReloadAllVP();
1794 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1804 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1805 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1808 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1809 gps_watchdog_timeout_ticks);
1810 wxLogMessage(dogmsg);
1812 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1820 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1822 pAnchorWatchPoint1 = NULL;
1823 pAnchorWatchPoint2 = NULL;
1827 gFrame->DoChartUpdate();
1832 gFrame->ReloadAllVP();
1834 gFrame->Refresh(
false);
1837 gFrame->GetPrimaryCanvas()->Enable();
1838 gFrame->GetPrimaryCanvas()->SetFocus();
1845 if (!g_bdisable_opengl) {
1849 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1850 gFrame->m_defer_size = gFrame->GetSize();
1851 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1852 g_pauimgr->Update();
1853 gFrame->m_bdefer_resize =
true;
1863 glDeleteTextures(n, texts);
1869 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1874 gFrame->SetSize(getAndroidDisplayDimensions());
1875 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1879 gFrame->GetPrimaryCanvas()->Enable();
1880 gFrame->GetPrimaryCanvas()->SetFocus();
1888 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1891 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1894 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1899 OCPNPlatform::Initialize_4();
1902 androidHideBusyIcon();
1905 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1913 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1914 (g_AndroidVersionCode != androidGetVersionCode())) {
1918 if (!ShowNavWarning()) {
1919 qDebug() <<
"Closing due to NavWarning Cancel";
1925 n_NavMessageShown = 1;
1929 g_AndroidVersionCode = androidGetVersionCode();
1930 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1935 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1936 if (!ShowNavWarning())
return false;
1937 n_NavMessageShown = 1;
1944 g_bHasHwClock =
true;
1945#if defined(__UNIX__) && !defined(__ANDROID__)
1948 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1949 (stat(
"/dev/misc/rtc", &buffer) == 0));
1952 g_config_version_string = vs;
1955 pConfig->UpdateSettings();
1958 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1960 g_pauimgr->Update();
1962 for (
auto *cp : TheConnectionParams()) {
1964 if (cp->GetDSPort().Contains(
"Serial")) {
1965 std::string port(cp->Port.ToStdString());
1973 m_comm_bridge.Initialize();
1975 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1978 if (ipv4_addrs.size()) {
1979 std::string ipAddr = ipv4_addrs[0];
1982 if (data_dir.Last() != wxFileName::GetPathSeparator())
1983 data_dir.Append(wxFileName::GetPathSeparator());
1985 make_certificate(ipAddr, data_dir.ToStdString());
1987 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1988 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
1994int MyApp::OnExit() {
1995 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
1997 m_usb_watcher.Stop();
2000 wxDateTime lognow = wxDateTime::Now();
2002 wxString day = lognow.FormatISODate();
2003 wxString utc = lognow.FormatISOTime();
2004 wxString navmsg = _T(
"LOGBOOK: ");
2008 navmsg += _T(
" UTC ");
2012 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2016 if (std::isnan(gCog))
2017 cog.Printf(_T(
"COG ----- "));
2019 cog.Printf(_T(
"COG %10.5f "), gCog);
2022 if (std::isnan(gSog))
2023 sog.Printf(_T(
"SOG ----- "));
2025 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2032 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2035 wxLogMessage(navmsg);
2036 g_loglast_time = lognow;
2038 if (ptcmgr)
delete ptcmgr;
2040 for (
Track *track : g_TrackList) {
2043 g_TrackList.clear();
2051 delete g_SencThreadManager;
2053 if (g_pGroupArray) {
2054 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2056 delete g_pGroupArray->Item(igroup);
2059 g_pGroupArray->Clear();
2060 delete g_pGroupArray;
2063 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2064 wxLog::FlushActive();
2066 g_Platform->CloseLogFile();
2068 delete pInit_Chart_Dir;
2070 for (
Track *track : g_TrackList) {
2073 g_TrackList.clear();
2076 delete pWayPointMan;
2078 delete pMessageOnceArray;
2080 DeInitializeUserColors();
2084 delete m_pRegistrarMan;
2087 delete g_StyleManager;
2092 if (s_glu_dll_ready) {
2093 FreeLibrary(s_hGLU_DLL);
2102 void RestoreSystemColors(
void);
2103 RestoreSystemColors();
2110#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2111 if (plocale_def_lang)
delete plocale_def_lang;
2114 FontMgr::Shutdown();
2116 g_Platform->OnExit_2();
2123#ifdef LINUX_CRASHRPT
2124void MyApp::OnFatalException() { g_crashprint.Report(); }
2130void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2135 if (eErrClass == CE_Debug)
2136 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2137 else if (eErrClass == CE_Warning)
2138 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2140 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2142 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.
Primary navigation console display for route and vessel tracking.
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.