Kerberos: add kerberos_inject_longterm_key() helper function
[wireshark-sm.git] / ui / qt / interface_toolbar.cpp
blobe4472d8c7eca71e8e3d5940caf55fd738b3b7515
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
8 */
10 #include "config.h"
12 #include <errno.h>
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)
19 DIAG_OFF(restrict)
20 #endif
21 #endif
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)
26 DIAG_ON(restrict)
27 #endif
28 #endif
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"
39 #ifdef _WIN32
40 #include <wsutil/win32-utils.h>
41 #endif
43 #include <QCheckBox>
44 #include <QComboBox>
45 #include <QDesktopServices>
46 #include <QLineEdit>
47 #include <QPushButton>
48 #include <QThread>
49 #include <QUrl>
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
68 // To do:
69 // - Move control pipe handling to extcap
71 InterfaceToolbar::InterfaceToolbar(QWidget *parent, const iface_toolbar *toolbar) :
72 QFrame(parent),
73 ui(new Ui::InterfaceToolbar),
74 help_link_(toolbar->help),
75 use_spacer_(true)
77 ui->setupUi(this);
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);
89 #ifdef Q_OS_MAC
90 foreach (QWidget *w, findChildren<QWidget *>())
92 w->setAttribute(Qt::WA_MacSmallSize, true);
94 #endif
96 if (!use_spacer_)
98 ui->horizontalSpacer->changeSize(0,0, QSizePolicy::Fixed, QSizePolicy::Fixed);
101 updateWidgets();
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();
117 delete ui;
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
129 continue;
132 QWidget *widget = NULL;
133 switch (control->ctrl_type)
135 case INTERFACE_TYPE_BOOLEAN:
136 widget = createCheckbox(control);
137 break;
139 case INTERFACE_TYPE_BUTTON:
140 widget = createButton(control);
141 break;
143 case INTERFACE_TYPE_SELECTOR:
144 widget = createSelector(control);
145 break;
147 case INTERFACE_TYPE_STRING:
148 widget = createString(control);
149 break;
151 default:
152 // Not supported
153 break;
156 if (widget)
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);
191 return 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()));
205 break;
207 case INTERFACE_ROLE_HELP:
208 connect(button, SIGNAL(clicked()), this, SLOT(onHelpButtonClicked()));
209 if (help_link_.isEmpty())
211 // No help URL provided
212 button->hide();
214 break;
216 case INTERFACE_ROLE_LOGGER:
217 connect(button, SIGNAL(clicked()), this, SLOT(onLogButtonClicked()));
218 break;
220 case INTERFACE_ROLE_RESTORE:
221 connect(button, SIGNAL(clicked()), this, SLOT(onRestoreButtonClicked()));
222 break;
224 default:
225 // Not supported
226 break;
229 ui->rightLayout->addWidget(button);
231 return 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);
246 if (value.isEmpty())
248 // Invalid value
249 continue;
251 QString display = QString().fromUtf8((char *)val->display);
252 QByteArray interface_value;
254 interface_value.append(value.toUtf8());
255 if (display.isEmpty())
257 display = value;
259 else
261 interface_value.append(QString('\0' + display).toUtf8());
263 combobox->addItem(display, value);
264 if (val->is_default)
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;
283 return combobox;
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;
305 use_spacer_ = false;
307 return lineedit;
310 void InterfaceToolbar::setWidgetValue(QWidget *widget, int command, QByteArray payload)
312 if (QComboBox *combobox = qobject_cast<QComboBox *>(widget))
314 combobox->blockSignals(true);
315 switch (command)
317 case commandControlSet:
319 int idx = combobox->findData(payload);
320 if (idx != -1)
322 combobox->setCurrentIndex(idx);
324 break;
327 case commandControlAdd:
329 QString value;
330 QString display;
331 if (payload.contains('\0'))
333 // The payload contains "value\0display"
334 QList<QByteArray> values = payload.split('\0');
335 value = values[0];
336 display = values[1];
338 else
340 value = display = payload;
343 int idx = combobox->findData(value);
344 if (idx != -1)
346 // The value already exists, update item text
347 combobox->setItemText(idx, display);
349 else
351 combobox->addItem(display, value);
353 break;
356 case commandControlRemove:
358 if (payload.size() == 0)
360 combobox->clear();
362 else
364 int idx = combobox->findData(payload);
365 if (idx != -1)
367 combobox->removeItem(idx);
370 break;
373 default:
374 break;
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.
382 switch (command)
384 case commandControlSet:
385 lineedit->setText(payload);
386 lineedit->disableApplyButton();
387 break;
389 default:
390 break;
393 else if (QCheckBox *checkbox = qobject_cast<QCheckBox *>(widget))
395 checkbox->blockSignals(true);
396 switch (command)
398 case commandControlSet:
400 Qt::CheckState state = Qt::Unchecked;
401 if (payload.size() > 0 && payload.at(0) != 0)
403 state = Qt::Checked;
405 checkbox->setCheckState(state);
406 break;
409 default:
410 break;
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)
426 if (!widget) {
427 return;
430 if (qobject_cast<QComboBox *>(widget))
432 switch (command)
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;
446 break;
448 case commandControlAdd:
449 interface_[ifname].list[num].append(payload);
450 break;
452 case commandControlRemove:
453 if (payload.size() == 0)
455 interface_[ifname].value[num].clear();
456 interface_[ifname].list[num].clear();
458 else
460 foreach (QByteArray entry, interface_[ifname].list[num])
462 if (entry == payload || entry.startsWith(payload + '\0'))
464 interface_[ifname].list[num].removeAll(entry);
468 break;
470 default:
471 break;
474 else if (qobject_cast<InterfaceToolbarLineEdit *>(widget))
476 switch (command)
478 case commandControlSet:
479 if (interface_[ifname].value[num] != payload)
481 interface_[ifname].value_changed[num] = false;
483 interface_[ifname].value[num] = payload;
484 break;
486 default:
487 break;
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
513 switch (command)
515 case commandControlSet:
516 if (interface_[ifname].value[num] != payload)
518 interface_[ifname].value_changed[num] = false;
520 interface_[ifname].value[num] = payload;
521 break;
523 default:
524 break;
529 void InterfaceToolbar::controlReceived(QString ifname, int num, int command, QByteArray payload)
531 switch (command)
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);
546 break;
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);
568 break;
570 case commandStatusMessage:
571 mainApp->pushStatus(MainApplication::TemporaryStatus, payload);
572 break;
574 case commandInformationMessage:
575 simple_dialog_async(ESD_TYPE_INFO, ESD_BTN_OK, "%s", payload.data());
576 break;
578 case commandWarningMessage:
579 simple_dialog_async(ESD_TYPE_WARN, ESD_BTN_OK, "%s", payload.data());
580 break;
582 case commandErrorMessage:
583 simple_dialog_async(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", payload.data());
584 break;
586 default:
587 // Unknown commands are silently ignored
588 break;
592 void InterfaceToolbar::controlSend(QString ifname, int num, int command, const QByteArray &payload = QByteArray())
594 if (payload.length() > 65535)
596 // Not supported
597 return;
600 if (ifname.isEmpty() || interface_[ifname].out_fd == -1)
602 // Does not have a control out channel
603 return;
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;
611 QByteArray ba;
613 ba.append(SP_TOOLBAR_CTRL);
614 ba.append(high_nibble);
615 ba.append(mid_nibble);
616 ba.append(low_nibble);
617 ba.append(num);
618 ba.append(command);
619 ba.append(payload);
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.",
625 g_strerror(errno));
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;
737 thread->start();
740 void InterfaceToolbar::startCapture(GArray *ifaces)
742 if (!ifaces || ifaces->len == 0)
743 return;
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
756 continue;
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
766 continue;
768 // Open control out channel
769 #ifdef _WIN32
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()));
783 else
785 interface_[ifname].out_fd = _open_osfhandle((intptr_t)duplicate_out_handle, O_APPEND | O_BINARY);
787 #else
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);
790 #endif
791 sendChangedValues(ifname);
792 controlSend(ifname, 0, commandControlInitialized);
795 if (!selected_found && !first_capturing_ifname.isEmpty())
797 ui->interfacesComboBox->setCurrentText(first_capturing_ifname);
799 else
801 updateWidgets();
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]);
845 updateWidgets();
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;
890 break;
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();
898 break;
900 default:
901 break;
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()
958 #ifdef HAVE_LIBPCAP
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);
968 if (device->hidden)
969 continue;
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);
985 if (!keep_selected)
987 // Select the first interface
988 on_interfacesComboBox_currentTextChanged(ui->interfacesComboBox->currentText());
991 updateWidgets();
992 #endif
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]);
1017 updateWidgets();