38#include <wx/apptrait.h>
39#include <wx/stdpaths.h>
40#include <wx/filename.h>
41#include <wx/tokenzr.h>
42#include <wx/textfile.h>
46#include "base_platform.h"
48#include "OCPNPlatform.h"
51#include "config_vars.h"
55#include "ocpn_utils.h"
56#include "conn_params.h"
61#include "AboutFrameImpl.h"
63#include "plugin_paths.h"
64#include "ocpn_frame.h"
68#ifdef __OCPN__ANDROID__
69#include "androidUTIL.h"
73#include "glChartCanvas.h"
77#ifdef OCPN_USE_CRASHREPORT
85#include "crashprint.h"
113void appendOSDirSlash(wxString *pString);
116struct sigaction sa_all;
117struct sigaction sa_all_old;
118extern sigjmp_buf env;
122extern wxString g_winPluginDir;
123extern bool g_bFirstRun;
124extern bool g_bUpgradeInProcess;
128extern bool g_bportable;
134extern bool g_bshowToolbar;
135extern bool g_bexpert;
136extern bool g_bBasicMenus;
137extern bool g_bUIexpert;
139extern bool g_bshowToolbar;
140extern bool g_bBasicMenus;
142extern bool g_bShowOutlines;
143extern int g_nAWDefault;
145extern bool g_bPermanentMOBIcon;
146extern float g_toolbar_scalefactor;
149extern bool g_boptionsactive;
152extern double g_CPAMax_NM;
153extern double g_CPAWarn_NM;
154extern double g_TCPA_Max;
155extern bool g_bMarkLost;
156extern double g_MarkLost_Mins;
157extern bool g_bRemoveLost;
158extern double g_RemoveLost_Mins;
159extern bool g_bShowCOG;
160extern bool g_bSyncCogPredictors;
161extern double g_ShowCOG_Mins;
162extern bool g_bHideMoored;
163extern double g_ShowMoored_Kts;
164extern bool g_bShowAreaNotices;
165extern bool g_bDrawAISSize;
166extern bool g_bDrawAISRealtime;
167extern double g_AIS_RealtPred_Kts;
168extern bool g_bShowAISName;
169extern bool g_bAIS_GCPA_Alert_Audio;
170extern bool g_bAIS_SART_Alert_Audio;
171extern bool g_bAIS_DSC_Alert_Audio;
172extern bool g_bAIS_CPA_Alert_Audio;
173extern bool g_bCPAWarn;
174extern bool g_bAIS_CPA_Alert;
176extern wxString *pInit_Chart_Dir;
178extern double g_config_display_size_mm;
179extern bool g_config_display_size_manual;
181extern float g_selection_radius_mm;
182extern float g_selection_radius_touch_mm;
184extern bool g_bTrackDaily;
185extern double g_PlanSpeed;
186extern bool g_bFullScreenQuilt;
187extern bool g_bQuiltEnable;
188extern bool g_bskew_comp;
190extern bool g_bopengl;
192extern bool g_bresponsive;
193extern bool g_bShowStatusBar;
194extern int g_cm93_zoom_factor;
195extern int g_GUIScaleFactor;
196extern bool g_fog_overzoom;
197extern bool g_oz_vector_scale;
198extern int g_nTrackPrecision;
199extern wxString g_toolbarConfig;
200extern bool g_bPreserveScaleOnX;
201extern bool g_running;
218extern int g_default_font_size;
219extern wxString g_default_font_facename;
222bool g_bEmailCrashReport;
223extern int g_ais_alert_dialog_x, g_ais_alert_dialog_y;
224extern int g_ais_alert_dialog_sx, g_ais_alert_dialog_sy;
226extern double g_ChartNotRenderScaleFactor;
227extern bool g_bRollover;
229#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
230extern wxLocale *plocale_def_lang;
232extern wxString g_locale;
233extern wxString g_localeOverride;
234extern wxArrayString g_locale_catalog_array;
237extern int options_lastPage;
239extern about *g_pAboutDlgLegacy;
240extern wxColour g_colourTrackLineColour;
241extern int g_n_ownship_min_mm;
243extern int g_AndroidVersionCode;
244extern bool g_bShowMuiZoomButtons;
245extern int g_FlushNavobjChangesTimeout;
246extern wxString g_CmdSoundString;
247extern int g_maintoolbar_x;
248extern int g_maintoolbar_y;
249extern wxArrayString TideCurrentDataSet;
250extern int g_Android_SDK_Version;
251extern wxString g_androidDownloadDirectory;
252extern wxString g_gpx_path;
261static const char *
const DEFAULT_XDG_DATA_DIRS =
262 "~/.local/share:/usr/local/share:/usr/share";
265static const char PATH_SEP =
';';
267static const char PATH_SEP =
':';
270static bool checkIfFlatpacked() {
272 if (!wxGetEnv(
"FLATPAK_ID", &
id)) {
275 return id ==
"org.opencpn.OpenCPN";
279OCPNPlatform::OCPNPlatform() {
281 m_bdisableWindowsDisplayEnum =
false;
282 m_displaySize = wxSize(0, 0);
283 m_displaySizeMM = wxSize(0, 0);
284 m_monitorWidth = m_monitorHeight = 0;
285 m_displaySizeMMOverride = 0;
286 m_pluginDataPath =
"";
289OCPNPlatform::~OCPNPlatform() {}
295int MyNewHandler(
size_t size) {
297 throw std::bad_alloc();
318void catch_signals(
int signo) {
349#ifdef OCPN_USE_CRASHREPORT
351int CALLBACK CrashCallback(CR_CRASH_CALLBACK_INFO *pInfo) {
353 if (g_logger) g_logger->Flush();
355 return CR_CB_DODEFAULT;
360void OCPNPlatform::Initialize_1(
void) {
361#ifdef OCPN_USE_CRASHREPORT
365 CR_INSTALL_INFO info;
366 memset(&info, 0,
sizeof(CR_INSTALL_INFO));
367 info.cb =
sizeof(CR_INSTALL_INFO);
368 info.pszAppName = _T(
"OpenCPN");
370 info.pszAppVersion = wxString(VERSION_FULL).c_str();
372 int type = MiniDumpNormal;
375 type |= MiniDumpWithDataSegs;
386 info.uMiniDumpType = (MINIDUMP_TYPE)type;
389 info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS;
392 info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER;
395 info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES;
398 info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS;
402 if (g_bEmailCrashReport) {
403 info.pszUrl = _T(
"https://bigdumboat.com/crashrpt/ocpn_crashrpt.php");
404 info.uPriorities[CR_HTTP] = 3;
406 info.dwFlags |= CR_INST_DONT_SEND_REPORT;
407 info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY;
410 info.uPriorities[CR_SMTP] =
411 CR_NEGATIVE_PRIORITY;
412 info.uPriorities[CR_SMAPI] =
413 CR_NEGATIVE_PRIORITY;
415 wxStandardPaths &crash_std_path = g_Platform->GetStdPaths();
417 wxString crash_rpt_save_locn = crash_std_path.GetConfigDir();
419 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
420 crash_rpt_save_locn =
421 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
424 wxString locn = crash_rpt_save_locn + _T(
"\\CrashReports");
426 if (!wxDirExists(locn)) wxMkdir(locn);
428 if (wxDirExists(locn)) {
429 wxCharBuffer buf = locn.ToUTF8();
431 if (buf && (locn.Length() <
sizeof(wlocn))) {
432 MultiByteToWideChar(0, 0, buf.data(), -1, wlocn,
sizeof(wlocn) - 1);
433 info.pszErrorReportSaveDir = (LPCWSTR)wlocn;
438 wxFileName exec_path_crash(crash_std_path.GetExecutablePath());
439 wxString policy_file =
440 exec_path_crash.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
441 policy_file += _T(
"PrivacyPolicy.txt");
442 policy_file.Prepend(_T(
"file:"));
444 info.pszPrivacyPolicyURL = policy_file.c_str();
447 int nResult = crInstall(&info);
450 crGetLastErrorMsg(buff, 256);
457 crSetCrashCallback(CrashCallback, NULL);
460 crAddScreenshot2(CR_AS_PROCESS_WINDOWS | CR_AS_USE_JPEG_FORMAT, 95);
463 wxString home_data_crash = crash_std_path.GetConfigDir();
465 wxFileName f(crash_std_path.GetExecutablePath());
466 home_data_crash = f.GetPath();
468 appendOSDirSlash(&home_data_crash);
470 wxString config_crash = _T(
"opencpn.ini");
471 config_crash.Prepend(home_data_crash);
472 crAddFile2(config_crash.c_str(), NULL, NULL,
473 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
475 wxString log_crash = _T(
"opencpn.log");
476 log_crash.Prepend(home_data_crash);
477 crAddFile2(log_crash.c_str(), NULL, NULL,
478 CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE);
484#if wxUSE_ON_FATAL_EXCEPTION
486 wxHandleFatalExceptions(
true);
492 _set_new_handler(MyNewHandler);
502 HANDLE hProc = GetCurrentProcess();
506 DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
509 GetProcessAffinityMask( hDup, &procMask, &sysMask );
513 if( ( procMask & 1 ) == 1 ) newMask = 1;
515 if( ( procMask & 2 ) == 2 ) newMask = 2;
517 if( ( procMask & 4 ) == 4 ) newMask = 4;
519 if( ( procMask & 8 ) == 8 ) newMask = 8;
522 BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask );
536 wxPlatformInfo Platform;
537 if (Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X)
538 SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
549 sa_all.sa_handler = catch_signals;
550 sigemptyset(&sa_all.sa_mask);
556 sigaction(SIGUSR1, NULL,
560 sigaction(SIGUSR1, &sa_all, NULL);
561 sigaction(SIGUSR1, NULL,
564 sigaction(SIGTERM, &sa_all, NULL);
565 sigaction(SIGTERM, NULL, &sa_all_old);
567 sigaction(SIGHUP, &sa_all, NULL);
568 sigaction(SIGHUP, NULL, &sa_all_old);
572#ifdef __OCPN__ANDROID__
573 qDebug() <<
"Initialize_1()";
585void OCPNPlatform::Initialize_2(
void) {
586#ifdef __OCPN__ANDROID__
587 wxLogMessage(androidGetDeviceInfo());
591 wxChar sep = wxFileName::GetPathSeparator();
593 wxString ChartDir = GetPrivateDataDir();
594 if (ChartDir.Last() != sep) ChartDir.Append(sep);
595 ChartDir.Append(
"Charts");
596 if (!::wxDirExists(ChartDir)) {
600 wxString GRIBDir = GetPrivateDataDir();
601 if (GRIBDir.Last() != sep) GRIBDir.Append(sep);
602 GRIBDir.Append(
"GRIBS");
603 if (!::wxDirExists(GRIBDir)) {
608 if (g_Android_SDK_Version >= 30){
609 if (!g_gpx_path.StartsWith(androidGetDownloadDirectory())){
610 g_gpx_path = androidGetDownloadDirectory();
617 g_toolbar_scalefactor = GetToolbarScaleFactor(g_GUIScaleFactor);
618 auto configdir = wxFileName(GetPrivateDataDir());
619 if (!configdir.DirExists()) {
620 if (!configdir.Mkdir()) {
621 auto msg = std::string(
"Cannot create config directory: ");
622 wxLogWarning(msg + configdir.GetFullPath());
629void OCPNPlatform::Initialize_3(
void) {
630 bool bcapable = IsGLCapable();
636 bool bAndroid =
false;
637#ifdef __OCPN__ANDROID__
647 if ((g_bFirstRun || g_bUpgradeInProcess || bAndroid) && bcapable) {
651 g_GLOptions.m_bUseAcceleratedPanning =
true;
652 g_GLOptions.m_bTextureCompression =
true;
653 g_GLOptions.m_bTextureCompressionCaching =
true;
655 g_GLOptions.m_iTextureDimension = 512;
656 g_GLOptions.m_iTextureMemorySize = 64;
658 g_GLOptions.m_GLPolygonSmoothing =
true;
659 g_GLOptions.m_GLLineSmoothing =
true;
662 gFrame->SetGPSCompassScale();
670 if (g_bFirstRun || g_bUpgradeInProcess) {
672 g_bRollover = g_btouch ? false :
true;
675 g_FlushNavobjChangesTimeout = 300;
679void OCPNPlatform::Initialize_4(
void) {
680#ifdef __OCPN__ANDROID__
681 if (pSelect) pSelect->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
683 pSelectTC->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
685 pSelectAIS->SetSelectPixelRadius(wxMax(25, 6.0 * getAndroidDPmm()));
692 options_lastPage = 1;
696void OCPNPlatform::OnExit_1(
void) {}
698void OCPNPlatform::OnExit_2(
void) {
699#ifdef OCPN_USE_CRASHREPORT
708bool OCPNPlatform::BuildGLCaps(
void *pbuf) {
714 wxGLContext *pctx =
new wxGLContext(tcanvas);
715 tcanvas->SetCurrent(*pctx);
719 char *str = (
char *)glGetString(GL_RENDERER);
726 pcaps->Renderer = std::string(str);
727 pcaps->Version = std::string((
char *)glGetString(GL_VERSION));
728 pcaps->GLSL_Version = std::string((
char *)glGetString(GL_SHADING_LANGUAGE_VERSION));
729 pcaps->dGLSL_Version = ::atof(pcaps->GLSL_Version.c_str());
731 if (pcaps->dGLSL_Version < 1.2){
733 msg.Printf(_T(
"GLCaps Probe: OpenGL-> GLSL Version reported: "));
734 msg += wxString(pcaps->GLSL_Version.c_str());
735 msg +=
"\n OpenGL disabled due to insufficient OpenGL capabilities";
737 pcaps->bCanDoGLSL =
false;
741 pcaps->bCanDoGLSL =
true;
743 if (QueryExtension(
"GL_ARB_texture_non_power_of_two"))
744 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
745 else if (QueryExtension(
"GL_OES_texture_npot"))
746 pcaps->TextureRectangleFormat = GL_TEXTURE_2D;
747 else if (QueryExtension(
"GL_ARB_texture_rectangle"))
748 pcaps->TextureRectangleFormat = GL_TEXTURE_RECTANGLE_ARB;
750 pcaps->bOldIntel =
false;
753 pcaps->bCanDoVBO =
true;
755#if defined(__WXMSW__) || defined(__WXOSX__)
756 if (pcaps->bOldIntel) pcaps->bCanDoVBO =
false;
759#ifdef __OCPN__ANDROID__
760 pcaps->bCanDoVBO =
false;
764 pcaps->bCanDoFBO =
true;
766#ifndef __OCPN__ANDROID__
768 if (!pcaps->TextureRectangleFormat) pcaps->bCanDoFBO =
false;
771 if (!QueryExtension(
"GL_EXT_framebuffer_object")) pcaps->bCanDoFBO =
false;
781bool OCPNPlatform::IsGLCapable() {
782#ifdef __OCPN__ANDROID__
789 BuildGLCaps(GL_Caps);
794 if (!GL_Caps->bCanDoGLSL)
return false;
799 if (!GL_Caps->bCanDoFBO)
return false;
805void OCPNPlatform::SetLocaleSearchPrefixes(
void) {
808#if defined(__WINDOWS__)
811 wxString locale_location = GetSharedDataDir();
812 locale_location += _T(
"share\\locale");
813 wxLocale::AddCatalogLookupPathPrefix(locale_location);
814 wxString imsg = _T(
"Adding catalog lookup path: ");
815 imsg += locale_location;
821 usrShare.RemoveLastDir();
822 locale_location = usrShare.GetFullPath() + (
"share\\locale");
823 wxLocale::AddCatalogLookupPathPrefix(locale_location);
824 imsg = _T(
"Adding catalog lookup path: ");
825 imsg += locale_location;
828#elif defined(__OCPN__ANDROID__)
830 wxString locale_location = GetSharedDataDir() + _T(
"locale");
831 wxLocale::AddCatalogLookupPathPrefix(locale_location);
833#elif defined(__UNIX__) && !defined(__WINE__)
838 wxString locale_location;
839 if (!wxGetEnv(_T(
"OPENCPN_PREFIX"), &locale_location)) {
840 locale_location = _T(
"/usr/local");
843 location.AssignDir(locale_location);
844 location.AppendDir(_T(
"share"));
845 location.SetName(_T(
"locale"));
846 locale_location = location.GetFullPath();
847 wxLocale::AddCatalogLookupPathPrefix(locale_location);
851 wxString managed_locale_location(dir +
"/locale");
852 wxLocale::AddCatalogLookupPathPrefix(managed_locale_location);
858 "/Library/Application Support/OpenCPN/Contents/Resources";
859 wxString Mac_managed_locale_location(macDir);
860 wxLocale::AddCatalogLookupPathPrefix(Mac_managed_locale_location);
866wxString OCPNPlatform::GetDefaultSystemLocale() {
867 wxLogMessage(_T(
"Getting DefaultSystemLocale..."));
869 wxString retval = _T(
"en_US");
873 const wxLanguageInfo *languageInfo =
874 wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
875 if (languageInfo) retval = languageInfo->CanonicalName;
877#if defined(__WXMSW__)
878 LANGID lang_id = GetUserDefaultUILanguage();
881 const wxLanguageInfo *languageInfoW = 0;
882 if (0 != GetLocaleInfo(MAKELCID(lang_id, SORT_DEFAULT), LOCALE_SENGLANGUAGE,
884 wxString lstring = wxString(lngcp);
886 languageInfoW = wxLocale::FindLanguageInfo(lngcp);
888 wxLogMessage(_T(
"Found LanguageInfo for: ") + lstring);
890 wxLogMessage(_T(
"Could not find LanguageInfo for: ") + lstring);
892 wxLogMessage(_T(
"Could not get LocaleInfo, using wxLANGUAGE_DEFAULT"));
893 languageInfoW = wxLocale::GetLanguageInfo(wxLANGUAGE_DEFAULT);
896 if (languageInfoW) retval = languageInfoW->CanonicalName;
899#if defined(__OCPN__ANDROID__)
900 retval = androidGetAndroidSystemLocale();
908#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
909wxString OCPNPlatform::GetAdjustedAppLocale() {
910 wxString adjLocale = g_locale;
915#if defined(__WXMSW__)
916 if (g_bFirstRun || wxIsEmpty(adjLocale)) {
917 wxRegKey RegKey(wxString(_T(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\OpenCPN")));
918 if (RegKey.Exists()) {
920 _T(
"Retrieving initial language selection from Windows Registry"));
921 RegKey.QueryValue(wxString(_T(
"InstallerLanguage")), adjLocale);
924 if (wxIsEmpty(adjLocale)) {
925 if (g_localeOverride.Length())
926 adjLocale = g_localeOverride;
928 adjLocale = GetDefaultSystemLocale();
931#if defined(__OCPN__ANDROID__)
932 if (g_localeOverride.Length())
933 adjLocale = g_localeOverride;
935 adjLocale = GetDefaultSystemLocale();
941wxString OCPNPlatform::ChangeLocale(wxString &newLocaleID,
942 wxLocale *presentLocale,
943 wxLocale **newLocale) {
946 wxString imsg = _T(
"ChangeLocale: Language load for: ");
951 delete (wxLocale *)presentLocale;
953 wxLocale *locale =
new wxLocale;
954 if (isFlatpacked()) {
955 std::string path(getenv(
"HOME"));
956 path +=
"/.var/app/org.opencpn.OpenCPN/data/locale";
957 locale->AddCatalogLookupPathPrefix(path);
958 wxLogMessage(
"Using flatpak locales at %s", path.c_str());
960 wxString loc_lang_canonical;
962 const wxLanguageInfo *pli = wxLocale::FindLanguageInfo(newLocaleID);
963 bool b_initok =
false;
966 locale->Init(pli->Language, 1);
970 if (!locale->IsOk()) {
971 wxString imsg = _T(
"ChangeLocale: could not initialize: ");
976 locale =
new wxLocale;
977 locale->Init(pli->Language, 0);
979 loc_lang_canonical = pli->CanonicalName;
981 b_initok = locale->IsOk();
982#ifdef __OCPN__ANDROID__
988 wxString imsg = _T(
"ChangeLocale: Fall back to en_US");
992 locale =
new wxLocale;
993 locale->Init(wxLANGUAGE_ENGLISH_US, 0);
995 wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH_US)->CanonicalName;
999 wxString imsg = _T(
"ChangeLocale: Locale Init OK for: ");
1000 imsg += loc_lang_canonical;
1012 for (
unsigned int i = 0; i < g_locale_catalog_array.GetCount(); i++) {
1013 if(!locale->AddCatalog(g_locale_catalog_array[i])){
1014 wxString emsg = _T(
"ERROR Loading translation catalog for: ");
1015 emsg += g_locale_catalog_array[i];
1019 wxString imsg = _T(
"Loaded translation catalog for: ");
1020 imsg += g_locale_catalog_array[i];
1026 wxLogMessage(_T(
"Loading catalog for opencpn core."));
1027 locale->AddCatalog(_T(
"opencpn"));
1029 return_val = locale->GetCanonicalName();
1032 if (return_val != GetDefaultSystemLocale())
1033 g_localeOverride = return_val;
1035 g_localeOverride = _T(
"");
1038 *newLocale = locale;
1041 setlocale(LC_NUMERIC,
"C");
1052void OCPNPlatform::SetDefaultOptions(
void) {
1054 g_bShowOutlines =
true;
1060 g_MarkLost_Mins = 8;
1061 g_bRemoveLost =
true;
1062 g_RemoveLost_Mins = 10;
1065 g_bSyncCogPredictors =
false;
1066 g_bHideMoored =
false;
1067 g_ShowMoored_Kts = 0.2;
1068 g_bTrackDaily =
false;
1070 g_bFullScreenQuilt =
true;
1071 g_bQuiltEnable =
true;
1072 g_bskew_comp =
false;
1073 g_bShowAreaNotices =
false;
1074 g_bDrawAISSize =
false;
1075 g_bDrawAISRealtime =
false;
1076 g_AIS_RealtPred_Kts = 0.7;
1077 g_bShowAISName =
false;
1078 g_nTrackPrecision = 2;
1079 g_bPreserveScaleOnX =
true;
1082 gps_watchdog_timeout_ticks = GPS_TIMEOUT_SECONDS;
1083 g_n_ownship_min_mm = 8;
1084 g_bShowMuiZoomButtons =
true;
1085 g_bresponsive =
false;
1089 pConfig->SetPath(_T (
"/Settings/GlobalState" ));
1090 pConfig->Write(_T (
"bShowS57Text" ),
true);
1091 pConfig->Write(_T (
"bShowS57ImportantTextOnly" ),
false);
1092 pConfig->Write(_T (
"nDisplayCategory" ), (
int)(_DisCat)STANDARD);
1093 pConfig->Write(_T (
"nSymbolStyle" ), (
int)(_LUPname)PAPER_CHART);
1094 pConfig->Write(_T (
"nBoundaryStyle" ), (
int)(_LUPname)PLAIN_BOUNDARIES);
1096 pConfig->Write(_T (
"bShowSoundg" ),
true);
1097 pConfig->Write(_T (
"bShowMeta" ),
false);
1098 pConfig->Write(_T (
"bUseSCAMIN" ),
true);
1099 pConfig->Write(_T (
"bShowAtonText" ),
false);
1100 pConfig->Write(_T (
"bShowLightDescription" ),
false);
1101 pConfig->Write(_T (
"bExtendLightSectors" ),
true);
1102 pConfig->Write(_T (
"bDeClutterText" ),
true);
1103 pConfig->Write(_T (
"bShowNationalText" ),
true);
1105 pConfig->Write(_T (
"S52_MAR_SAFETY_CONTOUR" ), 3);
1106 pConfig->Write(_T (
"S52_MAR_SHALLOW_CONTOUR" ), 2);
1107 pConfig->Write(_T (
"S52_MAR_DEEP_CONTOUR" ), 6);
1108 pConfig->Write(_T (
"S52_MAR_TWO_SHADES" ), 0);
1109 pConfig->Write(_T (
"S52_DEPTH_UNIT_SHOW" ), 1);
1111 pConfig->Write(_T (
"ZoomDetailFactorVector" ), 3);
1113 pConfig->Write(_T (
"nColorScheme" ), 1);
1119 pConfig->SetPath(_T (
"/PlugIns/chartdldr_pi.dll" ));
1120 pConfig->Write(_T (
"bEnabled" ),
true);
1122 pConfig->SetPath(_T (
"/PlugIns/wmm_pi.dll" ));
1123 pConfig->Write(_T (
"bEnabled" ),
true);
1125 pConfig->SetPath(_T (
"/Settings/WMM" ));
1126 pConfig->Write(_T (
"ShowIcon" ),
true);
1127 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1134 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.dylib" ));
1135 pConfig->Write(_T (
"bEnabled" ),
true);
1137 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.dylib" ));
1138 pConfig->Write(_T (
"bEnabled" ),
true);
1140 pConfig->SetPath(_T (
"/Settings/WMM" ));
1141 pConfig->Write(_T (
"ShowIcon" ),
true);
1142 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1149 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.so" ));
1150 pConfig->Write(_T (
"bEnabled" ),
true);
1152 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.so" ));
1153 pConfig->Write(_T (
"bEnabled" ),
true);
1155 pConfig->SetPath(_T (
"/Settings/WMM" ));
1156 pConfig->Write(_T (
"ShowIcon" ),
true);
1157 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1161#ifdef __OCPN__ANDROID__
1165 g_GLOptions.m_bTextureCompression = 1;
1166 g_GLOptions.m_bTextureCompressionCaching = 1;
1169 qDebug() <<
"SetDefaultOptions";
1172 g_bresponsive =
true;
1173 g_default_font_size = 18;
1176 g_bShowStatusBar =
true;
1177 g_cm93_zoom_factor = 0;
1178 g_oz_vector_scale =
false;
1179 g_fog_overzoom =
false;
1182 g_bShowMuiZoomButtons =
true;
1184 g_GUIScaleFactor = 0;
1185 g_ChartNotRenderScaleFactor = 2.0;
1189 g_toolbarConfig = _T(
"X.....XX.......XX.XXXXXXXXXXX");
1190 g_bPermanentMOBIcon =
false;
1192 wxString sGPS = _T(
"2;3;;0;0;;0;1;0;0;;0;;1;0;0;0;0");
1195 new_params->bEnabled =
true;
1196 TheConnectionParams()->Add(new_params);
1198 g_default_font_facename = _T(
"Roboto");
1203 pConfig->SetPath(_T (
"/PlugIns/libchartdldr_pi.so" ));
1204 pConfig->Write(_T (
"bEnabled" ),
true);
1206 pConfig->SetPath(_T (
"/PlugIns/libwmm_pi.so" ));
1207 pConfig->Write(_T (
"bEnabled" ),
true);
1209 pConfig->SetPath(_T (
"/Settings/WMM" ));
1210 pConfig->Write(_T (
"ShowIcon" ),
true);
1211 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1213 pConfig->SetPath(_T (
"/PlugIns/libgrib_pi.so" ));
1214 pConfig->Write(_T (
"bEnabled" ),
true);
1216 pConfig->SetPath(_T (
"/PlugIns/libdashboard_pi.so" ));
1217 pConfig->Write(_T (
"bEnabled" ),
true);
1219 pConfig->SetPath(_T (
"/PlugIns/GRIB" ));
1220 pConfig->Write(_T (
"GRIBCtrlBarPosX" ), 100);
1221 pConfig->Write(_T (
"GRIBCtrlBarPosY" ), 0);
1223 pConfig->SetPath(_T (
"/Settings/GRIB" ));
1224 pConfig->Write(_T (
"CursorDataShown" ), 0);
1228 pConfig->SetPath(_T (
"/PlugIns/liboesenc_pi.so" ));
1229 pConfig->Write(_T (
"bEnabled" ),
true);
1231 pConfig->SetPath(_T (
"/Settings/QTFonts" ));
1234 wxString str = _T(
"en_US-b25a3899");
1235 wxString pval = _T(
"StatusBar:Roboto,26,-1,5,75,0,0,0,0,0:rgb(0, 0, 0)");
1236 pConfig->Write(str, pval);
1237 FontMgr::Get().LoadFontNative(&str, &pval);
1240 str = _T(
"en_US-9c3b3a0d");
1241 pval = _T(
"DialogStatusBar:Roboto,18,-1,5,50,0,0,0,0,0:rgb(0, 0, 0)");
1242 pConfig->Write(str, pval);
1243 FontMgr::Get().LoadFontNative(&str, &pval);
1246 pConfig->SetPath(_T (
"/Settings/Others" ));
1247 pConfig->Write(_T(
"TrackLineColour"), _T(
"#C545C3"));
1248 g_colourTrackLineColour.Set(197, 69, 195);
1250 qDebug() <<
"SetDefaultOptions.Config";
1261void OCPNPlatform::SetUpgradeOptions(wxString vNew, wxString vOld) {
1262#ifdef __OCPN__ANDROID__
1264 qDebug() <<
"Upgrade check"
1265 <<
"from: " << vOld.mb_str() <<
" to: " << vNew.mb_str();
1267 if (androidGetVersionCode() > g_AndroidVersionCode) {
1268 qDebug() <<
"Upgrade detected"
1269 <<
"from VC: " << g_AndroidVersionCode
1270 <<
" to VC: " << androidGetVersionCode();
1274 pConfig->SetPath(_T (
"/Settings/GlobalState" ));
1275 pConfig->Write(_T (
"bShowS57Text" ),
true);
1278 g_ChartNotRenderScaleFactor = 2.0;
1279 g_n_ownship_min_mm = 8;
1280 g_toolbarConfig = _T(
"X.....XX.......XX.XXXXXXXXXXX");
1283 pConfig->DeleteGroup(_T (
"/Settings/QTFonts" ));
1284 g_default_font_size = 20;
1285 g_default_font_facename = _T(
"Roboto");
1287 FontMgr::Get().Shutdown();
1290 g_bShowMuiZoomButtons =
true;
1294 pInit_Chart_Dir->Clear();
1296 pConfig->SetPath(_T (
"/Settings/WMM" ));
1297 pConfig->Write(_T (
"ShowIcon" ),
true);
1298 pConfig->Write(_T (
"ShowLiveIcon" ),
true);
1302 g_colourTrackLineColour.Set(197, 69, 195);
1312 if (!vOld.IsSameAs(vNew)) {
1317 wxString UserIconPath = GetPrivateDataDir();
1318 wxChar sep = wxFileName::GetPathSeparator();
1319 if (UserIconPath.Last() != sep) UserIconPath.Append(sep);
1320 UserIconPath.Append(_T(
"UserIcons"));
1322 if (!::wxDirExists(UserIconPath)) {
1323 ::wxMkdir(UserIconPath);
1327 wxString LayersPath = GetPrivateDataDir();
1328 if (LayersPath.Last() != sep) LayersPath.Append(sep);
1329 LayersPath.Append(_T(
"layers"));
1331 if (!::wxDirExists(LayersPath)) {
1332 ::wxMkdir(LayersPath);
1338 g_CmdSoundString = wxString(OCPN_SOUND_CMD);
1339 pConfig->SetPath(_T (
"/Settings" ));
1340 pConfig->Write(_T(
"CmdSoundString" ), g_CmdSoundString);
1344 g_bAIS_GCPA_Alert_Audio =
true;
1345 g_bAIS_SART_Alert_Audio =
true;
1346 g_bAIS_DSC_Alert_Audio =
true;
1349 g_maintoolbar_x = -1;
1352 TideCurrentDataSet.Clear();
1356int OCPNPlatform::platformApplyPrivateSettingsString(wxString settings,
1357 ArrayOfCDI *pDirArray) {
1359#ifdef __OCPN__ANDROID__
1360 ret_val = androidApplySettingsString(settings, pDirArray);
1366void OCPNPlatform::applyExpertMode(
bool mode) {
1367#ifdef __OCPN__ANDROID__
1369 g_bBasicMenus = !mode;
1373wxString OCPNPlatform::GetSupplementalLicenseString() {
1375#ifdef __OCPN__ANDROID__
1376 lic = androidGetSupplementalLicense();
1386static wxString ExpandPaths(wxString paths,
OCPNPlatform *platform);
1389int OCPNPlatform::DoFileSelectorDialog(wxWindow *parent, wxString *file_spec,
1390 wxString Title, wxString initDir,
1391 wxString suggestedName,
1392 wxString wildcard) {
1394 int result = wxID_CANCEL;
1396#ifdef __OCPN__ANDROID__
1398 wxString idir = initDir;
1399 if (initDir.StartsWith(
1401 idir = GetWritableDocumentsDir();
1403 result = androidFileChooser(&file, idir, Title, suggestedName, wildcard);
1404 if (file_spec) *file_spec = file;
1406 long flag = wxFD_DEFAULT_STYLE;
1407 if (suggestedName.Length()) {
1411 wxString mask = wildcard;
1412 if (wxNOT_FOUND != mask.Find(_T(
"gpx")))
1413 mask.Prepend(_T(
"GPX files (*.gpx)|"));
1415 wxFileDialog *psaveDialog =
1416 new wxFileDialog(parent, Title, initDir, suggestedName, mask, flag);
1424 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1427 result = psaveDialog->ShowModal();
1430 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1433 if (file_spec) *file_spec = psaveDialog->GetPath();
1441int OCPNPlatform::DoDirSelectorDialog(wxWindow *parent, wxString *file_spec,
1442 wxString Title, wxString initDir,
1445 int result = wxID_CANCEL;
1447#ifdef __OCPN__ANDROID__
1449 wxString idir = initDir;
1450 if (initDir.StartsWith(
1452 idir = GetWritableDocumentsDir();
1454 result = androidFileChooser(&dir, idir, Title, _T(
""), _T(
""),
true,
1456 if (file_spec) *file_spec = dir;
1458 wxDirDialog *dirSelector =
new wxDirDialog(
1459 parent, Title, initDir, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1461 wxFont *qFont = GetOCPNScaledFont(_(
"Dialog"));
1462 dirSelector->SetFont(*qFont);
1469 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
1472 result = dirSelector->ShowModal();
1475 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
1478 if (result == wxID_CANCEL) {
1481 *file_spec = dirSelector->GetPath();
1491MyConfig *OCPNPlatform::GetConfigObject() {
1494 result =
new MyConfig(GetConfigFileName());
1503bool OCPNPlatform::hasInternalGPS(wxString profile) {
1504#ifdef __OCPN__ANDROID__
1505 bool t = androidDeviceHasGPS();
1519void OCPNPlatform::ShowBusySpinner(
void) {
1520#ifdef __OCPN__ANDROID__
1521 androidShowBusyIcon();
1523#if wxCHECK_VERSION(2, 9, 0)
1525 { ::wxBeginBusyCursor(); }
1530void OCPNPlatform::HideBusySpinner(
void) {
1531#ifdef __OCPN__ANDROID__
1532 androidHideBusyIcon();
1534#if wxCHECK_VERSION(2, 9, 0)
1536 { ::wxEndBusyCursor(); }
1541double OCPNPlatform::GetDisplayDensityFactor() {
1542#ifdef __OCPN__ANDROID__
1543 return getAndroidDisplayDensity();
1549long OCPNPlatform::GetDefaultToolbarOrientation() {
1550#ifndef __OCPN__ANDROID__
1551 return wxTB_VERTICAL;
1553 return wxTB_VERTICAL;
1557int OCPNPlatform::GetStatusBarFieldCount() {
1558#ifdef __OCPN__ANDROID__
1563 wxFont *templateFont = FontMgr::Get().GetFont(_(
"StatusBar"), 0);
1564 dc.SetFont(*templateFont);
1567 dc.GetTextExtent(_T(
"WWWWWW"), &width, NULL, NULL, NULL, templateFont);
1568 double font_size_pix = (double)width / 6.0;
1570 wxSize dispSize = getDisplaySize();
1572 double nChars = dispSize.x / font_size_pix;
1582 return STAT_FIELD_COUNT;
1586double OCPNPlatform::getFontPointsperPixel(
void) {
1587 double pt_per_pixel = 1.0;
1597 if (m_pt_per_pixel == 0) {
1601 wxFont *f = FontMgr::Get().FindOrCreateFont(
1602 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
1603 wxString(_T (
"" )), wxFONTENCODING_SYSTEM);
1607 dc.GetTextExtent(_T(
"H"), &width, &height, NULL, NULL, f);
1609 if (height > 0) m_pt_per_pixel = 12.0 / (double)height;
1611 if (m_pt_per_pixel > 0) pt_per_pixel = m_pt_per_pixel;
1614 return pt_per_pixel;
1617wxSize OCPNPlatform::getDisplaySize() {
1618#ifdef __OCPN__ANDROID__
1619 return getAndroidDisplayDimensions();
1621 if (m_displaySize.x < 10)
1622 m_displaySize = ::wxGetDisplaySize();
1623 return m_displaySize;
1627double OCPNPlatform::GetDisplaySizeMM() {
1628 if (m_displaySizeMMOverride > 0)
return m_displaySizeMMOverride;
1630 if (m_displaySizeMM.x < 1) m_displaySizeMM = wxGetDisplaySizeMM();
1632 double ret = m_displaySizeMM.GetWidth();
1636 GdkScreen *screen = gdk_screen_get_default();
1637 wxSize resolution = getDisplaySize();
1638 double gdk_monitor_mm;
1639 double ratio = (double)resolution.GetWidth() / (double)resolution.GetHeight();
1640 if( std::abs(ratio - 32.0/10.0) < std::abs(ratio - 16.0/10.0) ) {
1642 gdk_monitor_mm = gdk_screen_get_width_mm(screen);
1644 gdk_monitor_mm = gdk_screen_get_monitor_width_mm(screen, 0);
1646 if(gdk_monitor_mm > 0)
1647 ret = gdk_monitor_mm;
1654 if (!m_bdisableWindowsDisplayEnum) {
1655 if (GetWindowsMonitorSize(&w, &h) && (w > 100)) {
1656 m_displaySizeMM == wxSize(w, h);
1659 m_bdisableWindowsDisplayEnum =
true;
1665 ret = GetMacMonitorSize();
1668#ifdef __OCPN__ANDROID__
1669 ret = GetAndroidDisplaySize();
1673 msg.Printf(_T(
"Detected display size (horizontal): %d mm"), (
int)ret);
1679double OCPNPlatform::GetDisplayAreaCM2() {
1680 double size1 = GetDisplaySizeMM();
1681 wxSize sz = getDisplaySize();
1684 ratio = (double)sz.x / (
double)sz.y;
1686 ratio = (double)sz.y / (
double)sz.x;
1688 double area = size1 * (size1 * ratio) / 100.;
1693void OCPNPlatform::SetDisplaySizeMM(
double sizeMM) {
1694 m_displaySizeMMOverride = sizeMM;
1697double OCPNPlatform::GetDisplayDPmm() {
1698#ifdef __OCPN__ANDROID__
1699 return getAndroidDPmm();
1701 double r = getDisplaySize().x;
1702 return r / GetDisplaySizeMM();
1706unsigned int OCPNPlatform::GetSelectRadiusPix() {
1707 return GetDisplayDPmm() *
1708 (g_btouch ? g_selection_radius_touch_mm : g_selection_radius_mm);
1711bool OCPNPlatform::GetFullscreen() {
1713#ifdef __OCPN__ANDROID__
1714 bret = androidGetFullscreen();
1722bool OCPNPlatform::SetFullscreen(
bool bFull) {
1724#ifdef __OCPN__ANDROID__
1725 bret = androidSetFullscreen(bFull);
1732void OCPNPlatform::PositionAISAlert(wxWindow *alert_window) {
1733#ifndef __OCPN__ANDROID__
1735 alert_window->SetSize(g_ais_alert_dialog_x, g_ais_alert_dialog_y,
1736 g_ais_alert_dialog_sx, g_ais_alert_dialog_sy);
1740 alert_window->SetSize(g_ais_alert_dialog_x, g_ais_alert_dialog_y,
1741 g_ais_alert_dialog_sx, g_ais_alert_dialog_sy);
1742 alert_window->Centre();
1748wxDirDialog *OCPNPlatform::AdjustDirDialogFont(wxWindow *container,
1750 wxDirDialog *ret_dlg = dlg;
1754 dlg->SetSize(container->GetSize());
1757 wxSize sds = dlg->GetSize();
1758 wxSize ss = container->GetSize();
1763 wxString msg = dlg->GetMessage();
1764 wxString default_dir = dlg->GetPath();
1768 ret_dlg =
new wxDirDialog(NULL, msg, default_dir,
1769 wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
1771 wxFont *dialogFont = GetOCPNScaledFont(_(
"Dialog"));
1772 wxFont *smallFont =
new wxFont(*dialogFont);
1773 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1775 ret_dlg->SetFont(*smallFont);
1777 ret_dlg->SetSize(container->GetSize());
1785wxFileDialog *OCPNPlatform::AdjustFileDialogFont(wxWindow *container,
1786 wxFileDialog *dlg) {
1787 wxFileDialog *ret_dlg = dlg;
1791 dlg->SetSize(container->GetSize());
1794 wxSize sds = dlg->GetSize();
1795 wxSize ss = container->GetSize();
1800 wxString msg = dlg->GetMessage();
1801 wxString default_dir = dlg->GetDirectory();
1802 wxString default_file = dlg->GetFilename();
1803 wxString wildcard = dlg->GetWildcard();
1807 ret_dlg =
new wxFileDialog(NULL, msg, default_dir, default_file, wildcard,
1810 wxFont *dialogFont = GetOCPNScaledFont(_(
"Dialog"));
1811 wxFont *smallFont =
new wxFont(*dialogFont);
1812 smallFont->SetPointSize((smallFont->GetPointSize() / 2) +
1814 ret_dlg->SetFont(*smallFont);
1816 ret_dlg->SetSize(container->GetSize());
1824double OCPNPlatform::GetToolbarScaleFactor(
int GUIScaleFactor) {
1826#ifdef __OCPN__ANDROID__
1832 wxSize style_tool_size(32, 32);
1834 if (g_StyleManager) {
1836 if (style) style_tool_size = style->GetToolSize();
1838 double tool_size = style_tool_size.x;
1844 double premult = 1.0;
1845 if (g_config_display_size_manual && (g_config_display_size_mm > 0)) {
1846 double target_size = 9.0;
1848 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
1849 premult = target_size / basic_tool_size_mm;
1852 premult = wxMax(45 * getAndroidDisplayDensity(), 45) /
1858 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
1862 rv = premult * postmult;
1863 rv = wxMin(rv, getAndroidDisplayDensity() *
1867 double premult = 1.0;
1869 if (g_bresponsive) {
1872 wxSize style_tool_size = style->GetToolSize();
1873 double tool_size = style_tool_size.x;
1877 double target_size = 9.0;
1879 double basic_tool_size_mm = tool_size / GetDisplayDPmm();
1880 premult = target_size / basic_tool_size_mm;
1884 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
1886 rv = premult * postmult;
1887 rv = wxMin(rv, 3.0);
1888 rv = wxMax(rv, 0.5);
1890 rv /= g_BasePlatform->GetDisplayDIPMult(gFrame);
1897double OCPNPlatform::GetCompassScaleFactor(
int GUIScaleFactor) {
1899#ifdef __OCPN__ANDROID__
1904 if (g_bresponsive) {
1907 wxSize style_tool_size = style->GetToolSize();
1908 double compass_size = style_tool_size.x;
1914 double premult = wxMax(28 * getAndroidDisplayDensity(), 50) / compass_size;
1917 double postmult = exp(GUIScaleFactor * (log(2.0) / 5.0));
1920 rv = premult * postmult;
1921 rv = wxMin(rv, getAndroidDisplayDensity() *
1926 double premult = 1.0;
1928 if (g_bresponsive) {
1930 wxSize style_tool_size = style->GetToolSize();
1931 double compass_size = style_tool_size.x;
1934 double target_size = 6.0;
1936 double basic_tool_size_mm = compass_size / GetDisplayDPmm();
1937 premult = target_size / basic_tool_size_mm;
1940 double postmult = exp(GUIScaleFactor * (0.693 / 5.0));
1942 rv = premult * postmult;
1944 rv = wxMin(rv, 3.0);
1945 rv = wxMax(rv, 0.5);
1947#if defined(__WXOSX__) || defined(__WXGTK3__)
1950 rv *= gFrame->GetContentScaleFactor();
1953 rv /= g_BasePlatform->GetDisplayDIPMult(gFrame);
1960float OCPNPlatform::GetChartScaleFactorExp(
float scale_linear) {
1961 double factor = 1.0;
1962#ifndef __OCPN__ANDROID__
1963 factor = exp(scale_linear * (log(3.0) / 5.0));
1968 factor = exp(scale_linear * (0.693 / 5.0));
1972 factor = wxMax(factor, .5);
1973 factor = wxMin(factor, 6.);
1978float OCPNPlatform::GetMarkScaleFactorExp(
float scale_linear) {
1979 if(scale_linear <= 0)
1980 return GetChartScaleFactorExp(scale_linear);
1982 return GetChartScaleFactorExp(scale_linear-1);
1999bool OCPNPlatform::hasInternalBT(wxString profile) {
2000#ifdef __OCPN__ANDROID__
2001 bool t = androidDeviceHasBlueTooth();
2010bool OCPNPlatform::startBluetoothScan() {
2011#ifdef __OCPN__ANDROID__
2012 return androidStartBluetoothScan();
2019bool OCPNPlatform::stopBluetoothScan() {
2020#ifdef __OCPN__ANDROID__
2021 return androidStopBluetoothScan();
2028wxArrayString OCPNPlatform::getBluetoothScanResults() {
2029 wxArrayString ret_val;
2030#ifdef __OCPN__ANDROID__
2031 return androidGetBluetoothScanResults();
2034 ret_val.Add(_T(
"line 1"));
2035 ret_val.Add(_T(
"line 2"));
2036 ret_val.Add(_T(
"line 3"));
2046bool OCPNPlatform::AllowAlertDialog(
const wxString &class_name) {
2047#ifdef __OCPN__ANDROID__
2051 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
2053 wxWindow *win = node->GetData();
2054 if (win->IsShown()) nTLW++;
2056 node = node->GetNext();
2060 return (g_running && !g_boptionsactive && (nTLW <= 4));
2067void OCPNPlatform::setChartTypeMaskSel(
int mask, wxString &indicator) {
2068#ifdef __OCPN__ANDROID__
2069 return androidSetChartTypeMaskSel(mask, indicator);
2073#ifdef __OCPN__ANDROID__
2074QString g_qtStyleSheet;
2076bool LoadQtStyleSheet(wxString &sheet_file) {
2077 if (wxFileExists(sheet_file)) {
2080 QString file(sheet_file.c_str());
2082 File.open(QFile::ReadOnly);
2083 g_qtStyleSheet = QLatin1String(File.readAll());
2093QString getQtStyleSheet(
void) {
return g_qtStyleSheet; }
2098bool OCPNPlatform::isPlatformCapable(
int flag) {
2099#ifndef __OCPN__ANDROID__
2102 if (flag == PLATFORM_CAP_PLUGINS) {
2104 wxString tsdk(android_plat_spc.msdk);
2105 if (tsdk.ToLong(&platver)) {
2106 if (platver >= 11)
return true;
2108 }
else if (flag == PLATFORM_CAP_FASTPAN) {
2110 wxString tsdk(android_plat_spc.msdk);
2111 if (tsdk.ToLong(&platver)) {
2112 if (platver >= 14)
return true;
2120void OCPNPlatform::DoHelpDialog(
void) {
2121#ifndef __OCPN__ANDROID__
2125 g_pAboutDlg->SetFocus();
2127 g_pAboutDlg->Show();
2130 if (!g_pAboutDlgLegacy)
2131 g_pAboutDlgLegacy =
new about(gFrame, GetSharedDataDir());
2133 g_pAboutDlgLegacy->SetFocus();
2134 g_pAboutDlgLegacy->Show();
2139void OCPNPlatform::LaunchLocalHelp(
void) {
2140#ifdef __OCPN__ANDROID__
2141 androidLaunchHelpView();
2143 wxString def_lang_canonical = _T(
"en_US");
2146 if (plocale_def_lang)
2147 def_lang_canonical = plocale_def_lang->GetCanonicalName();
2150 wxString help_locn = g_Platform->GetSharedDataDir() + _T(
"doc/help_");
2152 wxString help_try = help_locn + def_lang_canonical + _T(
".html");
2154 if (!::wxFileExists(help_try)) {
2155 help_try = help_locn + _T(
"en_US") + _T(
".html");
2157 if (!::wxFileExists(help_try)) {
2158 help_try = help_locn + _T(
"web") + _T(
".html");
2161 if (!::wxFileExists(help_try))
return;
2164 wxLaunchDefaultBrowser(wxString(_T(
"file:///")) + help_try);
2168void OCPNPlatform::platformLaunchDefaultBrowser(wxString URL) {
2169#ifdef __OCPN__ANDROID__
2170 androidLaunchBrowser(URL);
2172 ::wxLaunchDefaultBrowser(URL);
2182EVT_PAINT(OCPNColourPickerCtrl::OnPaint)
2191 const wxColour &initial,
2193 const wxSize &size,
long style,
2194 const wxValidator &validator,
2195 const wxString &name) {
2196 Create(parent,
id, initial, pos, size, style, validator, name);
2199bool OCPNColourPickerCtrl::Create(wxWindow *parent, wxWindowID
id,
2200 const wxColour &col,
const wxPoint &pos,
2201 const wxSize &size,
long style,
2202 const wxValidator &validator,
2203 const wxString &name) {
2204 m_bitmap = wxBitmap(60, 13);
2207 if (!wxBitmapButton::Create(parent,
id, m_bitmap, pos, size,
2208 style | wxBU_AUTODRAW, validator, name)) {
2209 wxFAIL_MSG(wxT(
"OCPNColourPickerCtrl creation failed"));
2214 Connect(GetId(), wxEVT_BUTTON,
2215 wxCommandEventHandler(OCPNColourPickerCtrl::OnButtonClick), NULL,
2225void OCPNColourPickerCtrl::InitColourData() {
2227 ms_data.SetChooseFull(
true);
2228 unsigned char grey = 0;
2229 for (
int i = 0; i < 16; i++, grey += 16)
2232 wxColour colour(grey, grey, grey);
2233 ms_data.SetCustomColour(i, colour);
2238void OCPNColourPickerCtrl::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
2239#ifdef __OCPN__ANDROID__
2240 unsigned int cco = 0;
2243 cco |= m_colour.Red();
2245 cco |= m_colour.Green();
2247 cco |= m_colour.Blue();
2248 unsigned int cc = androidColorPicker(cco);
2251 unsigned char blue = (
unsigned char)cc % 256;
2252 unsigned char green = (
unsigned char)(cc >> 8) % 256;
2254 unsigned char red = (
unsigned char)(cc >> 16) % 256;
2255 cnew.Set(red, green, blue);
2261 ms_data.SetColour(m_colour);
2264 wxColourDialog dlg(
this, &ms_data);
2265 if (dlg.ShowModal() == wxID_OK) {
2266 ms_data = dlg.GetColourData();
2267 SetColour(ms_data.GetColour());
2272void OCPNColourPickerCtrl::UpdateColour() {
2273#ifndef __OCPN__ANDROID__
2274 SetBitmapLabel(wxBitmap());
2277 wxMemoryDC dc(m_bitmap);
2278 dc.SetPen(*wxTRANSPARENT_PEN);
2279 dc.SetBrush(wxBrush(m_colour));
2280 dc.DrawRectangle(0, 0, m_bitmap.GetWidth(), m_bitmap.GetHeight());
2282 dc.SelectObject(wxNullBitmap);
2283 SetBitmapLabel(m_bitmap);
2286void OCPNColourPickerCtrl::SetColour(wxColour &c) {
2288 m_bitmap = wxBitmap(GetSize().x - 20, GetSize().y - 20);
2292wxColour OCPNColourPickerCtrl::GetColour(
void) {
return m_colour; }
2294wxSize OCPNColourPickerCtrl::DoGetBestSize()
const {
2295 wxSize sz(wxBitmapButton::DoGetBestSize());
2302 if (HasFlag(wxCLRP_SHOW_LABEL))
return sz;
2310void OCPNColourPickerCtrl::OnPaint(wxPaintEvent &event) {
2313 int offset_x = (GetSize().x - m_bitmap.GetWidth()) / 2;
2314 int offset_y = (GetSize().y - m_bitmap.GetHeight()) / 2;
2316 dc.SetPen(*wxTRANSPARENT_PEN);
2317 dc.SetBrush(wxBrush(m_colour));
2318 dc.DrawRectangle(offset_x, offset_y, m_bitmap.GetWidth(),
2319 m_bitmap.GetHeight());
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.