1 /***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: Options Dialog
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25 #include <memory>
26
27 #ifdef __linux__
28 #include <unistd.h>
29 #endif
30
31 #ifdef __MINGW32__
32 #undef IPV6STRICT // mingw FTBS fix: missing struct ip_mreq
33 #include <windows.h>
34 #endif
35
36 // For compilers that support precompilation, includes "wx/wx.h".
37 #include "wx/wxprec.h"
38
39 #ifndef WX_PRECOMP
40 #include <wx/wx.h>
41 #endif
42
43 #include <wx/progdlg.h>
44 #include <wx/radiobox.h>
45 #include <wx/listbox.h>
46 #include <wx/imaglist.h>
47 #include <wx/display.h>
48 #include <wx/choice.h>
49 #include <wx/dirdlg.h>
50 #include <wx/clrpicker.h>
51 #include <wx/stdpaths.h>
52 #include "wx/tokenzr.h"
53 #include <wx/mediactrl.h>
54 #include "wx/dir.h"
55 #include "wx/odcombo.h"
56 #include <wx/statline.h>
57 #include "SignalKDataStream.h"
58
59 #if wxCHECK_VERSION(2, 9, \
60 4) /* does this work in 2.8 too.. do we need a test? */
61 #include <wx/renderer.h>
62 #endif
63 #if defined(__WXGTK__) || defined(__WXQT__)
64 #include <wx/colordlg.h>
65 #endif
66
67 #ifdef ocpnUSE_SVG
68 #include <wxSVG/svg.h>
69 #endif // ocpnUSE_SVG
70
71 #include "config.h"
72
73 #include "dychart.h"
74 #include "chart1.h"
75
76 #ifdef ocpnUSE_GL
77 #include "glChartCanvas.h"
78 extern GLuint g_raster_format;
79 #endif
80
81 #include "chartdbs.h"
82 #include "options.h"
83 #include "styles.h"
84 #include "datastream.h"
85 #include "multiplexer.h"
86 #include "FontMgr.h"
87 #include "OCPN_Sound.h"
88 #include "SoundFactory.h"
89
90 #ifndef __OCPN__ANDROID__
91 #include "SystemCmdSound.h"
92 #endif
93
94 #include "NMEALogWindow.h"
95 #include "wx28compat.h"
96 #include "routeman.h"
97 #include "chcanv.h"
98 #include "MarkInfo.h"
99
100 #include "ais.h"
101 #include "AIS_Decoder.h"
102 #include "AIS_Target_Data.h"
103
104 #include "navutil.h"
105
106 #include "s52plib.h"
107 #include "s52utils.h"
108 #include "cm93.h"
109
110 #ifdef __OCPN__ANDROID__
111 #include "androidUTIL.h"
112 #endif
113
114 #ifdef __OCPN__ANDROID__
115 #include <QtWidgets/QScroller>
116 #endif
117
118 #ifdef __WXOSX__
119 #include "DarkMode.h"
120 #endif
121
122 #include "OCPNPlatform.h"
123 #include "ConfigMgr.h"
124
125 #include "SignalKDataStream.h"
126
127 #if !defined(__WXOSX__)
128 #define SLIDER_STYLE wxSL_HORIZONTAL | wxSL_AUTOTICKS | wxSL_LABELS
129 #else
130 #define SLIDER_STYLE wxSL_HORIZONTAL | wxSL_AUTOTICKS
131 #endif
132
133 wxString GetOCPNKnownLanguage(const wxString lang_canonical,
134 wxString& lang_dir);
135 wxString GetOCPNKnownLanguage(const wxString lang_canonical);
136
137 extern OCPNPlatform* g_Platform;
138
139 extern MyFrame* gFrame;
140 extern WayPointman *pWayPointMan;
141 extern bool g_bSoftwareGL;
142 extern bool g_bShowFPS;
143
144 extern bool g_bShowOutlines;
145 extern bool g_bShowChartBar;
146 extern bool g_bShowDepthUnits;
147 extern bool g_bskew_comp;
148 extern bool g_bopengl;
149 extern bool g_bsmoothpanzoom;
150 extern bool g_bShowTrue, g_bShowMag;
151 extern double g_UserVar;
152 extern double gVar;
153 extern int g_chart_zoom_modifier;
154 extern int g_chart_zoom_modifier_vector;
155 extern int g_NMEAAPBPrecision;
156 extern wxString g_TalkerIdText;
157 extern int g_nDepthUnitDisplay;
158 extern bool g_bUIexpert;
159
160 extern wxString* pInit_Chart_Dir;
161 extern wxArrayOfConnPrm* g_pConnectionParams;
162 extern Multiplexer* g_pMUX;
163 extern bool g_bfilter_cogsog;
164 extern int g_COGFilterSec;
165 extern int g_SOGFilterSec;
166
167 extern PlugInManager* g_pi_manager;
168 extern ocpnStyle::StyleManager* g_StyleManager;
169
170 extern bool g_bDisplayGrid;
171
172 // LIVE ETA OPTION
173 extern bool g_bShowLiveETA;
174 extern double g_defaultBoatSpeed;
175 extern double g_defaultBoatSpeedUserUnit;
176
177 // AIS Global configuration
178 extern bool g_bCPAMax;
179 extern double g_CPAMax_NM;
180 extern bool g_bCPAWarn;
181 extern double g_CPAWarn_NM;
182 extern bool g_bTCPA_Max;
183 extern double g_TCPA_Max;
184 extern bool g_bMarkLost;
185 extern double g_MarkLost_Mins;
186 extern bool g_bRemoveLost;
187 extern double g_RemoveLost_Mins;
188 extern bool g_bShowCOG;
189 extern double g_ShowCOG_Mins;
190 extern bool g_bAISShowTracks;
191 extern double g_AISShowTracks_Mins;
192 extern double g_ShowMoored_Kts;
193 extern bool g_bHideMoored;
194 extern bool g_bAllowShowScaled;
195 extern int g_ShowScaled_Num;
196 extern bool g_bAIS_CPA_Alert;
197 extern bool g_bAIS_CPA_Alert_Audio;
198 extern wxString g_sAIS_Alert_Sound_File;
199 extern bool g_bAIS_CPA_Alert_Suppress_Moored;
200 extern bool g_bShowAreaNotices;
201 extern bool g_bDrawAISSize;
202 extern bool g_bDrawAISRealtime;
203 extern double g_AIS_RealtPred_Kts;
204 extern bool g_bShowAISName;
205 extern int g_Show_Target_Name_Scale;
206 extern bool g_bWplIsAprsPosition;
207
208 extern int g_iNavAidRadarRingsNumberVisible;
209 extern float g_fNavAidRadarRingsStep;
210 extern int g_pNavAidRadarRingsStepUnits;
211 extern int g_iWaypointRangeRingsNumber;
212 extern float g_fWaypointRangeRingsStep;
213 extern int g_iWaypointRangeRingsStepUnits;
214 extern wxColour g_colourWaypointRangeRingsColour;
215 extern bool g_bWayPointPreventDragging;
216 extern wxColour g_colourOwnshipRangeRingsColour;
217
218 extern bool g_own_ship_sog_cog_calc;
219 extern int g_own_ship_sog_cog_calc_damp_sec;
220
221 extern bool g_bPreserveScaleOnX;
222 extern bool g_bPlayShipsBells;
223
224 extern wxString g_CmdSoundString;
225
226 extern int g_iSoundDeviceIndex;
227 extern bool g_bFullscreenToolbar;
228 extern bool g_bTransparentToolbar;
229 extern bool g_bTransparentToolbarInOpenGLOK;
230
231 extern int g_OwnShipIconType;
232 extern double g_n_ownship_length_meters;
233 extern double g_n_ownship_beam_meters;
234 extern double g_n_gps_antenna_offset_y;
235 extern double g_n_gps_antenna_offset_x;
236 extern int g_n_ownship_min_mm;
237 extern double g_n_arrival_circle_radius;
238
239 extern bool g_bEnableZoomToCursor;
240 extern bool g_bTrackDaily;
241 extern int g_track_rotate_time;
242 extern int g_track_rotate_time_type;
243 extern bool g_bHighliteTracks;
244 extern double g_TrackDeltaDistance;
245 extern double g_TrackDeltaDistance;
246 extern int g_nTrackPrecision;
247 extern wxColour g_colourTrackLineColour;
248
249 extern int g_iSDMMFormat;
250 extern int g_iDistanceFormat;
251 extern int g_iSpeedFormat;
252
253 extern bool g_bAdvanceRouteWaypointOnArrivalOnly;
254
255 extern int g_cm93_zoom_factor;
256
257 extern int g_COGAvgSec;
258
259 extern bool g_bCourseUp;
260 extern bool g_bLookAhead;
261
262 extern double g_ownship_predictor_minutes;
263 extern double g_ownship_HDTpredictor_miles;
264
265 extern bool g_bAISRolloverShowClass;
266 extern bool g_bAISRolloverShowCOG;
267 extern bool g_bAISRolloverShowCPA;
268
269 extern bool g_bAIS_ACK_Timeout;
270 extern double g_AckTimeout_Mins;
271
272 extern bool g_bQuiltEnable;
273 extern bool g_bFullScreenQuilt;
274 extern bool g_bConfirmObjectDelete;
275 extern wxString g_GPS_Ident;
276 extern bool g_bGarminHostUpload;
277
278 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
279 extern wxLocale* plocale_def_lang;
280 #endif
281
282 extern OcpnSound* g_anchorwatch_sound;
283 extern bool g_bMagneticAPB;
284
285 extern bool g_fog_overzoom;
286 extern bool g_oz_vector_scale;
287 extern bool g_bShowStatusBar;
288
289 extern s52plib* ps52plib;
290
291 extern wxString g_locale;
292 extern bool g_bportable;
293 extern bool g_bdisable_opengl;
294
295 extern ChartGroupArray* g_pGroupArray;
296 extern ocpnStyle::StyleManager* g_StyleManager;
297
298 #ifdef ocpnUSE_GL
299 extern ocpnGLOptions g_GLOptions;
300 #endif
301
302 extern bool g_bGLexpert;
303 // Some constants
304 #define ID_CHOICE_NMEA wxID_HIGHEST + 1
305
306 extern wxArrayString* EnumerateSerialPorts(void); // in chart1.cpp
307
308 extern wxArrayString TideCurrentDataSet;
309 extern wxString g_TCData_Dir;
310
311 extern AIS_Decoder* g_pAIS;
312 extern bool g_bserial_access_checked;
313
314 options* g_pOptions;
315
316 extern bool g_bShowMenuBar;
317 extern bool g_bShowCompassWin;
318
319 extern bool g_btouch;
320 extern bool g_bresponsive;
321 extern bool g_bAutoHideToolbar;
322 extern int g_nAutoHideToolbar;
323 extern int g_GUIScaleFactor;
324 extern int g_ChartScaleFactor;
325 extern float g_ChartScaleFactorExp;
326 extern bool g_bRollover;
327 extern int g_ShipScaleFactor;
328 extern float g_ShipScaleFactorExp;
329 extern int g_ENCSoundingScaleFactor;
330 extern bool g_bShowMuiZoomButtons;
331
332 extern double g_config_display_size_mm;
333 extern bool g_config_display_size_manual;
334 extern bool g_bInlandEcdis;
335 extern bool g_bDarkDecorations;
336 extern unsigned int g_canvasConfig;
337 extern bool g_useMUI;
338 extern wxString g_lastAppliedTemplateGUID;
339 extern wxString g_default_wp_icon;
340 extern wxString g_default_routepoint_icon;
341 extern int g_iWpt_ScaMin;
342 extern bool g_bUseWptScaMin;
343 bool g_bOverruleScaMin;
344 extern int osMajor, osMinor;
345 extern bool g_bShowMuiZoomButtons;
346
347 extern "C" bool CheckSerialAccess(void);
348 extern wxString GetShipNameFromFile(int);
349
350 WX_DEFINE_ARRAY_PTR(ChartCanvas*, arrayofCanvasPtr);
351 extern arrayofCanvasPtr g_canvasArray;
352
353
354 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
355 static int lang_list[] = {
356 wxLANGUAGE_DEFAULT, wxLANGUAGE_ABKHAZIAN, wxLANGUAGE_AFAR,
357 wxLANGUAGE_AFRIKAANS, wxLANGUAGE_ALBANIAN, wxLANGUAGE_AMHARIC,
358 wxLANGUAGE_ARABIC, wxLANGUAGE_ARABIC_ALGERIA, wxLANGUAGE_ARABIC_BAHRAIN,
359 wxLANGUAGE_ARABIC_EGYPT, wxLANGUAGE_ARABIC_IRAQ, wxLANGUAGE_ARABIC_JORDAN,
360 wxLANGUAGE_ARABIC_KUWAIT, wxLANGUAGE_ARABIC_LEBANON,
361 wxLANGUAGE_ARABIC_LIBYA, wxLANGUAGE_ARABIC_MOROCCO, wxLANGUAGE_ARABIC_OMAN,
362 wxLANGUAGE_ARABIC_QATAR, wxLANGUAGE_ARABIC_SAUDI_ARABIA,
363 wxLANGUAGE_ARABIC_SUDAN, wxLANGUAGE_ARABIC_SYRIA, wxLANGUAGE_ARABIC_TUNISIA,
364 // wxLANGUAGE_ARABIC_UAE,
365 wxLANGUAGE_ARABIC_YEMEN, wxLANGUAGE_ARMENIAN, wxLANGUAGE_ASSAMESE,
366 wxLANGUAGE_AYMARA, wxLANGUAGE_AZERI, wxLANGUAGE_AZERI_CYRILLIC,
367 wxLANGUAGE_AZERI_LATIN, wxLANGUAGE_BASHKIR, wxLANGUAGE_BASQUE,
368 wxLANGUAGE_BELARUSIAN, wxLANGUAGE_BENGALI, wxLANGUAGE_BHUTANI,
369 wxLANGUAGE_BIHARI, wxLANGUAGE_BISLAMA, wxLANGUAGE_BRETON,
370 wxLANGUAGE_BULGARIAN, wxLANGUAGE_BURMESE, wxLANGUAGE_CAMBODIAN,
371 wxLANGUAGE_CATALAN,
372 // wxLANGUAGE_CHINESE,
373 // wxLANGUAGE_CHINESE_SIMPLIFIED,
374 // wxLANGUAGE_CHINESE_TRADITIONAL,
375 // wxLANGUAGE_CHINESE_HONGKONG,
376 // wxLANGUAGE_CHINESE_MACAU,
377 // wxLANGUAGE_CHINESE_SINGAPORE,
378 wxLANGUAGE_CHINESE_TAIWAN, wxLANGUAGE_CORSICAN, wxLANGUAGE_CROATIAN,
379 wxLANGUAGE_CZECH, wxLANGUAGE_DANISH, wxLANGUAGE_DUTCH,
380 wxLANGUAGE_DUTCH_BELGIAN, wxLANGUAGE_ENGLISH, wxLANGUAGE_ENGLISH_UK,
381 wxLANGUAGE_ENGLISH_US, wxLANGUAGE_ENGLISH_AUSTRALIA,
382 wxLANGUAGE_ENGLISH_BELIZE, wxLANGUAGE_ENGLISH_BOTSWANA,
383 wxLANGUAGE_ENGLISH_CANADA, wxLANGUAGE_ENGLISH_CARIBBEAN,
384 wxLANGUAGE_ENGLISH_DENMARK, wxLANGUAGE_ENGLISH_EIRE,
385 wxLANGUAGE_ENGLISH_JAMAICA, wxLANGUAGE_ENGLISH_NEW_ZEALAND,
386 wxLANGUAGE_ENGLISH_PHILIPPINES, wxLANGUAGE_ENGLISH_SOUTH_AFRICA,
387 wxLANGUAGE_ENGLISH_TRINIDAD, wxLANGUAGE_ENGLISH_ZIMBABWE,
388 wxLANGUAGE_ESPERANTO, wxLANGUAGE_ESTONIAN, wxLANGUAGE_FAEROESE,
389 wxLANGUAGE_FARSI, wxLANGUAGE_FIJI, wxLANGUAGE_FINNISH, wxLANGUAGE_FRENCH,
390 wxLANGUAGE_FRENCH_BELGIAN, wxLANGUAGE_FRENCH_CANADIAN,
391 wxLANGUAGE_FRENCH_LUXEMBOURG, wxLANGUAGE_FRENCH_MONACO,
392 wxLANGUAGE_FRENCH_SWISS, wxLANGUAGE_FRISIAN, wxLANGUAGE_GALICIAN,
393 wxLANGUAGE_GEORGIAN, wxLANGUAGE_GERMAN, wxLANGUAGE_GERMAN_AUSTRIAN,
394 wxLANGUAGE_GERMAN_BELGIUM, wxLANGUAGE_GERMAN_LIECHTENSTEIN,
395 wxLANGUAGE_GERMAN_LUXEMBOURG, wxLANGUAGE_GERMAN_SWISS, wxLANGUAGE_GREEK,
396 wxLANGUAGE_GREENLANDIC, wxLANGUAGE_GUARANI, wxLANGUAGE_GUJARATI,
397 wxLANGUAGE_HAUSA, wxLANGUAGE_HEBREW, wxLANGUAGE_HINDI, wxLANGUAGE_HUNGARIAN,
398 wxLANGUAGE_ICELANDIC, wxLANGUAGE_INDONESIAN, wxLANGUAGE_INTERLINGUA,
399 wxLANGUAGE_INTERLINGUE, wxLANGUAGE_INUKTITUT, wxLANGUAGE_INUPIAK,
400 wxLANGUAGE_IRISH, wxLANGUAGE_ITALIAN, wxLANGUAGE_ITALIAN_SWISS,
401 wxLANGUAGE_JAPANESE, wxLANGUAGE_JAVANESE, wxLANGUAGE_KANNADA,
402 wxLANGUAGE_KASHMIRI, wxLANGUAGE_KASHMIRI_INDIA, wxLANGUAGE_KAZAKH,
403 wxLANGUAGE_KERNEWEK, wxLANGUAGE_KINYARWANDA, wxLANGUAGE_KIRGHIZ,
404 wxLANGUAGE_KIRUNDI,
405 // wxLANGUAGE_KONKANI,
406 wxLANGUAGE_KOREAN, wxLANGUAGE_KURDISH, wxLANGUAGE_LAOTHIAN,
407 wxLANGUAGE_LATIN, wxLANGUAGE_LATVIAN, wxLANGUAGE_LINGALA,
408 wxLANGUAGE_LITHUANIAN, wxLANGUAGE_MACEDONIAN, wxLANGUAGE_MALAGASY,
409 wxLANGUAGE_MALAY, wxLANGUAGE_MALAYALAM, wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM,
410 wxLANGUAGE_MALAY_MALAYSIA, wxLANGUAGE_MALTESE,
411 // wxLANGUAGE_MANIPURI,
412 wxLANGUAGE_MAORI, wxLANGUAGE_MARATHI, wxLANGUAGE_MOLDAVIAN,
413 wxLANGUAGE_MONGOLIAN, wxLANGUAGE_NAURU, wxLANGUAGE_NEPALI,
414 wxLANGUAGE_NEPALI_INDIA, wxLANGUAGE_NORWEGIAN_BOKMAL,
415 wxLANGUAGE_NORWEGIAN_NYNORSK, wxLANGUAGE_OCCITAN, wxLANGUAGE_ORIYA,
416 wxLANGUAGE_OROMO, wxLANGUAGE_PASHTO, wxLANGUAGE_POLISH,
417 wxLANGUAGE_PORTUGUESE, wxLANGUAGE_PORTUGUESE_BRAZILIAN, wxLANGUAGE_PUNJABI,
418 wxLANGUAGE_QUECHUA, wxLANGUAGE_RHAETO_ROMANCE, wxLANGUAGE_ROMANIAN,
419 wxLANGUAGE_RUSSIAN, wxLANGUAGE_RUSSIAN_UKRAINE, wxLANGUAGE_SAMOAN,
420 wxLANGUAGE_SANGHO, wxLANGUAGE_SANSKRIT, wxLANGUAGE_SCOTS_GAELIC,
421 wxLANGUAGE_SERBIAN, wxLANGUAGE_SERBIAN_CYRILLIC, wxLANGUAGE_SERBIAN_LATIN,
422 wxLANGUAGE_SERBO_CROATIAN, wxLANGUAGE_SESOTHO, wxLANGUAGE_SETSWANA,
423 wxLANGUAGE_SHONA, wxLANGUAGE_SINDHI, wxLANGUAGE_SINHALESE,
424 wxLANGUAGE_SISWATI, wxLANGUAGE_SLOVAK, wxLANGUAGE_SLOVENIAN,
425 wxLANGUAGE_SOMALI, wxLANGUAGE_SPANISH, wxLANGUAGE_SPANISH_ARGENTINA,
426 wxLANGUAGE_SPANISH_BOLIVIA, wxLANGUAGE_SPANISH_CHILE,
427 wxLANGUAGE_SPANISH_COLOMBIA, wxLANGUAGE_SPANISH_COSTA_RICA,
428 wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC, wxLANGUAGE_SPANISH_ECUADOR,
429 wxLANGUAGE_SPANISH_EL_SALVADOR, wxLANGUAGE_SPANISH_GUATEMALA,
430 wxLANGUAGE_SPANISH_HONDURAS, wxLANGUAGE_SPANISH_MEXICAN,
431 // wxLANGUAGE_SPANISH_MODERN,
432 wxLANGUAGE_SPANISH_NICARAGUA, wxLANGUAGE_SPANISH_PANAMA,
433 wxLANGUAGE_SPANISH_PARAGUAY, wxLANGUAGE_SPANISH_PERU,
434 wxLANGUAGE_SPANISH_PUERTO_RICO, wxLANGUAGE_SPANISH_URUGUAY,
435 wxLANGUAGE_SPANISH_US, wxLANGUAGE_SPANISH_VENEZUELA, wxLANGUAGE_SUNDANESE,
436 wxLANGUAGE_SWAHILI, wxLANGUAGE_SWEDISH, wxLANGUAGE_SWEDISH_FINLAND,
437 wxLANGUAGE_TAGALOG, wxLANGUAGE_TAJIK, wxLANGUAGE_TAMIL, wxLANGUAGE_TATAR,
438 wxLANGUAGE_TELUGU, wxLANGUAGE_THAI, wxLANGUAGE_TIBETAN, wxLANGUAGE_TIGRINYA,
439 wxLANGUAGE_TONGA, wxLANGUAGE_TSONGA, wxLANGUAGE_TURKISH, wxLANGUAGE_TURKMEN,
440 wxLANGUAGE_TWI, wxLANGUAGE_UIGHUR, wxLANGUAGE_UKRAINIAN, wxLANGUAGE_URDU,
441 wxLANGUAGE_URDU_INDIA, wxLANGUAGE_URDU_PAKISTAN, wxLANGUAGE_UZBEK,
442 wxLANGUAGE_UZBEK_CYRILLIC, wxLANGUAGE_UZBEK_LATIN, wxLANGUAGE_VIETNAMESE,
443 wxLANGUAGE_VOLAPUK, wxLANGUAGE_WELSH, wxLANGUAGE_WOLOF, wxLANGUAGE_XHOSA,
444 wxLANGUAGE_YIDDISH, wxLANGUAGE_YORUBA, wxLANGUAGE_ZHUANG, wxLANGUAGE_ZULU};
445 #endif
446
447
448 // Helper utilities
LoadSVG(const wxString filename,unsigned int width,unsigned int height)449 static wxBitmap LoadSVG( const wxString filename, unsigned int width, unsigned int height )
450 {
451 #ifdef ocpnUSE_SVG
452 #ifdef __OCPN__ANDROID__
453 return loadAndroidSVG( filename, width, height );
454 #else
455 wxSVGDocument svgDoc;
456 if( svgDoc.Load(filename) )
457 return wxBitmap( svgDoc.Render( width, height, NULL, true, true ) );
458 else
459 return wxBitmap(width, height);
460 #endif
461 #else
462 return wxBitmap(width, height);
463 #endif // ocpnUSE_SVG
464 }
465
466
467 #ifdef __OCPN__ANDROID__
prepareSlider(wxSlider * slider)468 void prepareSlider(wxSlider *slider)
469 {
470 slider->GetHandle()->setStyleSheet(prepareAndroidSliderStyleSheet(slider->GetSize().x));
471 slider->GetHandle()->setAttribute(Qt::WA_AcceptTouchEvents);
472 slider->GetHandle()->grabGesture(Qt::PanGesture);
473 slider->GetHandle()->grabGesture(Qt::SwipeGesture);
474 }
475 #endif
476
477
478 // sort callback for Connections list Sort by priority.
479 #if wxCHECK_VERSION(2, 9, 0)
SortConnectionOnPriority(wxIntPtr item1,wxIntPtr item2,wxIntPtr list)480 int wxCALLBACK SortConnectionOnPriority(wxIntPtr item1, wxIntPtr item2, wxIntPtr list)
481 #else
482 int wxCALLBACK SortConnectionOnPriority(long item1, long item2, long list)
483 #endif
484 {
485 wxListCtrl* lc = reinterpret_cast<wxListCtrl*>(list);
486
487 wxListItem it1, it2;
488 it1.SetId(lc->FindItem(-1, item1));
489 it1.SetColumn(3);
490 it1.SetMask(it1.GetMask() | wxLIST_MASK_TEXT);
491
492 it2.SetId(lc->FindItem(-1, item2));
493 it2.SetColumn(3);
494 it2.SetMask(it2.GetMask() | wxLIST_MASK_TEXT);
495
496 lc->GetItem(it1);
497 lc->GetItem(it2);
498
499 #ifdef __WXOSX__
500 return it1.GetText().CmpNoCase(it2.GetText());
501 #else
502 return it2.GetText().CmpNoCase(it1.GetText());
503 #endif
504 }
505
506 WX_DECLARE_LIST(wxCheckBox, CBList);
507
508 class OCPNCheckedListCtrl : public wxScrolledWindow {
509 public:
OCPNCheckedListCtrl()510 OCPNCheckedListCtrl() {}
511
OCPNCheckedListCtrl(wxWindow * parent,wxWindowID id=-1,const wxPoint & pt=wxDefaultPosition,const wxSize & sz=wxDefaultSize,long style=wxHSCROLL|wxVSCROLL,const wxString & name=_T ("scrolledWindow"))512 OCPNCheckedListCtrl(wxWindow* parent, wxWindowID id = -1,
513 const wxPoint& pt = wxDefaultPosition,
514 const wxSize& sz = wxDefaultSize,
515 long style = wxHSCROLL | wxVSCROLL,
516 const wxString& name = _T("scrolledWindow")) {
517 Create(parent, id, pt, sz, style, name);
518 }
519
520 bool Create(wxWindow* parent, wxWindowID id = -1,
521 const wxPoint& pt = wxDefaultPosition,
522 const wxSize& sz = wxDefaultSize,
523 long style = wxHSCROLL | wxVSCROLL,
524 const wxString& name = _T("scrolledWindow"));
525
~OCPNCheckedListCtrl()526 virtual ~OCPNCheckedListCtrl() {}
527
528 unsigned int Append(wxString& label, bool benable = true);
GetCount()529 unsigned int GetCount() { return m_list.GetCount(); }
530
531 void Clear();
532 void Check(int index, bool val);
533 bool IsChecked(int index);
534
535 private:
536 wxBoxSizer* m_sizer;
537
538 CBList m_list;
539 };
540
541 #include <wx/listimpl.cpp>
542 WX_DEFINE_LIST(CBList);
543
Create(wxWindow * parent,wxWindowID id,const wxPoint & pt,const wxSize & sz,long style,const wxString & name)544 bool OCPNCheckedListCtrl::Create(wxWindow* parent, wxWindowID id,
545 const wxPoint& pt, const wxSize& sz,
546 long style, const wxString& name) {
547 if (!wxScrolledWindow::Create(parent, id, pt, sz, style, name)) return FALSE;
548
549 #ifdef __OCPN__ANDROID__
550 GetHandle()->setObjectName("OCPNCheckedListCtrl");
551 GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
552 #endif
553
554 SetScrollRate(0, 2);
555 m_sizer = new wxBoxSizer(wxVERTICAL);
556 SetSizer(m_sizer);
557
558 return TRUE;
559 }
560
Append(wxString & label,bool benable)561 unsigned int OCPNCheckedListCtrl::Append(wxString& label, bool benable) {
562 wxCheckBox* cb = new wxCheckBox(this, wxID_ANY, label);
563 cb->Enable(benable);
564 cb->SetValue(!benable);
565 m_sizer->Add(cb);
566 m_sizer->Layout();
567
568 m_list.Append(cb);
569
570 return m_list.GetCount() - 1;
571 }
572
Check(int index,bool val)573 void OCPNCheckedListCtrl::Check(int index, bool val) {
574 CBList::Node* node = m_list.Item(index);
575 wxCheckBox* cb = node->GetData();
576
577 if (cb) cb->SetValue(val);
578 }
579
IsChecked(int index)580 bool OCPNCheckedListCtrl::IsChecked(int index) {
581 CBList::Node* node = m_list.Item(index);
582 wxCheckBox* cb = node->GetData();
583
584 if (cb)
585 return cb->GetValue();
586 else
587 return false;
588 }
589
Clear()590 void OCPNCheckedListCtrl::Clear() {
591 for(unsigned int i=0 ; i < m_list.GetCount() ; i++){
592 wxCheckBox* cb = m_list[i];
593 delete cb;
594 }
595 m_list.Clear();
596 Scroll(0,0);
597 }
598
599 //Helper for conditional file name separator
600 void appendOSDirSlash(wxString* pString);
601
602 extern ArrayOfMMSIProperties g_MMSI_Props_Array;
603
604 ///////////////////////////////////////////////////////////////////////////////
605 /// Class ConfigCreateDialog
606 ///////////////////////////////////////////////////////////////////////////////
607
BEGIN_EVENT_TABLE(ConfigCreateDialog,wxDialog)608 BEGIN_EVENT_TABLE(ConfigCreateDialog, wxDialog)
609 EVT_BUTTON(ID_CONFIGEDIT_CANCEL, ConfigCreateDialog::OnConfigEditCancelClick)
610 EVT_BUTTON(ID_CONFIGEDIT_OK, ConfigCreateDialog::OnConfigEditOKClick)
611 END_EVENT_TABLE()
612
613 ConfigCreateDialog::ConfigCreateDialog(wxWindow* parent,
614 wxWindowID id, const wxString& caption,
615 const wxPoint& pos, const wxSize& size,
616 long style)
617 : wxDialog(parent, id, caption, pos, size,
618 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
619 {
620 CreateControls();
621 GetSizer()->SetSizeHints(this);
622 Centre();
623 }
624
~ConfigCreateDialog(void)625 ConfigCreateDialog::~ConfigCreateDialog(void)
626 {
627 }
628
CreateControls(void)629 void ConfigCreateDialog::CreateControls(void)
630 {
631 wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
632 SetSizer(mainSizer);
633
634 mainSizer->Add(new wxStaticText(this, wxID_STATIC, _("Title")), 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
635
636 m_TitleCtl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40 * GetCharHeight(), -1), 0);
637 mainSizer->Add(m_TitleCtl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
638
639 mainSizer->AddSpacer(2 * GetCharHeight());
640
641 mainSizer->Add(new wxStaticText(this, wxID_STATIC, _("Description")), 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
642
643 m_DescriptionCtl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1, 6 * GetCharHeight()), wxTE_MULTILINE);
644 mainSizer->Add(m_DescriptionCtl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
645
646 mainSizer->AddSpacer(2 * GetCharHeight());
647
648 mainSizer->Add(new wxStaticText(this, wxID_STATIC,
649 _("Create a private configuration template based on current settings.\n\
650 This template will be saved, and may be selected for further use at any time.\n\
651 ")),
652 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
653
654 mainSizer->AddSpacer(2 * GetCharHeight());
655
656 wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
657 mainSizer->Add(btnSizer, 0, wxALIGN_RIGHT | wxALL, 5);
658
659 m_CancelButton = new wxButton(this, ID_CONFIGEDIT_CANCEL, _("Cancel"));
660 btnSizer->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
661
662 m_OKButton = new wxButton(this, ID_CONFIGEDIT_OK, _("OK"));
663 btnSizer->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
664 m_OKButton->SetDefault();
665
666 }
667
OnConfigEditCancelClick(wxCommandEvent & event)668 void ConfigCreateDialog::OnConfigEditCancelClick(wxCommandEvent& event)
669 {
670 EndModal(wxID_CANCEL);
671 }
672
OnConfigEditOKClick(wxCommandEvent & event)673 void ConfigCreateDialog::OnConfigEditOKClick(wxCommandEvent& event)
674 {
675 const wxString &title = m_TitleCtl->GetValue();
676 const wxString &desc = m_DescriptionCtl->GetValue();
677 m_createdTemplateGUID = ConfigMgr::Get().CreateNamedConfig(title, desc, _T(""));
678 EndModal(wxID_OK);
679
680 }
681
682
683
684
685 ///////////////////////////////////////////////////////////////////////////////
686 /// Class MMSIEditDialog
687 ///////////////////////////////////////////////////////////////////////////////
688
BEGIN_EVENT_TABLE(MMSIEditDialog,wxDialog)689 BEGIN_EVENT_TABLE(MMSIEditDialog, wxDialog)
690 EVT_BUTTON(ID_MMSIEDIT_CANCEL, MMSIEditDialog::OnMMSIEditCancelClick)
691 EVT_BUTTON(ID_MMSIEDIT_OK, MMSIEditDialog::OnMMSIEditOKClick)
692 END_EVENT_TABLE()
693
694 MMSIEditDialog::MMSIEditDialog(MMSIProperties* props, wxWindow* parent,
695 wxWindowID id, const wxString& caption,
696 const wxPoint& pos, const wxSize& size,
697 long style)
698 : wxDialog(parent, id, caption, pos, size,
699 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
700 m_props(props) {
701 CreateControls();
702 GetSizer()->SetSizeHints(this);
703 Centre();
704 }
705
~MMSIEditDialog(void)706 MMSIEditDialog::~MMSIEditDialog(void) { delete m_MMSICtl; }
707
CreateControls(void)708 void MMSIEditDialog::CreateControls(void) {
709 wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
710 SetSizer(mainSizer);
711
712 wxStaticBox* mmsiBox =
713 new wxStaticBox(this, wxID_ANY, _("MMSI Extended Properties"));
714
715 wxStaticBoxSizer* mmsiSizer = new wxStaticBoxSizer(mmsiBox, wxVERTICAL);
716 mainSizer->Add(mmsiSizer, 0, wxEXPAND | wxALL, 5);
717
718 mmsiSizer->Add(new wxStaticText(this, wxID_STATIC, _("MMSI")), 0,
719 wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
720
721 m_MMSICtl = new wxTextCtrl(this, ID_MMSI_CTL, wxEmptyString,
722 wxDefaultPosition, wxSize(180, -1), 0);
723 mmsiSizer->Add(m_MMSICtl, 0,
724 wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
725
726 wxStaticBoxSizer* trackSizer = new wxStaticBoxSizer(
727 new wxStaticBox(this, wxID_ANY, _("Tracking")), wxVERTICAL);
728
729 wxGridSizer* gridSizer = new wxGridSizer(0, 3, 0, 0);
730
731 m_rbTypeTrackDefault =
732 new wxRadioButton(this, wxID_ANY, _("Default tracking"),
733 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
734 m_rbTypeTrackDefault->SetValue(TRUE);
735 gridSizer->Add(m_rbTypeTrackDefault, 0, wxALL, 5);
736
737 m_rbTypeTrackAlways = new wxRadioButton(this, wxID_ANY, _("Always track"));
738 gridSizer->Add(m_rbTypeTrackAlways, 0, wxALL, 5);
739
740 m_rbTypeTrackNever = new wxRadioButton(this, wxID_ANY, _(" Never track"));
741 gridSizer->Add(m_rbTypeTrackNever, 0, wxALL, 5);
742
743 m_cbTrackPersist = new wxCheckBox(this, wxID_ANY, _("Persistent"));
744 gridSizer->Add(m_cbTrackPersist, 0, wxALL, 5);
745
746 trackSizer->Add(gridSizer, 0, wxEXPAND, 0);
747 mmsiSizer->Add(trackSizer, 0, wxEXPAND, 0);
748
749 m_IgnoreButton = new wxCheckBox(this, wxID_ANY, _("Ignore this MMSI"));
750 mmsiSizer->Add(m_IgnoreButton, 0, wxEXPAND, 5);
751
752 m_MOBButton = new wxCheckBox(this, wxID_ANY,
753 _("Handle this MMSI as SART/PLB(AIS) MOB."));
754 mmsiSizer->Add(m_MOBButton, 0, wxEXPAND, 5);
755
756 m_VDMButton = new wxCheckBox(this, wxID_ANY, _("Convert AIVDM to AIVDO for this MMSI"));
757 mmsiSizer->Add(m_VDMButton, 0, wxEXPAND, 5);
758
759 m_FollowerButton = new wxCheckBox(this, wxID_ANY, _("This MMSI is my Follower - No CPA Alert"));
760 mmsiSizer->Add(m_FollowerButton, 0, wxEXPAND, 5);
761
762 wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
763 mainSizer->Add(btnSizer, 0, wxALIGN_RIGHT | wxALL, 5);
764
765 m_CancelButton = new wxButton(this, ID_MMSIEDIT_CANCEL, _("Cancel"));
766 btnSizer->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
767
768 m_OKButton = new wxButton(this, ID_MMSIEDIT_OK, _("OK"));
769 btnSizer->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
770 m_OKButton->SetDefault();
771
772 // Set initial values...
773 wxString sMMSI;
774 if (m_props->MMSI > 0)
775 sMMSI.Printf(_T("%d"), m_props->MMSI);
776 else
777 sMMSI = _T("");
778 m_MMSICtl->AppendText(sMMSI);
779
780 switch (m_props->TrackType) {
781 case TRACKTYPE_ALWAYS:
782 m_rbTypeTrackAlways->SetValue(TRUE);
783 break;
784 case TRACKTYPE_NEVER:
785 m_rbTypeTrackNever->SetValue(TRUE);
786 break;
787 default:
788 break;
789 }
790
791 m_cbTrackPersist->SetValue(m_props->m_bPersistentTrack);
792 m_IgnoreButton->SetValue(m_props->m_bignore);
793 m_MOBButton->SetValue(m_props->m_bMOB);
794 m_VDMButton->SetValue(m_props->m_bVDM);
795 m_FollowerButton->SetValue(m_props->m_bFollower);
796
797 SetColorScheme(GLOBAL_COLOR_SCHEME_RGB);
798 }
799
SetColorScheme(ColorScheme cs)800 void MMSIEditDialog::SetColorScheme(ColorScheme cs) { DimeControl(this); }
801
OnMMSIEditCancelClick(wxCommandEvent & event)802 void MMSIEditDialog::OnMMSIEditCancelClick(wxCommandEvent& event) {
803 EndModal(wxID_CANCEL);
804 }
805
Persist()806 void MMSIEditDialog::Persist() {
807 if (m_props) {
808
809 if (m_rbTypeTrackDefault->GetValue())
810 m_props->TrackType = TRACKTYPE_DEFAULT;
811 else if (m_rbTypeTrackAlways->GetValue())
812 m_props->TrackType = TRACKTYPE_ALWAYS;
813 else
814 m_props->TrackType = TRACKTYPE_NEVER;
815
816 m_props->m_bignore = m_IgnoreButton->GetValue();
817 m_props->m_bMOB = m_MOBButton->GetValue();
818 m_props->m_bVDM = m_VDMButton->GetValue();
819 m_props->m_bFollower = m_FollowerButton->GetValue();
820 m_props->m_bPersistentTrack = m_cbTrackPersist->GetValue();
821 if (m_props->m_ShipName == wxEmptyString) {
822 AIS_Target_Data *proptarget = g_pAIS->Get_Target_Data_From_MMSI(m_props->MMSI);
823 if (proptarget) {
824 wxString s = proptarget->GetFullName();
825 m_props->m_ShipName = s;
826 }
827 else {
828 wxString GetShipNameFromFile(int);
829 m_props->m_ShipName = GetShipNameFromFile(m_props->MMSI);
830 }
831 }
832 }
833 }
834
OnMMSIEditOKClick(wxCommandEvent & event)835 void MMSIEditDialog::OnMMSIEditOKClick(wxCommandEvent& event) {
836 // Update the MMSIProperties by the passed pointer
837 if (m_props) {
838 long nmmsi;
839 m_MMSICtl->GetValue().ToLong(&nmmsi);
840 m_props->MMSI = nmmsi;
841 Persist();
842
843
844 if (m_MMSICtl->GetValue().Length() != 9)
845 {
846 OCPNMessageDialog* dlg = new OCPNMessageDialog(this,
847 _("An MMSI Id is generally a number of nine digits.\nPlease check your entries and cancel if necessary."), _("OpenCPN Info"), wxOK | wxCANCEL);
848
849 dlg->ShowWindowModalThenDo([this,dlg](int retcode){
850 if ( retcode == wxID_OK ) {
851 Persist();
852 }
853 EndModal(retcode);
854 });
855 } else {
856 EndModal(wxID_OK);
857 }
858 }
859 }
860
OnCtlUpdated(wxCommandEvent & event)861 void MMSIEditDialog::OnCtlUpdated(wxCommandEvent& event) {}
862
BEGIN_EVENT_TABLE(MMSIListCtrl,wxListCtrl)863 BEGIN_EVENT_TABLE(MMSIListCtrl, wxListCtrl)
864 EVT_LIST_ITEM_SELECTED(ID_MMSI_PROPS_LIST, MMSIListCtrl::OnListItemClick)
865 EVT_LIST_ITEM_ACTIVATED(ID_MMSI_PROPS_LIST, MMSIListCtrl::OnListItemActivated)
866 EVT_LIST_ITEM_RIGHT_CLICK(ID_MMSI_PROPS_LIST,
867 MMSIListCtrl::OnListItemRightClick)
868 EVT_MENU(ID_DEF_MENU_MMSI_EDIT, MMSIListCtrl::PopupMenuHandler)
869 EVT_MENU(ID_DEF_MENU_MMSI_DELETE, MMSIListCtrl::PopupMenuHandler)
870 END_EVENT_TABLE()
871
872 MMSIListCtrl::MMSIListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos,
873 const wxSize& size, long style)
874 : wxListCtrl(parent, id, pos, size, style) {
875 m_parent = parent;
876 }
877
~MMSIListCtrl(void)878 MMSIListCtrl::~MMSIListCtrl(void) {}
879
OnGetItemText(long item,long column) const880 wxString MMSIListCtrl::OnGetItemText(long item, long column) const {
881 wxString ret;
882 MMSIProperties* props = g_MMSI_Props_Array[item];
883
884 if (!props) return ret;
885 switch (column) {
886 case mlMMSI:
887 if (props->MMSI > 0) ret = wxString::Format(_T( "%d" ), props->MMSI);
888 break;
889 case mlTrackMode:
890 switch (props->TrackType) {
891 case TRACKTYPE_DEFAULT:
892 ret = _("Default");
893 break;
894 case TRACKTYPE_ALWAYS:
895 ret = _("Always");
896 break;
897 case TRACKTYPE_NEVER:
898 ret = _("Never");
899 break;
900 default:
901 ret = _T( "???" );
902 }
903 if (props->m_bPersistentTrack)
904 ret.Append(_T( ", " )).Append(_("Persistent"));
905 break;
906 case mlIgnore:
907 if (props->m_bignore) ret = _T( "X" );
908 break;
909 case mlMOB:
910 if (props->m_bMOB) ret = _T( "X" );
911 break;
912 case mlVDM:
913 if (props->m_bVDM) ret = _T( "X" );
914 break;
915 case mlFollower:
916 if (props->m_bFollower) ret = _T("X");
917 break;
918 case mlShipName:
919 ret = props->m_ShipName;
920 break;
921 default:
922 ret = _T( "??" );
923 break;
924 }
925 return ret;
926 }
927
OnListItemClick(wxListEvent & event)928 void MMSIListCtrl::OnListItemClick(wxListEvent& event) {}
929
OnListItemActivated(wxListEvent & event)930 void MMSIListCtrl::OnListItemActivated(wxListEvent& event) {
931 MMSIProperties* props = g_MMSI_Props_Array.Item(event.GetIndex());
932 MMSIProperties* props_new = new MMSIProperties(*props);
933
934 MMSIEditDialog* pd =
935 new MMSIEditDialog(props_new, m_parent, -1, _("Edit MMSI Properties"),
936 wxDefaultPosition, wxSize(200, 200));
937
938 if (pd->ShowModal() == wxID_OK) {
939 g_MMSI_Props_Array.RemoveAt(event.GetIndex());
940 delete props;
941 g_MMSI_Props_Array.Insert(props_new, event.GetIndex());
942 }
943 else
944 delete props_new;
945
946 pd->Destroy();
947 }
948
OnListItemRightClick(wxListEvent & event)949 void MMSIListCtrl::OnListItemRightClick(wxListEvent& event) {
950 m_context_item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
951 if (m_context_item == wxNOT_FOUND) return;
952 wxMenu* menu = new wxMenu(_("MMSI Properties"));
953 wxMenuItem* item_edit =
954 new wxMenuItem(menu, ID_DEF_MENU_MMSI_EDIT, _("Edit") + _T("..."));
955 menu->Append(item_edit);
956 wxMenuItem* item_delete =
957 new wxMenuItem(menu, ID_DEF_MENU_MMSI_DELETE, _("Delete"));
958 menu->Append(item_delete);
959
960 #ifdef __WXMSW__
961 wxFont* qFont = GetOCPNScaledFont(_("Menu"));
962 item_edit->SetFont(*qFont);
963 item_delete->SetFont(*qFont);
964 #endif
965
966 wxPoint p = ScreenToClient(wxGetMousePosition());
967 PopupMenu(menu, p.x, p.y);
968
969 SetItemCount(g_MMSI_Props_Array.GetCount());
970 Refresh(TRUE);
971 }
972
PopupMenuHandler(wxCommandEvent & event)973 void MMSIListCtrl::PopupMenuHandler(wxCommandEvent& event) {
974 int context_item = m_context_item;
975 MMSIProperties* props = g_MMSI_Props_Array[context_item];
976
977 if (!props)
978 return;
979
980 switch (event.GetId()) {
981 case ID_DEF_MENU_MMSI_EDIT: {
982 MMSIProperties* props_new = new MMSIProperties(*props);
983 MMSIEditDialog* pd = new MMSIEditDialog(props_new, m_parent, -1, _("Edit MMSI Properties"),
984 wxDefaultPosition, wxSize(200, 200));
985
986 if (pd->ShowModal() == wxID_OK) {
987 g_MMSI_Props_Array.RemoveAt(context_item);
988 delete props;
989 props_new->m_ShipName = GetShipNameFromFile(props_new->MMSI);
990 g_MMSI_Props_Array.Insert(props_new, context_item);
991 }
992 else {
993 delete props_new;
994 }
995 pd->Destroy();
996 break;
997 }
998 case ID_DEF_MENU_MMSI_DELETE:
999 g_MMSI_Props_Array.RemoveAt(context_item);
1000 delete props;
1001 break;
1002 }
1003 }
1004
MMSI_Props_Panel(wxWindow * parent)1005 MMSI_Props_Panel::MMSI_Props_Panel(wxWindow* parent)
1006 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1007 wxBORDER_NONE) {
1008 m_pparent = parent;
1009
1010 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
1011 SetFont(*qFont);
1012
1013 wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
1014 SetSizer(topSizer);
1015
1016 wxString MMSI_props_column_spec = _T("120;120;100;100;100;100;100;100");
1017 // Parse the global column width string as read from config file
1018 wxStringTokenizer tkz(MMSI_props_column_spec, _T(";"));
1019 wxString s_width = tkz.GetNextToken();
1020 int width;
1021 long lwidth;
1022
1023 m_pListCtrlMMSI = new MMSIListCtrl(
1024 this, ID_MMSI_PROPS_LIST, wxDefaultPosition, wxSize(-1, -1),
1025 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES |
1026 wxBORDER_SUNKEN | wxLC_VIRTUAL);
1027 //wxImageList* imglist = new wxImageList(16, 16, TRUE, 2);
1028
1029 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
1030 //imglist->Add(style->GetIcon(_T( "sort_asc" )));
1031 //imglist->Add(style->GetIcon(_T( "sort_desc" )));
1032
1033 // m_pListCtrlMMSI->AssignImageList( imglist, wxIMAGE_LIST_SMALL );
1034 int dx = GetCharWidth();
1035
1036 width = dx * 5;
1037 if (s_width.ToLong(&lwidth)) {
1038 width = wxMax(dx * 2, lwidth);
1039 width = wxMin(width, dx * 13);
1040 }
1041 m_pListCtrlMMSI->InsertColumn(tlMMSI, _("MMSI"), wxLIST_FORMAT_LEFT, width);
1042
1043 s_width = tkz.GetNextToken();
1044 width = dx * 12;
1045 if (s_width.ToLong(&lwidth)) {
1046 width = wxMax(dx * 2, lwidth);
1047 width = wxMin(width, dx * 25);
1048 }
1049 m_pListCtrlMMSI->InsertColumn(tlCLASS, _("Track Mode"), wxLIST_FORMAT_CENTER, width);
1050
1051 s_width = tkz.GetNextToken();
1052 width = dx * 8;
1053 if (s_width.ToLong(&lwidth)) {
1054 width = wxMax(dx * 2, lwidth);
1055 width = wxMin(width, dx * 10);
1056 }
1057 m_pListCtrlMMSI->InsertColumn(tlTYPE, _("Ignore"), wxLIST_FORMAT_CENTER,
1058 width);
1059
1060 s_width = tkz.GetNextToken();
1061 width = dx * 8;
1062 if (s_width.ToLong(&lwidth)) {
1063 width = wxMax(dx * 2, lwidth);
1064 width = wxMin(width, dx * 10);
1065 }
1066 m_pListCtrlMMSI->InsertColumn(tlTYPE, _("MOB"), wxLIST_FORMAT_CENTER, width);
1067
1068 s_width = tkz.GetNextToken();
1069 width = dx * 8;
1070 if (s_width.ToLong(&lwidth)) {
1071 width = wxMax(dx * 2, lwidth);
1072 width = wxMin(width, dx * 15);
1073 }
1074 m_pListCtrlMMSI->InsertColumn(tlTYPE, _("VDM->VDO"), wxLIST_FORMAT_CENTER, width);
1075
1076 s_width = tkz.GetNextToken();
1077 width = dx * 8;
1078 if (s_width.ToLong(&lwidth)) {
1079 width = wxMax(dx * 2, lwidth);
1080 width = wxMin(width, dx * 30);
1081 }
1082 m_pListCtrlMMSI->InsertColumn(tlTYPE, _("Ship name"), wxLIST_FORMAT_CENTER, width);
1083
1084 s_width = tkz.GetNextToken();
1085 width = dx * 8;
1086 if (s_width.ToLong(&lwidth)) {
1087 width = wxMax(dx * 2, lwidth);
1088 width = wxMin(width, dx * 10);
1089 }
1090 m_pListCtrlMMSI->InsertColumn(tlTYPE, _("Follower"), wxLIST_FORMAT_CENTER, width); //Has
1091
1092 topSizer->Add(m_pListCtrlMMSI, 1, wxEXPAND | wxALL, 0);
1093
1094 m_pButtonNew = new wxButton(this, wxID_ANY, _("New..."), wxDefaultPosition,
1095 wxSize(200, -1));
1096 m_pButtonNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
1097 wxCommandEventHandler(MMSI_Props_Panel::OnNewButton),
1098 NULL, this);
1099 topSizer->Add(m_pButtonNew, 0, wxALIGN_RIGHT | wxALL, 0);
1100
1101 topSizer->Layout();
1102
1103 // This is silly, but seems to be required for __WXMSW__ build
1104 // If not done, the SECOND invocation of the panel fails to expand the list
1105 // to the full wxSizer size....
1106 SetSize(GetSize().x, GetSize().y - 1);
1107
1108 SetColorScheme(GLOBAL_COLOR_SCHEME_RGB);
1109 }
1110
~MMSI_Props_Panel(void)1111 MMSI_Props_Panel::~MMSI_Props_Panel(void) {}
1112
OnNewButton(wxCommandEvent & event)1113 void MMSI_Props_Panel::OnNewButton(wxCommandEvent& event) {
1114 MMSIProperties* props = new MMSIProperties(-1);
1115
1116 MMSIEditDialog* pd =
1117 new MMSIEditDialog(props, m_parent, -1, _("Add MMSI Properties"),
1118 wxDefaultPosition, wxSize(200, 200));
1119
1120 DimeControl( pd );
1121 pd->ShowWindowModalThenDo([this, pd, props](int retcode){
1122 if ( retcode == wxID_OK ) {
1123 g_MMSI_Props_Array.Add(props);
1124 }
1125 else {
1126 delete props;
1127 }
1128 UpdateMMSIList();
1129 });
1130 }
1131
UpdateMMSIList(void)1132 void MMSI_Props_Panel::UpdateMMSIList(void) {
1133 // Capture the MMSI of the curently selected list item
1134 long selItemID = wxNOT_FOUND;
1135 m_pListCtrlMMSI->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1136 wxLIST_STATE_SELECTED);
1137
1138 int selMMSI = wxNOT_FOUND;
1139 if (selItemID != wxNOT_FOUND)
1140 selMMSI = g_MMSI_Props_Array[selItemID]->MMSI;
1141
1142 m_pListCtrlMMSI->SetItemCount(g_MMSI_Props_Array.GetCount());
1143
1144 // Restore selected item
1145 long item_sel = wxNOT_FOUND;
1146 if (selItemID != wxNOT_FOUND && selMMSI != wxNOT_FOUND) {
1147 for (unsigned int i = 0; i < g_MMSI_Props_Array.GetCount(); i++) {
1148 if (g_MMSI_Props_Array[i]->MMSI == selMMSI) {
1149 item_sel = i;
1150 break;
1151 }
1152 }
1153 }
1154
1155 if (g_MMSI_Props_Array.GetCount() > 0)
1156 m_pListCtrlMMSI->SetItemState(item_sel,
1157 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1158 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1159
1160 #ifdef __WXMSW__
1161 m_pListCtrlMMSI->Refresh(FALSE);
1162 #endif
1163 }
1164
SetColorScheme(ColorScheme cs)1165 void MMSI_Props_Panel::SetColorScheme(ColorScheme cs) { DimeControl(this); }
1166
1167
1168 //WX_DECLARE_OBJARRAY(wxBitmap, ArrayOfBitmaps);
1169 //#include <wx/arrimpl.cpp>
1170 //WX_DEFINE_OBJARRAY(ArrayOfBitmaps);
1171
1172 class OCPNFatCombo : public wxOwnerDrawnComboBox
1173 {
1174 public:
1175
1176 OCPNFatCombo();
1177
1178 OCPNFatCombo(wxWindow* parent, wxWindowID id, const wxString& value = _T(""),
1179 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
1180 int n = 0, const wxString choices[] = NULL,
1181 long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = _T("OCPNFatCombo") );
1182
1183
1184
1185 ~OCPNFatCombo ();
1186
1187 void OnDrawItem(wxDC& dc, const wxRect& rect, int item, int flags) const;
1188 wxCoord OnMeasureItem(size_t item) const;
1189 wxCoord OnMeasureItemWidth(size_t item) const;
1190 bool SetFont(const wxFont& font);
1191
1192 int Append(const wxString& item, wxBitmap bmp);
1193 void Clear( void );
1194
1195 const wxFont *dfont;
1196
1197 private:
1198 int itemHeight;
1199 ArrayOfBitmaps bmpArray;
1200
1201 };
1202
OCPNFatCombo()1203 OCPNFatCombo::OCPNFatCombo()
1204 :wxOwnerDrawnComboBox(){}
1205
OCPNFatCombo(wxWindow * parent,wxWindowID id,const wxString & value,const wxPoint & pos,const wxSize & size,int n,const wxString choices[],long style,const wxValidator & validator,const wxString & name)1206 OCPNFatCombo::OCPNFatCombo (wxWindow* parent, wxWindowID id, const wxString& value,
1207 const wxPoint& pos, const wxSize& size, int n, const wxString choices[],
1208 long style, const wxValidator& validator, const wxString& name)
1209 :wxOwnerDrawnComboBox(parent, id, value, pos, size, n, choices, style, validator, name)
1210 {
1211 double fontHeight = GetFont().GetPointSize() / g_Platform->getFontPointsperPixel();
1212 itemHeight = (int)wxRound(fontHeight);
1213 SetPopupMaxHeight(::wxGetDisplaySize().y / 2);
1214 }
1215
~OCPNFatCombo()1216 OCPNFatCombo::~OCPNFatCombo ()
1217 {
1218 }
1219
SetFont(const wxFont & font)1220 bool OCPNFatCombo::SetFont(const wxFont& font)
1221 {
1222 dfont = &font;
1223 return true;
1224 }
1225
OnDrawItem(wxDC & dc,const wxRect & rect,int item,int flags) const1226 void OCPNFatCombo::OnDrawItem( wxDC& dc,
1227 const wxRect& rect,
1228 int item,
1229 int flags ) const
1230 {
1231
1232 int offset_x = 10;
1233 // dc.DrawBitmap(bmpArray.Item(item), rect.x, rect.y + (rect.height - bmpHeight)/2, true);
1234 dc.SetFont(*dfont);
1235
1236 wxColor bg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
1237 wxBrush br = wxBrush(bg);
1238 wxBrush sv = dc.GetBrush();
1239 dc.SetBrush(br);
1240 dc.DrawRectangle(0, 0, rect.width, rect.height);
1241 dc.SetBrush(sv);
1242 dc.SetTextForeground(wxColour(0, 0, 0));
1243
1244 if ( flags & wxODCB_PAINTING_CONTROL )
1245 {
1246 wxString text = GetValue();
1247 int margin_x = 2;
1248 dc.DrawText( text, rect.x + margin_x + offset_x, (rect.height-dc.GetCharHeight())/2 + rect.y );
1249 }
1250 else
1251 {
1252 dc.SetBackground(wxBrush(br));
1253 dc.Clear();
1254 dc.DrawText( GetVListBoxComboPopup()->GetString(item), rect.x + 2 + offset_x, (rect.height-dc.GetCharHeight())/2 + rect.y );
1255 }
1256 }
1257
1258
1259
OnMeasureItem(size_t item) const1260 wxCoord OCPNFatCombo::OnMeasureItem( size_t item ) const
1261 {
1262 if(item < bmpArray.GetCount())
1263 return wxMax(itemHeight, bmpArray.Item(item).GetHeight());
1264
1265 return itemHeight * 12 /10;
1266 }
1267
OnMeasureItemWidth(size_t item) const1268 wxCoord OCPNFatCombo::OnMeasureItemWidth( size_t item ) const
1269 {
1270 return -1;
1271 }
1272
Append(const wxString & item,wxBitmap bmp)1273 int OCPNFatCombo::Append(const wxString& item, wxBitmap bmp)
1274 {
1275 bmpArray.Add(bmp);
1276 int idx = wxOwnerDrawnComboBox::Append(item);
1277
1278 return idx;
1279 }
1280
Clear(void)1281 void OCPNFatCombo::Clear( void )
1282 {
1283 wxOwnerDrawnComboBox::Clear();
1284 bmpArray.Clear();
1285 }
1286
1287
1288
1289
1290
1291
1292
1293
BEGIN_EVENT_TABLE(options,wxDialog)1294 BEGIN_EVENT_TABLE(options, wxDialog)
1295 EVT_CHECKBOX(ID_DEBUGCHECKBOX1, options::OnDebugcheckbox1Click)
1296 EVT_BUTTON(ID_BUTTONADD, options::OnButtonaddClick)
1297 EVT_BUTTON(ID_BUTTONDELETE, options::OnButtondeleteClick)
1298 EVT_BUTTON(ID_PARSEENCBUTTON, options::OnButtonParseENC)
1299 EVT_BUTTON(ID_BUTTONCOMPRESS, options::OnButtoncompressClick)
1300 EVT_BUTTON(ID_TCDATAADD, options::OnInsertTideDataLocation)
1301 EVT_BUTTON(ID_TCDATADEL, options::OnRemoveTideDataLocation)
1302 EVT_BUTTON(ID_APPLY, options::OnApplyClick)
1303 EVT_BUTTON(xID_OK, options::OnXidOkClick)
1304 EVT_BUTTON(wxID_CANCEL, options::OnCancelClick)
1305 EVT_BUTTON(ID_BUTTONFONTCHOOSE, options::OnChooseFont)
1306 EVT_CHOICE(ID_CHOICE_FONTELEMENT, options::OnFontChoice)
1307 EVT_CLOSE(options::OnClose)
1308
1309 #if defined(__WXGTK__) || defined(__WXQT__)
1310 EVT_BUTTON(ID_BUTTONFONTCOLOR, options::OnChooseFontColor)
1311 #endif
1312 #ifdef ocpnUSE_GL
1313 EVT_BUTTON(ID_OPENGLOPTIONS, options::OnOpenGLOptions)
1314 #endif
1315 EVT_CHOICE(ID_RADARDISTUNIT, options::OnDisplayCategoryRadioButton)
1316 EVT_CHOICE(ID_DEPTHUNITSCHOICE, options::OnUnitsChoice)
1317 EVT_BUTTON(ID_CLEARLIST, options::OnButtonClearClick)
1318 EVT_BUTTON(ID_SELECTLIST, options::OnButtonSelectClick)
1319 EVT_BUTTON(ID_SETSTDLIST, options::OnButtonSetStd)
1320 EVT_BUTTON(ID_AISALERTSELECTSOUND, options::OnButtonSelectSound)
1321 EVT_BUTTON(ID_AISALERTTESTSOUND, options::OnButtonTestSound)
1322 EVT_CHECKBOX(ID_SHOWGPSWINDOW, options::OnShowGpsWindowCheckboxClick)
1323 EVT_CHOICE(ID_SHIPICONTYPE, options::OnShipTypeSelect)
1324 EVT_CHOICE(ID_RADARRINGS, options::OnRadarringSelect)
1325 EVT_CHOICE(ID_OPWAYPOINTRANGERINGS, options::OnWaypointRangeRingSelect)
1326 EVT_CHAR_HOOK(options::OnCharHook)
1327 EVT_TIMER(ID_BT_SCANTIMER, options::onBTScanTimer)
1328 END_EVENT_TABLE()
1329
1330
1331
1332 options::options(MyFrame* parent, wxWindowID id, const wxString& caption,
1333 const wxPoint& pos, const wxSize& size, long style) {
1334 Init();
1335
1336 pParent = parent;
1337
1338 long wstyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
1339 SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
1340
1341 wxDialog::Create(parent, id, caption, pos, size, wstyle);
1342 SetFont(*dialogFont);
1343
1344 CreateControls();
1345 RecalculateSize();
1346
1347 Center();
1348 }
1349
~options(void)1350 options::~options(void) {
1351
1352 wxNotebook* nb = dynamic_cast<wxNotebook*>(m_pListbook->GetPage(m_pageCharts));
1353 if (nb)
1354 nb->Disconnect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
1355 wxListbookEventHandler(options::OnChartsPageChange),
1356 NULL, this);
1357
1358 groupsPanel->EmptyChartGroupArray(m_pGroupArray);
1359 delete groupsPanel;
1360
1361 delete m_pSerialArray;
1362 delete m_pGroupArray;
1363 delete m_topImgList;
1364
1365 // Take care of the plugin manager...
1366
1367 delete m_pPlugInCtrl;
1368 if(g_pi_manager)
1369 g_pi_manager->SetListPanelPtr( NULL );
1370 #ifndef __OCPN__ANDROID__
1371 delete m_PluginCatalogMgrPanel;
1372 #endif
1373
1374 }
1375
1376 // with AIS it's called very often
1377 #if wxCHECK_VERSION(3,0,0)
SendIdleEvents(wxIdleEvent & event)1378 bool options::SendIdleEvents(wxIdleEvent &event ) {
1379 if (IsShown())
1380 return wxDialog::SendIdleEvents(event);
1381 return false;
1382 }
1383 #endif
1384
RecalculateSize(void)1385 void options::RecalculateSize(void) {
1386 if (!g_bresponsive) {
1387 wxSize canvas_size = gFrame->GetSize();
1388 wxSize fitted_size = GetSize();
1389
1390 fitted_size.x = wxMin(fitted_size.x, canvas_size.x);
1391 fitted_size.y = wxMin(fitted_size.y, canvas_size.y);
1392
1393 SetSize(fitted_size);
1394
1395 Fit();
1396 m_nCharWidthMax = GetSize().x / GetCharWidth();
1397
1398 return;
1399 }
1400
1401 wxSize esize;
1402 esize.x = GetCharWidth() * 110;
1403 esize.y = GetCharHeight() * 40;
1404
1405 wxSize dsize = GetParent()->GetSize(); // GetClientSize();
1406 esize.y = wxMin(esize.y, dsize.y - 0 /*(2 * GetCharHeight())*/);
1407 esize.x = wxMin(esize.x, dsize.x - 0 /*(2 * GetCharHeight())*/);
1408 SetSize(esize);
1409
1410 wxSize fsize = GetSize();
1411 wxSize canvas_size = GetParent()->GetSize();
1412 wxPoint screen_pos = GetParent()->GetScreenPosition();
1413 int xp = (canvas_size.x - fsize.x) / 2;
1414 int yp = (canvas_size.y - fsize.y) / 2;
1415 Move(screen_pos.x + xp, screen_pos.y + yp);
1416
1417 m_nCharWidthMax = GetSize().x / GetCharWidth();
1418 }
1419
Init(void)1420 void options::Init(void) {
1421 m_pWorkDirList = NULL;
1422
1423 pShowStatusBar = NULL;
1424 pShowMenuBar = NULL;
1425 pShowCompassWin = NULL;
1426 pSelCtl = NULL;
1427 pActiveChartsList = NULL;
1428 ps57CtlListBox = NULL;
1429 pDispCat = NULL;
1430 m_pSerialArray = NULL;
1431 pUpdateCheckBox = NULL;
1432 pParseENCButton = NULL;
1433 k_charts = 0;
1434 k_vectorcharts = 0;
1435 k_plugins = 0;
1436 k_tides = 0;
1437 m_pConfig = NULL;
1438
1439 pSoundDeviceIndex = NULL;
1440
1441 pCBNorthUp = NULL;
1442 pCBCourseUp = NULL;
1443 pCBLookAhead = NULL;
1444 pCDOQuilting = NULL;
1445 pPreserveScale = NULL;
1446 pSmoothPanZoom = NULL;
1447 pEnableZoomToCursor = NULL;
1448 pSDisplayGrid = NULL;
1449 pCDOOutlines = NULL;
1450 pSDepthUnits = NULL;
1451 pSLiveETA = NULL;
1452 pSDefaultBoatSpeed = NULL;
1453
1454 activeSizer = NULL;
1455 itemActiveChartStaticBox = NULL;
1456
1457 pCheck_SOUNDG = NULL;
1458 pCheck_META = NULL;
1459 pCheck_SHOWIMPTEXT = NULL;
1460 pCheck_SCAMIN = NULL;
1461 pCheck_ATONTEXT = NULL;
1462 pCheck_LDISTEXT = NULL;
1463 pCheck_XLSECTTEXT = NULL;
1464
1465 m_bVisitLang = FALSE;
1466 m_itemFontElementListBox = NULL;
1467 m_textSample = NULL;
1468 m_topImgList = NULL;
1469
1470 m_pListbook = NULL;
1471 m_pGroupArray = NULL;
1472 m_groups_changed = 0;
1473
1474 m_pageDisplay = -1;
1475 m_pageConnections = -1;
1476 m_pageCharts = -1;
1477 m_pageShips = -1;
1478 m_pageUI = -1;
1479 m_pagePlugins = -1;
1480 m_pageConnections = -1;
1481
1482 m_buttonScanBT = 0;
1483 m_stBTPairs = 0;
1484 m_choiceBTDataSources = 0;
1485
1486 b_haveWMM = g_pi_manager && g_pi_manager->IsPlugInAvailable(_T("WMM"));
1487 b_oldhaveWMM = b_haveWMM;
1488
1489 lastPage = 0;
1490 m_bneedNew =false;
1491
1492 m_cs = (ColorScheme) 0;
1493
1494 // for deferred loading
1495 m_pPlugInCtrl = NULL;
1496 m_PluginCatalogMgrPanel = NULL;
1497 m_pNMEAForm = NULL;
1498 mSelectedConnection = NULL;
1499
1500 #ifdef __OCPN__ANDROID__
1501 m_scrollRate = 1;
1502 #else
1503 m_scrollRate = 15;
1504 #endif
1505
1506 m_BTScanTimer.SetOwner(this, ID_BT_SCANTIMER);
1507 m_BTscanning = 0;
1508
1509 dialogFont = GetOCPNScaledFont(_("Dialog"));
1510
1511 dialogFontPlus = new wxFont(*dialogFont); // we can't use Smaller() because wx2.8 doesn't support it
1512 dialogFontPlus->SetPointSize((dialogFontPlus->GetPointSize() * 1.2) + 0.5); // + 0.5 to round instead of truncate
1513 dialogFontPlus->SetWeight(wxFONTWEIGHT_BOLD);
1514
1515
1516 m_bVectorInit = false;
1517
1518 // This variable is used by plugin callback function AddOptionsPage
1519 g_pOptions = this;
1520
1521 m_bcompact = false;
1522
1523 #ifdef __OCPN__ANDROID__
1524 m_bcompact = true;
1525 #endif
1526 pCmdSoundString = NULL;
1527
1528 m_sconfigSelect_single = NULL;
1529 m_sconfigSelect_twovertical = NULL;
1530
1531 wxScreenDC dc;
1532 dc.SetFont(*dialogFont);
1533 int width, height;
1534 dc.GetTextExtent(_T("H"), &width, &height, NULL, NULL, dialogFont);
1535
1536 m_colourPickerDefaultSize = wxSize(4 * height, height * 2);
1537
1538 }
1539
1540 #if defined(__GNUC__) && __GNUC__ < 8
1541 // Handle old gcc C++-11 bugs, remove when builders updated to gcc >= 8.1.1.
1542
1543 static const wxString BAD_ACCESS_MSG = _( \
1544 "The device selected is not accessible; opencpn will likely not be able\n"\
1545 "to use this device as-is. You might want to exit OpenCPN, reboot and\n"\
1546 "retry after creating a file called /etc/udev/rules.d/70-opencpn.rules\n"\
1547 "with the following contents:\n\n"\
1548 " KERNEL==\"ttyUSB*\", MODE=\"0666\"\n"\
1549 " KERNEL==\"ttyACM*\", MODE=\"0666\"\n"\
1550 " KERNEL==\"ttyS*\", MODE=\"0666\"\n\n"\
1551 "For more info, see the file LINUX_DEVICES.md in the distribution docs.\n"\
1552 );
1553
1554 #else
1555
1556 static const wxString BAD_ACCESS_MSG = _( R"(
1557 The device selected is not accessible; opencpn will likely not be able
1558 to use this device as-is. You might want to exit OpenCPN, reboot and
1559 retry after creating a file called /etc/udev/rules.d/70-opencpn.rules
1560 with the following contents:
1561
1562 KERNEL=="ttyUSB*", MODE="0666"
1563 KERNEL=="ttyACM*", MODE="0666"
1564 KERNEL=="ttyS*", MODE="0666"
1565
1566 For more info, see the file LINUX_DEVICES.md in the distribution docs.
1567 )" );
1568
1569 #endif // defined(__GNUC__) && __GNUC__ < 8
1570
CheckDeviceAccess(wxString & path)1571 void options::CheckDeviceAccess( /*[[maybe_unused]]*/ wxString &path) {
1572 // Microsoft compiler 19.14.26433 requires rightfully std=c++-17 for this.
1573
1574 #ifdef __OCPN__ANDROID__
1575 return;
1576 #endif
1577
1578 #ifndef __linux__
1579 return;
1580 #else
1581 if(path.IsEmpty())
1582 return;
1583 int r = access(path.mb_str(), R_OK | W_OK);
1584 if (r == 0)
1585 return;
1586 OCPNMessageBox (this, BAD_ACCESS_MSG, wxString( _("OpenCPN Warning") ),
1587 wxICON_WARNING | wxOK, 60 );
1588 #endif
1589
1590 }
1591
CreatePanel(const wxString & title)1592 size_t options::CreatePanel(const wxString& title) {
1593 size_t id = m_pListbook->GetPageCount();
1594 /* This is the default empty content for any top tab.
1595 It'll be replaced when we call AddPage */
1596 wxPanel* panel = new wxPanel(m_pListbook, wxID_ANY, wxDefaultPosition,
1597 wxDefaultSize, wxTAB_TRAVERSAL, title);
1598 m_pListbook->AddPage(panel, title, FALSE, id);
1599 return id;
1600 }
1601
AddPage(size_t parent,const wxString & title)1602 wxScrolledWindow* options::AddPage(size_t parent, const wxString& title) {
1603 if (parent > m_pListbook->GetPageCount() - 1) {
1604 wxLogMessage(
1605 wxString::Format(
1606 _T("Warning: invalid parent in options::AddPage( %d, "), parent) +
1607 title + _T(" )"));
1608 return NULL;
1609 }
1610 wxNotebookPage* page = m_pListbook->GetPage(parent);
1611 wxNotebook* nb;
1612 wxScrolledWindow* sw;
1613
1614 int style = wxVSCROLL | wxTAB_TRAVERSAL;
1615 if ((nb = dynamic_cast<wxNotebook*>(page))) {
1616 sw = new wxScrolledWindow(page, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1617 style);
1618 sw->SetScrollRate(m_scrollRate, m_scrollRate);
1619 nb->AddPage(sw, title);
1620 } else if ((sw = dynamic_cast<wxScrolledWindow*>(page))) {
1621 wxString toptitle = m_pListbook->GetPageText(parent);
1622 wxNotebook* nb = new wxNotebook(m_pListbook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
1623 /* Only remove the tab from listbook, we still have original content in
1624 * {page} */
1625 m_pListbook->InsertPage(parent, nb, toptitle, FALSE, parent);
1626 m_pListbook->RemovePage(parent + 1);
1627 wxString previoustitle = page->GetName();
1628 page->Reparent(nb);
1629 nb->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler(options::OnSubNBPageChange), NULL, this);
1630
1631 nb->AddPage(page, previoustitle);
1632 /* wxNotebookPage is hidden under wxGTK after RemovePage/Reparent
1633 * we must explicitely Show() it */
1634 page->Show();
1635 sw = new wxScrolledWindow(nb, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1636 style);
1637 sw->SetScrollRate(m_scrollRate, m_scrollRate);
1638 nb->AddPage(sw, title);
1639 nb->ChangeSelection(0);
1640 } else { // This is the default content, we can replace it now
1641 sw = new wxScrolledWindow(m_pListbook, wxID_ANY, wxDefaultPosition,
1642 wxDefaultSize, style, title);
1643 sw->SetScrollRate(m_scrollRate, m_scrollRate);
1644 wxString toptitle = m_pListbook->GetPageText(parent);
1645 m_pListbook->InsertPage(parent, sw, toptitle, FALSE, parent);
1646 m_pListbook->DeletePage(parent + 1);
1647 }
1648
1649 #ifdef __OCPN__ANDROID__
1650 sw->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
1651 #endif
1652
1653 return sw;
1654 }
1655
DeletePluginPage(wxScrolledWindow * page)1656 bool options::DeletePluginPage(wxScrolledWindow* page) {
1657 for (size_t i = 0; i < m_pListbook->GetPageCount(); i++) {
1658 wxNotebookPage* pg = m_pListbook->GetPage(i);
1659 wxNotebook* nb = dynamic_cast<wxNotebook*>(pg);
1660
1661 if (nb) {
1662 for (size_t j = 0; j < nb->GetPageCount(); j++) {
1663 wxNotebookPage* spg = nb->GetPage(j);
1664 if (spg == page){
1665 nb->DeletePage(j);
1666 if (nb->GetPageCount() != 1)
1667 return TRUE;
1668 /* There's only one page, remove inner notebook */
1669 spg = nb->GetPage(0);
1670 spg->Reparent(m_pListbook);
1671 nb->RemovePage(0);
1672 wxString toptitle = m_pListbook->GetPageText(i);
1673 m_pListbook->DeletePage(i);
1674 m_pListbook->InsertPage(i, spg, toptitle, FALSE, i);
1675 return TRUE;
1676 }
1677 }
1678 } else if (pg == page) {
1679 /* There's only one page, replace it with empty panel */
1680 m_pListbook->DeletePage(i);
1681 wxPanel* panel = new wxPanel(m_pListbook);
1682 wxString toptitle = m_pListbook->GetPageText(i);
1683 m_pListbook->InsertPage(i, panel, toptitle, FALSE, i);
1684 return TRUE;
1685 }
1686 }
1687 return FALSE;
1688 }
1689
CreatePanel_NMEA_Compact(size_t parent,int border_size,int group_item_spacing)1690 void options::CreatePanel_NMEA_Compact(size_t parent, int border_size,
1691 int group_item_spacing) {
1692 m_pNMEAForm = AddPage(parent, _("NMEA"));
1693
1694 wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL);
1695 m_pNMEAForm->SetSizer(bSizer4);
1696 m_pNMEAForm->SetSizeHints(wxDefaultSize, wxDefaultSize);
1697
1698 wxBoxSizer* bSizerOuterContainer = new wxBoxSizer(wxVERTICAL);
1699
1700 wxStaticBoxSizer* sbSizerGeneral;
1701 sbSizerGeneral = new wxStaticBoxSizer(
1702 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("General")), wxVERTICAL);
1703
1704 wxBoxSizer* bSizer151;
1705 bSizer151 = new wxBoxSizer(wxVERTICAL);
1706
1707 wxBoxSizer* bSizer161;
1708 bSizer161 = new wxBoxSizer(wxVERTICAL);
1709
1710 m_cbFilterSogCog =
1711 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Filter NMEA COG/SOG"),
1712 wxDefaultPosition, wxDefaultSize, 0);
1713 m_cbFilterSogCog->SetValue(g_bfilter_cogsog);
1714 bSizer161->Add(m_cbFilterSogCog, 0, wxALL, 5);
1715
1716 wxFlexGridSizer* bSizer171 = new wxFlexGridSizer(0, 2, 0, 0);
1717 bSizer171->SetFlexibleDirection(wxBOTH);
1718 bSizer171->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
1719
1720 m_stFilterSec =
1721 new wxStaticText(m_pNMEAForm, wxID_ANY, _("Filter period (sec)"),
1722 wxDefaultPosition, wxDefaultSize, 0);
1723 // m_stFilterSec->Wrap( -1 );
1724
1725 int nspace = 5;
1726 #ifdef __WXGTK__
1727 nspace = 9;
1728 #endif
1729 bSizer171->Add(m_stFilterSec, 1, wxALL, nspace);
1730
1731 m_tFilterSec = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
1732 wxDefaultPosition, wxSize(100, -1), 0);
1733 wxString sfilt;
1734 sfilt.Printf(_T( "%d" ), g_COGFilterSec);
1735 m_tFilterSec->SetValue(sfilt);
1736 bSizer171->Add(m_tFilterSec, 1, wxALL, 4);
1737
1738 bSizer161->Add(bSizer171, 1, wxEXPAND, 5);
1739
1740 int cb_space = 2;
1741 m_cbNMEADebug =
1742 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Show NMEA Debug Window"),
1743 wxDefaultPosition, wxDefaultSize, 0);
1744 m_cbNMEADebug->SetValue(NMEALogWindow::Get().Active());
1745 bSizer161->Add(m_cbNMEADebug, 0, wxALL, cb_space);
1746
1747 m_cbFurunoGP3X =
1748 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Use Furuno GP3X for uploads"),
1749 wxDefaultPosition, wxDefaultSize, 0);
1750 m_cbFurunoGP3X->SetValue(g_GPS_Ident == _T( "FurunoGP3X" ));
1751 bSizer161->Add(m_cbFurunoGP3X, 0, wxALL, cb_space);
1752
1753 m_cbGarminUploadHost =
1754 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Use GRMN for uploads"),
1755 wxDefaultPosition, wxDefaultSize, 0);
1756 m_cbGarminUploadHost->SetValue(g_bGarminHostUpload);
1757 bSizer161->Add(m_cbGarminUploadHost, 0, wxALL, cb_space);
1758
1759 m_cbAPBMagnetic =
1760 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Use magnetic bearings in output sentence ECAPB"),
1761 wxDefaultPosition, wxDefaultSize, 0);
1762 m_cbAPBMagnetic->SetValue(g_bMagneticAPB);
1763 bSizer161->Add(m_cbAPBMagnetic, 0, wxALL, cb_space);
1764
1765 bSizer151->Add(bSizer161, 1, wxEXPAND, 5);
1766 sbSizerGeneral->Add(bSizer151, 1, wxEXPAND, 5);
1767 bSizerOuterContainer->Add(sbSizerGeneral, 0, wxALL | wxEXPAND, 5);
1768
1769 // Connections listbox, etc
1770 wxStaticBoxSizer* sbSizerLB = new wxStaticBoxSizer(
1771 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Data Connections")),
1772 wxVERTICAL);
1773
1774 wxBoxSizer* bSizer17;
1775 bSizer17 = new wxBoxSizer(wxVERTICAL);
1776
1777 //m_lcSources = new wxListCtrl(m_pNMEAForm, wxID_ANY, wxDefaultPosition,
1778 // wxSize(300, m_fontHeight * 2), wxLC_REPORT | wxLC_SINGLE_SEL);
1779 //bSizer17->Add(m_lcSources, 1, wxALL | wxEXPAND, 5);
1780
1781 wxBoxSizer* bSizer18;
1782 bSizer18 = new wxBoxSizer(wxHORIZONTAL);
1783 bSizer17->Add(bSizer18, 0, wxEXPAND, 5);
1784
1785 m_buttonAdd = new wxButton(m_pNMEAForm, wxID_ANY, _("Add") + _T("..."),
1786 wxDefaultPosition, wxDefaultSize, 0);
1787 bSizer18->Add(m_buttonAdd, 0, wxALL, 5);
1788
1789 m_buttonRemove = new wxButton(m_pNMEAForm, wxID_ANY, _("Remove"),
1790 wxDefaultPosition, wxDefaultSize, 0);
1791 m_buttonRemove->Enable(FALSE);
1792 bSizer18->Add(m_buttonRemove, 0, wxALL, 5);
1793
1794 sbSizerLB->Add(bSizer17, 1, wxEXPAND, 5);
1795 bSizerOuterContainer->Add(sbSizerLB, 0, wxEXPAND, 5);
1796
1797 // Connections Properties
1798 sbSizerConnectionProps = new wxStaticBoxSizer(
1799 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Properties")), wxVERTICAL);
1800
1801 wxFlexGridSizer* bSizer15 = new wxFlexGridSizer(0, 2, 0, 0);
1802 bSizer15->SetFlexibleDirection(wxBOTH);
1803 bSizer15->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
1804
1805 sbSizerConnectionProps->Add(bSizer15, 0, wxEXPAND, 0);
1806
1807 m_rbTypeSerial =
1808 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Serial"), wxDefaultPosition,
1809 wxDefaultSize, wxRB_GROUP);
1810 m_rbTypeSerial->SetValue(TRUE);
1811 bSizer15->Add(m_rbTypeSerial, 0, wxALL, 5);
1812
1813 m_rbTypeNet = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Network"),
1814 wxDefaultPosition, wxDefaultSize, 0);
1815 bSizer15->Add(m_rbTypeNet, 0, wxALL, 5);
1816
1817 if (OCPNPlatform::hasInternalGPS()) {
1818 m_rbTypeInternalGPS =
1819 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Built-in GPS"),
1820 wxDefaultPosition, wxDefaultSize, 0);
1821 bSizer15->Add(m_rbTypeInternalGPS, 0, wxALL, 5);
1822 } else
1823 m_rbTypeInternalGPS = NULL;
1824
1825 // has built-in Bluetooth
1826 if (OCPNPlatform::hasInternalBT()) {
1827 m_rbTypeInternalBT =
1828 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Built-in Bluetooth"),
1829 wxDefaultPosition, wxDefaultSize, 0);
1830 bSizer15->Add(m_rbTypeInternalBT, 0, wxALL, 5);
1831
1832 m_buttonScanBT = new wxButton(m_pNMEAForm, wxID_ANY, _("BT Scan") + _T("..."),
1833 wxDefaultPosition, wxDefaultSize);
1834 m_buttonScanBT->Hide();
1835 sbSizerConnectionProps->Add(m_buttonScanBT, 0, wxALL, 5);
1836
1837 wxBoxSizer* bSizer15a = new wxBoxSizer(wxHORIZONTAL);
1838 sbSizerConnectionProps->Add(bSizer15a, 0, wxEXPAND, 5);
1839
1840 m_stBTPairs = new wxStaticText(m_pNMEAForm, wxID_ANY, _("BT Sources"),
1841 wxDefaultPosition, wxDefaultSize, 0);
1842 // m_stBTPairs->Wrap( -1 );
1843 // m_stBTPairs->Hide();
1844 bSizer15a->Add(m_stBTPairs, 0, wxALL, 5);
1845
1846 wxArrayString mt;
1847 mt.Add(_T( "unscanned" ));
1848 m_choiceBTDataSources = new wxChoice(m_pNMEAForm, wxID_ANY,
1849 wxDefaultPosition, wxDefaultSize, mt);
1850 bSizer15a->Add(m_choiceBTDataSources, 1, wxEXPAND | wxTOP, 5);
1851
1852 #if 0
1853 m_BTscan_results.Clear();
1854 m_BTscan_results.Add(_T("None"));
1855
1856 m_BTscan_results = g_Platform->getBluetoothScanResults();
1857 m_choiceBTDataSources->Clear();
1858 m_choiceBTDataSources->Append(m_BTscan_results[0]); // scan status
1859
1860 unsigned int i=1;
1861 while( (i+1) < m_BTscan_results.GetCount()){
1862 wxString item1 = m_BTscan_results[i] + _T(";");
1863 wxString item2 = m_BTscan_results.Item(i+1);
1864 m_choiceBTDataSources->Append(item1 + item2);
1865
1866 i += 2;
1867 }
1868
1869 if( m_BTscan_results.GetCount() > 1){
1870 m_choiceBTDataSources->SetSelection( 1 );
1871 }
1872 #endif
1873
1874 m_choiceBTDataSources->Hide();
1875 m_buttonScanBT->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
1876 wxCommandEventHandler(options::OnScanBTClick), NULL,
1877 this);
1878 } else
1879 m_rbTypeInternalBT = NULL;
1880
1881 wxBoxSizer* gSizerNetPropsV = new wxBoxSizer(wxVERTICAL);
1882 sbSizerConnectionProps->Add(gSizerNetPropsV, 0, wxEXPAND, 5);
1883
1884 m_stNetProto = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Protocol"),
1885 wxDefaultPosition, wxDefaultSize, 0);
1886 // m_stNetProto->Wrap( -1 );
1887 gSizerNetPropsV->Add(m_stNetProto, 0, wxALL, 5);
1888
1889 wxBoxSizer* bSizer16;
1890 bSizer16 = new wxBoxSizer(wxHORIZONTAL);
1891 gSizerNetPropsV->Add(bSizer16, 1, wxEXPAND, 5);
1892
1893 m_rbNetProtoTCP =
1894 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("TCP"), wxDefaultPosition,
1895 wxDefaultSize, wxRB_GROUP);
1896 m_rbNetProtoTCP->Enable(TRUE);
1897
1898 bSizer16->Add(m_rbNetProtoTCP, 0, wxALL, 5);
1899
1900 m_rbNetProtoUDP = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("UDP"),
1901 wxDefaultPosition, wxDefaultSize, 0);
1902 m_rbNetProtoUDP->Enable(TRUE);
1903
1904 bSizer16->Add(m_rbNetProtoUDP, 0, wxALL, 5);
1905
1906 m_rbNetProtoGPSD = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("GPSD"),
1907 wxDefaultPosition, wxDefaultSize, 0);
1908 m_rbNetProtoGPSD->SetValue(TRUE);
1909 bSizer16->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
1910
1911 m_rbNetProtoSignalK = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Signal K"),
1912 wxDefaultPosition, wxDefaultSize, 0);
1913 m_rbNetProtoSignalK->Enable(TRUE);
1914 bSizer16->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
1915
1916 wxFlexGridSizer* fgSizer1a = new wxFlexGridSizer(0, 2, 0, 0);
1917 fgSizer1a->SetFlexibleDirection(wxBOTH);
1918 fgSizer1a->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
1919 gSizerNetPropsV->Add(fgSizer1a, 0, wxEXPAND, 5);
1920
1921 m_stNetAddr = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Address"),
1922 wxDefaultPosition, wxDefaultSize, 0);
1923 fgSizer1a->Add(m_stNetAddr, 0, wxALL, 5);
1924
1925 m_tNetAddress = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
1926 wxDefaultPosition, wxSize(m_fontHeight * 4, -1), 0);
1927 fgSizer1a->Add(m_tNetAddress, 1, wxTOP | wxALIGN_RIGHT, 5);
1928
1929 m_stNetPort = new wxStaticText(m_pNMEAForm, wxID_ANY, _("DataPort"),
1930 wxDefaultPosition, wxDefaultSize, 0);
1931 fgSizer1a->Add(m_stNetPort, 1, wxALL, 5);
1932
1933 m_tNetPort = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
1934 wxDefaultPosition, wxSize(200, -1), 0);
1935 fgSizer1a->Add(m_tNetPort, 1, wxTOP | wxALIGN_RIGHT, 5);
1936
1937 gSizerSerProps = new wxGridSizer(0, 1, 0, 0);
1938
1939 wxFlexGridSizer* fgSizer1 = new wxFlexGridSizer(0, 2, 0, 0);
1940 fgSizer1->SetFlexibleDirection(wxBOTH);
1941 fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
1942 gSizerSerProps->Add(fgSizer1, 0, wxEXPAND, 5);
1943
1944 m_stSerPort = new wxStaticText(m_pNMEAForm, wxID_ANY, _("DataPort"),
1945 wxDefaultPosition, wxDefaultSize, 0);
1946 // m_stSerPort->Wrap( -1 );
1947 fgSizer1->Add(m_stSerPort, 0, wxALL, 5);
1948
1949 m_comboPort = new wxComboBox(m_pNMEAForm, wxID_ANY, wxEmptyString,
1950 wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
1951 fgSizer1->Add(m_comboPort, 0, wxEXPAND | wxTOP, 5);
1952
1953 m_stSerBaudrate = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Baudrate"),
1954 wxDefaultPosition, wxDefaultSize, 0);
1955 // m_stSerBaudrate->Wrap( -1 );
1956 fgSizer1->Add(m_stSerBaudrate, 0, wxALL, 5);
1957
1958 wxString m_choiceBaudRateChoices[] = {
1959 _("150"), _("300"), _("600"), _("1200"), _("2400"),
1960 _("4800"), _("9600"), _("19200"), _("38400"), _("57600"),
1961 _("115200"), _("230400"), _("460800"), _("921600")};
1962 int m_choiceBaudRateNChoices =
1963 sizeof(m_choiceBaudRateChoices) / sizeof(wxString);
1964 m_choiceBaudRate =
1965 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1966 m_choiceBaudRateNChoices, m_choiceBaudRateChoices, 0);
1967 m_choiceBaudRate->SetSelection(0);
1968 fgSizer1->Add(m_choiceBaudRate, 1, wxEXPAND | wxTOP, 5);
1969
1970 m_stSerProtocol = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Protocol"),
1971 wxDefaultPosition, wxDefaultSize, 0);
1972 // m_stSerProtocol->Wrap( -1 );
1973 fgSizer1->Add(m_stSerProtocol, 0, wxALL, 5);
1974
1975 wxString m_choiceSerialProtocolChoices[] = {_("NMEA 0183"), _("NMEA 2000"),
1976 _("Seatalk")};
1977 int m_choiceSerialProtocolNChoices =
1978 sizeof(m_choiceSerialProtocolChoices) / sizeof(wxString);
1979 m_choiceSerialProtocol = new wxChoice(
1980 m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1981 m_choiceSerialProtocolNChoices, m_choiceSerialProtocolChoices, 0);
1982 m_choiceSerialProtocol->SetSelection(0);
1983 m_choiceSerialProtocol->Enable(FALSE);
1984
1985 fgSizer1->Add(m_choiceSerialProtocol, 1, wxEXPAND | wxTOP, 5);
1986 m_stPriority = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Priority"),
1987 wxDefaultPosition, wxDefaultSize, 0);
1988 // m_stPriority->Wrap( -1 );
1989 fgSizer1->Add(m_stPriority, 0, wxALL, 5);
1990
1991 wxString m_choicePriorityChoices[] = {_("0"), _("1"), _("2"), _("3"), _("4"),
1992 _("5"), _("6"), _("7"), _("8"), _("9")};
1993 int m_choicePriorityNChoices =
1994 sizeof(m_choicePriorityChoices) / sizeof(wxString);
1995 m_choicePriority =
1996 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1997 m_choicePriorityNChoices, m_choicePriorityChoices, 0);
1998 m_choicePriority->SetSelection(9);
1999 fgSizer1->Add(m_choicePriority, 0, wxEXPAND | wxTOP, 5);
2000
2001 wxBoxSizer* fgSizer5 = new wxBoxSizer(wxVERTICAL);
2002
2003 m_cbCheckCRC = new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Control checksum"),
2004 wxDefaultPosition, wxDefaultSize, 0);
2005 m_cbCheckCRC->SetValue(TRUE);
2006 m_cbCheckCRC->SetToolTip(
2007 _("If checked, only the sentences with a valid checksum are passed through"));
2008 fgSizer5->Add(m_cbCheckCRC, 0, wxALL, 5);
2009
2010 m_cbGarminHost =
2011 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Use GRMN mode for input"),
2012 wxDefaultPosition, wxDefaultSize, 0);
2013 m_cbGarminHost->SetValue(FALSE);
2014 fgSizer5->Add(m_cbGarminHost, 0, wxALL, 5);
2015 #ifndef USE_GARMINHOST
2016 // m_cbGarminHost->Hide();
2017 #endif
2018
2019 m_cbInput =
2020 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Receive Input on this Port"),
2021 wxDefaultPosition, wxDefaultSize, 0);
2022 fgSizer5->Add(m_cbInput, 0, wxALL, 5);
2023
2024 m_cbOutput = new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Output on this port"),
2025 wxDefaultPosition, wxDefaultSize, 0);
2026 fgSizer5->Add(m_cbOutput, 0, wxALL, 5);
2027
2028 wxFlexGridSizer* fgSizer5a = new wxFlexGridSizer(0, 2, 0, 0);
2029 fgSizer5a->SetFlexibleDirection(wxBOTH);
2030 fgSizer5a->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
2031
2032 m_stTalkerIdText = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Talker ID"),
2033 wxDefaultPosition, wxDefaultSize, 0);
2034 // m_stTalkerIdText->Wrap( -1 );
2035 fgSizer5a->Add(m_stTalkerIdText, 0, wxALL, 5);
2036
2037 m_TalkerIdText = new wxTextCtrl(m_pNMEAForm, ID_OPTEXTCTRL, _T(""),
2038 wxDefaultPosition, wxSize(50, -1), 0);
2039 m_TalkerIdText->SetMaxLength(2);
2040 fgSizer5a->Add(m_TalkerIdText, 0, wxALIGN_LEFT | wxALL, group_item_spacing);
2041
2042 m_stPrecision =
2043 new wxStaticText(m_pNMEAForm, wxID_ANY, _("APB bearing precision"),
2044 wxDefaultPosition, wxDefaultSize, 0);
2045
2046 // m_stPrecision->Wrap( -1 );
2047 fgSizer5a->Add(m_stPrecision, 0, wxALL, 5);
2048
2049 wxString m_choicePrecisionChoices[] = {_T("x"), _T("x.x"), _T("x.xx"),
2050 _T("x.xxx"), _T("x.xxxx")};
2051 int m_choicePrecisionNChoices =
2052 sizeof(m_choicePrecisionChoices) / sizeof(wxString);
2053 m_choicePrecision =
2054 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2055 m_choicePrecisionNChoices, m_choicePrecisionChoices, 0);
2056 m_choicePrecision->SetSelection(g_NMEAAPBPrecision);
2057 fgSizer5a->Add(m_choicePrecision, 0, wxALL, 5);
2058
2059 sbSizerConnectionProps->Add(gSizerSerProps, 0, wxEXPAND, 5);
2060 sbSizerConnectionProps->Add(fgSizer5, 0, wxEXPAND, 5);
2061 sbSizerConnectionProps->Add(fgSizer5a, 0, wxEXPAND, 5);
2062
2063 sbSizerInFilter = new wxStaticBoxSizer(
2064 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Input filtering")), wxVERTICAL);
2065
2066 wxBoxSizer* bSizer9;
2067 bSizer9 = new wxBoxSizer(wxVERTICAL);
2068
2069 m_rbIAccept =
2070 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Accept only sentences"),
2071 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
2072 bSizer9->Add(m_rbIAccept, 0, wxALL, 5);
2073
2074 m_rbIIgnore = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Ignore sentences"),
2075 wxDefaultPosition, wxDefaultSize, 0);
2076 bSizer9->Add(m_rbIIgnore, 0, wxALL, 5);
2077
2078 sbSizerInFilter->Add(bSizer9, 0, wxEXPAND, 5);
2079
2080 wxBoxSizer* bSizer11;
2081 bSizer11 = new wxBoxSizer(wxHORIZONTAL);
2082
2083 m_tcInputStc =
2084 new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString, wxDefaultPosition,
2085 wxSize(-1, -1), wxTE_READONLY);
2086 bSizer11->Add(m_tcInputStc, 1, wxALL, 5);
2087
2088 m_btnInputStcList =
2089 new wxButton(m_pNMEAForm, wxID_ANY, _T("..."), wxDefaultPosition,
2090 wxDefaultSize, wxBU_EXACTFIT);
2091 bSizer11->Add(m_btnInputStcList, 0, wxALL, 5);
2092
2093 sbSizerInFilter->Add(bSizer11, 0, wxEXPAND, 5);
2094 sbSizerConnectionProps->Add(sbSizerInFilter, 0, wxEXPAND, 5);
2095
2096 sbSizerOutFilter = new wxStaticBoxSizer(
2097 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Output filtering")),
2098 wxVERTICAL);
2099
2100 wxBoxSizer* bSizer10;
2101 bSizer10 = new wxBoxSizer(wxVERTICAL);
2102
2103 m_rbOAccept =
2104 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Transmit sentences"),
2105 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
2106 bSizer10->Add(m_rbOAccept, 0, wxALL, 5);
2107
2108 m_rbOIgnore = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Drop sentences"),
2109 wxDefaultPosition, wxDefaultSize, 0);
2110 bSizer10->Add(m_rbOIgnore, 0, wxALL, 5);
2111
2112 sbSizerOutFilter->Add(bSizer10, 0, wxEXPAND, 5);
2113
2114 wxBoxSizer* bSizer12;
2115 bSizer12 = new wxBoxSizer(wxHORIZONTAL);
2116
2117 m_tcOutputStc =
2118 new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString, wxDefaultPosition,
2119 wxSize(-1, -1), wxTE_READONLY);
2120 bSizer12->Add(m_tcOutputStc, 1, wxALL, 5);
2121
2122 m_btnOutputStcList =
2123 new wxButton(m_pNMEAForm, wxID_ANY, _T("..."), wxDefaultPosition,
2124 wxDefaultSize, wxBU_EXACTFIT);
2125 bSizer12->Add(m_btnOutputStcList, 0, wxALL, 5);
2126
2127 sbSizerOutFilter->Add(bSizer12, 0, wxEXPAND, 5);
2128 sbSizerConnectionProps->Add(sbSizerOutFilter, 0, wxEXPAND, 5);
2129
2130 bSizerOuterContainer->Add(sbSizerConnectionProps, 1, wxALL | wxEXPAND, 5);
2131
2132 bSizer4->Add(bSizerOuterContainer, 1, wxEXPAND, 5);
2133
2134 // Connect Events
2135 // m_lcSources->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
2136 // wxListEventHandler(options::OnSelectDatasource), NULL,
2137 // this);
2138 m_buttonAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2139 wxCommandEventHandler(options::OnAddDatasourceClick),
2140 NULL, this);
2141 m_buttonRemove->Connect(
2142 wxEVT_COMMAND_BUTTON_CLICKED,
2143 wxCommandEventHandler(options::OnRemoveDatasourceClick), NULL, this);
2144
2145 m_rbTypeSerial->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2146 wxCommandEventHandler(options::OnTypeSerialSelected),
2147 NULL, this);
2148 m_rbTypeNet->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2149 wxCommandEventHandler(options::OnTypeNetSelected), NULL,
2150 this);
2151
2152 if (m_rbTypeInternalGPS)
2153 m_rbTypeInternalGPS->Connect(
2154 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2155 wxCommandEventHandler(options::OnTypeGPSSelected), NULL, this);
2156 if (m_rbTypeInternalBT)
2157 m_rbTypeInternalBT->Connect(
2158 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2159 wxCommandEventHandler(options::OnTypeBTSelected), NULL, this);
2160
2161 m_rbNetProtoTCP->Connect(
2162 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2163 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2164 m_rbNetProtoUDP->Connect(
2165 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2166 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2167 m_rbNetProtoGPSD->Connect(
2168 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2169 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2170 m_rbNetProtoSignalK->Connect(
2171 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2172 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2173 m_tNetAddress->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2174 wxCommandEventHandler(options::OnConnValChange), NULL,
2175 this);
2176 m_tNetPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2177 wxCommandEventHandler(options::OnConnValChange), NULL,
2178 this);
2179 m_comboPort->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
2180 wxCommandEventHandler(options::OnConnValChange), NULL,
2181 this);
2182 m_comboPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2183 wxCommandEventHandler(options::OnConnValChange), NULL,
2184 this);
2185 m_choiceBaudRate->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
2186 wxCommandEventHandler(options::OnBaudrateChoice),
2187 NULL, this);
2188 m_choiceSerialProtocol->Connect(
2189 wxEVT_COMMAND_CHOICE_SELECTED,
2190 wxCommandEventHandler(options::OnProtocolChoice), NULL, this);
2191 m_choicePriority->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
2192 wxCommandEventHandler(options::OnConnValChange),
2193 NULL, this);
2194 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2195 wxCommandEventHandler(options::OnCrcCheck), NULL, this);
2196 m_cbGarminHost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2197 wxCommandEventHandler(options::OnUploadFormatChange),
2198 NULL, this);
2199 m_cbGarminUploadHost->Connect(
2200 wxEVT_COMMAND_CHECKBOX_CLICKED,
2201 wxCommandEventHandler(options::OnUploadFormatChange), NULL, this);
2202 m_cbFurunoGP3X->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2203 wxCommandEventHandler(options::OnUploadFormatChange),
2204 NULL, this);
2205 m_rbIAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2206 wxCommandEventHandler(options::OnRbAcceptInput), NULL,
2207 this);
2208 m_rbIIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2209 wxCommandEventHandler(options::OnRbIgnoreInput), NULL,
2210 this);
2211 m_tcInputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2212 wxCommandEventHandler(options::OnConnValChange), NULL,
2213 this);
2214 m_btnInputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2215 wxCommandEventHandler(options::OnBtnIStcs), NULL,
2216 this);
2217 m_cbInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2218 wxCommandEventHandler(options::OnCbInput), NULL, this);
2219 m_cbOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2220 wxCommandEventHandler(options::OnCbOutput), NULL, this);
2221 m_rbOAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2222 wxCommandEventHandler(options::OnRbOutput), NULL, this);
2223 m_rbOIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2224 wxCommandEventHandler(options::OnRbOutput), NULL, this);
2225 m_tcOutputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2226 wxCommandEventHandler(options::OnConnValChange), NULL,
2227 this);
2228 m_btnOutputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2229 wxCommandEventHandler(options::OnBtnOStcs), NULL,
2230 this);
2231 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2232 wxCommandEventHandler(options::OnConnValChange), NULL, this);
2233 pOpenGL->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2234 wxCommandEventHandler(options::OnGLClicked), NULL, this);
2235
2236 m_cbNMEADebug->Connect(
2237 wxEVT_COMMAND_CHECKBOX_CLICKED,
2238 wxCommandEventHandler(options::OnShowGpsWindowCheckboxClick), NULL, this);
2239 m_cbFilterSogCog->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2240 wxCommandEventHandler(options::OnValChange), NULL,
2241 this);
2242 m_tFilterSec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2243 wxCommandEventHandler(options::OnValChange), NULL,
2244 this);
2245 m_cbAPBMagnetic->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2246 wxCommandEventHandler(options::OnValChange), NULL,
2247 this);
2248
2249 #if 0
2250 m_lcSources->Connect(wxEVT_LEFT_DOWN,
2251 wxMouseEventHandler(options::OnConnectionToggleEnableMouse),
2252 NULL, this);
2253 #if wxCHECK_VERSION(2, 9, 0)
2254 m_lcSources->Connect(wxEVT_LIST_ITEM_ACTIVATED,
2255 wxListEventHandler(options::OnConnectionToggleEnable),
2256 NULL, this);
2257 #endif
2258
2259 wxString columns[] = {_("On"), _("Type"), _("Data Port"), _("Prio"),
2260 _("Parm"), _("I/O"), _("Filters")};
2261 for (int i = 0; i < 7; ++i) {
2262 wxListItem col;
2263 col.SetId(i);
2264 col.SetText(columns[i]);
2265 m_lcSources->InsertColumn(i, col);
2266 }
2267
2268 // Build the image list
2269 wxImageList* imglist = new wxImageList(16, 16, TRUE, 1);
2270 wxBitmap unchecked_bmp(16, 16), checked_bmp(16, 16);
2271 wxMemoryDC renderer_dc;
2272
2273 // Unchecked
2274 renderer_dc.SelectObject(unchecked_bmp);
2275 renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(
2276 GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
2277 renderer_dc.Clear();
2278 wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16),
2279 0);
2280
2281 // Checked
2282 renderer_dc.SelectObject(checked_bmp);
2283 renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(
2284 GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
2285 renderer_dc.Clear();
2286 wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16),
2287 wxCONTROL_CHECKED);
2288
2289 // Deselect the renderer Object
2290 renderer_dc.SelectObject(wxNullBitmap);
2291
2292 imglist->Add(unchecked_bmp);
2293 imglist->Add(checked_bmp);
2294 m_lcSources->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
2295
2296 m_lcSources->Refresh();
2297 #endif
2298 FillSourceList();
2299
2300 ShowNMEACommon(FALSE);
2301 ShowNMEASerial(FALSE);
2302 ShowNMEANet(FALSE);
2303 connectionsaved = TRUE;
2304 }
2305
CreatePanel_NMEA(size_t parent,int border_size,int group_item_spacing)2306 void options::CreatePanel_NMEA(size_t parent, int border_size,
2307 int group_item_spacing) {
2308 m_pNMEAForm = AddPage(parent, _("NMEA"));
2309
2310 wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL);
2311 m_pNMEAForm->SetSizer(bSizer4);
2312 m_pNMEAForm->SetSizeHints(wxDefaultSize, wxDefaultSize);
2313
2314 wxBoxSizer* bSizerOuterContainer = new wxBoxSizer(wxVERTICAL);
2315
2316 wxStaticBoxSizer* sbSizerGeneral;
2317 sbSizerGeneral = new wxStaticBoxSizer(
2318 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("General")), wxVERTICAL);
2319
2320 wxBoxSizer* bSizer151;
2321 bSizer151 = new wxBoxSizer(wxVERTICAL);
2322
2323 wxBoxSizer* bSizer161;
2324 bSizer161 = new wxBoxSizer(wxVERTICAL);
2325
2326 wxBoxSizer* bSizer171;
2327 bSizer171 = new wxBoxSizer(wxHORIZONTAL);
2328
2329 m_cbFilterSogCog = new wxCheckBox(m_pNMEAForm, wxID_ANY,
2330 _("Filter NMEA Course and Speed data"),
2331 wxDefaultPosition, wxDefaultSize, 0);
2332 m_cbFilterSogCog->SetValue(g_bfilter_cogsog);
2333 bSizer171->Add(m_cbFilterSogCog, 0, wxALL, 5);
2334
2335 m_stFilterSec =
2336 new wxStaticText(m_pNMEAForm, wxID_ANY, _("Filter period (sec)"),
2337 wxDefaultPosition, wxDefaultSize, 0);
2338 m_stFilterSec->Wrap(-1);
2339
2340 int nspace = 5;
2341 #ifdef __WXGTK__
2342 nspace = 9;
2343 #endif
2344 bSizer171->Add(m_stFilterSec, 0, wxALL, nspace);
2345
2346 m_tFilterSec = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
2347 wxDefaultPosition, wxDefaultSize, 0);
2348 wxString sfilt;
2349 sfilt.Printf(_T("%d"), g_COGFilterSec);
2350 m_tFilterSec->SetValue(sfilt);
2351 bSizer171->Add(m_tFilterSec, 0, wxALL, 4);
2352 bSizer161->Add(bSizer171, 1, wxEXPAND, 5);
2353
2354 int cb_space = 2;
2355 m_cbNMEADebug =
2356 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Show NMEA Debug Window"),
2357 wxDefaultPosition, wxDefaultSize, 0);
2358 m_cbNMEADebug->SetValue(NMEALogWindow::Get().Active());
2359 bSizer161->Add(m_cbNMEADebug, 0, wxALL, cb_space);
2360
2361 m_cbFurunoGP3X =
2362 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Format uploads for Furuno GP3X"),
2363 wxDefaultPosition, wxDefaultSize, 0);
2364 m_cbFurunoGP3X->SetValue(g_GPS_Ident == _T( "FurunoGP3X" ));
2365 bSizer161->Add(m_cbFurunoGP3X, 0, wxALL, cb_space);
2366
2367 m_cbGarminUploadHost = new wxCheckBox(
2368 m_pNMEAForm, wxID_ANY, _("Use Garmin GRMN (Host) mode for uploads"),
2369 wxDefaultPosition, wxDefaultSize, 0);
2370 m_cbGarminUploadHost->SetValue(g_bGarminHostUpload);
2371 bSizer161->Add(m_cbGarminUploadHost, 0, wxALL, cb_space);
2372
2373 m_cbAPBMagnetic =
2374 new wxCheckBox(m_pNMEAForm, wxID_ANY,
2375 _("Use magnetic bearings in output sentence ECAPB"),
2376 wxDefaultPosition, wxDefaultSize, 0);
2377 m_cbAPBMagnetic->SetValue(g_bMagneticAPB);
2378 bSizer161->Add(m_cbAPBMagnetic, 0, wxALL, cb_space);
2379
2380 bSizer151->Add(bSizer161, 1, wxEXPAND, 5);
2381 sbSizerGeneral->Add(bSizer151, 1, wxEXPAND, 5);
2382 bSizerOuterContainer->Add(sbSizerGeneral, 0, wxALL | wxEXPAND, 5);
2383
2384 // Connections listbox, etc
2385 wxStaticBoxSizer* sbSizerLB = new wxStaticBoxSizer(
2386 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Data Connections")),
2387 wxVERTICAL);
2388
2389
2390
2391 /*
2392 wxBoxSizer* bSizer17;
2393 bSizer17 = new wxBoxSizer(wxVERTICAL);
2394
2395 m_lcSources = new wxListCtrl(m_pNMEAForm, wxID_ANY, wxDefaultPosition,
2396 wxSize(-1, 150), wxLC_REPORT | wxLC_SINGLE_SEL);
2397 bSizer17->Add(m_lcSources, 1, wxALL | wxEXPAND, 5);
2398 */
2399
2400 wxPanel *cPanel = new wxPanel(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,-1)), wxBG_STYLE_ERASE );
2401 sbSizerLB->Add(cPanel, 0, wxALL|wxEXPAND, 5);
2402
2403 wxBoxSizer *boxSizercPanel = new wxBoxSizer(wxVERTICAL);
2404 cPanel->SetSizer(boxSizercPanel);
2405
2406 m_scrollWinConnections = new wxScrolledWindow(cPanel, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(this, wxSize(-1,80)), wxBORDER_RAISED | wxVSCROLL | wxBG_STYLE_ERASE );
2407 m_scrollWinConnections->SetScrollRate(5, 5);
2408 boxSizercPanel->Add(m_scrollWinConnections, 0, wxALL|wxEXPAND, 5);
2409
2410 boxSizerConnections = new wxBoxSizer(wxVERTICAL);
2411 m_scrollWinConnections->SetSizer(boxSizerConnections);
2412
2413
2414 bSizerOuterContainer->Add(sbSizerLB, 0, wxEXPAND, 5);
2415
2416
2417 wxBoxSizer* bSizer18;
2418 bSizer18 = new wxBoxSizer(wxHORIZONTAL);
2419 sbSizerLB->Add(bSizer18, 1, wxEXPAND, 5);
2420
2421 m_buttonAdd = new wxButton(m_pNMEAForm, wxID_ANY, _("Add Connection"),
2422 wxDefaultPosition, wxDefaultSize, 0);
2423 bSizer18->Add(m_buttonAdd, 0, wxALL, 5);
2424
2425 m_buttonRemove = new wxButton(m_pNMEAForm, wxID_ANY, _("Remove Connection"),
2426 wxDefaultPosition, wxDefaultSize, 0);
2427 m_buttonRemove->Enable(FALSE);
2428 bSizer18->Add(m_buttonRemove, 0, wxALL, 5);
2429
2430
2431 // wxBoxSizer* bSizer19 = new wxBoxSizer(wxHORIZONTAL);
2432 // sbSizerLB->Add(bSizer19, 1, wxEXPAND, 5);
2433 //
2434 wxFont *dFont = GetOCPNScaledFont_PlugIn(_("Dialog"));
2435 double font_size = dFont->GetPointSize() * 17/16;
2436 wxFont *bFont = wxTheFontList->FindOrCreateFont( font_size, dFont->GetFamily(), dFont->GetStyle(), wxFONTWEIGHT_BOLD);
2437 //
2438 // m_stEditCon = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Edit Selected Connection"));
2439 // m_stEditCon->SetFont(*bFont);
2440 // bSizer19->Add(m_stEditCon, 0, wxALL | wxEXPAND | wxALIGN_CENTER_HORIZONTAL, 5);
2441 //
2442
2443 // Connections Properties
2444 m_sbConnEdit = new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Edit Selected Connection"));
2445 m_sbConnEdit->SetFont(*bFont);
2446
2447 sbSizerConnectionProps = new wxStaticBoxSizer( m_sbConnEdit, wxVERTICAL);
2448
2449 wxBoxSizer* bSizer15;
2450 bSizer15 = new wxBoxSizer(wxHORIZONTAL);
2451
2452 sbSizerConnectionProps->Add(bSizer15, 0, wxTOP | wxEXPAND, 5);
2453
2454 m_rbTypeSerial =
2455 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Serial"), wxDefaultPosition,
2456 wxDefaultSize, wxRB_GROUP);
2457 m_rbTypeSerial->SetValue(TRUE);
2458 bSizer15->Add(m_rbTypeSerial, 0, wxALL, 5);
2459
2460 m_rbTypeNet = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Network"),
2461 wxDefaultPosition, wxDefaultSize, 0);
2462 bSizer15->Add(m_rbTypeNet, 0, wxALL, 5);
2463
2464 if (OCPNPlatform::hasInternalGPS()) {
2465 m_rbTypeInternalGPS =
2466 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Built-in GPS"),
2467 wxDefaultPosition, wxDefaultSize, 0);
2468 bSizer15->Add(m_rbTypeInternalGPS, 0, wxALL, 5);
2469 } else
2470 m_rbTypeInternalGPS = NULL;
2471
2472 // has built-in Bluetooth
2473 if (OCPNPlatform::hasInternalBT()) {
2474 m_rbTypeInternalBT =
2475 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Built-in Bluetooth SPP"),
2476 wxDefaultPosition, wxDefaultSize, 0);
2477 bSizer15->Add(m_rbTypeInternalBT, 0, wxALL, 5);
2478
2479 m_buttonScanBT = new wxButton(m_pNMEAForm, wxID_ANY, _("BT Scan"),
2480 wxDefaultPosition, wxDefaultSize);
2481 m_buttonScanBT->Hide();
2482
2483 wxBoxSizer* bSizer15a = new wxBoxSizer(wxHORIZONTAL);
2484 sbSizerConnectionProps->Add(bSizer15a, 0, wxEXPAND, 5);
2485
2486 bSizer15a->Add(m_buttonScanBT, 0, wxALL, 5);
2487
2488 m_stBTPairs =
2489 new wxStaticText(m_pNMEAForm, wxID_ANY, _("Bluetooth Data Sources"),
2490 wxDefaultPosition, wxDefaultSize, 0);
2491 m_stBTPairs->Wrap(-1);
2492 m_stBTPairs->Hide();
2493 bSizer15a->Add(m_stBTPairs, 0, wxALL, 5);
2494
2495 wxArrayString mt;
2496 mt.Add(_T( "unscanned" ));
2497 m_choiceBTDataSources = new wxChoice(m_pNMEAForm, wxID_ANY,
2498 wxDefaultPosition, wxDefaultSize, mt);
2499
2500 #if 0
2501 m_BTscan_results.Clear();
2502 m_BTscan_results.Add(_T("None"));
2503
2504 m_BTscan_results = g_Platform->getBluetoothScanResults();
2505 m_choiceBTDataSources->Clear();
2506 m_choiceBTDataSources->Append(m_BTscan_results[0]); // scan status
2507
2508 unsigned int i=1;
2509 while( (i+1) < m_BTscan_results.GetCount()){
2510 wxString item1 = m_BTscan_results[i] + _T(";");
2511 wxString item2 = m_BTscan_results.Item(i+1);
2512 m_choiceBTDataSources->Append(item1 + item2);
2513
2514 i += 2;
2515 }
2516
2517 if( m_BTscan_results.GetCount() > 1){
2518 m_choiceBTDataSources->SetSelection( 1 );
2519 }
2520 #endif
2521
2522 m_choiceBTDataSources->Hide();
2523 bSizer15a->Add(m_choiceBTDataSources, 1, wxEXPAND | wxTOP, 5);
2524
2525 m_buttonScanBT->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2526 wxCommandEventHandler(options::OnScanBTClick), NULL,
2527 this);
2528 } else
2529 m_rbTypeInternalBT = NULL;
2530
2531 gSizerNetProps = new wxGridSizer(0, 2, 0, 0);
2532
2533 m_stNetProto = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Protocol"),
2534 wxDefaultPosition, wxDefaultSize, 0);
2535 m_stNetProto->Wrap(-1);
2536 gSizerNetProps->Add(m_stNetProto, 0, wxALL, 5);
2537
2538 wxBoxSizer* bSizer16;
2539 bSizer16 = new wxBoxSizer(wxHORIZONTAL);
2540
2541 m_rbNetProtoTCP =
2542 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("TCP"), wxDefaultPosition,
2543 wxDefaultSize, wxRB_GROUP);
2544 m_rbNetProtoTCP->Enable(TRUE);
2545
2546 bSizer16->Add(m_rbNetProtoTCP, 0, wxALL, 5);
2547
2548 m_rbNetProtoUDP = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("UDP"),
2549 wxDefaultPosition, wxDefaultSize, 0);
2550 m_rbNetProtoUDP->Enable(TRUE);
2551
2552 bSizer16->Add(m_rbNetProtoUDP, 0, wxALL, 5);
2553
2554 m_rbNetProtoGPSD = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("GPSD"),
2555 wxDefaultPosition, wxDefaultSize, 0);
2556 m_rbNetProtoGPSD->SetValue(TRUE);
2557 bSizer16->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
2558
2559 m_rbNetProtoSignalK = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Signal K"),
2560 wxDefaultPosition, wxDefaultSize, 0);
2561 m_rbNetProtoSignalK->Enable(TRUE);
2562 bSizer16->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
2563
2564 gSizerNetProps->Add(bSizer16, 1, wxEXPAND, 5);
2565
2566 m_stNetAddr = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Address"),
2567 wxDefaultPosition, wxDefaultSize, 0);
2568 m_stNetAddr->Wrap(-1);
2569 gSizerNetProps->Add(m_stNetAddr, 0, wxALL, 5);
2570
2571 m_tNetAddress = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
2572 wxDefaultPosition, wxDefaultSize, 0);
2573 gSizerNetProps->Add(m_tNetAddress, 0, wxEXPAND | wxTOP, 5);
2574
2575 m_stNetPort = new wxStaticText(m_pNMEAForm, wxID_ANY, _("DataPort"),
2576 wxDefaultPosition, wxDefaultSize, 0);
2577 m_stNetPort->Wrap(-1);
2578 gSizerNetProps->Add(m_stNetPort, 0, wxALL, 5);
2579
2580 m_tNetPort = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
2581 wxDefaultPosition, wxDefaultSize, 0);
2582 gSizerNetProps->Add(m_tNetPort, 1, wxEXPAND | wxTOP, 5);
2583
2584 // User Comments
2585 m_stNetComment = new wxStaticText(m_pNMEAForm, wxID_ANY, _("User Comment"),
2586 wxDefaultPosition, wxDefaultSize, 0);
2587 m_stNetComment->Wrap(-1);
2588 gSizerNetProps->Add(m_stNetComment, 0, wxALL, 5);
2589
2590 m_tNetComment = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
2591 wxDefaultPosition, wxDefaultSize, 0);
2592 gSizerNetProps->Add(m_tNetComment, 1, wxEXPAND | wxTOP, 5);
2593
2594
2595 sbSizerConnectionProps->Add(gSizerNetProps, 0, wxEXPAND, 5);
2596
2597 gSizerSerProps = new wxGridSizer(0, 1, 0, 0);
2598
2599 wxFlexGridSizer* fgSizer1;
2600 fgSizer1 = new wxFlexGridSizer(0, 4, 0, 0);
2601 fgSizer1->SetFlexibleDirection(wxBOTH);
2602 fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
2603
2604 m_stSerPort = new wxStaticText(m_pNMEAForm, wxID_ANY, _("DataPort"),
2605 wxDefaultPosition, wxDefaultSize, 0);
2606 m_stSerPort->Wrap(-1);
2607 fgSizer1->Add(m_stSerPort, 0, wxALL, 5);
2608
2609 m_comboPort = new wxComboBox(m_pNMEAForm, wxID_ANY, wxEmptyString,
2610 wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
2611 fgSizer1->Add(m_comboPort, 0, wxEXPAND | wxTOP, 5);
2612
2613 m_stSerBaudrate = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Baudrate"),
2614 wxDefaultPosition, wxDefaultSize, 0);
2615 m_stSerBaudrate->Wrap(-1);
2616 fgSizer1->Add(m_stSerBaudrate, 0, wxALL, 5);
2617
2618 wxString m_choiceBaudRateChoices[] = {
2619 _("150"), _("300"), _("600"), _("1200"), _("2400"),
2620 _("4800"), _("9600"), _("19200"), _("38400"), _("57600"),
2621 _("115200"), _("230400"), _("460800"), _("921600")};
2622 int m_choiceBaudRateNChoices =
2623 sizeof(m_choiceBaudRateChoices) / sizeof(wxString);
2624 m_choiceBaudRate =
2625 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2626 m_choiceBaudRateNChoices, m_choiceBaudRateChoices, 0);
2627 m_choiceBaudRate->SetSelection(0);
2628 fgSizer1->Add(m_choiceBaudRate, 1, wxEXPAND | wxTOP, 5);
2629
2630 m_stSerProtocol = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Protocol"),
2631 wxDefaultPosition, wxDefaultSize, 0);
2632 m_stSerProtocol->Wrap(-1);
2633 fgSizer1->Add(m_stSerProtocol, 0, wxALL, 5);
2634
2635 wxString m_choiceSerialProtocolChoices[] = {_("NMEA 0183"), _("NMEA 2000"),
2636 _("Seatalk")};
2637 int m_choiceSerialProtocolNChoices =
2638 sizeof(m_choiceSerialProtocolChoices) / sizeof(wxString);
2639 m_choiceSerialProtocol = new wxChoice(
2640 m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2641 m_choiceSerialProtocolNChoices, m_choiceSerialProtocolChoices, 0);
2642 m_choiceSerialProtocol->SetSelection(0);
2643 m_choiceSerialProtocol->Enable(FALSE);
2644 fgSizer1->Add(m_choiceSerialProtocol, 1, wxEXPAND | wxTOP, 5);
2645
2646 m_stPriority = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Priority"),
2647 wxDefaultPosition, wxDefaultSize, 0);
2648 m_stPriority->Wrap(-1);
2649 fgSizer1->Add(m_stPriority, 0, wxALL, 5);
2650
2651 wxString m_choicePriorityChoices[] = {_("0"), _("1"), _("2"), _("3"), _("4"),
2652 _("5"), _("6"), _("7"), _("8"), _("9")};
2653 int m_choicePriorityNChoices =
2654 sizeof(m_choicePriorityChoices) / sizeof(wxString);
2655 m_choicePriority =
2656 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2657 m_choicePriorityNChoices, m_choicePriorityChoices, 0);
2658 m_choicePriority->SetSelection(9);
2659 fgSizer1->Add(m_choicePriority, 0, wxEXPAND | wxTOP, 5);
2660
2661 gSizerSerProps->Add(fgSizer1, 0, wxEXPAND, 5);
2662
2663 wxFlexGridSizer* fgSizer5;
2664 fgSizer5 = new wxFlexGridSizer(0, 2, 0, 0);
2665 fgSizer5->SetFlexibleDirection(wxBOTH);
2666 fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
2667
2668 // User Comments
2669 m_stSerialComment = new wxStaticText(m_pNMEAForm, wxID_ANY, _("User Comment"),
2670 wxDefaultPosition, wxDefaultSize, 0);
2671 m_stSerialComment->Wrap(-1);
2672 fgSizer5->Add(m_stSerialComment, 0, wxALL, 5);
2673
2674 m_tSerialComment = new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString,
2675 wxDefaultPosition, wxDefaultSize, 0);
2676 fgSizer5->Add(m_tSerialComment, 1, wxEXPAND | wxTOP, 5);
2677
2678 m_cbCheckCRC = new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Control checksum"),
2679 wxDefaultPosition, wxDefaultSize, 0);
2680 m_cbCheckCRC->SetValue(TRUE);
2681 m_cbCheckCRC->SetToolTip(
2682 _("If checked, only the sentences with a valid checksum are passed through"));
2683 fgSizer5->Add(m_cbCheckCRC, 0, wxALL, 5);
2684
2685 m_cbGarminHost = new wxCheckBox(m_pNMEAForm, wxID_ANY,
2686 _("Use Garmin (GRMN) mode for input"),
2687 wxDefaultPosition, wxDefaultSize, 0);
2688 m_cbGarminHost->SetValue(FALSE);
2689 fgSizer5->Add(m_cbGarminHost, 0, wxALL, 5);
2690 #ifndef USE_GARMINHOST
2691 m_cbGarminHost->Hide();
2692 #endif
2693
2694 m_cbInput =
2695 new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Receive Input on this Port"),
2696 wxDefaultPosition, wxDefaultSize, 0);
2697 fgSizer5->Add(m_cbInput, 0, wxALL, 5);
2698
2699 m_cbOutput =
2700 new wxCheckBox(m_pNMEAForm, wxID_ANY,
2701 wxString::Format(_T("%s (%s)"), _("Output on this port"), _("as autopilot or NMEA repeater")),
2702 wxDefaultPosition, wxDefaultSize, 0);
2703 fgSizer5->Add(m_cbOutput, 0, wxALL, 5);
2704
2705 m_stTalkerIdText = new wxStaticText(m_pNMEAForm, wxID_ANY,
2706 wxString::Format(_T("%s (%s)"), _("Talker ID"), _("blank = default ID")),
2707 wxDefaultPosition, wxDefaultSize, 0);
2708 m_stTalkerIdText->Wrap(-1);
2709 fgSizer5->Add(m_stTalkerIdText, 0, wxALL, 5);
2710
2711 m_TalkerIdText = new wxTextCtrl(m_pNMEAForm, ID_OPTEXTCTRL, _T( "" ),
2712 wxDefaultPosition, wxSize(50, -1), 0);
2713 m_TalkerIdText->SetMaxLength(2);
2714 fgSizer5->Add(m_TalkerIdText, 0, wxALIGN_LEFT | wxALL, group_item_spacing);
2715
2716 m_stPrecision =
2717 new wxStaticText(m_pNMEAForm, wxID_ANY, _("APB bearing precision"),
2718 wxDefaultPosition, wxDefaultSize, 0);
2719
2720 m_stPrecision->Wrap(-1);
2721 fgSizer5->Add(m_stPrecision, 0, wxALL, 5);
2722
2723 wxString m_choicePrecisionChoices[] = {_("x"), _("x.x"), _("x.xx"),
2724 _("x.xxx"), _("x.xxxx")};
2725 int m_choicePrecisionNChoices =
2726 sizeof(m_choicePrecisionChoices) / sizeof(wxString);
2727 m_choicePrecision =
2728 new wxChoice(m_pNMEAForm, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2729 m_choicePrecisionNChoices, m_choicePrecisionChoices, 0);
2730 m_choicePrecision->SetSelection(g_NMEAAPBPrecision);
2731 fgSizer5->Add(m_choicePrecision, 0, wxALL, 5);
2732
2733 // signalK discovery enable
2734 m_cbCheckSKDiscover = new wxCheckBox(m_pNMEAForm, wxID_ANY, _("Automatic server discovery"),
2735 wxDefaultPosition, wxDefaultSize, 0);
2736 m_cbCheckSKDiscover->SetValue(TRUE);
2737 m_cbCheckSKDiscover->SetToolTip(_("If checked, signal K server will be discovered automatically"));
2738 fgSizer5->Add(m_cbCheckSKDiscover, 0, wxALL, 5);
2739
2740 // signal K "Discover now" button
2741 m_ButtonSKDiscover = new wxButton(m_pNMEAForm, wxID_ANY, _("Discover now..."), wxDefaultPosition, wxDefaultSize, 0);
2742 m_ButtonSKDiscover->Hide();
2743 fgSizer5->Add(m_ButtonSKDiscover, 0, wxALL, 5);
2744
2745 // signalK Server Status
2746 m_StaticTextSKServerStatus = new wxStaticText(m_pNMEAForm, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, 0);
2747 fgSizer5->Add(m_StaticTextSKServerStatus, 0, wxALL, 5);
2748
2749 sbSizerConnectionProps->Add(gSizerSerProps, 0, wxEXPAND, 5);
2750 sbSizerConnectionProps->Add(fgSizer5, 0, wxEXPAND, 5);
2751
2752 sbSizerInFilter = new wxStaticBoxSizer(
2753 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Input filtering")), wxVERTICAL);
2754
2755 wxBoxSizer* bSizer9;
2756 bSizer9 = new wxBoxSizer(wxHORIZONTAL);
2757
2758 m_rbIAccept =
2759 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Accept only sentences"),
2760 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
2761 bSizer9->Add(m_rbIAccept, 0, wxALL, 5);
2762
2763 m_rbIIgnore = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Ignore sentences"),
2764 wxDefaultPosition, wxDefaultSize, 0);
2765 bSizer9->Add(m_rbIIgnore, 0, wxALL, 5);
2766
2767 sbSizerInFilter->Add(bSizer9, 0, wxEXPAND, 5);
2768
2769 wxBoxSizer* bSizer11;
2770 bSizer11 = new wxBoxSizer(wxHORIZONTAL);
2771
2772 m_tcInputStc =
2773 new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString, wxDefaultPosition,
2774 wxDefaultSize, wxTE_READONLY);
2775 bSizer11->Add(m_tcInputStc, 1, wxALL | wxEXPAND, 5);
2776
2777 m_btnInputStcList =
2778 new wxButton(m_pNMEAForm, wxID_ANY, _T("..."), wxDefaultPosition,
2779 wxDefaultSize, wxBU_EXACTFIT);
2780 bSizer11->Add(m_btnInputStcList, 0, wxALL, 5);
2781
2782 sbSizerInFilter->Add(bSizer11, 0, wxEXPAND, 5);
2783
2784 sbSizerConnectionProps->Add(sbSizerInFilter, 0, wxEXPAND, 5);
2785
2786 sbSizerOutFilter = new wxStaticBoxSizer(
2787 new wxStaticBox(m_pNMEAForm, wxID_ANY, _("Output filtering")),
2788 wxVERTICAL);
2789
2790 wxBoxSizer* bSizer10;
2791 bSizer10 = new wxBoxSizer(wxHORIZONTAL);
2792
2793 m_rbOAccept =
2794 new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Transmit sentences"),
2795 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
2796 bSizer10->Add(m_rbOAccept, 0, wxALL, 5);
2797
2798 m_rbOIgnore = new wxRadioButton(m_pNMEAForm, wxID_ANY, _("Drop sentences"),
2799 wxDefaultPosition, wxDefaultSize, 0);
2800 bSizer10->Add(m_rbOIgnore, 0, wxALL, 5);
2801
2802 sbSizerOutFilter->Add(bSizer10, 0, wxEXPAND, 5);
2803
2804 wxBoxSizer* bSizer12;
2805 bSizer12 = new wxBoxSizer(wxHORIZONTAL);
2806
2807 m_tcOutputStc =
2808 new wxTextCtrl(m_pNMEAForm, wxID_ANY, wxEmptyString, wxDefaultPosition,
2809 wxDefaultSize, wxTE_READONLY);
2810 bSizer12->Add(m_tcOutputStc, 1, wxALL | wxEXPAND, 5);
2811
2812 m_btnOutputStcList =
2813 new wxButton(m_pNMEAForm, wxID_ANY, _T("..."), wxDefaultPosition,
2814 wxDefaultSize, wxBU_EXACTFIT);
2815 bSizer12->Add(m_btnOutputStcList, 0, wxALL, 5);
2816
2817 sbSizerOutFilter->Add(bSizer12, 0, wxEXPAND, 5);
2818 sbSizerConnectionProps->Add(sbSizerOutFilter, 0, wxEXPAND, 5);
2819
2820 bSizerOuterContainer->Add(sbSizerConnectionProps, 1, wxALL | wxEXPAND, 5);
2821
2822 bSizer4->Add(bSizerOuterContainer, 1, wxEXPAND, 5);
2823
2824 // Connect Events
2825 // m_lcSources->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
2826 // wxListEventHandler(options::OnSelectDatasource), NULL,
2827 // this);
2828 m_buttonAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2829 wxCommandEventHandler(options::OnAddDatasourceClick),
2830 NULL, this);
2831 m_buttonRemove->Connect(
2832 wxEVT_COMMAND_BUTTON_CLICKED,
2833 wxCommandEventHandler(options::OnRemoveDatasourceClick), NULL, this);
2834
2835 m_rbTypeSerial->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2836 wxCommandEventHandler(options::OnTypeSerialSelected),
2837 NULL, this);
2838 m_rbTypeNet->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2839 wxCommandEventHandler(options::OnTypeNetSelected), NULL,
2840 this);
2841
2842 if (m_rbTypeInternalGPS)
2843 m_rbTypeInternalGPS->Connect(
2844 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2845 wxCommandEventHandler(options::OnTypeGPSSelected), NULL, this);
2846 if (m_rbTypeInternalBT)
2847 m_rbTypeInternalBT->Connect(
2848 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2849 wxCommandEventHandler(options::OnTypeBTSelected), NULL, this);
2850
2851 m_rbNetProtoTCP->Connect(
2852 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2853 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2854 m_rbNetProtoUDP->Connect(
2855 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2856 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2857 m_rbNetProtoGPSD->Connect(
2858 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2859 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2860 m_rbNetProtoSignalK->Connect(
2861 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2862 wxCommandEventHandler(options::OnNetProtocolSelected), NULL, this);
2863 m_tNetAddress->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2864 wxCommandEventHandler(options::OnConnValChange), NULL,
2865 this);
2866 m_tNetPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2867 wxCommandEventHandler(options::OnConnValChange), NULL,
2868 this);
2869 m_comboPort->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
2870 wxCommandEventHandler(options::OnConnValChange), NULL,
2871 this);
2872 m_comboPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2873 wxCommandEventHandler(options::OnConnValChange), NULL,
2874 this);
2875 m_choiceBaudRate->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
2876 wxCommandEventHandler(options::OnBaudrateChoice),
2877 NULL, this);
2878 m_choiceSerialProtocol->Connect(
2879 wxEVT_COMMAND_CHOICE_SELECTED,
2880 wxCommandEventHandler(options::OnProtocolChoice), NULL, this);
2881 m_choicePriority->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
2882 wxCommandEventHandler(options::OnConnValChange),
2883 NULL, this);
2884 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2885 wxCommandEventHandler(options::OnCrcCheck), NULL, this);
2886 m_cbGarminHost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2887 wxCommandEventHandler(options::OnUploadFormatChange),
2888 NULL, this);
2889 m_cbGarminUploadHost->Connect(
2890 wxEVT_COMMAND_CHECKBOX_CLICKED,
2891 wxCommandEventHandler(options::OnUploadFormatChange), NULL, this);
2892 m_cbFurunoGP3X->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2893 wxCommandEventHandler(options::OnUploadFormatChange),
2894 NULL, this);
2895 m_cbCheckSKDiscover->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2896 wxCommandEventHandler(options::OnConnValChange), NULL, this);
2897 m_ButtonSKDiscover->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2898 wxCommandEventHandler(options::OnDiscoverButton), NULL, this);
2899
2900 m_rbIAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2901 wxCommandEventHandler(options::OnRbAcceptInput), NULL,
2902 this);
2903 m_rbIIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2904 wxCommandEventHandler(options::OnRbIgnoreInput), NULL,
2905 this);
2906 m_tcInputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2907 wxCommandEventHandler(options::OnConnValChange), NULL,
2908 this);
2909 m_btnInputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2910 wxCommandEventHandler(options::OnBtnIStcs), NULL,
2911 this);
2912 m_cbInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2913 wxCommandEventHandler(options::OnCbInput), NULL, this);
2914 m_cbOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2915 wxCommandEventHandler(options::OnCbOutput), NULL, this);
2916 m_rbOAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2917 wxCommandEventHandler(options::OnRbOutput), NULL, this);
2918 m_rbOIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2919 wxCommandEventHandler(options::OnRbOutput), NULL, this);
2920 m_tcOutputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2921 wxCommandEventHandler(options::OnConnValChange), NULL,
2922 this);
2923 m_btnOutputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2924 wxCommandEventHandler(options::OnBtnOStcs), NULL,
2925 this);
2926 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2927 wxCommandEventHandler(options::OnConnValChange), NULL, this);
2928
2929 pOpenGL->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2930 wxCommandEventHandler(options::OnGLClicked), NULL, this);
2931
2932 m_cbNMEADebug->Connect(
2933 wxEVT_COMMAND_CHECKBOX_CLICKED,
2934 wxCommandEventHandler(options::OnShowGpsWindowCheckboxClick), NULL, this);
2935 m_cbFilterSogCog->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2936 wxCommandEventHandler(options::OnValChange), NULL,
2937 this);
2938 m_tFilterSec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2939 wxCommandEventHandler(options::OnValChange), NULL,
2940 this);
2941 m_cbAPBMagnetic->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2942 wxCommandEventHandler(options::OnValChange), NULL,
2943 this);
2944
2945 m_tNetComment->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2946 wxCommandEventHandler(options::OnConnValChange), NULL,
2947 this);
2948 m_tSerialComment->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2949 wxCommandEventHandler(options::OnConnValChange), NULL,
2950 this);
2951
2952 #if 0
2953 // m_lcSources->Connect(wxEVT_LEFT_DOWN,
2954 // wxMouseEventHandler(options::OnConnectionToggleEnableMouse),
2955 // NULL, this);
2956 // #if wxCHECK_VERSION(2, 9, 0)
2957 // m_lcSources->Connect(wxEVT_LIST_ITEM_ACTIVATED,
2958 // wxListEventHandler(options::OnConnectionToggleEnable),
2959 // NULL, this);
2960 // #endif
2961
2962 wxString columns[] = {_("Enable"), _("Type"), _("DataPort"),
2963 _("Priority"), _("Parameters"), _("Connection"),
2964 _("Filters")};
2965 for (int i = 0; i < 7; ++i) {
2966 wxListItem col;
2967 col.SetId(i);
2968 col.SetText(columns[i]);
2969 // m_lcSources->InsertColumn(i, col);
2970 }
2971
2972 // Build the image list
2973 wxImageList* imglist = new wxImageList(16, 16, TRUE, 1);
2974 wxBitmap unchecked_bmp(16, 16), checked_bmp(16, 16);
2975 wxMemoryDC renderer_dc;
2976
2977 // Unchecked
2978 renderer_dc.SelectObject(unchecked_bmp);
2979 renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(
2980 GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
2981 renderer_dc.Clear();
2982 wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16),
2983 0);
2984
2985 // Checked
2986 renderer_dc.SelectObject(checked_bmp);
2987 renderer_dc.SetBackground(*wxTheBrushList->FindOrCreateBrush(
2988 GetBackgroundColour(), wxBRUSHSTYLE_SOLID));
2989 renderer_dc.Clear();
2990 wxRendererNative::Get().DrawCheckBox(this, renderer_dc, wxRect(0, 0, 16, 16),
2991 wxCONTROL_CHECKED);
2992
2993 // Deselect the renderer Object
2994 renderer_dc.SelectObject(wxNullBitmap);
2995
2996 imglist->Add(unchecked_bmp);
2997 imglist->Add(checked_bmp);
2998 // m_lcSources->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
2999
3000 // m_lcSources->Refresh();
3001 #endif
3002 FillSourceList();
3003
3004 ShowNMEACommon(FALSE);
3005 ShowNMEASerial(FALSE);
3006 ShowNMEANet(FALSE);
3007 connectionsaved = TRUE;
3008 }
3009
3010 #if 0
3011 void options::EnableItem(const long index) {
3012 if (index == wxNOT_FOUND) {
3013 ClearNMEAForm();
3014 m_buttonRemove->Disable();
3015 } else {
3016 ConnectionParams* conn =
3017 g_pConnectionParams->Item(m_lcSources->GetItemData(index));
3018 if (!conn) return;
3019 conn->bEnabled = !conn->bEnabled;
3020 m_connection_enabled = conn->bEnabled;
3021 // Mark as changed
3022 conn->b_IsSetup = FALSE;
3023 m_lcSources->SetItemImage(index, conn->bEnabled);
3024 }
3025 }
3026
3027 void options::OnConnectionToggleEnable(wxListEvent& event) {
3028 EnableItem(event.GetIndex());
3029 gFrame->RefreshAllCanvas();;
3030 }
3031
3032 void options::OnConnectionToggleEnableMouse(wxMouseEvent& event) {
3033 #if 0
3034 int flags;
3035 long index = m_lcSources->HitTest(event.GetPosition(), flags);
3036 if (index == wxNOT_FOUND || event.GetX() < m_lcSources->GetColumnWidth(0))
3037 EnableItem(index);
3038 #endif
3039 // Allow wx to process...
3040 event.Skip();
3041 }
3042 #endif
3043
EnableConnection(ConnectionParams * conn,bool value)3044 void options::EnableConnection( ConnectionParams *conn, bool value){
3045 if(conn){
3046 conn->bEnabled = value;
3047 conn->b_IsSetup = FALSE; // trigger a rebuild/takedown of the connection
3048 m_connection_enabled = conn->bEnabled;
3049 }
3050 }
3051
CreatePanel_Ownship(size_t parent,int border_size,int group_item_spacing)3052 void options::CreatePanel_Ownship(size_t parent, int border_size,
3053 int group_item_spacing) {
3054 itemPanelShip = AddPage(parent, _("Own ship"));
3055
3056 ownShip = new wxBoxSizer(wxVERTICAL);
3057 itemPanelShip->SetSizer(ownShip);
3058
3059 // OwnShip Display options
3060 wxStaticBox* osdBox =
3061 new wxStaticBox(itemPanelShip, wxID_ANY, _("Display Options"));
3062 dispOptions = new wxStaticBoxSizer(osdBox, wxVERTICAL);
3063 ownShip->Add(dispOptions, 0, wxTOP | wxALL | wxEXPAND, border_size);
3064
3065 wxFlexGridSizer* dispOptionsGrid =
3066 new wxFlexGridSizer(0, 2, group_item_spacing, group_item_spacing);
3067 dispOptionsGrid->AddGrowableCol(1);
3068 dispOptions->Add(dispOptionsGrid, 0, wxALL | wxEXPAND, border_size);
3069
3070 wxStaticText* pStatic_OSCOG_Predictor = new wxStaticText(
3071 itemPanelShip, wxID_ANY, _("COG Predictor Length (min)"));
3072 dispOptionsGrid->Add(pStatic_OSCOG_Predictor, 0);
3073
3074 m_pText_OSCOG_Predictor = new wxTextCtrl(itemPanelShip, wxID_ANY);
3075 dispOptionsGrid->Add(m_pText_OSCOG_Predictor, 0, wxALIGN_RIGHT);
3076
3077 wxStaticText* pStatic_OSHDT_Predictor = new wxStaticText(
3078 itemPanelShip, wxID_ANY, _("Heading Predictor Length (NMi)"));
3079 dispOptionsGrid->Add(pStatic_OSHDT_Predictor, 0);
3080
3081 m_pText_OSHDT_Predictor = new wxTextCtrl(itemPanelShip, wxID_ANY);
3082 dispOptionsGrid->Add(m_pText_OSHDT_Predictor, 0, wxALIGN_RIGHT);
3083
3084 wxStaticText* iconTypeTxt =
3085 new wxStaticText(itemPanelShip, wxID_ANY, _("Ship Icon Type"));
3086 dispOptionsGrid->Add(iconTypeTxt, 0);
3087
3088 wxString iconTypes[] = {_("Default"), _("Real Scale Bitmap"),
3089 _("Real Scale Vector")};
3090
3091 m_pShipIconType =
3092 new wxChoice(itemPanelShip, ID_SHIPICONTYPE, wxDefaultPosition, wxSize(GetCharWidth() * 20, GetCharHeight() * 2), 3, iconTypes);
3093 dispOptionsGrid->Add(m_pShipIconType, 0,
3094 wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxTOP,
3095 group_item_spacing);
3096
3097 realSizes = new wxFlexGridSizer(5, 2, group_item_spacing, group_item_spacing);
3098 realSizes->AddGrowableCol(1);
3099
3100 dispOptions->Add(realSizes, 0, wxEXPAND | wxLEFT, 30);
3101
3102 realSizes->Add(
3103 new wxStaticText(itemPanelShip, wxID_ANY, _("Length Over All (m)")), 1,
3104 wxALIGN_LEFT);
3105 m_pOSLength = new wxTextCtrl(itemPanelShip, 1);
3106 realSizes->Add(m_pOSLength, 1, wxALIGN_RIGHT | wxALL, group_item_spacing);
3107
3108 realSizes->Add(
3109 new wxStaticText(itemPanelShip, wxID_ANY, _("Width Over All (m)")), 1,
3110 wxALIGN_LEFT);
3111 m_pOSWidth = new wxTextCtrl(itemPanelShip, wxID_ANY);
3112 realSizes->Add(m_pOSWidth, 1, wxALIGN_RIGHT | wxALL, group_item_spacing);
3113
3114 realSizes->Add(
3115 new wxStaticText(itemPanelShip, wxID_ANY, _("GPS Offset from Bow (m)")),
3116 1, wxALIGN_LEFT);
3117 m_pOSGPSOffsetY = new wxTextCtrl(itemPanelShip, wxID_ANY);
3118 realSizes->Add(m_pOSGPSOffsetY, 1, wxALIGN_RIGHT | wxALL, group_item_spacing);
3119
3120 realSizes->Add(new wxStaticText(itemPanelShip, wxID_ANY,
3121 _("GPS Offset from Midship (m)")),
3122 1, wxALIGN_LEFT);
3123 m_pOSGPSOffsetX = new wxTextCtrl(itemPanelShip, wxID_ANY);
3124 realSizes->Add(m_pOSGPSOffsetX, 1, wxALIGN_RIGHT | wxALL, group_item_spacing);
3125
3126 realSizes->Add(
3127 new wxStaticText(itemPanelShip, wxID_ANY, _("Minimum Screen Size (mm)")),
3128 1, wxALIGN_LEFT);
3129 m_pOSMinSize = new wxTextCtrl(itemPanelShip, wxID_ANY);
3130 realSizes->Add(m_pOSMinSize, 1, wxALIGN_RIGHT | wxALL, group_item_spacing);
3131
3132 // Radar rings
3133 wxFlexGridSizer* rrSelect =
3134 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3135 rrSelect->AddGrowableCol(1);
3136 dispOptions->Add(rrSelect, 0, wxLEFT | wxRIGHT | wxEXPAND, border_size);
3137
3138 wxStaticText* rrTxt =
3139 new wxStaticText(itemPanelShip, wxID_ANY, _("Show range rings"));
3140 rrSelect->Add(rrTxt, 1, wxEXPAND | wxALL, group_item_spacing);
3141
3142 wxString rrAlt[] = {_("None"), _T( "1" ), _T( "2" ), _T( "3" ),
3143 _T( "4" ), _T( "5" ), _T( "6" ), _T( "7" ),
3144 _T( "8" ), _T( "9" ), _T( "10" )};
3145 pNavAidRadarRingsNumberVisible =
3146 new wxChoice(itemPanelShip, ID_RADARRINGS, wxDefaultPosition,
3147 m_pShipIconType->GetSize(), 11, rrAlt);
3148 rrSelect->Add(pNavAidRadarRingsNumberVisible, 0, wxALIGN_RIGHT | wxALL,
3149 group_item_spacing);
3150
3151 radarGrid = new wxFlexGridSizer(0, 2, group_item_spacing, group_item_spacing);
3152 radarGrid->AddGrowableCol(1);
3153 dispOptions->Add(radarGrid, 0, wxLEFT | wxEXPAND, 30);
3154
3155 wxStaticText* distanceText =
3156 new wxStaticText(itemPanelShip, wxID_STATIC, _("Distance between rings"));
3157 radarGrid->Add(distanceText, 1, wxEXPAND | wxALL, group_item_spacing);
3158
3159 pNavAidRadarRingsStep = new wxTextCtrl(itemPanelShip, ID_OPTEXTCTRL, _T(""),
3160 wxDefaultPosition, wxSize(100, -1), 0);
3161 radarGrid->Add(pNavAidRadarRingsStep, 0, wxALIGN_RIGHT | wxALL,
3162 group_item_spacing);
3163
3164 wxStaticText* unitText =
3165 new wxStaticText(itemPanelShip, wxID_STATIC, _("Distance Unit"));
3166 radarGrid->Add(unitText, 1, wxEXPAND | wxALL, group_item_spacing);
3167
3168 wxString pDistUnitsStrings[] = {_("Nautical miles"), _("Kilometers")};
3169 m_itemRadarRingsUnits =
3170 new wxChoice(itemPanelShip, ID_RADARDISTUNIT, wxDefaultPosition,
3171 m_pShipIconType->GetSize(), 2, pDistUnitsStrings);
3172 radarGrid->Add(m_itemRadarRingsUnits, 0, wxALIGN_RIGHT | wxALL, border_size);
3173
3174 wxStaticText* colourText = new wxStaticText(itemPanelShip, wxID_STATIC, _("Range Ring Colour"));
3175 radarGrid->Add(colourText, 1, wxEXPAND | wxALL, group_item_spacing);
3176
3177 m_colourOwnshipRangeRingColour = new OCPNColourPickerCtrl( itemPanelShip, wxID_ANY, *wxRED,
3178 wxDefaultPosition, m_colourPickerDefaultSize, 0, wxDefaultValidator, _T( "ID_COLOUROSRANGECOLOUR" ));
3179 radarGrid->Add(m_colourOwnshipRangeRingColour, 0, wxALIGN_RIGHT, border_size);
3180
3181 // Tracks
3182 wxStaticBox* trackText =
3183 new wxStaticBox(itemPanelShip, wxID_ANY, _("Tracks"));
3184 wxStaticBoxSizer* trackSizer = new wxStaticBoxSizer(trackText, wxVERTICAL);
3185 wxBoxSizer* trackSizer1 = new wxBoxSizer(wxHORIZONTAL);
3186 ownShip->Add(trackSizer, 0, wxGROW | wxALL, border_size);
3187
3188 pTrackDaily = new wxCheckBox(itemPanelShip, ID_DAILYCHECKBOX,
3189 _("Automatic Daily Tracks at midnight"));
3190
3191 trackSizer1->Add(pTrackDaily, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, border_size);
3192
3193 trackSizer1->Add( 0, 0, 1, wxEXPAND, 0 );
3194
3195 #if wxCHECK_VERSION(2, 9, 0)
3196 #if wxUSE_TIMEPICKCTRL
3197 pTrackDaily->SetLabel(_("Automatic Daily Tracks at"));
3198 #ifdef __WXGTK__
3199 pTrackRotateTime = new TimeCtrl( itemPanelShip, ID_TRACKROTATETIME, wxDateTime((time_t)g_track_rotate_time).ToUTC(), wxDefaultPosition, wxDefaultSize, 0 );
3200 #else
3201 pTrackRotateTime = new wxTimePickerCtrl( itemPanelShip, ID_TRACKROTATETIME, wxDateTime((time_t)g_track_rotate_time).ToUTC(), wxDefaultPosition, wxDefaultSize, 0 );
3202 #endif
3203 trackSizer1->Add( pTrackRotateTime, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, border_size );
3204 #endif
3205 #endif
3206
3207 pTrackRotateComputerTime = new wxRadioButton( itemPanelShip, ID_TRACKROTATECOMPUTER, _("Computer"), wxDefaultPosition, wxDefaultSize, 0 );
3208 trackSizer1->Add( pTrackRotateComputerTime, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, border_size );
3209
3210 pTrackRotateUTC = new wxRadioButton( itemPanelShip, ID_TRACKROTATEUTC, _("UTC"), wxDefaultPosition, wxDefaultSize, 0 );
3211 trackSizer1->Add( pTrackRotateUTC, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, border_size );
3212
3213 pTrackRotateLMT = new wxRadioButton( itemPanelShip, ID_TRACKROTATELMT, _("LMT"), wxDefaultPosition, wxDefaultSize, 0 );
3214 trackSizer1->Add( pTrackRotateLMT, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, border_size );
3215
3216 trackSizer->Add(trackSizer1, 1, wxEXPAND | wxALL, border_size);
3217
3218 wxFlexGridSizer* hTrackGrid =
3219 new wxFlexGridSizer(1, 3, group_item_spacing, group_item_spacing);
3220 hTrackGrid->AddGrowableCol(1);
3221 trackSizer->Add(hTrackGrid, 0, wxALL | wxEXPAND, border_size);
3222
3223 pTrackHighlite =
3224 new wxCheckBox(itemPanelShip, ID_TRACKHILITE, _("Highlight Tracks"));
3225 hTrackGrid->Add(pTrackHighlite, 1, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, border_size);
3226 wxStaticText* trackColourText =
3227 new wxStaticText( itemPanelShip, wxID_STATIC, _("Track Colour"));
3228 hTrackGrid->Add(trackColourText, 1, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, border_size);
3229 m_colourTrackLineColour = new OCPNColourPickerCtrl(
3230 itemPanelShip, wxID_STATIC, *wxRED, wxDefaultPosition, m_colourPickerDefaultSize, 0,
3231 wxDefaultValidator, _T( "ID_COLOURTRACKCOLOUR" ));
3232 hTrackGrid->Add(m_colourTrackLineColour, 1,
3233 wxALIGN_RIGHT, border_size);
3234
3235 wxFlexGridSizer* pTrackGrid =
3236 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3237 pTrackGrid->AddGrowableCol(1);
3238 trackSizer->Add(pTrackGrid, 0, wxALL | wxEXPAND, border_size);
3239
3240 wxStaticText* tpText =
3241 new wxStaticText(itemPanelShip, wxID_STATIC, _("Tracking Precision"));
3242 pTrackGrid->Add(tpText, 1, wxEXPAND | wxALL, group_item_spacing);
3243
3244 wxString trackAlt[] = {_("Low"), _("Medium"), _("High")};
3245 pTrackPrecision = new wxChoice(itemPanelShip, wxID_ANY, wxDefaultPosition,
3246 m_pShipIconType->GetSize(), 3, trackAlt);
3247 pTrackGrid->Add(pTrackPrecision, 0, wxALIGN_RIGHT | wxALL,
3248 group_item_spacing);
3249
3250 // Calculate values
3251 wxStaticBox* ownshipcalcText = new wxStaticBox(itemPanelShip, wxID_ANY, _("Calculate values"));
3252 wxStaticBoxSizer* ownshipcalcSizer = new wxStaticBoxSizer(ownshipcalcText, wxVERTICAL);
3253 ownShip->Add(ownshipcalcSizer, 0, wxTOP | wxALL | wxEXPAND, border_size);
3254
3255 wxFlexGridSizer* dispOwnShipCalcOptionsGrid = new wxFlexGridSizer(2, 2, group_item_spacing, group_item_spacing);
3256 ownshipcalcSizer->Add(dispOwnShipCalcOptionsGrid, 0, wxTOP | wxALL | wxEXPAND, border_size);
3257
3258 dispOwnShipCalcOptionsGrid->AddGrowableCol(1);
3259
3260 pSogCogFromLLCheckBox = new wxCheckBox(itemPanelShip, ID_SOGCOGFROMLLCHECKBOX, _("Calculate SOG and COG from position changes"));
3261 dispOwnShipCalcOptionsGrid->Add(pSogCogFromLLCheckBox, 1, wxALL, 5);
3262 dispOwnShipCalcOptionsGrid->AddSpacer(0);
3263
3264 wxStaticText* SogCogFromLLDampIntText = new wxStaticText(itemPanelShip, wxID_STATIC, _("Min seconds between updates"));
3265 dispOwnShipCalcOptionsGrid->Add(SogCogFromLLDampIntText, 1, wxEXPAND | wxALL, group_item_spacing);
3266
3267 pSogCogFromLLDampInterval = new wxSpinCtrl(itemPanelShip, ID_SOGCOGDAMPINTTEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10, 0 );
3268
3269 dispOwnShipCalcOptionsGrid->Add(pSogCogFromLLDampInterval, 0, wxALIGN_RIGHT | wxALL, group_item_spacing);
3270
3271 // DimeControl(itemPanelShip);
3272 }
3273
CreatePanel_Routes(size_t parent,int border_size,int group_item_spacing)3274 void options::CreatePanel_Routes(size_t parent, int border_size,
3275 int group_item_spacing) {
3276 itemPanelRoutes = AddPage(parent, _("Routes/Points"));
3277
3278 Routes = new wxBoxSizer(wxVERTICAL);
3279 itemPanelRoutes->SetSizer(Routes);
3280
3281
3282 wxString pDistUnitsStrings[] = {_("Nautical miles"), _("Kilometers")};
3283
3284 wxString rrAlt[] = {_("None"), _T( "1" ), _T( "2" ), _T( "3" ),
3285 _T( "4" ), _T( "5" ), _T( "6" ), _T( "7" ),
3286 _T( "8" ), _T( "9" ), _T( "10" )};
3287
3288 // Routes
3289 wxStaticBox* routeText =
3290 new wxStaticBox(itemPanelRoutes, wxID_ANY, _("New Routes"));
3291 wxStaticBoxSizer* routeSizer = new wxStaticBoxSizer(routeText, wxVERTICAL);
3292 Routes->Add(routeSizer, 0, wxGROW | wxALL, border_size);
3293
3294 routeSizer->AddSpacer(5);
3295
3296 // Default ICON
3297 wxFlexGridSizer* routepointiconSelect =
3298 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3299 routepointiconSelect->AddGrowableCol(1);
3300 routeSizer->Add(routepointiconSelect, 0, wxLEFT | wxRIGHT | wxEXPAND,
3301 border_size);
3302
3303 wxStaticText* routepointiconTxt =
3304 new wxStaticText(itemPanelRoutes, wxID_ANY, _("Waypoint default icon"));
3305 routepointiconSelect->Add(routepointiconTxt, 1, wxEXPAND | wxALL, group_item_spacing);
3306
3307 pRoutepointDefaultIconChoice = new OCPNIconCombo( itemPanelRoutes, wxID_ANY, _("Combo!"),
3308 wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
3309 routepointiconSelect->Add(pRoutepointDefaultIconChoice, 0, wxALIGN_RIGHT | wxALL,
3310 group_item_spacing);
3311
3312 pRoutepointDefaultIconChoice->SetPopupMaxHeight(::wxGetDisplaySize().y / 2);
3313
3314 // Accomodate scaling of icon
3315 int min_size = GetCharHeight() * 2;
3316 min_size = wxMax( min_size, (32 *g_ChartScaleFactorExp) + 4 );
3317 pRoutepointDefaultIconChoice->SetMinSize( wxSize(GetCharHeight() * 15, min_size) );
3318
3319 routeSizer->AddSpacer(5);
3320
3321
3322 wxFlexGridSizer* pRouteGrid =
3323 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3324 pRouteGrid->AddGrowableCol(1);
3325 routeSizer->Add(pRouteGrid, 0, wxALL | wxEXPAND, border_size);
3326
3327 wxStaticText* raText = new wxStaticText(
3328 itemPanelRoutes, wxID_STATIC, _("Waypoint Arrival Circle Radius (NMi)"));
3329 pRouteGrid->Add(raText, 1, wxEXPAND | wxALL, group_item_spacing);
3330
3331 m_pText_ACRadius = new wxTextCtrl(itemPanelRoutes, -1);
3332 pRouteGrid->Add(m_pText_ACRadius, 0, wxALL | wxALIGN_RIGHT,
3333 group_item_spacing);
3334
3335 pAdvanceRouteWaypointOnArrivalOnly =
3336 new wxCheckBox(itemPanelRoutes, ID_DAILYCHECKBOX,
3337 _("Advance route waypoint on arrival only"));
3338 routeSizer->Add(pAdvanceRouteWaypointOnArrivalOnly, 0, wxALL, 5);
3339
3340 #ifdef __WXGTK__
3341 Routes->AddSpacer(8 * group_item_spacing);
3342 wxStaticLine *pln = new wxStaticLine( itemPanelRoutes, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
3343 Routes->Add(pln, 0, wxEXPAND);
3344 #endif
3345
3346 // Waypoints
3347 wxStaticBox* waypointText =
3348 new wxStaticBox(itemPanelRoutes, wxID_ANY, _("New Waypoints"));
3349 wxStaticBoxSizer* waypointSizer =
3350 new wxStaticBoxSizer(waypointText, wxVERTICAL);
3351 Routes->Add(waypointSizer, 0, wxTOP | wxALL | wxEXPAND, border_size);
3352
3353 waypointSizer->AddSpacer(5);
3354
3355 // Default ICON
3356 wxFlexGridSizer* waypointiconSelect =
3357 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3358 waypointiconSelect->AddGrowableCol(1);
3359 waypointSizer->Add(waypointiconSelect, 0, wxLEFT | wxRIGHT | wxEXPAND,
3360 border_size);
3361
3362 wxStaticText* waypointiconTxt =
3363 new wxStaticText(itemPanelRoutes, wxID_ANY, _("Waypoint default icon"));
3364 waypointiconSelect->Add(waypointiconTxt, 1, wxEXPAND | wxALL, group_item_spacing);
3365
3366 pWaypointDefaultIconChoice = new OCPNIconCombo( itemPanelRoutes, wxID_ANY, _("Combo!"),
3367 wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
3368 waypointiconSelect->Add(pWaypointDefaultIconChoice, 0, wxALIGN_RIGHT | wxALL,
3369 group_item_spacing);
3370
3371 pWaypointDefaultIconChoice->SetPopupMaxHeight(::wxGetDisplaySize().y / 2);
3372
3373 // Accomodate scaling of icon
3374 int rmin_size = GetCharHeight() * 2;
3375 min_size = wxMax( rmin_size, (32 *g_ChartScaleFactorExp) + 4 );
3376 pWaypointDefaultIconChoice->SetMinSize( wxSize(GetCharHeight() * 15, rmin_size) );
3377
3378 waypointSizer->AddSpacer(5);
3379 // ScaMin
3380 wxFlexGridSizer* ScaMinSizer =
3381 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3382 ScaMinSizer->AddGrowableCol(1);
3383 waypointSizer->Add(ScaMinSizer, 0, wxLEFT | wxRIGHT | wxEXPAND,
3384 border_size);
3385 pScaMinChckB = new wxCheckBox(itemPanelRoutes, wxID_ANY,
3386 _("Show waypoints only at a chartscale greater than 1 :"));
3387 ScaMinSizer->Add(pScaMinChckB, 0);
3388 m_pText_ScaMin = new wxTextCtrl(itemPanelRoutes, -1);
3389 ScaMinSizer->Add(m_pText_ScaMin, 0, wxALL | wxALIGN_RIGHT,
3390 group_item_spacing);
3391
3392 //Overrule the Scamin settings
3393 pScaMinOverruleChckB = new wxCheckBox(itemPanelRoutes, wxID_ANY,
3394 _("Override the settings for chartscale based visibility and show always") );
3395 waypointSizer->Add(pScaMinOverruleChckB, 0, wxALL, 5);
3396
3397 waypointSizer->AddSpacer(5);
3398 //Range Rings
3399 wxFlexGridSizer* waypointrrSelect =
3400 new wxFlexGridSizer(1, 2, group_item_spacing, group_item_spacing);
3401 waypointrrSelect->AddGrowableCol(1);
3402 waypointSizer->Add(waypointrrSelect, 0, wxLEFT | wxRIGHT | wxEXPAND,
3403 border_size);
3404
3405 wxStaticText* waypointrrTxt =
3406 new wxStaticText(itemPanelRoutes, wxID_ANY, _("Waypoint range rings"));
3407 waypointrrSelect->Add(waypointrrTxt, 1, wxEXPAND | wxALL, group_item_spacing);
3408
3409 pWaypointRangeRingsNumber =
3410 new wxChoice(itemPanelRoutes, ID_OPWAYPOINTRANGERINGS, wxDefaultPosition,
3411 m_pShipIconType->GetSize(), 11, rrAlt);
3412 waypointrrSelect->Add(pWaypointRangeRingsNumber, 0, wxALIGN_RIGHT | wxALL,
3413 group_item_spacing);
3414
3415 waypointradarGrid =
3416 new wxFlexGridSizer(0, 2, group_item_spacing, group_item_spacing);
3417 waypointradarGrid->AddGrowableCol(1);
3418 waypointSizer->Add(waypointradarGrid, 0, wxLEFT | wxEXPAND, 30);
3419
3420 wxStaticText* waypointdistanceText = new wxStaticText(
3421 itemPanelRoutes, wxID_STATIC, _("Distance between rings"));
3422 waypointradarGrid->Add(waypointdistanceText, 1, wxEXPAND | wxALL,
3423 group_item_spacing);
3424
3425 pWaypointRangeRingsStep =
3426 new wxTextCtrl(itemPanelRoutes, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
3427 wxSize(100, -1), 0);
3428 waypointradarGrid->Add(pWaypointRangeRingsStep, 0, wxALIGN_RIGHT | wxALL,
3429 group_item_spacing);
3430
3431 wxStaticText* waypointunitText =
3432 new wxStaticText(itemPanelRoutes, wxID_STATIC, _("Distance Unit"));
3433 waypointradarGrid->Add(waypointunitText, 1, wxEXPAND | wxALL,
3434 group_item_spacing);
3435
3436 m_itemWaypointRangeRingsUnits =
3437 new wxChoice(itemPanelRoutes, ID_RADARDISTUNIT, wxDefaultPosition,
3438 m_pShipIconType->GetSize(), 2, pDistUnitsStrings);
3439 waypointradarGrid->Add(m_itemWaypointRangeRingsUnits, 0,
3440 wxALIGN_RIGHT | wxALL, border_size);
3441
3442 wxStaticText* waypointrangeringsColour = new wxStaticText(
3443 itemPanelRoutes, wxID_STATIC, _("Waypoint Range Ring Colours"));
3444 waypointradarGrid->Add(waypointrangeringsColour, 1, wxEXPAND | wxALL, 1);
3445
3446 m_colourWaypointRangeRingsColour = new OCPNColourPickerCtrl(
3447 itemPanelRoutes, wxID_ANY, *wxRED, wxDefaultPosition, m_colourPickerDefaultSize, 0,
3448 wxDefaultValidator, _T( "ID_COLOURWAYPOINTRANGERINGSCOLOUR" ));
3449 waypointradarGrid->Add(m_colourWaypointRangeRingsColour, 0,
3450 wxALIGN_RIGHT | wxALL, 1);
3451
3452
3453 // Control Options
3454
3455 #ifdef __WXGTK__
3456 Routes->AddSpacer(8 * group_item_spacing);
3457 wxStaticLine *pln1 = new wxStaticLine( itemPanelRoutes, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
3458 Routes->Add(pln1, 0, wxEXPAND);
3459 #endif
3460
3461 wxStaticBox* waypointControl =
3462 new wxStaticBox(itemPanelRoutes, wxID_ANY, _("Control Options"));
3463 wxStaticBoxSizer* ControlSizer =
3464 new wxStaticBoxSizer(waypointControl, wxVERTICAL);
3465 Routes->Add(ControlSizer, 0, wxTOP | wxALL | wxEXPAND, border_size);
3466
3467 ControlSizer->AddSpacer(5);
3468
3469 pWayPointPreventDragging = new wxCheckBox(
3470 itemPanelRoutes, ID_DRAGGINGCHECKBOX,
3471 _("Lock Waypoints (Unless waypoint property dialog visible)"));
3472 pWayPointPreventDragging->SetValue(FALSE);
3473 ControlSizer->Add(pWayPointPreventDragging, verticleInputFlags);
3474
3475 pConfirmObjectDeletion =
3476 new wxCheckBox(itemPanelRoutes, ID_DELETECHECKBOX,
3477 _("Confirm deletion of tracks and routes"));
3478 pConfirmObjectDeletion->SetValue(FALSE);
3479 ControlSizer->Add(pConfirmObjectDeletion, verticleInputFlags);
3480 ControlSizer->AddSpacer(5);
3481
3482
3483 // Fill the default waypoint icon selector combo box
3484 pWaypointDefaultIconChoice->Clear();
3485 // Iterate on the Icon Descriptions, filling in the combo control
3486 bool fillCombo = true;
3487
3488 if( fillCombo ){
3489 for( int i = 0; i < pWayPointMan->GetNumIcons(); i++ ) {
3490 wxString *ps = pWayPointMan->GetIconDescription( i );
3491 wxBitmap bmp = pWayPointMan->GetIconBitmapForList(i, 2 * GetCharHeight());
3492
3493 pWaypointDefaultIconChoice->Append( *ps, bmp );
3494 }
3495 }
3496
3497 // find the correct item in the combo box
3498 int iconToSelect = -1;
3499 for( int i = 0; i < pWayPointMan->GetNumIcons(); i++ ) {
3500 if( *pWayPointMan->GetIconKey( i ) == g_default_wp_icon ){
3501 iconToSelect = i;
3502 pWaypointDefaultIconChoice->Select( iconToSelect );
3503 break;
3504 }
3505 }
3506
3507 // Fill the default Routepoint icon selector combo box
3508 pRoutepointDefaultIconChoice->Clear();
3509 // Iterate on the Icon Descriptions, filling in the combo control
3510 fillCombo = true;
3511
3512 if( fillCombo ){
3513 for( int i = 0; i < pWayPointMan->GetNumIcons(); i++ ) {
3514 wxString *ps = pWayPointMan->GetIconDescription( i );
3515 wxBitmap bmp = pWayPointMan->GetIconBitmapForList(i, 2 * GetCharHeight());
3516
3517 pRoutepointDefaultIconChoice->Append( *ps, bmp );
3518 }
3519 }
3520
3521 // find the correct item in the combo box
3522 iconToSelect = -1;
3523 for( int i = 0; i < pWayPointMan->GetNumIcons(); i++ ) {
3524 if( *pWayPointMan->GetIconKey( i ) == g_default_routepoint_icon ){
3525 iconToSelect = i;
3526 pRoutepointDefaultIconChoice->Select( iconToSelect );
3527 break;
3528 }
3529 }
3530
3531 // DimeControl(itemPanelRoutes);
3532 }
3533
CreatePanel_ChartsLoad(size_t parent,int border_size,int group_item_spacing)3534 void options::CreatePanel_ChartsLoad(size_t parent, int border_size,
3535 int group_item_spacing) {
3536 wxScrolledWindow* chartPanelWin = AddPage(m_pageCharts, _("Chart Files"));
3537
3538 chartPanel = new wxBoxSizer(wxVERTICAL);
3539 chartPanelWin->SetSizer(chartPanel);
3540
3541 wxStaticBox* loadedBox =
3542 new wxStaticBox(chartPanelWin, wxID_ANY, _("Directories"));
3543 activeSizer = new wxStaticBoxSizer(loadedBox, wxHORIZONTAL);
3544 chartPanel->Add(activeSizer, 1, wxALL | wxEXPAND, border_size);
3545
3546 pActiveChartsList = new wxListCtrl( chartPanelWin, ID_LISTBOX, wxDefaultPosition, wxSize(100, -1),
3547 wxLC_REPORT | wxLC_NO_HEADER );
3548 #ifdef __OCPN__ANDROID__
3549 pActiveChartsList->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
3550 #endif
3551
3552
3553 activeSizer->Add(pActiveChartsList, 1, wxALL | wxEXPAND, border_size);
3554
3555 pActiveChartsList->Connect(
3556 wxEVT_COMMAND_LIST_ITEM_SELECTED,
3557 wxCommandEventHandler(options::OnChartDirListSelect), NULL, this);
3558
3559 wxBoxSizer* cmdButtonSizer = new wxBoxSizer(wxVERTICAL);
3560 activeSizer->Add(cmdButtonSizer, 0, wxALL, border_size);
3561
3562 // Currently loaded chart dirs
3563 wxString dirname;
3564 if (pActiveChartsList) {
3565 pActiveChartsList->DeleteAllItems();
3566
3567 // Add first column
3568 wxListItem col0;
3569 col0.SetId(0);
3570 col0.SetText( _("") );
3571 col0.SetAlign(wxLIST_FORMAT_LEFT);
3572 col0.SetWidth(500);
3573 pActiveChartsList->InsertColumn(0, col0);
3574
3575 for (size_t i = 0; i < m_CurrentDirList.GetCount(); i++) {
3576 wxString dirname = m_CurrentDirList[i].fullpath;
3577 wxListItem li;
3578 li.SetId( i );
3579 li.SetAlign(wxLIST_FORMAT_LEFT);
3580 li.SetText(dirname);
3581 li.SetColumn(0);
3582 long idx = pActiveChartsList->InsertItem( li );
3583 }
3584 }
3585
3586 wxButton* addBtn =
3587 new wxButton(chartPanelWin, ID_BUTTONADD, _("Add Directory..."));
3588 cmdButtonSizer->Add(addBtn, 1, wxALL | wxEXPAND, group_item_spacing);
3589
3590 m_removeBtn =
3591 new wxButton(chartPanelWin, ID_BUTTONDELETE, _("Remove Selected"));
3592 cmdButtonSizer->Add(m_removeBtn, 1, wxALL | wxEXPAND, group_item_spacing);
3593 m_removeBtn->Disable();
3594
3595 #ifdef OCPN_USE_LZMA
3596 m_compressBtn =
3597 new wxButton(chartPanelWin, ID_BUTTONCOMPRESS, _("Compress Selected"));
3598 cmdButtonSizer->Add(m_compressBtn, 1, wxALL | wxEXPAND, group_item_spacing);
3599 m_compressBtn->Disable();
3600 #else
3601 m_compressBtn = NULL;
3602 #endif
3603
3604 wxStaticBox* itemStaticBoxUpdateStatic =
3605 new wxStaticBox(chartPanelWin, wxID_ANY, _("Update Control"));
3606 wxStaticBoxSizer* itemStaticBoxSizerUpdate =
3607 new wxStaticBoxSizer(itemStaticBoxUpdateStatic, wxVERTICAL);
3608 chartPanel->Add(itemStaticBoxSizerUpdate, 0, wxGROW | wxALL, 5);
3609
3610 wxFlexGridSizer* itemFlexGridSizerUpdate = new wxFlexGridSizer(1);
3611 itemFlexGridSizerUpdate->SetFlexibleDirection( wxHORIZONTAL );
3612
3613 pScanCheckBox = new wxCheckBox(chartPanelWin, ID_SCANCHECKBOX, _("Scan Charts and Update Database"));
3614 itemFlexGridSizerUpdate->Add(pScanCheckBox, 1, wxALL, 5);
3615
3616 pUpdateCheckBox = new wxCheckBox(chartPanelWin, ID_UPDCHECKBOX, _("Force Full Database Rebuild"));
3617 itemFlexGridSizerUpdate->Add(pUpdateCheckBox, 1, wxALL, 5);
3618
3619 pParseENCButton = new wxButton(chartPanelWin, ID_PARSEENCBUTTON, _("Prepare all ENC Charts"));
3620 itemFlexGridSizerUpdate->Add(pParseENCButton, 1, wxALL, 5);
3621
3622 itemStaticBoxSizerUpdate->Add( itemFlexGridSizerUpdate, 1, wxEXPAND, 5 );
3623
3624
3625 chartPanel->Layout();
3626 }
3627
UpdateTemplateTitleText()3628 void options::UpdateTemplateTitleText()
3629 {
3630 if(!m_templateTitleText)
3631 return;
3632
3633 wxString activeTitle;
3634 if(!g_lastAppliedTemplateGUID.IsEmpty()){
3635 activeTitle = ConfigMgr::Get().GetTemplateTitle(g_lastAppliedTemplateGUID);
3636
3637 bool configCompare = ConfigMgr::Get().CheckTemplateGUID(g_lastAppliedTemplateGUID);
3638 if(!configCompare)
3639 activeTitle += _(" [Modified]");
3640 m_templateTitleText->SetLabel(activeTitle);
3641 }
3642 else
3643 m_templateTitleText->SetLabel(_("None"));
3644 }
3645
3646
CreatePanel_Configs(size_t parent,int border_size,int group_item_spacing)3647 void options::CreatePanel_Configs(size_t parent, int border_size, int group_item_spacing)
3648 {
3649 m_DisplayConfigsPage = AddPage(parent, _("Templates"));
3650
3651 //if (m_bcompact) {
3652 //}
3653 //else
3654 {
3655
3656 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
3657 m_DisplayConfigsPage->SetSizer(wrapperSizer);
3658
3659 // Template management
3660
3661 wxStaticBox* templateStatusBox = new wxStaticBox(m_DisplayConfigsPage, wxID_ANY, _("Template Status"));
3662 m_templateStatusBoxSizer = new wxStaticBoxSizer(templateStatusBox, wxHORIZONTAL);
3663 wrapperSizer->Add(m_templateStatusBoxSizer, 1, wxALL | wxEXPAND, border_size);
3664
3665 wxBoxSizer* statSizer = new wxBoxSizer(wxVERTICAL);
3666 m_templateStatusBoxSizer->Add(statSizer, 0, wxALL | wxEXPAND, border_size);
3667
3668 m_staticTextLastAppled = new wxStaticText(m_DisplayConfigsPage, wxID_ANY, _("Last Applied Template Title:"));
3669 m_staticTextLastAppled->Hide();
3670
3671 statSizer->Add(m_staticTextLastAppled);
3672
3673 m_templateTitleText = new wxStaticText(m_DisplayConfigsPage, wxID_ANY, wxEmptyString);
3674 statSizer->Add(m_templateTitleText);
3675 m_templateTitleText->Hide();
3676
3677 UpdateTemplateTitleText();
3678
3679
3680 wxStaticBox* configsBox = new wxStaticBox(m_DisplayConfigsPage, wxID_ANY, _("Saved Templates"));
3681 wxStaticBoxSizer* configSizer = new wxStaticBoxSizer(configsBox, wxHORIZONTAL);
3682 wrapperSizer->Add(configSizer, 4, wxALL | wxEXPAND, border_size);
3683
3684 wxPanel *cPanel = new wxPanel(m_DisplayConfigsPage, wxID_ANY );
3685 configSizer->Add(cPanel, 1, wxALL | wxEXPAND, border_size);
3686
3687 wxBoxSizer *boxSizercPanel = new wxBoxSizer(wxVERTICAL);
3688 cPanel->SetSizer(boxSizercPanel);
3689
3690 m_scrollWinConfigList = new wxScrolledWindow(cPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_RAISED | wxVSCROLL );
3691 m_scrollWinConfigList->SetScrollRate(1, 1);
3692 boxSizercPanel->Add(m_scrollWinConfigList, 0, wxALL|wxEXPAND, border_size);
3693 m_scrollWinConfigList->SetMinSize(wxSize(-1,15 * GetCharHeight()));
3694
3695 m_boxSizerConfigs = new wxBoxSizer(wxVERTICAL);
3696 m_scrollWinConfigList->SetSizer(m_boxSizerConfigs);
3697
3698
3699 wxBoxSizer* btnSizer = new wxBoxSizer(wxVERTICAL);
3700 configSizer->Add(btnSizer);
3701
3702 // Add the "Insert/Remove" buttons
3703 wxButton* createButton = new wxButton(m_DisplayConfigsPage, wxID_ANY, _("Create Config..."));
3704 btnSizer->Add(createButton, 1, wxALL | wxEXPAND, group_item_spacing);
3705 createButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(options::OnCreateConfig), NULL, this);
3706
3707 //wxButton* editButton = new wxButton(m_DisplayConfigsPage, wxID_ANY, _("Edit Config..."));
3708 //btnSizer->Add(editButton, 1, wxALL | wxEXPAND, group_item_spacing);
3709 //editButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(options::OnEditConfig), NULL, this);
3710
3711 m_configDeleteButton = new wxButton(m_DisplayConfigsPage, wxID_ANY, _("Delete Selected Config..."));
3712 btnSizer->Add(m_configDeleteButton, 1, wxALL | wxEXPAND, group_item_spacing);
3713 m_configDeleteButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(options::OnDeleteConfig), NULL, this);
3714
3715 m_configApplyButton = new wxButton(m_DisplayConfigsPage, wxID_ANY, _("Apply Selected Config"));
3716 btnSizer->Add(m_configApplyButton, 1, wxALL | wxEXPAND, group_item_spacing);
3717 m_configApplyButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(options::OnApplyConfig), NULL, this);
3718
3719 // Populate the configs list from the ConfigMgr
3720 ClearConfigList();
3721 BuildConfigList();
3722
3723 SetConfigButtonState();
3724 }
3725 }
3726
ClearConfigList()3727 void options::ClearConfigList()
3728 {
3729 if(m_scrollWinConfigList){
3730 wxWindowList kids = m_scrollWinConfigList->GetChildren();
3731 for( unsigned int i = 0; i < kids.GetCount(); i++ ) {
3732 wxWindowListNode *node = kids.Item(i);
3733 wxWindow *win = node->GetData();
3734 wxPanel *pcp = wxDynamicCast(win, wxPanel);
3735 if(pcp){
3736 ConfigPanel *cPanel = wxDynamicCast(pcp, ConfigPanel);
3737 if(cPanel){
3738 cPanel->Destroy();
3739 }
3740 }
3741 }
3742 }
3743 SetConfigButtonState();
3744 }
3745
BuildConfigList()3746 void options::BuildConfigList()
3747 {
3748 wxArrayString configGUIDs = ConfigMgr::Get().GetConfigGUIDArray();
3749
3750 for(size_t i=0 ; i < configGUIDs.GetCount() ; i++){
3751 wxPanel *pp = ConfigMgr::Get().GetConfigPanel( m_scrollWinConfigList,configGUIDs[i]);
3752 if(pp){
3753 m_panelBackgroundUnselected = pp->GetBackgroundColour();
3754 m_boxSizerConfigs->Add(pp, 1, wxEXPAND);
3755 pp->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(options::OnConfigMouseSelected), NULL, this);
3756
3757 // Set mouse handler for children of the panel, too.
3758 wxWindowList kids = pp->GetChildren();
3759 for( unsigned int i = 0; i < kids.GetCount(); i++ ) {
3760 wxWindowListNode *node = kids.Item(i);
3761 wxWindow *win = node->GetData();
3762 win->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(options::OnConfigMouseSelected), NULL, this);
3763 }
3764 }
3765 }
3766
3767 m_boxSizerConfigs->Layout();
3768
3769 m_selectedConfigPanelGUID = _T("");
3770 SetConfigButtonState();
3771 }
3772
SetConfigButtonState()3773 void options::SetConfigButtonState()
3774 {
3775 m_configDeleteButton->Enable(!m_selectedConfigPanelGUID.IsEmpty());
3776 if(m_selectedConfigPanelGUID.StartsWith(_T("11111111"))) // Cannot delete "Recovery" template
3777 m_configDeleteButton->Disable();
3778 m_configApplyButton->Enable(!m_selectedConfigPanelGUID.IsEmpty());
3779 }
3780
OnCreateConfig(wxCommandEvent & event)3781 void options::OnCreateConfig( wxCommandEvent &event)
3782 {
3783 ConfigCreateDialog* pd = new ConfigCreateDialog(this, -1, _("Create Config"), wxDefaultPosition, wxSize(200, 200));
3784 DimeControl( pd );
3785 pd->ShowWindowModalThenDo([this,pd](int retcode){
3786 if ( retcode == wxID_OK ) {
3787 g_lastAppliedTemplateGUID = pd->GetCreatedTemplateGUID();
3788 UpdateTemplateTitleText();
3789
3790 ClearConfigList();
3791 BuildConfigList();
3792 m_DisplayConfigsPage->Layout();
3793 }
3794 SetConfigButtonState();
3795 });
3796 }
3797
OnEditConfig(wxCommandEvent & event)3798 void options::OnEditConfig( wxCommandEvent &event)
3799 {
3800 }
3801
OnDeleteConfig(wxCommandEvent & event)3802 void options::OnDeleteConfig( wxCommandEvent &event)
3803 {
3804 if(m_selectedConfigPanelGUID.IsEmpty())
3805 return;
3806
3807 ConfigMgr::Get().DeleteConfig( m_selectedConfigPanelGUID);
3808 m_selectedConfigPanelGUID = _T("");
3809
3810 ClearConfigList();
3811 BuildConfigList();
3812
3813 m_DisplayConfigsPage->Layout();
3814 SetConfigButtonState();
3815 }
3816
OnApplyConfig(wxCommandEvent & event)3817 void options::OnApplyConfig( wxCommandEvent &event)
3818 {
3819 if(m_selectedConfigPanelGUID.IsEmpty())
3820 return;
3821
3822 // Record a few special items
3823 wxString currentLocale = g_locale;
3824
3825 // Apply any changed settings other than the target config template.
3826 wxCommandEvent evt;
3827 evt.SetId(ID_APPLY);
3828 OnApplyClick(evt);
3829
3830 // Then Apply the target config template
3831 bool bApplyStat = ConfigMgr::Get().ApplyConfigGUID( m_selectedConfigPanelGUID);
3832 if(bApplyStat){
3833 // OCPNMessageBox(this, _("Configuration successfully applied."), _("OpenCPN Info"), wxOK);
3834 g_lastAppliedTemplateGUID = m_selectedConfigPanelGUID;
3835 wxString activeTitle = ConfigMgr::Get().GetTemplateTitle(g_lastAppliedTemplateGUID);
3836 m_templateTitleText->SetLabel(activeTitle);
3837 m_templateTitleText->Show();
3838 m_staticTextLastAppled->Show();
3839 m_templateStatusBoxSizer->Layout();
3840 }
3841 else
3842 OCPNMessageBox(this, _("Problem applying selected configuration."), _("OpenCPN Info"), wxOK);
3843
3844 // Clear all selections
3845 if(m_scrollWinConfigList){
3846 wxWindowList kids = m_scrollWinConfigList->GetChildren();
3847 for( unsigned int i = 0; i < kids.GetCount(); i++ ) {
3848 wxWindowListNode *node = kids.Item(i);
3849 wxWindow *win = node->GetData();
3850 wxPanel *pcp = wxDynamicCast(win, wxPanel);
3851 if(pcp){
3852 ConfigPanel *cPanel = wxDynamicCast(pcp, ConfigPanel);
3853 if(cPanel){
3854 cPanel->SetBackgroundColour(m_panelBackgroundUnselected);
3855 }
3856 }
3857 }
3858 }
3859 m_selectedConfigPanelGUID = wxEmptyString;
3860
3861 m_returnChanges |= CONFIG_CHANGED;
3862
3863 if(!currentLocale.IsSameAs(g_locale))
3864 m_returnChanges |= LOCALE_CHANGED;
3865
3866 Finish();
3867 }
3868
3869
OnConfigMouseSelected(wxMouseEvent & event)3870 void options::OnConfigMouseSelected( wxMouseEvent &event)
3871 {
3872 wxPanel *selectedPanel = NULL;
3873 wxObject* obj = event.GetEventObject();
3874 if(obj){
3875 wxPanel *panel = wxDynamicCast(obj, wxPanel);
3876 if(panel){
3877 selectedPanel = panel;
3878 }
3879 //Clicked on child?
3880 else{
3881 wxWindow *win = wxDynamicCast(obj, wxWindow);
3882 if(win){
3883 wxPanel *parentpanel = wxDynamicCast(win->GetParent(), wxPanel);
3884 if(parentpanel){
3885 selectedPanel = parentpanel;
3886 }
3887 }
3888 }
3889
3890 if(m_scrollWinConfigList){
3891 wxWindowList kids = m_scrollWinConfigList->GetChildren();
3892 for( unsigned int i = 0; i < kids.GetCount(); i++ ) {
3893 wxWindowListNode *node = kids.Item(i);
3894 wxWindow *win = node->GetData();
3895 wxPanel *panel = wxDynamicCast(win, wxPanel);
3896 if(panel){
3897 if(panel == selectedPanel ){
3898 wxColour colour;
3899 GetGlobalColor(_T("UIBCK"), &colour);
3900 panel->SetBackgroundColour(colour);
3901 ConfigPanel *cPanel = wxDynamicCast(panel, ConfigPanel);
3902 if(cPanel)
3903 m_selectedConfigPanelGUID = cPanel->GetConfigGUID();
3904 }
3905 else
3906 panel->SetBackgroundColour(m_panelBackgroundUnselected);
3907
3908 panel->Refresh(true);
3909 }
3910 }
3911 }
3912 m_DisplayConfigsPage->Layout();
3913 SetConfigButtonState();
3914 }
3915 }
3916
3917
3918
CreatePanel_Advanced(size_t parent,int border_size,int group_item_spacing)3919 void options::CreatePanel_Advanced(size_t parent, int border_size,
3920 int group_item_spacing) {
3921 m_ChartDisplayPage = AddPage(parent, _("Advanced"));
3922
3923 if (m_bcompact) {
3924 wxSize sz = g_Platform->getDisplaySize();
3925 double dpmm = g_Platform->GetDisplayDPmm();
3926
3927 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
3928 m_ChartDisplayPage->SetSizer(wrapperSizer);
3929
3930 wxBoxSizer* itemBoxSizerUI = wrapperSizer;
3931
3932 // spacer
3933 itemBoxSizerUI->Add(0, border_size * 3);
3934 itemBoxSizerUI->Add(0, border_size * 3);
3935
3936 // Chart Display Options
3937 wxBoxSizer* boxCharts = new wxBoxSizer(wxVERTICAL);
3938 itemBoxSizerUI->Add(boxCharts, groupInputFlags);
3939
3940 pSkewComp = new wxCheckBox(m_ChartDisplayPage, ID_SKEWCOMPBOX,
3941 _("De-skew Raster Charts"));
3942 boxCharts->Add(pSkewComp, inputFlags);
3943
3944 itemBoxSizerUI->Add(0, border_size * 3);
3945 itemBoxSizerUI->Add(0, border_size * 3);
3946
3947 // OpenGL Options
3948 wxBoxSizer* OpenGLSizer = new wxBoxSizer(wxVERTICAL);
3949 itemBoxSizerUI->Add(OpenGLSizer, 0, 0, 0);
3950
3951 pOpenGL = new wxCheckBox(m_ChartDisplayPage, ID_OPENGLBOX,
3952 _("Use Accelerated Graphics (OpenGL)"));
3953 OpenGLSizer->Add(pOpenGL, inputFlags);
3954 pOpenGL->Enable(!g_bdisable_opengl);
3955
3956
3957 wxButton* bOpenGL =
3958 new wxButton(m_ChartDisplayPage, ID_OPENGLOPTIONS, _("OpenGL Options") + _T("..."));
3959 OpenGLSizer->Add(bOpenGL, inputFlags);
3960 bOpenGL->Enable(!g_bdisable_opengl);
3961
3962 #ifdef __OCPN__ANDROID__
3963 pOpenGL->Hide();
3964 bOpenGL->Hide();
3965 #endif
3966
3967 itemBoxSizerUI->Add(0, border_size * 3);
3968 itemBoxSizerUI->Add(0, border_size * 3);
3969
3970 // Course Up display update period
3971 wxStaticText *crat = new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Chart Rotation Averaging Time"));
3972 crat->Wrap(-1);
3973 wrapperSizer->Add(crat, 0, wxALL | wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, group_item_spacing);
3974
3975
3976 wxBoxSizer* pCOGUPFilterRow = new wxBoxSizer(wxHORIZONTAL);
3977 wrapperSizer->Add(pCOGUPFilterRow, 0, wxALL | wxEXPAND, group_item_spacing);
3978
3979 pCOGUPUpdateSecs =
3980 new wxTextCtrl(m_ChartDisplayPage, ID_OPTEXTCTRL, _T(""), wxDefaultPosition, wxSize(sz.x / 5, -1), wxTE_RIGHT);
3981 pCOGUPFilterRow->Add(pCOGUPUpdateSecs, 0, wxALIGN_RIGHT | wxALL, group_item_spacing);
3982
3983 pCOGUPFilterRow->Add( new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("seconds")), inputFlags);
3984
3985 itemBoxSizerUI->Add(0, border_size * 3);
3986 itemBoxSizerUI->Add(0, border_size * 3);
3987
3988 // Chart Zoom Scale Weighting
3989 wxStaticText* zoomTextHead = new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Chart Zoom/Scale Weighting"));
3990 zoomTextHead->Wrap(-1);
3991 itemBoxSizerUI->Add(zoomTextHead, 0, wxALL | wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL, group_item_spacing);
3992 itemBoxSizerUI->Add(0, border_size * 1);
3993
3994 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Raster")), inputFlags);
3995
3996 m_pSlider_Zoom = new wxSlider(m_ChartDisplayPage, ID_RASTERZOOM, 0, -5, 5,
3997 wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
3998
3999 #ifdef __OCPN__ANDROID__
4000 prepareSlider(m_pSlider_Zoom);
4001 #endif
4002
4003 itemBoxSizerUI->Add(m_pSlider_Zoom, inputFlags);
4004
4005 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Vector")), inputFlags);
4006
4007 m_pSlider_Zoom_Vector = new wxSlider( m_ChartDisplayPage, ID_VECZOOM, 0, -5, 5,
4008 wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
4009
4010 #ifdef __OCPN__ANDROID__
4011 prepareSlider(m_pSlider_Zoom_Vector);
4012 #endif
4013
4014 itemBoxSizerUI->Add(m_pSlider_Zoom_Vector, inputFlags);
4015
4016 itemBoxSizerUI->Add(
4017 new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("CM93 Detail level")), inputFlags);
4018 m_pSlider_CM93_Zoom = new wxSlider( m_ChartDisplayPage, ID_CM93ZOOM, 0,
4019 -CM93_ZOOM_FACTOR_MAX_RANGE, CM93_ZOOM_FACTOR_MAX_RANGE,
4020 wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
4021
4022 #ifdef __OCPN__ANDROID__
4023 prepareSlider(m_pSlider_CM93_Zoom);
4024 #endif
4025
4026 itemBoxSizerUI->Add(m_pSlider_CM93_Zoom, 0, wxALL, border_size);
4027
4028
4029 itemBoxSizerUI->Add(0, border_size * 3);
4030 itemBoxSizerUI->Add(0, border_size * 3);
4031 itemBoxSizerUI->Add(0, border_size * 3);
4032
4033 // Display size/DPI
4034 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage,
4035 wxID_ANY, _("Physical Screen Width")), inputFlags);
4036 wxBoxSizer* pDPIRow = new wxBoxSizer(wxHORIZONTAL);
4037 itemBoxSizerUI->Add(pDPIRow, 0, wxEXPAND);
4038
4039 pRBSizeAuto = new wxRadioButton(m_ChartDisplayPage, wxID_ANY, _("Auto"));
4040 pDPIRow->Add(pRBSizeAuto, inputFlags);
4041 pDPIRow->AddSpacer(10);
4042 pRBSizeManual = new wxRadioButton(m_ChartDisplayPage, ID_SIZEMANUALRADIOBUTTON, _("Manual:"));
4043 pDPIRow->Add(pRBSizeManual, inputFlags);
4044
4045 wxBoxSizer* pmmRow = new wxBoxSizer(wxHORIZONTAL);
4046 itemBoxSizerUI->Add(pmmRow, 0, wxEXPAND);
4047
4048 pScreenMM = new wxTextCtrl(m_ChartDisplayPage, ID_OPTEXTCTRL, _T(""), wxDefaultPosition, wxSize(sz.x / 5, -1), wxTE_RIGHT);
4049 pmmRow->Add(pScreenMM, 0, wxALIGN_RIGHT | wxALL, group_item_spacing);
4050
4051 pmmRow->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("mm")), inputFlags);
4052
4053 pRBSizeAuto->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
4054 wxCommandEventHandler(options::OnSizeAutoButton), NULL,
4055 this);
4056 pRBSizeManual->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
4057 wxCommandEventHandler(options::OnSizeManualButton),
4058 NULL, this);
4059
4060 }
4061
4062 else {
4063 wxFlexGridSizer* itemBoxSizerUI = new wxFlexGridSizer(2);
4064 itemBoxSizerUI->SetHGap(border_size);
4065 // itemBoxSizerUI->AddGrowableCol( 0, 1 );
4066 // itemBoxSizerUI->AddGrowableCol( 1, 1 );
4067 // m_ChartDisplayPage->SetSizer( itemBoxSizerUI );
4068
4069 // wxFlexGridSizer grows wrongly in wx2.8, so we need to centre it in
4070 // another sizer instead of letting it grow.
4071 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
4072 m_ChartDisplayPage->SetSizer(wrapperSizer);
4073 wrapperSizer->Add(itemBoxSizerUI, 1, wxALL | wxALIGN_CENTER, border_size);
4074
4075 // spacer
4076 itemBoxSizerUI->Add(0, border_size * 3);
4077 itemBoxSizerUI->Add(0, border_size * 3);
4078
4079 // Chart Display Options
4080 itemBoxSizerUI->Add(
4081 new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Chart Display")),
4082 groupLabelFlags);
4083 wxBoxSizer* boxCharts = new wxBoxSizer(wxVERTICAL);
4084 itemBoxSizerUI->Add(boxCharts, groupInputFlags);
4085
4086 pSkewComp = new wxCheckBox(m_ChartDisplayPage, ID_SKEWCOMPBOX,
4087 _("Show Skewed Raster Charts as North-Up"));
4088 boxCharts->Add(pSkewComp, verticleInputFlags);
4089
4090 // pFullScreenQuilt = new wxCheckBox(m_ChartDisplayPage, ID_FULLSCREENQUILT,
4091 // _("Disable Full Screen Quilting"));
4092 // boxCharts->Add(pFullScreenQuilt, verticleInputFlags);
4093
4094 // pOverzoomEmphasis =
4095 // new wxCheckBox(m_ChartDisplayPage, ID_FULLSCREENQUILT,
4096 // _("Suppress blur/fog effects on overzoom"));
4097 // boxCharts->Add(pOverzoomEmphasis, verticleInputFlags);
4098 //
4099 // pOZScaleVector =
4100 // new wxCheckBox(m_ChartDisplayPage, ID_FULLSCREENQUILT,
4101 // _("Suppress scaled vector charts on overzoom"));
4102 // boxCharts->Add(pOZScaleVector, verticleInputFlags);
4103
4104 // spacer
4105 itemBoxSizerUI->Add(0, border_size * 3);
4106 itemBoxSizerUI->Add(0, border_size * 3);
4107
4108 // Course Up display update period
4109 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY,
4110 _("Chart Rotation Averaging Time")),
4111 labelFlags);
4112 wxBoxSizer* pCOGUPFilterRow = new wxBoxSizer(wxHORIZONTAL);
4113 itemBoxSizerUI->Add(pCOGUPFilterRow, 0, wxALL | wxEXPAND,
4114 group_item_spacing);
4115
4116 pCOGUPUpdateSecs =
4117 new wxTextCtrl(m_ChartDisplayPage, ID_OPTEXTCTRL, _T(""),
4118 wxDefaultPosition, wxSize(50, -1), wxTE_RIGHT);
4119 pCOGUPFilterRow->Add(pCOGUPUpdateSecs, 0, wxALL,
4120 group_item_spacing);
4121
4122 pCOGUPFilterRow->Add(
4123 new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("seconds")),
4124 inputFlags);
4125
4126 // spacer
4127 itemBoxSizerUI->Add(0, border_size * 8);
4128 itemBoxSizerUI->Add(0, border_size * 8);
4129
4130 // Chart Zoom Scale Weighting
4131 wxStaticText* zoomTextHead = new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Chart Zoom/Scale Weighting"));
4132
4133 itemBoxSizerUI->Add(zoomTextHead, labelFlags);
4134 itemBoxSizerUI->Add(0, border_size * 1);
4135 itemBoxSizerUI->Add(0, border_size * 1);
4136
4137 wxStaticText* zoomText =
4138 new wxStaticText(m_ChartDisplayPage, wxID_ANY,
4139 _("With a lower value, the same zoom level shows a less detailed chart.\n\
4140 With a higher value, the same zoom level shows a more detailed chart."));
4141
4142 smallFont = *dialogFont; // we can't use Smaller() because
4143 // wx2.8 doesn't support it
4144 smallFont.SetPointSize((smallFont.GetPointSize() / 1.2) +
4145 0.5); // + 0.5 to round instead of truncate
4146 zoomText->SetFont(smallFont);
4147 itemBoxSizerUI->Add(zoomText, 0, wxALL | wxEXPAND, group_item_spacing);
4148
4149 // spacer
4150 /*itemBoxSizerUI->Add(0, border_size * 8); itemBoxSizerUI->Add(0, border_size * 8);*/
4151
4152 //wxSize sz = g_Platform->getDisplaySize();
4153
4154 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Raster")), labelFlags);
4155 m_pSlider_Zoom = new wxSlider(m_ChartDisplayPage, ID_RASTERZOOM, 0, -5, 5, wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
4156
4157 #ifdef __OCPN__ANDROID__
4158 prepareSlider( m_pSlider_Zoom );
4159 #endif
4160
4161 itemBoxSizerUI->Add(m_pSlider_Zoom, inputFlags);
4162
4163 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Vector")), labelFlags);
4164 m_pSlider_Zoom_Vector = new wxSlider(m_ChartDisplayPage, ID_VECZOOM, 0, -5, 5,
4165 wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
4166
4167 #ifdef __OCPN__ANDROID__
4168 prepareSlider( m_pSlider_Zoom_Vector );
4169 #endif
4170
4171 itemBoxSizerUI->Add(m_pSlider_Zoom_Vector, inputFlags);
4172
4173 //Spacer
4174 itemBoxSizerUI->Add(0, border_size * 3); itemBoxSizerUI->Add(0, border_size * 3);
4175
4176 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY,
4177 _("CM93 Detail level")), labelFlags);
4178 m_pSlider_CM93_Zoom = new wxSlider(m_ChartDisplayPage, ID_CM93ZOOM, 0,
4179 -CM93_ZOOM_FACTOR_MAX_RANGE, CM93_ZOOM_FACTOR_MAX_RANGE,
4180 wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
4181
4182 #ifdef __OCPN__ANDROID__
4183 prepareSlider(m_pSlider_CM93_Zoom);
4184 #endif
4185
4186 itemBoxSizerUI->Add(m_pSlider_CM93_Zoom, 0, wxALL, border_size);
4187
4188 // spacer
4189 itemBoxSizerUI->Add(0, border_size * 3); itemBoxSizerUI->Add(0, border_size * 3);
4190 itemBoxSizerUI->Add(0, border_size * 3); itemBoxSizerUI->Add(0, border_size * 3);
4191 itemBoxSizerUI->Add(0, border_size * 3); itemBoxSizerUI->Add(0, border_size * 3);
4192
4193 // Display size/DPI
4194 itemBoxSizerUI->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY,
4195 _("Physical Screen Width")),
4196 labelFlags);
4197 wxBoxSizer* pDPIRow = new wxBoxSizer(wxHORIZONTAL);
4198 itemBoxSizerUI->Add(pDPIRow, 0, wxEXPAND);
4199
4200 pRBSizeAuto = new wxRadioButton(m_ChartDisplayPage, wxID_ANY, _("Auto"));
4201 pDPIRow->Add(pRBSizeAuto, inputFlags);
4202 pDPIRow->AddSpacer(10);
4203 pRBSizeManual = new wxRadioButton(m_ChartDisplayPage,
4204 ID_SIZEMANUALRADIOBUTTON, _("Manual:"));
4205 pDPIRow->Add(pRBSizeManual, inputFlags);
4206
4207 pScreenMM = new wxTextCtrl(m_ChartDisplayPage, ID_OPTEXTCTRL, _T(""),
4208 wxDefaultPosition, wxSize(3 * m_fontHeight, -1),
4209 wxTE_RIGHT);
4210 pDPIRow->Add(pScreenMM, 0, wxALL, group_item_spacing);
4211
4212 pDPIRow->Add(new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("mm")),
4213 inputFlags);
4214
4215 pRBSizeAuto->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
4216 wxCommandEventHandler(options::OnSizeAutoButton), NULL,
4217 this);
4218 pRBSizeManual->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
4219 wxCommandEventHandler(options::OnSizeManualButton),
4220 NULL, this);
4221
4222 // spacer
4223 itemBoxSizerUI->Add(0, border_size * 3);
4224 itemBoxSizerUI->Add(0, border_size * 3);
4225
4226 // OpenGL Options
4227 itemBoxSizerUI->Add(
4228 new wxStaticText(m_ChartDisplayPage, wxID_ANY, _("Graphics")),
4229 labelFlags);
4230 wxBoxSizer* OpenGLSizer = new wxBoxSizer(wxHORIZONTAL);
4231 itemBoxSizerUI->Add(OpenGLSizer, 0, 0, 0);
4232
4233 pOpenGL = new wxCheckBox(m_ChartDisplayPage, ID_OPENGLBOX,
4234 _("Use Accelerated Graphics (OpenGL)"));
4235 OpenGLSizer->Add(pOpenGL, inputFlags);
4236 pOpenGL->Enable(!g_bdisable_opengl);
4237
4238 #ifdef __OCPN__ANDROID__
4239 pOpenGL->Disable();
4240 #endif
4241
4242 wxButton* bOpenGL =
4243 new wxButton(m_ChartDisplayPage, ID_OPENGLOPTIONS, _("Options") + _T("..."));
4244 OpenGLSizer->Add(bOpenGL, inputFlags);
4245 bOpenGL->Enable(!g_bdisable_opengl);
4246
4247 itemBoxSizerUI->Add(0, border_size * 3);
4248 /*
4249 pTransparentToolbar =
4250 new wxCheckBox(m_ChartDisplayPage, ID_TRANSTOOLBARCHECKBOX,
4251 _("Enable Transparent Toolbar"));
4252 itemBoxSizerUI->Add(pTransparentToolbar, 0, wxALL, border_size);
4253 if (g_bopengl && !g_bTransparentToolbarInOpenGLOK)
4254 pTransparentToolbar->Disable();
4255 */
4256 }
4257 }
4258
CreatePanel_VectorCharts(size_t parent,int border_size,int group_item_spacing)4259 void options::CreatePanel_VectorCharts(size_t parent, int border_size,
4260 int group_item_spacing) {
4261 ps57Ctl = AddPage(parent, _("Vector Chart Display"));
4262
4263 if (!m_bcompact) {
4264 vectorPanel = new wxBoxSizer(wxHORIZONTAL);
4265 ps57Ctl->SetSizer(vectorPanel);
4266
4267 // 1st column, all options except Mariner's Standard
4268 wxFlexGridSizer* optionsColumn = new wxFlexGridSizer(2);
4269 optionsColumn->SetHGap(border_size);
4270 optionsColumn->AddGrowableCol(0, 2);
4271 optionsColumn->AddGrowableCol(1, 3);
4272 vectorPanel->Add(optionsColumn, 3, wxALL | wxEXPAND, border_size);
4273
4274 // spacer
4275 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4276 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4277
4278 if(!g_useMUI){
4279 // display category
4280 optionsColumn->Add( new wxStaticText(ps57Ctl, wxID_ANY, _("Display Category")), labelFlags);
4281 wxString pDispCatStrings[] = {_("Base"), _("Standard"), _("All"), _("Mariner's Standard")};
4282 pDispCat = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4283 wxDefaultSize, 4, pDispCatStrings);
4284 optionsColumn->Add(pDispCat, 0, wxALL, 2);
4285 }
4286
4287 // spacer
4288 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4289 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4290
4291
4292 // display options
4293 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Display")), groupLabelFlags);
4294
4295 wxBoxSizer* miscSizer = new wxBoxSizer(wxVERTICAL);
4296 optionsColumn->Add(miscSizer, groupInputFlags);
4297
4298 if(!g_useMUI){
4299 pCheck_SOUNDG = new wxCheckBox(ps57Ctl, ID_SOUNDGCHECKBOX, _("Depth Soundings"));
4300 pCheck_SOUNDG->SetValue(FALSE);
4301 miscSizer->Add(pCheck_SOUNDG, verticleInputFlags);
4302 }
4303
4304 pCheck_META = new wxCheckBox(ps57Ctl, ID_METACHECKBOX, _("Chart Information Objects"));
4305 pCheck_META->SetValue(FALSE);
4306 miscSizer->Add(pCheck_META, verticleInputFlags);
4307
4308
4309 if(!g_useMUI){
4310 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Buoys/Lights")), groupLabelFlags);
4311
4312 wxBoxSizer* lightSizer = new wxBoxSizer(wxVERTICAL);
4313 optionsColumn->Add(lightSizer, groupInputFlags);
4314
4315 pCheck_ATONTEXT = new wxCheckBox(ps57Ctl, ID_ATONTEXTCHECKBOX, _("Buoy/Light Labels"));
4316 pCheck_ATONTEXT->SetValue(FALSE);
4317 lightSizer->Add(pCheck_ATONTEXT, verticleInputFlags);
4318
4319 pCheck_LDISTEXT = new wxCheckBox(ps57Ctl, ID_LDISTEXTCHECKBOX, _("Light Descriptions"));
4320 pCheck_LDISTEXT->SetValue(FALSE);
4321 lightSizer->Add(pCheck_LDISTEXT, verticleInputFlags);
4322
4323 pCheck_XLSECTTEXT = new wxCheckBox(ps57Ctl, ID_LDISTEXTCHECKBOX, _("Extended Light Sectors"));
4324 pCheck_XLSECTTEXT->SetValue(FALSE);
4325 lightSizer->Add(pCheck_XLSECTTEXT, verticleInputFlags);
4326 }
4327
4328 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Chart Texts")), groupLabelFlags);
4329
4330 wxBoxSizer* textSizer = new wxBoxSizer(wxVERTICAL);
4331 optionsColumn->Add(textSizer, groupInputFlags);
4332
4333 pCheck_NATIONALTEXT = new wxCheckBox(ps57Ctl, ID_NATIONALTEXTCHECKBOX, _("National text on chart"));
4334 pCheck_NATIONALTEXT->SetValue(FALSE);
4335 textSizer->Add(pCheck_NATIONALTEXT, verticleInputFlags);
4336
4337 pCheck_SHOWIMPTEXT =
4338 new wxCheckBox(ps57Ctl, ID_IMPTEXTCHECKBOX, _("Important Text Only"));
4339 pCheck_SHOWIMPTEXT->SetValue(FALSE);
4340 textSizer->Add(pCheck_SHOWIMPTEXT, verticleInputFlags);
4341
4342 pCheck_DECLTEXT =
4343 new wxCheckBox(ps57Ctl, ID_DECLTEXTCHECKBOX, _("De-Cluttered Text"));
4344 pCheck_DECLTEXT->SetValue(FALSE);
4345 textSizer->Add(pCheck_DECLTEXT, verticleInputFlags);
4346
4347 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Chart Detail")),
4348 labelFlags);
4349 pCheck_SCAMIN = new wxCheckBox(ps57Ctl, ID_SCAMINCHECKBOX,
4350 _("Reduced Detail at Small Scale"));
4351 pCheck_SCAMIN->SetValue(FALSE);
4352 optionsColumn->Add(pCheck_SCAMIN, inputFlags);
4353
4354 // spacer
4355 optionsColumn->Add(0, border_size * 4);
4356 optionsColumn->Add(0, border_size * 4);
4357
4358 // graphics options
4359 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Graphics Style")),
4360 labelFlags);
4361 wxString pPointStyleStrings[] = {
4362 _("Paper Chart"), _("Simplified"),
4363 };
4364 pPointStyle = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4365 wxDefaultSize, 2, pPointStyleStrings);
4366 optionsColumn->Add(pPointStyle, inputFlags);
4367
4368 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Boundaries")),
4369 labelFlags);
4370 wxString pBoundStyleStrings[] = {
4371 _("Plain"), _("Symbolized"),
4372 };
4373 pBoundStyle = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4374 wxDefaultSize, 2, pBoundStyleStrings);
4375 optionsColumn->Add(pBoundStyle, inputFlags);
4376
4377 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Colors")),
4378 labelFlags);
4379 wxString pColorNumStrings[] = {
4380 _("2 Color"), _("4 Color"),
4381 };
4382 p24Color = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4383 wxDefaultSize, 2, pColorNumStrings);
4384 optionsColumn->Add(p24Color, inputFlags);
4385
4386 // spacer
4387 optionsColumn->Add(0, border_size * 4);
4388 optionsColumn->Add(0, border_size * 4);
4389
4390 // depth options
4391 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Shallow Depth")),
4392 labelFlags);
4393 wxBoxSizer* depShalRow = new wxBoxSizer(wxHORIZONTAL);
4394 optionsColumn->Add(depShalRow);
4395 m_ShallowCtl =
4396 new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
4397 wxSize(60, -1), wxTE_RIGHT);
4398 depShalRow->Add(m_ShallowCtl, inputFlags);
4399 m_depthUnitsShal = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4400 depShalRow->Add(m_depthUnitsShal, inputFlags);
4401
4402 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Safety Depth")),
4403 labelFlags);
4404 wxBoxSizer* depSafeRow = new wxBoxSizer(wxHORIZONTAL);
4405 optionsColumn->Add(depSafeRow);
4406 m_SafetyCtl = new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""),
4407 wxDefaultPosition, wxSize(60, -1), wxTE_RIGHT);
4408 depSafeRow->Add(m_SafetyCtl, inputFlags);
4409 m_depthUnitsSafe = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4410 depSafeRow->Add(m_depthUnitsSafe, inputFlags);
4411
4412 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Deep Depth")),
4413 labelFlags);
4414 wxBoxSizer* depDeepRow = new wxBoxSizer(wxHORIZONTAL);
4415 optionsColumn->Add(depDeepRow);
4416 m_DeepCtl = new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""),
4417 wxDefaultPosition, wxSize(60, -1), wxTE_RIGHT);
4418 depDeepRow->Add(m_DeepCtl, inputFlags);
4419 m_depthUnitsDeep = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4420 depDeepRow->Add(m_depthUnitsDeep, inputFlags);
4421
4422
4423 // 2nd column, Display Category / Mariner's Standard options
4424 wxBoxSizer* dispSizer = new wxBoxSizer(wxVERTICAL);
4425 vectorPanel->Add(dispSizer, 2, wxALL | wxEXPAND, border_size);
4426
4427 wxStaticBox* marinersBox =
4428 new wxStaticBox(ps57Ctl, wxID_ANY, _("User Standard Objects"));
4429 wxStaticBoxSizer* marinersSizer =
4430 new wxStaticBoxSizer(marinersBox, wxVERTICAL);
4431 dispSizer->Add(marinersSizer, 1, wxALL | wxEXPAND, border_size);
4432
4433 ps57CtlListBox = new OCPNCheckedListCtrl(
4434 ps57Ctl, ID_CHECKLISTBOX, wxDefaultPosition, wxSize(250, 350));
4435 marinersSizer->Add(ps57CtlListBox, 1, wxALL | wxEXPAND, group_item_spacing);
4436
4437 wxBoxSizer* btnRow1 = new wxBoxSizer(wxHORIZONTAL);
4438 itemButtonSelectList = new wxButton(ps57Ctl, ID_SELECTLIST, _("Select All"));
4439 btnRow1->Add(itemButtonSelectList, 1, wxALL | wxEXPAND, group_item_spacing);
4440 itemButtonClearList = new wxButton(ps57Ctl, ID_CLEARLIST, _("Clear All"));
4441 btnRow1->Add(itemButtonClearList, 1, wxALL | wxEXPAND, group_item_spacing);
4442 marinersSizer->Add(btnRow1);
4443
4444 wxBoxSizer* btnRow2 = new wxBoxSizer(wxHORIZONTAL);
4445 itemButtonSetStd = new wxButton(ps57Ctl, ID_SETSTDLIST, _("Reset to STANDARD"));
4446 btnRow2->Add(itemButtonSetStd, 1, wxALL | wxEXPAND, group_item_spacing);
4447 marinersSizer->Add(btnRow2);
4448
4449
4450 }
4451
4452 else { // compact
4453 vectorPanel = new wxBoxSizer(wxVERTICAL);
4454 ps57Ctl->SetSizer(vectorPanel);
4455
4456 wxBoxSizer* optionsColumn = vectorPanel;
4457
4458 // spacer
4459 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4460
4461 // display category
4462 if(!g_useMUI){
4463 optionsColumn->Add( new wxStaticText(ps57Ctl, wxID_ANY, _("Display Category")), inputFlags);
4464 wxString pDispCatStrings[] = {_("Base"), _("Standard"), _("All"), _("Mariner's Standard")};
4465 pDispCat = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4466 wxSize(350, -1), 4, pDispCatStrings);
4467 optionsColumn->Add(pDispCat, 0, wxALL, 2);
4468
4469 // spacer
4470 optionsColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _T("")));
4471
4472 }
4473
4474 // display options
4475
4476 wxBoxSizer* miscSizer = new wxBoxSizer(wxVERTICAL);
4477 optionsColumn->Add(miscSizer, groupInputFlags);
4478
4479 pCheck_SOUNDG =
4480 new wxCheckBox(ps57Ctl, ID_SOUNDGCHECKBOX, _("Depth Soundings"));
4481 pCheck_SOUNDG->SetValue(FALSE);
4482 miscSizer->Add(pCheck_SOUNDG, inputFlags);
4483
4484 pCheck_META = new wxCheckBox(ps57Ctl, ID_METACHECKBOX,
4485 _("Chart Information Objects"));
4486 pCheck_META->SetValue(FALSE);
4487 miscSizer->Add(pCheck_META, inputFlags);
4488
4489 wxBoxSizer* lightSizer = new wxBoxSizer(wxVERTICAL);
4490 optionsColumn->Add(lightSizer, groupInputFlags);
4491
4492 pCheck_ATONTEXT =
4493 new wxCheckBox(ps57Ctl, ID_ATONTEXTCHECKBOX, _("Buoy/Light Labels"));
4494 pCheck_ATONTEXT->SetValue(FALSE);
4495 lightSizer->Add(pCheck_ATONTEXT, inputFlags);
4496
4497 pCheck_LDISTEXT =
4498 new wxCheckBox(ps57Ctl, ID_LDISTEXTCHECKBOX, _("Light Descriptions"));
4499 pCheck_LDISTEXT->SetValue(FALSE);
4500 lightSizer->Add(pCheck_LDISTEXT, inputFlags);
4501
4502 pCheck_XLSECTTEXT = new wxCheckBox(ps57Ctl, ID_LDISTEXTCHECKBOX, _("Extended Light Sectors"));
4503 pCheck_XLSECTTEXT->SetValue(FALSE);
4504 lightSizer->Add(pCheck_XLSECTTEXT, inputFlags);
4505
4506 wxBoxSizer* textSizer = new wxBoxSizer(wxVERTICAL);
4507 optionsColumn->Add(textSizer, groupInputFlags);
4508
4509 pCheck_NATIONALTEXT = new wxCheckBox(ps57Ctl, ID_NATIONALTEXTCHECKBOX,
4510 _("National text on chart"));
4511 pCheck_NATIONALTEXT->SetValue(FALSE);
4512 textSizer->Add(pCheck_NATIONALTEXT, inputFlags);
4513
4514 pCheck_SHOWIMPTEXT =
4515 new wxCheckBox(ps57Ctl, ID_IMPTEXTCHECKBOX, _("Important Text Only"));
4516 pCheck_SHOWIMPTEXT->SetValue(FALSE);
4517 textSizer->Add(pCheck_SHOWIMPTEXT, inputFlags);
4518
4519 pCheck_DECLTEXT =
4520 new wxCheckBox(ps57Ctl, ID_DECLTEXTCHECKBOX, _("De-Cluttered Text"));
4521 pCheck_DECLTEXT->SetValue(FALSE);
4522 textSizer->Add(pCheck_DECLTEXT, inputFlags);
4523
4524 pCheck_SCAMIN = new wxCheckBox(ps57Ctl, ID_SCAMINCHECKBOX,
4525 _("Reduced Detail at Small Scale"));
4526 pCheck_SCAMIN->SetValue(FALSE);
4527 optionsColumn->Add(pCheck_SCAMIN, inputFlags);
4528
4529 // spacer
4530 optionsColumn->Add(0, border_size * 4);
4531 optionsColumn->Add(0, border_size * 4);
4532
4533 // graphics options
4534
4535 wxFlexGridSizer* StyleColumn = new wxFlexGridSizer(2);
4536 StyleColumn->SetHGap(border_size);
4537 StyleColumn->AddGrowableCol(0, 2);
4538 StyleColumn->AddGrowableCol(1, 3);
4539 optionsColumn->Add(StyleColumn);
4540
4541 StyleColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Graphics Style")), inputFlags);
4542 wxString pPointStyleStrings[] = {
4543 _("Paper Chart"), _("Simplified"),
4544 };
4545 pPointStyle = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4546 wxSize(m_fontHeight * 3, m_fontHeight), 2, pPointStyleStrings);
4547 #ifdef __OCPN__ANDROID__
4548 setChoiceStyleSheet( pPointStyle, m_fontHeight *8/10);
4549 #endif
4550
4551 StyleColumn->Add(pPointStyle, inputFlags);
4552
4553 StyleColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Boundaries")), inputFlags);
4554 wxString pBoundStyleStrings[] = {
4555 _("Plain"), _("Symbolized"),
4556 };
4557 pBoundStyle = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4558 wxSize(m_fontHeight * 3, m_fontHeight), 2, pBoundStyleStrings);
4559 #ifdef __OCPN__ANDROID__
4560 setChoiceStyleSheet( pBoundStyle, m_fontHeight *8/10);
4561 #endif
4562
4563 StyleColumn->Add(pBoundStyle, inputFlags);
4564
4565 StyleColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Colors")), inputFlags);
4566
4567 wxString pColorNumStrings[] = {
4568 _("2 Color"), _("4 Color"),
4569 };
4570 p24Color = new wxChoice(ps57Ctl, ID_RADARDISTUNIT, wxDefaultPosition,
4571 wxSize(m_fontHeight * 3, m_fontHeight), 2, pColorNumStrings);
4572 #ifdef __OCPN__ANDROID__
4573 setChoiceStyleSheet( p24Color, m_fontHeight *8/10);
4574 #endif
4575 StyleColumn->Add(p24Color, inputFlags);
4576
4577 // spacer
4578 optionsColumn->Add(0, border_size * 4);
4579 optionsColumn->Add(0, border_size * 4);
4580
4581 wxFlexGridSizer* DepthColumn = new wxFlexGridSizer(3);
4582 DepthColumn->SetHGap(border_size);
4583 DepthColumn->AddGrowableCol(0, 3);
4584 DepthColumn->AddGrowableCol(1, 2);
4585 DepthColumn->AddGrowableCol(2, 3);
4586 optionsColumn->Add(DepthColumn);
4587
4588 // depth options
4589 DepthColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Shallow Depth")),
4590 inputFlags);
4591 m_ShallowCtl = new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
4592 wxSize(m_fontHeight * 2, m_fontHeight), wxTE_RIGHT);
4593 DepthColumn->Add(m_ShallowCtl, inputFlags);
4594 m_depthUnitsShal = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4595 DepthColumn->Add(m_depthUnitsShal, inputFlags);
4596
4597 DepthColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Safety Depth")), inputFlags);
4598 m_SafetyCtl = new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
4599 wxSize(m_fontHeight * 2, m_fontHeight), wxTE_RIGHT);
4600 DepthColumn->Add(m_SafetyCtl, inputFlags);
4601 m_depthUnitsSafe = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4602 DepthColumn->Add(m_depthUnitsSafe, inputFlags);
4603
4604 DepthColumn->Add(new wxStaticText(ps57Ctl, wxID_ANY, _("Deep Depth")), inputFlags);
4605 m_DeepCtl = new wxTextCtrl(ps57Ctl, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
4606 wxSize(m_fontHeight * 2, m_fontHeight), wxTE_CENTER);
4607 DepthColumn->Add(m_DeepCtl, inputFlags);
4608 m_depthUnitsDeep = new wxStaticText(ps57Ctl, wxID_ANY, _("meters"));
4609 DepthColumn->Add(m_depthUnitsDeep, inputFlags);
4610
4611 // spacer
4612 optionsColumn->Add(0, border_size * 4);
4613 optionsColumn->Add(0, border_size * 4);
4614
4615 // Display Category / Mariner's Standard options
4616 wxBoxSizer* dispSizer = new wxBoxSizer(wxVERTICAL);
4617 vectorPanel->Add(dispSizer, 2, wxALL | wxEXPAND, border_size);
4618
4619 wxStaticBox* marinersBox =
4620 new wxStaticBox(ps57Ctl, wxID_ANY, _("User Standard Objects"));
4621 wxStaticBoxSizer* marinersSizer =
4622 new wxStaticBoxSizer(marinersBox, wxVERTICAL);
4623 dispSizer->Add(marinersSizer, 1, wxALL | wxEXPAND, border_size);
4624
4625 wxBoxSizer* btnRow1 = new wxBoxSizer(wxHORIZONTAL);
4626 itemButtonSelectList = new wxButton(ps57Ctl, ID_SELECTLIST, _("Select All"));
4627 btnRow1->Add(itemButtonSelectList, 1, wxALL | wxEXPAND, group_item_spacing);
4628 itemButtonClearList = new wxButton(ps57Ctl, ID_CLEARLIST, _("Clear All"));
4629 btnRow1->Add(itemButtonClearList, 1, wxALL | wxEXPAND, group_item_spacing);
4630 marinersSizer->Add(btnRow1);
4631
4632 wxBoxSizer* btnRow2 = new wxBoxSizer(wxHORIZONTAL);
4633 itemButtonSetStd = new wxButton(ps57Ctl, ID_SETSTDLIST, _("Reset to STANDARD"));
4634 btnRow2->Add(itemButtonSetStd, 1, wxALL | wxEXPAND, group_item_spacing);
4635 marinersSizer->Add(btnRow2);
4636
4637
4638 // #if defined(__WXMSW__) || defined(__WXOSX__)
4639 // wxString* ps57CtlListBoxStrings = NULL;
4640 // ps57CtlListBox = new wxCheckListBox(
4641 // ps57Ctl, ID_CHECKLISTBOX, wxDefaultPosition, wxSize(250, 350), 0,
4642 // ps57CtlListBoxStrings, wxLB_SINGLE | wxLB_HSCROLL | wxLB_SORT);
4643 // #else
4644 ps57CtlListBox = new OCPNCheckedListCtrl(
4645 ps57Ctl, ID_CHECKLISTBOX, wxDefaultPosition, wxSize(250, 350));
4646 // #endif
4647
4648 marinersSizer->Add(ps57CtlListBox, 1, wxALL | wxEXPAND, group_item_spacing);
4649 }
4650 }
4651
CreatePanel_TidesCurrents(size_t parent,int border_size,int group_item_spacing)4652 void options::CreatePanel_TidesCurrents(size_t parent, int border_size,
4653 int group_item_spacing) {
4654 wxScrolledWindow* tcPanel = AddPage(parent, _("Tides && Currents"));
4655
4656 wxBoxSizer* mainHBoxSizer = new wxBoxSizer(wxVERTICAL);
4657 tcPanel->SetSizer(mainHBoxSizer);
4658
4659 wxStaticBox* tcBox = new wxStaticBox(tcPanel, wxID_ANY, _("Active Datasets"));
4660 wxStaticBoxSizer* tcSizer = new wxStaticBoxSizer(tcBox, wxHORIZONTAL);
4661 mainHBoxSizer->Add(tcSizer, 1, wxALL | wxEXPAND, border_size);
4662
4663 tcDataSelected = new wxListCtrl(tcPanel, ID_TIDESELECTED, wxDefaultPosition, wxSize(100, -1), wxLC_REPORT | wxLC_NO_HEADER);
4664
4665 tcSizer->Add(tcDataSelected, 1, wxALL | wxEXPAND, border_size);
4666
4667 // Populate Selection List Control with the contents
4668 // of the Global static array
4669 tcDataSelected->DeleteAllItems();
4670
4671 // Add first column
4672 wxListItem col0;
4673 col0.SetId(0);
4674 col0.SetText( _("") );
4675 col0.SetWidth(500);
4676 col0.SetAlign(wxLIST_FORMAT_LEFT);
4677
4678 tcDataSelected->InsertColumn(0, col0);
4679
4680 for (unsigned int id = 0; id < TideCurrentDataSet.Count(); id++) {
4681 wxListItem li;
4682 li.SetId( id );
4683 long idx = tcDataSelected->InsertItem( li );
4684
4685 wxString setName = TideCurrentDataSet[id];
4686 tcDataSelected->SetItem(id, 0, setName);
4687 }
4688
4689 // Add the "Insert/Remove" buttons
4690 wxButton* insertButton =
4691 new wxButton(tcPanel, ID_TCDATAADD, _("Add Dataset..."));
4692 wxButton* removeButton =
4693 new wxButton(tcPanel, ID_TCDATADEL, _("Remove Selected"));
4694
4695 wxBoxSizer* btnSizer = new wxBoxSizer(wxVERTICAL);
4696 tcSizer->Add(btnSizer);
4697
4698 btnSizer->Add(insertButton, 1, wxALL | wxEXPAND, group_item_spacing);
4699 btnSizer->Add(removeButton, 1, wxALL | wxEXPAND, group_item_spacing);
4700 }
4701
CreatePanel_ChartGroups(size_t parent,int border_size,int group_item_spacing)4702 void options::CreatePanel_ChartGroups(size_t parent, int border_size, int group_item_spacing)
4703 {
4704 // Special case for adding the tab here. We know this page has multiple tabs,
4705 // and we have the actual widgets in a separate class (because of its
4706 // complexity)
4707
4708 wxWindow *chartsPage = m_pListbook->GetPage(parent);
4709 groupsPanel = new ChartGroupsUI(chartsPage);
4710
4711 groupsPanel->m_panel = AddPage(parent, _("Chart Groups"));
4712
4713 groupsPanel->CreatePanel(parent, border_size, group_item_spacing);
4714
4715 }
4716
CreatePanel(size_t parent,int border_size,int group_item_spacing)4717 void ChartGroupsUI::CreatePanel(size_t parent, int border_size,
4718 int group_item_spacing)
4719 {
4720
4721 modified = FALSE;
4722 m_border_size = border_size;
4723 m_group_item_spacing = group_item_spacing;
4724
4725
4726 m_UIcomplete = FALSE;
4727
4728 CompletePanel();
4729
4730 }
4731
CompletePanel(void)4732 void ChartGroupsUI::CompletePanel(void)
4733 {
4734 m_topSizer = new wxBoxSizer(wxVERTICAL);
4735 m_panel->SetSizer(m_topSizer);
4736
4737 // The chart file/dir tree
4738 wxStaticText* allChartsLabel = new wxStaticText(m_panel, wxID_ANY, _("All Available Charts"));
4739 m_topSizer->Add(allChartsLabel, 0, wxTOP | wxRIGHT | wxLEFT, m_border_size);
4740
4741 wxBoxSizer *sizerCharts = new wxBoxSizer(wxHORIZONTAL);
4742 m_topSizer->Add(sizerCharts, 1, wxALL | wxEXPAND, 5);
4743
4744 wxBoxSizer* activeListSizer = new wxBoxSizer(wxVERTICAL);
4745 sizerCharts->Add(activeListSizer, 1, wxALL | wxEXPAND, 5);
4746
4747 #ifdef __OCPN__ANDROID__
4748 allAvailableCtl = new wxGenericDirCtrl(m_panel, ID_GROUPAVAILABLE, _T(""), wxDefaultPosition, wxDefaultSize, wxVSCROLL);
4749 #else
4750 allAvailableCtl = new wxGenericDirCtrl(m_panel, ID_GROUPAVAILABLE, _T(""), wxDefaultPosition, wxDefaultSize, wxVSCROLL);
4751 #endif
4752 activeListSizer->Add(allAvailableCtl, 1, wxEXPAND);
4753
4754 m_pAddButton = new wxButton(m_panel, ID_GROUPINSERTDIR, _("Add"));
4755 m_pAddButton->Disable();
4756 m_pRemoveButton = new wxButton(m_panel, ID_GROUPREMOVEDIR, _("Remove Chart"));
4757 m_pRemoveButton->Disable();
4758
4759 m_pAddButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ChartGroupsUI::OnInsertChartItem), NULL, this );
4760 m_pRemoveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ChartGroupsUI::OnRemoveChartItem), NULL, this );
4761
4762 wxBoxSizer* addRemove = new wxBoxSizer(wxVERTICAL);
4763 sizerCharts->Add(addRemove, 0, wxALL | wxEXPAND, m_border_size);
4764 addRemove->Add(m_pAddButton, 0, wxALL | wxEXPAND, m_group_item_spacing);
4765
4766 sizerCharts->AddSpacer(20); // Avoid potential scrollbar
4767
4768 // Add the Groups notebook control
4769 wxStaticText* groupsLabel = new wxStaticText(m_panel, wxID_ANY, _("Chart Groups"));
4770 m_topSizer->Add(groupsLabel, 0, wxTOP | wxRIGHT | wxLEFT, m_border_size);
4771
4772
4773 wxBoxSizer *sizerGroups = new wxBoxSizer(wxHORIZONTAL);
4774 m_topSizer->Add(sizerGroups, 1, wxALL | wxEXPAND, 5);
4775
4776 wxBoxSizer* nbSizer = new wxBoxSizer(wxVERTICAL);
4777 sizerGroups->Add(nbSizer, 1, wxALL | wxEXPAND, m_border_size);
4778 m_GroupNB = new wxNotebook(m_panel, ID_GROUPNOTEBOOK, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
4779 nbSizer->Add(m_GroupNB, 1, wxEXPAND);
4780
4781 m_GroupNB->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler(ChartGroupsUI::OnGroupPageChange), NULL, this);
4782
4783 // Add default (always present) Default Chart Group
4784 wxPanel* allActiveGroup = new wxPanel(m_GroupNB, -1, wxDefaultPosition, wxDefaultSize);
4785 m_GroupNB->AddPage(allActiveGroup, _("All Charts"));
4786
4787 wxBoxSizer* page0BoxSizer = new wxBoxSizer(wxHORIZONTAL);
4788 allActiveGroup->SetSizer(page0BoxSizer);
4789
4790 defaultAllCtl = new wxGenericDirCtrl(allActiveGroup, -1, _T(""), wxDefaultPosition, wxDefaultSize);
4791
4792 // Set the Font for the All Active Chart Group tree to be italic, dimmed
4793 iFont = new wxFont(*dialogFont);
4794 iFont->SetStyle(wxFONTSTYLE_ITALIC);
4795 iFont->SetWeight(wxFONTWEIGHT_LIGHT);
4796
4797 page0BoxSizer->Add(defaultAllCtl, 1, wxALIGN_TOP | wxALL | wxEXPAND);
4798
4799 m_DirCtrlArray.Add(defaultAllCtl);
4800
4801 // Add the Chart Group (page) "New" and "Delete" buttons
4802 m_pNewGroupButton = new wxButton(m_panel, ID_GROUPNEWGROUP, _("New Group..."));
4803 m_pDeleteGroupButton = new wxButton(m_panel, ID_GROUPDELETEGROUP, _("Delete Group"));
4804 m_pDeleteGroupButton->Disable(); // for default "all Charts" group
4805
4806 m_pNewGroupButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ChartGroupsUI::OnNewGroup), NULL, this );
4807 m_pDeleteGroupButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ChartGroupsUI::OnDeleteGroup), NULL, this );
4808
4809 wxBoxSizer* newDeleteGrp = new wxBoxSizer(wxVERTICAL);
4810 sizerGroups->Add(newDeleteGrp, 0, wxALL, m_border_size);
4811
4812 newDeleteGrp->AddSpacer(25);
4813 newDeleteGrp->Add(m_pNewGroupButton, 0, wxALL | wxEXPAND,
4814 m_group_item_spacing);
4815 newDeleteGrp->AddSpacer(15);
4816 newDeleteGrp->Add(m_pDeleteGroupButton, 0, wxALL | wxEXPAND,
4817 m_group_item_spacing);
4818 newDeleteGrp->AddSpacer(25);
4819 newDeleteGrp->Add(m_pRemoveButton, 0, wxALL | wxEXPAND, m_group_item_spacing);
4820
4821 sizerGroups->AddSpacer(20); // Avoid potential scrollbar
4822
4823 // Connect this last, otherwise handler is called before all objects are initialized.
4824 m_panel->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(ChartGroupsUI::OnAvailableSelection), NULL, this);
4825
4826 m_UIcomplete = TRUE;
4827 }
4828
CreatePanel_Display(size_t parent,int border_size,int group_item_spacing)4829 void options::CreatePanel_Display(size_t parent, int border_size,
4830 int group_item_spacing) {
4831 pDisplayPanel = AddPage(parent, _("General"));
4832
4833 if (!m_bcompact) {
4834 wxFlexGridSizer* generalSizer = new wxFlexGridSizer(2);
4835 generalSizer->SetHGap(border_size);
4836 // generalSizer->AddGrowableCol( 0, 1 );
4837 // generalSizer->AddGrowableCol( 1, 1 );
4838 // pDisplayPanel->SetSizer( generalSizer );
4839
4840 // wxFlexGridSizer grows wrongly in wx2.8, so we need to centre it in
4841 // another sizer instead of letting it grow.
4842 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
4843 pDisplayPanel->SetSizer(wrapperSizer);
4844 wrapperSizer->Add(generalSizer, 1, wxALL | wxALIGN_CENTER, border_size);
4845
4846 // spacer
4847 generalSizer->Add(0, border_size * 4);
4848 generalSizer->Add(0, border_size * 4);
4849
4850 if(!g_useMUI){
4851 // Nav Mode
4852 generalSizer->Add(
4853 new wxStaticText(pDisplayPanel, wxID_ANY, _("Navigation Mode")),
4854 groupLabelFlags);
4855 wxBoxSizer* boxNavMode = new wxBoxSizer(wxVERTICAL);
4856 generalSizer->Add(boxNavMode, groupInputFlags);
4857
4858 wxBoxSizer* rowOrientation = new wxBoxSizer(wxHORIZONTAL);
4859 boxNavMode->Add(rowOrientation);
4860
4861 pCBNorthUp = new wxRadioButton(pDisplayPanel, wxID_ANY, _("North Up"));
4862 rowOrientation->Add(pCBNorthUp, inputFlags);
4863 pCBCourseUp =
4864 new wxRadioButton(pDisplayPanel, ID_COURSEUPCHECKBOX, _("Course Up"));
4865 rowOrientation->Add(pCBCourseUp,
4866 wxSizerFlags(0)
4867 .Align(wxALIGN_CENTRE_VERTICAL)
4868 .Border(wxLEFT, group_item_spacing * 2));
4869
4870 pCBLookAhead =
4871 new wxCheckBox(pDisplayPanel, ID_CHECK_LOOKAHEAD, _("Look Ahead Mode"));
4872 boxNavMode->Add(pCBLookAhead, verticleInputFlags);
4873
4874 // spacer
4875 generalSizer->Add(0, border_size * 4);
4876 generalSizer->Add(0, border_size * 4);
4877
4878 // Control Options
4879 generalSizer->Add(
4880 new wxStaticText(pDisplayPanel, wxID_ANY, _("Chart Display")),
4881 groupLabelFlags);
4882 wxBoxSizer* boxCharts = new wxBoxSizer(wxVERTICAL);
4883 generalSizer->Add(boxCharts, groupInputFlags);
4884
4885 pCDOQuilting = new wxCheckBox(pDisplayPanel, ID_QUILTCHECKBOX1,
4886 _("Enable Chart Quilting"));
4887 boxCharts->Add(pCDOQuilting, verticleInputFlags);
4888
4889 pPreserveScale = new wxCheckBox(pDisplayPanel, ID_PRESERVECHECKBOX,
4890 _("Preserve scale when switching charts"));
4891 boxCharts->Add(pPreserveScale, verticleInputFlags);
4892
4893 // spacer
4894 generalSizer->Add(0, border_size * 4);
4895 generalSizer->Add(0, border_size * 4);
4896 }
4897
4898 // Control Options
4899 generalSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Controls")),
4900 groupLabelFlags);
4901 wxBoxSizer* boxCtrls = new wxBoxSizer(wxVERTICAL);
4902 generalSizer->Add(boxCtrls, groupInputFlags);
4903
4904 pSmoothPanZoom = new wxCheckBox(pDisplayPanel, ID_SMOOTHPANZOOMBOX,
4905 _("Smooth Panning / Zooming"));
4906 boxCtrls->Add(pSmoothPanZoom, verticleInputFlags);
4907
4908 pEnableZoomToCursor =
4909 new wxCheckBox(pDisplayPanel, ID_ZTCCHECKBOX, _("Zoom to Cursor"));
4910 pEnableZoomToCursor->SetValue(FALSE);
4911 boxCtrls->Add(pEnableZoomToCursor, verticleInputFlags);
4912
4913 // spacer
4914 generalSizer->Add(0, border_size * 4);
4915 generalSizer->Add(0, border_size * 4);
4916
4917 if(!g_useMUI){
4918 // Display Options
4919 generalSizer->Add(
4920 new wxStaticText(pDisplayPanel, wxID_ANY, _("Display Features")),
4921 groupLabelFlags);
4922 wxBoxSizer* boxDisp = new wxBoxSizer(wxVERTICAL);
4923 generalSizer->Add(boxDisp, groupInputFlags);
4924
4925 pSDisplayGrid =
4926 new wxCheckBox(pDisplayPanel, ID_CHECK_DISPLAYGRID, _("Show Grid"));
4927 boxDisp->Add(pSDisplayGrid, verticleInputFlags);
4928
4929 pCDOOutlines = new wxCheckBox(pDisplayPanel, ID_OUTLINECHECKBOX1,
4930 _("Show Chart Outlines"));
4931 boxDisp->Add(pCDOOutlines, verticleInputFlags);
4932
4933 pSDepthUnits = new wxCheckBox(pDisplayPanel, ID_SHOWDEPTHUNITSBOX1,
4934 _("Show Depth Units"));
4935 boxDisp->Add(pSDepthUnits, verticleInputFlags);
4936
4937 }
4938
4939 // CUSTOMIZATION - LIVE ETA OPTION
4940 // -------------------------------
4941 // Add a checkbox to activate live ETA option in status bar, and
4942 // Add a text field to set default boat speed (for calculation when
4943 // no GPS or when the boat is at the harbor).
4944
4945 // Spacer
4946 generalSizer->Add(0, border_size * 4);
4947 generalSizer->Add(0, border_size * 4);
4948
4949 // New menu status bar
4950 generalSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Status Bar Option")),
4951 groupLabelFlags);
4952 wxBoxSizer* boxDispStatusBar = new wxBoxSizer(wxVERTICAL);
4953 generalSizer->Add(boxDispStatusBar, groupInputFlags);
4954
4955 // Add option for live ETA
4956 pSLiveETA = new wxCheckBox(pDisplayPanel, ID_CHECK_LIVEETA, _("Live ETA at Cursor"));
4957 boxDispStatusBar->Add(pSLiveETA, verticleInputFlags);
4958
4959 // Add text input for default boat speed
4960 // (for calculation, in case GPS speed is null)
4961 wxBoxSizer *defaultBoatSpeedSizer = new wxBoxSizer(wxHORIZONTAL);
4962 boxDispStatusBar->Add(defaultBoatSpeedSizer, wxALL, group_item_spacing);
4963 defaultBoatSpeedSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Default Boat Speed ")),
4964 groupLabelFlagsHoriz);
4965 pSDefaultBoatSpeed = new wxTextCtrl(pDisplayPanel, ID_DEFAULT_BOAT_SPEED, _T(""), wxDefaultPosition,
4966 wxSize(50, -1), wxTE_RIGHT);
4967 defaultBoatSpeedSizer->Add(pSDefaultBoatSpeed, 0, wxALIGN_CENTER_VERTICAL, group_item_spacing);
4968
4969 // --------------------------------------
4970 // END OF CUSTOMIZATION - LIVE ETA OPTION
4971
4972 #ifndef __OCPN__ANDROID__
4973 // MultiChart selection panel
4974 if(g_Platform->GetDisplayAreaCM2() > 100){
4975
4976 wxStaticBox* itemStaticBoxScreenConfig = new wxStaticBox(pDisplayPanel, wxID_ANY, _("Canvas Layout"));
4977 wxStaticBoxSizer* itemStaticBoxSizerScreenConfig = new wxStaticBoxSizer(itemStaticBoxScreenConfig, wxHORIZONTAL);
4978 wrapperSizer->Add(itemStaticBoxSizerScreenConfig, 1, wxALL | wxEXPAND, 5);
4979
4980 // The standard screen configs...
4981 wxString iconDir = g_Platform->GetSharedDataDir();
4982 appendOSDirSlash(&iconDir);
4983 iconDir.append(_T("uidata"));
4984 appendOSDirSlash(&iconDir);
4985 iconDir.append(_T("MUI_flat"));
4986 appendOSDirSlash(&iconDir);
4987 int bmpSize = GetCharHeight() * 3;
4988
4989 wxBitmap bmp = LoadSVG( iconDir + _T("MUI_Sconfig_1.svg"), bmpSize, bmpSize );
4990 m_sconfigSelect_single = new CanvasConfigSelect( pDisplayPanel, this, ID_SCREENCONFIG1, bmp);
4991 itemStaticBoxSizerScreenConfig->Add(m_sconfigSelect_single, 0, wxALIGN_LEFT);
4992
4993 itemStaticBoxSizerScreenConfig->AddSpacer(GetCharHeight());
4994
4995 bmp = LoadSVG( iconDir + _T("MUI_Sconfig_2.svg"), bmpSize, bmpSize );
4996 m_sconfigSelect_twovertical = new CanvasConfigSelect( pDisplayPanel, this, ID_SCREENCONFIG2, bmp);
4997 itemStaticBoxSizerScreenConfig->Add(m_sconfigSelect_twovertical, 0, wxALIGN_LEFT);
4998
4999 itemStaticBoxSizerScreenConfig->AddSpacer(GetCharHeight());
5000 }
5001 #endif
5002
5003 } else { // compact follows
5004 wxFlexGridSizer* generalSizer = new wxFlexGridSizer(2);
5005 generalSizer->SetHGap(border_size);
5006 // generalSizer->AddGrowableCol( 0, 1 );
5007 // generalSizer->AddGrowableCol( 1, 1 );
5008 // pDisplayPanel->SetSizer( generalSizer );
5009
5010 // wxFlexGridSizer grows wrongly in wx2.8, so we need to centre it in
5011 // another sizer instead of letting it grow.
5012 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
5013 pDisplayPanel->SetSizer(wrapperSizer);
5014 wrapperSizer->Add(generalSizer, 1, wxALL | wxALIGN_CENTER, border_size);
5015
5016 // spacer
5017 generalSizer->Add(0, border_size * 4);
5018 generalSizer->Add(0, border_size * 4);
5019
5020 if(!g_useMUI){
5021 // Nav Mode
5022 generalSizer->Add(
5023 new wxStaticText(pDisplayPanel, wxID_ANY, _("Navigation Mode")),
5024 groupLabelFlags);
5025 wxBoxSizer* boxNavMode = new wxBoxSizer(wxVERTICAL);
5026 generalSizer->Add(boxNavMode, groupInputFlags);
5027
5028 wxBoxSizer* rowOrientation = new wxBoxSizer(wxHORIZONTAL);
5029 boxNavMode->Add(rowOrientation);
5030
5031 pCBNorthUp = new wxRadioButton(pDisplayPanel, wxID_ANY, _("North Up"));
5032 rowOrientation->Add(pCBNorthUp, inputFlags);
5033 pCBCourseUp =
5034 new wxRadioButton(pDisplayPanel, ID_COURSEUPCHECKBOX, _("Course Up"));
5035 rowOrientation->Add(pCBCourseUp,
5036 wxSizerFlags(0)
5037 .Align(wxALIGN_CENTRE_VERTICAL)
5038 .Border(wxLEFT, group_item_spacing * 2));
5039
5040 pCBLookAhead =
5041 new wxCheckBox(pDisplayPanel, ID_CHECK_LOOKAHEAD, _("Look Ahead Mode"));
5042 boxNavMode->Add(pCBLookAhead, verticleInputFlags);
5043
5044 // spacer
5045 generalSizer->Add(0, border_size * 4);
5046 generalSizer->Add(0, border_size * 4);
5047
5048 // Control Options
5049 generalSizer->Add(
5050 new wxStaticText(pDisplayPanel, wxID_ANY, _("Chart Display")),
5051 groupLabelFlags);
5052 wxBoxSizer* boxCharts = new wxBoxSizer(wxVERTICAL);
5053 generalSizer->Add(boxCharts, groupInputFlags);
5054
5055 pCDOQuilting = new wxCheckBox(pDisplayPanel, ID_QUILTCHECKBOX1,
5056 _("Enable Chart Quilting"));
5057 boxCharts->Add(pCDOQuilting, verticleInputFlags);
5058
5059 pPreserveScale = new wxCheckBox(pDisplayPanel, ID_PRESERVECHECKBOX,
5060 _("Preserve scale when switching charts"));
5061 boxCharts->Add(pPreserveScale, verticleInputFlags);
5062
5063 // spacer
5064 generalSizer->Add(0, border_size * 4);
5065 generalSizer->Add(0, border_size * 4);
5066 }
5067
5068 // Control Options
5069 generalSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Controls")),
5070 groupLabelFlags);
5071 wxBoxSizer* boxCtrls = new wxBoxSizer(wxVERTICAL);
5072 generalSizer->Add(boxCtrls, groupInputFlags);
5073
5074 pSmoothPanZoom = new wxCheckBox(pDisplayPanel, ID_SMOOTHPANZOOMBOX,
5075 _("Smooth Panning / Zooming"));
5076 boxCtrls->Add(pSmoothPanZoom, verticleInputFlags);
5077 pEnableZoomToCursor =
5078 new wxCheckBox(pDisplayPanel, ID_ZTCCHECKBOX, _("Zoom to Cursor"));
5079 pEnableZoomToCursor->SetValue(FALSE);
5080 boxCtrls->Add(pEnableZoomToCursor, verticleInputFlags);
5081
5082 #ifdef __OCPN__ANDROID__
5083 pSmoothPanZoom->Hide();
5084 pEnableZoomToCursor->Hide();
5085 #endif
5086
5087 // spacer
5088 generalSizer->Add(0, border_size * 4);
5089 generalSizer->Add(0, border_size * 4);
5090
5091 if(!g_useMUI){
5092 // Display Options
5093 generalSizer->Add(
5094 new wxStaticText(pDisplayPanel, wxID_ANY, _("Display Features")),
5095 groupLabelFlags);
5096 wxBoxSizer* boxDisp = new wxBoxSizer(wxVERTICAL);
5097 generalSizer->Add(boxDisp, groupInputFlags);
5098
5099 pSDisplayGrid =
5100 new wxCheckBox(pDisplayPanel, ID_CHECK_DISPLAYGRID, _("Show Grid"));
5101 boxDisp->Add(pSDisplayGrid, verticleInputFlags);
5102
5103 pCDOOutlines = new wxCheckBox(pDisplayPanel, ID_OUTLINECHECKBOX1,
5104 _("Show Chart Outlines"));
5105 boxDisp->Add(pCDOOutlines, verticleInputFlags);
5106
5107 pSDepthUnits = new wxCheckBox(pDisplayPanel, ID_SHOWDEPTHUNITSBOX1,
5108 _("Show Depth Units"));
5109 boxDisp->Add(pSDepthUnits, verticleInputFlags);
5110
5111 }
5112
5113 // CUSTOMIZATION - LIVE ETA OPTION
5114 // -------------------------------
5115 // Add a checkbox to activate live ETA option in status bar, and
5116 // Add a text field to set default boat speed (for calculation when
5117 // no GPS or when the boat is at the harbor).
5118
5119 // Spacer
5120 generalSizer->Add(0, border_size * 4);
5121 generalSizer->Add(0, border_size * 4);
5122
5123 // New menu status bar
5124 generalSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Status Bar")),
5125 groupLabelFlags);
5126 wxBoxSizer* boxDispStatusBar = new wxBoxSizer(wxVERTICAL);
5127 generalSizer->Add(boxDispStatusBar, groupInputFlags);
5128
5129 // Add option for live ETA
5130 pSLiveETA = new wxCheckBox(pDisplayPanel, ID_CHECK_LIVEETA, _("Live ETA at Cursor"));
5131 boxDispStatusBar->Add(pSLiveETA, verticleInputFlags);
5132
5133 // Add text input for default boat speed
5134 // (for calculation, in case GPS speed is null)
5135 wxBoxSizer *defaultBoatSpeedSizer = new wxBoxSizer(wxHORIZONTAL);
5136 boxDispStatusBar->Add(defaultBoatSpeedSizer, wxALL, group_item_spacing);
5137 defaultBoatSpeedSizer->Add(new wxStaticText(pDisplayPanel, wxID_ANY, _("Default Boat Speed ")),
5138 groupLabelFlagsHoriz);
5139 pSDefaultBoatSpeed = new wxTextCtrl(pDisplayPanel, ID_DEFAULT_BOAT_SPEED, _T(""), wxDefaultPosition,
5140 wxSize(50, -1), wxTE_RIGHT);
5141 defaultBoatSpeedSizer->Add(pSDefaultBoatSpeed, 0, wxALIGN_CENTER_VERTICAL, group_item_spacing);
5142
5143 // --------------------------------------
5144 // END OF CUSTOMIZATION - LIVE ETA OPTION
5145
5146 #ifndef __OCPN__ANDROID__
5147 if(g_Platform->GetDisplayAreaCM2() > 100){
5148 // MultiChart selection panel
5149 wxStaticBox* itemStaticBoxScreenConfig = new wxStaticBox(pDisplayPanel, wxID_ANY, _("Canvas Layout"));
5150 wxStaticBoxSizer* itemStaticBoxSizerScreenConfig = new wxStaticBoxSizer(itemStaticBoxScreenConfig, wxHORIZONTAL);
5151 wrapperSizer->Add(itemStaticBoxSizerScreenConfig, 1, wxALL | wxEXPAND, 5);
5152
5153 // The standard screen configs...
5154 wxString iconDir = g_Platform->GetSharedDataDir();
5155 appendOSDirSlash(&iconDir);
5156 iconDir.append(_T("uidata"));
5157 appendOSDirSlash(&iconDir);
5158 iconDir.append(_T("MUI_flat"));
5159 appendOSDirSlash(&iconDir);
5160 int bmpSize = GetCharHeight() * 3;
5161
5162 wxBitmap bmp = LoadSVG( iconDir + _T("MUI_Sconfig_1.svg"), bmpSize, bmpSize );
5163 m_sconfigSelect_single = new CanvasConfigSelect( pDisplayPanel, this, ID_SCREENCONFIG1, bmp);
5164 itemStaticBoxSizerScreenConfig->Add(m_sconfigSelect_single, 0, wxALIGN_LEFT);
5165
5166 itemStaticBoxSizerScreenConfig->AddSpacer(GetCharHeight());
5167
5168 bmp = LoadSVG( iconDir + _T("MUI_Sconfig_2.svg"), bmpSize, bmpSize );
5169 m_sconfigSelect_twovertical = new CanvasConfigSelect( pDisplayPanel, this, ID_SCREENCONFIG2, bmp);
5170 itemStaticBoxSizerScreenConfig->Add(m_sconfigSelect_twovertical, 0, wxALIGN_LEFT);
5171
5172 itemStaticBoxSizerScreenConfig->AddSpacer(GetCharHeight());
5173 }
5174 #endif
5175
5176 }
5177
5178 }
5179
CreatePanel_Units(size_t parent,int border_size,int group_item_spacing)5180 void options::CreatePanel_Units(size_t parent, int border_size,
5181 int group_item_spacing) {
5182 wxScrolledWindow* panelUnits = AddPage(parent, _("Units"));
5183
5184 if (m_bcompact) {
5185 wxFlexGridSizer* unitsSizer = new wxFlexGridSizer(2);
5186 unitsSizer->SetHGap(border_size);
5187
5188 // wxFlexGridSizer grows wrongly in wx2.8, so we need to centre it in
5189 // another sizer instead of letting it grow.
5190 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
5191 panelUnits->SetSizer(wrapperSizer);
5192
5193 wrapperSizer->Add(1, border_size * 24);
5194 wrapperSizer->Add(unitsSizer, 1, wxALL | wxALIGN_CENTER, border_size);
5195
5196 // spacer
5197 unitsSizer->Add(0, border_size * 4);
5198 unitsSizer->Add(0, border_size * 4);
5199
5200 // distance units
5201 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Distance")),
5202 labelFlags);
5203 wxString pDistanceFormats[] = {_("Nautical miles"), _("Statute miles"),
5204 _("Kilometers"), _("Meters")};
5205 int m_DistanceFormatsNChoices = sizeof(pDistanceFormats) / sizeof(wxString);
5206 pDistanceFormat = new wxChoice(panelUnits, ID_DISTANCEUNITSCHOICE,
5207 wxDefaultPosition, wxSize(m_fontHeight * 4, -1),
5208 m_DistanceFormatsNChoices, pDistanceFormats);
5209 #ifdef __OCPN__ANDROID__
5210 setChoiceStyleSheet( pDistanceFormat, m_fontHeight *8/10);
5211 #endif
5212 unitsSizer->Add(pDistanceFormat, inputFlags);
5213
5214 // speed units
5215 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Speed")),
5216 labelFlags);
5217 wxString pSpeedFormats[] = {_("Knots"), _("Mph"), _("km/h"), _("m/s")};
5218 int m_SpeedFormatsNChoices = sizeof(pSpeedFormats) / sizeof(wxString);
5219 pSpeedFormat =
5220 new wxChoice(panelUnits, ID_SPEEDUNITSCHOICE, wxDefaultPosition,
5221 wxSize(m_fontHeight * 4, -1), m_SpeedFormatsNChoices, pSpeedFormats);
5222 #ifdef __OCPN__ANDROID__
5223 setChoiceStyleSheet( pSpeedFormat, m_fontHeight *8/10);
5224 #endif
5225 unitsSizer->Add(pSpeedFormat, inputFlags);
5226
5227 // depth units
5228 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Depth")),
5229 labelFlags);
5230 wxString pDepthUnitStrings[] = {
5231 _("Feet"), _("Meters"), _("Fathoms"),
5232 };
5233 pDepthUnitSelect =
5234 new wxChoice(panelUnits, ID_DEPTHUNITSCHOICE, wxDefaultPosition,
5235 wxSize(m_fontHeight * 4, -1), 3, pDepthUnitStrings);
5236 #ifdef __OCPN__ANDROID__
5237 setChoiceStyleSheet( pDepthUnitSelect, m_fontHeight *8/10);
5238 #endif
5239 unitsSizer->Add(pDepthUnitSelect, inputFlags);
5240
5241 // spacer
5242 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5243 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5244
5245 // lat/long units
5246 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Lat/Long")),
5247 labelFlags);
5248 wxString pSDMMFormats[] = {_("Degrees, Decimal Minutes"),
5249 _("Decimal Degrees"),
5250 _("Degrees, Minutes, Seconds")};
5251 int m_SDMMFormatsNChoices = sizeof(pSDMMFormats) / sizeof(wxString);
5252 pSDMMFormat =
5253 new wxChoice(panelUnits, ID_SDMMFORMATCHOICE, wxDefaultPosition,
5254 wxSize(m_fontHeight * 4, -1), m_SDMMFormatsNChoices, pSDMMFormats);
5255 #ifdef __OCPN__ANDROID__
5256 setChoiceStyleSheet( pSDMMFormat, m_fontHeight *8/10);
5257 #endif
5258 unitsSizer->Add(pSDMMFormat, inputFlags);
5259
5260 // spacer
5261 unitsSizer->Add(0, border_size * 4);
5262 unitsSizer->Add(0, border_size * 4);
5263
5264 // bearings (magnetic/true, variation)
5265 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Bearings")),
5266 groupLabelFlags);
5267
5268 // "Mag Heading" checkbox
5269 pCBTrueShow =
5270 new wxCheckBox(panelUnits, ID_TRUESHOWCHECKBOX, _("Show true"));
5271 unitsSizer->Add(pCBTrueShow, 0, wxALL, group_item_spacing);
5272 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5273
5274 pCBMagShow = new wxCheckBox(panelUnits, ID_MAGSHOWCHECKBOX, _("Show magnetic"));
5275 unitsSizer->Add(pCBMagShow, 0, wxALL, group_item_spacing);
5276 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5277
5278 // Mag Heading user variation
5279
5280 wxStaticBox* itemStaticBoxVar = new wxStaticBox(panelUnits, wxID_ANY, _T(""));
5281
5282 wxStaticBoxSizer* itemStaticBoxSizerVar = new wxStaticBoxSizer(itemStaticBoxVar, wxVERTICAL);
5283 wrapperSizer->Add(itemStaticBoxSizerVar, 0, wxALL | wxEXPAND, 5);
5284
5285 itemStaticBoxSizerVar->Add(0, border_size * 4);
5286
5287 itemStaticTextUserVar = new wxStaticText(panelUnits, wxID_ANY, _("Assumed magnetic variation") );
5288 itemStaticBoxSizerVar->Add(itemStaticTextUserVar, 1, wxEXPAND | wxALL, group_item_spacing);
5289
5290 wxBoxSizer* magVarSizer = new wxBoxSizer(wxHORIZONTAL);
5291 itemStaticBoxSizerVar->Add(magVarSizer, 1, wxEXPAND | wxALL, group_item_spacing);
5292
5293 pMagVar = new wxTextCtrl(panelUnits, ID_OPTEXTCTRL, _T(""),
5294 wxDefaultPosition, wxSize(150, -1), wxTE_RIGHT);
5295 magVarSizer->AddSpacer(100);
5296
5297 magVarSizer->Add(pMagVar, 0, wxALIGN_CENTRE_VERTICAL, group_item_spacing);
5298
5299 itemStaticTextUserVar2 = new wxStaticText(panelUnits, wxID_ANY, _("deg (-W, +E)"));
5300
5301 magVarSizer->Add(itemStaticTextUserVar2, 0, wxALL | wxALIGN_CENTRE_VERTICAL, group_item_spacing);
5302
5303 itemStaticBoxSizerVar->Add(0, border_size * 40);
5304
5305 } else {
5306 wxFlexGridSizer* unitsSizer = new wxFlexGridSizer(2);
5307 unitsSizer->SetHGap(border_size);
5308
5309 // wxFlexGridSizer grows wrongly in wx2.8, so we need to centre it in
5310 // another sizer instead of letting it grow.
5311 wxBoxSizer* wrapperSizer = new wxBoxSizer(wxVERTICAL);
5312 panelUnits->SetSizer(wrapperSizer);
5313 wrapperSizer->Add(unitsSizer, 1, wxALL | wxALIGN_CENTER, border_size);
5314
5315 // spacer
5316 unitsSizer->Add(0, border_size * 4);
5317 unitsSizer->Add(0, border_size * 4);
5318
5319 // distance units
5320 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Distance")),
5321 labelFlags);
5322 wxString pDistanceFormats[] = {_("Nautical miles"), _("Statute miles"),
5323 _("Kilometers"), _("Meters")};
5324 int m_DistanceFormatsNChoices = sizeof(pDistanceFormats) / sizeof(wxString);
5325 pDistanceFormat = new wxChoice(panelUnits, ID_DISTANCEUNITSCHOICE,
5326 wxDefaultPosition, wxDefaultSize,
5327 m_DistanceFormatsNChoices, pDistanceFormats);
5328 unitsSizer->Add(pDistanceFormat, inputFlags);
5329
5330 // speed units
5331 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Speed")),
5332 labelFlags);
5333 wxString pSpeedFormats[] = {_("Knots"), _("Mph"), _("km/h"), _("m/s")};
5334 int m_SpeedFormatsNChoices = sizeof(pSpeedFormats) / sizeof(wxString);
5335 pSpeedFormat =
5336 new wxChoice(panelUnits, ID_SPEEDUNITSCHOICE, wxDefaultPosition,
5337 wxDefaultSize, m_SpeedFormatsNChoices, pSpeedFormats);
5338 unitsSizer->Add(pSpeedFormat, inputFlags);
5339
5340 // depth units
5341 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Depth")),
5342 labelFlags);
5343 wxString pDepthUnitStrings[] = {
5344 _("Feet"), _("Meters"), _("Fathoms"),
5345 };
5346 pDepthUnitSelect =
5347 new wxChoice(panelUnits, ID_DEPTHUNITSCHOICE, wxDefaultPosition,
5348 wxDefaultSize, 3, pDepthUnitStrings);
5349 unitsSizer->Add(pDepthUnitSelect, inputFlags);
5350
5351 // spacer
5352 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5353 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _T("")));
5354
5355 // lat/long units
5356 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Lat/Long")),
5357 labelFlags);
5358 wxString pSDMMFormats[] = {_("Degrees, Decimal Minutes"),
5359 _("Decimal Degrees"),
5360 _("Degrees, Minutes, Seconds")};
5361 int m_SDMMFormatsNChoices = sizeof(pSDMMFormats) / sizeof(wxString);
5362 pSDMMFormat =
5363 new wxChoice(panelUnits, ID_SDMMFORMATCHOICE, wxDefaultPosition,
5364 wxDefaultSize, m_SDMMFormatsNChoices, pSDMMFormats);
5365 unitsSizer->Add(pSDMMFormat, inputFlags);
5366
5367 // spacer
5368 unitsSizer->Add(0, border_size * 4);
5369 unitsSizer->Add(0, border_size * 4);
5370
5371 // bearings (magnetic/true, variation)
5372 unitsSizer->Add(new wxStaticText(panelUnits, wxID_ANY, _("Bearings")),
5373 groupLabelFlags);
5374
5375 wxBoxSizer* bearingsSizer = new wxBoxSizer(wxVERTICAL);
5376 unitsSizer->Add(bearingsSizer, 0, 0, 0);
5377
5378 // "Mag Heading" checkbox
5379 pCBTrueShow = new wxCheckBox(panelUnits, ID_TRUESHOWCHECKBOX,
5380 _("Show true bearings and headings"));
5381 bearingsSizer->Add(pCBTrueShow, 0, wxALL, group_item_spacing);
5382 pCBMagShow = new wxCheckBox(panelUnits, ID_MAGSHOWCHECKBOX,
5383 _("Show magnetic bearings and headings."));
5384 bearingsSizer->Add(pCBMagShow, 0, wxALL, group_item_spacing);
5385
5386 bearingsSizer->AddSpacer(10);
5387
5388
5389 // Mag Heading user variation
5390 wxBoxSizer* magVarSizer = new wxBoxSizer(wxHORIZONTAL);
5391 bearingsSizer->Add(magVarSizer, 0, wxALL, group_item_spacing);
5392
5393 itemStaticTextUserVar = new wxStaticText(panelUnits, wxID_ANY, wxEmptyString);
5394 itemStaticTextUserVar->SetLabel(_("WMM Plugin calculated magnetic variation"));
5395
5396 magVarSizer->Add(itemStaticTextUserVar, 0, wxALL | wxALIGN_CENTRE_VERTICAL,
5397 group_item_spacing);
5398
5399 pMagVar = new wxTextCtrl(panelUnits, ID_OPTEXTCTRL, _T(""),
5400 wxDefaultPosition, wxSize(50, -1), wxTE_RIGHT);
5401 magVarSizer->Add(pMagVar, 0, wxALIGN_CENTRE_VERTICAL, group_item_spacing);
5402
5403 itemStaticTextUserVar2 = new wxStaticText(panelUnits, wxID_ANY, _("deg (-W, +E)"));
5404 magVarSizer->Add(itemStaticTextUserVar2, 0, wxALL | wxALIGN_CENTRE_VERTICAL, group_item_spacing);
5405
5406 bearingsSizer->AddSpacer(10);
5407
5408 wxStaticText *varText = new wxStaticText(panelUnits, wxID_ANY, _(" To set the magnetic variation manually,\n you must disable the WMM plugin."));
5409 smallFont = *dialogFont;
5410 smallFont.SetPointSize((smallFont.GetPointSize() / 1.2) + 0.5); // + 0.5 to round instead of truncate
5411 varText->SetFont(smallFont);
5412
5413 bearingsSizer->Add(varText);
5414
5415 }
5416 }
5417
CreatePanel_MMSI(size_t parent,int border_size,int group_item_spacing)5418 void options::CreatePanel_MMSI(size_t parent, int border_size,
5419 int group_item_spacing) {
5420 wxScrolledWindow* panelMMSI = AddPage(parent, _("MMSI Properties"));
5421
5422 wxBoxSizer* MMSISizer = new wxBoxSizer(wxVERTICAL);
5423 panelMMSI->SetSizer(MMSISizer);
5424
5425 // MMSI list control (panel)
5426 wxStaticBox* itemStaticBoxMMSI =
5427 new wxStaticBox(panelMMSI, wxID_ANY, _("MMSI Properties"));
5428 wxStaticBoxSizer* itemStaticBoxSizerMMSI =
5429 new wxStaticBoxSizer(itemStaticBoxMMSI, wxVERTICAL);
5430 MMSISizer->Add(itemStaticBoxSizerMMSI, 0, wxALL | wxEXPAND, border_size);
5431
5432 MMSI_Props_Panel* pPropsPanel = new MMSI_Props_Panel(panelMMSI);
5433
5434 pPropsPanel->UpdateMMSIList();
5435
5436 itemStaticBoxSizerMMSI->Add(pPropsPanel, 0, wxALL | wxEXPAND, border_size);
5437
5438 panelMMSI->Layout();
5439 }
5440
CreatePanel_AIS(size_t parent,int border_size,int group_item_spacing)5441 void options::CreatePanel_AIS(size_t parent, int border_size,
5442 int group_item_spacing) {
5443 wxScrolledWindow* panelAIS = AddPage(parent, _("AIS Targets"));
5444
5445 wxBoxSizer* aisSizer = new wxBoxSizer(wxVERTICAL);
5446 panelAIS->SetSizer(aisSizer);
5447
5448 // CPA Box
5449 wxStaticBox* itemStaticBoxCPA =
5450 new wxStaticBox(panelAIS, wxID_ANY, _("CPA Calculation"));
5451 wxStaticBoxSizer* itemStaticBoxSizerCPA =
5452 new wxStaticBoxSizer(itemStaticBoxCPA, wxVERTICAL);
5453 aisSizer->Add(itemStaticBoxSizerCPA, 0, wxALL | wxEXPAND, border_size);
5454
5455 wxFlexGridSizer* pCPAGrid = new wxFlexGridSizer(2);
5456 pCPAGrid->AddGrowableCol(1);
5457 itemStaticBoxSizerCPA->Add(pCPAGrid, 0, wxALL | wxEXPAND, border_size);
5458
5459 m_pCheck_CPA_Max = new wxCheckBox(
5460 panelAIS, -1, _("No (T)CPA Alerts if target range is greater than (NMi)"));
5461 pCPAGrid->Add(m_pCheck_CPA_Max, 0, wxALL, group_item_spacing);
5462
5463 m_pText_CPA_Max = new wxTextCtrl(panelAIS, -1);
5464 pCPAGrid->Add(m_pText_CPA_Max, 0, wxALL | wxALIGN_RIGHT, group_item_spacing);
5465
5466 m_pCheck_CPA_Warn =
5467 new wxCheckBox(panelAIS, -1, _("Warn if CPA less than (NMi)"));
5468 pCPAGrid->Add(m_pCheck_CPA_Warn, 0, wxALL, group_item_spacing);
5469
5470 m_pText_CPA_Warn =
5471 new wxTextCtrl(panelAIS, -1, _T(""), wxDefaultPosition, wxSize(-1, -1));
5472 pCPAGrid->Add(m_pText_CPA_Warn, 0, wxALL | wxALIGN_RIGHT, group_item_spacing);
5473
5474 m_pCheck_CPA_Warn->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
5475 wxCommandEventHandler(options::OnCPAWarnClick),
5476 NULL, this);
5477
5478 m_pCheck_CPA_WarnT =
5479 new wxCheckBox(panelAIS, -1, _("...and TCPA is less than (min)"));
5480 pCPAGrid->Add(m_pCheck_CPA_WarnT, 0, wxALL, group_item_spacing);
5481
5482 m_pText_CPA_WarnT = new wxTextCtrl(panelAIS, -1);
5483 pCPAGrid->Add(m_pText_CPA_WarnT, 0, wxALL | wxALIGN_RIGHT,
5484 group_item_spacing);
5485
5486 // Lost Targets
5487 wxStaticBox* lostBox = new wxStaticBox(panelAIS, wxID_ANY, _("Lost Targets"));
5488 wxStaticBoxSizer* lostSizer = new wxStaticBoxSizer(lostBox, wxVERTICAL);
5489 aisSizer->Add(lostSizer, 0, wxALL | wxEXPAND, 3);
5490
5491 wxFlexGridSizer* pLostGrid = new wxFlexGridSizer(2);
5492 pLostGrid->AddGrowableCol(1);
5493 lostSizer->Add(pLostGrid, 0, wxALL | wxEXPAND, border_size);
5494
5495 m_pCheck_Mark_Lost =
5496 new wxCheckBox(panelAIS, -1, _("Mark targets as lost after (min)"));
5497 pLostGrid->Add(m_pCheck_Mark_Lost, 1, wxALL, group_item_spacing);
5498
5499 m_pText_Mark_Lost = new wxTextCtrl(panelAIS, -1);
5500 pLostGrid->Add(m_pText_Mark_Lost, 1, wxALL | wxALIGN_RIGHT,
5501 group_item_spacing);
5502
5503 m_pCheck_Remove_Lost = new wxCheckBox(panelAIS, -1, _("Remove lost targets after (min)"));
5504 pLostGrid->Add(m_pCheck_Remove_Lost, 1, wxALL, group_item_spacing);
5505
5506 m_pText_Remove_Lost = new wxTextCtrl(panelAIS, -1);
5507 pLostGrid->Add(m_pText_Remove_Lost, 1, wxALL | wxALIGN_RIGHT,
5508 group_item_spacing);
5509
5510 if(g_bInlandEcdis)
5511 lostSizer->Hide(pLostGrid, true);
5512
5513 // Display
5514 wxStaticBox* displBox = new wxStaticBox(panelAIS, wxID_ANY, _("Display"));
5515 wxStaticBoxSizer* displSizer = new wxStaticBoxSizer(displBox, wxHORIZONTAL);
5516 aisSizer->Add(displSizer, 0, wxALL | wxEXPAND, border_size);
5517
5518 wxFlexGridSizer* pDisplayGrid = new wxFlexGridSizer(2);
5519 pDisplayGrid->AddGrowableCol(1);
5520 displSizer->Add(pDisplayGrid, 1, wxALL | wxEXPAND, border_size);
5521
5522 m_pCheck_Show_COG = new wxCheckBox(
5523 panelAIS, -1, _("Show target COG predictor arrow, length (min)"));
5524 pDisplayGrid->Add(m_pCheck_Show_COG, 1, wxALL | wxEXPAND, group_item_spacing);
5525
5526 m_pText_COG_Predictor = new wxTextCtrl(panelAIS, -1);
5527 pDisplayGrid->Add(m_pText_COG_Predictor, 1, wxALL | wxALIGN_RIGHT,
5528 group_item_spacing);
5529
5530 m_pCheck_Show_Tracks =
5531 new wxCheckBox(panelAIS, -1, _("Show target tracks, length (min)"));
5532 pDisplayGrid->Add(m_pCheck_Show_Tracks, 1, wxALL, group_item_spacing);
5533
5534 m_pText_Track_Length = new wxTextCtrl(panelAIS, -1);
5535 pDisplayGrid->Add(m_pText_Track_Length, 1, wxALL | wxALIGN_RIGHT,
5536 group_item_spacing);
5537
5538 m_pCheck_Hide_Moored = new wxCheckBox(
5539 panelAIS, -1, _("Suppress anchored/moored targets, speed max (kn)"));
5540 pDisplayGrid->Add(m_pCheck_Hide_Moored, 1, wxALL, group_item_spacing);
5541
5542 m_pText_Moored_Speed = new wxTextCtrl(panelAIS, -1);
5543 pDisplayGrid->Add(m_pText_Moored_Speed, 1, wxALL | wxALIGN_RIGHT,
5544 group_item_spacing);
5545
5546 m_pCheck_Draw_Realtime_Prediction = new wxCheckBox(
5547 panelAIS, -1, _("Draw AIS realtime prediction, target speed min (kn)"));
5548 pDisplayGrid->Add(m_pCheck_Draw_Realtime_Prediction, 1, wxALL, group_item_spacing);
5549
5550 m_pText_RealtPred_Speed = new wxTextCtrl(panelAIS, -1);
5551 pDisplayGrid->Add(m_pText_RealtPred_Speed, 1, wxALL | wxALIGN_RIGHT,
5552 group_item_spacing);
5553
5554 m_pCheck_Scale_Priority = new wxCheckBox(
5555 panelAIS, -1, _("Allow attenuation of less critical targets if more than ... targets"));
5556 pDisplayGrid->Add(m_pCheck_Scale_Priority, 1, wxALL, group_item_spacing);
5557
5558 m_pText_Scale_Priority = new wxTextCtrl(panelAIS, -1);
5559 pDisplayGrid->Add(m_pText_Scale_Priority, 1, wxALL | wxALIGN_RIGHT,
5560 group_item_spacing);
5561
5562 m_pCheck_Show_Area_Notices = new wxCheckBox(
5563 panelAIS, -1, _("Show area notices (from AIS binary messages)"));
5564 pDisplayGrid->Add(m_pCheck_Show_Area_Notices, 1, wxALL, group_item_spacing);
5565
5566 wxStaticText* pStatic_Dummy5 = new wxStaticText(panelAIS, -1, _T(""));
5567 pDisplayGrid->Add(pStatic_Dummy5, 1, wxALL, group_item_spacing);
5568
5569 m_pCheck_Draw_Target_Size =
5570 new wxCheckBox(panelAIS, -1, _("Show AIS targets real size"));
5571 pDisplayGrid->Add(m_pCheck_Draw_Target_Size, 1, wxALL, group_item_spacing);
5572
5573 wxStaticText* pStatic_Dummy6 = new wxStaticText(panelAIS, -1, _T(""));
5574 pDisplayGrid->Add(pStatic_Dummy6, 1, wxALL, group_item_spacing);
5575
5576 m_pCheck_Show_Target_Name = new wxCheckBox(
5577 panelAIS, -1, _("Show names with AIS targets at scale greater than 1:"));
5578 pDisplayGrid->Add(m_pCheck_Show_Target_Name, 1, wxALL, group_item_spacing);
5579
5580 m_pText_Show_Target_Name_Scale = new wxTextCtrl(panelAIS, -1);
5581 pDisplayGrid->Add(m_pText_Show_Target_Name_Scale, 1, wxALL | wxALIGN_RIGHT,
5582 group_item_spacing);
5583
5584 m_pCheck_Wpl_Aprs = new wxCheckBox(
5585 panelAIS, -1, _("Treat WPL sentences as APRS position reports"));
5586 pDisplayGrid->Add(m_pCheck_Wpl_Aprs, 1, wxALL, group_item_spacing);
5587
5588 wxStaticText* pStatic_Dummy7 = new wxStaticText(panelAIS, -1, _T(""));
5589 pDisplayGrid->Add(pStatic_Dummy7, 1, wxALL, group_item_spacing);
5590
5591 wxStaticText* pStatic_Dummy5a = new wxStaticText(panelAIS, -1, _T(""));
5592 pDisplayGrid->Add(pStatic_Dummy5a, 1, wxALL, group_item_spacing);
5593
5594 // Rollover
5595 wxStaticBox* rolloverBox = new wxStaticBox(panelAIS, wxID_ANY, _("Rollover"));
5596 wxStaticBoxSizer* rolloverSizer =
5597 new wxStaticBoxSizer(rolloverBox, wxVERTICAL);
5598 aisSizer->Add(rolloverSizer, 0, wxALL | wxEXPAND, border_size);
5599
5600 pRollover = new wxCheckBox(panelAIS, ID_ROLLOVERBOX, _("Enable route/AIS info block"));
5601 rolloverSizer->Add(pRollover, 1, wxALL, 2 * group_item_spacing);
5602
5603 pRollover->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(options::OnAISRolloverClick), NULL, this);
5604
5605 pStatic_CallSign = new wxStaticText(panelAIS, -1, _("\"Ship Name\" MMSI (Call Sign)"));
5606 rolloverSizer->Add(pStatic_CallSign, 1, wxALL, 2 * group_item_spacing);
5607
5608 m_pCheck_Rollover_Class =
5609 new wxCheckBox(panelAIS, -1, _("[Class] Type (Status)"));
5610 rolloverSizer->Add(m_pCheck_Rollover_Class, 1, wxALL, 2 * group_item_spacing);
5611
5612 m_pCheck_Rollover_COG = new wxCheckBox(panelAIS, -1, _("SOG COG"));
5613 rolloverSizer->Add(m_pCheck_Rollover_COG, 1, wxALL, 2 * group_item_spacing);
5614
5615 m_pCheck_Rollover_CPA = new wxCheckBox(panelAIS, -1, _("CPA TCPA"));
5616 rolloverSizer->Add(m_pCheck_Rollover_CPA, 1, wxALL, 2 * group_item_spacing);
5617
5618 // Alert Box
5619 wxStaticBox* alertBox =
5620 new wxStaticBox(panelAIS, wxID_ANY, _("CPA/TCPA Alerts"));
5621 wxStaticBoxSizer* alertSizer = new wxStaticBoxSizer(alertBox, wxVERTICAL);
5622 aisSizer->Add(alertSizer, 0, wxALL | wxEXPAND, group_item_spacing);
5623
5624 wxFlexGridSizer* pAlertGrid = new wxFlexGridSizer(2);
5625 pAlertGrid->AddGrowableCol(1);
5626 alertSizer->Add(pAlertGrid, 0, wxALL | wxEXPAND, group_item_spacing);
5627
5628 m_pCheck_AlertDialog = new wxCheckBox(panelAIS, ID_AISALERTDIALOG,
5629 _("Show CPA/TCPA Alert Dialog"));
5630 pAlertGrid->Add(m_pCheck_AlertDialog, 0, wxALL, group_item_spacing);
5631
5632 wxButton* m_SelSound =
5633 new wxButton(panelAIS, ID_AISALERTSELECTSOUND, _("Select Alert Sound"),
5634 wxDefaultPosition, m_small_button_size, 0);
5635 pAlertGrid->Add(m_SelSound, 0, wxALL | wxALIGN_RIGHT, group_item_spacing);
5636
5637 m_pCheck_AlertAudio = new wxCheckBox(
5638 panelAIS, ID_AISALERTAUDIO,
5639 _("Play Sound on CPA/TCPA Alerts and DSC/SART emergencies."));
5640 pAlertGrid->Add(m_pCheck_AlertAudio, 0, wxALL, group_item_spacing);
5641
5642 wxButton* m_pPlay_Sound =
5643 new wxButton(panelAIS, ID_AISALERTTESTSOUND, _("Test Alert Sound"),
5644 wxDefaultPosition, m_small_button_size, 0);
5645 pAlertGrid->Add(m_pPlay_Sound, 0, wxALL | wxALIGN_RIGHT, group_item_spacing);
5646
5647 m_pCheck_Alert_Moored = new wxCheckBox(
5648 panelAIS, -1, _("Suppress Alerts for anchored/moored targets"));
5649 pAlertGrid->Add(m_pCheck_Alert_Moored, 1, wxALL, group_item_spacing);
5650
5651 wxStaticText* pStatic_Dummy2 = new wxStaticText(panelAIS, -1, _T(""));
5652 pAlertGrid->Add(pStatic_Dummy2, 1, wxALL, group_item_spacing);
5653
5654 m_pCheck_Ack_Timout = new wxCheckBox(
5655 panelAIS, -1, _("Enable Target Alert Acknowledge timeout (min)"));
5656 pAlertGrid->Add(m_pCheck_Ack_Timout, 1, wxALL, group_item_spacing);
5657
5658 m_pText_ACK_Timeout = new wxTextCtrl(panelAIS, -1);
5659 pAlertGrid->Add(m_pText_ACK_Timeout, 1, wxALL | wxALIGN_RIGHT,
5660 group_item_spacing);
5661
5662 panelAIS->Layout();
5663 }
5664
CreatePanel_UI(size_t parent,int border_size,int group_item_spacing)5665 void options::CreatePanel_UI(size_t parent, int border_size, int group_item_spacing)
5666 {
5667 wxScrolledWindow* itemPanelFont = AddPage(parent, _("General Options"));
5668
5669 m_itemBoxSizerFontPanel = new wxBoxSizer(wxVERTICAL);
5670 itemPanelFont->SetSizer(m_itemBoxSizerFontPanel);
5671
5672 wxBoxSizer* langStyleBox = new wxBoxSizer(wxHORIZONTAL);
5673 m_itemBoxSizerFontPanel->Add(langStyleBox, 0, wxEXPAND | wxALL, border_size);
5674
5675 wxStaticBox* itemLangStaticBox = new wxStaticBox(itemPanelFont, wxID_ANY, _("Language"));
5676 wxStaticBoxSizer* itemLangStaticBoxSizer = new wxStaticBoxSizer(itemLangStaticBox, wxVERTICAL);
5677
5678 langStyleBox->Add(itemLangStaticBoxSizer, 1, wxEXPAND | wxALL, border_size);
5679
5680 m_itemLangListBox = new wxChoice(itemPanelFont, ID_CHOICE_LANG);
5681
5682 itemLangStaticBoxSizer->Add(m_itemLangListBox, 0, wxEXPAND | wxALL, border_size);
5683 #ifdef __OCPN__ANDROID__
5684 m_itemLangListBox->Disable();
5685 #endif
5686
5687 wxStaticBox* itemFontStaticBox = new wxStaticBox(itemPanelFont, wxID_ANY, _("Fonts"));
5688
5689 wxSize fontChoiceSize = wxSize( -1, -1 );
5690
5691 int fLayout = wxHORIZONTAL;
5692 #ifdef __OCPN__ANDROID__
5693 // Compensate for very narrow displays on Android
5694 if(m_nCharWidthMax < 40)
5695 fLayout = wxVERTICAL;
5696
5697 // Need to set wxChoice vertical size explicitely in Android
5698 fontChoiceSize = wxSize( -1, m_fontHeight * 3 / 4);
5699 #endif
5700
5701 wxStaticBoxSizer* itemFontStaticBoxSizer = new wxStaticBoxSizer(itemFontStaticBox, fLayout);
5702 m_itemBoxSizerFontPanel->Add(itemFontStaticBoxSizer, 0, wxEXPAND | wxALL, border_size);
5703
5704 m_itemFontElementListBox = new wxChoice(itemPanelFont, ID_CHOICE_FONTELEMENT, wxDefaultPosition, fontChoiceSize, 0, NULL, wxCB_SORT);
5705
5706 int nFonts = FontMgr::Get().GetNumFonts();
5707 for (int it = 0; it < nFonts; it++) {
5708 const wxString& t = FontMgr::Get().GetDialogString(it);
5709
5710 if (FontMgr::Get().GetConfigString(it).StartsWith(g_locale)) {
5711 m_itemFontElementListBox->Append(t);
5712 }
5713 }
5714
5715 if (nFonts) m_itemFontElementListBox->SetSelection(0);
5716
5717 itemFontStaticBoxSizer->Add(m_itemFontElementListBox, 0, wxALL, border_size);
5718
5719 wxButton* itemFontChooseButton =
5720 new wxButton(itemPanelFont, ID_BUTTONFONTCHOOSE, _("Choose Font..."),
5721 wxDefaultPosition, wxDefaultSize, 0);
5722 itemFontStaticBoxSizer->Add(itemFontChooseButton, 0, wxALL, border_size);
5723 #if defined(__WXGTK__) || defined(__WXQT__)
5724 wxButton* itemFontColorButton =
5725 new wxButton(itemPanelFont, ID_BUTTONFONTCOLOR, _("Choose Font Color..."),
5726 wxDefaultPosition, wxDefaultSize, 0);
5727 itemFontStaticBoxSizer->Add(itemFontColorButton, 0, wxALL, border_size);
5728 #endif
5729 m_textSample = new wxStaticText(itemPanelFont, wxID_ANY, _("Sample"), wxDefaultPosition, wxDefaultSize, 0);
5730 itemFontStaticBoxSizer->Add(m_textSample, 0, wxALL, border_size);
5731 wxCommandEvent e;
5732 OnFontChoice(e);
5733
5734 #if 0
5735 wxStaticBox* itemStyleStaticBox =
5736 new wxStaticBox(itemPanelFont, wxID_ANY, _("Toolbar and Window Style"));
5737 wxStaticBoxSizer* itemStyleStaticBoxSizer =
5738 new wxStaticBoxSizer(itemStyleStaticBox, wxVERTICAL);
5739 langStyleBox->Add(itemStyleStaticBoxSizer, 1, wxEXPAND | wxALL, border_size);
5740
5741 m_itemStyleListBox = new wxChoice(itemPanelFont, ID_STYLESCOMBOBOX);
5742
5743 wxArrayPtrVoid styles = g_StyleManager->GetArrayOfStyles();
5744 for (unsigned int i = 0; i < styles.Count(); i++) {
5745 ocpnStyle::Style* style = (ocpnStyle::Style*)(styles[i]);
5746 m_itemStyleListBox->Append(style->name);
5747 }
5748 m_itemStyleListBox->SetStringSelection(
5749 g_StyleManager->GetCurrentStyle()->name);
5750 itemStyleStaticBoxSizer->Add(m_itemStyleListBox, 1, wxEXPAND | wxALL,
5751 border_size);
5752 #endif
5753 wxStaticBox* miscOptionsBox =
5754 new wxStaticBox(itemPanelFont, wxID_ANY, _("Interface Options"));
5755 wxStaticBoxSizer* miscOptions =
5756 new wxStaticBoxSizer(miscOptionsBox, wxVERTICAL);
5757 m_itemBoxSizerFontPanel->Add(miscOptions, 0, wxALL | wxEXPAND, border_size);
5758
5759 pShowStatusBar =
5760 new wxCheckBox(itemPanelFont, ID_DEBUGCHECKBOX1, _("Show Status Bar"));
5761 pShowStatusBar->SetValue(FALSE);
5762 miscOptions->Add(pShowStatusBar, 0, wxALL, border_size);
5763
5764 #ifndef __WXOSX__
5765 pShowMenuBar = new wxCheckBox(itemPanelFont, wxID_ANY, _("Show Menu Bar"));
5766 pShowMenuBar->SetValue(FALSE);
5767 miscOptions->Add(pShowMenuBar, 0, wxALL, border_size);
5768 #endif
5769
5770 #ifdef __OCPN__ANDROID__
5771 pShowMenuBar->Hide();
5772 #endif
5773
5774 pShowChartBar = new wxCheckBox(itemPanelFont, wxID_ANY, _("Show Chart Bar"));
5775 pShowChartBar->SetValue(g_bShowChartBar);
5776 miscOptions->Add(pShowChartBar, 0, wxALL, border_size);
5777
5778 pShowCompassWin = new wxCheckBox(itemPanelFont, wxID_ANY,
5779 _("Show Compass/GPS Status Window"));
5780 pShowCompassWin->SetValue(FALSE);
5781 miscOptions->Add(pShowCompassWin, 0, wxALL, border_size);
5782
5783 wxBoxSizer* pToolbarAutoHide = new wxBoxSizer(wxHORIZONTAL);
5784 miscOptions->Add(pToolbarAutoHide, 0, wxALL | wxEXPAND, group_item_spacing);
5785
5786 pToolbarAutoHideCB = new wxCheckBox(itemPanelFont, wxID_ANY,
5787 _("Enable Toolbar auto-hide"));
5788 pToolbarAutoHide->Add(pToolbarAutoHideCB, 0, wxALL, group_item_spacing);
5789
5790 pToolbarHideSecs =
5791 new wxTextCtrl(itemPanelFont, ID_OPTEXTCTRL, _T(""), wxDefaultPosition,
5792 wxSize(50, -1), wxTE_RIGHT);
5793 pToolbarAutoHide->Add(pToolbarHideSecs, 0, wxALL,
5794 group_item_spacing);
5795
5796 pToolbarAutoHide->Add(new wxStaticText(itemPanelFont, wxID_ANY, _("seconds")),
5797 group_item_spacing);
5798
5799 wxBoxSizer* pShipsBellsSizer = new wxBoxSizer(wxHORIZONTAL);
5800 miscOptions->Add(pShipsBellsSizer, 0, wxALL, group_item_spacing);
5801 // Sound options
5802 pPlayShipsBells =
5803 new wxCheckBox(itemPanelFont, ID_BELLSCHECKBOX, _("Play Ships Bells"));
5804 pShipsBellsSizer->Add(pPlayShipsBells, 0, wxALL | wxEXPAND, border_size);
5805
5806 #ifndef __OCPN__ANDROID__
5807 if ( g_bUIexpert && (bool) dynamic_cast<SystemCmdSound*>(SoundFactory()) ) {
5808 wxBoxSizer* pSoundSizer = new wxBoxSizer( wxVERTICAL );
5809 pShipsBellsSizer->Add( pSoundSizer, 0, wxALL | wxEXPAND, group_item_spacing );
5810 pCmdSoundString = new wxTextCtrl( itemPanelFont, wxID_ANY, _T( "" ),
5811 wxDefaultPosition,
5812 wxSize( 450, -1 ), wxTE_LEFT );
5813 pSoundSizer->Add( new wxStaticText( itemPanelFont, wxID_ANY,
5814 _( "Audio Play command:" ) ), 0,
5815 wxALIGN_CENTER_HORIZONTAL | wxALL );
5816 pSoundSizer->Add( pCmdSoundString, 1, wxEXPAND | wxALIGN_LEFT, border_size );
5817 }
5818 #endif
5819
5820 OcpnSound* sound = SoundFactory();
5821 int deviceCount = sound->DeviceCount();
5822 wxLogMessage("options: got device count: %d", deviceCount);
5823 if (deviceCount >= 1) {
5824 wxArrayString labels;
5825 for (int i = 0; i < deviceCount; i += 1) {
5826 if (!sound->IsOutputDevice(i)) {
5827 continue;
5828 }
5829 wxString label(sound->GetDeviceInfo(i));
5830 if (label == "") {
5831 std::ostringstream stm ;
5832 stm << i ;
5833 label = _("Unknown device :") + stm.str();
5834 labels.Add(label);
5835 }
5836 }
5837 pSoundDeviceIndex = new wxChoice();
5838 if (pSoundDeviceIndex) {
5839 pSoundDeviceIndex->Create(itemPanelFont,
5840 wxID_ANY,
5841 wxDefaultPosition,
5842 wxDefaultSize,
5843 labels);
5844 pSoundDeviceIndex->SetSelection(g_iSoundDeviceIndex);
5845 pSoundDeviceIndex->Show();
5846 wxFlexGridSizer* pSoundDeviceIndexGrid = new wxFlexGridSizer(2);
5847 miscOptions->Add(pSoundDeviceIndexGrid, 0, wxALL | wxEXPAND,
5848 group_item_spacing);
5849
5850 stSoundDeviceIndex = new wxStaticText(itemPanelFont, wxID_STATIC, _("Sound Device"));
5851 pSoundDeviceIndexGrid->Add(stSoundDeviceIndex, 0, wxALL, 5);
5852 pSoundDeviceIndexGrid->Add(pSoundDeviceIndex, 0, wxALL, border_size);
5853 }
5854 }
5855 #ifdef __OCPN__ANDROID__
5856 stSoundDeviceIndex->Hide();
5857 pSoundDeviceIndex->Hide();
5858 #endif
5859
5860 // Mobile/Touchscreen checkboxes
5861 pMobile = new wxCheckBox(itemPanelFont, ID_MOBILEBOX,
5862 _("Enable Touchscreen interface"));
5863 miscOptions->Add(pMobile, 0, wxALL, border_size);
5864
5865 pResponsive = new wxCheckBox(itemPanelFont, ID_REPONSIVEBOX,
5866 _("Enable Scaled Graphics interface"));
5867 miscOptions->Add(pResponsive, 0, wxALL, border_size);
5868
5869 // This two options are always needed for Android
5870 #ifdef __OCPN__ANDROID__
5871 pMobile->Hide();
5872 pResponsive->Hide();
5873 #endif
5874
5875 pZoomButtons = new wxCheckBox(itemPanelFont, ID_ZOOMBUTTONS, _("Show Zoom buttons"));
5876 miscOptions->Add(pZoomButtons, 0, wxALL, border_size);
5877 #ifndef __OCPN__ANDROID__
5878 pZoomButtons->Hide();
5879 #endif
5880
5881 pInlandEcdis = new wxCheckBox(itemPanelFont, ID_INLANDECDISBOX, _("Use Inland ECDIS V2.3"));
5882 miscOptions->Add(pInlandEcdis, 0, wxALL, border_size);
5883
5884 #ifdef __OCPN__ANDROID__
5885 pInlandEcdis->Hide();
5886 #endif
5887
5888 #ifdef __WXOSX__
5889 pDarkDecorations = new wxCheckBox(itemPanelFont, ID_DARKDECORATIONSBOX,
5890 _("Use dark window decorations"));
5891 miscOptions->Add(pDarkDecorations, 0, wxALL, border_size);
5892 pDarkDecorations->Enable( (osMajor >= 10) && (osMinor >= 12) );
5893
5894 #endif
5895
5896 miscOptions->AddSpacer(10);
5897
5898 wxFlexGridSizer* sliderSizer;
5899 sliderSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
5900 sliderSizer->AddGrowableCol( 1 );
5901 sliderSizer->SetFlexibleDirection( wxBOTH );
5902 sliderSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
5903
5904 m_pSlider_GUI_Factor = new wxSlider(
5905 itemPanelFont, wxID_ANY, 0, -5, 5, wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
5906 m_pSlider_GUI_Factor->Hide();
5907 sliderSizer->Add(new wxStaticText(itemPanelFont, wxID_ANY,
5908 _("User Interface scale factor")),
5909 inputFlags);
5910 sliderSizer->Add(m_pSlider_GUI_Factor, 0, wxALL, border_size);
5911 m_pSlider_GUI_Factor->Show();
5912
5913 #ifdef __OCPN__ANDROID__
5914 prepareSlider( m_pSlider_GUI_Factor);
5915 #endif
5916
5917 m_pSlider_Chart_Factor = new wxSlider(
5918 itemPanelFont, wxID_ANY, 0, -5, 5, wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
5919 m_pSlider_Chart_Factor->Hide();
5920 sliderSizer->Add(
5921 new wxStaticText(itemPanelFont, wxID_ANY, _("Chart Object scale factor")), inputFlags);
5922 sliderSizer->Add(m_pSlider_Chart_Factor, 0, wxALL, border_size);
5923 m_pSlider_Chart_Factor->Show();
5924
5925 #ifdef __OCPN__ANDROID__
5926 prepareSlider(m_pSlider_Chart_Factor);
5927 #endif
5928
5929 m_pSlider_Ship_Factor = new wxSlider( itemPanelFont, wxID_ANY, 0, -5, 5, wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
5930 m_pSlider_Ship_Factor->Hide();
5931 sliderSizer->Add(
5932 new wxStaticText(itemPanelFont, wxID_ANY, _("Ship scale factor")), inputFlags);
5933 sliderSizer->Add(m_pSlider_Ship_Factor, 0, wxALL, border_size);
5934 m_pSlider_Ship_Factor->Show();
5935
5936 #ifdef __OCPN__ANDROID__
5937 m_pSlider_Ship_Factor->GetHandle()->setStyleSheet(getQtStyleSheet());
5938 #endif
5939
5940 m_pSlider_Text_Factor = new wxSlider( itemPanelFont, wxID_ANY, 0, -5, 5, wxDefaultPosition, m_sliderSize, SLIDER_STYLE);
5941 m_pSlider_Text_Factor->Hide();
5942 sliderSizer->Add(
5943 new wxStaticText(itemPanelFont, wxID_ANY, _("ENC Sounding factor")), inputFlags);
5944 sliderSizer->Add(m_pSlider_Text_Factor, 0, wxALL, border_size);
5945 m_pSlider_Text_Factor->Show();
5946
5947 #ifdef __OCPN__ANDROID__
5948 m_pSlider_Text_Factor->GetHandle()->setStyleSheet(getQtStyleSheet());
5949 #endif
5950
5951 miscOptions->Add( sliderSizer, 0, wxEXPAND, 5 );
5952 miscOptions->AddSpacer(20);
5953 }
5954
CreateListbookIcons()5955 void options::CreateListbookIcons()
5956 {
5957 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
5958
5959 if(!g_bresponsive){
5960 m_topImgList = new wxImageList(40, 40, TRUE, 1);
5961
5962 #if wxCHECK_VERSION(2, 8, 12)
5963 m_topImgList->Add(style->GetIcon(_T("Display")));
5964 m_topImgList->Add(style->GetIcon(_T("Charts")));
5965 m_topImgList->Add(style->GetIcon(_T("Connections")));
5966 m_topImgList->Add(style->GetIcon(_T("Ship")));
5967 m_topImgList->Add(style->GetIcon(_T("UI")));
5968 m_topImgList->Add(style->GetIcon(_T("Plugins")));
5969 #else
5970 wxBitmap bmp;
5971 wxImage img;
5972 bmp = style->GetIcon(_T("Display"));
5973 img = bmp.ConvertToImage();
5974 img.ConvertAlphaToMask(128);
5975 bmp = wxBitmap(img);
5976 m_topImgList->Add(bmp);
5977 bmp = style->GetIcon(_T("Charts"));
5978 img = bmp.ConvertToImage();
5979 img.ConvertAlphaToMask(128);
5980 bmp = wxBitmap(img);
5981 m_topImgList->Add(bmp);
5982 bmp = style->GetIcon(_T("Connections"));
5983 img = bmp.ConvertToImage();
5984 img.ConvertAlphaToMask(128);
5985 bmp = wxBitmap(img);
5986 m_topImgList->Add(bmp);
5987 bmp = style->GetIcon(_T("Ship"));
5988 img = bmp.ConvertToImage();
5989 img.ConvertAlphaToMask(128);
5990 bmp = wxBitmap(img);
5991 m_topImgList->Add(bmp);
5992 bmp = style->GetIcon(_T("UI"));
5993 img = bmp.ConvertToImage();
5994 img.ConvertAlphaToMask(128);
5995 bmp = wxBitmap(img);
5996 m_topImgList->Add(bmp);
5997 bmp = style->GetIcon(_T("Plugins"));
5998 img = bmp.ConvertToImage();
5999 img.ConvertAlphaToMask(128);
6000 bmp = wxBitmap(img);
6001 m_topImgList->Add(bmp);
6002 #endif
6003 }
6004 else{
6005 wxBitmap bmps;
6006 bmps = style->GetIcon(_T("Display"));
6007 int base_size = bmps.GetWidth();
6008 double tool_size = base_size;
6009
6010 double premult = 1.0;
6011
6012 // unless overridden by user, we declare the "best" size
6013 // to be roughly 6 mm square.
6014 double target_size = 6.0; // mm
6015
6016 double basic_tool_size_mm = tool_size / g_Platform->GetDisplayDPmm();
6017 premult = target_size / basic_tool_size_mm;
6018
6019 //Adjust the scale factor using the global GUI scale parameter
6020 double postmult = exp( g_GUIScaleFactor * (0.693 / 5.0) ); // exp(2)
6021 postmult = wxMin(postmult, 3.0);
6022 postmult = wxMax(postmult, 1.0);
6023
6024 int sizeTab = base_size * postmult * premult;
6025
6026 m_topImgList = new wxImageList(sizeTab, sizeTab, TRUE, 1);
6027
6028 wxBitmap bmp;
6029 wxImage img, simg;
6030 bmp = style->GetIcon(_T("Display"));
6031 img = bmp.ConvertToImage();
6032 simg = img.Scale(sizeTab, sizeTab);
6033 bmp = wxBitmap(simg);
6034 m_topImgList->Add(bmp);
6035 bmp = style->GetIcon(_T("Charts"));
6036 img = bmp.ConvertToImage();
6037 simg = img.Scale(sizeTab, sizeTab);
6038 bmp = wxBitmap(simg);
6039 m_topImgList->Add(bmp);
6040 bmp = style->GetIcon(_T("Connections"));
6041 img = bmp.ConvertToImage();
6042 simg = img.Scale(sizeTab, sizeTab);
6043 bmp = wxBitmap(simg);
6044 m_topImgList->Add(bmp);
6045 bmp = style->GetIcon(_T("Ship"));
6046 img = bmp.ConvertToImage();
6047 simg = img.Scale(sizeTab, sizeTab);
6048 bmp = wxBitmap(simg);
6049 m_topImgList->Add(bmp);
6050 bmp = style->GetIcon(_T("UI"));
6051 img = bmp.ConvertToImage();
6052 simg = img.Scale(sizeTab, sizeTab);
6053 bmp = wxBitmap(simg);
6054 m_topImgList->Add(bmp);
6055 bmp = style->GetIcon(_T("Plugins"));
6056 img = bmp.ConvertToImage();
6057 simg = img.Scale(sizeTab, sizeTab);
6058 bmp = wxBitmap(simg);
6059 m_topImgList->Add(bmp);
6060 }
6061
6062 }
6063
6064
CreateControls(void)6065 void options::CreateControls(void) {
6066 int border_size = 4;
6067 // use for items within one group, with Add(...wxALL)
6068 int group_item_spacing = 2;
6069
6070 int font_size_y, font_descent, font_lead;
6071 GetTextExtent(_T("0"), NULL, &font_size_y, &font_descent, &font_lead);
6072 m_fontHeight = font_size_y + font_descent + font_lead;
6073
6074 #ifdef __OCPN__ANDROID__
6075 m_sliderSize = wxSize(wxMin(m_fontHeight * 8, g_Platform->getDisplaySize().x / 2), m_fontHeight * 8 / 10);
6076 #else
6077 m_sliderSize = wxSize(wxMin(m_fontHeight * 8, g_Platform->getDisplaySize().x / 2), m_fontHeight * 2);
6078 #endif
6079
6080 m_small_button_size =
6081 wxSize(-1, (int)(1.4 * (font_size_y + font_descent + font_lead)));
6082
6083 m_nCharWidthMax = GetSize().x / GetCharWidth();
6084
6085 // Some members (pointers to controls) need to initialized
6086 pEnableZoomToCursor = NULL;
6087 pSmoothPanZoom = NULL;
6088
6089 // Check the display size.
6090 // If "small", adjust some factors to squish out some more white space
6091 int width, height;
6092 ::wxDisplaySize(&width, &height);
6093
6094 if (!g_bresponsive && height <= 800) {
6095 border_size = 2;
6096 group_item_spacing = 1;
6097 }
6098
6099 labelFlags = wxSizerFlags(0)
6100 .Align(wxALIGN_RIGHT)
6101 .Border(wxALL, group_item_spacing);
6102 inputFlags = wxSizerFlags(0)
6103 .Align(wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL)
6104 .Border(wxALL, group_item_spacing);
6105 verticleInputFlags = wxSizerFlags(0)
6106 .Align(wxALIGN_LEFT)
6107 .Border(wxALL, group_item_spacing);
6108 groupLabelFlags = wxSizerFlags(0)
6109 .Align(wxALIGN_RIGHT | wxALIGN_TOP)
6110 .Border(wxALL, group_item_spacing);
6111 groupLabelFlagsHoriz = wxSizerFlags(0)
6112 .Align( wxALIGN_TOP)
6113 .Border(wxALL, group_item_spacing);
6114 groupInputFlags = wxSizerFlags(0)
6115 .Align(wxALIGN_LEFT | wxALIGN_TOP)
6116 .Border(wxBOTTOM, group_item_spacing * 2)
6117 .Expand();
6118
6119 #ifdef __WXGTK__
6120 groupLabelFlags.Border(wxTOP, group_item_spacing + 3);
6121 #endif
6122
6123 options* itemDialog1 = this;
6124
6125 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
6126 itemDialog1->SetSizer(itemBoxSizer2);
6127
6128 #ifdef __OCPN__ANDROID__
6129 // Set Dialog Font by custom crafted Qt Stylesheet.
6130 wxFont* qFont = dialogFont;
6131
6132 wxString wqs = getFontQtStylesheet(qFont);
6133 wxCharBuffer sbuf = wqs.ToUTF8();
6134 QString qsb = QString(sbuf.data());
6135
6136 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
6137
6138 itemDialog1->GetHandle()->setStyleSheet(qsb +
6139 qsbq); // Concatenated style sheets
6140
6141 #endif
6142
6143 int flags = 0;
6144
6145 #ifdef __OCPN__OPTIONS_USE_LISTBOOK__
6146 flags = wxLB_TOP;
6147 m_pListbook = new wxListbook(itemDialog1, ID_NOTEBOOK, wxDefaultPosition,
6148 wxSize(-1, -1), flags);
6149 m_pListbook->Connect(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED,
6150 wxListbookEventHandler(options::OnPageChange), NULL,
6151 this);
6152 #else
6153 flags = wxNB_TOP;
6154 m_pListbook = new wxNotebook(itemDialog1, ID_NOTEBOOK, wxDefaultPosition,
6155 wxSize(-1, -1), flags);
6156 m_pListbook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
6157 wxNotebookEventHandler(options::OnTopNBPageChange), NULL,
6158 this);
6159 #endif
6160
6161 #ifdef __OCPN__ANDROID__
6162 // In wxQT, we can dynamically style the little scroll buttons on a small
6163 // display, to make them bigger
6164 m_pListbook->GetHandle()->setStyleSheet( getListBookStyleSheet() );
6165
6166 #endif
6167
6168 #ifdef __WXMSW__
6169 // Windows clips the width of listbook selectors to about twice icon size
6170 // This makes the text render with ellipses if too large
6171
6172 // So, Measure and reduce the Font size on ListBook(ListView) selectors
6173 // to allow text layout without ellipsis...
6174 wxBitmap tbmp = g_StyleManager->GetCurrentStyle()->GetIcon(_T("Display"));
6175 wxScreenDC sdc;
6176 int text_width = tbmp.GetWidth();
6177 if (sdc.IsOk())
6178 sdc.GetTextExtent(_("Connections"), &text_width, NULL, NULL, NULL,
6179 dialogFont);
6180
6181 if (text_width > tbmp.GetWidth() * 2) {
6182 wxListView* lv = m_pListbook->GetListView();
6183 wxFont* qFont = dialogFont; // to get type, weight, etc...
6184
6185 wxFont* sFont = FontMgr::Get().FindOrCreateFont(
6186 10, qFont->GetFamily(), qFont->GetStyle(), qFont->GetWeight());
6187 lv->SetFont(*sFont);
6188 }
6189 #endif
6190
6191 CreateListbookIcons();
6192
6193 m_pListbook->SetImageList(m_topImgList);
6194 itemBoxSizer2->Add( m_pListbook, 1, wxALL | wxEXPAND, border_size);
6195
6196 wxBoxSizer* buttons = new wxBoxSizer(wxHORIZONTAL);
6197 itemBoxSizer2->Add(buttons, 0, wxALIGN_RIGHT | wxALL, border_size);
6198
6199 m_OKButton = new wxButton(itemDialog1, xID_OK, _("OK"));
6200 m_OKButton->SetDefault();
6201 buttons->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, border_size);
6202
6203 m_CancelButton = new wxButton(itemDialog1, wxID_CANCEL, _("Cancel"));
6204 buttons->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, border_size);
6205
6206 m_ApplyButton = new wxButton(itemDialog1, ID_APPLY, _("Apply"));
6207 buttons->Add(m_ApplyButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, border_size);
6208
6209 m_pageDisplay = CreatePanel(_("Display"));
6210 CreatePanel_Display(m_pageDisplay, border_size, group_item_spacing);
6211 CreatePanel_Units(m_pageDisplay, border_size, group_item_spacing);
6212 CreatePanel_Advanced(m_pageDisplay, border_size, group_item_spacing);
6213 CreatePanel_Configs(m_pageDisplay, border_size, group_item_spacing);
6214
6215 m_pageCharts = CreatePanel(_("Charts"));
6216 CreatePanel_ChartsLoad(m_pageCharts, border_size, group_item_spacing);
6217 CreatePanel_VectorCharts(m_pageCharts, border_size, group_item_spacing);
6218 // ChartGroups must be created after ChartsLoad and must be at least third
6219 CreatePanel_ChartGroups(m_pageCharts, border_size, group_item_spacing);
6220 RecalculateSize();
6221 CreatePanel_TidesCurrents(m_pageCharts, border_size, group_item_spacing);
6222
6223 wxNotebook* nb = dynamic_cast<wxNotebook*>(m_pListbook->GetPage(m_pageCharts));
6224 if (nb){
6225
6226 #ifdef __OCPN__OPTIONS_USE_LISTBOOK__
6227 nb->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
6228 wxListbookEventHandler(options::OnChartsPageChange),
6229 NULL, this);
6230 #else
6231 nb->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
6232 wxNotebookEventHandler(options::OnChartsPageChange),
6233 NULL, this);
6234
6235 #endif
6236 }
6237
6238
6239 m_pageConnections = CreatePanel(_("Connections"));
6240 #ifndef __OCPN__ANDROID__
6241 CreatePanel_NMEA(m_pageConnections, border_size, group_item_spacing);
6242 #else
6243 CreatePanel_NMEA(m_pageConnections, border_size, group_item_spacing);
6244 //CreatePanel_NMEA_Compact(m_pageConnections, border_size, group_item_spacing);
6245 #endif
6246
6247 // SetDefaultConnectionParams();
6248
6249 m_pageShips = CreatePanel(_("Ships"));
6250 CreatePanel_Ownship(m_pageShips, border_size, group_item_spacing);
6251 CreatePanel_AIS(m_pageShips, border_size, group_item_spacing);
6252 #ifndef __OCPN__ANDROID__
6253 CreatePanel_MMSI(m_pageShips, border_size, group_item_spacing);
6254 #endif
6255
6256 CreatePanel_Routes(m_pageShips, border_size, group_item_spacing);
6257
6258 m_pageUI = CreatePanel(_("User Interface"));
6259 CreatePanel_UI(m_pageUI, border_size, group_item_spacing);
6260
6261 m_pagePlugins = CreatePanel(_("Plugins"));
6262 itemPanelPlugins = AddPage(m_pagePlugins, _("Plugins"));
6263
6264 itemBoxSizerPanelPlugins = new wxBoxSizer(wxVERTICAL);
6265 itemPanelPlugins->SetSizer(itemBoxSizerPanelPlugins);
6266
6267 // PlugIns can add panels, too
6268 if (g_pi_manager) g_pi_manager->NotifySetupOptions();
6269
6270 SetColorScheme(static_cast<ColorScheme>(0));
6271
6272 // Set the maximum size of the entire settings dialog
6273 // leaving a slightly larger border for larger displays.
6274 int marginx = 10;
6275 int marginy = 40;
6276 if(width > 800){
6277 marginx = 100;
6278 marginy = 100;
6279 }
6280
6281 SetSizeHints(-1, -1, width - marginx, height - marginy);
6282
6283 // The s57 chart panel is the one which controls the minimum width required
6284 // to avoid horizontal scroll bars
6285 vectorPanel->SetSizeHints(ps57Ctl);
6286 }
6287
SetInitialPage(int page_sel,int sub_page)6288 void options::SetInitialPage(int page_sel, int sub_page)
6289 {
6290 if(page_sel < (int)m_pListbook->GetPageCount())
6291 m_pListbook->SetSelection(page_sel);
6292 else
6293 m_pListbook->SetSelection(0);
6294
6295 if(sub_page >= 0){
6296 for (size_t i = 0; i < m_pListbook->GetPageCount(); i++) {
6297 wxNotebookPage* pg = m_pListbook->GetPage(i);
6298 wxNotebook* nb = dynamic_cast<wxNotebook*>(pg);
6299 if (nb){
6300 if(i == (size_t) page_sel){
6301 if(sub_page < (int)nb->GetPageCount())
6302 nb->SetSelection(sub_page);
6303 else
6304 nb->SetSelection(0);
6305 }
6306 else
6307 nb->ChangeSelection(0);
6308 }
6309 }
6310 }
6311 }
6312
SetColorScheme(ColorScheme cs)6313 void options::SetColorScheme(ColorScheme cs) {
6314 DimeControl(this);
6315
6316 #ifdef __OCPN__OPTIONS_USE_LISTBOOK__
6317 wxListView* lv = m_pListbook->GetListView();
6318 lv->SetBackgroundColour(GetBackgroundColour());
6319
6320 if(m_cs != cs){
6321 delete m_topImgList;
6322 CreateListbookIcons();
6323 m_pListbook->SetImageList(m_topImgList);
6324
6325 m_cs = cs;
6326 }
6327
6328 #endif
6329 }
6330
OnAISRolloverClick(wxCommandEvent & event)6331 void options::OnAISRolloverClick(wxCommandEvent &event)
6332 {
6333 m_pCheck_Rollover_Class->Enable(event.IsChecked());
6334 m_pCheck_Rollover_COG->Enable(event.IsChecked());
6335 m_pCheck_Rollover_CPA->Enable(event.IsChecked());
6336 pStatic_CallSign->Enable(event.IsChecked());
6337 }
6338
6339
OnCanvasConfigSelectClick(int ID,bool selected)6340 void options::OnCanvasConfigSelectClick( int ID, bool selected)
6341 {
6342 switch(ID){
6343 case ID_SCREENCONFIG1:
6344 if(m_sconfigSelect_twovertical)
6345 m_sconfigSelect_twovertical->SetSelected(false);
6346 m_screenConfig = 0;
6347 break;
6348
6349 case ID_SCREENCONFIG2:
6350 if(m_sconfigSelect_single)
6351 m_sconfigSelect_single->SetSelected(false);
6352 m_screenConfig = 1;
6353 break;
6354 }
6355
6356 }
6357
SetInitialSettings(void)6358 void options::SetInitialSettings(void) {
6359 wxString s;
6360
6361 m_returnChanges = 0; // reset the flags
6362 m_bfontChanged = false;
6363
6364 b_oldhaveWMM = b_haveWMM;
6365 b_haveWMM = g_pi_manager && g_pi_manager->IsPlugInAvailable(_T("WMM"));
6366
6367 // Canvas configuration
6368 switch(g_canvasConfig){
6369 case 0:
6370 default:
6371 if(m_sconfigSelect_single)
6372 m_sconfigSelect_single->SetSelected(true);
6373 if(m_sconfigSelect_twovertical)
6374 m_sconfigSelect_twovertical->SetSelected(false);
6375 break;
6376 case 1:
6377 if(m_sconfigSelect_single)
6378 m_sconfigSelect_single->SetSelected(false);
6379 if(m_sconfigSelect_twovertical)
6380 m_sconfigSelect_twovertical->SetSelected(true);
6381 break;
6382 }
6383 m_screenConfig = g_canvasConfig;
6384
6385 // ChartsLoad
6386
6387 if (pActiveChartsList) {
6388 pActiveChartsList->DeleteAllItems();
6389
6390 for (size_t i = 0; i < m_CurrentDirList.GetCount(); i++) {
6391 wxString dirname = m_CurrentDirList[i].fullpath;
6392 wxListItem li;
6393 li.SetId( i );
6394 li.SetAlign(wxLIST_FORMAT_LEFT);
6395 li.SetText(dirname);
6396 li.SetColumn(0);
6397 long idx = pActiveChartsList->InsertItem( li );
6398 }
6399 }
6400
6401 // ChartGroups
6402 if (pActiveChartsList && m_pWorkDirList) {
6403 UpdateWorkArrayFromTextCtl();
6404 groupsPanel->SetDBDirs(*m_pWorkDirList);
6405
6406 // Make a deep copy of the current global Group Array
6407 groupsPanel->EmptyChartGroupArray(m_pGroupArray);
6408 delete m_pGroupArray;
6409 m_pGroupArray = groupsPanel->CloneChartGroupArray(g_pGroupArray);
6410 groupsPanel->SetGroupArray(m_pGroupArray);
6411 groupsPanel->SetInitialSettings();
6412 }
6413
6414 if (m_pConfig) {
6415 pShowStatusBar->SetValue(g_bShowStatusBar);
6416 #ifndef __WXOSX__
6417 pShowMenuBar->SetValue(g_bShowMenuBar);
6418 #endif
6419 pShowCompassWin->SetValue(g_bShowCompassWin);
6420 }
6421
6422 s.Printf(_T("%d"), g_COGAvgSec);
6423 pCOGUPUpdateSecs->SetValue(s);
6424
6425 if(pCDOOutlines) pCDOOutlines->SetValue(g_bShowOutlines);
6426 if(pCDOQuilting) pCDOQuilting->SetValue(g_bQuiltEnable);
6427 // if(pFullScreenQuilt) pFullScreenQuilt->SetValue(!g_bFullScreenQuilt);
6428 if(pSDepthUnits) pSDepthUnits->SetValue(g_bShowDepthUnits);
6429 if(pSkewComp) pSkewComp->SetValue(g_bskew_comp);
6430 pMobile->SetValue(g_btouch);
6431 pResponsive->SetValue(g_bresponsive);
6432 pRollover->SetValue(g_bRollover);
6433 m_pCheck_Rollover_Class->Enable(g_bRollover);
6434 m_pCheck_Rollover_COG->Enable(g_bRollover);
6435 m_pCheck_Rollover_CPA->Enable(g_bRollover);
6436 pStatic_CallSign->Enable(g_bRollover);
6437
6438
6439 pZoomButtons->SetValue( g_bShowMuiZoomButtons );
6440
6441 //pOverzoomEmphasis->SetValue(!g_fog_overzoom);
6442 //pOZScaleVector->SetValue(!g_oz_vector_scale);
6443 pInlandEcdis->SetValue(g_bInlandEcdis);
6444 #ifdef __WXOSX__
6445 pDarkDecorations->SetValue(g_bDarkDecorations);
6446 #endif
6447 pOpenGL->SetValue(g_bopengl);
6448 if(pSmoothPanZoom) pSmoothPanZoom->SetValue(g_bsmoothpanzoom);
6449 pCBTrueShow->SetValue(g_bShowTrue);
6450 pCBMagShow->SetValue(g_bShowMag);
6451
6452 int oldLength = itemStaticTextUserVar->GetLabel().Length();
6453
6454 //disable input for variation if WMM is available
6455 if(b_haveWMM){
6456 itemStaticTextUserVar->SetLabel(_("WMM Plugin calculated magnetic variation"));
6457 wxString s;
6458 s.Printf(_T("%4.1f"), gVar);
6459 pMagVar->SetValue(s);
6460 }
6461 else{
6462 itemStaticTextUserVar->SetLabel(_("User set magnetic variation"));
6463 wxString s;
6464 s.Printf(_T("%4.1f"), g_UserVar);
6465 pMagVar->SetValue(s);
6466 }
6467
6468 int newLength = itemStaticTextUserVar->GetLabel().Length();
6469
6470 // size hack to adjust change in static text size
6471 if( (newLength != oldLength) || (b_oldhaveWMM != b_haveWMM) ){
6472 wxSize sz = GetSize();
6473 SetSize(sz.x+1, sz.y);
6474 SetSize(sz);
6475 }
6476
6477 itemStaticTextUserVar2->Enable(!b_haveWMM);
6478 pMagVar->Enable(!b_haveWMM);
6479
6480 if(pSDisplayGrid) pSDisplayGrid->SetValue(g_bDisplayGrid);
6481
6482 // LIVE ETA OPTION
6483
6484 // Checkbox
6485 if(pSLiveETA) pSLiveETA->SetValue(g_bShowLiveETA);
6486
6487 // Defaut boat speed text input field
6488 // Speed always in knots, and converted to user speed unit
6489 wxString stringDefaultBoatSpeed;
6490 if (!g_defaultBoatSpeed || !g_defaultBoatSpeedUserUnit)
6491 {
6492 g_defaultBoatSpeed = 6.0;
6493 g_defaultBoatSpeedUserUnit = toUsrSpeed(g_defaultBoatSpeed, -1);
6494 }
6495 stringDefaultBoatSpeed.Printf(_T("%d"), (int)g_defaultBoatSpeedUserUnit);
6496 if(pSDefaultBoatSpeed) pSDefaultBoatSpeed->SetValue(stringDefaultBoatSpeed);
6497
6498 // END LIVE ETA OPTION
6499
6500 if(pCBCourseUp) pCBCourseUp->SetValue(g_bCourseUp);
6501 if(pCBNorthUp) pCBNorthUp->SetValue(!g_bCourseUp);
6502 if(pCBLookAhead) pCBLookAhead->SetValue(g_bLookAhead);
6503
6504 if (fabs(wxRound(g_ownship_predictor_minutes) - g_ownship_predictor_minutes) >
6505 1e-4)
6506 s.Printf(_T("%6.2f"), g_ownship_predictor_minutes);
6507 else
6508 s.Printf(_T("%4.0f"), g_ownship_predictor_minutes);
6509 m_pText_OSCOG_Predictor->SetValue(s);
6510
6511 if (fabs(wxRound(g_ownship_HDTpredictor_miles) -
6512 g_ownship_HDTpredictor_miles) > 1e-4)
6513 s.Printf(_T("%6.2f"), g_ownship_HDTpredictor_miles);
6514 else
6515 s.Printf(_T("%4.0f"), g_ownship_HDTpredictor_miles);
6516 m_pText_OSHDT_Predictor->SetValue(s);
6517
6518 m_pShipIconType->SetSelection(g_OwnShipIconType);
6519 wxCommandEvent eDummy;
6520 OnShipTypeSelect(eDummy);
6521 m_pOSLength->SetValue(
6522 wxString::Format(_T("%.1f"), g_n_ownship_length_meters));
6523 m_pOSWidth->SetValue(wxString::Format(_T("%.1f"), g_n_ownship_beam_meters));
6524 m_pOSGPSOffsetX->SetValue(
6525 wxString::Format(_T("%.1f"), g_n_gps_antenna_offset_x));
6526 m_pOSGPSOffsetY->SetValue(
6527 wxString::Format(_T("%.1f"), g_n_gps_antenna_offset_y));
6528 m_pOSMinSize->SetValue(wxString::Format(_T("%d"), g_n_ownship_min_mm));
6529 m_pText_ACRadius->SetValue(
6530 wxString::Format(_T("%.3f"), g_n_arrival_circle_radius));
6531
6532 wxString buf;
6533 if (g_iNavAidRadarRingsNumberVisible > 10)
6534 g_iNavAidRadarRingsNumberVisible = 10;
6535 pNavAidRadarRingsNumberVisible->SetSelection(
6536 g_iNavAidRadarRingsNumberVisible);
6537 buf.Printf(_T("%.3f"), g_fNavAidRadarRingsStep);
6538 pNavAidRadarRingsStep->SetValue(buf);
6539 m_itemRadarRingsUnits->SetSelection(g_pNavAidRadarRingsStepUnits);
6540 m_colourOwnshipRangeRingColour->SetColour(g_colourOwnshipRangeRingsColour);
6541
6542 pScaMinChckB->SetValue( g_bUseWptScaMin );
6543 m_pText_ScaMin->SetValue( wxString::Format(_T("%i"), g_iWpt_ScaMin ));
6544 pScaMinOverruleChckB->SetValue( g_bOverruleScaMin );
6545
6546 OnRadarringSelect(eDummy);
6547
6548 if (g_iWaypointRangeRingsNumber > 10) g_iWaypointRangeRingsNumber = 10;
6549 pWaypointRangeRingsNumber->SetSelection(g_iWaypointRangeRingsNumber);
6550 buf.Printf(_T("%.3f"), g_fWaypointRangeRingsStep);
6551 pWaypointRangeRingsStep->SetValue(buf);
6552 m_itemWaypointRangeRingsUnits->SetSelection(g_iWaypointRangeRingsStepUnits);
6553 m_colourWaypointRangeRingsColour->SetColour(g_colourWaypointRangeRingsColour);
6554 OnWaypointRangeRingSelect(eDummy);
6555
6556 pWayPointPreventDragging->SetValue(g_bWayPointPreventDragging);
6557 pConfirmObjectDeletion->SetValue(g_bConfirmObjectDelete);
6558
6559 pSogCogFromLLCheckBox->SetValue(g_own_ship_sog_cog_calc);
6560 pSogCogFromLLDampInterval->SetValue(g_own_ship_sog_cog_calc_damp_sec);
6561
6562 if(pEnableZoomToCursor) pEnableZoomToCursor->SetValue(g_bEnableZoomToCursor);
6563
6564 if(pPreserveScale) pPreserveScale->SetValue(g_bPreserveScaleOnX);
6565 pPlayShipsBells->SetValue(g_bPlayShipsBells);
6566
6567 if ( g_bUIexpert && pCmdSoundString )
6568 pCmdSoundString->SetValue(g_CmdSoundString);
6569
6570 if (pSoundDeviceIndex)
6571 pSoundDeviceIndex->SetSelection(g_iSoundDeviceIndex);
6572 // pFullScreenToolbar->SetValue( g_bFullscreenToolbar );
6573 //pTransparentToolbar->SetValue(g_bTransparentToolbar);
6574 pSDMMFormat->Select(g_iSDMMFormat);
6575 pDistanceFormat->Select(g_iDistanceFormat);
6576 pSpeedFormat->Select(g_iSpeedFormat);
6577
6578 pAdvanceRouteWaypointOnArrivalOnly->SetValue(
6579 g_bAdvanceRouteWaypointOnArrivalOnly);
6580
6581 pTrackDaily->SetValue(g_bTrackDaily);
6582 pTrackRotateLMT->SetValue(g_track_rotate_time_type == TIME_TYPE_LMT);
6583 pTrackRotateUTC->SetValue(g_track_rotate_time_type == TIME_TYPE_UTC);
6584 pTrackRotateComputerTime->SetValue(g_track_rotate_time_type == TIME_TYPE_COMPUTER);
6585 pTrackHighlite->SetValue(g_bHighliteTracks);
6586 m_colourTrackLineColour->SetColour(g_colourTrackLineColour);
6587
6588 pTrackPrecision->SetSelection(g_nTrackPrecision);
6589
6590 // AIS Parameters
6591 // CPA Box
6592 m_pCheck_CPA_Max->SetValue(g_bCPAMax);
6593
6594 s.Printf(_T("%4.1f"), g_CPAMax_NM);
6595 m_pText_CPA_Max->SetValue(s);
6596
6597 m_pCheck_CPA_Warn->SetValue(g_bCPAWarn);
6598
6599 s.Printf(_T("%4.1f"), g_CPAWarn_NM);
6600 m_pText_CPA_Warn->SetValue(s);
6601
6602 if (m_pCheck_CPA_Warn->GetValue()) {
6603 m_pCheck_CPA_WarnT->Enable();
6604 m_pCheck_CPA_WarnT->SetValue(g_bTCPA_Max);
6605 } else
6606 m_pCheck_CPA_WarnT->Disable();
6607
6608 s.Printf(_T("%4.0f"), g_TCPA_Max);
6609 m_pText_CPA_WarnT->SetValue(s);
6610
6611 // Lost Targets
6612 m_pCheck_Mark_Lost->SetValue(g_bMarkLost);
6613
6614 s.Printf(_T("%4.0f"), g_MarkLost_Mins);
6615 m_pText_Mark_Lost->SetValue(s);
6616
6617 m_pCheck_Remove_Lost->SetValue(g_bRemoveLost);
6618
6619 s.Printf(_T("%4.0f"), g_RemoveLost_Mins);
6620 m_pText_Remove_Lost->SetValue(s);
6621
6622 // Display
6623 m_pCheck_Show_COG->SetValue(g_bShowCOG);
6624
6625 s.Printf(_T("%4.0f"), g_ShowCOG_Mins);
6626 m_pText_COG_Predictor->SetValue(s);
6627
6628 m_pCheck_Show_Tracks->SetValue(g_bAISShowTracks);
6629
6630 s.Printf(_T("%4.0f"), g_AISShowTracks_Mins);
6631 m_pText_Track_Length->SetValue(s);
6632
6633 m_pCheck_Hide_Moored->SetValue(g_bHideMoored);
6634
6635 s.Printf(_T("%4.1f"), g_ShowMoored_Kts);
6636 m_pText_Moored_Speed->SetValue(s);
6637
6638 m_pCheck_Draw_Realtime_Prediction->SetValue(g_bDrawAISRealtime);
6639
6640 s.Printf(_T("%4.1f"), g_AIS_RealtPred_Kts);
6641 m_pText_RealtPred_Speed->SetValue(s);
6642
6643 m_pCheck_Scale_Priority->SetValue(g_bAllowShowScaled);
6644
6645 s.Printf(_T("%i"), g_ShowScaled_Num);
6646 m_pText_Scale_Priority->SetValue(s);
6647
6648
6649 m_pCheck_Show_Area_Notices->SetValue(g_bShowAreaNotices);
6650
6651 m_pCheck_Draw_Target_Size->SetValue(g_bDrawAISSize);
6652 m_pCheck_Draw_Realtime_Prediction->SetValue(g_bDrawAISRealtime);
6653
6654 m_pCheck_Show_Target_Name->SetValue(g_bShowAISName);
6655
6656 s.Printf(_T("%d"), g_Show_Target_Name_Scale);
6657 m_pText_Show_Target_Name_Scale->SetValue(s);
6658
6659 m_pCheck_Wpl_Aprs->SetValue(g_bWplIsAprsPosition);
6660
6661 // Alerts
6662 m_pCheck_AlertDialog->SetValue(g_bAIS_CPA_Alert);
6663 m_pCheck_AlertAudio->SetValue(g_bAIS_CPA_Alert_Audio);
6664 m_pCheck_Alert_Moored->SetValue(g_bAIS_CPA_Alert_Suppress_Moored);
6665
6666 m_pCheck_Ack_Timout->SetValue(g_bAIS_ACK_Timeout);
6667 s.Printf(_T("%4.0f"), g_AckTimeout_Mins);
6668 m_pText_ACK_Timeout->SetValue(s);
6669
6670 // Rollover
6671 m_pCheck_Rollover_Class->SetValue(g_bAISRolloverShowClass);
6672 m_pCheck_Rollover_COG->SetValue(g_bAISRolloverShowCOG);
6673 m_pCheck_Rollover_CPA->SetValue(g_bAISRolloverShowCPA);
6674
6675 m_pSlider_Zoom->SetValue(g_chart_zoom_modifier);
6676 m_pSlider_Zoom_Vector->SetValue(g_chart_zoom_modifier_vector);
6677
6678 m_pSlider_GUI_Factor->SetValue(g_GUIScaleFactor);
6679 m_pSlider_Chart_Factor->SetValue(g_ChartScaleFactor);
6680 m_pSlider_Ship_Factor->SetValue(g_ShipScaleFactor);
6681 m_pSlider_Text_Factor->SetValue(g_ENCSoundingScaleFactor);
6682 wxString screenmm;
6683
6684 if (!g_config_display_size_manual) {
6685 pRBSizeAuto->SetValue(TRUE);
6686 screenmm.Printf(_T("%d"), int(g_Platform->GetDisplaySizeMM()));
6687 pScreenMM->Disable();
6688 } else {
6689 screenmm.Printf(_T("%d"), int(g_config_display_size_mm));
6690 pRBSizeManual->SetValue(TRUE);
6691 }
6692
6693 pScreenMM->SetValue(screenmm);
6694
6695 m_TalkerIdText->SetValue(g_TalkerIdText.MakeUpper());
6696
6697 pDepthUnitSelect->SetSelection(g_nDepthUnitDisplay);
6698 UpdateOptionsUnits(); // sets depth values using the user's unit preference
6699
6700 SetInitialVectorSettings();
6701
6702 pToolbarAutoHideCB->SetValue(g_bAutoHideToolbar);
6703
6704 s.Printf(_T("%d"), g_nAutoHideToolbar);
6705 pToolbarHideSecs->SetValue(s);
6706
6707 m_cbNMEADebug->SetValue(false);
6708 if(NMEALogWindow::Get().GetTTYWindow()){
6709 if(NMEALogWindow::Get().GetTTYWindow()->IsShown()){
6710 m_cbNMEADebug->SetValue(true);
6711 }
6712 }
6713
6714 // Serial ports
6715
6716 delete m_pSerialArray;
6717 m_pSerialArray = NULL;
6718 m_pSerialArray = EnumerateSerialPorts();
6719
6720 if (m_pSerialArray) {
6721 m_comboPort->Clear();
6722 for (size_t i = 0; i < m_pSerialArray->Count(); i++) {
6723 m_comboPort->Append(m_pSerialArray->Item(i));
6724 }
6725 }
6726
6727 // On some platforms, the global connections list may be changed outside of the options dialog.
6728 // Pick up any changes here, and re-populate the dialog list.
6729 FillSourceList();
6730
6731 // Reset the touch flag...
6732 connectionsaved = true;
6733
6734 SetSelectedConnectionPanel( nullptr);
6735
6736 }
6737
resetMarStdList(bool bsetConfig,bool bsetStd)6738 void options::resetMarStdList(bool bsetConfig, bool bsetStd)
6739 {
6740 if (ps57CtlListBox) {
6741 // S52 Primary Filters
6742 ps57CtlListBox->Clear();
6743 marinersStdXref.clear();
6744
6745 for (unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++) {
6746 OBJLElement* pOLE = (OBJLElement*)(ps52plib->pOBJLArray->Item(iPtr));
6747
6748 wxString item;
6749 if (iPtr < ps52plib->OBJLDescriptions.size()) {
6750 item = ps52plib->OBJLDescriptions[iPtr];
6751 } else {
6752 item = wxString(pOLE->OBJLName, wxConvUTF8);
6753 }
6754
6755
6756 // Find the most conservative Category, among Point, Area, and Line LUPs
6757 DisCat cat = OTHER;
6758
6759 DisCat catp = ps52plib->findLUPDisCat(pOLE->OBJLName, SIMPLIFIED);
6760 DisCat cata = ps52plib->findLUPDisCat(pOLE->OBJLName, PLAIN_BOUNDARIES);
6761 DisCat catl = ps52plib->findLUPDisCat(pOLE->OBJLName, LINES);
6762
6763 if((catp == DISPLAYBASE) || (cata == DISPLAYBASE) || (catl== DISPLAYBASE) )
6764 cat = DISPLAYBASE;
6765 else if((catp == STANDARD) || (cata == STANDARD) || (catl== STANDARD) )
6766 cat = STANDARD;
6767
6768 bool benable = true;
6769 if(cat > 0)
6770 benable = cat != DISPLAYBASE;
6771
6772 // The ListBox control will insert entries in sorted order, which means
6773 // we need to
6774 // keep track of already inserted items that gets pushed down the line.
6775 int newpos = ps57CtlListBox->Append(item, benable);
6776 marinersStdXref.push_back(newpos);
6777 for (size_t i = 0; i < iPtr; i++) {
6778 if (marinersStdXref[i] >= newpos) marinersStdXref[i]++;
6779 }
6780
6781 bool bviz = 0;
6782 if(bsetConfig)
6783 bviz = !(pOLE->nViz == 0);
6784
6785 if(cat == DISPLAYBASE)
6786 bviz = true;
6787
6788 if(bsetStd){
6789 if(cat == STANDARD){
6790 bviz = true;
6791 }
6792 }
6793
6794 ps57CtlListBox->Check(newpos, bviz);
6795 }
6796 // Force the wxScrolledWindow to recalculate its scroll bars
6797 wxSize s = ps57CtlListBox->GetSize();
6798 ps57CtlListBox->SetSize(s.x, s.y-1);
6799 }
6800 }
6801
SetInitialVectorSettings(void)6802 void options::SetInitialVectorSettings(void)
6803 {
6804 m_pSlider_CM93_Zoom->SetValue(g_cm93_zoom_factor);
6805
6806 // Diplay Category
6807 if (ps52plib) {
6808 m_bVectorInit = true;
6809 resetMarStdList(true, false);
6810
6811 #ifdef __OCPN__ANDROID__
6812 ps57CtlListBox->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
6813 #endif
6814
6815 int nset = 2; // default OTHER
6816 switch (ps52plib->GetDisplayCategory()) {
6817 case (DISPLAYBASE):
6818 nset = 0;
6819 break;
6820 case (STANDARD):
6821 nset = 1;
6822 break;
6823 case (OTHER):
6824 nset = 2;
6825 break;
6826 case (MARINERS_STANDARD):
6827 nset = 3;
6828 break;
6829 default:
6830 nset = 3;
6831 break;
6832 }
6833
6834 if(pDispCat)
6835 pDispCat->SetSelection(nset);
6836
6837 // Enable the UserStandard object list if either canvas is in MARINERS_STANDARD display category
6838 bool benableMarStd = false;
6839 // .. for each canvas...
6840 for(unsigned int i=0 ; i < g_canvasArray.GetCount() ; i++){
6841 ChartCanvas *cc = g_canvasArray.Item(i);
6842 if(cc){
6843 if(cc->GetENCDisplayCategory() == MARINERS_STANDARD)
6844 benableMarStd = true;
6845 }
6846 }
6847
6848
6849 // if(g_useMUI)
6850 // benableMarStd = true;
6851
6852
6853 if( ps57CtlListBox )
6854 ps57CtlListBox->Enable(benableMarStd);
6855 itemButtonClearList->Enable(benableMarStd);
6856 itemButtonSelectList->Enable(benableMarStd);
6857 itemButtonSetStd->Enable(benableMarStd);
6858
6859
6860 // Other Display Filters
6861 if(pCheck_SOUNDG) pCheck_SOUNDG->SetValue(ps52plib->m_bShowSoundg);
6862 if(pCheck_ATONTEXT) pCheck_ATONTEXT->SetValue(ps52plib->m_bShowAtonText);
6863 if(pCheck_LDISTEXT) pCheck_LDISTEXT->SetValue(ps52plib->m_bShowLdisText);
6864 if(pCheck_XLSECTTEXT) pCheck_XLSECTTEXT->SetValue(ps52plib->m_bExtendLightSectors);
6865
6866 pCheck_META->SetValue(ps52plib->m_bShowMeta);
6867 pCheck_SHOWIMPTEXT->SetValue(ps52plib->m_bShowS57ImportantTextOnly);
6868 pCheck_SCAMIN->SetValue(ps52plib->m_bUseSCAMIN);
6869 pCheck_DECLTEXT->SetValue(ps52plib->m_bDeClutterText);
6870 pCheck_NATIONALTEXT->SetValue(ps52plib->m_bShowNationalTexts);
6871
6872 // Chart Display Style
6873 if (ps52plib->m_nSymbolStyle == PAPER_CHART)
6874 pPointStyle->SetSelection(0);
6875 else
6876 pPointStyle->SetSelection(1);
6877
6878 if (ps52plib->m_nBoundaryStyle == PLAIN_BOUNDARIES)
6879 pBoundStyle->SetSelection(0);
6880 else
6881 pBoundStyle->SetSelection(1);
6882
6883 if (S52_getMarinerParam(S52_MAR_TWO_SHADES) == 1.0)
6884 p24Color->SetSelection(0);
6885 else
6886 p24Color->SetSelection(1);
6887
6888 UpdateOptionsUnits(); // sets depth values using the user's unit preference
6889
6890 }
6891 }
6892
6893
UpdateOptionsUnits(void)6894 void options::UpdateOptionsUnits(void) {
6895 int depthUnit = pDepthUnitSelect->GetSelection();
6896
6897 depthUnit = wxMax(depthUnit, 0);
6898 depthUnit = wxMin(depthUnit, 2);
6899
6900 // depth unit conversion factor
6901 float conv = 1;
6902 if (depthUnit == 0) // feet
6903 conv = 0.3048f; // international definiton of 1 foot is 0.3048 metres
6904 else if (depthUnit == 2) // fathoms
6905 conv = 0.3048f * 6; // 1 fathom is 6 feet
6906
6907 // set depth input values
6908
6909 // set depth unit labels
6910 wxString depthUnitStrings[] = {_("feet"), _("meters"), _("fathoms")};
6911 wxString depthUnitString = depthUnitStrings[depthUnit];
6912 m_depthUnitsShal->SetLabel(depthUnitString);
6913 m_depthUnitsSafe->SetLabel(depthUnitString);
6914 m_depthUnitsDeep->SetLabel(depthUnitString);
6915
6916 wxString s;
6917 s.Printf(_T( "%6.2f" ), S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR) / conv);
6918 s.Trim(FALSE);
6919 m_ShallowCtl->SetValue(s);
6920
6921 s.Printf(_T( "%6.2f" ), S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR) / conv);
6922 s.Trim(FALSE);
6923 m_SafetyCtl->SetValue(s);
6924
6925 s.Printf(_T( "%6.2f" ), S52_getMarinerParam(S52_MAR_DEEP_CONTOUR) / conv);
6926 s.Trim(FALSE);
6927 m_DeepCtl->SetValue(s);
6928 /*
6929 int oldLength = itemStaticTextUserVar->GetLabel().Length();
6930
6931 //disable input for variation if WMM is available
6932 if(b_haveWMM){
6933 itemStaticTextUserVar->SetLabel(_("WMM Plugin calculated magnetic variation"));
6934 wxString s;
6935 s.Printf(_T("%4.1f"), gVar);
6936 pMagVar->SetValue(s);
6937 }
6938 else{
6939 itemStaticTextUserVar->SetLabel(_("User set magnetic variation"));
6940 wxString s;
6941 s.Printf(_T("%4.1f"), g_UserVar);
6942 pMagVar->SetValue(s);
6943 }
6944
6945 int newLength = itemStaticTextUserVar->GetLabel().Length();
6946
6947 // size hack to adjust change in static text size
6948 if( (newLength != oldLength) || (b_oldhaveWMM != b_haveWMM) ){
6949 wxSize sz = GetSize();
6950 SetSize(sz.x+1, sz.y);
6951 SetSize(sz);
6952 }
6953
6954 itemStaticTextUserVar2->Enable(!b_haveWMM);
6955 pMagVar->Enable(!b_haveWMM);
6956 */
6957 }
6958
OnSizeAutoButton(wxCommandEvent & event)6959 void options::OnSizeAutoButton(wxCommandEvent& event) {
6960 wxString screenmm = wxString::Format(
6961 _T( "%d" ), static_cast<int>(g_Platform->GetDisplaySizeMM()));
6962 pScreenMM->SetValue(screenmm);
6963 pScreenMM->Disable();
6964 g_config_display_size_manual = FALSE;
6965 }
6966
OnSizeManualButton(wxCommandEvent & event)6967 void options::OnSizeManualButton(wxCommandEvent& event) {
6968 wxString screenmm = wxString::Format(
6969 _T( "%d" ), static_cast<int>(g_config_display_size_mm > 0
6970 ? g_config_display_size_mm
6971 : g_Platform->GetDisplaySizeMM()));
6972 pScreenMM->SetValue(screenmm);
6973 pScreenMM->Enable();
6974 g_config_display_size_manual = TRUE;
6975 }
6976
OnUnitsChoice(wxCommandEvent & event)6977 void options::OnUnitsChoice(wxCommandEvent& event) { UpdateOptionsUnits(); }
6978
OnCPAWarnClick(wxCommandEvent & event)6979 void options::OnCPAWarnClick(wxCommandEvent& event) {
6980 if (m_pCheck_CPA_Warn->GetValue()) {
6981 m_pCheck_CPA_WarnT->Enable();
6982 } else {
6983 m_pCheck_CPA_WarnT->SetValue(FALSE);
6984 m_pCheck_CPA_WarnT->Disable();
6985 }
6986 }
6987
OnShowGpsWindowCheckboxClick(wxCommandEvent & event)6988 void options::OnShowGpsWindowCheckboxClick(wxCommandEvent& event) {
6989 if (!m_cbNMEADebug->GetValue()) {
6990 NMEALogWindow::Get().DestroyWindow();
6991 } else {
6992 NMEALogWindow::Get().Create(pParent, 35);
6993
6994 // Try to ensure that the log window is a least a little bit visible
6995 wxRect logRect(NMEALogWindow::Get().GetPosX(), NMEALogWindow::Get().GetPosY(),
6996 NMEALogWindow::Get().GetSizeW(), NMEALogWindow::Get().GetSizeH());
6997
6998 if(GetRect().Contains(logRect)){
6999 NMEALogWindow::Get().SetPos(GetRect().x/2, (GetRect().y + (GetRect().height - logRect.height)/2) );
7000 NMEALogWindow::Get().Move();
7001 }
7002
7003 Raise();
7004 }
7005 }
7006
OnShipTypeSelect(wxCommandEvent & event)7007 void options::OnShipTypeSelect(wxCommandEvent& event) {
7008 realSizes->ShowItems(m_pShipIconType->GetSelection() != 0);
7009 dispOptions->Layout();
7010 ownShip->Layout();
7011 itemPanelShip->Layout();
7012 itemPanelShip->Refresh();
7013 event.Skip();
7014 }
7015
OnRadarringSelect(wxCommandEvent & event)7016 void options::OnRadarringSelect(wxCommandEvent& event) {
7017 radarGrid->ShowItems(pNavAidRadarRingsNumberVisible->GetSelection() != 0);
7018 dispOptions->Layout();
7019 ownShip->Layout();
7020 itemPanelShip->Layout();
7021 itemPanelShip->Refresh();
7022 event.Skip();
7023 }
7024
OnWaypointRangeRingSelect(wxCommandEvent & event)7025 void options::OnWaypointRangeRingSelect(wxCommandEvent& event) {
7026 waypointradarGrid->ShowItems(pWaypointRangeRingsNumber->GetSelection() != 0);
7027 dispOptions->Layout();
7028 Routes->Layout();
7029 itemPanelRoutes->Layout();
7030 itemPanelRoutes->Refresh();
7031 event.Skip();
7032 }
7033
OnGLClicked(wxCommandEvent & event)7034 void options::OnGLClicked(wxCommandEvent& event) {
7035 // if (!g_bTransparentToolbarInOpenGLOK)
7036 // pTransparentToolbar->Enable(!pOpenGL->GetValue());
7037 }
7038
OnOpenGLOptions(wxCommandEvent & event)7039 void options::OnOpenGLOptions(wxCommandEvent& event) {
7040 #ifdef ocpnUSE_GL
7041 OpenGLOptionsDlg dlg(this);
7042
7043 if (dlg.ShowModal() == wxID_OK) {
7044 if(gFrame->GetPrimaryCanvas()->GetglCanvas()){
7045 g_GLOptions.m_bUseAcceleratedPanning =
7046 g_bGLexpert ? dlg.GetAcceleratedPanning()
7047 : gFrame->GetPrimaryCanvas()->GetglCanvas()->CanAcceleratePanning();
7048 }
7049
7050 g_bShowFPS = dlg.GetShowFPS();
7051 g_bSoftwareGL = dlg.GetSoftwareGL();
7052
7053 g_GLOptions.m_GLPolygonSmoothing = dlg.GetPolygonSmoothing();
7054 g_GLOptions.m_GLLineSmoothing = dlg.GetLineSmoothing();
7055
7056 if (g_bGLexpert) {
7057 // user defined
7058 g_GLOptions.m_bTextureCompressionCaching =
7059 dlg.GetTextureCompressionCaching();
7060 g_GLOptions.m_iTextureMemorySize = dlg.GetTextureMemorySize();
7061 } else {
7062 // caching is on if textures are compressed
7063 g_GLOptions.m_bTextureCompressionCaching = dlg.GetTextureCompression();
7064 }
7065
7066 if (g_bopengl && g_glTextureManager && g_GLOptions.m_bTextureCompression != dlg.GetTextureCompression()) {
7067 // new g_GLoptions setting is needed in callees
7068 g_GLOptions.m_bTextureCompression = dlg.GetTextureCompression();
7069
7070 if(gFrame->GetPrimaryCanvas()->GetglCanvas()){
7071 ::wxBeginBusyCursor();
7072 gFrame->GetPrimaryCanvas()->GetglCanvas()->SetupCompression();
7073 g_glTextureManager->ClearAllRasterTextures();
7074 ::wxEndBusyCursor();
7075 }
7076 }
7077 else
7078 g_GLOptions.m_bTextureCompression = dlg.GetTextureCompression();
7079
7080 }
7081
7082 if (dlg.GetRebuildCache()) {
7083 m_returnChanges = REBUILD_RASTER_CACHE;
7084 Finish();
7085 }
7086 #endif
7087 }
7088
OnChartDirListSelect(wxCommandEvent & event)7089 void options::OnChartDirListSelect(wxCommandEvent& event)
7090 {
7091 bool selected = (pActiveChartsList->GetSelectedItemCount() > 0);
7092 m_removeBtn->Enable(selected);
7093 if(m_compressBtn)
7094 m_compressBtn->Enable(selected);
7095 }
7096
OnDisplayCategoryRadioButton(wxCommandEvent & event)7097 void options::OnDisplayCategoryRadioButton(wxCommandEvent& event) {
7098
7099 if(!g_useMUI){
7100 if(pDispCat){
7101 const bool select = pDispCat->GetSelection() == 3;
7102 ps57CtlListBox->Enable(select);
7103 itemButtonClearList->Enable(select);
7104 itemButtonSelectList->Enable(select);
7105 itemButtonSetStd->Enable(select);
7106 }
7107 }
7108 event.Skip();
7109 }
7110
OnButtonClearClick(wxCommandEvent & event)7111 void options::OnButtonClearClick(wxCommandEvent& event) {
7112 resetMarStdList(false, false);
7113
7114 // int nOBJL = ps57CtlListBox->GetCount();
7115 // for (int iPtr = 0; iPtr < nOBJL; iPtr++){
7116 // ps57CtlListBox->Check(iPtr, FALSE);
7117 // }
7118 event.Skip();
7119 }
7120
OnButtonSelectClick(wxCommandEvent & event)7121 void options::OnButtonSelectClick(wxCommandEvent& event) {
7122 int nOBJL = ps57CtlListBox->GetCount();
7123 for (int iPtr = 0; iPtr < nOBJL; iPtr++) ps57CtlListBox->Check(iPtr, TRUE);
7124
7125 event.Skip();
7126 }
7127
OnButtonSetStd(wxCommandEvent & event)7128 void options::OnButtonSetStd(wxCommandEvent& event) {
7129 resetMarStdList(false, true);
7130
7131 event.Skip();
7132 }
7133
ShowToolTips(void)7134 bool options::ShowToolTips(void) { return TRUE; }
7135
OnCharHook(wxKeyEvent & event)7136 void options::OnCharHook(wxKeyEvent& event) {
7137 if (event.GetKeyCode() == WXK_RETURN &&
7138 event.GetModifiers() == wxMOD_CONTROL) {
7139 wxCommandEvent okEvent;
7140 okEvent.SetId(xID_OK);
7141 okEvent.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
7142 GetEventHandler()->AddPendingEvent(okEvent);
7143 }
7144 event.Skip();
7145 }
7146
OnButtonaddClick(wxCommandEvent & event)7147 void options::OnButtonaddClick(wxCommandEvent& event) {
7148 wxString selDir;
7149 int dresult = g_Platform->DoDirSelectorDialog( this, &selDir, _("Add a directory containing chart files"),*pInit_Chart_Dir, false); // no add files allowed
7150
7151 if (dresult != wxID_CANCEL) AddChartDir(selDir);
7152
7153 event.Skip();
7154 }
7155
AddChartDir(const wxString & dir)7156 void options::AddChartDir(const wxString& dir) {
7157 wxFileName dirname = wxFileName(dir);
7158 pInit_Chart_Dir->Empty();
7159
7160 wxString dirAdd;
7161 if (g_bportable) {
7162 wxFileName f(dir);
7163 f.MakeRelativeTo(g_Platform->GetHomeDir());
7164 dirAdd = f.GetFullPath();
7165 } else {
7166 pInit_Chart_Dir->Append(dirname.GetPath());
7167 dirAdd = dir;
7168 }
7169
7170 wxListItem li;
7171 int id = pActiveChartsList->GetItemCount(); // next index
7172 li.SetId( id );
7173 li.SetAlign(wxLIST_FORMAT_LEFT);
7174 li.SetText(dirAdd);
7175 li.SetColumn(0);
7176
7177 long idx = pActiveChartsList->InsertItem( li );
7178
7179 k_charts |= CHANGE_CHARTS;
7180
7181 pScanCheckBox->Disable();
7182 }
7183
UpdateDisplayedChartDirList(ArrayOfCDI p)7184 void options::UpdateDisplayedChartDirList(ArrayOfCDI p) {
7185 if (pActiveChartsList) {
7186 pActiveChartsList->DeleteAllItems();
7187 for (size_t i = 0; i < p.GetCount(); i++) {
7188 wxString dirname = p[i].fullpath;
7189 wxListItem li;
7190 li.SetId( i );
7191 li.SetAlign(wxLIST_FORMAT_LEFT);
7192 li.SetText(dirname);
7193 li.SetColumn(0);
7194 long idx = pActiveChartsList->InsertItem( li );
7195 }
7196 }
7197 }
7198
UpdateWorkArrayFromTextCtl(void)7199 void options::UpdateWorkArrayFromTextCtl(void) {
7200
7201 wxString dirname;
7202
7203 int n = pActiveChartsList->GetItemCount();
7204 if (m_pWorkDirList) {
7205 m_pWorkDirList->Clear();
7206 for (int i = 0; i < n; i++) {
7207
7208 dirname = pActiveChartsList->GetItemText(i);
7209 if (!dirname.IsEmpty()) {
7210 // This is a fix for OSX, which appends EOL to results of
7211 // GetLineText()
7212 while ((dirname.Last() == wxChar(_T('\n'))) ||
7213 (dirname.Last() == wxChar(_T('\r'))))
7214 dirname.RemoveLast();
7215
7216 // scan the current array to find a match
7217 // if found, add the info to the work list, preserving the magic
7218 // number
7219 // If not found, make a new ChartDirInfo, and add it
7220 bool b_added = FALSE;
7221 // if(m_pCurrentDirList)
7222 {
7223 int nDir = m_CurrentDirList.GetCount();
7224
7225 for (int i = 0; i < nDir; i++) {
7226 if (m_CurrentDirList[i].fullpath == dirname) {
7227 ChartDirInfo cdi = m_CurrentDirList[i];
7228 m_pWorkDirList->Add(cdi);
7229 b_added = TRUE;
7230 break;
7231 }
7232 }
7233 }
7234 if (!b_added) {
7235 ChartDirInfo cdin;
7236 cdin.fullpath = dirname;
7237 m_pWorkDirList->Add(cdin);
7238 }
7239 }
7240 }
7241 }
7242
7243 }
7244
CreateConnectionParamsFromSelectedItem(void)7245 ConnectionParams* options::CreateConnectionParamsFromSelectedItem(void) {
7246 if (!m_bNMEAParams_shown) return NULL;
7247
7248 // Special encoding for deleted connection
7249 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == _T("Deleted" ))
7250 return NULL;
7251
7252 // We check some values here for consistency.
7253 // If necessary, set defaults so user will see some result, however wrong...
7254
7255 // DataStreams should be Input, Output, or Both
7256 if (!(m_cbInput->GetValue() || m_cbOutput->GetValue())) {
7257 m_cbInput->SetValue( true );
7258 }
7259
7260 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == wxEmptyString) {
7261 m_comboPort->Select(0);
7262 }
7263 // TCP, GPSD and UDP require port field to be set.
7264 // TCP clients, GPSD and UDP output sockets require an address
7265 else if (m_rbTypeNet->GetValue()) {
7266 if (wxAtoi(m_tNetPort->GetValue()) == 0) {
7267 m_tNetPort->SetValue(_T("2947")); // reset to default
7268 }
7269 if (m_tNetAddress->GetValue() == wxEmptyString) {
7270 m_tNetAddress->SetValue(_T("0.0.0.0"));
7271 }
7272 }
7273
7274 ConnectionParams* pConnectionParams = new ConnectionParams();
7275
7276 UpdateConnectionParamsFromSelectedItem( pConnectionParams );
7277
7278 ConnectionParamsPanel *pPanel = new ConnectionParamsPanel( m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
7279 pConnectionParams, this);
7280 pPanel->SetSelected(false);
7281 boxSizerConnections->Add( pPanel, 0, wxEXPAND|wxALL, 0 );
7282 pConnectionParams->m_optionsPanel = pPanel;
7283
7284 return pConnectionParams;
7285
7286 }
7287
UpdateConnectionParamsFromSelectedItem(ConnectionParams * pConnectionParams)7288 ConnectionParams* options::UpdateConnectionParamsFromSelectedItem(ConnectionParams *pConnectionParams) {
7289
7290 pConnectionParams->Valid = TRUE;
7291 if (m_rbTypeSerial->GetValue())
7292 pConnectionParams->Type = SERIAL;
7293 else if (m_rbTypeNet->GetValue())
7294 pConnectionParams->Type = NETWORK;
7295 else if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue())
7296 pConnectionParams->Type = INTERNAL_GPS;
7297 else if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue())
7298 pConnectionParams->Type = INTERNAL_BT;
7299
7300 // Save the existing addr/port to allow closing of existing port
7301 pConnectionParams->LastNetworkAddress = pConnectionParams->NetworkAddress;
7302 pConnectionParams->LastNetworkPort = pConnectionParams->NetworkPort;
7303 pConnectionParams->LastNetProtocol = pConnectionParams->NetProtocol;
7304
7305 pConnectionParams->NetworkAddress = m_tNetAddress->GetValue();
7306 pConnectionParams->NetworkPort = wxAtoi(m_tNetPort->GetValue());
7307 if (m_rbNetProtoTCP->GetValue())
7308 pConnectionParams->NetProtocol = TCP;
7309 else if (m_rbNetProtoUDP->GetValue())
7310 pConnectionParams->NetProtocol = UDP;
7311 else if (m_rbNetProtoGPSD->GetValue())
7312 pConnectionParams->NetProtocol = GPSD;
7313 else if (m_rbNetProtoSignalK->GetValue())
7314 pConnectionParams->NetProtocol = SIGNALK;
7315 else
7316 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
7317
7318 pConnectionParams->Baudrate = wxAtoi(m_choiceBaudRate->GetStringSelection());
7319 pConnectionParams->Priority = wxAtoi(m_choicePriority->GetStringSelection());
7320 pConnectionParams->ChecksumCheck = m_cbCheckCRC->GetValue();
7321 pConnectionParams->AutoSKDiscover = m_cbCheckSKDiscover->GetValue();
7322 pConnectionParams->Garmin = m_cbGarminHost->GetValue();
7323 pConnectionParams->InputSentenceList =
7324 wxStringTokenize(m_tcInputStc->GetValue(), _T(","));
7325 if (m_rbIAccept->GetValue())
7326 pConnectionParams->InputSentenceListType = WHITELIST;
7327 else
7328 pConnectionParams->InputSentenceListType = BLACKLIST;
7329 if (m_cbInput->GetValue()) {
7330 if (m_cbOutput->GetValue()) {
7331 pConnectionParams->IOSelect = DS_TYPE_INPUT_OUTPUT;
7332 } else {
7333 pConnectionParams->IOSelect = DS_TYPE_INPUT;
7334 }
7335 } else
7336 pConnectionParams->IOSelect = DS_TYPE_OUTPUT;
7337
7338 pConnectionParams->OutputSentenceList =
7339 wxStringTokenize(m_tcOutputStc->GetValue(), _T(","));
7340 if (m_rbOAccept->GetValue())
7341 pConnectionParams->OutputSentenceListType = WHITELIST;
7342 else
7343 pConnectionParams->OutputSentenceListType = BLACKLIST;
7344 pConnectionParams->Port = m_comboPort->GetValue().BeforeFirst(' ');
7345
7346 if( (pConnectionParams->Type != INTERNAL_GPS) && (pConnectionParams->Type != INTERNAL_BT) )
7347 CheckDeviceAccess(pConnectionParams->Port);
7348 pConnectionParams->Protocol = PROTO_NMEA0183;
7349
7350 pConnectionParams->bEnabled = m_connection_enabled;
7351 pConnectionParams->b_IsSetup = FALSE;
7352
7353 if (pConnectionParams->Type == INTERNAL_GPS) {
7354 pConnectionParams->NetworkAddress = _T("");
7355 pConnectionParams->NetworkPort = 0;
7356 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
7357 pConnectionParams->Baudrate = 0;
7358 }
7359
7360 if (pConnectionParams->Type == INTERNAL_BT) {
7361 wxString parms = m_choiceBTDataSources->GetStringSelection();
7362 wxStringTokenizer tkz(parms, _T(";"));
7363 wxString name = tkz.GetNextToken();
7364 wxString mac = tkz.GetNextToken();
7365
7366 pConnectionParams->NetworkAddress = name;
7367 pConnectionParams->Port = mac;
7368 pConnectionParams->NetworkPort = 0;
7369 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
7370 pConnectionParams->Baudrate = 0;
7371 // pConnectionParams->SetAuxParameterStr(m_choiceBTDataSources->GetStringSelection());
7372 }
7373
7374 if (pConnectionParams->Type == SERIAL) {
7375 pConnectionParams->UserComment = m_tSerialComment->GetValue();
7376 }
7377 else if (pConnectionParams->Type == NETWORK) {
7378 pConnectionParams->UserComment = m_tNetComment->GetValue();
7379 }
7380
7381
7382 return pConnectionParams;
7383 }
7384
OnApplyClick(wxCommandEvent & event)7385 void options::OnApplyClick(wxCommandEvent& event) {
7386 //::wxBeginBusyCursor();
7387 StopBTScan();
7388
7389 // Start with the stuff that requires intelligent validation.
7390
7391 if (m_pShipIconType->GetSelection() > 0) {
7392 double n_ownship_length_meters;
7393 double n_ownship_beam_meters;
7394 double n_gps_antenna_offset_y;
7395 double n_gps_antenna_offset_x;
7396 long n_ownship_min_mm;
7397 m_pOSLength->GetValue().ToDouble(&n_ownship_length_meters);
7398 m_pOSWidth->GetValue().ToDouble(&n_ownship_beam_meters);
7399 m_pOSGPSOffsetX->GetValue().ToDouble(&n_gps_antenna_offset_x);
7400 m_pOSGPSOffsetY->GetValue().ToDouble(&n_gps_antenna_offset_y);
7401 m_pOSMinSize->GetValue().ToLong(&n_ownship_min_mm);
7402 wxString msg;
7403 if (n_ownship_length_meters <= 0)
7404 msg += _("\n - your ship's length must be > 0");
7405 if (n_ownship_beam_meters <= 0)
7406 msg += _("\n - your ship's beam must be > 0");
7407 if (fabs(n_gps_antenna_offset_x) > n_ownship_beam_meters / 2.0)
7408 msg += _(
7409 "\n - your GPS offset from midship must be within your ship's beam");
7410 if (n_gps_antenna_offset_y < 0 ||
7411 n_gps_antenna_offset_y > n_ownship_length_meters)
7412 msg +=
7413 _("\n - your GPS offset from bow must be within your ship's length");
7414 if (n_ownship_min_mm <= 0 || n_ownship_min_mm > 100)
7415 msg += _("\n - your minimum ship icon size must be between 1 and 100 mm");
7416 if (!msg.IsEmpty()) {
7417 msg.Prepend(_("The settings for own ship real size are not correct:"));
7418 OCPNMessageBox(this, msg, _("OpenCPN info"), wxICON_ERROR | wxOK);
7419 ::wxEndBusyCursor();
7420 event.SetInt(wxID_STOP);
7421 return;
7422 }
7423 g_n_ownship_length_meters = n_ownship_length_meters;
7424 g_n_ownship_beam_meters = n_ownship_beam_meters;
7425 g_n_gps_antenna_offset_y = n_gps_antenna_offset_y;
7426 g_n_gps_antenna_offset_x = n_gps_antenna_offset_x;
7427 g_n_ownship_min_mm = static_cast<int>(n_ownship_min_mm);
7428 }
7429 g_OwnShipIconType = m_pShipIconType->GetSelection();
7430
7431 m_pText_ACRadius->GetValue().ToDouble(&g_n_arrival_circle_radius);
7432 g_n_arrival_circle_radius = wxClip(g_n_arrival_circle_radius, 0.001, 0.6); // Correct abnormally
7433
7434 wxString *icon_name = pWayPointMan->GetIconKey( pWaypointDefaultIconChoice->GetSelection() );
7435 if(icon_name && icon_name->Length())
7436 g_default_wp_icon = *icon_name;
7437
7438 icon_name = pWayPointMan->GetIconKey( pRoutepointDefaultIconChoice->GetSelection() );
7439 if(icon_name && icon_name->Length())
7440 g_default_routepoint_icon = *icon_name;
7441
7442 g_bUseWptScaMin = pScaMinChckB->GetValue();
7443 g_iWpt_ScaMin = wxAtoi( m_pText_ScaMin->GetValue() );
7444 g_bOverruleScaMin = pScaMinOverruleChckB->GetValue();
7445
7446 // Any Font changes?
7447 if(m_bfontChanged)
7448 m_returnChanges |= FONT_CHANGED;
7449
7450 // Handle Chart Tab
7451 if (pActiveChartsList) {
7452 UpdateWorkArrayFromTextCtl();
7453 } else {
7454 m_pWorkDirList->Clear();
7455 int nDir = m_CurrentDirList.GetCount();
7456
7457 for (int i = 0; i < nDir; i++) {
7458 ChartDirInfo cdi = m_CurrentDirList[i];
7459 m_pWorkDirList->Add(cdi);
7460 }
7461 }
7462 groupsPanel->SetDBDirs(*m_pWorkDirList); // update the Groups tab
7463 groupsPanel->m_treespopulated = FALSE;
7464
7465 int k_force = FORCE_UPDATE;
7466 if (pUpdateCheckBox) {
7467 if (!pUpdateCheckBox->GetValue()) k_force = 0;
7468 pUpdateCheckBox->Enable();
7469 pUpdateCheckBox->SetValue(FALSE);
7470 } else {
7471 k_force = 0;
7472 }
7473
7474 m_returnChanges |= k_force;
7475
7476 int k_scan = SCAN_UPDATE;
7477 if (pScanCheckBox) {
7478 if (!pScanCheckBox->GetValue()) k_scan = 0;
7479 pScanCheckBox->Enable();
7480 pScanCheckBox->SetValue(FALSE);
7481 } else {
7482 k_scan = 0;
7483 }
7484
7485 m_returnChanges |= k_scan;
7486
7487 // Chart Groups
7488
7489 if (groupsPanel->modified) {
7490 groupsPanel->EmptyChartGroupArray(g_pGroupArray);
7491 delete g_pGroupArray;
7492 g_pGroupArray = groupsPanel->CloneChartGroupArray(m_pGroupArray);
7493 m_returnChanges |= GROUPS_CHANGED;
7494 }
7495
7496 // Handle Settings Tab
7497 if (m_pConfig) {
7498 g_bShowStatusBar = pShowStatusBar->GetValue();
7499 #ifndef __WXOSX__
7500 g_bShowMenuBar = pShowMenuBar->GetValue();
7501 #endif
7502 g_bShowCompassWin = pShowCompassWin->GetValue();
7503 }
7504
7505 g_bShowChartBar = pShowChartBar->GetValue();
7506
7507 wxString screenmm = pScreenMM->GetValue();
7508 long mm = -1;
7509 screenmm.ToLong(&mm);
7510 g_config_display_size_mm = mm > 0 ? mm : -1;
7511 g_config_display_size_manual = pRBSizeManual->GetValue();
7512
7513 // Connections page.
7514 g_bfilter_cogsog = m_cbFilterSogCog->GetValue();
7515
7516 long filter_val = 1;
7517 m_tFilterSec->GetValue().ToLong(&filter_val);
7518 g_COGFilterSec = wxMin(static_cast<int>(filter_val), MAX_COGSOG_FILTER_SECONDS);
7519 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
7520 g_SOGFilterSec = g_COGFilterSec;
7521
7522 g_bMagneticAPB = m_cbAPBMagnetic->GetValue();
7523 g_NMEAAPBPrecision = m_choicePrecision->GetCurrentSelection();
7524
7525 // NMEA Source
7526 // If the stream selected exists, capture some of its existing parameters
7527 // to facility identification and allow stop and restart of the stream
7528 wxString lastAddr;
7529 int lastPort = 0;
7530 NetworkProtocol lastNetProtocol = PROTO_UNDEFINED;
7531
7532 if (mSelectedConnection) {
7533 ConnectionParams* cpo = mSelectedConnection;
7534 lastAddr = cpo->NetworkAddress;
7535 lastPort = cpo->NetworkPort;
7536 lastNetProtocol = cpo->NetProtocol;
7537 }
7538
7539 if (!connectionsaved) {
7540 size_t nCurrentPanelCount = g_pConnectionParams->GetCount();
7541 ConnectionParams *cp = NULL;
7542 int old_priority = -1;
7543 {
7544 if (mSelectedConnection) {
7545 cp = mSelectedConnection;
7546 old_priority = cp->Priority;
7547 UpdateConnectionParamsFromSelectedItem( cp );
7548 cp->b_IsSetup = false;
7549
7550 //delete g_pConnectionParams->Item(itemIndex)->m_optionsPanel;
7551 //old_priority = g_pConnectionParams->Item(itemIndex)->Priority;
7552 //g_pConnectionParams->RemoveAt(itemIndex);
7553 //g_pConnectionParams->Insert(cp, itemIndex);
7554 //mSelectedConnection = cp;
7555 //cp->m_optionsPanel->SetSelected( true );
7556 } else {
7557 cp = CreateConnectionParamsFromSelectedItem();
7558 if(cp)
7559 g_pConnectionParams->Add(cp);
7560 }
7561
7562 // Record the previous parameters, if any
7563 if(cp){
7564 cp->LastNetProtocol = lastNetProtocol;
7565 cp->LastNetworkAddress = lastAddr;
7566 cp->LastNetworkPort = lastPort;
7567 }
7568
7569 if(g_pConnectionParams->GetCount() != nCurrentPanelCount)
7570 FillSourceList();
7571 else if(old_priority >= 0){
7572 if(old_priority != cp->Priority) // need resort
7573 UpdateSourceList( true );
7574 else
7575 UpdateSourceList( false );
7576 }
7577
7578
7579
7580
7581 connectionsaved = TRUE;
7582 }
7583 // else {
7584 // ::wxEndBusyCursor();
7585 // if (m_bNMEAParams_shown) event.SetInt(wxID_STOP);
7586 // }
7587
7588 SetSelectedConnectionPanel( nullptr );
7589
7590 }
7591
7592 // Recreate datastreams that are new, or have been edited
7593 for (size_t i = 0; i < g_pConnectionParams->Count(); i++) {
7594 ConnectionParams* cp = g_pConnectionParams->Item(i);
7595
7596 // Stream is new, or edited
7597 if (cp->b_IsSetup) continue;
7598 // Terminate and remove any existing stream with the same port name
7599 DataStream* pds_existing = g_pMUX->FindStream(cp->GetDSPort());
7600 if (pds_existing) g_pMUX->StopAndRemoveStream(pds_existing);
7601
7602 // Try to stop any previous stream to avoid orphans
7603 pds_existing = g_pMUX->FindStream(cp->GetLastDSPort());
7604 if (pds_existing) g_pMUX->StopAndRemoveStream(pds_existing);
7605
7606 // This for Bluetooth, which has strange parameters
7607 if(cp->Type == INTERNAL_BT){
7608 pds_existing = g_pMUX->FindStream(cp->GetPortStr());
7609 if (pds_existing) g_pMUX->StopAndRemoveStream(pds_existing);
7610 }
7611
7612 // Internal BlueTooth driver stacks commonly need a time delay to purge their buffers, etc.
7613 // before restating with new parameters...
7614 if(cp->Type == INTERNAL_BT)
7615 wxSleep(1);
7616
7617 if (!cp->bEnabled) continue;
7618 g_pMUX->AddStream(makeDataStream(g_pMUX, cp));
7619 cp->b_IsSetup = TRUE;
7620 }
7621
7622 g_bGarminHostUpload = m_cbGarminUploadHost->GetValue();
7623 g_GPS_Ident = m_cbFurunoGP3X->GetValue() ? _T( "FurunoGP3X" ) : _T( "Generic" );
7624
7625 // End of Connections page
7626 if(pCDOOutlines) g_bShowOutlines = pCDOOutlines->GetValue();
7627 if(pSDisplayGrid) g_bDisplayGrid = pSDisplayGrid->GetValue();
7628
7629 if(pCDOQuilting){
7630 bool temp_bquilting = pCDOQuilting->GetValue();
7631 // if (!g_bQuiltEnable && temp_bquilting)
7632 // cc1->ReloadVP(); /* compose the quilt */
7633 g_bQuiltEnable = temp_bquilting;
7634 }
7635 // g_bFullScreenQuilt = !pFullScreenQuilt->GetValue();
7636
7637 if(pSDepthUnits) g_bShowDepthUnits = pSDepthUnits->GetValue();
7638 g_bskew_comp = pSkewComp->GetValue();
7639 g_btouch = pMobile->GetValue();
7640 g_bresponsive = pResponsive->GetValue();
7641 g_bRollover = pRollover->GetValue();
7642 g_bShowMuiZoomButtons = pZoomButtons->GetValue();
7643
7644 g_bAutoHideToolbar = pToolbarAutoHideCB->GetValue();
7645
7646 long hide_val = 10;
7647 pToolbarHideSecs->GetValue().ToLong(&hide_val);
7648 g_nAutoHideToolbar = wxMin(static_cast<int>(hide_val), 100);
7649 g_nAutoHideToolbar = wxMax(g_nAutoHideToolbar, 2);
7650
7651 //g_fog_overzoom = !pOverzoomEmphasis->GetValue();
7652 //g_oz_vector_scale = !pOZScaleVector->GetValue();
7653
7654 g_bsmoothpanzoom = pSmoothPanZoom->GetValue();
7655 #ifdef __OCPN__ANDROID__
7656 g_bsmoothpanzoom = false;
7657 #endif
7658 if(pSmoothPanZoom) g_bsmoothpanzoom = pSmoothPanZoom->GetValue();
7659 #ifdef __OCPN__ANDROID__
7660 g_bsmoothpanzoom = false;
7661 #endif
7662
7663 long update_val = 1;
7664 pCOGUPUpdateSecs->GetValue().ToLong(&update_val);
7665 g_COGAvgSec = wxMin(static_cast<int>(update_val), MAX_COG_AVERAGE_SECONDS);
7666
7667 //TODO if (g_bCourseUp != pCBCourseUp->GetValue()) gFrame->ToggleCourseUp();
7668
7669 if(pCBLookAhead) g_bLookAhead = pCBLookAhead->GetValue();
7670
7671 g_bShowTrue = pCBTrueShow->GetValue();
7672 g_bShowMag = pCBMagShow->GetValue();
7673
7674 b_haveWMM = g_pi_manager && g_pi_manager->IsPlugInAvailable(_T("WMM"));
7675 if(!b_haveWMM && !b_oldhaveWMM)
7676 pMagVar->GetValue().ToDouble(&g_UserVar);
7677
7678 m_pText_OSCOG_Predictor->GetValue().ToDouble(&g_ownship_predictor_minutes);
7679 m_pText_OSHDT_Predictor->GetValue().ToDouble(&g_ownship_HDTpredictor_miles);
7680
7681 double temp_dbl;
7682 g_iNavAidRadarRingsNumberVisible =
7683 pNavAidRadarRingsNumberVisible->GetSelection();
7684 if (pNavAidRadarRingsStep->GetValue().ToDouble(&temp_dbl))
7685 g_fNavAidRadarRingsStep = temp_dbl;
7686 g_pNavAidRadarRingsStepUnits = m_itemRadarRingsUnits->GetSelection();
7687 g_iWaypointRangeRingsNumber = pWaypointRangeRingsNumber->GetSelection();
7688 if (pWaypointRangeRingsStep->GetValue().ToDouble(&temp_dbl))
7689 g_fWaypointRangeRingsStep = temp_dbl;
7690 g_iWaypointRangeRingsStepUnits = m_itemWaypointRangeRingsUnits->GetSelection();
7691 g_colourWaypointRangeRingsColour = m_colourWaypointRangeRingsColour->GetColour();
7692 g_colourWaypointRangeRingsColour =
7693 wxColour(g_colourWaypointRangeRingsColour.Red(), g_colourWaypointRangeRingsColour.Green(), g_colourWaypointRangeRingsColour.Blue());
7694 g_bWayPointPreventDragging = pWayPointPreventDragging->GetValue();
7695 g_own_ship_sog_cog_calc = pSogCogFromLLCheckBox->GetValue();
7696 g_own_ship_sog_cog_calc_damp_sec = pSogCogFromLLDampInterval->GetValue();
7697
7698 g_bConfirmObjectDelete = pConfirmObjectDeletion->GetValue();
7699
7700 if(pPreserveScale) g_bPreserveScaleOnX = pPreserveScale->GetValue();
7701
7702 if ( g_bUIexpert && pCmdSoundString) {
7703 g_CmdSoundString = pCmdSoundString->GetValue( );
7704 if ( wxIsEmpty( g_CmdSoundString ) ) {
7705 g_CmdSoundString = wxString( SYSTEM_SOUND_CMD );
7706 pCmdSoundString->SetValue( g_CmdSoundString );
7707 }
7708 }
7709
7710 g_bPlayShipsBells = pPlayShipsBells->GetValue();
7711 if (pSoundDeviceIndex)
7712 g_iSoundDeviceIndex = pSoundDeviceIndex->GetSelection();
7713 //g_bTransparentToolbar = pTransparentToolbar->GetValue();
7714 g_iSDMMFormat = pSDMMFormat->GetSelection();
7715 g_iDistanceFormat = pDistanceFormat->GetSelection();
7716 g_iSpeedFormat = pSpeedFormat->GetSelection();
7717
7718 // LIVE ETA OPTION
7719 if(pSLiveETA) g_bShowLiveETA = pSLiveETA->GetValue();
7720 if(pSDefaultBoatSpeed) pSDefaultBoatSpeed->GetValue().ToDouble(&g_defaultBoatSpeedUserUnit);
7721 g_defaultBoatSpeed = fromUsrSpeed(g_defaultBoatSpeedUserUnit);
7722
7723 g_bAdvanceRouteWaypointOnArrivalOnly = pAdvanceRouteWaypointOnArrivalOnly->GetValue();
7724
7725 g_colourTrackLineColour = m_colourTrackLineColour->GetColour();
7726 g_colourTrackLineColour = wxColour(g_colourTrackLineColour.Red(), g_colourTrackLineColour.Green(), g_colourTrackLineColour.Blue());
7727 g_nTrackPrecision = pTrackPrecision->GetSelection();
7728
7729 g_bTrackDaily = pTrackDaily->GetValue();
7730
7731 g_track_rotate_time = 0;
7732 #if wxCHECK_VERSION(2, 9, 0)
7733 #if wxUSE_TIMEPICKCTRL
7734 int h,m,s;
7735 if( pTrackRotateTime->GetTime(&h, &m, &s) )
7736 g_track_rotate_time = h*3600 + m*60 + s;
7737 #endif
7738 #endif
7739
7740 if( pTrackRotateUTC->GetValue() )
7741 g_track_rotate_time_type = TIME_TYPE_UTC;
7742 else if( pTrackRotateLMT->GetValue() )
7743 g_track_rotate_time_type = TIME_TYPE_LMT;
7744 else g_track_rotate_time_type = TIME_TYPE_COMPUTER;
7745
7746
7747 g_bHighliteTracks = pTrackHighlite->GetValue();
7748
7749 if(pEnableZoomToCursor) g_bEnableZoomToCursor = pEnableZoomToCursor->GetValue();
7750 #ifdef __OCPN__ANDROID__
7751 g_bEnableZoomToCursor = false;
7752 #endif
7753
7754 g_colourOwnshipRangeRingsColour = m_colourOwnshipRangeRingColour->GetColour();
7755 g_colourOwnshipRangeRingsColour = wxColour(g_colourOwnshipRangeRingsColour.Red(), g_colourOwnshipRangeRingsColour.Green(), g_colourOwnshipRangeRingsColour.Blue());
7756
7757 // AIS Parameters
7758 // CPA Box
7759 g_bCPAMax = m_pCheck_CPA_Max->GetValue();
7760 m_pText_CPA_Max->GetValue().ToDouble(&g_CPAMax_NM);
7761 g_bCPAWarn = m_pCheck_CPA_Warn->GetValue();
7762 m_pText_CPA_Warn->GetValue().ToDouble(&g_CPAWarn_NM);
7763 g_bTCPA_Max = m_pCheck_CPA_WarnT->GetValue();
7764 m_pText_CPA_WarnT->GetValue().ToDouble(&g_TCPA_Max);
7765
7766 // Lost Targets
7767 g_bMarkLost = m_pCheck_Mark_Lost->GetValue();
7768 m_pText_Mark_Lost->GetValue().ToDouble(&g_MarkLost_Mins);
7769 g_bRemoveLost = m_pCheck_Remove_Lost->GetValue();
7770 m_pText_Remove_Lost->GetValue().ToDouble(&g_RemoveLost_Mins);
7771
7772 // Display
7773 g_bShowCOG = m_pCheck_Show_COG->GetValue();
7774 m_pText_COG_Predictor->GetValue().ToDouble(&g_ShowCOG_Mins);
7775
7776 g_bAISShowTracks = m_pCheck_Show_Tracks->GetValue();
7777 m_pText_Track_Length->GetValue().ToDouble(&g_AISShowTracks_Mins);
7778
7779 // Update all the current targets
7780 if (g_pAIS) {
7781 AIS_Target_Hash::iterator it;
7782 AIS_Target_Hash* current_targets = g_pAIS->GetTargetList();
7783 for (it = current_targets->begin(); it != current_targets->end(); ++it) {
7784 AIS_Target_Data* pAISTarget = it->second;
7785 if (NULL != pAISTarget) pAISTarget->b_show_track = g_bAISShowTracks;
7786 }
7787 }
7788
7789 g_bHideMoored = m_pCheck_Hide_Moored->GetValue();
7790 m_pText_Moored_Speed->GetValue().ToDouble(&g_ShowMoored_Kts);
7791
7792 g_bDrawAISRealtime = m_pCheck_Draw_Realtime_Prediction->GetValue();
7793 m_pText_RealtPred_Speed->GetValue().ToDouble(&g_AIS_RealtPred_Kts);
7794
7795 g_bAllowShowScaled = m_pCheck_Scale_Priority->GetValue();
7796 long l;
7797 m_pText_Scale_Priority->GetValue().ToLong(&l);
7798 g_ShowScaled_Num = (int)l;
7799
7800 g_bShowAreaNotices = m_pCheck_Show_Area_Notices->GetValue();
7801 g_bDrawAISSize = m_pCheck_Draw_Target_Size->GetValue();
7802 g_bShowAISName = m_pCheck_Show_Target_Name->GetValue();
7803 long ais_name_scale = 5000;
7804 m_pText_Show_Target_Name_Scale->GetValue().ToLong(&ais_name_scale);
7805 g_Show_Target_Name_Scale = (int)wxMax(5000, ais_name_scale);
7806
7807 g_bWplIsAprsPosition = m_pCheck_Wpl_Aprs->GetValue();
7808
7809 // Alert
7810 g_bAIS_CPA_Alert = m_pCheck_AlertDialog->GetValue();
7811 g_bAIS_CPA_Alert_Audio = m_pCheck_AlertAudio->GetValue();
7812 g_bAIS_CPA_Alert_Suppress_Moored = m_pCheck_Alert_Moored->GetValue();
7813
7814 g_bAIS_ACK_Timeout = m_pCheck_Ack_Timout->GetValue();
7815 m_pText_ACK_Timeout->GetValue().ToDouble(&g_AckTimeout_Mins);
7816
7817 // Rollover
7818 g_bAISRolloverShowClass = m_pCheck_Rollover_Class->GetValue();
7819 g_bAISRolloverShowCOG = m_pCheck_Rollover_COG->GetValue();
7820 g_bAISRolloverShowCPA = m_pCheck_Rollover_CPA->GetValue();
7821
7822 g_chart_zoom_modifier = m_pSlider_Zoom->GetValue();
7823 g_chart_zoom_modifier_vector = m_pSlider_Zoom_Vector->GetValue();
7824 g_cm93_zoom_factor = m_pSlider_CM93_Zoom->GetValue();
7825 g_GUIScaleFactor = m_pSlider_GUI_Factor->GetValue();
7826 g_ChartScaleFactor = m_pSlider_Chart_Factor->GetValue();
7827 g_ChartScaleFactorExp = g_Platform->getChartScaleFactorExp(g_ChartScaleFactor);
7828 g_ShipScaleFactor = m_pSlider_Ship_Factor->GetValue();
7829 g_ShipScaleFactorExp = g_Platform->getChartScaleFactorExp(g_ShipScaleFactor);
7830 g_ENCSoundingScaleFactor = m_pSlider_Text_Factor->GetValue();
7831
7832
7833 // Only reload the icons if user has actually visted the UI page
7834 //if(m_bVisitLang)
7835 // pWayPointMan->ReloadAllIcons();
7836
7837 g_NMEAAPBPrecision = m_choicePrecision->GetCurrentSelection();
7838
7839 g_TalkerIdText = m_TalkerIdText->GetValue().MakeUpper();
7840
7841 if (g_bopengl != pOpenGL->GetValue()) m_returnChanges |= GL_CHANGED;
7842 g_bopengl = pOpenGL->GetValue();
7843
7844 // Handle Vector Charts Tab
7845 int depthUnit = pDepthUnitSelect->GetSelection();
7846 g_nDepthUnitDisplay = depthUnit;
7847
7848 // Process the UserStandard display list, noting if any changes were made
7849 bool bUserStdChange = false;
7850
7851 int nOBJL = ps57CtlListBox->GetCount();
7852
7853 for (int iPtr = 0; iPtr < nOBJL; iPtr++) {
7854 int itemIndex = -1;
7855 for (size_t i = 0; i < marinersStdXref.size(); i++) {
7856 if (marinersStdXref[i] == iPtr) {
7857 itemIndex = i;
7858 break;
7859 }
7860 }
7861 assert(itemIndex >= 0);
7862 OBJLElement* pOLE = (OBJLElement*)(ps52plib->pOBJLArray->Item(itemIndex));
7863 if(pOLE->nViz != ps57CtlListBox->IsChecked(iPtr))
7864 bUserStdChange = true;
7865 pOLE->nViz = ps57CtlListBox->IsChecked(iPtr);
7866 }
7867
7868 if (ps52plib) {
7869
7870 // Take a snapshot of the S52 config right now,
7871 // for later comparison
7872 ps52plib->GenerateStateHash();
7873 long stateHash = ps52plib->GetStateHash();
7874
7875
7876 if (m_returnChanges & GL_CHANGED) {
7877 // Do this now to handle the screen refresh that is automatically
7878 // generated on Windows at closure of the options dialog...
7879 ps52plib->FlushSymbolCaches();
7880 // some CNSY depends on renderer (e.g. CARC)
7881 ps52plib->ClearCNSYLUPArray();
7882 ps52plib->GenerateStateHash();
7883 }
7884
7885 if(pDispCat) {
7886 enum _DisCat nset = OTHER;
7887 switch (pDispCat->GetSelection()) {
7888 case 0:
7889 nset = DISPLAYBASE;
7890 break;
7891 case 1:
7892 nset = STANDARD;
7893 break;
7894 case 2:
7895 nset = OTHER;
7896 break;
7897 case 3:
7898 nset = MARINERS_STANDARD;
7899 break;
7900 }
7901 ps52plib->SetDisplayCategory(nset);
7902 }
7903
7904 if(pCheck_SOUNDG) ps52plib->m_bShowSoundg = pCheck_SOUNDG->GetValue();
7905 if(pCheck_ATONTEXT) ps52plib->m_bShowAtonText = pCheck_ATONTEXT->GetValue();
7906 if(pCheck_LDISTEXT) ps52plib->m_bShowLdisText = pCheck_LDISTEXT->GetValue();
7907 if(pCheck_XLSECTTEXT) ps52plib->m_bExtendLightSectors = pCheck_XLSECTTEXT->GetValue();
7908
7909 ps52plib->m_bShowMeta = pCheck_META->GetValue();
7910 ps52plib->m_bDeClutterText = pCheck_DECLTEXT->GetValue();
7911 ps52plib->m_bShowNationalTexts = pCheck_NATIONALTEXT->GetValue();
7912 ps52plib->m_bShowS57ImportantTextOnly = pCheck_SHOWIMPTEXT->GetValue();
7913 ps52plib->m_bUseSCAMIN = pCheck_SCAMIN->GetValue();
7914
7915 ps52plib->m_nSymbolStyle = pPointStyle->GetSelection() == 0 ? PAPER_CHART : SIMPLIFIED;
7916
7917 ps52plib->m_nBoundaryStyle = pBoundStyle->GetSelection() == 0
7918 ? PLAIN_BOUNDARIES
7919 : SYMBOLIZED_BOUNDARIES;
7920 ps52plib->m_nSoundingFactor = m_pSlider_Text_Factor->GetValue();
7921
7922 S52_setMarinerParam(S52_MAR_TWO_SHADES, (p24Color->GetSelection() == 0) ? 1.0 : 0.0);
7923
7924 // Depths
7925 double dval;
7926 float conv = 1;
7927
7928 if (depthUnit == 0) // feet
7929 conv = 0.3048f; // international definiton of 1 foot is 0.3048 metres
7930 else if (depthUnit == 2) // fathoms
7931 conv = 0.3048f * 6; // 1 fathom is 6 feet
7932
7933 if (m_SafetyCtl->GetValue().ToDouble(&dval)) {
7934 S52_setMarinerParam(S52_MAR_SAFETY_DEPTH, dval * conv); // controls sounding display
7935 S52_setMarinerParam(S52_MAR_SAFETY_CONTOUR, dval * conv); // controls colour
7936 }
7937
7938 if (m_ShallowCtl->GetValue().ToDouble(&dval))
7939 S52_setMarinerParam(S52_MAR_SHALLOW_CONTOUR, dval * conv);
7940
7941 if (m_DeepCtl->GetValue().ToDouble(&dval))
7942 S52_setMarinerParam(S52_MAR_DEEP_CONTOUR, dval * conv);
7943
7944 ps52plib->UpdateMarinerParams();
7945 ps52plib->m_nDepthUnitDisplay = depthUnit;
7946
7947 ps52plib->GenerateStateHash();
7948
7949 // Detect a change to S52 library config
7950 if( (stateHash != ps52plib->GetStateHash()) || bUserStdChange )
7951 m_returnChanges |= S52_CHANGED;
7952
7953 }
7954
7955 // User Interface Panel
7956 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
7957 if (m_bVisitLang) {
7958 wxString new_canon = _T("en_US");
7959 wxString lang_sel = m_itemLangListBox->GetStringSelection();
7960
7961 int nLang = sizeof(lang_list) / sizeof(int);
7962 for (int it = 0; it < nLang; it++) {
7963 const wxLanguageInfo* pli = wxLocale::GetLanguageInfo(lang_list[it]);
7964 if (pli) {
7965 wxString lang_canonical = pli->CanonicalName;
7966 wxString test_string = GetOCPNKnownLanguage(lang_canonical);
7967 if (lang_sel == test_string) {
7968 new_canon = lang_canonical;
7969 break;
7970 }
7971 }
7972 }
7973
7974 wxString locale_old = g_locale;
7975 g_locale = new_canon;
7976
7977 if (g_locale != locale_old) m_returnChanges |= LOCALE_CHANGED;
7978
7979 wxString oldStyle = g_StyleManager->GetCurrentStyle()->name;
7980 //g_StyleManager->SetStyleNextInvocation( m_itemStyleListBox->GetStringSelection());
7981 if (g_StyleManager->GetStyleNextInvocation() != oldStyle) {
7982 m_returnChanges |= STYLE_CHANGED;
7983 }
7984 wxSizeEvent nullEvent;
7985 gFrame->OnSize(nullEvent);
7986 }
7987 #endif
7988 if ( g_bInlandEcdis != pInlandEcdis->GetValue() ){ // InlandEcdis changed
7989 g_bInlandEcdis = pInlandEcdis->GetValue();
7990 SwitchInlandEcdisMode( g_bInlandEcdis );
7991 m_returnChanges |= TOOLBAR_CHANGED;
7992 }
7993 #ifdef __WXOSX__
7994 if ( g_bDarkDecorations != pDarkDecorations->GetValue() ) {
7995 g_bDarkDecorations = pDarkDecorations->GetValue();
7996
7997 OCPNMessageBox(this,
7998 _("The changes to the window decorations will take full effect the next time you start OpenCPN."),
7999 _("OpenCPN"));
8000 }
8001 #endif
8002 // PlugIn Manager Panel
8003
8004 // Pick up any changes to selections
8005 if (g_pi_manager->UpdatePlugIns())
8006 m_returnChanges |= TOOLBAR_CHANGED;
8007
8008 // And keep config in sync
8009 if (m_pPlugInCtrl) m_pPlugInCtrl->UpdatePluginsOrder();
8010 g_pi_manager->UpdateConfig();
8011
8012 // PlugIns may have added panels
8013 if (g_pi_manager) g_pi_manager->CloseAllPlugInPanels((int)wxOK);
8014
8015 m_returnChanges |= GENERIC_CHANGED | k_vectorcharts | k_charts |
8016 m_groups_changed | k_plugins | k_tides;
8017
8018 // Pick up all the entries in the Tide/current DataSelected control
8019 // and update the global static array
8020 TideCurrentDataSet.Clear();
8021 int nEntry = tcDataSelected->GetItemCount();
8022 for (int i = 0; i < nEntry; i++) {
8023 wxString setName = tcDataSelected->GetItemText(i);
8024 TideCurrentDataSet.Add(setName);
8025 }
8026
8027 if (event.GetId() != ID_APPLY) // only on ID_OK
8028 g_canvasConfig = m_screenConfig;
8029
8030 if (event.GetId() == ID_APPLY) {
8031 gFrame->ProcessOptionsDialog(m_returnChanges, m_pWorkDirList);
8032 m_CurrentDirList = *m_pWorkDirList; // Perform a deep copy back to main database.
8033
8034 // We can clear a few flag bits on "Apply", so they won't be recognised at the "OK" click.
8035 // Their actions have already been accomplished once...
8036 m_returnChanges &= ~( CHANGE_CHARTS | FORCE_UPDATE | SCAN_UPDATE );
8037 k_charts = 0;
8038
8039 gFrame->RefreshAllCanvas();
8040 }
8041
8042 // Some layout changes requiring a new options instance?
8043 if(m_bneedNew)
8044 m_returnChanges |= NEED_NEW_OPTIONS;
8045
8046 // Record notice of any changes to last applied template
8047 UpdateTemplateTitleText();
8048
8049 if (::wxIsBusy()) //FIXME: Not sure why this is needed here
8050 ::wxEndBusyCursor();
8051 }
8052
OnXidOkClick(wxCommandEvent & event)8053 void options::OnXidOkClick(wxCommandEvent& event) {
8054 // When closing the form with Ctrl-Enter sometimes we get double events, the
8055 // second is empty??
8056 if (event.GetEventObject() == NULL) return;
8057
8058 OnApplyClick(event);
8059 if (event.GetInt() == wxID_STOP) return;
8060
8061 Finish();
8062 }
8063
Finish(void)8064 void options::Finish(void) {
8065 // Required to avoid intermittent crash on wxGTK
8066 m_pListbook->ChangeSelection(0);
8067 for (size_t i = 0; i < m_pListbook->GetPageCount(); i++) {
8068 wxNotebookPage* pg = m_pListbook->GetPage(i);
8069 wxNotebook* nb = dynamic_cast<wxNotebook*>(pg);
8070 if (nb) nb->ChangeSelection(0);
8071 }
8072
8073 lastWindowPos = GetPosition();
8074 lastWindowSize = GetSize();
8075 SetReturnCode(m_returnChanges);
8076 EndModal(m_returnChanges);
8077 }
8078
OnButtondeleteClick(wxCommandEvent & event)8079 void options::OnButtondeleteClick(wxCommandEvent& event)
8080 {
8081 long item = -1;
8082 for ( ;; )
8083 {
8084 item = pActiveChartsList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
8085 if ( item == -1 )
8086 break;
8087 pActiveChartsList->DeleteItem( item );
8088
8089 // On Android, there is some trouble with wxLIST_STATE_SELECTED.
8090 // So, only allow deletion of one item per click.
8091 #ifdef __OCPN__ANDROID__
8092 break;
8093 #endif
8094
8095 item = -1; // Restart
8096 }
8097
8098 UpdateWorkArrayFromTextCtl();
8099
8100 if (m_pWorkDirList) {
8101 pActiveChartsList->DeleteAllItems();
8102 for (size_t id = 0; id < m_pWorkDirList->GetCount(); id++) {
8103 wxString dirname = m_pWorkDirList->Item(id).fullpath;
8104 wxListItem li;
8105 li.SetId( id );
8106 li.SetAlign(wxLIST_FORMAT_LEFT);
8107 li.SetText(dirname);
8108 li.SetColumn(0);
8109 long idx = pActiveChartsList->InsertItem( li );
8110 }
8111 }
8112
8113 k_charts |= CHANGE_CHARTS;
8114
8115 pScanCheckBox->Disable();
8116
8117 event.Skip();
8118
8119 }
8120
OnButtonParseENC(wxCommandEvent & event)8121 void options::OnButtonParseENC(wxCommandEvent &event)
8122 {
8123 gFrame->GetPrimaryCanvas()->EnablePaint(false);
8124
8125 extern void ParseAllENC(wxWindow* parent);
8126
8127 ParseAllENC(g_pOptions);
8128
8129 ViewPort vp;
8130 gFrame->ChartsRefresh();
8131
8132 gFrame->GetPrimaryCanvas()->EnablePaint(true);
8133
8134 }
8135
8136 #ifdef OCPN_USE_LZMA
8137 #include <lzma.h>
8138
8139 static bool
compress(lzma_stream * strm,FILE * infile,FILE * outfile)8140 compress(lzma_stream *strm, FILE *infile, FILE *outfile)
8141 {
8142 // This will be LZMA_RUN until the end of the input file is reached.
8143 // This tells lzma_code() when there will be no more input.
8144 lzma_action action = LZMA_RUN;
8145
8146 // Buffers to temporarily hold uncompressed input
8147 // and compressed output.
8148 uint8_t inbuf[BUFSIZ];
8149 uint8_t outbuf[BUFSIZ];
8150
8151 // Initialize the input and output pointers. Initializing next_in
8152 // and avail_in isn't really necessary when we are going to encode
8153 // just one file since LZMA_STREAM_INIT takes care of initializing
8154 // those already. But it doesn't hurt much and it will be needed
8155 // if encoding more than one file like we will in 02_decompress.c.
8156 //
8157 // While we don't care about strm->total_in or strm->total_out in this
8158 // example, it is worth noting that initializing the encoder will
8159 // always reset total_in and total_out to zero. But the encoder
8160 // initialization doesn't touch next_in, avail_in, next_out, or
8161 // avail_out.
8162 strm->next_in = NULL;
8163 strm->avail_in = 0;
8164 strm->next_out = outbuf;
8165 strm->avail_out = sizeof(outbuf);
8166
8167 // Loop until the file has been successfully compressed or until
8168 // an error occurs.
8169 while (true) {
8170 // Fill the input buffer if it is empty.
8171 if (strm->avail_in == 0 && !feof(infile)) {
8172 strm->next_in = inbuf;
8173 strm->avail_in = fread(inbuf, 1, sizeof(inbuf),
8174 infile);
8175
8176 if (ferror(infile)) {
8177 fprintf(stderr, "Read error: %s\n",
8178 strerror(errno));
8179 return false;
8180 }
8181
8182 // Once the end of the input file has been reached,
8183 // we need to tell lzma_code() that no more input
8184 // will be coming and that it should finish the
8185 // encoding.
8186 if (feof(infile))
8187 action = LZMA_FINISH;
8188 }
8189
8190 // Tell liblzma do the actual encoding.
8191 //
8192 // This reads up to strm->avail_in bytes of input starting
8193 // from strm->next_in. avail_in will be decremented and
8194 // next_in incremented by an equal amount to match the
8195 // number of input bytes consumed.
8196 //
8197 // Up to strm->avail_out bytes of compressed output will be
8198 // written starting from strm->next_out. avail_out and next_out
8199 // will be incremented by an equal amount to match the number
8200 // of output bytes written.
8201 //
8202 // The encoder has to do internal buffering, which means that
8203 // it may take quite a bit of input before the same data is
8204 // available in compressed form in the output buffer.
8205 lzma_ret ret = lzma_code(strm, action);
8206
8207 // If the output buffer is full or if the compression finished
8208 // successfully, write the data from the output bufffer to
8209 // the output file.
8210 if (strm->avail_out == 0 || ret == LZMA_STREAM_END) {
8211 // When lzma_code() has returned LZMA_STREAM_END,
8212 // the output buffer is likely to be only partially
8213 // full. Calculate how much new data there is to
8214 // be written to the output file.
8215 size_t write_size = sizeof(outbuf) - strm->avail_out;
8216
8217 if (fwrite(outbuf, 1, write_size, outfile)
8218 != write_size) {
8219 fprintf(stderr, "Write error: %s\n",
8220 strerror(errno));
8221 return false;
8222 }
8223
8224 // Reset next_out and avail_out.
8225 strm->next_out = outbuf;
8226 strm->avail_out = sizeof(outbuf);
8227 }
8228
8229 // Normally the return value of lzma_code() will be LZMA_OK
8230 // until everything has been encoded.
8231 if (ret != LZMA_OK) {
8232 // Once everything has been encoded successfully, the
8233 // return value of lzma_code() will be LZMA_STREAM_END.
8234 //
8235 // It is important to check for LZMA_STREAM_END. Do not
8236 // assume that getting ret != LZMA_OK would mean that
8237 // everything has gone well.
8238 if (ret == LZMA_STREAM_END)
8239 return true;
8240
8241 // It's not LZMA_OK nor LZMA_STREAM_END,
8242 // so it must be an error code. See lzma/base.h
8243 // (src/liblzma/api/lzma/base.h in the source package
8244 // or e.g. /usr/include/lzma/base.h depending on the
8245 // install prefix) for the list and documentation of
8246 // possible values. Most values listen in lzma_ret
8247 // enumeration aren't possible in this example.
8248 const char *msg;
8249 switch (ret) {
8250 case LZMA_MEM_ERROR:
8251 msg = "Memory allocation failed";
8252 break;
8253
8254 case LZMA_DATA_ERROR:
8255 // This error is returned if the compressed
8256 // or uncompressed size get near 8 EiB
8257 // (2^63 bytes) because that's where the .xz
8258 // file format size limits currently are.
8259 // That is, the possibility of this error
8260 // is mostly theoretical unless you are doing
8261 // something very unusual.
8262 //
8263 // Note that strm->total_in and strm->total_out
8264 // have nothing to do with this error. Changing
8265 // those variables won't increase or decrease
8266 // the chance of getting this error.
8267 msg = "File size limits exceeded";
8268 break;
8269
8270 default:
8271 // This is most likely LZMA_PROG_ERROR, but
8272 // if this program is buggy (or liblzma has
8273 // a bug), it may be e.g. LZMA_BUF_ERROR or
8274 // LZMA_OPTIONS_ERROR too.
8275 //
8276 // It is inconvenient to have a separate
8277 // error message for errors that should be
8278 // impossible to occur, but knowing the error
8279 // code is important for debugging. That's why
8280 // it is good to print the error code at least
8281 // when there is no good error message to show.
8282 msg = "Unknown error, possibly a bug";
8283 break;
8284 }
8285
8286 wxLogMessage(_T("LZMA Encoder error: %s (error code %u)\n"),
8287 msg, ret);
8288 return false;
8289 }
8290 }
8291 }
8292 #endif
8293
CompressChart(wxString in,wxString out)8294 static bool CompressChart(wxString in, wxString out)
8295 {
8296 #ifdef OCPN_USE_LZMA
8297 FILE *infile = fopen(in.mb_str(), "rb");
8298 if(!infile)
8299 return false;
8300
8301 FILE *outfile = fopen(out.mb_str(), "wb");
8302 if(!outfile) {
8303 fclose(infile);
8304 return false;
8305 }
8306
8307 lzma_stream strm = LZMA_STREAM_INIT;
8308 bool success = false;
8309 if(lzma_easy_encoder(&strm, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64) == LZMA_OK)
8310 success = compress(&strm, infile, outfile);
8311
8312 lzma_end(&strm);
8313 fclose(infile);
8314 fclose(outfile);
8315
8316 return success;
8317 #endif
8318 return false;
8319 }
8320
OnButtoncompressClick(wxCommandEvent & event)8321 void options::OnButtoncompressClick(wxCommandEvent& event)
8322 {
8323 wxArrayInt pListBoxSelections;
8324 long item = -1;
8325 for ( ;; )
8326 {
8327 item = pActiveChartsList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
8328 if ( item == -1 )
8329 break;
8330 pListBoxSelections.Add((int)item);
8331 item = -1; // Restart
8332 }
8333
8334
8335 if(OCPNMessageBox( this, _("Compression will alter chart files on disk.\n\
8336 This may make them incompatible with other programs or older versions of OpenCPN.\n\
8337 Compressed charts may take slightly longer to load and display on some systems.\n\
8338 They can be decompressed again using unxz or 7 zip programs."),
8339 _("OpenCPN Warning"),
8340 wxYES | wxCANCEL | wxCANCEL_DEFAULT | wxICON_WARNING) != wxID_YES)
8341 return;
8342
8343 wxArrayString filespecs;
8344 filespecs.Add("*.kap");
8345 filespecs.Add("*.KAP");
8346 filespecs.Add("*.000");
8347
8348 // should we verify we are in a cm93 directory for these?
8349 filespecs.Add("*.A"), filespecs.Add("*.B"), filespecs.Add("*.C"), filespecs.Add("*.D");
8350 filespecs.Add("*.E"), filespecs.Add("*.F"), filespecs.Add("*.G"), filespecs.Add("*.Z");
8351
8352 wxGenericProgressDialog prog1(_("OpenCPN Compress Charts"), wxEmptyString,
8353 filespecs.GetCount()*pListBoxSelections.GetCount()+1, this,
8354 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8355 wxPD_REMAINING_TIME | wxPD_CAN_SKIP);
8356
8357 // Make sure the dialog is big enough to be readable
8358 wxSize sz = prog1.GetSize();
8359 sz.x = gFrame->GetClientSize().x * 8 / 10;
8360 prog1.SetSize( sz );
8361
8362 wxArrayString charts;
8363 for(unsigned int i=0; i<pListBoxSelections.GetCount(); i++) {
8364 wxString dirname = pActiveChartsList->GetItemText( pListBoxSelections[i] );
8365 if (dirname.IsEmpty())
8366 continue;
8367 // This is a fix for OSX, which appends EOL to results of
8368 // GetLineText()
8369 while ((dirname.Last() == wxChar(_T('\n'))) ||
8370 (dirname.Last() == wxChar(_T('\r'))))
8371 dirname.RemoveLast();
8372
8373 if(!wxDir::Exists(dirname))
8374 continue;
8375
8376 wxDir dir(dirname);
8377 wxArrayString FileList;
8378 for(unsigned int j = 0; j<filespecs.GetCount(); j++) {
8379 dir.GetAllFiles(dirname, &FileList, filespecs[j]);
8380 bool skip = false;
8381 prog1.Update(i*filespecs.GetCount()+j, dirname+filespecs[j], &skip);
8382 if(skip)
8383 return;
8384 }
8385
8386
8387 for(unsigned int j=0; j<FileList.GetCount(); j++)
8388 charts.Add(FileList[j]);
8389 }
8390 prog1.Hide();
8391
8392 if(charts.GetCount() == 0) {
8393 OCPNMessageBox(
8394 this,
8395 _("No charts found to compress."),
8396 _("OpenCPN Info"));
8397 return;
8398 }
8399
8400
8401 // TODO: make this use threads
8402 unsigned long total_size = 0, total_compressed_size = 0, count = 0;
8403 wxGenericProgressDialog prog(_("OpenCPN Compress Charts"), wxEmptyString, charts.GetCount()+1, this,
8404 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8405 wxPD_REMAINING_TIME | wxPD_CAN_SKIP);
8406
8407 prog.SetSize( sz );
8408
8409 for(unsigned int i=0; i<charts.GetCount(); i++) {
8410 bool skip = false;
8411 prog.Update(i, charts[i], &skip);
8412 if(skip)
8413 break;
8414
8415 wxString compchart = charts[i] + _T(".xz");
8416 if(CompressChart(charts[i], compchart)) {
8417 total_size += wxFileName::GetSize(charts[i]).ToULong();
8418 total_compressed_size += wxFileName::GetSize(compchart).ToULong();
8419 wxRemoveFile(charts[i]);
8420 count++;
8421 }
8422 }
8423
8424 // report statistics
8425 double total_size_mb = total_size/1024.0/1024.0;
8426 double total_compressed_size_mb = total_compressed_size/1024.0/1024.0;
8427 OCPNMessageBox(
8428 this,
8429 wxString::Format(_("compressed %ld charts\nfrom %.1fMB to %.1fMB\nsaved %.1fMB (%.1f%%)"),
8430 count, total_size_mb, total_compressed_size_mb,
8431 total_size_mb - total_compressed_size_mb,
8432 (1 - total_compressed_size_mb / total_size_mb) * 100.0),
8433 _("OpenCPN Info"));
8434
8435 UpdateWorkArrayFromTextCtl();
8436
8437 if (m_pWorkDirList) {
8438 pActiveChartsList->DeleteAllItems();
8439 for (size_t id = 0; id < m_pWorkDirList->GetCount(); id++) {
8440 wxString dirname = m_pWorkDirList->Item(id).fullpath;
8441 wxListItem li;
8442 li.SetId( id );
8443 li.SetAlign(wxLIST_FORMAT_LEFT);
8444 li.SetText(dirname);
8445 li.SetColumn(0);
8446 long idx = pActiveChartsList->InsertItem( li );
8447 }
8448 }
8449
8450
8451 k_charts |= CHANGE_CHARTS;
8452
8453 pScanCheckBox->Disable();
8454
8455 event.Skip();
8456
8457 }
8458
OnDebugcheckbox1Click(wxCommandEvent & event)8459 void options::OnDebugcheckbox1Click(wxCommandEvent& event) { event.Skip(); }
8460
OnCancelClick(wxCommandEvent & event)8461 void options::OnCancelClick(wxCommandEvent& event) {
8462
8463 m_pListbook->ChangeSelection(0);
8464
8465 lastWindowPos = GetPosition();
8466 lastWindowSize = GetSize();
8467
8468 if (g_pi_manager) g_pi_manager->CloseAllPlugInPanels((int)wxCANCEL);
8469
8470 EndModal(0);
8471 }
8472
OnClose(wxCloseEvent & event)8473 void options::OnClose(wxCloseEvent& event) {
8474 // PlugIns may have added panels
8475 if (g_pi_manager) g_pi_manager->CloseAllPlugInPanels((int)wxOK);
8476
8477 m_pListbook->ChangeSelection(0);
8478
8479 lastWindowPos = GetPosition();
8480 lastWindowSize = GetSize();
8481
8482 EndModal(0);
8483 }
8484
OnFontChoice(wxCommandEvent & event)8485 void options::OnFontChoice(wxCommandEvent& event) {
8486 wxString sel_text_element = m_itemFontElementListBox->GetStringSelection();
8487
8488 wxFont* pif = FontMgr::Get().GetFont(sel_text_element);
8489 wxColour init_color = FontMgr::Get().GetFontColor(sel_text_element);
8490
8491 m_textSample->SetFont(*pif);
8492 m_textSample->SetForegroundColour(init_color);
8493 m_itemBoxSizerFontPanel->Layout();
8494 event.Skip();
8495 }
8496
OnChooseFont(wxCommandEvent & event)8497 void options::OnChooseFont(wxCommandEvent& event) {
8498
8499 #ifdef __OCPN__ANDROID__
8500 androidDisableRotation();
8501 #endif
8502
8503 wxString sel_text_element = m_itemFontElementListBox->GetStringSelection();
8504 wxFontData font_data;
8505
8506 wxFont* pif = FontMgr::Get().GetFont(sel_text_element);
8507 wxColour init_color = FontMgr::Get().GetFontColor(sel_text_element);
8508
8509 wxFontData init_font_data;
8510 if (pif) init_font_data.SetInitialFont(*pif);
8511 init_font_data.SetColour(init_color);
8512
8513 #ifdef __WXGTK__
8514 wxFontDialog dg(this, init_font_data);
8515 #else
8516 wxFontDialog dg(pParent, init_font_data);
8517 #endif
8518
8519 wxFont* qFont = dialogFont;
8520 dg.SetFont(*qFont);
8521
8522 #ifdef __WXQT__
8523 // Make sure that font dialog will fit on the screen without scrolling
8524 // We do this by setting the dialog font size "small enough" to show "n" lines
8525 wxSize proposed_size = GetSize();
8526 float n_lines = 30;
8527 float font_size = dialogFont->GetPointSize();
8528
8529 if ((proposed_size.y / font_size) < n_lines) {
8530 float new_font_size = proposed_size.y / n_lines;
8531 wxFont* smallFont = new wxFont(*dialogFont);
8532 smallFont->SetPointSize(new_font_size);
8533 dg.SetFont(*smallFont);
8534 }
8535 #endif
8536
8537 if (g_bresponsive) {
8538 dg.SetSize(GetSize());
8539 dg.Centre();
8540 }
8541
8542 int retval = dg.ShowModal();
8543 if (wxID_CANCEL != retval) {
8544 font_data = dg.GetFontData();
8545 wxFont font = font_data.GetChosenFont();
8546 wxFont* psfont = new wxFont(font);
8547 wxColor color = font_data.GetColour();
8548 FontMgr::Get().SetFont(sel_text_element, psfont, color);
8549 pParent->UpdateAllFonts();
8550 m_bfontChanged = true;
8551 OnFontChoice(event);
8552 }
8553
8554 #ifdef __OCPN__ANDROID__
8555 androidEnableRotation();
8556 #endif
8557
8558 event.Skip();
8559 }
8560
8561 #if defined(__WXGTK__) || defined(__WXQT__)
OnChooseFontColor(wxCommandEvent & event)8562 void options::OnChooseFontColor(wxCommandEvent& event) {
8563 wxString sel_text_element = m_itemFontElementListBox->GetStringSelection();
8564
8565 wxColourData colour_data;
8566
8567 wxFont* pif = FontMgr::Get().GetFont(sel_text_element);
8568 wxColour init_color = FontMgr::Get().GetFontColor(sel_text_element);
8569
8570 #ifdef __OCPN__ANDROID__
8571 androidDisableRotation();
8572
8573 unsigned int cco = 0;
8574 cco |= 0xff; cco = cco << 8;
8575 cco |= init_color.Red(); cco = cco << 8;
8576 cco |= init_color.Green(); cco = cco << 8;
8577 cco |= init_color.Blue();
8578 unsigned int cc = androidColorPicker( cco);
8579
8580 wxColor cn;
8581 unsigned char blue = (unsigned char) cc % 256;
8582 unsigned char green = (unsigned char) (cc >> 8) % 256;;
8583 unsigned char red = (unsigned char) (cc >> 16) % 256;
8584 cn.Set(red, green, blue);
8585
8586 FontMgr::Get().SetFont(sel_text_element, pif, cn);
8587
8588 pParent->UpdateAllFonts();
8589 m_bfontChanged = true;
8590
8591 androidEnableRotation();
8592 #else
8593 wxScrolledWindow *sw = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(400, 400));
8594
8595 wxColourData init_colour_data;
8596 init_colour_data.SetColour(init_color);
8597
8598 wxColourDialog dg(sw, &init_colour_data);
8599
8600 int retval = dg.ShowModal();
8601 if (wxID_CANCEL != retval) {
8602 colour_data = dg.GetColourData();
8603
8604 wxColor color = colour_data.GetColour();
8605 FontMgr::Get().SetFont(sel_text_element, pif, color);
8606
8607 pParent->UpdateAllFonts();
8608 m_bfontChanged = true;
8609 OnFontChoice(event);
8610 }
8611
8612 sw->Destroy();
8613 #endif
8614 event.Skip();
8615 }
8616 #endif
8617
OnChartsPageChange(wxListbookEvent & event)8618 void options::OnChartsPageChange(wxListbookEvent& event) {
8619 unsigned int i = event.GetSelection();
8620
8621 // User selected Chart Groups Page?
8622 // If so, build the remaining UI elements
8623 if (2 == i) { // 2 is the index of "Chart Groups" page
8624 if (!groupsPanel->m_UIcomplete) groupsPanel->CompletePanel();
8625
8626 if (!groupsPanel->m_settingscomplete) {
8627 ::wxBeginBusyCursor();
8628 groupsPanel->CompleteInitialSettings();
8629 ::wxEndBusyCursor();
8630 } else if (!groupsPanel->m_treespopulated) {
8631 groupsPanel->PopulateTrees();
8632 groupsPanel->m_treespopulated = TRUE;
8633 }
8634 }
8635 else if(1 == i){ // Vector charts panel
8636 LoadS57();
8637 if (!m_bVectorInit){
8638 SetInitialVectorSettings();
8639 UpdateOptionsUnits(); // sets depth values, overriding defaults
8640 }
8641 }
8642
8643 event.Skip(); // Allow continued event processing
8644 }
8645
OnPageChange(wxListbookEvent & event)8646 void options::OnPageChange(wxListbookEvent& event) {
8647 DoOnPageChange(event.GetSelection());
8648 }
8649
OnSubNBPageChange(wxNotebookEvent & event)8650 void options::OnSubNBPageChange(wxNotebookEvent& event) {
8651 // In the case where wxNotebooks are nested, we need to identify the subpage
8652 // But otherwise do nothing
8653 if(event.GetEventObject()){
8654 if(dynamic_cast<wxWindow*>(event.GetEventObject())){
8655 wxWindow *win = dynamic_cast<wxWindow*>(event.GetEventObject());
8656 wxWindow *parent = dynamic_cast<wxWindow*>(win->GetParent());
8657 if(dynamic_cast<wxNotebook*>(parent)){
8658 lastSubPage = event.GetSelection();
8659 return;
8660 }
8661 if(dynamic_cast<wxListbook*>(parent)){
8662 lastSubPage = event.GetSelection();
8663 return;
8664 }
8665
8666 }
8667 }
8668 }
8669
OnTopNBPageChange(wxNotebookEvent & event)8670 void options::OnTopNBPageChange(wxNotebookEvent& event) {
8671 DoOnPageChange(event.GetSelection());
8672 }
8673
DoOnPageChange(size_t page)8674 void options::DoOnPageChange(size_t page) {
8675
8676 unsigned int i = page;
8677
8678 // Sometimes there is a (-1) page selected.
8679 if(page > 10)
8680 return;
8681
8682 lastPage = i;
8683
8684 #ifndef __OCPN__ANDROID__
8685 if (0 == i) { // Display
8686 if(m_sconfigSelect_single)
8687 m_sconfigSelect_single->Refresh( true );
8688 if(m_sconfigSelect_twovertical)
8689 m_sconfigSelect_twovertical->Refresh( true );
8690 }
8691 #endif
8692
8693 // User selected Chart Page?
8694 // If so, build the "Charts" page variants
8695 if (1 == i) { // 2 is the index of "Charts" page
8696 k_charts = VISIT_CHARTS;
8697 }
8698
8699 else if (m_pageUI == i) { // 5 is the index of "User Interface" page
8700 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
8701
8702 if (!m_bVisitLang) {
8703 ::wxBeginBusyCursor();
8704
8705 int current_language = plocale_def_lang->GetLanguage();
8706 wxString current_sel = wxLocale::GetLanguageName(current_language);
8707
8708 current_sel = GetOCPNKnownLanguage(g_locale);
8709
8710 int nLang = sizeof(lang_list) / sizeof(int);
8711
8712 #ifdef __WXMSW__
8713 // always add us english
8714 m_itemLangListBox->Append(_T("English (U.S.)"));
8715
8716 wxString lang_dir = g_Platform->GetSharedDataDir() + _T("share/locale/");
8717 for (int it = 1; it < nLang; it++) {
8718 if (wxLocale::IsAvailable(lang_list[it])) {
8719 wxLocale ltest(lang_list[it], 0);
8720 ltest.AddCatalog(_T("opencpn"));
8721 if (!ltest.IsLoaded(_T("opencpn"))) continue;
8722
8723 // Defaults
8724 wxString loc_lang_name = wxLocale::GetLanguageName(lang_list[it]);
8725 wxString widgets_lang_name = loc_lang_name;
8726 wxString lang_canonical =
8727 wxLocale::GetLanguageInfo(lang_list[it])->CanonicalName;
8728
8729 // Make opencpn substitutions
8730 wxString lang_suffix;
8731 loc_lang_name = GetOCPNKnownLanguage(lang_canonical, lang_suffix);
8732
8733 // Look explicitely to see if .mo is available
8734 wxString test_dir = lang_dir + lang_suffix;
8735 if (!wxDir::Exists(test_dir)) continue;
8736
8737 m_itemLangListBox->Append(loc_lang_name);
8738 }
8739 }
8740 #else
8741 wxArrayString lang_array;
8742
8743 // always add us english
8744 lang_array.Add(_T("en_US"));
8745
8746 for (int it = 0; it < nLang; it++) {
8747 {
8748 wxLog::EnableLogging(
8749 FALSE); // avoid "Cannot set locale to..." log message
8750
8751 wxLocale ltest(lang_list[it], 0);
8752 #if wxCHECK_VERSION(2, 9, 0)
8753 #ifdef __WXGTK__
8754 ltest.AddCatalogLookupPathPrefix(wxStandardPaths::Get().GetInstallPrefix() + _T( "/share/locale" ) );
8755 #endif
8756 #endif
8757 ltest.AddCatalog(_T("opencpn"));
8758
8759 wxLog::EnableLogging(TRUE);
8760
8761 if (ltest.IsLoaded(_T("opencpn"))) {
8762 wxString s0 =
8763 wxLocale::GetLanguageInfo(lang_list[it])->CanonicalName;
8764 wxString sl = wxLocale::GetLanguageName(lang_list[it]);
8765 if (wxNOT_FOUND == lang_array.Index(s0)) lang_array.Add(s0);
8766 }
8767 }
8768 }
8769
8770 for (unsigned int i = 0; i < lang_array.GetCount(); i++) {
8771 // Make opencpn substitutions
8772 wxString loc_lang_name = GetOCPNKnownLanguage(lang_array[i]);
8773 m_itemLangListBox->Append(loc_lang_name);
8774 }
8775 #endif
8776
8777 // BUGBUG
8778 // Remember that wxLocale ctor has the effect of changing the system
8779 // locale, including the "C" libraries.
8780 // It should then also happen that the locale should be switched back to
8781 // ocpn initial load setting
8782 // upon the dtor of the above wxLocale instantiations....
8783 // wxWidgets may do so internally, but there seems to be no effect upon
8784 // the system libraries, so that
8785 // functions like strftime() do not revert to the correct locale setting.
8786 // Also, the catalog for the application is not reloaded by the ctor, so
8787 // we must reload them directly
8788 // So as workaround, we reset the locale explicitely.
8789
8790 delete plocale_def_lang;
8791 plocale_def_lang = new wxLocale(current_language);
8792
8793 setlocale(LC_NUMERIC, "C");
8794 plocale_def_lang->AddCatalog(_T("opencpn"));
8795
8796 m_itemLangListBox->SetStringSelection(current_sel);
8797
8798 // Initialize Language tab
8799 const wxLanguageInfo* pli = wxLocale::FindLanguageInfo(g_locale);
8800 if (pli) {
8801 wxString clang = pli->Description;
8802 // m_itemLangListBox->SetValue(clang);
8803 }
8804
8805 m_bVisitLang = TRUE;
8806
8807 ::wxEndBusyCursor();
8808 }
8809 #endif
8810 } else if (m_pagePlugins == i) { // 7 is the index of "Plugins" page
8811 // load the disabled plugins finally because the user might want to enable
8812 // them
8813 if (g_pi_manager->LoadAllPlugIns(FALSE)) {
8814 delete m_pPlugInCtrl;
8815 m_pPlugInCtrl = NULL;
8816 delete m_PluginCatalogMgrPanel;
8817 m_PluginCatalogMgrPanel = NULL;
8818 itemBoxSizerPanelPlugins->Clear();
8819 }
8820
8821 if (!m_pPlugInCtrl) {
8822 // Build the PlugIn Manager Panel
8823 ::wxBeginBusyCursor();
8824
8825 m_pPlugInCtrl =
8826 new PluginListPanel(itemPanelPlugins, ID_PANELPIM, wxDefaultPosition,
8827 wxDefaultSize, g_pi_manager->GetPlugInArray());
8828 m_pPlugInCtrl->SetScrollRate(m_scrollRate, m_scrollRate);
8829 itemBoxSizerPanelPlugins->Add(m_pPlugInCtrl, 01, wxEXPAND | wxGROW | wxALL, 4);
8830 if(g_pi_manager)
8831 g_pi_manager->SetListPanelPtr(m_pPlugInCtrl);
8832
8833 m_PluginCatalogMgrPanel = new CatalogMgrPanel(itemPanelPlugins);
8834 m_PluginCatalogMgrPanel->SetListPanelPtr(m_pPlugInCtrl);
8835
8836 itemBoxSizerPanelPlugins->Add(m_PluginCatalogMgrPanel, 0, wxEXPAND | wxALL, 4);
8837 itemBoxSizerPanelPlugins->Layout();
8838
8839 // Update the PlugIn page to reflect the state of individual selections
8840 m_pPlugInCtrl->UpdateSelections();
8841
8842 ::wxEndBusyCursor();
8843 }
8844
8845 k_plugins = TOOLBAR_CHANGED;
8846 }
8847 }
8848
8849 // void options::OnNMEASourceChoice( wxCommandEvent& event )
8850 //{
8851 /*TODO
8852 int i = event.GetSelection();
8853 wxString src( m_itemNMEAListBox->GetString( i ) );
8854 if( ( src.Upper().Find( _T("GPSD") ) != wxNOT_FOUND )
8855 || ( src.Upper().Find( _T("LIBGPS") ) != wxNOT_FOUND ) ) {
8856 m_itemNMEA_TCPIP_StaticBox->Enable();
8857 m_itemNMEA_TCPIP_Source->Enable();
8858
8859 m_itemNMEA_TCPIP_Source->Clear();
8860 m_itemNMEA_TCPIP_Source->WriteText( _T("localhost") ); // default
8861
8862 wxString source;
8863 source = *pNMEADataSource;
8864 if( source.Upper().StartsWith( _T("GPSD") ) ||
8865 source.Upper().StartsWith( _T("LIBGPS") ) ) {
8866 wxString ip;
8867 ip = source.AfterFirst( ':' );
8868
8869 if( ip.Len() ) {
8870 m_itemNMEA_TCPIP_Source->Clear();
8871 m_itemNMEA_TCPIP_Source->WriteText( ip );
8872 }
8873 }
8874 } else {
8875 m_itemNMEA_TCPIP_StaticBox->Disable();
8876 m_itemNMEA_TCPIP_Source->Disable();
8877 }
8878 */
8879 //}
8880
OnButtonSelectSound(wxCommandEvent & event)8881 void options::OnButtonSelectSound(wxCommandEvent& event) {
8882 wxString sound_dir = g_Platform->GetSharedDataDir();
8883 sound_dir.Append(_T("sounds"));
8884 wxString sel_file;
8885 int response;
8886
8887 #ifndef __OCPN__ANDROID__
8888 wxFileDialog* popenDialog = new wxFileDialog(
8889 NULL, _("Select Sound File"), sound_dir, wxEmptyString,
8890 _T("WAV files (*.wav)|*.wav|All files (*.*)|*.*"), wxFD_OPEN);
8891 if (g_bresponsive)
8892 popenDialog = g_Platform->AdjustFileDialogFont(this, popenDialog);
8893
8894 response = popenDialog->ShowModal();
8895 sel_file = popenDialog->GetPath();
8896 delete popenDialog;
8897
8898 #else
8899 response =
8900 g_Platform->DoFileSelectorDialog(this, &sel_file, _("Select Sound File"),
8901 sound_dir, wxEmptyString, wxT("*.*"));
8902 #endif
8903
8904 if (response == wxID_OK) {
8905 g_sAIS_Alert_Sound_File = g_Platform->NormalizePath(sel_file);
8906
8907 g_anchorwatch_sound->Stop();
8908 }
8909 }
8910
8911
OnButtonTestSound(wxCommandEvent & event)8912 void options::OnButtonTestSound(wxCommandEvent& event) {
8913 auto sound = SoundFactory();
8914 #ifndef __OCPN__ANDROID__
8915 if ((bool) dynamic_cast<SystemCmdSound*>(sound)) {
8916 sound->SetCmd(g_CmdSoundString.mb_str());
8917 }
8918 #endif
8919 sound->SetFinishedCallback([sound](void*) { delete sound; });
8920 sound->Load(g_sAIS_Alert_Sound_File, g_iSoundDeviceIndex);
8921 sound->Play();
8922 }
8923
8924
GetOCPNKnownLanguage(wxString lang_canonical,wxString & lang_dir)8925 wxString GetOCPNKnownLanguage(wxString lang_canonical, wxString& lang_dir) {
8926 wxString return_string;
8927 wxString dir_suffix;
8928
8929 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
8930
8931 if (lang_canonical == _T("en_US")) {
8932 dir_suffix = _T("en");
8933 return_string = wxString("English (U.S.)", wxConvUTF8);
8934 } else if (lang_canonical == _T("cs_CZ")) {
8935 dir_suffix = _T("cs");
8936 return_string = wxString("Čeština", wxConvUTF8);
8937 } else if (lang_canonical == _T("da_DK")) {
8938 dir_suffix = _T("da");
8939 return_string = wxString("Dansk", wxConvUTF8);
8940 } else if (lang_canonical == _T("de_DE")) {
8941 dir_suffix = _T("de");
8942 return_string = wxString("Deutsch", wxConvUTF8);
8943 } else if (lang_canonical == _T("et_EE")) {
8944 dir_suffix = _T("et");
8945 return_string = wxString("Eesti", wxConvUTF8);
8946 } else if (lang_canonical == _T("es_ES")) {
8947 dir_suffix = _T("es");
8948 return_string = wxString("Español", wxConvUTF8);
8949 } else if (lang_canonical == _T("fr_FR")) {
8950 dir_suffix = _T("fr");
8951 return_string = wxString("Français", wxConvUTF8);
8952 } else if (lang_canonical == _T("it_IT")) {
8953 dir_suffix = _T("it");
8954 return_string = wxString("Italiano", wxConvUTF8);
8955 } else if (lang_canonical == _T("nl_NL")) {
8956 dir_suffix = _T("nl");
8957 return_string = wxString("Nederlands", wxConvUTF8);
8958 } else if (lang_canonical == _T("pl_PL")) {
8959 dir_suffix = _T("pl");
8960 return_string = wxString("Polski", wxConvUTF8);
8961 } else if (lang_canonical == _T("pt_PT")) {
8962 dir_suffix = _T("pt_PT");
8963 return_string = wxString("Português", wxConvUTF8);
8964 } else if (lang_canonical == _T("pt_BR")) {
8965 dir_suffix = _T("pt_BR");
8966 return_string = wxString("Português Brasileiro", wxConvUTF8);
8967 } else if (lang_canonical == _T("ru_RU")) {
8968 dir_suffix = _T("ru");
8969 return_string = wxString("Русский", wxConvUTF8);
8970 } else if (lang_canonical == _T("sv_SE")) {
8971 dir_suffix = _T("sv");
8972 return_string = wxString("Svenska", wxConvUTF8);
8973 } else if (lang_canonical == _T("fi_FI")) {
8974 dir_suffix = _T("fi_FI");
8975 return_string = wxString("Suomi", wxConvUTF8);
8976 } else if (lang_canonical == _T("nb_NO")) {
8977 dir_suffix = _T("nb_NO");
8978 return_string = wxString("Norsk", wxConvUTF8);
8979 } else if (lang_canonical == _T("tr_TR")) {
8980 dir_suffix = _T("tr_TR");
8981 return_string = wxString("Türkçe", wxConvUTF8);
8982 } else if (lang_canonical == _T("el_GR")) {
8983 dir_suffix = _T("el_GR");
8984 return_string = wxString("Ελληνικά", wxConvUTF8);
8985 } else if (lang_canonical == _T("hu_HU")) {
8986 dir_suffix = _T("hu_HU");
8987 return_string = wxString("Magyar", wxConvUTF8);
8988 } else if (lang_canonical == _T("zh_TW")) {
8989 dir_suffix = _T("zh_TW");
8990 return_string = wxString("正體字", wxConvUTF8);
8991 } else if (lang_canonical == _T("zh_CN")) {
8992 dir_suffix = _T("zh_CN");
8993 return_string = wxString("Simplified Chinese", wxConvUTF8);
8994 } else if (lang_canonical == _T("ca_ES")) {
8995 dir_suffix = _T("ca_ES");
8996 return_string = wxString("Catalan", wxConvUTF8);
8997 } else if (lang_canonical == _T("gl_ES")) {
8998 dir_suffix = _T("gl_ES");
8999 return_string = wxString("Galician", wxConvUTF8);
9000 } else if (lang_canonical == _T("ja_JP")) {
9001 dir_suffix = _T("ja_JP");
9002 return_string = wxString("Japanese", wxConvUTF8);
9003 } else if (lang_canonical == _T("ar_SA")) {
9004 dir_suffix = _T("ar_SA");
9005 return_string = wxString("Arabic", wxConvUTF8);
9006 } else if (lang_canonical == _T("vi_VN")) {
9007 dir_suffix = _T("vi_VN");
9008 return_string = wxString("Vietnamese", wxConvUTF8);
9009 } else {
9010 dir_suffix = lang_canonical;
9011 const wxLanguageInfo* info = wxLocale::FindLanguageInfo(lang_canonical);
9012 if(info)
9013 return_string = info->Description;
9014 else
9015 return_string = lang_canonical;
9016 }
9017
9018 lang_dir = dir_suffix;
9019 #endif
9020 return return_string;
9021 }
9022
GetOCPNKnownLanguage(const wxString lang_canonical)9023 wxString GetOCPNKnownLanguage(const wxString lang_canonical) {
9024 wxString lang_dir;
9025 return GetOCPNKnownLanguage(lang_canonical, lang_dir);
9026 }
9027
CloneChartGroupArray(ChartGroupArray * s)9028 ChartGroupArray* ChartGroupsUI::CloneChartGroupArray(ChartGroupArray* s) {
9029 ChartGroupArray* d = new ChartGroupArray;
9030 for (unsigned int i = 0; i < s->GetCount(); i++) {
9031 ChartGroup* psg = s->Item(i);
9032 ChartGroup* pdg = new ChartGroup;
9033 pdg->m_group_name = psg->m_group_name;
9034 pdg->m_element_array.reserve(psg->m_element_array.size());
9035
9036 for(auto& elem : psg->m_element_array)
9037 pdg->m_element_array.emplace_back(new ChartGroupElement(*elem));
9038
9039 d->Add(pdg);
9040 }
9041 return d;
9042 }
9043
EmptyChartGroupArray(ChartGroupArray * s)9044 void ChartGroupsUI::EmptyChartGroupArray(ChartGroupArray* s) {
9045 if (!s) return;
9046
9047 // ChartGroups don't need anything special for delete, just calling the destructor is enough.
9048 WX_CLEAR_ARRAY(*s);
9049 }
9050
9051 // Chart Groups dialog implementation
BEGIN_EVENT_TABLE(ChartGroupsUI,wxEvtHandler)9052 BEGIN_EVENT_TABLE(ChartGroupsUI, wxEvtHandler)
9053 EVT_TREE_ITEM_EXPANDED(wxID_TREECTRL, ChartGroupsUI::OnNodeExpanded)
9054 EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, ChartGroupsUI::OnGroupPageChange) // This should work under Windows :-(
9055 END_EVENT_TABLE()
9056
9057 ChartGroupsUI::ChartGroupsUI(wxWindow* parent)
9058 {
9059 m_GroupSelectedPage = -1;
9060 m_pActiveChartsTree = 0;
9061 pParent = parent;
9062 lastSelectedCtl = NULL;
9063 allAvailableCtl = NULL;
9064 defaultAllCtl = NULL;
9065 iFont = NULL;
9066 m_pAddButton = NULL;
9067 m_pRemoveButton = NULL;
9068 m_pDeleteGroupButton = NULL;
9069 m_pNewGroupButton = NULL;
9070 m_pGroupArray = NULL;
9071 m_GroupNB = NULL;
9072 modified = false;
9073 m_UIcomplete = false;
9074 m_treespopulated = false;
9075 dialogFont = GetOCPNScaledFont(_("Dialog"));
9076 }
9077
~ChartGroupsUI(void)9078 ChartGroupsUI::~ChartGroupsUI(void) {
9079 m_DirCtrlArray.Clear();
9080 m_GroupNB->Disconnect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler(ChartGroupsUI::OnGroupPageChange), NULL, this);
9081
9082 delete iFont;
9083 }
9084
SetInitialSettings(void)9085 void ChartGroupsUI::SetInitialSettings(void) {
9086 m_settingscomplete = FALSE;
9087 m_treespopulated = FALSE;
9088 }
9089
PopulateTrees(void)9090 void ChartGroupsUI::PopulateTrees(void) {
9091 // Fill in the "Active chart" tree control
9092 // from the options dialog "Active Chart Directories" list
9093 wxArrayString dir_array;
9094 int nDir = m_db_dirs.GetCount();
9095 for (int i = 0; i < nDir; i++) {
9096 wxString dirname = m_db_dirs[i].fullpath;
9097 if (!dirname.IsEmpty()) dir_array.Add(dirname);
9098 }
9099
9100 PopulateTreeCtrl(allAvailableCtl->GetTreeCtrl(), dir_array, wxColour(0, 0, 0),
9101 dialogFont);
9102 m_pActiveChartsTree = allAvailableCtl->GetTreeCtrl();
9103
9104 // Fill in the Page 0 tree control
9105 // from the options dialog "Active Chart Directories" list
9106 wxArrayString dir_array0;
9107 int nDir0 = m_db_dirs.GetCount();
9108 for (int i = 0; i < nDir0; i++) {
9109 wxString dirname = m_db_dirs[i].fullpath;
9110 if (!dirname.IsEmpty()) dir_array0.Add(dirname);
9111 }
9112 PopulateTreeCtrl(defaultAllCtl->GetTreeCtrl(), dir_array0, wxColour(128, 128, 128), iFont);
9113 }
9114
CompleteInitialSettings(void)9115 void ChartGroupsUI::CompleteInitialSettings(void) {
9116 PopulateTrees();
9117
9118 BuildNotebookPages(m_pGroupArray);
9119
9120 m_panel->GetSizer()->Layout();
9121
9122 m_settingscomplete = TRUE;
9123 m_treespopulated = TRUE;
9124 }
9125
PopulateTreeCtrl(wxTreeCtrl * ptc,const wxArrayString & dir_array,const wxColour & col,wxFont * pFont)9126 void ChartGroupsUI::PopulateTreeCtrl(wxTreeCtrl* ptc,
9127 const wxArrayString& dir_array,
9128 const wxColour& col, wxFont* pFont) {
9129 ptc->DeleteAllItems();
9130
9131 wxDirItemData* rootData = new wxDirItemData(_T("Dummy"), _T("Dummy"), TRUE);
9132 wxString rootName;
9133 rootName = _T("Dummy");
9134 wxTreeItemId m_rootId = ptc->AddRoot(rootName, 3, -1, rootData);
9135 ptc->SetItemHasChildren(m_rootId);
9136
9137 wxString dirname;
9138 int nDir = dir_array.GetCount();
9139 for (int i = 0; i < nDir; i++) {
9140 wxString dirname = dir_array[i];
9141 if (!dirname.IsEmpty()) {
9142 wxDirItemData* dir_item = new wxDirItemData(dirname, dirname, TRUE);
9143 wxTreeItemId id = ptc->AppendItem(m_rootId, dirname, 0, -1, dir_item);
9144
9145 // wxWidgets bug workaraound (Ticket #10085)
9146 ptc->SetItemText(id, dirname);
9147 if (pFont) ptc->SetItemFont(id, *pFont);
9148 ptc->SetItemTextColour(id, col);
9149 ptc->SetItemHasChildren(id);
9150 }
9151 }
9152 }
9153
OnInsertChartItem(wxCommandEvent & event)9154 void ChartGroupsUI::OnInsertChartItem(wxCommandEvent& event) {
9155 wxString insert_candidate = allAvailableCtl->GetPath();
9156 if (!insert_candidate.IsEmpty()) {
9157 if (m_DirCtrlArray.GetCount()) {
9158 wxGenericDirCtrl* pDirCtrl = (m_DirCtrlArray[m_GroupSelectedPage]);
9159 ChartGroup* pGroup = m_pGroupArray->Item(m_GroupSelectedPage - 1);
9160 if (pDirCtrl) {
9161 wxTreeCtrl* ptree = pDirCtrl->GetTreeCtrl();
9162 if (ptree) {
9163 if (ptree->IsEmpty()) {
9164 wxDirItemData* rootData =
9165 new wxDirItemData(wxEmptyString, wxEmptyString, TRUE);
9166 wxString rootName = _T("Dummy");
9167 wxTreeItemId rootId = ptree->AddRoot(rootName, 3, -1, rootData);
9168
9169 ptree->SetItemHasChildren(rootId);
9170 }
9171
9172 wxTreeItemId root_Id = ptree->GetRootItem();
9173 wxDirItemData* dir_item =
9174 new wxDirItemData(insert_candidate, insert_candidate, TRUE);
9175 wxTreeItemId id =
9176 ptree->AppendItem(root_Id, insert_candidate, 0, -1, dir_item);
9177 if (wxDir::Exists(insert_candidate)) ptree->SetItemHasChildren(id);
9178 }
9179
9180 pGroup->m_element_array.emplace_back(new ChartGroupElement{insert_candidate});
9181 }
9182 }
9183 }
9184 modified = TRUE;
9185 allAvailableCtl->GetTreeCtrl()->UnselectAll();
9186 m_pAddButton->Disable();
9187 }
9188
OnRemoveChartItem(wxCommandEvent & event)9189 void ChartGroupsUI::OnRemoveChartItem(wxCommandEvent& event) {
9190 if (m_DirCtrlArray.GetCount()) {
9191 wxGenericDirCtrl* pDirCtrl = (m_DirCtrlArray[m_GroupSelectedPage]);
9192 ChartGroup* pGroup = m_pGroupArray->Item(m_GroupSelectedPage - 1);
9193
9194 if (pDirCtrl) {
9195 wxString sel_item = pDirCtrl->GetPath();
9196
9197 wxTreeCtrl* ptree = pDirCtrl->GetTreeCtrl();
9198 if (ptree && ptree->GetCount()) {
9199 wxTreeItemId id = ptree->GetSelection();
9200 lastDeletedItem = id;
9201 if (id.IsOk()) {
9202 wxString branch_adder;
9203 int group_item_index =
9204 FindGroupBranch(pGroup, ptree, id, &branch_adder);
9205 if (group_item_index >= 0) {
9206 ChartGroupElement* pelement = pGroup->m_element_array[group_item_index].get();
9207 bool b_duplicate = FALSE;
9208 for (unsigned int k = 0; k < pelement->m_missing_name_array.size(); k++) {
9209 if (pelement->m_missing_name_array[k] == sel_item) {
9210 b_duplicate = TRUE;
9211 break;
9212 }
9213 }
9214 if (!b_duplicate) {
9215 pelement->m_missing_name_array.Add(sel_item);
9216 }
9217
9218 // Special case...
9219 // If the selection is a branch itself,
9220 // Then delete from the tree, and delete from the group
9221 if (branch_adder == _T("")) {
9222 ptree->Delete(id);
9223 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + group_item_index);
9224 } else {
9225 ptree->SetItemTextColour(id, wxColour(128, 128, 128));
9226 // what about toggle back?
9227 }
9228 }
9229 }
9230 modified = TRUE;
9231 lastSelectedCtl->Unselect();
9232 lastSelectedCtl = 0;
9233 m_pRemoveButton->Disable();
9234 wxLogMessage(_T("Disable"));
9235 }
9236 }
9237 }
9238 event.Skip();
9239 }
9240
OnGroupPageChange(wxNotebookEvent & event)9241 void ChartGroupsUI::OnGroupPageChange(wxNotebookEvent& event) {
9242 m_GroupSelectedPage = event.GetSelection();
9243 allAvailableCtl->GetTreeCtrl()->UnselectAll();
9244 if (lastSelectedCtl) {
9245 lastSelectedCtl->UnselectAll();
9246 lastSelectedCtl = 0;
9247 }
9248 m_pRemoveButton->Disable();
9249 m_pAddButton->Disable();
9250
9251 // Disable delete option for "All Charts" group
9252 if(m_GroupSelectedPage == 0){
9253 if(m_pDeleteGroupButton)m_pDeleteGroupButton->Disable();
9254 }
9255 else{
9256 if(m_pDeleteGroupButton)m_pDeleteGroupButton->Enable();
9257 }
9258 }
9259
OnAvailableSelection(wxTreeEvent & event)9260 void ChartGroupsUI::OnAvailableSelection(wxTreeEvent& event) {
9261 wxObject* evtObj = event.GetEventObject();
9262 if (allAvailableCtl && (evtObj == allAvailableCtl->GetTreeCtrl())) {
9263 wxTreeItemId item = allAvailableCtl->GetTreeCtrl()->GetSelection();
9264 if (item && item.IsOk() && m_GroupSelectedPage > 0) {
9265 m_pAddButton->Enable();
9266 } else {
9267 m_pAddButton->Disable();
9268 }
9269 } else {
9270 lastSelectedCtl = dynamic_cast<wxTreeCtrl*>(evtObj);
9271 if (!lastSelectedCtl) goto out;
9272 wxTreeItemId item = lastSelectedCtl->GetSelection();
9273 if (item && item.IsOk() && m_GroupSelectedPage > 0) {
9274 // We need a trick for wxGTK here, since it gives us a Selection
9275 // event with the just deleted element after OnRemoveChartItem()
9276 wxGenericDirCtrl* dirCtrl =
9277 dynamic_cast<wxGenericDirCtrl*>(lastSelectedCtl->GetParent());
9278 if (!dirCtrl) goto out;
9279 wxString itemPath = dirCtrl->GetPath();
9280 if (!itemPath.IsEmpty()) m_pRemoveButton->Enable();
9281 } else {
9282 m_pRemoveButton->Disable();
9283 }
9284 }
9285
9286 out:
9287 event.Skip();
9288 }
9289
OnNewGroup(wxCommandEvent & event)9290 void ChartGroupsUI::OnNewGroup(wxCommandEvent& event) {
9291 wxTextEntryDialog* pd = new wxTextEntryDialog();
9292 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
9293 pd->SetFont(*qFont);
9294
9295 pd->Create(m_panel, _("Enter Group Name"), _("New Chart Group"));
9296
9297 if (pd->ShowModal() == wxID_OK) {
9298 if (pd->GetValue().Length()) {
9299 AddEmptyGroupPage(pd->GetValue());
9300 ChartGroup* pGroup = new ChartGroup;
9301 pGroup->m_group_name = pd->GetValue();
9302 m_pGroupArray->Add(pGroup);
9303
9304 m_GroupSelectedPage =
9305 m_GroupNB->GetPageCount() - 1; // select the new page
9306 m_GroupNB->ChangeSelection(m_GroupSelectedPage);
9307 m_pDeleteGroupButton->Enable();
9308 modified = TRUE;
9309 }
9310 }
9311 delete pd;
9312 }
9313
OnDeleteGroup(wxCommandEvent & event)9314 void ChartGroupsUI::OnDeleteGroup(wxCommandEvent& event) {
9315 if (0 != m_GroupSelectedPage) {
9316 m_DirCtrlArray.RemoveAt(m_GroupSelectedPage);
9317 if (m_pGroupArray) m_pGroupArray->RemoveAt(m_GroupSelectedPage - 1);
9318 m_GroupNB->DeletePage(m_GroupSelectedPage);
9319 modified = TRUE;
9320 }
9321 }
9322
FindGroupBranch(ChartGroup * pGroup,wxTreeCtrl * ptree,wxTreeItemId item,wxString * pbranch_adder)9323 int ChartGroupsUI::FindGroupBranch(ChartGroup* pGroup, wxTreeCtrl* ptree,
9324 wxTreeItemId item, wxString* pbranch_adder) {
9325 wxString branch_name;
9326 wxString branch_adder;
9327
9328 wxTreeItemId current_node = item;
9329 while (current_node.IsOk()) {
9330 wxTreeItemId parent_node = ptree->GetItemParent(current_node);
9331 if (!parent_node) break;
9332
9333 if (parent_node == ptree->GetRootItem()) {
9334 branch_name = ptree->GetItemText(current_node);
9335 break;
9336 }
9337
9338 branch_adder.Prepend(ptree->GetItemText(current_node));
9339 branch_adder.Prepend(wxString(wxFILE_SEP_PATH));
9340
9341 current_node = ptree->GetItemParent(current_node);
9342 }
9343
9344 // Find the index and element pointer of the target branch in the Group
9345 unsigned int target_item_index = -1;
9346
9347 for (unsigned int i = 0; i < pGroup->m_element_array.size(); i++) {
9348 wxString target = pGroup->m_element_array[i]->m_element_name;
9349 if (branch_name == target) {
9350 target_item_index = i;
9351 break;
9352 }
9353 }
9354
9355 if (pbranch_adder) *pbranch_adder = branch_adder;
9356
9357 return target_item_index;
9358 }
9359
OnNodeExpanded(wxTreeEvent & event)9360 void ChartGroupsUI::OnNodeExpanded(wxTreeEvent& event) {
9361 wxTreeItemId node = event.GetItem();
9362
9363 if (m_GroupSelectedPage <= 0) return;
9364 wxGenericDirCtrl* pDirCtrl = (m_DirCtrlArray[m_GroupSelectedPage]);
9365 ChartGroup* pGroup = m_pGroupArray->Item(m_GroupSelectedPage - 1);
9366 if (!pDirCtrl) return;
9367
9368 wxTreeCtrl* ptree = pDirCtrl->GetTreeCtrl();
9369 wxString branch_adder;
9370 int target_item_index = FindGroupBranch(pGroup, ptree, node, &branch_adder);
9371 if (target_item_index < 0) return;
9372 ChartGroupElement* target_element =
9373 pGroup->m_element_array[target_item_index].get();
9374 wxString branch_name = target_element->m_element_name;
9375
9376 // Walk the children of the expanded node, marking any items which appear in
9377 // the "missing" list
9378 if (!target_element->m_missing_name_array.GetCount()) return;
9379 wxString full_root = branch_name;
9380 full_root += branch_adder;
9381 full_root += wxString(wxFILE_SEP_PATH);
9382
9383 wxTreeItemIdValue cookie;
9384 wxTreeItemId child = ptree->GetFirstChild(node, cookie);
9385 while (child.IsOk()) {
9386 wxString target_string = full_root;
9387 target_string += ptree->GetItemText(child);
9388
9389 for (unsigned int k = 0;
9390 k < target_element->m_missing_name_array.GetCount(); k++) {
9391 if (target_element->m_missing_name_array[k] == target_string) {
9392 ptree->SetItemTextColour(child, wxColour(128, 128, 128));
9393 break;
9394 }
9395 }
9396 child = ptree->GetNextChild(node, cookie);
9397 }
9398 }
9399
BuildNotebookPages(ChartGroupArray * pGroupArray)9400 void ChartGroupsUI::BuildNotebookPages(ChartGroupArray* pGroupArray)
9401 {
9402 ClearGroupPages();
9403
9404 for (unsigned int i = 0; i < pGroupArray->GetCount(); i++) {
9405 ChartGroup* pGroup = pGroupArray->Item(i);
9406 wxTreeCtrl* ptc = AddEmptyGroupPage(pGroup->m_group_name);
9407
9408 wxString itemname;
9409 int nItems = pGroup->m_element_array.size();
9410 for (int i = 0; i < nItems; i++) {
9411 wxString itemname = pGroup->m_element_array[i]->m_element_name;
9412 if (!itemname.IsEmpty()) {
9413 wxDirItemData* dir_item = new wxDirItemData(itemname, itemname, TRUE);
9414 wxTreeItemId id =
9415 ptc->AppendItem(ptc->GetRootItem(), itemname, 0, -1, dir_item);
9416
9417 if (wxDir::Exists(itemname)) ptc->SetItemHasChildren(id);
9418 }
9419 }
9420 }
9421 }
9422
AddEmptyGroupPage(const wxString & label)9423 wxTreeCtrl* ChartGroupsUI::AddEmptyGroupPage(const wxString& label) {
9424 wxGenericDirCtrl* GroupDirCtl =
9425 new wxGenericDirCtrl(m_GroupNB, wxID_ANY, _T("TESTDIR"));
9426 m_GroupNB->AddPage(GroupDirCtl, label);
9427
9428 wxTreeCtrl* ptree = GroupDirCtl->GetTreeCtrl();
9429 ptree->DeleteAllItems();
9430
9431 wxDirItemData* rootData =
9432 new wxDirItemData(wxEmptyString, wxEmptyString, TRUE);
9433 wxString rootName = _T("Dummy");
9434 wxTreeItemId rootId = ptree->AddRoot(rootName, 3, -1, rootData);
9435 ptree->SetItemHasChildren(rootId);
9436
9437 m_DirCtrlArray.Add(GroupDirCtl);
9438
9439 return ptree;
9440 }
9441
ClearGroupPages()9442 void ChartGroupsUI::ClearGroupPages()
9443 {
9444 if (m_GroupNB->GetPageCount() == 0)
9445 return;
9446
9447 for(unsigned int i = m_GroupNB->GetPageCount()-1 ; i > 0 ; i--){
9448 m_DirCtrlArray.RemoveAt(i);
9449 m_GroupNB->DeletePage(i);
9450 }
9451 }
9452
9453
OnInsertTideDataLocation(wxCommandEvent & event)9454 void options::OnInsertTideDataLocation(wxCommandEvent& event) {
9455 wxString sel_file;
9456 int response = wxID_CANCEL;
9457
9458 #ifndef __OCPN__ANDROID__
9459 wxFileDialog* popenDialog = new wxFileDialog(
9460 NULL, _("Select Tide/Current Data"), g_TCData_Dir, wxT(""),
9461 wxT("Tide/Current Data files (*.IDX; *.TCD)|*.IDX;*.idx;*.TCD;*.tcd|All ")
9462 wxT("files (*.*)|*.*"),
9463 wxFD_OPEN);
9464 if (g_bresponsive)
9465 popenDialog = g_Platform->AdjustFileDialogFont(this, popenDialog);
9466
9467 response = popenDialog->ShowModal();
9468 sel_file = popenDialog->GetPath();
9469 delete popenDialog;
9470
9471 #else
9472 wxString path;
9473 response = g_Platform->DoFileSelectorDialog(this, &path,
9474 _("Select Tide/Current Data"),
9475 g_TCData_Dir, _T(""), wxT("*.*"));
9476 sel_file = path;
9477 #endif
9478
9479 if (response == wxID_OK) {
9480 wxListItem li;
9481 int id = tcDataSelected->GetItemCount(); // next index
9482 li.SetId( id );
9483 long idx = tcDataSelected->InsertItem( li );
9484 tcDataSelected->SetItem(id, 0, g_Platform->NormalizePath(sel_file));
9485
9486 // Record the currently selected directory for later use
9487 wxFileName fn(sel_file);
9488 wxString data_dir = fn.GetPath();
9489 g_TCData_Dir = g_Platform->NormalizePath(data_dir);
9490 }
9491 }
9492
OnRemoveTideDataLocation(wxCommandEvent & event)9493 void options::OnRemoveTideDataLocation(wxCommandEvent& event)
9494 {
9495 long item = -1;
9496 for ( ;; )
9497 {
9498 item = tcDataSelected->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
9499 if ( item == -1 )
9500 break;
9501 tcDataSelected->DeleteItem( item );
9502 item = -1; // Restart
9503 }
9504 }
9505
OnValChange(wxCommandEvent & event)9506 void options::OnValChange(wxCommandEvent& event) { event.Skip(); }
9507
OnScanBTClick(wxCommandEvent & event)9508 void options::OnScanBTClick(wxCommandEvent& event) {
9509 if (m_BTscanning)
9510 StopBTScan();
9511 else {
9512 m_btNoChangeCounter = 0;
9513 m_btlastResultCount = 0;
9514
9515 m_BTScanTimer.Start(1000, wxTIMER_CONTINUOUS);
9516 g_Platform->startBluetoothScan();
9517 m_BTscanning = 1;
9518 if (m_buttonScanBT) {
9519 m_buttonScanBT->SetLabel(_("Stop Scan"));
9520 }
9521 }
9522 }
9523
onBTScanTimer(wxTimerEvent & event)9524 void options::onBTScanTimer(wxTimerEvent& event) {
9525 if (m_BTscanning) {
9526 m_BTscanning++;
9527
9528 m_BTscan_results = g_Platform->getBluetoothScanResults();
9529
9530 m_choiceBTDataSources->Clear();
9531 m_choiceBTDataSources->Append(m_BTscan_results[0]); // scan status
9532
9533 unsigned int i = 1;
9534 while ((i + 1) < m_BTscan_results.GetCount()) {
9535 wxString item1 = m_BTscan_results[i] + _T(";");
9536 wxString item2 = m_BTscan_results.Item(i + 1);
9537 m_choiceBTDataSources->Append(item1 + item2);
9538
9539 i += 2;
9540 }
9541
9542 if (m_BTscan_results.GetCount() > 1) {
9543 m_choiceBTDataSources->SetSelection(1);
9544 }
9545
9546 // Watch for changes. When no changes occur after n seconds, stop the scan
9547 if (m_btNoChangeCounter > 5) StopBTScan();
9548
9549 if ((int)m_BTscan_results.GetCount() == m_btlastResultCount)
9550 m_btNoChangeCounter++;
9551 else
9552 m_btNoChangeCounter = 0;
9553
9554 m_btlastResultCount = m_BTscan_results.GetCount();
9555
9556 // Absolute fallback
9557 if (m_BTscanning >= 15) {
9558 StopBTScan();
9559 }
9560 } else {
9561 }
9562 return;
9563 }
9564
StopBTScan(void)9565 void options::StopBTScan(void) {
9566 m_BTScanTimer.Stop();
9567
9568 g_Platform->stopBluetoothScan();
9569
9570 m_BTscanning = 0;
9571
9572 if (m_buttonScanBT) {
9573 m_buttonScanBT->SetLabel(_("BT Scan"));
9574 m_buttonScanBT->Enable();
9575 }
9576 }
9577
OnConnValChange(wxCommandEvent & event)9578 void options::OnConnValChange(wxCommandEvent& event) {
9579 connectionsaved = FALSE;
9580 event.Skip();
9581 }
9582
OnTypeSerialSelected(wxCommandEvent & event)9583 void options::OnTypeSerialSelected(wxCommandEvent& event) {
9584 #ifdef __WXGTK__
9585 if (!g_bserial_access_checked) {
9586 if (!CheckSerialAccess()) {
9587 }
9588 g_bserial_access_checked = TRUE;
9589 }
9590 #endif
9591
9592 OnConnValChange(event);
9593 SetNMEAFormToSerial();
9594 }
9595
OnTypeNetSelected(wxCommandEvent & event)9596 void options::OnTypeNetSelected(wxCommandEvent& event) {
9597 OnConnValChange(event);
9598 SetNMEAFormToNet();
9599 }
9600
OnTypeGPSSelected(wxCommandEvent & event)9601 void options::OnTypeGPSSelected(wxCommandEvent& event) {
9602 OnConnValChange(event);
9603 SetNMEAFormToGPS();
9604 }
9605
OnTypeBTSelected(wxCommandEvent & event)9606 void options::OnTypeBTSelected(wxCommandEvent& event) {
9607 OnConnValChange(event);
9608 SetNMEAFormToBT();
9609 }
9610
OnUploadFormatChange(wxCommandEvent & event)9611 void options::OnUploadFormatChange(wxCommandEvent& event) {
9612 if (event.GetEventObject() == m_cbGarminUploadHost && event.IsChecked())
9613 m_cbFurunoGP3X->SetValue(FALSE);
9614 else if (event.GetEventObject() == m_cbFurunoGP3X && event.IsChecked())
9615 m_cbGarminUploadHost->SetValue(FALSE);
9616
9617 OnConnValChange(event);
9618 event.Skip();
9619 }
9620
ShowNMEACommon(bool visible)9621 void options::ShowNMEACommon(bool visible) {
9622 m_rbTypeSerial->Show(visible);
9623 m_rbTypeNet->Show(visible);
9624 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->Show(visible);
9625 if (m_rbTypeInternalBT) m_rbTypeInternalBT->Show(visible);
9626 m_rbIAccept->Show(visible);
9627 m_rbIIgnore->Show(visible);
9628 m_rbOAccept->Show(visible);
9629 m_rbOIgnore->Show(visible);
9630 m_tcInputStc->Show(visible);
9631 m_btnInputStcList->Show(visible);
9632 m_tcOutputStc->Show(visible);
9633 m_btnOutputStcList->Show(visible);
9634 m_cbInput->Show(visible);
9635 m_cbOutput->Show(visible);
9636 m_stPrecision->Show(visible);
9637 m_choicePrecision->Show(visible);
9638 m_choicePriority->Show(visible);
9639 m_stPriority->Show(visible);
9640 m_stPrecision->Show(visible);
9641 m_stTalkerIdText->Show(visible);
9642 m_TalkerIdText->Show(visible);
9643 m_cbCheckCRC->Show(visible);
9644 m_cbCheckSKDiscover->Show(visible);
9645 m_ButtonSKDiscover->Show(visible);
9646 if (visible) {
9647 const bool output = m_cbOutput->IsChecked();
9648 m_stPrecision->Enable(output);
9649 m_choicePrecision->Enable(output);
9650 m_stTalkerIdText->Enable(output);
9651 m_TalkerIdText->Enable(output);
9652 } else {
9653 sbSizerOutFilter->SetDimension(0, 0, 0, 0);
9654 sbSizerInFilter->SetDimension(0, 0, 0, 0);
9655 sbSizerConnectionProps->SetDimension(0, 0, 0, 0);
9656 m_sbConnEdit->SetLabel(_T(""));
9657 }
9658 m_bNMEAParams_shown = visible;
9659 }
9660
ShowNMEANet(bool visible)9661 void options::ShowNMEANet(bool visible) {
9662 m_stNetAddr->Show(visible);
9663 m_tNetAddress->Show(visible);
9664 m_stNetPort->Show(visible);
9665 m_tNetPort->Show(visible);
9666 m_stNetProto->Show(visible);
9667 m_rbNetProtoSignalK->Show(visible);
9668 m_rbNetProtoGPSD->Show(visible);
9669 m_rbNetProtoTCP->Show(visible);
9670 m_rbNetProtoUDP->Show(visible);
9671 m_stNetComment->Show(visible);
9672 m_tNetComment->Show(visible);
9673 }
9674
ShowNMEASerial(bool visible)9675 void options::ShowNMEASerial(bool visible) {
9676 m_stSerBaudrate->Show(visible);
9677 m_choiceBaudRate->Show(visible);
9678 m_stSerPort->Show(visible);
9679 m_comboPort->Show(visible);
9680 m_stSerProtocol->Show(visible);
9681 m_choiceSerialProtocol->Show(visible);
9682 m_cbGarminHost->Show(visible);
9683 m_stSerialComment->Show(visible);
9684 m_tSerialComment->Show(visible);
9685 }
9686
ShowNMEAGPS(bool visible)9687 void options::ShowNMEAGPS(bool visible) {}
9688
ShowNMEABT(bool visible)9689 void options::ShowNMEABT(bool visible) {
9690 if (visible) {
9691 if (m_buttonScanBT) m_buttonScanBT->Show();
9692 if (m_stBTPairs) m_stBTPairs->Show();
9693 if (m_choiceBTDataSources) {
9694 if (m_choiceBTDataSources->GetCount() > 1)
9695 m_choiceBTDataSources->SetSelection(1);
9696 m_choiceBTDataSources->Show();
9697 }
9698 } else {
9699 if (m_buttonScanBT) m_buttonScanBT->Hide();
9700 if (m_stBTPairs) m_stBTPairs->Hide();
9701 if (m_choiceBTDataSources) m_choiceBTDataSources->Hide();
9702 }
9703 m_tcOutputStc->Show(visible);
9704 m_btnOutputStcList->Show(visible);
9705 m_cbOutput->Show(visible);
9706
9707 }
9708
SetNMEAFormToSerial(void)9709 void options::SetNMEAFormToSerial(void) {
9710 ShowNMEACommon(TRUE);
9711 ShowNMEANet(FALSE);
9712 ShowNMEAGPS(FALSE);
9713 ShowNMEABT(FALSE);
9714 ShowNMEASerial(TRUE);
9715
9716 m_pNMEAForm->FitInside();
9717 Fit();
9718 RecalculateSize();
9719 SetDSFormRWStates();
9720 }
9721
SetNMEAFormToNet(void)9722 void options::SetNMEAFormToNet(void) {
9723 ShowNMEACommon(TRUE);
9724 ShowNMEANet(TRUE);
9725 ShowNMEAGPS(FALSE);
9726 ShowNMEABT(FALSE);
9727 ShowNMEASerial(FALSE);
9728 m_pNMEAForm->FitInside();
9729 Fit();
9730 RecalculateSize();
9731 SetDSFormRWStates();
9732 }
9733
SetNMEAFormToGPS(void)9734 void options::SetNMEAFormToGPS(void) {
9735 ShowNMEACommon(TRUE);
9736 ShowNMEANet(FALSE);
9737 ShowNMEAGPS(TRUE);
9738 ShowNMEABT(FALSE);
9739 ShowNMEASerial(FALSE);
9740 m_pNMEAForm->FitInside();
9741 Fit();
9742 RecalculateSize();
9743 SetDSFormRWStates();
9744 }
9745
SetNMEAFormToBT(void)9746 void options::SetNMEAFormToBT(void) {
9747 m_rbNetProtoUDP->SetValue( true );
9748 ShowNMEACommon(TRUE);
9749 ShowNMEANet(FALSE);
9750 ShowNMEAGPS(FALSE);
9751 ShowNMEABT(TRUE);
9752 ShowNMEASerial(FALSE);
9753 m_pNMEAForm->FitInside();
9754 Fit();
9755 RecalculateSize();
9756 SetDSFormRWStates();
9757 }
9758
ClearNMEAForm(void)9759 void options::ClearNMEAForm(void) {
9760 ShowNMEACommon(FALSE);
9761 ShowNMEANet(FALSE);
9762 ShowNMEAGPS(FALSE);
9763 ShowNMEABT(FALSE);
9764 ShowNMEASerial(FALSE);
9765 m_pNMEAForm->FitInside();
9766 Fit();
9767 RecalculateSize();
9768 }
9769
StringArrayToString(wxArrayString arr)9770 wxString StringArrayToString(wxArrayString arr) {
9771 wxString ret = wxEmptyString;
9772 for (size_t i = 0; i < arr.Count(); i++) {
9773 if (i > 0) ret.Append(_T(","));
9774 ret.Append(arr[i]);
9775 }
9776 return ret;
9777 }
9778
SetDSFormOptionVizStates(void)9779 void options::SetDSFormOptionVizStates(void) {
9780 m_cbInput->Show();
9781 m_cbOutput->Show();
9782 m_cbCheckCRC->Show();
9783 m_stPrecision->Show();
9784 m_choicePrecision->Show();
9785 m_stTalkerIdText->Show();
9786 m_TalkerIdText->Show();
9787 sbSizerInFilter->GetStaticBox()->Show();
9788 m_rbIAccept->Show();
9789 m_rbIIgnore->Show();
9790 sbSizerOutFilter->GetStaticBox()->Show();
9791 m_rbOAccept->Show();
9792 m_rbOIgnore->Show();
9793 m_tcInputStc->Show();
9794 m_btnInputStcList->Show();
9795 m_tcOutputStc->Show();
9796 m_btnOutputStcList->Show();
9797 m_cbCheckSKDiscover->Show();
9798 m_ButtonSKDiscover->Show();
9799 m_StaticTextSKServerStatus->Show();
9800
9801 if (m_rbTypeSerial->GetValue()) {
9802 m_cbCheckSKDiscover->Hide();
9803 m_ButtonSKDiscover->Hide();
9804 m_StaticTextSKServerStatus->Hide();
9805
9806 } else if (m_rbNetProtoGPSD->GetValue()) {
9807 m_cbCheckSKDiscover->Hide();
9808 m_cbInput->Hide();
9809 m_cbOutput->Hide();
9810 sbSizerOutFilter->GetStaticBox()->Hide();
9811 m_rbOAccept->Hide();
9812 m_rbOIgnore->Hide();
9813 m_tcOutputStc->Hide();
9814 m_btnOutputStcList->Hide();
9815 m_stPrecision->Hide();
9816 m_choicePrecision->Hide();
9817 m_stTalkerIdText->Hide();
9818 m_TalkerIdText->Hide();
9819 m_cbCheckSKDiscover->Hide();
9820 m_ButtonSKDiscover->Hide();
9821 m_StaticTextSKServerStatus->Hide();
9822
9823
9824 } else if (m_rbNetProtoSignalK->GetValue()) {
9825 //here
9826 m_cbInput->Hide();
9827 m_cbOutput->Hide();
9828 m_cbCheckCRC->Hide();
9829 m_stPrecision->Hide();
9830 m_choicePrecision->Hide();
9831 m_stTalkerIdText->Hide();
9832 m_TalkerIdText->Hide();
9833 sbSizerInFilter->GetStaticBox()->Hide();
9834 m_rbIAccept->Hide();
9835 m_rbIIgnore->Hide();
9836 sbSizerOutFilter->GetStaticBox()->Hide();
9837 m_rbOAccept->Hide();
9838 m_rbOIgnore->Hide();
9839 m_tcInputStc->Hide();
9840 m_btnInputStcList->Hide();
9841 m_tcOutputStc->Hide();
9842 m_btnOutputStcList->Hide();
9843
9844
9845 } else {
9846 m_cbCheckSKDiscover->Hide();
9847 m_ButtonSKDiscover->Hide();
9848 m_StaticTextSKServerStatus->Hide();
9849 }
9850 }
9851
9852
SetDSFormRWStates(void)9853 void options::SetDSFormRWStates(void) {
9854 if (m_rbTypeSerial->GetValue()) {
9855 m_cbInput->Enable(FALSE);
9856 m_cbOutput->Enable(TRUE);
9857 m_rbOAccept->Enable(TRUE);
9858 m_rbOIgnore->Enable(TRUE);
9859 m_btnOutputStcList->Enable(TRUE);
9860 } else if (m_rbNetProtoGPSD->GetValue()) {
9861 if (m_tNetPort->GetValue() == wxEmptyString)
9862 m_tNetPort->SetValue(_T("2947"));
9863 m_cbInput->SetValue(TRUE);
9864 m_cbInput->Enable(FALSE);
9865 m_cbOutput->SetValue(FALSE);
9866 m_cbOutput->Enable(FALSE);
9867 m_rbOAccept->Enable(FALSE);
9868 m_rbOIgnore->Enable(FALSE);
9869 m_btnOutputStcList->Enable(FALSE);
9870 } else if (m_rbNetProtoSignalK->GetValue()) {
9871 if (m_tNetPort->GetValue() == wxEmptyString)
9872 m_tNetPort->SetValue(_T("3000"));
9873 m_cbInput->SetValue(TRUE);
9874 m_cbInput->Enable(FALSE);
9875 m_cbOutput->SetValue(FALSE);
9876 m_cbOutput->Enable(FALSE);
9877 m_rbOAccept->Enable(FALSE);
9878 m_rbOIgnore->Enable(FALSE);
9879 UpdateDiscoverStatus( wxEmptyString );
9880
9881 } else {
9882 if (m_tNetPort->GetValue() == wxEmptyString)
9883 m_tNetPort->SetValue(_T("10110"));
9884 m_cbInput->Enable(TRUE);
9885 m_cbOutput->Enable(TRUE);
9886 m_rbOAccept->Enable(TRUE);
9887 m_rbOIgnore->Enable(TRUE);
9888 m_btnOutputStcList->Enable(TRUE);
9889 }
9890
9891 SetDSFormOptionVizStates();
9892 m_pNMEAForm->FitInside();
9893 //Fit();
9894 //RecalculateSize();
9895
9896 }
9897
SetConnectionParams(ConnectionParams * cp)9898 void options::SetConnectionParams(ConnectionParams* cp) {
9899 if(wxNOT_FOUND == m_comboPort->FindString(cp->Port))
9900 m_comboPort->Append(cp->Port);
9901
9902 m_comboPort->Select(m_comboPort->FindString(cp->Port));
9903
9904 m_cbCheckCRC->SetValue(cp->ChecksumCheck);
9905 m_cbGarminHost->SetValue(cp->Garmin);
9906 m_cbInput->SetValue(cp->IOSelect != DS_TYPE_OUTPUT);
9907 m_cbOutput->SetValue(cp->IOSelect != DS_TYPE_INPUT);
9908 m_cbCheckSKDiscover->SetValue(cp->AutoSKDiscover);
9909
9910 if (cp->InputSentenceListType == WHITELIST)
9911 m_rbIAccept->SetValue(TRUE);
9912 else
9913 m_rbIIgnore->SetValue(TRUE);
9914 if (cp->OutputSentenceListType == WHITELIST)
9915 m_rbOAccept->SetValue(TRUE);
9916 else
9917 m_rbOIgnore->SetValue(TRUE);
9918 m_tcInputStc->SetValue(StringArrayToString(cp->InputSentenceList));
9919 m_tcOutputStc->SetValue(StringArrayToString(cp->OutputSentenceList));
9920 m_choiceBaudRate->Select(
9921 m_choiceBaudRate->FindString(wxString::Format(_T( "%d" ), cp->Baudrate)));
9922 m_choiceSerialProtocol->Select(cp->Protocol); // TODO
9923 m_choicePriority->Select(
9924 m_choicePriority->FindString(wxString::Format(_T( "%d" ), cp->Priority)));
9925 m_tNetAddress->SetValue(cp->NetworkAddress);
9926
9927 if (cp->NetworkPort == 0)
9928 m_tNetPort->SetValue(wxEmptyString);
9929 else
9930 m_tNetPort->SetValue(wxString::Format(wxT("%i"), cp->NetworkPort));
9931
9932 if (cp->NetProtocol == TCP)
9933 m_rbNetProtoTCP->SetValue(TRUE);
9934 else if (cp->NetProtocol == UDP)
9935 m_rbNetProtoUDP->SetValue(TRUE);
9936 else if (cp->NetProtocol == GPSD)
9937 m_rbNetProtoGPSD->SetValue(TRUE);
9938 else if (cp->NetProtocol == SIGNALK)
9939 m_rbNetProtoSignalK->SetValue(TRUE);
9940 else
9941 m_rbNetProtoGPSD->SetValue(TRUE);
9942
9943 if (cp->Type == SERIAL) {
9944 m_rbTypeSerial->SetValue(TRUE);
9945 SetNMEAFormToSerial();
9946 } else if (cp->Type == NETWORK) {
9947 m_rbTypeNet->SetValue(TRUE);
9948 SetNMEAFormToNet();
9949 } else if (cp->Type == INTERNAL_GPS) {
9950 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->SetValue(TRUE);
9951 SetNMEAFormToGPS();
9952 } else if (cp->Type == INTERNAL_BT) {
9953 if (m_rbTypeInternalBT) m_rbTypeInternalBT->SetValue(TRUE);
9954 SetNMEAFormToBT();
9955
9956 // Preset the source selector
9957 wxString bts = cp->NetworkAddress + _T(";") + cp->GetPortStr();
9958 m_choiceBTDataSources->Clear();
9959 m_choiceBTDataSources->Append(bts);
9960 m_choiceBTDataSources->SetSelection(0);
9961 } else
9962 ClearNMEAForm();
9963
9964 if(cp->Type == SERIAL)
9965 m_tSerialComment->SetValue(cp->UserComment);
9966 else if (cp->Type == NETWORK)
9967 m_tNetComment->SetValue(cp->UserComment);
9968
9969 m_connection_enabled = cp->bEnabled;
9970
9971 // Reset touch flag
9972 connectionsaved = true;
9973
9974 }
9975
SetDefaultConnectionParams(void)9976 void options::SetDefaultConnectionParams(void) {
9977 m_comboPort->Select(0);
9978 m_comboPort->SetValue(wxEmptyString);
9979 m_cbCheckCRC->SetValue(TRUE);
9980 m_cbGarminHost->SetValue(FALSE);
9981 m_cbInput->SetValue(TRUE);
9982 m_cbOutput->SetValue(FALSE);
9983 m_rbIAccept->SetValue(TRUE);
9984 m_rbOAccept->SetValue(TRUE);
9985 m_tcInputStc->SetValue(wxEmptyString);
9986 m_tcOutputStc->SetValue(wxEmptyString);
9987 m_choiceBaudRate->Select(m_choiceBaudRate->FindString(_T( "4800" )));
9988 // m_choiceSerialProtocol->Select( cp->Protocol ); // TODO
9989 m_choicePriority->Select(m_choicePriority->FindString(_T( "1" )));
9990
9991 m_tNetAddress->SetValue(_T("0.0.0.0"));
9992
9993 m_tNetComment->SetValue(wxEmptyString);
9994 m_tSerialComment->SetValue(wxEmptyString);
9995
9996 bool bserial = TRUE;
9997 #ifdef __WXGTK__
9998 if (!g_bserial_access_checked) bserial = FALSE;
9999 #endif
10000
10001
10002 #ifdef __OCPN__ANDROID__
10003 if(m_rbTypeInternalGPS){
10004 m_rbTypeInternalGPS->SetValue(true);
10005 SetNMEAFormToGPS();
10006 }
10007 else{
10008 m_rbTypeNet->SetValue( true );
10009 SetNMEAFormToNet();
10010 }
10011
10012 #else
10013 m_rbTypeSerial->SetValue(bserial);
10014 m_rbTypeNet->SetValue(!bserial);
10015 bserial ? SetNMEAFormToSerial() : SetNMEAFormToNet();
10016 #endif
10017
10018 m_connection_enabled = TRUE;
10019
10020 // Reset touch flag
10021 connectionsaved = false;
10022
10023 }
10024
SortSourceList(void)10025 bool options::SortSourceList(void) {
10026
10027 if(g_pConnectionParams->Count() < 2)
10028 return false;
10029
10030 std::vector<int> ivec;
10031 for (size_t i = 0; i < g_pConnectionParams->Count(); i++)
10032 ivec.push_back(i);
10033
10034 bool did_sort = false;
10035 bool did_swap = true;
10036 while(did_swap){
10037 did_swap = false;
10038 for (size_t j=1 ; j < ivec.size() ; j++){
10039 ConnectionParams *c1 = g_pConnectionParams->Item(ivec[j]);
10040 ConnectionParams *c2 = g_pConnectionParams->Item(ivec[j-1]);
10041
10042 if(c1->Priority > c2->Priority){
10043 int t = ivec[j-1];
10044 ivec[j-1] = ivec[j];
10045 ivec[j] = t;
10046 did_swap = true;
10047 did_sort = true;
10048 }
10049 }
10050 }
10051
10052 //if(did_sort)
10053 {
10054 boxSizerConnections = new wxBoxSizer(wxVERTICAL);
10055 m_scrollWinConnections->SetSizer(boxSizerConnections );
10056
10057 for(size_t i=0 ; i < ivec.size() ; i++){
10058 ConnectionParamsPanel *pPanel = g_pConnectionParams->Item(ivec[i])->m_optionsPanel;
10059 boxSizerConnections->Add( pPanel, 0, wxEXPAND|wxALL, 0 );
10060 }
10061 }
10062
10063 return did_sort;
10064
10065 }
10066
FillSourceList(void)10067 void options::FillSourceList(void) {
10068 m_buttonRemove->Enable(FALSE);
10069
10070 // Add new panels as necessary
10071 for (size_t i = 0; i < g_pConnectionParams->Count(); i++) {
10072
10073 if(!g_pConnectionParams->Item(i)->m_optionsPanel){
10074 ConnectionParamsPanel *pPanel = new ConnectionParamsPanel( m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
10075 g_pConnectionParams->Item(i), this);
10076 pPanel->SetSelected(false);
10077 boxSizerConnections->Add( pPanel, 0, wxEXPAND|wxALL, 0 );
10078 g_pConnectionParams->Item(i)->m_optionsPanel = pPanel;
10079 }
10080 else{
10081 g_pConnectionParams->Item(i)->m_optionsPanel->Update(g_pConnectionParams->Item(i));
10082 }
10083
10084 }
10085 SortSourceList();
10086 m_scrollWinConnections->Layout();
10087
10088 mSelectedConnection = NULL;
10089 m_buttonAdd->Enable( true );
10090 m_buttonAdd->Show();
10091
10092 }
10093
UpdateSourceList(bool bResort)10094 void options::UpdateSourceList( bool bResort ) {
10095
10096 for (size_t i = 0; i < g_pConnectionParams->Count(); i++){
10097 ConnectionParams *cp = g_pConnectionParams->Item(i);
10098 ConnectionParamsPanel *panel = cp->m_optionsPanel;
10099 if(panel)
10100 panel->Update(g_pConnectionParams->Item(i));
10101 }
10102
10103 if(bResort){
10104 SortSourceList();
10105 }
10106
10107 m_scrollWinConnections->Layout();
10108 }
10109
OnAddDatasourceClick(wxCommandEvent & event)10110 void options::OnAddDatasourceClick(wxCommandEvent& event) {
10111
10112 // Unselect all panels
10113 for (size_t i = 0; i < g_pConnectionParams->Count(); i++)
10114 g_pConnectionParams->Item(i)->m_optionsPanel->SetSelected( false );
10115
10116 connectionsaved = FALSE;
10117 SetDefaultConnectionParams();
10118 m_sbConnEdit->SetLabel(_("Configure new connection"));
10119
10120 m_buttonRemove->Hide();//Disable();
10121 m_buttonAdd->Hide(); //Disable();
10122
10123 SetDSFormRWStates();
10124
10125 RecalculateSize();
10126
10127 // Scroll the panel to allow the user to see more of the NMEA parameter settings area
10128 wxPoint buttonPosition = m_buttonAdd->GetPosition();
10129 m_pNMEAForm->Scroll(-1, buttonPosition.y / m_scrollRate);
10130 }
10131
10132
OnRemoveDatasourceClick(wxCommandEvent & event)10133 void options::OnRemoveDatasourceClick(wxCommandEvent& event) {
10134 if(mSelectedConnection){
10135 // Find the index
10136 int index = -1;
10137 ConnectionParams *cp = NULL;
10138 for (size_t i = 0; i < g_pConnectionParams->Count(); i++){
10139 cp = g_pConnectionParams->Item(i);
10140 if(mSelectedConnection == cp){
10141 index = i;
10142 break;
10143 }
10144 }
10145
10146 if((index >= 0) && (cp)){
10147 delete g_pConnectionParams->Item(index)->m_optionsPanel;
10148 g_pConnectionParams->RemoveAt(index);
10149
10150 DataStream* pds_existing = g_pMUX->FindStream(cp->GetDSPort());
10151 if (pds_existing)
10152 g_pMUX->StopAndRemoveStream(pds_existing);
10153 //delete mSelectedConnection->m_optionsPanel;
10154 mSelectedConnection = NULL;
10155 }
10156 }
10157
10158 // Mark connection deleted
10159 m_rbTypeSerial->SetValue(TRUE);
10160 m_comboPort->SetValue(_T( "Deleted" ));
10161
10162 FillSourceList();
10163 ShowNMEACommon(FALSE);
10164 ShowNMEANet(FALSE);
10165 ShowNMEASerial(FALSE);
10166 }
10167
OnSelectDatasource(wxListEvent & event)10168 void options::OnSelectDatasource(wxListEvent& event) {
10169 SetConnectionParams(g_pConnectionParams->Item(event.GetData()));
10170 m_buttonRemove->Enable();
10171 m_buttonRemove->Show();
10172 event.Skip();
10173 }
10174
SetSelectedConnectionPanel(ConnectionParamsPanel * panel)10175 void options::SetSelectedConnectionPanel( ConnectionParamsPanel *panel ) {
10176 // Only one panel can be selected at any time
10177 // Clear any selections
10178
10179 if(mSelectedConnection && mSelectedConnection->m_optionsPanel)
10180 mSelectedConnection->m_optionsPanel->SetSelected( false );
10181
10182 if(panel){
10183 mSelectedConnection = panel->m_pConnectionParams;
10184 panel->SetSelected( true );
10185 SetConnectionParams(mSelectedConnection);
10186 m_buttonRemove->Enable();
10187 m_buttonRemove->Show();
10188 m_buttonAdd->Disable();
10189 m_sbConnEdit->SetLabel(_("Edit Selected Connection"));
10190
10191 }
10192 else{
10193 mSelectedConnection = NULL;
10194 m_buttonRemove->Disable();
10195 m_buttonAdd->Enable();
10196 m_buttonAdd->Show();
10197 m_sbConnEdit->SetLabel(_T(""));
10198 ClearNMEAForm();
10199 }
10200
10201 }
10202
OnDiscoverButton(wxCommandEvent & event)10203 void options::OnDiscoverButton(wxCommandEvent &event){
10204
10205 wxString ip;
10206 int port;
10207 std::string serviceIdent = std::string("_signalk-ws._tcp.local."); // Works for node.js server
10208
10209 g_Platform->ShowBusySpinner();
10210
10211 if(SignalKDataStream::DiscoverSKServer( serviceIdent, ip, port, 1)) // 1 second scan
10212 {
10213 m_tNetAddress->SetValue( ip);
10214 m_tNetPort->SetValue(wxString::Format(wxT("%i"), port));
10215 UpdateDiscoverStatus(_("Signal K server available."));
10216 }
10217 else{
10218 UpdateDiscoverStatus(_("Signal K server not found."));
10219 }
10220 g_Platform->HideBusySpinner();
10221
10222
10223 event.Skip();
10224 }
10225
UpdateDiscoverStatus(wxString stat)10226 void options::UpdateDiscoverStatus(wxString stat){
10227 m_StaticTextSKServerStatus->SetLabel(stat);
10228 }
10229
OnBtnIStcs(wxCommandEvent & event)10230 void options::OnBtnIStcs(wxCommandEvent& event) {
10231 const ListType type = m_rbIAccept->GetValue() ? WHITELIST : BLACKLIST;
10232 const wxArrayString list =
10233 wxStringTokenize(m_tcInputStc->GetValue(), _T( "," ));
10234 SentenceListDlg dlg(this, FILTER_INPUT, type, list);
10235
10236 if (dlg.ShowModal() == wxID_OK) m_tcInputStc->SetValue(dlg.GetSentences());
10237 }
10238
OnBtnOStcs(wxCommandEvent & event)10239 void options::OnBtnOStcs(wxCommandEvent& event) {
10240 const ListType type = m_rbOAccept->GetValue() ? WHITELIST : BLACKLIST;
10241 const wxArrayString list =
10242 wxStringTokenize(m_tcOutputStc->GetValue(), _T( "," ));
10243 SentenceListDlg dlg(this, FILTER_OUTPUT, type, list);
10244
10245 if (dlg.ShowModal() == wxID_OK) m_tcOutputStc->SetValue(dlg.GetSentences());
10246 }
10247
OnNetProtocolSelected(wxCommandEvent & event)10248 void options::OnNetProtocolSelected(wxCommandEvent& event) {
10249 if (m_rbNetProtoGPSD->GetValue()) {
10250 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "2947" ));
10251 } else if (m_rbNetProtoUDP->GetValue()) {
10252 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "10110" ));
10253 if (m_tNetAddress->GetValue().IsEmpty())
10254 m_tNetAddress->SetValue(_T( "0.0.0.0" ));
10255 } else if (m_rbNetProtoSignalK->GetValue()) {
10256 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "8375" ));
10257 } else if (m_rbNetProtoTCP->GetValue()) {
10258 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "10110" ));
10259 }
10260
10261 SetDSFormRWStates();
10262 OnConnValChange(event);
10263 }
10264
OnRbAcceptInput(wxCommandEvent & event)10265 void options::OnRbAcceptInput(wxCommandEvent& event) { OnConnValChange(event); }
OnRbIgnoreInput(wxCommandEvent & event)10266 void options::OnRbIgnoreInput(wxCommandEvent& event) { OnConnValChange(event); }
10267
OnRbOutput(wxCommandEvent & event)10268 void options::OnRbOutput(wxCommandEvent& event) { OnConnValChange(event); }
10269
OnCbInput(wxCommandEvent & event)10270 void options::OnCbInput(wxCommandEvent& event) { OnConnValChange(event); }
10271
OnCbOutput(wxCommandEvent & event)10272 void options::OnCbOutput(wxCommandEvent& event) {
10273 OnConnValChange(event);
10274 const bool checked = m_cbOutput->IsChecked();
10275 m_stPrecision->Enable(checked);
10276 m_choicePrecision->Enable(checked);
10277 m_stTalkerIdText->Enable(checked);
10278 m_TalkerIdText->Enable(checked);
10279 }
10280
SentenceListDlg(wxWindow * parent,FilterDirection dir,ListType type,const wxArrayString & list)10281 SentenceListDlg::SentenceListDlg(wxWindow* parent, FilterDirection dir,
10282 ListType type, const wxArrayString& list)
10283 : wxDialog(parent, wxID_ANY, _("Sentence Filter"), wxDefaultPosition,
10284 wxSize(280, 420)),
10285 m_type(type),
10286 m_dir(dir),
10287 m_sentences(NMEA0183().GetRecognizedArray()) {
10288 wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
10289 wxBoxSizer* secondSizer = new wxBoxSizer(wxHORIZONTAL);
10290 wxStaticBox* pclbBox = new wxStaticBox(this, wxID_ANY, GetBoxLabel());
10291 wxStaticBoxSizer* stcSizer = new wxStaticBoxSizer(pclbBox, wxVERTICAL);
10292 m_clbSentences = new wxCheckListBox(this, wxID_ANY, wxDefaultPosition,
10293 wxDefaultSize, m_sentences);
10294 wxBoxSizer* btnEntrySizer = new wxBoxSizer(wxVERTICAL);
10295 wxButton* btnCheckAll = new wxButton(this, wxID_ANY, _("Select All"));
10296 wxButton* btnClearAll = new wxButton(this, wxID_ANY, _("Clear All"));
10297 wxButton* btnAdd = new wxButton(this, wxID_ANY, _("Add"));
10298 m_btnDel = new wxButton(this, wxID_ANY, _("Delete"));
10299 m_btnDel->Disable();
10300 wxStdDialogButtonSizer* btnSizer = new wxStdDialogButtonSizer();
10301 wxButton* btnOK = new wxButton(this, wxID_OK);
10302 wxButton* btnCancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
10303
10304 secondSizer->Add(stcSizer, 1, wxALL | wxEXPAND, 5);
10305 stcSizer->Add(m_clbSentences, 1, wxALL | wxEXPAND, 5);
10306 btnEntrySizer->Add(btnCheckAll, 0, wxALL, 5);
10307 btnEntrySizer->Add(btnClearAll, 0, wxALL, 5);
10308 btnEntrySizer->AddSpacer(1);
10309 btnEntrySizer->Add(btnAdd, 0, wxALL, 5);
10310 btnEntrySizer->Add(m_btnDel, 0, wxALL, 5);
10311 secondSizer->Add(btnEntrySizer, 0, wxALL | wxEXPAND, 5);
10312 mainSizer->Add(secondSizer, 1, wxEXPAND, 5);
10313 btnSizer->AddButton(btnOK);
10314 btnSizer->AddButton(btnCancel);
10315 btnSizer->Realize();
10316 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
10317
10318 SetSizer(mainSizer);
10319 mainSizer->SetSizeHints(this);
10320 Centre();
10321
10322 // Connect Events
10323 btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
10324 wxCommandEventHandler(SentenceListDlg::OnAddClick), NULL,
10325 this);
10326 m_btnDel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
10327 wxCommandEventHandler(SentenceListDlg::OnDeleteClick), NULL,
10328 this);
10329 m_clbSentences->Connect(wxEVT_COMMAND_LISTBOX_SELECTED,
10330 wxCommandEventHandler(SentenceListDlg::OnCLBSelect),
10331 NULL, this);
10332 btnCheckAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
10333 wxCommandEventHandler(SentenceListDlg::OnCheckAllClick),
10334 NULL, this);
10335 btnClearAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
10336 wxCommandEventHandler(SentenceListDlg::OnClearAllClick),
10337 NULL, this);
10338
10339 Populate(list);
10340 }
10341
GetBoxLabel(void) const10342 wxString SentenceListDlg::GetBoxLabel(void) const {
10343 if (m_dir == FILTER_OUTPUT)
10344 return m_type == WHITELIST ? _("Transmit sentences") : _("Drop sentences");
10345 else
10346 return m_type == WHITELIST ? _("Accept only sentences") : _("Ignore sentences");
10347 }
10348
Populate(const wxArrayString & list)10349 void SentenceListDlg::Populate(const wxArrayString& list) {
10350 if (m_dir == FILTER_OUTPUT) {
10351 m_sentences.Add(_T("ECRMB"));
10352 m_sentences.Add(_T("ECRMC"));
10353 m_sentences.Add(_T("ECAPB"));
10354 }
10355 m_sentences.Add(_T("AIVDM"));
10356 m_sentences.Add(_T("AIVDO"));
10357 m_sentences.Add(_T("FRPOS"));
10358 m_sentences.Add(_T("CD"));
10359 m_clbSentences->Clear();
10360 m_clbSentences->InsertItems(m_sentences, 0);
10361
10362 if (list.Count() == 0) {
10363 for (size_t i = 0; i < m_clbSentences->GetCount(); ++i)
10364 m_clbSentences->Check(i, m_type == WHITELIST);
10365 } else {
10366 m_clbSentences->InsertItems(list, m_sentences.GetCount());
10367 for (size_t i = 0; i < list.Count(); ++i) {
10368 int item = m_clbSentences->FindString(list[i]);
10369 if (item != wxNOT_FOUND) m_clbSentences->Check(item);
10370 }
10371 }
10372 }
10373
GetSentences(void)10374 wxString SentenceListDlg::GetSentences(void) {
10375 wxArrayString retString;
10376 for (size_t i = 0; i < m_clbSentences->GetCount(); i++) {
10377 if (m_clbSentences->IsChecked(i))
10378 retString.Add(m_clbSentences->GetString(i));
10379 }
10380 return StringArrayToString(retString);
10381 }
10382
OnCLBSelect(wxCommandEvent & e)10383 void SentenceListDlg::OnCLBSelect(wxCommandEvent& e) {
10384 // Only activate the "Delete" button if the selection is not in the standard
10385 // list
10386 m_btnDel->Enable(m_sentences.Index(e.GetString()) == wxNOT_FOUND);
10387 }
10388
OnAddClick(wxCommandEvent & event)10389 void SentenceListDlg::OnAddClick(wxCommandEvent& event) {
10390 wxTextEntryDialog textdlg(
10391 this, _("Enter the NMEA sentence (2, 3 or 5 characters) "),
10392 _("Enter the NMEA sentence"));
10393 #if wxCHECK_VERSION(2, 9, 0)
10394 textdlg.SetMaxLength(5);
10395 #endif
10396
10397 textdlg.SetTextValidator(wxFILTER_ALPHANUMERIC);
10398 if (textdlg.ShowModal() == wxID_CANCEL) return;
10399 wxString stc = textdlg.GetValue();
10400
10401 if (stc.Length() == 2 || stc.Length() == 3 || stc.Length() == 5) {
10402 m_clbSentences->Append(stc);
10403 m_clbSentences->Check(m_clbSentences->FindString(stc));
10404 return;
10405 }
10406
10407 OCPNMessageBox(
10408 this,
10409 _("An NMEA sentence is generally 3 characters long (like RMC, GGA etc.)\n \
10410 It can also have a two letter prefix identifying the source, or TALKER, of the message.\n \
10411 The whole sentences then looks like GPGGA or AITXT.\n \
10412 You may filter out all the sentences with certain TALKER prefix (like GP, AI etc.).\n\n \
10413 The filter accepts just these three formats."),
10414 _("OpenCPN Info"));
10415 }
10416
OnDeleteClick(wxCommandEvent & event)10417 void SentenceListDlg::OnDeleteClick(wxCommandEvent& event) {
10418 m_clbSentences->Delete(event.GetSelection());
10419 }
10420
OnClearAllClick(wxCommandEvent & event)10421 void SentenceListDlg::OnClearAllClick(wxCommandEvent& event) {
10422 for (size_t i = 0; i < m_clbSentences->GetCount(); i++)
10423 m_clbSentences->Check(i, FALSE);
10424 }
10425
OnCheckAllClick(wxCommandEvent & event)10426 void SentenceListDlg::OnCheckAllClick(wxCommandEvent& event) {
10427 for (size_t i = 0; i < m_clbSentences->GetCount(); i++)
10428 m_clbSentences->Check(i, TRUE);
10429 }
10430
10431 // OpenGLOptionsDlg
10432 enum { ID_BUTTON_REBUILD, ID_BUTTON_CLEAR };
10433
10434 #ifdef ocpnUSE_GL
BEGIN_EVENT_TABLE(OpenGLOptionsDlg,wxDialog)10435 BEGIN_EVENT_TABLE(OpenGLOptionsDlg, wxDialog)
10436 EVT_BUTTON(ID_BUTTON_REBUILD, OpenGLOptionsDlg::OnButtonRebuild)
10437 EVT_BUTTON(ID_BUTTON_CLEAR, OpenGLOptionsDlg::OnButtonClear)
10438 END_EVENT_TABLE()
10439
10440 OpenGLOptionsDlg::OpenGLOptionsDlg(wxWindow* parent)
10441 : wxDialog(parent, wxID_ANY, _T( "OpenGL Options" ), wxDefaultPosition,
10442 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
10443 #ifdef __WXOSX__
10444 | wxSTAY_ON_TOP
10445 #endif
10446 ),
10447 m_brebuild_cache(FALSE) {
10448
10449 wxFont* dialogFont = GetOCPNScaledFont(_("Dialog"));
10450 SetFont(*dialogFont);
10451
10452 wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
10453 wxFlexGridSizer* flexSizer = new wxFlexGridSizer(2);
10454
10455 m_cbTextureCompression = new wxCheckBox(
10456 this, wxID_ANY, g_bGLexpert ? _("Texture Compression")
10457 : _("Texture Compression with Caching"));
10458 m_cbTextureCompressionCaching =
10459 new wxCheckBox(this, wxID_ANY, _("Texture Compression Caching"));
10460 m_memorySize =
10461 new wxStaticText(this, wxID_ANY, _("Texture Memory Size (MB)"));
10462 m_sTextureMemorySize = new wxSpinCtrl(this);
10463 m_sTextureMemorySize->SetRange(1, 16384);
10464 m_cacheSize =
10465 new wxStaticText(this, wxID_ANY, _("Size: ") + GetTextureCacheSize());
10466 wxButton* btnRebuild =
10467 new wxButton(this, ID_BUTTON_REBUILD, _("Rebuild Texture Cache"));
10468 wxButton* btnClear =
10469 new wxButton(this, ID_BUTTON_CLEAR, _("Clear Texture Cache"));
10470 btnRebuild->Enable(g_GLOptions.m_bTextureCompressionCaching);
10471 if (!g_bopengl || g_raster_format == GL_RGB) btnRebuild->Disable();
10472 btnClear->Enable(g_GLOptions.m_bTextureCompressionCaching);
10473 m_cbShowFPS = new wxCheckBox(this, wxID_ANY, _("Show FPS"));
10474 m_cbPolygonSmoothing = new wxCheckBox(this, wxID_ANY, _("Polygon Smoothing"));
10475 m_cbLineSmoothing = new wxCheckBox(this, wxID_ANY, _("Line Smoothing"));
10476 m_cbSoftwareGL =
10477 new wxCheckBox(this, wxID_ANY, _("Software OpenGL (restart OpenCPN)"));
10478 m_cbUseAcceleratedPanning =
10479 new wxCheckBox(this, wxID_ANY, _("Use Accelerated Panning"));
10480
10481 flexSizer->Add(new wxStaticText(this, wxID_ANY, _("Texture Settings")), 0,
10482 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
10483 flexSizer->Add(m_cbTextureCompression, 0, wxALL | wxEXPAND, 5);
10484 flexSizer->AddSpacer(0);
10485 flexSizer->Add(m_cbTextureCompressionCaching, 0, wxALL | wxEXPAND, 5);
10486 flexSizer->Add(m_memorySize, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
10487 flexSizer->Add(m_sTextureMemorySize, 0, wxALL | wxEXPAND, 5);
10488 flexSizer->Add(new wxStaticText(this, wxID_ANY, _("Texture Cache")), 0,
10489 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
10490 flexSizer->Add(m_cacheSize, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, 5);
10491 flexSizer->AddSpacer(0);
10492 flexSizer->Add(btnRebuild, 0, wxALL | wxEXPAND, 5);
10493 flexSizer->AddSpacer(0);
10494 flexSizer->Add(btnClear, 0, wxALL | wxEXPAND, 5);
10495 flexSizer->Add(new wxStaticText(this, wxID_ANY, _("Miscellaneous")), 0,
10496 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
10497 flexSizer->Add(m_cbPolygonSmoothing, 0, wxALL | wxEXPAND, 5);
10498 flexSizer->AddSpacer(0);
10499 flexSizer->Add(m_cbLineSmoothing, 0, wxALL | wxEXPAND, 5);
10500 flexSizer->AddSpacer(0);
10501 flexSizer->Add(m_cbShowFPS, 0, wxALL | wxEXPAND, 5);
10502 flexSizer->AddSpacer(0);
10503 flexSizer->Add(m_cbSoftwareGL, 0, wxALL | wxEXPAND, 5);
10504 flexSizer->AddSpacer(0);
10505 flexSizer->Add(m_cbUseAcceleratedPanning, 0, wxALL | wxEXPAND, 5);
10506 flexSizer->AddGrowableCol(1);
10507 mainSizer->Add(flexSizer, 0, wxALL | wxEXPAND, 5);
10508
10509 wxStdDialogButtonSizer* btnSizer = new wxStdDialogButtonSizer();
10510 btnSizer->AddButton(new wxButton(this, wxID_OK));
10511 btnSizer->AddButton(new wxButton(this, wxID_CANCEL, _("Cancel")));
10512 btnSizer->Realize();
10513
10514 mainSizer->AddStretchSpacer();
10515 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
10516
10517 Populate();
10518
10519 SetSizer(mainSizer);
10520 mainSizer->SetSizeHints(this);
10521 Centre();
10522 }
10523
GetAcceleratedPanning(void) const10524 bool OpenGLOptionsDlg::GetAcceleratedPanning(void) const {
10525 return m_cbUseAcceleratedPanning->GetValue();
10526 }
10527
GetTextureCompression(void) const10528 bool OpenGLOptionsDlg::GetTextureCompression(void) const {
10529 return m_cbTextureCompression->GetValue();
10530 }
10531
GetPolygonSmoothing(void) const10532 bool OpenGLOptionsDlg::GetPolygonSmoothing(void) const {
10533 return m_cbPolygonSmoothing->GetValue();
10534 }
10535
GetLineSmoothing(void) const10536 bool OpenGLOptionsDlg::GetLineSmoothing(void) const {
10537 return m_cbLineSmoothing->GetValue();
10538 }
10539
GetShowFPS(void) const10540 bool OpenGLOptionsDlg::GetShowFPS(void) const {
10541 return m_cbShowFPS->GetValue();
10542 }
10543
GetSoftwareGL(void) const10544 bool OpenGLOptionsDlg::GetSoftwareGL(void) const {
10545 return m_cbSoftwareGL->GetValue();
10546 }
10547
GetTextureCompressionCaching(void) const10548 bool OpenGLOptionsDlg::GetTextureCompressionCaching(void) const {
10549 return m_cbTextureCompressionCaching->GetValue();
10550 }
10551
GetRebuildCache(void) const10552 bool OpenGLOptionsDlg::GetRebuildCache(void) const {
10553 return m_brebuild_cache;
10554 }
10555
GetTextureMemorySize(void) const10556 int OpenGLOptionsDlg::GetTextureMemorySize(void) const {
10557 return m_sTextureMemorySize->GetValue();
10558 }
10559
Populate(void)10560 void OpenGLOptionsDlg::Populate(void) {
10561 extern PFNGLCOMPRESSEDTEXIMAGE2DPROC s_glCompressedTexImage2D;
10562 extern bool b_glEntryPointsSet;
10563
10564 m_cbTextureCompression->SetValue(g_GLOptions.m_bTextureCompression);
10565 /* disable caching if unsupported */
10566 if (b_glEntryPointsSet && !s_glCompressedTexImage2D) {
10567 g_GLOptions.m_bTextureCompressionCaching = FALSE;
10568 m_cbTextureCompression->Disable();
10569 m_cbTextureCompression->SetValue(FALSE);
10570 }
10571
10572 m_cbTextureCompressionCaching->Show(g_bGLexpert);
10573 m_memorySize->Show(g_bGLexpert);
10574 m_sTextureMemorySize->Show(g_bGLexpert);
10575 if (g_bGLexpert) {
10576 m_cbTextureCompressionCaching->SetValue(
10577 g_GLOptions.m_bTextureCompressionCaching);
10578 m_sTextureMemorySize->SetValue(g_GLOptions.m_iTextureMemorySize);
10579 }
10580 m_cbShowFPS->SetValue(g_bShowFPS);
10581 m_cbPolygonSmoothing->SetValue(g_GLOptions.m_GLPolygonSmoothing);
10582 m_cbLineSmoothing->SetValue(g_GLOptions.m_GLLineSmoothing);
10583
10584 #if defined(__UNIX__) && !defined(__OCPN__ANDROID__) && !defined(__WXOSX__)
10585 if (gFrame->GetPrimaryCanvas()->GetglCanvas()){
10586 if(gFrame->GetPrimaryCanvas()->GetglCanvas()->GetVersionString().Upper().Find(_T( "MESA" )) != wxNOT_FOUND)
10587 m_cbSoftwareGL->SetValue(g_bSoftwareGL);
10588 }
10589 #else
10590 m_cbSoftwareGL->Hide();
10591 #endif
10592
10593 wxFont* dialogFont = GetOCPNScaledFont(_("Dialog"));
10594 SetFont(*dialogFont);
10595
10596 if (g_bGLexpert) {
10597 if (gFrame->GetPrimaryCanvas()->GetglCanvas()){
10598 if(gFrame->GetPrimaryCanvas()->GetglCanvas()->CanAcceleratePanning()) {
10599 m_cbUseAcceleratedPanning->Enable();
10600 m_cbUseAcceleratedPanning->SetValue(g_GLOptions.m_bUseAcceleratedPanning);
10601 } else {
10602 m_cbUseAcceleratedPanning->SetValue(FALSE);
10603 m_cbUseAcceleratedPanning->Disable();
10604 }
10605 } else {
10606 m_cbUseAcceleratedPanning->SetValue(g_GLOptions.m_bUseAcceleratedPanning);
10607 }
10608 } else {
10609 m_cbUseAcceleratedPanning->SetValue(g_GLOptions.m_bUseAcceleratedPanning);
10610 m_cbUseAcceleratedPanning->Disable();
10611 }
10612 }
10613
OnButtonRebuild(wxCommandEvent & event)10614 void OpenGLOptionsDlg::OnButtonRebuild(wxCommandEvent& event) {
10615 if (g_GLOptions.m_bTextureCompressionCaching) {
10616 m_brebuild_cache = TRUE;
10617 EndModal(wxID_CANCEL);
10618 }
10619 }
10620
OnButtonClear(wxCommandEvent & event)10621 void OpenGLOptionsDlg::OnButtonClear(wxCommandEvent& event) {
10622
10623 if (g_bopengl && g_glTextureManager){
10624 ::wxBeginBusyCursor();
10625 g_glTextureManager->ClearAllRasterTextures();
10626
10627 wxString path = g_Platform->GetPrivateDataDir();
10628 appendOSDirSlash(&path);
10629 path.append(_T("raster_texture_cache"));
10630
10631 if (::wxDirExists(path)) {
10632 wxArrayString files;
10633 size_t nfiles = wxDir::GetAllFiles(path, &files);
10634 for (unsigned int i = 0; i < files.GetCount(); i++)
10635 ::wxRemoveFile(files[i]);
10636 }
10637
10638 m_cacheSize->SetLabel(_("Size: ") + GetTextureCacheSize());
10639 ::wxEndBusyCursor();
10640 }
10641 }
10642
GetTextureCacheSize(void)10643 wxString OpenGLOptionsDlg::GetTextureCacheSize(void) {
10644 wxString path = g_Platform->GetPrivateDataDir();
10645 appendOSDirSlash(&path);
10646 path.append(_T("raster_texture_cache"));
10647 long long total = 0;
10648
10649 if (::wxDirExists(path)) {
10650 wxArrayString files;
10651 size_t nfiles = wxDir::GetAllFiles(path, &files);
10652 for (unsigned int i = 0; i < files.GetCount(); i++)
10653 total += wxFile(files[i]).Length();
10654 }
10655 double mb = total / (1024.0 * 1024.0);
10656 if (mb < 10000.0) return wxString::Format(_T( "%.1f MB" ), mb);
10657 mb = mb / 1024.0;
10658 return wxString::Format(_T( "%.1f GB" ), mb);
10659 }
10660
10661
10662 //-------------------------------------------------------------------------------------------------
10663 // CanvasConfig selection panel
10664 //-------------------------------------------------------------------------------------------------
10665
BEGIN_EVENT_TABLE(CanvasConfigSelect,wxPanel)10666 BEGIN_EVENT_TABLE(CanvasConfigSelect, wxPanel)
10667 EVT_PAINT ( CanvasConfigSelect::OnPaint )
10668 END_EVENT_TABLE()
10669
10670 CanvasConfigSelect::CanvasConfigSelect(wxWindow *parent, options *parentOptions, wxWindowID id, wxBitmap &bmp, const wxPoint &pos, const wxSize &size)
10671 :wxPanel(parent, id, pos, size, wxBORDER_NONE)
10672 {
10673 m_parentOptions = parentOptions;
10674 m_bmpNormal = bmp;
10675 m_borderWidth = 5;
10676 SetSelected(false);
10677
10678 int refHeight = GetCharHeight();
10679 //SetMinSize(wxSize(-1, 5 * refHeight));
10680 SetMinSize(wxSize(bmp.GetSize().x + m_borderWidth * 2, bmp.GetSize().y + m_borderWidth * 2));
10681
10682 Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CanvasConfigSelect::OnMouseSelected), NULL, this);
10683 }
10684
~CanvasConfigSelect()10685 CanvasConfigSelect::~CanvasConfigSelect()
10686 {
10687 }
10688
OnMouseSelected(wxMouseEvent & event)10689 void CanvasConfigSelect::OnMouseSelected( wxMouseEvent &event )
10690 {
10691 if(!m_bSelected){
10692 SetSelected( true );
10693 }
10694 else{
10695 SetSelected( false );
10696 }
10697 if(m_parentOptions)
10698 m_parentOptions->OnCanvasConfigSelectClick( GetId(), GetSelected());
10699
10700 }
10701
SetSelected(bool selected)10702 void CanvasConfigSelect::SetSelected( bool selected )
10703 {
10704 m_bSelected = selected;
10705 wxColour colour;
10706
10707 if (selected)
10708 {
10709 GetGlobalColor(_T("UIBCK"), &colour);
10710 m_boxColour = colour;
10711 }
10712 else
10713 {
10714 GetGlobalColor(_T("DILG0"), &colour);
10715 m_boxColour = colour;
10716 }
10717
10718 Refresh( true );
10719
10720 }
10721
OnPaint(wxPaintEvent & event)10722 void CanvasConfigSelect::OnPaint( wxPaintEvent &event )
10723 {
10724 int width, height;
10725 GetSize( &width, &height );
10726 wxPaintDC dc( this );
10727
10728 dc.SetBackground(*wxLIGHT_GREY);
10729
10730 dc.SetPen(*wxTRANSPARENT_PEN);
10731 dc.SetBrush(wxBrush(GetBackgroundColour()));
10732 dc.DrawRectangle(GetVirtualSize());
10733
10734 wxColour c;
10735
10736 if(m_bSelected){
10737 dc.SetBrush( wxBrush( m_boxColour ) );
10738
10739 GetGlobalColor( _T ( "UITX1" ), &c );
10740 dc.SetPen( wxPen( wxColor(0xCE, 0xD5, 0xD6), 3 ));
10741
10742 dc.DrawRoundedRectangle( 0, 0, width-1, height-1, height / 10);
10743 }
10744 else {
10745 dc.SetBrush( wxBrush( m_boxColour ) );
10746
10747 GetGlobalColor( _T ( "UITX1" ), &c );
10748 dc.SetPen( wxPen( wxColor(0xCE, 0xD5, 0xD6), 3 ));
10749
10750 dc.DrawRoundedRectangle( 0, 0, width-1, height-1, height / 10);
10751 }
10752
10753 dc.DrawBitmap(m_bmpNormal, m_borderWidth, m_borderWidth, false);
10754 }
10755
10756 #endif // ocpnUSE_GL
10757