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>
102#include "model/certificates.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"
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"
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;
517std::vector<std::string> ChartDirectoryExcludedVector;
521std::vector<std::string> TideCurrentDataSet;
522wxString g_TCData_Dir;
525bool g_bDeferredInitDone;
526int options_lastPage = 0;
527int options_subpage = 0;
529wxPoint options_lastWindowPos(0, 0);
530wxSize options_lastWindowSize(0, 0);
533bool g_bsimplifiedScalebar;
537bool GetMemoryStatus(
int *mem_total,
int *mem_used);
540int g_nAIS_activity_timer;
542bool g_bEnableZoomToCursor;
545bool g_bDeferredStartTrack;
546bool g_bHighliteTracks;
547wxColour g_colourTrackLineColour;
548wxString g_default_wp_icon;
551double g_TrackIntervalSeconds;
553int g_cm93_zoom_factor;
555bool g_bShowDetailSlider;
556int g_detailslider_dialog_x, g_detailslider_dialog_y;
563bool g_b_overzoom_x =
true;
565int g_OwnShipIconType;
566double g_n_ownship_length_meters;
567double g_n_ownship_beam_meters;
568double g_n_gps_antenna_offset_y;
569double g_n_gps_antenna_offset_x;
570int g_n_ownship_min_mm;
575bool g_bPreserveScaleOnX;
576bool g_CanvasHideNotificationIcon;
578bool g_bhide_depth_units;
579bool g_bhide_overzoom_flag;
582About *g_pAboutDlgLegacy;
584#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
585wxLocale *plocale_def_lang = 0;
597wxString g_localeOverride;
598bool g_b_assume_azerty;
604bool g_bShowStatusBar;
610int g_AisTargetList_count;
611bool g_bAisTargetList_autosort;
616wxAuiDefaultDockArt *g_pauidockart;
618wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
623long g_maintoolbar_orient;
624float g_toolbar_scalefactor;
626float g_compass_scalefactor;
628bool g_bShowCompassWin;
630bool g_benable_rotate;
638double gQueryVar = 361.0;
640char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
642int portaudio_initialized;
644char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
647int g_sticky_projection;
649int n_NavMessageShown;
650wxString g_config_version_string;
652wxString g_CmdSoundString;
670bool b_inCompressAllCharts;
674int g_chart_zoom_modifier_raster;
675int g_chart_zoom_modifier_vector;
677bool g_bAdvanceRouteWaypointOnArrivalOnly;
679bool g_bSpaceDropMark;
681wxArrayString g_locale_catalog_array;
682bool b_reloadForPlugins;
683bool g_btrackContinuous;
685unsigned int g_canvasConfig;
687bool g_bmasterToolbarFull =
true;
689int g_AndroidVersionCode;
694WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
696arrayofCanvasPtr g_canvasArray;
697wxString g_lastAppliedTemplateGUID;
703bool g_disable_main_toolbar;
705bool g_declutter_anchorage;
706bool g_bhide_route_console;
707bool g_bhide_context_menus;
719DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
720 0x6b, 0xba, 0xe7, 0x22, 0xc0);
724#include <wx/msw/msvcrt.h>
728static const long long lNaN = 0xfff8000000000000;
729#define NAN (*(double *)&lNaN)
733void appendOSDirSlash(wxString *pString);
735void InitializeUserColors(
void);
736void DeInitializeUserColors(
void);
737void SetSystemColors(ColorScheme cs);
739static bool LoadAllPlugIns(
bool load_enabled) {
740 g_Platform->ShowBusySpinner();
741 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
742 g_Platform->HideBusySpinner();
750#if defined(__WXGTK__) || defined(__WXQT__)
751#include "bitmaps/opencpn.xpm"
754wxString newPrivateFileName(wxString,
const char *name,
755 [[maybe_unused]]
const char *windowsName) {
756 wxString fname = wxString::FromUTF8(name);
757 wxString filePathAndName;
760 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
761 filePathAndName.Append(wxFileName::GetPathSeparator());
764 wxString fwname = wxString::FromUTF8(windowsName);
765 filePathAndName.Append(fwname);
767 filePathAndName.Append(fname);
770 return filePathAndName;
779BEGIN_EVENT_TABLE(
MyApp, wxApp)
780EVT_ACTIVATE_APP(MyApp::OnActivateApp)
783static
void ActivateRoute(const std::
string &guid) {
784 Route *route = g_pRouteMan->FindRouteByGUID(guid);
786 wxLogMessage(
"Cannot activate guid: no such route");
789 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
795 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
797 point = route->GetPoint(2);
804static void ReverseRoute(
const std::string &guid) {
805 Route *route = g_pRouteMan->FindRouteByGUID(guid);
807 wxLogMessage(
"Cannot activate guid: no such route");
814void MyApp::InitRestListeners() {
815 auto activate_route = [&](wxCommandEvent ev) {
816 auto guid = ev.GetString().ToStdString();
820 auto reverse_route = [&](wxCommandEvent ev) {
821 auto guid = ev.GetString().ToStdString();
827bool MyApp::OpenFile(
const std::string &path) {
829 auto result = nav_objects.load_file(path.c_str());
831 std::string s(_(
"Cannot load route or waypoint file: "));
832 s += std::string(
"\"") + path +
"\"";
833 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
839 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
841 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
842 pRouteManagerDialog->UpdateLists();
843 LLBBox box = nav_objects.GetBBox();
844 if (box.GetValid()) {
845 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
851void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
854 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
855 parser.AddSwitch(
"p",
"portable");
856 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
857 wxCMD_LINE_PARAM_OPTIONAL);
858 parser.AddSwitch(
"f",
"fullscreen");
859 parser.AddSwitch(
"G",
"no_opengl");
860 parser.AddSwitch(
"W",
"config_wizard");
861 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
862 parser.AddSwitch(
"D",
"rebuild_chart_db");
863 parser.AddSwitch(
"P",
"parse_all_enc");
864 parser.AddOption(
"l",
"loglevel");
865 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
866 parser.AddSwitch(
"U",
"unit_test_2");
867 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
868 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
869 parser.AddSwitch(
"s",
"safe_mode");
870 parser.AddSwitch(
"r",
"remote");
871 parser.AddSwitch(
"R",
"raise");
872 parser.AddSwitch(
"q",
"quit");
873 parser.AddSwitch(
"e",
"get_rest_endpoint");
874 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
875 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
881static void ParseLoglevel(wxCmdLineParser &parser) {
882 wxLog::SetLogLevel(wxLOG_Message);
885static void ParseLoglevel(wxCmdLineParser &parser) {
886 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
887 strLevel = strLevel ? strLevel :
"info";
889 if (parser.Found(
"l", &wxLevel)) {
890 strLevel = wxLevel.c_str();
892 wxLogLevel level = OcpnLog::str2level(strLevel);
893 if (level == OcpnLog::LOG_BADLEVEL) {
894 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
897 wxLog::SetLogLevel(level);
902bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
909bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
914 g_unit_test_2 = parser.Found(
"unit_test_2");
915 g_bportable = parser.Found(
"p");
916 g_start_fullscreen = parser.Found(
"fullscreen");
917 g_bdisable_opengl = parser.Found(
"no_opengl");
918 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
919 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
920 g_parse_all_enc = parser.Found(
"parse_all_enc");
921 g_config_wizard = parser.Found(
"config_wizard");
922 if (parser.Found(
"unit_test_1", &number)) {
923 g_unit_test_1 =
static_cast<int>(number);
924 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
926 safe_mode::set_mode(parser.Found(
"safe_mode"));
927 ParseLoglevel(parser);
929 if (parser.Found(
"configdir", &wxstr)) {
930 g_configdir = wxstr.ToStdString();
931 fs::path path(g_configdir);
932 if (!fs::exists(path) || !fs::is_directory(path)) {
933 std::cerr << g_configdir <<
" is not an existing directory.\n";
938 bool has_start_options =
false;
939 static const std::vector<std::string> kStartOptions = {
944 "rebuild_gl_raster_cache",
950 for (
const auto &opt : kStartOptions) {
951 if (parser.Found(opt)) has_start_options =
true;
953 if (has_start_options && parser.Found(
"remote")) {
954 std::cerr <<
"this option is not compatible with --remote\n";
958 bool has_remote_options =
false;
959 static const std::vector<std::string> kRemoteOptions = {
960 "raise",
"quit",
"open",
"get_rest_endpoint"};
961 for (
const auto &opt : kRemoteOptions) {
962 if (parser.Found(opt)) has_remote_options =
true;
964 if (has_remote_options && !parser.Found(
"remote")) {
965 std::cerr <<
"This option requires --remote\n";
969 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
970 g_params.push_back(parser.GetParam(paramNr).ToStdString());
973 if (!parser.Found(
"remote"))
974 m_parsed_cmdline = ParsedCmdline();
975 else if (parser.Found(
"raise"))
976 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
977 else if (parser.Found(
"quit"))
978 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
979 else if (parser.Found(
"get_rest_endpoint"))
980 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
981 else if (parser.Found(
"open", &optarg))
982 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
983 else if (parser.GetParamCount() == 1)
985 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
986 else if (!has_start_options && !has_remote_options) {
988 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
998bool MyApp::OnExceptionInMainLoop() {
999 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
1004void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
1006static wxStopWatch init_sw;
1009 if (m_exitcode != -2)
return m_exitcode;
1010 return wxAppConsole::OnRun();
1021 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1022 setenv(
"GDK_BACKEND",
"x11", 1);
1025 "mesa_glthread",
"false",
1031bool MyApp::OnInit() {
1032 if (!wxApp::OnInit())
return false;
1034 androidEnableBackButton(
false);
1035 androidEnableOptionItems(
false);
1040#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1046 wxBitmap bmp(10, 10, -1);
1048 dc.SelectObject(bmp);
1049 dc.DrawText(_T(
"X"), 0, 0);
1054 g_BasePlatform = g_Platform;
1061 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1065 std::cerr <<
"No remote opencpn found. Giving up.\n";
1070 std::unique_ptr<LocalClientApi> client;
1072 client = LocalClientApi::GetClient();
1074 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1081 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1082 "to respond.\nPlease retry."),
1083 "OpenCPN", wxICON_INFORMATION | wxOK);
1088 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1089 m_parsed_cmdline.arg);
1093 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1102 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1103 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1108 if (!safe_mode::get_mode()) {
1114 OCPNPlatform::Initialize_1();
1119 MyApp::SetAppDisplayName(
"OpenCPN");
1122 wxDateTime x = wxDateTime::UNow();
1123 long seed = x.GetMillisecond();
1124 seed *= x.GetTicks();
1129 setlocale(LC_NUMERIC,
"C");
1131 g_start_time = wxDateTime::Now();
1133 g_loglast_time = g_start_time;
1134 g_loglast_time.MakeGMT();
1135 g_loglast_time.Subtract(
1136 wxTimeSpan(0, 29, 0, 0));
1138 AnchorPointMinDist = 5.0;
1144 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1148 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1149 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1150 wxFONTENCODING_SYSTEM);
1151 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1154 auto ¬eman = NotificationManager::GetInstance();
1155 noteman.ScrubNotificationDirectory(30);
1158 if (!g_Platform->InitializeLogFile()) {
1170 wxLogMessage(_T(
"\n\n________\n"));
1172 wxDateTime now = wxDateTime::Now();
1173 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1174 now.FormatISODate().mb_str().data());
1175 wxLogLevel level = wxLog::GetLogLevel();
1176 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1178 wxString wxver(wxVERSION_STRING);
1179 wxver.Prepend(_T(
"wxWidgets version: "));
1181 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1185 os_name = platforminfo.GetOperatingSystemIdName();
1187 os_name = platforminfo.GetOperatingSystemFamilyName();
1190 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1191 platforminfo.GetPortIdName();
1193 wxLogMessage(wxver + _T(
" ") + platform);
1195 ::wxGetOsVersion(&osMajor, &osMinor);
1196 wxString osVersionMsg;
1197 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1198 wxLogMessage(osVersionMsg);
1200 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1201 g_mem_total / 1024, g_mem_initial / 1024);
1206 if (!detail->osd_names_like.empty())
1207 like0 = detail->osd_names_like[0].c_str();
1208 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1209 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1210 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1212 wxLogMessage(msgplat);
1214 wxString imsg = _T(
"SData_Locn is ");
1215 imsg += g_Platform->GetSharedDataDir();
1219 ::wxInitAllImageHandlers();
1223 prepareAndroidStyleSheets();
1227 pInit_Chart_Dir =
new wxString();
1230 g_pGroupArray =
new ChartGroupArray;
1232 imsg = _T(
"PrivateDataDir is ");
1238 pMessageOnceArray =
new wxArrayString;
1242 new Routeman(RoutePropDlg::GetDlgCtx(), RoutemanGui::GetDlgCtx());
1246 pSelect->SetSelectPixelRadius(12);
1249 pSelectTC =
new Select();
1251 pSelectTC->SetSelectPixelRadius(25);
1254 pSelectAIS =
new Select();
1255 pSelectAIS->SetSelectPixelRadius(12);
1259 g_pais_query_dialog_active = NULL;
1262 g_hostname = ::wxGetHostName();
1263 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1265 androidGetDeviceInfo();
1266 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1267 g_hostname.Replace(
" ",
"-",
true);
1272 wxString p(
"Portable-");
1273 g_hostname = p + g_hostname;
1278 pLayerList =
new LayerList;
1280 pRouteList =
new RouteList;
1283 auto &navobj_db = NavObj_dB::GetInstance();
1290#ifdef PROBE_PORTS__WITH_HELPER
1291 user_user_id = getuid();
1292 file_user_id = geteuid();
1296 bool b_initial_load =
false;
1298 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1299 if (config_test_file_name.FileExists())
1300 wxLogMessage(_T(
"Using existing Config_File: ") +
1301 g_Platform->GetConfigFileName());
1304 wxLogMessage(_T(
"Creating new Config_File: ") +
1305 g_Platform->GetConfigFileName());
1307 b_initial_load =
true;
1310 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1311 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1312 wxLogMessage(_T(
"Cannot create config file directory for ") +
1313 g_Platform->GetConfigFileName());
1318 pConfig = g_Platform->GetConfigObject();
1319 InitBaseConfig(pConfig);
1320 pConfig->LoadMyConfig();
1324 if (b_initial_load) g_Platform->SetDefaultOptions();
1326 g_Platform->applyExpertMode(g_bUIexpert);
1334 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1335 if (!g_StyleManager->IsOK()) {
1336 wxString msg = _(
"Failed to initialize the user interface. ");
1337 msg << _(
"OpenCPN cannot start. ");
1338 msg << _(
"The necessary configuration files were not found. ");
1339 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1340 << _(
" for details.") << _T(
"\n\n");
1341 msg << g_Platform->GetSharedDataDir();
1343 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1344 wxCANCEL | wxICON_ERROR);
1351 if (style) style->chartStatusWindowTransparent =
true;
1355 pWayPointMan = NULL;
1359 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1360 (
int)g_display_size_mm);
1364 if (g_config_display_size_manual &&
1365 g_config_display_size_mm.size() > g_current_monitor &&
1366 g_config_display_size_mm[g_current_monitor] > 0) {
1367 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1369 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1370 (
int)g_display_size_mm);
1375 g_display_size_mm = wxMax(50, g_display_size_mm);
1378 int SelectPixelRadius = 50;
1380 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1381 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1382 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1386 if (!n_NavMessageShown) {
1393#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1396 g_Platform->SetLocaleSearchPrefixes();
1398 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1400 imsg = _T(
"System default Language: ") + def_lang_canonical;
1403 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1404 wxLogMessage(cflmsg);
1406 if (g_locale.IsEmpty()) {
1407 g_locale = def_lang_canonical;
1409 _T(
"Config file language empty, using system default: ") + g_locale;
1410 wxLogMessage(cflmsg);
1414 g_locale = g_Platform->GetAdjustedAppLocale();
1415 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1416 wxLogMessage(cflmsg);
1419 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1421 imsg = _T(
"Opencpn language set to: ");
1428 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1430 wxLogMessage(_T(
"wxLocale support not available"));
1435 if (g_config_wizard || b_initial_load) {
1437 auto res = wiz.Run();
1448 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1449 g_bUpgradeInProcess = (vs != g_config_version_string);
1451 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1454 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1455 wxLogMessage(g_Platform->GetLargeLogMessage());
1460 g_bdisable_opengl =
true;
1464 if (g_bdisable_opengl) g_bopengl =
false;
1466#if defined(__linux__) && !defined(__ANDROID__)
1467 if (g_bSoftwareGL) {
1468 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1481 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1483 wxMin(g_memCacheLimit, 1024 * 1024);
1489 g_memCacheLimit = 0;
1490 if (0 == g_nCacheLimit)
1491 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1496 "chartlist.dat",
"CHRTLIST.DAT");
1500 "mmsitoname.csv",
"MMSINAME.CSV");
1503 if (pInit_Chart_Dir->IsEmpty()) {
1504 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1508 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1510 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1514 InitRestListeners();
1517 gDefaultWorldMapLocation =
"gshhs";
1518 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1519 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1520 if (gWorldMapLocation == wxEmptyString) {
1521 gWorldMapLocation = gDefaultWorldMapLocation;
1526 wxString default_tcdata0 =
1527 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1528 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1529 wxString default_tcdata1 =
1530 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1531 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1533 if (TideCurrentDataSet.empty()) {
1534 TideCurrentDataSet.push_back(
1535 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1536 TideCurrentDataSet.push_back(
1537 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1542 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1543 wxString default_sound =
1544 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1545 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1546 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1551 g_Platform->Initialize_2();
1555 wxSize new_frame_size(-1, -1);
1557 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1559 InitializeUserColors();
1561 auto style = g_StyleManager->GetCurrentStyle();
1562 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1564 PluginLoader::GetInstance()->SetPluginDefaultIcon(bitmap);
1566 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1568 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1569 (g_nframewin_y <= ch))
1570 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1572 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1578 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1579 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1580 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1581 g_bframemax =
false;
1584 g_lastClientRectx = cx;
1585 g_lastClientRecty = cy;
1586 g_lastClientRectw = cw;
1587 g_lastClientRecth = ch;
1590 wxPoint position(0, 0);
1591 wxSize dsize = wxGetDisplaySize();
1594 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1597 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1598 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1603 frame_rect.left = position.x;
1604 frame_rect.top = position.y;
1605 frame_rect.right = position.x + new_frame_size.x;
1606 frame_rect.bottom = position.y + new_frame_size.y;
1610 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1611 position = wxPoint(10, 10);
1616 const wxPoint ptScreen(position.x, position.y);
1617 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1619 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1622 g_nframewin_posx = position.x;
1623 g_nframewin_posy = position.y;
1626 wxSize asz = getAndroidDisplayDimensions();
1631 if ((cw > 200) && (ch > 200))
1632 new_frame_size.Set(cw, ch);
1634 new_frame_size.Set(800, 400);
1638 long app_style = wxDEFAULT_FRAME_STYLE;
1639 app_style |= wxWANTS_CHARS;
1644 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1645 wxString myframe_window_title =
1646 wxString(wxT(
"OpenCPN ") + short_version_name);
1649 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1650 myframe_window_title += g_Platform->GetHomeDir();
1651 myframe_window_title += _T(
"]");
1655 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1656 new_frame_size.x, new_frame_size.y, position.x, position.y);
1659 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1661 wxTheApp->SetTopWindow(gFrame);
1664 g_Platform->Initialize_3();
1671 g_pauidockart =
new wxAuiDefaultDockArt;
1672 g_pauimgr->SetArtProvider(g_pauidockart);
1673 g_pauimgr->SetDockSizeConstraint(.9, .9);
1678 g_pauimgr->SetManagedWindow(gFrame);
1680 gFrame->CreateCanvasLayout();
1684 gFrame->SetChartUpdatePeriod();
1688 gFrame->GetPrimaryCanvas()->SetFocus();
1690 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1692 gFrame->ApplyGlobalSettings(
false);
1694 gFrame->SetAllToolbarScale();
1700 gFrame->SetAndApplyColorScheme(global_color_scheme);
1702 if (g_bframemax) gFrame->Maximize(
true);
1705 if (
g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1706 gFrame->Maximize(
true);
1713 ArrayOfCDI ChartDirArray;
1714 pConfig->LoadChartDirArray(ChartDirArray);
1719 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1722 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1723 if (RegKey.Exists()) {
1725 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1727 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1729 wxStringTokenizer tkz(dirs, _T(
";"));
1730 while (tkz.HasMoreTokens()) {
1731 wxString token = tkz.GetNextToken();
1734 cdi.fullpath = token.Trim();
1735 cdi.magic_number = _T(
"");
1737 ChartDirArray.Add(cdi);
1744 cdi.fullpath = _T(
"charts");
1745 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1746 cdi.magic_number = _T(
"");
1747 ChartDirArray.Add(cdi);
1751 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1761 if (!ChartDirArray.GetCount())
1762 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1766 if (g_NeedDBUpdate == 0 &&
1767 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1772 if (g_restore_dbindex >= 0) {
1773 if (ChartData->GetChartTableEntries() == 0)
1774 g_restore_dbindex = -1;
1776 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1777 g_restore_dbindex = 0;
1781 ChartData->ApplyGroupArray(g_pGroupArray);
1789 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1790 g_GLOptions.m_bTextureCompressionCaching) {
1791 gFrame->ReloadAllVP();
1800 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1810 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1811 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1814 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1815 gps_watchdog_timeout_ticks);
1816 wxLogMessage(dogmsg);
1818 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1826 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1828 pAnchorWatchPoint1 = NULL;
1829 pAnchorWatchPoint2 = NULL;
1833 gFrame->DoChartUpdate();
1838 gFrame->ReloadAllVP();
1840 gFrame->Refresh(
false);
1843 gFrame->GetPrimaryCanvas()->Enable();
1844 gFrame->GetPrimaryCanvas()->SetFocus();
1851 if (!g_bdisable_opengl) {
1855 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1856 gFrame->m_defer_size = gFrame->GetSize();
1857 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1858 g_pauimgr->Update();
1859 gFrame->m_bdefer_resize =
true;
1869 glDeleteTextures(n, texts);
1875 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1880 gFrame->SetSize(getAndroidDisplayDimensions());
1881 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1885 gFrame->GetPrimaryCanvas()->Enable();
1886 gFrame->GetPrimaryCanvas()->SetFocus();
1894 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1897 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1900 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1905 OCPNPlatform::Initialize_4();
1908 androidHideBusyIcon();
1911 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1919 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1920 (g_AndroidVersionCode != androidGetVersionCode())) {
1924 if (!ShowNavWarning()) {
1925 qDebug() <<
"Closing due to NavWarning Cancel";
1931 n_NavMessageShown = 1;
1935 g_AndroidVersionCode = androidGetVersionCode();
1936 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1941 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1942 if (!ShowNavWarning())
return false;
1943 n_NavMessageShown = 1;
1950 g_bHasHwClock =
true;
1951#if defined(__UNIX__) && !defined(__ANDROID__)
1954 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1955 (stat(
"/dev/misc/rtc", &buffer) == 0));
1958 g_config_version_string = vs;
1961 pConfig->UpdateSettings();
1964 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1966 g_pauimgr->Update();
1968 for (
auto *cp : TheConnectionParams()) {
1970 if (cp->GetDSPort().Contains(
"Serial")) {
1971 std::string port(cp->Port.ToStdString());
1979 m_comm_bridge.Initialize();
1981 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1984 if (ipv4_addrs.size()) {
1985 std::string ipAddr = ipv4_addrs[0];
1988 if (data_dir.Last() != wxFileName::GetPathSeparator())
1989 data_dir.Append(wxFileName::GetPathSeparator());
1991 make_certificate(ipAddr, data_dir.ToStdString());
1993 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1994 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
2000int MyApp::OnExit() {
2001 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
2003 m_usb_watcher.Stop();
2006 wxDateTime lognow = wxDateTime::Now();
2008 wxString day = lognow.FormatISODate();
2009 wxString utc = lognow.FormatISOTime();
2010 wxString navmsg = _T(
"LOGBOOK: ");
2014 navmsg += _T(
" UTC ");
2018 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2022 if (std::isnan(gCog))
2023 cog.Printf(_T(
"COG ----- "));
2025 cog.Printf(_T(
"COG %10.5f "), gCog);
2028 if (std::isnan(gSog))
2029 sog.Printf(_T(
"SOG ----- "));
2031 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2038 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2041 wxLogMessage(navmsg);
2042 g_loglast_time = lognow;
2044 if (ptcmgr)
delete ptcmgr;
2046 for (
Track *track : g_TrackList) {
2049 g_TrackList.clear();
2057 delete g_SencThreadManager;
2059 if (g_pGroupArray) {
2060 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2062 delete g_pGroupArray->Item(igroup);
2065 g_pGroupArray->Clear();
2066 delete g_pGroupArray;
2069 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2070 wxLog::FlushActive();
2072 g_Platform->CloseLogFile();
2074 delete pInit_Chart_Dir;
2076 for (
Track *track : g_TrackList) {
2079 g_TrackList.clear();
2082 delete pWayPointMan;
2084 delete pMessageOnceArray;
2086 DeInitializeUserColors();
2090 delete m_pRegistrarMan;
2093 delete g_StyleManager;
2098 if (s_glu_dll_ready) {
2099 FreeLibrary(s_hGLU_DLL);
2108 void RestoreSystemColors(
void);
2109 RestoreSystemColors();
2116#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2117 if (plocale_def_lang)
delete plocale_def_lang;
2120 FontMgr::Shutdown();
2122 g_Platform->OnExit_2();
2129#ifdef LINUX_CRASHRPT
2130void MyApp::OnFatalException() { g_crashprint.Report(); }
2136void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2141 if (eErrClass == CE_Debug)
2142 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2143 else if (eErrClass == CE_Warning)
2144 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2146 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2148 wxString str(msg, wxConvUTF8);
bool g_bresponsive
Flag to control adaptive UI scaling.
Class AisDecoder and helpers.
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.
void Notify() override
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, const 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 CommBridge class and helpers.
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.
Multiplexer class and helpers.
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.
General observable implementation with several specializations.
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.