39#include <wx/tokenzr.h>
42#if defined(__linux__) && !defined(__ANDROID__)
44#include <linux/can/raw.h>
48#include <sys/socket.h>
53#include "androidUTIL.h"
57#include "model/comm_drv_factory.h"
58#include "model/config_vars.h"
60#include "model/ser_ports.h"
64#include "conn_params_panel.h"
67#include "OCPNPlatform.h"
70#include "priority_gui.h"
75static wxString StringArrayToString(
const wxArrayString& arr) {
76 wxString ret = wxEmptyString;
77 for (
size_t i = 0; i < arr.Count(); i++) {
78 if (i > 0) ret.Append(
",");
86#if defined(__linux__) && !defined(__ANDROID__)
88std::vector<std::string> can_if_candidates;
89static int print_intf(
const struct intf_entry* entry,
void* arg) {
90 std::string iface = entry->intf_name;
91 if (entry->intf_type == 1 && iface.find(
"can") != std::string::npos) {
92 can_if_candidates.push_back(entry->intf_name);
98static wxArrayString GetAvailableSocketCANInterfaces() {
101#if defined(__linux__) && !defined(__ANDROID__)
102 struct intf_entry* entry;
104 can_if_candidates.clear();
106 if ((intf = intf_open()) == NULL) {
107 wxLogWarning(
"Error opening interface list");
110 if (intf_loop(intf, print_intf, NULL) < 0) {
111 wxLogWarning(
"Error looping over interface list");
115 for (
const auto& iface : can_if_candidates) {
116 int sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
122 struct ifreq if_request;
123 strcpy(if_request.ifr_name, iface.c_str());
124 if (ioctl(sock, SIOCGIFINDEX, &if_request) < 0) {
129 struct sockaddr_can can_address;
130 can_address.can_family = AF_CAN;
131 can_address.can_ifindex = if_request.ifr_ifindex;
132 if (ioctl(sock, SIOCGIFFLAGS, &if_request) < 0) {
135 if (if_request.ifr_flags & IFF_UP) {
145static void LoadSerialPorts(wxComboBox* box) {
149 std::string GetKey(
const std::string& s)
const {
150 if (s.find(
"->") == std::string::npos)
return s;
155 bool operator()(
const std::string& lhs,
const std::string& rhs)
const {
156 return GetKey(lhs) < GetKey(rhs);
160 std::set<std::string, PortSorter> sorted_ports(port_sorter);
161 std::unique_ptr<wxArrayString> ports(EnumerateSerialPorts());
162 for (
size_t i = 0; i < ports->GetCount(); i++)
163 sorted_ports.insert((*ports)[i].ToStdString());
166 for (
auto& p : sorted_ports) box->Append(p);
178ConnectionEditDialog::ConnectionEditDialog() {}
180ConnectionEditDialog::ConnectionEditDialog(wxWindow* parent)
181 : wxDialog(parent, wxID_ANY, _(
"Connection Edit"), wxDefaultPosition,
191ConnectionEditDialog::~ConnectionEditDialog() {}
193void ConnectionEditDialog::SetInitialSettings(
void) {
194 LoadSerialPorts(m_comboPort);
197void ConnectionEditDialog::Init() {
198 MORE =
"<span foreground=\'blue\'>";
200 MORE +=
"...</span>";
201 LESS =
"<span foreground=\'blue\'>";
203 LESS +=
"...</span>";
211 m_choiceBTDataSources = 0;
213 m_BTScanTimer.SetOwner(
this, ID_BT_SCANTIMER);
215 wxSize displaySize = wxGetDisplaySize();
219 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
221 wxBoxSizer* boxSizer02 =
new wxBoxSizer(wxVERTICAL);
222 mainSizer->Add(boxSizer02, 1, wxEXPAND | wxALL, 2);
225 new wxScrolledWindow(
this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1),
226 wxTAB_TRAVERSAL | wxVSCROLL);
227 m_scrolledwin->SetScrollRate(0, 5);
228 boxSizer02->Add(m_scrolledwin, 1, wxALL | wxEXPAND, 3);
230 auto boxSizerSWin =
new wxBoxSizer(wxVERTICAL);
231 m_scrolledwin->SetSizer(boxSizerSWin);
233 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
234 wxButton* btnOK =
new wxButton(
this, wxID_OK);
235 wxButton* btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"Cancel"));
236 btnSizer->AddButton(btnOK);
237 btnSizer->AddButton(btnCancel);
239 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
243 int group_item_spacing = 2;
245 wxFont* dFont = GetOCPNScaledFont_PlugIn(_(
"Dialog"));
246 double font_size = dFont->GetPointSize() * 17 / 16;
247 wxFont* bFont = wxTheFontList->FindOrCreateFont(
248 font_size, dFont->GetFamily(), dFont->GetStyle(), wxFONTWEIGHT_BOLD);
257 new wxStaticBox(m_scrolledwin, wxID_ANY, _(
"Edit Selected Connection"));
258 m_sbConnEdit->SetFont(*bFont);
260 sbSizerConnectionProps =
new wxStaticBoxSizer(m_sbConnEdit, wxVERTICAL);
261 m_scrolledwin->GetSizer()->Add(sbSizerConnectionProps, 1, wxALL | wxEXPAND,
264 wxBoxSizer* bSizer15;
265 bSizer15 =
new wxBoxSizer(wxHORIZONTAL);
267 sbSizerConnectionProps->Add(bSizer15, 0, wxTOP | wxEXPAND, 5);
271 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Serial"), wxDefaultPosition,
272 wxDefaultSize, wxRB_GROUP);
273 m_rbTypeSerial->SetValue(TRUE);
274 bSizer15->Add(m_rbTypeSerial, 0, wxALL, 5);
276 m_rbTypeNet =
new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Network"),
277 wxDefaultPosition, wxDefaultSize, 0);
278 bSizer15->Add(m_rbTypeNet, 0, wxALL, 5);
280 m_rbTypeCAN =
new wxRadioButton(m_scrolledwin, wxID_ANY,
"socketCAN",
281 wxDefaultPosition, wxDefaultSize, 0);
282#if defined(__linux__) && !defined(__ANDROID__) && !defined(__WXOSX__)
283 bSizer15->Add(m_rbTypeCAN, 0, wxALL, 5);
288 wxBoxSizer* bSizer15a =
new wxBoxSizer(wxHORIZONTAL);
289 sbSizerConnectionProps->Add(bSizer15a, 0, wxEXPAND, 5);
291 if (OCPNPlatform::hasInternalGPS()) {
292 m_rbTypeInternalGPS =
293 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Built-in GPS"),
294 wxDefaultPosition, wxDefaultSize, 0);
295 bSizer15a->Add(m_rbTypeInternalGPS, 0, wxALL, 5);
297 m_rbTypeInternalGPS = NULL;
300 if (OCPNPlatform::hasInternalBT()) {
302 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Built-in Bluetooth SPP"),
303 wxDefaultPosition, wxDefaultSize, 0);
304 bSizer15a->Add(m_rbTypeInternalBT, 0, wxALL, 5);
306 m_buttonScanBT =
new wxButton(m_scrolledwin, wxID_ANY, _(
"BT Scan"),
307 wxDefaultPosition, wxDefaultSize);
308 m_buttonScanBT->Hide();
313 sbSizerConnectionProps->Add(m_buttonScanBT, 0, wxALL, 5);
316 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Bluetooth Data Sources"),
317 wxDefaultPosition, wxDefaultSize, 0);
318 m_stBTPairs->Wrap(-1);
320 sbSizerConnectionProps->Add(m_stBTPairs, 0, wxALL, 5);
325 int ref_size = m_scrolledwin->GetCharWidth();
326 m_choiceBTDataSources =
327 new wxChoice(m_scrolledwin, wxID_ANY, wxDefaultPosition,
328 wxSize(40 * ref_size, 2 * ref_size), mt);
331 m_choiceBTDataSources->SetSelection(0);
332 m_choiceBTDataSources->Hide();
333 sbSizerConnectionProps->Add(m_choiceBTDataSources, 1, wxEXPAND | wxTOP, 5);
336 m_rbTypeInternalBT = NULL;
338 gSizerNetProps =
new wxFlexGridSizer(0, 2, 0, 0);
340 sbSizerConnectionProps->Add(gSizerNetProps, 0, wxEXPAND, 5);
343 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Network Protocol"),
344 wxDefaultPosition, wxDefaultSize, 0);
345 m_stNetProto->Wrap(-1);
346 gSizerNetProps->Add(m_stNetProto, 0, wxALL, 5);
348 wxBoxSizer* bSizer16;
349 bSizer16 =
new wxBoxSizer(wxHORIZONTAL);
350 gSizerNetProps->Add(bSizer16, 1, wxEXPAND, 5);
351 gSizerNetProps->AddSpacer(1);
352 gSizerNetProps->AddSpacer(1);
355 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"TCP"), wxDefaultPosition,
356 wxDefaultSize, wxRB_GROUP);
357 m_rbNetProtoTCP->Enable(TRUE);
358 m_rbNetProtoTCP->SetValue(TRUE);
360 bSizer16->Add(m_rbNetProtoTCP, 0, wxALL, 5);
362 m_rbNetProtoUDP =
new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"UDP"),
363 wxDefaultPosition, wxDefaultSize, 0);
364 m_rbNetProtoUDP->Enable(TRUE);
366 bSizer16->Add(m_rbNetProtoUDP, 0, wxALL, 5);
369 if (displaySize.x < displaySize.y) {
370 wxBoxSizer* bSizer16a;
371 bSizer16a =
new wxBoxSizer(wxHORIZONTAL);
372 gSizerNetProps->AddSpacer(1);
373 gSizerNetProps->Add(bSizer16a, 1, wxEXPAND, 5);
374 gSizerNetProps->AddSpacer(1);
375 gSizerNetProps->AddSpacer(1);
376 m_rbNetProtoGPSD =
new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"GPSD"),
377 wxDefaultPosition, wxDefaultSize, 0);
378 m_rbNetProtoGPSD->Enable(TRUE);
379 bSizer16a->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
381 m_rbNetProtoSignalK =
382 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Signal K"),
383 wxDefaultPosition, wxDefaultSize, 0);
384 m_rbNetProtoSignalK->Enable(TRUE);
385 bSizer16a->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
387 m_rbNetProtoGPSD =
new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"GPSD"),
388 wxDefaultPosition, wxDefaultSize, 0);
389 m_rbNetProtoGPSD->Enable(TRUE);
390 bSizer16->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
392 m_rbNetProtoSignalK =
393 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Signal K"),
394 wxDefaultPosition, wxDefaultSize, 0);
395 m_rbNetProtoSignalK->Enable(TRUE);
396 bSizer16->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
399 m_stNetDataProtocol =
400 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Data Protocol"),
401 wxDefaultPosition, wxDefaultSize, 0);
402 m_stNetDataProtocol->Wrap(-1);
404 gSizerNetProps->Add(m_stNetDataProtocol, 0, wxALL, 5);
406 wxString m_choiceNetProtocolChoices[] = {_(
"NMEA 0183"), _(
"NMEA 2000")};
407 int m_choiceNetProtocolNChoices =
408 sizeof(m_choiceNetProtocolChoices) /
sizeof(wxString);
409 m_choiceNetDataProtocol =
410 new wxChoice(m_scrolledwin, wxID_ANY, wxDefaultPosition, wxDefaultSize,
411 m_choiceNetProtocolNChoices, m_choiceNetProtocolChoices, 0);
414 m_choiceNetDataProtocol->SetSelection(0);
415 m_choiceNetDataProtocol->Enable(TRUE);
417 gSizerNetProps->Add(m_choiceNetDataProtocol, 1, wxEXPAND | wxTOP, 5);
418 gSizerNetProps->AddSpacer(1);
419 gSizerNetProps->AddSpacer(1);
421 m_stNetAddr =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Address"),
422 wxDefaultPosition, wxDefaultSize, 0);
423 m_stNetAddr->Wrap(-1);
424 int column1width = 16 * m_stNetProto->GetCharWidth();
425 m_stNetAddr->SetMinSize(wxSize(column1width, -1));
426 gSizerNetProps->Add(m_stNetAddr, 0, wxALL, 5);
428 m_tNetAddress =
new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString,
429 wxDefaultPosition, wxDefaultSize, 0);
430 int column2width = 40 * m_scrolledwin->GetCharWidth();
431 m_tNetAddress->SetMaxSize(wxSize(column2width, -1));
432 m_tNetAddress->SetMinSize(wxSize(column2width, -1));
434 gSizerNetProps->Add(m_tNetAddress, 0, wxEXPAND | wxTOP, 5);
435 gSizerNetProps->AddSpacer(1);
436 gSizerNetProps->AddSpacer(1);
438 m_stNetPort =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"DataPort"),
439 wxDefaultPosition, wxDefaultSize, 0);
440 m_stNetPort->Wrap(-1);
441 gSizerNetProps->Add(m_stNetPort, 0, wxALL, 5);
443 m_tNetPort =
new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString,
444 wxDefaultPosition, wxDefaultSize, 0);
445 gSizerNetProps->Add(m_tNetPort, 1, wxEXPAND | wxTOP, 5);
446 gSizerNetProps->AddSpacer(1);
447 gSizerNetProps->AddSpacer(1);
449 gSizerCanProps =
new wxGridSizer(0, 1, 0, 0);
451 wxFlexGridSizer* fgSizer1C;
452 fgSizer1C =
new wxFlexGridSizer(0, 2, 0, 0);
457 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"socketCAN Source"),
458 wxDefaultPosition, wxDefaultSize, 0);
459 m_stCANSource->Wrap(-1);
460 m_stCANSource->SetMinSize(wxSize(column1width, -1));
461 fgSizer1C->Add(m_stCANSource, 0, wxALL, 5);
463 wxArrayString choices = GetAvailableSocketCANInterfaces();
464 m_choiceCANSource =
new wxChoice(m_scrolledwin, wxID_ANY, wxDefaultPosition,
465 wxDefaultSize, choices);
467 m_choiceCANSource->SetSelection(0);
468 m_choiceCANSource->Enable(TRUE);
469 m_choiceCANSource->SetMaxSize(wxSize(column2width, -1));
470 m_choiceCANSource->SetMinSize(wxSize(column2width, -1));
471 fgSizer1C->Add(m_choiceCANSource, 1, wxEXPAND | wxTOP, 5);
473 gSizerCanProps->Add(fgSizer1C, 0, wxEXPAND, 5);
475 sbSizerConnectionProps->Add(gSizerCanProps, 0, wxEXPAND, 5);
477 gSizerSerProps =
new wxGridSizer(0, 1, 0, 0);
478 sbSizerConnectionProps->Add(gSizerSerProps, 0, wxEXPAND, 5);
480 wxFlexGridSizer* fgSizer1;
481 fgSizer1 =
new wxFlexGridSizer(0, 4, 0, 0);
482 fgSizer1->SetFlexibleDirection(wxBOTH);
483 fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
486 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Data port"),
487 wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
488 m_stSerPort->SetMinSize(wxSize(column1width, -1));
489 m_stSerPort->Wrap(-1);
491 fgSizer1->Add(m_stSerPort, 0, wxALL, 5);
493 m_comboPort =
new wxComboBox(m_scrolledwin, wxID_ANY, wxEmptyString,
494 wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
496 m_comboPort->SetMaxSize(wxSize(column2width, -1));
497 m_comboPort->SetMinSize(wxSize(column2width, -1));
499 fgSizer1->Add(m_comboPort, 0, wxEXPAND | wxTOP, 5);
501 m_stSerBaudrate =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Baudrate"),
502 wxDefaultPosition, wxDefaultSize, 0);
503 m_stSerBaudrate->Wrap(-1);
504 fgSizer1->AddSpacer(1);
505 fgSizer1->AddSpacer(1);
506 fgSizer1->Add(m_stSerBaudrate, 0, wxALL, 5);
508 wxString m_choiceBaudRateChoices[] = {
509 _(
"150"), _(
"300"), _(
"600"), _(
"1200"), _(
"2400"),
510 _(
"4800"), _(
"9600"), _(
"19200"), _(
"38400"), _(
"57600"),
511 _(
"115200"), _(
"230400"), _(
"460800"), _(
"921600")};
512 int m_choiceBaudRateNChoices =
513 sizeof(m_choiceBaudRateChoices) /
sizeof(wxString);
515 new wxChoice(m_scrolledwin, wxID_ANY, wxDefaultPosition, wxDefaultSize,
516 m_choiceBaudRateNChoices, m_choiceBaudRateChoices, 0);
520 m_choiceBaudRate->SetSelection(0);
522 fgSizer1->Add(m_choiceBaudRate, 1, wxEXPAND | wxTOP, 5);
523 fgSizer1->AddSpacer(1);
524 fgSizer1->AddSpacer(1);
526 m_stSerProtocol =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Protocol"),
527 wxDefaultPosition, wxDefaultSize, 0);
528 m_stSerProtocol->Wrap(-1);
529 fgSizer1->Add(m_stSerProtocol, 0, wxALL, 5);
531 wxString m_choiceSerialProtocolChoices[] = {_(
"NMEA 0183"), _(
"NMEA 2000")};
532 int m_choiceSerialProtocolNChoices =
533 sizeof(m_choiceSerialProtocolChoices) /
sizeof(wxString);
534 m_choiceSerialProtocol =
new wxChoice(
535 m_scrolledwin, wxID_ANY, wxDefaultPosition, wxDefaultSize,
536 m_choiceSerialProtocolNChoices, m_choiceSerialProtocolChoices, 0);
540 m_choiceSerialProtocol->SetSelection(0);
541 m_choiceSerialProtocol->Enable(TRUE);
542 fgSizer1->Add(m_choiceSerialProtocol, 1, wxEXPAND | wxTOP, 5);
544 gSizerSerProps->Add(fgSizer1, 0, wxEXPAND, 5);
548 wxFlexGridSizer* commentSizer =
new wxFlexGridSizer(0, 2, 0, 0);
552 m_stNetComment =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Description"),
553 wxDefaultPosition, wxDefaultSize, 0);
554 m_stNetComment->Wrap(-1);
555 m_stNetComment->SetMinSize(wxSize(column1width, -1));
556 commentSizer->Add(m_stNetComment, 0, wxALL, 5);
558 m_tNetComment =
new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString,
559 wxDefaultPosition, wxDefaultSize, 0);
560 m_tNetComment->SetMaxSize(wxSize(column2width, -1));
561 m_tNetComment->SetMinSize(wxSize(column2width, -1));
563 commentSizer->Add(m_tNetComment, 1, wxEXPAND | wxTOP, 5);
567 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"User Comment"),
568 wxDefaultPosition, wxDefaultSize, 0);
569 m_stSerialComment->Wrap(-1);
570 m_stSerialComment->SetMinSize(wxSize(column1width, -1));
571 commentSizer->Add(m_stSerialComment, 0, wxALL, 5);
573 m_tSerialComment =
new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString,
574 wxDefaultPosition, wxDefaultSize, 0);
575 m_tSerialComment->SetMaxSize(wxSize(column2width, -1));
576 m_tSerialComment->SetMinSize(wxSize(column2width, -1));
578 commentSizer->Add(m_tSerialComment, 1, wxTOP, 5);
580 sbSizerConnectionProps->Add(commentSizer, 0, wxEXPAND, 5);
582 wxFlexGridSizer* fgSizer5;
583 fgSizer5 =
new wxFlexGridSizer(0, 2, 0, 0);
584 fgSizer5->SetFlexibleDirection(wxBOTH);
585 fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
586 sbSizerConnectionProps->Add(fgSizer5, 0, wxEXPAND, 5);
589 new wxCheckBox(m_scrolledwin, wxID_ANY, _(
"Receive Input on this Port"),
590 wxDefaultPosition, wxDefaultSize, 0);
591 fgSizer5->Add(m_cbInput, 0, wxALL, 2);
592 fgSizer5->AddSpacer(1);
595 new wxCheckBox(m_scrolledwin, wxID_ANY,
596 wxString::Format(
"%s (%s)", _(
"Output on this port"),
597 _(
"as autopilot or NMEA repeater")),
598 wxDefaultPosition, wxDefaultSize, 0);
599 fgSizer5->Add(m_cbOutput, 0, wxALL, 2);
600 fgSizer5->AddSpacer(1);
604 m_stAuthToken =
new wxStaticText(m_scrolledwin, wxID_ANY, _(
"Auth Token"),
605 wxDefaultPosition, wxDefaultSize, 0);
606 m_stAuthToken->SetMinSize(wxSize(column1width, -1));
607 m_stAuthToken->Wrap(-1);
608 fgSizer5->Add(m_stAuthToken, 0, wxALL, 5);
609 m_stAuthToken->Hide();
611 m_tAuthToken =
new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString,
612 wxDefaultPosition, wxDefaultSize, 0);
613 m_tAuthToken->SetMinSize(wxSize(column2width, -1));
614 fgSizer5->Add(m_tAuthToken, 1, wxEXPAND | wxTOP, 5);
616 m_tAuthToken->Hide();
618 m_cbCheckCRC =
new wxCheckBox(m_scrolledwin, wxID_ANY, _(
"Control checksum"),
619 wxDefaultPosition, wxDefaultSize, 0);
620 m_cbCheckCRC->SetValue(TRUE);
621 m_cbCheckCRC->SetToolTip(
622 _(
"If checked, only the sentences with a valid checksum are passed "
624 fgSizer5->Add(m_cbCheckCRC, 0, wxALL, 2);
625 fgSizer5->AddSpacer(1);
627 m_cbGarminHost =
new wxCheckBox(m_scrolledwin, wxID_ANY,
628 _(
"Use Garmin (GRMN) mode for input"),
629 wxDefaultPosition, wxDefaultSize, 0);
630 m_cbGarminHost->SetValue(FALSE);
631 fgSizer5->Add(m_cbGarminHost, 0, wxALL, 2);
632 fgSizer5->AddSpacer(1);
634#ifndef USE_GARMINHOST
635 m_cbGarminHost->Hide();
638 m_cbMultiCast =
new wxCheckBox(m_scrolledwin, wxID_ANY, _(
" UDP Multicast"),
639 wxDefaultPosition, wxDefaultSize, 0);
640 m_cbMultiCast->SetValue(FALSE);
643 fgSizer5->Add(m_cbMultiCast, 0, wxALL, 2);
644 fgSizer5->AddSpacer(1);
647 new wxStaticText(m_scrolledwin, wxID_ANY, _(
"APB bearing precision"),
648 wxDefaultPosition, wxDefaultSize, 0);
650 m_stPrecision->Wrap(-1);
651 fgSizer5->Add(m_stPrecision, 0, wxALL, 2);
653 wxString m_choicePrecisionChoices[] = {_(
"x"), _(
"x.x"), _(
"x.xx"),
654 _(
"x.xxx"), _(
"x.xxxx")};
655 int m_choicePrecisionNChoices =
656 sizeof(m_choicePrecisionChoices) /
sizeof(wxString);
658 new wxChoice(m_scrolledwin, wxID_ANY, wxDefaultPosition, wxDefaultSize,
659 m_choicePrecisionNChoices, m_choicePrecisionChoices, 0);
663 m_choicePrecision->SetSelection(g_NMEAAPBPrecision);
664 fgSizer5->Add(m_choicePrecision, 0, wxALL, 2);
667 m_cbCheckSKDiscover =
668 new wxCheckBox(m_scrolledwin, wxID_ANY, _(
"Automatic server discovery"),
669 wxDefaultPosition, wxDefaultSize, 0);
670 m_cbCheckSKDiscover->SetValue(TRUE);
671 m_cbCheckSKDiscover->SetToolTip(
672 _(
"If checked, signal K server will be discovered automatically"));
674 fgSizer5->Add(m_cbCheckSKDiscover, 0, wxALL, 2);
678 new wxButton(m_scrolledwin, wxID_ANY, _(
"Discover now..."),
679 wxDefaultPosition, wxDefaultSize, 0);
680 m_ButtonSKDiscover->Hide();
681 fgSizer5->Add(m_ButtonSKDiscover, 0, wxALL, 2);
684 m_StaticTextSKServerStatus =
new wxStaticText(
685 m_scrolledwin, wxID_ANY,
"", wxDefaultPosition, wxDefaultSize, 0);
686 fgSizer5->Add(m_StaticTextSKServerStatus, 0, wxALL, 2);
688 sbSizerInFilter =
new wxStaticBoxSizer(
689 new wxStaticBox(m_scrolledwin, wxID_ANY, _(
"Input filtering")),
691 sbSizerConnectionProps->Add(sbSizerInFilter,
692 wxSizerFlags().Expand().Border());
695 bSizer9 =
new wxBoxSizer(wxHORIZONTAL);
698 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Accept only sentences"),
699 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
700 bSizer9->Add(m_rbIAccept, 0, wxALL, 5);
703 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Ignore sentences"),
704 wxDefaultPosition, wxDefaultSize, 0);
705 bSizer9->Add(m_rbIIgnore, 0, wxALL, 5);
707 sbSizerInFilter->Add(bSizer9, 0, wxEXPAND, 5);
709 wxBoxSizer* bSizer11;
710 bSizer11 =
new wxBoxSizer(wxHORIZONTAL);
711 sbSizerInFilter->Add(bSizer11, 0, wxEXPAND, 5);
714 new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString, wxDefaultPosition,
715 wxDefaultSize, wxTE_READONLY);
716 bSizer11->Add(m_tcInputStc, 1, wxALL | wxEXPAND, 5);
719 new wxButton(m_scrolledwin, wxID_ANY,
"...", wxDefaultPosition,
720 wxDefaultSize, wxBU_EXACTFIT);
721 bSizer11->Add(m_btnInputStcList, 0, wxALL, 5);
723 bSizer11->AddSpacer(GetCharWidth() * 5);
725 sbSizerOutFilter =
new wxStaticBoxSizer(
726 new wxStaticBox(m_scrolledwin, wxID_ANY, _(
"Output filtering")),
728 sbSizerConnectionProps->Add(sbSizerOutFilter, 0, wxEXPAND, 5);
730 wxBoxSizer* bSizer10;
731 bSizer10 =
new wxBoxSizer(wxHORIZONTAL);
734 new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Transmit sentences"),
735 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
736 bSizer10->Add(m_rbOAccept, 0, wxALL, 5);
738 m_rbOIgnore =
new wxRadioButton(m_scrolledwin, wxID_ANY, _(
"Drop sentences"),
739 wxDefaultPosition, wxDefaultSize, 0);
740 bSizer10->Add(m_rbOIgnore, 0, wxALL, 5);
742 sbSizerOutFilter->Add(bSizer10, 0, wxEXPAND, 5);
744 wxBoxSizer* bSizer12;
745 bSizer12 =
new wxBoxSizer(wxHORIZONTAL);
746 sbSizerOutFilter->Add(bSizer12, 0, wxEXPAND, 5);
749 new wxTextCtrl(m_scrolledwin, wxID_ANY, wxEmptyString, wxDefaultPosition,
750 wxDefaultSize, wxTE_READONLY);
751 bSizer12->Add(m_tcOutputStc, 1, wxALL | wxEXPAND, 5);
754 new wxButton(m_scrolledwin, wxID_ANY,
"...", wxDefaultPosition,
755 wxDefaultSize, wxBU_EXACTFIT);
756 bSizer12->Add(m_btnOutputStcList, 0, wxALL, 5);
758 bSizer12->AddSpacer(GetCharWidth() * 5);
760 sbSizerConnectionProps->AddSpacer(20);
762 m_more =
new wxStaticText(m_scrolledwin, wxID_ANY,
"4 chars",
763 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
764 m_more->SetLabelMarkup(MORE);
765 sbSizerConnectionProps->Add(m_more, wxSizerFlags().Border());
769 SetInitialSettings();
773 ShowNMEACommon(
true);
774 ShowNMEASerial(
true);
777 connectionsaved = TRUE;
779 GetSizer()->Fit(m_scrolledwin);
781 new_device_listener.
Init(SystemEvents::GetInstance().evt_dev_change,
782 [&](
ObservedEvt&) { LoadSerialPorts(m_comboPort); });
789void ConnectionEditDialog::SetSelectedConnectionPanel(
794 if (mSelectedConnection && mSelectedConnection->m_optionsPanel)
795 mSelectedConnection->m_optionsPanel->SetSelected(
false);
798 mSelectedConnection = panel->m_pConnectionParams;
799 panel->SetSelected(
true);
800 SetConnectionParams(mSelectedConnection);
801 m_buttonRemove->Enable();
802 m_buttonRemove->Show();
803 m_buttonAdd->Disable();
804 m_sbConnEdit->SetLabel(_(
"Edit Selected Connection"));
807 mSelectedConnection = NULL;
808 m_buttonRemove->Disable();
809 m_buttonAdd->Enable();
811 m_sbConnEdit->SetLabel(
"");
821void ConnectionEditDialog::SetPropsLabel(wxString label) {
822 m_sbConnEdit->SetLabel(label);
829 conn->b_IsSetup = FALSE;
830 m_connection_enabled = conn->bEnabled;
835void ConnectionEditDialog::OnValChange(wxCommandEvent& event) {
event.Skip(); }
837void ConnectionEditDialog::OnScanBTClick(wxCommandEvent& event) {
841 m_btNoChangeCounter = 0;
842 m_btlastResultCount = 0;
844 m_BTScanTimer.Start(1000, wxTIMER_CONTINUOUS);
845 g_Platform->startBluetoothScan();
847 if (m_buttonScanBT) {
848 m_buttonScanBT->SetLabel(_(
"Stop Scan"));
853void ConnectionEditDialog::onBTScanTimer(wxTimerEvent& event) {
857 m_BTscan_results = g_Platform->getBluetoothScanResults();
859 m_choiceBTDataSources->Clear();
860 m_choiceBTDataSources->Append(m_BTscan_results[0]);
863 while ((i + 1) < m_BTscan_results.GetCount()) {
864 wxString item1 = m_BTscan_results[i] +
";";
865 wxString item2 = m_BTscan_results.Item(i + 1);
866 m_choiceBTDataSources->Append(item1 + item2);
871 if (m_BTscan_results.GetCount() > 1) {
872 m_choiceBTDataSources->SetSelection(1);
876 if (m_btNoChangeCounter > 5) StopBTScan();
878 if ((
int)m_BTscan_results.GetCount() == m_btlastResultCount)
879 m_btNoChangeCounter++;
881 m_btNoChangeCounter = 0;
883 m_btlastResultCount = m_BTscan_results.GetCount();
886 if (m_BTscanning >= 15) {
894void ConnectionEditDialog::StopBTScan(
void) {
895 m_BTScanTimer.Stop();
897 g_Platform->stopBluetoothScan();
901 if (m_buttonScanBT) {
902 m_buttonScanBT->SetLabel(_(
"BT Scan"));
903 m_buttonScanBT->Enable();
907void ConnectionEditDialog::OnConnValChange(wxCommandEvent& event) {
908 connectionsaved = FALSE;
912void ConnectionEditDialog::OnTypeSerialSelected(wxCommandEvent& event) {
913 OnConnValChange(event);
914 SetNMEAFormToSerial();
917void ConnectionEditDialog::OnTypeNetSelected(wxCommandEvent& event) {
918 OnConnValChange(event);
922void ConnectionEditDialog::OnTypeCANSelected(wxCommandEvent& event) {
923 OnConnValChange(event);
927void ConnectionEditDialog::OnTypeGPSSelected(wxCommandEvent& event) {
928 OnConnValChange(event);
932void ConnectionEditDialog::OnTypeBTSelected(wxCommandEvent& event) {
933 OnConnValChange(event);
937void ConnectionEditDialog::OnUploadFormatChange(wxCommandEvent& event) {
938 if (event.GetEventObject() == m_cbGarminUploadHost && event.IsChecked())
939 m_cbFurunoGP3X->SetValue(FALSE);
940 else if (event.GetEventObject() == m_cbFurunoGP3X && event.IsChecked())
941 m_cbGarminUploadHost->SetValue(FALSE);
943 OnConnValChange(event);
948void ConnectionEditDialog::ShowTypeCommon(
bool visible) {
949 m_rbTypeSerial->Show(visible);
950 m_rbTypeNet->Show(visible);
951#if defined(__linux__) && !defined(__ANDROID__) && !defined(__WXOSX__)
952 m_rbTypeCAN->Show(visible);
954 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->Show(visible);
955 if (m_rbTypeInternalBT) m_rbTypeInternalBT->Show(visible);
958void ConnectionEditDialog::ShowNMEACommon(
bool visible) {
959 bool advanced = m_advanced;
960 m_cbInput->Show(visible);
961 m_cbOutput->Show(visible);
962 m_stPrecision->Show(visible && advanced);
963 m_choicePrecision->Show(visible && advanced);
964 m_stPrecision->Show(visible && advanced);
965 m_cbCheckCRC->Show(visible && advanced);
966 m_stAuthToken->Show(visible && advanced);
967 m_tAuthToken->Show(visible && advanced);
969 const bool bout_enable = (m_cbOutput->IsChecked() && advanced);
970 m_stPrecision->Enable(bout_enable);
971 m_choicePrecision->Enable(bout_enable);
973 sbSizerOutFilter->SetDimension(0, 0, 0, 0);
974 sbSizerInFilter->SetDimension(0, 0, 0, 0);
975 sbSizerConnectionProps->SetDimension(0, 0, 0, 0);
976 m_sbConnEdit->SetLabel(
"");
979 m_cbCheckSKDiscover->Hide();
980 m_ButtonSKDiscover->Hide();
982 const bool bin_enable = (m_cbInput->IsChecked() && advanced);
983 ShowInFilter(visible && bin_enable);
984 const bool bout_enable = (m_cbOutput->IsChecked() && advanced);
985 ShowOutFilter(visible && bout_enable);
987 m_bNMEAParams_shown = visible;
990void ConnectionEditDialog::ShowNMEANet(
bool visible) {
991 bool advanced = m_advanced;
992 m_stNetAddr->Show(visible);
993 m_tNetAddress->Show(visible);
994 m_stNetDataProtocol->Show(visible);
995 m_stNetPort->Show(visible);
996 m_choiceNetDataProtocol->Show(visible);
997 m_tNetPort->Show(visible);
998 m_stNetProto->Show(visible);
999 m_rbNetProtoSignalK->Show(visible);
1000 m_rbNetProtoGPSD->Show(visible);
1001 m_rbNetProtoTCP->Show(visible);
1002 m_rbNetProtoUDP->Show(visible);
1003 m_stNetComment->Show(visible);
1004 m_tNetComment->Show(visible);
1005 m_stAuthToken->Show(visible);
1006 m_tAuthToken->Show(visible);
1007 m_cbGarminHost->Hide();
1010void ConnectionEditDialog::ShowNMEASerial(
bool visible) {
1011 bool advanced = m_advanced;
1012 m_stSerBaudrate->Show(visible);
1013 m_choiceBaudRate->Show(visible);
1014 m_stSerPort->Show(visible);
1015 m_comboPort->Show(visible);
1016 m_stSerProtocol->Show(visible);
1017 m_choiceSerialProtocol->Show(visible);
1018 m_cbGarminHost->Show(visible && advanced);
1019 m_stSerialComment->Show(visible);
1020 m_tSerialComment->Show(visible);
1023void ConnectionEditDialog::ShowNMEAGPS(
bool visible) {
1024 m_cbCheckSKDiscover->Hide();
1025 m_ButtonSKDiscover->Hide();
1026 m_stAuthToken->Hide();
1027 m_tAuthToken->Hide();
1031void ConnectionEditDialog::ShowNMEACAN(
bool visible) {
1032 m_stCANSource->Show(visible);
1033 m_choiceCANSource->Show(visible);
1036void ConnectionEditDialog::ShowNMEABT(
bool visible) {
1038 if (m_buttonScanBT) m_buttonScanBT->Show();
1039 if (m_stBTPairs) m_stBTPairs->Show();
1040 if (m_choiceBTDataSources) {
1041 if (m_choiceBTDataSources->GetCount() > 1)
1042 m_choiceBTDataSources->SetSelection(1);
1043 m_choiceBTDataSources->Show();
1046 if (m_buttonScanBT) m_buttonScanBT->Hide();
1047 if (m_stBTPairs) m_stBTPairs->Hide();
1048 if (m_choiceBTDataSources) m_choiceBTDataSources->Hide();
1050 m_cbCheckSKDiscover->Hide();
1051 m_stAuthToken->Hide();
1052 m_tAuthToken->Hide();
1053 m_cbCheckSKDiscover->Hide();
1054 m_ButtonSKDiscover->Hide();
1055 m_tcOutputStc->Show(visible);
1056 m_btnOutputStcList->Show(visible);
1057 m_cbOutput->Show(visible);
1060void ConnectionEditDialog::SetNMEAFormToSerial(
void) {
1061 bool advanced = m_advanced;
1062 ShowNMEACommon(TRUE);
1066 ShowNMEASerial(TRUE);
1068 SetDSFormRWStates();
1072void ConnectionEditDialog::SetNMEAFormToNet(
void) {
1073 bool advanced = m_advanced;
1074 ShowNMEACommon(TRUE);
1078 ShowNMEASerial(FALSE);
1080 SetUDPNetAddressVisiblity();
1081 SetDSFormRWStates();
1086void ConnectionEditDialog::SetNMEAFormToCAN(
void) {
1087 bool advanced = m_advanced;
1088 ShowNMEACommon(FALSE);
1092 ShowNMEASerial(FALSE);
1094 sbSizerInFilter->Show(
false);
1095 sbSizerOutFilter->Show(
false);
1096 SetDSFormRWStates();
1101void ConnectionEditDialog::SetNMEAFormToGPS(
void) {
1102 ShowNMEACommon(TRUE);
1106 ShowNMEASerial(FALSE);
1111 SetDSFormRWStates();
1115void ConnectionEditDialog::SetNMEAFormToBT(
void) {
1116 m_rbNetProtoUDP->SetValue(
true);
1117 ShowNMEACommon(TRUE);
1121 ShowNMEASerial(FALSE);
1126 SetDSFormRWStates();
1130void ConnectionEditDialog::ClearNMEAForm(
void) {
1131 ShowNMEACommon(FALSE);
1135 ShowNMEASerial(FALSE);
1142void ConnectionEditDialog::SetDSFormOptionVizStates(
void) {
1143 bool advanced = m_advanced;
1147 m_cbCheckCRC->Show(advanced);
1148 m_stPrecision->Show(
true);
1149 m_choicePrecision->Show(
true);
1151 ShowInFilter(advanced);
1152 ShowOutFilter(advanced);
1155 m_stAuthToken->Show(advanced);
1156 m_tAuthToken->Show(advanced);
1158 m_StaticTextSKServerStatus->Show(advanced);
1160 if (m_rbTypeSerial->GetValue()) {
1161 m_cbMultiCast->Hide();
1162 m_cbCheckSKDiscover->Hide();
1163 m_stAuthToken->Hide();
1164 m_tAuthToken->Hide();
1165 m_ButtonSKDiscover->Hide();
1166 m_StaticTextSKServerStatus->Hide();
1167 bool n0183ctlenabled =
1168 (DataProtocol)m_choiceSerialProtocol->GetSelection() ==
1169 DataProtocol::PROTO_NMEA0183;
1170 if (!n0183ctlenabled) {
1173 ShowOutFilter(
false);
1174 ShowInFilter(
false);
1175 m_stPrecision->Hide();
1176 m_choicePrecision->Hide();
1177 m_cbCheckCRC->Hide();
1178 m_stNetDataProtocol->Hide();
1179 m_choiceNetDataProtocol->Hide();
1182 m_cbInput->Enable();
1184 ShowInFilter(m_cbInput->IsChecked() && advanced);
1185 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1187 m_stPrecision->Show(m_cbOutput->IsChecked() && advanced);
1188 m_choicePrecision->Show(m_cbOutput->IsChecked() && advanced);
1190 m_cbGarminHost->Show(m_cbInput->IsChecked() && advanced);
1194 if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue()) {
1195 m_cbMultiCast->Hide();
1196 m_cbCheckSKDiscover->Hide();
1197 m_stAuthToken->Hide();
1198 m_tAuthToken->Hide();
1199 m_ButtonSKDiscover->Hide();
1200 m_StaticTextSKServerStatus->Hide();
1203 ShowOutFilter(
false);
1204 ShowInFilter(
false);
1205 m_stPrecision->Hide();
1206 m_choicePrecision->Hide();
1207 m_cbCheckCRC->Hide();
1208 m_cbGarminHost->Hide();
1212 if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue()) {
1213 m_cbMultiCast->Hide();
1214 m_cbCheckSKDiscover->Hide();
1215 m_stAuthToken->Hide();
1216 m_tAuthToken->Hide();
1217 m_ButtonSKDiscover->Hide();
1218 m_StaticTextSKServerStatus->Hide();
1220 ShowInFilter(m_cbInput->IsChecked() && advanced);
1221 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1223 m_stPrecision->Show(m_cbOutput->IsChecked() && advanced);
1224 m_choicePrecision->Show(m_cbOutput->IsChecked() && advanced);
1227 if (m_rbTypeCAN->GetValue()) {
1228 m_cbMultiCast->Hide();
1229 m_cbCheckSKDiscover->Hide();
1230 m_stAuthToken->Hide();
1231 m_tAuthToken->Hide();
1232 m_ButtonSKDiscover->Hide();
1233 m_StaticTextSKServerStatus->Hide();
1234 m_cbGarminHost->Hide();
1238 ShowInFilter(
false);
1239 ShowOutFilter(
false);
1241 m_stPrecision->Hide();
1242 m_choicePrecision->Hide();
1243 m_cbCheckCRC->Hide();
1245 m_stNetDataProtocol->Hide();
1246 m_choiceNetDataProtocol->Hide();
1250 if (m_rbTypeNet->GetValue()) {
1251 if (m_rbNetProtoGPSD->GetValue()) {
1252 m_cbMultiCast->Hide();
1253 m_cbCheckSKDiscover->Hide();
1256 ShowInFilter(
false);
1257 ShowOutFilter(
false);
1258 m_cbCheckCRC->Hide();
1259 m_stPrecision->Hide();
1260 m_choicePrecision->Hide();
1261 m_ButtonSKDiscover->Hide();
1262 m_StaticTextSKServerStatus->Hide();
1263 m_stAuthToken->Hide();
1264 m_tAuthToken->Hide();
1265 m_stNetDataProtocol->Hide();
1266 m_choiceNetDataProtocol->Hide();
1267 m_cbGarminHost->Hide();
1270 }
else if (m_rbNetProtoSignalK->GetValue()) {
1271 m_cbMultiCast->Hide();
1274 ShowInFilter(
false);
1275 ShowOutFilter(
false);
1276 m_cbCheckCRC->Hide();
1277 m_stPrecision->Hide();
1278 m_choicePrecision->Hide();
1279 m_stNetDataProtocol->Hide();
1280 m_choiceNetDataProtocol->Hide();
1281 m_cbGarminHost->Hide();
1284 m_stAuthToken->Hide();
1285 m_tAuthToken->Hide();
1286 m_cbCheckSKDiscover->Hide();
1287 m_ButtonSKDiscover->Hide();
1288 m_StaticTextSKServerStatus->Hide();
1289 m_stNetDataProtocol->Show();
1290 m_choiceNetDataProtocol->Show();
1291 m_cbGarminHost->Hide();
1295 if ((DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1296 DataProtocol::PROTO_NMEA2000) {
1297 m_cbCheckCRC->Hide();
1298 m_stPrecision->Hide();
1299 m_choicePrecision->Hide();
1301 ShowInFilter(
false);
1302 ShowOutFilter(
false);
1303 if (m_rbNetProtoTCP->GetValue()) m_more->Hide();
1305 if ((DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1306 DataProtocol::PROTO_NMEA0183) {
1307 m_stPrecision->Show(advanced);
1308 m_choicePrecision->Show(advanced);
1309 m_stPrecision->Enable(m_cbOutput->IsChecked() && advanced);
1310 m_choicePrecision->Enable(m_cbOutput->IsChecked() && advanced);
1312 ShowInFilter(m_cbInput->IsChecked() && advanced);
1313 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1319void ConnectionEditDialog::SetDSFormRWStates(
void) {
1320 if (m_rbTypeSerial->GetValue()) {
1321 m_cbInput->Enable(FALSE);
1322 m_cbOutput->Enable(TRUE);
1324 ShowOutFilter(m_cbOutput->IsChecked());
1325 }
else if (m_rbNetProtoGPSD->GetValue()) {
1326 if (m_tNetPort->GetValue() == wxEmptyString)
1327 m_tNetPort->SetValue(DEFAULT_GPSD_PORT);
1328 m_cbInput->SetValue(TRUE);
1329 m_cbInput->Enable(FALSE);
1331 m_cbOutput->Enable(FALSE);
1332 m_rbOAccept->Enable(FALSE);
1333 m_rbOIgnore->Enable(FALSE);
1334 m_btnOutputStcList->Enable(FALSE);
1335 }
else if (m_rbNetProtoSignalK->GetValue()) {
1336 if (m_tNetPort->GetValue() == wxEmptyString)
1337 m_tNetPort->SetValue(DEFAULT_SIGNALK_PORT);
1338 m_cbInput->SetValue(TRUE);
1339 m_cbInput->Enable(FALSE);
1341 m_cbOutput->Enable(FALSE);
1342 m_rbOAccept->Enable(FALSE);
1343 m_rbOIgnore->Enable(FALSE);
1344 UpdateDiscoverStatus(wxEmptyString);
1346 if (m_tNetPort->GetValue() == wxEmptyString) {
1347 if (m_rbNetProtoTCP->GetValue()) {
1348 m_tNetPort->SetValue(DEFAULT_TCP_PORT);
1350 m_tNetPort->SetValue(DEFAULT_UDP_PORT);
1353 m_cbInput->Enable(TRUE);
1354 m_cbOutput->Enable(TRUE);
1355 m_rbOAccept->Enable(TRUE);
1356 m_rbOIgnore->Enable(TRUE);
1357 m_btnOutputStcList->Enable(TRUE);
1360 SetDSFormOptionVizStates();
1364void ConnectionEditDialog::ShowInFilter(
bool bshow) {
1365 sbSizerInFilter->GetStaticBox()->Show(bshow);
1366 m_rbIAccept->Show(bshow);
1367 m_rbIIgnore->Show(bshow);
1368 m_tcInputStc->Show(bshow);
1369 m_btnInputStcList->Show(bshow);
1372void ConnectionEditDialog::ShowOutFilter(
bool bshow) {
1373 sbSizerOutFilter->GetStaticBox()->Show(bshow);
1374 m_rbOAccept->Show(bshow);
1375 m_rbOIgnore->Show(bshow);
1376 m_tcOutputStc->Show(bshow);
1377 m_btnOutputStcList->Show(bshow);
1381 SetConnectionParams(cp);
1385 if (wxNOT_FOUND == m_comboPort->FindString(cp->Port))
1386 m_comboPort->Append(cp->Port);
1388 m_comboPort->Select(m_comboPort->FindString(cp->Port));
1390 m_cbCheckCRC->SetValue(cp->ChecksumCheck);
1391 m_cbGarminHost->SetValue(cp->Garmin);
1392 m_cbInput->SetValue(cp->IOSelect != DS_TYPE_OUTPUT);
1393 m_cbOutput->SetValue(cp->IOSelect != DS_TYPE_INPUT);
1394 m_cbCheckSKDiscover->SetValue(cp->AutoSKDiscover);
1396 if (cp->InputSentenceListType == WHITELIST)
1397 m_rbIAccept->SetValue(TRUE);
1399 m_rbIIgnore->SetValue(TRUE);
1400 if (cp->OutputSentenceListType == WHITELIST)
1401 m_rbOAccept->SetValue(TRUE);
1403 m_rbOIgnore->SetValue(TRUE);
1404 m_tcInputStc->SetValue(StringArrayToString(cp->InputSentenceList));
1405 m_tcOutputStc->SetValue(StringArrayToString(cp->OutputSentenceList));
1406 m_choiceBaudRate->Select(
1407 m_choiceBaudRate->FindString(wxString::Format(
"%d", cp->Baudrate)));
1408 m_choiceSerialProtocol->Select(cp->Protocol);
1409 m_tNetAddress->SetValue(cp->NetworkAddress);
1411 m_choiceNetDataProtocol->Select(cp->Protocol);
1413 m_cbMultiCast->SetValue(IsAddressMultiCast(m_tNetAddress->GetValue()));
1415 if (cp->NetworkPort == 0)
1416 m_tNetPort->SetValue(wxEmptyString);
1418 m_tNetPort->SetValue(wxString::Format(wxT(
"%i"), cp->NetworkPort));
1420 if (cp->NetProtocol == TCP)
1421 m_rbNetProtoTCP->SetValue(TRUE);
1422 else if (cp->NetProtocol == UDP)
1423 m_rbNetProtoUDP->SetValue(TRUE);
1424 else if (cp->NetProtocol == GPSD)
1425 m_rbNetProtoGPSD->SetValue(TRUE);
1426 else if (cp->NetProtocol == SIGNALK)
1427 m_rbNetProtoSignalK->SetValue(TRUE);
1429 m_rbNetProtoGPSD->SetValue(TRUE);
1431 if (cp->Type == SERIAL) {
1432 m_rbTypeSerial->SetValue(TRUE);
1433 SetNMEAFormToSerial();
1434 SetNMEAFormForSerialProtocol();
1435 }
else if (cp->Type == NETWORK) {
1436 m_rbTypeNet->SetValue(TRUE);
1438 }
else if (cp->Type == SOCKETCAN) {
1439 m_rbTypeCAN->SetValue(TRUE);
1442 }
else if (cp->Type == INTERNAL_GPS) {
1443 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->SetValue(TRUE);
1445 }
else if (cp->Type == INTERNAL_BT) {
1446 if (m_rbTypeInternalBT) m_rbTypeInternalBT->SetValue(TRUE);
1450 wxString bts = cp->NetworkAddress +
";" + cp->GetPortStr();
1451 m_choiceBTDataSources->Clear();
1452 m_choiceBTDataSources->Append(bts);
1453 m_choiceBTDataSources->SetSelection(0);
1457 if (cp->Type == SERIAL)
1458 m_tSerialComment->SetValue(cp->UserComment);
1459 else if (cp->Type == NETWORK)
1460 m_tNetComment->SetValue(cp->UserComment);
1462 m_tAuthToken->SetValue(cp->AuthToken);
1464 m_connection_enabled = cp->bEnabled;
1467 connectionsaved =
true;
1470void ConnectionEditDialog::SetUDPNetAddressVisiblity(
void) {
1471 if (m_rbNetProtoUDP->GetValue() && !m_cbMultiCast->IsChecked() &&
1472 !m_cbOutput->IsChecked()) {
1475 m_tNetAddress->Enable(TRUE);
1477 m_stNetAddr->Show(TRUE);
1478 m_tNetAddress->Show(TRUE);
1479 m_tNetAddress->Enable(TRUE);
1481 if (!m_rbNetProtoUDP->GetValue()) {
1482 m_stNetAddr->Show(TRUE);
1483 m_tNetAddress->Show(TRUE);
1484 m_tNetAddress->Enable(TRUE);
1486 if (m_rbNetProtoUDP->GetValue() && m_advanced) {
1489 m_cbMultiCast->Hide();
1492void ConnectionEditDialog::SetDefaultConnectionParams(
void) {
1493 if (m_comboPort && !m_comboPort->IsListEmpty()) {
1494 m_comboPort->Select(0);
1495 m_comboPort->SetValue(wxEmptyString);
1497 m_cbCheckCRC->SetValue(TRUE);
1498 m_cbGarminHost->SetValue(FALSE);
1499 m_cbInput->SetValue(TRUE);
1500 m_cbOutput->SetValue(FALSE);
1501 m_rbIAccept->SetValue(TRUE);
1502 m_rbOAccept->SetValue(TRUE);
1503 m_tcInputStc->SetValue(wxEmptyString);
1504 m_tcOutputStc->SetValue(wxEmptyString);
1505 m_choiceBaudRate->Select(m_choiceBaudRate->FindString(
"4800"));
1508 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1510 m_tNetComment->SetValue(wxEmptyString);
1511 m_tSerialComment->SetValue(wxEmptyString);
1512 m_tAuthToken->SetValue(wxEmptyString);
1514 bool bserial = TRUE;
1524 if (m_rbTypeInternalGPS) {
1525 m_rbTypeInternalGPS->SetValue(
true);
1528 m_rbTypeNet->SetValue(
true);
1533 m_rbTypeSerial->SetValue(bserial);
1534 m_rbTypeNet->SetValue(!bserial);
1535 bserial ? SetNMEAFormToSerial() : SetNMEAFormToNet();
1536 m_rbTypeCAN->SetValue(FALSE);
1539 m_connection_enabled = TRUE;
1542 connectionsaved =
false;
1545void ConnectionEditDialog::LayoutDialog() {
1546 gSizerNetProps->Layout();
1547 gSizerSerProps->Layout();
1548 m_scrolledwin->Layout();
1549 m_scrolledwin->Fit();
1550 GetSizer()->Layout();
1553void ConnectionEditDialog::UpdateSourceList(
bool bResort) {
1554 for (
auto* cp : TheConnectionParams()) {
1556 if (panel) panel->Update(cp);
1559 m_scrollWinConnections->Layout();
1562void ConnectionEditDialog::OnSelectDatasource(wxListEvent& event) {
1563 SetConnectionParams(TheConnectionParams()[event.GetData()]);
1564 m_buttonRemove->Enable();
1565 m_buttonRemove->Show();
1569void ConnectionEditDialog::OnDiscoverButton(wxCommandEvent& event) {
1573 std::string serviceIdent =
1574 std::string(
"_signalk-ws._tcp.local.");
1576 g_Platform->ShowBusySpinner();
1578 if (SignalKDataStream::DiscoverSKServer(serviceIdent, ip, port,
1581 m_tNetAddress->SetValue(ip);
1582 m_tNetPort->SetValue(wxString::Format(wxT(
"%i"), port));
1583 UpdateDiscoverStatus(_(
"Signal K server available."));
1585 UpdateDiscoverStatus(_(
"Signal K server not found."));
1587 g_Platform->HideBusySpinner();
1592void ConnectionEditDialog::UpdateDiscoverStatus(wxString stat) {
1593 m_StaticTextSKServerStatus->SetLabel(stat);
1596void ConnectionEditDialog::OnBtnIStcs(wxCommandEvent& event) {
1597 const ListType type = m_rbIAccept->GetValue() ? WHITELIST : BLACKLIST;
1598 const wxArrayString list = wxStringTokenize(m_tcInputStc->GetValue(),
",");
1601 if (dlg.ShowModal() == wxID_OK) m_tcInputStc->SetValue(dlg.GetSentences());
1604void ConnectionEditDialog::OnBtnOStcs(wxCommandEvent& event) {
1605 const ListType type = m_rbOAccept->GetValue() ? WHITELIST : BLACKLIST;
1606 const wxArrayString list = wxStringTokenize(m_tcOutputStc->GetValue(),
",");
1609 if (dlg.ShowModal() == wxID_OK) m_tcOutputStc->SetValue(dlg.GetSentences());
1612void ConnectionEditDialog::OnNetProtocolSelected(wxCommandEvent& event) {
1613 if (m_rbNetProtoGPSD->GetValue()) {
1614 if (IsDefaultPort(m_tNetPort->GetValue())) {
1615 m_tNetPort->SetValue(DEFAULT_GPSD_PORT);
1617 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1618 }
else if (m_rbNetProtoUDP->GetValue()) {
1619 if (IsDefaultPort(m_tNetPort->GetValue())) {
1620 m_tNetPort->SetValue(DEFAULT_UDP_PORT);
1622 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1623 if (m_cbInput->GetValue() && !m_cbMultiCast->GetValue() &&
1624 m_rbNetProtoUDP->GetValue())
1625 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1626 else if (m_cbOutput->GetValue() && !m_cbMultiCast->GetValue())
1627 m_tNetPort->SetValue(DEFAULT_UDP_OUT_ADDRESS);
1629 if (m_cbInput->GetValue() && m_cbOutput->GetValue())
1630 m_cbOutput->SetValue(
false);
1632 }
else if (m_rbNetProtoSignalK->GetValue()) {
1633 if (IsDefaultPort(m_tNetPort->GetValue())) {
1634 m_tNetPort->SetValue(DEFAULT_SIGNALK_PORT);
1636 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1637 }
else if (m_rbNetProtoTCP->GetValue()) {
1638 if (IsDefaultPort(m_tNetPort->GetValue())) {
1639 m_tNetPort->SetValue(DEFAULT_TCP_PORT);
1641 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1644 SetUDPNetAddressVisiblity();
1645 SetDSFormRWStates();
1647 OnConnValChange(event);
1650void ConnectionEditDialog::OnRbAcceptInput(wxCommandEvent& event) {
1651 OnConnValChange(event);
1653void ConnectionEditDialog::OnRbIgnoreInput(wxCommandEvent& event) {
1654 OnConnValChange(event);
1657void ConnectionEditDialog::OnRbOutput(wxCommandEvent& event) {
1658 OnConnValChange(event);
1661void ConnectionEditDialog::OnCbInput(wxCommandEvent& event) {
1662 const bool checked = m_cbInput->IsChecked();
1663 ShowInFilter(checked);
1664 if (checked && m_rbNetProtoUDP->GetValue() && m_rbTypeNet->GetValue()) {
1665 m_cbOutput->SetValue(FALSE);
1667 if (!m_cbMultiCast->GetValue()) m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1669 SetDSFormRWStates();
1671 if (m_rbTypeNet->GetValue()) SetUDPNetAddressVisiblity();
1672 OnConnValChange(event);
1675void ConnectionEditDialog::OnCbOutput(wxCommandEvent& event) {
1676 OnConnValChange(event);
1677 const bool checked = m_cbOutput->IsChecked();
1678 m_stPrecision->Enable(checked);
1679 m_choicePrecision->Enable(checked);
1680 ShowOutFilter(checked);
1682 if (!m_cbMultiCast->IsChecked() && m_rbNetProtoUDP->GetValue()) {
1684 m_tNetAddress->SetValue(
1685 DEFAULT_UDP_OUT_ADDRESS);
1687 NetworkProtocol proto = UDP;
1688 for (
auto* cp : TheConnectionParams()) {
1689 if (cp->NetProtocol == proto &&
1690 cp->NetworkPort == wxAtoi(m_tNetPort->GetValue()) &&
1691 cp->IOSelect == DS_TYPE_INPUT) {
1694 m_more->SetLabelMarkup(m_advanced ? LESS : MORE);
1695 SetNMEAFormForNetProtocol();
1702 _(
"There is an enabled UDP input connection that uses the "
1705 << _(
"Please apply a filter on both connections to avoid a "
1710 _(
"There is a disabled UDP Input connection that uses the "
1713 << _(
"If you enable that input please apply a filter on both "
1714 "connections to avoid a feedback loop.");
1717 << _(
"Or consider using a different data port for one of them");
1719 OCPNMessageBox(
this, mes, _(
"OpenCPN Warning"),
1720 wxOK | wxICON_EXCLAMATION, 60);
1722 OCPNMessageBox(
this, mes, _(
"OpenCPN info"),
1723 wxOK | wxICON_INFORMATION, 60);
1728 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1732 if (checked && m_rbNetProtoUDP->GetValue()) {
1733 m_cbInput->SetValue(FALSE);
1736 if (m_rbTypeNet->GetValue()) SetUDPNetAddressVisiblity();
1737 SetDSFormRWStates();
1741void ConnectionEditDialog::OnCbMultiCast(wxCommandEvent& event) {
1742 const bool checked = m_cbMultiCast->IsChecked();
1744 if (!IsAddressMultiCast(m_tNetAddress->GetValue())) {
1745 m_tNetAddress->SetValue(
"224.0.2.21");
1747 }
else if (m_cbOutput->IsChecked()) {
1748 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1750 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1753 SetUDPNetAddressVisiblity();
1757void ConnectionEditDialog::OnClickMore(wxMouseEvent& event) {
1759 m_advanced = !m_advanced;
1760 m_more->SetLabelMarkup(m_advanced ? LESS : MORE);
1761 if (m_rbTypeNet->GetValue())
1762 SetNMEAFormForNetProtocol();
1764 SetNMEAFormForSerialProtocol();
1768void ConnectionEditDialog::OnCbAdvanced(wxCommandEvent& event) {
1769 if (m_rbTypeNet->GetValue())
1770 SetNMEAFormForNetProtocol();
1772 SetNMEAFormForSerialProtocol();
1776void ConnectionEditDialog::OnShowGpsWindowCheckboxClick(wxCommandEvent& event) {
1791 if (m_container->GetRect().Contains(logRect)) {
1792 NMEALogWindow::Get().SetPos(
1793 m_container->GetRect().x / 2,
1794 (m_container->GetRect().y +
1795 (m_container->GetRect().height - logRect.height) / 2));
1796 NMEALogWindow::Get().Move();
1802void ConnectionEditDialog::SetNMEAFormForSerialProtocol() {
1803 bool n0183ctlenabled = (DataProtocol)m_choiceSerialProtocol->GetSelection() ==
1804 DataProtocol::PROTO_NMEA0183;
1805 bool advanced = m_advanced;
1806 ShowNMEACommon(n0183ctlenabled && advanced);
1807 m_cbGarminHost->Show(n0183ctlenabled && advanced);
1809 SetDSFormRWStates();
1813void ConnectionEditDialog::SetNMEAFormForNetProtocol() {
1814 bool n0183ctlenabled =
1815 (DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1816 DataProtocol::PROTO_NMEA0183;
1817 bool advanced = m_advanced;
1818 ShowNMEACommon(n0183ctlenabled && advanced);
1819 m_cbGarminHost->Show(n0183ctlenabled && advanced);
1821 SetDSFormRWStates();
1826void ConnectionEditDialog::OnProtocolChoice(wxCommandEvent& event) {
1827 if (m_rbTypeNet->GetValue())
1828 SetNMEAFormForNetProtocol();
1830 SetNMEAFormForSerialProtocol();
1832 OnConnValChange(event);
1835void ConnectionEditDialog::ApplySettings() {
1837 g_bfilter_cogsog = m_cbFilterSogCog->GetValue();
1839 long filter_val = 1;
1840 m_tFilterSec->GetValue().ToLong(&filter_val);
1842 wxMin(
static_cast<int>(filter_val),
1844 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
1845 g_SOGFilterSec = g_COGFilterSec;
1847 g_bMagneticAPB = m_cbAPBMagnetic->GetValue();
1848 g_NMEAAPBPrecision = m_choicePrecision->GetCurrentSelection();
1855 NetworkProtocol lastNetProtocol = PROTO_UNDEFINED;
1856 DataProtocol lastDataProtocol = PROTO_NMEA0183;
1858 if (mSelectedConnection) {
1860 lastAddr = cpo->NetworkAddress;
1861 lastPort = cpo->NetworkPort;
1862 lastNetProtocol = cpo->NetProtocol;
1863 lastDataProtocol = cpo->Protocol;
1866 if (!connectionsaved) {
1867 size_t nCurrentPanelCount = TheConnectionParams()->GetCount();
1869 int old_priority = -1;
1871 if (mSelectedConnection) {
1872 cp = mSelectedConnection;
1873 old_priority = cp->Priority;
1874 UpdateConnectionParamsFromControls(cp);
1875 cp->b_IsSetup =
false;
1887 cp = CreateConnectionParamsFromSelectedItem();
1888 if (cp) TheConnectionParams()->Add(cp);
1893 cp->LastNetProtocol = lastNetProtocol;
1894 cp->LastNetworkAddress = lastAddr;
1895 cp->LastNetworkPort = lastPort;
1896 cp->LastDataProtocol = lastDataProtocol;
1899 if (TheConnectionParams()->GetCount() != nCurrentPanelCount)
1901 else if (old_priority >= 0) {
1902 if (old_priority != cp->Priority)
1903 UpdateSourceList(
true);
1905 UpdateSourceList(
false);
1908 connectionsaved = TRUE;
1915 SetSelectedConnectionPanel(
nullptr);
1919 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1922 if (cp->b_IsSetup)
continue;
1927 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
1930 StopAndRemoveCommDriver(cp->GetLastDSPort(), cp->GetLastCommProtocol());
1934 if (cp->Type == INTERNAL_BT) wxSleep(1);
1937 if (!cp->bEnabled)
continue;
1941 cp->b_IsSetup = TRUE;
1944 g_bGarminHostUpload = m_cbGarminUploadHost->GetValue();
1946 m_cbFurunoGP3X->GetValue() ?
"FurunoGP3X" :
"Generic";
1951ConnectionEditDialog::CreateConnectionParamsFromSelectedItem() {
1957 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() ==
"Deleted")
1964 if (!(m_cbInput->GetValue() || m_cbOutput->GetValue())) {
1965 m_cbInput->SetValue(
true);
1968 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == wxEmptyString) {
1969 m_comboPort->Select(0);
1973 else if (m_rbTypeNet->GetValue()) {
1974 if (wxAtoi(m_tNetPort->GetValue()) == 0) {
1975 m_tNetPort->SetValue(
"10110");
1977 if (m_tNetAddress->GetValue() == wxEmptyString) {
1978 m_tNetAddress->SetValue(
"0.0.0.0");
1980 }
else if (m_rbTypeCAN->GetValue()) {
1985 UpdateConnectionParamsFromSelectedItem(pConnectionParams);
1988 m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1989 pConnectionParams,
this);
1990 pPanel->SetSelected(
false);
1991 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxALL, 0);
1992 pConnectionParams->m_optionsPanel = pPanel;
1994 return pConnectionParams;
2001 UpdateConnectionParamsFromControls(pConnectionParams);
2002 return pConnectionParams;
2007 pConnectionParams->Valid = TRUE;
2008 if (m_rbTypeSerial->GetValue())
2009 pConnectionParams->Type = SERIAL;
2010 else if (m_rbTypeNet->GetValue())
2011 pConnectionParams->Type = NETWORK;
2012 else if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue())
2013 pConnectionParams->Type = INTERNAL_GPS;
2014 else if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue())
2015 pConnectionParams->Type = INTERNAL_BT;
2016 else if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
2017 pConnectionParams->Type = SOCKETCAN;
2019 if (m_rbTypeNet->GetValue()) {
2021 pConnectionParams->LastNetworkAddress = pConnectionParams->NetworkAddress;
2022 pConnectionParams->LastNetworkPort = pConnectionParams->NetworkPort;
2023 pConnectionParams->LastNetProtocol = pConnectionParams->NetProtocol;
2024 pConnectionParams->LastDataProtocol = pConnectionParams->Protocol;
2026 pConnectionParams->NetworkAddress =
2027 m_tNetAddress->GetValue().Trim(
false).Trim(
true);
2028 pConnectionParams->NetworkPort =
2029 wxAtoi(m_tNetPort->GetValue().Trim(
false).Trim(
true));
2030 if (m_rbNetProtoTCP->GetValue()) {
2031 pConnectionParams->NetProtocol = TCP;
2032 pConnectionParams->Protocol =
2033 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2034 }
else if (m_rbNetProtoUDP->GetValue()) {
2035 pConnectionParams->NetProtocol = UDP;
2036 pConnectionParams->Protocol =
2037 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2038 }
else if (m_rbNetProtoGPSD->GetValue())
2039 pConnectionParams->NetProtocol = GPSD;
2040 else if (m_rbNetProtoSignalK->GetValue())
2041 pConnectionParams->NetProtocol = SIGNALK;
2043 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2046 if (m_rbTypeSerial->GetValue())
2047 pConnectionParams->Protocol =
2048 (DataProtocol)m_choiceSerialProtocol->GetSelection();
2049 else if (m_rbTypeNet->GetValue())
2050 pConnectionParams->Protocol =
2051 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2053 pConnectionParams->Baudrate = wxAtoi(m_choiceBaudRate->GetStringSelection());
2054 pConnectionParams->ChecksumCheck = m_cbCheckCRC->GetValue();
2055 pConnectionParams->AutoSKDiscover = m_cbCheckSKDiscover->GetValue();
2056 pConnectionParams->Garmin = m_cbGarminHost->GetValue();
2057 pConnectionParams->InputSentenceList =
2058 wxStringTokenize(m_tcInputStc->GetValue(),
",");
2059 if (m_rbIAccept->GetValue())
2060 pConnectionParams->InputSentenceListType = WHITELIST;
2062 pConnectionParams->InputSentenceListType = BLACKLIST;
2063 if (m_cbInput->GetValue()) {
2064 if (m_cbOutput->GetValue()) {
2065 pConnectionParams->IOSelect = DS_TYPE_INPUT_OUTPUT;
2067 pConnectionParams->IOSelect = DS_TYPE_INPUT;
2070 pConnectionParams->IOSelect = DS_TYPE_OUTPUT;
2072 pConnectionParams->OutputSentenceList =
2073 wxStringTokenize(m_tcOutputStc->GetValue(),
",");
2074 if (m_rbOAccept->GetValue())
2075 pConnectionParams->OutputSentenceListType = WHITELIST;
2077 pConnectionParams->OutputSentenceListType = BLACKLIST;
2078 pConnectionParams->Port = m_comboPort->GetValue().BeforeFirst(
' ');
2079#if defined(__linux__) && !defined(__ANDROID__)
2080 if (pConnectionParams->Type == SERIAL)
2084 if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
2085 pConnectionParams->Protocol = PROTO_NMEA2000;
2087 pConnectionParams->bEnabled = m_connection_enabled;
2088 pConnectionParams->b_IsSetup = FALSE;
2090 if (pConnectionParams->Type == INTERNAL_GPS) {
2091 pConnectionParams->NetworkAddress =
"";
2092 pConnectionParams->NetworkPort = 0;
2093 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2094 pConnectionParams->Baudrate = 0;
2097 if (pConnectionParams->Type == INTERNAL_BT) {
2098 wxString parms = m_choiceBTDataSources->GetStringSelection();
2099 wxStringTokenizer tkz(parms,
";");
2100 wxString name = tkz.GetNextToken();
2101 wxString mac = tkz.GetNextToken();
2103 pConnectionParams->NetworkAddress = name;
2104 pConnectionParams->Port = mac;
2105 pConnectionParams->NetworkPort = 0;
2106 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2107 pConnectionParams->Baudrate = 0;
2111 if (pConnectionParams->Type == SOCKETCAN) {
2112 pConnectionParams->NetworkAddress =
"";
2113 pConnectionParams->NetworkPort = 0;
2114 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2115 pConnectionParams->Baudrate = 0;
2116 pConnectionParams->socketCAN_port =
2117 m_choiceCANSource->GetString(m_choiceCANSource->GetSelection());
2120 if (pConnectionParams->Type == SERIAL) {
2121 pConnectionParams->UserComment = m_tSerialComment->GetValue();
2122 }
else if (pConnectionParams->Type == NETWORK) {
2123 pConnectionParams->UserComment = m_tNetComment->GetValue();
2125 pConnectionParams->AuthToken = m_tAuthToken->GetValue();
2127 return pConnectionParams;
2130void ConnectionEditDialog::OnPriorityDialog(wxCommandEvent& event) {
2135void ConnectionEditDialog::ConnectControls() {
2137 m_rbTypeSerial->Connect(
2138 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2139 wxCommandEventHandler(ConnectionEditDialog::OnTypeSerialSelected), NULL,
2141 m_rbTypeNet->Connect(
2142 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2143 wxCommandEventHandler(ConnectionEditDialog::OnTypeNetSelected), NULL,
2146 m_rbTypeCAN->Connect(
2147 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2148 wxCommandEventHandler(ConnectionEditDialog::OnTypeCANSelected), NULL,
2151 if (m_rbTypeInternalGPS)
2152 m_rbTypeInternalGPS->Connect(
2153 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2154 wxCommandEventHandler(ConnectionEditDialog::OnTypeGPSSelected), NULL,
2156 if (m_rbTypeInternalBT)
2157 m_rbTypeInternalBT->Connect(
2158 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2159 wxCommandEventHandler(ConnectionEditDialog::OnTypeBTSelected), NULL,
2163 m_rbNetProtoTCP->Connect(
2164 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2165 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2167 m_rbNetProtoUDP->Connect(
2168 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2169 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2171 m_rbNetProtoGPSD->Connect(
2172 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2173 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2175 m_rbNetProtoSignalK->Connect(
2176 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2177 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2179 m_choiceNetDataProtocol->Connect(
2180 wxEVT_COMMAND_CHOICE_SELECTED,
2181 wxCommandEventHandler(ConnectionEditDialog::OnProtocolChoice), NULL,
2183 m_choiceSerialProtocol->Connect(
2184 wxEVT_COMMAND_CHOICE_SELECTED,
2185 wxCommandEventHandler(ConnectionEditDialog::OnProtocolChoice), NULL,
2187 m_cbMultiCast->Connect(
2188 wxEVT_COMMAND_CHECKBOX_CLICKED,
2189 wxCommandEventHandler(ConnectionEditDialog::OnCbMultiCast), NULL,
this);
2193 m_more->Bind(wxEVT_LEFT_DOWN, &ConnectionEditDialog::OnClickMore,
this);
2196 m_cbInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2197 wxCommandEventHandler(ConnectionEditDialog::OnCbInput),
2199 m_cbOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2200 wxCommandEventHandler(ConnectionEditDialog::OnCbOutput),
2216 m_btnInputStcList->Connect(
2217 wxEVT_COMMAND_BUTTON_CLICKED,
2218 wxCommandEventHandler(ConnectionEditDialog::OnBtnIStcs), NULL,
this);
2221 m_btnOutputStcList->Connect(
2222 wxEVT_COMMAND_BUTTON_CLICKED,
2223 wxCommandEventHandler(ConnectionEditDialog::OnBtnOStcs), NULL,
this);
2226 m_tNetAddress->Connect(
2227 wxEVT_COMMAND_TEXT_UPDATED,
2228 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2229 m_tNetPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2230 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange),
2232 m_comboPort->Connect(
2233 wxEVT_COMMAND_COMBOBOX_SELECTED,
2234 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2235 m_comboPort->Connect(
2236 wxEVT_COMMAND_TEXT_UPDATED,
2237 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2238 m_choiceBaudRate->Connect(
2239 wxEVT_COMMAND_CHOICE_SELECTED,
2240 wxCommandEventHandler(ConnectionEditDialog::OnBaudrateChoice), NULL,
this);
2241 m_choicePriority->Connect(
2242 wxEVT_COMMAND_CHOICE_SELECTED,
2243 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2244 m_choiceCANSource->Connect(
2245 wxEVT_COMMAND_CHOICE_SELECTED,
2246 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2247 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2248 wxCommandEventHandler(ConnectionEditDialog::OnCrcCheck),
2250 m_cbGarminHost->Connect(
2251 wxEVT_COMMAND_CHECKBOX_CLICKED,
2252 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2254 m_cbGarminUploadHost->Connect(
2255 wxEVT_COMMAND_CHECKBOX_CLICKED,
2256 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2258 m_cbFurunoGP3X->Connect(
2259 wxEVT_COMMAND_CHECKBOX_CLICKED,
2260 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2262 m_cbCheckSKDiscover->Connect(
2263 wxEVT_COMMAND_CHECKBOX_CLICKED,
2264 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2265 m_ButtonSKDiscover->Connect(
2266 wxEVT_COMMAND_BUTTON_CLICKED,
2267 wxCommandEventHandler(ConnectionEditDialog::OnDiscoverButton), NULL,
this);
2269 m_rbOAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2270 wxCommandEventHandler(ConnectionEditDialog::OnRbOutput),
2272 m_rbOIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2273 wxCommandEventHandler(ConnectionEditDialog::OnRbOutput),
2275 m_tcOutputStc->Connect(
2276 wxEVT_COMMAND_TEXT_UPDATED,
2277 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2278 m_cbCheckCRC->Connect(
2279 wxEVT_COMMAND_CHECKBOX_CLICKED,
2280 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2282 m_cbNMEADebug->Connect(
2283 wxEVT_COMMAND_CHECKBOX_CLICKED,
2284 wxCommandEventHandler(ConnectionEditDialog::OnShowGpsWindowCheckboxClick),
2286 m_cbFilterSogCog->Connect(
2287 wxEVT_COMMAND_CHECKBOX_CLICKED,
2288 wxCommandEventHandler(ConnectionEditDialog::OnValChange), NULL,
this);
2289 m_tFilterSec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2290 wxCommandEventHandler(ConnectionEditDialog::OnValChange),
2292 m_cbAPBMagnetic->Connect(
2293 wxEVT_COMMAND_CHECKBOX_CLICKED,
2294 wxCommandEventHandler(ConnectionEditDialog::OnValChange), NULL,
this);
2296 m_ButtonPriorityDialog->Connect(
2297 wxEVT_COMMAND_BUTTON_CLICKED,
2298 wxCommandEventHandler(ConnectionEditDialog::OnPriorityDialog), NULL,
this);
2300 m_tNetComment->Connect(
2301 wxEVT_COMMAND_TEXT_UPDATED,
2302 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2303 m_tSerialComment->Connect(
2304 wxEVT_COMMAND_TEXT_UPDATED,
2305 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2306 m_tAuthToken->Connect(
2307 wxEVT_COMMAND_TEXT_UPDATED,
2308 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2311 m_buttonScanBT->Connect(
2312 wxEVT_COMMAND_BUTTON_CLICKED,
2313 wxCommandEventHandler(ConnectionEditDialog::OnScanBTClick), NULL,
this);
2317bool ConnectionEditDialog::IsAddressMultiCast(wxString ip) {
2318 wxArrayString bytes = wxSplit(ip,
'.');
2319 if (bytes.size() != 4) {
2322 unsigned long ipNum = (wxAtoi(bytes[0]) << 24) + (wxAtoi(bytes[1]) << 16) +
2323 (wxAtoi(bytes[2]) << 8) + wxAtoi(bytes[3]);
2324 unsigned long multicastStart = (224 << 24);
2325 unsigned long multicastEnd = (239 << 24) + (255 << 16) + (255 << 8) + 255;
2326 return ipNum >= multicastStart && ipNum <= multicastEnd;
2329bool ConnectionEditDialog::IsDefaultPort(wxString address) {
2330 return (address == DEFAULT_TCP_PORT) || (address == DEFAULT_UDP_PORT) ||
2331 (address == DEFAULT_SIGNALK_PORT) || (address == DEFAULT_GPSD_PORT);
2334bool ConnectionEditDialog::IsAddressBroadcast(wxString ip) {
2335 wxArrayString bytes = wxSplit(ip,
'.');
2336 if (bytes.size() != 4) {
2337 std::cerr <<
"Invalid IP format." << std::endl;
2340 return wxAtoi(bytes[3]) == 255;
2343SentenceListDlg::SentenceListDlg(wxWindow* parent, FilterDirection dir,
2344 ListType type,
const wxArrayString& list)
2345 : wxDialog(parent, wxID_ANY, _(
"Sentence Filter"), wxDefaultPosition,
2349 m_sentences(NMEA0183().GetRecognizedArray()) {
2351 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
2352 wxBoxSizer* secondSizer =
new wxBoxSizer(wxHORIZONTAL);
2353 wxStaticBox* pclbBox =
new wxStaticBox(
this, wxID_ANY, GetBoxLabel());
2354 wxStaticBoxSizer* stcSizer =
new wxStaticBoxSizer(pclbBox, wxVERTICAL);
2355 m_clbSentences =
new wxCheckListBox(
this, wxID_ANY, wxDefaultPosition,
2356 wxDefaultSize, m_sentences);
2357 wxBoxSizer* btnEntrySizer =
new wxBoxSizer(wxVERTICAL);
2358 wxButton* btnCheckAll =
new wxButton(
this, wxID_ANY, _(
"Select All"));
2359 wxButton* btnClearAll =
new wxButton(
this, wxID_ANY, _(
"Clear All"));
2360 wxButton* btnAdd =
new wxButton(
this, wxID_ANY, _(
"Add"));
2361 m_btnDel =
new wxButton(
this, wxID_ANY, _(
"Delete"));
2362 m_btnDel->Disable();
2363 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
2364 wxButton* btnOK =
new wxButton(
this, wxID_OK);
2365 wxButton* btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"Cancel"));
2367 secondSizer->Add(stcSizer, 1, wxALL | wxEXPAND, 5);
2368 stcSizer->Add(m_clbSentences, 1, wxALL | wxEXPAND, 5);
2369 btnEntrySizer->Add(btnCheckAll, 0, wxALL, 5);
2370 btnEntrySizer->Add(btnClearAll, 0, wxALL, 5);
2371 btnEntrySizer->AddSpacer(1);
2372 btnEntrySizer->Add(btnAdd, 0, wxALL, 5);
2373 btnEntrySizer->Add(m_btnDel, 0, wxALL, 5);
2374 secondSizer->Add(btnEntrySizer, 0, wxALL | wxEXPAND, 5);
2375 mainSizer->Add(secondSizer, 1, wxEXPAND, 5);
2376 btnSizer->AddButton(btnOK);
2377 btnSizer->AddButton(btnCancel);
2378 btnSizer->Realize();
2379 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
2381 SetSizer(mainSizer);
2382 mainSizer->SetSizeHints(
this);
2386 btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2387 wxCommandEventHandler(SentenceListDlg::OnAddClick), NULL,
2389 m_btnDel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2390 wxCommandEventHandler(SentenceListDlg::OnDeleteClick), NULL,
2392 m_clbSentences->Connect(wxEVT_COMMAND_LISTBOX_SELECTED,
2393 wxCommandEventHandler(SentenceListDlg::OnCLBSelect),
2395 btnCheckAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2396 wxCommandEventHandler(SentenceListDlg::OnCheckAllClick),
2398 btnClearAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2399 wxCommandEventHandler(SentenceListDlg::OnClearAllClick),
2405wxString SentenceListDlg::GetBoxLabel(
void)
const {
2406 if (m_dir == FILTER_OUTPUT)
2407 return m_type == WHITELIST ? _(
"Transmit sentences") : _(
"Drop sentences");
2409 return m_type == WHITELIST ? _(
"Accept only sentences")
2410 : _(
"Ignore sentences");
2413void SentenceListDlg::Populate(
const wxArrayString& list) {
2414 if (m_dir == FILTER_OUTPUT) {
2416 m_sentences.Add(g_TalkerIdText + wxString(
"RMB"));
2417 m_sentences.Add(g_TalkerIdText + wxString(
"RMC"));
2418 m_sentences.Add(g_TalkerIdText + wxString(
"APB"));
2419 m_sentences.Add(g_TalkerIdText + wxString(
"XTE"));
2421 m_sentences.Add(
"AIVDM");
2422 m_sentences.Add(
"AIVDO");
2423 m_sentences.Add(
"FRPOS");
2424 m_sentences.Add(g_TalkerIdText);
2425 m_sentences.Add(
"CD");
2427 m_clbSentences->Clear();
2428 m_clbSentences->InsertItems(m_sentences, 0);
2430 wxArrayString new_strings;
2432 if (list.Count() == 0) {
2433 for (
size_t i = 0; i < m_clbSentences->GetCount(); ++i)
2434 m_clbSentences->Check(i, m_type == WHITELIST);
2436 for (
size_t i = 0; i < list.Count(); ++i) {
2437 int item = m_clbSentences->FindString(list[i]);
2438 if (item != wxNOT_FOUND)
2439 m_clbSentences->Check(item);
2441 new_strings.Add(list[i]);
2443 if (new_strings.GetCount()) {
2444 m_clbSentences->InsertItems(new_strings, m_clbSentences->GetCount());
2445 for (
size_t i = 0; i < new_strings.GetCount(); ++i) {
2446 int item = m_clbSentences->FindString(new_strings[i]);
2447 if (item != wxNOT_FOUND) m_clbSentences->Check(item);
2453wxString SentenceListDlg::GetSentences(
void) {
2454 wxArrayString retString;
2455 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++) {
2456 if (m_clbSentences->IsChecked(i))
2457 retString.Add(m_clbSentences->GetString(i));
2459 return StringArrayToString(retString);
2462void SentenceListDlg::OnCLBSelect(wxCommandEvent& e) {
2465 m_btnDel->Enable(m_sentences.Index(e.GetString()) == wxNOT_FOUND);
2468void SentenceListDlg::OnAddClick(wxCommandEvent& event) {
2470 androidDisableRotation();
2473 wxTextEntryDialog textdlg(
2475 _(
"Enter the NMEA sentence (2, 3 or 5 characters)\n or a valid REGEX "
2476 "expression (6 characters or longer)"),
2477 _(
"Enter the NMEA sentence"));
2479 textdlg.SetTextValidator(wxFILTER_ASCII);
2480 int result = textdlg.ShowModal();
2483 androidEnableRotation();
2486 if (result == wxID_CANCEL)
return;
2487 wxString stc = textdlg.GetValue();
2489 if (stc.Length() == 2 || stc.Length() == 3 || stc.Length() == 5) {
2490 m_clbSentences->Append(stc);
2491 m_clbSentences->Check(m_clbSentences->FindString(stc));
2493 }
else if (stc.Length() < 2) {
2496 _(
"An NMEA sentence is generally 3 characters long (like RMC, GGA etc.)\n \
2497 It can also have a two letter prefix identifying the source, or TALKER, of the message.\n \
2498 The whole sentences then looks like GPGGA or AITXT.\n \
2499 You may filter out all the sentences with certain TALKER prefix (like GP, AI etc.).\n \
2500 The filter also accepts Regular Expressions (REGEX) with 6 or more characters. \n\n"),
2509 m_clbSentences->Append(stc);
2510 m_clbSentences->Check(m_clbSentences->FindString(stc));
2513 OCPNMessageBox(
this, _(
"REGEX syntax error: \n") + stc,
2520void SentenceListDlg::OnDeleteClick(wxCommandEvent& event) {
2521 m_clbSentences->Delete(m_clbSentences->GetSelection());
2524void SentenceListDlg::OnClearAllClick(wxCommandEvent& event) {
2525 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++)
2526 m_clbSentences->Check(i, FALSE);
2529void SentenceListDlg::OnCheckAllClick(wxCommandEvent& event) {
2530 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++)
2531 m_clbSentences->Check(i, TRUE);
Panel for displaying and editing connection parameters.
void Init(const KeyProvider &kp, std::function< void(ObservedEvt &ev)> action)
Initiate an object yet not listening.
Custom event class for OpenCPN's notification system.
Dialog and support code for editing a connection.
General purpose GUI support.
std::vector< std::string > split(const char *token_string, const std::string &delimiter)
Return vector of items in s separated by delimiter.
std::string trim(std::string s)
Strip possibly trailing and/or leading space characters in s.
PlugIn Object Definition/API.
Miscellaneous utilities, many of which string related.
Suspend/resume and new devices events exchange point.
bool CheckSerialAccess(wxWindow *parent, const std::string device)
Run checks and possible dialogs to ensure device is accessible.
Access checks for comm devices and dongle.