1 /* manage_interfaces_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "manage_interfaces_dialog.h"
24 #include <ui_manage_interfaces_dialog.h>
25 #include "epan/prefs.h"
26 #include "epan/to_str.h"
27 #include "ui/last_open_dir.h"
28 #include "capture_opts.h"
29 #include "ui/capture_globals.h"
30 #include "ui/qt/capture_interfaces_dialog.h"
31 #ifdef HAVE_PCAP_REMOTE
32 #include "ui/qt/remote_capture_dialog.h"
33 #include "ui/qt/remote_settings_dialog.h"
35 #include "ui/iface_lists.h"
36 #include "ui/preference_utils.h"
37 #include "ui/ui_util.h"
38 #include <wsutil/utf8_entities.h>
40 #include "qt_ui_utils.h"
42 #include "wireshark_application.h"
48 #include <QFileDialog>
49 #include <QHBoxLayout>
51 #include <QStandardItemModel>
52 #include <QTreeWidgetItemIterator>
55 // - Check the validity of pipes and remote interfaces and provide feedback
57 // - We might want to move PathChooserDelegate to its own module and use it in
58 // other parts of the application such as the general preferences and UATs.
59 // Qt Creator has a much more elaborate version from which we might want
60 // to draw inspiration.
86 ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
88 ui(new Ui::ManageInterfacesDialog)
93 ui->addPipe->setAttribute(Qt::WA_MacSmallSize, true);
94 ui->addPipe->setAttribute(Qt::WA_MacSmallSize, true);
95 ui->addRemote->setAttribute(Qt::WA_MacSmallSize, true);
96 ui->delRemote->setAttribute(Qt::WA_MacSmallSize, true);
99 int one_em = fontMetrics().height();
101 ui->localList->setColumnWidth(col_l_show_, one_em * 3);
103 ui->localList->setColumnHidden(col_l_friendly_name_, true);
106 ui->pipeList->setItemDelegateForColumn(col_p_pipe_, &new_pipe_item_delegate_);
107 new_pipe_item_delegate_.setTree(ui->pipeList);
110 showLocalInterfaces();
112 #if defined(HAVE_PCAP_REMOTE)
113 // The default indentation (20) means our checkboxes are shifted too far on Windows.
114 // Assume that our disclosure and checkbox controls are square, or at least fit within an em.
115 ui->remoteList->setIndentation(one_em);
116 ui->remoteList->setColumnWidth(col_r_show_, one_em * 4);
117 ui->remoteSettings->setEnabled(false);
118 showRemoteInterfaces();
120 ui->remoteTab->setEnabled(false);
123 connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateWidgets()));
124 connect(this, SIGNAL(ifsChanged()), parent, SIGNAL(ifsChanged()));
126 #ifdef HAVE_PCAP_REMOTE
127 connect(this, SIGNAL(remoteAdded(GList*, remote_options*)), this, SLOT(addRemoteInterfaces(GList*, remote_options*)));
128 connect(this, SIGNAL(remoteSettingsChanged(interface_t *)), this, SLOT(setRemoteSettings(interface_t *)));
129 connect(ui->remoteList, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(remoteSelectionChanged(QTreeWidgetItem*, int)));
132 ui->tabWidget->setCurrentIndex(tab_local_);
136 ManageInterfacesDialog::~ManageInterfacesDialog()
141 void ManageInterfacesDialog::updateWidgets()
145 if (ui->pipeList->selectedItems().length() > 0) {
146 ui->delPipe->setEnabled(true);
148 ui->delPipe->setEnabled(false);
151 #ifdef HAVE_PCAP_REMOTE
152 bool enable_del_remote = false;
153 bool enable_remote_settings = false;
154 QTreeWidgetItem *item = ui->remoteList->currentItem();
157 if (item->childCount() < 1) { // Leaf
158 enable_remote_settings = true;
160 enable_del_remote = true;
163 ui->delRemote->setEnabled(enable_del_remote);
164 ui->remoteSettings->setEnabled(enable_remote_settings);
167 switch (ui->tabWidget->currentIndex()) {
169 hint = tr("This version of Wireshark does not save pipe settings.");
172 #ifdef HAVE_PCAP_REMOTE
173 hint = tr("This version of Wireshark does not save remote settings.");
175 hint = tr("This version of Wireshark does not support remote interfaces.");
182 hint.prepend("<small><i>");
183 hint.append("</i></small>");
184 ui->hintLabel->setText(hint);
187 void ManageInterfacesDialog::showPipes()
189 ui->pipeList->clear();
191 if (global_capture_opts.all_ifaces->len > 0) {
194 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
195 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
197 /* Continue if capture device is hidden */
198 if (device.hidden || device.type != IF_PIPE) {
201 QTreeWidgetItem *item = new QTreeWidgetItem(ui->pipeList);
202 item->setFlags(item->flags() | Qt::ItemIsEditable);
203 item->setText(col_p_pipe_, device.display_name);
208 void ManageInterfacesDialog::on_buttonBox_accepted()
212 #ifdef HAVE_PCAP_REMOTE
219 const QString new_pipe_default_ = QObject::tr("New Pipe");
220 void ManageInterfacesDialog::on_addPipe_clicked()
222 QTreeWidgetItem *item = new QTreeWidgetItem(ui->pipeList);
223 item->setText(col_p_pipe_, new_pipe_default_);
224 item->setFlags(item->flags() | Qt::ItemIsEditable);
225 ui->pipeList->setCurrentItem(item);
226 ui->pipeList->editItem(item, col_p_pipe_);
229 void ManageInterfacesDialog::pipeAccepted()
233 // First clear the current pipes
234 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
235 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
236 /* Continue if capture device is hidden or not a pipe */
237 if (device.hidden || device.type != IF_PIPE) {
240 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
243 // Next rebuild a fresh list
244 QTreeWidgetItemIterator it(ui->pipeList);
246 QString pipe_name = (*it)->text(col_p_pipe_);
247 if (pipe_name.isEmpty() || pipe_name == new_pipe_default_) {
252 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
253 // Instead of just deleting the device we might want to add a hint label
254 // and let the user know what's going to happen.
255 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
256 if (pipe_name.compare(device.name) == 0) { // Duplicate
262 device.name = qstring_strdup(pipe_name);
263 device.display_name = g_strdup(device.name);
264 device.hidden = FALSE;
265 device.selected = TRUE;
266 device.type = IF_PIPE;
267 device.pmode = global_capture_opts.default_options.promisc_mode;
268 device.has_snaplen = global_capture_opts.default_options.has_snaplen;
269 device.snaplen = global_capture_opts.default_options.snaplen;
270 device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
271 device.addresses = NULL;
272 device.no_addresses = 0;
273 device.last_packets = 0;
275 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
276 device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
278 device.active_dlt = -1;
279 device.locked = FALSE;
280 device.if_info.name = g_strdup(device.name);
281 device.if_info.friendly_name = NULL;
282 device.if_info.vendor_description = NULL;
283 device.if_info.addrs = NULL;
284 device.if_info.loopback = FALSE;
285 device.if_info.type = IF_PIPE;
287 device.if_info.extcap = NULL;
288 device.external_cap_args_settings = NULL;
290 #if defined(HAVE_PCAP_CREATE)
291 device.monitor_mode_enabled = FALSE;
292 device.monitor_mode_supported = FALSE;
294 global_capture_opts.num_selected++;
295 g_array_append_val(global_capture_opts.all_ifaces, device);
300 void ManageInterfacesDialog::on_delPipe_clicked()
302 // We're just managing a list of strings at this point.
303 delete ui->pipeList->currentItem();
306 void ManageInterfacesDialog::on_pipeList_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
311 void ManageInterfacesDialog::showLocalInterfaces()
315 gchar *pr_descr = g_strdup("");
316 char *comment = NULL;
318 ui->localList->clear();
319 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
320 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
321 if (device.local && device.type != IF_PIPE && device.type != IF_STDIN) {
322 QTreeWidgetItem *item = new QTreeWidgetItem(ui->localList);
323 item->setFlags(item->flags() | Qt::ItemIsEditable);
324 if (prefs.capture_device && strstr(prefs.capture_device, device.name)) {
325 // Force the default device to be checked.
326 item->setFlags(item->flags() ^ Qt::ItemIsUserCheckable);
327 item->setCheckState(col_l_show_, Qt::Checked);
329 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
330 item->setCheckState(col_l_show_, device.hidden ? Qt::Unchecked : Qt::Checked);
333 item->setText(col_l_friendly_name_, device.friendly_name);
335 item->setText(col_l_local_name_, device.name);
337 comment = capture_dev_user_descr_find(device.name);
339 item->setText(col_l_comment_, comment);
349 void ManageInterfacesDialog::saveLocalHideChanges(QTreeWidgetItem *item)
358 QString name = item->text(col_l_local_name_);
359 /* See if this is the currently selected capturing device */
361 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
362 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
363 if (name.compare(device.name)) {
366 device.hidden = (item->checkState(col_l_show_) == Qt::Checked ? false : true);
367 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
368 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
372 void ManageInterfacesDialog::saveLocalCommentChanges(QTreeWidgetItem* item)
381 QString name = item->text(col_l_local_name_);
382 QString comment = item->text(col_l_comment_);
383 /* See if this is the currently selected capturing device */
385 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
386 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
387 if (name.compare(device.name)) {
391 g_free(device.display_name);
392 // XXX The GTK+ UI uses the raw device name instead of the friendly name.
393 // This seems to make more sense.
394 gchar *if_string = device.friendly_name ? device.friendly_name : device.name;
395 if (comment.isEmpty()) {
396 device.display_name = g_strdup(if_string);
398 device.display_name = qstring_strdup(QString("%1: %2").arg(comment).arg(if_string));
400 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
401 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
406 void ManageInterfacesDialog::checkBoxChanged(QTreeWidgetItem* item)
415 QString name = item->text(col_l_local_name_);
416 /* See if this is the currently selected capturing device */
418 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
419 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
420 if (name.compare(device.name)) {
423 if (prefs.capture_device && strstr(prefs.capture_device, device.name) && item->checkState() == Qt::Checked) {
424 /* Don't allow current interface to be hidden */
425 QMessageBox::warning(this, tr("Error"),
426 tr("Default interface cannot be hidden."));
427 item->setCheckState(Qt::Unchecked);
432 #endif // checkBoxChanged not needed?
434 void ManageInterfacesDialog::localAccepted()
437 if (global_capture_opts.all_ifaces->len > 0) {
438 QStringList hide_list;
439 QStringList comment_list;
440 QTreeWidgetItemIterator it(ui->localList);
442 if ((*it)->checkState(col_l_show_) != Qt::Checked) {
443 hide_list << (*it)->text(col_l_local_name_);
446 if (!(*it)->text(col_l_local_name_).isEmpty()) {
447 comment_list << QString("%1(%2)").arg((*it)->text(col_l_local_name_)).arg((*it)->text(col_l_comment_));
450 saveLocalHideChanges(*it);
451 saveLocalCommentChanges(*it);
454 /* write new "hidden" string to preferences */
455 g_free(prefs.capture_devices_hide);
456 gchar *new_hide = qstring_strdup(hide_list.join(","));
457 prefs.capture_devices_hide = new_hide;
458 hide_interface(g_strdup(new_hide));
460 /* write new description string to preferences */
461 if (prefs.capture_devices_descr)
462 g_free(prefs.capture_devices_descr);
463 prefs.capture_devices_descr = qstring_strdup(comment_list.join(","));;
467 void ManageInterfacesDialog::on_buttonBox_helpRequested()
469 wsApp->helpTopicAction(HELP_CAPTURE_MANAGE_INTERFACES_DIALOG);
472 #ifdef HAVE_PCAP_REMOTE
473 void ManageInterfacesDialog::remoteSelectionChanged(QTreeWidgetItem*, int)
478 void ManageInterfacesDialog::addRemoteInterfaces(GList* rlist, remote_options *roptions)
480 GList *if_entry, *lt_entry;
482 char *if_string = NULL;
483 gchar *descr, *str = NULL, *link_type_name = NULL, *auth_str;
484 if_capabilities_t *caps;
486 bool monitor_mode, found = false;
491 data_link_info_t *data_link_info;
493 link_row *linkr = NULL;
496 guint num_interfaces = global_capture_opts.all_ifaces->len;
497 for (if_entry = g_list_first(rlist); if_entry != NULL; if_entry = g_list_next(if_entry)) {
499 if_info = (if_info_t *)if_entry->data;
500 for (i = 0; i < num_interfaces; i++) {
501 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
504 if (strcmp(device.name, if_info->name) == 0) {
513 ip_str = g_string_new("");
516 device.name = g_strdup(if_info->name);
517 /* Is this interface hidden and, if so, should we include it
519 descr = capture_dev_user_descr_find(if_info->name);
521 /* Yes, we have a user-supplied description; use it. */
522 if_string = g_strdup_printf("%s: %s", descr, if_info->name);
525 /* No, we don't have a user-supplied description; did we get
526 one from the OS or libpcap? */
527 if (if_info->vendor_description != NULL) {
529 if_string = g_strdup_printf("%s: %s", if_info->vendor_description, if_info->name);
532 if_string = g_strdup(if_info->name);
534 } /* else descr != NULL */
535 if (if_info->loopback) {
536 device.display_name = g_strdup_printf("%s (loopback)", if_string);
538 device.display_name = g_strdup(if_string);
540 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
541 if ((device.buffer = capture_dev_user_buffersize_find(if_string)) == -1) {
542 device.buffer = global_capture_opts.default_options.buffer_size;
545 if (!capture_dev_user_pmode_find(if_string, &device.pmode)) {
546 device.pmode = global_capture_opts.default_options.promisc_mode;
548 if (!capture_dev_user_snaplen_find(if_string, &device.has_snaplen,
550 device.has_snaplen = global_capture_opts.default_options.has_snaplen;
551 device.snaplen = global_capture_opts.default_options.snaplen;
553 device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
554 monitor_mode = prefs_capture_device_monitor_mode(if_string);
555 #ifdef HAVE_PCAP_REMOTE
556 if (roptions->remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
557 auth_str = g_strdup_printf("%s:%s", roptions->remote_host_opts.auth_username,
558 roptions->remote_host_opts.auth_password);
561 caps = capture_get_if_capabilities(if_string, monitor_mode, auth_str, NULL, main_window_update);
563 for (; (curr_addr = g_slist_nth(if_info->addrs, ips)) != NULL; ips++) {
565 char* temp_addr_str = NULL;
567 g_string_append(ip_str, "\n");
569 addr = (if_addr_t *)curr_addr->data;
570 switch (addr->ifat_type) {
572 SET_ADDRESS(&addr_str, AT_IPv4, 4, &addr->addr.ip4_addr);
573 temp_addr_str = (char*)address_to_str(NULL, &addr_str);
574 g_string_append(ip_str, temp_addr_str);
577 SET_ADDRESS(&addr_str, AT_IPv6, 16, addr->addr.ip6_addr);
578 temp_addr_str = (char*)address_to_str(NULL, &addr_str);
579 g_string_append(ip_str, temp_addr_str);
582 /* In case we add non-IP addresses */
585 wmem_free(NULL, temp_addr_str);
586 } /* for curr_addr */
590 #ifdef HAVE_PCAP_CREATE
591 device.monitor_mode_enabled = monitor_mode;
592 device.monitor_mode_supported = caps->can_set_rfmon;
594 for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
595 data_link_info = (data_link_info_t *)lt_entry->data;
596 linkr = (link_row *)g_malloc(sizeof(link_row));
598 * For link-layer types libpcap/WinPcap doesn't know about, the
599 * name will be "DLT n", and the description will be null.
600 * We mark those as unsupported, and don't allow them to be
603 if (data_link_info->description != NULL) {
604 str = g_strdup_printf("%s", data_link_info->description);
605 linkr->dlt = data_link_info->dlt;
607 str = g_strdup_printf("%s (not supported)", data_link_info->name);
610 if (linktype_count == 0) {
611 link_type_name = g_strdup(str);
612 device.active_dlt = data_link_info->dlt;
614 linkr->name = g_strdup(str);
616 device.links = g_list_append(device.links, linkr);
618 } /* for link_types */
620 #if defined(HAVE_PCAP_CREATE)
621 device.monitor_mode_enabled = FALSE;
622 device.monitor_mode_supported = FALSE;
624 device.active_dlt = -1;
625 link_type_name = g_strdup("default");
627 device.addresses = g_strdup(ip_str->str);
628 device.no_addresses = ips;
629 device.remote_opts.src_type= roptions->src_type;
630 if (device.remote_opts.src_type == CAPTURE_IFREMOTE) {
631 device.local = FALSE;
633 device.remote_opts.remote_host_opts.remote_host = g_strdup(roptions->remote_host_opts.remote_host);
634 device.remote_opts.remote_host_opts.remote_port = g_strdup(roptions->remote_host_opts.remote_port);
635 device.remote_opts.remote_host_opts.auth_type = roptions->remote_host_opts.auth_type;
636 device.remote_opts.remote_host_opts.auth_username = g_strdup(roptions->remote_host_opts.auth_username);
637 device.remote_opts.remote_host_opts.auth_password = g_strdup(roptions->remote_host_opts.auth_password);
638 device.remote_opts.remote_host_opts.datatx_udp = roptions->remote_host_opts.datatx_udp;
639 device.remote_opts.remote_host_opts.nocap_rpcap = roptions->remote_host_opts.nocap_rpcap;
640 device.remote_opts.remote_host_opts.nocap_local = roptions->remote_host_opts.nocap_local;
641 #ifdef HAVE_PCAP_SETSAMPLING
642 device.remote_opts.sampling_method = roptions->sampling_method;
643 device.remote_opts.sampling_param = roptions->sampling_param;
645 device.selected = TRUE;
646 global_capture_opts.num_selected++;
647 g_array_append_val(global_capture_opts.all_ifaces, device);
648 g_string_free(ip_str, TRUE);
650 showRemoteInterfaces();
653 // We don't actually store these. When we do we should make sure they're stored
654 // securely using CryptProtectData, the OS X Keychain, GNOME Keyring, KWallet, etc.
655 void ManageInterfacesDialog::remoteAccepted()
657 QTreeWidgetItemIterator it(ui->remoteList);
660 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
661 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
662 if ((*it)->text(col_r_host_dev_).compare(device.name))
664 device.hidden = ((*it)->checkState(col_r_show_) == Qt::Checked ? false : true);
665 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
666 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
672 void ManageInterfacesDialog::on_remoteList_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
677 void ManageInterfacesDialog::on_remoteList_itemClicked(QTreeWidgetItem *item, int column)
679 if (!item || column != col_r_show_) {
683 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
684 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
686 if (item->text(col_r_host_dev_).compare(device.name))
688 device.hidden = (item->checkState(col_r_show_) == Qt::Checked ? false : true);
693 void ManageInterfacesDialog::on_delRemote_clicked()
695 QTreeWidgetItem* item = ui->remoteList->currentItem();
700 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
701 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
702 if (item->text(col_r_host_dev_).compare(device.remote_opts.remote_host_opts.remote_host))
704 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
707 fflush(stdout); // ???
710 void ManageInterfacesDialog::on_addRemote_clicked()
712 RemoteCaptureDialog *dlg = new RemoteCaptureDialog(this);
716 void ManageInterfacesDialog::showRemoteInterfaces()
720 QTreeWidgetItem *item = NULL;
722 // We assume that remote interfaces are grouped by host.
723 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
724 QTreeWidgetItem *child;
725 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
727 if (!item || item->text(col_r_host_dev_).compare(device.remote_opts.remote_host_opts.remote_host) != 0) {
728 item = new QTreeWidgetItem(ui->remoteList);
729 item->setText(col_r_host_dev_, device.remote_opts.remote_host_opts.remote_host);
730 item->setExpanded(true);
732 child = new QTreeWidgetItem(item);
733 child->setCheckState(col_r_show_, device.hidden ? Qt::Unchecked : Qt::Checked);
734 child->setText(col_r_host_dev_, QString(device.name));
739 void ManageInterfacesDialog::on_remoteSettings_clicked()
743 QTreeWidgetItem* item = ui->remoteList->currentItem();
748 for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
749 device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
751 if (item->text(col_r_host_dev_).compare(device.name)) {
754 RemoteSettingsDialog *dlg = new RemoteSettingsDialog(this, &device);
762 void ManageInterfacesDialog::setRemoteSettings(interface_t *iface)
764 for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
765 interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
767 if (strcmp(iface->name, device.name)) {
770 device.remote_opts.remote_host_opts.nocap_rpcap = iface->remote_opts.remote_host_opts.nocap_rpcap;
771 device.remote_opts.remote_host_opts.datatx_udp = iface->remote_opts.remote_host_opts.datatx_udp;
772 #ifdef HAVE_PCAP_SETSAMPLING
773 device.remote_opts.sampling_method = iface->remote_opts.sampling_method;
774 device.remote_opts.sampling_param = iface->remote_opts.sampling_param;
775 #endif //HAVE_PCAP_SETSAMPLING
776 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
777 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
781 #endif // HAVE_PCAP_REMOTE
783 PathChooserDelegate::PathChooserDelegate(QObject *parent)
784 : QStyledItemDelegate(parent)
788 PathChooserDelegate::~PathChooserDelegate()
792 QWidget* PathChooserDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &) const
794 QTreeWidgetItem *item = tree_->currentItem();
800 path_editor_ = new QWidget(parent);
801 QHBoxLayout *hbox = new QHBoxLayout(path_editor_);
802 path_editor_->setLayout(hbox);
803 path_le_ = new QLineEdit(path_editor_);
804 QPushButton *pb = new QPushButton(path_editor_);
806 path_le_->setText(item->text(col_p_pipe_));
807 pb->setText(QString(tr("Browse" UTF8_HORIZONTAL_ELLIPSIS)));
809 hbox->setContentsMargins(0, 0, 0, 0);
810 hbox->addWidget(path_le_);
812 hbox->setSizeConstraint(QLayout::SetMinimumSize);
814 // Grow the item to match the editor. According to the QAbstractItemDelegate
815 // documenation we're supposed to reimplement sizeHint but this seems to work.
816 QSize size = option.rect.size();
817 size.setHeight(qMax(option.rect.height(), hbox->sizeHint().height()));
818 item->setData(col_p_pipe_, Qt::SizeHintRole, size);
820 path_le_->selectAll();
821 path_editor_->setFocusProxy(path_le_);
822 path_editor_->setFocusPolicy(path_le_->focusPolicy());
824 connect(path_le_, SIGNAL(destroyed()), this, SLOT(stopEditor()));
825 connect(pb, SIGNAL(pressed()), this, SLOT(browse_button_clicked()));
829 void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
831 QRect rect = option.rect;
833 // Make sure the editor doesn't get squashed.
834 editor->adjustSize();
835 rect.setHeight(qMax(option.rect.height(), editor->height()));
836 editor->setGeometry(rect);
839 void PathChooserDelegate::stopEditor()
841 path_item_->setData(col_p_pipe_, Qt::SizeHintRole, QVariant());
842 path_item_->setText(col_p_pipe_, path_le_->text());
845 void PathChooserDelegate::browse_button_clicked()
847 char *open_dir = NULL;
849 switch (prefs.gui_fileopen_style) {
851 case FO_STYLE_LAST_OPENED:
852 open_dir = get_last_open_dir();
855 case FO_STYLE_SPECIFIED:
856 if (prefs.gui_fileopen_dir[0] != '\0')
857 open_dir = prefs.gui_fileopen_dir;
860 QString file_name = QFileDialog::getOpenFileName(tree_, tr("Open Pipe"), open_dir);
861 if (!file_name.isEmpty()) {
862 path_le_->setText(file_name);
866 #endif /* HAVE_LIBPCAP */
874 * indent-tabs-mode: nil
877 * ex: set shiftwidth=4 tabstop=8 expandtab:
878 * :indentSize=4:tabSize=8:noTabs=true: