1 /******************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  Grib Settings Dialog
5  * Author:   Sean D'Epagnier
6  *
7  ***************************************************************************
8  *   Copyright (C) 2015 by Sean D'Epagnier                                 *
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  */
27 
28 #include "grib_pi.h"
29 #include "folder.xpm"
30 
31 static const wxString units0_names[] = {_("Knots"), _("m/s"), _("mph"), _("km/h"), _("Beaufort"), wxEmptyString};
32 static const wxString units1_names[] = {_("MilliBars"), _("mmHG"), _("inHG"), wxEmptyString};
33 static const wxString units2_names[] = {_("Meters"), _("Feet"), wxEmptyString};
34 static const wxString units3_names[] = {_("Celsius"), _("Fahrenheit"), wxEmptyString};
35 static const wxString units4_names[] = {_("Millimeters"), _("Inches"), wxEmptyString};
36 static const wxString units5_names[] = {_("Percentage"), wxEmptyString};
37 static const wxString units6_names[] = {_("j/kg"), wxEmptyString};
38 static const wxString units7_names[] = {_("Knots"), _("m/s"), _("mph"), _("km/h"), wxEmptyString};
39 static const wxString units8_names[] = {_("dBZ"), wxEmptyString};
40 static const wxString *unit_names[] = {units0_names, units1_names, units2_names,
41                                        units3_names, units4_names, units5_names,
42                                        units6_names, units7_names, units8_names};
43 
44 static const wxString name_from_index[] = {_T("Wind"), _T("WindGust"), _T("Pressure"),
45                                            _T("Waves"), _T("Current"),
46                                            _T("Rainfall"), _T("CloudCover"),
47                                            _T("AirTemperature"), _T("SeaTemperature"), _T("CAPE"),
48                                            _T("CompositeReflectivity"),_T("Altitude"), _T("RelativeHumidity") };
49 static const wxString tname_from_index[] = {_("Wind"), _("Wind Gust"),  _("Pressure"),
50                                             _("Waves"), _("Current"),
51                                             _("Rainfall"), _("Cloud Cover"),
52                                             _("Air Temperature"), _("Sea Temperature"), _("CAPE"),
53                                             _T("Composite Reflectivity"),
54                                             _("Altitude(Geopotential)"), _("Relative Humidity") };
55 
56 static const int unittype[GribOverlaySettings::SETTINGS_COUNT] = {0, 0, 1, 2, 7, 4, 5, 3, 3, 6, 8, 2, 5};
57 
58 static const int minuttes_from_index [] = { 2, 5, 10, 20, 30, 60, 90, 180, 360, 720, 1440 };
59 
60 static const wxString altitude_from_index[3][5] = {
61     {_T("Std"), _T("850"), _T("700"), _T("500"), _T("300")},
62     {_T("Std"), _T("637"), _T("525"), _T("375"), _T("225")},
63     {_T("Std"), _T("25.2"), _T("20.7"), _T("14.8"), _T("8.9")}
64     };
65 
66 enum SettingsDisplay {B_ARROWS, ISO_LINE, ISO_ABBR, ISO_LINE_VISI, ISO_LINE_SHORT, D_ARROWS, OVERLAY,
67                         NUMBERS, PARTICLES};
68 
69 #ifdef __OCPN__ANDROID__
70 
71 QString qtStyleSheet = "QScrollBar:horizontal {\
72 border: 0px solid grey;\
73 background-color: rgb(240, 240, 240);\
74 height: 35px;\
75 margin: 0px 1px 0 1px;\
76 }\
77 QScrollBar::handle:horizontal {\
78 background-color: rgb(200, 200, 200);\
79 min-width: 20px;\
80 border-radius: 10px;\
81 }\
82 QScrollBar::add-line:horizontal {\
83 border: 0px solid grey;\
84 background: #32CC99;\
85 width: 0px;\
86 subcontrol-position: right;\
87 subcontrol-origin: margin;\
88 }\
89 QScrollBar::sub-line:horizontal {\
90 border: 0px solid grey;\
91 background: #32CC99;\
92 width: 0px;\
93 subcontrol-position: left;\
94 subcontrol-origin: margin;\
95 }\
96 QScrollBar:vertical {\
97 border: 0px solid grey;\
98 background-color: rgb(240, 240, 240);\
99 width: 35px;\
100 margin: 1px 0px 1px 0px;\
101 }\
102 QScrollBar::handle:vertical {\
103 background-color: rgb(200, 200, 200);\
104 min-height: 20px;\
105 border-radius: 10px;\
106 }\
107 QScrollBar::add-line:vertical {\
108 border: 0px solid grey;\
109 background: #32CC99;\
110 height: 0px;\
111 subcontrol-position: top;\
112 subcontrol-origin: margin;\
113 }\
114 QScrollBar::sub-line:vertical {\
115 border: 0px solid grey;\
116 background: #32CC99;\
117 height: 0px;\
118 subcontrol-position: bottom;\
119 subcontrol-origin: margin;\
120 }\
121 QCheckBox {\
122 spacing: 25px;\
123 }\
124 QCheckBox::indicator {\
125 width: 30px;\
126 height: 30px;\
127 }\
128 ";
129 
130 #endif
131 
132 
133 extern int   m_DialogStyle;
134 
GetAltitudeFromIndex(int index,int unit)135 wxString GribOverlaySettings::GetAltitudeFromIndex( int index, int unit )
136 {
137     return wxGetTranslation(altitude_from_index[unit][index]);
138 }
139 
GetMinFromIndex(int index)140 int GribOverlaySettings::GetMinFromIndex( int index )
141 {
142     return minuttes_from_index[index];
143 }
144 
NameFromIndex(int index)145 wxString GribOverlaySettings::NameFromIndex(int index)
146 {
147     return wxGetTranslation(tname_from_index[index]);
148 }
149 
Read()150 void GribOverlaySettings::Read()
151 {
152     /* read settings here */
153     wxFileConfig *pConf = GetOCPNConfigObject();
154 
155     if(!pConf)
156         return;
157 
158     pConf->SetPath ( _T( "/PlugIns/GRIB" ) );
159 	//Overlay general parameter
160 	pConf->Read ( _T ( "OverlayTransparency" ), &m_iOverlayTransparency, 220);
161 	//Playback Options
162     pConf->Read ( _T ( "LoopMode" ), &m_bLoopMode, false );
163     pConf->Read ( _T ( "LoopStartPoint" ), &m_LoopStartPoint, 0 );
164     pConf->Read ( _T ( "SlicesPerUpdate" ), &m_SlicesPerUpdate, 5);
165     pConf->Read ( _T ( "UpdatesPerSecond" ), &m_UpdatesPerSecond, 4);
166 	pConf->Read ( _T ( "Interpolate" ), &m_bInterpolate, false );
167 	//gui options
168     m_iCtrlandDataStyle = m_DialogStyle;
169     wxString s1, s2;
170     wxString const dflt = _T( "XXXXXXXXX" );
171     pConf->Read ( _T( "CtrlBarCtrlVisibility1" ), &s1, dflt );
172     if(s1.Len() != dflt.Len() )
173         s1 = dflt;
174     pConf->Read ( _T( "CtrlBarCtrlVisibility2" ), &s2, dflt );
175     if(s2.Len() != dflt.Len() )
176         s2 = dflt;
177     m_iCtrlBarCtrlVisible[0] = s1;
178     m_iCtrlBarCtrlVisible[1] = s2;
179 	//data options
180     for(int i=0; i<SETTINGS_COUNT; i++) {
181         wxString Name=name_from_index[i];
182 
183         int units;
184         pConf->Read ( Name + _T ( "Units" ), &units,0);
185         int j;
186         for( j=0; !unit_names[unittype[i]][j].empty(); j++);
187         Settings[i].m_Units = ( units < 0 || units > j - 1 ) ? (SettingsType) 0 : (SettingsType)units;
188 
189         pConf->Read ( Name + _T ( "BarbedArrows" ), &Settings[i].m_bBarbedArrows, i==WIND);
190         pConf->Read ( Name + _T ( "BarbedVisibility" ), &Settings[i].m_iBarbedVisibility, i==WIND);
191         pConf->Read ( Name + _T ( "BarbedColors" ), &Settings[i].m_iBarbedColour, 0);
192         pConf->Read ( Name + _T ( "BarbedArrowFixedSpacing" ), &Settings[i].m_bBarbArrFixSpac, 0);
193         pConf->Read ( Name + _T ( "BarbedArrowSpacing" ), &Settings[i].m_iBarbArrSpacing, 50);
194 
195         pConf->Read ( Name + _T ( "Display Isobars" ), &Settings[i].m_bIsoBars, i==PRESSURE);
196         pConf->Read ( Name + _T ( "Abbreviated Isobars Numbers" ), &Settings[i].m_bAbbrIsoBarsNumbers, i==PRESSURE);
197 
198         double defspacing[SETTINGS_COUNT] = {4, 4, 4, 0, 0, 0, 0, 2, 2, 100};
199         pConf->Read ( Name + _T ( "IsoBarSpacing" ), &Settings[i].m_iIsoBarSpacing, defspacing[i]);
200         pConf->Read ( Name + _T ( "IsoBarVisibility" ), &Settings[i].m_iIsoBarVisibility, i==PRESSURE);
201 
202         pConf->Read ( Name + _T ( "DirectionArrows" ), &Settings[i].m_bDirectionArrows, i==CURRENT || i==WAVE);
203         double defform[SETTINGS_COUNT] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0};
204         pConf->Read ( Name + _T ( "DirectionArrowForm" ), &Settings[i].m_iDirectionArrowForm, defform[i]);
205         pConf->Read ( Name + _T ( "DirectionArrowSize" ), &Settings[i].m_iDirectionArrowSize, 0);
206         pConf->Read ( Name + _T ( "DirectionArrowFixedSpacing" ), &Settings[i].m_bDirArrFixSpac, 0);
207         pConf->Read ( Name + _T ( "DirectionArrowSpacing" ), &Settings[i].m_iDirArrSpacing, 50);
208 
209         pConf->Read ( Name + _T ( "OverlayMap" ), &Settings[i].m_bOverlayMap, i!=WIND && i!=PRESSURE);
210         int defcolor[SETTINGS_COUNT] = {1, 1, 0, 0, 6, 4, 5, 2, 3, 7};
211         pConf->Read ( Name + _T ( "OverlayMapColors" ), &Settings[i].m_iOverlayMapColors, defcolor[i]);
212 
213         pConf->Read ( Name + _T ( "Numbers" ), &Settings[i].m_bNumbers, false);
214 		pConf->Read ( Name + _T ( "NumbersFixedSpacing" ), &Settings[i].m_bNumFixSpac, 0);
215         pConf->Read ( Name + _T ( "NumbersSpacing" ), &Settings[i].m_iNumbersSpacing, 50);
216 
217         pConf->Read ( Name + _T ( "Particles" ), &Settings[i].m_bParticles, false);
218         pConf->Read ( Name + _T ( "ParticleDensity" ), &Settings[i].m_dParticleDensity, 1.0);
219     }
220 }
221 
Write()222 void GribOverlaySettings::Write()
223 {
224     /* save settings here */
225     wxFileConfig *pConf = GetOCPNConfigObject();
226 
227     if(!pConf)
228         return;
229 
230     pConf->SetPath ( _T( "/PlugIns/GRIB" ) );
231 	//Overlay general parameter
232     pConf->Write ( _T ( "OverlayTransparency" ), m_iOverlayTransparency);
233 	//playback options
234     pConf->Write ( _T ( "Interpolate" ), m_bInterpolate);
235     pConf->Write ( _T ( "LoopMode" ), m_bLoopMode );
236     pConf->Write ( _T ( "LoopStartPoint" ), m_LoopStartPoint);
237     pConf->Write ( _T ( "SlicesPerUpdate" ), m_SlicesPerUpdate);
238     pConf->Write ( _T ( "UpdatesPerSecond" ), m_UpdatesPerSecond);
239 	//gui options
240 	pConf->Write( _T ( "GribCursorDataDisplayStyle" ), m_iCtrlandDataStyle );
241     wxString s1 = m_iCtrlBarCtrlVisible[0], s2 = m_iCtrlBarCtrlVisible[1];
242     pConf->Write( _T ( "CtrlBarCtrlVisibility1" ), s1 );
243     pConf->Write( _T ( "CtrlBarCtrlVisibility2" ), s2 );
244 
245     for(int i=0; i<SETTINGS_COUNT; i++) {
246 
247         pConf->Write ( name_from_index[i] + _T ( "Units" ), (int)Settings[i].m_Units);
248 
249         if(i == WIND){
250             SaveSettingGroups(pConf, i, B_ARROWS);
251             SaveSettingGroups(pConf, i, ISO_LINE_SHORT);
252             SaveSettingGroups(pConf, i, OVERLAY);
253             SaveSettingGroups(pConf, i, NUMBERS);
254             SaveSettingGroups(pConf, i, PARTICLES);
255         }
256         else if(i == WIND_GUST || i == AIR_TEMPERATURE || i == SEA_TEMPERATURE || i == CAPE || i == COMP_REFL) {
257             SaveSettingGroups(pConf, i, ISO_LINE_SHORT);
258             SaveSettingGroups(pConf, i, OVERLAY);
259             SaveSettingGroups(pConf, i, NUMBERS);
260         }
261         else if(i == PRESSURE) {
262             SaveSettingGroups(pConf, i, ISO_LINE_SHORT);
263             SaveSettingGroups(pConf, i, ISO_LINE_VISI);
264             SaveSettingGroups(pConf, i, NUMBERS);
265         }
266         else if(i == WAVE || i == CURRENT) {
267             SaveSettingGroups(pConf, i, D_ARROWS);
268             SaveSettingGroups(pConf, i, OVERLAY);
269             SaveSettingGroups(pConf, i, NUMBERS);
270             SaveSettingGroups(pConf, i, PARTICLES);
271         }
272         else if( i == PRECIPITATION || i == CLOUD) {
273             SaveSettingGroups(pConf, i, OVERLAY);
274             SaveSettingGroups(pConf, i, NUMBERS);
275         }
276     }
277 
278 }
279 
SaveSettingGroups(wxFileConfig * pConf,int settings,int group)280 void GribOverlaySettings::SaveSettingGroups(wxFileConfig *pConf, int settings, int group)
281 {
282     wxString Name=name_from_index[settings];
283 
284     switch(group) {
285     case B_ARROWS:
286         pConf->Write ( Name + _T ( "BarbedArrows" ), Settings[settings].m_bBarbedArrows);
287         pConf->Write ( Name + _T ( "BarbedVisibility" ), Settings[settings].m_iBarbedVisibility);
288         pConf->Write ( Name + _T ( "BarbedColors" ), Settings[settings].m_iBarbedColour);
289         pConf->Write ( Name + _T ( "BarbedArrowFixedSpacing" ), Settings[settings].m_bBarbArrFixSpac);
290         pConf->Write ( Name + _T ( "BarbedArrowSpacing" ), Settings[settings].m_iBarbArrSpacing);
291         break;
292     case ISO_LINE_SHORT:
293         pConf->Write ( Name + _T ( "Display Isobars" ), Settings[settings].m_bIsoBars);
294         pConf->Write ( Name + _T ( "Abbreviated Isobars Numbers" ), Settings[settings].m_bAbbrIsoBarsNumbers);
295         pConf->Write ( Name + _T ( "IsoBarSpacing" ), Settings[settings].m_iIsoBarSpacing);
296         break;
297     case ISO_LINE_VISI:
298         pConf->Write ( Name + _T ( "IsoBarVisibility" ), Settings[settings].m_iIsoBarVisibility);
299         break;
300     case D_ARROWS:
301         pConf->Write ( Name + _T ( "DirectionArrows" ), Settings[settings].m_bDirectionArrows);
302         pConf->Write ( Name + _T ( "DirectionArrowForm" ), Settings[settings].m_iDirectionArrowForm);
303         pConf->Write ( Name + _T ( "DirectionArrowSize" ), Settings[settings].m_iDirectionArrowSize);
304         pConf->Write ( Name + _T ( "DirectionArrowFixedSpacing" ), Settings[settings].m_bDirArrFixSpac);
305         pConf->Write ( Name + _T ( "DirectionArrowSpacing" ), Settings[settings].m_iDirArrSpacing);
306         break;
307     case OVERLAY:
308         pConf->Write ( Name + _T ( "OverlayMap" ), Settings[settings].m_bOverlayMap);
309         pConf->Write ( Name + _T ( "OverlayMapColors" ), Settings[settings].m_iOverlayMapColors);
310         break;
311     case NUMBERS:
312         pConf->Write ( Name + _T ( "Numbers" ), Settings[settings].m_bNumbers);
313 		pConf->Write ( Name + _T ( "NumbersFixedSpacing" ), Settings[settings].m_bNumFixSpac);
314         pConf->Write ( Name + _T ( "NumbersSpacing" ), Settings[settings].m_iNumbersSpacing);
315         break;
316     case PARTICLES:
317         pConf->Write ( Name + _T ( "Particles" ), Settings[settings].m_bParticles);
318         pConf->Write ( Name + _T ( "ParticleDensity" ), Settings[settings].m_dParticleDensity);
319         break;
320     }
321 }
322 
CalibrationOffset(int settings)323 double GribOverlaySettings::CalibrationOffset(int settings)
324 {
325     switch(unittype[settings]) {
326     case 3: switch(Settings[settings].m_Units) { /* only have offset for temperature */
327         case CELCIUS:    return -273.15;
328         case FAHRENHEIT: return -273.15 + 32*5/9.0;
329         } break;
330     }
331 
332     return 0;
333 }
334 
CalibrationFactor(int settings,double input,bool reverse)335 double GribOverlaySettings::CalibrationFactor(int settings, double input, bool reverse)
336 {
337     switch(unittype[settings]) {
338     case 7:
339     case 0: switch(Settings[settings].m_Units) {
340         case KNOTS:  return 3.6 / 1.852;
341         case M_S:    return 1;
342         case MPH:    return 3.6 / 1.60934;
343         case KPH:    return 3.6;
344         case BFS:    return (reverse) ? GetbftomsFactor(input) : GetmstobfFactor(input);
345         } break;
346     case 1: switch(Settings[settings].m_Units) {
347         case MILLIBARS: return 1 / 100.;
348         case MMHG: return 1 / (100. * 1.333);
349         case INHG: return 1 / (100. * 33.864);
350         } break;
351     case 2: switch(Settings[settings].m_Units) {
352         case METERS: return 1;
353         case FEET:   return 3.28;
354         } break;
355     case 3: switch(Settings[settings].m_Units) {
356         case CELCIUS:     return 1;
357         case FAHRENHEIT: return 9./5;
358         } break;
359     case 4: switch(Settings[settings].m_Units) {
360         case MILLIMETERS: return 1;
361         case INCHES:      return 1./25.4;
362         } break;
363     case 5:
364     case 6:
365     case 8: return 1;
366     }
367 
368     return 1;
369 }
370 
371 /*
372 Beaufort scale
373     force             in knots   in m/s         in knots
374     0                   < 1        <0.5             < 1
375     1         from      1         0.5       to      3
376     2                   4         2.1               6
377     3                   7         3.6               10
378     4                   11        5.7               16
379     5                   17        8.7               21
380     6                   22        11.3              27
381     7                   28        14.4              33
382     8                   34        17.5              40
383     9                   41        21.1              47
384     10                  48        24.7              55
385     11                  56        28.8              63
386     12                   >= 64     >= 32.9           >= 64
387 */
388 
GetmstobfFactor(double input)389 double GribOverlaySettings::GetmstobfFactor(double input)
390 {
391     double val = fabs(input);
392     //find bf value ( m/s ) and return the corresponding factor
393     if(val < 0.5 ) return 0;
394     if(val < 2.1 ) return 1/input;
395     if(val < 3.6 ) return 2/input;
396     if(val < 5.7 ) return 3/input;
397     if(val < 8.7 ) return 4/input;
398     if(val < 11.3 ) return 5/input;
399     if(val < 14.4 ) return 6/input;
400     if(val < 17.5 ) return 7/input;
401     if(val < 21.1 ) return 8/input;
402     if(val < 24.7 ) return 9/input;
403     if(val < 28.8 ) return 10/input;
404     if(val < 32.9 ) return 11/input;
405     return 12/input;
406 }
407 
GetbftomsFactor(double input)408 double GribOverlaySettings::GetbftomsFactor(double input)
409 {
410     //find the limit value in m/s in Beaufort scale and return the corresponding factor
411     switch((int) input) {
412     case 1:  return input/0.5;
413     case 2:  return input/2.1;
414     case 3:  return input/3.6;
415     case 4:  return input/5.7;
416     case 5:  return input/8.7;
417     case 6:  return input/11.3;
418     case 7:  return input/14.4;
419     case 8:  return input/17.5;
420     case 9:  return input/21.1;
421     case 10: return input/24.7;
422     case 11: return input/28.7;
423     case 12: return input/32.9;
424     }
425     return 1;
426 }
427 
GetUnitSymbol(int settings)428 wxString GribOverlaySettings::GetUnitSymbol(int settings)
429 {
430     switch(unittype[settings]) {
431     case 0: switch(Settings[settings].m_Units) {
432         case KNOTS:  return _T("kts");
433         case M_S:    return _T("m/s");
434         case MPH:    return _T("mph");
435         case KPH:    return _T("km/h");
436         case BFS:    return _T("bf");
437         } break;
438     case 1: switch(Settings[settings].m_Units) {
439         case MILLIBARS: return _T("hPa");
440         case MMHG: return _T("mmHg");
441         case INHG: return _T("inHg");
442         } break;
443     case 2: switch(Settings[settings].m_Units) {
444         case METERS: return _T("m");
445         case FEET:   return _T("ft");
446         } break;
447     case 3: switch(Settings[settings].m_Units) {
448         case CELCIUS:     return _T("\u00B0C");
449         case FAHRENHEIT: return _T("\u00B0F");
450         } break;
451     case 4: switch(Settings[settings].m_Units) {
452         case MILLIMETERS: return _T("mm");
453         case INCHES:      return _T("in");
454         } break;
455     case 5: switch(Settings[settings].m_Units) {
456         case PERCENTAGE:  return _T("%");
457         } break;
458     case 6: switch(Settings[settings].m_Units) {
459         case JPKG:  return _T("j/kg");
460         } break;
461     case 7: switch(Settings[settings].m_Units) {
462         case KNOTS:  return _T("kts");
463         case M_S:    return _T("m/s");
464         case MPH:    return _T("mph");
465         case KPH:    return _T("km/h");
466         } break;
467     case 8: switch(Settings[settings].m_Units) {
468         case DBZ:  return _T("dBZ");
469         } break;
470     }
471     return _T("");
472 }
473 
GetMin(int settings)474 double GribOverlaySettings::GetMin(int settings)
475 {
476     double min = 0;
477     switch(settings) {
478     case PRESSURE:        min = 84000;   break; /* 100's of millibars */
479     case AIR_TEMPERATURE: min = 273.15-40; break; /* kelvin */
480     case SEA_TEMPERATURE: min = 273.15-40;  break; /* kelvin */
481     }
482     return CalibrateValue(settings, min);
483 }
484 
GetMax(int settings)485 double GribOverlaySettings::GetMax(int settings)
486 {
487     double max = 0;
488     switch(settings) {
489     case WIND:            max = 40;     break; /* m/s */
490     case WIND_GUST:       max = 40;     break; /* m/s */
491     case PRESSURE:        max = 112000;  break; /* 100s of millibars */
492     case WAVE:            max = 30;      break; /* meters */
493     case CURRENT:         max = 12;      break; /* m/s */
494     case PRECIPITATION:   max = 80;      break; /* mm */
495     case CLOUD:           max = 100;     break; /* percent */
496     case AIR_TEMPERATURE: max = 273.15+50;  break; /* kelvin */
497     case SEA_TEMPERATURE: max = 273.15+50;  break; /* kelvin */
498     case CAPE:            max = 3500;    break; /* j/kg */
499     case COMP_REFL:       max = 80;    break; /* dBZ */
500     }
501     return CalibrateValue(settings, max);
502 }
503 
GribSettingsDialog(GRIBUICtrlBar & parent,GribOverlaySettings & Settings,int & lastdatatype,int fileIntervalIndex)504 GribSettingsDialog::GribSettingsDialog(GRIBUICtrlBar &parent, GribOverlaySettings &Settings, int &lastdatatype, int fileIntervalIndex)
505     : GribSettingsDialogBase(&parent),
506       m_parent(parent), m_extSettings(Settings), m_lastdatatype(lastdatatype)
507 {
508     m_Settings = m_extSettings;
509     //populate interval choice
510     m_sSlicesPerUpdate->Clear();
511     for( int i=0; i < fileIntervalIndex + 1; i++){
512         int mn = m_Settings.GetMinFromIndex(i);
513         m_sSlicesPerUpdate->Append(wxString::Format(_T("%2d "), mn / 60) + _("h") + wxString::Format(_T(" %.2d "), mn % 60) + _("mn"));
514     }
515     //Set Bitmap
516 	m_biAltitude->SetBitmap(parent.GetScaledBitmap(wxBitmap(altitude), _T("altitude"), parent.m_ScaledFactor));
517 	m_biNow->SetBitmap(parent.GetScaledBitmap(wxBitmap(now), _T("now"), parent.m_ScaledFactor));
518 	m_biZoomToCenter->SetBitmap(parent.GetScaledBitmap(wxBitmap(zoomto), _T("zoomto"), parent.m_ScaledFactor));
519 	m_biShowCursorData->SetBitmap(parent.GetScaledBitmap(parent.m_CDataIsShown ? wxBitmap(curdata) : wxBitmap(ncurdata),
520 		parent.m_CDataIsShown ? _T("curdata") : _T("ncurdata"), parent.m_ScaledFactor));
521 	m_biPlay->SetBitmap(parent.GetScaledBitmap(wxBitmap(play), _T("play"), parent.m_ScaledFactor));
522 	m_biTimeSlider->SetBitmap(parent.GetScaledBitmap(wxBitmap(slider), _T("slider"), parent.m_ScaledFactor));
523 	m_biOpenFile->SetBitmap(parent.GetScaledBitmap(wxBitmap(openfile), _T("openfile"), parent.m_ScaledFactor));
524 	m_biSettings->SetBitmap(parent.GetScaledBitmap(wxBitmap(setting), _T("setting"), parent.m_ScaledFactor));
525 	m_biRequest->SetBitmap(parent.GetScaledBitmap(wxBitmap(request), _T("request"), parent.m_ScaledFactor));
526 	//read bookpage
527 	wxFileConfig *pConf = GetOCPNConfigObject();
528      if(pConf) {
529         pConf->SetPath ( _T ( "/Settings/GRIB" ) );
530         pConf->Read( _T ( "GribSettingsBookPageIndex" ), &m_SetBookpageIndex, 0 );
531 	 }
532 
533     m_cInterpolate->SetValue(m_Settings.m_bInterpolate);
534     m_cLoopMode->SetValue(m_Settings.m_bLoopMode);
535     m_cLoopStartPoint->SetSelection(m_Settings.m_LoopStartPoint);
536     m_sSlicesPerUpdate->SetSelection(m_Settings.m_SlicesPerUpdate);
537     m_sUpdatesPerSecond->SetValue(m_Settings.m_UpdatesPerSecond);
538     m_sTransparency->SetValue(100. - ((float) m_Settings.m_iOverlayTransparency * 100. / 254.));
539     if(!m_cInterpolate->IsChecked() ) {              //eventually disable parameters
540         m_tSlicesPerUpdate->Disable();
541         m_sSlicesPerUpdate->Disable();
542     }
543     if( !m_cLoopMode->IsChecked() ) {
544         m_staticText26->Disable();
545         m_cLoopStartPoint->Disable();
546     }
547 
548 	m_rbCurDataAttaWCap->SetValue( m_Settings.m_iCtrlandDataStyle == 0 );
549     m_rbCurDataAttaWoCap->SetValue( m_Settings.m_iCtrlandDataStyle == 1 );
550 	m_rbCurDataIsolHoriz->SetValue( m_Settings.m_iCtrlandDataStyle == 2 );
551 	m_rbCurDataIsolVertic->SetValue( m_Settings.m_iCtrlandDataStyle == 3 );
552 
553     for( unsigned int i = 0; i < (m_Settings.m_iCtrlBarCtrlVisible[0].Len() * 2) ; i += 2 ) {
554         ((wxCheckBox*) FindWindow( i + AC0 ) )->SetValue( m_Settings.m_iCtrlBarCtrlVisible[0].GetChar(i / 2) == _T('X') );
555         ((wxCheckBox*) FindWindow( i + 1 + AC0 ) )->SetValue( m_Settings.m_iCtrlBarCtrlVisible[1].GetChar(i / 2) == _T('X') );
556     }
557 
558     m_cDataType->Clear();
559     for(int i=0; i<GribOverlaySettings::SETTINGS_COUNT; i++)
560         m_cDataType->Append( wxGetTranslation(tname_from_index[i]) );
561 
562     m_cDataType->SetSelection(m_lastdatatype);
563     PopulateUnits(m_lastdatatype);
564     ReadDataTypeSettings(m_lastdatatype);
565     m_sButtonApply->SetLabel(_("Apply"));
566 
567     DimeWindow( this );                             //aplly global colours scheme
568 
569 #ifdef __OCPN__ANDROID__
570     GetHandle()->setStyleSheet( qtStyleSheet);
571 #endif
572 
573     Fit();
574 }
575 
SaveLastPage()576 void GribSettingsDialog::SaveLastPage()
577 {
578 	wxFileConfig *pConf = GetOCPNConfigObject();
579 
580      if(pConf) {
581         pConf->SetPath ( _T ( "/Settings/GRIB" ) );
582 
583         pConf->Write( _T ( "GribSettingsBookPageIndex" ), m_SetBookpageIndex );
584 	 }
585 }
586 
OnPageChange(wxNotebookEvent & event)587 void GribSettingsDialog::OnPageChange( wxNotebookEvent& event )
588 {
589 	m_SetBookpageIndex = event.GetSelection();
590     SetSettingsDialogSize();
591 }
592 
SetSettingsDialogSize()593 void GribSettingsDialog::SetSettingsDialogSize()
594 {
595 #ifdef __OCPN__ANDROID__
596     /*Sizing do not work with wxScolledWindow so we need to compute it
597     using fixed X/Y margin to try to center nicely the dialog in the screen*/
598 	int wt,ht,w,h;
599         ::wxDisplaySize( &wt, &ht);                                                         // the screen size
600 
601 	int XMargin = 100, YMargin = 200;													//set margins
602 	w = wt - XMargin;																	//maximum scolled window size
603     h = ht - ( m_sButton->GetSize().GetY() + YMargin );
604 	wxSize scroll(0, 0);
605 #else
606     /*Sizing do not work with wxScolledWindow so we need to compute it*/
607 
608     wxWindow *frame = wxTheApp->GetTopWindow();
609 
610     int w = frame->GetClientSize().x;           // the display size
611     int h = frame->GetClientSize().y;
612     int dMargin = 80;                          //set a margin
613 	w -= dMargin;								//width available for the scrolled window
614     h -= (2 * m_sButton->GetSize().GetY()) + dMargin; //height available for the scrolled window
615                                                       //two times the button's height to handle pages tab's height
616 #endif
617 #ifdef __WXGTK__
618     SetMinSize( wxSize( 0, 0 ) );
619 #endif
620 	for( size_t i = 0; i < m_nSettingsBook->GetPageCount(); i++ ) {						//compute and set scrolled windows size
621 		wxScrolledWindow *sc = ((wxScrolledWindow*) m_nSettingsBook->GetPage( i ));
622 		sc->SetMinSize( wxSize( 0, 0 ) );
623 		wxSize scr;
624 		if( (int)i == m_SetBookpageIndex ) {
625             switch( i ) {
626                 case 0:
627                     scr = m_fgSetDataSizer->Fit( sc ); break;
628                 case 1:
629                     //set a reasonable speed slider's width
630                     m_sUpdatesPerSecond->SetMinSize( wxSize( m_cLoopStartPoint->GetSize().x, -1) );
631                     scr = m_fgSetPlaybackSizer->Fit( sc );
632                     break;
633                 case 2:
634                     scr = m_fgSetGuiSizer->Fit( sc );
635             }
636             sc->SetMinSize( wxSize(wxMin( scr.x, w ), wxMin( scr.y, h )) );
637 #if defined __WXMSW__ || defined ( __WXOSX__ )
638             sc->Show();
639 #endif
640         }
641     } // end compute
642 
643 #ifdef __OCPN__ANDROID__
644 	m_nSettingsBook->SetSize( wt, -1);
645 #endif
646 
647 	Layout();
648     Fit();
649 #ifdef __WXGTK__
650     wxSize sd = GetSize();
651     if( sd.y == GetClientSize().y ) sd.y += 30;
652     SetSize( wxSize( sd.x, sd.y ) );
653     SetMinSize( wxSize( sd.x, sd.y ) );
654 #endif
655 	Refresh();
656 }
657 
658 /* set settings to the dialog controls */
WriteSettings()659 void GribSettingsDialog::WriteSettings()
660 {
661     m_Settings.m_bInterpolate = m_cInterpolate->GetValue();
662     m_Settings.m_bLoopMode = m_cLoopMode->GetValue();
663     m_Settings.m_LoopStartPoint = m_cLoopStartPoint->GetSelection();
664     m_Settings.m_SlicesPerUpdate = m_sSlicesPerUpdate->GetCurrentSelection();
665     m_Settings.m_UpdatesPerSecond = m_sUpdatesPerSecond->GetValue();
666 
667 	m_Settings.m_iCtrlandDataStyle = m_rbCurDataAttaWCap->GetValue() ? ATTACHED_HAS_CAPTION
668         : m_rbCurDataAttaWoCap->GetValue() ? ATTACHED_NO_CAPTION
669         : m_rbCurDataIsolHoriz->GetValue() ? SEPARATED_HORIZONTAL : SEPARATED_VERTICAL;
670 
671     for( unsigned int i = 0; i < (m_Settings.m_iCtrlBarCtrlVisible[0].Len() * 2) ; i += 2 ) {
672         m_Settings.m_iCtrlBarCtrlVisible[0].SetChar( i / 2, ((wxCheckBox*) FindWindow(i + AC0))->GetValue() ? _T('X') : _T('.') );
673         m_Settings.m_iCtrlBarCtrlVisible[1].SetChar(i / 2, ((wxCheckBox*) FindWindow( i + 1 + AC0))->GetValue() ? _T('X') : _T('.') );
674     }
675 
676     SetDataTypeSettings(m_lastdatatype);
677 
678     m_extSettings = m_Settings;
679     m_DialogStyle = m_Settings.m_iCtrlandDataStyle;
680 }
681 
SetDataTypeSettings(int settings)682 void GribSettingsDialog::SetDataTypeSettings(int settings)
683 {
684     GribOverlaySettings::OverlayDataSettings &odc = m_Settings.Settings[settings];
685     odc.m_Units = m_cDataUnits->GetSelection();
686     odc.m_bBarbedArrows = m_cbBarbedArrows->GetValue();
687     odc.m_iBarbedVisibility = m_cBarbedVisibility->GetValue();
688     odc.m_iBarbedColour = m_cBarbedColours->GetSelection();
689     odc.m_bBarbArrFixSpac = m_cBarbArrFixSpac->GetValue();
690     odc.m_iBarbArrSpacing = m_sBarbArrSpacing->GetValue();
691     odc.m_bIsoBars = m_cbIsoBars->GetValue();
692     odc.m_bAbbrIsoBarsNumbers = m_cbAbbrIsoBarsNumbers->GetValue();
693     odc.m_iIsoBarVisibility = m_sIsoBarVisibility->GetValue();
694     odc.m_iIsoBarSpacing = m_sIsoBarSpacing->GetValue();
695     odc.m_bDirectionArrows = m_cbDirectionArrows->GetValue();
696     odc.m_iDirectionArrowForm = m_cDirectionArrowForm->GetSelection();
697     odc.m_iDirectionArrowSize = m_cDirectionArrowSize->GetSelection();
698     odc.m_bDirArrFixSpac = m_cDirArrFixSpac->GetValue();
699     odc.m_iDirArrSpacing = m_sDirArrSpacing->GetValue();
700     odc.m_bOverlayMap = m_cbOverlayMap->GetValue();
701     odc.m_iOverlayMapColors = m_cOverlayColors->GetSelection();
702     odc.m_bNumbers = m_cbNumbers->GetValue();
703     odc.m_bNumFixSpac = m_cNumFixSpac->GetValue();
704     odc.m_iNumbersSpacing = m_sNumbersSpacing->GetValue();
705     odc.m_bParticles = m_cbParticles->GetValue();
706     odc.m_dParticleDensity = 4.0*exp(m_sParticleDensity->GetValue() - 7.0);
707 }
708 
ReadDataTypeSettings(int settings)709 void GribSettingsDialog::ReadDataTypeSettings(int settings)
710 {
711     GribOverlaySettings::OverlayDataSettings &odc = m_Settings.Settings[settings];
712 
713     m_cDataUnits->SetSelection(odc.m_Units);
714     m_cbBarbedArrows->SetValue(odc.m_bBarbedArrows);
715     m_cBarbedVisibility->SetValue(odc.m_iBarbedVisibility);
716     m_cBarbedColours->SetSelection(odc.m_iBarbedColour);
717     m_cBarbArrFixSpac->SetValue(odc.m_bBarbArrFixSpac);
718     m_cBarbArrMinSpac->SetValue(!odc.m_bBarbArrFixSpac);
719     m_sBarbArrSpacing->SetValue(odc.m_iBarbArrSpacing);
720     m_cbIsoBars->SetValue(odc.m_bIsoBars);
721     m_cbAbbrIsoBarsNumbers->SetValue(odc.m_bAbbrIsoBarsNumbers);
722     m_sIsoBarVisibility->SetValue(odc.m_iIsoBarVisibility);
723     m_sIsoBarSpacing->SetValue(odc.m_iIsoBarSpacing);
724     m_cbDirectionArrows->SetValue(odc.m_bDirectionArrows);
725     m_cDirectionArrowForm->SetSelection(odc.m_iDirectionArrowForm);
726     m_cDirectionArrowSize->SetSelection(odc.m_iDirectionArrowSize);
727     m_cDirArrFixSpac->SetValue(odc.m_bDirArrFixSpac);
728     m_cDirArrMinSpac->SetValue(!odc.m_bDirArrFixSpac);
729     m_sDirArrSpacing->SetValue(odc.m_iDirArrSpacing);
730     m_cbOverlayMap->SetValue(odc.m_bOverlayMap);
731     m_cOverlayColors->SetSelection(odc.m_iOverlayMapColors);
732     m_cbNumbers->SetValue(odc.m_bNumbers);
733     m_cNumFixSpac->SetValue(odc.m_bNumFixSpac);
734     m_cNumMinSpac->SetValue(!odc.m_bNumFixSpac);
735     m_sNumbersSpacing->SetValue(odc.m_iNumbersSpacing);
736     m_cbParticles->SetValue(odc.m_bParticles);
737     m_sParticleDensity->SetValue(log(odc.m_dParticleDensity/4.0) + 7);
738 
739     ShowFittingSettings(settings);
740 }
741 
ShowFittingSettings(int settings)742 void GribSettingsDialog::ShowFittingSettings( int settings )
743 {
744     //Hide all Parameters
745     ShowSettings( B_ARROWS, false );
746     ShowSettings( ISO_LINE, false );
747     if(m_fIsoBarSpacing->GetItem(m_sIsoBarSpacing) != NULL)  m_fIsoBarSpacing->Detach(m_sIsoBarSpacing);
748     if(m_fIsoBarVisibility->GetItem(m_sIsoBarSpacing) != NULL)  m_fIsoBarVisibility->Detach(m_sIsoBarSpacing);
749     if(m_fIsoBarVisibility->GetItem(m_sIsoBarVisibility) != NULL)  m_fIsoBarVisibility->Detach(m_sIsoBarVisibility);
750     ShowSettings( ISO_ABBR, false );
751     ShowSettings( D_ARROWS, false  );
752     ShowSettings( OVERLAY, false  );
753     ShowSettings( NUMBERS, false );
754     ShowSettings( PARTICLES, false );
755     this->Fit();
756     //Show only fitting parameters
757     switch(settings){
758     case GribOverlaySettings::WIND:
759         ShowSettings( ISO_LINE_SHORT );
760         ShowSettings( ISO_LINE );
761         m_cbIsoBars->SetLabel(_("Display Isotachs"));
762         ShowSettings( B_ARROWS );
763         ShowSettings( OVERLAY );
764         ShowSettings( NUMBERS );
765         ShowSettings( PARTICLES );
766         break;
767     case GribOverlaySettings::WIND_GUST:
768         ShowSettings( ISO_LINE_SHORT );
769         ShowSettings( ISO_LINE );
770         m_cbIsoBars->SetLabel(_("Display Isotachs"));
771         ShowSettings( OVERLAY );
772         ShowSettings( NUMBERS );
773         break;
774     case GribOverlaySettings::PRESSURE:
775         ShowSettings( ISO_LINE_VISI );
776         ShowSettings( ISO_LINE );
777         m_cbIsoBars->SetLabel(_("Display Isobars"));
778         ShowSettings( ISO_ABBR );
779         ShowSettings( NUMBERS );
780         break;
781     case GribOverlaySettings::CURRENT:
782         ShowSettings( PARTICLES ); // should we allow particles for waves?
783     case GribOverlaySettings::WAVE:
784         ShowSettings( D_ARROWS );
785         ShowSettings( OVERLAY );
786         ShowSettings( NUMBERS );
787         break;
788     case GribOverlaySettings::PRECIPITATION:
789     case GribOverlaySettings::CLOUD:
790         ShowSettings( OVERLAY );
791         ShowSettings( NUMBERS );
792         break;
793     case GribOverlaySettings::AIR_TEMPERATURE:
794     case GribOverlaySettings::SEA_TEMPERATURE:
795         ShowSettings( ISO_LINE_SHORT );
796         ShowSettings( ISO_LINE );
797         m_cbIsoBars->SetLabel(_("Display Isotherms"));
798         ShowSettings( OVERLAY );
799         ShowSettings( NUMBERS );
800         break;
801     case GribOverlaySettings::CAPE:
802         ShowSettings( ISO_LINE_SHORT );
803         ShowSettings( ISO_LINE );
804         m_cbIsoBars->SetLabel(_("Display Iso CAPE"));
805         ShowSettings( OVERLAY );
806         ShowSettings( NUMBERS );
807         break;
808     case GribOverlaySettings::COMP_REFL:
809         ShowSettings( ISO_LINE_SHORT );
810         ShowSettings( ISO_LINE );
811         m_cbIsoBars->SetLabel(_("Display Comp. Reflectivity"));
812         ShowSettings( OVERLAY );
813         ShowSettings( NUMBERS );
814         break;
815     }
816 
817 	wxString l = (m_lastdatatype == GribOverlaySettings::PRESSURE && m_cDataUnits->GetSelection() == GribOverlaySettings::INHG) ? _T("(0.03 " ) : _T("(");
818 	m_tIsoBarSpacing->SetLabel( wxString(_("Spacing")).Append(l).Append(m_Settings.GetUnitSymbol( m_lastdatatype ) ).Append( _T(")") ) );
819 }
820 
ShowSettings(int params,bool show)821 void GribSettingsDialog::ShowSettings( int params, bool show)
822 {
823     switch(params){
824     case B_ARROWS:
825         m_cbBarbedArrows->Show(show);
826         m_fgBarbedData1->ShowItems( show );
827         m_fgBarbedData2->ShowItems( show );
828         break;
829     case ISO_LINE:
830         m_cbIsoBars->Show(show);
831         m_fIsoBarSpacing->ShowItems(show);
832         m_fIsoBarVisibility->ShowItems(show);
833         break;
834     case ISO_ABBR:
835         m_cbAbbrIsoBarsNumbers->Show(show);
836         break;
837     case ISO_LINE_VISI:
838         m_fIsoBarSpacing->Add(m_sIsoBarSpacing, 0, 5,wxALL|wxEXPAND);
839         m_fIsoBarVisibility->Add(m_sIsoBarVisibility, 0, 5,wxTOP|wxLEFT|wxEXPAND);
840        // m_sIsoBarSpacing->SetMinSize(wxSize(70, -1));
841         break;
842     case ISO_LINE_SHORT:
843         m_fIsoBarVisibility->Add(m_sIsoBarSpacing, 0, 5,wxTOP|wxLEFT|wxEXPAND);
844       //  m_sIsoBarSpacing->SetMinSize(wxSize(-1, -1));
845         break;
846     case D_ARROWS:
847         m_cbDirectionArrows->Show(show);
848         m_fgDirArrData1->ShowItems( show );
849         m_fgDirArrData2->ShowItems( show );
850         break;
851     case OVERLAY:
852         m_cbOverlayMap->Show(show);
853         m_tOverlayColors->Show(show);
854         m_cOverlayColors->Show(show);
855         break;
856     case NUMBERS:
857         m_cbNumbers->Show(show);
858         m_fgNumData1->ShowItems( show );
859         m_sNumbersSpacing->Show(show);
860         break;
861     case PARTICLES:
862         m_cbParticles->Show(show);
863         m_ctParticles->Show(show);
864         m_sParticleDensity->Show(show);
865         break;
866     }
867 }
868 
PopulateUnits(int settings)869 void GribSettingsDialog::PopulateUnits(int settings)
870 {
871     m_cDataUnits->Clear();
872     for(int i=0; !unit_names[unittype[m_lastdatatype]][i].empty(); i++)
873         m_cDataUnits->Append( wxGetTranslation((unit_names[unittype[m_lastdatatype]][i])));
874 }
875 
OnDataTypeChoice(wxCommandEvent & event)876 void GribSettingsDialog::OnDataTypeChoice( wxCommandEvent& event )
877 {
878     SetDataTypeSettings(m_lastdatatype);
879     m_lastdatatype = m_cDataType->GetSelection();
880     PopulateUnits(m_lastdatatype);
881     ReadDataTypeSettings(m_lastdatatype);
882     SetSettingsDialogSize();
883 }
884 
OnUnitChange(wxCommandEvent & event)885 void GribSettingsDialog::OnUnitChange( wxCommandEvent& event )
886 {
887     m_Settings.Settings[m_lastdatatype].m_Units = m_cDataUnits->GetSelection();
888     wxString l = (m_lastdatatype == GribOverlaySettings::PRESSURE && m_cDataUnits->GetSelection() == GribOverlaySettings::INHG) ? _T("(0.03 " ) : _T("(");
889     m_tIsoBarSpacing->SetLabel( wxString(_("Spacing")).Append(l).Append(m_Settings.GetUnitSymbol( m_lastdatatype ) ).Append( _T(")") ) );
890     SetSettingsDialogSize();
891 }
892 
OnTransparencyChange(wxScrollEvent & event)893 void GribSettingsDialog::OnTransparencyChange( wxScrollEvent& event  )
894 {
895     m_Settings.m_iOverlayTransparency = 254. - ( (long) m_sTransparency->GetValue() * 254. / 100. );
896     m_extSettings.m_iOverlayTransparency = m_Settings.m_iOverlayTransparency;
897     m_parent.SetFactoryOptions();
898 }
899 
OnCtrlandDataStyleChanged(wxCommandEvent & event)900 void GribSettingsDialog::OnCtrlandDataStyleChanged( wxCommandEvent& event )
901 {
902     wxString messages;
903     if( (m_Settings.m_iCtrlandDataStyle == 0 && !m_rbCurDataAttaWCap->GetValue()) )
904         messages.Printf( _("You want to remove the dialog title/drag bar\n") );
905     if( (m_Settings.m_iCtrlandDataStyle != 0 && m_rbCurDataAttaWCap->GetValue()) )
906         messages.Printf( _("You want to add a title/drag bar to the dialog\n") );
907     if( !messages.IsEmpty() ) {
908         m_parent.pPlugIn->m_DialogStyleChanged = true;
909         messages.Append( _("This change needs a complete reload.\nIt will be applied after closing and re-opening the plugin") );
910         OCPNMessageBox_PlugIn(this, messages );
911     }
912 }
913 
OnApply(wxCommandEvent & event)914 void GribSettingsDialog::OnApply( wxCommandEvent& event )
915 {
916     if( m_Settings.Settings[GribOverlaySettings::WIND].m_Units != m_extSettings.Settings[GribOverlaySettings::WIND].m_Units
917                 && (m_Settings.Settings[GribOverlaySettings::WIND].m_Units == GribOverlaySettings::BFS
918                 || m_extSettings.Settings[GribOverlaySettings::WIND].m_Units == GribOverlaySettings::BFS) )
919             m_parent.m_old_DialogStyle = STARTING_STATE_STYLE;                   //must recompute dialogs size
920 
921     WriteSettings();
922     m_parent.SetFactoryOptions();
923     m_parent.SetDialogsStyleSizePosition(true);
924 }
925 
OnIntepolateChange(wxCommandEvent & event)926 void GribSettingsDialog::OnIntepolateChange( wxCommandEvent& event )
927 {
928     if( m_cInterpolate->IsChecked() ) {
929         OCPNMessageBox_PlugIn(this, _("You have chosen to authorize interpolation.\nDon't forget that data displayed will not be real but recomputed\nThis can decrease accuracy!"),
930                             _("Warning!") );
931         m_tSlicesPerUpdate->Enable();
932         m_sSlicesPerUpdate->Enable();
933     } else {                                        //hide no suiting parameters
934         m_tSlicesPerUpdate->Disable();
935         m_sSlicesPerUpdate->Disable();
936     }
937     if( m_cLoopMode->IsChecked() ) {
938         m_staticText26->Enable();
939         m_cLoopStartPoint->Enable();
940     } else {
941         m_staticText26->Disable();
942         m_cLoopStartPoint->Disable();
943     }
944     Refresh();
945    // SetSettingsDialogSize();
946 }
947 
OnSpacingModeChange(wxCommandEvent & event)948 void GribSettingsDialog::OnSpacingModeChange( wxCommandEvent& event )
949 {
950     bool message = false;
951     switch( event.GetId() ) {
952     case BARBFIXSPACING:
953         m_cBarbArrMinSpac->SetValue( !m_cBarbArrFixSpac->IsChecked() );
954         if( m_cBarbArrFixSpac->IsChecked() ) message = true;
955         break;
956     case BARBMINSPACING:
957         m_cBarbArrFixSpac->SetValue( !m_cBarbArrMinSpac->IsChecked() );
958         break;
959     case DIRFIXSPACING:
960         m_cDirArrMinSpac->SetValue( !m_cDirArrFixSpac->IsChecked() );
961         if( m_cDirArrFixSpac->IsChecked() ) message = true;
962         break;
963     case DIRMINSPACING:
964         m_cDirArrFixSpac->SetValue( !m_cDirArrMinSpac->IsChecked() );
965         break;
966     case NUMFIXSPACING:
967         m_cNumMinSpac->SetValue( !m_cNumFixSpac->IsChecked() );
968         if( m_cNumFixSpac->IsChecked() ) message = true;
969         break;
970     case NUMMINSPACING:
971         m_cNumFixSpac->SetValue( !m_cNumMinSpac->IsChecked() );
972     }
973 
974     if( message ) {
975         OCPNMessageBox_PlugIn(this, _("This option imply you authorize intrepolation\nDon't forget that data displayed will not be real but recomputed\nThis can decrease accuracy!"),
976                             _("Warning!") );
977     }
978 }
979 
980 
SettingsToJSON(wxString json)981 wxString GribOverlaySettings::SettingsToJSON(wxString json)
982 {
983     wxJSONValue v(json);
984 
985     for(int i=0; i<SETTINGS_COUNT; i++) {
986 
987         wxString units; units.Printf(_T("%d"), (int)Settings[i].m_Units);
988         v[name_from_index[i] + _T ( "Units" )] = units;
989 
990         if(i == WIND){
991             UpdateJSONval(v, i, B_ARROWS);
992             UpdateJSONval(v, i, ISO_LINE_SHORT);
993             UpdateJSONval(v, i, OVERLAY);
994             UpdateJSONval(v, i, NUMBERS);
995             UpdateJSONval(v, i, PARTICLES);
996         }
997         else if(i == WIND_GUST || i == AIR_TEMPERATURE || i == SEA_TEMPERATURE || i == CAPE || i == COMP_REFL) {
998             UpdateJSONval(v, i, ISO_LINE_SHORT);
999             UpdateJSONval(v, i, OVERLAY);
1000             UpdateJSONval(v, i, NUMBERS);
1001         }
1002         else if(i == PRESSURE) {
1003             UpdateJSONval(v, i, ISO_LINE_SHORT);
1004             UpdateJSONval(v, i, ISO_LINE_VISI);
1005             UpdateJSONval(v, i, NUMBERS);
1006         }
1007         else if(i == WAVE || i == CURRENT) {
1008             UpdateJSONval(v, i, D_ARROWS);
1009             UpdateJSONval(v, i, OVERLAY);
1010             UpdateJSONval(v, i, NUMBERS);
1011             UpdateJSONval(v, i, PARTICLES);
1012         }
1013         else if( i == PRECIPITATION || i == CLOUD) {
1014             UpdateJSONval(v, i, OVERLAY);
1015             UpdateJSONval(v, i, NUMBERS);
1016         }
1017     }
1018 
1019     wxJSONWriter w;
1020     wxString out;
1021     w.Write(v, out);
1022     return out;
1023 }
1024 
UpdateJSONval(wxJSONValue & v,int settings,int group)1025 bool GribOverlaySettings::UpdateJSONval( wxJSONValue &v, int settings, int group)
1026 {
1027     wxString Name=name_from_index[settings];
1028 
1029     switch(group) {
1030     case B_ARROWS:
1031         v[ Name + _T ( "BarbedArrows" )] = Settings[settings].m_bBarbedArrows;
1032         v[ Name + _T ( "BarbedVisibility" )] = Settings[settings].m_iBarbedVisibility;
1033         v[ Name + _T ( "BarbedColors" )] = Settings[settings].m_iBarbedColour;
1034         v[ Name + _T ( "BarbedArrowFixedSpacing" )] = Settings[settings].m_bBarbArrFixSpac;
1035         v[ Name + _T ( "BarbedArrowSpacing" )] = Settings[settings].m_iBarbArrSpacing;
1036         break;
1037     case ISO_LINE_SHORT:
1038         v[ Name + _T ( "DisplayIsobars" )] = Settings[settings].m_bIsoBars;
1039         v[ Name + _T ( "IsoBarSpacing" )] = Settings[settings].m_iIsoBarSpacing;
1040         break;
1041     case ISO_ABBR:
1042         v[ Name + _T ( "AbbrIsobarsNumbers" )] = Settings[settings].m_bAbbrIsoBarsNumbers;
1043         break;
1044     case ISO_LINE_VISI:
1045         v[ Name + _T ( "IsoBarVisibility" )] = Settings[settings].m_iIsoBarVisibility;
1046         break;
1047     case D_ARROWS:
1048         v[ Name + _T ( "DirectionArrows" )] = Settings[settings].m_bDirectionArrows;
1049         v[ Name + _T ( "DirectionArrowForm" )] = Settings[settings].m_iDirectionArrowForm;
1050         v[ Name + _T ( "DirectionArrowSize" )] = Settings[settings].m_iDirectionArrowSize;
1051         v[ Name + _T ( "DirectionArrowFixedSpacing" )] = Settings[settings].m_bDirArrFixSpac;
1052         v[ Name + _T ( "DirectionArrowSpacing" )] = Settings[settings].m_iDirArrSpacing;
1053         break;
1054     case OVERLAY:
1055         v[ Name + _T ( "OverlayMap" )] = Settings[settings].m_bOverlayMap;
1056         v[ Name + _T ( "OverlayMapColors" )] = Settings[settings].m_iOverlayMapColors;
1057         break;
1058     case NUMBERS:
1059         v[ Name + _T ( "Numbers" )] = Settings[settings].m_bNumbers;
1060         v[ Name + _T ( "NumbersFixedSpacing" )] = Settings[settings].m_bNumFixSpac;
1061         v[ Name + _T ( "NumbersSpacing" )] = Settings[settings].m_iNumbersSpacing;
1062         break;
1063     case PARTICLES:
1064         v[ Name + _T ( "Particles" )] = Settings[settings].m_bParticles;
1065         v[ Name + _T ( "ParticleDensity" )] = Settings[settings].m_dParticleDensity;
1066         break;
1067     default:
1068         break;
1069     }
1070 
1071     return true;
1072 }
1073 
JSONToSettings(wxString json)1074 bool GribOverlaySettings::JSONToSettings(wxString json)
1075 {
1076     wxJSONValue  root;
1077     wxJSONReader reader;
1078 
1079     // now read the JSON text and store it in the 'root' structure
1080     // check for errors before retreiving values...
1081     int numErrors = reader.Parse( json, &root );
1082     if ( numErrors > 0 )  {
1083         return false;
1084     }
1085 
1086     //  Read all the JSON values, and populate the local settings
1087 
1088     if(root[_T ( "overlay_transparency" )].IsString()){
1089         wxString s = root[_T ( "overlay_transparency" )].AsString(); long transparency = -1; s.ToLong(&transparency);
1090         transparency = wxMax(1, transparency);
1091         transparency = wxMin(100, transparency);
1092         m_iOverlayTransparency = transparency * (double)(254. / 100.);
1093     }
1094 
1095     for(int i=0; i<SETTINGS_COUNT; i++) {
1096         wxString Name=name_from_index[i];
1097         wxString s;
1098 
1099         if(root[Name + _T ( "Units" )].IsString()){
1100             wxString s = root[Name + _T ( "Units" )].AsString(); long units = -1; s.ToLong(&units);
1101             for( int j=0; !unit_names[unittype[i]][j].empty(); j++)
1102                 Settings[i].m_Units = ( units < 0 || units > j - 1 ) ? (SettingsType) 0 : (SettingsType)units;
1103         }
1104 
1105         if(root[Name + _T ( "BarbedArrows" )].IsBool())
1106             Settings[i].m_bBarbedArrows = root[Name + _T ( "BarbedArrows" )].AsBool();
1107 
1108         if(root[Name + _T ( "BarbedVisibility" )].IsBool())
1109             Settings[i].m_iBarbedVisibility = root[Name + _T ( "BarbedVisibility" )].AsBool();
1110 
1111         if(root[Name + _T ( "BarbedColors" )].IsString()){
1112             wxString s = root[Name + _T ( "BarbedColors" )].AsString(); long val = -1; s.ToLong(&val);
1113             Settings[i].m_iBarbedColour = val;
1114         }
1115 
1116         if(root[Name + _T ( "BarbedArrowFixedSpacing" )].IsBool())
1117             Settings[i].m_bBarbArrFixSpac = root[Name + _T ( "BarbedArrowFixedSpacing" )].AsBool();
1118 
1119          if(root[Name + _T ( "BarbedArrowSpacing" )].IsString()){
1120             wxString s = root[Name + _T ( "BarbedArrowSpacing" )].AsString(); long val = -1; s.ToLong(&val);
1121             Settings[i].m_iBarbArrSpacing = val;
1122         }
1123 
1124         if(root[Name + _T ( "DisplayIsobars" )].IsBool())
1125             Settings[i].m_bIsoBars = root[Name + _T ( "DisplayIsobars" )].AsBool();
1126 
1127         if(root[Name + _T ( "IsoBarSpacing" )].IsString()){
1128             wxString s = root[Name + _T ( "IsoBarSpacing" )].AsString(); long val = -1; s.ToLong(&val);
1129             Settings[i].m_iIsoBarSpacing = val;
1130         }
1131 
1132         if(root[Name + _T ( "AbbrIsobarsNumbers" )].IsBool())
1133             Settings[i].m_bAbbrIsoBarsNumbers = root[Name + _T ( "AbbrIsobarsNumbers" )].AsBool();
1134 
1135         if(root[Name + _T ( "IsoBarVisibility" )].IsBool())
1136             Settings[i].m_iIsoBarVisibility = root[Name + _T ( "IsoBarVisibility" )].AsBool();
1137 
1138         if(root[Name + _T ( "DirectionArrows" )].IsBool())
1139             Settings[i].m_bDirectionArrows = root[Name + _T ( "DirectionArrows" )].AsBool();
1140 
1141         if(root[Name + _T ( "DirectionArrowForm" )].IsString()){
1142             wxString s = root[Name + _T ( "DirectionArrowForm" )].AsString(); long val = -1; s.ToLong(&val);
1143             Settings[i].m_iDirectionArrowForm = val;
1144         }
1145 
1146         if(root[Name + _T ( "DirectionArrowSize" )].IsString()){
1147             wxString s = root[Name + _T ( "DirectionArrowSize" )].AsString(); long val = -1; s.ToLong(&val);
1148             Settings[i].m_iDirectionArrowSize = val;
1149         }
1150 
1151         if(root[Name + _T ( "DirectionArrowFixedSpacing" )].IsBool())
1152             Settings[i].m_bDirArrFixSpac = root[Name + _T ( "DirectionArrowFixedSpacing" )].AsBool();
1153 
1154         if(root[Name + _T ( "DirectionArrowSpacing" )].IsString()){
1155             wxString s = root[Name + _T ( "DirectionArrowSpacing" )].AsString(); long val = -1; s.ToLong(&val);
1156             Settings[i].m_iDirArrSpacing = val;
1157         }
1158 
1159         if(root[Name + _T ( "OverlayMap" )].IsBool())
1160             Settings[i].m_bOverlayMap = root[Name + _T ( "OverlayMap" )].AsBool();
1161 
1162         if(root[Name + _T ( "OverlayMapColors" )].IsString()){
1163             wxString s = root[Name + _T ( "OverlayMapColors" )].AsString(); long val = -1; s.ToLong(&val);
1164             Settings[i].m_iOverlayMapColors = val;
1165         }
1166 
1167         if(root[Name + _T ( "Numbers" )].IsBool())
1168             Settings[i].m_bNumbers = root[Name + _T ( "Numbers" )].AsBool();
1169 
1170         if(root[Name + _T ( "NumbersFixedSpacing" )].IsBool())
1171             Settings[i].m_bNumFixSpac = root[Name + _T ( "NumbersFixedSpacing" )].AsBool();
1172 
1173         if(root[Name + _T ( "NumbersSpacing" )].IsString()){
1174             wxString s = root[Name + _T ( "NumbersSpacing" )].AsString(); long val = -1; s.ToLong(&val);
1175             Settings[i].m_iNumbersSpacing = val;
1176         }
1177 
1178         if(root[Name + _T ( "Particles" )].IsBool())
1179             Settings[i].m_bParticles = root[Name + _T ( "Particles" )].AsBool();
1180 
1181         if(root[Name + _T ( "ParticleDensity" )].IsString()){
1182             wxString s = root[Name + _T ( "ParticleDensity" )].AsString(); double val = -1; s.ToDouble(&val);
1183             Settings[i].m_dParticleDensity = val;
1184         }
1185 
1186     }
1187 
1188     return true;
1189 }
1190 
1191 
1192