summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extcap.c26
-rw-r--r--extcap.h11
-rw-r--r--extcap_parser.c4
-rw-r--r--extcap_parser.h21
-rw-r--r--ui/gtk/extcap_gtk.c4
-rw-r--r--ui/help_url.c3
-rw-r--r--ui/help_url.h3
-rw-r--r--ui/qt/CMakeLists.txt25
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common8
-rw-r--r--ui/qt/Wireshark.pro7
-rw-r--r--ui/qt/extcap_argument.cpp657
-rw-r--r--ui/qt/extcap_argument.h117
-rw-r--r--ui/qt/extcap_argument_file.cpp111
-rw-r--r--ui/qt/extcap_argument_file.h65
-rw-r--r--ui/qt/extcap_options_dialog.cpp243
-rw-r--r--ui/qt/extcap_options_dialog.h91
-rw-r--r--ui/qt/extcap_options_dialog.ui34
-rw-r--r--ui/qt/interface_tree.cpp84
-rw-r--r--ui/qt/interface_tree.h12
-rw-r--r--ui/qt/main_welcome.cpp23
-rw-r--r--ui/qt/main_welcome.h6
-rw-r--r--ui/qt/main_welcome.ui3
-rw-r--r--ui/qt/main_window.cpp5
-rw-r--r--ui/qt/main_window.h5
-rw-r--r--ui/qt/main_window_slots.cpp27
26 files changed, 1560 insertions, 37 deletions
diff --git a/extcap.c b/extcap.c
index f02f86f678..339021971b 100644
--- a/extcap.c
+++ b/extcap.c
@@ -428,6 +428,32 @@ extcap_get_if_configuration(const char * ifname) {
return ret;
}
+gboolean
+extcap_has_configuration(const char * ifname) {
+ GList * arguments = 0;
+ GList * walker = 0, * item = 0;
+
+ gboolean found = FALSE;
+
+ arguments = extcap_get_if_configuration((const char *)( ifname ) );
+ walker = g_list_first(arguments);
+
+ while ( walker != NULL && ! found )
+ {
+ item = g_list_first((GList *)(walker->data));
+ while ( item != NULL && ! found )
+ {
+ if ( (extcap_arg *)(item->data) != NULL )
+ found = TRUE;
+
+ item = item->next;
+ }
+ walker = walker->next;
+ }
+
+ return found;
+}
+
void extcap_cleanup(capture_options * capture_opts) {
interface_options interface_opts;
guint icnt = 0;
diff --git a/extcap.h b/extcap.h
index 259c088d89..60f3904ce0 100644
--- a/extcap.h
+++ b/extcap.h
@@ -48,6 +48,10 @@
#define EXTCAP_ARGUMENT_RUN_CAPTURE "--capture"
#define EXTCAP_ARGUMENT_RUN_PIPE "--fifo"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
/* try to get if capabilities from extcap */
if_capabilities_t *
extcap_get_if_dlts(const gchar * ifname, char ** err_str);
@@ -61,6 +65,9 @@ extcap_interface_list(char **err_str);
GList *
extcap_get_if_configuration(const char * ifname);
+gboolean
+extcap_has_configuration(const char * ifname);
+
#ifdef WIN32
HANDLE
extcap_get_win32_handle();
@@ -75,6 +82,10 @@ extcap_create_pipe(char ** fifo);
void
extcap_cleanup(capture_options * capture_opts _U_);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif
#endif
diff --git a/extcap_parser.c b/extcap_parser.c
index 0dd85ac937..dc74b2588f 100644
--- a/extcap_parser.c
+++ b/extcap_parser.c
@@ -60,7 +60,7 @@ gchar *extcap_get_complex_as_string(extcap_complex *comp) {
break;
case EXTCAP_ARG_BOOLEAN:
g_snprintf(ret, 32, "%s",
- comp->complex_value.bool_value ? "TRUE" : "FALSE");
+ comp->complex_value.bool_value ? "true" : "false");
break;
case EXTCAP_ARG_STRING:
case EXTCAP_ARG_FILESELECT:
@@ -604,8 +604,6 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
target_arg->arg_type = EXTCAP_ARG_BOOLEAN;
} else if (g_ascii_strcasecmp(v->value, "boolflag") == 0) {
target_arg->arg_type = EXTCAP_ARG_BOOLFLAG;
- } else if (g_ascii_strcasecmp(v->value, "menu") == 0) {
- target_arg->arg_type = EXTCAP_ARG_MENU;
} else if (g_ascii_strcasecmp(v->value, "selector") == 0) {
target_arg->arg_type = EXTCAP_ARG_SELECTOR;
} else if (g_ascii_strcasecmp(v->value, "radio") == 0) {
diff --git a/extcap_parser.h b/extcap_parser.h
index feb7f11c2b..9e1e51b388 100644
--- a/extcap_parser.h
+++ b/extcap_parser.h
@@ -46,7 +46,6 @@ typedef enum {
EXTCAP_ARG_BOOLFLAG,
EXTCAP_ARG_STRING,
/* Complex GUI types which are populated with value sentences */
- EXTCAP_ARG_MENU,
EXTCAP_ARG_SELECTOR,
EXTCAP_ARG_RADIO,
EXTCAP_ARG_MULTICHECK,
@@ -128,9 +127,6 @@ typedef struct _extcap_interface {
struct _extcap_interface *next_interface;
} extcap_interface;
-extcap_interface *extcap_new_interface(void);
-void extcap_free_interface(extcap_interface *interface);
-
typedef struct _extcap_dlt {
gint number;
gchar *name;
@@ -139,9 +135,6 @@ typedef struct _extcap_dlt {
struct _extcap_dlt *next_dlt;
} extcap_dlt;
-extcap_dlt *extcap_new_dlt(void);
-void extcap_free_dlt(extcap_dlt *dlt);
-
/* Parser internals */
typedef struct _extcap_token_param {
gchar *arg;
@@ -160,6 +153,16 @@ typedef struct _extcap_token_sentence {
struct _extcap_token_sentence *next_sentence;
} extcap_token_sentence;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extcap_interface *extcap_new_interface(void);
+void extcap_free_interface(extcap_interface *interface);
+
+extcap_dlt *extcap_new_dlt(void);
+void extcap_free_dlt(extcap_dlt *dlt);
+
/* Parse a string into a complex type */
extcap_complex *extcap_parse_complex(extcap_arg_type complex_type,
const gchar *data);
@@ -239,6 +242,10 @@ int extcap_parse_dlt_sentence(extcap_token_sentence *s, extcap_dlt **ri);
/* Parse all sentences for DLTs */
int extcap_parse_dlts(extcap_token_sentence *first_s, extcap_dlt **first_dlt);
+#ifdef __cplusplus
+}
+#endif
+
#endif
/*
diff --git a/ui/gtk/extcap_gtk.c b/ui/gtk/extcap_gtk.c
index acd0b07b20..c2a1e3386e 100644
--- a/ui/gtk/extcap_gtk.c
+++ b/ui/gtk/extcap_gtk.c
@@ -181,8 +181,6 @@ GHashTable *extcap_gtk_get_state(GtkWidget *widget) {
continue;
}
break;
- case EXTCAP_ARG_MENU:
- break;
case EXTCAP_ARG_RADIO:
if ((radio_widget = (GtkWidget *) g_object_get_data(
G_OBJECT(list_widget),
@@ -859,8 +857,6 @@ GSList *extcap_populate_gtk_vbox(GList *arguments, GtkWidget *vbox,
}
break;
- case EXTCAP_ARG_MENU:
- break;
case EXTCAP_ARG_RADIO:
label = gtk_label_new(arg_iter->display);
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.1f);
diff --git a/ui/help_url.c b/ui/help_url.c
index 9cf9aa0592..6a93cb9407 100644
--- a/ui/help_url.c
+++ b/ui/help_url.c
@@ -259,6 +259,9 @@ topic_action_url(topic_action_e action)
case(HELP_EXPERT_INFO_DIALOG):
url = user_guide_url("ChAdvExpert.html");
break;
+ case(HELP_EXTCAP_OPTIONS_DIALOG):
+ url = user_guide_url("ChExtcapOptions.html");
+ break;
case(HELP_STATS_SUMMARY_DIALOG):
url = user_guide_url("ChStatSummary.html");
break;
diff --git a/ui/help_url.h b/ui/help_url.h
index 85ce20d488..033ef8ff8c 100644
--- a/ui/help_url.h
+++ b/ui/help_url.h
@@ -83,6 +83,9 @@ typedef enum {
HELP_DECODE_AS_SHOW_DIALOG,
HELP_FOLLOW_STREAM_DIALOG,
HELP_EXPERT_INFO_DIALOG,
+#if HAVE_EXTCAP
+ HELP_EXTCAP_OPTIONS_DIALOG,
+#endif
HELP_STATS_SUMMARY_DIALOG,
HELP_STATS_PROTO_HIERARCHY_DIALOG,
HELP_STATS_ENDPOINTS_DIALOG,
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index b1c56139bf..e52e803185 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -117,6 +117,15 @@ if(HAVE_PCAP_REMOTE)
)
endif()
+if(ENABLE_EXTCAP)
+ set(WIRESHARK_QT_HEADERS
+ ${WIRESHARK_QT_HEADERS}
+ extcap_argument.h
+ extcap_argument_file.h
+ extcap_options_dialog.h
+ )
+endif()
+
file(GLOB EXTRA_QT_HEADERS
packet_list_record.h
qt_ui_utils.h
@@ -221,6 +230,15 @@ if(HAVE_PCAP_REMOTE)
)
endif()
+if(ENABLE_EXTCAP)
+ set(WIRESHARK_QT_SRC
+ ${WIRESHARK_QT_SRC}
+ extcap_argument.cpp
+ extcap_argument_file.cpp
+ extcap_options_dialog.cpp
+ )
+endif()
+
set(WIRESHARK_QT_TAP_SRC
conversation_dialog.cpp
endpoint_dialog.cpp
@@ -296,6 +314,13 @@ if(HAVE_PCAP_REMOTE)
)
endif()
+if(ENABLE_EXTCAP)
+ set(WIRESHARK_QT_UI
+ ${WIRESHARK_QT_UI}
+ extcap_options_dialog.ui
+ )
+endif()
+
set(WIRESHARK_QT_QRC
../../image/about.qrc
../../image/display_filter.qrc
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index bfa6a44344..372ed6f675 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -144,6 +144,8 @@ export_object_dialog.cpp export_object_dialog.h: ui_export_object_dialog.h
export_pdu_dialog.cpp export_pdu_dialog.h: ui_export_pdu_dialog.h
+extcap_options_dialog.cpp extcap_options_dialog.h: ui_extcap_options_dialog.h
+
file_set_dialog.cpp file_set_dialog.h: ui_file_set_dialog.h
filter_expressions_preferences_frame.cpp filter_expressions_preferences_frame.h: ui_filter_expressions_preferences_frame.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index b201bb9c10..bd5da843d9 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -41,6 +41,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_decode_as_dialog.h \
ui_export_object_dialog.h \
ui_export_pdu_dialog.h \
+ ui_extcap_options_dialog.h \
ui_file_set_dialog.h \
ui_filter_expressions_preferences_frame.h \
ui_follow_stream_dialog.h \
@@ -146,6 +147,9 @@ MOC_HDRS = \
export_dissection_dialog.h \
export_object_dialog.h \
export_pdu_dialog.h \
+ extcap_argument.h \
+ extcap_argument_file.h \
+ extcap_options_dialog.h \
file_set_dialog.h \
filter_action.h \
filter_expressions_preferences_frame.h \
@@ -224,6 +228,7 @@ UI_FILES = \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
+ extcap_options_dialog.ui \
file_set_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
@@ -345,6 +350,9 @@ WIRESHARK_QT_SRC = \
export_dissection_dialog.cpp \
export_object_dialog.cpp \
export_pdu_dialog.cpp \
+ extcap_argument.cpp \
+ extcap_argument_file.cpp \
+ extcap_options_dialog.cpp \
file_set_dialog.cpp \
filter_action.cpp \
filter_expressions_preferences_frame.cpp \
diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro
index 5ac94cdf1c..ec80b40281 100644
--- a/ui/qt/Wireshark.pro
+++ b/ui/qt/Wireshark.pro
@@ -217,6 +217,7 @@ FORMS += \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
+ extcap_options_dialog.ui \
file_set_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
@@ -279,6 +280,9 @@ HEADERS += $$HEADERS_WS_C \
export_dissection_dialog.h \
export_object_dialog.h \
export_pdu_dialog.h \
+ extcap_argument.h \
+ extcap_argument_file.h \
+ extcap_options_dialog.h \
filter_action.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
@@ -627,6 +631,9 @@ SOURCES += \
export_dissection_dialog.cpp \
export_object_dialog.cpp \
export_pdu_dialog.cpp \
+ extcap_argument.cpp \
+ extcap_argument_file.cpp \
+ extcap_options_dialog.cpp \
file_set_dialog.cpp \
filter_action.cpp \
filter_expressions_preferences_frame.cpp \
diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp
new file mode 100644
index 0000000000..f8c2d7a50d
--- /dev/null
+++ b/ui/qt/extcap_argument.cpp
@@ -0,0 +1,657 @@
+/* extcap_argument.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <extcap_argument.h>
+
+#include <QObject>
+#include <QWidget>
+#include <QLabel>
+#include <QLineEdit>
+#include <QIntValidator>
+#include <QDoubleValidator>
+#include <QCheckBox>
+#include <QButtonGroup>
+#include <QBoxLayout>
+#include <QRadioButton>
+#include <QComboBox>
+#include <QPushButton>
+#include <QMargins>
+#include <QVariant>
+#include <QAbstractItemModel>
+#include <QStringList>
+#include <QStandardItem>
+#include <QStandardItemModel>
+#include <QItemSelectionModel>
+#include <QTreeView>
+
+#include <extcap_parser.h>
+#include <extcap_argument_file.h>
+
+class ExtArgMultiSelect : public ExtcapArgument
+{
+public:
+ ExtArgMultiSelect(extcap_arg * argument) :
+ ExtcapArgument(argument), treeView(0), viewModel(0) {};
+
+ virtual QList<QStandardItem *> valueWalker(ExtcapValueList list, QStringList &defaults)
+ {
+ ExtcapValueList::iterator iter = list.begin();
+ QList<QStandardItem *> items;
+
+ while ( iter != list.end() )
+ {
+ QStandardItem * item = new QStandardItem((*iter).value());
+ if ( (*iter).enabled() == false )
+ {
+ item->setSelectable(false);
+ }
+ else
+ item->setSelectable(true);
+
+ item->setData((*iter).call(), Qt::UserRole);
+ if ((*iter).isDefault())
+ defaults << (*iter).call();
+
+ item->setEditable(false);
+ QList<QStandardItem *> childs = valueWalker((*iter).children(), defaults);
+ if ( childs.length() > 0 )
+ item->appendRows(childs);
+
+ items << item;
+ ++iter;
+ }
+
+ return items;
+ }
+
+ void selectItemsWalker(QStandardItem * item, QStringList defaults)
+ {
+ QModelIndexList results;
+ QModelIndex index;
+
+ if ( item->hasChildren() )
+ {
+ for (int row = 0; row < item->rowCount(); row++)
+ {
+ QStandardItem * child = item->child(row);
+ if ( child != 0 )
+ {
+ selectItemsWalker(child, defaults);
+ }
+ }
+ }
+
+ QString data = item->data(Qt::UserRole).toString();
+
+ if ( defaults.contains(data) )
+ {
+ treeView->selectionModel()->select(item->index(), QItemSelectionModel::Select);
+ index = item->index();
+ while ( index.isValid() )
+ {
+ treeView->setExpanded(index, true);
+ index = index.parent();
+ }
+ }
+ }
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+ QStringList defaults;
+
+ QList<QStandardItem *> items = valueWalker(values, defaults);
+ if (items.length() == 0)
+ return new QWidget();
+
+ if ( _default != 0 )
+ defaults = _default->toString().split(",", QString::SkipEmptyParts);
+
+ viewModel = new QStandardItemModel();
+ QList<QStandardItem *>::const_iterator iter = items.constBegin();
+ while ( iter != items.constEnd() )
+ {
+ ((QStandardItemModel *)viewModel)->appendRow((*iter));
+ ++iter;
+ }
+
+ treeView = new QTreeView(parent);
+ treeView->setModel(viewModel);
+
+ /* Shows at minimum 6 entries at most desktops */
+ treeView->setMinimumHeight(100);
+ treeView->setHeaderHidden(true);
+ treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ for (int row = 0; row < viewModel->rowCount(); row++ )
+ selectItemsWalker(((QStandardItemModel*)viewModel)->item(row), defaults);
+
+ return treeView;
+ }
+
+ virtual QString value()
+ {
+ if ( viewModel == 0 )
+ return QString();
+
+ QStringList result;
+ QModelIndexList selected = treeView->selectionModel()->selectedIndexes();
+
+ if ( selected.size() <= 0 )
+ return QString();
+
+ QModelIndexList::const_iterator iter = selected.constBegin();
+ while ( iter != selected.constEnd() )
+ {
+ QModelIndex index = (QModelIndex)(*iter);
+
+ result << viewModel->data(index, Qt::UserRole).toString();
+
+ ++iter;
+ }
+
+ return result.join(QString(","));
+ }
+
+ virtual QString defaultValue()
+ {
+ if ( _argument != 0 && _argument->default_complex != 0)
+ {
+ gchar * str = extcap_get_complex_as_string(_argument->default_complex);
+ if ( str != 0 )
+ return QString(str);
+ }
+
+ return QString();
+ }
+
+private:
+ QTreeView * treeView;
+ QAbstractItemModel * viewModel;
+};
+
+class ExtArgSelector : public ExtcapArgument
+{
+public:
+ ExtArgSelector(extcap_arg * argument) :
+ ExtcapArgument(argument), boxSelection(0) {};
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+ int counter = 0;
+ int selected = -1;
+
+ boxSelection = new QComboBox(parent);
+
+ if ( values.length() > 0 )
+ {
+ ExtcapValueList::const_iterator iter = values.constBegin();
+
+ while ( iter != values.constEnd() )
+ {
+ boxSelection->addItem((*iter).value(), (*iter).call());
+ if ( (*iter).isDefault() )
+ selected = counter;
+
+ counter++;
+ ++iter;
+ }
+
+ if ( selected > -1 && selected < boxSelection->count() )
+ boxSelection->setCurrentIndex(selected);
+ }
+
+ return boxSelection;
+ }
+
+ virtual QString value()
+ {
+ if ( boxSelection == 0 )
+ return QString();
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
+ QVariant data = boxSelection->currentData();
+#else
+ QVariant data = boxSelection->itemData(boxSelection->currentIndex());
+#endif
+
+ return data.toString();
+ }
+
+private:
+ QComboBox * boxSelection;
+};
+
+class ExtArgRadio : public ExtcapArgument
+{
+public:
+ ExtArgRadio(extcap_arg * argument) :
+ ExtcapArgument(argument), selectorGroup(0), callStrings(0)
+ {
+ };
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+
+ int count = 0;
+ bool anyChecked = false;
+
+ selectorGroup = new QButtonGroup(parent);
+ QWidget * radioButtons = new QWidget;
+ QVBoxLayout * vrLayout = new QVBoxLayout();
+ QMargins margins = vrLayout->contentsMargins();
+ vrLayout->setContentsMargins(0, 0, 0, margins.bottom());
+ if ( callStrings != 0 )
+ delete callStrings;
+
+ callStrings = new QList<QString>();
+
+ if ( values.length() > 0 )
+ {
+ ExtcapValueList::const_iterator iter = values.constBegin();
+
+ while ( iter != values.constEnd() )
+ {
+ QRadioButton * radio = new QRadioButton((*iter).value());
+ QString callString = (*iter).call();
+ callStrings->append(callString);
+
+ if ( _default != NULL && (*iter).isDefault() )
+ {
+ radio->setChecked(true);
+ anyChecked = true;
+ }
+ else if (_default != NULL)
+ {
+ if ( callString.compare(_default->toString()) == 0 )
+ {
+ radio->setChecked(true);
+ anyChecked = true;
+ }
+ }
+ selectorGroup->addButton(radio, count);
+
+ vrLayout->addWidget(radio);
+ count++;
+
+ ++iter;
+ }
+ }
+
+ /* No default was provided, and not saved value exists */
+ if ( anyChecked == false && count > 0 )
+ ((QRadioButton*)(selectorGroup->button(0)))->setChecked(true);
+
+ radioButtons->setLayout(vrLayout);
+
+ return radioButtons;
+ }
+
+ virtual QString value()
+ {
+ int idx = 0;
+ if ( selectorGroup == 0 || callStrings == 0 )
+ return QString();
+
+ idx = selectorGroup->checkedId();
+ if ( idx > -1 && callStrings->length() > idx )
+ return callStrings->takeAt(idx);
+
+ return QString();
+ }
+
+private:
+ QButtonGroup * selectorGroup;
+ QList<QString> * callStrings;
+};
+
+class ExtArgBool : public ExtcapArgument
+{
+public:
+ ExtArgBool(extcap_arg * argument) :
+ ExtcapArgument(argument), boolBox(0) {};
+
+ virtual QWidget * createLabel(QWidget * parent)
+ {
+ return new QWidget(parent);
+ }
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+ boolBox = new QCheckBox(QString().fromUtf8(_argument->display), parent);
+ if ( _argument->tooltip != NULL )
+ boolBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+
+ if ( _argument->default_complex != NULL )
+ if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
+ boolBox->setCheckState(Qt::Checked);
+
+ if ( _default != NULL )
+ {
+ if ( _default->toString().compare("true") )
+ boolBox->setCheckState(Qt::Checked);
+ }
+
+ return boolBox;
+ }
+
+ virtual QString call()
+ {
+ if ( boolBox == NULL )
+ return QString("");
+
+ if ( _argument->arg_type == EXTCAP_ARG_BOOLEAN )
+ return ExtcapArgument::call();
+
+ return QString(boolBox->checkState() == Qt::Checked ? _argument->call : "");
+ }
+
+ virtual QString value()
+ {
+ if ( boolBox == NULL || _argument->arg_type == EXTCAP_ARG_BOOLFLAG )
+ return QString();
+ return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
+ }
+
+ virtual QString defaultValue()
+ {
+ if ( _argument != 0 && _argument->default_complex != NULL )
+ if ( extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE )
+ return QString("true");
+
+ return QString("false");
+ }
+
+private:
+ QCheckBox * boolBox;
+};
+
+class ExtArgText : public ExtcapArgument
+{
+public:
+ ExtArgText(extcap_arg * argument) :
+ ExtcapArgument(argument), textBox(0)
+ {
+ _default = new QVariant(QString(""));
+ };
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+ textBox = new QLineEdit(_default->toString(), parent);
+
+ textBox->setText(defaultValue());
+
+ if ( _argument->tooltip != NULL )
+ textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+
+ return textBox;
+ }
+
+ virtual QString value()
+ {
+ if ( textBox == 0 )
+ return QString();
+
+ return textBox->text();
+ }
+
+ virtual QString defaultValue()
+ {
+ if ( _argument != 0 && _argument->default_complex != 0)
+ {
+ gchar * str = extcap_get_complex_as_string(_argument->default_complex);
+ if ( str != 0 )
+ return QString(str);
+ }
+
+ return QString();
+ }
+
+protected:
+ QLineEdit * textBox;
+};
+
+class ExtArgNumber : public ExtArgText
+{
+public:
+ ExtArgNumber(extcap_arg * argument) :
+ ExtArgText(argument) {};
+
+ virtual QWidget * createEditor(QWidget * parent)
+ {
+ textBox = (QLineEdit *)ExtArgText::createEditor(parent);
+
+ if ( _argument->arg_type == EXTCAP_ARG_INTEGER || _argument->arg_type == EXTCAP_ARG_UNSIGNED )
+ {
+ QIntValidator * textValidator = new QIntValidator(parent);
+ if ( _argument->range_start != NULL )
+ textValidator->setBottom(extcap_complex_get_int(_argument->range_start));
+
+ if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED && textValidator->bottom() < 0 )
+ textValidator->setBottom(0);
+
+ if ( _argument->range_end != NULL )
+ textValidator->setTop(extcap_complex_get_int(_argument->range_end));
+ textBox->setValidator(textValidator);
+ }
+ else if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
+ {
+ QDoubleValidator * textValidator = new QDoubleValidator(parent);
+ if ( _argument->range_start != NULL )
+ textValidator->setBottom(extcap_complex_get_double(_argument->range_start));
+ if ( _argument->range_end != NULL )
+ textValidator->setTop(extcap_complex_get_double(_argument->range_end));
+
+ textBox->setValidator(textValidator);
+ }
+
+ textBox->setText(defaultValue());
+
+ return textBox;
+ };
+
+ virtual QString defaultValue()
+ {
+ QString result;
+
+ if ( _argument != 0 && _argument->default_complex != NULL )
+ {
+ if ( _argument->arg_type == EXTCAP_ARG_DOUBLE )
+ result = QString::number(extcap_complex_get_double(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_INTEGER )
+ result = QString::number(extcap_complex_get_int(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_UNSIGNED )
+ result = QString::number(extcap_complex_get_uint(_argument->default_complex));
+ else if ( _argument->arg_type == EXTCAP_ARG_LONG )
+ result = QString::number(extcap_complex_get_long(_argument->default_complex));
+ else
+ result = QString();
+ }
+
+ return result;
+ }
+};
+
+ExtcapValue::~ExtcapValue() {}
+
+void ExtcapValue::setChildren(ExtcapValueList children)
+{
+ ExtcapValueList::iterator iter = children.begin();
+ while ( iter != children.end() )
+ {
+ (*iter)._depth = _depth + 1;
+ ++iter;
+ }
+
+ _children.append(children);
+}
+
+ExtcapArgument::ExtcapArgument(extcap_arg * argument, QObject *parent) :
+ QObject(parent), _argument(argument), _default(0)
+{
+ if ( _argument->values != 0 )
+ {
+ ExtcapValueList elements = loadValues(QString(""));
+ if ( elements.length() > 0 )
+ values.append(elements);
+ }
+}
+
+ExtcapValueList ExtcapArgument::loadValues(QString parent)
+{
+ if (_argument->values == 0 )
+ return ExtcapValueList();
+
+ GList * walker = 0;
+ extcap_value * v;
+ ExtcapValueList elements;
+
+ for (walker = g_list_first((GList *)(_argument->values)); walker != NULL ; walker = walker->next)
+ {
+ v = (extcap_value *) walker->data;
+ if (v == NULL || v->display == NULL || v->call == NULL )
+ break;
+
+ QString valParent(v->parent == 0 ? "" : QString().fromUtf8(v->parent));
+
+ if ( parent.compare(valParent) == 0 )
+ {
+
+ QString display = QString().fromUtf8(v->display);
+ QString call = QString().fromUtf8(v->call);
+
+ ExtcapValue element = ExtcapValue(display, call,
+ v->enabled == (gboolean)TRUE, v->is_default == (gboolean)TRUE);
+
+ element.setChildren(this->loadValues(call));
+ elements.append(element);
+ }
+ }
+
+ return elements;
+}
+
+ExtcapArgument::~ExtcapArgument() {
+ // TODO Auto-generated destructor stub
+}
+
+QWidget * ExtcapArgument::createLabel(QWidget * parent)
+{
+ if ( _argument == 0 || _argument->display == 0 )
+ return 0;
+
+ QString text = QString().fromUtf8(_argument->display);
+
+ QLabel * label = new QLabel(text, parent);
+ if ( _argument->tooltip != 0 )
+ label->setToolTip(QString().fromUtf8(_argument->tooltip));
+
+ return label;
+}
+
+QWidget * ExtcapArgument::createEditor(QWidget * parent)
+{
+ Q_UNUSED(parent);
+ return 0;
+}
+
+QString ExtcapArgument::call()
+{
+ return QString(_argument->call);
+}
+
+QString ExtcapArgument::value()
+{
+ return QString();
+}
+
+QString ExtcapArgument::defaultValue()
+{
+ return QString();
+}
+
+void ExtcapArgument::setDefault(GHashTable * defaultsList)
+{
+ if ( defaultsList != NULL && g_hash_table_size(defaultsList) > 0 )
+ {
+ GList * keys = g_hash_table_get_keys(defaultsList);
+ while ( keys != NULL )
+ {
+ if ( call().compare(QString().fromUtf8((gchar *)keys->data)) == 0 )
+ {
+ gpointer data = g_hash_table_lookup(defaultsList, keys->data);
+ QString dataStr = QString().fromUtf8((gchar *)data);
+ /* We assume an empty value but set entry must be a boolflag */
+ if ( dataStr.length() == 0 )
+ dataStr = "true";
+ _default = new QVariant(dataStr);
+ break;
+ }
+ keys = keys->next;
+ }
+ }
+}
+
+ExtcapArgument * ExtcapArgument::create(extcap_arg * argument, GHashTable * device_defaults)
+{
+ if ( argument == 0 || argument->display == 0 )
+ return 0;
+
+ ExtcapArgument * result = 0;
+
+ if ( argument->arg_type == EXTCAP_ARG_STRING )
+ result = new ExtArgText(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_INTEGER || argument->arg_type == EXTCAP_ARG_LONG ||
+ argument->arg_type == EXTCAP_ARG_UNSIGNED || argument->arg_type == EXTCAP_ARG_DOUBLE )
+ result = new ExtArgNumber(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_BOOLEAN || argument->arg_type == EXTCAP_ARG_BOOLFLAG )
+ result = new ExtArgBool(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_SELECTOR )
+ result = new ExtArgSelector(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_RADIO )
+ result = new ExtArgRadio(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_FILESELECT )
+ result = new ExtcapArgumentFileSelection(argument);
+ else if ( argument->arg_type == EXTCAP_ARG_MULTICHECK )
+ result = new ExtArgMultiSelect(argument);
+ else
+ {
+ /* For everything else, we just print the label */
+ result = new ExtcapArgument(argument);
+ }
+
+ result->setDefault(device_defaults);
+
+ return result;
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h
new file mode 100644
index 0000000000..185f2bc607
--- /dev/null
+++ b/ui/qt/extcap_argument.h
@@ -0,0 +1,117 @@
+/* extcap_argument.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef UI_QT_EXTCAP_ARGUMENT_H_
+#define UI_QT_EXTCAP_ARGUMENT_H_
+
+#include <QObject>
+#include <QWidget>
+#include <QLabel>
+#include <QVariant>
+#include <QList>
+
+#include <extcap_parser.h>
+
+class ExtcapValue;
+
+typedef QList<ExtcapValue> ExtcapValueList;
+
+class ExtcapValue
+{
+public:
+ ExtcapValue(QString value, QString call, bool enabled, bool isDefault) :
+ _value(value), _call(call), _enabled(enabled),
+ _isDefault(isDefault), _depth(0) {};
+ virtual ~ExtcapValue();
+
+ void setChildren(ExtcapValueList children);
+ ExtcapValueList children()
+ {
+ if ( _children.length() == 0 )
+ return ExtcapValueList();
+ return _children;
+ };
+
+ QString value() const { return _value; }
+ const QString call() const { return _call; }
+ bool enabled() const { return _enabled; }
+ bool isDefault() const { return _isDefault; }
+
+ int depth() { return _depth; }
+
+private:
+ QString _value;
+ QString _call;
+
+ bool _enabled;
+ bool _isDefault;
+
+ int _depth;
+
+ ExtcapValueList _children;
+};
+
+
+class ExtcapArgument: public QObject
+{
+ Q_OBJECT
+
+public:
+ ExtcapArgument(extcap_arg * argument, QObject *parent=0);
+
+ virtual ~ExtcapArgument();
+
+ virtual QWidget * createLabel(QWidget * parent = 0);
+ virtual QWidget * createEditor(QWidget * parent = 0);
+
+ virtual extcap_arg * argument() { return _argument; }
+ virtual QString call();
+ virtual QString value();
+ virtual QString defaultValue();
+
+ static ExtcapArgument * create(extcap_arg * argument = 0, GHashTable * device_defaults = 0);
+
+protected:
+
+ void setDefault(GHashTable * defaultsList);
+
+ ExtcapValueList loadValues(QString parent);
+
+ ExtcapValueList values;
+
+ extcap_arg * _argument;
+ QVariant * _default;
+};
+
+#endif /* UI_QT_EXTCAP_ARGUMENT_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_argument_file.cpp b/ui/qt/extcap_argument_file.cpp
new file mode 100644
index 0000000000..370df9792d
--- /dev/null
+++ b/ui/qt/extcap_argument_file.cpp
@@ -0,0 +1,111 @@
+/* extcap_argument_file.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <extcap_argument.h>
+#include <extcap_argument_file.h>
+#include <QObject>
+#include <QWidget>
+#include <QLabel>
+#include <QLineEdit>
+#include <QBoxLayout>
+#include <QPushButton>
+#include <QFileDialog>
+#include <QDir>
+#include <QFileInfo>
+#include <QVariant>
+
+#include <extcap_parser.h>
+
+
+ExtcapArgumentFileSelection::ExtcapArgumentFileSelection (extcap_arg * argument) :
+ ExtcapArgument(argument), textBox(0)
+{
+ _default = new QVariant(QString(""));
+}
+
+QWidget * ExtcapArgumentFileSelection::createEditor(QWidget * parent)
+{
+ QWidget * fileWidget = new QWidget(parent);
+ QHBoxLayout * editLayout = new QHBoxLayout();
+ QMargins margins = editLayout->contentsMargins();
+ editLayout->setContentsMargins(0, 0, 0, margins.bottom());
+ fileWidget->setContentsMargins(margins.left(), margins.right(), 0, margins.bottom());
+ QPushButton * button = new QPushButton("...", fileWidget);
+
+ textBox = new QLineEdit(_default->toString(), parent);
+ textBox->setReadOnly(true);
+
+ if ( _argument->default_complex != NULL && _argument->arg_type == EXTCAP_ARG_STRING )
+ textBox->setText(QString().fromUtf8(extcap_complex_get_string(_argument->default_complex)));
+
+ if ( _argument->tooltip != NULL )
+ {
+ textBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+ button->setToolTip(QString().fromUtf8(_argument->tooltip));
+ }
+
+
+ connect(button, SIGNAL(clicked()), (QObject *)this, SLOT(openFileDialog()));
+
+ editLayout->addWidget(textBox);
+ editLayout->addWidget(button);
+
+ fileWidget->setLayout(editLayout);
+
+ return fileWidget;
+}
+
+QString ExtcapArgumentFileSelection::value()
+{
+ if ( textBox == 0 )
+ return QString();
+ return textBox->text();
+}
+
+/* opens the file dialog */
+void ExtcapArgumentFileSelection::openFileDialog()
+{
+ QString filename = textBox->text();
+
+ QDir workingDir = QDir::currentPath();
+ if (QFileInfo(filename).exists())
+ workingDir = QFileInfo(filename).dir();
+
+ filename = QFileDialog::getOpenFileName((QWidget *)(textBox->parent()),
+ QString().fromUtf8(_argument->display) + " " + tr("Open File"),
+ workingDir.absolutePath(), tr("All Files (*.*)"));
+
+ if ( QFileInfo(filename).exists() )
+ textBox->setText(filename);
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_argument_file.h b/ui/qt/extcap_argument_file.h
new file mode 100644
index 0000000000..14f715cb45
--- /dev/null
+++ b/ui/qt/extcap_argument_file.h
@@ -0,0 +1,65 @@
+/* extcap_argument_file.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef UI_QT_EXTCAP_ARGUMENT_FILE_H_
+#define UI_QT_EXTCAP_ARGUMENT_FILE_H_
+
+#include <QObject>
+#include <QWidget>
+#include <QLineEdit>
+
+#include <extcap_parser.h>
+#include <extcap_argument.h>
+
+class ExtcapArgumentFileSelection : public ExtcapArgument
+{
+ Q_OBJECT
+
+public:
+ ExtcapArgumentFileSelection (extcap_arg * argument);
+
+ virtual QWidget * createEditor(QWidget * parent);
+
+ virtual QString value();
+
+protected:
+ QLineEdit * textBox;
+
+private slots:
+ /* opens the file dialog */
+ void openFileDialog();
+
+};
+
+#endif /* UI_QT_EXTCAP_ARGUMENT_FILE_H_ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp
new file mode 100644
index 0000000000..987fb6e843
--- /dev/null
+++ b/ui/qt/extcap_options_dialog.cpp
@@ -0,0 +1,243 @@
+/* extcap_options_dialog.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <extcap_options_dialog.h>
+#include <ui_extcap_options_dialog.h>
+
+#include <wireshark_application.h>
+
+#ifdef HAVE_EXTCAP
+#include <QMessageBox>
+#include <QMap>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+
+#include "ringbuffer.h"
+#include "ui/capture_ui_utils.h"
+#include "ui/capture_globals.h"
+#include "ui/iface_lists.h"
+#include "ui/last_open_dir.h"
+
+#include "ui/ui_util.h"
+#include "ui/util.h"
+#include "ui/utf8_entities.h"
+
+#include <cstdio>
+#include <epan/addr_resolv.h>
+#include <wsutil/filesystem.h>
+
+#include <extcap.h>
+#include <extcap_parser.h>
+
+#include "qt_ui_utils.h"
+
+#include <ui/qt/extcap_argument.h>
+#include <ui/qt/extcap_argument_file.h>
+
+ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ExtcapOptionsDialog)
+{
+ ui->setupUi(this);
+
+ setWindowTitle(wsApp->windowTitleString(tr("Extcap Interface Options")));
+
+ device_idx = 0;
+
+ start_bt_ = ui->buttonBox->addButton(tr("Start"), QDialogButtonBox::YesRole);
+
+ start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
+ connect(start_bt_, SIGNAL(clicked(bool)), this, SLOT(start_button_clicked()));
+}
+
+ExtcapOptionsDialog * ExtcapOptionsDialog::createForDevice(QString &dev_name, QWidget *parent)
+{
+ interface_t device;
+ ExtcapOptionsDialog * resultDialog = NULL;
+ bool dev_found = false;
+ guint if_idx;
+
+ if ( dev_name.length() == 0 )
+ return NULL;
+
+ for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++)
+ {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
+ if (dev_name.compare(QString(device.name)) == 0 && device.if_info.type == IF_EXTCAP)
+ {
+ dev_found = true;
+ break;
+ }
+ }
+
+ if ( ! dev_found )
+ return NULL;
+
+ resultDialog = new ExtcapOptionsDialog(parent);
+ resultDialog->device_name = QString(dev_name);
+ resultDialog->device_idx = if_idx;
+ resultDialog->device_defaults = device.external_cap_args_settings;
+
+ resultDialog->setWindowTitle(wsApp->windowTitleString(tr("Extcap Interface Options") + ": " + device.display_name));
+
+ resultDialog->updateWidgets();
+
+ return resultDialog;
+}
+
+
+ExtcapOptionsDialog::~ExtcapOptionsDialog()
+{
+ delete ui;
+}
+
+void ExtcapOptionsDialog::start_button_clicked()
+{
+ if (saveOptionsToPreferences()) {
+ accept();
+ }
+}
+
+void ExtcapOptionsDialog::updateWidgets()
+{
+ GList * arguments = NULL, * walker = NULL, * item = NULL;
+ QWidget * lblWidget = NULL, *editWidget = NULL;
+ ExtcapArgument * argument = NULL;
+
+ unsigned int counter = 0;
+
+ if ( device_name.length() == 0 )
+ return;
+
+ arguments = extcap_get_if_configuration((const char *)( device_name.toStdString().c_str() ) );
+ walker = g_list_first(arguments);
+
+ QGridLayout * layout = new QGridLayout();
+
+ while ( walker != NULL )
+ {
+ item = g_list_first((GList *)(walker->data));
+ while ( item != NULL )
+ {
+ argument = ExtcapArgument::create((extcap_arg *)(item->data), device_defaults);
+ if ( argument != NULL )
+ {
+ extcapArguments << argument;
+
+ lblWidget = argument->createLabel((QWidget *)this);
+ if ( lblWidget != NULL )
+ {
+ layout->addWidget(lblWidget, counter, 0, Qt::AlignTop);
+ editWidget = argument->createEditor((QWidget *) this);
+ if ( editWidget != NULL )
+ {
+ layout->addWidget(editWidget, counter, 1, Qt::AlignTop);
+ }
+ counter++;
+ }
+ }
+
+ item = item->next;
+ }
+ walker = walker->next;
+ }
+
+ if ( counter > 0 )
+ ui->verticalLayout->addLayout(layout);
+
+ if ( counter > 0 )
+ ui->verticalLayout->addSpacerItem(new QSpacerItem(20, 100, QSizePolicy::Minimum, QSizePolicy::Expanding));
+}
+
+// Not sure why we have to do this manually.
+void ExtcapOptionsDialog::on_buttonBox_rejected()
+{
+ if (saveOptionsToPreferences()) {
+ reject();
+ }
+}
+
+void ExtcapOptionsDialog::on_buttonBox_helpRequested()
+{
+ // Probably the wrong URL.
+ wsApp->helpTopicAction(HELP_EXTCAP_OPTIONS_DIALOG);
+}
+
+bool ExtcapOptionsDialog::saveOptionsToPreferences()
+{
+ GHashTable * ret_args;
+ interface_t device;
+
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, device_idx);
+
+ ret_args = g_hash_table_new(g_str_hash, g_str_equal);
+
+ ExtcapArgumentList::const_iterator iter;
+
+ for(iter = extcapArguments.constBegin(); iter != extcapArguments.constEnd(); ++iter)
+ {
+ QString call = (*iter)->call();
+ QString value = (*iter)->value();
+
+ if ((*iter)->argument()->arg_type != EXTCAP_ARG_BOOLFLAG && value.length() == 0)
+ continue;
+
+ if ( call.length() <= 0 )
+ continue;
+
+ if ( value.compare((*iter)->defaultValue()) == 0 )
+ continue;
+
+ gchar * call_string = g_strdup(call.toStdString().c_str());
+ gchar * value_string = g_strdup(value.toStdString().c_str());
+
+ g_hash_table_insert(ret_args, call_string, value_string );
+ }
+
+ if (device.external_cap_args_settings != NULL)
+ g_hash_table_unref(device.external_cap_args_settings);
+ device.external_cap_args_settings = ret_args;
+
+ g_array_insert_val(global_capture_opts.all_ifaces, device_idx, device);
+
+ return true;
+}
+
+#endif /* HAVE_LIBPCAP */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_options_dialog.h b/ui/qt/extcap_options_dialog.h
new file mode 100644
index 0000000000..9cd57fe9cb
--- /dev/null
+++ b/ui/qt/extcap_options_dialog.h
@@ -0,0 +1,91 @@
+/* extcap_options_dialog.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#ifndef EXTCAP_OPTIONS_DIALOG_H
+#define EXTCAP_OPTIONS_DIALOG_H
+
+#include <config.h>
+
+#ifdef HAVE_EXTCAP
+
+#include <QWidget>
+#include <QDialog>
+#include <QPushButton>
+#include <QList>
+
+#include "interface_tree.h"
+
+#include "ui/qt/extcap_argument.h"
+
+#include <extcap.h>
+#include <extcap_parser.h>
+
+namespace Ui {
+class ExtcapOptionsDialog;
+}
+
+typedef QList<ExtcapArgument *> ExtcapArgumentList;
+
+class ExtcapOptionsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ ~ExtcapOptionsDialog();
+ static ExtcapOptionsDialog * createForDevice(QString &device_name, QWidget *parent = 0);
+
+private slots:
+ void start_button_clicked();
+ void on_buttonBox_rejected();
+ void on_buttonBox_helpRequested();
+ void updateWidgets();
+
+private:
+ explicit ExtcapOptionsDialog(QWidget *parent = 0);
+
+ Ui::ExtcapOptionsDialog *ui;
+ QString device_name;
+ guint device_idx;
+ GHashTable * device_defaults;
+ QPushButton *start_bt_;
+
+ ExtcapArgumentList extcapArguments;
+
+ bool saveOptionsToPreferences();
+};
+
+#endif /* HAVE_EXTCAP */
+
+#endif // EXTCAP_OPTIONS_DIALOG_H
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/extcap_options_dialog.ui b/ui/qt/extcap_options_dialog.ui
new file mode 100644
index 0000000000..1600df9b7b
--- /dev/null
+++ b/ui/qt/extcap_options_dialog.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ExtcapOptionsDialog</class>
+ <widget class="QDialog" name="ExtcapOptionsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>450</width>
+ <height>49</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>450</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/ui/qt/interface_tree.cpp b/ui/qt/interface_tree.cpp
index 883dd7e870..29498d4834 100644
--- a/ui/qt/interface_tree.cpp
+++ b/ui/qt/interface_tree.cpp
@@ -34,6 +34,10 @@
#include "sparkline_delegate.h"
#include "wireshark_application.h"
+#ifdef HAVE_EXTCAP
+#include "extcap.h"
+#endif
+
#include <QLabel>
#include <QHeaderView>
#include <QTimer>
@@ -54,17 +58,19 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
header()->setVisible(false);
setRootIsDecorated(false);
setUniformRowHeights(true);
- setColumnCount(2);
+ /* Seems to have no effect, still the default value (2) is being used, as it
+ * was set in the .ui file. But better safe, then sorry. */
+ resetColumnCount();
setSelectionMode(QAbstractItemView::ExtendedSelection);
setAccessibleName(tr("Welcome screen list"));
- setItemDelegateForColumn(1, new SparkLineDelegate());
+ setItemDelegateForColumn(IFTREE_COL_STATS, new SparkLineDelegate());
setDisabled(true);
ti = new QTreeWidgetItem();
- ti->setText(0, tr("Waiting for startup%1").arg(UTF8_HORIZONTAL_ELLIPSIS));
+ ti->setText(IFTREE_COL_NAME, tr("Waiting for startup%1").arg(UTF8_HORIZONTAL_ELLIPSIS));
addTopLevelItem(ti);
- resizeColumnToContents(0);
+ resizeColumnToContents(IFTREE_COL_NAME);
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList()));
connect(wsApp, SIGNAL(localInterfaceListChanged()), this, SLOT(interfaceListChanged()));
@@ -83,13 +89,23 @@ InterfaceTree::~InterfaceTree() {
while (*iter) {
QList<int> *points;
- points = (*iter)->data(1, Qt::UserRole).value<QList<int> *>();
+ points = (*iter)->data(IFTREE_COL_STATS, Qt::UserRole).value<QList<int> *>();
delete(points);
++iter;
}
#endif // HAVE_LIBPCAP
}
+/* Resets the column count to the maximum colum count
+ *
+ * This is necessary, because the treeview may have more columns, then
+ * the default value (2).
+ */
+void InterfaceTree::resetColumnCount()
+{
+ setColumnCount(IFTREE_COL_MAX);
+}
+
void InterfaceTree::hideEvent(QHideEvent *evt) {
Q_UNUSED(evt);
@@ -109,17 +125,18 @@ void InterfaceTree::showEvent(QShowEvent *evt) {
if (stat_timer_) stat_timer_->start(stat_update_interval_);
#endif // HAVE_LIBPCAP
}
-
+#include <QDebug>
void InterfaceTree::resizeEvent(QResizeEvent *evt)
{
Q_UNUSED(evt);
int max_if_width = width() * 2 / 3; // Arbitrary
setUpdatesEnabled(false);
- resizeColumnToContents(0);
- if (columnWidth(0) > max_if_width) {
- setColumnWidth(0, max_if_width);
+ resizeColumnToContents(IFTREE_COL_NAME);
+ if (columnWidth(IFTREE_COL_NAME) > max_if_width) {
+ setColumnWidth(IFTREE_COL_NAME, max_if_width);
}
+
setUpdatesEnabled(true);
}
@@ -127,6 +144,9 @@ void InterfaceTree::display()
{
#ifdef HAVE_LIBPCAP
interface_t device;
+#if HAVE_EXTCAP
+ QIcon extcap_icon(":/icons/toolbar/16x16/x-capture-options.png");
+#endif
setDisabled(false);
clear();
@@ -161,13 +181,36 @@ void InterfaceTree::display()
}
QTreeWidgetItem *ti = new QTreeWidgetItem();
- ti->setText(0, QString().fromUtf8(device.display_name));
- ti->setData(0, Qt::UserRole, QString(device.name));
+ ti->setText(IFTREE_COL_NAME, QString().fromUtf8(device.display_name));
+ ti->setData(IFTREE_COL_NAME, Qt::UserRole, QString(device.name));
points = new QList<int>();
- ti->setData(1, Qt::UserRole, qVariantFromValue(points));
+ ti->setData(IFTREE_COL_STATS, Qt::UserRole, qVariantFromValue(points));
+#if HAVE_EXTCAP
+ if ( device.if_info.type == IF_EXTCAP )
+ {
+ if ( extcap_has_configuration((const char *)(device.name)) )
+ {
+ ti->setIcon(IFTREE_COL_EXTCAP, extcap_icon);
+ ti->setData(IFTREE_COL_EXTCAP, Qt::UserRole, QString(device.if_info.extcap));
+
+ if ( !(device.external_cap_args_settings != 0 &&
+ g_hash_table_size(device.external_cap_args_settings ) > 0) )
+ {
+ QFont ti_font = ti->font(IFTREE_COL_NAME);
+ ti_font.setItalic(true);
+ ti->setFont(IFTREE_COL_NAME, ti_font );
+ }
+ }
+ }
+#endif
addTopLevelItem(ti);
// XXX Add other device information
- resizeColumnToContents(1);
+ resizeColumnToContents(IFTREE_COL_STATS);
+
+#if HAVE_EXTCAP
+ resizeColumnToContents(IFTREE_COL_EXTCAP);
+#endif
+
if (strstr(prefs.capture_device, device.name) != NULL) {
device.selected = TRUE;
global_capture_opts.num_selected++;
@@ -214,8 +257,7 @@ void InterfaceTree::getPoints(int row, PointList *pts)
if (row == i)
{
//qDebug("found! row:%d", row);
- QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
- QList<int> *punkt = (*iter)->data(1, Qt::UserRole).value<QList<int> *>();
+ QList<int> *punkt = (*iter)->data(IFTREE_COL_STATS, Qt::UserRole).value<QList<int> *>();
for (int j = 0; j < punkt->length(); j++)
{
pts->append(punkt->at(j));
@@ -250,7 +292,8 @@ void InterfaceTree::updateStatistics(void) {
for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
- QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
+ QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
+
if (device_name.compare(device.name) || device.hidden || device.type == IF_PIPE)
continue;
@@ -263,9 +306,10 @@ void InterfaceTree::updateStatistics(void) {
device.last_packets = stats.ps_recv;
}
- points = (*iter)->data(1, Qt::UserRole).value<QList<int> *>();
+ points = (*iter)->data(IFTREE_COL_STATS, Qt::UserRole).value<QList<int> *>();
+
points->append(diff);
- update(indexFromItem((*iter), 1));
+ update(indexFromItem((*iter), IFTREE_COL_STATS));
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx);
g_array_insert_val(global_capture_opts.all_ifaces, if_idx, device);
}
@@ -283,7 +327,7 @@ void InterfaceTree::updateSelectedInterfaces()
while (*iter) {
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
- QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
+ QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
if (!device.locked) {
@@ -318,7 +362,7 @@ void InterfaceTree::setSelectedInterfaces()
QTreeWidgetItemIterator iter(this);
while (*iter) {
- QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
+ QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
diff --git a/ui/qt/interface_tree.h b/ui/qt/interface_tree.h
index 33c8ed2f19..7b08172094 100644
--- a/ui/qt/interface_tree.h
+++ b/ui/qt/interface_tree.h
@@ -37,6 +37,16 @@
typedef QList<int> PointList;
+enum InterfaceTreeColumns
+{
+#if HAVE_EXTCAP
+ IFTREE_COL_EXTCAP,
+#endif
+ IFTREE_COL_NAME,
+ IFTREE_COL_STATS,
+ IFTREE_COL_MAX
+};
+
class InterfaceTree : public QTreeWidget
{
Q_OBJECT
@@ -44,6 +54,8 @@ public:
explicit InterfaceTree(QWidget *parent = 0);
~InterfaceTree();
+ void resetColumnCount();
+
protected:
void hideEvent(QHideEvent *evt);
void showEvent(QShowEvent *evt);
diff --git a/ui/qt/main_welcome.cpp b/ui/qt/main_welcome.cpp
index 5c551c5c92..8033617a70 100644
--- a/ui/qt/main_welcome.cpp
+++ b/ui/qt/main_welcome.cpp
@@ -53,6 +53,8 @@ MainWelcome::MainWelcome(QWidget *parent) :
{
welcome_ui_->setupUi(this);
+ welcome_ui_->interfaceTree->resetColumnCount();
+
welcome_ui_->mainWelcomeBanner->setText(tr("Welcome to Wireshark."));
recent_files_ = welcome_ui_->recentList;
@@ -147,6 +149,10 @@ MainWelcome::MainWelcome(QWidget *parent) :
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(appInitialized()));
connect(welcome_ui_->interfaceTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
this, SLOT(interfaceDoubleClicked(QTreeWidgetItem*,int)));
+#if HAVE_EXTCAP
+ connect(welcome_ui_->interfaceTree, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
+ this, SLOT(interfaceClicked(QTreeWidgetItem*,int)));
+#endif
connect(welcome_ui_->interfaceTree, SIGNAL(interfaceUpdated(const char*,bool)),
welcome_ui_->captureFilterComboBox, SIGNAL(interfacesChanged()));
connect(welcome_ui_->captureFilterComboBox, SIGNAL(pushFilterSyntaxStatus(const QString&)),
@@ -210,6 +216,23 @@ void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int column)
emit startCapture();
}
}
+#include <QDebug>
+void MainWelcome::interfaceClicked(QTreeWidgetItem *item, int column)
+{
+#if HAVE_EXTCAP
+ if ( column == IFTREE_COL_EXTCAP )
+ {
+ QString extcap_string = QVariant(item->data(IFTREE_COL_EXTCAP, Qt::UserRole)).toString();
+ /* We trust the string here. If this interface is really extcap, the string is
+ * being checked immediatly before the dialog is being generated */
+ if ( extcap_string.length() > 0 )
+ {
+ QString device_name = QVariant(item->data(IFTREE_COL_NAME, Qt::UserRole)).toString();
+ emit showExtcapOptions(device_name);
+ }
+ }
+#endif
+}
void MainWelcome::updateRecentFiles() {
QString itemLabel;
diff --git a/ui/qt/main_welcome.h b/ui/qt/main_welcome.h
index e9d1eb40ba..49d188488a 100644
--- a/ui/qt/main_welcome.h
+++ b/ui/qt/main_welcome.h
@@ -61,9 +61,15 @@ signals:
void pushFilterSyntaxStatus(const QString&);
void popFilterSyntaxStatus();
void captureFilterSyntaxChanged(bool valid);
+#if HAVE_EXTCAP
+ void showExtcapOptions(QString &device_name);
+#endif
private slots:
void appInitialized();
+#if HAVE_EXTCAP
+ void interfaceClicked(QTreeWidgetItem *item, int column);
+#endif
void interfaceDoubleClicked(QTreeWidgetItem *item, int column);
void updateRecentFiles();
void openRecentItem(QListWidgetItem *item);
diff --git a/ui/qt/main_welcome.ui b/ui/qt/main_welcome.ui
index 8efaa9330b..9362aa1f3a 100644
--- a/ui/qt/main_welcome.ui
+++ b/ui/qt/main_welcome.ui
@@ -189,9 +189,6 @@
<property name="uniformRowHeights">
<bool>true</bool>
</property>
- <property name="columnCount">
- <number>2</number>
- </property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 8ce826dd3e..8948ec432d 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -421,6 +421,11 @@ MainWindow::MainWindow(QWidget *parent) :
connect(main_ui_->welcomePage, SIGNAL(captureFilterSyntaxChanged(bool)),
this, SLOT(captureFilterSyntaxChanged(bool)));
+#if HAVE_EXTCAP
+ connect(this->main_welcome_, SIGNAL(showExtcapOptions(QString&)),
+ this, SLOT(showExtcapOptionsDialog(QString&)));
+#endif
+
connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
connect(&capture_interfaces_dialog_, SIGNAL(setSelectedInterfaces()),
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index c97aefa520..408a5ab0ab 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -473,6 +473,11 @@ private slots:
void externalMenuItem_triggered();
void changeEvent(QEvent* event);
+
+#if HAVE_EXTCAP
+ void extcap_options_finished(int result);
+ void showExtcapOptionsDialog(QString & device_name);
+#endif
};
#endif // MAINWINDOW_H
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 3704b49365..feb11fe7b2 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -82,6 +82,9 @@
#include "endpoint_dialog.h"
#include "export_object_dialog.h"
#include "export_pdu_dialog.h"
+#if HAVE_EXTCAP
+#include "extcap_options_dialog.h"
+#endif
#include "io_graph_dialog.h"
#include "lbm_stream_dialog.h"
#include "lbm_uimflow_dialog.h"
@@ -2928,6 +2931,30 @@ void MainWindow::externalMenuItem_triggered()
}
}
+#ifdef HAVE_EXTCAP
+#include <QDebug>
+void MainWindow::extcap_options_finished(int result)
+{
+ if ( result == QDialog::Accepted )
+ {
+ startCapture();
+ }
+ this->main_welcome_->getInterfaceTree()->interfaceListChanged();
+}
+
+void MainWindow::showExtcapOptionsDialog(QString &device_name)
+{
+ ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
+ /* The dialog returns null, if the given device name is not a valid extcap device */
+ if ( extcap_options_dialog != NULL )
+ {
+ connect(extcap_options_dialog, SIGNAL(finished(int)),
+ this, SLOT(extcap_options_finished(int)));
+ extcap_options_dialog->show();
+ }
+}
+#endif
+
/*
* Editor modelines
*