54#include <wx/apptrait.h>
55#include <wx/stdpaths.h>
56#include <wx/filename.h>
57#include <wx/tokenzr.h>
58#include <wx/textfile.h>
59#include <wx/jsonval.h>
60#include <wx/jsonreader.h>
66#include "model/base_platform.h"
69#include "model/conn_params.h"
70#include "model/cutil.h"
73#include "model/plugin_cache.h"
75#include "model/select.h"
83#include "ocpn_frame.h"
84#include "OCPNPlatform.h"
87#include "snd_config.h"
91#include "androidUTIL.h"
95#include "glChartCanvas.h"
99#ifdef OCPN_USE_CRASHREPORT
111#include "model/macutils.h"
114#if (defined(OCPN_GHC_FILESYSTEM) || \
115 (defined(__clang_major__) && (__clang_major__ < 15)))
117#include <ghc/filesystem.hpp>
118namespace fs = ghc::filesystem;
122namespace fs = std::filesystem;
130void appendOSDirSlash(wxString *pString);
133struct sigaction sa_all;
134struct sigaction sa_all_old;
135extern sigjmp_buf env;
139extern bool g_bFirstRun;
140extern bool g_bUpgradeInProcess;
149extern bool g_bshowToolbar;
150extern bool g_bexpert;
151extern bool g_bBasicMenus;
152extern bool g_bUIexpert;
154extern bool g_bshowToolbar;
155extern bool g_bBasicMenus;
157extern bool g_bShowOutlines;
158extern int g_nAWDefault;
160extern bool g_bPermanentMOBIcon;
161extern float g_toolbar_scalefactor;
165extern wxString *pInit_Chart_Dir;
168extern bool g_config_display_size_manual;
170extern bool g_bFullScreenQuilt;
171extern bool g_bQuiltEnable;
172extern bool g_bskew_comp;
174extern bool g_bopengl;
175extern bool g_bresponsive;
176extern bool g_bShowStatusBar;
177extern int g_cm93_zoom_factor;
178extern int g_GUIScaleFactor;
179extern bool g_fog_overzoom;
180extern bool g_oz_vector_scale;
181extern wxString g_toolbarConfig;
182extern bool g_bPreserveScaleOnX;
183extern bool g_running;
184extern bool g_bEnableZoomToCursor;
186extern bool g_bShowMenuBar;
193extern int g_default_font_size;
194extern wxString g_default_font_facename;
196extern double g_ChartNotRenderScaleFactor;
199#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
200extern wxLocale *plocale_def_lang;
202extern wxString g_locale;
203extern wxString g_localeOverride;
204extern wxArrayString g_locale_catalog_array;
207extern int options_lastPage;
209extern About *g_pAboutDlgLegacy;
210extern wxColour g_colourTrackLineColour;
211extern int g_n_ownship_min_mm;
213extern int g_AndroidVersionCode;
214extern bool g_bShowMuiZoomButtons;
215extern int g_FlushNavobjChangesTimeout;
216extern wxString g_CmdSoundString;
217extern int g_maintoolbar_x;
218extern int g_maintoolbar_y;
219extern std::vector<std::string> TideCurrentDataSet;
220extern int g_Android_SDK_Version;
221extern wxString g_androidDownloadDirectory;
222extern wxString g_gpx_path;
233static const char *
const DEFAULT_XDG_DATA_DIRS =
234 "~/.local/share:/usr/local/share:/usr/share";
237static const char PATH_SEP =
';';
239static const char PATH_SEP =
':';
242static bool checkIfFlatpacked() {
244 if (!wxGetEnv(
"FLATPAK_ID", &
id)) {
247 return id ==
"org.opencpn.OpenCPN";
250OCPNPlatform::OCPNPlatform() {
252 m_bdisableWindowsDisplayEnum =
false;
253 m_monitorWidth = m_monitorHeight = 0;
255 for (
size_t i = 0; i < g_monitor_info.size(); i++) {
256 m_displaySizeMMOverride.push_back(0);
258 m_pluginDataPath =
"";
261OCPNPlatform::~OCPNPlatform() {
273int MyNewHandler(
size_t size) {
275 throw std::bad_alloc();
296void catch_signals(
int signo) {
327#ifdef OCPN_USE_CRASHREPORT
329int CALLBACK CrashCallback(CR_CRASH_CALLBACK_INFO *pInfo) {
330 wxLog::GetActiveTarget()->Flush();
331 return CR_CB_DODEFAULT;
336void OCPNPlatform::Initialize_1(
void) {
337#ifdef OCPN_USE_CRASHREPORT
341 CR_INSTALL_INFO info;
342 memset(&info, 0,
sizeof(CR_INSTALL_INFO));
343 info.cb =
sizeof(CR_INSTALL_INFO);
344 info.pszAppName = _T(
"OpenCPN");
346 info.pszAppVersion = wxString(VERSION_FULL).c_str();
348 int type = MiniDumpNormal;
351 type |= MiniDumpWithDataSegs;
362 info.uMiniDumpType = (MINIDUMP_TYPE)type;
365 info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS;
368 info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER;
371 info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES;
374 info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS;
378 if (g_bEmailCrashReport) {
379 info.pszUrl = _T(
"https://bigdumboat.com/crashrpt/ocpn_crashrpt.php");
380 info.uPriorities[CR_HTTP] = 3;
382 info.dwFlags |= CR_INST_DONT_SEND_REPORT;
383 info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY;
386 info.uPriorities[CR_SMTP] =
387 CR_NEGATIVE_PRIORITY;
388 info.uPriorities[CR_SMAPI] =
389 CR_NEGATIVE_PRIORITY;
391 wxStandardPaths &crash_std_path = g_Platform->GetStdPaths();
393 wxString crash_rpt_save_locn = crash_std_path.GetConfigDir();
395 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
396 crash_rpt_save_locn =
397 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
400 wxString locn = crash_rpt_save_locn +
"\\CrashReports";
402 if (!wxDirExists(locn)) wxMkdir(locn);
404 if (wxDirExists(locn)) {
405 wxCharBuffer buf = locn.ToUTF8();
407 if (buf && (locn.Length() <
sizeof(wlocn))) {
408 MultiByteToWideChar(0, 0, buf.data(), -1, wlocn,
sizeof(wlocn) - 1);
409 info.pszErrorReportSaveDir = (LPCWSTR)wlocn;
414 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
415 wxString policy_file =
416 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
417 policy_file +=
"PrivacyPolicy.txt";
418 policy_file.Prepend(
"file:");
420 info.pszPrivacyPolicyURL = policy_file.c_str();
423 int nResult = crInstall(&info);
426 crGetLastErrorMsg(buff, 256);
433 crSetCrashCallback(CrashCallback, NULL);
436 crAddScreenshot2(CR_AS_PROCESS_WINDOWS | CR_AS_USE_JPEG_FORMAT, 95);
439 wxString home_data_crash = crash_std_path.GetConfigDir();
441 wxFileName f(crash_std_path.GetExecutablePath());
442 home_data_crash = f.GetPath();
444 appendOSDirSlash(&home_data_crash);
446 wxString config_crash =
"opencpn.ini";
447 config_crash.Prepend(home_data_crash);
448 crAddFile2(config_crash.c_str(), NULL, NULL,
449 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
451 wxString log_crash =
"opencpn.log";
452 log_crash.Prepend(home_data_crash);
453 crAddFile2(log_crash.c_str(), NULL, NULL,
454 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
460#if wxUSE_ON_FATAL_EXCEPTION
462 wxHandleFatalExceptions(
true);
468 _set_new_handler(MyNewHandler);
478 HANDLE hProc = GetCurrentProcess();
482 DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
485 GetProcessAffinityMask( hDup, &procMask, &sysMask );
489 if( ( procMask & 1 ) == 1 ) newMask = 1;
491 if( ( procMask & 2 ) == 2 ) newMask = 2;
493 if( ( procMask & 4 ) == 4 ) newMask = 4;
495 if( ( procMask & 8 ) == 8 ) newMask = 8;
498 BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask );
512 wxPlatformInfo Platform;
513 if (Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X)
514 SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
525 sa_all.sa_handler = catch_signals;
526 sigemptyset(&sa_all.sa_mask);
532 sigaction(SIGUSR1, NULL,
536 sigaction(SIGUSR1, &sa_all, NULL);
537 sigaction(SIGUSR1, NULL,
540 sigaction(SIGTERM, &sa_all, NULL);
541 sigaction(SIGTERM, NULL, &sa_all_old);
543 sigaction(SIGHUP, &sa_all, NULL);
544 sigaction(SIGHUP, NULL, &sa_all_old);
549 qDebug() <<
"Initialize_1()";
559void OCPNPlatform::Initialize_2(
void) {
561 wxLogMessage(androidGetDeviceInfo());
565 wxChar sep = wxFileName::GetPathSeparator();
568 if (ChartDir.Last() != sep) ChartDir.Append(sep);
569 ChartDir.Append(
"Charts");
570 if (!::wxDirExists(ChartDir)) {
575 if (GRIBDir.Last() != sep) GRIBDir.Append(sep);
576 GRIBDir.Append(
"GRIBS");
577 if (!::wxDirExists(GRIBDir)) {
582 if (VDRDir.Last() != sep) VDRDir.Append(sep);
583 VDRDir.Append(
"VDR");
584 if (!::wxDirExists(VDRDir)) {
589 if (g_Android_SDK_Version >= 30) {
590 if (!g_gpx_path.StartsWith(androidGetDocumentsDirectory())) {
591 g_gpx_path = androidGetDocumentsDirectory();
598 g_toolbar_scalefactor = GetToolbarScaleFactor(g_GUIScaleFactor);
600 if (!configdir.DirExists()) {
601 if (!configdir.Mkdir()) {
602 auto msg = std::string(
"Cannot create config directory: ");
603 wxLogWarning(msg + configdir.GetFullPath());
610void OCPNPlatform::Initialize_3(
void) {
611 bool bcapable = IsGLCapable();
617 bool bAndroid =
false;
626 g_bdisable_opengl =
false;
627 pConfig->UpdateSettings();
634 if ((g_bFirstRun || g_bUpgradeInProcess || bAndroid) && bcapable) {
638 g_GLOptions.m_bUseAcceleratedPanning =
true;
639 g_GLOptions.m_bTextureCompression =
true;
640 g_GLOptions.m_bTextureCompressionCaching =
true;
642 g_GLOptions.m_iTextureDimension = 512;
643 g_GLOptions.m_iTextureMemorySize = 64;
645 g_GLOptions.m_GLPolygonSmoothing =
true;
646 g_GLOptions.m_GLLineSmoothing =
true;
650 gFrame->SetGPSCompassScale();
658 if (g_bFirstRun || g_bUpgradeInProcess) {
663 g_FlushNavobjChangesTimeout = 300;
667void OCPNPlatform::Initialize_4(
void) {
669 if (pSelect) pSelect->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
671 pSelectTC->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
673 pSelectAIS->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
680 options_lastPage = 1;
684void OCPNPlatform::OnExit_1(
void) {}
686void OCPNPlatform::OnExit_2(
void) {
687#ifdef OCPN_USE_CRASHREPORT
697bool HasGLExt(
wxJSONValue &glinfo,
const std::string ext) {
698 if (!glinfo.
HasMember(
"GL_EXTENSIONS")) {
701 for (
int i = 0; i < glinfo[
"GL_EXTENSIONS"].
Size(); i++) {
702 if (glinfo[
"GL_EXTENSIONS"][i].AsString() == ext) {
709bool OCPNPlatform::BuildGLCaps(
void *pbuf) {
711 fs::path ep(GetExePath().ToStdString());
713 std::string gl_util_exe =
"opencpn-glutil";
715 std::string gl_util_exe =
"opencpn-glutil.exe";
717 fs::path gl_util_path = ep.parent_path().append(gl_util_exe);
719 if (!fs::exists(gl_util_path)) {
722 wxLogMessage(
"OpenGL test utility not found at %s.", gl_util_path.c_str());
727 .append(
"gl_caps.json")
730 wxString cmd = wxString::Format(
"\"%s\" opengl-info \"%s\"",
731 gl_util_path.c_str(), gl_json.c_str());
733 wxLogMessage(
"Starting OpenGL test utility: %s", cmd);
735 wxArrayString output;
736 if (
long res = wxExecute(cmd, output); res != 0) {
737 wxLogMessage(
"OpenGL test utility failed with exit code %d", res);
738 for (
const auto &l : output) {
744 wxFileInputStream fis(gl_json);
747 reader.
Parse(fis, &root);
749 wxLogMessage(
"Failed to parse JSON output from OpenGL test utility.");
750 for (
const auto &l : reader.GetErrors()) {
759 pcaps->Renderer = root[
"GL_RENDERER"].
AsString();
761 wxLogMessage(
"GL_RENDERER not found.");
765 pcaps->Version = root[
"GL_VERSION"].
AsString();
767 wxLogMessage(
"GL_VERSION not found.");
770 if (root.
HasMember(
"GL_SHADING_LANGUAGE_VERSION")) {
771 pcaps->GLSL_Version = root[
"GL_SHADING_LANGUAGE_VERSION"].
AsString();
773 wxLogMessage(
"GL_SHADING_LANGUAGE_VERSION not found.");
777 if (!root[
"GL_USABLE"].AsBool()) {
778 wxLogMessage(
"OpenGL test utility reports that OpenGL is not usable.");
782 wxLogMessage(
"GL_USABLE not found.");
785 pcaps->dGLSL_Version = 0;
786 pcaps->dGLSL_Version = ::atof(pcaps->GLSL_Version.c_str());
787 if (pcaps->dGLSL_Version < 1.2) {
789 msg.Printf(
"GLCaps Probe: OpenGL-> GLSL Version reported: ");
790 msg += wxString(pcaps->GLSL_Version.c_str());
791 msg +=
"\n OpenGL disabled due to insufficient OpenGL capabilities";
793 pcaps->bCanDoGLSL =
false;
796 pcaps->bCanDoGLSL =
true;
797 if (HasGLExt(root,
"GL_ARB_texture_non_power_of_two")) {
798 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
799 }
else if (HasGLExt(root,
"GL_OES_texture_npot")) {
800 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
801 }
else if (HasGLExt(root,
"GL_ARB_texture_rectangle")) {
802 pcaps->TextureRectangleFormat = GL_TEXTURE_RECTANGLE_ARB;
805 pcaps->bOldIntel =
false;
807 pcaps->bCanDoFBO = HasGLExt(root,
"GL_EXT_framebuffer_object");
808 if (!pcaps->TextureRectangleFormat) {
809 pcaps->bCanDoFBO =
false;
812 pcaps->bCanDoVBO = HasGLExt(
813 root,
"GL_ARB_vertex_buffer_object");
825 wxGLContext *pctx =
new wxGLContext(tcanvas);
826 tcanvas->SetCurrent(*pctx);
830 char *str = (
char *)glGetString(GL_RENDERER);
832 wxLogMessage(
"GL_RENDERER not found.");
837 pcaps->Renderer = std::string(str);
839 char *stv = (
char *)glGetString(GL_VERSION);
841 wxLogMessage(
"GL_VERSION not found");
846 pcaps->Version = std::string(stv);
848 char *stsv = (
char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
850 wxLogMessage(
"GL_SHADING_LANGUAGE_VERSION not found");
855 pcaps->GLSL_Version = std::string(stsv);
857 pcaps->dGLSL_Version = 0;
858 pcaps->dGLSL_Version = ::atof(pcaps->GLSL_Version.c_str());
860 if (pcaps->dGLSL_Version < 1.2) {
862 msg.Printf(
"GLCaps Probe: OpenGL-> GLSL Version reported: ");
863 msg += wxString(pcaps->GLSL_Version.c_str());
864 msg +=
"\n OpenGL disabled due to insufficient OpenGL capabilities";
866 pcaps->bCanDoGLSL =
false;
872 pcaps->bCanDoGLSL =
true;
874 if (QueryExtension(
"GL_ARB_texture_non_power_of_two"))
875 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
876 else if (QueryExtension(
"GL_OES_texture_npot"))
877 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
878 else if (QueryExtension(
"GL_ARB_texture_rectangle"))
879 pcaps->TextureRectangleFormat = GL_TEXTURE_RECTANGLE_ARB;
881 pcaps->bOldIntel =
false;
884 pcaps->bCanDoVBO =
true;
886#if defined(__WXMSW__) || defined(__WXOSX__)
887 if (pcaps->bOldIntel) pcaps->bCanDoVBO =
false;
891 pcaps->bCanDoVBO =
false;
895 pcaps->bCanDoFBO =
true;
899 if (!pcaps->TextureRectangleFormat) pcaps->bCanDoFBO =
false;
902 if (!QueryExtension(
"GL_EXT_framebuffer_object")) pcaps->bCanDoFBO =
false;
912bool OCPNPlatform::IsGLCapable() {
921 if (g_bdisable_opengl)
return false;
923 wxLogMessage(
"Starting OpenGL test...");
924 wxLog::FlushActive();
928 bool bcaps = BuildGLCaps(GL_Caps);
930 wxLogMessage(
"OpenGL test complete.");
932 wxLogMessage(
"BuildGLCaps fails.");
933 wxLog::FlushActive();
941 if (!GL_Caps->bCanDoGLSL) {
947 if (!GL_Caps->bCanDoFBO) {
952 wxLogMessage(
"OpenGL determined CAPABLE.");
953 wxLog::FlushActive();
955 g_bdisable_opengl =
false;
959 pConfig->UpdateSettings();
968void OCPNPlatform::SetLocaleSearchPrefixes(
void) {
971#if defined(__WINDOWS__)
974 wxString locale_location = GetSharedDataDir();
975 locale_location +=
"share\\locale";
976 wxLocale::AddCatalogLookupPathPrefix(locale_location);
977 wxString imsg =
"Adding catalog lookup path: ";
978 imsg += locale_location;
983 usrShare.RemoveLastDir();
984 locale_location = usrShare.GetFullPath() + (
"share\\locale");
985 wxLocale::AddCatalogLookupPathPrefix(locale_location);
986 imsg =
"Adding catalog lookup path: ";
987 imsg += locale_location;
990#elif defined(__ANDROID__)
992 wxString locale_location = GetSharedDataDir() +
"locale";
993 wxLocale::AddCatalogLookupPathPrefix(locale_location);
995#elif defined(__UNIX__) && !defined(__WINE__)
1000 wxString locale_location;
1001 if (!wxGetEnv(
"OPENCPN_PREFIX", &locale_location)) {
1002 locale_location =
"/usr/local";
1006 locale_location = g_Platform->GetHomeDir();
1009 wxFileName location;
1010 location.AssignDir(locale_location);
1011 location.AppendDir(
"share");
1012 location.SetName(
"locale");
1013 locale_location = location.GetFullPath();
1014 wxLocale::AddCatalogLookupPathPrefix(locale_location);
1018 wxString managed_locale_location(dir +
"/locale");
1019 wxLocale::AddCatalogLookupPathPrefix(managed_locale_location);
1023 std::string macDir =
1025 "/Library/Application Support/OpenCPN/Contents/Resources";
1026 wxString Mac_managed_locale_location(macDir);
1027 wxLocale::AddCatalogLookupPathPrefix(Mac_managed_locale_location);
1033wxString OCPNPlatform::GetDefaultSystemLocale() {
1034 wxLogMessage(
"Getting DefaultSystemLocale...");
1036 wxString retval =
"en_US";
1040 const wxLanguageInfo *languageInfo =
1041 wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
1042 if (languageInfo) retval = languageInfo->CanonicalName;
1044#if defined(__WXMSW__)
1045 LANGID lang_id = GetUserDefaultUILanguage();
1048 const wxLanguageInfo *languageInfoW = 0;
1049 if (0 != GetLocaleInfo(MAKELCID(lang_id, SORT_DEFAULT), LOCALE_SENGLANGUAGE,
1051 wxString lstring = wxString(lngcp);
1053 languageInfoW = wxLocale::FindLanguageInfo(lngcp);
1055 wxLogMessage(
"Found LanguageInfo for: " + lstring);
1057 wxLogMessage(
"Could not find LanguageInfo for: " + lstring);
1059 wxLogMessage(
"Could not get LocaleInfo, using wxLANGUAGE_DEFAULT");
1060 languageInfoW = wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
1063 if (languageInfoW) retval = languageInfoW->CanonicalName;
1066#if defined(__ANDROID__)
1067 retval = androidGetAndroidSystemLocale();
1075#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
1076wxString OCPNPlatform::GetAdjustedAppLocale() {
1077 wxString adjLocale = g_locale;
1082#if defined(__WXMSW__)
1083 if (g_bFirstRun || wxIsEmpty(adjLocale)) {
1084 wxRegKey RegKey(wxString(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN"));
1085 if (RegKey.Exists()) {
1087 "Retrieving initial language selection from Windows Registry");
1088 RegKey.QueryValue(wxString(
"InstallerLanguage"), adjLocale);
1091 if (wxIsEmpty(adjLocale)) {
1092 if (g_localeOverride.Length())
1093 adjLocale = g_localeOverride;
1095 adjLocale = GetDefaultSystemLocale();
1098#if defined(__ANDROID__)
1099 if (g_localeOverride.Length())
1100 adjLocale = g_localeOverride;
1102 adjLocale = GetDefaultSystemLocale();
1108wxString OCPNPlatform::ChangeLocale(wxString &newLocaleID,
1109 wxLocale *presentLocale,
1110 wxLocale **newLocale) {
1111 wxString return_val;
1113 wxString imsg =
"ChangeLocale: Language load for: ";
1114 imsg += newLocaleID;
1118 delete (wxLocale *)presentLocale;
1120 wxLocale *locale =
new wxLocale;
1121 if (isFlatpacked()) {
1122 std::string path(getenv(
"HOME"));
1123 path +=
"/.var/app/org.opencpn.OpenCPN/data/locale";
1124 locale->AddCatalogLookupPathPrefix(path);
1125 wxLogMessage(
"Using flatpak locales at %s", path.c_str());
1127 wxString loc_lang_canonical;
1129 const wxLanguageInfo *pli = wxLocale::FindLanguageInfo(newLocaleID);
1130 bool b_initok =
false;
1133 locale->Init(pli->Language, 1);
1137 if (!locale->IsOk()) {
1138 wxString imsg =
"ChangeLocale: could not initialize: ";
1139 imsg += newLocaleID;
1143 locale =
new wxLocale;
1144 locale->Init(pli->Language, 0);
1146 loc_lang_canonical = pli->CanonicalName;
1148 b_initok = locale->IsOk();
1155 wxString imsg =
"ChangeLocale: Fall back to en_US";
1159 locale =
new wxLocale;
1160 locale->Init(wxLANGUAGE_ENGLISH_US, 0);
1161 loc_lang_canonical =
1162 wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US)->CanonicalName;
1166 wxString imsg =
"ChangeLocale: Locale Init OK for: ";
1167 imsg += loc_lang_canonical;
1179 for (
unsigned int i = 0; i < g_locale_catalog_array.GetCount(); i++) {
1180 if (!locale->AddCatalog(g_locale_catalog_array[i])) {
1181 wxString emsg =
"ERROR Loading translation catalog for: ";
1182 emsg += g_locale_catalog_array[i];
1185 wxString imsg =
"Loaded translation catalog for: ";
1186 imsg += g_locale_catalog_array[i];
1192 wxLogMessage(
"Loading catalog for opencpn core.");
1193 locale->AddCatalog(
"opencpn");
1195 return_val = locale->GetCanonicalName();
1198 if (return_val != GetDefaultSystemLocale())
1199 g_localeOverride = return_val;
1201 g_localeOverride =
"";
1204 *newLocale = locale;
1207 setlocale(LC_NUMERIC,
"C");
1218void OCPNPlatform::SetDefaultOptions(
void) {
1220 g_bShowOutlines =
true;
1226 g_MarkLost_Mins = 8;
1227 g_bRemoveLost =
true;
1228 g_RemoveLost_Mins = 10;
1231 g_bSyncCogPredictors =
false;
1232 g_bHideMoored =
false;
1233 g_ShowMoored_Kts = 0.2;
1234 g_SOGminCOG_kts = 0.2;
1235 g_bTrackDaily =
false;
1237 g_bFullScreenQuilt =
true;
1238 g_bQuiltEnable =
true;
1239 g_bskew_comp =
false;
1240 g_bShowAreaNotices =
false;
1241 g_bDrawAISSize =
false;
1242 g_bDrawAISRealtime =
false;
1243 g_AIS_RealtPred_Kts = 0.7;
1244 g_bShowAISName =
false;
1245 g_nTrackPrecision = 2;
1246 g_bPreserveScaleOnX =
true;
1249 gps_watchdog_timeout_ticks = GPS_TIMEOUT_SECONDS;
1250 g_n_ownship_min_mm = 8;
1251 g_bShowMuiZoomButtons =
true;
1252 g_bresponsive =
false;
1256 pConfig->SetPath(_T (
"/Settings/GlobalState" ));
1257 pConfig->Write(_T (
"bShowS57Text" ),
true);
1258 pConfig->Write(_T (
"bShowS57ImportantTextOnly" ),
false);
1259 pConfig->Write(_T (
"nDisplayCategory" ), (
int)(_DisCat)OTHER);
1260 pConfig->Write(_T (
"nSymbolStyle" ), (
int)(_LUPname)PAPER_CHART);
1261 pConfig->Write(_T (
"nBoundaryStyle" ), (
int)(_LUPname)PLAIN_BOUNDARIES);
1263 pConfig->Write(_T (
"bShowSoundg" ),
true);
1264 pConfig->Write(_T (
"bShowMeta" ),
false);
1265 pConfig->Write(_T (
"bUseSCAMIN" ),
true);
1266 pConfig->Write(_T (
"bShowAtonText" ),
false);
1267 pConfig->Write(_T (
"bShowLightDescription" ),
false);
1268 pConfig->Write(_T (
"bExtendLightSectors" ),
true);
1269 pConfig->Write(_T (
"bDeClutterText" ),
true);
1270 pConfig->Write(_T (
"bShowNationalText" ),
true);
1272 pConfig->Write(_T (
"S52_MAR_SAFETY_CONTOUR" ), 3);
1273 pConfig->Write(_T (
"S52_MAR_SHALLOW_CONTOUR" ), 2);
1274 pConfig->Write(_T (
"S52_MAR_DEEP_CONTOUR" ), 6);
1275 pConfig->Write(_T (
"S52_MAR_TWO_SHADES" ), 0);
1276 pConfig->Write(_T (
"S52_DEPTH_UNIT_SHOW" ), 1);
1278 pConfig->Write(_T (
"ZoomDetailFactorVector" ), 3);
1280 pConfig->Write(_T (
"nColorScheme" ), 1);
1284 g_bEnableZoomToCursor =
true;
1286 g_bShowMenuBar =
true;
1293 pConfig->SetPath(_T (
"/PlugIns/chartdldr_pi.dll" ));
1294 pConfig->Write(_T (
"bEnabled" ),
true);
1296 pConfig->SetPath(_T (
"/PlugIns/wmm_pi.dll" ));
1297 pConfig->Write(_T (
"bEnabled" ),
true);
1299 pConfig->SetPath(_T (
"/Settings/WMM" ));
1300 pConfig->Write(_T (
"ShowIcon" ),
true);
1301 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1308 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.dylib" ));
1309 pConfig->Write(_T (
"bEnabled" ),
true);
1311 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.dylib" ));
1312 pConfig->Write(_T (
"bEnabled" ),
true);
1314 pConfig->SetPath(_T (
"/Settings/WMM" ));
1315 pConfig->Write(_T (
"ShowIcon" ),
true);
1316 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1323 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.so" ));
1324 pConfig->Write(_T (
"bEnabled" ),
true);
1326 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.so" ));
1327 pConfig->Write(_T (
"bEnabled" ),
true);
1329 pConfig->SetPath(_T (
"/Settings/WMM" ));
1330 pConfig->Write(_T (
"ShowIcon" ),
true);
1331 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1339 g_GLOptions.m_bTextureCompression = 1;
1340 g_GLOptions.m_bTextureCompressionCaching = 1;
1343 qDebug() <<
"SetDefaultOptions";
1346 g_bresponsive =
true;
1347 g_default_font_size = 18;
1350 g_bShowStatusBar =
true;
1351 g_cm93_zoom_factor = 0;
1352 g_oz_vector_scale =
false;
1353 g_fog_overzoom =
false;
1356 g_bShowMuiZoomButtons =
true;
1358 g_GUIScaleFactor = 0;
1359 g_ChartNotRenderScaleFactor = 2.0;
1363 g_toolbarConfig =
"X.....XX.......XX.XXXXXXXXXXX";
1364 g_bPermanentMOBIcon =
false;
1366 wxString sGPS =
"2;3;;0;0;;0;1;0;0;;0;;1;0;0;0;0";
1369 new_params->bEnabled =
true;
1370 TheConnectionParams().push_back(new_params);
1372 g_default_font_facename =
"Roboto";
1377 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.so" ));
1378 pConfig->Write(_T (
"bEnabled" ),
true);
1380 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.so" ));
1381 pConfig->Write(_T (
"bEnabled" ),
true);
1383 pConfig->SetPath(_T (
"/Settings/WMM" ));
1384 pConfig->Write(_T (
"ShowIcon" ),
true);
1385 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1387 pConfig->SetPath(_T (
"/PlugIns/libgrib_pi.so" ));
1388 pConfig->Write(_T (
"bEnabled" ),
true);
1390 pConfig->SetPath(_T (
"/PlugIns/libdashboard_pi.so" ));
1391 pConfig->Write(_T (
"bEnabled" ),
true);
1393 pConfig->SetPath(_T (
"/PlugIns/GRIB" ));
1394 pConfig->Write(_T (
"GRIBCtrlBarPosX" ), 100);
1395 pConfig->Write(_T (
"GRIBCtrlBarPosY" ), 0);
1397 pConfig->SetPath(_T (
"/Settings/GRIB" ));
1398 pConfig->Write(_T (
"CursorDataShown" ), 0);
1402 pConfig->SetPath(_T (
"/PlugIns/liboesenc_pi.so" ));
1403 pConfig->Write(_T (
"bEnabled" ),
true);
1405 pConfig->SetPath(_T (
"/Settings/QTFonts" ));
1408 wxString str =
"en_US-b25a3899";
1409 wxString pval =
"StatusBar:Roboto,26,-1,5,75,0,0,0,0,0:rgb(0, 0, 0)";
1410 pConfig->Write(str, pval);
1414 str =
"en_US-9c3b3a0d";
1415 pval =
"DialogStatusBar:Roboto,18,-1,5,50,0,0,0,0,0:rgb(0, 0, 0)";
1416 pConfig->Write(str, pval);
1420 pConfig->SetPath(_T (
"/Settings/Others" ));
1421 pConfig->Write(
"TrackLineColour",
"#C545C3");
1422 g_colourTrackLineColour.Set(197, 69, 195);
1424 qDebug() <<
"SetDefaultOptions.Config";
1435void OCPNPlatform::SetUpgradeOptions(wxString vNew, wxString vOld) {
1438 qDebug() <<
"Upgrade check"
1439 <<
"from: " << vOld.mb_str() <<
" to: " << vNew.mb_str();
1441 if (androidGetVersionCode() > g_AndroidVersionCode) {
1442 qDebug() <<
"Upgrade detected"
1443 <<
"from VC: " << g_AndroidVersionCode
1444 <<
" to VC: " << androidGetVersionCode();
1448 pConfig->SetPath(_T (
"/Settings/GlobalState" ));
1449 pConfig->Write(_T (
"bShowS57Text" ),
true);
1452 g_ChartNotRenderScaleFactor = 2.0;
1453 g_n_ownship_min_mm = 8;
1454 g_toolbarConfig =
"X.....XX.......XX.XXXXXXXXXXX";
1457 pConfig->DeleteGroup(_T (
"/Settings/QTFonts" ));
1458 g_default_font_size = 20;
1459 g_default_font_facename =
"Roboto";
1461 FontMgr::Get().Shutdown();
1464 g_bShowMuiZoomButtons =
true;
1468 pInit_Chart_Dir->Clear();
1472 pConfig->SetPath(_T (
"/Settings/WMM" ));
1473 pConfig->Write(_T (
"ShowIcon" ),
true);
1474 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1476 pConfig->SetPath(
"/Canvas/CanvasConfig1");
1477 pConfig->Write(_T (
"canvasENCShowVisibleSectorLights" ), 0);
1487 AndroidRemoveSystemFile(
1488 "/data/user/0/org.opencpn.opencpn/manPlug/libchartscale_pi.so");
1492 g_colourTrackLineColour.Set(197, 69, 195);
1496 if (!vOld.IsSameAs(vNew)) {
1502 wxChar sep = wxFileName::GetPathSeparator();
1503 if (UserIconPath.Last() != sep) UserIconPath.Append(sep);
1504 UserIconPath.Append(
"UserIcons");
1506 if (!::wxDirExists(UserIconPath)) {
1507 ::wxMkdir(UserIconPath);
1512 if (LayersPath.Last() != sep) LayersPath.Append(sep);
1513 LayersPath.Append(
"layers");
1515 if (!::wxDirExists(LayersPath)) {
1516 ::wxMkdir(LayersPath);
1522 g_CmdSoundString = wxString(OCPN_SOUND_CMD);
1523 pConfig->SetPath(_T (
"/Settings" ));
1524 pConfig->Write(_T(
"CmdSoundString" ), g_CmdSoundString);
1528 g_bAIS_GCPA_Alert_Audio =
true;
1529 g_bAIS_SART_Alert_Audio =
true;
1530 g_bAIS_DSC_Alert_Audio =
true;
1533 g_maintoolbar_x = -1;
1537 std::vector<std::string> TCDS_temp;
1538 for (
unsigned int i = 0; i < TideCurrentDataSet.size(); i++)
1539 TCDS_temp.push_back(TideCurrentDataSet[i]);
1541 TideCurrentDataSet.clear();
1542 for (
unsigned int i = 0; i < TCDS_temp.size(); i++) {
1543 wxString tide = TCDS_temp[i];
1544 wxFileName ft(tide);
1545 if (ft.FileExists()) TideCurrentDataSet.push_back(TCDS_temp[i]);
1552 g_compatOsVersion =
"";
1553 pConfig->SetPath(_T (
"/Settings" ));
1554 pConfig->Write(_T (
"CompatOS" ), g_compatOS);
1555 pConfig->Write(_T (
"CompatOsVersion" ), g_compatOsVersion);
1559int OCPNPlatform::platformApplyPrivateSettingsString(wxString settings,
1560 ArrayOfCDI *pDirArray) {
1563 ret_val = androidApplySettingsString(settings, pDirArray);
1569void OCPNPlatform::applyExpertMode(
bool mode) {
1572 g_bBasicMenus = !mode;
1580static wxString ExpandPaths(wxString paths,
OCPNPlatform *platform);
1582int OCPNPlatform::DoFileSelectorDialog(wxWindow *parent, wxString *file_spec,
1583 wxString Title, wxString initDir,
1584 wxString suggestedName,
1585 wxString wildcard) {
1587 int result = wxID_CANCEL;
1591 wxString idir = initDir;
1592 if (initDir.StartsWith(
1596 result = androidFileChooser(&file, idir, Title, suggestedName, wildcard);
1597 if (file_spec) *file_spec = file;
1599 long flag = wxFD_DEFAULT_STYLE;
1600 if (suggestedName.Length()) {
1604 wxString mask = wildcard;
1605 if (wxNOT_FOUND != mask.Find(
"gpx")) mask.Prepend(
"GPX files (*.gpx)|");
1607 wxFileDialog *psaveDialog =
1608 new wxFileDialog(parent, Title, initDir, suggestedName, mask, flag);
1616 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1619 result = psaveDialog->ShowModal();
1622 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1625 if (file_spec) *file_spec = psaveDialog->GetPath();
1633int OCPNPlatform::DoDirSelectorDialog(wxWindow *parent, wxString *file_spec,
1634 wxString Title, wxString initDir,
1637 int result = wxID_CANCEL;
1641 wxString idir = initDir;
1642 if (initDir.StartsWith(
1646 result = androidFileChooser(&dir, idir, Title,
"",
"",
true,
1648 if (file_spec) *file_spec = dir;
1650 wxDirDialog *dirSelector =
new wxDirDialog(
1651 parent, Title, initDir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1654 dirSelector->SetFont(*qFont);
1661 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1664 result = dirSelector->ShowModal();
1667 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1670 if (result == wxID_CANCEL) {
1673 *file_spec = dirSelector->GetPath();
1683MyConfig *OCPNPlatform::GetConfigObject() {
1686 result =
new MyConfig(GetConfigFileName());
1695bool OCPNPlatform::hasInternalGPS(wxString profile) {
1697 bool t = androidDeviceHasGPS();
1711void OCPNPlatform::ShowBusySpinner(
void) {
1712 AbstractPlatform::ShowBusySpinner();
1715void OCPNPlatform::HideBusySpinner(
void) {
1716 AbstractPlatform::HideBusySpinner();
1719double OCPNPlatform::GetDisplayDensityFactor() {
1721 return getAndroidDisplayDensity();
1727long OCPNPlatform::GetDefaultToolbarOrientation() {
1729 return wxTB_VERTICAL;
1731 return wxTB_VERTICAL;
1735int OCPNPlatform::GetStatusBarFieldCount() {
1741 wxFont *templateFont = FontMgr::Get().
GetFont(_(
"StatusBar"), 0);
1742 dc.SetFont(*templateFont);
1745 dc.GetTextExtent(
"WWWWWW", &width, NULL, NULL, NULL, templateFont);
1746 double font_size_pix = (double)width / 6.0;
1750 double nChars = dispSize.x / font_size_pix;
1760 return STAT_FIELD_COUNT;
1764double OCPNPlatform::getFontPointsperPixel(
void) {
1765 double pt_per_pixel = 1.0;
1775 if (m_pt_per_pixel == 0) {
1780 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
1781 wxString(_T (
"" )), wxFONTENCODING_SYSTEM);
1785 dc.GetTextExtent(
"H", &width, &height, NULL, NULL, f);
1787 if (height > 0) m_pt_per_pixel = 12.0 / (double)height;
1789 if (m_pt_per_pixel > 0) pt_per_pixel = m_pt_per_pixel;
1792 return pt_per_pixel;
1797 return getAndroidDisplayDimensions();
1799 return wxSize(g_monitor_info[g_current_monitor].width,
1800 g_monitor_info[g_current_monitor].height);
1805 if (g_current_monitor < m_displaySizeMMOverride.size()) {
1806 if (m_displaySizeMMOverride[g_current_monitor] > 0) {
1807 return m_displaySizeMMOverride[g_current_monitor];
1811 double ret = g_monitor_info[g_current_monitor].width_mm;
1814 ret = GetAndroidDisplaySize();
1820double OCPNPlatform::GetDisplayAreaCM2() {
1825 ratio = (double)sz.x / (
double)sz.y;
1827 ratio = (double)sz.y / (
double)sz.x;
1829 double area = size1 * (size1 * ratio) / 100.;
1835 if (monitor < m_displaySizeMMOverride.size()) {
1836 m_displaySizeMMOverride[monitor] = sizeMM;
1840double OCPNPlatform::GetDisplayDPmm() {
1842 return getAndroidDPmm();
1849unsigned int OCPNPlatform::GetSelectRadiusPix() {
1850 return GetDisplayDPmm() *
1851 (g_btouch ? g_selection_radius_touch_mm : g_selection_radius_mm);
1854bool OCPNPlatform::GetFullscreen() {
1857 bret = androidGetFullscreen();
1865bool OCPNPlatform::SetFullscreen(
bool bFull) {
1868 bret = androidSetFullscreen(bFull);
1875void OCPNPlatform::PositionAISAlert(wxWindow *alert_window) {
1878 alert_window->SetSize(g_ais_alert_dialog_x, g_ais_alert_dialog_y,
1879 g_ais_alert_dialog_sx, g_ais_alert_dialog_sy);
1883 alert_window->Centre();
1889wxDirDialog *OCPNPlatform::AdjustDirDialogFont(wxWindow *container,
1891 wxDirDialog *ret_dlg = dlg;
1895 dlg->SetSize(container->GetSize());
1898 wxSize sds = dlg->GetSize();
1899 wxSize ss = container->GetSize();
1904 wxString msg = dlg->GetMessage();
1905 wxString default_dir = dlg->GetPath();
1909 ret_dlg =
new wxDirDialog(NULL, msg, default_dir,
1910 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1913 wxFont *smallFont =
new wxFont(*dialogFont);
1914 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1916 ret_dlg->SetFont(*smallFont);
1918 ret_dlg->SetSize(container->GetSize());
1926wxFileDialog *OCPNPlatform::AdjustFileDialogFont(wxWindow *container,
1927 wxFileDialog *dlg) {
1928 wxFileDialog *ret_dlg = dlg;
1932 dlg->SetSize(container->GetSize());
1935 wxSize sds = dlg->GetSize();
1936 wxSize ss = container->GetSize();
1941 wxString msg = dlg->GetMessage();
1942 wxString default_dir = dlg->GetDirectory();
1943 wxString default_file = dlg->GetFilename();
1944 wxString wildcard = dlg->GetWildcard();
1948 ret_dlg =
new wxFileDialog(NULL, msg, default_dir, default_file, wildcard,
1952 wxFont *smallFont =
new wxFont(*dialogFont);
1953 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1955 ret_dlg->SetFont(*smallFont);
1957 ret_dlg->SetSize(container->GetSize());
1965double OCPNPlatform::GetToolbarScaleFactor(
int GUIScaleFactor) {
1973 wxSize style_tool_size(32, 32);
1975 if (g_StyleManager) {
1977 if (style) style_tool_size = style->GetToolSize();
1979 double tool_size = style_tool_size.x;
1985 double premult = 1.0;
1987 double target_size = 9.0;
1989 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
1990 premult = target_size / basic_tool_size_mm;
1993 premult = wxMax(45 * getAndroidDisplayDensity(), 45) /
1999 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
2003 rv = premult * postmult;
2004 rv = wxMin(rv, getAndroidDisplayDensity() *
2008 double premult = 1.0;
2010 if (g_bresponsive) {
2013 wxSize style_tool_size = style->GetToolSize();
2014 double tool_size = style_tool_size.x;
2018 double target_size = 9.0;
2020 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
2021 premult = target_size / basic_tool_size_mm;
2025 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
2027 rv = premult * postmult;
2028 rv = wxMin(rv, 3.0);
2029 rv = wxMax(rv, 0.5);
2038double OCPNPlatform::GetCompassScaleFactor(
int GUIScaleFactor) {
2045 if (g_bresponsive) {
2048 wxSize style_tool_size = style->GetToolSize();
2049 double compass_size = style_tool_size.x;
2055 double premult = wxMax(28 * getAndroidDisplayDensity(), 50) / compass_size;
2058 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
2061 rv = premult * postmult;
2062 rv = wxMin(rv, getAndroidDisplayDensity() *
2067 double premult = 1.0;
2069 if (g_bresponsive) {
2071 wxSize style_tool_size = style->GetToolSize();
2072 double compass_size = style_tool_size.x;
2075 double target_size = 6.0;
2077 double basic_tool_size_mm = compass_size / GetDisplayDPmm();
2078 premult = target_size / basic_tool_size_mm;
2081 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
2083 rv = premult * postmult;
2085 rv = wxMin(rv, 3.0);
2086 rv = wxMax(rv, 0.5);
2088#if defined(__WXOSX__) || defined(__WXGTK3__)
2090 if (gFrame) rv *= gFrame->GetContentScaleFactor();
2100float OCPNPlatform::GetChartScaleFactorExp(
float scale_linear) {
2101 double factor = 1.0;
2103 factor = exp(scale_linear * (log(3.0) / 5.0));
2108 factor = exp(scale_linear * (0.693 / 5.0));
2112 factor = wxMax(factor, .5);
2113 factor = wxMin(factor, 6.);
2118float OCPNPlatform::GetMarkScaleFactorExp(
float scale_linear) {
2119 if (scale_linear <= 0)
2120 return GetChartScaleFactorExp(scale_linear);
2122 return GetChartScaleFactorExp(scale_linear - 1);
2139bool OCPNPlatform::hasInternalBT(wxString profile) {
2141 bool t = androidDeviceHasBlueTooth();
2150bool OCPNPlatform::startBluetoothScan() {
2152 return androidStartBluetoothScan();
2159bool OCPNPlatform::stopBluetoothScan() {
2161 return androidStopBluetoothScan();
2168wxArrayString OCPNPlatform::getBluetoothScanResults() {
2169 wxArrayString ret_val;
2171 return androidGetBluetoothScanResults();
2174 ret_val.Add(
"line 1");
2175 ret_val.Add(
"line 2");
2176 ret_val.Add(
"line 3");
2186bool OCPNPlatform::AllowAlertDialog(
const wxString &class_name) {
2191 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
2193 wxWindow *win = node->GetData();
2194 if (win->IsShown()) nTLW++;
2196 node = node->GetNext();
2201 return (g_running && !g_options->IsShown() && (nTLW <= 4));
2203 return (g_running && (nTLW <= 4));
2210void OCPNPlatform::setChartTypeMaskSel(
int mask, wxString &indicator) {
2212 return androidSetChartTypeMaskSel(mask, indicator);
2217QString g_qtStyleSheet;
2219bool LoadQtStyleSheet(wxString &sheet_file) {
2220 if (wxFileExists(sheet_file)) {
2223 QString file(sheet_file.c_str());
2225 File.open(QFile::ReadOnly);
2226 g_qtStyleSheet = QLatin1String(File.readAll());
2236QString getQtStyleSheet(
void) {
return g_qtStyleSheet; }
2240bool OCPNPlatform::isPlatformCapable(
int flag) {
2244 if (flag == PLATFORM_CAP_PLUGINS) {
2246 wxString tsdk(android_plat_spc.msdk);
2247 if (tsdk.ToLong(&platver)) {
2248 if (platver >= 11)
return true;
2250 }
else if (flag == PLATFORM_CAP_FASTPAN) {
2252 wxString tsdk(android_plat_spc.msdk);
2253 if (tsdk.ToLong(&platver)) {
2254 if (platver >= 14)
return true;
2262void OCPNPlatform::platformLaunchDefaultBrowser(wxString URL) {
2264 androidLaunchBrowser(URL);
2266 ::wxLaunchDefaultBrowser(URL);
2276EVT_PAINT(OCPNColourPickerCtrl::OnPaint)
2285 const wxColour &initial,
2287 const wxSize &size,
long style,
2288 const wxValidator &validator,
2289 const wxString &name) {
2290 Create(parent,
id, initial, pos, size, style, validator, name);
2293bool OCPNColourPickerCtrl::Create(wxWindow *parent, wxWindowID
id,
2294 const wxColour &col,
const wxPoint &pos,
2295 const wxSize &size,
long style,
2296 const wxValidator &validator,
2297 const wxString &name) {
2298 m_bitmap = wxBitmap(60, 13);
2301 if (!wxBitmapButton::Create(parent,
id, m_bitmap, pos, size,
2302 style | wxBU_AUTODRAW, validator, name)) {
2303 wxFAIL_MSG(
"OCPNColourPickerCtrl creation failed");
2308 Connect(GetId(), wxEVT_BUTTON,
2309 wxCommandEventHandler(OCPNColourPickerCtrl::OnButtonClick), NULL,
2319void OCPNColourPickerCtrl::InitColourData() {
2321 ms_data.SetChooseFull(
true);
2322 unsigned char grey = 0;
2323 for (
int i = 0; i < 16; i++, grey += 16)
2326 wxColour colour(grey, grey, grey);
2327 ms_data.SetCustomColour(i, colour);
2332void OCPNColourPickerCtrl::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
2334 unsigned int cco = 0;
2337 cco |= m_colour.Red();
2339 cco |= m_colour.Green();
2341 cco |= m_colour.Blue();
2342 unsigned int cc = androidColorPicker(cco);
2345 unsigned char blue = (
unsigned char)cc % 256;
2346 unsigned char green = (
unsigned char)(cc >> 8) % 256;
2348 unsigned char red = (
unsigned char)(cc >> 16) % 256;
2349 cnew.Set(red, green, blue);
2355 ms_data.SetColour(m_colour);
2358 wxColourDialog dlg(
this, &ms_data);
2359 if (dlg.ShowModal() == wxID_OK) {
2360 ms_data = dlg.GetColourData();
2361 SetColour(ms_data.GetColour());
2366void OCPNColourPickerCtrl::UpdateColour() {
2368 SetBitmapLabel(wxBitmap());
2371 wxMemoryDC dc(m_bitmap);
2372 dc.SetPen(*wxTRANSPARENT_PEN);
2373 dc.SetBrush(wxBrush(m_colour));
2374 dc.DrawRectangle(0, 0, m_bitmap.GetWidth(), m_bitmap.GetHeight());
2376 dc.SelectObject(wxNullBitmap);
2377 SetBitmapLabel(m_bitmap);
2380void OCPNColourPickerCtrl::SetColour(wxColour &c) {
2382 m_bitmap = wxBitmap(GetSize().x - 20, GetSize().y - 20);
2386wxColour OCPNColourPickerCtrl::GetColour(
void) {
return m_colour; }
2388wxSize OCPNColourPickerCtrl::DoGetBestSize()
const {
2389 wxSize sz(wxBitmapButton::DoGetBestSize());
2396 if (HasFlag(wxCLRP_SHOW_LABEL))
return sz;
2404void OCPNColourPickerCtrl::OnPaint(wxPaintEvent &event) {
2407 int offset_x = (GetSize().x - m_bitmap.GetWidth()) / 2;
2408 int offset_y = (GetSize().y - m_bitmap.GetHeight()) / 2;
2410 dc.SetPen(*wxTRANSPARENT_PEN);
2411 dc.SetBrush(wxBrush(m_colour));
2412 dc.DrawRectangle(offset_x, offset_y, m_bitmap.GetWidth(),
2413 m_bitmap.GetHeight());
Class AisDecoder and helpers.
Global state for AIS decoder.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
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)
Gets 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.
int GetErrorCount() const
Return the size of the error message's array.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
int Size() const
Return the size of the array or map stored in this value.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
Global variables reflecting command line options and arguments.
bool g_bsmoothpanzoom
Controls how the chart panning and zooming smoothing is done during user interactions.
bool g_bRollover
enable/disable mouse rollover GUI effects
std::vector< size_t > g_config_display_size_mm
g_config_display_size_mm: Size of pysical screen in millimeters.
Global variables stored in configuration file.
Dump debug info on crash.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
Enhanced logging interface on top of wx/log.h.
void cache_clear()
Remove all files in cache:
Miscellaneous utilities, many of which string related.
Plugin installation and data paths support.
wxString GetWritableDocumentsDir(void)
Returns the platform-specific default documents directory.