51#include <wx/apptrait.h>
52#include <wx/stdpaths.h>
53#include <wx/filename.h>
54#include <wx/tokenzr.h>
55#include <wx/textfile.h>
58#include "nlohmann/json.hpp"
84#include "snd_config.h"
85#include "std_filesystem.h"
90#include "androidUTIL.h"
98#ifdef OCPN_USE_CRASHREPORT
120void appendOSDirSlash(wxString *pString);
123struct sigaction sa_all;
124struct sigaction sa_all_old;
131#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
132extern wxLocale *plocale_def_lang;
143static const char *
const DEFAULT_XDG_DATA_DIRS =
144 "~/.local/share:/usr/local/share:/usr/share";
147static const char PATH_SEP =
';';
149static const char PATH_SEP =
':';
153constexpr int kStatFieldCount = 2;
155constexpr int kStatFieldCount = 5;
158static bool checkIfFlatpacked() {
160 if (!wxGetEnv(
"FLATPAK_ID", &
id)) {
163 return id ==
"org.opencpn.OpenCPN";
166OCPNPlatform::OCPNPlatform() {
168 m_bdisableWindowsDisplayEnum =
false;
169 m_monitorWidth = m_monitorHeight = 0;
172 m_displaySizeMMOverride.push_back(0);
174 m_pluginDataPath =
"";
177OCPNPlatform::~OCPNPlatform() {
189int MyNewHandler(
size_t size) {
191 throw std::bad_alloc();
212void catch_signals(
int signo) {
225 top_frame::Get()->FastClose();
232 top_frame::Get()->FastClose();
243#ifdef OCPN_USE_CRASHREPORT
245int CALLBACK CrashCallback(CR_CRASH_CALLBACK_INFO *pInfo) {
246 wxLog::GetActiveTarget()->Flush();
247 return CR_CB_DODEFAULT;
252void OCPNPlatform::Initialize_1() {
253#ifdef OCPN_USE_CRASHREPORT
257 CR_INSTALL_INFO info;
258 memset(&info, 0,
sizeof(CR_INSTALL_INFO));
259 info.cb =
sizeof(CR_INSTALL_INFO);
260 info.pszAppName = L
"OpenCPN";
262 info.pszAppVersion = wxString(VERSION_FULL).c_str();
264 int type = MiniDumpNormal;
267 type |= MiniDumpWithDataSegs;
278 info.uMiniDumpType = (MINIDUMP_TYPE)type;
281 info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS;
284 info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER;
287 info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES;
290 info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS;
294 if (g_bEmailCrashReport) {
295 info.pszUrl = L
"https://bigdumboat.com/crashrpt/ocpn_crashrpt.php";
296 info.uPriorities[CR_HTTP] = 3;
298 info.dwFlags |= CR_INST_DONT_SEND_REPORT;
299 info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY;
302 info.uPriorities[CR_SMTP] =
303 CR_NEGATIVE_PRIORITY;
304 info.uPriorities[CR_SMAPI] =
305 CR_NEGATIVE_PRIORITY;
307 wxStandardPaths &crash_std_path =
g_Platform->GetStdPaths();
309 wxString crash_rpt_save_locn = crash_std_path.GetConfigDir();
311 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
312 crash_rpt_save_locn =
313 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
316 wxString locn = crash_rpt_save_locn +
"\\CrashReports";
318 if (!wxDirExists(locn)) wxMkdir(locn);
320 if (wxDirExists(locn)) {
321 wxCharBuffer buf = locn.ToUTF8();
323 if (buf && (locn.Length() <
sizeof(wlocn))) {
324 MultiByteToWideChar(0, 0, buf.data(), -1, wlocn,
sizeof(wlocn) - 1);
325 info.pszErrorReportSaveDir = (LPCWSTR)wlocn;
330 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
331 wxString policy_file =
332 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
333 policy_file +=
"PrivacyPolicy.txt";
334 policy_file.Prepend(
"file:");
336 info.pszPrivacyPolicyURL = policy_file.c_str();
339 int nResult = crInstall(&info);
342 crGetLastErrorMsg(buff, 256);
349 crSetCrashCallback(CrashCallback, NULL);
352 crAddScreenshot2(CR_AS_PROCESS_WINDOWS | CR_AS_USE_JPEG_FORMAT, 95);
355 wxString home_data_crash = crash_std_path.GetConfigDir();
357 wxFileName f(crash_std_path.GetExecutablePath());
358 home_data_crash = f.GetPath();
360 appendOSDirSlash(&home_data_crash);
362 wxString config_crash =
"opencpn.ini";
363 config_crash.Prepend(home_data_crash);
364 crAddFile2(config_crash.c_str(), NULL, NULL,
365 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
367 wxString log_crash =
"opencpn.log";
368 log_crash.Prepend(home_data_crash);
369 crAddFile2(log_crash.c_str(), NULL, NULL,
370 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
376#if wxUSE_ON_FATAL_EXCEPTION
378 wxHandleFatalExceptions(
true);
384 _set_new_handler(MyNewHandler);
394 HANDLE hProc = GetCurrentProcess();
398 DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
401 GetProcessAffinityMask( hDup, &procMask, &sysMask );
405 if( ( procMask & 1 ) == 1 ) newMask = 1;
407 if( ( procMask & 2 ) == 2 ) newMask = 2;
409 if( ( procMask & 4 ) == 4 ) newMask = 4;
411 if( ( procMask & 8 ) == 8 ) newMask = 8;
414 BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask );
428 wxPlatformInfo Platform;
429 if (Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X)
430 SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
441 sa_all.sa_handler = catch_signals;
442 sigemptyset(&sa_all.sa_mask);
448 sigaction(SIGUSR1, NULL,
452 sigaction(SIGUSR1, &sa_all, NULL);
453 sigaction(SIGUSR1, NULL,
456 sigaction(SIGTERM, &sa_all, NULL);
457 sigaction(SIGTERM, NULL, &sa_all_old);
459 sigaction(SIGHUP, &sa_all, NULL);
460 sigaction(SIGHUP, NULL, &sa_all_old);
465 qDebug() <<
"Initialize_1()";
475void OCPNPlatform::Initialize_2() {
477 wxLogMessage(androidGetDeviceInfo());
481 wxChar sep = wxFileName::GetPathSeparator();
484 if (ChartDir.Last() != sep) ChartDir.Append(sep);
485 ChartDir.Append(
"Charts");
486 if (!::wxDirExists(ChartDir)) {
491 if (GRIBDir.Last() != sep) GRIBDir.Append(sep);
492 GRIBDir.Append(
"GRIBS");
493 if (!::wxDirExists(GRIBDir)) {
498 if (VDRDir.Last() != sep) VDRDir.Append(sep);
499 VDRDir.Append(
"VDR");
500 if (!::wxDirExists(VDRDir)) {
505 if (g_Android_SDK_Version >= 30) {
506 if (!g_gpx_path.StartsWith(androidGetDocumentsDirectory())) {
507 g_gpx_path = androidGetDocumentsDirectory();
516 g_toolbar_scalefactor = GetToolbarScaleFactor(g_GUIScaleFactor);
518 if (!configdir.DirExists()) {
519 if (!configdir.Mkdir()) {
520 auto msg = std::string(
"Cannot create config directory: ");
521 wxLogWarning(msg + configdir.GetFullPath());
528void OCPNPlatform::Initialize_3() {
529 bool bcapable = IsGLCapable();
535 bool bAndroid =
false;
544 g_bdisable_opengl =
false;
552 if ((g_bFirstRun || g_bUpgradeInProcess || bAndroid) && bcapable) {
556 g_GLOptions.m_bUseAcceleratedPanning =
true;
557 g_GLOptions.m_bTextureCompression =
true;
558 g_GLOptions.m_bTextureCompressionCaching =
true;
560 g_GLOptions.m_iTextureDimension = 512;
561 g_GLOptions.m_iTextureMemorySize = 64;
563 g_GLOptions.m_GLPolygonSmoothing =
true;
564 g_GLOptions.m_GLLineSmoothing =
true;
574 if (g_bFirstRun || g_bUpgradeInProcess) {
579 g_FlushNavobjChangesTimeout = 300;
583void OCPNPlatform::Initialize_4() {
585 if (
pSelect)
pSelect->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
587 pSelectTC->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
589 pSelectAIS->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
596 options_lastPage = 1;
600void OCPNPlatform::OnExit_1() {}
602void OCPNPlatform::OnExit_2() {
603#ifdef OCPN_USE_CRASHREPORT
613static bool HasGLExt(
const nlohmann::json &glinfo,
const std::string &ext) {
614 if (glinfo.count(
"GL_EXTENSIONS") <= 0) {
617 for (
const auto &extension : glinfo[
"GL_EXTENSIONS"]) {
618 if (extension.get<std::string>() == ext) {
625bool OCPNPlatform::BuildGLCaps(
void *pbuf) {
627 fs::path ep(GetExePath().ToStdString());
629 std::string gl_util_exe =
"opencpn-glutil";
631 std::string gl_util_exe =
"opencpn-glutil.exe";
633 fs::path gl_util_path = ep.parent_path().append(gl_util_exe);
635 if (!fs::exists(gl_util_path)) {
637 ep.parent_path().parent_path().append(
"libexec").append(gl_util_exe);
639 if (!fs::exists(gl_util_path)) {
642 wxLogMessage(
"OpenGL test utility not found at %s.", gl_util_path.c_str());
647 .append(
"gl_caps.json")
650 wxString cmd = wxString::Format(
"\"%s\" opengl-info \"%s\"",
651 gl_util_path.c_str(), gl_json.c_str());
653 wxLogMessage(
"Starting OpenGL test utility: %s", cmd);
655 wxArrayString output;
656 if (
long res = wxExecute(cmd, output); res != 0) {
657 wxLogMessage(
"OpenGL test utility failed with exit code %d", res);
658 for (
const auto &l : output) {
664 std::ifstream f(gl_json);
666 root = nlohmann::json::parse(f);
667 }
catch (nlohmann::json::exception &e) {
668 wxLogMessage(
"Failed to parse JSON output from OpenGL test utility.");
669 wxLogMessage(e.what());
674 if (root.contains(
"GL_RENDERER")) {
675 pcaps->Renderer = root[
"GL_RENDERER"].get<std::string>();
677 wxLogMessage(
"GL_RENDERER not found.");
680 if (root.contains(
"GL_VERSION")) {
681 pcaps->Version = root[
"GL_VERSION"].get<std::string>();
683 wxLogMessage(
"GL_VERSION not found.");
686 if (root.contains(
"GL_SHADING_LANGUAGE_VERSION")) {
687 pcaps->GLSL_Version =
688 root[
"GL_SHADING_LANGUAGE_VERSION"].get<std::string>();
690 wxLogMessage(
"GL_SHADING_LANGUAGE_VERSION not found.");
693 if (root.contains(
"GL_USABLE")) {
694 if (!root[
"GL_USABLE"].get<bool>()) {
695 wxLogMessage(
"OpenGL test utility reports that OpenGL is not usable.");
698 }
else if (root.contains(
"\"GL_USABLE\"")) {
699 if (!root[
"\"GL_USABLE\""].get<bool>()) {
700 wxLogMessage(
"OpenGL test utility reports that OpenGL is not usable.");
704 wxLogMessage(
"GL_USABLE not found.");
707 pcaps->dGLSL_Version = 0;
708 pcaps->dGLSL_Version = ::atof(pcaps->GLSL_Version.c_str());
709 if (pcaps->dGLSL_Version < 1.2) {
711 msg.Printf(
"GLCaps Probe: OpenGL-> GLSL Version reported: ");
712 msg += wxString(pcaps->GLSL_Version.c_str());
713 msg +=
"\n OpenGL disabled due to insufficient OpenGL capabilities";
715 pcaps->bCanDoGLSL =
false;
718 pcaps->bCanDoGLSL =
true;
719 if (HasGLExt(root,
"GL_ARB_texture_non_power_of_two")) {
720 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
721 }
else if (HasGLExt(root,
"GL_OES_texture_npot")) {
722 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
723 }
else if (HasGLExt(root,
"GL_ARB_texture_rectangle")) {
724 pcaps->TextureRectangleFormat = GL_TEXTURE_RECTANGLE_ARB;
727 pcaps->bOldIntel =
false;
729 pcaps->bCanDoFBO = HasGLExt(root,
"GL_EXT_framebuffer_object");
730 if (!pcaps->TextureRectangleFormat) {
731 pcaps->bCanDoFBO =
false;
734 pcaps->bCanDoVBO = HasGLExt(root,
"GL_ARB_vertex_buffer_object");
738 top_frame::Get()->Show();
743 top_frame::Get()->Show();
747 wxGLContext *pctx =
new wxGLContext(tcanvas);
748 tcanvas->SetCurrent(*pctx);
752 char *str = (
char *)glGetString(GL_RENDERER);
754 wxLogMessage(
"GL_RENDERER not found.");
759 pcaps->Renderer = std::string(str);
761 char *stv = (
char *)glGetString(GL_VERSION);
763 wxLogMessage(
"GL_VERSION not found");
768 pcaps->Version = std::string(stv);
770 char *stsv = (
char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
772 wxLogMessage(
"GL_SHADING_LANGUAGE_VERSION not found");
777 pcaps->GLSL_Version = std::string(stsv);
779 pcaps->dGLSL_Version = 0;
780 pcaps->dGLSL_Version = ::atof(pcaps->GLSL_Version.c_str());
782 if (pcaps->dGLSL_Version < 1.2) {
784 msg.Printf(
"GLCaps Probe: OpenGL-> GLSL Version reported: ");
785 msg += wxString(pcaps->GLSL_Version.c_str());
786 msg +=
"\n OpenGL disabled due to insufficient OpenGL capabilities";
788 pcaps->bCanDoGLSL =
false;
794 pcaps->bCanDoGLSL =
true;
796 if (QueryExtension(
"GL_ARB_texture_non_power_of_two"))
797 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
798 else if (QueryExtension(
"GL_OES_texture_npot"))
799 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
800 else if (QueryExtension(
"GL_ARB_texture_rectangle"))
801 pcaps->TextureRectangleFormat = GL_TEXTURE_RECTANGLE_ARB;
803 pcaps->bOldIntel =
false;
806 pcaps->bCanDoVBO =
true;
808#if defined(__WXMSW__) || defined(__WXOSX__)
809 if (pcaps->bOldIntel) pcaps->bCanDoVBO =
false;
813 pcaps->bCanDoVBO =
false;
817 pcaps->bCanDoFBO =
true;
821 if (!pcaps->TextureRectangleFormat) pcaps->bCanDoFBO =
false;
824 if (!QueryExtension(
"GL_EXT_framebuffer_object")) pcaps->bCanDoFBO =
false;
834bool OCPNPlatform::IsGLCapable() {
843 if (g_bdisable_opengl)
return false;
845 wxLogMessage(
"Starting OpenGL test...");
846 wxLog::FlushActive();
850 bool bcaps = BuildGLCaps(GL_Caps);
852 wxLogMessage(
"OpenGL test complete.");
854 wxLogMessage(
"BuildGLCaps fails.");
855 wxLog::FlushActive();
863 if (!GL_Caps->bCanDoGLSL) {
869 if (!GL_Caps->bCanDoFBO) {
874 wxLogMessage(
"OpenGL determined CAPABLE.");
875 wxLog::FlushActive();
877 g_bdisable_opengl =
false;
890void OCPNPlatform::SetLocaleSearchPrefixes() {
893#if defined(__WINDOWS__)
896 wxString locale_location = GetSharedDataDir();
897 locale_location +=
"share\\locale";
898 wxLocale::AddCatalogLookupPathPrefix(locale_location);
899 wxString imsg =
"Adding catalog lookup path: ";
900 imsg += locale_location;
905 usrShare.RemoveLastDir();
906 locale_location = usrShare.GetFullPath() + (
"share\\locale");
907 wxLocale::AddCatalogLookupPathPrefix(locale_location);
908 imsg =
"Adding catalog lookup path: ";
909 imsg += locale_location;
912#elif defined(__ANDROID__)
914 wxString locale_location = GetSharedDataDir() +
"locale";
915 wxLocale::AddCatalogLookupPathPrefix(locale_location);
917#elif defined(__UNIX__) && !defined(__WINE__)
922 wxString locale_location;
923 if (!wxGetEnv(
"OPENCPN_PREFIX", &locale_location)) {
924 locale_location =
"/usr/local";
932 location.AssignDir(locale_location);
933 location.AppendDir(
"share");
934 location.SetName(
"locale");
935 locale_location = location.GetFullPath();
936 wxLocale::AddCatalogLookupPathPrefix(locale_location);
940 wxString managed_locale_location(dir +
"/locale");
941 wxLocale::AddCatalogLookupPathPrefix(managed_locale_location);
947 "/Library/Application Support/OpenCPN/Contents/Resources";
948 wxString Mac_managed_locale_location(macDir);
949 wxLocale::AddCatalogLookupPathPrefix(Mac_managed_locale_location);
955wxString OCPNPlatform::GetDefaultSystemLocale() {
956 wxLogMessage(
"Getting DefaultSystemLocale...");
958 wxString retval =
"en_US";
962 const wxLanguageInfo *languageInfo =
963 wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
964 if (languageInfo) retval = languageInfo->CanonicalName;
966#if defined(__WXMSW__)
967 LANGID lang_id = GetUserDefaultUILanguage();
970 const wxLanguageInfo *languageInfoW = 0;
971 if (0 != GetLocaleInfo(MAKELCID(lang_id, SORT_DEFAULT), LOCALE_SENGLANGUAGE,
973 wxString lstring = wxString(lngcp);
975 languageInfoW = wxLocale::FindLanguageInfo(lngcp);
977 wxLogMessage(
"Found LanguageInfo for: " + lstring);
979 wxLogMessage(
"Could not find LanguageInfo for: " + lstring);
981 wxLogMessage(
"Could not get LocaleInfo, using wxLANGUAGE_DEFAULT");
982 languageInfoW = wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
985 if (languageInfoW) retval = languageInfoW->CanonicalName;
988#if defined(__ANDROID__)
989 retval = androidGetAndroidSystemLocale();
997#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
998wxString OCPNPlatform::GetAdjustedAppLocale() {
999 wxString adjLocale = g_locale;
1004#if defined(__WXMSW__)
1005 if (g_bFirstRun || wxIsEmpty(adjLocale)) {
1006 wxRegKey RegKey(wxString(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN"));
1007 if (RegKey.Exists()) {
1009 "Retrieving initial language selection from Windows Registry");
1010 RegKey.QueryValue(wxString(
"InstallerLanguage"), adjLocale);
1013 if (wxIsEmpty(adjLocale)) {
1014 if (g_localeOverride.Length())
1015 adjLocale = g_localeOverride;
1017 adjLocale = GetDefaultSystemLocale();
1020#if defined(__ANDROID__)
1021 if (g_localeOverride.Length())
1022 adjLocale = g_localeOverride;
1024 adjLocale = GetDefaultSystemLocale();
1030wxString OCPNPlatform::ChangeLocale(wxString &newLocaleID,
1031 wxLocale *presentLocale,
1032 wxLocale **newLocale) {
1033 wxString return_val;
1035 wxString imsg =
"ChangeLocale: Language load for: ";
1036 imsg += newLocaleID;
1040 delete (wxLocale *)presentLocale;
1042 wxLocale *locale =
new wxLocale;
1043 if (isFlatpacked()) {
1044 std::string path(getenv(
"HOME"));
1045 path +=
"/.var/app/org.opencpn.OpenCPN/data/locale";
1046 locale->AddCatalogLookupPathPrefix(path);
1047 wxLogMessage(
"Using flatpak locales at %s", path.c_str());
1049 wxString loc_lang_canonical;
1051 const wxLanguageInfo *pli = wxLocale::FindLanguageInfo(newLocaleID);
1052 bool b_initok =
false;
1055 locale->Init(pli->Language, 1);
1059 if (!locale->IsOk()) {
1060 wxString imsg =
"ChangeLocale: could not initialize: ";
1061 imsg += newLocaleID;
1065 locale =
new wxLocale;
1066 locale->Init(pli->Language, 0);
1068 loc_lang_canonical = pli->CanonicalName;
1070 b_initok = locale->IsOk();
1077 wxString imsg =
"ChangeLocale: Fall back to en_US";
1081 locale =
new wxLocale;
1082 locale->Init(wxLANGUAGE_ENGLISH_US, 0);
1083 loc_lang_canonical =
1084 wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US)->CanonicalName;
1088 wxString imsg =
"ChangeLocale: Locale Init OK for: ";
1089 imsg += loc_lang_canonical;
1103 wxString emsg =
"ERROR Loading translation catalog for: ";
1107 wxString imsg =
"Loaded translation catalog for: ";
1114 wxLogMessage(
"Loading catalog for opencpn core.");
1115 locale->AddCatalog(
"opencpn");
1117 return_val = locale->GetCanonicalName();
1120 if (return_val != GetDefaultSystemLocale())
1121 g_localeOverride = return_val;
1123 g_localeOverride =
"";
1126 *newLocale = locale;
1129 setlocale(LC_NUMERIC,
"C");
1140void OCPNPlatform::SetDefaultOptions() {
1142 g_bShowOutlines =
true;
1148 g_MarkLost_Mins = 8;
1149 g_bRemoveLost =
true;
1150 g_RemoveLost_Mins = 10;
1153 g_bSyncCogPredictors =
false;
1154 g_bHideMoored =
false;
1155 g_ShowMoored_Kts = 0.2;
1156 g_SOGminCOG_kts = 0.2;
1157 g_bTrackDaily =
false;
1159 g_bFullScreenQuilt =
true;
1160 g_bQuiltEnable =
true;
1161 g_bskew_comp =
false;
1162 g_bShowAreaNotices =
false;
1163 g_bDrawAISSize =
false;
1164 g_bDrawAISRealtime =
false;
1165 g_AIS_RealtPred_Kts = 0.7;
1166 g_bShowAISName =
false;
1167 g_nTrackPrecision = 2;
1168 g_bPreserveScaleOnX =
true;
1172 g_n_ownship_min_mm = 8;
1173 g_bShowMuiZoomButtons =
true;
1174 g_bresponsive =
false;
1178 pConfig->SetPath(
"/Settings/GlobalState");
1179 pConfig->Write(
"bShowS57Text",
true);
1180 pConfig->Write(
"bShowS57ImportantTextOnly",
false);
1181 pConfig->Write(
"nDisplayCategory", (
int)(_DisCat)OTHER);
1182 pConfig->Write(
"nSymbolStyle", (
int)(_LUPname)PAPER_CHART);
1183 pConfig->Write(
"nBoundaryStyle", (
int)(_LUPname)PLAIN_BOUNDARIES);
1185 pConfig->Write(
"bShowSoundg",
true);
1186 pConfig->Write(
"bShowMeta",
false);
1187 pConfig->Write(
"bUseSCAMIN",
true);
1188 pConfig->Write(
"bShowAtonText",
false);
1189 pConfig->Write(
"bShowLightDescription",
false);
1190 pConfig->Write(
"bExtendLightSectors",
true);
1191 pConfig->Write(
"bDeClutterText",
true);
1192 pConfig->Write(
"bShowNationalText",
true);
1194 pConfig->Write(
"S52_MAR_SAFETY_CONTOUR", 3);
1195 pConfig->Write(
"S52_MAR_SHALLOW_CONTOUR", 2);
1196 pConfig->Write(
"S52_MAR_DEEP_CONTOUR", 6);
1197 pConfig->Write(
"S52_MAR_TWO_SHADES", 0);
1198 pConfig->Write(
"S52_DEPTH_UNIT_SHOW", 1);
1200 pConfig->Write(
"ZoomDetailFactorVector", 3);
1202 pConfig->Write(
"nColorScheme", 1);
1206 g_bEnableZoomToCursor =
true;
1208 g_bShowMenuBar =
true;
1213 g_bShowMenuBar =
false;
1216 pConfig->SetPath(
"/PlugIns/chartdldr_pi.dll");
1217 pConfig->Write(
"bEnabled",
true);
1219 pConfig->SetPath(
"/PlugIns/wmm_pi.dll");
1220 pConfig->Write(
"bEnabled",
true);
1222 pConfig->SetPath(
"/Settings/WMM");
1223 pConfig->Write(
"ShowIcon",
true);
1224 pConfig->Write(
"ShowLiveIcon",
true);
1231 pConfig->SetPath(
"/PlugIns/libchartdldr_pi.dylib");
1232 pConfig->Write(
"bEnabled",
true);
1234 pConfig->SetPath(
"/PlugIns/libwmm_pi.dylib");
1235 pConfig->Write(
"bEnabled",
true);
1237 pConfig->SetPath(
"/Settings/WMM");
1238 pConfig->Write(
"ShowIcon",
true);
1239 pConfig->Write(
"ShowLiveIcon",
true);
1246 pConfig->SetPath(
"/PlugIns/libchartdldr_pi.so");
1247 pConfig->Write(
"bEnabled",
true);
1249 pConfig->SetPath(
"/PlugIns/libwmm_pi.so");
1250 pConfig->Write(
"bEnabled",
true);
1252 pConfig->SetPath(
"/Settings/WMM");
1253 pConfig->Write(
"ShowIcon",
true);
1254 pConfig->Write(
"ShowLiveIcon",
true);
1262 g_GLOptions.m_bTextureCompression = 1;
1263 g_GLOptions.m_bTextureCompressionCaching = 1;
1266 qDebug() <<
"SetDefaultOptions";
1269 g_bresponsive =
true;
1270 g_default_font_size = 18;
1273 g_bShowStatusBar =
true;
1274 g_cm93_zoom_factor = 0;
1275 g_oz_vector_scale =
false;
1276 g_fog_overzoom =
false;
1279 g_bShowMuiZoomButtons =
true;
1281 g_GUIScaleFactor = 0;
1282 g_ChartNotRenderScaleFactor = 2.0;
1286 g_toolbarConfig =
"X.....XX.......XX.XXXXXXXXXXX";
1287 g_bPermanentMOBIcon =
false;
1289 wxString sGPS =
"2;3;;0;0;;0;1;0;0;;0;;1;0;0;0;0";
1292 new_params->bEnabled =
true;
1293 TheConnectionParams().push_back(new_params);
1300 pConfig->SetPath(
"/PlugIns/libchartdldr_pi.so");
1301 pConfig->Write(
"bEnabled",
true);
1303 pConfig->SetPath(
"/PlugIns/libwmm_pi.so");
1304 pConfig->Write(
"bEnabled",
true);
1306 pConfig->SetPath(
"/Settings/WMM");
1307 pConfig->Write(
"ShowIcon",
true);
1308 pConfig->Write(
"ShowLiveIcon",
true);
1310 pConfig->SetPath(
"/PlugIns/libgrib_pi.so");
1311 pConfig->Write(
"bEnabled",
true);
1313 pConfig->SetPath(
"/PlugIns/libdashboard_pi.so");
1314 pConfig->Write(
"bEnabled",
true);
1316 pConfig->SetPath(
"/PlugIns/GRIB");
1317 pConfig->Write(
"GRIBCtrlBarPosX", 100);
1318 pConfig->Write(
"GRIBCtrlBarPosY", 0);
1320 pConfig->SetPath(
"/Settings/GRIB");
1321 pConfig->Write(
"CursorDataShown", 0);
1325 pConfig->SetPath(
"/PlugIns/liboesenc_pi.so");
1326 pConfig->Write(
"bEnabled",
true);
1328 pConfig->SetPath(
"/Settings/QTFonts");
1331 wxString str =
"en_US-b25a3899";
1332 wxString pval =
"StatusBar:Roboto,26,-1,5,75,0,0,0,0,0:rgb(0, 0, 0)";
1337 str =
"en_US-9c3b3a0d";
1338 pval =
"DialogStatusBar:Roboto,18,-1,5,50,0,0,0,0,0:rgb(0, 0, 0)";
1343 pConfig->SetPath(
"/Settings/Others");
1344 pConfig->Write(
"TrackLineColour",
"#C545C3");
1345 g_colourTrackLineColour.Set(197, 69, 195);
1347 qDebug() <<
"SetDefaultOptions.Config";
1358void OCPNPlatform::SetUpgradeOptions(wxString vNew, wxString vOld) {
1361 qDebug() <<
"Upgrade check"
1362 <<
"from: " << vOld.mb_str() <<
" to: " << vNew.mb_str();
1364 if (androidGetVersionCode() > g_AndroidVersionCode) {
1365 qDebug() <<
"Upgrade detected"
1366 <<
"from VC: " << g_AndroidVersionCode
1367 <<
" to VC: " << androidGetVersionCode();
1371 pConfig->SetPath(
"/Settings/GlobalState");
1372 pConfig->Write(
"bShowS57Text",
true);
1375 g_ChartNotRenderScaleFactor = 2.0;
1376 g_n_ownship_min_mm = 8;
1377 g_toolbarConfig =
"X.....XX.......XX.XXXXXXXXXXX";
1386 g_bShowMuiZoomButtons =
true;
1390 pInit_Chart_Dir->Clear();
1394 pConfig->SetPath(
"/Settings/WMM");
1395 pConfig->Write(
"ShowIcon",
true);
1396 pConfig->Write(
"ShowLiveIcon",
true);
1398 pConfig->SetPath(
"/Canvas/CanvasConfig1");
1399 pConfig->Write(
"canvasENCShowVisibleSectorLights", 0);
1409 AndroidRemoveSystemFile(
1410 "/data/user/0/org.opencpn.opencpn/manPlug/libchartscale_pi.so");
1414 g_colourTrackLineColour.Set(197, 69, 195);
1418 if (!vOld.IsSameAs(vNew)) {
1424 wxChar sep = wxFileName::GetPathSeparator();
1425 if (UserIconPath.Last() != sep) UserIconPath.Append(sep);
1426 UserIconPath.Append(
"UserIcons");
1428 if (!::wxDirExists(UserIconPath)) {
1429 ::wxMkdir(UserIconPath);
1434 if (LayersPath.Last() != sep) LayersPath.Append(sep);
1435 LayersPath.Append(
"layers");
1437 if (!::wxDirExists(LayersPath)) {
1438 ::wxMkdir(LayersPath);
1444 g_CmdSoundString = wxString(OCPN_SOUND_CMD);
1445 pConfig->SetPath(
"/Settings");
1446 pConfig->Write(
"CmdSoundString", g_CmdSoundString);
1450 g_bAIS_GCPA_Alert_Audio =
true;
1451 g_bAIS_SART_Alert_Audio =
true;
1452 g_bAIS_DSC_Alert_Audio =
true;
1455 g_maintoolbar_x = -1;
1459 std::vector<std::string> TCDS_temp;
1460 for (
unsigned int i = 0; i < TideCurrentDataSet.size(); i++)
1461 TCDS_temp.push_back(TideCurrentDataSet[i]);
1463 TideCurrentDataSet.clear();
1464 for (
unsigned int i = 0; i < TCDS_temp.size(); i++) {
1465 wxString tide = TCDS_temp[i];
1466 wxFileName ft(tide);
1467 if (ft.FileExists()) TideCurrentDataSet.push_back(TCDS_temp[i]);
1474 g_compatOsVersion =
"";
1475 pConfig->SetPath(
"/Settings");
1476 pConfig->Write(
"CompatOS", g_compatOS);
1477 pConfig->Write(
"CompatOsVersion", g_compatOsVersion);
1481int OCPNPlatform::platformApplyPrivateSettingsString(wxString settings,
1482 ArrayOfCDI *pDirArray) {
1485 ret_val = androidApplySettingsString(settings, pDirArray);
1491void OCPNPlatform::applyExpertMode(
bool mode) {
1495 g_bBasicMenus = !mode;
1503static wxString ExpandPaths(wxString paths,
OCPNPlatform *platform);
1505int OCPNPlatform::DoFileSelectorDialog(wxWindow *parent, wxString *file_spec,
1506 wxString Title, wxString initDir,
1507 wxString suggestedName,
1508 wxString wildcard) {
1510 int result = wxID_CANCEL;
1514 wxString idir = initDir;
1515 if (initDir.StartsWith(
1519 result = androidFileChooser(&file, idir, Title, suggestedName, wildcard);
1520 if (file_spec) *file_spec = file;
1522 long flag = wxFD_DEFAULT_STYLE;
1523 if (suggestedName.Length()) {
1527 wxString mask = wildcard;
1528 if (wxNOT_FOUND != mask.Find(
"gpx")) mask.Prepend(
"GPX files (*.gpx)|");
1530 wxFileDialog *psaveDialog =
1531 new wxFileDialog(parent, Title, initDir, suggestedName, mask, flag);
1539 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1542 result = psaveDialog->ShowModal();
1545 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1548 if (file_spec) *file_spec = psaveDialog->GetPath();
1556int OCPNPlatform::DoDirSelectorDialog(wxWindow *parent, wxString *file_spec,
1557 wxString Title, wxString initDir,
1560 int result = wxID_CANCEL;
1564 wxString idir = initDir;
1565 if (initDir.StartsWith(
1569 result = androidFileChooser(&dir, idir, Title,
"",
"",
true,
1571 if (file_spec) *file_spec = dir;
1573 wxDirDialog *dirSelector =
new wxDirDialog(
1574 parent, Title, initDir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1577 dirSelector->SetFont(*qFont);
1584 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1587 result = dirSelector->ShowModal();
1590 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1593 if (result == wxID_CANCEL) {
1596 *file_spec = dirSelector->GetPath();
1606MyConfig *OCPNPlatform::GetConfigObject() {
1609 result =
new MyConfig(GetConfigFileName());
1618bool OCPNPlatform::hasInternalGPS(wxString profile) {
1620 bool t = androidDeviceHasGPS();
1634void OCPNPlatform::ShowBusySpinner() { AbstractPlatform::ShowBusySpinner(); }
1636void OCPNPlatform::HideBusySpinner() { AbstractPlatform::HideBusySpinner(); }
1638double OCPNPlatform::GetDisplayDensityFactor() {
1640 return getAndroidDisplayDensity();
1646long OCPNPlatform::GetDefaultToolbarOrientation() {
1648 return wxTB_VERTICAL;
1650 return wxTB_VERTICAL;
1654int OCPNPlatform::GetStatusBarFieldCount() {
1660 wxFont *templateFont = FontMgr::Get().
GetFont(_(
"StatusBar"), 0);
1661 dc.SetFont(*templateFont);
1664 dc.GetTextExtent(
"WWWWWW", &width, NULL, NULL, NULL, templateFont);
1665 double font_size_pix = (double)width / 6.0;
1669 double nChars = dispSize.x / font_size_pix;
1679 return kStatFieldCount;
1683double OCPNPlatform::getFontPointsperPixel() {
1684 double pt_per_pixel = 1.0;
1694 if (m_pt_per_pixel == 0) {
1699 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
1700 wxString(
""), wxFONTENCODING_SYSTEM);
1704 dc.GetTextExtent(
"H", &width, &height, NULL, NULL, f);
1706 if (height > 0) m_pt_per_pixel = 12.0 / (double)height;
1708 if (m_pt_per_pixel > 0) pt_per_pixel = m_pt_per_pixel;
1711 return pt_per_pixel;
1716 return getAndroidDisplayDimensions();
1733 ret = GetAndroidDisplaySize();
1739double OCPNPlatform::GetDisplayAreaCM2() {
1744 ratio = (double)sz.x / (
double)sz.y;
1746 ratio = (double)sz.y / (
double)sz.x;
1748 double area = size1 * (size1 * ratio) / 100.;
1754 if (monitor < m_displaySizeMMOverride.size()) {
1755 m_displaySizeMMOverride[monitor] = sizeMM;
1759double OCPNPlatform::GetDisplayDPmm() {
1761 return getAndroidDPmm();
1768unsigned int OCPNPlatform::GetSelectRadiusPix() {
1769 return GetDisplayDPmm() *
1770 (g_btouch ? g_selection_radius_touch_mm : g_selection_radius_mm);
1773bool OCPNPlatform::GetFullscreen() {
1776 bret = androidGetFullscreen();
1784bool OCPNPlatform::SetFullscreen(
bool bFull) {
1787 bret = androidSetFullscreen(bFull);
1794void OCPNPlatform::PositionAISAlert(wxWindow *alert_window) {
1797 alert_window->SetSize(g_ais_alert_dialog_x, g_ais_alert_dialog_y,
1798 g_ais_alert_dialog_sx, g_ais_alert_dialog_sy);
1802 alert_window->Centre();
1808wxDirDialog *OCPNPlatform::AdjustDirDialogFont(wxWindow *container,
1810 wxDirDialog *ret_dlg = dlg;
1814 dlg->SetSize(container->GetSize());
1817 wxSize sds = dlg->GetSize();
1818 wxSize ss = container->GetSize();
1823 wxString msg = dlg->GetMessage();
1824 wxString default_dir = dlg->GetPath();
1828 ret_dlg =
new wxDirDialog(NULL, msg, default_dir,
1829 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1832 wxFont *smallFont =
new wxFont(*dialogFont);
1833 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1835 ret_dlg->SetFont(*smallFont);
1837 ret_dlg->SetSize(container->GetSize());
1845wxFileDialog *OCPNPlatform::AdjustFileDialogFont(wxWindow *container,
1846 wxFileDialog *dlg) {
1847 wxFileDialog *ret_dlg = dlg;
1851 dlg->SetSize(container->GetSize());
1854 wxSize sds = dlg->GetSize();
1855 wxSize ss = container->GetSize();
1860 wxString msg = dlg->GetMessage();
1861 wxString default_dir = dlg->GetDirectory();
1862 wxString default_file = dlg->GetFilename();
1863 wxString wildcard = dlg->GetWildcard();
1867 ret_dlg =
new wxFileDialog(NULL, msg, default_dir, default_file, wildcard,
1871 wxFont *smallFont =
new wxFont(*dialogFont);
1872 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1874 ret_dlg->SetFont(*smallFont);
1876 ret_dlg->SetSize(container->GetSize());
1884double OCPNPlatform::GetToolbarScaleFactor(
int GUIScaleFactor) {
1892 wxSize style_tool_size(32, 32);
1894 if (g_StyleManager) {
1896 if (style) style_tool_size = style->GetToolSize();
1898 double tool_size = style_tool_size.x;
1904 double premult = 1.0;
1907 double target_size = 9.0;
1908 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
1909 premult = target_size / basic_tool_size_mm;
1912 premult = wxMax(45 * getAndroidDisplayDensity(), 45) /
1918 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
1922 rv = premult * postmult;
1923 rv = wxMin(rv, getAndroidDisplayDensity() *
1927 double premult = 1.0;
1929 if (g_bresponsive) {
1932 wxSize style_tool_size = style->GetToolSize();
1933 double tool_size = style_tool_size.x;
1937 double target_size = 9.0;
1939 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
1940 premult = target_size / basic_tool_size_mm;
1944 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
1946 rv = premult * postmult;
1947 rv = wxMin(rv, 3.0);
1948 rv = wxMax(rv, 0.5);
1957double OCPNPlatform::GetCompassScaleFactor(
int GUIScaleFactor) {
1964 if (g_bresponsive) {
1967 wxSize style_tool_size = style->GetToolSize();
1968 double compass_size = style_tool_size.x;
1974 double premult = wxMax(28 * getAndroidDisplayDensity(), 50) / compass_size;
1977 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
1980 rv = premult * postmult;
1981 rv = wxMin(rv, getAndroidDisplayDensity() *
1986 double premult = 1.0;
1988 if (g_bresponsive) {
1990 wxSize style_tool_size = style->GetToolSize();
1991 double compass_size = style_tool_size.x;
1994 double target_size = 6.0;
1996 double basic_tool_size_mm = compass_size / GetDisplayDPmm();
1997 premult = target_size / basic_tool_size_mm;
2000 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
2002 rv = premult * postmult;
2004 rv = wxMin(rv, 3.0);
2005 rv = wxMax(rv, 0.5);
2007#if defined(__WXOSX__) || defined(__WXGTK3__)
2010 if (top_frame::Get()) rv *= top_frame::Get()->GetContentScaleFactor();
2020float OCPNPlatform::GetChartScaleFactorExp(
float scale_linear) {
2021 double factor = 1.0;
2023 factor = exp(scale_linear * (log(3.0) / 5.0));
2028 factor = exp(scale_linear * (0.693 / 5.0));
2032 factor = wxMax(factor, .5);
2033 factor = wxMin(factor, 6.);
2038float OCPNPlatform::GetMarkScaleFactorExp(
float scale_linear) {
2039 if (scale_linear <= 0)
2040 return GetChartScaleFactorExp(scale_linear);
2042 return GetChartScaleFactorExp(scale_linear - 1);
2059bool OCPNPlatform::hasInternalBT(wxString profile) {
2061 bool t = androidDeviceHasBlueTooth();
2070bool OCPNPlatform::startBluetoothScan() {
2072 return androidStartBluetoothScan();
2079bool OCPNPlatform::stopBluetoothScan() {
2081 return androidStopBluetoothScan();
2088wxArrayString OCPNPlatform::getBluetoothScanResults() {
2089 wxArrayString ret_val;
2091 return androidGetBluetoothScanResults();
2094 ret_val.Add(
"line 1");
2095 ret_val.Add(
"line 2");
2096 ret_val.Add(
"line 3");
2106bool OCPNPlatform::AllowAlertDialog(
const wxString &class_name) {
2111 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
2113 wxWindow *win = node->GetData();
2114 if (win->IsShown()) nTLW++;
2116 node = node->GetNext();
2130void OCPNPlatform::setChartTypeMaskSel(
int mask, wxString &indicator) {
2132 return androidSetChartTypeMaskSel(mask, indicator);
2137QString g_qtStyleSheet;
2139bool LoadQtStyleSheet(wxString &sheet_file) {
2140 if (wxFileExists(sheet_file)) {
2143 QString file(sheet_file.c_str());
2145 File.open(QFile::ReadOnly);
2146 g_qtStyleSheet = QLatin1String(File.readAll());
2156QString getQtStyleSheet() {
return g_qtStyleSheet; }
2160bool OCPNPlatform::isPlatformCapable(
int flag) {
2164 if (flag == PLATFORM_CAP_PLUGINS) {
2166 wxString tsdk(android_plat_spc.msdk);
2167 if (tsdk.ToLong(&platver)) {
2168 if (platver >= 11)
return true;
2170 }
else if (flag == PLATFORM_CAP_FASTPAN) {
2172 wxString tsdk(android_plat_spc.msdk);
2173 if (tsdk.ToLong(&platver)) {
2174 if (platver >= 14)
return true;
2182void OCPNPlatform::platformLaunchDefaultBrowser(wxString URL) {
2184 androidLaunchBrowser(URL);
2186 ::wxLaunchDefaultBrowser(URL);
2196EVT_PAINT(OCPNColourPickerCtrl::OnPaint)
2205 const wxColour &initial,
2207 const wxSize &size,
long style,
2208 const wxValidator &validator,
2209 const wxString &name) {
2210 Create(parent,
id, initial, pos, size, style, validator, name);
2213bool OCPNColourPickerCtrl::Create(wxWindow *parent, wxWindowID
id,
2214 const wxColour &col,
const wxPoint &pos,
2215 const wxSize &size,
long style,
2216 const wxValidator &validator,
2217 const wxString &name) {
2218 m_bitmap = wxBitmap(60, 13);
2221 if (!wxBitmapButton::Create(parent,
id, m_bitmap, pos, size,
2222 style | wxBU_AUTODRAW, validator, name)) {
2223 wxFAIL_MSG(
"OCPNColourPickerCtrl creation failed");
2228 Connect(GetId(), wxEVT_BUTTON,
2229 wxCommandEventHandler(OCPNColourPickerCtrl::OnButtonClick), NULL,
2239void OCPNColourPickerCtrl::InitColourData() {
2241 ms_data.SetChooseFull(
true);
2242 unsigned char grey = 0;
2243 for (
int i = 0; i < 16; i++, grey += 16)
2246 wxColour colour(grey, grey, grey);
2247 ms_data.SetCustomColour(i, colour);
2252void OCPNColourPickerCtrl::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
2254 unsigned int cco = 0;
2257 cco |= m_colour.Red();
2259 cco |= m_colour.Green();
2261 cco |= m_colour.Blue();
2262 unsigned int cc = androidColorPicker(cco);
2265 unsigned char blue = (
unsigned char)cc % 256;
2266 unsigned char green = (
unsigned char)(cc >> 8) % 256;
2268 unsigned char red = (
unsigned char)(cc >> 16) % 256;
2269 cnew.Set(red, green, blue);
2275 ms_data.SetColour(m_colour);
2278 wxColourDialog dlg(
this, &ms_data);
2279 if (dlg.ShowModal() == wxID_OK) {
2280 ms_data = dlg.GetColourData();
2281 SetColour(ms_data.GetColour());
2286void OCPNColourPickerCtrl::UpdateColour() {
2288 SetBitmapLabel(wxBitmap());
2291 wxMemoryDC dc(m_bitmap);
2292 dc.SetPen(*wxTRANSPARENT_PEN);
2293 dc.SetBrush(wxBrush(m_colour));
2294 dc.DrawRectangle(0, 0, m_bitmap.GetWidth(), m_bitmap.GetHeight());
2296 dc.SelectObject(wxNullBitmap);
2297 SetBitmapLabel(m_bitmap);
2300void OCPNColourPickerCtrl::SetColour(wxColour &c) {
2302 m_bitmap = wxBitmap(GetSize().x - 20, GetSize().y - 20);
2306wxColour OCPNColourPickerCtrl::GetColour() {
return m_colour; }
2308wxSize OCPNColourPickerCtrl::DoGetBestSize()
const {
2309 wxSize sz(wxBitmapButton::DoGetBestSize());
2316 if (HasFlag(wxCLRP_SHOW_LABEL))
return sz;
2324void OCPNColourPickerCtrl::OnPaint(wxPaintEvent &event) {
2327 int offset_x = (GetSize().x - m_bitmap.GetWidth()) / 2;
2328 int offset_y = (GetSize().y - m_bitmap.GetHeight()) / 2;
2330 dc.SetPen(*wxTRANSPARENT_PEN);
2331 dc.SetBrush(wxBrush(m_colour));
2332 dc.DrawRectangle(offset_x, offset_y, m_bitmap.GetWidth(),
2333 m_bitmap.GetHeight());
Select * pSelectAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void LoadFontNative(wxString *pConfigString, wxString *pNativeDesc)
Loads font settings from a string descriptor.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
std::string Homedir() const
home directory, convenience stuff.
std::string UserDatadir()
The single, user-writable common parent for plugin data directories, typically ending in 'plugins'.
static PluginPaths * GetInstance()
Return the singleton instance.
Global variables reflecting command line options and arguments.
bool g_bsmoothpanzoom
Controls how the chart panning and zooming smoothing is done during user interactions.
wxString g_default_font_facename
Default font size for user interface elements such as menus, dialogs, etc.
bool g_bRollover
enable/disable mouse rollover GUI effects
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
Global variables stored in configuration file.
Dump debug info on crash.
Extern C linked utilities.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
void EnumerateMonitors()
Enumerate the monitors connected to the system.
bool g_running
Android only.
OpenGL chart rendering canvas.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
Enhanced logging interface on top of wx/log.h.
MacOS hardware probing functions.
void cache_clear()
Remove all files in cache:
MyConfig * pConfig
Global instance.
Miscellaneous utilities, many of which string related.
options * g_options
Global instance.
Downloaded plugins cache.
Plugin installation and data paths support.
wxString GetWritableDocumentsDir()
Returns the platform-specific default documents directory.
Select * pSelect
Global instance.
Select * pSelectTC
Global instance.
Selected route, segment, waypoint, etc.
Abstract gFrame/MyFrame interface.