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