diff options
author | Roland Knall <roland.knall@br-automation.com> | 2015-04-28 10:26:46 +0200 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2015-05-05 09:35:10 +0000 |
commit | 5727ebe6890bc263b90b3a77435b7aa7ae0ca411 (patch) | |
tree | 28e492c5118ad14481c0759859fc59829a78686e /ui | |
parent | cdaad860720a17d889e759d9e263c5fcadaf36a2 (diff) |
extcap: Implement QT extcap options
Implementing a button in the interface list, to bring up
the extcap options dialog, as well as a dialog, which will
be generated depending on the selected extcap options.
Change-Id: I1733dc6a8c1a121089a9c353aff10bc4a53e86de
Reviewed-on: https://code.wireshark.org/review/8224
Petri-Dish: Michal Labedzki <michal.labedzki@tieto.com>
Reviewed-by: Roland Knall <rknall@gmail.com>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gtk/extcap_gtk.c | 4 | ||||
-rw-r--r-- | ui/help_url.c | 3 | ||||
-rw-r--r-- | ui/help_url.h | 3 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 25 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 8 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 7 | ||||
-rw-r--r-- | ui/qt/extcap_argument.cpp | 657 | ||||
-rw-r--r-- | ui/qt/extcap_argument.h | 117 | ||||
-rw-r--r-- | ui/qt/extcap_argument_file.cpp | 111 | ||||
-rw-r--r-- | ui/qt/extcap_argument_file.h | 65 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.cpp | 243 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.h | 91 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.ui | 34 | ||||
-rw-r--r-- | ui/qt/interface_tree.cpp | 84 | ||||
-rw-r--r-- | ui/qt/interface_tree.h | 12 | ||||
-rw-r--r-- | ui/qt/main_welcome.cpp | 23 | ||||
-rw-r--r-- | ui/qt/main_welcome.h | 6 | ||||
-rw-r--r-- | ui/qt/main_welcome.ui | 3 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 5 | ||||
-rw-r--r-- | ui/qt/main_window.h | 5 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 27 |
22 files changed, 1508 insertions, 27 deletions
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 * |