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"
114#include "model/nav_object_database.h"
115#include "model/navutil_base.h"
117#include "model/own_ship.h"
118#include "model/plugin_handler.h"
119#include "model/route.h"
120#include "model/routeman.h"
121#include "model/select.h"
122#include "model/track.h"
126#include "ais_info_gui.h"
127#include "AISTargetAlertDialog.h"
128#include "AISTargetListDialog.h"
129#include "AISTargetQueryDialog.h"
130#include "CanvasConfig.h"
136#include "ConfigMgr.h"
137#include "DetailSlider.h"
140#include "gdal/cpl_csv.h"
141#include "glTexCache.h"
142#include "GoToPositionDialog.h"
146#include "observable.h"
148#include "OCPN_AUIManager.h"
149#include "ocpn_frame.h"
150#include "OCPNPlatform.h"
152#include "rest_server_gui.h"
153#include "route_ctx_factory.h"
154#include "routemanagerdialog.h"
155#include "routeman_gui.h"
156#include "RoutePropDlgImpl.h"
159#include "S57QueryDialog.h"
160#include "safe_mode_gui.h"
161#include "SoundFactory.h"
165#include "TrackPropDlg.h"
169#include "glChartCanvas.h"
173#include "model/macutils.h"
177#include "model/garmin_protocol_mgr.h"
178void RedirectIOToConsole();
181#if defined(__WXMSW__) && defined(__MSVC__LEAK)
182#include "Stackwalker.h"
186#include "crashprint.h"
190#include "androidUTIL.h"
196const char *
const kUsage =
199 opencpn [-p] [-f] [-G] [-g] [-P] [-l <str>] [-u <num>] [-U] [-s] [GPX file ...]
200 opencpn --remote [-R] | -q] | -e] |-o <str>]
202Options for starting opencpn
204 -c, --configdir=<dirpath> Use alternative configuration directory.
205 -p, --portable Run in portable mode.
206 -f, --fullscreen Switch to full screen mode on start.
207 -G, --no_opengl Disable OpenGL video acceleration. This setting will
209 -g, --rebuild_gl_raster_cache Rebuild OpenGL raster cache on start.
210 -D, --rebuild_chart_db Rescan chart directories and rebuild the chart database
211 -P, --parse_all_enc Convert all S-57 charts to OpenCPN's internal format on start.
212 -l, --loglevel=<str> Amount of logging: error, warning, message, info, debug or trace
213 -u, --unit_test_1=<num> Display a slideshow of <num> charts and then exit.
214 Zero or negative <num> specifies no limit.
216 -s, --safe_mode Run without plugins, opengl and other "dangerous" stuff
217 -W, --config_wizard Start with initial configuration wizard
219Options manipulating already started opencpn
220 -r, --remote Execute commands on already running instance
221 -R, --raise Make running OpenCPN visible if hidden
222 -q, --quit Terminate already running opencpn
223 -e, --get_rest_endpoint Print rest server endpoint and exit.
224 -o, --open=<GPX file> Open file in running opencpn
227 GPX file GPX-formatted file with waypoints or routes.
231wxDEFINE_EVENT(EVT_N2K_129029, wxCommandEvent);
232wxDEFINE_EVENT(EVT_N2K_129026, wxCommandEvent);
234wxDEFINE_EVENT(EVT_N0183_RMC, wxCommandEvent);
235wxDEFINE_EVENT(EVT_N0183_HDT, wxCommandEvent);
236wxDEFINE_EVENT(EVT_N0183_HDG, wxCommandEvent);
237wxDEFINE_EVENT(EVT_N0183_HDM, wxCommandEvent);
238wxDEFINE_EVENT(EVT_N0183_VTG, wxCommandEvent);
239wxDEFINE_EVENT(EVT_N0183_GSV, wxCommandEvent);
240wxDEFINE_EVENT(EVT_N0183_GGA, wxCommandEvent);
241wxDEFINE_EVENT(EVT_N0183_GLL, wxCommandEvent);
242wxDEFINE_EVENT(EVT_N0183_AIVDO, wxCommandEvent);
252WX_DEFINE_OBJARRAY(ArrayOfCDI);
257bool g_bUpgradeInProcess;
269int g_restore_stackindex;
270int g_restore_dbindex;
271double g_ChartNotRenderScaleFactor;
273LayerList *pLayerList;
285int g_nbrightness = 100;
287bool bDBUpdateInProgress;
292bool g_bshowToolbar =
true;
293bool g_bexpert =
true;
294bool g_bBasicMenus =
false;
296bool bDrawCurrentValues;
298wxString ChartListFileName;
299wxString gWorldMapLocation, gDefaultWorldMapLocation;
300wxString gWorldShapefileLocation;
301wxString *pInit_Chart_Dir;
303wxString g_SENCPrefix;
304wxString g_UserPresLibData;
305wxString g_VisibleLayers;
306wxString g_InvisibleLayers;
307wxString g_VisiNameinLayers;
308wxString g_InVisiNameinLayers;
310bool g_bcompression_wait;
311bool g_FlushNavobjChanges;
312int g_FlushNavobjChangesTimeout;
314wxString g_uploadConnection;
321int g_mem_total, g_mem_initial;
323bool s_bSetSystemTime;
325static unsigned int malloc_max;
327wxDateTime g_start_time;
328wxDateTime g_loglast_time;
329static OcpnSound *_bells_sounds[] = {SoundFactory(), SoundFactory()};
330std::vector<OcpnSound *> bells_sound(_bells_sounds, _bells_sounds + 2);
332OcpnSound *g_anchorwatch_sound = SoundFactory();
334double AnchorPointMinDist;
335bool AnchorAlertOn1, AnchorAlertOn2;
343bool g_bShowDepthUnits;
347bool g_bShowActiveRouteHighway;
350bool g_bPlayShipsBells;
351bool g_bFullscreenToolbar;
353bool g_bTransparentToolbar;
354bool g_bTransparentToolbarInOpenGLOK;
355int g_nAutoHideToolbar;
356bool g_bAutoHideToolbar;
358bool g_bPermanentMOBIcon;
359bool g_bTempShowMenuBar;
361int g_iNavAidRadarRingsNumberVisible;
362bool g_bNavAidRadarRingsShown;
363float g_fNavAidRadarRingsStep;
364int g_pNavAidRadarRingsStepUnits;
365bool g_bWayPointPreventDragging;
366bool g_bConfirmObjectDelete;
367wxColour g_colourOwnshipRangeRingsColour;
371ColorScheme global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
373wxArrayPtrVoid *UserColourHashTableArray;
374wxColorHashMap *pcurrent_user_color_hash;
383int g_ChartUpdatePeriod;
384int g_SkewCompUpdatePeriod;
386int g_lastClientRectx;
387int g_lastClientRecty;
388int g_lastClientRectw;
389int g_lastClientRecth;
393double g_display_size_mm;
394std::vector<size_t> g_config_display_size_mm;
395bool g_config_display_size_manual;
398int g_ChartScaleFactor;
399float g_MarkScaleFactorExp;
400int g_last_ChartScaleFactor;
401int g_ShipScaleFactor;
402float g_ShipScaleFactorExp;
403int g_ENCSoundingScaleFactor;
404int g_ENCTextScaleFactor;
410s57RegistrarMgr *m_pRegistrarMan;
415#include "model/macutils.h"
424extern bool s_glu_dll_ready;
425extern HINSTANCE s_hGLU_DLL;
431double g_ownship_predictor_minutes;
432double g_ownship_HDTpredictor_miles;
433int g_cog_predictor_style;
434wxString g_cog_predictor_color;
435int g_cog_predictor_endmarker;
436int g_ownship_HDTpredictor_style;
437wxString g_ownship_HDTpredictor_color;
438int g_ownship_HDTpredictor_endmarker;
439int g_ownship_HDTpredictor_width;
441bool g_own_ship_sog_cog_calc;
442int g_own_ship_sog_cog_calc_damp_sec;
447int g_iSoundDeviceIndex;
449int g_S57_dialog_sx, g_S57_dialog_sy;
457bool g_bAutoAnchorMark;
460long gStart_LMT_Offset;
462wxArrayString *pMessageOnceArray;
464bool g_bUseGLL =
true;
495bool g_bsmoothpanzoom;
497bool g_bSmoothRecenter =
true;
499double g_overzoom_emphasis_base;
500bool g_oz_vector_scale;
501double g_plus_minus_zoom_factor;
504bool g_b_legacy_input_filter_behaviour;
511bool g_bFullScreenQuilt =
true;
515ChartGroupArray *g_pGroupArray;
519std::vector<std::string> TideCurrentDataSet;
520wxString g_TCData_Dir;
523bool g_bDeferredInitDone;
524int options_lastPage = 0;
525int options_subpage = 0;
527wxPoint options_lastWindowPos(0, 0);
528wxSize options_lastWindowSize(0, 0);
531bool g_bsimplifiedScalebar;
535bool GetMemoryStatus(
int *mem_total,
int *mem_used);
538int g_nAIS_activity_timer;
540bool g_bEnableZoomToCursor;
543bool g_bDeferredStartTrack;
544bool g_bHighliteTracks;
545wxColour g_colourTrackLineColour;
546wxString g_default_wp_icon;
549double g_TrackIntervalSeconds;
551int g_cm93_zoom_factor;
553bool g_bShowDetailSlider;
554int g_detailslider_dialog_x, g_detailslider_dialog_y;
561bool g_b_overzoom_x =
true;
563int g_OwnShipIconType;
564double g_n_ownship_length_meters;
565double g_n_ownship_beam_meters;
566double g_n_gps_antenna_offset_y;
567double g_n_gps_antenna_offset_x;
568int g_n_ownship_min_mm;
573bool g_bPreserveScaleOnX;
574bool g_CanvasHideNotificationIcon;
577About *g_pAboutDlgLegacy;
579#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
580wxLocale *plocale_def_lang = 0;
592wxString g_localeOverride;
593bool g_b_assume_azerty;
599bool g_bShowStatusBar;
605int g_AisTargetList_count;
606bool g_bAisTargetList_autosort;
611wxAuiDefaultDockArt *g_pauidockart;
613wxString g_toolbarConfig = _T(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
618long g_maintoolbar_orient;
619float g_toolbar_scalefactor;
621float g_compass_scalefactor;
623bool g_bShowCompassWin;
625bool g_benable_rotate;
633double gQueryVar = 361.0;
635char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
637int portaudio_initialized;
639char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
642int g_sticky_projection;
644int n_NavMessageShown;
645wxString g_config_version_string;
647wxString g_CmdSoundString;
665bool b_inCompressAllCharts;
669int g_chart_zoom_modifier_raster;
670int g_chart_zoom_modifier_vector;
672bool g_bAdvanceRouteWaypointOnArrivalOnly;
674bool g_bSpaceDropMark;
676wxArrayString g_locale_catalog_array;
677bool b_reloadForPlugins;
678bool g_btrackContinuous;
680unsigned int g_canvasConfig;
682bool g_bmasterToolbarFull =
true;
684int g_AndroidVersionCode;
689WX_DEFINE_ARRAY_PTR(
ChartCanvas *, arrayofCanvasPtr);
691arrayofCanvasPtr g_canvasArray;
692wxString g_lastAppliedTemplateGUID;
698bool g_disable_main_toolbar;
711DEFINE_GUID(GARMIN_DETECT_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81,
712 0x6b, 0xba, 0xe7, 0x22, 0xc0);
716#include <wx/msw/msvcrt.h>
720static const long long lNaN = 0xfff8000000000000;
721#define NAN (*(double *)&lNaN)
725void appendOSDirSlash(wxString *pString);
727void InitializeUserColors(
void);
728void DeInitializeUserColors(
void);
729void SetSystemColors(ColorScheme cs);
731static bool LoadAllPlugIns(
bool load_enabled) {
732 g_Platform->ShowBusySpinner();
733 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
734 g_Platform->HideBusySpinner();
742#if defined(__WXGTK__) || defined(__WXQT__)
743#include "bitmaps/opencpn.xpm"
746wxString newPrivateFileName(wxString,
const char *name,
747 [[maybe_unused]]
const char *windowsName) {
748 wxString fname = wxString::FromUTF8(name);
749 wxString filePathAndName;
752 if (filePathAndName.Last() != wxFileName::GetPathSeparator())
753 filePathAndName.Append(wxFileName::GetPathSeparator());
756 wxString fwname = wxString::FromUTF8(windowsName);
757 filePathAndName.Append(fwname);
759 filePathAndName.Append(fname);
762 return filePathAndName;
771BEGIN_EVENT_TABLE(
MyApp, wxApp)
772EVT_ACTIVATE_APP(MyApp::OnActivateApp)
775static
void ActivateRoute(const std::
string &guid) {
776 Route *route = g_pRouteMan->FindRouteByGUID(guid);
778 wxLogMessage(
"Cannot activate guid: no such route");
781 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
787 point = g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
789 point = route->GetPoint(2);
796static void ReverseRoute(
const std::string &guid) {
797 Route *route = g_pRouteMan->FindRouteByGUID(guid);
799 wxLogMessage(
"Cannot activate guid: no such route");
806void MyApp::InitRestListeners() {
807 auto activate_route = [&](wxCommandEvent ev) {
808 auto guid = ev.GetString().ToStdString();
812 auto reverse_route = [&](wxCommandEvent ev) {
813 auto guid = ev.GetString().ToStdString();
819bool MyApp::OpenFile(
const std::string &path) {
821 auto result = nav_objects.load_file(path.c_str());
823 std::string s(_(
"Cannot load route or waypoint file: "));
824 s += std::string(
"\"") + path +
"\"";
825 wxMessageBox(s,
"OpenCPN", wxICON_WARNING | wxOK);
831 nav_objects.LoadAllGPXObjects(!nav_objects.IsOpenCPN(), wpt_dups,
true);
833 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
834 pRouteManagerDialog->UpdateLists();
835 LLBBox box = nav_objects.GetBBox();
836 if (box.GetValid()) {
837 gFrame->CenterView(gFrame->GetPrimaryCanvas(), box);
843void MyApp::OnInitCmdLine(wxCmdLineParser &parser) {
846 parser.AddSwitch(
"h",
"help",
"", wxCMD_LINE_OPTION_HELP);
847 parser.AddSwitch(
"p",
"portable");
848 parser.AddOption(
"c",
"configdir",
"", wxCMD_LINE_VAL_STRING,
849 wxCMD_LINE_PARAM_OPTIONAL);
850 parser.AddSwitch(
"f",
"fullscreen");
851 parser.AddSwitch(
"G",
"no_opengl");
852 parser.AddSwitch(
"W",
"config_wizard");
853 parser.AddSwitch(
"g",
"rebuild_gl_raster_cache");
854 parser.AddSwitch(
"D",
"rebuild_chart_db");
855 parser.AddSwitch(
"P",
"parse_all_enc");
856 parser.AddOption(
"l",
"loglevel");
857 parser.AddOption(
"u",
"unit_test_1",
"", wxCMD_LINE_VAL_NUMBER);
858 parser.AddSwitch(
"U",
"unit_test_2");
859 parser.AddParam(
"import GPX files", wxCMD_LINE_VAL_STRING,
860 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
861 parser.AddSwitch(
"s",
"safe_mode");
862 parser.AddSwitch(
"r",
"remote");
863 parser.AddSwitch(
"R",
"raise");
864 parser.AddSwitch(
"q",
"quit");
865 parser.AddSwitch(
"e",
"get_rest_endpoint");
866 parser.AddOption(
"o",
"open",
"", wxCMD_LINE_VAL_STRING,
867 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
873static void ParseLoglevel(wxCmdLineParser &parser) {
874 wxLog::SetLogLevel(wxLOG_Message);
877static void ParseLoglevel(wxCmdLineParser &parser) {
878 const char *strLevel = std::getenv(
"OPENCPN_LOGLEVEL");
879 strLevel = strLevel ? strLevel :
"info";
881 if (parser.Found(
"l", &wxLevel)) {
882 strLevel = wxLevel.c_str();
884 wxLogLevel level = OcpnLog::str2level(strLevel);
885 if (level == OcpnLog::LOG_BADLEVEL) {
886 fprintf(stderr,
"Bad loglevel %s, using \"info\"", strLevel);
889 wxLog::SetLogLevel(level);
894bool MyApp::OnCmdLineHelp(wxCmdLineParser &parser) {
901bool MyApp::OnCmdLineParsed(wxCmdLineParser &parser) {
906 g_unit_test_2 = parser.Found(
"unit_test_2");
907 g_bportable = parser.Found(
"p");
908 g_start_fullscreen = parser.Found(
"fullscreen");
909 g_bdisable_opengl = parser.Found(
"no_opengl");
910 g_rebuild_gl_cache = parser.Found(
"rebuild_gl_raster_cache");
911 g_NeedDBUpdate = parser.Found(
"rebuild_chart_db") ? 2 : 0;
912 g_parse_all_enc = parser.Found(
"parse_all_enc");
913 g_config_wizard = parser.Found(
"config_wizard");
914 if (parser.Found(
"unit_test_1", &number)) {
915 g_unit_test_1 =
static_cast<int>(number);
916 if (g_unit_test_1 == 0) g_unit_test_1 = -1;
918 safe_mode::set_mode(parser.Found(
"safe_mode"));
919 ParseLoglevel(parser);
921 if (parser.Found(
"configdir", &wxstr)) {
922 g_configdir = wxstr.ToStdString();
923 fs::path path(g_configdir);
924 if (!fs::exists(path) || !fs::is_directory(path)) {
925 std::cerr << g_configdir <<
" is not an existing directory.\n";
930 bool has_start_options =
false;
931 static const std::vector<std::string> kStartOptions = {
936 "rebuild_gl_raster_cache",
942 for (
const auto &opt : kStartOptions) {
943 if (parser.Found(opt)) has_start_options =
true;
945 if (has_start_options && parser.Found(
"remote")) {
946 std::cerr <<
"this option is not compatible with --remote\n";
950 bool has_remote_options =
false;
951 static const std::vector<std::string> kRemoteOptions = {
952 "raise",
"quit",
"open",
"get_rest_endpoint"};
953 for (
const auto &opt : kRemoteOptions) {
954 if (parser.Found(opt)) has_remote_options =
true;
956 if (has_remote_options && !parser.Found(
"remote")) {
957 std::cerr <<
"This option requires --remote\n";
961 for (
size_t paramNr = 0; paramNr < parser.GetParamCount(); ++paramNr)
962 g_params.push_back(parser.GetParam(paramNr).ToStdString());
965 if (!parser.Found(
"remote"))
966 m_parsed_cmdline = ParsedCmdline();
967 else if (parser.Found(
"raise"))
968 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
969 else if (parser.Found(
"quit"))
970 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Quit);
971 else if (parser.Found(
"get_rest_endpoint"))
972 m_parsed_cmdline = ParsedCmdline(CmdlineAction::GetRestEndpoint);
973 else if (parser.Found(
"open", &optarg))
974 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Open, optarg.ToStdString());
975 else if (parser.GetParamCount() == 1)
977 ParsedCmdline(CmdlineAction::Open, parser.GetParam(0).ToStdString());
978 else if (!has_start_options && !has_remote_options) {
980 m_parsed_cmdline = ParsedCmdline(CmdlineAction::Raise);
990bool MyApp::OnExceptionInMainLoop() {
991 wxLogWarning(_T(
"Caught MainLoopException, continuing..."));
996void MyApp::OnActivateApp(wxActivateEvent &event) {
return; }
998static wxStopWatch init_sw;
1001 if (m_exitcode != -2)
return m_exitcode;
1002 return wxAppConsole::OnRun();
1013 if (wxGetEnv(
"WAYLAND_DISPLAY", NULL)) {
1014 setenv(
"GDK_BACKEND",
"x11", 1);
1017 "mesa_glthread",
"false",
1023bool MyApp::OnInit() {
1024 if (!wxApp::OnInit())
return false;
1026 androidEnableBackButton(
false);
1027 androidEnableOptionItems(
false);
1032#if defined(__WXGTK__) && defined(ocpnUSE_GLES) && defined(__ARM_ARCH)
1038 wxBitmap bmp(10, 10, -1);
1040 dc.SelectObject(bmp);
1041 dc.DrawText(_T(
"X"), 0, 0);
1046 g_BasePlatform = g_Platform;
1053 if (m_parsed_cmdline.action == CmdlineAction::Skip) {
1057 std::cerr <<
"No remote opencpn found. Giving up.\n";
1062 std::unique_ptr<LocalClientApi> client;
1064 client = LocalClientApi::GetClient();
1066 WARNING_LOG <<
"Ipc client exception: " << ie.str();
1073 wxMessageBox(_(
"Sorry, an existing instance of OpenCPN may be too busy "
1074 "to respond.\nPlease retry."),
1075 "OpenCPN", wxICON_INFORMATION | wxOK);
1080 auto result = client->HandleCmdline(m_parsed_cmdline.action,
1081 m_parsed_cmdline.arg);
1085 wxLogDebug(
"Error running remote command: %s", result.second.c_str());
1094 if (getenv(
"OPENCPN_FATAL_ERROR") != 0) {
1095 wxLogFatalError(getenv(
"OPENCPN_FATAL_ERROR"));
1100 if (!safe_mode::get_mode()) {
1106 OCPNPlatform::Initialize_1();
1111 MyApp::SetAppDisplayName(
"OpenCPN");
1114 wxDateTime x = wxDateTime::UNow();
1115 long seed = x.GetMillisecond();
1116 seed *= x.GetTicks();
1121 setlocale(LC_NUMERIC,
"C");
1123 g_start_time = wxDateTime::Now();
1125 g_loglast_time = g_start_time;
1126 g_loglast_time.MakeGMT();
1127 g_loglast_time.Subtract(
1128 wxTimeSpan(0, 29, 0, 0));
1130 AnchorPointMinDist = 5.0;
1136 GetMemoryStatus(&g_mem_total, &g_mem_initial);
1140 wxFont temp_font(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
1141 wxFONTWEIGHT_NORMAL, FALSE, wxString(_T(
"")),
1142 wxFONTENCODING_SYSTEM);
1143 temp_font.SetDefaultEncoding(wxFONTENCODING_SYSTEM);
1146 auto ¬eman = NotificationManager::GetInstance();
1147 noteman.ScrubNotificationDirectory(30);
1150 if (!g_Platform->InitializeLogFile()) {
1162 wxLogMessage(_T(
"\n\n________\n"));
1164 wxDateTime now = wxDateTime::Now();
1165 LOG_INFO(
"------- OpenCPN version %s restarted at %s -------\n", VERSION_FULL,
1166 now.FormatISODate().mb_str().data());
1167 wxLogLevel level = wxLog::GetLogLevel();
1168 LOG_INFO(
"Using loglevel %s", OcpnLog::level2str(level).c_str());
1170 wxString wxver(wxVERSION_STRING);
1171 wxver.Prepend(_T(
"wxWidgets version: "));
1173 wxPlatformInfo platforminfo = wxPlatformInfo::Get();
1177 os_name = platforminfo.GetOperatingSystemIdName();
1179 os_name = platforminfo.GetOperatingSystemFamilyName();
1182 wxString platform = os_name + _T(
" ") + platforminfo.GetArchName() + _T(
" ") +
1183 platforminfo.GetPortIdName();
1185 wxLogMessage(wxver + _T(
" ") + platform);
1187 ::wxGetOsVersion(&osMajor, &osMinor);
1188 wxString osVersionMsg;
1189 osVersionMsg.Printf(_T(
"OS Version reports as: %d.%d"), osMajor, osMinor);
1190 wxLogMessage(osVersionMsg);
1192 wxLogMessage(_T(
"MemoryStatus: mem_total: %d mb, mem_initial: %d mb"),
1193 g_mem_total / 1024, g_mem_initial / 1024);
1198 if (!detail->osd_names_like.empty())
1199 like0 = detail->osd_names_like[0].c_str();
1200 msgplat.Printf(
"OCPN_OSDetail: %s ; %s ; %s ; %s ; %s",
1201 detail->osd_arch.c_str(), detail->osd_name.c_str(),
1202 detail->osd_version.c_str(), detail->osd_ID.c_str(),
1204 wxLogMessage(msgplat);
1206 wxString imsg = _T(
"SData_Locn is ");
1207 imsg += g_Platform->GetSharedDataDir();
1211 ::wxInitAllImageHandlers();
1215 prepareAndroidStyleSheets();
1219 pInit_Chart_Dir =
new wxString();
1222 g_pGroupArray =
new ChartGroupArray;
1224 imsg = _T(
"PrivateDataDir is ");
1230 pMessageOnceArray =
new wxArrayString;
1234 new Routeman(RoutePropDlg::GetDlgCtx(), RoutemanGui::GetDlgCtx());
1238 pSelect->SetSelectPixelRadius(12);
1241 pSelectTC =
new Select();
1243 pSelectTC->SetSelectPixelRadius(25);
1246 pSelectAIS =
new Select();
1247 pSelectAIS->SetSelectPixelRadius(12);
1251 g_pais_query_dialog_active = NULL;
1254 g_hostname = ::wxGetHostName();
1255 if (g_hostname.IsEmpty()) g_hostname = wxGetUserName();
1257 androidGetDeviceInfo();
1258 g_hostname = wxString(
"Android-") + g_android_Device_Model;
1259 g_hostname.Replace(
" ",
"-",
true);
1264 wxString p(
"Portable-");
1265 g_hostname = p + g_hostname;
1270 pLayerList =
new LayerList;
1272 pRouteList =
new RouteList;
1279#ifdef PROBE_PORTS__WITH_HELPER
1280 user_user_id = getuid();
1281 file_user_id = geteuid();
1285 bool b_initial_load =
false;
1287 wxFileName config_test_file_name(g_Platform->GetConfigFileName());
1288 if (config_test_file_name.FileExists())
1289 wxLogMessage(_T(
"Using existing Config_File: ") +
1290 g_Platform->GetConfigFileName());
1293 wxLogMessage(_T(
"Creating new Config_File: ") +
1294 g_Platform->GetConfigFileName());
1296 b_initial_load =
true;
1299 config_test_file_name.DirExists(config_test_file_name.GetPath()))
1300 if (!config_test_file_name.Mkdir(config_test_file_name.GetPath()))
1301 wxLogMessage(_T(
"Cannot create config file directory for ") +
1302 g_Platform->GetConfigFileName());
1307 pConfig = g_Platform->GetConfigObject();
1308 InitBaseConfig(pConfig);
1309 pConfig->LoadMyConfig();
1313 if (b_initial_load) g_Platform->SetDefaultOptions();
1315 g_Platform->applyExpertMode(g_bUIexpert);
1323 g_StyleManager->SetStyle(_T(
"MUI_flat"));
1324 if (!g_StyleManager->IsOK()) {
1325 wxString msg = _(
"Failed to initialize the user interface. ");
1326 msg << _(
"OpenCPN cannot start. ");
1327 msg << _(
"The necessary configuration files were not found. ");
1328 msg << _(
"See the log file at ") << g_Platform->GetLogFileName()
1329 << _(
" for details.") << _T(
"\n\n");
1330 msg << g_Platform->GetSharedDataDir();
1332 wxMessageDialog w(NULL, msg, _(
"Failed to initialize the user interface. "),
1333 wxCANCEL | wxICON_ERROR);
1340 if (style) style->chartStatusWindowTransparent =
true;
1344 pWayPointMan = NULL;
1348 msg.Printf(_T(
"Detected display size (horizontal): %d mm"),
1349 (
int)g_display_size_mm);
1353 if (g_config_display_size_manual &&
1354 g_config_display_size_mm.size() > g_current_monitor &&
1355 g_config_display_size_mm[g_current_monitor] > 0) {
1356 g_display_size_mm = g_config_display_size_mm[g_current_monitor];
1358 msg.Printf(_T(
"Display size (horizontal) config override: %d mm"),
1359 (
int)g_display_size_mm);
1364 g_display_size_mm = wxMax(50, g_display_size_mm);
1367 int SelectPixelRadius = 50;
1369 pSelect->SetSelectPixelRadius(SelectPixelRadius);
1370 pSelectTC->SetSelectPixelRadius(wxMax(25, SelectPixelRadius));
1371 pSelectAIS->SetSelectPixelRadius(SelectPixelRadius);
1375 if (!n_NavMessageShown) {
1382#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1385 g_Platform->SetLocaleSearchPrefixes();
1387 wxString def_lang_canonical = g_Platform->GetDefaultSystemLocale();
1389 imsg = _T(
"System default Language: ") + def_lang_canonical;
1392 wxString cflmsg = _T(
"Config file language: ") + g_locale;
1393 wxLogMessage(cflmsg);
1395 if (g_locale.IsEmpty()) {
1396 g_locale = def_lang_canonical;
1398 _T(
"Config file language empty, using system default: ") + g_locale;
1399 wxLogMessage(cflmsg);
1403 g_locale = g_Platform->GetAdjustedAppLocale();
1404 cflmsg = _T(
"Adjusted App language: ") + g_locale;
1405 wxLogMessage(cflmsg);
1408 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
1410 imsg = _T(
"Opencpn language set to: ");
1417 if (g_locale == _T(
"fr_FR")) g_b_assume_azerty =
true;
1419 wxLogMessage(_T(
"wxLocale support not available"));
1424 if (g_config_wizard || b_initial_load) {
1426 auto res = wiz.Run();
1437 wxString vs = wxString(
"Version ") + VERSION_FULL +
" Build " + VERSION_DATE;
1438 g_bUpgradeInProcess = (vs != g_config_version_string);
1440 g_Platform->SetUpgradeOptions(vs, g_config_version_string);
1443 if (!g_Platform->GetLargeLogMessage().IsEmpty()) {
1444 wxLogMessage(g_Platform->GetLargeLogMessage());
1449 g_bdisable_opengl =
true;
1453 if (g_bdisable_opengl) g_bopengl =
false;
1455#if defined(__linux__) && !defined(__ANDROID__)
1456 if (g_bSoftwareGL) {
1457 setenv(
"LIBGL_ALWAYS_SOFTWARE",
"1", 1);
1470 if (0 == g_memCacheLimit) g_memCacheLimit = (int)(g_mem_total * 0.5);
1472 wxMin(g_memCacheLimit, 1024 * 1024);
1478 g_memCacheLimit = 0;
1479 if (0 == g_nCacheLimit)
1480 g_nCacheLimit = CACHE_N_LIMIT_DEFAULT;
1485 "chartlist.dat",
"CHRTLIST.DAT");
1489 "mmsitoname.csv",
"MMSINAME.CSV");
1492 if (pInit_Chart_Dir->IsEmpty()) {
1493 wxStandardPaths &std_path = g_Platform->GetStdPaths();
1497 pInit_Chart_Dir->Append(std_path.GetDocumentsDir());
1499 pInit_Chart_Dir->Append(androidGetExtStorageDir());
1503 InitRestListeners();
1506 gDefaultWorldMapLocation =
"gshhs";
1507 gDefaultWorldMapLocation.Prepend(g_Platform->GetSharedDataDir());
1508 gDefaultWorldMapLocation.Append(wxFileName::GetPathSeparator());
1509 if (gWorldMapLocation == wxEmptyString) {
1510 gWorldMapLocation = gDefaultWorldMapLocation;
1515 wxString default_tcdata0 =
1516 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1517 wxFileName::GetPathSeparator() + _T(
"harmonics-dwf-20210110-free.tcd"));
1518 wxString default_tcdata1 =
1519 (g_Platform->GetSharedDataDir() + _T(
"tcdata") +
1520 wxFileName::GetPathSeparator() + _T(
"HARMONICS_NO_US.IDX"));
1522 if (TideCurrentDataSet.empty()) {
1523 TideCurrentDataSet.push_back(
1524 g_Platform->NormalizePath(default_tcdata0).ToStdString());
1525 TideCurrentDataSet.push_back(
1526 g_Platform->NormalizePath(default_tcdata1).ToStdString());
1531 if (g_sAIS_Alert_Sound_File.IsEmpty()) {
1532 wxString default_sound =
1533 (g_Platform->GetSharedDataDir() + _T(
"sounds") +
1534 wxFileName::GetPathSeparator() + _T(
"2bells.wav"));
1535 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(default_sound);
1540 g_Platform->Initialize_2();
1544 wxSize new_frame_size(-1, -1);
1546 ::wxClientDisplayRect(&cx, &cy, &cw, &ch);
1548 InitializeUserColors();
1550 auto style = g_StyleManager->GetCurrentStyle();
1551 auto bitmap =
new wxBitmap(style->GetIcon(
"default_pi", 32, 32));
1553 PluginLoader::GetInstance()->SetPluginDefaultIcon(bitmap);
1555 wxLogWarning(
"Cannot initiate plugin default jigsaw icon.");
1557 if ((g_nframewin_x > 100) && (g_nframewin_y > 100) && (g_nframewin_x <= cw) &&
1558 (g_nframewin_y <= ch))
1559 new_frame_size.Set(g_nframewin_x, g_nframewin_y);
1561 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1567 if ((g_lastClientRectx != cx) || (g_lastClientRecty != cy) ||
1568 (g_lastClientRectw != cw) || (g_lastClientRecth != ch)) {
1569 new_frame_size.Set(cw * 7 / 10, ch * 7 / 10);
1570 g_bframemax =
false;
1573 g_lastClientRectx = cx;
1574 g_lastClientRecty = cy;
1575 g_lastClientRectw = cw;
1576 g_lastClientRecth = ch;
1579 wxPoint position(0, 0);
1580 wxSize dsize = wxGetDisplaySize();
1583 g_nframewin_posy = wxMax(g_nframewin_posy, 22);
1586 if ((g_nframewin_posx < dsize.x) && (g_nframewin_posy < dsize.y))
1587 position = wxPoint(g_nframewin_posx, g_nframewin_posy);
1592 frame_rect.left = position.x;
1593 frame_rect.top = position.y;
1594 frame_rect.right = position.x + new_frame_size.x;
1595 frame_rect.bottom = position.y + new_frame_size.y;
1599 if (NULL == MonitorFromRect(&frame_rect, MONITOR_DEFAULTTONULL))
1600 position = wxPoint(10, 10);
1605 const wxPoint ptScreen(position.x, position.y);
1606 const int displayIndex = wxDisplay::GetFromPoint(ptScreen);
1608 if (displayIndex == wxNOT_FOUND) position = wxPoint(10, 30);
1611 g_nframewin_posx = position.x;
1612 g_nframewin_posy = position.y;
1615 wxSize asz = getAndroidDisplayDimensions();
1620 if ((cw > 200) && (ch > 200))
1621 new_frame_size.Set(cw, ch);
1623 new_frame_size.Set(800, 400);
1627 long app_style = wxDEFAULT_FRAME_STYLE;
1628 app_style |= wxWANTS_CHARS;
1633 wxString short_version_name = wxString(PACKAGE_VERSION).BeforeFirst(
'+');
1634 wxString myframe_window_title =
1635 wxString(wxT(
"OpenCPN ") + short_version_name);
1638 myframe_window_title += _(
" -- [Portable(-p) executing from ");
1639 myframe_window_title += g_Platform->GetHomeDir();
1640 myframe_window_title += _T(
"]");
1644 fmsg.Printf(_T(
"Creating MyFrame...size(%d, %d) position(%d, %d)"),
1645 new_frame_size.x, new_frame_size.y, position.x, position.y);
1648 gFrame =
new MyFrame(NULL, myframe_window_title, position, new_frame_size,
1650 wxTheApp->SetTopWindow(gFrame);
1653 g_Platform->Initialize_3();
1660 g_pauidockart =
new wxAuiDefaultDockArt;
1661 g_pauimgr->SetArtProvider(g_pauidockart);
1662 g_pauimgr->SetDockSizeConstraint(.9, .9);
1667 g_pauimgr->SetManagedWindow(gFrame);
1669 gFrame->CreateCanvasLayout();
1673 gFrame->SetChartUpdatePeriod();
1677 gFrame->GetPrimaryCanvas()->SetFocus();
1679 pthumbwin =
new ThumbWin(gFrame->GetPrimaryCanvas());
1681 gFrame->ApplyGlobalSettings(
false);
1683 gFrame->SetAllToolbarScale();
1689 gFrame->SetAndApplyColorScheme(global_color_scheme);
1691 if (g_bframemax) gFrame->Maximize(
true);
1694 if (
g_bresponsive && (gFrame->GetPrimaryCanvas()->GetPixPerMM() > 4.0))
1695 gFrame->Maximize(
true);
1702 ArrayOfCDI ChartDirArray;
1703 pConfig->LoadChartDirArray(ChartDirArray);
1708 if (g_bFirstRun && (ChartDirArray.GetCount() == 0)) {
1711 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
1712 if (RegKey.Exists()) {
1714 _(
"Retrieving initial Chart Directory set from Windows Registry"));
1716 RegKey.QueryValue(wxString(_T(
"ChartDirs")), dirs);
1718 wxStringTokenizer tkz(dirs, _T(
";"));
1719 while (tkz.HasMoreTokens()) {
1720 wxString token = tkz.GetNextToken();
1723 cdi.fullpath = token.Trim();
1724 cdi.magic_number = _T(
"");
1726 ChartDirArray.Add(cdi);
1733 cdi.fullpath = _T(
"charts");
1734 cdi.fullpath.Prepend(g_Platform->GetSharedDataDir());
1735 cdi.magic_number = _T(
"");
1736 ChartDirArray.Add(cdi);
1740 if (ndirs) pConfig->UpdateChartDirs(ChartDirArray);
1750 if (!ChartDirArray.GetCount())
1751 if (::wxFileExists(ChartListFileName)) ::wxRemoveFile(ChartListFileName);
1755 if (g_NeedDBUpdate == 0 &&
1756 !ChartData->
LoadBinary(ChartListFileName, ChartDirArray)) {
1761 if (g_restore_dbindex >= 0) {
1762 if (ChartData->GetChartTableEntries() == 0)
1763 g_restore_dbindex = -1;
1765 else if (g_restore_dbindex > (ChartData->GetChartTableEntries() - 1))
1766 g_restore_dbindex = 0;
1770 ChartData->ApplyGroupArray(g_pGroupArray);
1778 if (g_rebuild_gl_cache && g_bopengl && g_GLOptions.m_bTextureCompression &&
1779 g_GLOptions.m_bTextureCompressionCaching) {
1780 gFrame->ReloadAllVP();
1789 if (g_glTextureManager) g_glTextureManager->BuildCompressedCache();
1799 if ((gps_watchdog_timeout_ticks > 60) || (gps_watchdog_timeout_ticks <= 0))
1800 gps_watchdog_timeout_ticks = (GPS_TIMEOUT_SECONDS * 1000) / TIMER_GFRAME_1;
1803 dogmsg.Printf(_T(
"GPS Watchdog Timeout is: %d sec."),
1804 gps_watchdog_timeout_ticks);
1805 wxLogMessage(dogmsg);
1807 sat_watchdog_timeout_ticks = gps_watchdog_timeout_ticks;
1815 if (g_bTrackCarryOver) g_bDeferredStartTrack =
true;
1817 pAnchorWatchPoint1 = NULL;
1818 pAnchorWatchPoint2 = NULL;
1822 gFrame->DoChartUpdate();
1827 gFrame->ReloadAllVP();
1829 gFrame->Refresh(
false);
1832 gFrame->GetPrimaryCanvas()->Enable();
1833 gFrame->GetPrimaryCanvas()->SetFocus();
1840 if (!g_bdisable_opengl) {
1844 (pgl->GetRendererString().Find(_T(
"UniChrome")) != wxNOT_FOUND)) {
1845 gFrame->m_defer_size = gFrame->GetSize();
1846 gFrame->SetSize(gFrame->m_defer_size.x - 10, gFrame->m_defer_size.y);
1847 g_pauimgr->Update();
1848 gFrame->m_bdefer_resize =
true;
1858 glDeleteTextures(n, texts);
1864 if (g_start_fullscreen) gFrame->ToggleFullScreen();
1869 gFrame->SetSize(getAndroidDisplayDimensions());
1870 androidSetFollowTool(gFrame->GetPrimaryCanvas()->m_bFollow ? 1 : 0, true);
1874 gFrame->GetPrimaryCanvas()->Enable();
1875 gFrame->GetPrimaryCanvas()->SetFocus();
1883 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
1886 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
1889 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
1894 OCPNPlatform::Initialize_4();
1897 androidHideBusyIcon();
1900 wxString::Format(_(
"OpenCPN Initialized in %ld ms."), init_sw.Time()));
1908 if (!n_NavMessageShown || (vs != g_config_version_string) ||
1909 (g_AndroidVersionCode != androidGetVersionCode())) {
1913 if (!ShowNavWarning()) {
1914 qDebug() <<
"Closing due to NavWarning Cancel";
1920 n_NavMessageShown = 1;
1924 g_AndroidVersionCode = androidGetVersionCode();
1925 qDebug() <<
"Persisting Version Code: " << g_AndroidVersionCode;
1930 if (!n_NavMessageShown || (vs != g_config_version_string)) {
1931 if (!ShowNavWarning())
return false;
1932 n_NavMessageShown = 1;
1939 g_bHasHwClock =
true;
1940#if defined(__UNIX__) && !defined(__ANDROID__)
1943 ((stat(
"/dev/rtc", &buffer) == 0) || (stat(
"/dev/rtc0", &buffer) == 0) ||
1944 (stat(
"/dev/misc/rtc", &buffer) == 0));
1947 g_config_version_string = vs;
1950 pConfig->UpdateSettings();
1953 gFrame->InitTimer.Start(5, wxTIMER_CONTINUOUS);
1955 g_pauimgr->Update();
1957 for (
auto *cp : TheConnectionParams()) {
1959 if (cp->GetDSPort().Contains(
"Serial")) {
1960 std::string port(cp->Port.ToStdString());
1968 m_comm_bridge.Initialize();
1970 std::vector<std::string> ipv4_addrs = get_local_ipv4_addresses();
1973 if (ipv4_addrs.size()) {
1974 std::string ipAddr = ipv4_addrs[0];
1977 if (data_dir.Last() != wxFileName::GetPathSeparator())
1978 data_dir.Append(wxFileName::GetPathSeparator());
1980 make_certificate(ipAddr, data_dir.ToStdString());
1982 m_rest_server.
StartServer(fs::path(data_dir.ToStdString()));
1983 StartMDNSService(g_hostname.ToStdString(),
"opencpn-object-control-service",
1989int MyApp::OnExit() {
1990 wxLogMessage(_T(
"opencpn::MyApp starting exit."));
1992 m_usb_watcher.Stop();
1995 wxDateTime lognow = wxDateTime::Now();
1997 wxString day = lognow.FormatISODate();
1998 wxString utc = lognow.FormatISOTime();
1999 wxString navmsg = _T(
"LOGBOOK: ");
2003 navmsg += _T(
" UTC ");
2007 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f "), gLat, gLon);
2011 if (std::isnan(gCog))
2012 cog.Printf(_T(
"COG ----- "));
2014 cog.Printf(_T(
"COG %10.5f "), gCog);
2017 if (std::isnan(gSog))
2018 sog.Printf(_T(
"SOG ----- "));
2020 sog.Printf(_T(
"SOG %6.2f ") + getUsrSpeedUnit(), toUsrSpeed(gSog));
2027 data.Printf(_T(
"OFF: Lat %10.5f Lon %10.5f"), gLat, gLon);
2030 wxLogMessage(navmsg);
2031 g_loglast_time = lognow;
2033 if (ptcmgr)
delete ptcmgr;
2035 for (
Track *track : g_TrackList) {
2038 g_TrackList.clear();
2046 delete g_SencThreadManager;
2048 if (g_pGroupArray) {
2049 for (
unsigned int igroup = 0; igroup < g_pGroupArray->GetCount();
2051 delete g_pGroupArray->Item(igroup);
2054 g_pGroupArray->Clear();
2055 delete g_pGroupArray;
2058 wxLogMessage(_T(
"opencpn::MyApp exiting cleanly...\n"));
2059 wxLog::FlushActive();
2061 g_Platform->CloseLogFile();
2063 delete pInit_Chart_Dir;
2065 for (
Track *track : g_TrackList) {
2068 g_TrackList.clear();
2071 delete pWayPointMan;
2073 delete pMessageOnceArray;
2075 DeInitializeUserColors();
2079 delete m_pRegistrarMan;
2082 delete g_StyleManager;
2087 if (s_glu_dll_ready) {
2088 FreeLibrary(s_hGLU_DLL);
2097 void RestoreSystemColors(
void);
2098 RestoreSystemColors();
2105#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2106 if (plocale_def_lang)
delete plocale_def_lang;
2109 FontMgr::Shutdown();
2111 g_Platform->OnExit_2();
2118#ifdef LINUX_CRASHRPT
2119void MyApp::OnFatalException() { g_crashprint.Report(); }
2125void MyCPLErrorHandler(CPLErr eErrClass,
int nError,
const char *pszErrorMsg)
2130 if (eErrClass == CE_Debug)
2131 snprintf(msg, 255,
"CPL: %s", pszErrorMsg);
2132 else if (eErrClass == CE_Warning)
2133 snprintf(msg, 255,
"CPL Warning %d: %s", nError, pszErrorMsg);
2135 snprintf(msg, 255,
"CPL ERROR %d: %s", nError, pszErrorMsg);
2137 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.
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.