1 /***************************************************************************
2  *
3  * Project:  OpenCPN
4  *
5  ***************************************************************************
6  *   Copyright (C) 2018 by David S. Register                               *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
22  **************************************************************************/
23 
24 #ifdef __MINGW32__
25 #undef IPV6STRICT    // mingw FTBS fix:  missing struct ip_mreq
26 #include <windows.h>
27 #endif
28 
29 #include <wx/tokenzr.h>
30 
31 #include "config.h"
32 #include "ConfigMgr.h"
33 
34 #include <wx/filename.h>
35 #include <wx/fileconf.h>
36 #include <wx/statline.h>
37 
38 
39 #include "dychart.h"
40 
41 #include <stdlib.h>
42 //#include <math.h>
43 #include <time.h>
44 #include <locale>
45 #include <list>
46 
47 #include <wx/listimpl.cpp>
48 #include <wx/progdlg.h>
49 
50 #include "chart1.h"
51 #include "navutil.h"
52 #include "chcanv.h"
53 #include "georef.h"
54 #include "cutil.h"
55 #include "styles.h"
56 #include "routeman.h"
57 #include "s52utils.h"
58 #include "chartbase.h"
59 #include "ocpndc.h"
60 #include "geodesic.h"
61 #include "datastream.h"
62 #include "multiplexer.h"
63 #include "ais.h"
64 #include "Route.h"
65 #include "Select.h"
66 #include "FontMgr.h"
67 #include "Layer.h"
68 #include "NavObjectCollection.h"
69 #include "NMEALogWindow.h"
70 #include "AIS_Decoder.h"
71 #include "OCPNPlatform.h"
72 #include "Track.h"
73 #include "chartdb.h"
74 #include "CanvasConfig.h"
75 
76 #include "s52plib.h"
77 #include "cm93.h"
78 
79 #ifdef ocpnUSE_GL
80 #include "glChartCanvas.h"
81 #endif
82 
83 // Global statics
84 //    Statics
85 
86 extern OCPNPlatform     *g_Platform;
87 extern MyFrame          *gFrame;
88 
89 extern int              g_restore_stackindex;
90 extern int              g_restore_dbindex;
91 extern LayerList        *pLayerList;
92 extern MyConfig         *pConfig;
93 extern double           initial_scale_ppm, initial_rotation;
94 extern int              g_nbrightness;
95 extern bool             g_bShowTrue, g_bShowMag;
96 extern double           g_UserVar;
97 extern bool             g_bShowStatusBar;
98 extern bool             g_bUIexpert;
99 extern bool             g_bFullscreen;
100 extern int              g_nDepthUnitDisplay;
101 
102 
103 
104 extern wxString         g_SENCPrefix;
105 extern wxString         g_UserPresLibData;
106 
107 extern wxString         *pInit_Chart_Dir;
108 extern wxString         gWorldMapLocation;
109 
110 extern bool             s_bSetSystemTime;
111 extern bool             g_bDisplayGrid;         //Flag indicating if grid is to be displayed
112 extern bool             g_bPlayShipsBells;
113 extern int              g_iSoundDeviceIndex;
114 extern bool             g_bFullscreenToolbar;
115 extern bool             g_bShowLayers;
116 extern bool             g_bTransparentToolbar;
117 extern bool             g_bPermanentMOBIcon;
118 
119 extern bool             g_bShowDepthUnits;
120 extern bool             g_bAutoAnchorMark;
121 extern bool             g_bskew_comp;
122 extern bool             g_bopengl;
123 extern bool             g_bSoftwareGL;
124 extern bool             g_bShowFPS;
125 extern bool             g_bsmoothpanzoom;
126 
127 extern bool             g_bShowOutlines;
128 extern bool             g_bShowActiveRouteHighway;
129 extern bool             g_bShowRouteTotal;
130 extern int              g_nNMEADebug;
131 extern int              g_nAWDefault;
132 extern int              g_nAWMax;
133 extern int              g_nTrackPrecision;
134 
135 extern int              g_iSDMMFormat;
136 extern int              g_iDistanceFormat;
137 extern int              g_iSpeedFormat;
138 
139 extern int              g_nframewin_x;
140 extern int              g_nframewin_y;
141 extern int              g_nframewin_posx;
142 extern int              g_nframewin_posy;
143 extern bool             g_bframemax;
144 extern int              g_route_prop_x, g_route_prop_y;
145 extern int              g_route_prop_sx, g_route_prop_sy;
146 
147 extern double           g_PlanSpeed;
148 extern wxString         g_VisibleLayers;
149 extern wxString         g_InvisibleLayers;
150 
151 
152 // LIVE ETA OPTION
153 extern bool             g_bShowLiveETA;
154 extern double           g_defaultBoatSpeed;
155 
156 //    AIS Global configuration
157 extern bool             g_bCPAMax;
158 extern double           g_CPAMax_NM;
159 extern bool             g_bCPAWarn;
160 extern double           g_CPAWarn_NM;
161 extern bool             g_bTCPA_Max;
162 extern double           g_TCPA_Max;
163 extern bool             g_bMarkLost;
164 extern double           g_MarkLost_Mins;
165 extern bool             g_bRemoveLost;
166 extern double           g_RemoveLost_Mins;
167 extern bool             g_bShowCOG;
168 extern double           g_ShowCOG_Mins;
169 extern bool             g_bAISShowTracks;
170 extern bool             g_bTrackCarryOver;
171 extern bool             g_bTrackDaily;
172 extern int              g_track_rotate_time;
173 extern int              g_track_rotate_time_type;
174 extern double           g_AISShowTracks_Mins;
175 extern double           g_AISShowTracks_Limit;
176 extern bool             g_bHideMoored;
177 extern double           g_ShowMoored_Kts;
178 extern bool             g_bAllowShowScaled;
179 extern bool             g_bShowScaled;
180 extern int              g_ShowScaled_Num;
181 extern bool             g_bAIS_CPA_Alert;
182 extern bool             g_bAIS_CPA_Alert_Audio;
183 extern int              g_ais_alert_dialog_x, g_ais_alert_dialog_y;
184 extern int              g_ais_alert_dialog_sx, g_ais_alert_dialog_sy;
185 extern int              g_ais_query_dialog_x, g_ais_query_dialog_y;
186 extern wxString         g_sAIS_Alert_Sound_File;
187 extern bool             g_bAIS_CPA_Alert_Suppress_Moored;
188 extern bool             g_bAIS_ACK_Timeout;
189 extern double           g_AckTimeout_Mins;
190 extern wxString         g_AisTargetList_perspective;
191 extern int              g_AisTargetList_range;
192 extern int              g_AisTargetList_sortColumn;
193 extern bool             g_bAisTargetList_sortReverse;
194 extern wxString         g_AisTargetList_column_spec;
195 extern wxString         g_AisTargetList_column_order;
196 extern bool             g_bShowAreaNotices;
197 extern bool             g_bDrawAISSize;
198 extern bool             g_bDrawAISRealtime;
199 extern double           g_AIS_RealtPred_Kts;
200 extern bool             g_bShowAISName;
201 extern int              g_Show_Target_Name_Scale;
202 extern bool             g_bWplIsAprsPosition;
203 extern bool             g_benableAISNameCache;
204 extern int              g_ScaledNumWeightSOG;
205 extern int              g_ScaledNumWeightCPA;
206 extern int              g_ScaledNumWeightTCPA;
207 extern int              g_ScaledNumWeightRange;
208 extern int              g_ScaledNumWeightSizeOfT;
209 extern int              g_ScaledSizeMinimal;
210 
211 extern int              g_S57_dialog_sx, g_S57_dialog_sy;
212 
213 extern int              g_iNavAidRadarRingsNumberVisible;
214 extern float            g_fNavAidRadarRingsStep;
215 extern int              g_pNavAidRadarRingsStepUnits;
216 extern int              g_iWaypointRangeRingsNumber;
217 extern float            g_fWaypointRangeRingsStep;
218 extern int              g_iWaypointRangeRingsStepUnits;
219 extern wxColour         g_colourWaypointRangeRingsColour;
220 extern bool             g_bWayPointPreventDragging;
221 extern bool             g_bConfirmObjectDelete;
222 extern wxColour         g_colourOwnshipRangeRingsColour;
223 
224 extern bool             g_bEnableZoomToCursor;
225 extern wxString         g_toolbarConfig;
226 extern double           g_TrackIntervalSeconds;
227 extern double           g_TrackDeltaDistance;
228 extern int              gps_watchdog_timeout_ticks;
229 
230 
231 extern bool             g_bGDAL_Debug;
232 extern bool             g_bDebugCM93;
233 extern bool             g_bDebugS57;
234 
235 extern double           g_ownship_predictor_minutes;
236 extern double           g_ownship_HDTpredictor_miles;
237 
238 extern bool             g_own_ship_sog_cog_calc;
239 extern int              g_own_ship_sog_cog_calc_damp_sec;
240 
241 extern s52plib          *ps52plib;
242 
243 extern int              g_cm93_zoom_factor;
244 extern bool             g_b_legacy_input_filter_behaviour;
245 extern bool             g_bShowDetailSlider;
246 extern int              g_detailslider_dialog_x, g_detailslider_dialog_y;
247 
248 
249 extern int              g_OwnShipIconType;
250 extern double           g_n_ownship_length_meters;
251 extern double           g_n_ownship_beam_meters;
252 extern double           g_n_gps_antenna_offset_y;
253 extern double           g_n_gps_antenna_offset_x;
254 extern int              g_n_ownship_min_mm;
255 extern double           g_n_arrival_circle_radius;
256 
257 extern bool             g_bPreserveScaleOnX;
258 extern bool             g_bsimplifiedScalebar;
259 
260 extern bool             g_bUseGLL;
261 
262 extern wxString         g_locale;
263 extern wxString         g_localeOverride;
264 
265 
266 extern bool             g_bCourseUp;
267 extern bool             g_bLookAhead;
268 extern int              g_COGAvgSec;
269 extern bool             g_bMagneticAPB;
270 extern bool             g_bShowChartBar;
271 
272 extern int              g_MemFootMB;
273 
274 extern int              g_nCOMPortCheck;
275 
276 
277 extern wxString         g_AW1GUID;
278 extern wxString         g_AW2GUID;
279 extern int              g_BSBImgDebug;
280 
281 extern wxString        g_config_version_string;
282 extern wxString        g_config_version_string;
283 
284 
285 extern bool             g_bAISRolloverShowClass;
286 extern bool             g_bAISRolloverShowCOG;
287 extern bool             g_bAISRolloverShowCPA;
288 
289 extern bool             g_bDebugGPSD;
290 
291 extern bool             g_bfilter_cogsog;
292 extern int              g_COGFilterSec;
293 
294 extern int              g_navobjbackups;
295 
296 extern bool             g_bQuiltEnable;
297 extern bool             g_bFullScreenQuilt;
298 extern bool             g_bQuiltStart;
299 
300 extern int              g_SkewCompUpdatePeriod;
301 
302 extern int              g_maintoolbar_x;
303 extern int              g_maintoolbar_y;
304 extern long             g_maintoolbar_orient;
305 
306 
307 extern int              g_lastClientRectx;
308 extern int              g_lastClientRecty;
309 extern int              g_lastClientRectw;
310 extern int              g_lastClientRecth;
311 
312 extern bool             g_bHighliteTracks;
313 extern int              g_cog_predictor_width;
314 extern int              g_ais_cog_predictor_width;
315 
316 extern int              g_route_line_width;
317 extern int              g_track_line_width;
318 extern wxColour         g_colourTrackLineColour;
319 extern wxString         g_default_wp_icon;
320 
321 extern ChartGroupArray  *g_pGroupArray;
322 
323 extern bool             g_bDebugOGL;
324 extern wxString         g_GPS_Ident;
325 extern bool             g_bGarminHostUpload;
326 extern wxString         g_uploadConnection;
327 
328 extern wxArrayString    TideCurrentDataSet;
329 extern wxString         g_TCData_Dir;
330 
331 extern bool             g_btouch;
332 extern bool             g_bresponsive;
333 
334 extern bool             g_bGLexpert;
335 
336 extern int              g_SENC_LOD_pixels;
337 extern ArrayOfMMSIProperties   g_MMSI_Props_Array;
338 
339 extern int              g_chart_zoom_modifier;
340 extern int              g_chart_zoom_modifier_vector;
341 
342 extern int              g_NMEAAPBPrecision;
343 
344 extern wxString         g_TalkerIdText;
345 extern int              g_maxWPNameLength;
346 
347 extern bool             g_bAdvanceRouteWaypointOnArrivalOnly;
348 extern double           g_display_size_mm;
349 extern double           g_config_display_size_mm;
350 extern bool             g_config_display_size_manual;
351 
352 extern bool             g_benable_rotate;
353 extern bool             g_bEmailCrashReport;
354 
355 extern int              g_default_font_size;
356 
357 extern bool             g_bAutoHideToolbar;
358 extern int              g_nAutoHideToolbar;
359 extern int              g_GUIScaleFactor;
360 extern int              g_ChartScaleFactor;
361 extern int              g_ShipScaleFactor;
362 
363 extern bool             g_bInlandEcdis;
364 extern int              g_iENCToolbarPosX;
365 extern int              g_iENCToolbarPosY;
366 
367 extern bool             g_bSpaceDropMark;
368 
369 
370 extern bool             g_benableUDPNullHeader;
371 extern bool             g_bShowMenuBar;
372 extern bool             g_bShowCompassWin;
373 
374 extern wxString         g_uiStyle;
375 extern bool             g_useMUI;
376 extern wxString         g_gpx_path;
377 
378 
379 extern bool             g_bDarkDecorations;
380 extern unsigned int     g_canvasConfig;
381 
382 #ifdef ocpnUSE_GL
383 extern ocpnGLOptions g_GLOptions;
384 #endif
385 
386 #if !defined(NAN)
387 static const long long lNaN = 0xfff8000000000000;
388 #define NAN (*(double*)&lNaN)
389 #endif
390 
391 
392 
393 ConfigMgr * ConfigMgr::instance = NULL;
394 
395 //--------------------------------------------------------------------------
396 //
397 //      Utility functions
398 //
399 //--------------------------------------------------------------------------
GetRandomNumber(int range_min,int range_max)400 int GetRandomNumber(int range_min, int range_max)
401 {
402     long u = (long)wxRound(((double)rand() / ((double)(RAND_MAX) + 1) * (range_max - range_min)) + range_min);
403     return (int)u;
404 }
405 
406 //Helper conditional file name dir slash
407 void appendOSDirSlash(wxString* pString);
408 
409 
410 class OCPNConfigObject
411 {
412 public:
413     OCPNConfigObject();
414     ~OCPNConfigObject();
415 
416     OCPNConfigObject( int canvas_config );
417 
418     void Init();
419     wxPanel *GetSettingsPanel();
420 
421     int m_canvasConfig;
422     wxString m_GUID;
423     wxString templateFileName;
424     wxString m_title;
425     wxString m_description;
426 
427 
428 };
429 
OCPNConfigObject()430 OCPNConfigObject::OCPNConfigObject()
431 {
432     Init();
433 }
434 
OCPNConfigObject(int canvas_config)435 OCPNConfigObject::OCPNConfigObject( int canvas_config )
436 {
437     Init();
438     m_canvasConfig = canvas_config;
439 }
440 
~OCPNConfigObject()441 OCPNConfigObject::~OCPNConfigObject()
442 {
443 }
444 
Init()445 void OCPNConfigObject::Init()
446 {
447     m_canvasConfig = 0;
448 }
449 
450 #include <wx/listimpl.cpp>
451 WX_DEFINE_LIST(ConfigObjectList);
452 
453 //--------------------------------------------------------------------
454 //   Private ( XML encoded ) catalog of available configurations
455 //--------------------------------------------------------------------
456 
457 class OCPNConfigCatalog : public pugi::xml_document
458 {
459 public:
460     OCPNConfigCatalog();
461     ~OCPNConfigCatalog();
462 
463     bool AddConfig( OCPNConfigObject *config, unsigned int flags );
464     bool RemoveConfig( wxString GUID);
465 
466 
467     void SetRootConfigNode(void);
468     bool IsOpenCPN();
469     bool SaveFile( const wxString filename );
470     bool LoadFile( const wxString filename );
471 
472     pugi::xml_node      m_config_root;
473 };
474 
OCPNConfigCatalog()475 OCPNConfigCatalog::OCPNConfigCatalog()
476 : pugi::xml_document()
477 {
478 }
479 
~OCPNConfigCatalog()480 OCPNConfigCatalog::~OCPNConfigCatalog()
481 {
482 }
483 
SetRootConfigNode(void)484 void OCPNConfigCatalog::SetRootConfigNode(void)
485 {
486     if(!strlen(m_config_root.name())) {
487         m_config_root = append_child("configs");
488         m_config_root.append_attribute ( "version" ) = "1.0";
489         m_config_root.append_attribute ( "creator" ) = "OpenCPN";
490         m_config_root.append_attribute( "xmlns:xsi" ) = "http://www.w3.org/2001/XMLSchema-instance";
491         m_config_root.append_attribute( "xmlns" ) = "http://www.topografix.com/GPX/1/1";
492         m_config_root.append_attribute( "xmlns:gpxx" ) =  "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
493         m_config_root.append_attribute( "xsi:schemaLocation" ) = "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd";
494         m_config_root.append_attribute( "xmlns:opencpn" ) = "http://www.opencpn.org";
495     }
496 }
497 
IsOpenCPN()498 bool OCPNConfigCatalog::IsOpenCPN()
499 {
500     for (pugi::xml_attribute attr = root().first_child().first_attribute(); attr; attr = attr.next_attribute())
501         if( !strcmp(attr.name(), "creator") && !strcmp(attr.value(), "OpenCPN") )
502             return true;
503     return false;
504 }
505 
SaveFile(const wxString filename)506 bool OCPNConfigCatalog::SaveFile( const wxString filename )
507 {
508     save_file(filename.fn_str(), "  ");
509     return true;
510 }
511 
LoadFile(const wxString filename)512 bool OCPNConfigCatalog::LoadFile( const wxString filename )
513 {
514     load_file( filename.fn_str() );
515     m_config_root =  this->child("configs");
516     return true;
517 }
518 
AddConfig(OCPNConfigObject * config,unsigned int flags)519 bool OCPNConfigCatalog::AddConfig( OCPNConfigObject *config, unsigned int flags )
520 {
521     pugi::xml_node node = m_config_root.append_child("config");
522 
523     node.append_attribute("GUID") = config->m_GUID.mb_str();
524 
525     //  Handle non-ASCII characters as UTF8
526     wxCharBuffer abuf = config->m_title.ToUTF8();
527     if( abuf.data() )
528         node.append_attribute("title") = abuf.data();
529     else
530         node.append_attribute("title") = _T("Substitute Title");
531 
532     abuf = config->m_description.ToUTF8();
533     if( abuf.data() )
534         node.append_attribute("description") = abuf.data();
535     else
536         node.append_attribute("description") = _T("Substitute Description");
537 
538     node.append_attribute("templateFile") = config->templateFileName.mb_str();
539 
540 
541     return true;
542 }
543 
RemoveConfig(wxString GUID)544 bool OCPNConfigCatalog::RemoveConfig( wxString GUID)
545 {
546     for (pugi::xml_node child = m_config_root.first_child(); child; )
547     {
548         pugi::xml_node next = child.next_sibling();
549         const char* guid = child.attribute("GUID").value();
550 
551         if(!strcmp(guid, GUID.mb_str())){
552             child.parent().remove_child(child);
553             return true;
554         }
555 
556         child = next;
557     }
558 
559     return false;
560 }
561 
562 
563 
564 
565 //--------------------------------------------------------------------
566 //   ConfigPanel implementation
567 //--------------------------------------------------------------------
568 
ConfigPanel(OCPNConfigObject * config,wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size)569 ConfigPanel::ConfigPanel(OCPNConfigObject *config, wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size)
570 :wxPanel(parent, id, pos, size, wxSIMPLE_BORDER)
571 
572 {
573     m_config = config;
574     wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
575     SetSizer(mainSizer);
576 
577     mainSizer->Add(new wxStaticText(this, wxID_ANY, _("Title")));
578     mainSizer->Add(new wxStaticText(this, wxID_ANY, config->m_title));
579 
580     mainSizer->Add(new wxStaticLine(this, wxID_ANY), 0, wxEXPAND | wxALL, 1);
581 
582     mainSizer->Add(new wxStaticText(this, wxID_ANY, _("Description")));
583     mainSizer->Add(new wxStaticText(this, wxID_ANY, config->m_description));
584 
585     SetMinSize(wxSize(-1, 6 * GetCharHeight()) );
586 
587     wxColour colour;
588     GetGlobalColor(_T("COMP1"), &colour);
589     SetBackgroundColour(colour);
590     //Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(ConfigPanel::OnConfigPanelMouseSelected), NULL, this);
591 
592 }
593 
~ConfigPanel()594 ConfigPanel::~ConfigPanel()
595 {
596 }
597 
OnConfigPanelMouseSelected(wxMouseEvent & event)598 void ConfigPanel::OnConfigPanelMouseSelected( wxMouseEvent &event)
599 {
600 //     SetBackgroundColour(*wxRED);
601 //     event.Skip();
602 }
603 
GetConfigGUID()604 wxString ConfigPanel::GetConfigGUID()
605 {
606     return m_config->m_GUID;
607 }
608 
609 
610 //--------------------------------------------------------------------
611 //   ConfigMgr implementation
612 //   Singleton Pattern
613 //--------------------------------------------------------------------
614 
615 
Get()616 ConfigMgr & ConfigMgr::Get()
617 {
618     if (!instance)
619         instance = new ConfigMgr;
620     return *instance;
621 }
622 
Shutdown()623 void ConfigMgr::Shutdown()
624 {
625     if (instance)
626     {
627         delete instance;
628         instance = NULL;
629     }
630 }
631 
ConfigMgr()632 ConfigMgr::ConfigMgr()
633 {
634     Init();
635 
636     // Load any existing configs from the catalog
637     LoadCatalog();
638 
639 }
640 
~ConfigMgr()641 ConfigMgr::~ConfigMgr()
642 {
643     delete configList;
644 }
645 
Init()646 void ConfigMgr::Init()
647 {
648     m_configDir = g_Platform->GetPrivateDataDir();
649     appendOSDirSlash(&m_configDir);
650     m_configDir.append(_T("Configs"));
651     appendOSDirSlash(&m_configDir);
652     if(!wxFileName::DirExists( m_configDir )){
653         wxFileName::Mkdir( m_configDir );
654     }
655 
656     m_configCatalogName = g_Platform->GetPrivateDataDir();
657     appendOSDirSlash(&m_configCatalogName);
658     m_configCatalogName.append(_T("Configs"));
659     appendOSDirSlash(&m_configCatalogName);
660     m_configCatalogName.append(_T("configs.xml"));
661 
662     //Create the catalog, if necessary
663     if(!wxFileExists(m_configCatalogName)){
664 
665         wxLogMessage( _T("Creating new Configs catalog: ") + m_configCatalogName );
666 
667         OCPNConfigCatalog *cat = new OCPNConfigCatalog();
668         cat->SetRootConfigNode();
669         cat->SaveFile( m_configCatalogName);
670         delete cat;
671     }
672 
673     m_configCatalog = new OCPNConfigCatalog();
674 
675     configList = new ConfigObjectList;
676 
677     //  Add the default "Recovery" template
678      wxString t_title = _("Recovery Template");
679      wxString t_desc = _("Apply this template to return to a known safe configuration");
680      CreateNamedConfig( t_title, t_desc, _T("11111111-1111-1111-1111-111111111111"));
681 
682 }
683 
LoadCatalog()684 bool ConfigMgr::LoadCatalog()
685 {
686     wxLogMessage( _T("Loading Configs catalog: ") + m_configCatalogName );
687     m_configCatalog->LoadFile( m_configCatalogName );
688 
689     // Parse the config catalog
690     pugi::xml_node objects = m_configCatalog->child("configs");
691 
692     //pugi::xml_node node = m_config_root.append_child("config");
693 
694     //node.append_attribute("GUID") = config->m_GUID.mb_str();
695     //node.append_attribute("title") = config->m_title.mb_str();
696     //node.append_attribute("description") = config->m_description.mb_str();
697     //node.append_attribute("templateFile") = config->templateFileName.mb_str();
698 
699     for (pugi::xml_node object = objects.first_child(); object; object = object.next_sibling())
700     {
701         if( !strcmp(object.name(), "config") ) {
702 
703             //Check the GUID for duplicates
704             wxString testGUID = wxString::FromUTF8(object.attribute( "GUID" ).as_string());
705 
706             bool bFound = false;
707             for ( ConfigObjectList::Node *node = configList->GetFirst(); node; node = node->GetNext() )
708             {
709                 OCPNConfigObject *look = node->GetData();
710                 if(look->m_GUID == testGUID){
711                     bFound = true;
712                     break;
713                 }
714             }
715 
716             if(!bFound){
717                 OCPNConfigObject *newConfig = new OCPNConfigObject;
718 
719                 newConfig->m_GUID = wxString::FromUTF8(object.attribute( "GUID" ).as_string());
720                 newConfig->m_title = wxString::FromUTF8(object.attribute( "title" ).as_string());
721                 newConfig->m_description = wxString::FromUTF8(object.attribute( "description" ).as_string());
722                 newConfig->templateFileName = wxString::FromUTF8(object.attribute( "templateFile" ).as_string());
723 
724                 // Add to the class list of configs
725                 configList->Append(newConfig);
726             }
727         }
728     }
729 
730     return true;
731 
732 }
733 
SaveCatalog()734 bool ConfigMgr::SaveCatalog()
735 {
736     m_configCatalog->SaveFile( m_configCatalogName);
737 
738     return true;
739 }
740 
CreateNamedConfig(const wxString & title,const wxString & description,wxString UUID)741 wxString ConfigMgr::CreateNamedConfig( const wxString &title, const wxString &description, wxString UUID )
742 {
743     wxString GUID;
744 
745     // Must have title
746     if( title.IsEmpty())
747         return GUID;
748 
749     OCPNConfigObject *pConfig = new OCPNConfigObject;
750 
751     //If no UUID is passed, then create a new GUID for this config
752     if(UUID.IsEmpty())
753         GUID = GetUUID();
754     else
755         GUID = UUID;
756 
757     pConfig->m_GUID = GUID;
758     pConfig->m_title = title;
759     pConfig->m_description = description;
760 
761     if(UUID.IsEmpty()){
762         // create template file name
763         pConfig->templateFileName = _T("OCPNTemplate-") + GUID + _T(".conf");
764 
765         //  Save the template contents
766         wxString templateFullFileName = GetConfigDir() + pConfig->templateFileName;
767         if(!SaveTemplate( templateFullFileName )){
768             wxLogMessage(_T("Unable to save template titled: ") + title + _T(" as file: ") + templateFullFileName);
769             delete pConfig;
770             return _T("");
771         }
772     }
773 
774     // Add this config to the catalog
775     if(!m_configCatalog->AddConfig( pConfig, 0 )){
776         wxLogMessage(_T("Unable to add config to catalog...Title: ") + title);
777         delete pConfig;
778         return _T("");
779     }
780 
781     // Add to the class list of configs
782     configList->Append(pConfig);
783 
784     if(UUID.IsEmpty())
785         SaveCatalog();
786 
787     return GUID;
788 }
789 
DeleteConfig(wxString GUID)790 bool ConfigMgr::DeleteConfig(wxString GUID)
791 {
792     OCPNConfigObject *cfg = GetConfig( GUID );
793     if(!cfg)
794         return false;
795 
796     // Find and delete the template file
797     wxString templateFullFileName = GetConfigDir() + cfg->templateFileName;
798     if(wxFileExists(templateFullFileName))
799         wxRemoveFile(templateFullFileName);
800 
801     // Remove the config from the catalog
802     bool rv = m_configCatalog->RemoveConfig(GUID);
803 
804     if(rv)
805         SaveCatalog();
806 
807     //  Remove the config from the member list
808     bool bDel = configList->DeleteObject(cfg);
809     if(bDel)
810         delete cfg;
811 
812     return rv;
813 }
814 
815 
816 
GetConfigPanel(wxWindow * parent,wxString GUID)817 wxPanel *ConfigMgr::GetConfigPanel( wxWindow *parent, wxString GUID )
818 {
819     wxPanel *retPanel = NULL;
820 
821     // Find the GUID-matching config in the member list
822     OCPNConfigObject *config = GetConfig( GUID );
823 
824     //  Found it?
825     if(config){
826         retPanel = new ConfigPanel( config, parent );
827     }
828 
829     return retPanel;
830 }
831 
GetConfig(wxString GUID)832 OCPNConfigObject *ConfigMgr::GetConfig( wxString GUID )
833 {
834     // Find the GUID-matching config in the member list
835     for ( ConfigObjectList::Node *node = configList->GetFirst(); node; node = node->GetNext() )
836     {
837         OCPNConfigObject *look = node->GetData();
838         if(look->m_GUID == GUID){
839             return look;
840             break;
841         }
842     }
843 
844     return NULL;
845 }
846 
GetTemplateTitle(wxString GUID)847 wxString ConfigMgr::GetTemplateTitle( wxString GUID)
848 {
849     for ( ConfigObjectList::Node *node = configList->GetFirst(); node; node = node->GetNext() )
850     {
851         OCPNConfigObject *look = node->GetData();
852         if(look->m_GUID == GUID){
853             return look->m_title;
854             break;
855         }
856     }
857 
858     return wxEmptyString;
859 }
860 
861 
GetConfigGUIDArray()862 wxArrayString ConfigMgr::GetConfigGUIDArray()
863 {
864     wxArrayString ret_val;
865 
866     for ( ConfigObjectList::Node *node = configList->GetFirst(); node; node = node->GetNext() )
867     {
868         OCPNConfigObject *look = node->GetData();
869         ret_val.Add(look->m_GUID);
870     }
871 
872     return ret_val;
873 }
874 
ApplyConfigGUID(wxString GUID)875 bool ConfigMgr::ApplyConfigGUID( wxString GUID)
876 {
877 
878     // Find the GUID-matching config in the member list
879     OCPNConfigObject *config = GetConfig( GUID );
880 
881     //  Found it?
882     if(config){
883         wxString thisConfig = GetConfigDir() + config->templateFileName;
884 
885         // Special case for Recovery template
886         if(GUID.StartsWith(_T("11111111"))){
887             thisConfig = *GetpSharedDataLocation() + _T("configs/OCPNTemplate-Recovery.conf");
888         }
889 
890         MyConfig fconf( thisConfig );
891 
892         //  Load the template contents, without resetting defaults
893         fconf.LoadMyConfigRaw( true );
894 
895         //  Load Canvas configs, applying only the "templateable" items
896         fconf.LoadCanvasConfigs( true );
897 
898         if( ps52plib && ps52plib->m_bOK )
899             fconf.LoadS57Config();
900 
901         return true;
902     }
903 
904     return false;
905 }
906 
907 
908 // RFC4122 version 4 compliant random UUIDs generator.
GetUUID(void)909 wxString ConfigMgr::GetUUID(void)
910 {
911     wxString str;
912     struct {
913         int time_low;
914         int time_mid;
915         int time_hi_and_version;
916         int clock_seq_hi_and_rsv;
917         int clock_seq_low;
918         int node_hi;
919         int node_low;
920     } uuid;
921 
922     uuid.time_low = GetRandomNumber(0, 2147483647);//FIXME: the max should be set to something like MAXINT32, but it doesn't compile un gcc...
923     uuid.time_mid = GetRandomNumber(0, 65535);
924     uuid.time_hi_and_version = GetRandomNumber(0, 65535);
925     uuid.clock_seq_hi_and_rsv = GetRandomNumber(0, 255);
926     uuid.clock_seq_low = GetRandomNumber(0, 255);
927     uuid.node_hi = GetRandomNumber(0, 65535);
928     uuid.node_low = GetRandomNumber(0, 2147483647);
929 
930     /* Set the two most significant bits (bits 6 and 7) of the
931      * clock_seq_hi_and_rsv to zero and one, respectively. */
932     uuid.clock_seq_hi_and_rsv = (uuid.clock_seq_hi_and_rsv & 0x3F) | 0x80;
933 
934     /* Set the four most significant bits (bits 12 through 15) of the
935      * time_hi_and_version field to 4 */
936     uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0fff) | 0x4000;
937 
938     str.Printf(_T("%08x-%04x-%04x-%02x%02x-%04x%08x"),
939                   uuid.time_low,
940                   uuid.time_mid,
941                   uuid.time_hi_and_version,
942                   uuid.clock_seq_hi_and_rsv,
943                   uuid.clock_seq_low,
944                   uuid.node_hi,
945                   uuid.node_low);
946 
947     return str;
948 }
949 
950 
SaveTemplate(wxString fileName)951 bool ConfigMgr::SaveTemplate( wxString fileName)
952 {
953     //  Assuming the file exists, and is empty....
954 
955     //  Create a private wxFileConfig object
956     MyConfig *conf = new MyConfig( fileName );
957 
958     //  Write out all the elements of a config template....
959 
960     //  Temporarily suppress logging of trivial non-fatal wxLogSysError() messages provoked by Android security...
961     #ifdef __OCPN__ANDROID__
962     wxLogNull logNo;
963     #endif
964 
965     //    Global options and settings
966     conf->SetPath( _T ( "/Settings" ) );
967 
968     conf->Write( _T ( "InlandEcdis" ), g_bInlandEcdis );
969     conf->Write( _T ( "DarkDecorations"), g_bDarkDecorations );
970     conf->Write( _T ( "UIexpert" ), g_bUIexpert );
971     conf->Write( _T ( "SpaceDropMark" ), g_bSpaceDropMark );
972 
973     conf->Write( _T ( "ShowStatusBar" ), g_bShowStatusBar );
974     #ifndef __WXOSX__
975     conf->Write( _T ( "ShowMenuBar" ), g_bShowMenuBar );
976     #endif
977     conf->Write( _T ( "DefaultFontSize" ), g_default_font_size );
978 
979     conf->Write( _T ( "Fullscreen" ), g_bFullscreen );
980     conf->Write( _T ( "ShowCompassWindow" ), g_bShowCompassWin );
981     conf->Write( _T ( "SetSystemTime" ), s_bSetSystemTime );
982     conf->Write( _T ( "ShowGrid" ), g_bDisplayGrid );
983     conf->Write( _T ( "PlayShipsBells" ), g_bPlayShipsBells );
984     conf->Write( _T ( "SoundDeviceIndex" ), g_iSoundDeviceIndex );
985     conf->Write( _T ( "FullscreenToolbar" ), g_bFullscreenToolbar );
986     //conf->Write( _T ( "TransparentToolbar" ), g_bTransparentToolbar );
987     conf->Write( _T ( "PermanentMOBIcon" ), g_bPermanentMOBIcon );
988     conf->Write( _T ( "ShowLayers" ), g_bShowLayers );
989     conf->Write( _T ( "AutoAnchorDrop" ), g_bAutoAnchorMark );
990     conf->Write( _T ( "ShowChartOutlines" ), g_bShowOutlines );
991     conf->Write( _T ( "ShowActiveRouteTotal" ), g_bShowRouteTotal );
992     conf->Write( _T ( "ShowActiveRouteHighway" ), g_bShowActiveRouteHighway );
993     conf->Write( _T ( "SDMMFormat" ), g_iSDMMFormat );
994     conf->Write( _T ( "ShowChartBar" ), g_bShowChartBar );
995 
996     conf->Write( _T ( "GUIScaleFactor" ), g_GUIScaleFactor );
997     conf->Write( _T ( "ChartObjectScaleFactor" ), g_ChartScaleFactor );
998     conf->Write( _T ( "ShipScaleFactor" ), g_ShipScaleFactor );
999 
1000     conf->Write( _T ( "ShowTrue" ), g_bShowTrue );
1001     conf->Write( _T ( "ShowMag" ), g_bShowMag );
1002     conf->Write( _T ( "UserMagVariation" ), wxString::Format( _T("%.2f"), g_UserVar ) );
1003 
1004     conf->Write( _T ( "CM93DetailFactor" ), g_cm93_zoom_factor );
1005     conf->Write( _T ( "CM93DetailZoomPosX" ), g_detailslider_dialog_x );
1006     conf->Write( _T ( "CM93DetailZoomPosY" ), g_detailslider_dialog_y );
1007     conf->Write( _T ( "ShowCM93DetailSlider" ), g_bShowDetailSlider );
1008 
1009     conf->Write( _T ( "SkewToNorthUp" ), g_bskew_comp );
1010 
1011     conf->Write( _T ( "ZoomDetailFactor" ), g_chart_zoom_modifier );
1012     conf->Write( _T ( "ZoomDetailFactorVector" ), g_chart_zoom_modifier_vector );
1013 
1014     conf->Write( _T ( "SmoothPanZoom" ), g_bsmoothpanzoom );
1015 
1016     conf->Write( _T ( "CourseUpMode" ), g_bCourseUp );
1017     if (!g_bInlandEcdis )
1018         conf->Write( _T ( "LookAheadMode" ), g_bLookAhead );
1019     conf->Write( _T ( "COGUPAvgSeconds" ), g_COGAvgSec );
1020     conf->Write( _T ( "UseMagAPB" ), g_bMagneticAPB );
1021 
1022     conf->Write( _T ( "OwnshipCOGPredictorMinutes" ), g_ownship_predictor_minutes );
1023     conf->Write( _T ( "OwnshipCOGPredictorWidth" ), g_cog_predictor_width );
1024     conf->Write( _T ( "OwnshipHDTPredictorMiles" ), g_ownship_HDTpredictor_miles );
1025     conf->Write( _T ( "OwnShipIconType" ), g_OwnShipIconType );
1026     conf->Write( _T ( "OwnShipLength" ), g_n_ownship_length_meters );
1027     conf->Write( _T ( "OwnShipWidth" ), g_n_ownship_beam_meters );
1028     conf->Write( _T ( "OwnShipGPSOffsetX" ), g_n_gps_antenna_offset_x );
1029     conf->Write( _T ( "OwnShipGPSOffsetY" ), g_n_gps_antenna_offset_y );
1030     conf->Write( _T ( "OwnShipMinSize" ), g_n_ownship_min_mm );
1031     conf->Write( _T ( "OwnShipSogCogCalc" ), g_own_ship_sog_cog_calc );
1032     conf->Write( _T ( "OwnShipSogCogCalcDampSec"), g_own_ship_sog_cog_calc_damp_sec );
1033 
1034     conf->Write( _T ( "RouteArrivalCircleRadius" ), wxString::Format( _T("%.3f"), g_n_arrival_circle_radius ));
1035     conf->Write( _T ( "ChartQuilting" ), g_bQuiltEnable );
1036 
1037     conf->Write( _T ( "StartWithTrackActive" ), g_bTrackCarryOver );
1038     conf->Write( _T ( "AutomaticDailyTracks" ), g_bTrackDaily );
1039     conf->Write( _T ( "TrackRotateAt" ), g_track_rotate_time );
1040     conf->Write( _T ( "TrackRotateTimeType" ), g_track_rotate_time_type );
1041     conf->Write( _T ( "HighlightTracks" ), g_bHighliteTracks );
1042 
1043     conf->Write( _T ( "InitialStackIndex" ), g_restore_stackindex );
1044     conf->Write( _T ( "InitialdBIndex" ), g_restore_dbindex );
1045 
1046     conf->Write( _T ( "AnchorWatch1GUID" ), g_AW1GUID );
1047     conf->Write( _T ( "AnchorWatch2GUID" ), g_AW2GUID );
1048 
1049     conf->Write( _T ( "ToolbarX" ), g_maintoolbar_x );
1050     conf->Write( _T ( "ToolbarY" ), g_maintoolbar_y );
1051     conf->Write( _T ( "ToolbarOrient" ), g_maintoolbar_orient );
1052 
1053     conf->Write( _T ( "iENCToolbarX" ), g_iENCToolbarPosX );
1054     conf->Write( _T ( "iENCToolbarY" ), g_iENCToolbarPosY );
1055 
1056     if ( !g_bInlandEcdis ){
1057         conf->Write( _T ( "GlobalToolbarConfig" ), g_toolbarConfig );
1058         conf->Write( _T ( "DistanceFormat" ), g_iDistanceFormat );
1059         conf->Write( _T ( "SpeedFormat" ), g_iSpeedFormat );
1060         conf->Write( _T ( "ShowDepthUnits" ), g_bShowDepthUnits );
1061     }
1062 
1063     conf->Write( _T ( "MobileTouch" ), g_btouch );
1064     conf->Write( _T ( "ResponsiveGraphics" ), g_bresponsive );
1065 
1066     conf->Write( _T ( "AutoHideToolbar" ), g_bAutoHideToolbar );
1067     conf->Write( _T ( "AutoHideToolbarSecs" ), g_nAutoHideToolbar );
1068 
1069     conf->Write( _T ( "DisplaySizeMM" ), g_config_display_size_mm );
1070     conf->Write( _T ( "DisplaySizeManual" ), g_config_display_size_manual );
1071 
1072     conf->Write( _T ( "PlanSpeed" ), wxString::Format( _T("%.2f"), g_PlanSpeed ));
1073 
1074 #if 0
1075     wxString vis, invis;
1076     LayerList::iterator it;
1077     int index = 0;
1078     for( it = ( *pLayerList ).begin(); it != ( *pLayerList ).end(); ++it, ++index ) {
1079         Layer *lay = (Layer *) ( *it );
1080         if( lay->IsVisibleOnChart() ) vis += ( lay->m_LayerName ) + _T(";");
1081         else
1082             invis += ( lay->m_LayerName ) + _T(";");
1083     }
1084     conf->Write( _T ( "VisibleLayers" ), vis );
1085     conf->Write( _T ( "InvisibleLayers" ), invis );
1086 #endif
1087 
1088     conf->Write( _T ( "Locale" ), g_locale );
1089     conf->Write( _T ( "LocaleOverride" ), g_localeOverride );
1090 
1091     // LIVE ETA OPTION
1092     conf->Write( _T( "LiveETA" ), g_bShowLiveETA);
1093     conf->Write( _T( "DefaultBoatSpeed" ), g_defaultBoatSpeed);
1094 
1095     //    S57 Object Filter Settings
1096     conf->SetPath( _T ( "/Settings/ObjectFilter" ) );
1097 
1098     if( ps52plib ) {
1099         for( unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
1100             OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
1101 
1102             wxString st1( _T ( "viz" ) );
1103             char name[7];
1104             strncpy( name, pOLE->OBJLName, 6 );
1105             name[6] = 0;
1106             st1.Append( wxString( name, wxConvUTF8 ) );
1107             conf->Write( st1, pOLE->nViz );
1108         }
1109     }
1110 
1111     //    Global State
1112 
1113     conf->SetPath( _T ( "/Settings/GlobalState" ) );
1114 
1115     //    Various Options
1116     if ( !g_bInlandEcdis )
1117         conf->Write( _T ( "nColorScheme" ), (int) gFrame->GetColorScheme() );
1118 
1119 
1120     //    AIS
1121     conf->SetPath( _T ( "/Settings/AIS" ) );
1122 
1123     conf->Write( _T ( "bNoCPAMax" ), g_bCPAMax );
1124     conf->Write( _T ( "NoCPAMaxNMi" ), g_CPAMax_NM );
1125     conf->Write( _T ( "bCPAWarn" ), g_bCPAWarn );
1126     conf->Write( _T ( "CPAWarnNMi" ), g_CPAWarn_NM );
1127     conf->Write( _T ( "bTCPAMax" ), g_bTCPA_Max );
1128     conf->Write( _T ( "TCPAMaxMinutes" ), g_TCPA_Max );
1129     conf->Write( _T ( "bMarkLostTargets" ), g_bMarkLost );
1130     conf->Write( _T ( "MarkLost_Minutes" ), g_MarkLost_Mins );
1131     conf->Write( _T ( "bRemoveLostTargets" ), g_bRemoveLost );
1132     conf->Write( _T ( "RemoveLost_Minutes" ), g_RemoveLost_Mins );
1133     conf->Write( _T ( "bShowCOGArrows" ), g_bShowCOG );
1134     conf->Write( _T ( "CogArrowMinutes" ), g_ShowCOG_Mins );
1135     conf->Write( _T ( "bShowTargetTracks" ), g_bAISShowTracks );
1136     conf->Write( _T ( "TargetTracksMinutes" ), g_AISShowTracks_Mins );
1137 
1138     conf->Write( _T ( "bHideMooredTargets" ), g_bHideMoored );
1139     conf->Write( _T ( "MooredTargetMaxSpeedKnots" ), g_ShowMoored_Kts );
1140 
1141     conf->Write( _T ( "bAISAlertDialog" ), g_bAIS_CPA_Alert );
1142     conf->Write( _T ( "bAISAlertAudio" ), g_bAIS_CPA_Alert_Audio );
1143     conf->Write( _T ( "AISAlertAudioFile" ), g_sAIS_Alert_Sound_File );
1144     conf->Write( _T ( "bAISAlertSuppressMoored" ), g_bAIS_CPA_Alert_Suppress_Moored );
1145     conf->Write( _T ( "bShowAreaNotices" ), g_bShowAreaNotices );
1146     conf->Write( _T ( "bDrawAISSize" ), g_bDrawAISSize );
1147     conf->Write( _T ( "bDrawAISRealtime" ), g_bDrawAISRealtime );
1148     conf->Write( _T ( "AISRealtimeMinSpeedKnots" ), g_AIS_RealtPred_Kts );
1149     conf->Write( _T ( "bShowAISName" ), g_bShowAISName );
1150     conf->Write( _T ( "ShowAISTargetNameScale" ), g_Show_Target_Name_Scale );
1151     conf->Write( _T ( "bWplIsAprsPositionReport" ), g_bWplIsAprsPosition );
1152     conf->Write( _T ( "AISCOGPredictorWidth" ), g_ais_cog_predictor_width );
1153     conf->Write( _T ( "bShowScaledTargets" ), g_bAllowShowScaled );
1154     conf->Write( _T ( "AISScaledNumber" ), g_ShowScaled_Num );
1155     conf->Write( _T ( "AISScaledNumberWeightSOG" ), g_ScaledNumWeightSOG );
1156     conf->Write( _T ( "AISScaledNumberWeightCPA" ), g_ScaledNumWeightCPA );
1157     conf->Write( _T ( "AISScaledNumberWeightTCPA" ), g_ScaledNumWeightTCPA );
1158     conf->Write( _T ( "AISScaledNumberWeightRange" ), g_ScaledNumWeightRange );
1159     conf->Write( _T ( "AISScaledNumberWeightSizeOfTarget" ), g_ScaledNumWeightSizeOfT );
1160     conf->Write( _T ( "AISScaledSizeMinimal" ), g_ScaledSizeMinimal );
1161     conf->Write( _T ( "AISShowScaled"), g_bShowScaled);
1162 
1163     conf->Write( _T ( "AlertDialogSizeX" ), g_ais_alert_dialog_sx );
1164     conf->Write( _T ( "AlertDialogSizeY" ), g_ais_alert_dialog_sy );
1165     conf->Write( _T ( "AlertDialogPosX" ), g_ais_alert_dialog_x );
1166     conf->Write( _T ( "AlertDialogPosY" ), g_ais_alert_dialog_y );
1167     conf->Write( _T ( "QueryDialogPosX" ), g_ais_query_dialog_x );
1168     conf->Write( _T ( "QueryDialogPosY" ), g_ais_query_dialog_y );
1169     conf->Write( _T ( "AISTargetListPerspective" ), g_AisTargetList_perspective );
1170     conf->Write( _T ( "AISTargetListRange" ), g_AisTargetList_range );
1171     conf->Write( _T ( "AISTargetListSortColumn" ), g_AisTargetList_sortColumn );
1172     conf->Write( _T ( "bAISTargetListSortReverse" ), g_bAisTargetList_sortReverse );
1173     conf->Write( _T ( "AISTargetListColumnSpec" ), g_AisTargetList_column_spec );
1174     conf->Write( _T ( "AISTargetListColumnOrder" ), g_AisTargetList_column_order);
1175     conf->Write( _T ( "S57QueryDialogSizeX" ), g_S57_dialog_sx );
1176     conf->Write( _T ( "S57QueryDialogSizeY" ), g_S57_dialog_sy );
1177     conf->Write( _T ( "bAISRolloverShowClass" ), g_bAISRolloverShowClass );
1178     conf->Write( _T ( "bAISRolloverShowCOG" ), g_bAISRolloverShowCOG );
1179     conf->Write( _T ( "bAISRolloverShowCPA" ), g_bAISRolloverShowCPA );
1180     conf->Write( _T ( "bAISAlertAckTimeout" ), g_bAIS_ACK_Timeout );
1181     conf->Write( _T ( "AlertAckTimeoutMinutes" ), g_AckTimeout_Mins );
1182 
1183     conf->SetPath( _T ( "/Settings/GlobalState" ) );
1184     if( ps52plib ) {
1185         conf->Write( _T ( "bShowS57Text" ), ps52plib->GetShowS57Text() );
1186         conf->Write( _T ( "bShowS57ImportantTextOnly" ), ps52plib->GetShowS57ImportantTextOnly() );
1187         if ( !g_bInlandEcdis )
1188             conf->Write( _T ( "nDisplayCategory" ), (long) ps52plib->GetDisplayCategory() );
1189         conf->Write( _T ( "nSymbolStyle" ), (int) ps52plib->m_nSymbolStyle );
1190         conf->Write( _T ( "nBoundaryStyle" ), (int) ps52plib->m_nBoundaryStyle );
1191 
1192         conf->Write( _T ( "bShowSoundg" ), ps52plib->m_bShowSoundg );
1193         conf->Write( _T ( "bShowMeta" ), ps52plib->m_bShowMeta );
1194         conf->Write( _T ( "bUseSCAMIN" ), ps52plib->m_bUseSCAMIN );
1195         conf->Write( _T ( "bShowAtonText" ), ps52plib->m_bShowAtonText );
1196         conf->Write( _T ( "bShowLightDescription" ), ps52plib->m_bShowLdisText );
1197         conf->Write( _T ( "bExtendLightSectors" ), ps52plib->m_bExtendLightSectors );
1198         conf->Write( _T ( "bDeClutterText" ), ps52plib->m_bDeClutterText );
1199         conf->Write( _T ( "bShowNationalText" ), ps52plib->m_bShowNationalTexts );
1200 
1201         conf->Write( _T ( "S52_MAR_SAFETY_CONTOUR" ), S52_getMarinerParam( S52_MAR_SAFETY_CONTOUR ) );
1202         conf->Write( _T ( "S52_MAR_SHALLOW_CONTOUR" ), S52_getMarinerParam( S52_MAR_SHALLOW_CONTOUR ) );
1203         conf->Write( _T ( "S52_MAR_DEEP_CONTOUR" ), S52_getMarinerParam( S52_MAR_DEEP_CONTOUR ) );
1204         conf->Write( _T ( "S52_MAR_TWO_SHADES" ), S52_getMarinerParam( S52_MAR_TWO_SHADES ) );
1205         conf->Write( _T ( "S52_DEPTH_UNIT_SHOW" ), ps52plib->m_nDepthUnitDisplay );
1206     }
1207 
1208     conf->SetPath( _T ( "/Settings/Others" ) );
1209 
1210     // Radar rings
1211     conf->Write( _T ( "ShowRadarRings" ), (bool)(g_iNavAidRadarRingsNumberVisible > 0) );  //3.0.0 config support
1212     conf->Write( _T ( "RadarRingsNumberVisible" ), g_iNavAidRadarRingsNumberVisible );
1213     conf->Write( _T ( "RadarRingsStep" ), g_fNavAidRadarRingsStep );
1214     conf->Write( _T ( "RadarRingsStepUnits" ), g_pNavAidRadarRingsStepUnits );
1215     conf->Write( _T ( "RadarRingsColour" ), g_colourOwnshipRangeRingsColour.GetAsString( wxC2S_HTML_SYNTAX ) );
1216 
1217     // Waypoint Radar rings
1218     conf->Write( _T ( "WaypointRangeRingsNumber" ), g_iWaypointRangeRingsNumber );
1219     conf->Write( _T ( "WaypointRangeRingsStep" ), g_fWaypointRangeRingsStep );
1220     conf->Write( _T ( "WaypointRangeRingsStepUnits" ), g_iWaypointRangeRingsStepUnits );
1221     conf->Write( _T ( "WaypointRangeRingsColour" ), g_colourWaypointRangeRingsColour.GetAsString( wxC2S_HTML_SYNTAX ) );
1222 
1223     conf->Write( _T ( "ConfirmObjectDeletion" ), g_bConfirmObjectDelete );
1224 
1225     // Waypoint dragging with mouse
1226     conf->Write( _T ( "WaypointPreventDragging" ), g_bWayPointPreventDragging );
1227 
1228     conf->Write( _T ( "EnableZoomToCursor" ), g_bEnableZoomToCursor );
1229 
1230     conf->Write( _T ( "TrackIntervalSeconds" ), g_TrackIntervalSeconds );
1231     conf->Write( _T ( "TrackDeltaDistance" ), g_TrackDeltaDistance );
1232     conf->Write( _T ( "TrackPrecision" ), g_nTrackPrecision );
1233 
1234     conf->Write( _T ( "RouteLineWidth" ), g_route_line_width );
1235     conf->Write( _T ( "TrackLineWidth" ), g_track_line_width );
1236     conf->Write( _T ( "TrackLineColour" ), g_colourTrackLineColour.GetAsString( wxC2S_HTML_SYNTAX ) );
1237     conf->Write( _T ( "DefaultWPIcon" ), g_default_wp_icon );
1238 
1239     //    Fonts
1240 
1241     //  Store the persistent Auxiliary Font descriptor Keys
1242     conf->SetPath( _T ( "/Settings/AuxFontKeys" ) );
1243 
1244     wxArrayString keyArray = FontMgr::Get().GetAuxKeyArray();
1245     for(unsigned int i=0 ; i <  keyArray.GetCount() ; i++){
1246         wxString key;
1247         key.Printf(_T("Key%i"), i);
1248         wxString keyval = keyArray[i];
1249         conf->Write( key, keyval );
1250     }
1251 
1252     wxString font_path;
1253     #ifdef __WXX11__
1254     font_path = ( _T ( "/Settings/X11Fonts" ) );
1255     #endif
1256 
1257     #ifdef __WXGTK__
1258     font_path = ( _T ( "/Settings/GTKFonts" ) );
1259     #endif
1260 
1261     #ifdef __WXMSW__
1262     font_path = ( _T ( "/Settings/MSWFonts" ) );
1263     #endif
1264 
1265     #ifdef __WXMAC__
1266     font_path = ( _T ( "/Settings/MacFonts" ) );
1267     #endif
1268 
1269     #ifdef __WXQT__
1270     font_path = ( _T ( "/Settings/QTFonts" ) );
1271     #endif
1272 
1273     conf->DeleteGroup(font_path);
1274 
1275     conf->SetPath( font_path );
1276 
1277     int nFonts = FontMgr::Get().GetNumFonts();
1278 
1279     for( int i = 0; i < nFonts; i++ ) {
1280         wxString cfstring(FontMgr::Get().GetConfigString(i));
1281         wxString valstring = FontMgr::Get().GetFullConfigDesc( i );
1282         conf->Write( cfstring, valstring );
1283     }
1284 
1285     //  Save the per-canvas config options
1286     conf->SaveCanvasConfigs( );
1287 
1288     conf->Flush();
1289 
1290     delete conf;
1291 
1292     return true;
1293 }
1294 
1295 
CheckTemplateGUID(wxString GUID)1296 bool ConfigMgr::CheckTemplateGUID( wxString GUID )
1297 {
1298     bool rv = false;
1299 
1300     OCPNConfigObject *config = GetConfig( GUID );
1301     if(config){
1302         rv = CheckTemplate( GetConfigDir() + config->templateFileName );
1303     }
1304 
1305     return rv;
1306 }
1307 
1308 
1309 #define CHECK_INT(s, t)         read_int = *t; \
1310                                 if(!conf->Read( s , &read_int)) wxLogMessage(s); \
1311                                 if( (int)*t  != read_int) return false;
1312 
1313 #define CHECK_STR(s, t)         val = t;  \
1314                                 conf->Read( s , &val); \
1315                                 if( !t.IsSameAs( val )) return false;
1316 
1317 #define CHECK_STRP(s, t)        conf->Read( s , &val); \
1318                                 if( !t->IsSameAs( val )) return false;
1319 
1320 #define CHECK_FLT(s, t, eps)    conf->Read(s, &val);  \
1321                                 val.ToDouble( &dval ); \
1322                                 if(fabs(dval - *t) > eps) return false;
1323 
CheckTemplate(wxString fileName)1324 bool ConfigMgr::CheckTemplate( wxString fileName)
1325 {
1326     bool rv = true;
1327 
1328 
1329     int read_int;
1330     wxString val;
1331     double dval;
1332 
1333     MyConfig *conf = new MyConfig( fileName );
1334 
1335 //    Global options and settings
1336     conf->SetPath( _T ( "/Settings" ) );
1337 
1338 
1339 
1340     CHECK_INT( _T ( "UIexpert" ), &g_bUIexpert );
1341 
1342     ///CHECK_STR( _T ( "UIStyle" ), g_uiStyle  );
1343 
1344 
1345     CHECK_INT( _T ( "InlandEcdis" ), &g_bInlandEcdis );
1346 
1347     CHECK_INT( _T ("DarkDecorations" ), &g_bDarkDecorations );
1348 
1349     CHECK_INT( _T( "SpaceDropMark" ), &g_bSpaceDropMark );
1350 
1351     ///CHECK_INT( _T ( "UseModernUI5" ), &g_useMUI );
1352 
1353 #if 0
1354     CHECK_INT( _T ( "DebugGDAL" ), &g_bGDAL_Debug );
1355     CHECK_INT( _T ( "DebugNMEA" ), &g_nNMEADebug );
1356     CHECK_INT( _T ( "DebugOpenGL" ), &g_bDebugOGL );
1357     ///CHECK_INT( _T ( "AnchorWatchDefault" ), &g_nAWDefault );
1358     ///CHECK_INT( _T ( "AnchorWatchMax" ), &g_nAWMax );
1359     ///CHECK_INT( _T ( "GPSDogTimeout" ), &gps_watchdog_timeout_ticks );
1360     CHECK_INT( _T ( "DebugCM93" ), &g_bDebugCM93 );
1361     CHECK_INT( _T ( "DebugS57" ), &g_bDebugS57 );         // Show LUP and Feature info in object query
1362     CHECK_INT( _T ( "DebugBSBImg" ), &g_BSBImgDebug );
1363     CHECK_INT( _T ( "DebugGPSD" ), &g_bDebugGPSD );
1364 #endif
1365 
1366     CHECK_INT( _T ( "DefaultFontSize"), &g_default_font_size );
1367 
1368 //    Read( _T ( "GPSIdent" ), &g_GPS_Ident );
1369     CHECK_INT( _T ( "UseGarminHostUpload" ),  &g_bGarminHostUpload );
1370 
1371     CHECK_INT( _T ( "UseNMEA_GLL" ), &g_bUseGLL );
1372 
1373     CHECK_INT( _T ( "AutoHideToolbar" ), &g_bAutoHideToolbar );
1374     CHECK_INT( _T ( "AutoHideToolbarSecs" ), &g_nAutoHideToolbar );
1375 
1376     CHECK_INT( _T ( "UseSimplifiedScalebar" ), &g_bsimplifiedScalebar );
1377 
1378     CHECK_INT( _T ( "DisplaySizeMM" ), &g_display_size_mm );
1379     CHECK_INT( _T ( "DisplaySizeManual" ), &g_config_display_size_manual );
1380 
1381     CHECK_INT( _T ( "GUIScaleFactor" ), &g_GUIScaleFactor );
1382 
1383     CHECK_INT( _T ( "ChartObjectScaleFactor" ), &g_ChartScaleFactor );
1384     CHECK_INT( _T ( "ShipScaleFactor" ), &g_ShipScaleFactor );
1385 
1386     CHECK_INT( _T ( "FilterNMEA_Avg" ), &g_bfilter_cogsog );
1387     CHECK_INT( _T ( "FilterNMEA_Sec" ), &g_COGFilterSec );
1388 
1389     CHECK_INT( _T ( "ShowTrue" ), &g_bShowTrue );
1390     CHECK_INT( _T ( "ShowMag" ), &g_bShowMag );
1391 
1392     CHECK_FLT( _T ( "UserMagVariation" ), &g_UserVar, 0.1)
1393 
1394     CHECK_INT( _T ( "UseMagAPB" ), &g_bMagneticAPB );
1395 
1396     CHECK_INT( _T ( "ScreenBrightness" ), &g_nbrightness );
1397 
1398     CHECK_INT( _T ( "MemFootprintTargetMB" ), &g_MemFootMB );
1399 
1400     CHECK_INT( _T ( "WindowsComPortMax" ), &g_nCOMPortCheck );
1401 
1402     CHECK_INT( _T ( "ChartQuilting" ), &g_bQuiltEnable );
1403     CHECK_INT( _T ( "ChartQuiltingInitial" ), &g_bQuiltStart );
1404 
1405     CHECK_INT( _T ( "CourseUpMode" ), &g_bCourseUp );
1406     CHECK_INT( _T ( "COGUPAvgSeconds" ), &g_COGAvgSec );
1407     //CHECK_INT( _T ( "LookAheadMode" ), &g_bLookAhead );
1408     //CHECK_INT( _T ( "SkewToNorthUp" ), &g_bskew_comp );
1409     CHECK_INT( _T ( "OpenGL" ), &g_bopengl );
1410     CHECK_INT( _T ( "SoftwareGL" ), &g_bSoftwareGL );
1411 
1412     CHECK_INT( _T ( "ShowFPS" ), &g_bShowFPS );
1413 
1414     CHECK_INT( _T( "NMEAAPBPrecision" ), &g_NMEAAPBPrecision );
1415 
1416     CHECK_STR( _T( "TalkerIdText" ), g_TalkerIdText );
1417     CHECK_INT( _T( "MaxWaypointNameLength" ), &g_maxWPNameLength );
1418 
1419     /* opengl options */
1420 #ifdef ocpnUSE_GL
1421     CHECK_INT( _T ( "OpenGLExpert" ), &g_bGLexpert );
1422     CHECK_INT( _T ( "UseAcceleratedPanning" ), &g_GLOptions.m_bUseAcceleratedPanning );
1423     CHECK_INT( _T ( "GPUTextureCompression" ), &g_GLOptions.m_bTextureCompression);
1424     CHECK_INT( _T ( "GPUTextureCompressionCaching" ), &g_GLOptions.m_bTextureCompressionCaching);
1425     CHECK_INT( _T ( "PolygonSmoothing" ), &g_GLOptions.m_GLPolygonSmoothing);
1426     CHECK_INT( _T ( "LineSmoothing" ), &g_GLOptions.m_GLLineSmoothing);
1427     CHECK_INT( _T ( "GPUTextureDimension" ), &g_GLOptions.m_iTextureDimension );
1428     CHECK_INT( _T ( "GPUTextureMemSize" ), &g_GLOptions.m_iTextureMemorySize );
1429 
1430 #endif
1431     CHECK_INT( _T ( "SmoothPanZoom" ), &g_bsmoothpanzoom );
1432 
1433     CHECK_INT( _T ( "ToolbarX"), &g_maintoolbar_x );
1434     CHECK_INT( _T ( "ToolbarY" ), &g_maintoolbar_y );
1435     CHECK_INT( _T ( "ToolbarOrient" ), &g_maintoolbar_orient );
1436     CHECK_STR( _T ( "GlobalToolbarConfig" ), g_toolbarConfig );
1437 
1438     CHECK_INT( _T ( "iENCToolbarX"), &g_iENCToolbarPosX );
1439     CHECK_INT( _T ( "iENCToolbarY"), &g_iENCToolbarPosY );
1440 
1441     CHECK_STR( _T ( "AnchorWatch1GUID" ), g_AW1GUID );
1442     CHECK_STR( _T ( "AnchorWatch2GUID" ), g_AW2GUID );
1443 
1444     CHECK_INT( _T ( "MobileTouch" ), &g_btouch );
1445     CHECK_INT( _T ( "ResponsiveGraphics" ), &g_bresponsive );
1446 
1447     CHECK_INT( _T ( "ZoomDetailFactor" ), &g_chart_zoom_modifier );
1448     CHECK_INT( _T ( "ZoomDetailFactorVector" ), &g_chart_zoom_modifier_vector );
1449 
1450     CHECK_INT( _T ( "CM93DetailFactor" ), &g_cm93_zoom_factor );
1451     CHECK_INT( _T ( "CM93DetailZoomPosX" ), &g_detailslider_dialog_x );
1452     CHECK_INT( _T ( "CM93DetailZoomPosY" ), &g_detailslider_dialog_y );
1453     CHECK_INT( _T ( "ShowCM93DetailSlider" ), &g_bShowDetailSlider );
1454 
1455     CHECK_INT( _T ( "SENC_LOD_Pixels" ), &g_SENC_LOD_pixels );
1456 
1457     CHECK_INT( _T ( "SkewCompUpdatePeriod" ), &g_SkewCompUpdatePeriod );
1458 
1459     CHECK_INT( _T ( "ShowStatusBar" ), &g_bShowStatusBar );
1460 #ifndef __WXOSX__
1461     CHECK_INT( _T ( "ShowMenuBar" ), &g_bShowMenuBar );
1462 #endif
1463     CHECK_INT( _T ( "Fullscreen" ), &g_bFullscreen );
1464     CHECK_INT( _T ( "ShowCompassWindow" ), &g_bShowCompassWin );
1465     CHECK_INT( _T ( "PlayShipsBells" ), &g_bPlayShipsBells );
1466     CHECK_INT( _T ( "SoundDeviceIndex" ), &g_iSoundDeviceIndex );
1467     CHECK_INT( _T ( "FullscreenToolbar" ), &g_bFullscreenToolbar );
1468     //CHECK_INT( _T ( "TransparentToolbar" ), &g_bTransparentToolbar );
1469     CHECK_INT( _T ( "PermanentMOBIcon" ), &g_bPermanentMOBIcon );
1470     CHECK_INT( _T ( "ShowLayers" ), &g_bShowLayers );
1471     CHECK_INT( _T ( "ShowDepthUnits" ), &g_bShowDepthUnits );
1472     CHECK_INT( _T ( "AutoAnchorDrop" ), &g_bAutoAnchorMark );
1473     CHECK_INT( _T ( "ShowActiveRouteHighway" ), &g_bShowActiveRouteHighway );
1474     CHECK_INT( _T ( "ShowActiveRouteTotal" ), &g_bShowRouteTotal );
1475     CHECK_STR( _T ( "MostRecentGPSUploadConnection" ), g_uploadConnection);
1476     CHECK_INT( _T ( "ShowChartBar" ), &g_bShowChartBar );
1477     CHECK_INT( _T ( "SDMMFormat" ), &g_iSDMMFormat ); //0 = "Degrees, Decimal minutes"), 1 = "Decimal degrees", 2 = "Degrees,Minutes, Seconds"
1478 
1479     CHECK_INT( _T ( "DistanceFormat" ), &g_iDistanceFormat ); //0 = "Nautical miles"), 1 = "Statute miles", 2 = "Kilometers", 3 = "Meters"
1480     CHECK_INT( _T ( "SpeedFormat" ), &g_iSpeedFormat ); //0 = "kts"), 1 = "mph", 2 = "km/h", 3 = "m/s"
1481 
1482     // LIVE ETA OPTION
1483     CHECK_INT( _T ( "LiveETA" ), &g_bShowLiveETA );
1484     CHECK_INT( _T ( "DefaultBoatSpeed" ), &g_defaultBoatSpeed );
1485 
1486     CHECK_INT( _T ( "OwnshipCOGPredictorMinutes" ), &g_ownship_predictor_minutes );
1487     CHECK_INT( _T ( "OwnshipCOGPredictorWidth" ), &g_cog_predictor_width );
1488     CHECK_INT( _T ( "OwnshipHDTPredictorMiles" ), &g_ownship_HDTpredictor_miles );
1489 
1490     CHECK_INT( _T ( "OwnShipIconType" ), &g_OwnShipIconType );
1491     CHECK_FLT( _T ( "OwnShipLength" ), &g_n_ownship_length_meters, 0.1 );
1492     CHECK_FLT( _T ( "OwnShipWidth" ), &g_n_ownship_beam_meters, 0.1 );
1493     CHECK_FLT( _T ( "OwnShipGPSOffsetX" ), &g_n_gps_antenna_offset_x, 0.1 );
1494     CHECK_FLT( _T ( "OwnShipGPSOffsetY" ), &g_n_gps_antenna_offset_y, 0.1 );
1495     CHECK_INT( _T ( "OwnShipMinSize" ), &g_n_ownship_min_mm );
1496     CHECK_INT( _T ( "OwnShipSogCogCalc" ), &g_own_ship_sog_cog_calc );
1497     CHECK_INT( _T ( "OwnShipSogCogCalcDampSec"), &g_own_ship_sog_cog_calc_damp_sec );
1498 
1499     CHECK_FLT( _T ( "RouteArrivalCircleRadius" ), &g_n_arrival_circle_radius, .01 );
1500 
1501     CHECK_INT( _T ( "FullScreenQuilt" ), &g_bFullScreenQuilt );
1502 
1503     CHECK_INT( _T ( "StartWithTrackActive" ), &g_bTrackCarryOver );
1504     CHECK_INT( _T ( "AutomaticDailyTracks" ), &g_bTrackDaily );
1505     CHECK_INT( _T ( "TrackRotateAt" ), &g_track_rotate_time );
1506     CHECK_INT( _T ( "TrackRotateTimeType" ), &g_track_rotate_time_type );
1507     CHECK_INT( _T ( "HighlightTracks" ), &g_bHighliteTracks );
1508 
1509     CHECK_FLT( _T ( "PlanSpeed" ), &g_PlanSpeed, 0.1)
1510 
1511     ///CHECK_STR( _T ( "VisibleLayers" ), g_VisibleLayers );
1512     ///CHECK_STR( _T ( "InvisibleLayers" ), g_InvisibleLayers );
1513 
1514     CHECK_INT( _T ( "PreserveScaleOnX" ), &g_bPreserveScaleOnX );
1515 
1516     CHECK_STR( _T ( "Locale" ), g_locale );
1517     CHECK_STR( _T ( "LocaleOverride" ), g_localeOverride );
1518 
1519     //We allow 0-99 backups ov navobj.xml
1520     CHECK_INT( _T ( "KeepNavobjBackups" ), &g_navobjbackups );
1521 
1522 //     NMEALogWindow::Get().SetSize(Read(_T("NMEALogWindowSizeX"), 600L), Read(_T("NMEALogWindowSizeY"), 400L));
1523 //     NMEALogWindow::Get().SetPos(Read(_T("NMEALogWindowPosX"), 10L), Read(_T("NMEALogWindowPosY"), 10L));
1524 //     NMEALogWindow::Get().CheckPos(display_width, display_height);
1525 
1526     // Boolean to cater for legacy Input COM Port filer behaviour, i.e. show msg filtered but put msg on bus.
1527     CHECK_INT( _T ( "LegacyInputCOMPortFilterBehaviour" ), &g_b_legacy_input_filter_behaviour );
1528 
1529     CHECK_INT( _T( "AdvanceRouteWaypointOnArrivalOnly" ), &g_bAdvanceRouteWaypointOnArrivalOnly);
1530 
1531     CHECK_INT( _T ( "EnableRotateKeys" ),  &g_benable_rotate );
1532     CHECK_INT( _T ( "EmailCrashReport" ),  &g_bEmailCrashReport );
1533 
1534     CHECK_INT( _T ( "EnableAISNameCache" ),  &g_benableAISNameCache );
1535 
1536     CHECK_INT( _T ( "EnableUDPNullHeader" ),  &g_benableUDPNullHeader );
1537 
1538     conf->SetPath( _T ( "/Settings/GlobalState" ) );
1539 
1540     CHECK_INT( _T ( "FrameWinX" ), &g_nframewin_x );
1541     CHECK_INT( _T ( "FrameWinY" ), &g_nframewin_y );
1542     CHECK_INT( _T ( "FrameWinPosX" ), &g_nframewin_posx );
1543     CHECK_INT( _T ( "FrameWinPosY" ), &g_nframewin_posy );
1544     CHECK_INT( _T ( "FrameMax" ), &g_bframemax );
1545 
1546     CHECK_INT( _T ( "ClientPosX" ), &g_lastClientRectx );
1547     CHECK_INT( _T ( "ClientPosY" ), &g_lastClientRecty );
1548     CHECK_INT( _T ( "ClientSzX" ), &g_lastClientRectw );
1549     CHECK_INT( _T ( "ClientSzY" ), &g_lastClientRecth );
1550 
1551     CHECK_INT( _T( "RoutePropSizeX" ), &g_route_prop_sx );
1552     CHECK_INT( _T( "RoutePropSizeY" ), &g_route_prop_sy );
1553     CHECK_INT( _T( "RoutePropPosX" ), &g_route_prop_x );
1554     CHECK_INT( _T( "RoutePropPosY" ), &g_route_prop_y );
1555 
1556     CHECK_INT( _T ( "S52_DEPTH_UNIT_SHOW" ), &g_nDepthUnitDisplay );   // default is metres
1557 
1558     //    AIS
1559     conf->SetPath( _T ( "/Settings/AIS" ) );
1560     CHECK_INT( _T ( "bNoCPAMax" ), &g_bCPAMax );
1561     CHECK_FLT( _T ( "NoCPAMaxNMi" ), &g_CPAMax_NM, .01 )
1562     CHECK_INT( _T ( "bCPAWarn" ), &g_bCPAWarn );
1563     CHECK_FLT( _T ( "CPAWarnNMi" ), &g_CPAWarn_NM, .01 )
1564     CHECK_INT( _T ( "bTCPAMax" ), &g_bTCPA_Max );
1565     CHECK_FLT( _T ( "TCPAMaxMinutes" ), &g_TCPA_Max, 1  )
1566     CHECK_INT( _T ( "bMarkLostTargets" ), &g_bMarkLost );
1567     CHECK_FLT( _T ( "MarkLost_Minutes" ), &g_MarkLost_Mins, 1 )
1568     CHECK_INT( _T ( "bRemoveLostTargets" ), &g_bRemoveLost );
1569     CHECK_FLT( _T ( "RemoveLost_Minutes" ), &g_RemoveLost_Mins, 1 )
1570     CHECK_INT( _T ( "bShowCOGArrows" ), &g_bShowCOG );
1571     CHECK_FLT( _T ( "CogArrowMinutes" ), &g_ShowCOG_Mins, 1 );
1572     CHECK_INT( _T ( "bShowTargetTracks" ), &g_bAISShowTracks );
1573     CHECK_FLT( _T ( "TargetTracksMinutes" ), &g_AISShowTracks_Mins, 1 )
1574     CHECK_FLT( _T ( "TargetTracksLimit" ), &g_AISShowTracks_Limit, 300 )
1575     CHECK_INT( _T ( "bHideMooredTargets" ), &g_bHideMoored )
1576     CHECK_FLT( _T ( "MooredTargetMaxSpeedKnots" ), &g_ShowMoored_Kts, .1 )
1577     CHECK_INT( _T ( "bShowScaledTargets"), &g_bAllowShowScaled );
1578     CHECK_INT( _T ( "AISScaledNumber" ), &g_ShowScaled_Num );
1579     CHECK_INT( _T ( "AISScaledNumberWeightSOG" ), &g_ScaledNumWeightSOG );
1580     CHECK_INT( _T ( "AISScaledNumberWeightCPA" ), &g_ScaledNumWeightCPA );
1581     CHECK_INT( _T ( "AISScaledNumberWeightTCPA" ), &g_ScaledNumWeightTCPA );
1582     CHECK_INT( _T ( "AISScaledNumberWeightRange" ), &g_ScaledNumWeightRange );
1583     CHECK_INT( _T ( "AISScaledNumberWeightSizeOfTarget" ), &g_ScaledNumWeightSizeOfT );
1584     CHECK_INT( _T ( "AISScaledSizeMinimal" ), &g_ScaledSizeMinimal );
1585     CHECK_INT( _T(  "AISShowScaled"), &g_bShowScaled );
1586     CHECK_INT( _T ( "bShowAreaNotices" ), &g_bShowAreaNotices );
1587     CHECK_INT( _T ( "bDrawAISSize" ), &g_bDrawAISSize );
1588     CHECK_INT( _T ( "bDrawAISRealtime" ), &g_bDrawAISRealtime );
1589     CHECK_FLT( _T ( "AISRealtimeMinSpeedKnots" ), &g_AIS_RealtPred_Kts, .1 );
1590     CHECK_INT( _T ( "bShowAISName" ), &g_bShowAISName );
1591     CHECK_INT( _T ( "bAISAlertDialog" ), &g_bAIS_CPA_Alert );
1592     CHECK_INT( _T ( "ShowAISTargetNameScale" ), &g_Show_Target_Name_Scale );
1593     CHECK_INT( _T ( "bWplIsAprsPositionReport" ), &g_bWplIsAprsPosition );
1594     CHECK_INT( _T ( "AISCOGPredictorWidth" ), &g_ais_cog_predictor_width );
1595     CHECK_INT( _T ( "bAISAlertAudio" ), &g_bAIS_CPA_Alert_Audio );
1596     CHECK_STR( _T ( "AISAlertAudioFile" ), g_sAIS_Alert_Sound_File );
1597     CHECK_INT( _T ( "bAISAlertSuppressMoored" ), &g_bAIS_CPA_Alert_Suppress_Moored );
1598     CHECK_INT( _T ( "bAISAlertAckTimeout" ), &g_bAIS_ACK_Timeout );
1599     CHECK_FLT( _T ( "AlertAckTimeoutMinutes" ), &g_AckTimeout_Mins, 1 )
1600     CHECK_STR( _T ( "AISTargetListPerspective" ), g_AisTargetList_perspective );
1601     CHECK_INT( _T ( "AISTargetListRange" ), &g_AisTargetList_range );
1602     CHECK_INT( _T ( "AISTargetListSortColumn" ), &g_AisTargetList_sortColumn );
1603     CHECK_INT( _T ( "bAISTargetListSortReverse" ), &g_bAisTargetList_sortReverse );
1604     CHECK_STR( _T ( "AISTargetListColumnSpec" ), g_AisTargetList_column_spec );
1605     CHECK_STR( _T ("AISTargetListColumnOrder"), g_AisTargetList_column_order);
1606     CHECK_INT( _T ( "bAISRolloverShowClass" ), &g_bAISRolloverShowClass );
1607     CHECK_INT( _T ( "bAISRolloverShowCOG" ), &g_bAISRolloverShowCOG );
1608     CHECK_INT( _T ( "bAISRolloverShowCPA" ), &g_bAISRolloverShowCPA );
1609 
1610     CHECK_INT( _T ( "S57QueryDialogSizeX" ), &g_S57_dialog_sx );
1611     CHECK_INT( _T ( "S57QueryDialogSizeY" ), &g_S57_dialog_sy );
1612     CHECK_INT( _T ( "AlertDialogSizeX" ), &g_ais_alert_dialog_sx );
1613     CHECK_INT( _T ( "AlertDialogSizeY" ), &g_ais_alert_dialog_sy );
1614     CHECK_INT( _T ( "AlertDialogPosX" ), &g_ais_alert_dialog_x );
1615     CHECK_INT( _T ( "AlertDialogPosY" ), &g_ais_alert_dialog_y );
1616     CHECK_INT( _T ( "QueryDialogPosX" ), &g_ais_query_dialog_x );
1617     CHECK_INT( _T ( "QueryDialogPosY" ), &g_ais_query_dialog_y );
1618 
1619 
1620     conf->SetPath( _T ( "/Directories" ) );
1621     CHECK_STR( _T ( "PresentationLibraryData" ), g_UserPresLibData)
1622     ///CHECK_STRP( _T ( "InitChartDir" ), pInit_Chart_Dir)
1623 
1624     CHECK_STR( _T ( "SENCFileLocation" ), g_SENCPrefix)
1625 
1626 
1627     CHECK_STR( _T ( "GPXIODir" ), g_gpx_path );           // Get the Directory name
1628     CHECK_STR( _T ( "TCDataDir" ), g_TCData_Dir );           // Get the Directory name
1629     CHECK_STR( _T ( "BasemapDir"), gWorldMapLocation );
1630 
1631 //    Fonts
1632 
1633 #if 0
1634     //  Load the persistent Auxiliary Font descriptor Keys
1635     conf->SetPath ( _T ( "/Settings/AuxFontKeys" ) );
1636 
1637     wxString strk;
1638     long dummyk;
1639     wxString kval;
1640     bool bContk = conf->GetFirstEntry( strk, dummyk );
1641     bool bNewKey = false;
1642     while( bContk ) {
1643         Read( strk, &kval );
1644         bNewKey = FontMgr::Get().AddAuxKey(kval);
1645         if(!bNewKey) {
1646             DeleteEntry( strk );
1647             dummyk--;
1648         }
1649         bContk = GetNextEntry( strk, dummyk );
1650     }
1651 #endif
1652 
1653 #ifdef __WXX11__
1654     conf->SetPath ( _T ( "/Settings/X11Fonts" ) );
1655 #endif
1656 
1657 #ifdef __WXGTK__
1658     conf->SetPath ( _T ( "/Settings/GTKFonts" ) );
1659 #endif
1660 
1661 #ifdef __WXMSW__
1662     conf->SetPath( _T ( "/Settings/MSWFonts" ) );
1663 #endif
1664 
1665 #ifdef __WXMAC__
1666     conf->SetPath ( _T ( "/Settings/MacFonts" ) );
1667 #endif
1668 
1669 #ifdef __WXQT__
1670     conf->SetPath ( _T ( "/Settings/QTFonts" ) );
1671 #endif
1672 
1673 #if 0
1674     if(conf->GetNumberOfEntries() != (unsigned int)FontMgr::Get().GetNumFonts() )
1675         return false;
1676 
1677     wxString str;
1678     long dummy;
1679     wxString pval;
1680 
1681     bool bCont = conf->GetFirstEntry( str, dummy );
1682     while( bCont ) {
1683         conf->Read( str, &pval );
1684         if(!FontMgr::Get().FindFontByConfigString(str))
1685             return false;
1686 
1687         bCont = conf->GetNextEntry( str, dummy );
1688     }
1689 
1690 
1691 //  Tide/Current Data Sources
1692     conf->SetPath( _T ( "/TideCurrentDataSources" ) );
1693     if( conf->GetNumberOfEntries() != TideCurrentDataSet.GetCount())
1694         return false;
1695 
1696     if( conf->GetNumberOfEntries()){
1697         wxString str, val;
1698         long dummy;
1699         bool bCont = conf->GetFirstEntry( str, dummy );
1700         while( bCont ) {
1701             conf->Read( str, &val );              // Get a file name
1702             if( TideCurrentDataSet.Index(val) == wxNOT_FOUND)
1703                 return false;
1704             bCont = conf->GetNextEntry( str, dummy );
1705         }
1706     }
1707 
1708 #endif
1709 
1710 #if 0
1711     //    Groups
1712     conf->SetPath( _T ( "/Groups" ) );
1713     unsigned int group_count;
1714     conf->Read( _T ( "GroupCount" ), (int *) &group_count, 0 );
1715 
1716     if(group_count != g_pGroupArray->GetCount())
1717         return false;
1718 
1719     // Walk the array of groups in the target template
1720     for( unsigned int i = 0; i < group_count; i++ ) {
1721         wxString s;
1722         s.Printf( _T("Group%d"), i + 1 );
1723         s.Prepend( _T ( "/Groups/" ) );
1724         conf->SetPath( s );
1725 
1726         wxString t;
1727         conf->Read( _T ( "GroupName" ), &t );
1728 
1729         // Look for this group name int the active array
1730         bool bfound = false;
1731         ChartGroup *pGroup;
1732         for(unsigned int j = 0 ; j < g_pGroupArray->GetCount() ; j++){
1733             pGroup = g_pGroupArray->Item(i);
1734             if(pGroup && (pGroup->m_group_name.IsSameAs(t))){
1735                 bfound = true;
1736                 break;
1737             }
1738         }
1739 
1740         if(!bfound)
1741             return false;
1742         //TODO
1743         // Here we could further check the contents of the found group.
1744     }
1745 
1746 
1747 #endif
1748 
1749 
1750 
1751     conf->SetPath( _T ( "/Settings/Others" ) );
1752 
1753     // Radar rings
1754     CHECK_INT( _T ( "RadarRingsNumberVisible" ), &g_iNavAidRadarRingsNumberVisible )
1755     CHECK_INT( _T ( "RadarRingsStep" ), &g_fNavAidRadarRingsStep )
1756 
1757     CHECK_INT( _T ( "RadarRingsStepUnits" ), &g_pNavAidRadarRingsStepUnits );
1758 
1759 //    wxString l_wxsOwnshipRangeRingsColour;
1760 //    CHECK_STR( _T ( "RadarRingsColour" ), &l_wxsOwnshipRangeRingsColour );
1761 //    if(l_wxsOwnshipRangeRingsColour.Length()) g_colourOwnshipRangeRingsColour.Set( l_wxsOwnshipRangeRingsColour );
1762 
1763     // Waypoint Radar rings
1764     CHECK_INT( _T ( "WaypointRangeRingsNumber" ), &g_iWaypointRangeRingsNumber )
1765 
1766     CHECK_FLT( _T ( "WaypointRangeRingsStep" ), &g_fWaypointRangeRingsStep, .1 )
1767 
1768     CHECK_INT( _T ( "WaypointRangeRingsStepUnits" ), &g_iWaypointRangeRingsStepUnits );
1769 
1770 //    wxString l_wxsWaypointRangeRingsColour;
1771 //    CHECK_STR( _T( "WaypointRangeRingsColour" ), &l_wxsWaypointRangeRingsColour );
1772 //    g_colourWaypointRangeRingsColour.Set( l_wxsWaypointRangeRingsColour );
1773 
1774 
1775     CHECK_INT( _T ( "ConfirmObjectDeletion" ), &g_bConfirmObjectDelete );
1776 
1777     // Waypoint dragging with mouse
1778     CHECK_INT( _T ( "WaypointPreventDragging" ), &g_bWayPointPreventDragging );
1779 
1780     CHECK_INT( _T ( "EnableZoomToCursor" ), &g_bEnableZoomToCursor );
1781 
1782     CHECK_FLT( _T ( "TrackIntervalSeconds" ), &g_TrackIntervalSeconds, 1 )
1783 
1784     CHECK_FLT( _T ( "TrackDeltaDistance" ), &g_TrackDeltaDistance, .1 )
1785 
1786     CHECK_INT( _T ( "TrackPrecision" ), &g_nTrackPrecision );
1787 
1788     //CHECK_STR( _T ( "NavObjectFileName" ), m_sNavObjSetFile );
1789 
1790     CHECK_INT( _T ( "RouteLineWidth" ), &g_route_line_width );
1791     CHECK_INT( _T ( "TrackLineWidth" ), &g_track_line_width );
1792 
1793 //     wxString l_wxsTrackLineColour;
1794 //     CHECK_STR( _T( "TrackLineColour" ), l_wxsTrackLineColour )
1795 //         g_colourTrackLineColour.Set( l_wxsTrackLineColour );
1796 
1797     CHECK_STR( _T ( "DefaultWPIcon" ), g_default_wp_icon )
1798 
1799     // S57 template items
1800 
1801     #define CHECK_BFN(s, t)         conf->Read( s , &read_int); \
1802                                     bval = t; \
1803                                     bval0 = read_int != 0; \
1804                                     if( bval != bval0 ) return false;
1805 
1806     #define CHECK_IFN(s, t)         conf->Read( s , &read_int); \
1807                                     if( read_int != t ) return false;
1808 
1809     #define CHECK_FFN(s, t)         conf->Read( s , &dval); \
1810                                     if( fabs(dval - t) > 0.1) return false;
1811 
1812     if( ps52plib ){
1813 
1814         int read_int;
1815         double dval;
1816         bool bval, bval0;
1817 
1818         conf->SetPath( _T ( "/Settings/GlobalState" ) );
1819 
1820         CHECK_BFN( _T ( "bShowS57Text" ), ps52plib->GetShowS57Text() );
1821 
1822         CHECK_BFN( _T ( "bShowS57ImportantTextOnly" ), ps52plib->GetShowS57ImportantTextOnly() );
1823         CHECK_BFN( _T ( "bShowLightDescription" ), ps52plib->m_bShowLdisText );
1824         CHECK_BFN( _T ( "bExtendLightSectors" ), ps52plib->m_bExtendLightSectors );
1825         CHECK_BFN( _T ( "bShowSoundg" ), ps52plib->m_bShowSoundg );
1826         CHECK_BFN( _T ( "bShowMeta" ), ps52plib->m_bShowMeta );
1827         CHECK_BFN( _T ( "bUseSCAMIN" ), ps52plib->m_bUseSCAMIN );
1828         CHECK_BFN( _T ( "bShowAtonText" ), ps52plib->m_bShowAtonText );
1829         CHECK_BFN( _T ( "bDeClutterText" ), ps52plib->m_bDeClutterText );
1830         CHECK_BFN( _T ( "bShowNationalText" ), ps52plib->m_bShowNationalTexts );
1831         CHECK_IFN( _T ( "nDisplayCategory" ), ps52plib->GetDisplayCategory() );
1832         CHECK_IFN( _T ( "nSymbolStyle" ), ps52plib->m_nSymbolStyle );
1833         CHECK_IFN( _T ( "nBoundaryStyle" ), ps52plib->m_nBoundaryStyle );
1834         CHECK_FFN( _T ( "S52_MAR_SAFETY_CONTOUR" ), S52_getMarinerParam( S52_MAR_SAFETY_CONTOUR ));
1835         CHECK_FFN( _T ( "S52_MAR_SHALLOW_CONTOUR" ), S52_getMarinerParam( S52_MAR_SHALLOW_CONTOUR ));
1836         CHECK_FFN( _T ( "S52_MAR_DEEP_CONTOUR" ), S52_getMarinerParam( S52_MAR_DEEP_CONTOUR ));
1837         CHECK_FFN( _T ( "S52_MAR_TWO_SHADES" ), S52_getMarinerParam( S52_MAR_TWO_SHADES ));
1838         CHECK_INT( _T ( "S52_DEPTH_UNIT_SHOW" ), &g_nDepthUnitDisplay );
1839 
1840         //    S57 Object Class Visibility
1841 
1842         OBJLElement *pOLE;
1843 
1844         conf->SetPath( _T ( "/Settings/ObjectFilter" ) );
1845 
1846         unsigned int iOBJMax = conf->GetNumberOfEntries();
1847 
1848         if(iOBJMax != ps52plib->pOBJLArray->GetCount() )
1849             return false;
1850 
1851         if( iOBJMax ) {
1852 
1853             wxString str, sObj;
1854             long val;
1855             long dummy;
1856 
1857             bool bCont = conf->GetFirstEntry( str, dummy );
1858             while( bCont ) {
1859                 conf->Read( str, &val );              // Get an Object Viz
1860 
1861                 // scan for the same key in the global list
1862                 bool bfound = false;
1863                 if( str.StartsWith( _T ( "viz" ), &sObj ) ) {
1864                     for( unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
1865                         pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
1866                         if( !strncmp( pOLE->OBJLName, sObj.mb_str(), 6 ) ) {
1867                             bfound = true;
1868                             if(pOLE->nViz != val){
1869                                 return false;
1870                             }
1871                         }
1872                     }
1873 
1874                     if(!bfound)
1875                         return false;
1876                 }
1877                 bCont = conf->GetNextEntry( str, dummy );
1878             }
1879         }
1880     }
1881 
1882     conf->SetPath( _T ( "/MMSIProperties" ) );
1883     int iPMax = conf->GetNumberOfEntries();
1884     if( iPMax ) {
1885         wxString str, val;
1886         long dummy;
1887 
1888         bool bCont = conf->GetFirstEntry( str, dummy );
1889         while( bCont ) {
1890             conf->Read( str, &val );              // Get an entry
1891 
1892             bool bfound = false;
1893             for(unsigned int j=0 ; j < g_MMSI_Props_Array.GetCount() ; j++){
1894                 MMSIProperties *pProps = g_MMSI_Props_Array.Item(j);
1895                 if(pProps->Serialize().IsSameAs( val )){
1896                     bfound = true;
1897                     break;
1898                 }
1899             }
1900             if(!bfound)
1901                 return false;
1902 
1903             bCont = conf->GetNextEntry( str, dummy );
1904         }
1905     }
1906 
1907     return rv;
1908 }
1909 
1910