1 /* interface_toolbar.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <ws_diag_control.h>
16 #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
17 DIAG_OFF(stringop
-overflow
)
18 #if WS_IS_AT_LEAST_GNUC_VERSION(13,0)
22 #include "interface_toolbar.h"
23 #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
24 DIAG_ON(stringop
-overflow
)
25 #if WS_IS_AT_LEAST_GNUC_VERSION(13,0)
29 #include <ui/qt/widgets/interface_toolbar_lineedit.h>
30 #include "simple_dialog.h"
31 #include "main_application.h"
32 #include <ui_interface_toolbar.h>
34 #include "capture_opts.h"
35 #include "ui/capture_globals.h"
36 #include "sync_pipe.h"
37 #include "wsutil/file_util.h"
40 #include <wsutil/win32-utils.h>
45 #include <QDesktopServices>
47 #include <QPushButton>
51 static const char *interface_type_property
= "control_type";
52 static const char *interface_role_property
= "control_role";
54 // From interface control protocol.
55 enum InterfaceControlCommand
{
56 commandControlInitialized
= 0,
57 commandControlSet
= 1,
58 commandControlAdd
= 2,
59 commandControlRemove
= 3,
60 commandControlEnable
= 4,
61 commandControlDisable
= 5,
62 commandStatusMessage
= 6,
63 commandInformationMessage
= 7,
64 commandWarningMessage
= 8,
65 commandErrorMessage
= 9
69 // - Move control pipe handling to extcap
71 InterfaceToolbar::InterfaceToolbar(QWidget
*parent
, const iface_toolbar
*toolbar
) :
73 ui(new Ui::InterfaceToolbar
),
74 help_link_(toolbar
->help
),
79 // Fill inn interfaces list and initialize default interface values
80 for (GList
*walker
= toolbar
->ifnames
; walker
; walker
= walker
->next
)
82 QString
ifname((char *)walker
->data
);
83 interface_
[ifname
].reader_thread
= NULL
;
84 interface_
[ifname
].out_fd
= -1;
87 initializeControls(toolbar
);
90 foreach (QWidget
*w
, findChildren
<QWidget
*>())
92 w
->setAttribute(Qt::WA_MacSmallSize
, true);
98 ui
->horizontalSpacer
->changeSize(0,0, QSizePolicy::Fixed
, QSizePolicy::Fixed
);
104 InterfaceToolbar::~InterfaceToolbar()
106 foreach (QString ifname
, interface_
.keys())
108 foreach (int num
, control_widget_
.keys())
110 if (interface_
[ifname
].log_dialog
.contains(num
))
112 interface_
[ifname
].log_dialog
[num
]->close();
120 void InterfaceToolbar::initializeControls(const iface_toolbar
*toolbar
)
122 for (GList
*walker
= toolbar
->controls
; walker
; walker
= walker
->next
)
124 iface_toolbar_control
*control
= (iface_toolbar_control
*)walker
->data
;
126 if (control_widget_
.contains(control
->num
))
128 // Already have a widget with this number
132 QWidget
*widget
= NULL
;
133 switch (control
->ctrl_type
)
135 case INTERFACE_TYPE_BOOLEAN
:
136 widget
= createCheckbox(control
);
139 case INTERFACE_TYPE_BUTTON
:
140 widget
= createButton(control
);
143 case INTERFACE_TYPE_SELECTOR
:
144 widget
= createSelector(control
);
147 case INTERFACE_TYPE_STRING
:
148 widget
= createString(control
);
158 widget
->setProperty(interface_type_property
, control
->ctrl_type
);
159 widget
->setProperty(interface_role_property
, control
->ctrl_role
);
160 control_widget_
[control
->num
] = widget
;
165 void InterfaceToolbar::setDefaultValue(int num
, const QByteArray
&value
)
167 foreach (QString ifname
, interface_
.keys())
169 // Adding default value to all interfaces
170 interface_
[ifname
].value
[num
] = value
;
172 default_value_
[num
] = value
;
175 QWidget
*InterfaceToolbar::createCheckbox(iface_toolbar_control
*control
)
177 QCheckBox
*checkbox
= new QCheckBox(QString().fromUtf8(control
->display
));
178 checkbox
->setToolTip(QString().fromUtf8(control
->tooltip
));
180 if (control
->default_value
.boolean
)
182 checkbox
->setCheckState(Qt::Checked
);
183 QByteArray
default_value(1, 1);
184 setDefaultValue(control
->num
, default_value
);
187 connect(checkbox
, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxChanged(int)));
189 ui
->leftLayout
->addWidget(checkbox
);
194 QWidget
*InterfaceToolbar::createButton(iface_toolbar_control
*control
)
196 QPushButton
*button
= new QPushButton(QString().fromUtf8((char *)control
->display
));
197 button
->setMaximumHeight(27);
198 button
->setToolTip(QString().fromUtf8(control
->tooltip
));
200 switch (control
->ctrl_role
)
202 case INTERFACE_ROLE_CONTROL
:
203 setDefaultValue(control
->num
, (char *)control
->display
);
204 connect(button
, SIGNAL(clicked()), this, SLOT(onControlButtonClicked()));
207 case INTERFACE_ROLE_HELP
:
208 connect(button
, SIGNAL(clicked()), this, SLOT(onHelpButtonClicked()));
209 if (help_link_
.isEmpty())
211 // No help URL provided
216 case INTERFACE_ROLE_LOGGER
:
217 connect(button
, SIGNAL(clicked()), this, SLOT(onLogButtonClicked()));
220 case INTERFACE_ROLE_RESTORE
:
221 connect(button
, SIGNAL(clicked()), this, SLOT(onRestoreButtonClicked()));
229 ui
->rightLayout
->addWidget(button
);
234 QWidget
*InterfaceToolbar::createSelector(iface_toolbar_control
*control
)
236 QLabel
*label
= new QLabel(QString().fromUtf8(control
->display
));
237 label
->setToolTip(QString().fromUtf8(control
->tooltip
));
238 QComboBox
*combobox
= new QComboBox();
239 combobox
->setToolTip(QString().fromUtf8(control
->tooltip
));
240 combobox
->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
242 for (GList
*walker
= control
->values
; walker
; walker
= walker
->next
)
244 iface_toolbar_value
*val
= (iface_toolbar_value
*)walker
->data
;
245 QString value
= QString().fromUtf8((char *)val
->value
);
251 QString display
= QString().fromUtf8((char *)val
->display
);
252 QByteArray interface_value
;
254 interface_value
.append(value
.toUtf8());
255 if (display
.isEmpty())
261 interface_value
.append(QString('\0' + display
).toUtf8());
263 combobox
->addItem(display
, value
);
266 combobox
->setCurrentText(display
);
267 setDefaultValue(control
->num
, value
.toUtf8());
269 foreach (QString ifname
, interface_
.keys())
271 // Adding values to all interfaces
272 interface_
[ifname
].list
[control
->num
].append(interface_value
);
274 default_list_
[control
->num
].append(interface_value
);
277 connect(combobox
, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxChanged(int)));
279 ui
->leftLayout
->addWidget(label
);
280 ui
->leftLayout
->addWidget(combobox
);
281 label_widget_
[control
->num
] = label
;
286 QWidget
*InterfaceToolbar::createString(iface_toolbar_control
*control
)
288 QLabel
*label
= new QLabel(QString().fromUtf8(control
->display
));
289 label
->setToolTip(QString().fromUtf8(control
->tooltip
));
290 InterfaceToolbarLineEdit
*lineedit
= new InterfaceToolbarLineEdit(NULL
, control
->validation
, control
->is_required
);
291 lineedit
->setToolTip(QString().fromUtf8(control
->tooltip
));
292 lineedit
->setPlaceholderText(QString().fromUtf8(control
->placeholder
));
294 if (control
->default_value
.string
)
296 lineedit
->setText(QString().fromUtf8(control
->default_value
.string
));
297 setDefaultValue(control
->num
, control
->default_value
.string
);
300 connect(lineedit
, SIGNAL(editedTextApplied()), this, SLOT(onLineEditChanged()));
302 ui
->leftLayout
->addWidget(label
);
303 ui
->leftLayout
->addWidget(lineedit
);
304 label_widget_
[control
->num
] = label
;
310 void InterfaceToolbar::setWidgetValue(QWidget
*widget
, int command
, QByteArray payload
)
312 if (QComboBox
*combobox
= qobject_cast
<QComboBox
*>(widget
))
314 combobox
->blockSignals(true);
317 case commandControlSet
:
319 int idx
= combobox
->findData(payload
);
322 combobox
->setCurrentIndex(idx
);
327 case commandControlAdd
:
331 if (payload
.contains('\0'))
333 // The payload contains "value\0display"
334 QList
<QByteArray
> values
= payload
.split('\0');
340 value
= display
= payload
;
343 int idx
= combobox
->findData(value
);
346 // The value already exists, update item text
347 combobox
->setItemText(idx
, display
);
351 combobox
->addItem(display
, value
);
356 case commandControlRemove
:
358 if (payload
.size() == 0)
364 int idx
= combobox
->findData(payload
);
367 combobox
->removeItem(idx
);
376 combobox
->blockSignals(false);
378 else if (InterfaceToolbarLineEdit
*lineedit
= qobject_cast
<InterfaceToolbarLineEdit
*>(widget
))
380 // We don't block signals here because changes are applied with enter or apply button,
381 // and we want InterfaceToolbarLineEdit to always syntax check the text.
384 case commandControlSet
:
385 lineedit
->setText(payload
);
386 lineedit
->disableApplyButton();
393 else if (QCheckBox
*checkbox
= qobject_cast
<QCheckBox
*>(widget
))
395 checkbox
->blockSignals(true);
398 case commandControlSet
:
400 Qt::CheckState state
= Qt::Unchecked
;
401 if (payload
.size() > 0 && payload
.at(0) != 0)
405 checkbox
->setCheckState(state
);
412 checkbox
->blockSignals(false);
414 else if (QPushButton
*button
= qobject_cast
<QPushButton
*>(widget
))
416 if ((command
== commandControlSet
) &&
417 widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
)
419 button
->setText(payload
);
424 void InterfaceToolbar::setInterfaceValue(QString ifname
, QWidget
*widget
, int num
, int command
, QByteArray payload
)
430 if (qobject_cast
<QComboBox
*>(widget
))
434 case commandControlSet
:
435 if (interface_
[ifname
].value
[num
] != payload
)
437 interface_
[ifname
].value_changed
[num
] = false;
439 foreach (QByteArray entry
, interface_
[ifname
].list
[num
])
441 if (entry
== payload
|| entry
.startsWith(payload
+ '\0'))
443 interface_
[ifname
].value
[num
] = payload
;
448 case commandControlAdd
:
449 interface_
[ifname
].list
[num
].append(payload
);
452 case commandControlRemove
:
453 if (payload
.size() == 0)
455 interface_
[ifname
].value
[num
].clear();
456 interface_
[ifname
].list
[num
].clear();
460 foreach (QByteArray entry
, interface_
[ifname
].list
[num
])
462 if (entry
== payload
|| entry
.startsWith(payload
+ '\0'))
464 interface_
[ifname
].list
[num
].removeAll(entry
);
474 else if (qobject_cast
<InterfaceToolbarLineEdit
*>(widget
))
478 case commandControlSet
:
479 if (interface_
[ifname
].value
[num
] != payload
)
481 interface_
[ifname
].value_changed
[num
] = false;
483 interface_
[ifname
].value
[num
] = payload
;
490 else if ((widget
->property(interface_type_property
).toInt() == INTERFACE_TYPE_BUTTON
) &&
491 (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_LOGGER
))
493 if (command
== commandControlSet
)
495 if (interface_
[ifname
].log_dialog
.contains(num
))
497 interface_
[ifname
].log_dialog
[num
]->clearText();
499 interface_
[ifname
].log_text
.clear();
501 if (command
== commandControlSet
|| command
== commandControlAdd
)
503 if (interface_
[ifname
].log_dialog
.contains(num
))
505 interface_
[ifname
].log_dialog
[num
]->appendText(payload
);
507 interface_
[ifname
].log_text
[num
].append(payload
);
510 else if (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
)
512 // QCheckBox or QPushButton
515 case commandControlSet
:
516 if (interface_
[ifname
].value
[num
] != payload
)
518 interface_
[ifname
].value_changed
[num
] = false;
520 interface_
[ifname
].value
[num
] = payload
;
529 void InterfaceToolbar::controlReceived(QString ifname
, int num
, int command
, QByteArray payload
)
533 case commandControlSet
:
534 case commandControlAdd
:
535 case commandControlRemove
:
536 if (control_widget_
.contains(num
))
538 QWidget
*widget
= control_widget_
[num
];
539 setInterfaceValue(ifname
, widget
, num
, command
, payload
);
541 if (ifname
.compare(ui
->interfacesComboBox
->currentText()) == 0)
543 setWidgetValue(widget
, command
, payload
);
548 case commandControlEnable
:
549 case commandControlDisable
:
550 if (control_widget_
.contains(num
))
552 QWidget
*widget
= control_widget_
[num
];
553 if (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
)
555 bool enable
= (command
== commandControlEnable
? true : false);
556 interface_
[ifname
].widget_disabled
[num
] = !enable
;
558 if (ifname
.compare(ui
->interfacesComboBox
->currentText()) == 0)
560 widget
->setEnabled(enable
);
561 if (label_widget_
.contains(num
))
563 label_widget_
[num
]->setEnabled(enable
);
570 case commandStatusMessage
:
571 mainApp
->pushStatus(MainApplication::TemporaryStatus
, payload
);
574 case commandInformationMessage
:
575 simple_dialog_async(ESD_TYPE_INFO
, ESD_BTN_OK
, "%s", payload
.data());
578 case commandWarningMessage
:
579 simple_dialog_async(ESD_TYPE_WARN
, ESD_BTN_OK
, "%s", payload
.data());
582 case commandErrorMessage
:
583 simple_dialog_async(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", payload
.data());
587 // Unknown commands are silently ignored
592 void InterfaceToolbar::controlSend(QString ifname
, int num
, int command
, const QByteArray
&payload
= QByteArray())
594 if (payload
.length() > 65535)
600 if (ifname
.isEmpty() || interface_
[ifname
].out_fd
== -1)
602 // Does not have a control out channel
606 ssize_t payload_length
= payload
.length() + 2;
607 unsigned char high_nibble
= (payload_length
>> 16) & 0xFF;
608 unsigned char mid_nibble
= (payload_length
>> 8) & 0xFF;
609 unsigned char low_nibble
= (payload_length
>> 0) & 0xFF;
613 ba
.append(SP_TOOLBAR_CTRL
);
614 ba
.append(high_nibble
);
615 ba
.append(mid_nibble
);
616 ba
.append(low_nibble
);
621 if (ws_write(interface_
[ifname
].out_fd
, ba
.data(), ba
.length()) != ba
.length())
623 simple_dialog_async(ESD_TYPE_ERROR
, ESD_BTN_OK
,
624 "Unable to send control message:\n%s.",
629 void InterfaceToolbar::onControlButtonClicked()
631 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
632 QPushButton
*button
= static_cast<QPushButton
*>(sender());
633 int num
= control_widget_
.key(button
);
635 controlSend(ifname
, num
, commandControlSet
);
638 void InterfaceToolbar::onCheckBoxChanged(int state
)
640 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
641 QCheckBox
*checkbox
= static_cast<QCheckBox
*>(sender());
642 int num
= control_widget_
.key(checkbox
);
644 QByteArray
payload(1, state
== Qt::Unchecked
? 0 : 1);
645 controlSend(ifname
, num
, commandControlSet
, payload
);
646 interface_
[ifname
].value
[num
] = payload
;
647 interface_
[ifname
].value_changed
[num
] = true;
650 void InterfaceToolbar::onComboBoxChanged(int idx
)
652 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
653 QComboBox
*combobox
= static_cast<QComboBox
*>(sender());
654 int num
= control_widget_
.key(combobox
);
655 QString value
= combobox
->itemData(idx
).toString();
657 QByteArray
payload(value
.toUtf8());
658 controlSend(ifname
, num
, commandControlSet
, payload
);
659 interface_
[ifname
].value
[num
] = payload
;
660 interface_
[ifname
].value_changed
[num
] = true;
663 void InterfaceToolbar::onLineEditChanged()
665 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
666 InterfaceToolbarLineEdit
*lineedit
= static_cast<InterfaceToolbarLineEdit
*>(sender());
667 int num
= control_widget_
.key(lineedit
);
669 QByteArray
payload(lineedit
->text().toUtf8());
670 controlSend(ifname
, num
, commandControlSet
, payload
);
671 interface_
[ifname
].value
[num
] = payload
;
672 interface_
[ifname
].value_changed
[num
] = true;
675 void InterfaceToolbar::onLogButtonClicked()
677 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
678 QPushButton
*button
= static_cast<QPushButton
*>(sender());
679 int num
= control_widget_
.key(button
);
681 if (!interface_
[ifname
].log_dialog
.contains(num
))
683 interface_
[ifname
].log_dialog
[num
] = new FunnelTextDialog(window(), ifname
+ " " + button
->text());
684 connect(interface_
[ifname
].log_dialog
[num
], SIGNAL(accepted()), this, SLOT(closeLog()));
685 connect(interface_
[ifname
].log_dialog
[num
], SIGNAL(rejected()), this, SLOT(closeLog()));
687 interface_
[ifname
].log_dialog
[num
]->setText(interface_
[ifname
].log_text
[num
]);
690 interface_
[ifname
].log_dialog
[num
]->show();
691 interface_
[ifname
].log_dialog
[num
]->raise();
692 interface_
[ifname
].log_dialog
[num
]->activateWindow();
695 void InterfaceToolbar::onHelpButtonClicked()
697 QUrl
help_url(help_link_
);
699 if (help_url
.scheme().compare("file") != 0)
701 QDesktopServices::openUrl(help_url
);
705 void InterfaceToolbar::closeLog()
707 FunnelTextDialog
*log_dialog
= static_cast<FunnelTextDialog
*>(sender());
709 foreach (QString ifname
, interface_
.keys())
711 foreach (int num
, control_widget_
.keys())
713 if (interface_
[ifname
].log_dialog
.value(num
) == log_dialog
)
715 interface_
[ifname
].log_dialog
.remove(num
);
722 void InterfaceToolbar::startReaderThread(QString ifname
, void *control_in
)
724 QThread
*thread
= new QThread
;
725 InterfaceToolbarReader
*reader
= new InterfaceToolbarReader(ifname
, control_in
);
726 reader
->moveToThread(thread
);
728 connect(thread
, SIGNAL(started()), reader
, SLOT(loop()));
729 connect(reader
, SIGNAL(finished()), thread
, SLOT(quit()));
730 connect(reader
, SIGNAL(finished()), reader
, SLOT(deleteLater()));
731 connect(thread
, SIGNAL(finished()), reader
, SLOT(deleteLater()));
732 connect(reader
, SIGNAL(received(QString
, int, int, QByteArray
)),
733 this, SLOT(controlReceived(QString
, int, int, QByteArray
)));
735 interface_
[ifname
].reader_thread
= thread
;
740 void InterfaceToolbar::startCapture(GArray
*ifaces
)
742 if (!ifaces
|| ifaces
->len
== 0)
745 const QString
&selected_ifname
= ui
->interfacesComboBox
->currentText();
746 QString first_capturing_ifname
;
747 bool selected_found
= false;
749 for (unsigned i
= 0; i
< ifaces
->len
; i
++)
751 interface_options
*interface_opts
= &g_array_index(ifaces
, interface_options
, i
);
752 QString
ifname(interface_opts
->name
);
754 if (!interface_
.contains(ifname
))
755 // This interface is not for us
758 if (first_capturing_ifname
.isEmpty())
759 first_capturing_ifname
= ifname
;
761 if (ifname
.compare(selected_ifname
) == 0)
762 selected_found
= true;
764 if (interface_
[ifname
].out_fd
!= -1)
765 // Already have control channels for this interface
768 // Open control out channel
770 startReaderThread(ifname
, interface_opts
->extcap_control_in_h
);
771 // Duplicate control out handle and pass the duplicate handle to _open_osfhandle().
772 // This allows the C run-time file descriptor (out_fd) and the extcap_control_out_h to be closed independently.
773 // The duplicated handle will get closed at the same time the file descriptor is closed.
774 // The control out pipe will close when both out_fd and extcap_control_out_h are closed.
775 HANDLE duplicate_out_handle
= INVALID_HANDLE_VALUE
;
776 if (!DuplicateHandle(GetCurrentProcess(), interface_opts
->extcap_control_out_h
,
777 GetCurrentProcess(), &duplicate_out_handle
, 0, true, DUPLICATE_SAME_ACCESS
))
779 simple_dialog_async(ESD_TYPE_ERROR
, ESD_BTN_OK
,
780 "Failed to duplicate extcap control out handle: %s\n.",
781 win32strerror(GetLastError()));
785 interface_
[ifname
].out_fd
= _open_osfhandle((intptr_t)duplicate_out_handle
, O_APPEND
| O_BINARY
);
788 startReaderThread(ifname
, interface_opts
->extcap_control_in
);
789 interface_
[ifname
].out_fd
= ws_open(interface_opts
->extcap_control_out
, O_WRONLY
| O_BINARY
, 0);
791 sendChangedValues(ifname
);
792 controlSend(ifname
, 0, commandControlInitialized
);
795 if (!selected_found
&& !first_capturing_ifname
.isEmpty())
797 ui
->interfacesComboBox
->setCurrentText(first_capturing_ifname
);
805 void InterfaceToolbar::stopCapture()
807 foreach (QString ifname
, interface_
.keys())
809 if (interface_
[ifname
].reader_thread
)
811 if (!interface_
[ifname
].reader_thread
->isFinished())
813 interface_
[ifname
].reader_thread
->requestInterruption();
815 interface_
[ifname
].reader_thread
= NULL
;
818 if (interface_
[ifname
].out_fd
!= -1)
820 ws_close_if_possible (interface_
[ifname
].out_fd
);
822 interface_
[ifname
].out_fd
= -1;
825 foreach (int num
, control_widget_
.keys())
827 // Reset disabled property for all widgets
828 interface_
[ifname
].widget_disabled
[num
] = false;
830 QWidget
*widget
= control_widget_
[num
];
831 if ((widget
->property(interface_type_property
).toInt() == INTERFACE_TYPE_BUTTON
) &&
832 (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
))
834 // Reset default value for control buttons
835 interface_
[ifname
].value
[num
] = default_value_
[num
];
837 if (ifname
.compare(ui
->interfacesComboBox
->currentText()) == 0)
839 setWidgetValue(widget
, commandControlSet
, default_value_
[num
]);
848 void InterfaceToolbar::sendChangedValues(QString ifname
)
850 // Send all values which has changed
851 foreach (int num
, control_widget_
.keys())
853 QWidget
*widget
= control_widget_
[num
];
854 if ((interface_
[ifname
].value_changed
[num
]) &&
855 (widget
->property(interface_type_property
).toInt() != INTERFACE_TYPE_BUTTON
) &&
856 (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
))
858 controlSend(ifname
, num
, commandControlSet
, interface_
[ifname
].value
[num
]);
863 void InterfaceToolbar::onRestoreButtonClicked()
865 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
867 // Set default values to all widgets and interfaces
868 foreach (int num
, control_widget_
.keys())
870 QWidget
*widget
= control_widget_
[num
];
871 if (default_list_
[num
].size() > 0)
873 // This is a QComboBox. Clear list and add new entries.
874 setWidgetValue(widget
, commandControlRemove
, QByteArray());
875 interface_
[ifname
].list
[num
].clear();
877 foreach (QByteArray value
, default_list_
[num
])
879 setWidgetValue(widget
, commandControlAdd
, value
);
880 interface_
[ifname
].list
[num
].append(value
);
884 switch (widget
->property(interface_role_property
).toInt())
886 case INTERFACE_ROLE_CONTROL
:
887 setWidgetValue(widget
, commandControlSet
, default_value_
[num
]);
888 interface_
[ifname
].value
[num
] = default_value_
[num
];
889 interface_
[ifname
].value_changed
[num
] = false;
892 case INTERFACE_ROLE_LOGGER
:
893 if (interface_
[ifname
].log_dialog
.contains(num
))
895 interface_
[ifname
].log_dialog
[num
]->clearText();
897 interface_
[ifname
].log_text
[num
].clear();
906 bool InterfaceToolbar::hasInterface(QString ifname
)
908 return interface_
.contains(ifname
);
911 void InterfaceToolbar::updateWidgets()
913 const QString
&ifname
= ui
->interfacesComboBox
->currentText();
914 bool is_capturing
= (interface_
[ifname
].out_fd
== -1 ? false : true);
916 foreach (int num
, control_widget_
.keys())
918 QWidget
*widget
= control_widget_
[num
];
919 bool widget_enabled
= true;
921 if (ifname
.isEmpty() &&
922 (widget
->property(interface_role_property
).toInt() != INTERFACE_ROLE_HELP
))
924 // No interface selected, disable all but Help button
925 widget_enabled
= false;
927 else if (!is_capturing
&&
928 (widget
->property(interface_type_property
).toInt() == INTERFACE_TYPE_BUTTON
) &&
929 (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
))
931 widget_enabled
= false;
933 else if (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
)
935 widget_enabled
= !interface_
[ifname
].widget_disabled
[num
];
938 widget
->setEnabled(widget_enabled
);
939 if (label_widget_
.contains(num
))
941 label_widget_
[num
]->setEnabled(widget_enabled
);
945 foreach (int num
, control_widget_
.keys())
947 QWidget
*widget
= control_widget_
[num
];
948 if ((widget
->property(interface_type_property
).toInt() == INTERFACE_TYPE_BUTTON
) &&
949 (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_RESTORE
))
951 widget
->setEnabled(!is_capturing
);
956 void InterfaceToolbar::interfaceListChanged()
959 const QString
&selected_ifname
= ui
->interfacesComboBox
->currentText();
960 bool keep_selected
= false;
962 ui
->interfacesComboBox
->blockSignals(true);
963 ui
->interfacesComboBox
->clear();
965 for (unsigned i
= 0; i
< global_capture_opts
.all_ifaces
->len
; i
++)
967 interface_t
*device
= &g_array_index(global_capture_opts
.all_ifaces
, interface_t
, i
);
971 if (interface_
.keys().contains(device
->name
))
973 ui
->interfacesComboBox
->addItem(device
->name
);
974 if (selected_ifname
.compare(device
->name
) == 0)
976 // Keep selected interface
977 ui
->interfacesComboBox
->setCurrentText(device
->name
);
978 keep_selected
= true;
983 ui
->interfacesComboBox
->blockSignals(false);
987 // Select the first interface
988 on_interfacesComboBox_currentTextChanged(ui
->interfacesComboBox
->currentText());
995 void InterfaceToolbar::on_interfacesComboBox_currentTextChanged(const QString
&ifname
)
997 foreach (int num
, control_widget_
.keys())
999 QWidget
*widget
= control_widget_
[num
];
1000 if (interface_
[ifname
].list
[num
].size() > 0)
1002 // This is a QComboBox. Clear list and add new entries.
1003 setWidgetValue(widget
, commandControlRemove
, QByteArray());
1005 foreach (QByteArray value
, interface_
[ifname
].list
[num
])
1007 setWidgetValue(widget
, commandControlAdd
, value
);
1011 if (widget
->property(interface_role_property
).toInt() == INTERFACE_ROLE_CONTROL
)
1013 setWidgetValue(widget
, commandControlSet
, interface_
[ifname
].value
[num
]);