OpenCPN Partial API docs
Loading...
Searching...
No Matches
connections_dialog.cpp
1/******************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose:
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2022 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 ***************************************************************************
25 *
26 *
27 */
28
29#include <wx/wxprec.h>
30
31#ifndef WX_PRECOMP
32#include <wx/wx.h>
33#endif // precompiled headers
34
35#include <wx/tokenzr.h>
36#include <wx/regex.h>
37
38#if defined(__linux__) && !defined(__ANDROID__)
39#include <linux/can.h>
40#include <linux/can/raw.h>
41#include <net/if.h>
42#include <serial/serial.h>
43#include <sys/ioctl.h>
44#include <sys/socket.h>
45#endif
46
47
48#ifdef __OCPN__ANDROID__
49#include "androidUTIL.h"
50#include "qdebug.h"
51#endif
52
53#include "connections_dialog.h"
54#include "config_vars.h"
55#include "conn_params_panel.h"
56#include "NMEALogWindow.h"
57#include "OCPNPlatform.h"
58#include "ocpn_plugin.h" // FIXME for GetOCPNScaledFont_PlugIn
59#include "options.h"
60#include "udev_rule_mgr.h"
61#include "comm_drv_factory.h"
62#include "gui_lib.h"
63#include "nmea0183.h"
64#include "priority_gui.h"
65
66extern bool g_bMagneticAPB;
67extern bool g_bfilter_cogsog;
68extern int g_COGFilterSec;
69extern int g_SOGFilterSec;
70extern int g_NMEAAPBPrecision;
71extern OCPNPlatform* g_Platform;
72
73wxString StringArrayToString(wxArrayString arr) {
74 wxString ret = wxEmptyString;
75 for (size_t i = 0; i < arr.Count(); i++) {
76 if (i > 0) ret.Append(_T(","));
77 ret.Append(arr[i]);
78 }
79 return ret;
80}
81
82// Check available SocketCAN interfaces
83
84wxArrayString GetAvailableSocketCANInterfaces() {
85 wxArrayString rv;
86
87#if defined(__linux__) && !defined(__ANDROID__)
88 wxString candidates[] = {
89 "can0",
90 "can1",
91 "can2",
92 "can3",
93 "slcan0",
94 "slcan1",
95 "vcan0",
96 "vcan1"
97 };
98 size_t ncandidates = sizeof(candidates) / sizeof(wxString);
99
100 for (size_t i=0 ; i < ncandidates; i++){
101 int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
102 if (sock < 0) {
103 continue;
104 }
105
106 // Get the interface index
107 struct ifreq if_request;
108 strcpy(if_request.ifr_name, candidates[i].c_str());
109 if (ioctl(sock, SIOCGIFINDEX, &if_request) < 0) {
110 continue;
111 }
112
113 // Check if interface is UP
114 struct sockaddr_can can_address;
115 can_address.can_family = AF_CAN;
116 can_address.can_ifindex = if_request.ifr_ifindex;
117 if (ioctl(sock, SIOCGIFFLAGS, &if_request) < 0) {
118 continue;
119 }
120 if (if_request.ifr_flags & IFF_UP) {
121 rv.Add(candidates[i]);
122 } else {
123 continue;
124 }
125 }
126#endif
127 return rv;
128}
129
130
131//------------------------------------------------------------------------------
132// ConnectionsDialog Implementation
133//------------------------------------------------------------------------------
134
135BEGIN_EVENT_TABLE(ConnectionsDialog, wxEvtHandler)
136EVT_TIMER(ID_BT_SCANTIMER, ConnectionsDialog::onBTScanTimer)
137END_EVENT_TABLE()
138
139
140// Define constructors
142
143ConnectionsDialog::ConnectionsDialog(wxScrolledWindow *container, options *parent){
144 m_container = container;
145 m_parent = parent;
146
147 Init();
148}
149
150
151
152ConnectionsDialog::~ConnectionsDialog() {
153}
154
155void ConnectionsDialog::SetInitialSettings(void) {
156 m_TalkerIdText->SetValue(g_TalkerIdText.MakeUpper());
157
158 m_cbNMEADebug->SetValue(false);
159 if (NMEALogWindow::Get().GetTTYWindow()) {
160 if (NMEALogWindow::Get().GetTTYWindow()->IsShown()) {
161 m_cbNMEADebug->SetValue(true);
162 }
163 }
164
165 if (m_parent->GetSerialArray()) {
166 m_comboPort->Clear();
167 for (size_t i = 0; i < m_parent->GetSerialArray()->Count(); i++) {
168 m_comboPort->Append(m_parent->GetSerialArray()->Item(i));
169 }
170 }
171
172 // On some platforms, the global connections list may be changed outside of
173 // the options dialog. Pick up any changes here, and re-populate the dialog
174 // list.
175 FillSourceList();
176
177 // Reset the touch flag...
178 connectionsaved = true;
179 SetSelectedConnectionPanel(nullptr);
180}
181
182void ConnectionsDialog::RecalculateSize(void) {
183#if 0
184//FIXME Implement this
185 if (!g_bresponsive) {
186 m_nCharWidthMax = GetSize().x / GetCharWidth();
187 return;
188 }
189
190 wxSize esize;
191 esize.x = GetCharWidth() * 110;
192 esize.y = GetCharHeight() * 40;
193
194 wxSize dsize = GetParent()->GetSize(); // GetClientSize();
195 esize.y = wxMin(esize.y, dsize.y - 0 /*(2 * GetCharHeight())*/);
196 esize.x = wxMin(esize.x, dsize.x - 0 /*(2 * GetCharHeight())*/);
197 SetSize(esize);
198
199 wxSize fsize = GetSize();
200 wxSize canvas_size = GetParent()->GetSize();
201 wxPoint screen_pos = GetParent()->GetScreenPosition();
202 int xp = (canvas_size.x - fsize.x) / 2;
203 int yp = (canvas_size.y - fsize.y) / 2;
204 Move(screen_pos.x + xp, screen_pos.y + yp);
205
206 m_nCharWidthMax = GetSize().x / GetCharWidth();
207#endif
208}
209
210void ConnectionsDialog::Init(){
211
212 // Setup some inital values
213 m_buttonScanBT = 0;
214 m_stBTPairs = 0;
215 m_choiceBTDataSources = 0;
216
217 //Create the UI
218 int group_item_spacing = 2;
219
220 wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL);
221 m_container->SetSizer(bSizer4);
222 m_container->SetSizeHints(wxDefaultSize, wxDefaultSize);
223
224 wxBoxSizer* bSizerOuterContainer = new wxBoxSizer(wxVERTICAL);
225
226 wxStaticBoxSizer* sbSizerGeneral;
227 sbSizerGeneral = new wxStaticBoxSizer(
228 new wxStaticBox(m_container, wxID_ANY, _("General")), wxVERTICAL);
229
230 wxBoxSizer* bSizer151;
231 bSizer151 = new wxBoxSizer(wxVERTICAL);
232
233 wxBoxSizer* bSizer161;
234 bSizer161 = new wxBoxSizer(wxVERTICAL);
235
236 wxBoxSizer* bSizer171;
237 bSizer171 = new wxBoxSizer(wxHORIZONTAL);
238
239 m_cbFilterSogCog = new wxCheckBox(m_container, wxID_ANY,
240 _("Filter NMEA Course and Speed data"),
241 wxDefaultPosition, wxDefaultSize, 0);
242 m_cbFilterSogCog->SetValue(g_bfilter_cogsog);
243 bSizer171->Add(m_cbFilterSogCog, 0, wxALL, 5);
244
245 m_stFilterSec =
246 new wxStaticText(m_container, wxID_ANY, _("Filter period (sec)"),
247 wxDefaultPosition, wxDefaultSize, 0);
248 m_stFilterSec->Wrap(-1);
249
250 int nspace = 5;
251#ifdef __WXGTK__
252 nspace = 9;
253#endif
254 bSizer171->Add(m_stFilterSec, 0, wxALL, nspace);
255
256 m_tFilterSec = new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
257 wxDefaultPosition, wxDefaultSize, 0);
258 wxString sfilt;
259 sfilt.Printf(_T("%d"), g_COGFilterSec);
260 m_tFilterSec->SetValue(sfilt);
261 bSizer171->Add(m_tFilterSec, 0, wxALL, 4);
262 bSizer161->Add(bSizer171, 1, wxEXPAND, 5);
263
264 int cb_space = 2;
265 m_cbNMEADebug =
266 new wxCheckBox(m_container, wxID_ANY, _("Show NMEA Debug Window"),
267 wxDefaultPosition, wxDefaultSize, 0);
268 m_cbNMEADebug->SetValue(NMEALogWindow::Get().Active());
269 bSizer161->Add(m_cbNMEADebug, 0, wxALL, cb_space);
270
271 m_cbFurunoGP3X =
272 new wxCheckBox(m_container, wxID_ANY, _("Format uploads for Furuno GP3X"),
273 wxDefaultPosition, wxDefaultSize, 0);
274 m_cbFurunoGP3X->SetValue(g_GPS_Ident == _T( "FurunoGP3X" ));
275 bSizer161->Add(m_cbFurunoGP3X, 0, wxALL, cb_space);
276
277 m_cbGarminUploadHost = new wxCheckBox(
278 m_container, wxID_ANY, _("Use Garmin GRMN (Host) mode for uploads"),
279 wxDefaultPosition, wxDefaultSize, 0);
280 m_cbGarminUploadHost->SetValue(g_bGarminHostUpload);
281 bSizer161->Add(m_cbGarminUploadHost, 0, wxALL, cb_space);
282
283 m_cbAPBMagnetic =
284 new wxCheckBox(m_container, wxID_ANY,
285 _("Use magnetic bearings in output sentence ECAPB"),
286 wxDefaultPosition, wxDefaultSize, 0);
287 m_cbAPBMagnetic->SetValue(g_bMagneticAPB);
288 bSizer161->Add(m_cbAPBMagnetic, 0, wxALL, cb_space);
289
290 m_ButtonPriorityDialog =
291 new wxButton(m_container, wxID_ANY,
292 _("Adjust communication priorities..."),
293 wxDefaultPosition, wxDefaultSize, 0);
294 bSizer161->Add(m_ButtonPriorityDialog, 0, wxALL, cb_space);
295
296 bSizer151->Add(bSizer161, 1, wxEXPAND, 5);
297 sbSizerGeneral->Add(bSizer151, 1, wxEXPAND, 5);
298 bSizerOuterContainer->Add(sbSizerGeneral, 0, wxALL | wxEXPAND, 5);
299
300#if 1
301 // Connections listbox, etc
302 wxStaticBoxSizer* sbSizerLB = new wxStaticBoxSizer(
303 new wxStaticBox(m_container, wxID_ANY, _("Data Connections")),
304 wxVERTICAL);
305
306 /*
307 wxBoxSizer* bSizer17;
308 bSizer17 = new wxBoxSizer(wxVERTICAL);
309
310 m_lcSources = new wxListCtrl(m_pNMEAForm, wxID_ANY, wxDefaultPosition,
311 wxSize(-1, 150), wxLC_REPORT |
312 wxLC_SINGLE_SEL); bSizer17->Add(m_lcSources, 1, wxALL | wxEXPAND, 5);
313 */
314
315 wxPanel* cPanel =
316 new wxPanel(m_container, wxID_ANY, wxDefaultPosition,
317 wxDLG_UNIT(m_parent, wxSize(-1, -1)), wxBG_STYLE_ERASE);
318 sbSizerLB->Add(cPanel, 0, wxALL | wxEXPAND, 5);
319
320 wxBoxSizer* boxSizercPanel = new wxBoxSizer(wxVERTICAL);
321 cPanel->SetSizer(boxSizercPanel);
322
323 m_scrollWinConnections = new wxScrolledWindow(
324 cPanel, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_parent, wxSize(-1, 80)),
325 wxBORDER_RAISED | wxVSCROLL | wxBG_STYLE_ERASE);
326 m_scrollWinConnections->SetScrollRate(5, 5);
327 boxSizercPanel->Add(m_scrollWinConnections, 0, wxALL | wxEXPAND, 5);
328
329 boxSizerConnections = new wxBoxSizer(wxVERTICAL);
330 m_scrollWinConnections->SetSizer(boxSizerConnections);
331
332 bSizerOuterContainer->Add(sbSizerLB, 0, wxEXPAND, 5);
333
334 wxBoxSizer* bSizer18;
335 bSizer18 = new wxBoxSizer(wxHORIZONTAL);
336 sbSizerLB->Add(bSizer18, 1, wxEXPAND, 5);
337
338 m_buttonAdd = new wxButton(m_container, wxID_ANY, _("Add Connection"),
339 wxDefaultPosition, wxDefaultSize, 0);
340 bSizer18->Add(m_buttonAdd, 0, wxALL, 5);
341
342 m_buttonRemove = new wxButton(m_container, wxID_ANY, _("Remove Connection"),
343 wxDefaultPosition, wxDefaultSize, 0);
344 m_buttonRemove->Enable(FALSE);
345 bSizer18->Add(m_buttonRemove, 0, wxALL, 5);
346
347 // wxBoxSizer* bSizer19 = new wxBoxSizer(wxHORIZONTAL);
348 // sbSizerLB->Add(bSizer19, 1, wxEXPAND, 5);
349 //
350 wxFont* dFont = GetOCPNScaledFont_PlugIn(_("Dialog"));
351 double font_size = dFont->GetPointSize() * 17 / 16;
352 wxFont* bFont = wxTheFontList->FindOrCreateFont(
353 font_size, dFont->GetFamily(), dFont->GetStyle(), wxFONTWEIGHT_BOLD);
354 //
355 // m_stEditCon = new wxStaticText(m_pNMEAForm, wxID_ANY, _("Edit Selected
356 // Connection")); m_stEditCon->SetFont(*bFont); bSizer19->Add(m_stEditCon,
357 // 0, wxALL | wxEXPAND | wxALIGN_CENTER_HORIZONTAL, 5);
358 //
359
360 // Connections Properties
361 m_sbConnEdit =
362 new wxStaticBox(m_container, wxID_ANY, _("Edit Selected Connection"));
363 m_sbConnEdit->SetFont(*bFont);
364
365 sbSizerConnectionProps = new wxStaticBoxSizer(m_sbConnEdit, wxVERTICAL);
366
367 wxBoxSizer* bSizer15;
368 bSizer15 = new wxBoxSizer(wxHORIZONTAL);
369
370 sbSizerConnectionProps->Add(bSizer15, 0, wxTOP | wxEXPAND, 5);
371
372 m_rbTypeSerial =
373 new wxRadioButton(m_container, wxID_ANY, _("Serial"), wxDefaultPosition,
374 wxDefaultSize, wxRB_GROUP);
375 m_rbTypeSerial->SetValue(TRUE);
376 bSizer15->Add(m_rbTypeSerial, 0, wxALL, 5);
377
378 m_rbTypeNet = new wxRadioButton(m_container, wxID_ANY, _("Network"),
379 wxDefaultPosition, wxDefaultSize, 0);
380 bSizer15->Add(m_rbTypeNet, 0, wxALL, 5);
381
382
383 m_rbTypeCAN = new wxRadioButton(m_container, wxID_ANY, "socketCAN",
384 wxDefaultPosition, wxDefaultSize, 0);
385#if defined(__linux__) && !defined(__OCPN__ANDROID__) && !defined(__WXOSX__)
386 bSizer15->Add(m_rbTypeCAN, 0, wxALL, 5);
387#else
388 m_rbTypeCAN->Hide();
389#endif
390
391 if (OCPNPlatform::hasInternalGPS()) {
392 m_rbTypeInternalGPS =
393 new wxRadioButton(m_container, wxID_ANY, _("Built-in GPS"),
394 wxDefaultPosition, wxDefaultSize, 0);
395 bSizer15->Add(m_rbTypeInternalGPS, 0, wxALL, 5);
396 } else
397 m_rbTypeInternalGPS = NULL;
398
399 // has built-in Bluetooth
400 if (OCPNPlatform::hasInternalBT()) {
401 m_rbTypeInternalBT =
402 new wxRadioButton(m_container, wxID_ANY, _("Built-in Bluetooth SPP"),
403 wxDefaultPosition, wxDefaultSize, 0);
404 bSizer15->Add(m_rbTypeInternalBT, 0, wxALL, 5);
405
406 m_buttonScanBT = new wxButton(m_container, wxID_ANY, _("BT Scan"),
407 wxDefaultPosition, wxDefaultSize);
408 m_buttonScanBT->Hide();
409
410 wxBoxSizer* bSizer15a = new wxBoxSizer(wxHORIZONTAL);
411 sbSizerConnectionProps->Add(bSizer15a, 0, wxEXPAND, 5);
412
413 bSizer15a->Add(m_buttonScanBT, 0, wxALL, 5);
414
415 m_stBTPairs =
416 new wxStaticText(m_container, wxID_ANY, _("Bluetooth Data Sources"),
417 wxDefaultPosition, wxDefaultSize, 0);
418 m_stBTPairs->Wrap(-1);
419 m_stBTPairs->Hide();
420 bSizer15a->Add(m_stBTPairs, 0, wxALL, 5);
421
422 wxArrayString mt;
423 mt.Add(_T( "unscanned" ));
424 m_choiceBTDataSources = new wxChoice(m_container, wxID_ANY,
425 wxDefaultPosition, wxDefaultSize, mt);
426
427#if 0
428 m_BTscan_results.Clear();
429 m_BTscan_results.Add(_T("None"));
430
431 m_BTscan_results = g_Platform->getBluetoothScanResults();
432 m_choiceBTDataSources->Clear();
433 m_choiceBTDataSources->Append(m_BTscan_results[0]); // scan status
434
435 unsigned int i=1;
436 while( (i+1) < m_BTscan_results.GetCount()){
437 wxString item1 = m_BTscan_results[i] + _T(";");
438 wxString item2 = m_BTscan_results.Item(i+1);
439 m_choiceBTDataSources->Append(item1 + item2);
440
441 i += 2;
442 }
443
444 if( m_BTscan_results.GetCount() > 1){
445 m_choiceBTDataSources->SetSelection( 1 );
446 }
447#endif
448
449 m_choiceBTDataSources->Hide();
450 bSizer15a->Add(m_choiceBTDataSources, 1, wxEXPAND | wxTOP, 5);
451
452 } else
453 m_rbTypeInternalBT = NULL;
454
455 gSizerNetProps = new wxGridSizer(0, 2, 0, 0);
456
457 m_stNetProto = new wxStaticText(m_container, wxID_ANY, _("Protocol"),
458 wxDefaultPosition, wxDefaultSize, 0);
459 m_stNetProto->Wrap(-1);
460 gSizerNetProps->Add(m_stNetProto, 0, wxALL, 5);
461
462 wxBoxSizer* bSizer16;
463 bSizer16 = new wxBoxSizer(wxHORIZONTAL);
464
465 m_rbNetProtoTCP =
466 new wxRadioButton(m_container, wxID_ANY, _("TCP"), wxDefaultPosition,
467 wxDefaultSize, wxRB_GROUP);
468 m_rbNetProtoTCP->Enable(TRUE);
469
470 bSizer16->Add(m_rbNetProtoTCP, 0, wxALL, 5);
471
472 m_rbNetProtoUDP = new wxRadioButton(m_container, wxID_ANY, _("UDP"),
473 wxDefaultPosition, wxDefaultSize, 0);
474 m_rbNetProtoUDP->Enable(TRUE);
475
476 bSizer16->Add(m_rbNetProtoUDP, 0, wxALL, 5);
477
478 m_rbNetProtoGPSD = new wxRadioButton(m_container, wxID_ANY, _("GPSD"),
479 wxDefaultPosition, wxDefaultSize, 0);
480 m_rbNetProtoGPSD->SetValue(TRUE);
481 bSizer16->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
482
483 m_rbNetProtoSignalK = new wxRadioButton(m_container, wxID_ANY, _("Signal K"),
484 wxDefaultPosition, wxDefaultSize, 0);
485 m_rbNetProtoSignalK->Enable(TRUE);
486 bSizer16->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
487
488 gSizerNetProps->Add(bSizer16, 1, wxEXPAND, 5);
489
490 m_stNetAddr = new wxStaticText(m_container, wxID_ANY, _("Address"),
491 wxDefaultPosition, wxDefaultSize, 0);
492 m_stNetAddr->Wrap(-1);
493 gSizerNetProps->Add(m_stNetAddr, 0, wxALL, 5);
494
495 m_tNetAddress = new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
496 wxDefaultPosition, wxDefaultSize, 0);
497 gSizerNetProps->Add(m_tNetAddress, 0, wxEXPAND | wxTOP, 5);
498
499 m_stNetPort = new wxStaticText(m_container, wxID_ANY, _("DataPort"),
500 wxDefaultPosition, wxDefaultSize, 0);
501 m_stNetPort->Wrap(-1);
502 gSizerNetProps->Add(m_stNetPort, 0, wxALL, 5);
503
504 m_tNetPort = new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
505 wxDefaultPosition, wxDefaultSize, 0);
506 gSizerNetProps->Add(m_tNetPort, 1, wxEXPAND | wxTOP, 5);
507
508 // User Comments
509 m_stNetComment = new wxStaticText(m_container, wxID_ANY, _("User Comment"),
510 wxDefaultPosition, wxDefaultSize, 0);
511 m_stNetComment->Wrap(-1);
512 gSizerNetProps->Add(m_stNetComment, 0, wxALL, 5);
513
514 m_tNetComment = new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
515 wxDefaultPosition, wxDefaultSize, 0);
516 gSizerNetProps->Add(m_tNetComment, 1, wxEXPAND | wxTOP, 5);
517
518 sbSizerConnectionProps->Add(gSizerNetProps, 0, wxEXPAND, 5);
519
520 gSizerSerProps = new wxGridSizer(0, 1, 0, 0);
521
522 wxFlexGridSizer* fgSizer1;
523 fgSizer1 = new wxFlexGridSizer(0, 4, 0, 0);
524 fgSizer1->SetFlexibleDirection(wxBOTH);
525 fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
526
527 m_stSerPort = new wxStaticText(m_container, wxID_ANY, _("DataPort"),
528 wxDefaultPosition, wxDefaultSize, 0);
529 m_stSerPort->Wrap(-1);
530 fgSizer1->Add(m_stSerPort, 0, wxALL, 5);
531
532 m_comboPort = new wxComboBox(m_container, wxID_ANY, wxEmptyString,
533 wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
534 fgSizer1->Add(m_comboPort, 0, wxEXPAND | wxTOP, 5);
535
536 m_stSerBaudrate = new wxStaticText(m_container, wxID_ANY, _("Baudrate"),
537 wxDefaultPosition, wxDefaultSize, 0);
538 m_stSerBaudrate->Wrap(-1);
539 fgSizer1->Add(m_stSerBaudrate, 0, wxALL, 5);
540
541 wxString m_choiceBaudRateChoices[] = {
542 _("150"), _("300"), _("600"), _("1200"), _("2400"),
543 _("4800"), _("9600"), _("19200"), _("38400"), _("57600"),
544 _("115200"), _("230400"), _("460800"), _("921600")};
545 int m_choiceBaudRateNChoices =
546 sizeof(m_choiceBaudRateChoices) / sizeof(wxString);
547 m_choiceBaudRate =
548 new wxChoice(m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
549 m_choiceBaudRateNChoices, m_choiceBaudRateChoices, 0);
550 m_choiceBaudRate->SetSelection(0);
551 fgSizer1->Add(m_choiceBaudRate, 1, wxEXPAND | wxTOP, 5);
552
553 m_stSerProtocol = new wxStaticText(m_container, wxID_ANY, _("Protocol"),
554 wxDefaultPosition, wxDefaultSize, 0);
555 m_stSerProtocol->Wrap(-1);
556 fgSizer1->Add(m_stSerProtocol, 0, wxALL, 5);
557
558 wxString m_choiceSerialProtocolChoices[] = {_("NMEA 0183"), _("NMEA 2000")};
559 int m_choiceSerialProtocolNChoices =
560 sizeof(m_choiceSerialProtocolChoices) / sizeof(wxString);
561 m_choiceSerialProtocol = new wxChoice(
562 m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
563 m_choiceSerialProtocolNChoices, m_choiceSerialProtocolChoices, 0);
564 m_choiceSerialProtocol->SetSelection(0);
565 m_choiceSerialProtocol->Enable(TRUE);
566 fgSizer1->Add(m_choiceSerialProtocol, 1, wxEXPAND | wxTOP, 5);
567
568 m_stPriority = new wxStaticText(m_container, wxID_ANY, _("List position"),
569 wxDefaultPosition, wxDefaultSize, 0);
570 m_stPriority->Wrap(-1);
571 fgSizer1->Add(m_stPriority, 0, wxALL, 5);
572
573 wxString m_choicePriorityChoices[] = {_("0"), _("1"), _("2"), _("3"), _("4"),
574 _("5"), _("6"), _("7"), _("8"), _("9")};
575 int m_choicePriorityNChoices =
576 sizeof(m_choicePriorityChoices) / sizeof(wxString);
577 m_choicePriority =
578 new wxChoice(m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
579 m_choicePriorityNChoices, m_choicePriorityChoices, 0);
580 m_choicePriority->SetSelection(9);
581 fgSizer1->Add(m_choicePriority, 0, wxEXPAND | wxTOP, 5);
582
583 m_stCANSource = new wxStaticText(m_container, wxID_ANY, _("socketCAN Source"),
584 wxDefaultPosition, wxDefaultSize, 0);
585 m_stCANSource->Wrap(-1);
586 fgSizer1->Add(m_stCANSource, 0, wxALL, 5);
587
588 wxArrayString choices = GetAvailableSocketCANInterfaces();
589 m_choiceCANSource = new wxChoice(
590 m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
591 choices);
592 m_choiceCANSource->SetSelection(0);
593 m_choiceCANSource->Enable(TRUE);
594 fgSizer1->Add(m_choiceCANSource, 1, wxEXPAND | wxTOP, 5);
595
596 gSizerSerProps->Add(fgSizer1, 0, wxEXPAND, 5);
597
598 wxFlexGridSizer* fgSizer5;
599 fgSizer5 = new wxFlexGridSizer(0, 2, 0, 0);
600 fgSizer5->SetFlexibleDirection(wxBOTH);
601 fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
602
603 // User Comments
604 m_stSerialComment = new wxStaticText(m_container, wxID_ANY, _("User Comment"),
605 wxDefaultPosition, wxDefaultSize, 0);
606 m_stSerialComment->Wrap(-1);
607 fgSizer5->Add(m_stSerialComment, 0, wxALL, 5);
608
609 m_tSerialComment = new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
610 wxDefaultPosition, wxDefaultSize, 0);
611 fgSizer5->Add(m_tSerialComment, 1, wxEXPAND | wxTOP, 5);
612
613 m_cbCheckCRC = new wxCheckBox(m_container, wxID_ANY, _("Control checksum"),
614 wxDefaultPosition, wxDefaultSize, 0);
615 m_cbCheckCRC->SetValue(TRUE);
616 m_cbCheckCRC->SetToolTip(
617 _("If checked, only the sentences with a valid checksum are passed "
618 "through"));
619 fgSizer5->Add(m_cbCheckCRC, 0, wxALL, 5);
620
621 m_cbGarminHost = new wxCheckBox(m_container, wxID_ANY,
622 _("Use Garmin (GRMN) mode for input"),
623 wxDefaultPosition, wxDefaultSize, 0);
624 m_cbGarminHost->SetValue(FALSE);
625 fgSizer5->Add(m_cbGarminHost, 0, wxALL, 5);
626#ifndef USE_GARMINHOST
627 m_cbGarminHost->Hide();
628#endif
629
630 m_cbInput =
631 new wxCheckBox(m_container, wxID_ANY, _("Receive Input on this Port"),
632 wxDefaultPosition, wxDefaultSize, 0);
633 fgSizer5->Add(m_cbInput, 0, wxALL, 5);
634
635 m_cbOutput =
636 new wxCheckBox(m_container, wxID_ANY,
637 wxString::Format(_T("%s (%s)"), _("Output on this port"),
638 _("as autopilot or NMEA repeater")),
639 wxDefaultPosition, wxDefaultSize, 0);
640 fgSizer5->Add(m_cbOutput, 0, wxALL, 5);
641
642 m_stTalkerIdText = new wxStaticText(
643 m_container, wxID_ANY,
644 wxString::Format(_T("%s (%s)"), _("Talker ID"), _("blank = default ID")),
645 wxDefaultPosition, wxDefaultSize, 0);
646 m_stTalkerIdText->Wrap(-1);
647 fgSizer5->Add(m_stTalkerIdText, 0, wxALL, 5);
648
649 // FIXME Verify "-1" ID is OK
650 m_TalkerIdText = new wxTextCtrl(m_container, -1, _T( "" ),
651 wxDefaultPosition, wxSize(50, -1), 0);
652 m_TalkerIdText->SetMaxLength(2);
653 fgSizer5->Add(m_TalkerIdText, 0, wxALIGN_LEFT | wxALL, group_item_spacing);
654
655 m_stPrecision =
656 new wxStaticText(m_container, wxID_ANY, _("APB bearing precision"),
657 wxDefaultPosition, wxDefaultSize, 0);
658
659 m_stPrecision->Wrap(-1);
660 fgSizer5->Add(m_stPrecision, 0, wxALL, 5);
661
662 wxString m_choicePrecisionChoices[] = {_("x"), _("x.x"), _("x.xx"),
663 _("x.xxx"), _("x.xxxx")};
664 int m_choicePrecisionNChoices =
665 sizeof(m_choicePrecisionChoices) / sizeof(wxString);
666 m_choicePrecision =
667 new wxChoice(m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
668 m_choicePrecisionNChoices, m_choicePrecisionChoices, 0);
669 m_choicePrecision->SetSelection(g_NMEAAPBPrecision);
670 fgSizer5->Add(m_choicePrecision, 0, wxALL, 5);
671
672 // signalK discovery enable
673 m_cbCheckSKDiscover =
674 new wxCheckBox(m_container, wxID_ANY, _("Automatic server discovery"),
675 wxDefaultPosition, wxDefaultSize, 0);
676 m_cbCheckSKDiscover->SetValue(TRUE);
677 m_cbCheckSKDiscover->SetToolTip(
678 _("If checked, signal K server will be discovered automatically"));
679 fgSizer5->Add(m_cbCheckSKDiscover, 0, wxALL, 5);
680
681 // signal K "Discover now" button
682 m_ButtonSKDiscover = new wxButton(m_container, wxID_ANY, _("Discover now..."),
683 wxDefaultPosition, wxDefaultSize, 0);
684 m_ButtonSKDiscover->Hide();
685 fgSizer5->Add(m_ButtonSKDiscover, 0, wxALL, 5);
686
687 // signalK Server Status
688 m_StaticTextSKServerStatus = new wxStaticText(
689 m_container, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, 0);
690 fgSizer5->Add(m_StaticTextSKServerStatus, 0, wxALL, 5);
691
692 sbSizerConnectionProps->Add(gSizerSerProps, 0, wxEXPAND, 5);
693 sbSizerConnectionProps->Add(fgSizer5, 0, wxEXPAND, 5);
694
695 sbSizerInFilter = new wxStaticBoxSizer(
696 new wxStaticBox(m_container, wxID_ANY, _("Input filtering")), wxVERTICAL);
697
698 wxBoxSizer* bSizer9;
699 bSizer9 = new wxBoxSizer(wxHORIZONTAL);
700
701 m_rbIAccept =
702 new wxRadioButton(m_container, wxID_ANY, _("Accept only sentences"),
703 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
704 bSizer9->Add(m_rbIAccept, 0, wxALL, 5);
705
706 m_rbIIgnore = new wxRadioButton(m_container, wxID_ANY, _("Ignore sentences"),
707 wxDefaultPosition, wxDefaultSize, 0);
708 bSizer9->Add(m_rbIIgnore, 0, wxALL, 5);
709
710 sbSizerInFilter->Add(bSizer9, 0, wxEXPAND, 5);
711
712 wxBoxSizer* bSizer11;
713 bSizer11 = new wxBoxSizer(wxHORIZONTAL);
714
715 m_tcInputStc =
716 new wxTextCtrl(m_container, wxID_ANY, wxEmptyString, wxDefaultPosition,
717 wxDefaultSize, wxTE_READONLY);
718 bSizer11->Add(m_tcInputStc, 1, wxALL | wxEXPAND, 5);
719
720 m_btnInputStcList =
721 new wxButton(m_container, wxID_ANY, _T("..."), wxDefaultPosition,
722 wxDefaultSize, wxBU_EXACTFIT);
723 bSizer11->Add(m_btnInputStcList, 0, wxALL, 5);
724
725 sbSizerInFilter->Add(bSizer11, 0, wxEXPAND, 5);
726
727 sbSizerConnectionProps->Add(sbSizerInFilter, 0, wxEXPAND, 5);
728
729 sbSizerOutFilter = new wxStaticBoxSizer(
730 new wxStaticBox(m_container, wxID_ANY, _("Output filtering")),
731 wxVERTICAL);
732
733 wxBoxSizer* bSizer10;
734 bSizer10 = new wxBoxSizer(wxHORIZONTAL);
735
736 m_rbOAccept =
737 new wxRadioButton(m_container, wxID_ANY, _("Transmit sentences"),
738 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
739 bSizer10->Add(m_rbOAccept, 0, wxALL, 5);
740
741 m_rbOIgnore = new wxRadioButton(m_container, wxID_ANY, _("Drop sentences"),
742 wxDefaultPosition, wxDefaultSize, 0);
743 bSizer10->Add(m_rbOIgnore, 0, wxALL, 5);
744
745 sbSizerOutFilter->Add(bSizer10, 0, wxEXPAND, 5);
746
747 wxBoxSizer* bSizer12;
748 bSizer12 = new wxBoxSizer(wxHORIZONTAL);
749
750 m_tcOutputStc =
751 new wxTextCtrl(m_container, wxID_ANY, wxEmptyString, wxDefaultPosition,
752 wxDefaultSize, wxTE_READONLY);
753 bSizer12->Add(m_tcOutputStc, 1, wxALL | wxEXPAND, 5);
754
755 m_btnOutputStcList =
756 new wxButton(m_container, wxID_ANY, _T("..."), wxDefaultPosition,
757 wxDefaultSize, wxBU_EXACTFIT);
758 bSizer12->Add(m_btnOutputStcList, 0, wxALL, 5);
759
760 sbSizerOutFilter->Add(bSizer12, 0, wxEXPAND, 5);
761 sbSizerConnectionProps->Add(sbSizerOutFilter, 0, wxEXPAND, 5);
762
763 bSizerOuterContainer->Add(sbSizerConnectionProps, 1, wxALL | wxEXPAND, 5);
764#endif
765 bSizer4->Add(bSizerOuterContainer, 1, wxEXPAND, 5);
766
767 m_buttonAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
768 wxCommandEventHandler(ConnectionsDialog::OnAddDatasourceClick),
769 NULL, this);
770 m_buttonRemove->Connect(
771 wxEVT_COMMAND_BUTTON_CLICKED,
772 wxCommandEventHandler(ConnectionsDialog::OnRemoveDatasourceClick), NULL, this);
773
774 m_rbTypeSerial->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
775 wxCommandEventHandler(ConnectionsDialog::OnTypeSerialSelected),
776 NULL, this);
777 m_rbTypeNet->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
778 wxCommandEventHandler(ConnectionsDialog::OnTypeNetSelected), NULL,
779 this);
780
781 m_rbTypeCAN->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
782 wxCommandEventHandler(ConnectionsDialog::OnTypeCANSelected), NULL,
783 this);
784
785 if (m_rbTypeInternalGPS)
786 m_rbTypeInternalGPS->Connect(
787 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
788 wxCommandEventHandler(ConnectionsDialog::OnTypeGPSSelected), NULL, this);
789 if (m_rbTypeInternalBT)
790 m_rbTypeInternalBT->Connect(
791 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
792 wxCommandEventHandler(ConnectionsDialog::OnTypeBTSelected), NULL, this);
793
794 m_rbNetProtoTCP->Connect(
795 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
796 wxCommandEventHandler(ConnectionsDialog::OnNetProtocolSelected), NULL, this);
797 m_rbNetProtoUDP->Connect(
798 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
799 wxCommandEventHandler(ConnectionsDialog::OnNetProtocolSelected), NULL, this);
800 m_rbNetProtoGPSD->Connect(
801 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
802 wxCommandEventHandler(ConnectionsDialog::OnNetProtocolSelected), NULL, this);
803 m_rbNetProtoSignalK->Connect(
804 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
805 wxCommandEventHandler(ConnectionsDialog::OnNetProtocolSelected), NULL, this);
806 m_tNetAddress->Connect(wxEVT_COMMAND_TEXT_UPDATED,
807 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
808 this);
809 m_tNetPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
810 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
811 this);
812 m_comboPort->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED,
813 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
814 this);
815 m_comboPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
816 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
817 this);
818 m_choiceBaudRate->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
819 wxCommandEventHandler(ConnectionsDialog::OnBaudrateChoice),
820 NULL, this);
821 m_choiceSerialProtocol->Connect(
822 wxEVT_COMMAND_CHOICE_SELECTED,
823 wxCommandEventHandler(ConnectionsDialog::OnProtocolChoice), NULL, this);
824 m_choicePriority->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
825 wxCommandEventHandler(ConnectionsDialog::OnConnValChange),
826 NULL, this);
827 m_choiceCANSource->Connect(wxEVT_COMMAND_CHOICE_SELECTED,
828 wxCommandEventHandler(ConnectionsDialog::OnConnValChange),
829 NULL, this);
830 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
831 wxCommandEventHandler(ConnectionsDialog::OnCrcCheck), NULL, this);
832 m_cbGarminHost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
833 wxCommandEventHandler(ConnectionsDialog::OnUploadFormatChange),
834 NULL, this);
835 m_cbGarminUploadHost->Connect(
836 wxEVT_COMMAND_CHECKBOX_CLICKED,
837 wxCommandEventHandler(ConnectionsDialog::OnUploadFormatChange), NULL, this);
838 m_cbFurunoGP3X->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
839 wxCommandEventHandler(ConnectionsDialog::OnUploadFormatChange),
840 NULL, this);
841 m_cbCheckSKDiscover->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
842 wxCommandEventHandler(ConnectionsDialog::OnConnValChange),
843 NULL, this);
844 m_ButtonSKDiscover->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
845 wxCommandEventHandler(ConnectionsDialog::OnDiscoverButton),
846 NULL, this);
847
848 m_rbIAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
849 wxCommandEventHandler(ConnectionsDialog::OnRbAcceptInput), NULL,
850 this);
851 m_rbIIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
852 wxCommandEventHandler(ConnectionsDialog::OnRbIgnoreInput), NULL,
853 this);
854 m_tcInputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
855 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
856 this);
857 m_btnInputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
858 wxCommandEventHandler(ConnectionsDialog::OnBtnIStcs), NULL,
859 this);
860 m_cbInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
861 wxCommandEventHandler(ConnectionsDialog::OnCbInput), NULL, this);
862 m_cbOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
863 wxCommandEventHandler(ConnectionsDialog::OnCbOutput), NULL, this);
864 m_rbOAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
865 wxCommandEventHandler(ConnectionsDialog::OnRbOutput), NULL, this);
866 m_rbOIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
867 wxCommandEventHandler(ConnectionsDialog::OnRbOutput), NULL, this);
868 m_tcOutputStc->Connect(wxEVT_COMMAND_TEXT_UPDATED,
869 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
870 this);
871 m_btnOutputStcList->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
872 wxCommandEventHandler(ConnectionsDialog::OnBtnOStcs), NULL,
873 this);
874 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
875 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
876 this);
877
878 m_cbNMEADebug->Connect(
879 wxEVT_COMMAND_CHECKBOX_CLICKED,
880 wxCommandEventHandler(ConnectionsDialog::OnShowGpsWindowCheckboxClick), NULL, this);
881 m_cbFilterSogCog->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
882 wxCommandEventHandler(ConnectionsDialog::OnValChange), NULL,
883 this);
884 m_tFilterSec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
885 wxCommandEventHandler(ConnectionsDialog::OnValChange), NULL,
886 this);
887 m_cbAPBMagnetic->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
888 wxCommandEventHandler(ConnectionsDialog::OnValChange), NULL,
889 this);
890
891 m_ButtonPriorityDialog->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
892 wxCommandEventHandler(ConnectionsDialog::OnPriorityDialog), NULL,
893 this);
894
895 m_tNetComment->Connect(wxEVT_COMMAND_TEXT_UPDATED,
896 wxCommandEventHandler(ConnectionsDialog::OnConnValChange), NULL,
897 this);
898 m_tSerialComment->Connect(wxEVT_COMMAND_TEXT_UPDATED,
899 wxCommandEventHandler(ConnectionsDialog::OnConnValChange),
900 NULL, this);
901
902 if (m_buttonScanBT)
903 m_buttonScanBT->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
904 wxCommandEventHandler(ConnectionsDialog::OnScanBTClick), NULL,
905 this);
906
907 FillSourceList();
908
909 ShowNMEACommon(true);
910 ShowNMEASerial(true);
911 ShowNMEANet(true);
912 connectionsaved = TRUE;
913}
914
915void ConnectionsDialog::SetSelectedConnectionPanel(ConnectionParamsPanel* panel) {
916 // Only one panel can be selected at any time
917 // Clear any selections
918
919 if (mSelectedConnection && mSelectedConnection->m_optionsPanel)
920 mSelectedConnection->m_optionsPanel->SetSelected(false);
921
922 if (panel) {
923 mSelectedConnection = panel->m_pConnectionParams;
924 panel->SetSelected(true);
925 SetConnectionParams(mSelectedConnection);
926 m_buttonRemove->Enable();
927 m_buttonRemove->Show();
928 m_buttonAdd->Disable();
929 m_sbConnEdit->SetLabel(_("Edit Selected Connection"));
930
931 } else {
932 mSelectedConnection = NULL;
933 m_buttonRemove->Disable();
934 m_buttonAdd->Enable();
935 m_buttonAdd->Show();
936 m_sbConnEdit->SetLabel(_T(""));
937 ClearNMEAForm();
938 }
939}
940
941void ConnectionsDialog::EnableConnection(ConnectionParams* conn, bool value) {
942 if (conn) {
943 conn->bEnabled = value;
944 conn->b_IsSetup = FALSE; // trigger a rebuild/takedown of the connection
945 m_connection_enabled = conn->bEnabled;
946 }
947}
948
949#if 1
950void ConnectionsDialog::OnValChange(wxCommandEvent& event) { event.Skip(); }
951
952void ConnectionsDialog::OnScanBTClick(wxCommandEvent& event) {
953 if (m_BTscanning)
954 StopBTScan();
955 else {
956 m_btNoChangeCounter = 0;
957 m_btlastResultCount = 0;
958
959 m_BTScanTimer.Start(1000, wxTIMER_CONTINUOUS);
960 g_Platform->startBluetoothScan();
961 m_BTscanning = 1;
962 if (m_buttonScanBT) {
963 m_buttonScanBT->SetLabel(_("Stop Scan"));
964 }
965 }
966}
967
968void ConnectionsDialog::onBTScanTimer(wxTimerEvent& event) {
969 if (m_BTscanning) {
970 m_BTscanning++;
971
972 m_BTscan_results = g_Platform->getBluetoothScanResults();
973
974 m_choiceBTDataSources->Clear();
975 m_choiceBTDataSources->Append(m_BTscan_results[0]); // scan status
976
977 unsigned int i = 1;
978 while ((i + 1) < m_BTscan_results.GetCount()) {
979 wxString item1 = m_BTscan_results[i] + _T(";");
980 wxString item2 = m_BTscan_results.Item(i + 1);
981 m_choiceBTDataSources->Append(item1 + item2);
982
983 i += 2;
984 }
985
986 if (m_BTscan_results.GetCount() > 1) {
987 m_choiceBTDataSources->SetSelection(1);
988 }
989
990 // Watch for changes. When no changes occur after n seconds, stop the scan
991 if (m_btNoChangeCounter > 5) StopBTScan();
992
993 if ((int)m_BTscan_results.GetCount() == m_btlastResultCount)
994 m_btNoChangeCounter++;
995 else
996 m_btNoChangeCounter = 0;
997
998 m_btlastResultCount = m_BTscan_results.GetCount();
999
1000 // Absolute fallback
1001 if (m_BTscanning >= 15) {
1002 StopBTScan();
1003 }
1004 } else {
1005 }
1006 return;
1007}
1008
1009void ConnectionsDialog::StopBTScan(void) {
1010 m_BTScanTimer.Stop();
1011
1012 g_Platform->stopBluetoothScan();
1013
1014 m_BTscanning = 0;
1015
1016 if (m_buttonScanBT) {
1017 m_buttonScanBT->SetLabel(_("BT Scan"));
1018 m_buttonScanBT->Enable();
1019 }
1020}
1021
1022void ConnectionsDialog::OnConnValChange(wxCommandEvent& event) {
1023 connectionsaved = FALSE;
1024 event.Skip();
1025}
1026
1027void ConnectionsDialog::OnTypeSerialSelected(wxCommandEvent& event) {
1028 OnConnValChange(event);
1029 SetNMEAFormToSerial();
1030}
1031
1032void ConnectionsDialog::OnTypeNetSelected(wxCommandEvent& event) {
1033 OnConnValChange(event);
1034 SetNMEAFormToNet();
1035}
1036
1037void ConnectionsDialog::OnTypeCANSelected(wxCommandEvent& event) {
1038 OnConnValChange(event);
1039 SetNMEAFormToCAN();
1040}
1041
1042void ConnectionsDialog::OnTypeGPSSelected(wxCommandEvent& event) {
1043 OnConnValChange(event);
1044 SetNMEAFormToGPS();
1045}
1046
1047void ConnectionsDialog::OnTypeBTSelected(wxCommandEvent& event) {
1048 OnConnValChange(event);
1049 SetNMEAFormToBT();
1050}
1051
1052void ConnectionsDialog::OnUploadFormatChange(wxCommandEvent& event) {
1053 if (event.GetEventObject() == m_cbGarminUploadHost && event.IsChecked())
1054 m_cbFurunoGP3X->SetValue(FALSE);
1055 else if (event.GetEventObject() == m_cbFurunoGP3X && event.IsChecked())
1056 m_cbGarminUploadHost->SetValue(FALSE);
1057
1058 OnConnValChange(event);
1059 event.Skip();
1060}
1061#endif
1062
1063void ConnectionsDialog::ShowNMEACommon(bool visible) {
1064 m_rbTypeSerial->Show(TRUE);
1065 m_rbTypeNet->Show(TRUE);
1066#if defined(__linux__) && !defined(__OCPN__ANDROID__) && !defined(__WXOSX__)
1067 m_rbTypeCAN->Show(TRUE);
1068#endif
1069 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->Show(visible);
1070 if (m_rbTypeInternalBT) m_rbTypeInternalBT->Show(visible);
1071 m_rbIAccept->Show(visible);
1072 m_rbIIgnore->Show(visible);
1073 m_rbOAccept->Show(visible);
1074 m_rbOIgnore->Show(visible);
1075 m_tcInputStc->Show(visible);
1076 m_btnInputStcList->Show(visible);
1077 m_tcOutputStc->Show(visible);
1078 m_btnOutputStcList->Show(visible);
1079 m_cbInput->Show(visible);
1080 m_cbOutput->Show(visible);
1081 m_stPrecision->Show(visible);
1082 m_choicePrecision->Show(visible);
1083 m_choicePriority->Show(visible);
1084 m_stPriority->Show(visible);
1085 m_stPrecision->Show(visible);
1086 m_stTalkerIdText->Show(visible);
1087 m_TalkerIdText->Show(visible);
1088 m_cbCheckCRC->Show(visible);
1089 m_cbCheckSKDiscover->Show(visible);
1090 m_ButtonSKDiscover->Show(visible);
1091 if (visible) {
1092 const bool output = m_cbOutput->IsChecked();
1093 m_stPrecision->Enable(output);
1094 m_choicePrecision->Enable(output);
1095 m_stTalkerIdText->Enable(output);
1096 m_TalkerIdText->Enable(output);
1097 } else {
1098 sbSizerOutFilter->SetDimension(0, 0, 0, 0);
1099 sbSizerInFilter->SetDimension(0, 0, 0, 0);
1100 sbSizerConnectionProps->SetDimension(0, 0, 0, 0);
1101 m_sbConnEdit->SetLabel(_T(""));
1102 }
1103 sbSizerInFilter->Show(visible);
1104 sbSizerOutFilter->Show(visible);
1105 m_bNMEAParams_shown = visible;
1106}
1107
1108void ConnectionsDialog::ShowNMEANet(bool visible) {
1109 m_stNetAddr->Show(visible);
1110 m_tNetAddress->Show(visible);
1111 m_stNetPort->Show(visible);
1112 m_tNetPort->Show(visible);
1113 m_stNetProto->Show(visible);
1114 m_rbNetProtoSignalK->Show(visible);
1115 m_rbNetProtoGPSD->Show(visible);
1116 m_rbNetProtoTCP->Show(visible);
1117 m_rbNetProtoUDP->Show(visible);
1118 m_stNetComment->Show(visible);
1119 m_tNetComment->Show(visible);
1120}
1121
1122void ConnectionsDialog::ShowNMEASerial(bool visible) {
1123 m_stSerBaudrate->Show(visible);
1124 m_choiceBaudRate->Show(visible);
1125 m_stSerPort->Show(visible);
1126 m_comboPort->Show(visible);
1127 m_stSerProtocol->Show(visible);
1128 m_choiceSerialProtocol->Show(visible);
1129 m_cbGarminHost->Show(visible);
1130 m_stSerialComment->Show(visible);
1131 m_tSerialComment->Show(visible);
1132}
1133
1134void ConnectionsDialog::ShowNMEAGPS(bool visible) {}
1135
1136void ConnectionsDialog::ShowNMEACAN(bool visible) {
1137 m_stCANSource->Show(visible);
1138 m_choiceCANSource->Show(visible);
1139}
1140
1141void ConnectionsDialog::ShowNMEABT(bool visible) {
1142 if (visible) {
1143 if (m_buttonScanBT) m_buttonScanBT->Show();
1144 if (m_stBTPairs) m_stBTPairs->Show();
1145 if (m_choiceBTDataSources) {
1146 if (m_choiceBTDataSources->GetCount() > 1)
1147 m_choiceBTDataSources->SetSelection(1);
1148 m_choiceBTDataSources->Show();
1149 }
1150 } else {
1151 if (m_buttonScanBT) m_buttonScanBT->Hide();
1152 if (m_stBTPairs) m_stBTPairs->Hide();
1153 if (m_choiceBTDataSources) m_choiceBTDataSources->Hide();
1154 }
1155 m_tcOutputStc->Show(visible);
1156 m_btnOutputStcList->Show(visible);
1157 m_cbOutput->Show(visible);
1158}
1159
1160void ConnectionsDialog::SetNMEAFormToSerial(void) {
1161 ShowNMEACommon(TRUE);
1162 ShowNMEANet(FALSE);
1163 ShowNMEAGPS(FALSE);
1164 ShowNMEABT(FALSE);
1165 ShowNMEASerial(TRUE);
1166 ShowNMEACAN(FALSE);
1167
1168 m_container->FitInside();
1169 // Fit();
1170 RecalculateSize();
1171 SetDSFormRWStates();
1172}
1173
1174void ConnectionsDialog::SetNMEAFormToNet(void) {
1175 ShowNMEACommon(TRUE);
1176 ShowNMEANet(TRUE);
1177 ShowNMEAGPS(FALSE);
1178 ShowNMEABT(FALSE);
1179 ShowNMEASerial(FALSE);
1180 ShowNMEACAN(FALSE);
1181
1182 m_container->FitInside();
1183 // Fit();
1184 RecalculateSize();
1185 SetDSFormRWStates();
1186}
1187
1188void ConnectionsDialog::SetNMEAFormToCAN(void) {
1189 ShowNMEACommon(FALSE);
1190 ShowNMEANet(FALSE);
1191 ShowNMEAGPS(FALSE);
1192 ShowNMEABT(FALSE);
1193 ShowNMEASerial(FALSE);
1194 ShowNMEACAN(TRUE);
1195 sbSizerInFilter->Show(false);
1196 sbSizerOutFilter->Show(false);
1197
1198 m_container->FitInside();
1199 // Fit();
1200 RecalculateSize();
1201 SetDSFormRWStates();
1202}
1203
1204void ConnectionsDialog::SetNMEAFormToGPS(void) {
1205 ShowNMEACommon(TRUE);
1206 ShowNMEANet(FALSE);
1207 ShowNMEAGPS(TRUE);
1208 ShowNMEABT(FALSE);
1209 ShowNMEASerial(FALSE);
1210 ShowNMEACAN(FALSE);
1211
1212 m_container->FitInside();
1213 // Fit();
1214 RecalculateSize();
1215 SetDSFormRWStates();
1216}
1217
1218void ConnectionsDialog::SetNMEAFormToBT(void) {
1219 m_rbNetProtoUDP->SetValue(true);
1220 ShowNMEACommon(TRUE);
1221 ShowNMEANet(FALSE);
1222 ShowNMEAGPS(FALSE);
1223 ShowNMEABT(TRUE);
1224 ShowNMEASerial(FALSE);
1225 ShowNMEACAN(FALSE);
1226
1227 m_container->FitInside();
1228 // Fit();
1229 RecalculateSize();
1230 SetDSFormRWStates();
1231}
1232
1233void ConnectionsDialog::ClearNMEAForm(void) {
1234 ShowNMEACommon(FALSE);
1235 ShowNMEANet(FALSE);
1236 ShowNMEAGPS(FALSE);
1237 ShowNMEABT(FALSE);
1238 ShowNMEASerial(FALSE);
1239 ShowNMEACAN(FALSE);
1240
1241 m_container->FitInside();
1242 // Fit();
1243 RecalculateSize();
1244}
1245
1246
1247void ConnectionsDialog::SetDSFormOptionVizStates(void) {
1248 m_cbInput->Show();
1249 m_cbOutput->Show();
1250 m_cbCheckCRC->Show();
1251 m_stPrecision->Show();
1252 m_choicePrecision->Show();
1253 m_stTalkerIdText->Show();
1254 m_TalkerIdText->Show();
1255 sbSizerInFilter->GetStaticBox()->Show();
1256 m_rbIAccept->Show();
1257 m_rbIIgnore->Show();
1258 sbSizerOutFilter->GetStaticBox()->Show();
1259 m_rbOAccept->Show();
1260 m_rbOIgnore->Show();
1261 m_tcInputStc->Show();
1262 m_btnInputStcList->Show();
1263 m_tcOutputStc->Show();
1264 m_btnOutputStcList->Show();
1265 m_cbCheckSKDiscover->Show();
1266 m_ButtonSKDiscover->Show();
1267 m_StaticTextSKServerStatus->Show();
1268
1269 if (m_rbTypeSerial->GetValue()) {
1270 m_cbCheckSKDiscover->Hide();
1271 m_ButtonSKDiscover->Hide();
1272 m_StaticTextSKServerStatus->Hide();
1273 bool n0183ctlenabled = (DataProtocol)m_choiceSerialProtocol->GetSelection() == DataProtocol::PROTO_NMEA0183;
1274 if (!n0183ctlenabled) {
1275 m_cbInput->Hide();
1276 m_cbOutput->Hide();
1277 sbSizerOutFilter->GetStaticBox()->Hide();
1278 m_rbOAccept->Hide();
1279 m_rbOIgnore->Hide();
1280 m_tcOutputStc->Hide();
1281 m_tcInputStc->Hide();
1282 m_btnOutputStcList->Hide();
1283 m_btnInputStcList->Hide();
1284 m_stPrecision->Hide();
1285 m_choicePrecision->Hide();
1286 m_stTalkerIdText->Hide();
1287 m_TalkerIdText->Hide();
1288 m_cbCheckCRC->Hide();
1289 sbSizerInFilter->GetStaticBox()->Hide();
1290 m_rbIAccept->Hide();
1291 m_rbIIgnore->Hide();
1292 sbSizerOutFilter->GetStaticBox()->Hide();
1293 m_rbOAccept->Hide();
1294 m_rbOIgnore->Hide();
1295 }
1296 }
1297
1298 if (m_rbTypeCAN->GetValue()) {
1299 m_cbCheckSKDiscover->Hide();
1300 m_ButtonSKDiscover->Hide();
1301 m_StaticTextSKServerStatus->Hide();
1302 m_cbInput->Hide();
1303 m_cbOutput->Hide();
1304 sbSizerOutFilter->GetStaticBox()->Hide();
1305 m_rbOAccept->Hide();
1306 m_rbOIgnore->Hide();
1307 m_tcOutputStc->Hide();
1308 m_tcInputStc->Hide();
1309 m_btnOutputStcList->Hide();
1310 m_btnInputStcList->Hide();
1311 m_stPrecision->Hide();
1312 m_choicePrecision->Hide();
1313 m_stTalkerIdText->Hide();
1314 m_TalkerIdText->Hide();
1315 m_cbCheckCRC->Hide();
1316 sbSizerInFilter->GetStaticBox()->Hide();
1317 m_rbIAccept->Hide();
1318 m_rbIIgnore->Hide();
1319 sbSizerOutFilter->GetStaticBox()->Hide();
1320 m_rbOAccept->Hide();
1321 m_rbOIgnore->Hide();
1322 }
1323
1324 if (m_rbTypeNet->GetValue()) {
1325 if (m_rbNetProtoGPSD->GetValue()) {
1326 m_cbCheckSKDiscover->Hide();
1327 m_cbInput->Hide();
1328 m_cbOutput->Hide();
1329 sbSizerOutFilter->GetStaticBox()->Hide();
1330 m_rbOAccept->Hide();
1331 m_rbOIgnore->Hide();
1332 m_tcInputStc->Hide();
1333 m_tcOutputStc->Hide();
1334 m_btnOutputStcList->Hide();
1335 m_btnInputStcList->Hide();
1336 m_stPrecision->Hide();
1337 m_choicePrecision->Hide();
1338 m_stTalkerIdText->Hide();
1339 m_TalkerIdText->Hide();
1340 m_cbCheckSKDiscover->Hide();
1341 m_ButtonSKDiscover->Hide();
1342 m_StaticTextSKServerStatus->Hide();
1343
1344 } else if (m_rbNetProtoSignalK->GetValue()) {
1345 m_cbInput->Hide();
1346 m_cbOutput->Hide();
1347 m_cbCheckCRC->Hide();
1348 m_stPrecision->Hide();
1349 m_choicePrecision->Hide();
1350 m_stTalkerIdText->Hide();
1351 m_TalkerIdText->Hide();
1352 sbSizerInFilter->GetStaticBox()->Hide();
1353 m_rbIAccept->Hide();
1354 m_rbIIgnore->Hide();
1355 sbSizerOutFilter->GetStaticBox()->Hide();
1356 m_rbOAccept->Hide();
1357 m_rbOIgnore->Hide();
1358 m_tcInputStc->Hide();
1359 m_btnInputStcList->Hide();
1360 m_tcOutputStc->Hide();
1361 m_btnOutputStcList->Hide();
1362
1363 } else {
1364 m_cbCheckSKDiscover->Hide();
1365 m_ButtonSKDiscover->Hide();
1366 m_StaticTextSKServerStatus->Hide();
1367 }
1368 }
1369}
1370
1371void ConnectionsDialog::SetDSFormRWStates(void) {
1372 if (m_rbTypeSerial->GetValue()) {
1373 m_cbInput->Enable(FALSE);
1374 m_cbOutput->Enable(TRUE);
1375 m_rbOAccept->Enable(TRUE);
1376 m_rbOIgnore->Enable(TRUE);
1377 m_btnOutputStcList->Enable(TRUE);
1378 } else if (m_rbNetProtoGPSD->GetValue()) {
1379 if (m_tNetPort->GetValue() == wxEmptyString)
1380 m_tNetPort->SetValue(_T("2947"));
1381 m_cbInput->SetValue(TRUE);
1382 m_cbInput->Enable(FALSE);
1383 m_cbOutput->SetValue(FALSE);
1384 m_cbOutput->Enable(FALSE);
1385 m_rbOAccept->Enable(FALSE);
1386 m_rbOIgnore->Enable(FALSE);
1387 m_btnOutputStcList->Enable(FALSE);
1388 } else if (m_rbNetProtoSignalK->GetValue()) {
1389 if (m_tNetPort->GetValue() == wxEmptyString)
1390 m_tNetPort->SetValue(_T("3000"));
1391 m_cbInput->SetValue(TRUE);
1392 m_cbInput->Enable(FALSE);
1393 m_cbOutput->SetValue(FALSE);
1394 m_cbOutput->Enable(FALSE);
1395 m_rbOAccept->Enable(FALSE);
1396 m_rbOIgnore->Enable(FALSE);
1397 UpdateDiscoverStatus(wxEmptyString);
1398
1399 } else {
1400 if (m_tNetPort->GetValue() == wxEmptyString)
1401 m_tNetPort->SetValue(_T("10110"));
1402 m_cbInput->Enable(TRUE);
1403 m_cbOutput->Enable(TRUE);
1404 m_rbOAccept->Enable(TRUE);
1405 m_rbOIgnore->Enable(TRUE);
1406 m_btnOutputStcList->Enable(TRUE);
1407 }
1408
1409 SetDSFormOptionVizStates();
1410 m_container->FitInside();
1411}
1412
1413void ConnectionsDialog::SetConnectionParams(ConnectionParams* cp) {
1414 if (wxNOT_FOUND == m_comboPort->FindString(cp->Port))
1415 m_comboPort->Append(cp->Port);
1416
1417 m_comboPort->Select(m_comboPort->FindString(cp->Port));
1418
1419 m_cbCheckCRC->SetValue(cp->ChecksumCheck);
1420 m_cbGarminHost->SetValue(cp->Garmin);
1421 m_cbInput->SetValue(cp->IOSelect != DS_TYPE_OUTPUT);
1422 m_cbOutput->SetValue(cp->IOSelect != DS_TYPE_INPUT);
1423 m_cbCheckSKDiscover->SetValue(cp->AutoSKDiscover);
1424
1425 if (cp->InputSentenceListType == WHITELIST)
1426 m_rbIAccept->SetValue(TRUE);
1427 else
1428 m_rbIIgnore->SetValue(TRUE);
1429 if (cp->OutputSentenceListType == WHITELIST)
1430 m_rbOAccept->SetValue(TRUE);
1431 else
1432 m_rbOIgnore->SetValue(TRUE);
1433 m_tcInputStc->SetValue(StringArrayToString(cp->InputSentenceList));
1434 m_tcOutputStc->SetValue(StringArrayToString(cp->OutputSentenceList));
1435 m_choiceBaudRate->Select(
1436 m_choiceBaudRate->FindString(wxString::Format(_T( "%d" ), cp->Baudrate)));
1437 m_choiceSerialProtocol->Select(cp->Protocol); // TODO
1438 m_choicePriority->Select(
1439 m_choicePriority->FindString(wxString::Format(_T( "%d" ), cp->Priority)));
1440 m_tNetAddress->SetValue(cp->NetworkAddress);
1441
1442 if (cp->NetworkPort == 0)
1443 m_tNetPort->SetValue(wxEmptyString);
1444 else
1445 m_tNetPort->SetValue(wxString::Format(wxT("%i"), cp->NetworkPort));
1446
1447 if (cp->NetProtocol == TCP)
1448 m_rbNetProtoTCP->SetValue(TRUE);
1449 else if (cp->NetProtocol == UDP)
1450 m_rbNetProtoUDP->SetValue(TRUE);
1451 else if (cp->NetProtocol == GPSD)
1452 m_rbNetProtoGPSD->SetValue(TRUE);
1453 else if (cp->NetProtocol == SIGNALK)
1454 m_rbNetProtoSignalK->SetValue(TRUE);
1455 else
1456 m_rbNetProtoGPSD->SetValue(TRUE);
1457
1458 if (cp->Type == SERIAL) {
1459 m_rbTypeSerial->SetValue(TRUE);
1460 SetNMEAFormToSerial();
1461 SetNMEAFormForProtocol();
1462 } else if (cp->Type == NETWORK) {
1463 m_rbTypeNet->SetValue(TRUE);
1464 SetNMEAFormToNet();
1465 } else if (cp->Type == SOCKETCAN) {
1466 m_rbTypeCAN->SetValue(TRUE);
1467 SetNMEAFormToCAN();
1468
1469 } else if (cp->Type == INTERNAL_GPS) {
1470 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->SetValue(TRUE);
1471 SetNMEAFormToGPS();
1472 } else if (cp->Type == INTERNAL_BT) {
1473 if (m_rbTypeInternalBT) m_rbTypeInternalBT->SetValue(TRUE);
1474 SetNMEAFormToBT();
1475
1476 // Preset the source selector
1477 wxString bts = cp->NetworkAddress + _T(";") + cp->GetPortStr();
1478 m_choiceBTDataSources->Clear();
1479 m_choiceBTDataSources->Append(bts);
1480 m_choiceBTDataSources->SetSelection(0);
1481 } else
1482 ClearNMEAForm();
1483
1484 if (cp->Type == SERIAL)
1485 m_tSerialComment->SetValue(cp->UserComment);
1486 else if (cp->Type == NETWORK)
1487 m_tNetComment->SetValue(cp->UserComment);
1488
1489 m_connection_enabled = cp->bEnabled;
1490
1491 // Reset touch flag
1492 connectionsaved = true;
1493}
1494
1495
1496void ConnectionsDialog::SetDefaultConnectionParams(void) {
1497 if (m_comboPort && !m_comboPort->IsListEmpty()) {
1498 m_comboPort->Select(0);
1499 m_comboPort->SetValue(wxEmptyString); // These two broke it
1500 }
1501 m_cbCheckCRC->SetValue(TRUE);
1502 m_cbGarminHost->SetValue(FALSE);
1503 m_cbInput->SetValue(TRUE);
1504 m_cbOutput->SetValue(FALSE);
1505 m_rbIAccept->SetValue(TRUE);
1506 m_rbOAccept->SetValue(TRUE);
1507 m_tcInputStc->SetValue(wxEmptyString);
1508 m_tcOutputStc->SetValue(wxEmptyString);
1509 m_choiceBaudRate->Select(m_choiceBaudRate->FindString(_T( "4800" )));
1510 // m_choiceSerialProtocol->Select( cp->Protocol ); // TODO
1511 m_choicePriority->Select(m_choicePriority->FindString(_T( "1" )));
1512
1513 m_tNetAddress->SetValue(_T("0.0.0.0"));
1514
1515 m_tNetComment->SetValue(wxEmptyString);
1516 m_tSerialComment->SetValue(wxEmptyString);
1517
1518 bool bserial = TRUE;
1519#ifdef __WXGTK__
1520 bserial = FALSE;
1521#endif
1522
1523#ifdef __WXOSX__
1524 bserial = FALSE;
1525#endif
1526
1527#ifdef __OCPN__ANDROID__
1528 if (m_rbTypeInternalGPS) {
1529 m_rbTypeInternalGPS->SetValue(true);
1530 SetNMEAFormToGPS();
1531 } else {
1532 m_rbTypeNet->SetValue(true);
1533 SetNMEAFormToNet();
1534 }
1535
1536#else
1537 m_rbTypeSerial->SetValue(bserial);
1538 m_rbTypeNet->SetValue(!bserial);
1539 bserial ? SetNMEAFormToSerial() : SetNMEAFormToNet();
1540 m_rbTypeCAN->SetValue(FALSE);
1541#endif
1542
1543 m_connection_enabled = TRUE;
1544
1545 // Reset touch flag
1546 connectionsaved = false;
1547}
1548
1549bool ConnectionsDialog::SortSourceList(void) {
1550 if (TheConnectionParams()->Count() < 2) return false;
1551
1552 std::vector<int> ivec;
1553 for (size_t i = 0; i < TheConnectionParams()->Count(); i++) ivec.push_back(i);
1554
1555 bool did_sort = false;
1556 bool did_swap = true;
1557 while (did_swap) {
1558 did_swap = false;
1559 for (size_t j = 1; j < ivec.size(); j++) {
1560 ConnectionParams* c1 = TheConnectionParams()->Item(ivec[j]);
1561 ConnectionParams* c2 = TheConnectionParams()->Item(ivec[j - 1]);
1562
1563 if (c1->Priority > c2->Priority) {
1564 int t = ivec[j - 1];
1565 ivec[j - 1] = ivec[j];
1566 ivec[j] = t;
1567 did_swap = true;
1568 did_sort = true;
1569 }
1570 }
1571 }
1572
1573 // if(did_sort)
1574 {
1575 boxSizerConnections = new wxBoxSizer(wxVERTICAL);
1576 m_scrollWinConnections->SetSizer(boxSizerConnections);
1577
1578 for (size_t i = 0; i < ivec.size(); i++) {
1579 ConnectionParamsPanel* pPanel =
1580 TheConnectionParams()->Item(ivec[i])->m_optionsPanel;
1581 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxALL, 0);
1582 }
1583 }
1584
1585 return did_sort;
1586}
1587
1588void ConnectionsDialog::FillSourceList(void) {
1589 m_buttonRemove->Enable(FALSE);
1590
1591 // Add new panels as necessary
1592 for (size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1593 if (!TheConnectionParams()->Item(i)->m_optionsPanel) {
1595 m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1596 TheConnectionParams()->Item(i), this);
1597 pPanel->SetSelected(false);
1598 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxALL, 0);
1599 TheConnectionParams()->Item(i)->m_optionsPanel = pPanel;
1600 } else {
1601 TheConnectionParams()->Item(i)->m_optionsPanel->Update(
1602 TheConnectionParams()->Item(i));
1603 }
1604 }
1605 SortSourceList();
1606 m_scrollWinConnections->Layout();
1607
1608 mSelectedConnection = NULL;
1609 m_buttonAdd->Enable(true);
1610 m_buttonAdd->Show();
1611}
1612
1613void ConnectionsDialog::UpdateSourceList(bool bResort) {
1614 for (size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1615 ConnectionParams* cp = TheConnectionParams()->Item(i);
1616 ConnectionParamsPanel* panel = cp->m_optionsPanel;
1617 if (panel) panel->Update(TheConnectionParams()->Item(i));
1618 }
1619
1620 if (bResort) {
1621 SortSourceList();
1622 }
1623
1624 m_scrollWinConnections->Layout();
1625}
1626
1627void ConnectionsDialog::OnAddDatasourceClick(wxCommandEvent& event) {
1628 // Unselect all panels
1629 for (size_t i = 0; i < TheConnectionParams()->Count(); i++)
1630 TheConnectionParams()->Item(i)->m_optionsPanel->SetSelected(false);
1631
1632 connectionsaved = FALSE;
1633 SetDefaultConnectionParams();
1634
1635 m_sbConnEdit->SetLabel(_("Configure new connection"));
1636
1637 m_buttonRemove->Hide(); // Disable();
1638 m_buttonAdd->Hide(); // Disable();
1639
1640 SetDSFormRWStates();
1641
1642 RecalculateSize();
1643
1644 // Scroll the panel to allow the user to see more of the NMEA parameter
1645 // settings area
1646 wxPoint buttonPosition = m_buttonAdd->GetPosition();
1647 m_container->Scroll(-1, buttonPosition.y / m_parent->GetScrollRate());
1648}
1649
1650void ConnectionsDialog::OnRemoveDatasourceClick(wxCommandEvent& event) {
1651 if (mSelectedConnection) {
1652 // Find the index
1653 int index = -1;
1654 ConnectionParams* cp = NULL;
1655 for (size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1656 cp = TheConnectionParams()->Item(i);
1657 if (mSelectedConnection == cp) {
1658 index = i;
1659 break;
1660 }
1661 }
1662
1663 if ((index >= 0) && (cp)) {
1664 delete TheConnectionParams()->Item(index)->m_optionsPanel;
1665 TheConnectionParams()->RemoveAt(index);
1666 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
1667 mSelectedConnection = NULL;
1668 }
1669 }
1670
1671 // Mark connection deleted
1672 m_rbTypeSerial->SetValue(TRUE);
1673 m_comboPort->SetValue(_T( "Deleted" ));
1674
1675 FillSourceList();
1676 ShowNMEACommon(FALSE);
1677 ShowNMEANet(FALSE);
1678 ShowNMEASerial(FALSE);
1679}
1680
1681void ConnectionsDialog::OnSelectDatasource(wxListEvent& event) {
1682 SetConnectionParams(TheConnectionParams()->Item(event.GetData()));
1683 m_buttonRemove->Enable();
1684 m_buttonRemove->Show();
1685 event.Skip();
1686}
1687
1688void ConnectionsDialog::OnDiscoverButton(wxCommandEvent& event) {
1689#if 0 //FIXME (dave)
1690 wxString ip;
1691 int port;
1692 std::string serviceIdent =
1693 std::string("_signalk-ws._tcp.local."); // Works for node.js server
1694
1695 g_Platform->ShowBusySpinner();
1696
1697 if (SignalKDataStream::DiscoverSKServer(serviceIdent, ip, port,
1698 1)) // 1 second scan
1699 {
1700 m_tNetAddress->SetValue(ip);
1701 m_tNetPort->SetValue(wxString::Format(wxT("%i"), port));
1702 UpdateDiscoverStatus(_("Signal K server available."));
1703 } else {
1704 UpdateDiscoverStatus(_("Signal K server not found."));
1705 }
1706 g_Platform->HideBusySpinner();
1707#endif
1708 event.Skip();
1709}
1710
1711void ConnectionsDialog::UpdateDiscoverStatus(wxString stat) {
1712 m_StaticTextSKServerStatus->SetLabel(stat);
1713}
1714
1715void ConnectionsDialog::OnBtnIStcs(wxCommandEvent& event) {
1716 const ListType type = m_rbIAccept->GetValue() ? WHITELIST : BLACKLIST;
1717 const wxArrayString list =
1718 wxStringTokenize(m_tcInputStc->GetValue(), _T( "," ));
1719 SentenceListDlg dlg(m_parent, FILTER_INPUT, type, list);
1720
1721 if (dlg.ShowModal() == wxID_OK) m_tcInputStc->SetValue(dlg.GetSentences());
1722}
1723
1724void ConnectionsDialog::OnBtnOStcs(wxCommandEvent& event) {
1725 const ListType type = m_rbOAccept->GetValue() ? WHITELIST : BLACKLIST;
1726 const wxArrayString list =
1727 wxStringTokenize(m_tcOutputStc->GetValue(), _T( "," ));
1728 SentenceListDlg dlg(m_parent, FILTER_OUTPUT, type, list);
1729
1730 if (dlg.ShowModal() == wxID_OK) m_tcOutputStc->SetValue(dlg.GetSentences());
1731}
1732
1733void ConnectionsDialog::OnNetProtocolSelected(wxCommandEvent& event) {
1734 if (m_rbNetProtoGPSD->GetValue()) {
1735 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "2947" ));
1736 } else if (m_rbNetProtoUDP->GetValue()) {
1737 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "10110" ));
1738 if (m_tNetAddress->GetValue().IsEmpty())
1739 m_tNetAddress->SetValue(_T( "0.0.0.0" ));
1740 } else if (m_rbNetProtoSignalK->GetValue()) {
1741 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "8375" ));
1742 } else if (m_rbNetProtoTCP->GetValue()) {
1743 if (m_tNetPort->GetValue().IsEmpty()) m_tNetPort->SetValue(_T( "10110" ));
1744 }
1745
1746 SetDSFormRWStates();
1747 OnConnValChange(event);
1748}
1749void ConnectionsDialog::OnRbAcceptInput(wxCommandEvent& event) { OnConnValChange(event); }
1750void ConnectionsDialog::OnRbIgnoreInput(wxCommandEvent& event) { OnConnValChange(event); }
1751
1752void ConnectionsDialog::OnRbOutput(wxCommandEvent& event) { OnConnValChange(event); }
1753
1754void ConnectionsDialog::OnCbInput(wxCommandEvent& event) { OnConnValChange(event); }
1755
1756void ConnectionsDialog::OnCbOutput(wxCommandEvent& event) {
1757 OnConnValChange(event);
1758 const bool checked = m_cbOutput->IsChecked();
1759 m_stPrecision->Enable(checked);
1760 m_choicePrecision->Enable(checked);
1761 m_stTalkerIdText->Enable(checked);
1762 m_TalkerIdText->Enable(checked);
1763}
1764
1765void ConnectionsDialog::OnShowGpsWindowCheckboxClick(wxCommandEvent& event) {
1766 if (!m_cbNMEADebug->GetValue()) {
1767 NMEALogWindow::Get().DestroyWindow();
1768 } else {
1769 NMEALogWindow::Get().Create((wxWindow *)(m_parent->pParent), 35);
1770
1771 // Try to ensure that the log window is a least a little bit visible
1772 wxRect logRect(
1773 NMEALogWindow::Get().GetPosX(), NMEALogWindow::Get().GetPosY(),
1774 NMEALogWindow::Get().GetSizeW(), NMEALogWindow::Get().GetSizeH());
1775
1776 if (m_container->GetRect().Contains(logRect)) {
1777 NMEALogWindow::Get().SetPos(
1778 m_container->GetRect().x / 2,
1779 (m_container->GetRect().y + (m_container->GetRect().height - logRect.height) / 2));
1780 NMEALogWindow::Get().Move();
1781 }
1782
1783 m_parent->Raise();
1784 }
1785}
1786
1787void ConnectionsDialog::ApplySettings(){
1788
1789 g_bfilter_cogsog = m_cbFilterSogCog->GetValue();
1790
1791 long filter_val = 1;
1792 m_tFilterSec->GetValue().ToLong(&filter_val);
1793 g_COGFilterSec =
1794 wxMin(static_cast<int>(filter_val), 60/*MAX_COGSOG_FILTER_SECONDS*/); //FIXME (dave) should be
1795 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
1796 g_SOGFilterSec = g_COGFilterSec;
1797
1798 g_bMagneticAPB = m_cbAPBMagnetic->GetValue();
1799 g_NMEAAPBPrecision = m_choicePrecision->GetCurrentSelection();
1800
1801 // NMEA Source
1802 // If the stream selected exists, capture some of its existing parameters
1803 // to facility identification and allow stop and restart of the stream
1804 wxString lastAddr;
1805 int lastPort = 0;
1806 NetworkProtocol lastNetProtocol = PROTO_UNDEFINED;
1807 DataProtocol lastDataProtocol = PROTO_NMEA0183;
1808
1809 if (mSelectedConnection) {
1810 ConnectionParams* cpo = mSelectedConnection;
1811 lastAddr = cpo->NetworkAddress;
1812 lastPort = cpo->NetworkPort;
1813 lastNetProtocol = cpo->NetProtocol;
1814 lastDataProtocol = cpo->Protocol;
1815 }
1816
1817 if (!connectionsaved) {
1818 size_t nCurrentPanelCount = TheConnectionParams()->GetCount();
1819 ConnectionParams* cp = NULL;
1820 int old_priority = -1;
1821 {
1822 if (mSelectedConnection) {
1823 cp = mSelectedConnection;
1824 old_priority = cp->Priority;
1825 UpdateConnectionParamsFromSelectedItem(cp);
1826 cp->b_IsSetup = false;
1827 cp->bEnabled = false;
1828 if (cp->m_optionsPanel)
1829 cp->m_optionsPanel->SetEnableCheckbox(false);
1830
1831 // delete TheConnectionParams()->Item(itemIndex)->m_optionsPanel;
1832 // old_priority = TheConnectionParams()->Item(itemIndex)->Priority;
1833 // TheConnectionParams()->RemoveAt(itemIndex);
1834 // TheConnectionParams()->Insert(cp, itemIndex);
1835 // mSelectedConnection = cp;
1836 // cp->m_optionsPanel->SetSelected( true );
1837 } else {
1838 cp = CreateConnectionParamsFromSelectedItem();
1839 if (cp) TheConnectionParams()->Add(cp);
1840 }
1841
1842 // Record the previous parameters, if any
1843 if (cp) {
1844 cp->LastNetProtocol = lastNetProtocol;
1845 cp->LastNetworkAddress = lastAddr;
1846 cp->LastNetworkPort = lastPort;
1847 cp->LastDataProtocol = lastDataProtocol;
1848 }
1849
1850 if (TheConnectionParams()->GetCount() != nCurrentPanelCount)
1851 FillSourceList();
1852 else if (old_priority >= 0) {
1853 if (old_priority != cp->Priority) // need resort
1854 UpdateSourceList(true);
1855 else
1856 UpdateSourceList(false);
1857 }
1858
1859 connectionsaved = TRUE;
1860 }
1861 // else {
1862 // ::wxEndBusyCursor();
1863 // if (m_bNMEAParams_shown) event.SetInt(wxID_STOP);
1864 // }
1865
1866 SetSelectedConnectionPanel(nullptr);
1867 }
1868
1869 // Recreate datastreams that are new, or have been edited
1870 for (size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1871 ConnectionParams* cp = TheConnectionParams()->Item(i);
1872
1873 if (cp->b_IsSetup) continue;
1874
1875 // Connection is new, or edited, or disabled
1876
1877 // Terminate and remove any existing driver, if present in registry
1878 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
1879
1880 // Stop and remove "previous" port, in case other params have changed.
1881 StopAndRemoveCommDriver(cp->GetLastDSPort(), cp->GetLastCommProtocol());
1882
1883 // Internal BlueTooth driver stacks commonly need a time delay to purge
1884 // their buffers, etc. before restating with new parameters...
1885 if (cp->Type == INTERNAL_BT) wxSleep(1);
1886
1887 //Connection has been disabled
1888 if (!cp->bEnabled) continue;
1889
1890 //Make any new or re-enabled drivers
1891 MakeCommDriver(cp);
1892 cp->b_IsSetup = TRUE;
1893 }
1894
1895 g_bGarminHostUpload = m_cbGarminUploadHost->GetValue();
1896 g_GPS_Ident =
1897 m_cbFurunoGP3X->GetValue() ? _T( "FurunoGP3X" ) : _T( "Generic" );
1898}
1899
1900ConnectionParams* ConnectionsDialog::CreateConnectionParamsFromSelectedItem(void) {
1901 //FIXME (dave) How could this happen?
1902 //if (!m_bNMEAParams_shown) return NULL;
1903
1904 // Special encoding for deleted connection
1905 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == _T("Deleted" ))
1906 return NULL;
1907
1908 // We check some values here for consistency.
1909 // If necessary, set defaults so user will see some result, however wrong...
1910
1911 // DataStreams should be Input, Output, or Both
1912 if (!(m_cbInput->GetValue() || m_cbOutput->GetValue())) {
1913 m_cbInput->SetValue(true);
1914 }
1915
1916 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == wxEmptyString) {
1917 m_comboPort->Select(0);
1918 }
1919 // TCP, GPSD and UDP require port field to be set.
1920 // TCP clients, GPSD and UDP output sockets require an address
1921 else if (m_rbTypeNet->GetValue()) {
1922 if (wxAtoi(m_tNetPort->GetValue()) == 0) {
1923 m_tNetPort->SetValue(_T("10110")); // reset to default
1924 }
1925 if (m_tNetAddress->GetValue() == wxEmptyString) {
1926 m_tNetAddress->SetValue(_T("0.0.0.0"));
1927 }
1928 }
1929 else if (m_rbTypeCAN->GetValue()){
1930 }
1931
1932 ConnectionParams* pConnectionParams = new ConnectionParams();
1933
1934 UpdateConnectionParamsFromSelectedItem(pConnectionParams);
1935
1937 m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1938 pConnectionParams, this);
1939 pPanel->SetSelected(false);
1940 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxALL, 0);
1941 pConnectionParams->m_optionsPanel = pPanel;
1942
1943 return pConnectionParams;
1944}
1945
1946ConnectionParams* ConnectionsDialog::UpdateConnectionParamsFromSelectedItem(
1947 ConnectionParams* pConnectionParams) {
1948 pConnectionParams->Valid = TRUE;
1949 if (m_rbTypeSerial->GetValue())
1950 pConnectionParams->Type = SERIAL;
1951 else if (m_rbTypeNet->GetValue())
1952 pConnectionParams->Type = NETWORK;
1953 else if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue())
1954 pConnectionParams->Type = INTERNAL_GPS;
1955 else if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue())
1956 pConnectionParams->Type = INTERNAL_BT;
1957 else if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
1958 pConnectionParams->Type = SOCKETCAN;
1959
1960 if (m_rbTypeNet->GetValue()){
1961 // Save the existing addr/port to allow closing of existing port
1962 pConnectionParams->LastNetworkAddress = pConnectionParams->NetworkAddress;
1963 pConnectionParams->LastNetworkPort = pConnectionParams->NetworkPort;
1964 pConnectionParams->LastNetProtocol = pConnectionParams->NetProtocol;
1965 pConnectionParams->LastDataProtocol = pConnectionParams->Protocol;
1966
1967 pConnectionParams->NetworkAddress = m_tNetAddress->GetValue();
1968 pConnectionParams->NetworkPort = wxAtoi(m_tNetPort->GetValue());
1969 if (m_rbNetProtoTCP->GetValue())
1970 pConnectionParams->NetProtocol = TCP;
1971 else if (m_rbNetProtoUDP->GetValue())
1972 pConnectionParams->NetProtocol = UDP;
1973 else if (m_rbNetProtoGPSD->GetValue())
1974 pConnectionParams->NetProtocol = GPSD;
1975 else if (m_rbNetProtoSignalK->GetValue())
1976 pConnectionParams->NetProtocol = SIGNALK;
1977 else
1978 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
1979 }
1980
1981 pConnectionParams->Baudrate = wxAtoi(m_choiceBaudRate->GetStringSelection());
1982 pConnectionParams->Protocol = (DataProtocol)m_choiceSerialProtocol->GetSelection();
1983 pConnectionParams->Priority = wxAtoi(m_choicePriority->GetStringSelection());
1984 pConnectionParams->ChecksumCheck = m_cbCheckCRC->GetValue();
1985 pConnectionParams->AutoSKDiscover = m_cbCheckSKDiscover->GetValue();
1986 pConnectionParams->Garmin = m_cbGarminHost->GetValue();
1987 pConnectionParams->InputSentenceList =
1988 wxStringTokenize(m_tcInputStc->GetValue(), _T(","));
1989 if (m_rbIAccept->GetValue())
1990 pConnectionParams->InputSentenceListType = WHITELIST;
1991 else
1992 pConnectionParams->InputSentenceListType = BLACKLIST;
1993 if (m_cbInput->GetValue()) {
1994 if (m_cbOutput->GetValue()) {
1995 pConnectionParams->IOSelect = DS_TYPE_INPUT_OUTPUT;
1996 } else {
1997 pConnectionParams->IOSelect = DS_TYPE_INPUT;
1998 }
1999 } else
2000 pConnectionParams->IOSelect = DS_TYPE_OUTPUT;
2001
2002 pConnectionParams->OutputSentenceList =
2003 wxStringTokenize(m_tcOutputStc->GetValue(), _T(","));
2004 if (m_rbOAccept->GetValue())
2005 pConnectionParams->OutputSentenceListType = WHITELIST;
2006 else
2007 pConnectionParams->OutputSentenceListType = BLACKLIST;
2008 pConnectionParams->Port = m_comboPort->GetValue().BeforeFirst(' ');
2009#if defined(__linux__) && !defined(__OCPN__ANDROID__)
2010 if (pConnectionParams->Type == SERIAL)
2011 CheckSerialAccess(m_parent, pConnectionParams->Port.ToStdString());
2012#endif
2013
2014 if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
2015 pConnectionParams->Protocol = PROTO_NMEA2000;
2016
2017 pConnectionParams->bEnabled = m_connection_enabled;
2018 pConnectionParams->b_IsSetup = FALSE;
2019
2020 if (pConnectionParams->Type == INTERNAL_GPS) {
2021 pConnectionParams->NetworkAddress = _T("");
2022 pConnectionParams->NetworkPort = 0;
2023 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2024 pConnectionParams->Baudrate = 0;
2025 }
2026
2027 if (pConnectionParams->Type == INTERNAL_BT) {
2028 wxString parms = m_choiceBTDataSources->GetStringSelection();
2029 wxStringTokenizer tkz(parms, _T(";"));
2030 wxString name = tkz.GetNextToken();
2031 wxString mac = tkz.GetNextToken();
2032
2033 pConnectionParams->NetworkAddress = name;
2034 pConnectionParams->Port = mac;
2035 pConnectionParams->NetworkPort = 0;
2036 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2037 pConnectionParams->Baudrate = 0;
2038 // pConnectionParams->SetAuxParameterStr(m_choiceBTDataSources->GetStringSelection());
2039 }
2040
2041 if (pConnectionParams->Type == SOCKETCAN) {
2042 pConnectionParams->NetworkAddress = _T("");
2043 pConnectionParams->NetworkPort = 0;
2044 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2045 pConnectionParams->Baudrate = 0;
2046 pConnectionParams->socketCAN_port = m_choiceCANSource->GetString(m_choiceCANSource->GetSelection());
2047 }
2048
2049 if (pConnectionParams->Type == SERIAL) {
2050 pConnectionParams->UserComment = m_tSerialComment->GetValue();
2051 } else if (pConnectionParams->Type == NETWORK) {
2052 pConnectionParams->UserComment = m_tNetComment->GetValue();
2053 }
2054
2055 return pConnectionParams;
2056}
2057
2058void ConnectionsDialog::OnPriorityDialog(wxCommandEvent &event){
2059
2060 PriorityDlg *pdlg = new PriorityDlg(m_parent);
2061 pdlg->ShowModal();
2062
2063}
2064
2065
2066SentenceListDlg::SentenceListDlg(wxWindow* parent, FilterDirection dir,
2067 ListType type, const wxArrayString& list)
2068 : wxDialog(parent, wxID_ANY, _("Sentence Filter"), wxDefaultPosition,
2069 wxSize(280, 420)),
2070 m_type(type),
2071 m_dir(dir),
2072 m_sentences(NMEA0183().GetRecognizedArray()) {
2073 wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
2074 wxBoxSizer* secondSizer = new wxBoxSizer(wxHORIZONTAL);
2075 wxStaticBox* pclbBox = new wxStaticBox(this, wxID_ANY, GetBoxLabel());
2076 wxStaticBoxSizer* stcSizer = new wxStaticBoxSizer(pclbBox, wxVERTICAL);
2077 m_clbSentences = new wxCheckListBox(this, wxID_ANY, wxDefaultPosition,
2078 wxDefaultSize, m_sentences);
2079 wxBoxSizer* btnEntrySizer = new wxBoxSizer(wxVERTICAL);
2080 wxButton* btnCheckAll = new wxButton(this, wxID_ANY, _("Select All"));
2081 wxButton* btnClearAll = new wxButton(this, wxID_ANY, _("Clear All"));
2082 wxButton* btnAdd = new wxButton(this, wxID_ANY, _("Add"));
2083 m_btnDel = new wxButton(this, wxID_ANY, _("Delete"));
2084 m_btnDel->Disable();
2085 wxStdDialogButtonSizer* btnSizer = new wxStdDialogButtonSizer();
2086 wxButton* btnOK = new wxButton(this, wxID_OK);
2087 wxButton* btnCancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
2088
2089 secondSizer->Add(stcSizer, 1, wxALL | wxEXPAND, 5);
2090 stcSizer->Add(m_clbSentences, 1, wxALL | wxEXPAND, 5);
2091 btnEntrySizer->Add(btnCheckAll, 0, wxALL, 5);
2092 btnEntrySizer->Add(btnClearAll, 0, wxALL, 5);
2093 btnEntrySizer->AddSpacer(1);
2094 btnEntrySizer->Add(btnAdd, 0, wxALL, 5);
2095 btnEntrySizer->Add(m_btnDel, 0, wxALL, 5);
2096 secondSizer->Add(btnEntrySizer, 0, wxALL | wxEXPAND, 5);
2097 mainSizer->Add(secondSizer, 1, wxEXPAND, 5);
2098 btnSizer->AddButton(btnOK);
2099 btnSizer->AddButton(btnCancel);
2100 btnSizer->Realize();
2101 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
2102
2103 SetSizer(mainSizer);
2104 mainSizer->SetSizeHints(this);
2105 Centre();
2106
2107 // Connect Events
2108 btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2109 wxCommandEventHandler(SentenceListDlg::OnAddClick), NULL,
2110 this);
2111 m_btnDel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2112 wxCommandEventHandler(SentenceListDlg::OnDeleteClick), NULL,
2113 this);
2114 m_clbSentences->Connect(wxEVT_COMMAND_LISTBOX_SELECTED,
2115 wxCommandEventHandler(SentenceListDlg::OnCLBSelect),
2116 NULL, this);
2117 btnCheckAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2118 wxCommandEventHandler(SentenceListDlg::OnCheckAllClick),
2119 NULL, this);
2120 btnClearAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2121 wxCommandEventHandler(SentenceListDlg::OnClearAllClick),
2122 NULL, this);
2123
2124 Populate(list);
2125}
2126
2127wxString SentenceListDlg::GetBoxLabel(void) const {
2128 if (m_dir == FILTER_OUTPUT)
2129 return m_type == WHITELIST ? _("Transmit sentences") : _("Drop sentences");
2130 else
2131 return m_type == WHITELIST ? _("Accept only sentences")
2132 : _("Ignore sentences");
2133}
2134
2135void SentenceListDlg::Populate(const wxArrayString& list) {
2136 if (m_dir == FILTER_OUTPUT) {
2137 m_sentences.Add(_T("ECRMB"));
2138 m_sentences.Add(_T("ECRMC"));
2139 m_sentences.Add(_T("ECAPB"));
2140 }
2141 m_sentences.Add(_T("AIVDM"));
2142 m_sentences.Add(_T("AIVDO"));
2143 m_sentences.Add(_T("FRPOS"));
2144 m_sentences.Add(_T("CD"));
2145 m_clbSentences->Clear();
2146 m_clbSentences->InsertItems(m_sentences, 0);
2147
2148 if (list.Count() == 0) {
2149 for (size_t i = 0; i < m_clbSentences->GetCount(); ++i)
2150 m_clbSentences->Check(i, m_type == WHITELIST);
2151 } else {
2152 m_clbSentences->InsertItems(list, m_sentences.GetCount());
2153 for (size_t i = 0; i < list.Count(); ++i) {
2154 int item = m_clbSentences->FindString(list[i]);
2155 if (item != wxNOT_FOUND) m_clbSentences->Check(item);
2156 }
2157 }
2158}
2159
2160wxString SentenceListDlg::GetSentences(void) {
2161 wxArrayString retString;
2162 for (size_t i = 0; i < m_clbSentences->GetCount(); i++) {
2163 if (m_clbSentences->IsChecked(i))
2164 retString.Add(m_clbSentences->GetString(i));
2165 }
2166 return StringArrayToString(retString);
2167}
2168
2169void SentenceListDlg::OnCLBSelect(wxCommandEvent& e) {
2170 // Only activate the "Delete" button if the selection is not in the standard
2171 // list
2172 m_btnDel->Enable(m_sentences.Index(e.GetString()) == wxNOT_FOUND);
2173}
2174
2175void SentenceListDlg::OnAddClick(wxCommandEvent& event) {
2176#ifdef __OCPN__ANDROID__
2177 androidDisableRotation();
2178#endif
2179
2180 wxTextEntryDialog textdlg(
2181 this,
2182 _("Enter the NMEA sentence (2, 3 or 5 characters)\n or a valid REGEX "
2183 "expression (6 characters or longer)"),
2184 _("Enter the NMEA sentence"));
2185
2186 textdlg.SetTextValidator(wxFILTER_ASCII);
2187 int result = textdlg.ShowModal();
2188
2189#ifdef __OCPN__ANDROID__
2190 androidEnableRotation();
2191#endif
2192
2193 if (result == wxID_CANCEL) return;
2194 wxString stc = textdlg.GetValue();
2195
2196 if (stc.Length() == 2 || stc.Length() == 3 || stc.Length() == 5) {
2197 m_clbSentences->Append(stc);
2198 m_clbSentences->Check(m_clbSentences->FindString(stc));
2199 return;
2200 } else if (stc.Length() < 2) {
2201 OCPNMessageBox(
2202 this,
2203 _("An NMEA sentence is generally 3 characters long (like RMC, GGA etc.)\n \
2204 It can also have a two letter prefix identifying the source, or TALKER, of the message.\n \
2205 The whole sentences then looks like GPGGA or AITXT.\n \
2206 You may filter out all the sentences with certain TALKER prefix (like GP, AI etc.).\n \
2207 The filter also accepts Regular Expressions (REGEX) with 6 or more characters. \n\n"),
2208 _("OpenCPN Info"));
2209 return;
2210 }
2211
2212 else {
2213 // Verify that a longer text entry is a valid RegEx
2214 wxRegEx r(stc);
2215 if (r.IsValid()) {
2216 m_clbSentences->Append(stc);
2217 m_clbSentences->Check(m_clbSentences->FindString(stc));
2218 return;
2219 } else {
2220 OCPNMessageBox(this, _("REGEX syntax error: \n") + stc,
2221 _("OpenCPN Info"));
2222 return;
2223 }
2224 }
2225}
2226
2227void SentenceListDlg::OnDeleteClick(wxCommandEvent& event) {
2228 m_clbSentences->Delete(m_clbSentences->GetSelection());
2229}
2230
2231void SentenceListDlg::OnClearAllClick(wxCommandEvent& event) {
2232 for (size_t i = 0; i < m_clbSentences->GetCount(); i++)
2233 m_clbSentences->Check(i, FALSE);
2234}
2235
2236void SentenceListDlg::OnCheckAllClick(wxCommandEvent& event) {
2237 for (size_t i = 0; i < m_clbSentences->GetCount(); i++)
2238 m_clbSentences->Check(i, TRUE);
2239}
2240
2241void ConnectionsDialog::SetNMEAFormForProtocol() {
2242 bool n0183ctlenabled = (DataProtocol)m_choiceSerialProtocol->GetSelection() == DataProtocol::PROTO_NMEA0183;
2243 ShowNMEACommon(n0183ctlenabled);
2244 m_cbGarminHost->Show(n0183ctlenabled);
2245 m_stPriority->Show(true);
2246 m_choicePriority->Show(true);
2247 m_container->FitInside();
2248 RecalculateSize();
2249 SetDSFormRWStates();
2250}
2251
2252void ConnectionsDialog::OnProtocolChoice(wxCommandEvent &event) {
2253 SetNMEAFormForProtocol();
2254 OnConnValChange(event);
2255}