29 #include <wx/wxprec.h>
35 #include <wx/statline.h>
37 #include "model/comm_drv_factory.h"
38 #include "model/config_vars.h"
39 #include "model/sys_events.h"
41 #include "connections_dialog.h"
42 #include "conn_params_panel.h"
43 #include "NMEALogWindow.h"
44 #include "OCPNPlatform.h"
46 #include "priority_gui.h"
47 #include "connection_edit.h"
49 extern bool g_bfilter_cogsog;
50 extern int g_COGFilterSec;
51 extern int g_SOGFilterSec;
59 ConnectionsDialog::ConnectionsDialog() {}
61 ConnectionsDialog::ConnectionsDialog(wxScrolledWindow* container,
63 m_container = container;
69 ConnectionsDialog::~ConnectionsDialog() {}
71 void ConnectionsDialog::SetInitialSettings(
void) {
73 m_cbNMEADebug->SetValue(
false);
74 if (NMEALogWindow::GetInstance().GetTTYWindow()) {
75 if (NMEALogWindow::GetInstance().GetTTYWindow()->IsShown()) {
76 m_cbNMEADebug->SetValue(
true);
83 SetSelectedConnectionPanel(
nullptr);
87 void ::ConnectionsDialog::OnSize(wxSizeEvent &ev){
89 m_sbSizerLB->Layout();
92 void ConnectionsDialog::Init() {
94 mSelectedConnection = NULL;
100 bool bcompact =
false;
101 wxSize displaySize = wxGetDisplaySize();
102 if ((displaySize.y < 500) && (displaySize.x > displaySize.y))
105 wxBoxSizer* bSizer4 =
new wxBoxSizer(wxVERTICAL);
106 m_container->SetSizer(bSizer4);
107 m_container->SetVirtualSize(m_container->GetParent()->GetSize());
112 m_container->SetScrollRate(1, 1);
114 m_container->SetScrollRate(0, 0);
117 m_bSizerOuterContainer =
new wxBoxSizer(wxVERTICAL);
118 bSizer4->Add(m_bSizerOuterContainer, 1, wxEXPAND, 5);
120 wxStaticBoxSizer* sbSizerGeneral;
121 sbSizerGeneral =
new wxStaticBoxSizer(
122 new wxStaticBox(m_container, wxID_ANY, _(
"General")), wxVERTICAL);
123 m_bSizerOuterContainer->Add(sbSizerGeneral, 0, wxRIGHT | wxEXPAND, 5);
125 wxBoxSizer* bSizer151;
126 bSizer151 =
new wxBoxSizer(wxVERTICAL);
128 wxBoxSizer* bSizer161;
129 bSizer161 =
new wxBoxSizer(wxVERTICAL);
131 wxBoxSizer* bSizer171;
132 bSizer171 =
new wxBoxSizer(wxHORIZONTAL);
134 m_cbFilterSogCog =
new wxCheckBox(m_container, wxID_ANY,
135 _(
"Filter NMEA Course and Speed data"),
136 wxDefaultPosition, wxDefaultSize, 0);
137 m_cbFilterSogCog->SetValue(g_bfilter_cogsog);
138 bSizer171->Add(m_cbFilterSogCog, 0, wxALL, 5);
141 new wxStaticText(m_container, wxID_ANY, _(
"Filter period (sec)"),
142 wxDefaultPosition, wxDefaultSize, 0);
143 m_stFilterSec->Wrap(-1);
149 bSizer171->Add(m_stFilterSec, 0, wxALL, nspace);
151 m_tFilterSec =
new wxTextCtrl(m_container, wxID_ANY, wxEmptyString,
153 wxSize(50, 3 * m_container->GetCharWidth()), 0);
155 sfilt.Printf(
"%d", g_COGFilterSec);
156 m_tFilterSec->SetValue(sfilt);
157 bSizer171->Add(m_tFilterSec, 0, wxALL, 4);
158 bSizer161->Add(bSizer171, 0, wxEXPAND, 5);
164 wxFlexGridSizer *GenProps =
new wxFlexGridSizer(0, 2, 0, 0);
165 bSizer161->Add(GenProps, 0, wxALL, cb_space);
168 new wxCheckBox(m_container, wxID_ANY, _(
"Show NMEA Debug Window"),
169 wxDefaultPosition, wxDefaultSize, 0);
170 m_cbNMEADebug->SetValue(NMEALogWindow::GetInstance().Active());
171 GenProps->Add(m_cbNMEADebug, 0, wxALL, cb_space);
173 m_cbFurunoGP3X =
new wxCheckBox(m_container, wxID_ANY,
174 _(
"Format uploads for Furuno GP3X"),
175 wxDefaultPosition, wxDefaultSize, 0);
176 m_cbFurunoGP3X->SetValue(g_GPS_Ident ==
"FurunoGP3X");
177 GenProps->Add(m_cbFurunoGP3X, 0, wxALL, cb_space);
179 m_cbGarminUploadHost =
new wxCheckBox(
180 m_container, wxID_ANY, _(
"Use Garmin GRMN (Host) mode for uploads"),
181 wxDefaultPosition, wxDefaultSize, 0);
182 m_cbGarminUploadHost->SetValue(g_bGarminHostUpload);
183 GenProps->Add(m_cbGarminUploadHost, 0, wxALL, cb_space);
186 new wxCheckBox(m_container, wxID_ANY,
187 _(
"Use magnetic bearings in output sentence APB"),
188 wxDefaultPosition, wxDefaultSize, 0);
189 m_cbAPBMagnetic->SetValue(g_bMagneticAPB);
190 GenProps->Add(m_cbAPBMagnetic, 0, wxALL, cb_space);
192 wxSizer *talkerSizer =
new wxBoxSizer(wxHORIZONTAL);
193 bSizer161->Add(talkerSizer, 0, wxALL, 1);
195 m_ButtonPriorityDialog =
new wxButton(m_container, wxID_ANY,
196 _(
"Adjust communication priorities..."),
197 wxDefaultPosition, wxDefaultSize, 0);
198 talkerSizer->Add(m_ButtonPriorityDialog, 0, wxALL, cb_space);
200 talkerSizer->AddSpacer(12 * m_container->GetCharWidth());
202 m_stTalkerIdText =
new wxStaticText(
203 m_container, wxID_ANY,
204 wxString::Format(
"%s", _(
"NMEA0183 Talker ID")),
205 wxDefaultPosition, wxDefaultSize, 0);
206 m_stTalkerIdText->Wrap(-1);
207 talkerSizer->Add(m_stTalkerIdText, 0, wxALL, 2);
209 talkerSizer->AddSpacer(2 * m_container->GetCharWidth());
211 m_TalkerIdText =
new wxTextCtrl(m_container, -1,
"", wxDefaultPosition,
212 wxSize(50, 3 * m_container->GetCharWidth()), 0);
213 m_TalkerIdText->SetMaxLength(2);
214 m_TalkerIdText->SetValue(g_TalkerIdText.MakeUpper());
215 talkerSizer->Add(m_TalkerIdText, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
220 new wxCheckBox(m_container, wxID_ANY, _(
"Show NMEA Debug Window"),
221 wxDefaultPosition, wxDefaultSize, 0);
222 m_cbNMEADebug->SetValue(NMEALogWindow::GetInstance().Active());
223 bSizer161->Add(m_cbNMEADebug, 0, wxALL, cb_space);
225 m_cbFurunoGP3X =
new wxCheckBox(m_container, wxID_ANY,
226 _(
"Format uploads for Furuno GP3X"),
227 wxDefaultPosition, wxDefaultSize, 0);
228 m_cbFurunoGP3X->SetValue(g_GPS_Ident ==
"FurunoGP3X");
229 bSizer161->Add(m_cbFurunoGP3X, 0, wxALL, cb_space);
231 m_cbGarminUploadHost =
new wxCheckBox(
232 m_container, wxID_ANY, _(
"Use Garmin GRMN (Host) mode for uploads"),
233 wxDefaultPosition, wxDefaultSize, 0);
234 m_cbGarminUploadHost->SetValue(g_bGarminHostUpload);
235 bSizer161->Add(m_cbGarminUploadHost, 0, wxALL, cb_space);
238 new wxCheckBox(m_container, wxID_ANY,
239 _(
"Use magnetic bearings in output sentence APB"),
240 wxDefaultPosition, wxDefaultSize, 0);
241 m_cbAPBMagnetic->SetValue(g_bMagneticAPB);
242 bSizer161->Add(m_cbAPBMagnetic, 0, wxALL, cb_space);
244 wxSizer* talkerSizer =
new wxBoxSizer(wxHORIZONTAL);
245 bSizer161->Add(talkerSizer, 0, wxALL, 1);
247 talkerSizer->AddSpacer(3 * m_container->GetCharWidth());
249 m_stTalkerIdText =
new wxStaticText(
250 m_container, wxID_ANY, wxString::Format(
"%s", _(
"NMEA0183 Talker ID")),
251 wxDefaultPosition, wxDefaultSize, 0);
252 m_stTalkerIdText->Wrap(-1);
253 talkerSizer->Add(m_stTalkerIdText, 0, wxALL, 2);
255 talkerSizer->AddSpacer(2 * m_container->GetCharWidth());
258 new wxTextCtrl(m_container, -1,
"", wxDefaultPosition,
259 wxSize(50, 3 * m_container->GetCharWidth()), 0);
260 m_TalkerIdText->SetMaxLength(2);
261 m_TalkerIdText->SetValue(g_TalkerIdText.MakeUpper());
262 talkerSizer->Add(m_TalkerIdText, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
264 m_ButtonPriorityDialog =
new wxButton(
265 m_container, wxID_ANY, _(
"Adjust communication priorities..."),
266 wxDefaultPosition, wxDefaultSize, 0);
267 bSizer161->Add(m_ButtonPriorityDialog, 0, wxALL, cb_space);
270 bSizer151->Add(bSizer161, 0, wxEXPAND, 5);
271 sbSizerGeneral->Add(bSizer151, 0, wxEXPAND, 5);
274 m_sbSizerLB =
new wxStaticBoxSizer(
275 new wxStaticBox(m_container, wxID_ANY, _(
"Data Connections")),
277 m_bSizerOuterContainer->Add(m_sbSizerLB, 1, wxEXPAND | wxRIGHT, 5);
280 wxBoxSizer* bSizer18;
281 bSizer18 =
new wxBoxSizer(wxHORIZONTAL);
282 m_sbSizerLB->Add(bSizer18, 0, wxEXPAND, 5);
284 m_buttonAdd =
new wxButton(m_container, wxID_ANY, _(
"Add Connection..."),
285 wxDefaultPosition, wxDefaultSize, 0);
286 bSizer18->Add(m_buttonAdd, 0, wxALL, 5);
288 m_buttonEdit =
new wxButton(m_container, wxID_ANY, _(
"Edit Connection..."),
289 wxDefaultPosition, wxDefaultSize, 0);
290 m_buttonEdit->Enable(FALSE);
291 bSizer18->Add(m_buttonEdit, 0, wxALL, 5);
293 m_buttonRemove =
new wxButton(m_container, wxID_ANY, _(
"Remove Connection"),
294 wxDefaultPosition, wxDefaultSize, 0);
295 m_buttonRemove->Enable(FALSE);
296 bSizer18->Add(m_buttonRemove, 0, wxALL, 5);
298 wxStaticLine *staticline5 =
new wxStaticLine(m_container, wxID_ANY, wxDefaultPosition,
299 wxDefaultSize, wxLI_HORIZONTAL);
300 m_sbSizerLB->Add(staticline5, 0, wxEXPAND | wxALL, 5);
313 m_scrollWinConnections =
314 new wxPanel(m_container, wxID_ANY, wxDefaultPosition, wxDefaultSize,
315 wxBORDER_RAISED | wxBG_STYLE_ERASE);
317 m_scrollWinConnections =
new wxScrolledWindow(
318 m_container, wxID_ANY, wxDefaultPosition, wxDLG_UNIT(m_parent, wxSize(-1, -1)),
319 wxBORDER_RAISED | wxVSCROLL | wxBG_STYLE_ERASE);
324 m_scrollWinConnections->SetScrollRate(0, 0);
326 m_scrollWinConnections->SetScrollRate(5, 5);
330 m_sbSizerLB->Add(m_scrollWinConnections, 1, wxRIGHT | wxEXPAND, 5);
332 boxSizerConnections =
new wxBoxSizer(wxVERTICAL);
333 m_scrollWinConnections->SetSizer(boxSizerConnections);
336 m_buttonAdd->Connect(
337 wxEVT_COMMAND_BUTTON_CLICKED,
338 wxCommandEventHandler(ConnectionsDialog::OnAddDatasourceClick), NULL,
340 m_buttonEdit->Connect(
341 wxEVT_COMMAND_BUTTON_CLICKED,
342 wxCommandEventHandler(ConnectionsDialog::OnEditDatasourceClick), NULL,
344 m_buttonRemove->Connect(
345 wxEVT_COMMAND_BUTTON_CLICKED,
346 wxCommandEventHandler(ConnectionsDialog::OnRemoveDatasourceClick), NULL,
349 m_cbNMEADebug->Connect(
350 wxEVT_COMMAND_CHECKBOX_CLICKED,
351 wxCommandEventHandler(ConnectionsDialog::OnShowGpsWindowCheckboxClick),
363 m_ButtonPriorityDialog->Connect(
364 wxEVT_COMMAND_BUTTON_CLICKED,
365 wxCommandEventHandler(ConnectionsDialog::OnPriorityDialog), NULL,
this);
368 m_container->Connect(wxEVT_SIZE, wxSizeEventHandler(ConnectionsDialog::OnSize), NULL,
this);
372 void ConnectionsDialog::SetSelectedConnectionPanel(
377 if (mSelectedConnection && mSelectedConnection->m_optionsPanel)
378 mSelectedConnection->m_optionsPanel->SetSelected(
false);
381 mSelectedConnection = panel->m_pConnectionParams;
382 panel->SetSelected(
true);
383 m_buttonRemove->Enable();
384 m_buttonRemove->Show();
385 m_buttonEdit->Enable();
386 m_buttonEdit->Show();
387 m_buttonAdd->Disable();
390 mSelectedConnection = NULL;
391 m_buttonRemove->Disable();
392 m_buttonAdd->Enable();
394 m_buttonEdit->Disable();
397 m_container->FitInside();
400 wxPoint buttonPosition = m_buttonAdd->GetPosition();
401 m_container->Scroll(-1, buttonPosition.y / m_parent->GetScrollRate());
404 void ConnectionsDialog::EnableConnection(
ConnectionParams* conn,
bool value) {
406 conn->bEnabled = value;
408 conn->b_IsSetup = FALSE;
412 bool ConnectionsDialog::SortSourceList(
void) {
413 if (TheConnectionParams()->Count() < 2)
return false;
415 std::vector<int> ivec;
416 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) ivec.push_back(i);
418 bool did_sort =
false;
419 bool did_swap =
true;
422 for (
size_t j = 1; j < ivec.size(); j++) {
426 if (c1->Priority < c2->Priority) {
428 ivec[j - 1] = ivec[j];
438 boxSizerConnections =
new wxBoxSizer(wxVERTICAL);
439 m_scrollWinConnections->SetSizer(boxSizerConnections);
441 for (
size_t i = 0; i < ivec.size(); i++) {
443 TheConnectionParams()->Item(ivec[i])->m_optionsPanel;
444 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxRIGHT, 10);
451 void ConnectionsDialog::FillSourceList(
void) {
452 m_buttonRemove->Enable(FALSE);
455 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
457 if (!cp->m_optionsPanel) {
459 m_scrollWinConnections, wxID_ANY, wxDefaultPosition, wxDefaultSize,
461 pPanel->SetSelected(
false);
462 boxSizerConnections->Add(pPanel, 0, wxEXPAND | wxRIGHT, 10);
463 cp->m_optionsPanel = pPanel;
465 cp->m_optionsPanel->Update(cp);
470 mSelectedConnection = NULL;
471 mSelectedConnection = NULL;
472 m_buttonAdd->Enable(
true);
476 void ConnectionsDialog::UpdateSourceList(
bool bResort) {
477 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
480 if (panel) panel->Update(TheConnectionParams()->Item(i));
487 m_scrollWinConnections->Layout();
490 void ConnectionsDialog::OnAddDatasourceClick(wxCommandEvent& event) {
492 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++)
493 TheConnectionParams()->Item(i)->m_optionsPanel->SetSelected(
false);
496 dialog.SetSize(wxSize(m_parent->GetSize().x, m_parent->GetSize().y * 8/10));
497 dialog.SetPropsLabel(_(
"Configure new connection"));
498 dialog.SetDefaultConnectionParams();
500 auto rv = dialog.ShowModal();
504 cp->b_IsSetup =
false;
505 TheConnectionParams()->Add(cp);
509 m_sbSizerLB->Layout();
513 void ConnectionsDialog::OnRemoveDatasourceClick(wxCommandEvent& event) {
514 if (mSelectedConnection) {
518 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
519 cp = TheConnectionParams()->Item(i);
520 if (mSelectedConnection == cp) {
526 if ((index >= 0) && (cp)) {
527 delete TheConnectionParams()->Item(index)->m_optionsPanel;
528 TheConnectionParams()->RemoveAt(index);
529 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
530 mSelectedConnection = NULL;
534 m_buttonEdit->Disable();
535 m_buttonRemove->Disable();
537 m_sbSizerLB->Layout();
541 void ConnectionsDialog::OnEditDatasourceClick(wxCommandEvent& event) {
542 if (mSelectedConnection) {
546 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
547 cp = TheConnectionParams()->Item(i);
548 if (mSelectedConnection == cp) {
554 if ((index >= 0) && (cp)) {
556 dialog.SetSize(wxSize(m_parent->GetSize().x, m_parent->GetSize().y * 8/10));
557 dialog.SetPropsLabel(_(
"Edit Selected Connection"));
559 dialog.PreloadControls(cp);
561 auto rv = dialog.ShowModal();
564 delete cp->m_optionsPanel;
565 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
567 TheConnectionParams()->Item(index) = cp_edited;
568 cp_edited->b_IsSetup =
false;
571 m_sbSizerLB->Layout();
579 void ConnectionsDialog::OnShowGpsWindowCheckboxClick(wxCommandEvent& event) {
580 if (!m_cbNMEADebug->GetValue()) {
581 NMEALogWindow::GetInstance().DestroyWindow();
583 NMEALogWindow::GetInstance().Create((wxWindow*)(m_parent->pParent), 35);
586 wxRect logRect(NMEALogWindow::GetInstance().GetPosX(),
587 NMEALogWindow::GetInstance().GetPosY(),
588 NMEALogWindow::GetInstance().GetSizeW(),
589 NMEALogWindow::GetInstance().GetSizeH());
591 if (m_container->GetRect().Contains(logRect)) {
592 NMEALogWindow::GetInstance().SetPos(
593 m_container->GetRect().x / 2,
594 (m_container->GetRect().y +
595 (m_container->GetRect().height - logRect.height) / 2));
596 NMEALogWindow::GetInstance().Move();
603 void ConnectionsDialog::ApplySettings() {
604 g_bfilter_cogsog = m_cbFilterSogCog->GetValue();
607 m_tFilterSec->GetValue().ToLong(&filter_val);
609 wxMin(
static_cast<int>(filter_val),
611 g_COGFilterSec = wxMax(g_COGFilterSec, 1);
612 g_SOGFilterSec = g_COGFilterSec;
614 g_bMagneticAPB = m_cbAPBMagnetic->GetValue();
615 g_TalkerIdText = m_TalkerIdText->GetValue();
617 g_bGarminHostUpload = m_cbGarminUploadHost->GetValue();
618 g_GPS_Ident = m_cbFurunoGP3X->GetValue() ?
"FurunoGP3X" :
"Generic";
623 void ConnectionsDialog::UpdateDatastreams() {
625 std::vector<std::string>enabled_conns;
627 for (
size_t i = 0; i < TheConnectionParams()->Count(); i++) {
633 enabled_conns.push_back(cp->GetStrippedDSPort());
644 if ( std::find(enabled_conns.begin(), enabled_conns.end(),
645 cp->GetStrippedDSPort()) != enabled_conns.end()) {
650 StopAndRemoveCommDriver(cp->GetStrippedDSPort(), cp->GetCommProtocol());
653 StopAndRemoveCommDriver(cp->GetLastDSPort(), cp->GetLastCommProtocol());
657 if (cp->Type == INTERNAL_BT) wxSleep(1);
660 if (!cp->bEnabled)
continue;
664 cp->b_IsSetup = TRUE;
665 enabled_conns.push_back(cp->GetStrippedDSPort());
669 void ConnectionsDialog::OnPriorityDialog(wxCommandEvent& event) {