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());
165 auto value = box->GetValue();
167 for (
auto& p : sorted_ports) box->Append(p);
168 if (!value.empty()) box->SetValue(value);
176ConnectionEditDialog::ConnectionEditDialog() {}
178ConnectionEditDialog::ConnectionEditDialog(
182 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), 0,
184 m_on_edit_click(_on_edit_click) {
190ConnectionEditDialog::~ConnectionEditDialog() {}
192void ConnectionEditDialog::SetInitialSettings(
void) {
193 LoadSerialPorts(m_comboPort);
196void ConnectionEditDialog::AddOKCancelButtons() {
199 m_btnSizer =
new wxStdDialogButtonSizer();
200 m_btnOK =
new wxButton(
this, wxID_OK);
201 m_btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"Cancel"));
202 m_btnSizer->AddButton(m_btnOK);
203 m_btnSizer->AddButton(m_btnCancel);
204 m_btnSizer->Realize();
205 GetSizer()->Add(m_btnSizer, 0, wxALL | wxEXPAND, 5);
206 m_btnSizer->Show(
true);
209 if (!m_btnSizerBox) {
210 m_btnSizerBox =
new wxBoxSizer(wxHORIZONTAL);
211 m_btnOK =
new wxButton(
this, wxID_OK);
212 m_btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"Cancel"));
213 m_btnSizerBox->AddSpacer(wxWindow::GetCharWidth());
214 m_btnSizerBox->Add(m_btnOK, 0, wxALL, 5);
215 m_btnSizerBox->Add(m_btnCancel, 0, wxALL, 5);
216 GetSizer()->Add(m_btnSizerBox, 0, wxALL | wxEXPAND, 5);
220 m_btnOK->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
221 [&](wxCommandEvent& ev) { OnOKClick(); });
222 m_btnCancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
223 [&](wxCommandEvent& ev) { OnCancelClick(); });
226void ConnectionEditDialog::OnOKClick() {
227 m_on_edit_click(m_cp_original, new_mode,
true);
230void ConnectionEditDialog::OnCancelClick() {
231 m_on_edit_click(
nullptr,
false,
false);
234void ConnectionEditDialog::Init() {
238 m_btnSizer =
nullptr;
239 m_btnSizerBox =
nullptr;
244 m_choiceBTDataSources = 0;
246 m_BTScanTimer.SetOwner(
this, ID_BT_SCANTIMER);
248 wxSize displaySize = wxGetDisplaySize();
252 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
256 wxBoxSizer* boxSizer02 =
new wxBoxSizer(wxVERTICAL);
257 mainSizer->Add(boxSizer02, 1, wxEXPAND | wxALL, 2);
262 new wxScrolledWindow(
this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1),
263 wxVSCROLL | wxHSCROLL);
264 m_scrolledwin->ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
265 m_scrolledwin->SetScrollRate(1, 1);
269 QString qtStyleSheetFont =
"font: bold;background-color: red;font-size: 48px;";
274 boxSizer02->Add(m_scrolledwin, 1, wxALL | wxEXPAND, 3);
276 auto boxSizerSWin =
new wxBoxSizer(wxVERTICAL);
277 m_scrolledwin->SetSizer(boxSizerSWin);
278 boxSizerSWin->SetSizeHints(m_scrolledwin);
281 int group_item_spacing = 2;
283 wxFont* dFont = GetOCPNScaledFont_PlugIn(_(
"Dialog"));
284 double font_size = dFont->GetPointSize() * 17 / 16;
285 wxFont* bFont = wxTheFontList->FindOrCreateFont(
286 font_size, dFont->GetFamily(), dFont->GetStyle(), wxFONTWEIGHT_BOLD);
295 m_sbConnEdit =
new wxStaticBox(
this, wxID_ANY, _(
"Edit Selected Connection"));
296 m_sbConnEdit->SetFont(*bFont);
298 sbSizerConnectionProps =
new wxStaticBoxSizer(m_sbConnEdit, wxVERTICAL);
299 GetSizer()->Add(sbSizerConnectionProps, 1, wxALL | wxEXPAND, 5);
301 wxBoxSizer* bSizer15;
302 bSizer15 =
new wxBoxSizer(wxHORIZONTAL);
304 sbSizerConnectionProps->Add(bSizer15, 0, wxTOP | wxEXPAND, 5);
307 new wxRadioButton(
this, wxID_ANY, _(
"Serial"), wxDefaultPosition,
308 wxDefaultSize, wxRB_GROUP);
309 m_rbTypeSerial->SetValue(TRUE);
310 bSizer15->Add(m_rbTypeSerial, 0, wxALL, 5);
312 m_rbTypeNet =
new wxRadioButton(
this, wxID_ANY, _(
"Network"),
313 wxDefaultPosition, wxDefaultSize, 0);
314 bSizer15->Add(m_rbTypeNet, 0, wxALL, 5);
316 m_rbTypeCAN =
new wxRadioButton(
this, wxID_ANY,
"socketCAN",
317 wxDefaultPosition, wxDefaultSize, 0);
318#if defined(__linux__) && !defined(__ANDROID__) && !defined(__WXOSX__)
319 bSizer15->Add(m_rbTypeCAN, 0, wxALL, 5);
324 wxBoxSizer* bSizer15a =
new wxBoxSizer(wxHORIZONTAL);
325 sbSizerConnectionProps->Add(bSizer15a, 0, wxEXPAND, 5);
327 if (OCPNPlatform::hasInternalGPS()) {
328 m_rbTypeInternalGPS =
new wxRadioButton(
329 this, wxID_ANY, _(
"Built-in GPS"), wxDefaultPosition, wxDefaultSize, 0);
330 bSizer15a->Add(m_rbTypeInternalGPS, 0, wxALL, 5);
332 m_rbTypeInternalGPS = NULL;
335 if (OCPNPlatform::hasInternalBT()) {
337 new wxRadioButton(
this, wxID_ANY, _(
"Built-in Bluetooth SPP"),
338 wxDefaultPosition, wxDefaultSize, 0);
339 bSizer15a->Add(m_rbTypeInternalBT, 0, wxALL, 5);
341 m_buttonScanBT =
new wxButton(
this, wxID_ANY, _(
"BT Scan") +
" ",
342 wxDefaultPosition, wxDefaultSize);
343 m_buttonScanBT->Hide();
345 sbSizerConnectionProps->Add(m_buttonScanBT, 0, wxALL, 25);
347 m_stBTPairs =
new wxStaticText(
this, wxID_ANY, _(
"Bluetooth Data Sources"),
348 wxDefaultPosition, wxDefaultSize, 0);
349 m_stBTPairs->Wrap(-1);
351 sbSizerConnectionProps->Add(m_stBTPairs, 0, wxALL, 5);
356 int ref_size = this->GetCharWidth();
357 m_choiceBTDataSources =
358 new wxChoice(
this, wxID_ANY, wxDefaultPosition,
359 wxSize(40 * ref_size, 2 * ref_size), mt);
360 m_choiceBTDataSources->SetSelection(0);
361 m_choiceBTDataSources->Hide();
362 sbSizerConnectionProps->Add(m_choiceBTDataSources, 1, wxEXPAND | wxTOP, 25);
365 m_rbTypeInternalBT = NULL;
367 gSizerNetProps =
new wxFlexGridSizer(0, 2, 0, 0);
369 sbSizerConnectionProps->Add(gSizerNetProps, 0, wxEXPAND, 5);
371 m_stNetProto =
new wxStaticText(
this, wxID_ANY, _(
"Network Protocol"),
372 wxDefaultPosition, wxDefaultSize, 0);
373 m_stNetProto->Wrap(-1);
374 gSizerNetProps->Add(m_stNetProto, 0, wxALL, 5);
376 wxBoxSizer* bSizer16;
377 bSizer16 =
new wxBoxSizer(wxHORIZONTAL);
378 gSizerNetProps->Add(bSizer16, 1, wxEXPAND, 5);
379 gSizerNetProps->AddSpacer(1);
380 gSizerNetProps->AddSpacer(1);
382 m_rbNetProtoTCP =
new wxRadioButton(
383 this, wxID_ANY, _(
"TCP"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
384 m_rbNetProtoTCP->Enable(TRUE);
385 m_rbNetProtoTCP->SetValue(TRUE);
387 bSizer16->Add(m_rbNetProtoTCP, 0, wxALL, 5);
389 m_rbNetProtoUDP =
new wxRadioButton(
this, wxID_ANY, _(
"UDP"),
390 wxDefaultPosition, wxDefaultSize, 0);
391 m_rbNetProtoUDP->Enable(TRUE);
393 bSizer16->Add(m_rbNetProtoUDP, 0, wxALL, 5);
396 if (displaySize.x < displaySize.y) {
397 wxBoxSizer* bSizer16a;
398 bSizer16a =
new wxBoxSizer(wxHORIZONTAL);
399 gSizerNetProps->AddSpacer(1);
400 gSizerNetProps->Add(bSizer16a, 1, wxEXPAND, 5);
401 gSizerNetProps->AddSpacer(1);
402 gSizerNetProps->AddSpacer(1);
403 m_rbNetProtoGPSD =
new wxRadioButton(
this, wxID_ANY, _(
"GPSD"),
404 wxDefaultPosition, wxDefaultSize, 0);
405 m_rbNetProtoGPSD->Enable(TRUE);
406 bSizer16a->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
408 m_rbNetProtoSignalK =
new wxRadioButton(
409 this, wxID_ANY, _(
"Signal K"), wxDefaultPosition, wxDefaultSize, 0);
410 m_rbNetProtoSignalK->Enable(TRUE);
411 bSizer16a->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
413 m_rbNetProtoGPSD =
new wxRadioButton(
this, wxID_ANY, _(
"GPSD"),
414 wxDefaultPosition, wxDefaultSize, 0);
415 m_rbNetProtoGPSD->Enable(TRUE);
416 bSizer16->Add(m_rbNetProtoGPSD, 0, wxALL, 5);
418 m_rbNetProtoSignalK =
new wxRadioButton(
419 this, wxID_ANY, _(
"Signal K"), wxDefaultPosition, wxDefaultSize, 0);
420 m_rbNetProtoSignalK->Enable(TRUE);
421 bSizer16->Add(m_rbNetProtoSignalK, 0, wxALL, 5);
424 m_stNetDataProtocol =
new wxStaticText(
this, wxID_ANY, _(
"Data Protocol"),
425 wxDefaultPosition, wxDefaultSize, 0);
426 m_stNetDataProtocol->Wrap(-1);
428 gSizerNetProps->Add(m_stNetDataProtocol, 0, wxALL, 5);
430 wxString m_choiceNetProtocolChoices[] = {_(
"NMEA 0183"), _(
"NMEA 2000")};
431 int m_choiceNetProtocolNChoices =
432 sizeof(m_choiceNetProtocolChoices) /
sizeof(wxString);
433 m_choiceNetDataProtocol =
434 new wxChoice(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
435 m_choiceNetProtocolNChoices, m_choiceNetProtocolChoices, 0);
438 m_choiceNetDataProtocol->SetSelection(0);
439 m_choiceNetDataProtocol->Enable(TRUE);
441 gSizerNetProps->Add(m_choiceNetDataProtocol, 1, wxEXPAND | wxTOP, 5);
442 gSizerNetProps->AddSpacer(1);
443 gSizerNetProps->AddSpacer(1);
445 m_stNetAddr =
new wxStaticText(
this, wxID_ANY, _(
"Address"),
446 wxDefaultPosition, wxDefaultSize, 0);
447 m_stNetAddr->Wrap(-1);
448 int column1width = 16 * m_stNetProto->GetCharWidth();
449 m_stNetAddr->SetMinSize(wxSize(column1width, -1));
450 gSizerNetProps->Add(m_stNetAddr, 0, wxALL, 5);
452 m_tNetAddress =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString,
453 wxDefaultPosition, wxDefaultSize, 0);
454 int column2width = 40 * this->GetCharWidth();
455 m_tNetAddress->SetMaxSize(wxSize(column2width, -1));
456 m_tNetAddress->SetMinSize(wxSize(column2width, -1));
458 gSizerNetProps->Add(m_tNetAddress, 0, wxEXPAND | wxTOP, 5);
459 gSizerNetProps->AddSpacer(1);
460 gSizerNetProps->AddSpacer(1);
462 m_stNetPort =
new wxStaticText(
this, wxID_ANY, _(
"DataPort"),
463 wxDefaultPosition, wxDefaultSize, 0);
464 m_stNetPort->Wrap(-1);
465 gSizerNetProps->Add(m_stNetPort, 0, wxALL, 5);
467 m_tNetPort =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString, wxDefaultPosition,
469 gSizerNetProps->Add(m_tNetPort, 1, wxEXPAND | wxTOP, 5);
470 gSizerNetProps->AddSpacer(1);
471 gSizerNetProps->AddSpacer(1);
473 gSizerCanProps =
new wxGridSizer(0, 1, 0, 0);
475 wxFlexGridSizer* fgSizer1C;
476 fgSizer1C =
new wxFlexGridSizer(0, 2, 0, 0);
480 m_stCANSource =
new wxStaticText(
this, wxID_ANY, _(
"socketCAN Source"),
481 wxDefaultPosition, wxDefaultSize, 0);
482 m_stCANSource->Wrap(-1);
483 m_stCANSource->SetMinSize(wxSize(column1width, -1));
484 fgSizer1C->Add(m_stCANSource, 0, wxALL, 5);
486 wxArrayString choices = GetAvailableSocketCANInterfaces();
488 new wxChoice(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
490 m_choiceCANSource->SetSelection(0);
491 m_choiceCANSource->Enable(TRUE);
492 m_choiceCANSource->SetMaxSize(wxSize(column2width, -1));
493 m_choiceCANSource->SetMinSize(wxSize(column2width, -1));
494 fgSizer1C->Add(m_choiceCANSource, 1, wxEXPAND | wxTOP, 5);
496 gSizerCanProps->Add(fgSizer1C, 0, wxEXPAND, 5);
498 sbSizerConnectionProps->Add(gSizerCanProps, 0, wxEXPAND, 5);
500 gSizerSerProps =
new wxGridSizer(0, 1, 0, 0);
501 sbSizerConnectionProps->Add(gSizerSerProps, 0, wxEXPAND, 5);
503 wxFlexGridSizer* fgSizer1;
504 fgSizer1 =
new wxFlexGridSizer(0, 4, 0, 0);
505 fgSizer1->SetFlexibleDirection(wxBOTH);
506 fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
509 new wxStaticText(
this, wxID_ANY, _(
"Data port"), wxDefaultPosition,
510 wxDefaultSize, wxST_ELLIPSIZE_END);
511 m_stSerPort->SetMinSize(wxSize(column1width, -1));
512 m_stSerPort->Wrap(-1);
514 fgSizer1->Add(m_stSerPort, 0, wxALL, 5);
516 m_comboPort =
new wxComboBox(
this, wxID_ANY, wxEmptyString, wxDefaultPosition,
517 wxDefaultSize, 0, NULL, 0);
519 m_comboPort->SetMaxSize(wxSize(column2width, -1));
520 m_comboPort->SetMinSize(wxSize(column2width, -1));
522 fgSizer1->Add(m_comboPort, 0, wxEXPAND | wxTOP, 5);
524 m_stSerBaudrate =
new wxStaticText(
this, wxID_ANY, _(
"Baudrate"),
525 wxDefaultPosition, wxDefaultSize, 0);
526 m_stSerBaudrate->Wrap(-1);
527 fgSizer1->AddSpacer(1);
528 fgSizer1->AddSpacer(1);
529 fgSizer1->Add(m_stSerBaudrate, 0, wxALL, 5);
531 wxString m_choiceBaudRateChoices[] = {
532 _(
"150"), _(
"300"), _(
"600"), _(
"1200"), _(
"2400"),
533 _(
"4800"), _(
"9600"), _(
"19200"), _(
"38400"), _(
"57600"),
534 _(
"115200"), _(
"230400"), _(
"460800"), _(
"921600")};
535 int m_choiceBaudRateNChoices =
536 sizeof(m_choiceBaudRateChoices) /
sizeof(wxString);
538 new wxChoice(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
539 m_choiceBaudRateNChoices, m_choiceBaudRateChoices, 0);
543 m_choiceBaudRate->SetSelection(0);
545 fgSizer1->Add(m_choiceBaudRate, 1, wxEXPAND | wxTOP, 5);
546 fgSizer1->AddSpacer(1);
547 fgSizer1->AddSpacer(1);
549 m_stSerProtocol =
new wxStaticText(
this, wxID_ANY, _(
"Protocol"),
550 wxDefaultPosition, wxDefaultSize, 0);
551 m_stSerProtocol->Wrap(-1);
552 fgSizer1->Add(m_stSerProtocol, 0, wxALL, 5);
554 wxString m_choiceSerialProtocolChoices[] = {_(
"NMEA 0183"), _(
"NMEA 2000")};
555 int m_choiceSerialProtocolNChoices =
556 sizeof(m_choiceSerialProtocolChoices) /
sizeof(wxString);
557 m_choiceSerialProtocol =
new wxChoice(
558 this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
559 m_choiceSerialProtocolNChoices, m_choiceSerialProtocolChoices, 0);
563 m_choiceSerialProtocol->SetSelection(0);
564 m_choiceSerialProtocol->Enable(TRUE);
565 fgSizer1->Add(m_choiceSerialProtocol, 1, wxEXPAND | wxTOP, 5);
567 gSizerSerProps->Add(fgSizer1, 0, wxEXPAND, 5);
571 wxFlexGridSizer* commentSizer =
new wxFlexGridSizer(0, 2, 0, 0);
575 m_stNetComment =
new wxStaticText(
this, wxID_ANY, _(
"Description"),
576 wxDefaultPosition, wxDefaultSize, 0);
577 m_stNetComment->Wrap(-1);
578 m_stNetComment->SetMinSize(wxSize(column1width, -1));
579 commentSizer->Add(m_stNetComment, 0, wxALL, 5);
581 m_tNetComment =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString,
582 wxDefaultPosition, wxDefaultSize, 0);
583 m_tNetComment->SetMaxSize(wxSize(column2width, -1));
584 m_tNetComment->SetMinSize(wxSize(column2width, -1));
586 commentSizer->Add(m_tNetComment, 1, wxEXPAND | wxTOP, 5);
589 m_stSerialComment =
new wxStaticText(
this, wxID_ANY, _(
"User Comment"),
590 wxDefaultPosition, wxDefaultSize, 0);
591 m_stSerialComment->Wrap(-1);
592 m_stSerialComment->SetMinSize(wxSize(column1width, -1));
593 commentSizer->Add(m_stSerialComment, 0, wxALL, 5);
595 m_tSerialComment =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString,
596 wxDefaultPosition, wxDefaultSize, 0);
597 m_tSerialComment->SetMaxSize(wxSize(column2width, -1));
598 m_tSerialComment->SetMinSize(wxSize(column2width, -1));
600 commentSizer->Add(m_tSerialComment, 1, wxTOP, 5);
602 sbSizerConnectionProps->Add(commentSizer, 0, wxEXPAND, 5);
604 wxFlexGridSizer* fgSizer5;
605 fgSizer5 =
new wxFlexGridSizer(0, 2, 0, 0);
606 fgSizer5->SetFlexibleDirection(wxBOTH);
607 fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
608 sbSizerConnectionProps->Add(fgSizer5, 0, wxEXPAND, 5);
610 m_cbInput =
new wxCheckBox(
this, wxID_ANY, _(
"Receive Input on this Port"),
611 wxDefaultPosition, wxDefaultSize, 0);
612 fgSizer5->Add(m_cbInput, 0, wxALL, 2);
613 fgSizer5->AddSpacer(1);
616 new wxCheckBox(
this, wxID_ANY,
617 wxString::Format(
"%s (%s)", _(
"Output on this port"),
618 _(
"as autopilot or NMEA repeater")),
619 wxDefaultPosition, wxDefaultSize, 0);
620 fgSizer5->Add(m_cbOutput, 0, wxALL, 2);
621 fgSizer5->AddSpacer(1);
625 auto flags = wxSizerFlags().Border();
626 m_collapse_box =
new wxBoxSizer(wxHORIZONTAL);
628 m_collapse_box->Add(
new wxStaticText(
this, wxID_ANY, _(
"Advanced: ")), flags);
631 [&](
bool collapsed) { OnCollapsedToggle(collapsed); }),
633 fgSizer5->Add(m_collapse_box, wxSizerFlags());
634 fgSizer5->Add(
new wxStaticText(
this, wxID_ANY,
""));
636 m_stAuthToken =
new wxStaticText(
this, wxID_ANY, _(
"Auth Token"),
637 wxDefaultPosition, wxDefaultSize, 0);
638 m_stAuthToken->SetMinSize(wxSize(column1width, -1));
639 m_stAuthToken->Wrap(-1);
640 fgSizer5->Add(m_stAuthToken, 0, wxALL, 5);
641 m_stAuthToken->Hide();
643 m_tAuthToken =
new wxTextCtrl(
this, wxID_ANY, wxEmptyString,
644 wxDefaultPosition, wxDefaultSize, 0);
645 m_tAuthToken->SetMinSize(wxSize(column2width, -1));
646 fgSizer5->Add(m_tAuthToken, 1, wxEXPAND | wxTOP, 5);
648 m_tAuthToken->Hide();
651 new wxCheckBox(
this, wxID_ANY, _(
"Use Garmin (GRMN) mode for input"),
652 wxDefaultPosition, wxDefaultSize, 0);
653 m_cbGarminHost->SetValue(FALSE);
654 fgSizer5->Add(m_cbGarminHost, 0, wxALL, 2);
655 fgSizer5->AddSpacer(1);
657#ifndef USE_GARMINHOST
658 m_cbGarminHost->Hide();
661 m_cbMultiCast =
new wxCheckBox(
this, wxID_ANY, _(
" UDP Multicast"),
662 wxDefaultPosition, wxDefaultSize, 0);
663 m_cbMultiCast->SetValue(FALSE);
666 fgSizer5->Add(m_cbMultiCast, 0, wxALL, 2);
667 fgSizer5->AddSpacer(1);
669 m_stPrecision =
new wxStaticText(
this, wxID_ANY, _(
"APB bearing precision"),
670 wxDefaultPosition, wxDefaultSize, 0);
672 m_stPrecision->Wrap(-1);
673 fgSizer5->Add(m_stPrecision, 0, wxALL, 2);
675 wxString m_choicePrecisionChoices[] = {_(
"x"), _(
"x.x"), _(
"x.xx"),
676 _(
"x.xxx"), _(
"x.xxxx")};
677 int m_choicePrecisionNChoices =
678 sizeof(m_choicePrecisionChoices) /
sizeof(wxString);
680 new wxChoice(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
681 m_choicePrecisionNChoices, m_choicePrecisionChoices, 0);
685 m_choicePrecision->SetSelection(g_NMEAAPBPrecision);
686 fgSizer5->Add(m_choicePrecision, 0, wxALL, 2);
689 m_cbCheckSKDiscover =
690 new wxCheckBox(
this, wxID_ANY, _(
"Automatic server discovery"),
691 wxDefaultPosition, wxDefaultSize, 0);
692 m_cbCheckSKDiscover->SetValue(TRUE);
693 m_cbCheckSKDiscover->SetToolTip(
694 _(
"If checked, signal K server will be discovered automatically"));
696 fgSizer5->Add(m_cbCheckSKDiscover, 0, wxALL, 2);
699 m_ButtonSKDiscover =
new wxButton(
this, wxID_ANY, _(
"Discover now..."),
700 wxDefaultPosition, wxDefaultSize, 0);
701 m_ButtonSKDiscover->Hide();
702 fgSizer5->Add(m_ButtonSKDiscover, 0, wxALL, 2);
705 m_StaticTextSKServerStatus =
706 new wxStaticText(
this, wxID_ANY,
"", wxDefaultPosition, wxDefaultSize, 0);
707 fgSizer5->Add(m_StaticTextSKServerStatus, 0, wxALL, 2);
709 sbSizerInFilter =
new wxStaticBoxSizer(
710 new wxStaticBox(
this, wxID_ANY, _(
"Input filtering")), wxVERTICAL);
711 sbSizerConnectionProps->Add(sbSizerInFilter,
712 wxSizerFlags().Expand().Border());
715 bSizer9 =
new wxBoxSizer(wxHORIZONTAL);
717 m_rbIAccept =
new wxRadioButton(
this, wxID_ANY, _(
"Accept only sentences"),
718 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
719 bSizer9->Add(m_rbIAccept, 0, wxALL, 5);
721 m_rbIIgnore =
new wxRadioButton(
this, wxID_ANY, _(
"Ignore sentences"),
722 wxDefaultPosition, wxDefaultSize, 0);
723 bSizer9->Add(m_rbIIgnore, 0, wxALL, 5);
725 sbSizerInFilter->Add(bSizer9, 0, wxEXPAND, 5);
727 wxBoxSizer* bSizer11;
728 bSizer11 =
new wxBoxSizer(wxHORIZONTAL);
729 sbSizerInFilter->Add(bSizer11, 0, wxEXPAND, 5);
732 new wxTextCtrl(
this, wxID_ANY, wxEmptyString, wxDefaultPosition,
733 wxDefaultSize, wxTE_READONLY);
734 bSizer11->Add(m_tcInputStc, 1, wxALL | wxEXPAND, 5);
736 m_btnInputStcList =
new wxButton(
this, wxID_ANY,
"...", wxDefaultPosition,
737 wxDefaultSize, wxBU_EXACTFIT);
738 bSizer11->Add(m_btnInputStcList, 0, wxALL, 5);
740 bSizer11->AddSpacer(GetCharWidth() * 5);
742 sbSizerOutFilter =
new wxStaticBoxSizer(
743 new wxStaticBox(
this, wxID_ANY, _(
"Output filtering")), wxVERTICAL);
744 sbSizerConnectionProps->Add(sbSizerOutFilter, 0, wxEXPAND, 5);
746 wxBoxSizer* bSizer10;
747 bSizer10 =
new wxBoxSizer(wxHORIZONTAL);
749 m_rbOAccept =
new wxRadioButton(
this, wxID_ANY, _(
"Transmit sentences"),
750 wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
751 bSizer10->Add(m_rbOAccept, 0, wxALL, 5);
753 m_rbOIgnore =
new wxRadioButton(
this, wxID_ANY, _(
"Drop sentences"),
754 wxDefaultPosition, wxDefaultSize, 0);
755 bSizer10->Add(m_rbOIgnore, 0, wxALL, 5);
757 sbSizerOutFilter->Add(bSizer10, 0, wxEXPAND, 5);
759 wxBoxSizer* bSizer12;
760 bSizer12 =
new wxBoxSizer(wxHORIZONTAL);
761 sbSizerOutFilter->Add(bSizer12, 0, wxEXPAND, 5);
764 new wxTextCtrl(
this, wxID_ANY, wxEmptyString, wxDefaultPosition,
765 wxDefaultSize, wxTE_READONLY);
766 bSizer12->Add(m_tcOutputStc, 1, wxALL | wxEXPAND, 5);
768 m_btnOutputStcList =
new wxButton(
this, wxID_ANY,
"...", wxDefaultPosition,
769 wxDefaultSize, wxBU_EXACTFIT);
770 bSizer12->Add(m_btnOutputStcList, 0, wxALL, 5);
772 bSizer12->AddSpacer(GetCharWidth() * 5);
774 sbSizerConnectionProps->AddSpacer(20);
778 SetInitialSettings();
782 ShowNMEACommon(
true);
783 ShowNMEASerial(
true);
786 connectionsaved = TRUE;
788 GetSizer()->Fit(
this);
790 new_device_listener.
Init(SystemEvents::GetInstance().evt_dev_change,
791 [&](
ObservedEvt&) { LoadSerialPorts(m_comboPort); });
798void ConnectionEditDialog::SetSelectedConnectionPanel(
803 if (mSelectedConnection && mSelectedConnection->m_optionsPanel)
804 mSelectedConnection->m_optionsPanel->SetSelected(
false);
807 mSelectedConnection = panel->m_pConnectionParams;
808 panel->SetSelected(
true);
809 SetConnectionParams(mSelectedConnection);
810 m_buttonRemove->Enable();
811 m_buttonRemove->Show();
812 m_buttonAdd->Disable();
813 m_sbConnEdit->SetLabel(_(
"Edit Selected Connection"));
816 mSelectedConnection = NULL;
817 m_buttonRemove->Disable();
818 m_buttonAdd->Enable();
820 m_sbConnEdit->SetLabel(
"");
830void ConnectionEditDialog::SetPropsLabel(wxString label) {
831 m_sbConnEdit->SetLabel(label);
838 conn->b_IsSetup = FALSE;
839 m_connection_enabled = conn->bEnabled;
844void ConnectionEditDialog::OnValChange(wxCommandEvent& event) {
event.Skip(); }
846void ConnectionEditDialog::OnScanBTClick(wxCommandEvent& event) {
850 m_btNoChangeCounter = 0;
851 m_btlastResultCount = 0;
853 Bind(wxEVT_TIMER, &ConnectionEditDialog::onBTScanTimer,
this,
855 m_BTScanTimer.Start(1000, wxTIMER_CONTINUOUS);
856 g_Platform->startBluetoothScan();
858 if (m_buttonScanBT) {
859 m_buttonScanBT->SetLabel(_(
"Stop Scan"));
864void ConnectionEditDialog::onBTScanTimer(wxTimerEvent& event) {
868 m_BTscan_results = g_Platform->getBluetoothScanResults();
870 m_choiceBTDataSources->Clear();
871 m_choiceBTDataSources->Append(m_BTscan_results[0]);
874 while ((i + 1) < m_BTscan_results.GetCount()) {
875 wxString item1 = m_BTscan_results[i] +
";";
876 wxString item2 = m_BTscan_results.Item(i + 1);
877 m_choiceBTDataSources->Append(item1 + item2);
882 if (m_BTscan_results.GetCount() > 1) {
883 m_choiceBTDataSources->SetSelection(1);
887 if (m_btNoChangeCounter > 5) StopBTScan();
889 if ((
int)m_BTscan_results.GetCount() == m_btlastResultCount)
890 m_btNoChangeCounter++;
892 m_btNoChangeCounter = 0;
894 m_btlastResultCount = m_BTscan_results.GetCount();
897 if (m_BTscanning >= 15) {
905void ConnectionEditDialog::StopBTScan(
void) {
906 m_BTScanTimer.Stop();
908 g_Platform->stopBluetoothScan();
912 if (m_buttonScanBT) {
913 m_buttonScanBT->SetLabel(_(
"BT Scan"));
914 m_buttonScanBT->Enable();
918void ConnectionEditDialog::OnConnValChange(wxCommandEvent& event) {
919 connectionsaved = FALSE;
923void ConnectionEditDialog::OnTypeSerialSelected(wxCommandEvent& event) {
924 OnConnValChange(event);
925 SetNMEAFormToSerial();
928void ConnectionEditDialog::OnTypeNetSelected(wxCommandEvent& event) {
929 OnConnValChange(event);
933void ConnectionEditDialog::OnTypeCANSelected(wxCommandEvent& event) {
934 OnConnValChange(event);
938void ConnectionEditDialog::OnTypeGPSSelected(wxCommandEvent& event) {
939 OnConnValChange(event);
943void ConnectionEditDialog::OnTypeBTSelected(wxCommandEvent& event) {
944 OnConnValChange(event);
948void ConnectionEditDialog::OnUploadFormatChange(wxCommandEvent& event) {
949 if (event.GetEventObject() == m_cbGarminUploadHost && event.IsChecked())
950 m_cbFurunoGP3X->SetValue(FALSE);
951 else if (event.GetEventObject() == m_cbFurunoGP3X && event.IsChecked())
952 m_cbGarminUploadHost->SetValue(FALSE);
954 OnConnValChange(event);
959void ConnectionEditDialog::ShowTypeCommon(
bool visible) {
960 m_rbTypeSerial->Show(visible);
961 m_rbTypeNet->Show(visible);
962#if defined(__linux__) && !defined(__ANDROID__) && !defined(__WXOSX__)
963 m_rbTypeCAN->Show(visible);
965 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->Show(visible);
966 if (m_rbTypeInternalBT) m_rbTypeInternalBT->Show(visible);
969void ConnectionEditDialog::ShowNMEACommon(
bool visible) {
970 bool advanced = m_advanced;
971 m_cbInput->Show(visible);
972 m_cbOutput->Show(visible);
973 m_stPrecision->Show(visible && advanced);
974 m_choicePrecision->Show(visible && advanced);
975 m_stPrecision->Show(visible && advanced);
976 m_stAuthToken->Show(visible && advanced);
977 m_tAuthToken->Show(visible && advanced);
979 const bool bout_enable = (m_cbOutput->IsChecked() && advanced);
980 m_stPrecision->Enable(bout_enable);
981 m_choicePrecision->Enable(bout_enable);
983 sbSizerOutFilter->SetDimension(0, 0, 0, 0);
984 sbSizerInFilter->SetDimension(0, 0, 0, 0);
985 sbSizerConnectionProps->SetDimension(0, 0, 0, 0);
986 m_sbConnEdit->SetLabel(
"");
989 m_cbCheckSKDiscover->Hide();
990 m_ButtonSKDiscover->Hide();
992 const bool bin_enable = (m_cbInput->IsChecked() && advanced);
993 ShowInFilter(visible && bin_enable);
994 const bool bout_enable = (m_cbOutput->IsChecked() && advanced);
995 ShowOutFilter(visible && bout_enable);
997 m_bNMEAParams_shown = visible;
1000void ConnectionEditDialog::ShowNMEANet(
bool visible) {
1001 bool advanced = m_advanced;
1002 m_stNetAddr->Show(visible);
1003 m_tNetAddress->Show(visible);
1004 m_stNetDataProtocol->Show(visible);
1005 m_stNetPort->Show(visible);
1006 m_choiceNetDataProtocol->Show(visible);
1007 m_tNetPort->Show(visible);
1008 m_stNetProto->Show(visible);
1009 m_rbNetProtoSignalK->Show(visible);
1010 m_rbNetProtoGPSD->Show(visible);
1011 m_rbNetProtoTCP->Show(visible);
1012 m_rbNetProtoUDP->Show(visible);
1013 m_stNetComment->Show(visible);
1014 m_tNetComment->Show(visible);
1015 m_stAuthToken->Show(visible);
1016 m_tAuthToken->Show(visible);
1017 m_cbGarminHost->Hide();
1020void ConnectionEditDialog::ShowNMEASerial(
bool visible) {
1021 bool advanced = m_advanced;
1022 m_stSerBaudrate->Show(visible);
1023 m_choiceBaudRate->Show(visible);
1024 m_stSerPort->Show(visible);
1025 m_comboPort->Show(visible);
1026 m_stSerProtocol->Show(visible);
1027 m_choiceSerialProtocol->Show(visible);
1028 m_cbGarminHost->Show(visible && advanced);
1029 m_stSerialComment->Show(visible);
1030 m_tSerialComment->Show(visible);
1033void ConnectionEditDialog::ShowNMEAGPS(
bool visible) {
1034 m_cbCheckSKDiscover->Hide();
1035 m_ButtonSKDiscover->Hide();
1036 m_stAuthToken->Hide();
1037 m_tAuthToken->Hide();
1041void ConnectionEditDialog::ShowNMEACAN(
bool visible) {
1042 m_stCANSource->Show(visible);
1043 m_choiceCANSource->Show(visible);
1046void ConnectionEditDialog::ShowNMEABT(
bool visible) {
1048 if (m_buttonScanBT) m_buttonScanBT->Show();
1049 if (m_stBTPairs) m_stBTPairs->Show();
1050 if (m_choiceBTDataSources) {
1051 if (m_choiceBTDataSources->GetCount() > 1)
1052 m_choiceBTDataSources->SetSelection(1);
1053 m_choiceBTDataSources->Show();
1056 if (m_buttonScanBT) m_buttonScanBT->Hide();
1057 if (m_stBTPairs) m_stBTPairs->Hide();
1058 if (m_choiceBTDataSources) m_choiceBTDataSources->Hide();
1060 m_cbCheckSKDiscover->Hide();
1061 m_stAuthToken->Hide();
1062 m_tAuthToken->Hide();
1063 m_cbCheckSKDiscover->Hide();
1064 m_ButtonSKDiscover->Hide();
1065 m_tcOutputStc->Show(visible);
1066 m_btnOutputStcList->Show(visible);
1067 m_cbOutput->Show(visible);
1070void ConnectionEditDialog::SetNMEAFormToSerial(
void) {
1071 bool advanced = m_advanced;
1072 ShowNMEACommon(TRUE);
1076 ShowNMEASerial(TRUE);
1078 SetDSFormRWStates();
1082void ConnectionEditDialog::SetNMEAFormToNet(
void) {
1083 bool advanced = m_advanced;
1084 ShowNMEACommon(TRUE);
1088 ShowNMEASerial(FALSE);
1090 SetUDPNetAddressVisiblity();
1091 SetDSFormRWStates();
1096void ConnectionEditDialog::SetNMEAFormToCAN(
void) {
1097 bool advanced = m_advanced;
1098 ShowNMEACommon(FALSE);
1102 ShowNMEASerial(FALSE);
1104 sbSizerInFilter->Show(
false);
1105 sbSizerOutFilter->Show(
false);
1106 SetDSFormRWStates();
1111void ConnectionEditDialog::SetNMEAFormToGPS(
void) {
1112 ShowNMEACommon(TRUE);
1116 ShowNMEASerial(FALSE);
1121 SetDSFormRWStates();
1125void ConnectionEditDialog::SetNMEAFormToBT(
void) {
1126 m_rbNetProtoUDP->SetValue(
true);
1127 ShowNMEACommon(TRUE);
1131 ShowNMEASerial(FALSE);
1136 SetDSFormRWStates();
1140void ConnectionEditDialog::ClearNMEAForm(
void) {
1141 ShowNMEACommon(FALSE);
1145 ShowNMEASerial(FALSE);
1152void ConnectionEditDialog::SetDSFormOptionVizStates(
void) {
1153 bool advanced = m_advanced;
1154 m_collapse_box->ShowItems(
true);
1157 m_stPrecision->Show(
true);
1158 m_choicePrecision->Show(
true);
1160 ShowInFilter(advanced);
1161 ShowOutFilter(advanced);
1164 m_stAuthToken->Show(advanced);
1165 m_tAuthToken->Show(advanced);
1167 m_StaticTextSKServerStatus->Show(advanced);
1169 if (m_rbTypeSerial->GetValue()) {
1170 m_cbMultiCast->Hide();
1171 m_cbCheckSKDiscover->Hide();
1172 m_stAuthToken->Hide();
1173 m_tAuthToken->Hide();
1174 m_ButtonSKDiscover->Hide();
1175 m_StaticTextSKServerStatus->Hide();
1176 bool n0183ctlenabled =
1177 (DataProtocol)m_choiceSerialProtocol->GetSelection() ==
1178 DataProtocol::PROTO_NMEA0183;
1179 bool n2kctlenabled = (DataProtocol)m_choiceSerialProtocol->GetSelection() ==
1180 DataProtocol::PROTO_NMEA2000;
1181 if (!n0183ctlenabled) {
1182 if (n2kctlenabled) {
1189 ShowOutFilter(
false);
1190 ShowInFilter(
false);
1191 m_stPrecision->Hide();
1192 m_choicePrecision->Hide();
1193 m_stNetDataProtocol->Hide();
1194 m_choiceNetDataProtocol->Hide();
1197 m_cbInput->Enable();
1199 ShowInFilter(m_cbInput->IsChecked() && advanced);
1200 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1202 m_stPrecision->Show(m_cbOutput->IsChecked() && advanced);
1203 m_choicePrecision->Show(m_cbOutput->IsChecked() && advanced);
1205 m_cbGarminHost->Show(m_cbInput->IsChecked() && advanced);
1209 if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue()) {
1210 m_cbMultiCast->Hide();
1211 m_cbCheckSKDiscover->Hide();
1212 m_stAuthToken->Hide();
1213 m_tAuthToken->Hide();
1214 m_ButtonSKDiscover->Hide();
1215 m_StaticTextSKServerStatus->Hide();
1218 ShowOutFilter(
false);
1219 ShowInFilter(
false);
1220 m_stPrecision->Hide();
1221 m_choicePrecision->Hide();
1222 m_cbGarminHost->Hide();
1223 m_collapse_box->ShowItems(
false);
1226 if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue()) {
1227 m_cbMultiCast->Hide();
1228 m_cbCheckSKDiscover->Hide();
1229 m_stAuthToken->Hide();
1230 m_tAuthToken->Hide();
1231 m_ButtonSKDiscover->Hide();
1232 m_StaticTextSKServerStatus->Hide();
1234 ShowInFilter(m_cbInput->IsChecked() && advanced);
1235 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1237 m_stPrecision->Show(m_cbOutput->IsChecked() && advanced);
1238 m_choicePrecision->Show(m_cbOutput->IsChecked() && advanced);
1241 if (m_rbTypeCAN->GetValue()) {
1242 m_cbMultiCast->Hide();
1243 m_cbCheckSKDiscover->Hide();
1244 m_stAuthToken->Hide();
1245 m_tAuthToken->Hide();
1246 m_ButtonSKDiscover->Hide();
1247 m_StaticTextSKServerStatus->Hide();
1248 m_cbGarminHost->Hide();
1252 ShowInFilter(
false);
1253 ShowOutFilter(
false);
1255 m_stPrecision->Hide();
1256 m_choicePrecision->Hide();
1258 m_stNetDataProtocol->Hide();
1259 m_choiceNetDataProtocol->Hide();
1260 m_collapse_box->Show(
false);
1263 if (m_rbTypeNet->GetValue()) {
1264 if (m_rbNetProtoGPSD->GetValue()) {
1265 m_cbMultiCast->Hide();
1266 m_cbCheckSKDiscover->Hide();
1270 ShowOutFilter(
false);
1271 m_stPrecision->Hide();
1272 m_choicePrecision->Hide();
1273 m_ButtonSKDiscover->Hide();
1274 m_StaticTextSKServerStatus->Hide();
1275 m_stAuthToken->Hide();
1276 m_tAuthToken->Hide();
1277 m_stNetDataProtocol->Hide();
1278 m_choiceNetDataProtocol->Hide();
1279 m_cbGarminHost->Hide();
1280 m_collapse_box->Show(
false);
1282 }
else if (m_rbNetProtoSignalK->GetValue()) {
1283 m_cbMultiCast->Hide();
1286 ShowInFilter(
false);
1287 ShowOutFilter(
false);
1288 m_stPrecision->Hide();
1289 m_choicePrecision->Hide();
1290 m_stNetDataProtocol->Hide();
1291 m_choiceNetDataProtocol->Hide();
1292 m_cbGarminHost->Hide();
1295 m_stAuthToken->Hide();
1296 m_tAuthToken->Hide();
1297 m_cbCheckSKDiscover->Hide();
1298 m_ButtonSKDiscover->Hide();
1299 m_StaticTextSKServerStatus->Hide();
1300 m_stNetDataProtocol->Show();
1301 m_choiceNetDataProtocol->Show();
1302 m_cbGarminHost->Hide();
1306 if ((DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1307 DataProtocol::PROTO_NMEA2000) {
1308 m_stPrecision->Hide();
1309 m_choicePrecision->Hide();
1311 ShowInFilter(
false);
1312 ShowOutFilter(
false);
1313 if (m_rbNetProtoTCP->GetValue()) m_collapse_box->ShowItems(
false);
1315 if ((DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1316 DataProtocol::PROTO_NMEA0183) {
1317 m_stPrecision->Show(advanced);
1318 m_choicePrecision->Show(advanced);
1319 m_stPrecision->Enable(m_cbOutput->IsChecked() && advanced);
1320 m_choicePrecision->Enable(m_cbOutput->IsChecked() && advanced);
1322 ShowInFilter(m_cbInput->IsChecked() && advanced);
1323 ShowOutFilter(m_cbOutput->IsChecked() && advanced);
1329void ConnectionEditDialog::SetDSFormRWStates(
void) {
1330 if (m_rbTypeSerial->GetValue()) {
1331 m_cbInput->Enable(TRUE);
1332 m_cbOutput->Enable(TRUE);
1334 ShowOutFilter(m_cbOutput->IsChecked());
1335 }
else if (m_rbNetProtoGPSD->GetValue()) {
1336 if (m_tNetPort->GetValue() == wxEmptyString)
1337 m_tNetPort->SetValue(DEFAULT_GPSD_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 m_btnOutputStcList->Enable(FALSE);
1345 }
else if (m_rbNetProtoSignalK->GetValue()) {
1346 if (m_tNetPort->GetValue() == wxEmptyString)
1347 m_tNetPort->SetValue(DEFAULT_SIGNALK_PORT);
1348 m_cbInput->SetValue(TRUE);
1349 m_cbInput->Enable(FALSE);
1351 m_cbOutput->Enable(FALSE);
1352 m_rbOAccept->Enable(FALSE);
1353 m_rbOIgnore->Enable(FALSE);
1354 UpdateDiscoverStatus(wxEmptyString);
1356 if (m_tNetPort->GetValue() == wxEmptyString) {
1357 if (m_rbNetProtoTCP->GetValue()) {
1358 m_tNetPort->SetValue(DEFAULT_TCP_PORT);
1360 m_tNetPort->SetValue(DEFAULT_UDP_PORT);
1363 m_cbInput->Enable(TRUE);
1364 m_cbOutput->Enable(TRUE);
1365 m_rbOAccept->Enable(TRUE);
1366 m_rbOIgnore->Enable(TRUE);
1367 m_btnOutputStcList->Enable(TRUE);
1370 SetDSFormOptionVizStates();
1374void ConnectionEditDialog::ShowInFilter(
bool bshow) {
1375 sbSizerInFilter->GetStaticBox()->Show(bshow);
1376 m_rbIAccept->Show(bshow);
1377 m_rbIIgnore->Show(bshow);
1378 m_tcInputStc->Show(bshow);
1379 m_btnInputStcList->Show(bshow);
1382void ConnectionEditDialog::ShowOutFilter(
bool bshow) {
1383 sbSizerOutFilter->GetStaticBox()->Show(bshow);
1384 m_rbOAccept->Show(bshow);
1385 m_rbOIgnore->Show(bshow);
1386 m_tcOutputStc->Show(bshow);
1387 m_btnOutputStcList->Show(bshow);
1392 SetConnectionParams(cp);
1396 if (wxNOT_FOUND == m_comboPort->FindString(cp->Port))
1397 m_comboPort->Append(cp->Port);
1399 m_comboPort->Select(m_comboPort->FindString(cp->Port));
1401 m_cbGarminHost->SetValue(cp->Garmin);
1402 m_cbInput->SetValue(cp->IOSelect != DS_TYPE_OUTPUT);
1403 m_cbOutput->SetValue(cp->IOSelect != DS_TYPE_INPUT);
1404 m_cbCheckSKDiscover->SetValue(cp->AutoSKDiscover);
1406 if (cp->InputSentenceListType == WHITELIST)
1407 m_rbIAccept->SetValue(TRUE);
1409 m_rbIIgnore->SetValue(TRUE);
1410 if (cp->OutputSentenceListType == WHITELIST)
1411 m_rbOAccept->SetValue(TRUE);
1413 m_rbOIgnore->SetValue(TRUE);
1414 m_tcInputStc->SetValue(StringArrayToString(cp->InputSentenceList));
1415 m_tcOutputStc->SetValue(StringArrayToString(cp->OutputSentenceList));
1416 m_choiceBaudRate->Select(
1417 m_choiceBaudRate->FindString(wxString::Format(
"%d", cp->Baudrate)));
1418 m_choiceSerialProtocol->Select(cp->Protocol);
1419 m_tNetAddress->SetValue(cp->NetworkAddress);
1421 m_choiceNetDataProtocol->Select(cp->Protocol);
1423 m_cbMultiCast->SetValue(IsAddressMultiCast(m_tNetAddress->GetValue()));
1425 if (cp->NetworkPort == 0)
1426 m_tNetPort->SetValue(wxEmptyString);
1428 m_tNetPort->SetValue(wxString::Format(wxT(
"%i"), cp->NetworkPort));
1430 if (cp->NetProtocol == TCP)
1431 m_rbNetProtoTCP->SetValue(TRUE);
1432 else if (cp->NetProtocol == UDP)
1433 m_rbNetProtoUDP->SetValue(TRUE);
1434 else if (cp->NetProtocol == GPSD)
1435 m_rbNetProtoGPSD->SetValue(TRUE);
1436 else if (cp->NetProtocol == SIGNALK)
1437 m_rbNetProtoSignalK->SetValue(TRUE);
1439 m_rbNetProtoGPSD->SetValue(TRUE);
1441 if (cp->Type == SERIAL) {
1442 m_rbTypeSerial->SetValue(TRUE);
1443 SetNMEAFormToSerial();
1444 SetNMEAFormForSerialProtocol();
1445 }
else if (cp->Type == NETWORK) {
1446 m_rbTypeNet->SetValue(TRUE);
1448 }
else if (cp->Type == SOCKETCAN) {
1449 m_rbTypeCAN->SetValue(TRUE);
1452 }
else if (cp->Type == INTERNAL_GPS) {
1453 if (m_rbTypeInternalGPS) m_rbTypeInternalGPS->SetValue(TRUE);
1455 }
else if (cp->Type == INTERNAL_BT) {
1456 if (m_rbTypeInternalBT) m_rbTypeInternalBT->SetValue(TRUE);
1460 wxString bts = cp->NetworkAddress +
";" + cp->GetPortStr();
1461 m_choiceBTDataSources->Clear();
1462 m_choiceBTDataSources->Append(bts);
1463 m_choiceBTDataSources->SetSelection(0);
1467 if (cp->Type == SERIAL)
1468 m_tSerialComment->SetValue(cp->UserComment);
1469 else if (cp->Type == NETWORK)
1470 m_tNetComment->SetValue(cp->UserComment);
1472 m_tAuthToken->SetValue(cp->AuthToken);
1474 m_connection_enabled = cp->bEnabled;
1477 connectionsaved =
true;
1480void ConnectionEditDialog::SetUDPNetAddressVisiblity(
void) {
1481 if (m_rbNetProtoUDP->GetValue() && !m_cbMultiCast->IsChecked() &&
1482 !m_cbOutput->IsChecked()) {
1485 m_tNetAddress->Enable(TRUE);
1487 m_stNetAddr->Show(TRUE);
1488 m_tNetAddress->Show(TRUE);
1489 m_tNetAddress->Enable(TRUE);
1491 if (!m_rbNetProtoUDP->GetValue()) {
1492 m_stNetAddr->Show(TRUE);
1493 m_tNetAddress->Show(TRUE);
1494 m_tNetAddress->Enable(TRUE);
1496 if (m_rbNetProtoUDP->GetValue() && m_advanced) {
1499 m_cbMultiCast->Hide();
1502void ConnectionEditDialog::SetDefaultConnectionParams(
void) {
1503 if (m_comboPort && !m_comboPort->IsListEmpty()) {
1504 m_comboPort->Select(0);
1505 m_comboPort->SetValue(wxEmptyString);
1507 m_cbGarminHost->SetValue(FALSE);
1508 m_cbInput->SetValue(TRUE);
1509 m_cbOutput->SetValue(FALSE);
1510 m_rbIAccept->SetValue(TRUE);
1511 m_rbOAccept->SetValue(TRUE);
1512 m_tcInputStc->SetValue(wxEmptyString);
1513 m_tcOutputStc->SetValue(wxEmptyString);
1514 m_choiceBaudRate->Select(m_choiceBaudRate->FindString(
"4800"));
1517 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1519 m_tNetComment->SetValue(wxEmptyString);
1520 m_tSerialComment->SetValue(wxEmptyString);
1521 m_tAuthToken->SetValue(wxEmptyString);
1523 bool bserial = TRUE;
1533 if (m_rbTypeInternalGPS) {
1534 m_rbTypeInternalGPS->SetValue(
true);
1537 m_rbTypeNet->SetValue(
true);
1542 m_rbTypeSerial->SetValue(bserial);
1543 m_rbTypeNet->SetValue(!bserial);
1544 bserial ? SetNMEAFormToSerial() : SetNMEAFormToNet();
1545 m_rbTypeCAN->SetValue(FALSE);
1548 m_connection_enabled = TRUE;
1551 connectionsaved =
false;
1554void ConnectionEditDialog::LayoutDialog() {
1555 gSizerNetProps->Layout();
1556 gSizerSerProps->Layout();
1559 GetSizer()->Layout();
1562void ConnectionEditDialog::UpdateSourceList(
bool bResort) {
1563 for (
auto* cp : TheConnectionParams()) {
1565 if (panel) panel->Update(cp);
1568 m_scrollWinConnections->Layout();
1571void ConnectionEditDialog::OnSelectDatasource(wxListEvent& event) {
1572 SetConnectionParams(TheConnectionParams()[event.GetData()]);
1573 m_buttonRemove->Enable();
1574 m_buttonRemove->Show();
1578void ConnectionEditDialog::OnDiscoverButton(wxCommandEvent& event) {
1582 std::string serviceIdent =
1583 std::string(
"_signalk-ws._tcp.local.");
1585 g_Platform->ShowBusySpinner();
1587 if (SignalKDataStream::DiscoverSKServer(serviceIdent, ip, port,
1590 m_tNetAddress->SetValue(ip);
1591 m_tNetPort->SetValue(wxString::Format(wxT(
"%i"), port));
1592 UpdateDiscoverStatus(_(
"Signal K server available."));
1594 UpdateDiscoverStatus(_(
"Signal K server not found."));
1596 g_Platform->HideBusySpinner();
1601void ConnectionEditDialog::UpdateDiscoverStatus(wxString stat) {
1602 m_StaticTextSKServerStatus->SetLabel(stat);
1605void ConnectionEditDialog::OnBtnIStcs(wxCommandEvent& event) {
1606 const ListType type = m_rbIAccept->GetValue() ? WHITELIST : BLACKLIST;
1607 const wxArrayString list = wxStringTokenize(m_tcInputStc->GetValue(),
",");
1610 if (dlg.ShowModal() == wxID_OK) m_tcInputStc->SetValue(dlg.GetSentences());
1613void ConnectionEditDialog::OnBtnOStcs(wxCommandEvent& event) {
1614 const ListType type = m_rbOAccept->GetValue() ? WHITELIST : BLACKLIST;
1615 const wxArrayString list = wxStringTokenize(m_tcOutputStc->GetValue(),
",");
1618 if (dlg.ShowModal() == wxID_OK) m_tcOutputStc->SetValue(dlg.GetSentences());
1621void ConnectionEditDialog::OnNetProtocolSelected(wxCommandEvent& event) {
1622 if (m_rbNetProtoGPSD->GetValue()) {
1623 if (IsDefaultPort(m_tNetPort->GetValue())) {
1624 m_tNetPort->SetValue(DEFAULT_GPSD_PORT);
1626 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1627 }
else if (m_rbNetProtoUDP->GetValue()) {
1628 if (IsDefaultPort(m_tNetPort->GetValue())) {
1629 m_tNetPort->SetValue(DEFAULT_UDP_PORT);
1631 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1632 if (m_cbInput->GetValue() && !m_cbMultiCast->GetValue() &&
1633 m_rbNetProtoUDP->GetValue())
1634 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1635 else if (m_cbOutput->GetValue() && !m_cbMultiCast->GetValue())
1636 m_tNetPort->SetValue(DEFAULT_UDP_OUT_ADDRESS);
1638 if (m_cbInput->GetValue() && m_cbOutput->GetValue())
1639 m_cbOutput->SetValue(
false);
1641 }
else if (m_rbNetProtoSignalK->GetValue()) {
1642 if (IsDefaultPort(m_tNetPort->GetValue())) {
1643 m_tNetPort->SetValue(DEFAULT_SIGNALK_PORT);
1645 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1646 }
else if (m_rbNetProtoTCP->GetValue()) {
1647 if (IsDefaultPort(m_tNetPort->GetValue())) {
1648 m_tNetPort->SetValue(DEFAULT_TCP_PORT);
1650 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1653 SetUDPNetAddressVisiblity();
1654 SetDSFormRWStates();
1656 OnConnValChange(event);
1659void ConnectionEditDialog::OnRbAcceptInput(wxCommandEvent& event) {
1660 OnConnValChange(event);
1662void ConnectionEditDialog::OnRbIgnoreInput(wxCommandEvent& event) {
1663 OnConnValChange(event);
1666void ConnectionEditDialog::OnRbOutput(wxCommandEvent& event) {
1667 OnConnValChange(event);
1670void ConnectionEditDialog::OnCbInput(wxCommandEvent& event) {
1671 const bool checked = m_cbInput->IsChecked();
1672 ShowInFilter(checked);
1673 if (checked && m_rbNetProtoUDP->GetValue() && m_rbTypeNet->GetValue()) {
1674 m_cbOutput->SetValue(FALSE);
1676 if (!m_cbMultiCast->GetValue()) m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1678 SetDSFormRWStates();
1680 if (m_rbTypeNet->GetValue()) SetUDPNetAddressVisiblity();
1681 OnConnValChange(event);
1684void ConnectionEditDialog::OnCbOutput(wxCommandEvent& event) {
1685 OnConnValChange(event);
1686 const bool checked = m_cbOutput->IsChecked();
1687 m_stPrecision->Enable(checked);
1688 m_choicePrecision->Enable(checked);
1689 ShowOutFilter(checked);
1691 if (!m_cbMultiCast->IsChecked() && m_rbNetProtoUDP->GetValue()) {
1693 m_tNetAddress->SetValue(
1694 DEFAULT_UDP_OUT_ADDRESS);
1696 NetworkProtocol proto = UDP;
1697 for (
auto* cp : TheConnectionParams()) {
1698 if (cp->NetProtocol == proto &&
1699 cp->NetworkPort == wxAtoi(m_tNetPort->GetValue()) &&
1700 cp->IOSelect == DS_TYPE_INPUT) {
1703 SetNMEAFormForNetProtocol();
1710 _(
"There is an enabled UDP input connection that uses the "
1713 << _(
"Please apply a filter on both connections to avoid a "
1718 _(
"There is a disabled UDP Input connection that uses the "
1721 << _(
"If you enable that input please apply a filter on both "
1722 "connections to avoid a feedback loop.");
1725 << _(
"Or consider using a different data port for one of them");
1727 OCPNMessageBox(
this, mes, _(
"OpenCPN Warning"),
1728 wxOK | wxICON_EXCLAMATION, 60);
1730 OCPNMessageBox(
this, mes, _(
"OpenCPN info"),
1731 wxOK | wxICON_INFORMATION, 60);
1736 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1740 if (checked && m_rbNetProtoUDP->GetValue()) {
1741 m_cbInput->SetValue(FALSE);
1744 if (m_rbTypeNet->GetValue()) SetUDPNetAddressVisiblity();
1745 SetDSFormRWStates();
1749void ConnectionEditDialog::OnCbMultiCast(wxCommandEvent& event) {
1750 const bool checked = m_cbMultiCast->IsChecked();
1752 if (!IsAddressMultiCast(m_tNetAddress->GetValue())) {
1753 m_tNetAddress->SetValue(
"224.0.2.21");
1755 }
else if (m_cbOutput->IsChecked()) {
1756 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1758 m_tNetAddress->SetValue(DEFAULT_IP_ADDRESS);
1761 SetUDPNetAddressVisiblity();
1765void ConnectionEditDialog::OnCollapsedToggle(
bool collapsed) {
1766 m_advanced = !collapsed;
1767 if (m_rbTypeNet->GetValue())
1768 SetNMEAFormForNetProtocol();
1770 SetNMEAFormForSerialProtocol();
1774void ConnectionEditDialog::OnCbAdvanced(wxCommandEvent& event) {
1775 if (m_rbTypeNet->GetValue())
1776 SetNMEAFormForNetProtocol();
1778 SetNMEAFormForSerialProtocol();
1782void ConnectionEditDialog::OnShowGpsWindowCheckboxClick(wxCommandEvent& event) {
1797 if (m_container->GetRect().Contains(logRect)) {
1798 NMEALogWindow::Get().SetPos(
1799 m_container->GetRect().x / 2,
1800 (m_container->GetRect().y +
1801 (m_container->GetRect().height - logRect.height) / 2));
1802 NMEALogWindow::Get().Move();
1808void ConnectionEditDialog::SetNMEAFormForSerialProtocol() {
1809 bool n0183ctlenabled = (DataProtocol)m_choiceSerialProtocol->GetSelection() ==
1810 DataProtocol::PROTO_NMEA0183;
1811 bool advanced = m_advanced;
1812 ShowNMEACommon(n0183ctlenabled && advanced);
1813 m_cbGarminHost->Show(n0183ctlenabled && advanced);
1815 SetDSFormRWStates();
1819void ConnectionEditDialog::SetNMEAFormForNetProtocol() {
1820 bool n0183ctlenabled =
1821 (DataProtocol)m_choiceNetDataProtocol->GetSelection() ==
1822 DataProtocol::PROTO_NMEA0183;
1823 bool advanced = m_advanced;
1824 ShowNMEACommon(n0183ctlenabled && advanced);
1825 m_cbGarminHost->Show(n0183ctlenabled && advanced);
1827 SetDSFormRWStates();
1832void ConnectionEditDialog::OnProtocolChoice(wxCommandEvent& event) {
1833 if (m_rbTypeNet->GetValue())
1834 SetNMEAFormForNetProtocol();
1836 SetNMEAFormForSerialProtocol();
1838 OnConnValChange(event);
1841void ConnectionEditDialog::ApplySettings() {
1843 g_bfilter_cogsog = m_cbFilterSogCog->GetValue();
1845 long filter_val = 1;
1846 m_tFilterSec->GetValue().ToLong(&filter_val);
1848 wxMin(
static_cast<int>(filter_val),
1850 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
1851 g_SOGFilterSec = g_COGFilterSec;
1853 g_bMagneticAPB = m_cbAPBMagnetic->GetValue();
1854 g_NMEAAPBPrecision = m_choicePrecision->GetCurrentSelection();
1861 NetworkProtocol lastNetProtocol = PROTO_UNDEFINED;
1862 DataProtocol lastDataProtocol = PROTO_NMEA0183;
1864 if (mSelectedConnection) {
1866 lastAddr = cpo->NetworkAddress;
1867 lastPort = cpo->NetworkPort;
1868 lastNetProtocol = cpo->NetProtocol;
1869 lastDataProtocol = cpo->Protocol;
1872 if (!connectionsaved) {
1873 size_t nCurrentPanelCount = TheConnectionParams()->GetCount();
1875 int old_priority = -1;
1877 if (mSelectedConnection) {
1878 cp = mSelectedConnection;
1879 old_priority = cp->Priority;
1880 UpdateConnectionParamsFromControls(cp);
1881 cp->b_IsSetup =
false;
1893 cp = CreateConnectionParamsFromSelectedItem();
1894 if (cp) TheConnectionParams()->Add(cp);
1899 cp->LastNetProtocol = lastNetProtocol;
1900 cp->LastNetworkAddress = lastAddr;
1901 cp->LastNetworkPort = lastPort;
1902 cp->LastDataProtocol = lastDataProtocol;
1905 if (TheConnectionParams()->GetCount() != nCurrentPanelCount)
1907 else if (old_priority >= 0) {
1908 if (old_priority != cp->Priority)
1909 UpdateSourceList(
true);
1911 UpdateSourceList(
false);
1914 connectionsaved = TRUE;
1921 SetSelectedConnectionPanel(
nullptr);
1925 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
1928 if (cp->b_IsSetup)
continue;
1933 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
1936 StopAndRemoveCommDriver(cp->GetLastDSPort(), cp->GetLastCommProtocol());
1940 if (cp->Type == INTERNAL_BT) wxSleep(1);
1943 if (!cp->bEnabled)
continue;
1947 cp->b_IsSetup = TRUE;
1950 g_bGarminHostUpload = m_cbGarminUploadHost->GetValue();
1952 m_cbFurunoGP3X->GetValue() ?
"FurunoGP3X" :
"Generic";
1957ConnectionEditDialog::CreateConnectionParamsFromSelectedItem() {
1963 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() ==
"Deleted")
1970 if (!(m_cbInput->GetValue() || m_cbOutput->GetValue())) {
1971 m_cbInput->SetValue(
true);
1974 if (m_rbTypeSerial->GetValue() && m_comboPort->GetValue() == wxEmptyString) {
1975 m_comboPort->Select(0);
1979 else if (m_rbTypeNet->GetValue()) {
1980 if (wxAtoi(m_tNetPort->GetValue()) == 0) {
1981 m_tNetPort->SetValue(
"10110");
1983 if (m_tNetAddress->GetValue() == wxEmptyString) {
1984 m_tNetAddress->SetValue(
"0.0.0.0");
1986 }
else if (m_rbTypeCAN->GetValue()) {
1991 UpdateConnectionParamsFromSelectedItem(pConnectionParams);
1994 m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1995 pConnectionParams,
this);
1996 pPanel->SetSelected(
false);
1997 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxALL, 0);
1998 pConnectionParams->m_optionsPanel = pPanel;
2000 return pConnectionParams;
2007 UpdateConnectionParamsFromControls(pConnectionParams);
2008 return pConnectionParams;
2013 pConnectionParams->Valid = TRUE;
2014 if (m_rbTypeSerial->GetValue())
2015 pConnectionParams->Type = SERIAL;
2016 else if (m_rbTypeNet->GetValue())
2017 pConnectionParams->Type = NETWORK;
2018 else if (m_rbTypeInternalGPS && m_rbTypeInternalGPS->GetValue())
2019 pConnectionParams->Type = INTERNAL_GPS;
2020 else if (m_rbTypeInternalBT && m_rbTypeInternalBT->GetValue())
2021 pConnectionParams->Type = INTERNAL_BT;
2022 else if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
2023 pConnectionParams->Type = SOCKETCAN;
2025 if (m_rbTypeNet->GetValue()) {
2027 pConnectionParams->LastNetworkAddress = pConnectionParams->NetworkAddress;
2028 pConnectionParams->LastNetworkPort = pConnectionParams->NetworkPort;
2029 pConnectionParams->LastNetProtocol = pConnectionParams->NetProtocol;
2030 pConnectionParams->LastDataProtocol = pConnectionParams->Protocol;
2032 pConnectionParams->NetworkAddress =
2033 m_tNetAddress->GetValue().Trim(
false).Trim(
true);
2034 pConnectionParams->NetworkPort =
2035 wxAtoi(m_tNetPort->GetValue().Trim(
false).Trim(
true));
2036 if (m_rbNetProtoTCP->GetValue()) {
2037 pConnectionParams->NetProtocol = TCP;
2038 pConnectionParams->Protocol =
2039 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2040 }
else if (m_rbNetProtoUDP->GetValue()) {
2041 pConnectionParams->NetProtocol = UDP;
2042 pConnectionParams->Protocol =
2043 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2044 }
else if (m_rbNetProtoGPSD->GetValue())
2045 pConnectionParams->NetProtocol = GPSD;
2046 else if (m_rbNetProtoSignalK->GetValue())
2047 pConnectionParams->NetProtocol = SIGNALK;
2049 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2052 if (m_rbTypeSerial->GetValue())
2053 pConnectionParams->Protocol =
2054 (DataProtocol)m_choiceSerialProtocol->GetSelection();
2055 else if (m_rbTypeNet->GetValue())
2056 pConnectionParams->Protocol =
2057 (DataProtocol)m_choiceNetDataProtocol->GetSelection();
2059 pConnectionParams->Baudrate = wxAtoi(m_choiceBaudRate->GetStringSelection());
2060 pConnectionParams->ChecksumCheck =
true;
2061 pConnectionParams->AutoSKDiscover = m_cbCheckSKDiscover->GetValue();
2062 pConnectionParams->Garmin = m_cbGarminHost->GetValue();
2063 pConnectionParams->InputSentenceList =
2064 wxStringTokenize(m_tcInputStc->GetValue(),
",");
2065 if (m_rbIAccept->GetValue())
2066 pConnectionParams->InputSentenceListType = WHITELIST;
2068 pConnectionParams->InputSentenceListType = BLACKLIST;
2069 if (m_cbInput->GetValue()) {
2070 if (m_cbOutput->GetValue()) {
2071 pConnectionParams->IOSelect = DS_TYPE_INPUT_OUTPUT;
2073 pConnectionParams->IOSelect = DS_TYPE_INPUT;
2076 pConnectionParams->IOSelect = DS_TYPE_OUTPUT;
2078 pConnectionParams->OutputSentenceList =
2079 wxStringTokenize(m_tcOutputStc->GetValue(),
",");
2080 if (m_rbOAccept->GetValue())
2081 pConnectionParams->OutputSentenceListType = WHITELIST;
2083 pConnectionParams->OutputSentenceListType = BLACKLIST;
2084 pConnectionParams->Port = m_comboPort->GetValue().BeforeFirst(
' ');
2085#if defined(__linux__) && !defined(__ANDROID__)
2086 if (pConnectionParams->Type == SERIAL)
2090 if (m_rbTypeCAN && m_rbTypeCAN->GetValue())
2091 pConnectionParams->Protocol = PROTO_NMEA2000;
2093 pConnectionParams->bEnabled = m_connection_enabled;
2094 pConnectionParams->b_IsSetup = FALSE;
2096 if (pConnectionParams->Type == INTERNAL_GPS) {
2097 pConnectionParams->NetworkAddress =
"";
2098 pConnectionParams->NetworkPort = 0;
2099 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2100 pConnectionParams->Baudrate = 0;
2101 pConnectionParams->Port =
"Internal GPS";
2104 if (pConnectionParams->Type == INTERNAL_BT) {
2105 wxString parms = m_choiceBTDataSources->GetStringSelection();
2106 wxStringTokenizer tkz(parms,
";");
2107 wxString name = tkz.GetNextToken();
2108 wxString mac = tkz.GetNextToken();
2110 pConnectionParams->NetworkAddress = name;
2111 pConnectionParams->Port = mac;
2112 pConnectionParams->NetworkPort = 0;
2113 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2114 pConnectionParams->Baudrate = 0;
2118 if (pConnectionParams->Type == SOCKETCAN) {
2119 pConnectionParams->NetworkAddress =
"";
2120 pConnectionParams->NetworkPort = 0;
2121 pConnectionParams->NetProtocol = PROTO_UNDEFINED;
2122 pConnectionParams->Baudrate = 0;
2123 pConnectionParams->socketCAN_port =
2124 m_choiceCANSource->GetString(m_choiceCANSource->GetSelection());
2127 if (pConnectionParams->Type == SERIAL) {
2128 pConnectionParams->UserComment = m_tSerialComment->GetValue();
2129 }
else if (pConnectionParams->Type == NETWORK) {
2130 pConnectionParams->UserComment = m_tNetComment->GetValue();
2132 pConnectionParams->AuthToken = m_tAuthToken->GetValue();
2134 return pConnectionParams;
2137void ConnectionEditDialog::OnPriorityDialog(wxCommandEvent& event) {
2142void ConnectionEditDialog::ConnectControls() {
2144 m_rbTypeSerial->Connect(
2145 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2146 wxCommandEventHandler(ConnectionEditDialog::OnTypeSerialSelected), NULL,
2148 m_rbTypeNet->Connect(
2149 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2150 wxCommandEventHandler(ConnectionEditDialog::OnTypeNetSelected), NULL,
2153 m_rbTypeCAN->Connect(
2154 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2155 wxCommandEventHandler(ConnectionEditDialog::OnTypeCANSelected), NULL,
2158 if (m_rbTypeInternalGPS)
2159 m_rbTypeInternalGPS->Connect(
2160 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2161 wxCommandEventHandler(ConnectionEditDialog::OnTypeGPSSelected), NULL,
2163 if (m_rbTypeInternalBT)
2164 m_rbTypeInternalBT->Connect(
2165 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2166 wxCommandEventHandler(ConnectionEditDialog::OnTypeBTSelected), NULL,
2170 m_rbNetProtoTCP->Connect(
2171 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2172 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2174 m_rbNetProtoUDP->Connect(
2175 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2176 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2178 m_rbNetProtoGPSD->Connect(
2179 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2180 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2182 m_rbNetProtoSignalK->Connect(
2183 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2184 wxCommandEventHandler(ConnectionEditDialog::OnNetProtocolSelected), NULL,
2186 m_choiceNetDataProtocol->Connect(
2187 wxEVT_COMMAND_CHOICE_SELECTED,
2188 wxCommandEventHandler(ConnectionEditDialog::OnProtocolChoice), NULL,
2190 m_choiceSerialProtocol->Connect(
2191 wxEVT_COMMAND_CHOICE_SELECTED,
2192 wxCommandEventHandler(ConnectionEditDialog::OnProtocolChoice), NULL,
2194 m_cbMultiCast->Connect(
2195 wxEVT_COMMAND_CHECKBOX_CLICKED,
2196 wxCommandEventHandler(ConnectionEditDialog::OnCbMultiCast), NULL,
this);
2199 m_cbInput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2200 wxCommandEventHandler(ConnectionEditDialog::OnCbInput),
2202 m_cbOutput->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2203 wxCommandEventHandler(ConnectionEditDialog::OnCbOutput),
2207 m_buttonScanBT->Connect(
2208 wxEVT_COMMAND_BUTTON_CLICKED,
2209 wxCommandEventHandler(ConnectionEditDialog::OnScanBTClick), NULL,
this);
2224 m_btnInputStcList->Connect(
2225 wxEVT_COMMAND_BUTTON_CLICKED,
2226 wxCommandEventHandler(ConnectionEditDialog::OnBtnIStcs), NULL,
this);
2229 m_btnOutputStcList->Connect(
2230 wxEVT_COMMAND_BUTTON_CLICKED,
2231 wxCommandEventHandler(ConnectionEditDialog::OnBtnOStcs), NULL,
this);
2234 m_tNetAddress->Connect(
2235 wxEVT_COMMAND_TEXT_UPDATED,
2236 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2237 m_tNetPort->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2238 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange),
2240 m_comboPort->Connect(
2241 wxEVT_COMMAND_COMBOBOX_SELECTED,
2242 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2243 m_comboPort->Connect(
2244 wxEVT_COMMAND_TEXT_UPDATED,
2245 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2246 m_choiceBaudRate->Connect(
2247 wxEVT_COMMAND_CHOICE_SELECTED,
2248 wxCommandEventHandler(ConnectionEditDialog::OnBaudrateChoice), NULL,
this);
2249 m_choicePriority->Connect(
2250 wxEVT_COMMAND_CHOICE_SELECTED,
2251 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2252 m_choiceCANSource->Connect(
2253 wxEVT_COMMAND_CHOICE_SELECTED,
2254 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2255 m_cbCheckCRC->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
2256 wxCommandEventHandler(ConnectionEditDialog::OnCrcCheck),
2258 m_cbGarminHost->Connect(
2259 wxEVT_COMMAND_CHECKBOX_CLICKED,
2260 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2262 m_cbGarminUploadHost->Connect(
2263 wxEVT_COMMAND_CHECKBOX_CLICKED,
2264 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2266 m_cbFurunoGP3X->Connect(
2267 wxEVT_COMMAND_CHECKBOX_CLICKED,
2268 wxCommandEventHandler(ConnectionEditDialog::OnUploadFormatChange), NULL,
2270 m_cbCheckSKDiscover->Connect(
2271 wxEVT_COMMAND_CHECKBOX_CLICKED,
2272 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2273 m_ButtonSKDiscover->Connect(
2274 wxEVT_COMMAND_BUTTON_CLICKED,
2275 wxCommandEventHandler(ConnectionEditDialog::OnDiscoverButton), NULL,
this);
2277 m_rbOAccept->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2278 wxCommandEventHandler(ConnectionEditDialog::OnRbOutput),
2280 m_rbOIgnore->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
2281 wxCommandEventHandler(ConnectionEditDialog::OnRbOutput),
2283 m_tcOutputStc->Connect(
2284 wxEVT_COMMAND_TEXT_UPDATED,
2285 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2286 m_cbCheckCRC->Connect(
2287 wxEVT_COMMAND_CHECKBOX_CLICKED,
2288 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2290 m_cbNMEADebug->Connect(
2291 wxEVT_COMMAND_CHECKBOX_CLICKED,
2292 wxCommandEventHandler(ConnectionEditDialog::OnShowGpsWindowCheckboxClick),
2294 m_cbFilterSogCog->Connect(
2295 wxEVT_COMMAND_CHECKBOX_CLICKED,
2296 wxCommandEventHandler(ConnectionEditDialog::OnValChange), NULL,
this);
2297 m_tFilterSec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
2298 wxCommandEventHandler(ConnectionEditDialog::OnValChange),
2300 m_cbAPBMagnetic->Connect(
2301 wxEVT_COMMAND_CHECKBOX_CLICKED,
2302 wxCommandEventHandler(ConnectionEditDialog::OnValChange), NULL,
this);
2304 m_ButtonPriorityDialog->Connect(
2305 wxEVT_COMMAND_BUTTON_CLICKED,
2306 wxCommandEventHandler(ConnectionEditDialog::OnPriorityDialog), NULL,
this);
2308 m_tNetComment->Connect(
2309 wxEVT_COMMAND_TEXT_UPDATED,
2310 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2311 m_tSerialComment->Connect(
2312 wxEVT_COMMAND_TEXT_UPDATED,
2313 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2314 m_tAuthToken->Connect(
2315 wxEVT_COMMAND_TEXT_UPDATED,
2316 wxCommandEventHandler(ConnectionEditDialog::OnConnValChange), NULL,
this);
2319 m_buttonScanBT->Connect(
2320 wxEVT_COMMAND_BUTTON_CLICKED,
2321 wxCommandEventHandler(ConnectionEditDialog::OnScanBTClick), NULL,
this);
2325bool ConnectionEditDialog::IsAddressMultiCast(wxString ip) {
2326 wxArrayString bytes = wxSplit(ip,
'.');
2327 if (bytes.size() != 4) {
2330 unsigned long ipNum = (wxAtoi(bytes[0]) << 24) + (wxAtoi(bytes[1]) << 16) +
2331 (wxAtoi(bytes[2]) << 8) + wxAtoi(bytes[3]);
2332 unsigned long multicastStart = (224 << 24);
2333 unsigned long multicastEnd = (239 << 24) + (255 << 16) + (255 << 8) + 255;
2334 return ipNum >= multicastStart && ipNum <= multicastEnd;
2337bool ConnectionEditDialog::IsDefaultPort(wxString address) {
2338 return (address == DEFAULT_TCP_PORT) || (address == DEFAULT_UDP_PORT) ||
2339 (address == DEFAULT_SIGNALK_PORT) || (address == DEFAULT_GPSD_PORT);
2342bool ConnectionEditDialog::IsAddressBroadcast(wxString ip) {
2343 wxArrayString bytes = wxSplit(ip,
'.');
2344 if (bytes.size() != 4) {
2345 std::cerr <<
"Invalid IP format." << std::endl;
2348 return wxAtoi(bytes[3]) == 255;
2351SentenceListDlg::SentenceListDlg(wxWindow* parent, FilterDirection dir,
2352 ListType type,
const wxArrayString& list)
2353 : wxDialog(parent, wxID_ANY, _(
"Sentence Filter"), wxDefaultPosition,
2357 m_sentences(NMEA0183().GetRecognizedArray()) {
2359 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
2360 wxBoxSizer* secondSizer =
new wxBoxSizer(wxHORIZONTAL);
2361 wxStaticBox* pclbBox =
new wxStaticBox(
this, wxID_ANY, GetBoxLabel());
2362 wxStaticBoxSizer* stcSizer =
new wxStaticBoxSizer(pclbBox, wxVERTICAL);
2363 m_clbSentences =
new wxCheckListBox(
this, wxID_ANY, wxDefaultPosition,
2364 wxDefaultSize, m_sentences);
2365 wxBoxSizer* btnEntrySizer =
new wxBoxSizer(wxVERTICAL);
2366 wxButton* btnCheckAll =
new wxButton(
this, wxID_ANY, _(
"Select All"));
2367 wxButton* btnClearAll =
new wxButton(
this, wxID_ANY, _(
"Clear All"));
2368 wxButton* btnAdd =
new wxButton(
this, wxID_ANY, _(
"Add"));
2369 m_btnDel =
new wxButton(
this, wxID_ANY, _(
"Delete"));
2370 m_btnDel->Disable();
2371 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
2372 wxButton* btnOK =
new wxButton(
this, wxID_OK);
2373 wxButton* btnCancel =
new wxButton(
this, wxID_CANCEL, _(
"Cancel"));
2375 secondSizer->Add(stcSizer, 1, wxALL | wxEXPAND, 5);
2376 stcSizer->Add(m_clbSentences, 1, wxALL | wxEXPAND, 5);
2377 btnEntrySizer->Add(btnCheckAll, 0, wxALL, 5);
2378 btnEntrySizer->Add(btnClearAll, 0, wxALL, 5);
2379 btnEntrySizer->AddSpacer(1);
2380 btnEntrySizer->Add(btnAdd, 0, wxALL, 5);
2381 btnEntrySizer->Add(m_btnDel, 0, wxALL, 5);
2382 secondSizer->Add(btnEntrySizer, 0, wxALL | wxEXPAND, 5);
2383 mainSizer->Add(secondSizer, 1, wxEXPAND, 5);
2384 btnSizer->AddButton(btnOK);
2385 btnSizer->AddButton(btnCancel);
2386 btnSizer->Realize();
2387 mainSizer->Add(btnSizer, 0, wxALL | wxEXPAND, 5);
2389 SetSizer(mainSizer);
2390 mainSizer->SetSizeHints(
this);
2394 btnAdd->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2395 wxCommandEventHandler(SentenceListDlg::OnAddClick), NULL,
2397 m_btnDel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2398 wxCommandEventHandler(SentenceListDlg::OnDeleteClick), NULL,
2400 m_clbSentences->Connect(wxEVT_COMMAND_LISTBOX_SELECTED,
2401 wxCommandEventHandler(SentenceListDlg::OnCLBSelect),
2403 btnCheckAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2404 wxCommandEventHandler(SentenceListDlg::OnCheckAllClick),
2406 btnClearAll->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2407 wxCommandEventHandler(SentenceListDlg::OnClearAllClick),
2413wxString SentenceListDlg::GetBoxLabel(
void)
const {
2414 if (m_dir == FILTER_OUTPUT)
2415 return m_type == WHITELIST ? _(
"Transmit sentences") : _(
"Drop sentences");
2417 return m_type == WHITELIST ? _(
"Accept only sentences")
2418 : _(
"Ignore sentences");
2421void SentenceListDlg::Populate(
const wxArrayString& list) {
2422 if (m_dir == FILTER_OUTPUT) {
2424 m_sentences.Add(g_TalkerIdText + wxString(
"RMB"));
2425 m_sentences.Add(g_TalkerIdText + wxString(
"RMC"));
2426 m_sentences.Add(g_TalkerIdText + wxString(
"APB"));
2427 m_sentences.Add(g_TalkerIdText + wxString(
"XTE"));
2429 m_sentences.Add(
"AIVDM");
2430 m_sentences.Add(
"AIVDO");
2431 m_sentences.Add(
"FRPOS");
2432 m_sentences.Add(g_TalkerIdText);
2433 m_sentences.Add(
"CD");
2435 m_clbSentences->Clear();
2436 m_clbSentences->InsertItems(m_sentences, 0);
2438 wxArrayString new_strings;
2440 if (list.Count() == 0) {
2441 for (
size_t i = 0; i < m_clbSentences->GetCount(); ++i)
2442 m_clbSentences->Check(i, m_type == WHITELIST);
2444 for (
size_t i = 0; i < list.Count(); ++i) {
2445 int item = m_clbSentences->FindString(list[i]);
2446 if (item != wxNOT_FOUND)
2447 m_clbSentences->Check(item);
2449 new_strings.Add(list[i]);
2451 if (new_strings.GetCount()) {
2452 m_clbSentences->InsertItems(new_strings, m_clbSentences->GetCount());
2453 for (
size_t i = 0; i < new_strings.GetCount(); ++i) {
2454 int item = m_clbSentences->FindString(new_strings[i]);
2455 if (item != wxNOT_FOUND) m_clbSentences->Check(item);
2461wxString SentenceListDlg::GetSentences(
void) {
2462 wxArrayString retString;
2463 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++) {
2464 if (m_clbSentences->IsChecked(i))
2465 retString.Add(m_clbSentences->GetString(i));
2467 return StringArrayToString(retString);
2470void SentenceListDlg::OnCLBSelect(wxCommandEvent& e) {
2473 m_btnDel->Enable(m_sentences.Index(e.GetString()) == wxNOT_FOUND);
2476void SentenceListDlg::OnAddClick(wxCommandEvent& event) {
2478 androidDisableRotation();
2481 wxTextEntryDialog textdlg(
2483 _(
"Enter the NMEA sentence (2, 3 or 5 characters)\n or a valid REGEX "
2484 "expression (6 characters or longer)"),
2485 _(
"Enter the NMEA sentence"));
2487 textdlg.SetTextValidator(wxFILTER_ASCII);
2488 int result = textdlg.ShowModal();
2491 androidEnableRotation();
2494 if (result == wxID_CANCEL)
return;
2495 wxString stc = textdlg.GetValue();
2497 if (stc.Length() == 2 || stc.Length() == 3 || stc.Length() == 5) {
2498 m_clbSentences->Append(stc);
2499 m_clbSentences->Check(m_clbSentences->FindString(stc));
2501 }
else if (stc.Length() < 2) {
2504 _(
"An NMEA sentence is generally 3 characters long (like RMC, GGA etc.)\n \
2505 It can also have a two letter prefix identifying the source, or TALKER, of the message.\n \
2506 The whole sentences then looks like GPGGA or AITXT.\n \
2507 You may filter out all the sentences with certain TALKER prefix (like GP, AI etc.).\n \
2508 The filter also accepts Regular Expressions (REGEX) with 6 or more characters. \n\n"),
2517 m_clbSentences->Append(stc);
2518 m_clbSentences->Check(m_clbSentences->FindString(stc));
2521 OCPNMessageBox(
this, _(
"REGEX syntax error: \n") + stc,
2528void SentenceListDlg::OnDeleteClick(wxCommandEvent& event) {
2529 m_clbSentences->Delete(m_clbSentences->GetSelection());
2532void SentenceListDlg::OnClearAllClick(wxCommandEvent& event) {
2533 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++)
2534 m_clbSentences->Check(i, FALSE);
2537void SentenceListDlg::OnCheckAllClick(wxCommandEvent& event) {
2538 for (
size_t i = 0; i < m_clbSentences->GetCount(); i++)
2539 m_clbSentences->Check(i, TRUE);
Panel for displaying and editing connection parameters.
Simple panel showing either an "expand" or "collapse" icon, state switches when clicked.
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.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
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.