257 const std::vector<ConnectionParams*>& connections,
261 : wxGrid(parent, wxID_ANY),
262 m_connections(connections),
263 m_header_column_widths({0, 0, 0, 0, 0, 0, 0}),
264 m_last_tooltip_cell(100),
265 m_cs(GLOBAL_COLOR_SCHEME_DAY),
266 m_on_conn_delete(on_conn_update),
267 m_on_edit_conn(on_edit_conn) {
268 ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
269 SetTable(
new wxGridStringTable(),
true);
270 GetTable()->AppendCols(8);
273 SetDefaultRowSize(wxWindow::GetCharHeight() * 2);
274 SetColLabelSize(wxWindow::GetCharHeight() * 2);
276 static const std::array<wxString, 7> headers = {
277 "", _(
"Protocol") +
" ", _(
"In/Out"), _(
"Data port"), _(
"Status"),
"",
280 for (
auto hdr = headers.begin(); hdr != headers.end(); hdr++, ic++) {
281 SetColLabelValue(
static_cast<int>(hdr - headers.begin()), *hdr);
282 unsigned col_width = hdr->Length() * wxWindow::GetCharWidth();
283 col_width = wxMax(col_width, 6 * wxWindow::GetCharWidth());
284 m_header_column_widths[ic] =
static_cast<int>(col_width);
285 SetColSize(ic,
static_cast<int>(col_width));
289 SetLabelBackgroundColour(GetGlobalColor(
"DILG1"));
290 SetLabelTextColour(GetGlobalColor(
"DILG3"));
293 SetColAttributes(parent);
297 DisableDragColSize();
298 DisableDragRowSize();
299 wxWindow::Show(GetNumberRows() > 0);
301 GetGridWindow()->Bind(wxEVT_MOTION, [&](wxMouseEvent& ev) {
305 GetGridWindow()->Bind(wxEVT_MOUSEWHEEL,
306 [&](
const wxMouseEvent& ev) {
OnWheel(ev); });
308 Bind(wxEVT_GRID_LABEL_LEFT_CLICK,
309 [&](wxGridEvent& ev) { HandleSort(ev.GetCol()); });
310 Bind(wxEVT_GRID_CELL_LEFT_CLICK,
311 [&](wxGridEvent& ev) { OnClickCell(ev.GetRow(), ev.GetCol()); });
312 Bind(wxEVT_PAINT, [&](wxPaintEvent& ev) {
313 SetColAttributes(
dynamic_cast<const wxWindow*
>(ev.GetEventObject()));
316 Bind(wxEVT_SYS_COLOUR_CHANGED,
317 [&](wxSysColourChangedEvent& ev) { OnColorChange(ev); });
318 conn_change_lstnr.Init(
320 [&](
ObservedEvt&) { OnConnectionChange(m_connections); });
323 void SetColorScheme(
const ColorScheme cs) {
328 void OnColorChange() {
329 auto foreground = wxSystemSettings::GetColour(wxSYS_COLOUR_MENUTEXT);
330 auto background = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
331 SetLabelBackgroundColour(background);
332 SetLabelTextColour(foreground);
333 for (
int row = 0; row <= GetNumberRows(); row++) {
334 for (
unsigned col = 0; col < 7; col++) {
335 SetCellBackgroundColour(row, col, background);
336 SetCellTextColour(row, col, foreground);
341 void OnColorChange(wxSysColourChangedEvent& ev) {
346 wxSize GetEstimatedSize()
const {
348 for (
auto s : m_header_column_widths) rs += s;
349 return {
static_cast<int>(rs), -1};
355 dynamic_cast<wxScrolledWindow*
>(FindWindowByName(TopScrollWindowName));
356 assert(w &&
"No TopScroll window found");
359 w->GetViewStart(&xpos, &ypos);
362 w->GetScrollPixelsPerUnit(&x, &y);
364 const int dir = ev.GetWheelRotation();
365 w->Scroll(-1, ypos - dir / y / 4);
369 void ReloadGrid(
const std::vector<ConnectionParams*>& connections) {
372 for (
auto it = connections.begin(); it != connections.end(); ++it) {
373 const auto row =
static_cast<int>(it - connections.begin());
375 SetCellValue(row, 0, (*it)->is_enabled ?
"1" :
"");
376 if ((*it)->is_enabled)
377 m_tooltips[row][0] = _(
"Enabled, click to disable");
379 m_tooltips[row][0] = _(
"Disabled, click to enable");
380 std::string protocol = NavAddr::BusToString((*it)->GetCommProtocol());
381 SetCellValue(row, 1, protocol);
382 SetCellValue(row, 2, (*it)->GetPortDirectionValueStr());
383 SetCellValue(row, 3, (*it)->GetStrippedDSPort());
384 m_tooltips[row][3] = (*it)->user_comment;
385 SetCellValue(row, 5, UtfGear());
386 m_tooltips[row][5] = _(
"Edit connection");
387 SetCellValue(row, 6, UtfWastebasket());
388 m_tooltips[row][6] = _(
"Delete connection");
389 SetCellValue(row, 7, (*it)->GetKey());
392 wxString sp(protocol);
393 unsigned size = sp.Length() * wxWindow::GetCharWidth();
394 m_header_column_widths[1] = std::max(m_header_column_widths[1], size);
395 size = (*it)->GetPortDirectionValueStr().Length() *
396 wxWindow::GetCharWidth();
397 m_header_column_widths[2] = std::max(m_header_column_widths[2], size);
398 sp = wxString((*it)->GetStrippedDSPort());
399 size = sp.Length() * wxWindow::GetCharWidth();
400 m_header_column_widths[3] = std::max(m_header_column_widths[3], size);
403 OnConnectionChange(m_connections);
408 for (
auto val : m_header_column_widths) {
409 SetColSize(ic,
static_cast<int>(val));
420 : m_conns(connections) {}
425 if (row1 == -1 && row2 == -1)
return false;
426 if (row1 == -1)
return false;
427 if (row2 == -1)
return true;
428 const int v1 = m_conns->GetCellValue(row1, 4)[0];
429 const int v2 = m_conns->GetCellValue(row2, 4)[0];
442 auto found = find_if(
443 m_connections.begin(), m_connections.end(),
445 if (found == m_connections.end())
return -1;
446 return static_cast<int>(found - m_connections.begin());
455 auto found = find_if(m_connections.begin(), m_connections.end(),
457 return GetCellValue(row, 7) == p->GetKey();
459 return found != m_connections.end() ? *found :
nullptr;
466 void EnsureRows(
size_t rows) {
467 for (
unsigned i = m_tooltips.size(); i <= rows; i++)
468 m_tooltips.emplace_back(std::vector<std::string>(7));
469 for (
unsigned i = GetNumberRows(); i <= rows; i++) AppendRows(1,
false);
473 void SetColAttributes(
const wxWindow* parent) {
476 SetDefaultCellBackgroundColour(GetGlobalColor(
"DILG1"));
478 auto enable_attr =
new wxGridCellAttr();
479 enable_attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
482 enable_attr->SetRenderer(
485 enable_attr->SetRenderer(
new wxGridCellBoolRenderer());
487 enable_attr->SetEditor(
new wxGridCellBoolEditor());
488 if (IsWindows()) enable_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
489 SetColAttr(0, enable_attr);
491 auto protocol_attr =
new wxGridCellAttr();
492 protocol_attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTRE);
493 protocol_attr->SetReadOnly(
true);
495 protocol_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
496 SetColAttr(1, protocol_attr);
498 auto in_out_attr =
new wxGridCellAttr();
499 in_out_attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
500 in_out_attr->SetReadOnly(
true);
501 if (IsWindows()) in_out_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
502 SetColAttr(2, in_out_attr);
504 auto port_attr =
new wxGridCellAttr();
505 port_attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTRE);
506 port_attr->SetReadOnly(
true);
507 if (IsWindows()) port_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
508 SetColAttr(3, port_attr);
510 auto status_attr =
new wxGridCellAttr();
511 status_attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
512 status_attr->SetReadOnly(
true);
513 status_attr->SetFont(parent->GetFont().Scale(1.3));
514 if (IsWindows()) status_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
515 SetColAttr(4, status_attr);
517 auto edit_attr =
new wxGridCellAttr();
518 edit_attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
519 edit_attr->SetFont(parent->GetFont().Scale(1.3));
520 edit_attr->SetReadOnly(
true);
521 if (IsWindows()) edit_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
522 SetColAttr(5, edit_attr);
524 auto delete_attr =
new wxGridCellAttr();
525 delete_attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTRE);
526 delete_attr->SetFont(parent->GetFont().Scale(1.3));
527 delete_attr->SetTextColour(*wxRED);
528 delete_attr->SetReadOnly(
true);
529 if (IsWindows()) delete_attr->SetBackgroundColour(GetGlobalColor(
"DILG1"));
530 SetColAttr(6, delete_attr);
534 void OnClickCell(
int row,
int col) {
539 }
else if (col == 6) {
545 void OnMouseMove(
const wxMouseEvent& ev) {
546 const wxPoint pt = ev.GetPosition();
547 int row = YToRow(pt.y);
548 int col = XToCol(pt.x);
549 if (col < 0 || col >= 7 || row < 0 || row >= GetNumberRows())
return;
550 if (row * 7 + col == m_last_tooltip_cell)
return;
551 m_last_tooltip_cell = row * 7 + col;
552 GetGridWindow()->SetToolTip(m_tooltips[row][col]);
556 void OnConnectionChange(
const std::vector<ConnectionParams*>& connections) {
557 bool refresh_needed =
false;
558 for (
auto it = connections.begin(); it != connections.end(); ++it) {
559 ConnState state = m_conn_states.GetDriverState(
560 (*it)->GetCommProtocol(), (*it)->GetStrippedDSPort());
561 if (!(*it)->is_enabled) state = ConnState::Disabled;
562 auto row =
static_cast<int>(it - connections.begin());
565 case ConnState::Disabled:
566 SetCellValue(row, 4, UtfFilledCircle());
567 m_tooltips[row][4] = _(
"Disabled");
568 refresh_needed =
true;
570 case ConnState::NoStats:
571 SetCellValue(row, 4, UtfOpenCircle());
572 m_tooltips[row][4] = _(
"No driver statistics available");
573 refresh_needed =
true;
575 case ConnState::NoData:
576 SetCellValue(row, 4,
"!");
577 m_tooltips[row][4] = _(
"No data flowing through connection");
578 refresh_needed =
true;
580 case ConnState::Unavailable:
581 SetCellValue(row, 4,
"X");
582 m_tooltips[row][4] = _(
"The device is unavailable");
583 refresh_needed =
true;
586 SetCellValue(row, 4, UtfCheckMark());
587 m_tooltips[row][4] = _(
"Data is flowing");
588 refresh_needed =
true;
592 if (refresh_needed) ForceRefresh();
596 void SetSortingColumn(
int col) {
597 if (GetSortingColumn() != wxNOT_FOUND) {
598 int old_col = GetSortingColumn();
599 auto label = GetColLabelValue(old_col);
600 if (label[0] == UtfArrowDown()[0])
601 SetColLabelValue(old_col, label.substr(2));
603 auto label = GetColLabelValue(col);
604 if (label[0] != UtfArrowDown()[0])
605 SetColLabelValue(col, UtfArrowDown() +
" " + label);
606 wxGrid::SetSortingColumn(col);
611 void HandleSort(
int col) {
615 std::sort(params.begin(), params.end(),
ConnCompare(col));
617 std::sort(params.begin(), params.end(), ConnStateCompare(
this));
619 SetSortingColumn(col);
623 void HandleEnable(
int row) {
626 cp->is_enabled = !cp->is_enabled;
627 cp->is_setup = FALSE;
628 SetCellValue(row, 0, cp->is_enabled ?
"1" :
"");
630 m_tooltips[row][0] = _(
"Enabled, click to disable");
632 m_tooltips[row][0] = _(
"Disabled, click to enable");
636 m_conn_states.HandleDriverStats(stats);
640 if (!cp->is_enabled) {
641 SetCellValue(row, 4, UtfFilledCircle());
648 void HandleEdit(
int row) {
650 Show(GetNumberRows() > 0);
651 m_on_edit_conn(cp,
true);
656 void HandleDelete(
int row) {
658 auto found = std::find(m_connections.begin(), m_connections.end(), cp);
659 if (found != m_connections.end()) {
660 std::stringstream ss;
661 ss << _(
"Ok to delete connection on ") << (*found)->GetStrippedDSPort();
662 int rcode = OCPNMessageBox(
this, ss.str(), _(
"Delete connection?"),
664 if (rcode != wxID_OK && rcode != wxID_YES)
return;
665 delete (*found)->options_panel;
666 StopAndRemoveCommDriver((*found)->GetStrippedDSPort(),
667 (*found)->GetCommProtocol());
669 if (GetNumberRows() >
static_cast<int>(m_connections.size()))
670 DeleteRows(GetNumberRows() - 1);
671 m_on_conn_delete.
Notify();
675 obs::Listener conn_change_lstnr;
676 std::vector<std::vector<std::string>> m_tooltips;
678 const std::vector<ConnectionParams*>& m_connections;
679 std::array<unsigned, 7> m_header_column_widths;
680 int m_last_tooltip_cell;
793 : wxPanel(parent, wxID_ANY) {
794 auto sizer =
new wxStaticBoxSizer(wxVERTICAL,
this,
"");
795 sizer->Add(
new BearingsCheckbox(
this), wxSizerFlags().Expand());
796 sizer->Add(
new ExtraRmbRmcLine(
this), wxSizerFlags().Expand());
797 sizer->Add(
new NmeaFilterRow(
this), wxSizerFlags().Expand());
798 sizer->Add(
new TalkerIdRow(
this), wxSizerFlags().Expand());
799 sizer->Add(
new NetmaskRow(
this), wxSizerFlags().Expand());
801 wxWindow::SetMaxSize(max_size);
806 class BearingsCheckbox :
public wxCheckBox,
public ApplyCancel {
808 explicit BearingsCheckbox(wxWindow* parent)
809 : wxCheckBox(parent, wxID_ANY,
810 _(
"Use magnetic bearing in output sentence APB")) {
811 wxCheckBox::SetValue(g_bMagneticAPB);
814 void Apply()
override { g_bMagneticAPB = GetValue(); }
815 void Cancel()
override { SetValue(g_bMagneticAPB); }
818 class ExtraRmbRmcLine :
public wxPanel {
819 class RmbRmcCheckbox :
public wxCheckBox,
public ApplyCancel {
821 explicit RmbRmcCheckbox(wxWindow* parent)
822 : wxCheckBox(parent, wxID_ANY,
823 _(
"Always send RMB and RMC NMEA0183 data")) {
832 explicit ExtraRmbRmcLine(wxWindow* parent) : wxPanel(parent, wxID_ANY) {
833 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
834 hbox->Add(
new RmbRmcCheckbox(
this), wxSizerFlags().Expand());
835 hbox->Add(1, 1, 1, wxEXPAND);
836 hbox->Add(
new InfoButton(
this, g_btouch, kInfoHeader, kInfo),
837 wxSizerFlags().Border());
843 class ExtraRmbRmcCheckbox final :
public wxCheckBox,
public ApplyCancel {
845 explicit ExtraRmbRmcCheckbox(wxWindow* parent)
846 : wxCheckBox(parent, wxID_ANY,
847 _(
"Always send RMB and RMC NMEA0183 data")) {
856 class NmeaFilterRow :
public wxPanel,
public ApplyCancel {
857 wxCheckBox* checkbox;
858 wxTextCtrl* filter_period;
861 explicit NmeaFilterRow(wxWindow* parent) : wxPanel(parent) {
862 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
863 checkbox =
new wxCheckBox(
865 _(
"Filter NMEA course and speed data. Filter period: "));
866 checkbox->SetValue(g_bfilter_cogsog);
867 hbox->Add(checkbox, wxSizerFlags().Align(wxALIGN_CENTRE));
869 new wxTextCtrl(
this, wxID_ANY,
"", wxDefaultPosition,
870 wxSize(50, 3 * wxWindow::GetCharWidth()), 0);
871 filter_period->SetValue(std::to_string(g_COGFilterSec));
872 hbox->Add(filter_period, wxSizerFlags().Border());
874 NmeaFilterRow::Cancel();
877 void Apply()
override {
878 std::stringstream ss;
879 ss << filter_period->GetValue();
880 ss >> g_COGFilterSec;
881 g_bfilter_cogsog = checkbox->GetValue();
884 void Cancel()
override {
885 std::stringstream ss;
886 ss << g_COGFilterSec;
887 filter_period->SetValue(ss.str());
888 checkbox->SetValue(g_bfilter_cogsog);
893 class TalkerIdRow :
public wxPanel,
public ApplyCancel {
894 wxTextCtrl* text_ctrl;
897 explicit TalkerIdRow(wxWindow* parent) : wxPanel(parent) {
898 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
899 hbox->Add(
new wxStaticText(
this, wxID_ANY, _(
"NMEA 0183 Talker Id: ")),
900 wxSizerFlags().Align(wxALIGN_CENTRE_VERTICAL).Border());
901 text_ctrl =
new wxTextCtrl(
902 this, wxID_ANY,
"", wxDefaultPosition,
903 wxSize(4 * wxWindow::GetCharWidth(), 3 * wxWindow::GetCharWidth()));
904 text_ctrl->SetToolTip(
905 _(
"Enter a two-letter talker ID to override the default ID in NMEA "
906 "sentences generated by OpenCPN (e.g., GP, HC, EC). This affects "
907 "only sentences created by OpenCPN, not those forwarded from other "
909 text_ctrl->SetValue(g_TalkerIdText);
910 hbox->Add(text_ctrl, wxSizerFlags().Border());
912 TalkerIdRow::Cancel();
915 void Apply()
override { g_TalkerIdText = text_ctrl->GetValue(); }
916 void Cancel()
override { text_ctrl->SetValue(g_TalkerIdText); }
920 class NetmaskRow :
public wxPanel,
public ApplyCancel {
922 explicit NetmaskRow(wxWindow* parent)
924 m_spin_ctrl(
new wxSpinCtrl(
this, wxID_ANY)),
925 m_text(
new wxStaticText(
this, wxID_ANY,
"")) {
926 m_spin_ctrl->SetRange(8, 32);
927 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
928 auto flags = wxSizerFlags().Align(wxALIGN_CENTRE_VERTICAL).Border();
929 hbox->Add(
new wxStaticText(
this, wxID_ANY, _(
"Netmask: ")), flags);
930 hbox->Add(m_text, flags);
931 hbox->Add(
new wxStaticText(
this, wxID_ANY, _(
"length (bits): ")), flags);
932 hbox->Add(m_spin_ctrl, flags);
934 NetmaskRow::Cancel();
936 Bind(wxEVT_SPINCTRL, [&](wxSpinEvent&) {
937 m_text->SetLabel(BitsToDottedMask(m_spin_ctrl->GetValue()));
942 void Apply()
override { g_netmask_bits = m_spin_ctrl->GetValue(); }
944 void Cancel()
override {
945 m_spin_ctrl->SetValue(g_netmask_bits);
946 m_text->SetLabel(BitsToDottedMask(m_spin_ctrl->GetValue()));
951 wxSpinCtrl* m_spin_ctrl;
952 wxStaticText* m_text;
959 TopPanel(wxWindow* parent,
const std::vector<ConnectionParams*>& connections,
963 : wxPanel(parent, wxID_ANY),
964 m_evt_add_connection(evt_add_connection),
965 m_connections(connections) {
966 auto vbox =
new wxBoxSizer(wxVERTICAL);
967 auto conn_grid =
new Connections(
this, m_connections, m_evt_add_connection,
969 wxSize panel_max_size(conn_grid->GetEstimatedSize());
970 vbox->AddSpacer(wxWindow::GetCharHeight());
971 auto conn_flags = wxSizerFlags().Border();
972 if (IsAndroid()) conn_flags = wxSizerFlags().Border().Expand();
973 vbox->Add(conn_grid, conn_flags);
975 wxSizerFlags().Border());
976 vbox->Add(0, wxWindow::GetCharHeight());
978 wxSizerFlags().Border(wxLEFT | wxDOWN | wxRIGHT).Expand();
979 m_general_panel =
new GeneralPanel(
this, panel_max_size);
980 vbox->Add(m_general_panel, panel_flags);
982 auto advanced_panel =
new AdvancedPanel(
this, panel_max_size);
983 m_advanced_panel = advanced_panel;
984 auto on_toggle = [&, advanced_panel, vbox](
bool show) {
986 advanced_panel->Show(show);
987 vbox->SetSizeHints(
this);
990 vbox->Add(
new ShowAdvanced(
this, on_toggle), panel_flags);
991 vbox->Add(advanced_panel, panel_flags.ReserveSpaceEvenIfHidden());
994 vbox->SetSizeHints(
this);
999 auto on_evt_update_connections = [&, conn_grid](
ObservedEvt&) {
1001 conn_grid->Show(conn_grid->GetNumberRows() > 0);
1004 m_add_connection_lstnr.Init(m_evt_add_connection,
1005 on_evt_update_connections);
1006 m_conn_grid = conn_grid;
1009 void SetColorScheme(
const ColorScheme cs)
const {
1010 m_conn_grid->SetColorScheme(cs);
1011 m_general_panel->SetColorScheme(cs);
1013 [[nodiscard]]
Connections* GetConnectionsGrid()
const {
return m_conn_grid; }
1018 const std::vector<ConnectionParams*>& m_connections;
1019 obs::Listener m_add_connection_lstnr;
1028 TopScroll(wxWindow* parent,
const std::vector<ConnectionParams*>& connections,
1030 : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
1031 wxVSCROLL | wxHSCROLL, TopScrollWindowName) {
1032 ShowScrollbars(wxSHOW_SB_NEVER, wxSHOW_SB_ALWAYS);
1033 auto vbox =
new wxBoxSizer(wxVERTICAL);
1044 new TopPanel(
this, connections, evt_add_connection, on_edit_connection);
1045 vbox->Add(top_panel, wxSizerFlags(1).Expand());
1049 HandleEditFinish(p, new_mode, ok_cancel);
1053 m_edit_panel->SetPropsLabel(_(
"Edit Selected Connection"));
1054 wxWindow*
options = FindWindowByName(
"Options");
1055 assert(
options &&
"Null Options window!");
1060 m_edit_panel->SetSize(
1061 wxSize(
options->GetSize().x,
options->GetSize().y * fraction / 10));
1062 vbox->Add(m_edit_panel, wxSizerFlags(0).Expand());
1063 m_edit_panel->Hide();
1065 SetScrollRate(0, 10);
1066 if (IsAndroid()) SetScrollRate(1, 1);
1068 SetScrollRate(0, 10);
1069 if (IsAndroid()) SetScrollRate(1, 1);
1072 void SetColorScheme(ColorScheme cs)
const {
1073 if (top_panel) top_panel->SetColorScheme(cs);
1077 m_edit_panel->SetPropsLabel(_(
"Edit Selected Connection"));
1078 m_edit_panel->SetNewMode(
false);
1079 m_edit_panel->PreloadControls(p);
1080 m_edit_panel->AddOKCancelButtons();
1085 m_edit_panel->SetPropsLabel(_(
"Configure new connection"));
1086 m_edit_panel->SetDefaultConnectionParams();
1087 m_edit_panel->SetNewMode(
true);
1088 m_edit_panel->AddOKCancelButtons();
1089 m_edit_panel->InitiateNewConnection();
1093 void SwitchToEditor() {
1096 DimeControl(m_edit_panel);
1097 m_edit_panel->Show();
1102 void SwitchToGrid() {
1104 m_edit_panel->Hide();
1120 delete cp_orig->options_panel;
1124 assert(index != -1 &&
"Cannot look up connection index");
1126 cp_edited->is_setup =
false;
1132 if (FindConnectionByIface(cp)) {
1133 wxMessageDialog dialog(
this, kInterfaceExistsMessage,
1134 _(
"Driver creation warning"),
1135 wxOK | wxCENTRE | wxICON_WARNING);
1140 cp->is_setup =
false;
1145 _(
"Unable to create a connection as configured. "
1146 "Connected port or address was missing.");
1147 auto& noteman = NotificationManager::GetInstance();
1148 noteman.AddNotification(NotificationSeverity::kWarning,
1149 msg.ToStdString(), 60);
1153 UpdateDatastreams();
1154 top_panel->m_evt_add_connection.
Notify();
1158 UpdateDatastreams();