OpenCPN Partial API docs
Loading...
Searching...
No Matches
navutil.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: Navigation Utility Functions
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25
26#include <wx/wxprec.h>
27
28#ifdef __MINGW32__
29#undef IPV6STRICT // mingw FTBS fix: missing struct ip_mreq
30#include <windows.h>
31#endif
32
33#include <stdlib.h>
34#include <time.h>
35#include <locale>
36#include <list>
37
38#ifndef WX_PRECOMP
39#include <wx/wx.h>
40#endif // precompiled headers
41
42#include <wx/bmpcbox.h>
43#include <wx/dir.h>
44#include <wx/filename.h>
45#include <wx/graphics.h>
46#include <wx/image.h>
47#include <wx/listbook.h>
48#include <wx/listimpl.cpp>
49#include <wx/progdlg.h>
50#include <wx/sstream.h>
51#include <wx/tglbtn.h>
52#include <wx/timectrl.h>
53#include <wx/tokenzr.h>
54
55#include "model/ais_decoder.h"
57#include "model/cmdline.h"
58#include "model/config_vars.h"
59#include "model/conn_params.h"
60#include "model/cutil.h"
61#include "model/geodesic.h"
62#include "model/georef.h"
63#include "model/idents.h"
64#include "model/multiplexer.h"
65#include "model/nav_object_database.h"
66#include "model/navutil_base.h"
67#include "model/navobj_db.h"
68#include "model/own_ship.h"
69#include "model/plugin_comm.h"
70#include "model/route.h"
71#include "model/routeman.h"
72#include "model/select.h"
73#include "model/track.h"
74
75#include "ais.h"
76#include "CanvasConfig.h"
77#include "chartbase.h"
78#include "chartdb.h"
79#include "chcanv.h"
80#include "cm93.h"
81#include "config.h"
82#include "ConfigMgr.h"
83#include "displays.h"
84#include "dychart.h"
85#include "FontMgr.h"
86#include "Layer.h"
87#include "navutil.h"
88#include "nmea0183.h"
89#include "observable_globvar.h"
90#include "ocpndc.h"
91#include "ocpn_frame.h"
92#include "ocpn_plugin.h"
93#include "OCPNPlatform.h"
94#include "OCPN_Sound.h"
95#include "s52plib.h"
96#include "s52utils.h"
97#include "snd_config.h"
98#include "styles.h"
99
100#ifdef ocpnUSE_GL
101#include "glChartCanvas.h"
102#endif
103
104#ifdef __ANDROID__
105#include "androidUTIL.h"
106#endif
107
108// Statics
109
110extern OCPNPlatform *g_Platform;
111extern MyFrame *gFrame;
112
113extern double g_ChartNotRenderScaleFactor;
114extern int g_restore_stackindex;
115extern int g_restore_dbindex;
116extern RouteList *pRouteList;
117extern std::vector<Track *> g_TrackList;
118extern LayerList *pLayerList;
119extern MyConfig *pConfig;
120extern double vLat, vLon;
121extern double kLat, kLon;
122extern ColorScheme global_color_scheme;
123extern int g_nbrightness;
124extern bool g_bShowStatusBar;
125extern bool g_bUIexpert;
126extern bool g_bFullscreen;
127
128extern wxString g_SENCPrefix;
129extern wxString g_UserPresLibData;
130
131extern wxString *pInit_Chart_Dir;
132extern wxString gWorldMapLocation;
133extern wxString gWorldShapefileLocation;
134
135extern bool s_bSetSystemTime;
136extern bool g_bDisplayGrid; // Flag indicating if grid is to be displayed
137extern bool g_bPlayShipsBells;
138extern int g_iSoundDeviceIndex;
139extern bool g_bFullscreenToolbar;
140extern bool g_bShowLayers;
141extern bool g_bTransparentToolbar;
142extern bool g_bPermanentMOBIcon;
143
144extern bool g_bShowDepthUnits;
145extern bool g_bAutoAnchorMark;
146extern bool g_bskew_comp;
147extern bool g_bopengl;
148extern bool g_bSoftwareGL;
149extern bool g_bsmoothpanzoom;
150extern bool g_fog_overzoom;
151extern double g_overzoom_emphasis_base;
152extern bool g_oz_vector_scale;
153extern double g_plus_minus_zoom_factor;
154extern bool g_bShowOutlines;
155extern bool g_bShowActiveRouteHighway;
156extern bool g_bShowRouteTotal;
157extern int g_nAWDefault;
158extern int g_nAWMax;
159extern bool g_btenhertz;
160extern bool g_declutter_anchorage;
161
162extern int g_nframewin_x;
163extern int g_nframewin_y;
164extern int g_nframewin_posx;
165extern int g_nframewin_posy;
166extern bool g_bframemax;
167
168extern wxString g_VisibleLayers;
169extern wxString g_InvisibleLayers;
170extern wxString g_VisiNameinLayers;
171extern wxString g_InVisiNameinLayers;
172
173extern wxArrayString *pMessageOnceArray;
174
175// LIVE ETA OPTION
176extern bool g_bShowLiveETA;
177extern double g_defaultBoatSpeed;
178extern double g_defaultBoatSpeedUserUnit;
179
180extern bool g_bUseOnlyConfirmedAISName;
181extern int g_ScaledNumWeightSOG;
182
183extern int g_S57_dialog_sx, g_S57_dialog_sy;
184int g_S57_extradialog_sx, g_S57_extradialog_sy;
185
186extern int g_iNavAidRadarRingsNumberVisible;
187extern bool g_bNavAidRadarRingsShown;
188extern float g_fNavAidRadarRingsStep;
189extern int g_pNavAidRadarRingsStepUnits;
190extern bool g_bWayPointPreventDragging;
191extern bool g_bConfirmObjectDelete;
192extern wxColour g_colourOwnshipRangeRingsColour;
193
194extern bool g_bEnableZoomToCursor;
195extern wxString g_toolbarConfig;
196extern double g_TrackIntervalSeconds;
197
198extern int g_nCacheLimit;
199extern int g_memCacheLimit;
200
201extern bool g_bGDAL_Debug;
202extern bool g_bDebugCM93;
203extern bool g_bDebugS57;
204
205extern double g_ownship_predictor_minutes;
206extern int g_cog_predictor_style;
207extern wxString g_cog_predictor_color;
208extern int g_cog_predictor_endmarker;
209extern int g_cog_predictor_width;
210extern int g_ownship_HDTpredictor_style;
211extern wxString g_ownship_HDTpredictor_color;
212extern int g_ownship_HDTpredictor_endmarker;
213extern int g_ownship_HDTpredictor_width;
214extern double g_ownship_HDTpredictor_miles;
215
216extern bool g_own_ship_sog_cog_calc;
217extern int g_own_ship_sog_cog_calc_damp_sec;
218
219extern bool g_bShowMenuBar;
220extern bool g_bShowCompassWin;
221
222extern s52plib *ps52plib;
223
224extern int g_cm93_zoom_factor;
225extern bool g_b_legacy_input_filter_behaviour;
226extern bool g_bShowDetailSlider;
227extern int g_detailslider_dialog_x, g_detailslider_dialog_y;
228
229extern bool g_bUseGreenShip;
230
231extern unsigned g_OwnShipmmsi;
232extern int g_OwnShipIconType;
233extern double g_n_ownship_length_meters;
234extern double g_n_ownship_beam_meters;
235extern double g_n_gps_antenna_offset_y;
236extern double g_n_gps_antenna_offset_x;
237extern int g_n_ownship_min_mm;
238extern int g_maxzoomin;
239
240extern bool g_bShowShipToActive;
241extern int g_shipToActiveStyle;
242extern int g_shipToActiveColor;
243
244extern bool g_bPreserveScaleOnX;
245extern bool g_bsimplifiedScalebar;
246
247extern bool g_bUseGLL;
248
249extern wxString g_locale;
250extern wxString g_localeOverride;
251
252extern bool g_bCourseUp;
253extern bool g_bLookAhead;
254extern int g_COGAvgSec;
255extern bool g_bShowChartBar;
256
257extern int g_MemFootMB;
258
259extern wxString g_AW1GUID;
260extern wxString g_AW2GUID;
261extern int g_BSBImgDebug;
262
263extern int n_NavMessageShown;
264extern wxString g_config_version_string;
265
266extern wxString g_CmdSoundString;
267
268extern bool g_bDebugGPSD;
269
270int g_navobjbackups;
271
272extern bool g_bQuiltEnable;
273extern bool g_bFullScreenQuilt;
274extern bool g_bQuiltStart;
275
276extern int g_SkewCompUpdatePeriod;
277
278extern int g_maintoolbar_x;
279extern int g_maintoolbar_y;
280extern long g_maintoolbar_orient;
281
282extern int g_lastClientRectx;
283extern int g_lastClientRecty;
284extern int g_lastClientRectw;
285extern int g_lastClientRecth;
286
287extern bool g_bHighliteTracks;
288extern int g_cog_predictor_width;
289extern int g_ais_cog_predictor_width;
290
291extern wxColour g_colourTrackLineColour;
292extern wxString g_default_wp_icon;
293
294extern ChartGroupArray *g_pGroupArray;
295
296extern bool g_bDebugOGL;
297extern int g_tcwin_scale;
298extern wxString g_uploadConnection;
299
300extern ocpnStyle::StyleManager *g_StyleManager;
301extern std::vector<std::string> TideCurrentDataSet;
302extern wxString g_TCData_Dir;
303
304extern bool g_bresponsive;
305
306extern bool g_bGLexpert;
307
308extern int g_SENC_LOD_pixels;
309extern ArrayOfMmsiProperties g_MMSI_Props_Array;
310
311extern int g_chart_zoom_modifier_raster;
312extern int g_chart_zoom_modifier_vector;
313
314extern bool g_bShowTrackPointTime;
315
316extern bool g_bAdvanceRouteWaypointOnArrivalOnly;
317extern double g_display_size_mm;
318extern std::vector<size_t> g_config_display_size_mm;
319extern bool g_config_display_size_manual;
320
321extern bool g_benable_rotate;
322extern bool g_bEmailCrashReport;
323
324extern int g_default_font_size;
325extern wxString g_default_font_facename;
326
327extern bool g_bAutoHideToolbar;
328extern int g_nAutoHideToolbar;
329extern int g_GUIScaleFactor;
330extern int g_ChartScaleFactor;
331extern float g_MarkScaleFactorExp;
332
333extern int g_ShipScaleFactor;
334extern float g_ShipScaleFactorExp;
335extern int g_ENCSoundingScaleFactor;
336extern int g_ENCTextScaleFactor;
337
338extern int g_iENCToolbarPosX;
339extern int g_iENCToolbarPosY;
340extern bool g_bRollover;
341
342extern bool g_bSpaceDropMark;
343
344extern bool g_bShowTide;
345extern bool g_bShowCurrent;
346
347extern wxString g_uiStyle;
348extern bool g_btrackContinuous;
349extern bool g_useMUI;
350
351int g_nCPUCount;
352
353extern unsigned int g_canvasConfig;
354extern wxString g_lastAppliedTemplateGUID;
355
356extern int g_route_prop_x, g_route_prop_y;
357extern int g_route_prop_sx, g_route_prop_sy;
358extern int g_AndroidVersionCode;
359
360extern wxString g_ObjQFileExt;
361
362wxString g_gpx_path;
363bool g_bLayersLoaded;
364bool g_bShowMuiZoomButtons = true;
365
366double g_mouse_zoom_sensitivity;
367int g_mouse_zoom_sensitivity_ui;
368
369#ifdef ocpnUSE_GL
370extern ocpnGLOptions g_GLOptions;
371#endif
372
373#if !defined(NAN)
374static const long long lNaN = 0xfff8000000000000;
375#define NAN (*(double *)&lNaN)
376#endif
377
378// Layer helper function
379
380wxString GetLayerName(int id) {
381 wxString name(_T("unknown layer"));
382 if (id <= 0) return (name);
383 LayerList::iterator it;
384 int index = 0;
385 for (it = (*pLayerList).begin(); it != (*pLayerList).end(); ++it, ++index) {
386 Layer *lay = (Layer *)(*it);
387 if (lay->m_LayerID == id) return (lay->m_LayerName);
388 }
389 return (name);
390}
391
392// Helper conditional file name dir slash
393void appendOSDirSlash(wxString *pString);
394
395//-----------------------------------------------------------------------------
396// MyConfig Implementation
397//-----------------------------------------------------------------------------
398//
399
400MyConfig::MyConfig(const wxString &LocalFileName)
401 : wxFileConfig(_T (""), _T (""), LocalFileName, _T (""),
402 wxCONFIG_USE_LOCAL_FILE) {}
403
404MyConfig::~MyConfig() {}
405
406int MyConfig::LoadMyConfig() {
407 int display_width, display_height;
408 display_width = g_monitor_info[g_current_monitor].width;
409 display_height = g_monitor_info[g_current_monitor].height;
410
411 // Set up any defaults not set elsewhere
412 g_useMUI = true;
413 g_TalkerIdText = _T("EC");
414 g_maxWPNameLength = 6;
415 g_NMEAAPBPrecision = 3;
416
417#ifdef ocpnUSE_GL
418 g_GLOptions.m_bUseAcceleratedPanning = true;
419 g_GLOptions.m_GLPolygonSmoothing = true;
420 g_GLOptions.m_GLLineSmoothing = true;
421 g_GLOptions.m_iTextureDimension = 512;
422 g_GLOptions.m_iTextureMemorySize = 128;
423 if (!g_bGLexpert) {
424 g_GLOptions.m_iTextureMemorySize =
425 wxMax(128, g_GLOptions.m_iTextureMemorySize);
426 g_GLOptions.m_bTextureCompressionCaching =
427 g_GLOptions.m_bTextureCompression;
428 }
429#endif
430
431 g_maintoolbar_orient = wxTB_HORIZONTAL;
432 g_iENCToolbarPosX = -1;
433 g_iENCToolbarPosY = -1;
434 g_restore_dbindex = -1;
435 g_ChartNotRenderScaleFactor = 1.5;
436 g_detailslider_dialog_x = 200L;
437 g_detailslider_dialog_y = 200L;
438 g_SENC_LOD_pixels = 2;
439 g_SkewCompUpdatePeriod = 10;
440
441 g_bShowStatusBar = 1;
442 g_bShowCompassWin = 1;
443 g_iSoundDeviceIndex = -1;
444 g_bFullscreenToolbar = 1;
445 g_bTransparentToolbar = 0;
446 g_bShowLayers = 1;
447 g_bShowDepthUnits = 1;
448 g_bShowActiveRouteHighway = 1;
449 g_bShowChartBar = 1;
450 g_defaultBoatSpeed = 6.0;
451 g_ownship_predictor_minutes = 5;
452 g_cog_predictor_style = 105;
453 g_cog_predictor_color = _T("rgb(255,0,0)" );
454 g_cog_predictor_endmarker = 1;
455 g_ownship_HDTpredictor_style = 105;
456 g_ownship_HDTpredictor_color = _T("rgb(255,0,0)" );
457 g_ownship_HDTpredictor_endmarker = 1;
458 g_ownship_HDTpredictor_width = 0;
459 g_cog_predictor_width = 3;
460 g_ownship_HDTpredictor_miles = 1;
461 g_n_ownship_min_mm = 2;
462 g_own_ship_sog_cog_calc_damp_sec = 1;
463 g_bFullScreenQuilt = 1;
464 g_track_rotate_time_type = TIME_TYPE_COMPUTER;
465 g_bHighliteTracks = 1;
466 g_bPreserveScaleOnX = 1;
467 g_navobjbackups = 5;
468 g_benableAISNameCache = true;
469 g_n_arrival_circle_radius = 0.05;
470 g_plus_minus_zoom_factor = 2.0;
471 g_mouse_zoom_sensitivity = 1.5;
472 g_datetime_format = "UTC";
473
474 g_AISShowTracks_Mins = 20;
475 g_AISShowTracks_Limit = 300.0;
476 g_ShowScaled_Num = 10;
477 g_ScaledNumWeightSOG = 50;
478 g_ScaledNumWeightCPA = 60;
479 g_ScaledNumWeightTCPA = 25;
480 g_ScaledSizeMinimal = 50;
481 g_ScaledNumWeightRange = 75;
482 g_ScaledNumWeightSizeOfT = 25;
483 g_Show_Target_Name_Scale = 250000;
484 g_bWplUsePosition = 0;
485 g_WplAction = 0;
486 g_ais_cog_predictor_width = 3;
487 g_ais_alert_dialog_sx = 200;
488 g_ais_alert_dialog_sy = 200;
489 g_ais_alert_dialog_x = 200;
490 g_ais_alert_dialog_y = 200;
491 g_ais_query_dialog_x = 200;
492 g_ais_query_dialog_y = 200;
493 g_AisTargetList_range = 40;
494 g_AisTargetList_sortColumn = 2; // Column #2 is MMSI
495 g_S57_dialog_sx = 400;
496 g_S57_dialog_sy = 400;
497 g_S57_extradialog_sx = 400;
498 g_S57_extradialog_sy = 400;
499
500 // Reasonable starting point
501 vLat = START_LAT; // display viewpoint
502 vLon = START_LON;
503 gLat = START_LAT; // GPS position, as default
504 gLon = START_LON;
505 g_maxzoomin = 800;
506
507 g_iNavAidRadarRingsNumberVisible = 0;
508 g_bNavAidRadarRingsShown = false;
509 g_fNavAidRadarRingsStep = 1.0;
510 g_pNavAidRadarRingsStepUnits = 0;
511 g_colourOwnshipRangeRingsColour = *wxRED;
512 g_iWaypointRangeRingsNumber = 0;
513 g_fWaypointRangeRingsStep = 1.0;
514 g_iWaypointRangeRingsStepUnits = 0;
515 g_colourWaypointRangeRingsColour = wxColour(*wxRED);
516 g_bConfirmObjectDelete = true;
517
518 g_TrackIntervalSeconds = 60.0;
519 g_TrackDeltaDistance = 0.10;
520 g_route_line_width = 2;
521 g_track_line_width = 2;
522 g_colourTrackLineColour = wxColour(243, 229, 47); // Yellow
523
524 g_tcwin_scale = 100;
525 g_default_wp_icon = _T("triangle");
526 g_default_routepoint_icon = _T("diamond");
527
528 g_nAWDefault = 50;
529 g_nAWMax = 1852;
530 g_ObjQFileExt = _T("txt,rtf,png,html,gif,tif,jpg");
531
532 // Load the raw value, with no defaults, and no processing
533 int ret_Val = LoadMyConfigRaw();
534
535 // Perform any required post processing and validation
536 if (!ret_Val) {
537 g_ChartScaleFactorExp =
538 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
539 g_ShipScaleFactorExp =
540 g_Platform->GetChartScaleFactorExp(g_ShipScaleFactor);
541 g_MarkScaleFactorExp =
542 g_Platform->GetMarkScaleFactorExp(g_ChartScaleFactor);
543
544 g_COGFilterSec = wxMin(g_COGFilterSec, MAX_COGSOG_FILTER_SECONDS);
545 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
546 g_SOGFilterSec = g_COGFilterSec;
547
548 if (!g_bShowTrue && !g_bShowMag) g_bShowTrue = true;
549 g_COGAvgSec =
550 wxMin(g_COGAvgSec, MAX_COG_AVERAGE_SECONDS); // Bound the array size
551
552 if (g_bInlandEcdis) g_bLookAhead = 1;
553
554 if (g_bdisable_opengl) g_bopengl = false;
555
556#ifdef ocpnUSE_GL
557 if (!g_bGLexpert) {
558 g_GLOptions.m_iTextureMemorySize =
559 wxMax(128, g_GLOptions.m_iTextureMemorySize);
560 g_GLOptions.m_bTextureCompressionCaching =
561 g_GLOptions.m_bTextureCompression;
562 }
563#endif
564
565 g_chart_zoom_modifier_raster = wxMin(g_chart_zoom_modifier_raster, 5);
566 g_chart_zoom_modifier_raster = wxMax(g_chart_zoom_modifier_raster, -5);
567 g_chart_zoom_modifier_vector = wxMin(g_chart_zoom_modifier_vector, 5);
568 g_chart_zoom_modifier_vector = wxMax(g_chart_zoom_modifier_vector, -5);
569 g_cm93_zoom_factor = wxMin(g_cm93_zoom_factor, CM93_ZOOM_FACTOR_MAX_RANGE);
570 g_cm93_zoom_factor =
571 wxMax(g_cm93_zoom_factor, (-CM93_ZOOM_FACTOR_MAX_RANGE));
572
573 if ((g_detailslider_dialog_x < 0) ||
574 (g_detailslider_dialog_x > display_width))
575 g_detailslider_dialog_x = 5;
576 if ((g_detailslider_dialog_y < 0) ||
577 (g_detailslider_dialog_y > display_height))
578 g_detailslider_dialog_y = 5;
579
580 g_defaultBoatSpeedUserUnit = toUsrSpeed(g_defaultBoatSpeed, -1);
581 g_n_ownship_min_mm = wxMax(g_n_ownship_min_mm, 2);
582
583 if (g_navobjbackups > 99) g_navobjbackups = 99;
584 if (g_navobjbackups < 0) g_navobjbackups = 0;
585 g_n_arrival_circle_radius = wxClip(g_n_arrival_circle_radius, 0.001, 0.6);
586
587 g_selection_radius_mm = wxMax(g_selection_radius_mm, 0.5);
588 g_selection_radius_touch_mm = wxMax(g_selection_radius_touch_mm, 1.0);
589
590 g_Show_Target_Name_Scale = wxMax(5000, g_Show_Target_Name_Scale);
591
592 if ((g_ais_alert_dialog_x < 0) || (g_ais_alert_dialog_x > display_width))
593 g_ais_alert_dialog_x = 5;
594 if ((g_ais_alert_dialog_y < 0) || (g_ais_alert_dialog_y > display_height))
595 g_ais_alert_dialog_y = 5;
596 if ((g_ais_query_dialog_x < 0) || (g_ais_query_dialog_x > display_width))
597 g_ais_query_dialog_x = 5;
598 if ((g_ais_query_dialog_y < 0) || (g_ais_query_dialog_y > display_height))
599 g_ais_query_dialog_y = 5;
600
601 SwitchInlandEcdisMode(g_bInlandEcdis);
602 if (g_bInlandEcdis)
603 global_color_scheme =
604 GLOBAL_COLOR_SCHEME_DUSK; // startup in duskmode if inlandEcdis
605
606 // Multicanvas Settings
607 LoadCanvasConfigs();
608 }
609
610 return ret_Val;
611}
612
613int MyConfig::LoadMyConfigRaw(bool bAsTemplate) {
614 int read_int;
615 wxString val;
616
617 int display_width, display_height;
618 display_width = g_monitor_info[g_current_monitor].width;
619 display_height = g_monitor_info[g_current_monitor].height;
620
621 // Global options and settings
622 SetPath(_T ( "/Settings" ));
623 Read("ActiveRoute", &g_active_route);
624 Read("PersistActiveRoute", &g_persist_active_route);
625 Read("AlwaysSendRmbRmc", &g_always_send_rmb_rmc);
626 Read(_T ( "LastAppliedTemplate" ), &g_lastAppliedTemplateGUID);
627 Read(_T ( "CompatOS" ), &g_compatOS);
628 Read(_T ( "CompatOsVersion" ), &g_compatOsVersion);
629
630 // Some undocumented values
631 Read(_T ( "ConfigVersionString" ), &g_config_version_string);
632 Read(_T("CmdSoundString"), &g_CmdSoundString, wxString(OCPN_SOUND_CMD));
633 if (wxIsEmpty(g_CmdSoundString)) g_CmdSoundString = wxString(OCPN_SOUND_CMD);
634 Read(_T ( "NavMessageShown" ), &n_NavMessageShown);
635
636 Read(_T ( "AndroidVersionCode" ), &g_AndroidVersionCode);
637
638 Read(_T ( "UIexpert" ), &g_bUIexpert);
639
640 Read(_T ( "UIStyle" ), &g_uiStyle);
641
642 Read(_T ( "NCacheLimit" ), &g_nCacheLimit);
643
644 Read(_T ( "InlandEcdis" ),
645 &g_bInlandEcdis); // First read if in iENC mode as this will override
646 // some config settings
647
648 Read(_T( "SpaceDropMark" ), &g_bSpaceDropMark);
649
650 int mem_limit = 0;
651 Read(_T ( "MEMCacheLimit" ), &mem_limit);
652 if (mem_limit > 0)
653 g_memCacheLimit = mem_limit * 1024; // convert from MBytes to kBytes
654
655 Read(_T ( "UseModernUI5" ), &g_useMUI);
656
657 Read(_T( "NCPUCount" ), &g_nCPUCount);
658
659 Read(_T ( "DebugGDAL" ), &g_bGDAL_Debug);
660 Read(_T ( "DebugNMEA" ), &g_nNMEADebug);
661 Read(_T ( "AnchorWatchDefault" ), &g_nAWDefault);
662 Read(_T ( "AnchorWatchMax" ), &g_nAWMax);
663 Read(_T ( "GPSDogTimeout" ), &gps_watchdog_timeout_ticks);
664 Read(_T ( "DebugCM93" ), &g_bDebugCM93);
665 Read(_T ( "DebugS57" ),
666 &g_bDebugS57); // Show LUP and Feature info in object query
667 Read(_T ( "DebugBSBImg" ), &g_BSBImgDebug);
668 Read(_T ( "DebugGPSD" ), &g_bDebugGPSD);
669 Read(_T ( "MaxZoomScale" ), &g_maxzoomin);
670 g_maxzoomin = wxMax(g_maxzoomin, 50);
671
672 Read(_T ( "DefaultFontSize"), &g_default_font_size);
673 Read(_T ( "DefaultFontFacename"), &g_default_font_facename);
674
675 Read(_T ( "UseGreenShipIcon" ), &g_bUseGreenShip);
676
677 Read(_T ( "AutoHideToolbar" ), &g_bAutoHideToolbar);
678 Read(_T ( "AutoHideToolbarSecs" ), &g_nAutoHideToolbar);
679
680 Read(_T ( "UseSimplifiedScalebar" ), &g_bsimplifiedScalebar);
681 Read(_T ( "ShowTide" ), &g_bShowTide);
682 Read(_T ( "ShowCurrent" ), &g_bShowCurrent);
683
684 wxString size_mm;
685 Read(_T ( "DisplaySizeMM" ), &size_mm);
686
687 Read(_T ( "SelectionRadiusMM" ), &g_selection_radius_mm);
688 Read(_T ( "SelectionRadiusTouchMM" ), &g_selection_radius_touch_mm);
689
690 if (!bAsTemplate) {
691 g_config_display_size_mm.clear();
692 wxStringTokenizer tokenizer(size_mm, ",");
693 while (tokenizer.HasMoreTokens()) {
694 wxString token = tokenizer.GetNextToken();
695 int size;
696 try {
697 size = std::stoi(token.ToStdString());
698 } catch (std::invalid_argument &e) {
699 size = 0;
700 }
701 if (size > 100 && size < 2000) {
702 g_config_display_size_mm.push_back(size);
703 } else {
704 g_config_display_size_mm.push_back(0);
705 }
706 }
707 Read(_T ( "DisplaySizeManual" ), &g_config_display_size_manual);
708 }
709
710 Read(_T ( "GUIScaleFactor" ), &g_GUIScaleFactor);
711
712 Read(_T ( "ChartObjectScaleFactor" ), &g_ChartScaleFactor);
713 Read(_T ( "ShipScaleFactor" ), &g_ShipScaleFactor);
714 Read(_T ( "ENCSoundingScaleFactor" ), &g_ENCSoundingScaleFactor);
715 Read(_T ( "ENCTextScaleFactor" ), &g_ENCTextScaleFactor);
716 Read(_T ( "ObjQueryAppendFilesExt" ), &g_ObjQFileExt);
717
718 // Plugin catalog handler persistent variables.
719 Read("CatalogCustomURL", &g_catalog_custom_url);
720 Read("CatalogChannel", &g_catalog_channel);
721
722 Read("NetmaskBits", &g_netmask_bits);
723
724 // NMEA connection options.
725 if (!bAsTemplate) {
726 Read(_T ( "FilterNMEA_Avg" ), &g_bfilter_cogsog);
727 Read(_T ( "FilterNMEA_Sec" ), &g_COGFilterSec);
728 Read(_T ( "GPSIdent" ), &g_GPS_Ident);
729 Read(_T ( "UseGarminHostUpload" ), &g_bGarminHostUpload);
730 Read(_T ( "UseNMEA_GLL" ), &g_bUseGLL);
731 Read(_T ( "UseMagAPB" ), &g_bMagneticAPB);
732 Read(_T ( "TrackContinuous" ), &g_btrackContinuous, false);
733 Read(_T ( "FilterTrackDropLargeJump" ), &g_trackFilterMax, 1000);
734 }
735
736 Read(_T ( "ShowTrue" ), &g_bShowTrue);
737 Read(_T ( "ShowMag" ), &g_bShowMag);
738
739 wxString umv;
740 Read(_T ( "UserMagVariation" ), &umv);
741 if (umv.Len()) umv.ToDouble(&g_UserVar);
742
743 Read(_T ( "ScreenBrightness" ), &g_nbrightness);
744
745 Read(_T ( "MemFootprintTargetMB" ), &g_MemFootMB);
746
747 Read(_T ( "WindowsComPortMax" ), &g_nCOMPortCheck);
748
749 Read(_T ( "ChartQuilting" ), &g_bQuiltEnable);
750 Read(_T ( "ChartQuiltingInitial" ), &g_bQuiltStart);
751
752 Read(_T ( "CourseUpMode" ), &g_bCourseUp);
753 Read(_T ( "COGUPAvgSeconds" ), &g_COGAvgSec);
754 Read(_T ( "LookAheadMode" ), &g_bLookAhead);
755 Read(_T ( "SkewToNorthUp" ), &g_bskew_comp);
756 Read(_T ( "TenHzUpdate" ), &g_btenhertz, 0);
757 Read(_T ( "DeclutterAnchorage" ), &g_declutter_anchorage, 0);
758
759 Read(_T( "NMEAAPBPrecision" ), &g_NMEAAPBPrecision);
760
761 Read(_T( "TalkerIdText" ), &g_TalkerIdText);
762 Read(_T( "MaxWaypointNameLength" ), &g_maxWPNameLength);
763 Read(_T( "MbtilesMaxLayers" ), &g_mbtilesMaxLayers);
764
765 Read(_T( "ShowTrackPointTime" ), &g_bShowTrackPointTime, true);
766 /* opengl options */
767#ifdef ocpnUSE_GL
768 if (!bAsTemplate) {
769 Read(_T ( "OpenGLExpert" ), &g_bGLexpert, false);
770 Read(_T ( "UseAcceleratedPanning" ), &g_GLOptions.m_bUseAcceleratedPanning,
771 true);
772 Read(_T ( "GPUTextureCompression" ), &g_GLOptions.m_bTextureCompression);
773 Read(_T ( "GPUTextureCompressionCaching" ),
774 &g_GLOptions.m_bTextureCompressionCaching);
775 Read(_T ( "PolygonSmoothing" ), &g_GLOptions.m_GLPolygonSmoothing);
776 Read(_T ( "LineSmoothing" ), &g_GLOptions.m_GLLineSmoothing);
777 Read(_T ( "GPUTextureDimension" ), &g_GLOptions.m_iTextureDimension);
778 Read(_T ( "GPUTextureMemSize" ), &g_GLOptions.m_iTextureMemorySize);
779 Read(_T ( "DebugOpenGL" ), &g_bDebugOGL);
780 Read(_T ( "OpenGL" ), &g_bopengl);
781 Read(_T ( "SoftwareGL" ), &g_bSoftwareGL);
782 }
783#endif
784
785 Read(_T ( "SmoothPanZoom" ), &g_bsmoothpanzoom);
786
787 Read(_T ( "ToolbarX"), &g_maintoolbar_x);
788 Read(_T ( "ToolbarY" ), &g_maintoolbar_y);
789 Read(_T ( "ToolbarOrient" ), &g_maintoolbar_orient);
790 Read(_T ( "GlobalToolbarConfig" ), &g_toolbarConfig);
791
792 Read(_T ( "iENCToolbarX"), &g_iENCToolbarPosX);
793 Read(_T ( "iENCToolbarY"), &g_iENCToolbarPosY);
794
795 Read(_T ( "AnchorWatch1GUID" ), &g_AW1GUID);
796 Read(_T ( "AnchorWatch2GUID" ), &g_AW2GUID);
797
798 Read(_T ( "InitialStackIndex" ), &g_restore_stackindex);
799 Read(_T ( "InitialdBIndex" ), &g_restore_dbindex);
800
801 Read(_T ( "ChartNotRenderScaleFactor" ), &g_ChartNotRenderScaleFactor);
802
803 Read(_T ( "MobileTouch" ), &g_btouch);
804
805// "Responsive graphics" option deprecated in O58+
806// Read(_T ( "ResponsiveGraphics" ), &g_bresponsive);
807#ifdef __ANDROID__
808 g_bresponsive = true;
809#else
810 g_bresponsive = false;
811#endif
812
813 Read(_T ( "EnableRolloverBlock" ), &g_bRollover);
814
815 Read(_T ( "ZoomDetailFactor" ), &g_chart_zoom_modifier_raster);
816 Read(_T ( "ZoomDetailFactorVector" ), &g_chart_zoom_modifier_vector);
817 Read(_T ( "PlusMinusZoomFactor" ), &g_plus_minus_zoom_factor, 2.0);
818 Read("MouseZoomSensitivity", &g_mouse_zoom_sensitivity, 1.3);
819 g_mouse_zoom_sensitivity_ui =
820 MouseZoom::config_to_ui(g_mouse_zoom_sensitivity);
821 Read(_T ( "CM93DetailFactor" ), &g_cm93_zoom_factor);
822
823 Read(_T ( "CM93DetailZoomPosX" ), &g_detailslider_dialog_x);
824 Read(_T ( "CM93DetailZoomPosY" ), &g_detailslider_dialog_y);
825 Read(_T ( "ShowCM93DetailSlider" ), &g_bShowDetailSlider);
826
827 Read(_T ( "SENC_LOD_Pixels" ), &g_SENC_LOD_pixels);
828
829 Read(_T ( "SkewCompUpdatePeriod" ), &g_SkewCompUpdatePeriod);
830
831 Read(_T ( "SetSystemTime" ), &s_bSetSystemTime);
832 Read(_T ( "ShowStatusBar" ), &g_bShowStatusBar);
833#ifndef __WXOSX__
834 Read(_T ( "ShowMenuBar" ), &g_bShowMenuBar);
835#endif
836 Read(_T ( "Fullscreen" ), &g_bFullscreen);
837 Read(_T ( "ShowCompassWindow" ), &g_bShowCompassWin);
838 Read(_T ( "ShowGrid" ), &g_bDisplayGrid);
839 Read(_T ( "PlayShipsBells" ), &g_bPlayShipsBells);
840 Read(_T ( "SoundDeviceIndex" ), &g_iSoundDeviceIndex);
841 Read(_T ( "FullscreenToolbar" ), &g_bFullscreenToolbar);
842 Read(_T ( "PermanentMOBIcon" ), &g_bPermanentMOBIcon);
843 Read(_T ( "ShowLayers" ), &g_bShowLayers);
844 Read(_T ( "ShowDepthUnits" ), &g_bShowDepthUnits);
845 Read(_T ( "AutoAnchorDrop" ), &g_bAutoAnchorMark);
846 Read(_T ( "ShowChartOutlines" ), &g_bShowOutlines);
847 Read(_T ( "ShowActiveRouteHighway" ), &g_bShowActiveRouteHighway);
848 Read(_T ( "ShowActiveRouteTotal" ), &g_bShowRouteTotal);
849 Read(_T ( "MostRecentGPSUploadConnection" ), &g_uploadConnection);
850 Read(_T ( "ShowChartBar" ), &g_bShowChartBar);
851 Read(_T ( "SDMMFormat" ),
852 &g_iSDMMFormat); // 0 = "Degrees, Decimal minutes"), 1 = "Decimal
853 // degrees", 2 = "Degrees,Minutes, Seconds"
854
855 Read(_T ( "DistanceFormat" ),
856 &g_iDistanceFormat); // 0 = "Nautical miles"), 1 = "Statute miles", 2 =
857 // "Kilometers", 3 = "Meters"
858 Read(_T ( "SpeedFormat" ),
859 &g_iSpeedFormat); // 0 = "kts"), 1 = "mph", 2 = "km/h", 3 = "m/s"
860 Read(_T ( "WindSpeedFormat" ),
861 &g_iWindSpeedFormat); // 0 = "knots"), 1 = "m/s", 2 = "Mph", 3 = "km/h"
862 Read(_T ("TemperatureFormat"), &g_iTempFormat); // 0 = C, 1 = F, 2 = K
863
864 // LIVE ETA OPTION
865 Read(_T ( "LiveETA" ), &g_bShowLiveETA);
866 Read(_T ( "DefaultBoatSpeed" ), &g_defaultBoatSpeed);
867
868 Read(_T ( "OwnshipCOGPredictorMinutes" ), &g_ownship_predictor_minutes);
869 Read(_T ( "OwnshipCOGPredictorStyle" ), &g_cog_predictor_style);
870 Read(_T ( "OwnshipCOGPredictorColor" ), &g_cog_predictor_color);
871 Read(_T ( "OwnshipCOGPredictorEndmarker" ), &g_cog_predictor_endmarker);
872 Read(_T ( "OwnshipCOGPredictorWidth" ), &g_cog_predictor_width);
873 Read(_T ( "OwnshipHDTPredictorStyle" ), &g_ownship_HDTpredictor_style);
874 Read(_T ( "OwnshipHDTPredictorColor" ), &g_ownship_HDTpredictor_color);
875 Read(_T ( "OwnshipHDTPredictorEndmarker" ),
876 &g_ownship_HDTpredictor_endmarker);
877 Read(_T ( "OwnshipHDTPredictorWidth" ), &g_ownship_HDTpredictor_width);
878 Read(_T ( "OwnshipHDTPredictorMiles" ), &g_ownship_HDTpredictor_miles);
879 int mmsi;
880 Read(_T ( "OwnShipMMSINumber" ), &mmsi);
881 g_OwnShipmmsi = mmsi >= 0 ? static_cast<unsigned>(mmsi) : 0;
882 Read(_T ( "OwnShipIconType" ), &g_OwnShipIconType);
883 Read(_T ( "OwnShipLength" ), &g_n_ownship_length_meters);
884 Read(_T ( "OwnShipWidth" ), &g_n_ownship_beam_meters);
885 Read(_T ( "OwnShipGPSOffsetX" ), &g_n_gps_antenna_offset_x);
886 Read(_T ( "OwnShipGPSOffsetY" ), &g_n_gps_antenna_offset_y);
887 Read(_T ( "OwnShipMinSize" ), &g_n_ownship_min_mm);
888 Read(_T ( "OwnShipSogCogCalc" ), &g_own_ship_sog_cog_calc);
889 Read(_T ( "OwnShipSogCogCalcDampSec"), &g_own_ship_sog_cog_calc_damp_sec);
890 Read(_T ( "ShowDirectRouteLine"), &g_bShowShipToActive);
891 Read(_T ( "DirectRouteLineStyle"), &g_shipToActiveStyle);
892 Read(_T( "DirectRouteLineColor" ), &g_shipToActiveColor);
893
894 wxString racr;
895 Read(_T ( "RouteArrivalCircleRadius" ), &racr);
896 if (racr.Len()) racr.ToDouble(&g_n_arrival_circle_radius);
897
898 Read(_T ( "FullScreenQuilt" ), &g_bFullScreenQuilt);
899
900 Read(_T ( "StartWithTrackActive" ), &g_bTrackCarryOver);
901 Read(_T ( "AutomaticDailyTracks" ), &g_bTrackDaily);
902 Read(_T ( "TrackRotateAt" ), &g_track_rotate_time);
903 Read(_T ( "TrackRotateTimeType" ), &g_track_rotate_time_type);
904 Read(_T ( "HighlightTracks" ), &g_bHighliteTracks);
905
906 Read(_T ( "DateTimeFormat" ), &g_datetime_format);
907
908 wxString stps;
909 Read(_T ( "PlanSpeed" ), &stps);
910 if (!stps.IsEmpty()) stps.ToDouble(&g_PlanSpeed);
911
912 Read(_T ( "VisibleLayers" ), &g_VisibleLayers);
913 Read(_T ( "InvisibleLayers" ), &g_InvisibleLayers);
914 Read(_T ( "VisNameInLayers" ), &g_VisiNameinLayers);
915 Read(_T ( "InvisNameInLayers" ), &g_InVisiNameinLayers);
916
917 Read(_T ( "PreserveScaleOnX" ), &g_bPreserveScaleOnX);
918
919 Read(_T ( "ShowMUIZoomButtons" ), &g_bShowMuiZoomButtons);
920
921 Read(_T ( "Locale" ), &g_locale);
922 Read(_T ( "LocaleOverride" ), &g_localeOverride);
923
924 // We allow 0-99 backups ov navobj.xml
925 Read(_T ( "KeepNavobjBackups" ), &g_navobjbackups);
926
927 // Boolean to cater for legacy Input COM Port filer behaviour, i.e. show msg
928 // filtered but put msg on bus.
929 Read(_T ( "LegacyInputCOMPortFilterBehaviour" ),
930 &g_b_legacy_input_filter_behaviour);
931
932 // Boolean to cater for sailing when not approaching waypoint
933 Read(_T( "AdvanceRouteWaypointOnArrivalOnly" ),
934 &g_bAdvanceRouteWaypointOnArrivalOnly);
935 Read("EnableRootMenuDebug", &g_enable_root_menu_debug);
936
937 Read(_T ( "EnableRotateKeys" ), &g_benable_rotate);
938 Read(_T ( "EmailCrashReport" ), &g_bEmailCrashReport);
939
940 g_benableAISNameCache = true;
941 Read(_T ( "EnableAISNameCache" ), &g_benableAISNameCache);
942
943 Read(_T ( "EnableUDPNullHeader" ), &g_benableUDPNullHeader);
944
945 SetPath(_T ( "/Settings/GlobalState" ));
946
947 Read(_T ( "FrameWinX" ), &g_nframewin_x);
948 Read(_T ( "FrameWinY" ), &g_nframewin_y);
949 Read(_T ( "FrameWinPosX" ), &g_nframewin_posx);
950 Read(_T ( "FrameWinPosY" ), &g_nframewin_posy);
951 Read(_T ( "FrameMax" ), &g_bframemax);
952
953 Read(_T ( "ClientPosX" ), &g_lastClientRectx);
954 Read(_T ( "ClientPosY" ), &g_lastClientRecty);
955 Read(_T ( "ClientSzX" ), &g_lastClientRectw);
956 Read(_T ( "ClientSzY" ), &g_lastClientRecth);
957
958 Read(_T( "RoutePropSizeX" ), &g_route_prop_sx);
959 Read(_T( "RoutePropSizeY" ), &g_route_prop_sy);
960 Read(_T( "RoutePropPosX" ), &g_route_prop_x);
961 Read(_T( "RoutePropPosY" ), &g_route_prop_y);
962
963 read_int = -1;
964 Read(_T ( "S52_DEPTH_UNIT_SHOW" ), &read_int); // default is metres
965 if (read_int >= 0) {
966 read_int = wxMax(read_int, 0); // qualify value
967 read_int = wxMin(read_int, 2);
968 g_nDepthUnitDisplay = read_int;
969 }
970
971 // Sounds
972 SetPath(_T ( "/Settings/Audio" ));
973
974 // Set reasonable defaults
975 wxString sound_dir = g_Platform->GetSharedDataDir();
976 sound_dir.Append(_T("sounds"));
977 sound_dir.Append(wxFileName::GetPathSeparator());
978
979 g_AIS_sound_file = sound_dir + _T("beep_ssl.wav");
980 g_DSC_sound_file = sound_dir + _T("phonering1.wav");
981 g_SART_sound_file = sound_dir + _T("beep3.wav");
982 g_anchorwatch_sound_file = sound_dir + _T("beep1.wav");
983
984 Read(_T ( "AISAlertSoundFile" ), &g_AIS_sound_file);
985 Read(_T ( "DSCAlertSoundFile" ), &g_DSC_sound_file);
986 Read(_T ( "SARTAlertSoundFile" ), &g_SART_sound_file);
987 Read(_T ( "AnchorAlarmSoundFile" ), &g_anchorwatch_sound_file);
988
989 Read(_T ( "bAIS_GCPA_AlertAudio" ), &g_bAIS_GCPA_Alert_Audio);
990 Read(_T ( "bAIS_SART_AlertAudio" ), &g_bAIS_SART_Alert_Audio);
991 Read(_T ( "bAIS_DSC_AlertAudio" ), &g_bAIS_DSC_Alert_Audio);
992 Read(_T ( "bAnchorAlertAudio" ), &g_bAnchor_Alert_Audio);
993
994 // AIS
995 wxString s;
996 SetPath(_T ( "/Settings/AIS" ));
997
998 g_bUseOnlyConfirmedAISName = false;
999 Read(_T ( "UseOnlyConfirmedAISName" ), &g_bUseOnlyConfirmedAISName);
1000
1001 Read(_T ( "bNoCPAMax" ), &g_bCPAMax);
1002
1003 Read(_T ( "NoCPAMaxNMi" ), &s);
1004 s.ToDouble(&g_CPAMax_NM);
1005
1006 Read(_T ( "bCPAWarn" ), &g_bCPAWarn);
1007
1008 Read(_T ( "CPAWarnNMi" ), &s);
1009 s.ToDouble(&g_CPAWarn_NM);
1010
1011 Read(_T ( "bTCPAMax" ), &g_bTCPA_Max);
1012
1013 Read(_T ( "TCPAMaxMinutes" ), &s);
1014 s.ToDouble(&g_TCPA_Max);
1015
1016 Read(_T ( "bMarkLostTargets" ), &g_bMarkLost);
1017
1018 Read(_T ( "MarkLost_Minutes" ), &s);
1019 s.ToDouble(&g_MarkLost_Mins);
1020
1021 Read(_T ( "bRemoveLostTargets" ), &g_bRemoveLost);
1022
1023 Read(_T ( "RemoveLost_Minutes" ), &s);
1024 s.ToDouble(&g_RemoveLost_Mins);
1025
1026 Read(_T ( "bShowCOGArrows" ), &g_bShowCOG);
1027
1028 Read(_T ("bSyncCogPredictors"), &g_bSyncCogPredictors);
1029
1030 Read(_T ( "CogArrowMinutes" ), &s);
1031 s.ToDouble(&g_ShowCOG_Mins);
1032
1033 Read(_T ( "bShowTargetTracks" ), &g_bAISShowTracks);
1034
1035 if (Read(_T ( "TargetTracksLimit" ), &s)) {
1036 s.ToDouble(&g_AISShowTracks_Limit);
1037 g_AISShowTracks_Limit = wxMax(300.0, g_AISShowTracks_Limit);
1038 }
1039 if (Read(_T ( "TargetTracksMinutes" ), &s)) {
1040 s.ToDouble(&g_AISShowTracks_Mins);
1041 g_AISShowTracks_Mins = wxMax(1.0, g_AISShowTracks_Mins);
1042 g_AISShowTracks_Mins = wxMin(g_AISShowTracks_Limit, g_AISShowTracks_Mins);
1043 }
1044
1045 Read(_T ( "bHideMooredTargets" ), &g_bHideMoored);
1046 if (Read(_T ( "MooredTargetMaxSpeedKnots" ), &s))
1047 s.ToDouble(&g_ShowMoored_Kts);
1048
1049 g_SOGminCOG_kts = 0.2;
1050 if (Read(_T ( "SOGMinimumForCOGDisplay" ), &s)) s.ToDouble(&g_SOGminCOG_kts);
1051
1052 Read(_T ("bShowScaledTargets"), &g_bAllowShowScaled);
1053 Read(_T ( "AISScaledNumber" ), &g_ShowScaled_Num);
1054 Read(_T ( "AISScaledNumberWeightSOG" ), &g_ScaledNumWeightSOG);
1055 Read(_T ( "AISScaledNumberWeightCPA" ), &g_ScaledNumWeightCPA);
1056 Read(_T ( "AISScaledNumberWeightTCPA" ), &g_ScaledNumWeightTCPA);
1057 Read(_T ( "AISScaledNumberWeightRange" ), &g_ScaledNumWeightRange);
1058 Read(_T ( "AISScaledNumberWeightSizeOfTarget" ), &g_ScaledNumWeightSizeOfT);
1059 Read(_T ( "AISScaledSizeMinimal" ), &g_ScaledSizeMinimal);
1060 Read(_T("AISShowScaled"), &g_bShowScaled);
1061
1062 Read(_T ( "bShowAreaNotices" ), &g_bShowAreaNotices);
1063 Read(_T ( "bDrawAISSize" ), &g_bDrawAISSize);
1064 Read(_T ( "bDrawAISRealtime" ), &g_bDrawAISRealtime);
1065 Read(_T ( "bShowAISName" ), &g_bShowAISName);
1066 Read(_T ( "AISRealtimeMinSpeedKnots" ), &g_AIS_RealtPred_Kts, 0.7);
1067 Read(_T ( "bAISAlertDialog" ), &g_bAIS_CPA_Alert);
1068 Read(_T ( "ShowAISTargetNameScale" ), &g_Show_Target_Name_Scale);
1069 Read(_T ( "bWplIsAprsPositionReport" ), &g_bWplUsePosition);
1070 Read(_T ( "WplSelAction"), &g_WplAction);
1071 Read(_T ( "AISCOGPredictorWidth" ), &g_ais_cog_predictor_width);
1072
1073 Read(_T ( "bAISAlertAudio" ), &g_bAIS_CPA_Alert_Audio);
1074 Read(_T ( "AISAlertAudioFile" ), &g_sAIS_Alert_Sound_File);
1075 Read(_T ( "bAISAlertSuppressMoored" ), &g_bAIS_CPA_Alert_Suppress_Moored);
1076
1077 Read(_T ( "bAISAlertAckTimeout" ), &g_bAIS_ACK_Timeout);
1078 if (Read(_T ( "AlertAckTimeoutMinutes" ), &s)) s.ToDouble(&g_AckTimeout_Mins);
1079
1080 Read(_T ( "AlertDialogSizeX" ), &g_ais_alert_dialog_sx);
1081 Read(_T ( "AlertDialogSizeY" ), &g_ais_alert_dialog_sy);
1082 Read(_T ( "AlertDialogPosX" ), &g_ais_alert_dialog_x);
1083 Read(_T ( "AlertDialogPosY" ), &g_ais_alert_dialog_y);
1084 Read(_T ( "QueryDialogPosX" ), &g_ais_query_dialog_x);
1085 Read(_T ( "QueryDialogPosY" ), &g_ais_query_dialog_y);
1086
1087 Read(_T ( "AISTargetListPerspective" ), &g_AisTargetList_perspective);
1088 Read(_T ( "AISTargetListRange" ), &g_AisTargetList_range);
1089 Read(_T ( "AISTargetListSortColumn" ), &g_AisTargetList_sortColumn);
1090 Read(_T ( "bAISTargetListSortReverse" ), &g_bAisTargetList_sortReverse);
1091 Read(_T ( "AISTargetListColumnSpec" ), &g_AisTargetList_column_spec);
1092 Read(_T ("AISTargetListColumnOrder"), &g_AisTargetList_column_order);
1093
1094 Read(_T ( "bAISRolloverShowClass" ), &g_bAISRolloverShowClass);
1095 Read(_T ( "bAISRolloverShowCOG" ), &g_bAISRolloverShowCOG);
1096 Read(_T ( "bAISRolloverShowCPA" ), &g_bAISRolloverShowCPA);
1097
1098 Read(_T ( "S57QueryDialogSizeX" ), &g_S57_dialog_sx);
1099 Read(_T ( "S57QueryDialogSizeY" ), &g_S57_dialog_sy);
1100 Read(_T ( "S57QueryExtraDialogSizeX" ), &g_S57_extradialog_sx);
1101 Read(_T ( "S57QueryExtraDialogSizeY" ), &g_S57_extradialog_sy);
1102
1103 wxString strpres(_T ( "PresentationLibraryData" ));
1104 wxString valpres;
1105 SetPath(_T ( "/Directories" ));
1106 Read(strpres, &valpres); // Get the File name
1107 if (!valpres.IsEmpty()) g_UserPresLibData = valpres;
1108
1109 wxString strs(_T ( "SENCFileLocation" ));
1110 SetPath(_T ( "/Directories" ));
1111 wxString vals;
1112 Read(strs, &vals); // Get the Directory name
1113 if (!vals.IsEmpty()) g_SENCPrefix = vals;
1114
1115 SetPath(_T ( "/Directories" ));
1116 wxString vald;
1117 Read(_T ( "InitChartDir" ), &vald); // Get the Directory name
1118
1119 wxString dirnamed(vald);
1120 if (!dirnamed.IsEmpty()) {
1121 if (pInit_Chart_Dir->IsEmpty()) // on second pass, don't overwrite
1122 {
1123 pInit_Chart_Dir->Clear();
1124 pInit_Chart_Dir->Append(vald);
1125 }
1126 }
1127
1128 Read(_T ( "GPXIODir" ), &g_gpx_path); // Get the Directory name
1129 Read(_T ( "TCDataDir" ), &g_TCData_Dir); // Get the Directory name
1130 Read(_T ( "BasemapDir"), &gWorldMapLocation);
1131 Read(_T ( "BaseShapefileDir"), &gWorldShapefileLocation);
1132 Read(_T ( "pluginInstallDir"), &g_winPluginDir);
1133 wxLogMessage("winPluginDir, read from ini file: %s",
1134 g_winPluginDir.mb_str().data());
1135
1136 SetPath(_T ( "/Settings/GlobalState" ));
1137
1138 if (Read(_T ( "nColorScheme" ), &read_int))
1139 global_color_scheme = (ColorScheme)read_int;
1140
1141 if (!bAsTemplate) {
1142 SetPath(_T ( "/Settings/NMEADataSource" ));
1143
1144 TheConnectionParams().clear();
1145 wxString connectionconfigs;
1146 Read(_T( "DataConnections" ), &connectionconfigs);
1147 if (!connectionconfigs.IsEmpty()) {
1148 wxArrayString confs = wxStringTokenize(connectionconfigs, _T("|"));
1149 for (size_t i = 0; i < confs.Count(); i++) {
1150 ConnectionParams *prm = new ConnectionParams(confs[i]);
1151 if (!prm->Valid) {
1152 wxLogMessage(_T( "Skipped invalid DataStream config"));
1153 delete prm;
1154 continue;
1155 }
1156 TheConnectionParams().push_back(prm);
1157 }
1158 }
1159 }
1160
1161 SetPath(_T ( "/Settings/GlobalState" ));
1162 wxString st;
1163
1164 double st_lat, st_lon;
1165 if (Read(_T ( "VPLatLon" ), &st)) {
1166 sscanf(st.mb_str(wxConvUTF8), "%lf,%lf", &st_lat, &st_lon);
1167
1168 // Sanity check the lat/lon...both have to be reasonable.
1169 if (fabs(st_lon) < 360.) {
1170 while (st_lon < -180.) st_lon += 360.;
1171
1172 while (st_lon > 180.) st_lon -= 360.;
1173
1174 vLon = st_lon;
1175 }
1176
1177 if (fabs(st_lat) < 90.0) vLat = st_lat;
1178
1179 s.Printf(_T ( "Setting Viewpoint Lat/Lon %g, %g" ), vLat, vLon);
1180 wxLogMessage(s);
1181 }
1182
1183 double st_view_scale, st_rotation;
1184 if (Read(wxString(_T ( "VPScale" )), &st)) {
1185 sscanf(st.mb_str(wxConvUTF8), "%lf", &st_view_scale);
1186 // Sanity check the scale
1187 st_view_scale = fmax(st_view_scale, .001 / 32);
1188 st_view_scale = fmin(st_view_scale, 4);
1189 }
1190
1191 if (Read(wxString(_T ( "VPRotation" )), &st)) {
1192 sscanf(st.mb_str(wxConvUTF8), "%lf", &st_rotation);
1193 // Sanity check the rotation
1194 st_rotation = fmin(st_rotation, 360);
1195 st_rotation = fmax(st_rotation, 0);
1196 }
1197
1198 wxString sll;
1199 double lat, lon;
1200 if (Read(_T ( "OwnShipLatLon" ), &sll)) {
1201 sscanf(sll.mb_str(wxConvUTF8), "%lf,%lf", &lat, &lon);
1202
1203 // Sanity check the lat/lon...both have to be reasonable.
1204 if (fabs(lon) < 360.) {
1205 while (lon < -180.) lon += 360.;
1206
1207 while (lon > 180.) lon -= 360.;
1208
1209 gLon = lon;
1210 }
1211
1212 if (fabs(lat) < 90.0) gLat = lat;
1213
1214 s.Printf(_T ( "Setting Ownship Lat/Lon %g, %g" ), gLat, gLon);
1215 wxLogMessage(s);
1216 }
1217
1218 // Fonts
1219
1220 // Load the persistent Auxiliary Font descriptor Keys
1221 SetPath(_T ( "/Settings/AuxFontKeys" ));
1222
1223 wxString strk;
1224 long dummyk;
1225 wxString kval;
1226 bool bContk = GetFirstEntry(strk, dummyk);
1227 bool bNewKey = false;
1228 while (bContk) {
1229 Read(strk, &kval);
1230 bNewKey = FontMgr::Get().AddAuxKey(kval);
1231 if (!bAsTemplate && !bNewKey) {
1232 DeleteEntry(strk);
1233 dummyk--;
1234 }
1235 bContk = GetNextEntry(strk, dummyk);
1236 }
1237
1238#ifdef __WXX11__
1239 SetPath(_T ( "/Settings/X11Fonts" ));
1240#endif
1241
1242#ifdef __WXGTK__
1243 SetPath(_T ( "/Settings/GTKFonts" ));
1244#endif
1245
1246#ifdef __WXMSW__
1247 SetPath(_T ( "/Settings/MSWFonts" ));
1248#endif
1249
1250#ifdef __WXMAC__
1251 SetPath(_T ( "/Settings/MacFonts" ));
1252#endif
1253
1254#ifdef __WXQT__
1255 SetPath(_T ( "/Settings/QTFonts" ));
1256#endif
1257
1258 wxString str;
1259 long dummy;
1260 wxString pval;
1261 wxArrayString deleteList;
1262
1263 bool bCont = GetFirstEntry(str, dummy);
1264 while (bCont) {
1265 pval = Read(str);
1266
1267 if (str.StartsWith(_T("Font"))) {
1268 // Convert pre 3.1 setting. Can't delete old entries from inside the
1269 // GetNextEntry() loop, so we need to save those and delete outside.
1270 deleteList.Add(str);
1271 wxString oldKey = pval.BeforeFirst(_T(':'));
1272 str = FontMgr::GetFontConfigKey(oldKey);
1273 }
1274
1275 if (pval.IsEmpty() || pval.StartsWith(_T(":"))) {
1276 deleteList.Add(str);
1277 } else
1278 FontMgr::Get().LoadFontNative(&str, &pval);
1279
1280 bCont = GetNextEntry(str, dummy);
1281 }
1282
1283 for (unsigned int i = 0; i < deleteList.Count(); i++) {
1284 DeleteEntry(deleteList[i]);
1285 }
1286 deleteList.Clear();
1287
1288 // Tide/Current Data Sources
1289 SetPath(_T ( "/TideCurrentDataSources" ));
1290 if (GetNumberOfEntries()) {
1291 TideCurrentDataSet.clear();
1292 wxString str, val;
1293 long dummy;
1294 bool bCont = GetFirstEntry(str, dummy);
1295 while (bCont) {
1296 Read(str, &val); // Get a file name and add it to the list just in case
1297 // it is not repeated
1298 // We have seen duplication of dataset entries in
1299 // https://github.com/OpenCPN/OpenCPN/issues/3042, this effectively gets
1300 // rid of them.
1301 if (std::find(TideCurrentDataSet.begin(), TideCurrentDataSet.end(),
1302 val.ToStdString()) == TideCurrentDataSet.end()) {
1303 TideCurrentDataSet.push_back(val.ToStdString());
1304 }
1305 bCont = GetNextEntry(str, dummy);
1306 }
1307 }
1308
1309 // Groups
1310 LoadConfigGroups(g_pGroupArray);
1311
1312 // // Multicanvas Settings
1313 // LoadCanvasConfigs();
1314
1315 SetPath(_T ( "/Settings/Others" ));
1316
1317 // Radar rings
1318 Read(_T ( "RadarRingsNumberVisible" ), &val);
1319 if (val.Length() > 0) g_iNavAidRadarRingsNumberVisible = atoi(val.mb_str());
1320 g_bNavAidRadarRingsShown = g_iNavAidRadarRingsNumberVisible > 0;
1321
1322 Read(_T ( "RadarRingsStep" ), &val);
1323 if (val.Length() > 0) g_fNavAidRadarRingsStep = atof(val.mb_str());
1324
1325 Read(_T ( "RadarRingsStepUnits" ), &g_pNavAidRadarRingsStepUnits);
1326
1327 wxString l_wxsOwnshipRangeRingsColour;
1328 Read(_T ( "RadarRingsColour" ), &l_wxsOwnshipRangeRingsColour);
1329 if (l_wxsOwnshipRangeRingsColour.Length())
1330 g_colourOwnshipRangeRingsColour.Set(l_wxsOwnshipRangeRingsColour);
1331
1332 // Waypoint Radar rings
1333 Read(_T ( "WaypointRangeRingsNumber" ), &val);
1334 if (val.Length() > 0) g_iWaypointRangeRingsNumber = atoi(val.mb_str());
1335
1336 Read(_T ( "WaypointRangeRingsStep" ), &val);
1337 if (val.Length() > 0) g_fWaypointRangeRingsStep = atof(val.mb_str());
1338
1339 Read(_T ( "WaypointRangeRingsStepUnits" ), &g_iWaypointRangeRingsStepUnits);
1340
1341 wxString l_wxsWaypointRangeRingsColour;
1342 Read(_T( "WaypointRangeRingsColour" ), &l_wxsWaypointRangeRingsColour);
1343 g_colourWaypointRangeRingsColour.Set(l_wxsWaypointRangeRingsColour);
1344
1345 if (!Read(_T("WaypointUseScaMin"), &g_bUseWptScaMin)) g_bUseWptScaMin = false;
1346 if (!Read(_T("WaypointScaMinValue"), &g_iWpt_ScaMin))
1347 g_iWpt_ScaMin = 2147483646;
1348 if (!Read(_T("WaypointUseScaMinOverrule"), &g_bOverruleScaMin))
1349 g_bOverruleScaMin = false;
1350 if (!Read(_T("WaypointsShowName"), &g_bShowWptName)) g_bShowWptName = true;
1351 if (!Read(_T("UserIconsFirst"), &g_bUserIconsFirst)) g_bUserIconsFirst = true;
1352
1353 // Support Version 3.0 and prior config setting for Radar Rings
1354 bool b300RadarRings = true;
1355 if (Read(_T ( "ShowRadarRings" ), &b300RadarRings)) {
1356 if (!b300RadarRings) g_iNavAidRadarRingsNumberVisible = 0;
1357 }
1358
1359 Read(_T ( "ConfirmObjectDeletion" ), &g_bConfirmObjectDelete);
1360
1361 // Waypoint dragging with mouse
1362 g_bWayPointPreventDragging = false;
1363 Read(_T ( "WaypointPreventDragging" ), &g_bWayPointPreventDragging);
1364
1365 g_bEnableZoomToCursor = false;
1366 Read(_T ( "EnableZoomToCursor" ), &g_bEnableZoomToCursor);
1367
1368 val.Clear();
1369 Read(_T ( "TrackIntervalSeconds" ), &val);
1370 if (val.Length() > 0) {
1371 double tval = atof(val.mb_str());
1372 if (tval >= 2.) g_TrackIntervalSeconds = tval;
1373 }
1374
1375 val.Clear();
1376 Read(_T ( "TrackDeltaDistance" ), &val);
1377 if (val.Length() > 0) {
1378 double tval = atof(val.mb_str());
1379 if (tval >= 0.05) g_TrackDeltaDistance = tval;
1380 }
1381
1382 Read(_T ( "TrackPrecision" ), &g_nTrackPrecision);
1383
1384 Read(_T ( "RouteLineWidth" ), &g_route_line_width);
1385 Read(_T ( "TrackLineWidth" ), &g_track_line_width);
1386
1387 wxString l_wxsTrackLineColour;
1388 if (Read(_T( "TrackLineColour" ), &l_wxsTrackLineColour))
1389 g_colourTrackLineColour.Set(l_wxsTrackLineColour);
1390
1391 Read(_T ( "TideCurrentWindowScale" ), &g_tcwin_scale);
1392 Read(_T ( "DefaultWPIcon" ), &g_default_wp_icon);
1393 Read(_T ( "DefaultRPIcon" ), &g_default_routepoint_icon);
1394
1395 SetPath(_T ( "/MmsiProperties" ));
1396 int iPMax = GetNumberOfEntries();
1397 if (iPMax) {
1398 g_MMSI_Props_Array.Empty();
1399 wxString str, val;
1400 long dummy;
1401 bool bCont = pConfig->GetFirstEntry(str, dummy);
1402 while (bCont) {
1403 pConfig->Read(str, &val); // Get an entry
1404
1405 MmsiProperties *pProps = new MmsiProperties(val);
1406 g_MMSI_Props_Array.Add(pProps);
1407
1408 bCont = pConfig->GetNextEntry(str, dummy);
1409 }
1410 }
1411
1412 return (0);
1413}
1414
1415void MyConfig::LoadS57Config() {
1416 if (!ps52plib) return;
1417
1418 int read_int;
1419 double dval;
1420 SetPath(_T ( "/Settings/GlobalState" ));
1421
1422 Read(_T ( "bShowS57Text" ), &read_int, 1);
1423 ps52plib->SetShowS57Text(!(read_int == 0));
1424
1425 Read(_T ( "bShowS57ImportantTextOnly" ), &read_int, 0);
1426 ps52plib->SetShowS57ImportantTextOnly(!(read_int == 0));
1427
1428 Read(_T ( "bShowLightDescription" ), &read_int, 0);
1429 ps52plib->SetShowLdisText(!(read_int == 0));
1430
1431 Read(_T ( "bExtendLightSectors" ), &read_int, 0);
1432 ps52plib->SetExtendLightSectors(!(read_int == 0));
1433
1434 Read(_T ( "nDisplayCategory" ), &read_int, (enum _DisCat)STANDARD);
1435 ps52plib->SetDisplayCategory((enum _DisCat)read_int);
1436
1437 Read(_T ( "nSymbolStyle" ), &read_int, (enum _LUPname)PAPER_CHART);
1438 ps52plib->m_nSymbolStyle = (LUPname)read_int;
1439
1440 Read(_T ( "nBoundaryStyle" ), &read_int, PLAIN_BOUNDARIES);
1441 ps52plib->m_nBoundaryStyle = (LUPname)read_int;
1442
1443 Read(_T ( "bShowSoundg" ), &read_int, 1);
1444 ps52plib->m_bShowSoundg = !(read_int == 0);
1445
1446 Read(_T ( "bShowMeta" ), &read_int, 0);
1447 ps52plib->m_bShowMeta = !(read_int == 0);
1448
1449 Read(_T ( "bUseSCAMIN" ), &read_int, 1);
1450 ps52plib->m_bUseSCAMIN = !(read_int == 0);
1451
1452 Read(_T ( "bUseSUPER_SCAMIN" ), &read_int, 0);
1453 ps52plib->m_bUseSUPER_SCAMIN = !(read_int == 0);
1454
1455 Read(_T ( "bShowAtonText" ), &read_int, 1);
1456 ps52plib->m_bShowAtonText = !(read_int == 0);
1457
1458 Read(_T ( "bDeClutterText" ), &read_int, 0);
1459 ps52plib->m_bDeClutterText = !(read_int == 0);
1460
1461 Read(_T ( "bShowNationalText" ), &read_int, 0);
1462 ps52plib->m_bShowNationalTexts = !(read_int == 0);
1463
1464 Read(_T ( "ENCSoundingScaleFactor" ), &read_int, 0);
1465 ps52plib->m_nSoundingFactor = read_int;
1466
1467 Read(_T ( "ENCTextScaleFactor" ), &read_int, 0);
1468 ps52plib->m_nTextFactor = read_int;
1469
1470 if (Read(_T ( "S52_MAR_SAFETY_CONTOUR" ), &dval, 3.0)) {
1471 S52_setMarinerParam(S52_MAR_SAFETY_CONTOUR, dval);
1472 S52_setMarinerParam(S52_MAR_SAFETY_DEPTH,
1473 dval); // Set safety_contour and safety_depth the same
1474 }
1475
1476 if (Read(_T ( "S52_MAR_SHALLOW_CONTOUR" ), &dval, 2.0))
1477 S52_setMarinerParam(S52_MAR_SHALLOW_CONTOUR, dval);
1478
1479 if (Read(_T ( "S52_MAR_DEEP_CONTOUR" ), &dval, 6.0))
1480 S52_setMarinerParam(S52_MAR_DEEP_CONTOUR, dval);
1481
1482 if (Read(_T ( "S52_MAR_TWO_SHADES" ), &dval, 0.0))
1483 S52_setMarinerParam(S52_MAR_TWO_SHADES, dval);
1484
1485 ps52plib->UpdateMarinerParams();
1486
1487 SetPath(_T ( "/Settings/GlobalState" ));
1488 Read(_T ( "S52_DEPTH_UNIT_SHOW" ), &read_int, 1); // default is metres
1489 read_int = wxMax(read_int, 0); // qualify value
1490 read_int = wxMin(read_int, 2);
1491 ps52plib->m_nDepthUnitDisplay = read_int;
1492 g_nDepthUnitDisplay = read_int;
1493
1494 // S57 Object Class Visibility
1495
1496 OBJLElement *pOLE;
1497
1498 SetPath(_T ( "/Settings/ObjectFilter" ));
1499
1500 int iOBJMax = GetNumberOfEntries();
1501 if (iOBJMax) {
1502 wxString str;
1503 long val;
1504 long dummy;
1505
1506 wxString sObj;
1507
1508 bool bCont = pConfig->GetFirstEntry(str, dummy);
1509 while (bCont) {
1510 pConfig->Read(str, &val); // Get an Object Viz
1511
1512 bool bNeedNew = true;
1513
1514 if (str.StartsWith(_T ( "viz" ), &sObj)) {
1515 for (unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
1516 iPtr++) {
1517 pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
1518 if (!strncmp(pOLE->OBJLName, sObj.mb_str(), 6)) {
1519 pOLE->nViz = val;
1520 bNeedNew = false;
1521 break;
1522 }
1523 }
1524
1525 if (bNeedNew) {
1526 pOLE = (OBJLElement *)calloc(sizeof(OBJLElement), 1);
1527 memcpy(pOLE->OBJLName, sObj.mb_str(), OBJL_NAME_LEN);
1528 pOLE->nViz = 1;
1529
1530 ps52plib->pOBJLArray->Add((void *)pOLE);
1531 }
1532 }
1533 bCont = pConfig->GetNextEntry(str, dummy);
1534 }
1535 }
1536}
1537
1538bool MyConfig::LoadLayers(wxString &path) {
1539 wxArrayString file_array;
1540 wxDir dir;
1541 Layer *l;
1542 dir.Open(path);
1543 if (dir.IsOpened()) {
1544 wxString filename;
1545 bool cont = dir.GetFirst(&filename);
1546 while (cont) {
1547 file_array.Clear();
1548 filename.Prepend(wxFileName::GetPathSeparator());
1549 filename.Prepend(path);
1550 wxFileName f(filename);
1551 size_t nfiles = 0;
1552 if (f.GetExt().IsSameAs(wxT("gpx")))
1553 file_array.Add(filename); // single-gpx-file layer
1554 else {
1555 if (wxDir::Exists(filename)) {
1556 wxDir dir(filename);
1557 if (dir.IsOpened()) {
1558 nfiles = dir.GetAllFiles(filename, &file_array,
1559 wxT("*.gpx")); // layers subdirectory set
1560 }
1561 }
1562 }
1563
1564 if (file_array.GetCount()) {
1565 l = new Layer();
1566 l->m_LayerID = ++g_LayerIdx;
1567 l->m_LayerFileName = file_array[0];
1568 if (file_array.GetCount() <= 1)
1569 wxFileName::SplitPath(file_array[0], NULL, NULL, &(l->m_LayerName),
1570 NULL, NULL);
1571 else
1572 wxFileName::SplitPath(filename, NULL, NULL, &(l->m_LayerName), NULL,
1573 NULL);
1574
1575 bool bLayerViz = g_bShowLayers;
1576
1577 if (g_VisibleLayers.Contains(l->m_LayerName)) bLayerViz = true;
1578 if (g_InvisibleLayers.Contains(l->m_LayerName)) bLayerViz = false;
1579
1580 l->m_bHasVisibleNames = wxCHK_UNDETERMINED;
1581 if (g_VisiNameinLayers.Contains(l->m_LayerName))
1582 l->m_bHasVisibleNames = wxCHK_CHECKED;
1583 if (g_InVisiNameinLayers.Contains(l->m_LayerName))
1584 l->m_bHasVisibleNames = wxCHK_UNCHECKED;
1585
1586 l->m_bIsVisibleOnChart = bLayerViz;
1587
1588 wxString laymsg;
1589 laymsg.Printf(wxT("New layer %d: %s"), l->m_LayerID,
1590 l->m_LayerName.c_str());
1591 wxLogMessage(laymsg);
1592
1593 pLayerList->Insert(l);
1594
1595 // Load the entire file array as a single layer
1596
1597 for (unsigned int i = 0; i < file_array.GetCount(); i++) {
1598 wxString file_path = file_array[i];
1599
1600 if (::wxFileExists(file_path)) {
1602 if (pSet->load_file(file_path.fn_str()).status !=
1603 pugi::xml_parse_status::status_ok) {
1604 wxLogMessage("Error loading GPX file " + file_path);
1605 pSet->reset();
1606 }
1607 long nItems = pSet->LoadAllGPXObjectsAsLayer(
1608 l->m_LayerID, bLayerViz, l->m_bHasVisibleNames);
1609 l->m_NoOfItems += nItems;
1610 l->m_LayerType = _("Persistent");
1611
1612 wxString objmsg;
1613 objmsg.Printf(wxT("Loaded GPX file %s with %ld items."),
1614 file_path.c_str(), nItems);
1615 wxLogMessage(objmsg);
1616
1617 delete pSet;
1618 }
1619 }
1620 }
1621
1622 cont = dir.GetNext(&filename);
1623 }
1624 }
1625 g_bLayersLoaded = true;
1626
1627 return true;
1628}
1629
1630bool MyConfig::LoadChartDirArray(ArrayOfCDI &ChartDirArray) {
1631 // Chart Directories
1632 SetPath(_T ( "/ChartDirectories" ));
1633 int iDirMax = GetNumberOfEntries();
1634 if (iDirMax) {
1635 ChartDirArray.Empty();
1636 wxString str, val;
1637 long dummy;
1638 int nAdjustChartDirs = 0;
1639 int iDir = 0;
1640 bool bCont = pConfig->GetFirstEntry(str, dummy);
1641 while (bCont) {
1642 pConfig->Read(str, &val); // Get a Directory name
1643
1644 wxString dirname(val);
1645 if (!dirname.IsEmpty()) {
1646 /* Special case for first time run after Windows install with sample
1647 chart data... We desire that the sample configuration file opencpn.ini
1648 should not contain any installation dependencies, so... Detect and
1649 update the sample [ChartDirectories] entries to point to the Shared
1650 Data directory For instance, if the (sample) opencpn.ini file should
1651 contain shortcut coded entries like:
1652
1653 [ChartDirectories]
1654 ChartDir1=SampleCharts\\MaptechRegion7
1655
1656 then this entry will be updated to be something like:
1657 ChartDir1=c:\Program Files\opencpn\SampleCharts\\MaptechRegion7
1658
1659 */
1660 if (dirname.Find(_T ( "SampleCharts" )) ==
1661 0) // only update entries starting with "SampleCharts"
1662 {
1663 nAdjustChartDirs++;
1664
1665 pConfig->DeleteEntry(str);
1666 wxString new_dir = dirname.Mid(dirname.Find(_T ( "SampleCharts" )));
1667 new_dir.Prepend(g_Platform->GetSharedDataDir());
1668 dirname = new_dir;
1669 }
1670
1671 ChartDirInfo cdi;
1672 cdi.fullpath = dirname.BeforeFirst('^');
1673 cdi.magic_number = dirname.AfterFirst('^');
1674
1675 ChartDirArray.Add(cdi);
1676 iDir++;
1677 }
1678
1679 bCont = pConfig->GetNextEntry(str, dummy);
1680 }
1681
1682 if (nAdjustChartDirs) pConfig->UpdateChartDirs(ChartDirArray);
1683 }
1684
1685 return true;
1686}
1687
1688bool MyConfig::UpdateChartDirs(ArrayOfCDI &dir_array) {
1689 wxString key, dir;
1690 wxString str_buf;
1691
1692 SetPath(_T ( "/ChartDirectories" ));
1693 int iDirMax = GetNumberOfEntries();
1694 if (iDirMax) {
1695 long dummy;
1696
1697 for (int i = 0; i < iDirMax; i++) {
1698 GetFirstEntry(key, dummy);
1699 DeleteEntry(key, false);
1700 }
1701 }
1702
1703 iDirMax = dir_array.GetCount();
1704
1705 for (int iDir = 0; iDir < iDirMax; iDir++) {
1706 ChartDirInfo cdi = dir_array[iDir];
1707
1708 wxString dirn = cdi.fullpath;
1709 dirn.Append(_T("^"));
1710 dirn.Append(cdi.magic_number);
1711
1712 str_buf.Printf(_T ( "ChartDir%d" ), iDir + 1);
1713
1714 Write(str_buf, dirn);
1715 }
1716
1717// Avoid nonsense log errors...
1718#ifdef __ANDROID__
1719 wxLogNull logNo;
1720#endif
1721
1722 Flush();
1723 return true;
1724}
1725
1726void MyConfig::CreateConfigGroups(ChartGroupArray *pGroupArray) {
1727 if (!pGroupArray) return;
1728
1729 SetPath(_T ( "/Groups" ));
1730 Write(_T ( "GroupCount" ), (int)pGroupArray->GetCount());
1731
1732 for (unsigned int i = 0; i < pGroupArray->GetCount(); i++) {
1733 ChartGroup *pGroup = pGroupArray->Item(i);
1734 wxString s;
1735 s.Printf(_T("Group%d"), i + 1);
1736 s.Prepend(_T ( "/Groups/" ));
1737 SetPath(s);
1738
1739 Write(_T ( "GroupName" ), pGroup->m_group_name);
1740 Write(_T ( "GroupItemCount" ), (int)pGroup->m_element_array.size());
1741
1742 for (unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
1743 wxString sg;
1744 sg.Printf(_T("Group%d/Item%d"), i + 1, j);
1745 sg.Prepend(_T ( "/Groups/" ));
1746 SetPath(sg);
1747 Write(_T ( "IncludeItem" ), pGroup->m_element_array[j].m_element_name);
1748
1749 wxString t;
1750 wxArrayString u = pGroup->m_element_array[j].m_missing_name_array;
1751 if (u.GetCount()) {
1752 for (unsigned int k = 0; k < u.GetCount(); k++) {
1753 t += u[k];
1754 t += _T(";");
1755 }
1756 Write(_T ( "ExcludeItems" ), t);
1757 }
1758 }
1759 }
1760}
1761
1762void MyConfig::DestroyConfigGroups(void) {
1763 DeleteGroup(_T ( "/Groups" )); // zap
1764}
1765
1766void MyConfig::LoadConfigGroups(ChartGroupArray *pGroupArray) {
1767 SetPath(_T ( "/Groups" ));
1768 unsigned int group_count;
1769 Read(_T ( "GroupCount" ), (int *)&group_count, 0);
1770
1771 for (unsigned int i = 0; i < group_count; i++) {
1772 ChartGroup *pGroup = new ChartGroup;
1773 wxString s;
1774 s.Printf(_T("Group%d"), i + 1);
1775 s.Prepend(_T ( "/Groups/" ));
1776 SetPath(s);
1777
1778 wxString t;
1779 Read(_T ( "GroupName" ), &t);
1780 pGroup->m_group_name = t;
1781
1782 unsigned int item_count;
1783 Read(_T ( "GroupItemCount" ), (int *)&item_count);
1784 for (unsigned int j = 0; j < item_count; j++) {
1785 wxString sg;
1786 sg.Printf(_T("Group%d/Item%d"), i + 1, j);
1787 sg.Prepend(_T ( "/Groups/" ));
1788 SetPath(sg);
1789
1790 wxString v;
1791 Read(_T ( "IncludeItem" ), &v);
1792
1793 ChartGroupElement pelement{v};
1794 wxString u;
1795 if (Read(_T ( "ExcludeItems" ), &u)) {
1796 if (!u.IsEmpty()) {
1797 wxStringTokenizer tk(u, _T(";"));
1798 while (tk.HasMoreTokens()) {
1799 wxString token = tk.GetNextToken();
1800 pelement.m_missing_name_array.Add(token);
1801 }
1802 }
1803 }
1804 pGroup->m_element_array.push_back(std::move(pelement));
1805 }
1806 pGroupArray->Add(pGroup);
1807 }
1808}
1809
1810void MyConfig::LoadCanvasConfigs(bool bApplyAsTemplate) {
1811 wxString s;
1812 canvasConfig *pcc;
1813 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1814
1815 SetPath(_T ( "/Canvas" ));
1816
1817 // If the canvas config has never been set/persisted, use the global settings
1818 if (!HasEntry(_T ( "CanvasConfig" ))) {
1819 pcc = new canvasConfig(0);
1820 pcc->LoadFromLegacyConfig(this);
1821 config_array.Add(pcc);
1822
1823 return;
1824 }
1825
1826 Read(_T ( "CanvasConfig" ), (int *)&g_canvasConfig, 0);
1827
1828 // Do not recreate canvasConfigs when applying config dynamically
1829 if (config_array.GetCount() == 0) { // This is initial load from startup
1830 s.Printf(_T("/Canvas/CanvasConfig%d"), 1);
1831 SetPath(s);
1832 canvasConfig *pcca = new canvasConfig(0);
1833 LoadConfigCanvas(pcca, bApplyAsTemplate);
1834 config_array.Add(pcca);
1835
1836 s.Printf(_T("/Canvas/CanvasConfig%d"), 2);
1837 SetPath(s);
1838 pcca = new canvasConfig(1);
1839 LoadConfigCanvas(pcca, bApplyAsTemplate);
1840 config_array.Add(pcca);
1841 } else { // This is a dynamic (i.e. Template) load
1842 canvasConfig *pcca = config_array[0];
1843 s.Printf(_T("/Canvas/CanvasConfig%d"), 1);
1844 SetPath(s);
1845 LoadConfigCanvas(pcca, bApplyAsTemplate);
1846
1847 if (config_array.GetCount() > 1) {
1848 canvasConfig *pcca = config_array[1];
1849 s.Printf(_T("/Canvas/CanvasConfig%d"), 2);
1850 SetPath(s);
1851 LoadConfigCanvas(pcca, bApplyAsTemplate);
1852 } else {
1853 s.Printf(_T("/Canvas/CanvasConfig%d"), 2);
1854 SetPath(s);
1855 pcca = new canvasConfig(1);
1856 LoadConfigCanvas(pcca, bApplyAsTemplate);
1857 config_array.Add(pcca);
1858 }
1859 }
1860}
1861
1862void MyConfig::LoadConfigCanvas(canvasConfig *cConfig, bool bApplyAsTemplate) {
1863 wxString st;
1864 double st_lat, st_lon;
1865
1866 if (!bApplyAsTemplate) {
1867 // Reasonable starting point
1868 cConfig->iLat = START_LAT; // display viewpoint
1869 cConfig->iLon = START_LON;
1870
1871 if (Read(_T ( "canvasVPLatLon" ), &st)) {
1872 sscanf(st.mb_str(wxConvUTF8), "%lf,%lf", &st_lat, &st_lon);
1873
1874 // Sanity check the lat/lon...both have to be reasonable.
1875 if (fabs(st_lon) < 360.) {
1876 while (st_lon < -180.) st_lon += 360.;
1877
1878 while (st_lon > 180.) st_lon -= 360.;
1879
1880 cConfig->iLon = st_lon;
1881 }
1882
1883 if (fabs(st_lat) < 90.0) cConfig->iLat = st_lat;
1884 }
1885
1886 cConfig->iScale = .0003; // decent initial value
1887 cConfig->iRotation = 0;
1888
1889 double st_view_scale;
1890 if (Read(wxString(_T ( "canvasVPScale" )), &st)) {
1891 sscanf(st.mb_str(wxConvUTF8), "%lf", &st_view_scale);
1892 // Sanity check the scale
1893 st_view_scale = fmax(st_view_scale, .001 / 32);
1894 st_view_scale = fmin(st_view_scale, 4);
1895 cConfig->iScale = st_view_scale;
1896 }
1897
1898 double st_rotation;
1899 if (Read(wxString(_T ( "canvasVPRotation" )), &st)) {
1900 sscanf(st.mb_str(wxConvUTF8), "%lf", &st_rotation);
1901 // Sanity check the rotation
1902 st_rotation = fmin(st_rotation, 360);
1903 st_rotation = fmax(st_rotation, 0);
1904 cConfig->iRotation = st_rotation * PI / 180.;
1905 }
1906
1907 Read(_T ( "canvasInitialdBIndex" ), &cConfig->DBindex, 0);
1908 Read(_T ( "canvasbFollow" ), &cConfig->bFollow, 0);
1909
1910 Read(_T ( "canvasCourseUp" ), &cConfig->bCourseUp, 0);
1911 Read(_T ( "canvasHeadUp" ), &cConfig->bHeadUp, 0);
1912 Read(_T ( "canvasLookahead" ), &cConfig->bLookahead, 0);
1913 }
1914
1915 Read(_T ( "ActiveChartGroup" ), &cConfig->GroupID, 0);
1916
1917 // Special check for group selection when applied as template
1918 if (cConfig->GroupID && bApplyAsTemplate) {
1919 if (cConfig->GroupID > (int)g_pGroupArray->GetCount()) cConfig->GroupID = 0;
1920 }
1921
1922 Read(_T ( "canvasShowTides" ), &cConfig->bShowTides, 0);
1923 Read(_T ( "canvasShowCurrents" ), &cConfig->bShowCurrents, 0);
1924
1925 Read(_T ( "canvasQuilt" ), &cConfig->bQuilt, 1);
1926 Read(_T ( "canvasShowGrid" ), &cConfig->bShowGrid, 0);
1927 Read(_T ( "canvasShowOutlines" ), &cConfig->bShowOutlines, 0);
1928 Read(_T ( "canvasShowDepthUnits" ), &cConfig->bShowDepthUnits, 0);
1929
1930 Read(_T ( "canvasShowAIS" ), &cConfig->bShowAIS, 1);
1931 Read(_T ( "canvasAttenAIS" ), &cConfig->bAttenAIS, 0);
1932
1933 // ENC options
1934 Read(_T ( "canvasShowENCText" ), &cConfig->bShowENCText, 1);
1935 Read(_T ( "canvasENCDisplayCategory" ), &cConfig->nENCDisplayCategory,
1936 STANDARD);
1937 Read(_T ( "canvasENCShowDepths" ), &cConfig->bShowENCDepths, 1);
1938 Read(_T ( "canvasENCShowBuoyLabels" ), &cConfig->bShowENCBuoyLabels, 1);
1939 Read(_T ( "canvasENCShowLightDescriptions" ),
1940 &cConfig->bShowENCLightDescriptions, 1);
1941 Read(_T ( "canvasENCShowLights" ), &cConfig->bShowENCLights, 1);
1942 Read(_T ( "canvasENCShowVisibleSectorLights" ),
1943 &cConfig->bShowENCVisibleSectorLights, 0);
1944 Read(_T ( "canvasENCShowAnchorInfo" ), &cConfig->bShowENCAnchorInfo, 0);
1945 Read(_T ( "canvasENCShowDataQuality" ), &cConfig->bShowENCDataQuality, 0);
1946
1947 int sx, sy;
1948 Read(_T ( "canvasSizeX" ), &sx, 0);
1949 Read(_T ( "canvasSizeY" ), &sy, 0);
1950 cConfig->canvasSize = wxSize(sx, sy);
1951}
1952
1953void MyConfig::SaveCanvasConfigs() {
1954 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1955
1956 SetPath(_T ( "/Canvas" ));
1957 Write(_T ( "CanvasConfig" ), (int)g_canvasConfig);
1958
1959 wxString s;
1960 canvasConfig *pcc;
1961
1962 switch (g_canvasConfig) {
1963 case 0:
1964 default:
1965
1966 s.Printf(_T("/Canvas/CanvasConfig%d"), 1);
1967 SetPath(s);
1968
1969 if (config_array.GetCount() > 0) {
1970 pcc = config_array.Item(0);
1971 if (pcc) {
1972 SaveConfigCanvas(pcc);
1973 }
1974 }
1975 break;
1976
1977 case 1:
1978
1979 if (config_array.GetCount() > 1) {
1980 s.Printf(_T("/Canvas/CanvasConfig%d"), 1);
1981 SetPath(s);
1982 pcc = config_array.Item(0);
1983 if (pcc) {
1984 SaveConfigCanvas(pcc);
1985 }
1986
1987 s.Printf(_T("/Canvas/CanvasConfig%d"), 2);
1988 SetPath(s);
1989 pcc = config_array.Item(1);
1990 if (pcc) {
1991 SaveConfigCanvas(pcc);
1992 }
1993 }
1994 break;
1995 }
1996}
1997
1998void MyConfig::SaveConfigCanvas(canvasConfig *cConfig) {
1999 wxString st1;
2000
2001 if (cConfig->canvas) {
2002 ViewPort vp = cConfig->canvas->GetVP();
2003
2004 if (vp.IsValid()) {
2005 st1.Printf(_T ( "%10.4f,%10.4f" ), vp.clat, vp.clon);
2006 Write(_T ( "canvasVPLatLon" ), st1);
2007 st1.Printf(_T ( "%g" ), vp.view_scale_ppm);
2008 Write(_T ( "canvasVPScale" ), st1);
2009 st1.Printf(_T ( "%i" ), ((int)(vp.rotation * 180 / PI)) % 360);
2010 Write(_T ( "canvasVPRotation" ), st1);
2011 }
2012
2013 int restore_dbindex = 0;
2014 ChartStack *pcs = cConfig->canvas->GetpCurrentStack();
2015 if (pcs) restore_dbindex = pcs->GetCurrentEntrydbIndex();
2016 if (cConfig->canvas->GetQuiltMode())
2017 restore_dbindex = cConfig->canvas->GetQuiltReferenceChartIndex();
2018 Write(_T ( "canvasInitialdBIndex" ), restore_dbindex);
2019
2020 Write(_T ( "canvasbFollow" ), cConfig->canvas->m_bFollow);
2021 Write(_T ( "ActiveChartGroup" ), cConfig->canvas->m_groupIndex);
2022
2023 Write(_T ( "canvasQuilt" ), cConfig->canvas->GetQuiltMode());
2024 Write(_T ( "canvasShowGrid" ), cConfig->canvas->GetShowGrid());
2025 Write(_T ( "canvasShowOutlines" ), cConfig->canvas->GetShowOutlines());
2026 Write(_T ( "canvasShowDepthUnits" ), cConfig->canvas->GetShowDepthUnits());
2027
2028 Write(_T ( "canvasShowAIS" ), cConfig->canvas->GetShowAIS());
2029 Write(_T ( "canvasAttenAIS" ), cConfig->canvas->GetAttenAIS());
2030
2031 Write(_T ( "canvasShowTides" ), cConfig->canvas->GetbShowTide());
2032 Write(_T ( "canvasShowCurrents" ), cConfig->canvas->GetbShowCurrent());
2033
2034 // ENC options
2035 Write(_T ( "canvasShowENCText" ), cConfig->canvas->GetShowENCText());
2036 Write(_T ( "canvasENCDisplayCategory" ),
2037 cConfig->canvas->GetENCDisplayCategory());
2038 Write(_T ( "canvasENCShowDepths" ), cConfig->canvas->GetShowENCDepth());
2039 Write(_T ( "canvasENCShowBuoyLabels" ),
2040 cConfig->canvas->GetShowENCBuoyLabels());
2041 Write(_T ( "canvasENCShowLightDescriptions" ),
2042 cConfig->canvas->GetShowENCLightDesc());
2043 Write(_T ( "canvasENCShowLights" ), cConfig->canvas->GetShowENCLights());
2044 Write(_T ( "canvasENCShowVisibleSectorLights" ),
2045 cConfig->canvas->GetShowVisibleSectors());
2046 Write(_T ( "canvasENCShowAnchorInfo" ),
2047 cConfig->canvas->GetShowENCAnchor());
2048 Write(_T ( "canvasENCShowDataQuality" ),
2049 cConfig->canvas->GetShowENCDataQual());
2050 Write(_T ( "canvasCourseUp" ),
2051 cConfig->canvas->GetUpMode() == COURSE_UP_MODE);
2052 Write(_T ( "canvasHeadUp" ), cConfig->canvas->GetUpMode() == HEAD_UP_MODE);
2053 Write(_T ( "canvasLookahead" ), cConfig->canvas->GetLookahead());
2054
2055 int width = cConfig->canvas->GetSize().x;
2056 // if(cConfig->canvas->IsPrimaryCanvas()){
2057 // width = wxMax(width, gFrame->GetClientSize().x / 10);
2058 // }
2059 // else{
2060 // width = wxMin(width, gFrame->GetClientSize().x * 9 / 10);
2061 // }
2062
2063 Write(_T ( "canvasSizeX" ), width);
2064 Write(_T ( "canvasSizeY" ), cConfig->canvas->GetSize().y);
2065 }
2066}
2067
2068void MyConfig::UpdateSettings() {
2069 // Temporarily suppress logging of trivial non-fatal wxLogSysError() messages
2070 // provoked by Android security...
2071#ifdef __ANDROID__
2072 wxLogNull logNo;
2073#endif
2074
2075 // Global options and settings
2076 SetPath(_T ( "/Settings" ));
2077
2078 Write(_T ( "LastAppliedTemplate" ), g_lastAppliedTemplateGUID);
2079 Write(_T ( "CompatOS" ), g_compatOS);
2080 Write(_T ( "CompatOsVersion" ), g_compatOsVersion);
2081 Write(_T ( "ConfigVersionString" ), g_config_version_string);
2082 if (wxIsEmpty(g_CmdSoundString)) g_CmdSoundString = wxString(OCPN_SOUND_CMD);
2083 Write(_T( "CmdSoundString" ), g_CmdSoundString);
2084 Write(_T ( "NavMessageShown" ), n_NavMessageShown);
2085 Write(_T ( "InlandEcdis" ), g_bInlandEcdis);
2086
2087 Write(_T ( "AndroidVersionCode" ), g_AndroidVersionCode);
2088
2089 Write(_T ( "UIexpert" ), g_bUIexpert);
2090 Write(_T( "SpaceDropMark" ), g_bSpaceDropMark);
2091 // Write( _T ( "UIStyle" ), g_StyleManager->GetStyleNextInvocation() );
2092 // //Not desired for O5 MUI
2093
2094 Write(_T ( "ShowStatusBar" ), g_bShowStatusBar);
2095#ifndef __WXOSX__
2096 Write(_T ( "ShowMenuBar" ), g_bShowMenuBar);
2097#endif
2098 Write(_T ( "DefaultFontSize" ), g_default_font_size);
2099 Write(_T ( "DefaultFontFacename" ), g_default_font_facename);
2100
2101 Write(_T ( "Fullscreen" ), g_bFullscreen);
2102 Write(_T ( "ShowCompassWindow" ), g_bShowCompassWin);
2103 Write(_T ( "SetSystemTime" ), s_bSetSystemTime);
2104 Write(_T ( "ShowGrid" ), g_bDisplayGrid);
2105 Write(_T ( "PlayShipsBells" ), g_bPlayShipsBells);
2106 Write(_T ( "SoundDeviceIndex" ), g_iSoundDeviceIndex);
2107 Write(_T ( "FullscreenToolbar" ), g_bFullscreenToolbar);
2108 Write(_T ( "TransparentToolbar" ), g_bTransparentToolbar);
2109 Write(_T ( "PermanentMOBIcon" ), g_bPermanentMOBIcon);
2110 Write(_T ( "ShowLayers" ), g_bShowLayers);
2111 Write(_T ( "AutoAnchorDrop" ), g_bAutoAnchorMark);
2112 Write(_T ( "ShowChartOutlines" ), g_bShowOutlines);
2113 Write(_T ( "ShowActiveRouteTotal" ), g_bShowRouteTotal);
2114 Write(_T ( "ShowActiveRouteHighway" ), g_bShowActiveRouteHighway);
2115 Write(_T ( "SDMMFormat" ), g_iSDMMFormat);
2116 Write(_T ( "MostRecentGPSUploadConnection" ), g_uploadConnection);
2117 Write(_T ( "ShowChartBar" ), g_bShowChartBar);
2118
2119 Write(_T ( "GUIScaleFactor" ), g_GUIScaleFactor);
2120 Write(_T ( "ChartObjectScaleFactor" ), g_ChartScaleFactor);
2121 Write(_T ( "ShipScaleFactor" ), g_ShipScaleFactor);
2122 Write(_T ( "ENCSoundingScaleFactor" ), g_ENCSoundingScaleFactor);
2123 Write(_T ( "ENCTextScaleFactor" ), g_ENCTextScaleFactor);
2124 Write(_T ( "ObjQueryAppendFilesExt" ), g_ObjQFileExt);
2125
2126 // Plugin catalog persistent values.
2127 Write(_T( "CatalogCustomURL"), g_catalog_custom_url);
2128 Write(_T( "CatalogChannel"), g_catalog_channel);
2129
2130 Write("NetmaskBits", g_netmask_bits);
2131 Write(_T ( "FilterNMEA_Avg" ), g_bfilter_cogsog);
2132 Write(_T ( "FilterNMEA_Sec" ), g_COGFilterSec);
2133
2134 Write(_T ( "TrackContinuous" ), g_btrackContinuous);
2135
2136 Write(_T ( "ShowTrue" ), g_bShowTrue);
2137 Write(_T ( "ShowMag" ), g_bShowMag);
2138 Write(_T ( "UserMagVariation" ), wxString::Format(_T("%.2f"), g_UserVar));
2139
2140 Write(_T ( "CM93DetailFactor" ), g_cm93_zoom_factor);
2141 Write(_T ( "CM93DetailZoomPosX" ), g_detailslider_dialog_x);
2142 Write(_T ( "CM93DetailZoomPosY" ), g_detailslider_dialog_y);
2143 Write(_T ( "ShowCM93DetailSlider" ), g_bShowDetailSlider);
2144
2145 Write(_T ( "SkewToNorthUp" ), g_bskew_comp);
2146 if (!g_bdisable_opengl) { // Only modify the saved value if OpenGL is not
2147 // force-disabled from the command line
2148 Write(_T ( "OpenGL" ), g_bopengl);
2149 }
2150 Write(_T ( "SoftwareGL" ), g_bSoftwareGL);
2151
2152 Write(_T ( "ZoomDetailFactor" ), g_chart_zoom_modifier_raster);
2153 Write(_T ( "ZoomDetailFactorVector" ), g_chart_zoom_modifier_vector);
2154
2155 Write(_T ( "FogOnOverzoom" ), g_fog_overzoom);
2156 Write(_T ( "OverzoomVectorScale" ), g_oz_vector_scale);
2157 Write(_T ( "OverzoomEmphasisBase" ), g_overzoom_emphasis_base);
2158 Write(_T ( "PlusMinusZoomFactor" ), g_plus_minus_zoom_factor);
2159 Write("MouseZoomSensitivity",
2160 MouseZoom::ui_to_config(g_mouse_zoom_sensitivity_ui));
2161 Write(_T ( "ShowMUIZoomButtons" ), g_bShowMuiZoomButtons);
2162
2163#ifdef ocpnUSE_GL
2164 /* opengl options */
2165 Write(_T ( "UseAcceleratedPanning" ), g_GLOptions.m_bUseAcceleratedPanning);
2166
2167 Write(_T ( "GPUTextureCompression" ), g_GLOptions.m_bTextureCompression);
2168 Write(_T ( "GPUTextureCompressionCaching" ),
2169 g_GLOptions.m_bTextureCompressionCaching);
2170 Write(_T ( "GPUTextureDimension" ), g_GLOptions.m_iTextureDimension);
2171 Write(_T ( "GPUTextureMemSize" ), g_GLOptions.m_iTextureMemorySize);
2172 Write(_T ( "PolygonSmoothing" ), g_GLOptions.m_GLPolygonSmoothing);
2173 Write(_T ( "LineSmoothing" ), g_GLOptions.m_GLLineSmoothing);
2174#endif
2175 Write(_T ( "SmoothPanZoom" ), g_bsmoothpanzoom);
2176
2177 Write(_T ( "CourseUpMode" ), g_bCourseUp);
2178 if (!g_bInlandEcdis) Write(_T ( "LookAheadMode" ), g_bLookAhead);
2179 Write(_T ( "TenHzUpdate" ), g_btenhertz);
2180
2181 Write(_T ( "COGUPAvgSeconds" ), g_COGAvgSec);
2182 Write(_T ( "UseMagAPB" ), g_bMagneticAPB);
2183
2184 Write(_T ( "OwnshipCOGPredictorMinutes" ), g_ownship_predictor_minutes);
2185 Write(_T ( "OwnshipCOGPredictorStyle" ), g_cog_predictor_style);
2186 Write(_T ( "OwnshipCOGPredictorColor" ), g_cog_predictor_color);
2187 Write(_T ( "OwnshipCOGPredictorEndmarker" ), g_cog_predictor_endmarker);
2188 Write(_T ( "OwnshipCOGPredictorWidth" ), g_cog_predictor_width);
2189 Write(_T ( "OwnshipHDTPredictorStyle" ), g_ownship_HDTpredictor_style);
2190 Write(_T ( "OwnshipHDTPredictorColor" ), g_ownship_HDTpredictor_color);
2191 Write(_T ( "OwnshipHDTPredictorEndmarker" ),
2192 g_ownship_HDTpredictor_endmarker);
2193 Write(_T ( "OwnShipMMSINumber" ), g_OwnShipmmsi);
2194 Write(_T ( "OwnshipHDTPredictorWidth" ), g_ownship_HDTpredictor_width);
2195 Write(_T ( "OwnshipHDTPredictorMiles" ), g_ownship_HDTpredictor_miles);
2196
2197 Write(_T ( "OwnShipIconType" ), g_OwnShipIconType);
2198 Write(_T ( "OwnShipLength" ), g_n_ownship_length_meters);
2199 Write(_T ( "OwnShipWidth" ), g_n_ownship_beam_meters);
2200 Write(_T ( "OwnShipGPSOffsetX" ), g_n_gps_antenna_offset_x);
2201 Write(_T ( "OwnShipGPSOffsetY" ), g_n_gps_antenna_offset_y);
2202 Write(_T ( "OwnShipMinSize" ), g_n_ownship_min_mm);
2203 Write(_T ( "OwnShipSogCogCalc" ), g_own_ship_sog_cog_calc);
2204 Write(_T ( "OwnShipSogCogCalcDampSec"), g_own_ship_sog_cog_calc_damp_sec);
2205 Write(_T ( "ShowDirectRouteLine"), g_bShowShipToActive);
2206 Write(_T ( "DirectRouteLineStyle"), g_shipToActiveStyle);
2207 Write(_T ( "DirectRouteLineColor" ), g_shipToActiveColor);
2208
2209 wxString racr;
2210 // racr.Printf( _T ( "%g" ), g_n_arrival_circle_radius );
2211 // Write( _T ( "RouteArrivalCircleRadius" ), racr );
2212 Write(_T ( "RouteArrivalCircleRadius" ),
2213 wxString::Format(_T("%.2f"), g_n_arrival_circle_radius));
2214
2215 Write(_T ( "ChartQuilting" ), g_bQuiltEnable);
2216
2217 Write(_T ( "PreserveScaleOnX" ), g_bPreserveScaleOnX);
2218
2219 Write(_T ( "StartWithTrackActive" ), g_bTrackCarryOver);
2220 Write(_T ( "AutomaticDailyTracks" ), g_bTrackDaily);
2221 Write(_T ( "TrackRotateAt" ), g_track_rotate_time);
2222 Write(_T ( "TrackRotateTimeType" ), g_track_rotate_time_type);
2223 Write(_T ( "HighlightTracks" ), g_bHighliteTracks);
2224
2225 Write(_T ( "DateTimeFormat" ), g_datetime_format);
2226 Write(_T ( "InitialStackIndex" ), g_restore_stackindex);
2227 Write(_T ( "InitialdBIndex" ), g_restore_dbindex);
2228
2229 Write(_T( "NMEAAPBPrecision" ), g_NMEAAPBPrecision);
2230
2231 Write(_T("TalkerIdText"), g_TalkerIdText);
2232 Write(_T("ShowTrackPointTime"), g_bShowTrackPointTime);
2233
2234 Write(_T ( "AnchorWatch1GUID" ), g_AW1GUID);
2235 Write(_T ( "AnchorWatch2GUID" ), g_AW2GUID);
2236
2237 Write(_T ( "ToolbarX" ), g_maintoolbar_x);
2238 Write(_T ( "ToolbarY" ), g_maintoolbar_y);
2239 // Write( _T ( "ToolbarOrient" ), g_maintoolbar_orient );
2240
2241 Write(_T ( "iENCToolbarX" ), g_iENCToolbarPosX);
2242 Write(_T ( "iENCToolbarY" ), g_iENCToolbarPosY);
2243
2244 if (!g_bInlandEcdis) {
2245 Write(_T ( "GlobalToolbarConfig" ), g_toolbarConfig);
2246 Write(_T ( "DistanceFormat" ), g_iDistanceFormat);
2247 Write(_T ( "SpeedFormat" ), g_iSpeedFormat);
2248 Write(_T ( "WindSpeedFormat" ), g_iWindSpeedFormat);
2249 Write(_T ( "ShowDepthUnits" ), g_bShowDepthUnits);
2250 Write(_T ( "TemperatureFormat" ), g_iTempFormat);
2251 }
2252 Write(_T ( "GPSIdent" ), g_GPS_Ident);
2253 Write("ActiveRoute", g_active_route);
2254 Write("PersistActiveRoute", g_persist_active_route);
2255 Write("AlwaysSendRmbRmc", g_always_send_rmb_rmc);
2256
2257 Write(_T ( "UseGarminHostUpload" ), g_bGarminHostUpload);
2258
2259 Write(_T ( "MobileTouch" ), g_btouch);
2260 Write(_T ( "ResponsiveGraphics" ), g_bresponsive);
2261 Write(_T ( "EnableRolloverBlock" ), g_bRollover);
2262
2263 Write(_T ( "AutoHideToolbar" ), g_bAutoHideToolbar);
2264 Write(_T ( "AutoHideToolbarSecs" ), g_nAutoHideToolbar);
2265
2266 wxString st0;
2267 for (const auto &mm : g_config_display_size_mm) {
2268 st0.Append(wxString::Format(_T ( "%zu," ), mm));
2269 }
2270 st0.RemoveLast(); // Strip last comma
2271 Write(_T ( "DisplaySizeMM" ), st0);
2272 Write(_T ( "DisplaySizeManual" ), g_config_display_size_manual);
2273
2274 Write(_T ( "SelectionRadiusMM" ), g_selection_radius_mm);
2275 Write(_T ( "SelectionRadiusTouchMM" ), g_selection_radius_touch_mm);
2276
2277 st0.Printf(_T ( "%g" ), g_PlanSpeed);
2278 Write(_T ( "PlanSpeed" ), st0);
2279
2280 if (g_bLayersLoaded) {
2281 wxString vis, invis, visnames, invisnames;
2282 LayerList::iterator it;
2283 int index = 0;
2284 for (it = (*pLayerList).begin(); it != (*pLayerList).end(); ++it, ++index) {
2285 Layer *lay = (Layer *)(*it);
2286 if (lay->IsVisibleOnChart())
2287 vis += (lay->m_LayerName) + _T(";");
2288 else
2289 invis += (lay->m_LayerName) + _T(";");
2290
2291 if (lay->HasVisibleNames() == wxCHK_CHECKED) {
2292 visnames += (lay->m_LayerName) + _T(";");
2293 } else if (lay->HasVisibleNames() == wxCHK_UNCHECKED) {
2294 invisnames += (lay->m_LayerName) + _T(";");
2295 }
2296 }
2297 Write(_T ( "VisibleLayers" ), vis);
2298 Write(_T ( "InvisibleLayers" ), invis);
2299 Write(_T ( "VisNameInLayers" ), visnames);
2300 Write(_T ( "InvisNameInLayers" ), invisnames);
2301 }
2302 Write(_T ( "Locale" ), g_locale);
2303 Write(_T ( "LocaleOverride" ), g_localeOverride);
2304
2305 Write(_T ( "KeepNavobjBackups" ), g_navobjbackups);
2306 Write(_T ( "LegacyInputCOMPortFilterBehaviour" ),
2307 g_b_legacy_input_filter_behaviour);
2308 Write(_T( "AdvanceRouteWaypointOnArrivalOnly" ),
2309 g_bAdvanceRouteWaypointOnArrivalOnly);
2310 Write("EnableRootMenuDebug", g_enable_root_menu_debug);
2311
2312 // LIVE ETA OPTION
2313 Write(_T( "LiveETA" ), g_bShowLiveETA);
2314 Write(_T( "DefaultBoatSpeed" ), g_defaultBoatSpeed);
2315
2316 // S57 Object Filter Settings
2317
2318 SetPath(_T ( "/Settings/ObjectFilter" ));
2319
2320 if (ps52plib) {
2321 for (unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
2322 iPtr++) {
2323 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
2324
2325 wxString st1(_T ( "viz" ));
2326 char name[7];
2327 strncpy(name, pOLE->OBJLName, 6);
2328 name[6] = 0;
2329 st1.Append(wxString(name, wxConvUTF8));
2330 Write(st1, pOLE->nViz);
2331 }
2332 }
2333
2334 // Global State
2335
2336 SetPath(_T ( "/Settings/GlobalState" ));
2337
2338 wxString st1;
2339
2340 // if( cc1 ) {
2341 // ViewPort vp = cc1->GetVP();
2342 //
2343 // if( vp.IsValid() ) {
2344 // st1.Printf( _T ( "%10.4f,%10.4f" ), vp.clat, vp.clon );
2345 // Write( _T ( "VPLatLon" ), st1 );
2346 // st1.Printf( _T ( "%g" ), vp.view_scale_ppm );
2347 // Write( _T ( "VPScale" ), st1 );
2348 // st1.Printf( _T ( "%i" ), ((int)(vp.rotation * 180 / PI)) % 360
2349 // ); Write( _T ( "VPRotation" ), st1 );
2350 // }
2351 // }
2352
2353 st1.Printf(_T ( "%10.4f, %10.4f" ), gLat, gLon);
2354 Write(_T ( "OwnShipLatLon" ), st1);
2355
2356 // Various Options
2357 SetPath(_T ( "/Settings/GlobalState" ));
2358 if (!g_bInlandEcdis)
2359 Write(_T ( "nColorScheme" ), (int)gFrame->GetColorScheme());
2360
2361 Write(_T ( "FrameWinX" ), g_nframewin_x);
2362 Write(_T ( "FrameWinY" ), g_nframewin_y);
2363 Write(_T ( "FrameWinPosX" ), g_nframewin_posx);
2364 Write(_T ( "FrameWinPosY" ), g_nframewin_posy);
2365 Write(_T ( "FrameMax" ), g_bframemax);
2366
2367 Write(_T ( "ClientPosX" ), g_lastClientRectx);
2368 Write(_T ( "ClientPosY" ), g_lastClientRecty);
2369 Write(_T ( "ClientSzX" ), g_lastClientRectw);
2370 Write(_T ( "ClientSzY" ), g_lastClientRecth);
2371
2372 Write(_T ( "S52_DEPTH_UNIT_SHOW" ), g_nDepthUnitDisplay);
2373
2374 Write(_T( "RoutePropSizeX" ), g_route_prop_sx);
2375 Write(_T( "RoutePropSizeY" ), g_route_prop_sy);
2376 Write(_T( "RoutePropPosX" ), g_route_prop_x);
2377 Write(_T( "RoutePropPosY" ), g_route_prop_y);
2378
2379 // Sounds
2380 SetPath(_T ( "/Settings/Audio" ));
2381 Write(_T ( "AISAlertSoundFile" ), g_AIS_sound_file);
2382 Write(_T ( "DSCAlertSoundFile" ), g_DSC_sound_file);
2383 Write(_T ( "SARTAlertSoundFile" ), g_SART_sound_file);
2384 Write(_T ( "AnchorAlarmSoundFile" ), g_anchorwatch_sound_file);
2385
2386 Write(_T ( "bAIS_GCPA_AlertAudio" ), g_bAIS_GCPA_Alert_Audio);
2387 Write(_T ( "bAIS_SART_AlertAudio" ), g_bAIS_SART_Alert_Audio);
2388 Write(_T ( "bAIS_DSC_AlertAudio" ), g_bAIS_DSC_Alert_Audio);
2389 Write(_T ( "bAnchorAlertAudio" ), g_bAnchor_Alert_Audio);
2390
2391 // AIS
2392 SetPath(_T ( "/Settings/AIS" ));
2393
2394 Write(_T ( "bNoCPAMax" ), g_bCPAMax);
2395 Write(_T ( "NoCPAMaxNMi" ), g_CPAMax_NM);
2396 Write(_T ( "bCPAWarn" ), g_bCPAWarn);
2397 Write(_T ( "CPAWarnNMi" ), g_CPAWarn_NM);
2398 Write(_T ( "bTCPAMax" ), g_bTCPA_Max);
2399 Write(_T ( "TCPAMaxMinutes" ), g_TCPA_Max);
2400 Write(_T ( "bMarkLostTargets" ), g_bMarkLost);
2401 Write(_T ( "MarkLost_Minutes" ), g_MarkLost_Mins);
2402 Write(_T ( "bRemoveLostTargets" ), g_bRemoveLost);
2403 Write(_T ( "RemoveLost_Minutes" ), g_RemoveLost_Mins);
2404 Write(_T ( "bShowCOGArrows" ), g_bShowCOG);
2405 Write(_T ( "bSyncCogPredictors" ), g_bSyncCogPredictors);
2406 Write(_T ( "CogArrowMinutes" ), g_ShowCOG_Mins);
2407 Write(_T ( "bShowTargetTracks" ), g_bAISShowTracks);
2408 Write(_T ( "TargetTracksMinutes" ), g_AISShowTracks_Mins);
2409
2410 Write(_T ( "bHideMooredTargets" ), g_bHideMoored);
2411 Write(_T ( "MooredTargetMaxSpeedKnots" ), g_ShowMoored_Kts);
2412
2413 Write(_T ( "bAISAlertDialog" ), g_bAIS_CPA_Alert);
2414 Write(_T ( "bAISAlertAudio" ), g_bAIS_CPA_Alert_Audio);
2415
2416 Write(_T ( "AISAlertAudioFile" ), g_sAIS_Alert_Sound_File);
2417 Write(_T ( "bAISAlertSuppressMoored" ), g_bAIS_CPA_Alert_Suppress_Moored);
2418 Write(_T ( "bShowAreaNotices" ), g_bShowAreaNotices);
2419 Write(_T ( "bDrawAISSize" ), g_bDrawAISSize);
2420 Write(_T ( "bDrawAISRealtime" ), g_bDrawAISRealtime);
2421 Write(_T ( "AISRealtimeMinSpeedKnots" ), g_AIS_RealtPred_Kts);
2422 Write(_T ( "bShowAISName" ), g_bShowAISName);
2423 Write(_T ( "ShowAISTargetNameScale" ), g_Show_Target_Name_Scale);
2424 Write(_T ( "bWplIsAprsPositionReport" ), g_bWplUsePosition);
2425 Write(_T ( "WplSelAction" ), g_WplAction);
2426 Write(_T ( "AISCOGPredictorWidth" ), g_ais_cog_predictor_width);
2427 Write(_T ( "bShowScaledTargets" ), g_bAllowShowScaled);
2428 Write(_T ( "AISScaledNumber" ), g_ShowScaled_Num);
2429 Write(_T ( "AISScaledNumberWeightSOG" ), g_ScaledNumWeightSOG);
2430 Write(_T ( "AISScaledNumberWeightCPA" ), g_ScaledNumWeightCPA);
2431 Write(_T ( "AISScaledNumberWeightTCPA" ), g_ScaledNumWeightTCPA);
2432 Write(_T ( "AISScaledNumberWeightRange" ), g_ScaledNumWeightRange);
2433 Write(_T ( "AISScaledNumberWeightSizeOfTarget" ), g_ScaledNumWeightSizeOfT);
2434 Write(_T ( "AISScaledSizeMinimal" ), g_ScaledSizeMinimal);
2435 Write(_T ( "AISShowScaled"), g_bShowScaled);
2436
2437 Write(_T ( "AlertDialogSizeX" ), g_ais_alert_dialog_sx);
2438 Write(_T ( "AlertDialogSizeY" ), g_ais_alert_dialog_sy);
2439 Write(_T ( "AlertDialogPosX" ), g_ais_alert_dialog_x);
2440 Write(_T ( "AlertDialogPosY" ), g_ais_alert_dialog_y);
2441 Write(_T ( "QueryDialogPosX" ), g_ais_query_dialog_x);
2442 Write(_T ( "QueryDialogPosY" ), g_ais_query_dialog_y);
2443 Write(_T ( "AISTargetListPerspective" ), g_AisTargetList_perspective);
2444 Write(_T ( "AISTargetListRange" ), g_AisTargetList_range);
2445 Write(_T ( "AISTargetListSortColumn" ), g_AisTargetList_sortColumn);
2446 Write(_T ( "bAISTargetListSortReverse" ), g_bAisTargetList_sortReverse);
2447 Write(_T ( "AISTargetListColumnSpec" ), g_AisTargetList_column_spec);
2448 Write(_T ("AISTargetListColumnOrder"), g_AisTargetList_column_order);
2449
2450 Write(_T ( "S57QueryDialogSizeX" ), g_S57_dialog_sx);
2451 Write(_T ( "S57QueryDialogSizeY" ), g_S57_dialog_sy);
2452 Write(_T ( "S57QueryExtraDialogSizeX" ), g_S57_extradialog_sx);
2453 Write(_T ( "S57QueryExtraDialogSizeY" ), g_S57_extradialog_sy);
2454
2455 Write(_T ( "bAISRolloverShowClass" ), g_bAISRolloverShowClass);
2456 Write(_T ( "bAISRolloverShowCOG" ), g_bAISRolloverShowCOG);
2457 Write(_T ( "bAISRolloverShowCPA" ), g_bAISRolloverShowCPA);
2458
2459 Write(_T ( "bAISAlertAckTimeout" ), g_bAIS_ACK_Timeout);
2460 Write(_T ( "AlertAckTimeoutMinutes" ), g_AckTimeout_Mins);
2461
2462 SetPath(_T ( "/Settings/GlobalState" ));
2463 if (ps52plib) {
2464 Write(_T ( "bShowS57Text" ), ps52plib->GetShowS57Text());
2465 Write(_T ( "bShowS57ImportantTextOnly" ),
2466 ps52plib->GetShowS57ImportantTextOnly());
2467 if (!g_bInlandEcdis)
2468 Write(_T ( "nDisplayCategory" ), (long)ps52plib->GetDisplayCategory());
2469 Write(_T ( "nSymbolStyle" ), (int)ps52plib->m_nSymbolStyle);
2470 Write(_T ( "nBoundaryStyle" ), (int)ps52plib->m_nBoundaryStyle);
2471
2472 Write(_T ( "bShowSoundg" ), ps52plib->m_bShowSoundg);
2473 Write(_T ( "bShowMeta" ), ps52plib->m_bShowMeta);
2474 Write(_T ( "bUseSCAMIN" ), ps52plib->m_bUseSCAMIN);
2475 Write(_T ( "bUseSUPER_SCAMIN" ), ps52plib->m_bUseSUPER_SCAMIN);
2476 Write(_T ( "bShowAtonText" ), ps52plib->m_bShowAtonText);
2477 Write(_T ( "bShowLightDescription" ), ps52plib->m_bShowLdisText);
2478 Write(_T ( "bExtendLightSectors" ), ps52plib->m_bExtendLightSectors);
2479 Write(_T ( "bDeClutterText" ), ps52plib->m_bDeClutterText);
2480 Write(_T ( "bShowNationalText" ), ps52plib->m_bShowNationalTexts);
2481
2482 Write(_T ( "S52_MAR_SAFETY_CONTOUR" ),
2483 S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR));
2484 Write(_T ( "S52_MAR_SHALLOW_CONTOUR" ),
2485 S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR));
2486 Write(_T ( "S52_MAR_DEEP_CONTOUR" ),
2487 S52_getMarinerParam(S52_MAR_DEEP_CONTOUR));
2488 Write(_T ( "S52_MAR_TWO_SHADES" ), S52_getMarinerParam(S52_MAR_TWO_SHADES));
2489 Write(_T ( "S52_DEPTH_UNIT_SHOW" ), ps52plib->m_nDepthUnitDisplay);
2490 Write(_T ( "ENCSoundingScaleFactor" ), g_ENCSoundingScaleFactor);
2491 Write(_T ( "ENCTextScaleFactor" ), g_ENCTextScaleFactor);
2492 }
2493 SetPath(_T ( "/Directories" ));
2494 Write(_T ( "S57DataLocation" ), _T(""));
2495 // Write( _T ( "SENCFileLocation" ), _T("") );
2496
2497 SetPath(_T ( "/Directories" ));
2498 Write(_T ( "InitChartDir" ), *pInit_Chart_Dir);
2499 Write(_T ( "GPXIODir" ), g_gpx_path);
2500 Write(_T ( "TCDataDir" ), g_TCData_Dir);
2501 Write(_T ( "BasemapDir" ), g_Platform->NormalizePath(gWorldMapLocation));
2502 Write(_T ( "BaseShapefileDir" ),
2503 g_Platform->NormalizePath(gWorldShapefileLocation));
2504 Write(_T ( "pluginInstallDir" ), g_Platform->NormalizePath(g_winPluginDir));
2505
2506 SetPath(_T ( "/Settings/NMEADataSource" ));
2507 wxString connectionconfigs;
2508 for (size_t i = 0; i < TheConnectionParams().size(); i++) {
2509 if (i > 0) connectionconfigs.Append(_T("|"));
2510 connectionconfigs.Append(TheConnectionParams()[i]->Serialize());
2511 }
2512 Write(_T ( "DataConnections" ), connectionconfigs);
2513
2514 // Fonts
2515
2516 // Store the persistent Auxiliary Font descriptor Keys
2517 SetPath(_T ( "/Settings/AuxFontKeys" ));
2518
2519 wxArrayString keyArray = FontMgr::Get().GetAuxKeyArray();
2520 for (unsigned int i = 0; i < keyArray.GetCount(); i++) {
2521 wxString key;
2522 key.Printf(_T("Key%i"), i);
2523 wxString keyval = keyArray[i];
2524 Write(key, keyval);
2525 }
2526
2527 wxString font_path;
2528#ifdef __WXX11__
2529 font_path = (_T ( "/Settings/X11Fonts" ));
2530#endif
2531
2532#ifdef __WXGTK__
2533 font_path = (_T ( "/Settings/GTKFonts" ));
2534#endif
2535
2536#ifdef __WXMSW__
2537 font_path = (_T ( "/Settings/MSWFonts" ));
2538#endif
2539
2540#ifdef __WXMAC__
2541 font_path = (_T ( "/Settings/MacFonts" ));
2542#endif
2543
2544#ifdef __WXQT__
2545 font_path = (_T ( "/Settings/QTFonts" ));
2546#endif
2547
2548 DeleteGroup(font_path);
2549
2550 SetPath(font_path);
2551
2552 int nFonts = FontMgr::Get().GetNumFonts();
2553
2554 for (int i = 0; i < nFonts; i++) {
2555 wxString cfstring(FontMgr::Get().GetConfigString(i));
2556 wxString valstring = FontMgr::Get().GetFullConfigDesc(i);
2557 Write(cfstring, valstring);
2558 }
2559
2560 // Tide/Current Data Sources
2561 DeleteGroup(_T ( "/TideCurrentDataSources" ));
2562 SetPath(_T ( "/TideCurrentDataSources" ));
2563 unsigned int id = 0;
2564 for (auto val : TideCurrentDataSet) {
2565 wxString key;
2566 key.Printf(_T("tcds%d"), id);
2567 Write(key, wxString(val));
2568 ++id;
2569 }
2570
2571 SetPath(_T ( "/Settings/Others" ));
2572
2573 // Radar rings
2574 Write(_T ( "ShowRadarRings" ),
2575 (bool)(g_iNavAidRadarRingsNumberVisible > 0)); // 3.0.0 config support
2576 Write(_T ( "RadarRingsNumberVisible" ), g_iNavAidRadarRingsNumberVisible);
2577 Write(_T ( "RadarRingsStep" ), g_fNavAidRadarRingsStep);
2578 Write(_T ( "RadarRingsStepUnits" ), g_pNavAidRadarRingsStepUnits);
2579 Write(_T ( "RadarRingsColour" ),
2580 g_colourOwnshipRangeRingsColour.GetAsString(wxC2S_HTML_SYNTAX));
2581 Write(_T( "WaypointUseScaMin" ), g_bUseWptScaMin);
2582 Write(_T( "WaypointScaMinValue" ), g_iWpt_ScaMin);
2583 Write(_T( "WaypointUseScaMinOverrule" ), g_bOverruleScaMin);
2584 Write(_T("WaypointsShowName"), g_bShowWptName);
2585 Write(_T("UserIconsFirst"), g_bUserIconsFirst);
2586
2587 // Waypoint Radar rings
2588 Write(_T ( "WaypointRangeRingsNumber" ), g_iWaypointRangeRingsNumber);
2589 Write(_T ( "WaypointRangeRingsStep" ), g_fWaypointRangeRingsStep);
2590 Write(_T ( "WaypointRangeRingsStepUnits" ), g_iWaypointRangeRingsStepUnits);
2591 Write(_T ( "WaypointRangeRingsColour" ),
2592 g_colourWaypointRangeRingsColour.GetAsString(wxC2S_HTML_SYNTAX));
2593
2594 Write(_T ( "ConfirmObjectDeletion" ), g_bConfirmObjectDelete);
2595
2596 // Waypoint dragging with mouse; toh, 2009.02.24
2597 Write(_T ( "WaypointPreventDragging" ), g_bWayPointPreventDragging);
2598
2599 Write(_T ( "EnableZoomToCursor" ), g_bEnableZoomToCursor);
2600
2601 Write(_T ( "TrackIntervalSeconds" ), g_TrackIntervalSeconds);
2602 Write(_T ( "TrackDeltaDistance" ), g_TrackDeltaDistance);
2603 Write(_T ( "TrackPrecision" ), g_nTrackPrecision);
2604
2605 Write(_T ( "RouteLineWidth" ), g_route_line_width);
2606 Write(_T ( "TrackLineWidth" ), g_track_line_width);
2607 Write(_T ( "TrackLineColour" ),
2608 g_colourTrackLineColour.GetAsString(wxC2S_HTML_SYNTAX));
2609 Write(_T ( "DefaultWPIcon" ), g_default_wp_icon);
2610 Write(_T ( "DefaultRPIcon" ), g_default_routepoint_icon);
2611
2612 DeleteGroup(_T ( "/MmsiProperties" ));
2613 SetPath(_T ( "/MmsiProperties" ));
2614 for (unsigned int i = 0; i < g_MMSI_Props_Array.GetCount(); i++) {
2615 wxString p;
2616 p.Printf(_T("Props%d"), i);
2617 Write(p, g_MMSI_Props_Array[i]->Serialize());
2618 }
2619
2620 SaveCanvasConfigs();
2621
2622 Flush();
2623 SendMessageToAllPlugins("GLOBAL_SETTINGS_UPDATED", "{\"updated\":\"1\"}");
2624}
2625
2626static wxFileName exportFileName(wxWindow *parent,
2627 const wxString suggestedName) {
2628 wxFileName ret;
2629 wxString path;
2630 wxString valid_name = SanitizeFileName(suggestedName);
2631
2632#ifdef __ANDROID__
2633 if (!valid_name.EndsWith(".gpx")) {
2634 wxFileName fn(valid_name);
2635 fn.ClearExt();
2636 fn.SetExt("gpx");
2637 valid_name = fn.GetFullName();
2638 }
2639#endif
2640 int response =
2641 g_Platform->DoFileSelectorDialog(parent, &path, _("Export GPX file"),
2642 g_gpx_path, valid_name, wxT("*.gpx"));
2643
2644 if (response == wxID_OK) {
2645 wxFileName fn(path);
2646 g_gpx_path = fn.GetPath();
2647 if (!fn.GetExt().StartsWith("gpx")) fn.SetExt(_T("gpx"));
2648
2649#if defined(__WXMSW__) || defined(__WXGTK__)
2650 if (wxFileExists(fn.GetFullPath())) {
2651 int answer = OCPNMessageBox(NULL, _("Overwrite existing file?"),
2652 _T("Confirm"), wxICON_QUESTION | wxYES_NO);
2653 if (answer != wxID_YES) return ret;
2654 }
2655#endif
2656 ret = fn;
2657 }
2658 return ret;
2659}
2660
2661int BackupDatabase(wxWindow *parent) {
2662 bool backupResult = false;
2663 wxDateTime tm = wxDateTime::Now();
2664 wxString proposedName = tm.Format("navobj-%Y-%m-%d_%H_%M");
2665 wxString acceptedName;
2666
2667 if (wxID_OK ==
2668 g_Platform->DoFileSelectorDialog(parent, &acceptedName, _("Backup"),
2669 wxStandardPaths::Get().GetDocumentsDir(),
2670 proposedName, wxT("*.bkp"))) {
2671 wxFileName fileName(acceptedName);
2672 if (fileName.IsOk()) {
2673#if defined(__WXMSW__) || defined(__WXGTK__)
2674 if (fileName.FileExists()) {
2675 if (wxID_YES != OCPNMessageBox(NULL, _("Overwrite existing file?"),
2676 _T("Confirm"),
2677 wxICON_QUESTION | wxYES_NO)) {
2678 return wxID_ABORT; // We've decided not to overwrite a file, aborting
2679 }
2680 }
2681#endif
2682
2683#ifdef __ANDROID__
2684 wxString secureFileName = androidGetCacheDir() +
2685 wxFileName::GetPathSeparator() +
2686 fileName.GetFullName();
2687 backupResult = NavObj_dB::GetInstance().Backup(secureFileName);
2688 AndroidSecureCopyFile(secureFileName, fileName.GetFullPath());
2689#else
2690 backupResult = NavObj_dB::GetInstance().Backup(fileName.GetFullPath());
2691#endif
2692 }
2693 return backupResult ? wxID_YES : wxID_NO;
2694 }
2695 return wxID_ABORT; // Cancelled the file open dialog, aborting
2696}
2697
2698bool ExportGPXRoutes(wxWindow *parent, RouteList *pRoutes,
2699 const wxString suggestedName) {
2700#ifndef __ANDROID__
2701 wxFileName fn = exportFileName(parent, suggestedName);
2702 if (fn.IsOk()) {
2704 pgpx->AddGPXRoutesList(pRoutes);
2705 pgpx->SaveFile(fn.GetFullPath());
2706 delete pgpx;
2707 return true;
2708 }
2709#else
2710 // Create the .GPX file, saving it in the OCPN Android cache directory
2711 wxString fns = androidGetCacheDir() + wxFileName::GetPathSeparator() +
2712 suggestedName + ".gpx";
2714 pgpx->AddGPXRoutesList(pRoutes);
2715 pgpx->SaveFile(fns);
2716 delete pgpx;
2717
2718 // Kick off the Android file chooser activity
2719 wxString path;
2720 int response = g_Platform->DoFileSelectorDialog(
2721 parent, &path, _("Export GPX file"), g_gpx_path, suggestedName + ".gpx",
2722 wxT("*.gpx"));
2723
2724 if (path.IsEmpty()) // relocation handled by SAF logic in Java
2725 return true;
2726
2727 wxCopyFile(fns, path); // known to be safe paths, since SAF is not involved.
2728 return true;
2729
2730#endif
2731
2732 return false;
2733}
2734
2735bool ExportGPXTracks(wxWindow *parent, std::vector<Track *> *pTracks,
2736 const wxString suggestedName) {
2737#ifndef __ANDROID__
2738 wxFileName fn = exportFileName(parent, suggestedName);
2739 if (fn.IsOk()) {
2741 pgpx->AddGPXTracksList(pTracks);
2742 pgpx->SaveFile(fn.GetFullPath());
2743 delete pgpx;
2744 return true;
2745 }
2746#else
2747 // Create the .GPX file, saving it in the OCPN Android cache directory
2748 wxString fns = androidGetCacheDir() + wxFileName::GetPathSeparator() +
2749 suggestedName + ".gpx";
2751 pgpx->AddGPXTracksList(pTracks);
2752 pgpx->SaveFile(fns);
2753 delete pgpx;
2754
2755 // Kick off the Android file chooser activity
2756 wxString path;
2757 int response = g_Platform->DoFileSelectorDialog(
2758 parent, &path, _("Export GPX file"), g_gpx_path, suggestedName + ".gpx",
2759 wxT("*.gpx"));
2760
2761 if (path.IsEmpty()) // relocation handled by SAF logic in Java
2762 return true;
2763
2764 wxCopyFile(fns, path); // known to be safe paths, since SAF is not involved.
2765 return true;
2766#endif
2767
2768 return false;
2769}
2770
2771bool ExportGPXWaypoints(wxWindow *parent, RoutePointList *pRoutePoints,
2772 const wxString suggestedName) {
2773#ifndef __ANDROID__
2774 wxFileName fn = exportFileName(parent, suggestedName);
2775 if (fn.IsOk()) {
2777 pgpx->AddGPXPointsList(pRoutePoints);
2778 pgpx->SaveFile(fn.GetFullPath());
2779 delete pgpx;
2780 return true;
2781 }
2782#else
2783 // Create the .GPX file, saving it in the OCPN Android cache directory
2784 wxString fns = androidGetCacheDir() + wxFileName::GetPathSeparator() +
2785 suggestedName + ".gpx";
2787 pgpx->AddGPXPointsList(pRoutePoints);
2788 pgpx->SaveFile(fns);
2789 delete pgpx;
2790
2791 // Kick off the Android file chooser activity
2792 wxString path;
2793 int response = g_Platform->DoFileSelectorDialog(
2794 parent, &path, _("Export GPX file"), g_gpx_path, suggestedName + ".gpx",
2795 wxT("*.gpx"));
2796
2797 if (path.IsEmpty()) // relocation handled by SAF logic in Java
2798 return true;
2799
2800 wxCopyFile(fns, path); // known to be safe paths, since SAF is not involved.
2801 return true;
2802
2803#endif
2804
2805 return false;
2806}
2807
2808void ExportGPX(wxWindow *parent, bool bviz_only, bool blayer) {
2810 wxString fns;
2811
2812#ifndef __ANDROID__
2813 wxFileName fn = exportFileName(parent, _T("userobjects.gpx"));
2814 if (!fn.IsOk()) return;
2815 fns = fn.GetFullPath();
2816#else
2817 // Create the .GPX file, saving it in the OCPN Android cache directory
2818 fns =
2819 androidGetCacheDir() + wxFileName::GetPathSeparator() + "userobjects.gpx";
2820
2821#endif
2822 ::wxBeginBusyCursor();
2823
2824 wxGenericProgressDialog *pprog = nullptr;
2825 int count = pWayPointMan->GetWaypointList()->GetCount();
2826 int progStep = count / 32;
2827 if (count > 200) {
2828 pprog = new wxGenericProgressDialog(
2829 _("Export GPX file"), _T("0/0"), count, NULL,
2830 wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
2831 wxPD_REMAINING_TIME);
2832 pprog->SetSize(400, wxDefaultCoord);
2833 pprog->Centre();
2834 }
2835
2836 // WPTs
2837 int ic = 1;
2838
2839 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
2840 RoutePoint *pr;
2841 while (node) {
2842 if (pprog && !(ic % progStep)) {
2843 wxString msg;
2844 msg.Printf(_T("%d/%d"), ic, count);
2845 pprog->Update(ic, msg);
2846 }
2847 ic++;
2848
2849 pr = node->GetData();
2850
2851 bool b_add = true;
2852
2853 if (bviz_only && !pr->m_bIsVisible) b_add = false;
2854
2855 if (pr->m_bIsInLayer && !blayer) b_add = false;
2856 if (b_add) {
2857 if (pr->IsShared() || !WptIsInRouteList(pr)) pgpx->AddGPXWaypoint(pr);
2858 }
2859
2860 node = node->GetNext();
2861 }
2862 // RTEs and TRKs
2863 wxRouteListNode *node1 = pRouteList->GetFirst();
2864 while (node1) {
2865 Route *pRoute = node1->GetData();
2866
2867 bool b_add = true;
2868
2869 if (bviz_only && !pRoute->IsVisible()) b_add = false;
2870
2871 if (pRoute->m_bIsInLayer && !blayer) b_add = false;
2872
2873 if (b_add) pgpx->AddGPXRoute(pRoute);
2874
2875 node1 = node1->GetNext();
2876 }
2877
2878 for (Track *pTrack : g_TrackList) {
2879 bool b_add = true;
2880
2881 if (bviz_only && !pTrack->IsVisible()) b_add = false;
2882
2883 if (pTrack->m_bIsInLayer && !blayer) b_add = false;
2884
2885 if (b_add) pgpx->AddGPXTrack(pTrack);
2886 }
2887
2888 pgpx->SaveFile(fns);
2889
2890#ifdef __ANDROID__
2891 // Kick off the Android file chooser activity
2892 wxString path;
2893 int response = g_Platform->DoFileSelectorDialog(
2894 parent, &path, _("Export GPX file"), g_gpx_path, "userobjects.gpx",
2895 wxT("*.gpx"));
2896 if (path.IsEmpty()) // relocation handled by SAF logic in Java
2897 return;
2898
2899 wxCopyFile(fns, path); // known to be safe paths, since SAF is not involved.
2900 return;
2901#endif
2902 delete pgpx;
2903 ::wxEndBusyCursor();
2904 delete pprog;
2905}
2906
2907void UI_ImportGPX(wxWindow *parent, bool islayer, wxString dirpath,
2908 bool isdirectory, bool isPersistent) {
2909 int response = wxID_CANCEL;
2910 wxArrayString file_array;
2911
2912 if (!islayer || dirpath.IsSameAs(_T(""))) {
2913 // Platform DoFileSelectorDialog method does not properly handle multiple
2914 // selections So use native method if not Android, which means Android gets
2915 // single selection only.
2916#ifndef __ANDROID__
2917 wxFileDialog *popenDialog =
2918 new wxFileDialog(NULL, _("Import GPX file"), g_gpx_path, wxT(""),
2919 wxT("GPX files (*.gpx)|*.gpx|All files (*.*)|*.*"),
2920 wxFD_OPEN | wxFD_MULTIPLE);
2921
2922 if (g_bresponsive && parent)
2923 popenDialog = g_Platform->AdjustFileDialogFont(parent, popenDialog);
2924
2925 popenDialog->Centre();
2926
2927#ifdef __WXOSX__
2928 if (parent) parent->HideWithEffect(wxSHOW_EFFECT_BLEND);
2929#endif
2930
2931 response = popenDialog->ShowModal();
2932
2933#ifdef __WXOSX__
2934 if (parent) parent->ShowWithEffect(wxSHOW_EFFECT_BLEND);
2935#endif
2936
2937 if (response == wxID_OK) {
2938 popenDialog->GetPaths(file_array);
2939
2940 // Record the currently selected directory for later use
2941 if (file_array.GetCount()) {
2942 wxFileName fn(file_array[0]);
2943 g_gpx_path = fn.GetPath();
2944 }
2945 }
2946 delete popenDialog;
2947#else // Android
2948 wxString path;
2949 response = g_Platform->DoFileSelectorDialog(
2950 NULL, &path, _("Import GPX file"), g_gpx_path, _T(""), wxT("*.gpx"));
2951
2952 wxFileName fn(path);
2953 g_gpx_path = fn.GetPath();
2954 if (path.IsEmpty()) // Return from SAF processing, expecting callback
2955 return;
2956 else
2957 file_array.Add(path); // Return from safe app arena access
2958
2959#endif
2960 } else {
2961 if (isdirectory) {
2962 if (wxDir::GetAllFiles(dirpath, &file_array, wxT("*.gpx")))
2963 response = wxID_OK;
2964 } else {
2965 file_array.Add(dirpath);
2966 response = wxID_OK;
2967 }
2968 }
2969
2970 if (response == wxID_OK) {
2971 ImportFileArray(file_array, islayer, isPersistent, dirpath);
2972 }
2973}
2974
2975void ImportFileArray(const wxArrayString &file_array, bool islayer,
2976 bool isPersistent, wxString dirpath) {
2977 Layer *l = NULL;
2978
2979 if (islayer) {
2980 l = new Layer();
2981 l->m_LayerID = ++g_LayerIdx;
2982 l->m_LayerFileName = file_array[0];
2983 if (file_array.GetCount() <= 1)
2984 wxFileName::SplitPath(file_array[0], NULL, NULL, &(l->m_LayerName), NULL,
2985 NULL);
2986 else {
2987 if (dirpath.IsSameAs(_T("")))
2988 wxFileName::SplitPath(g_gpx_path, NULL, NULL, &(l->m_LayerName), NULL,
2989 NULL);
2990 else
2991 wxFileName::SplitPath(dirpath, NULL, NULL, &(l->m_LayerName), NULL,
2992 NULL);
2993 }
2994
2995 bool bLayerViz = g_bShowLayers;
2996 if (g_VisibleLayers.Contains(l->m_LayerName)) bLayerViz = true;
2997 if (g_InvisibleLayers.Contains(l->m_LayerName)) bLayerViz = false;
2998 l->m_bIsVisibleOnChart = bLayerViz;
2999
3000 // Default for new layers is "Names visible"
3001 l->m_bHasVisibleNames = wxCHK_CHECKED;
3002
3003 wxString laymsg;
3004 laymsg.Printf(wxT("New layer %d: %s"), l->m_LayerID,
3005 l->m_LayerName.c_str());
3006 wxLogMessage(laymsg);
3007
3008 pLayerList->Insert(l);
3009 }
3010
3011 for (unsigned int i = 0; i < file_array.GetCount(); i++) {
3012 wxString path = file_array[i];
3013
3014 if (::wxFileExists(path)) {
3016 if (pSet->load_file(path.fn_str()).status !=
3017 pugi::xml_parse_status::status_ok) {
3018 wxLogMessage("Error loading GPX file " + path);
3019 pSet->reset();
3020 delete pSet;
3021 continue;
3022 }
3023
3024 if (islayer) {
3025 l->m_NoOfItems = pSet->LoadAllGPXObjectsAsLayer(
3026 l->m_LayerID, l->m_bIsVisibleOnChart, l->m_bHasVisibleNames);
3027 l->m_LayerType = isPersistent ? _("Persistent") : _("Temporary");
3028
3029 if (isPersistent) {
3030 // If this is a persistent layer also copy the file to config file
3031 // dir /layers
3032 wxString destf, f, name, ext;
3033 f = l->m_LayerFileName;
3034 wxFileName::SplitPath(f, NULL, NULL, &name, &ext);
3035 destf = g_Platform->GetPrivateDataDir();
3036 appendOSDirSlash(&destf);
3037 destf.Append(_T("layers"));
3038 appendOSDirSlash(&destf);
3039 if (!wxDirExists(destf)) {
3040 if (!wxMkdir(destf, wxS_DIR_DEFAULT))
3041 wxLogMessage(_T("Error creating layer directory"));
3042 }
3043
3044 destf << name << _T(".") << ext;
3045 wxString msg;
3046 if (wxCopyFile(f, destf, true))
3047 msg.Printf(_T("File: %s.%s also added to persistent layers"), name,
3048 ext);
3049 else
3050 msg.Printf(_T("Failed adding %s.%s to persistent layers"), name,
3051 ext);
3052 wxLogMessage(msg);
3053 }
3054 } else {
3055 int wpt_dups;
3056 pSet->LoadAllGPXObjects(
3057 !pSet->IsOpenCPN(),
3058 wpt_dups); // Import with full visibility of names and objects
3059 if (wpt_dups > 0) {
3060 OCPNMessageBox(
3061 NULL,
3062 wxString::Format(_T("%d ") + _("duplicate waypoints detected "
3063 "during import and ignored."),
3064 wpt_dups),
3065 _("OpenCPN Info"), wxICON_INFORMATION | wxOK, 10);
3066 }
3067 }
3068 delete pSet;
3069 }
3070 }
3071}
3072
3073//-------------------------------------------------------------------------
3074// Static Routine Switch to Inland Ecdis Mode
3075//-------------------------------------------------------------------------
3076void SwitchInlandEcdisMode(bool Switch) {
3077 if (Switch) {
3078 wxLogMessage(_T("Switch InlandEcdis mode On"));
3079 LoadS57();
3080 // Overule some sewttings to comply with InlandEcdis
3081 // g_toolbarConfig = _T ( ".....XXXX.X...XX.XXXXXXXXXXXX" );
3082 g_iDistanceFormat = 2; // 0 = "Nautical miles"), 1 = "Statute miles", 2 =
3083 // "Kilometers", 3 = "Meters"
3084 g_iSpeedFormat = 2; // 0 = "kts"), 1 = "mph", 2 = "km/h", 3 = "m/s"
3085 if (ps52plib) ps52plib->SetDisplayCategory(STANDARD);
3086 g_bDrawAISSize = false;
3087 if (gFrame) gFrame->RequestNewToolbars(true);
3088 } else {
3089 wxLogMessage(_T("Switch InlandEcdis mode Off"));
3090 // reread the settings overruled by inlandEcdis
3091 if (pConfig) {
3092 pConfig->SetPath(_T ( "/Settings" ));
3093 pConfig->Read(_T ( "GlobalToolbarConfig" ), &g_toolbarConfig);
3094 pConfig->Read(_T ( "DistanceFormat" ), &g_iDistanceFormat);
3095 pConfig->Read(_T ( "SpeedFormat" ), &g_iSpeedFormat);
3096 pConfig->Read(_T ( "ShowDepthUnits" ), &g_bShowDepthUnits, 1);
3097 int read_int;
3098 pConfig->Read(_T ( "nDisplayCategory" ), &read_int,
3099 (enum _DisCat)STANDARD);
3100 if (ps52plib) ps52plib->SetDisplayCategory((enum _DisCat)read_int);
3101 pConfig->SetPath(_T ( "/Settings/AIS" ));
3102 pConfig->Read(_T ( "bDrawAISSize" ), &g_bDrawAISSize);
3103 pConfig->Read(_T ( "bDrawAISRealtime" ), &g_bDrawAISRealtime);
3104 }
3105 if (gFrame) gFrame->RequestNewToolbars(true);
3106 }
3107}
3108
3109//-------------------------------------------------------------------------
3110//
3111// Static GPX Support Routines
3112//
3113//-------------------------------------------------------------------------
3114// This function formats the input date/time into a valid GPX ISO 8601
3115// time string specified in the UTC time zone.
3116
3117wxString FormatGPXDateTime(wxDateTime dt) {
3118 // return dt.Format(wxT("%Y-%m-%dT%TZ"), wxDateTime::GMT0);
3119 return dt.Format(wxT("%Y-%m-%dT%H:%M:%SZ"));
3120}
3121
3122/**************************************************************************/
3123/* LogMessageOnce */
3124/**************************************************************************/
3125
3126bool LogMessageOnce(const wxString &msg) {
3127 // Search the array for a match
3128
3129 for (unsigned int i = 0; i < pMessageOnceArray->GetCount(); i++) {
3130 if (msg.IsSameAs(pMessageOnceArray->Item(i))) return false;
3131 }
3132
3133 // Not found, so add to the array
3134 pMessageOnceArray->Add(msg);
3135
3136 // And print it
3137 wxLogMessage(msg);
3138 return true;
3139}
3140
3141/**************************************************************************/
3142/* Some assorted utilities */
3143/**************************************************************************/
3144
3145wxDateTime toUsrDateTime(const wxDateTime ts, const int format,
3146 const double lon) {
3147 if (!ts.IsValid()) {
3148 return ts;
3149 }
3150 int effective_format = format;
3151 if (effective_format == GLOBAL_SETTINGS_INPUT) {
3152 if (::g_datetime_format == "UTC") {
3153 effective_format = UTCINPUT;
3154 } else if (::g_datetime_format == "LMT") {
3155 effective_format = LMTINPUT;
3156 } else if (::g_datetime_format == "Local Time") {
3157 effective_format = LTINPUT;
3158 } else {
3159 // Default to UTC
3160 effective_format = UTCINPUT;
3161 }
3162 }
3163 wxDateTime dt;
3164 switch (effective_format) {
3165 case LMTINPUT: // LMT@Location
3166 if (std::isnan(lon)) {
3167 dt = wxInvalidDateTime;
3168 } else {
3169 dt =
3170 ts.Add(wxTimeSpan(wxTimeSpan(0, 0, wxLongLong(lon * 3600. / 15.))));
3171 }
3172 break;
3173 case LTINPUT: // Local@PC
3174 // Convert date/time from UTC to local time.
3175 dt = ts.FromUTC();
3176 break;
3177 case UTCINPUT: // UTC
3178 // The date/time is already in UTC.
3179 dt = ts;
3180 break;
3181 }
3182 return dt;
3183}
3184
3185wxDateTime fromUsrDateTime(const wxDateTime ts, const int format,
3186 const double lon) {
3187 if (!ts.IsValid()) {
3188 return ts;
3189 }
3190 int effective_format = format;
3191 if (effective_format == GLOBAL_SETTINGS_INPUT) {
3192 if (::g_datetime_format == "UTC") {
3193 effective_format = UTCINPUT;
3194 } else if (::g_datetime_format == "LMT") {
3195 effective_format = LMTINPUT;
3196 } else if (::g_datetime_format == "Local Time") {
3197 effective_format = LTINPUT;
3198 } else {
3199 // Default to UTC
3200 effective_format = UTCINPUT;
3201 }
3202 }
3203 wxDateTime dt;
3204 switch (effective_format) {
3205 case LMTINPUT: // LMT@Location
3206 if (std::isnan(lon)) {
3207 dt = wxInvalidDateTime;
3208 } else {
3209 dt = ts.Subtract(wxTimeSpan(0, 0, wxLongLong(lon * 3600. / 15.)));
3210 }
3211 break;
3212 case LTINPUT: // Local@PC
3213 // The input date/time is in local time, so convert it to UTC.
3214 dt = ts.ToUTC();
3215 break;
3216 case UTCINPUT: // UTC
3217 dt = ts;
3218 break;
3219 }
3220 return dt;
3221}
3222
3223/**************************************************************************/
3224/* Converts the distance from the units selected by user to NMi */
3225/**************************************************************************/
3226double fromUsrDistance(double usr_distance, int unit) {
3227 double ret = NAN;
3228 if (unit == -1) unit = g_iDistanceFormat;
3229 switch (unit) {
3230 case DISTANCE_NMI: // Nautical miles
3231 ret = usr_distance;
3232 break;
3233 case DISTANCE_MI: // Statute miles
3234 ret = usr_distance / 1.15078;
3235 break;
3236 case DISTANCE_KM:
3237 ret = usr_distance / 1.852;
3238 break;
3239 case DISTANCE_M:
3240 ret = usr_distance / 1852;
3241 break;
3242 case DISTANCE_FT:
3243 ret = usr_distance / 6076.12;
3244 break;
3245 }
3246 return ret;
3247}
3248/**************************************************************************/
3249/* Converts the speed from the units selected by user to knots */
3250/**************************************************************************/
3251double fromUsrSpeed(double usr_speed, int unit) {
3252 double ret = NAN;
3253 if (unit == -1) unit = g_iSpeedFormat;
3254 switch (unit) {
3255 case SPEED_KTS: // kts
3256 ret = usr_speed;
3257 break;
3258 case SPEED_MPH: // mph
3259 ret = usr_speed / 1.15078;
3260 break;
3261 case SPEED_KMH: // km/h
3262 ret = usr_speed / 1.852;
3263 break;
3264 case SPEED_MS: // m/s
3265 ret = usr_speed / 0.514444444;
3266 break;
3267 }
3268 return ret;
3269}
3270/**************************************************************************/
3271/* Converts the wind speed from the units selected by user to knots */
3272/**************************************************************************/
3273double fromUsrWindSpeed(double usr_wspeed, int unit) {
3274 double ret = NAN;
3275 if (unit == -1) unit = g_iWindSpeedFormat;
3276 switch (unit) {
3277 case WSPEED_KTS: // kts
3278 ret = usr_wspeed;
3279 break;
3280 case WSPEED_MS: // m/s
3281 ret = usr_wspeed / 0.514444444;
3282 break;
3283 case WSPEED_MPH: // mph
3284 ret = usr_wspeed / 1.15078;
3285 break;
3286 case WSPEED_KMH: // km/h
3287 ret = usr_wspeed / 1.852;
3288 break;
3289 }
3290 return ret;
3291}
3292
3293/**************************************************************************/
3294/* Converts the temperature from the units selected by user to Celsius */
3295/**************************************************************************/
3296double fromUsrTemp(double usr_temp, int unit) {
3297 double ret = NAN;
3298 if (unit == -1) unit = g_iTempFormat;
3299 switch (unit) {
3300 case TEMPERATURE_C: // C
3301 ret = usr_temp;
3302 break;
3303 case TEMPERATURE_F: // F
3304 ret = (usr_temp - 32) * 5.0 / 9.0;
3305 break;
3306 case TEMPERATURE_K: // K
3307 ret = usr_temp - 273.15;
3308 break;
3309 }
3310 return ret;
3311}
3312
3313wxString formatAngle(double angle) {
3314 wxString out;
3315 if (g_bShowMag && g_bShowTrue) {
3316 out.Printf(wxT("%03.0f %cT (%.0f %cM)"), angle, 0x00B0, toMagnetic(angle),
3317 0x00B0);
3318 } else if (g_bShowTrue) {
3319 out.Printf(wxT("%03.0f %cT"), angle, 0x00B0);
3320 } else {
3321 out.Printf(wxT("%03.0f %cM"), toMagnetic(angle), 0x00B0);
3322 }
3323 return out;
3324}
3325
3326/* render a rectangle at a given color and transparency */
3327void AlphaBlending(ocpnDC &dc, int x, int y, int size_x, int size_y,
3328 float radius, wxColour color, unsigned char transparency) {
3329 wxDC *pdc = dc.GetDC();
3330 if (pdc) {
3331 // Get wxImage of area of interest
3332 wxBitmap obm(size_x, size_y);
3333 wxMemoryDC mdc1;
3334 mdc1.SelectObject(obm);
3335 mdc1.Blit(0, 0, size_x, size_y, pdc, x, y);
3336 mdc1.SelectObject(wxNullBitmap);
3337 wxImage oim = obm.ConvertToImage();
3338
3339 // Create destination image
3340 wxBitmap olbm(size_x, size_y);
3341 wxMemoryDC oldc(olbm);
3342 if (!oldc.IsOk()) return;
3343
3344 oldc.SetBackground(*wxBLACK_BRUSH);
3345 oldc.SetBrush(*wxWHITE_BRUSH);
3346 oldc.Clear();
3347
3348 if (radius > 0.0) oldc.DrawRoundedRectangle(0, 0, size_x, size_y, radius);
3349
3350 wxImage dest = olbm.ConvertToImage();
3351 unsigned char *dest_data =
3352 (unsigned char *)malloc(size_x * size_y * 3 * sizeof(unsigned char));
3353 unsigned char *bg = oim.GetData();
3354 unsigned char *box = dest.GetData();
3355 unsigned char *d = dest_data;
3356
3357 // Sometimes, on Windows, the destination image is corrupt...
3358 if (NULL == box) {
3359 free(d);
3360 return;
3361 }
3362 float alpha = 1.0 - (float)transparency / 255.0;
3363 int sb = size_x * size_y;
3364 for (int i = 0; i < sb; i++) {
3365 float a = alpha;
3366 if (*box == 0 && radius > 0.0) a = 1.0;
3367 int r = ((*bg++) * a) + (1.0 - a) * color.Red();
3368 *d++ = r;
3369 box++;
3370 int g = ((*bg++) * a) + (1.0 - a) * color.Green();
3371 *d++ = g;
3372 box++;
3373 int b = ((*bg++) * a) + (1.0 - a) * color.Blue();
3374 *d++ = b;
3375 box++;
3376 }
3377
3378 dest.SetData(dest_data);
3379
3380 // Convert destination to bitmap and draw it
3381 wxBitmap dbm(dest);
3382 dc.DrawBitmap(dbm, x, y, false);
3383
3384 // on MSW, the dc Bounding box is not updated on DrawBitmap() method.
3385 // Do it explicitely here for all platforms.
3386 dc.CalcBoundingBox(x, y);
3387 dc.CalcBoundingBox(x + size_x, y + size_y);
3388 } else {
3389#ifdef ocpnUSE_GL
3390 glEnable(GL_BLEND);
3391
3392 float radMod = wxMax(radius, 2.0);
3393 wxColour c(color.Red(), color.Green(), color.Blue(), transparency);
3394 dc.SetBrush(wxBrush(c));
3395 dc.SetPen(wxPen(c, 1));
3396 dc.DrawRoundedRectangle(x, y, size_x, size_y, radMod);
3397
3398 glDisable(GL_BLEND);
3399
3400#endif
3401 }
3402}
3403
3404void DimeControl(wxWindow *ctrl) {
3405#ifdef __WXOSX__
3406 // On macOS 10.14+, we use the native colours in both light mode and dark
3407 // mode, and do not need to do anything else. Dark mode is toggled at the
3408 // application level in `SetAndApplyColorScheme`, and is also respected if it
3409 // is enabled system-wide.
3410 if (wxPlatformInfo::Get().CheckOSVersion(10, 14)) {
3411 return;
3412 }
3413#endif
3414#ifdef __WXQT__
3415 return; // this is seriously broken on wxqt
3416#endif
3417
3418 if (wxSystemSettings::GetColour(wxSystemColour::wxSYS_COLOUR_WINDOW).Red() <
3419 128) {
3420 // Dark system color themes usually do better job than we do on diming UI
3421 // controls, do not fight with them
3422 return;
3423 }
3424
3425 if (NULL == ctrl) return;
3426
3427 wxColour col, window_back_color, gridline, uitext, udkrd, ctrl_back_color,
3428 text_color;
3429 col = GetGlobalColor(_T("DILG0")); // Dialog Background white
3430 window_back_color = GetGlobalColor(_T("DILG1")); // Dialog Background
3431 ctrl_back_color = GetGlobalColor(_T("DILG1")); // Control Background
3432 text_color = GetGlobalColor(_T("DILG3")); // Text
3433 uitext = GetGlobalColor(_T("UITX1")); // Menu Text, derived from UINFF
3434 udkrd = GetGlobalColor(_T("UDKRD"));
3435 gridline = GetGlobalColor(_T("GREY2"));
3436
3437 DimeControl(ctrl, col, window_back_color, ctrl_back_color, text_color, uitext,
3438 udkrd, gridline);
3439}
3440
3441void DimeControl(wxWindow *ctrl, wxColour col, wxColour window_back_color,
3442 wxColour ctrl_back_color, wxColour text_color, wxColour uitext,
3443 wxColour udkrd, wxColour gridline) {
3444#ifdef __WXOSX__
3445 // On macOS 10.14+, we use the native colours in both light mode and dark
3446 // mode, and do not need to do anything else. Dark mode is toggled at the
3447 // application level in `SetAndApplyColorScheme`, and is also respected if it
3448 // is enabled system-wide.
3449 if (wxPlatformInfo::Get().CheckOSVersion(10, 14)) {
3450 return;
3451 }
3452#endif
3453
3454 ColorScheme cs = global_color_scheme;
3455
3456 // Are we in dusk or night mode? (Used below in several places.)
3457 bool darkMode =
3458 (cs == GLOBAL_COLOR_SCHEME_DUSK || cs == GLOBAL_COLOR_SCHEME_NIGHT);
3459
3460 static int depth = 0; // recursion count
3461 if (depth == 0) { // only for the window root, not for every child
3462 // If the color scheme is DAY or RGB, use the default platform native colour
3463 // for backgrounds
3464 if (!darkMode) {
3465#ifdef _WIN32
3466 window_back_color = wxNullColour;
3467#else
3468 window_back_color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
3469#endif
3470 col = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
3471 uitext = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
3472 }
3473
3474 ctrl->SetBackgroundColour(window_back_color);
3475 if (darkMode) ctrl->SetForegroundColour(text_color);
3476 }
3477
3478 wxWindowList kids = ctrl->GetChildren();
3479 for (unsigned int i = 0; i < kids.GetCount(); i++) {
3480 wxWindowListNode *node = kids.Item(i);
3481 wxWindow *win = node->GetData();
3482
3483 if (dynamic_cast<wxListBox *>(win) || dynamic_cast<wxListCtrl *>(win) ||
3484 dynamic_cast<wxTextCtrl *>(win) ||
3485 dynamic_cast<wxTimePickerCtrl *>(win)) {
3486 win->SetBackgroundColour(col);
3487 } else if (dynamic_cast<wxStaticText *>(win) ||
3488 dynamic_cast<wxCheckBox *>(win) ||
3489 dynamic_cast<wxRadioButton *>(win)) {
3490 win->SetForegroundColour(uitext);
3491 }
3492#ifndef __WXOSX__
3493 // On macOS most controls can't be styled, and trying to do so only creates
3494 // weird coloured boxes around them. Fortunately, however, many of them
3495 // inherit a colour or tint from the background of their parent.
3496
3497 else if (dynamic_cast<wxBitmapComboBox *>(win) ||
3498 dynamic_cast<wxChoice *>(win) || dynamic_cast<wxComboBox *>(win) ||
3499 dynamic_cast<wxTreeCtrl *>(win)) {
3500 win->SetBackgroundColour(col);
3501 }
3502
3503 else if (dynamic_cast<wxScrolledWindow *>(win) ||
3504 dynamic_cast<wxGenericDirCtrl *>(win) ||
3505 dynamic_cast<wxListbook *>(win) || dynamic_cast<wxButton *>(win) ||
3506 dynamic_cast<wxToggleButton *>(win)) {
3507 win->SetBackgroundColour(window_back_color);
3508 }
3509
3510 else if (dynamic_cast<wxNotebook *>(win)) {
3511 win->SetBackgroundColour(window_back_color);
3512 win->SetForegroundColour(text_color);
3513 }
3514#endif
3515
3516 else if (dynamic_cast<wxHtmlWindow *>(win)) {
3517 if (cs != GLOBAL_COLOR_SCHEME_DAY && cs != GLOBAL_COLOR_SCHEME_RGB)
3518 win->SetBackgroundColour(ctrl_back_color);
3519 else
3520 win->SetBackgroundColour(wxNullColour);
3521 }
3522
3523 else if (dynamic_cast<wxGrid *>(win)) {
3524 dynamic_cast<wxGrid *>(win)->SetDefaultCellBackgroundColour(
3525 window_back_color);
3526 dynamic_cast<wxGrid *>(win)->SetDefaultCellTextColour(uitext);
3527 dynamic_cast<wxGrid *>(win)->SetLabelBackgroundColour(col);
3528 dynamic_cast<wxGrid *>(win)->SetLabelTextColour(uitext);
3529 dynamic_cast<wxGrid *>(win)->SetGridLineColour(gridline);
3530 }
3531
3532 if (win->GetChildren().GetCount() > 0) {
3533 depth++;
3534 wxWindow *w = win;
3535 DimeControl(w, col, window_back_color, ctrl_back_color, text_color,
3536 uitext, udkrd, gridline);
3537 depth--;
3538 }
3539 }
3540}
3541
3542#define LUMIMOSITY_NIGHT (-0.8)
3543#define LUMIMOSITY_DUSK (-0.5)
3544
3545wxColor GetDimedColor(const wxColor &c) {
3546 switch (global_color_scheme) {
3547 case ColorScheme::GLOBAL_COLOR_SCHEME_NIGHT:
3548 return (wxColor(
3549 wxMax(0, wxMin(c.Red() + c.Red() * LUMIMOSITY_NIGHT, 255)),
3550 wxMax(0, wxMin(c.Green() + c.Green() * LUMIMOSITY_NIGHT, 255)),
3551 wxMax(0, wxMin(c.Blue() + c.Blue() * LUMIMOSITY_NIGHT, 255))));
3552 case ColorScheme::GLOBAL_COLOR_SCHEME_DUSK:
3553 return (
3554 wxColor(wxMax(0, wxMin(c.Red() + c.Red() * LUMIMOSITY_DUSK, 255)),
3555 wxMax(0, wxMin(c.Green() + c.Green() * LUMIMOSITY_DUSK, 255)),
3556 wxMax(0, wxMin(c.Blue() + c.Blue() * LUMIMOSITY_DUSK, 255))));
3557 default:
3558 return c;
3559 }
3560}
bool g_bresponsive
Flag to control adaptive UI scaling.
Definition ocpn_app.cpp:666
Class AisDecoder and helpers.
Global state for AIS decoder.
wxString & GetPrivateDataDir()
Return dir path for opencpn.log, etc., respecting -c cli option.
Represents an individual component within a ChartGroup.
Definition chartdbs.h:446
Represents a user-defined collection of logically related charts.
Definition chartdbs.h:466
wxString GetFullConfigDesc(int i) const
Gets description of font at index i.
Definition FontMgr.cpp:379
bool AddAuxKey(wxString key)
Adds new plugin-defined font configuration key.
Definition FontMgr.cpp:684
void LoadFontNative(wxString *pConfigString, wxString *pNativeDesc)
Loads font settings from a string descriptor.
Definition FontMgr.cpp:409
static wxString GetFontConfigKey(const wxString &description)
Creates configuration key from UI element name by combining locale with hash.
Definition FontMgr.cpp:132
int GetNumFonts(void) const
Gets the total number of font configurations currently loaded.
Definition FontMgr.cpp:342
wxArrayString & GetAuxKeyArray()
Gets array of plugin-defined font configuration keys.
Definition FontMgr.h:183
Represents a layer of chart objects in OpenCPN.
Definition Layer.h:38
Process incoming AIS messages.
Definition ais_decoder.h:73
static int config_to_ui(double value)
Convert configuration 1.02..3.0 value to slider scale 1..100.
Definition navutil.h:167
static double ui_to_config(int slider_pos)
Convert a slider scale 1-100 value to configuration value 1.02..3.0.
Definition navutil.h:162
Main application frame.
Definition ocpn_frame.h:136
Provides platform-specific support utilities for OpenCPN.
Represents a waypoint or mark within the navigation system.
Definition route_point.h:70
bool m_bIsVisible
Flag indicating if the waypoint should be drawn on the chart.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
Definition route.h:98
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
Definition route.h:277
Represents a track, which is a series of connected track points.
Definition track.h:111
ViewPort - Core geographic projection and coordinate transformation engine.
Definition viewport.h:81
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
Definition viewport.h:229
double rotation
Rotation angle of the viewport in radians.
Definition viewport.h:239
double clon
Center longitude of the viewport in degrees.
Definition viewport.h:224
double clat
Center latitude of the viewport in degrees.
Definition viewport.h:222
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowENCText
Display ENC text elements.
bool bShowAIS
Display AIS targets.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
bool bAttenAIS
Enable AIS target attenuation.
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:64
Global variables reflecting command line options and arguments.
NavmsgFilter Read(const std::string &name)
Read filter with given name from disk.
bool Write(const NavmsgFilter &filter, const std::string &name)
Write contents for given filter to disk.
Multiplexer class and helpers.
Class NavObj_dB.
Global variables Listen()/Notify() wrapper.
PlugIn Object Definition/API.
Tools to send data to plugins.