aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorRoland Knall <rknall@gmail.com>2016-10-25 14:27:56 +0200
committerRoland Knall <rknall@gmail.com>2016-10-27 23:54:04 +0000
commit6500a660c2285aa558be58b084de9554fccdfc09 (patch)
treebc5e12962c7864464f6ac9350c17110eefaf21f8 /ui
parent1fae14257a8a7ade813930097a12dd3e555a9f76 (diff)
ManageInterfacesDialog: New handling of pipes
This moves the handling of pipes to the new InterfaceTreeModel as well. It also includes a new PathChooserDelegate and cache handling for adding data to an interface list without putting it into storage Change-Id: Id255a81161b4da517e26127abe8ea7f5eb36d55a Reviewed-on: https://code.wireshark.org/review/18497 Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/CMakeLists.txt2
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/interface_sort_filter_model.cpp26
-rw-r--r--ui/qt/interface_sort_filter_model.h1
-rw-r--r--ui/qt/interface_tree_cache_model.cpp247
-rw-r--r--ui/qt/interface_tree_cache_model.h10
-rw-r--r--ui/qt/interface_tree_model.cpp10
-rw-r--r--ui/qt/interface_tree_model.h1
-rw-r--r--ui/qt/manage_interfaces_dialog.cpp249
-rw-r--r--ui/qt/manage_interfaces_dialog.h32
-rw-r--r--ui/qt/manage_interfaces_dialog.ui7
-rw-r--r--ui/qt/path_chooser_delegate.cpp152
-rw-r--r--ui/qt/path_chooser_delegate.h58
13 files changed, 530 insertions, 267 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 3220c835d6..3cd9d2e503 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -111,6 +111,7 @@ set(WIRESHARK_QT_HEADERS
packet_list.h
packet_list_model.h
packet_range_group_box.h
+ path_chooser_delegate.h
percent_bar_delegate.h
preference_editor_frame.h
preferences_dialog.h
@@ -273,6 +274,7 @@ set(WIRESHARK_QT_SRC
packet_list_model.cpp
packet_list_record.cpp
packet_range_group_box.cpp
+ path_chooser_delegate.cpp
percent_bar_delegate.cpp
preference_editor_frame.cpp
preferences_dialog.cpp
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index d674fc2e98..f543f42c0a 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -235,6 +235,7 @@ MOC_HDRS = \
numeric_value_chooser_delegate.h \
overlay_scroll_bar.h \
packet_comment_dialog.h \
+ path_chooser_delegate.h \
packet_dialog.h \
packet_format_group_box.h \
packet_list.h \
@@ -517,6 +518,7 @@ WIRESHARK_QT_SRC = \
packet_list_model.cpp \
packet_list_record.cpp \
packet_range_group_box.cpp \
+ path_chooser_delegate.cpp \
percent_bar_delegate.cpp \
preference_editor_frame.cpp \
preferences_dialog.cpp \
diff --git a/ui/qt/interface_sort_filter_model.cpp b/ui/qt/interface_sort_filter_model.cpp
index fab21ec6e0..9b850e151b 100644
--- a/ui/qt/interface_sort_filter_model.cpp
+++ b/ui/qt/interface_sort_filter_model.cpp
@@ -21,6 +21,7 @@
*/
#include "ui/qt/interface_tree_model.h"
+#include "ui/qt/interface_tree_cache_model.h"
#include "ui/qt/interface_sort_filter_model.h"
#include <glib.h>
@@ -36,6 +37,11 @@
InterfaceSortFilterModel::InterfaceSortFilterModel(QObject *parent) :
QSortFilterProxyModel(parent)
{
+ resetAllFilter();
+}
+
+void InterfaceSortFilterModel::resetAllFilter()
+{
_filterHidden = true;
_filterTypes = true;
_invertTypeFilter = false;
@@ -44,6 +50,9 @@ InterfaceSortFilterModel::InterfaceSortFilterModel(QObject *parent) :
/* Adding all columns, to have a default setting */
for ( int col = 0; col < IFTREE_COL_MAX; col++ )
_columns.append((InterfaceTreeColumns)col);
+
+ invalidateFilter();
+ invalidate();
}
void InterfaceSortFilterModel::setStoreOnChange(bool storeOnChange)
@@ -214,8 +223,21 @@ bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex
if ( sourceModel()->rowCount() == 0 )
return false;
- int type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
- bool hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
+ int type = -1;
+ bool hidden = false;
+
+ if (dynamic_cast<InterfaceTreeCacheModel*>(sourceModel()) != 0)
+ {
+ type = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
+ hidden = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
+ }
+ else if (dynamic_cast<InterfaceTreeModel*>(sourceModel()) != 0)
+ {
+ type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
+ hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
+ }
+ else
+ return false;
if ( hidden && _filterHidden )
return false;
diff --git a/ui/qt/interface_sort_filter_model.h b/ui/qt/interface_sort_filter_model.h
index dd062acfb7..7f28eb0151 100644
--- a/ui/qt/interface_sort_filter_model.h
+++ b/ui/qt/interface_sort_filter_model.h
@@ -38,6 +38,7 @@ public:
InterfaceSortFilterModel(QObject *parent);
void setStoreOnChange(bool storeOnChange);
+ void resetAllFilter();
void setFilterHidden(bool filter);
bool filterHidden() const;
diff --git a/ui/qt/interface_tree_cache_model.cpp b/ui/qt/interface_tree_cache_model.cpp
index 842697204b..126d9be074 100644
--- a/ui/qt/interface_tree_cache_model.cpp
+++ b/ui/qt/interface_tree_cache_model.cpp
@@ -50,7 +50,7 @@ InterfaceTreeCacheModel::InterfaceTreeCacheModel(QObject *parent) :
checkableColumns << IFTREE_COL_MONITOR_MODE;
#endif
- editableColumns << IFTREE_COL_INTERFACE_COMMENT << IFTREE_COL_SNAPLEN;
+ editableColumns << IFTREE_COL_INTERFACE_COMMENT << IFTREE_COL_SNAPLEN << IFTREE_COL_PIPE_PATH;
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
editableColumns << IFTREE_COL_BUFFERLEN;
@@ -59,6 +59,13 @@ InterfaceTreeCacheModel::InterfaceTreeCacheModel(QObject *parent) :
InterfaceTreeCacheModel::~InterfaceTreeCacheModel()
{
+ /* This list should only exist, if the dialog is closed, without calling save first */
+ if ( newDevices.size() > 0 )
+ {
+ qDeleteAll(newDevices);
+ newDevices.clear();
+ }
+
delete storage;
delete sourceModel;
}
@@ -82,6 +89,60 @@ QVariant InterfaceTreeCacheModel::getColumnContent(int idx, int col, int role)
return InterfaceTreeCacheModel::data(index(idx, col), role);
}
+void InterfaceTreeCacheModel::saveNewDevices()
+{
+ QList<interface_t *>::const_iterator it = newDevices.constBegin();
+ /* idx is used for iterating only over the indices of the new devices. As all new
+ * devices are stored with an index higher then sourceModel->rowCount(), we start
+ * only with those storage indices.
+ * it is just the iterator over the new devices. A new device must not necessarily
+ * have storage, which will lead to that device not being stored in global_capture_opts */
+ for (int idx = sourceModel->rowCount(); it != newDevices.constEnd(); ++it, idx++)
+ {
+ interface_t * device = (interface_t *)(*it);
+ bool useDevice = false;
+
+ QMap<InterfaceTreeColumns, QVariant> * dataField = storage->value(idx, 0);
+ /* When devices are being added, they are added using generic values. So only devices
+ * whose data have been changed should be used from here on out. */
+ if ( dataField != 0 )
+ {
+ if ( device->if_info.type != IF_PIPE )
+ {
+ continue;
+ }
+
+ if ( device->if_info.type == IF_PIPE )
+ {
+ QVariant saveValue = dataField->value(IFTREE_COL_PIPE_PATH);
+ if ( saveValue.isValid() )
+ {
+ g_free(device->if_info.name);
+ device->if_info.name = qstring_strdup(saveValue.toString());
+
+ g_free(device->name);
+ device->name = qstring_strdup(saveValue.toString());
+
+ g_free(device->display_name);
+ device->display_name = qstring_strdup(saveValue.toString());
+ useDevice = true;
+ }
+ }
+
+ if ( useDevice )
+ g_array_append_val(global_capture_opts.all_ifaces, *device);
+
+ }
+
+ /* All entries of this new devices have been considered */
+ storage->remove(idx);
+ delete dataField;
+ }
+
+ qDeleteAll(newDevices);
+ newDevices.clear();
+}
+
void InterfaceTreeCacheModel::save()
{
if ( storage->count() == 0 )
@@ -89,9 +150,13 @@ void InterfaceTreeCacheModel::save()
QMap<char**, QStringList> prefStorage;
+ /* Storing new devices first including their changed values */
+ saveNewDevices();
+
for(unsigned int idx = 0; idx < global_capture_opts.all_ifaces->len; idx++)
{
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
+
if (! device.name )
continue;
@@ -108,7 +173,7 @@ void InterfaceTreeCacheModel::save()
QVariant saveValue = it.value();
/* Setting the field values for each individual saved value cannot be generic, as the
- * struct cannot be accessed generically. Therefore below, each individually changed
+ * struct cannot be accessed in a generic way. Therefore below, each individually changed
* value has to be handled separately. Comments are stored only in the preference file
* and applied to the data name during loading. Therefore comments are not handled here */
@@ -226,11 +291,13 @@ void InterfaceTreeCacheModel::save()
++it;
}
+
+ wsApp->emitAppSignal(WiresharkApplication::LocalInterfacesChanged);
}
int InterfaceTreeCacheModel::rowCount(const QModelIndex & parent) const
{
- return sourceModel->rowCount(parent);
+ return sourceModel->rowCount(parent) + newDevices.size();
}
bool InterfaceTreeCacheModel::changeIsAllowed(InterfaceTreeColumns col) const
@@ -240,54 +307,70 @@ bool InterfaceTreeCacheModel::changeIsAllowed(InterfaceTreeColumns col) const
return false;
}
+interface_t * InterfaceTreeCacheModel::lookup(const QModelIndex &index) const
+{
+ interface_t * result = 0;
+
+ if ( ! index.isValid() )
+ return result;
+ if ( ! global_capture_opts.all_ifaces && newDevices.size() == 0 )
+ return result;
+
+ int idx = index.row();
+
+ if ( (unsigned int) idx >= global_capture_opts.all_ifaces->len )
+ {
+ idx = idx - global_capture_opts.all_ifaces->len;
+ if ( idx < newDevices.size() )
+ result = newDevices[idx];
+ }
+ else
+ {
+ result = &g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
+ }
+
+ return result;
+}
+
/* This checks if the column can be edited for the given index. This differs from
* isAllowedToBeChanged in such a way, that it is only used in flags and not any
* other method.*/
bool InterfaceTreeCacheModel::isAllowedToBeEdited(const QModelIndex &index) const
{
- if ( ! index.isValid() || ! global_capture_opts.all_ifaces )
- return false;
-
- int idx = index.row();
- if ( (unsigned int) idx >= global_capture_opts.all_ifaces->len )
- return false;
-
- interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
+ interface_t * device = lookup(index);
+ if ( device == 0 )
+ return false;
- InterfaceTreeColumns col = (InterfaceTreeColumns) index.column();
+ InterfaceTreeColumns col = (InterfaceTreeColumns) index.column();
#ifdef HAVE_EXTCAP
- if ( device.if_info.type == IF_EXTCAP )
- {
- /* extcap interfaces do not have those settings */
- if ( col == IFTREE_COL_PROMISCUOUSMODE || col == IFTREE_COL_SNAPLEN )
- return false;
+ if ( device->if_info.type == IF_EXTCAP )
+ {
+ /* extcap interfaces do not have those settings */
+ if ( col == IFTREE_COL_PROMISCUOUSMODE || col == IFTREE_COL_SNAPLEN )
+ return false;
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
- if ( col == IFTREE_COL_BUFFERLEN )
- return false;
+ if ( col == IFTREE_COL_BUFFERLEN )
+ return false;
#endif
- }
+ }
#endif
- return true;
+ return true;
}
bool InterfaceTreeCacheModel::isAllowedToBeChanged(const QModelIndex &index) const
{
- if ( ! index.isValid() || ! global_capture_opts.all_ifaces )
- return false;
+ interface_t * device = lookup(index);
- int idx = index.row();
- if ( (unsigned int) idx >= global_capture_opts.all_ifaces->len )
+ if ( device == 0 )
return false;
- interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
-
InterfaceTreeColumns col = (InterfaceTreeColumns) index.column();
if ( col == IFTREE_COL_HIDDEN )
{
if ( prefs.capture_device )
{
- if ( ! g_strcmp0(prefs.capture_device, device.display_name) )
+ if ( ! g_strcmp0(prefs.capture_device, device->display_name) )
return false;
}
}
@@ -360,6 +443,7 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const
return QVariant();
int row = index.row();
+
InterfaceTreeColumns col = (InterfaceTreeColumns)index.column();
if ( isAllowedToBeEdited(index) )
@@ -385,7 +469,112 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const
return QString("-");
}
- return sourceModel->data(index, role);
+ if ( row >= sourceModel->rowCount() )
+ {
+ /* Handle all fields, which will have to be displayed for new devices. Only pipes
+ * are supported at the moment, so the information to be displayed is pretty limited.
+ * After saving, the devices are stored in global_capture_opts and no longer
+ * classify as new devices. */
+ interface_t * device = lookup(index);
+
+ if ( device != 0 )
+ {
+ if ( role == Qt::DisplayRole || role == Qt::EditRole )
+ {
+ if ( col == IFTREE_COL_PIPE_PATH ||
+ col == IFTREE_COL_NAME ||
+ col == IFTREE_COL_INTERFACE_NAME )
+ {
+
+ QMap<InterfaceTreeColumns, QVariant> * dataField = 0;
+ if ( ( dataField = storage->value(row, 0) ) != 0 &&
+ dataField->contains(IFTREE_COL_PIPE_PATH) )
+ {
+ return dataField->value(IFTREE_COL_PIPE_PATH, QVariant());
+ }
+ else
+ return QString(device->name);
+ }
+ else if ( col == IFTREE_COL_TYPE )
+ {
+ return QVariant::fromValue((int)device->if_info.type);
+ }
+ }
+ else if ( role == Qt::CheckStateRole )
+ {
+ if ( col == IFTREE_COL_HIDDEN )
+ {
+ /* Hidden is a de-selection, therefore inverted logic here */
+ return device->hidden ? Qt::Unchecked : Qt::Checked;
+ }
+ }
+ }
+ }
+ else
+ return sourceModel->data(index, role);
+
+ return QVariant();
+}
+
+QModelIndex InterfaceTreeCacheModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if ( row >= sourceModel->rowCount() && ( row - sourceModel->rowCount() ) < newDevices.count() )
+ {
+ return createIndex(row, column, (void *)0);
+ }
+
+ return sourceModel->index(row, column, parent);
+}
+
+void InterfaceTreeCacheModel::addDevice(interface_t * newDevice)
+{
+ emit beginInsertRows(QModelIndex(), rowCount(), rowCount());
+ newDevices << newDevice;
+ emit endInsertRows();
+}
+
+void InterfaceTreeCacheModel::deleteDevice(const QModelIndex &index)
+{
+ if ( ! index.isValid() )
+ return;
+
+ emit beginRemoveRows(QModelIndex(), index.row(), index.row());
+
+ int row = index.row();
+
+ /* device is in newDevices */
+ if ( row >= sourceModel->rowCount() )
+ {
+ int newDeviceIdx = row - sourceModel->rowCount();
+
+ newDevices.removeAt(newDeviceIdx);
+ if ( storage->contains(index.row()) )
+ storage->remove(index.row());
+
+ /* The storage array has to be resorted, if the index, that was removed
+ * had been in the middle of the array. Can't start at index.row(), as
+ * it may not be contained in storage
+ * We must iterate using a list, not an iterator, otherwise the change
+ * will fold on itself. */
+ QList<int> storageKeys = storage->keys();
+ for ( int i = 0; i < storageKeys.size(); ++i )
+ {
+ int key = storageKeys.at(i);
+ if ( key > index.row() )
+ {
+ storage->insert(key - 1, storage->value(key));
+ storage->remove(key);
+ }
+ }
+
+ emit endRemoveRows();
+ }
+ else
+ {
+ g_array_remove_index(global_capture_opts.all_ifaces, row);
+ emit endRemoveRows();
+ wsApp->emitAppSignal(WiresharkApplication::LocalInterfacesChanged);
+ }
}
/*
diff --git a/ui/qt/interface_tree_cache_model.h b/ui/qt/interface_tree_cache_model.h
index fffa0ebb84..74163b12e7 100644
--- a/ui/qt/interface_tree_cache_model.h
+++ b/ui/qt/interface_tree_cache_model.h
@@ -45,16 +45,26 @@ public:
QVariant getColumnContent(int idx, int col, int role = Qt::DisplayRole);
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+
void reset(int row);
void save();
+ void addDevice(interface_t * newDevice);
+ void deleteDevice(const QModelIndex &index);
+
private:
InterfaceTreeModel * sourceModel;
+ QList<interface_t *> newDevices;
+
+ void saveNewDevices();
+
QMap<int, QMap<InterfaceTreeColumns, QVariant> *> * storage;
QList<InterfaceTreeColumns> editableColumns;
QList<InterfaceTreeColumns> checkableColumns;
+ interface_t * lookup(const QModelIndex &index) const;
bool changeIsAllowed(InterfaceTreeColumns col) const;
bool isAllowedToBeChanged(const QModelIndex &index) const;
bool isAllowedToBeEdited(const QModelIndex &index) const;
diff --git a/ui/qt/interface_tree_model.cpp b/ui/qt/interface_tree_model.cpp
index 062ef4e792..bae432be0b 100644
--- a/ui/qt/interface_tree_model.cpp
+++ b/ui/qt/interface_tree_model.cpp
@@ -135,6 +135,10 @@ QVariant InterfaceTreeModel::data(const QModelIndex &index, int role) const
{
return QString(device.name);
}
+ else if ( col == IFTREE_COL_PIPE_PATH )
+ {
+ return QString(device.if_info.name);
+ }
else if ( col == IFTREE_COL_CAPTURE_FILTER )
{
if ( device.cfilter && strlen(device.cfilter) > 0 )
@@ -264,10 +268,14 @@ QVariant InterfaceTreeModel::headerData(int section, Qt::Orientation orientation
{
return tr("Friendly Name");
}
- else if ( section == IFTREE_COL_INTERFACE_NAME )
+ else if ( section == IFTREE_COL_NAME )
{
return tr("Interface Name");
}
+ else if ( section == IFTREE_COL_PIPE_PATH )
+ {
+ return tr("Local Pipe Path");
+ }
else if ( section == IFTREE_COL_INTERFACE_COMMENT )
{
return tr("Comment");
diff --git a/ui/qt/interface_tree_model.h b/ui/qt/interface_tree_model.h
index 3d0816bfed..5517308791 100644
--- a/ui/qt/interface_tree_model.h
+++ b/ui/qt/interface_tree_model.h
@@ -61,6 +61,7 @@ enum InterfaceTreeColumns
IFTREE_COL_MONITOR_MODE,
#endif
IFTREE_COL_CAPTURE_FILTER,
+ IFTREE_COL_PIPE_PATH,
IFTREE_COL_MAX /* is not being displayed, it is the definition for the maximum numbers of columns */
};
diff --git a/ui/qt/manage_interfaces_dialog.cpp b/ui/qt/manage_interfaces_dialog.cpp
index 1f33ce77db..eb053c45d2 100644
--- a/ui/qt/manage_interfaces_dialog.cpp
+++ b/ui/qt/manage_interfaces_dialog.cpp
@@ -22,9 +22,9 @@
#include <glib.h>
#include "manage_interfaces_dialog.h"
#include <ui_manage_interfaces_dialog.h>
+
#include "epan/prefs.h"
#include "epan/to_str.h"
-#include "ui/last_open_dir.h"
#include "capture_opts.h"
#include "ui/capture_globals.h"
#include "ui/qt/capture_interfaces_dialog.h"
@@ -49,6 +49,8 @@
#include "ui/capture_ui_utils.h"
+#include "ui/qt/path_chooser_delegate.h"
+
#include <QCheckBox>
#include <QFileDialog>
#include <QHBoxLayout>
@@ -90,7 +92,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
#ifdef Q_OS_MAC
ui->addPipe->setAttribute(Qt::WA_MacSmallSize, true);
- ui->addPipe->setAttribute(Qt::WA_MacSmallSize, true);
+ ui->delPipe->setAttribute(Qt::WA_MacSmallSize, true);
ui->addRemote->setAttribute(Qt::WA_MacSmallSize, true);
ui->delRemote->setAttribute(Qt::WA_MacSmallSize, true);
#endif
@@ -110,14 +112,27 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
proxyModel->setFilterHidden(false);
proxyModel->setFilterByType(false);
-
ui->localView->setModel(proxyModel);
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_HIDDEN));
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_INTERFACE_NAME));
- ui->pipeList->setItemDelegateForColumn(col_p_pipe_, &new_pipe_item_delegate_);
- new_pipe_item_delegate_.setTree(ui->pipeList);
- showPipes();
+ pipeProxyModel = new InterfaceSortFilterModel(this);
+ columns.clear();
+ columns.append(IFTREE_COL_PIPE_PATH);
+ pipeProxyModel->setColumns(columns);
+ pipeProxyModel->setSourceModel(sourceModel);
+ pipeProxyModel->setFilterHidden(true);
+ pipeProxyModel->setFilterByType(true, true);
+ pipeProxyModel->setInterfaceTypeVisible(IF_PIPE, false);
+ ui->pipeView->setModel(pipeProxyModel);
+ ui->delPipe->setEnabled(pipeProxyModel->rowCount() > 0);
+
+ ui->pipeView->setItemDelegateForColumn(
+ pipeProxyModel->mapSourceToColumn(IFTREE_COL_PIPE_PATH), new PathChooserDelegate()
+ );
+ connect(ui->pipeView->selectionModel(),
+ SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this,
+ SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
#if defined(HAVE_PCAP_REMOTE)
// The default indentation (20) means our checkboxes are shifted too far on Windows.
@@ -128,7 +143,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
ui->remoteSettings->setEnabled(false);
showRemoteInterfaces();
#else
- ui->remoteTab->setEnabled(false);
+ ui->tabWidget->removeTab(tab_remote_);
#endif
connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateWidgets()));
@@ -149,16 +164,15 @@ ManageInterfacesDialog::~ManageInterfacesDialog()
delete ui;
}
+void ManageInterfacesDialog::onSelectionChanged(const QItemSelection &sel, const QItemSelection &)
+{
+ ui->delPipe->setEnabled( sel.count() > 0 );
+}
+
void ManageInterfacesDialog::updateWidgets()
{
QString hint;
- if (ui->pipeList->selectedItems().length() > 0) {
- ui->delPipe->setEnabled(true);
- } else {
- ui->delPipe->setEnabled(false);
- }
-
#ifdef HAVE_PCAP_REMOTE
bool enable_del_remote = false;
bool enable_remote_settings = false;
@@ -195,30 +209,8 @@ void ManageInterfacesDialog::updateWidgets()
ui->hintLabel->setText(hint);
}
-void ManageInterfacesDialog::showPipes()
-{
- ui->pipeList->clear();
-
- if (global_capture_opts.all_ifaces->len > 0) {
- interface_t device;
-
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
- device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
-
- /* Continue if capture device is hidden */
- if (device.hidden || device.type != IF_PIPE) {
- continue;
- }
- QTreeWidgetItem *item = new QTreeWidgetItem(ui->pipeList);
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- item->setText(col_p_pipe_, device.display_name);
- }
- }
-}
-
void ManageInterfacesDialog::on_buttonBox_accepted()
{
- pipeAccepted();
sourceModel->save();
#ifdef HAVE_PCAP_REMOTE
remoteAccepted();
@@ -228,97 +220,37 @@ void ManageInterfacesDialog::on_buttonBox_accepted()
emit ifsChanged();
}
-const QString new_pipe_default_ = QObject::tr("New Pipe");
void ManageInterfacesDialog::on_addPipe_clicked()
{
- QTreeWidgetItem *item = new QTreeWidgetItem(ui->pipeList);
- item->setText(col_p_pipe_, new_pipe_default_);
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- ui->pipeList->setCurrentItem(item);
- ui->pipeList->editItem(item, col_p_pipe_);
-}
-
-void ManageInterfacesDialog::pipeAccepted()
-{
- interface_t device;
-
- // First clear the current pipes
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
- device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
- /* Continue if capture device is hidden or not a pipe */
- if (device.hidden || device.type != IF_PIPE) {
- continue;
- }
- global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
- capture_opts_free_interface_t(&device);
- }
-
- // Next rebuild a fresh list
- QTreeWidgetItemIterator it(ui->pipeList);
- while (*it) {
- QString pipe_name = (*it)->text(col_p_pipe_);
- if (pipe_name.isEmpty() || pipe_name == new_pipe_default_) {
- ++it;
- continue;
- }
-
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
- // Instead of just deleting the device we might want to add a hint label
- // and let the user know what's going to happen.
- device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
- if (pipe_name.compare(device.name) == 0) { // Duplicate
- ++it;
- continue;
- }
- }
-
- memset(&device, 0, sizeof(device));
- device.name = qstring_strdup(pipe_name);
- device.display_name = g_strdup(device.name);
- device.hidden = FALSE;
- device.selected = TRUE;
- device.type = IF_PIPE;
- device.pmode = global_capture_opts.default_options.promisc_mode;
- device.has_snaplen = global_capture_opts.default_options.has_snaplen;
- device.snaplen = global_capture_opts.default_options.snaplen;
- device.cfilter = g_strdup(global_capture_opts.default_options.cfilter);
- device.addresses = NULL;
- device.no_addresses = 0;
- device.last_packets = 0;
- device.links = NULL;
+ interface_t * device = g_new0(interface_t, 1);
+
+ device->name = qstring_strdup(tr("New Pipe"));
+ device->display_name = g_strdup(device->name);
+ device->hidden = FALSE;
+ device->selected = TRUE;
+ device->pmode = global_capture_opts.default_options.promisc_mode;
+ device->has_snaplen = global_capture_opts.default_options.has_snaplen;
+ device->snaplen = global_capture_opts.default_options.snaplen;
+ device->cfilter = g_strdup(global_capture_opts.default_options.cfilter);
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
- device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
-#endif
- device.active_dlt = -1;
- device.locked = FALSE;
- device.if_info.name = g_strdup(device.name);
- device.if_info.friendly_name = NULL;
- device.if_info.vendor_description = NULL;
- device.if_info.addrs = NULL;
- device.if_info.loopback = FALSE;
- device.if_info.type = IF_PIPE;
-#ifdef HAVE_EXTCAP
- device.if_info.extcap = NULL;
- device.external_cap_args_settings = NULL;
+ device->buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
#endif
-#if defined(HAVE_PCAP_CREATE)
- device.monitor_mode_enabled = FALSE;
- device.monitor_mode_supported = FALSE;
-#endif
- global_capture_opts.num_selected++;
- g_array_append_val(global_capture_opts.all_ifaces, device);
- ++it;
- }
+ device->active_dlt = -1;
+ device->if_info.name = g_strdup(device->name);
+ device->if_info.type = IF_PIPE;
+
+ sourceModel->addDevice(device);
+ updateWidgets();
}
void ManageInterfacesDialog::on_delPipe_clicked()
{
- // We're just managing a list of strings at this point.
- delete ui->pipeList->currentItem();
-}
+ /* Get correct selection and tell the source model to delete the itm. pipe view only
+ * displays IF_PIPE devices, therefore this will only delete pipes, and this is set
+ * to only select single items. */
+ QModelIndex selIndex = ui->pipeView->selectionModel()->selectedIndexes().at(0);
-void ManageInterfacesDialog::on_pipeList_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
-{
+ sourceModel->deleteDevice( pipeProxyModel->mapToSource(selIndex) );
updateWidgets();
}
@@ -638,89 +570,6 @@ void ManageInterfacesDialog::setRemoteSettings(interface_t *iface)
}
#endif // HAVE_PCAP_REMOTE
-PathChooserDelegate::PathChooserDelegate(QObject *parent)
- : QStyledItemDelegate(parent), tree_(NULL), path_item_(NULL), path_editor_(NULL), path_le_(NULL)
-{
-}
-
-PathChooserDelegate::~PathChooserDelegate()
-{
-}
-
-QWidget* PathChooserDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &) const
-{
- QTreeWidgetItem *item = tree_->currentItem();
- if (!item) {
- return NULL;
- }
- path_item_ = item;
-
- path_editor_ = new QWidget(parent);
- QHBoxLayout *hbox = new QHBoxLayout(path_editor_);
- path_editor_->setLayout(hbox);
- path_le_ = new QLineEdit(path_editor_);
- QPushButton *pb = new QPushButton(path_editor_);
-
- path_le_->setText(item->text(col_p_pipe_));
- pb->setText(QString(tr("Browse" UTF8_HORIZONTAL_ELLIPSIS)));
-
- hbox->setContentsMargins(0, 0, 0, 0);
- hbox->addWidget(path_le_);
- hbox->addWidget(pb);
- hbox->setSizeConstraint(QLayout::SetMinimumSize);
-
- // Grow the item to match the editor. According to the QAbstractItemDelegate
- // documenation we're supposed to reimplement sizeHint but this seems to work.
- QSize size = option.rect.size();
- size.setHeight(qMax(option.rect.height(), hbox->sizeHint().height()));
- item->setData(col_p_pipe_, Qt::SizeHintRole, size);
-
- path_le_->selectAll();
- path_editor_->setFocusProxy(path_le_);
- path_editor_->setFocusPolicy(path_le_->focusPolicy());
-
- connect(path_le_, SIGNAL(destroyed()), this, SLOT(stopEditor()));
- connect(pb, SIGNAL(pressed()), this, SLOT(browse_button_clicked()));
- return path_editor_;
-}
-
-void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
-{
- QRect rect = option.rect;
-
- // Make sure the editor doesn't get squashed.
- editor->adjustSize();
- rect.setHeight(qMax(option.rect.height(), editor->height()));
- editor->setGeometry(rect);
-}
-
-void PathChooserDelegate::stopEditor()
-{
- path_item_->setData(col_p_pipe_, Qt::SizeHintRole, QVariant());
- path_item_->setText(col_p_pipe_, path_le_->text());
-}
-
-void PathChooserDelegate::browse_button_clicked()
-{
- char *open_dir = NULL;
-
- switch (prefs.gui_fileopen_style) {
-
- case FO_STYLE_LAST_OPENED:
- open_dir = get_last_open_dir();
- break;
-
- case FO_STYLE_SPECIFIED:
- if (prefs.gui_fileopen_dir[0] != '\0')
- open_dir = prefs.gui_fileopen_dir;
- break;
- }
- QString file_name = QFileDialog::getOpenFileName(tree_, tr("Open Pipe"), open_dir);
- if (!file_name.isEmpty()) {
- path_le_->setText(file_name);
- }
-}
-
#endif /* HAVE_LIBPCAP */
/*
diff --git a/ui/qt/manage_interfaces_dialog.h b/ui/qt/manage_interfaces_dialog.h
index 1a812a583a..63b07c77c3 100644
--- a/ui/qt/manage_interfaces_dialog.h
+++ b/ui/qt/manage_interfaces_dialog.h
@@ -39,31 +39,6 @@ class QStandardItemModel;
class QLineEdit;
-class PathChooserDelegate : public QStyledItemDelegate
-{
- Q_OBJECT
-
-private:
- QTreeWidget* tree_;
- mutable QTreeWidgetItem *path_item_;
- mutable QWidget *path_editor_;
- mutable QLineEdit *path_le_;
-
-public:
- PathChooserDelegate(QObject *parent = 0);
- ~PathChooserDelegate();
-
- void setTree(QTreeWidget* tree) { tree_ = tree; }
-
-protected:
- QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
- void updateEditorGeometry (QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;
-
-private slots:
- void stopEditor();
- void browse_button_clicked();
-};
-
namespace Ui {
class ManageInterfacesDialog;
@@ -79,11 +54,11 @@ public:
private:
Ui::ManageInterfacesDialog *ui;
- PathChooserDelegate new_pipe_item_delegate_;
InterfaceTreeCacheModel * sourceModel;
InterfaceSortFilterModel * proxyModel;
- void showPipes();
+ InterfaceSortFilterModel * pipeProxyModel;
+
void showRemoteInterfaces();
signals:
@@ -100,9 +75,8 @@ private slots:
void on_addPipe_clicked();
void on_delPipe_clicked();
- void pipeAccepted();
- void on_pipeList_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void onSelectionChanged(const QItemSelection &sel, const QItemSelection &desel);
#ifdef HAVE_PCAP_REMOTE
void on_addRemote_clicked();
diff --git a/ui/qt/manage_interfaces_dialog.ui b/ui/qt/manage_interfaces_dialog.ui
index 8e09fa477a..417c4c8477 100644
--- a/ui/qt/manage_interfaces_dialog.ui
+++ b/ui/qt/manage_interfaces_dialog.ui
@@ -63,7 +63,7 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QTreeWidget" name="pipeList">
+ <widget class="QTreeView" name="pipeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -91,11 +91,6 @@
<property name="itemsExpandable">
<bool>false</bool>
</property>
- <column>
- <property name="text">
- <string>Named Pipe Path</string>
- </property>
- </column>
</widget>
</item>
<item>
diff --git a/ui/qt/path_chooser_delegate.cpp b/ui/qt/path_chooser_delegate.cpp
new file mode 100644
index 0000000000..0fe2130ffd
--- /dev/null
+++ b/ui/qt/path_chooser_delegate.cpp
@@ -0,0 +1,152 @@
+/* path_chooser_delegate.cpp
+ * Delegate to select a file path for a treeview entry
+ *
+ * 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 "epan/prefs.h"
+#include "ui/last_open_dir.h"
+
+#include "ui/qt/path_chooser_delegate.h"
+
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QFileDialog>
+#include <QWidget>
+#include <QLineEdit>
+
+PathChooserDelegate::PathChooserDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+QWidget* PathChooserDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &) const
+{
+ QWidget * pathEditor = new QWidget(parent);
+ QHBoxLayout *hbox = new QHBoxLayout(pathEditor);
+ pathEditor->setLayout(hbox);
+ QLineEdit * lineEdit = new QLineEdit(pathEditor);
+ QPushButton *btnBrowse = new QPushButton(pathEditor);
+
+ btnBrowse->setText(tr("Browse"));
+
+ hbox->setContentsMargins(0, 0, 0, 0);
+ hbox->addWidget(lineEdit);
+ hbox->addWidget(btnBrowse);
+ hbox->setSizeConstraint(QLayout::SetMinimumSize);
+
+ // Grow the item to match the editor. According to the QAbstractItemDelegate
+ // documenation we're supposed to reimplement sizeHint but this seems to work.
+ QSize size = option.rect.size();
+ size.setHeight(qMax(option.rect.height(), hbox->sizeHint().height()));
+
+ lineEdit->selectAll();
+ pathEditor->setFocusProxy(lineEdit);
+ pathEditor->setFocusPolicy(lineEdit->focusPolicy());
+
+ connect(btnBrowse, SIGNAL(pressed()), this, SLOT(browse_button_clicked()));
+ return pathEditor;
+}
+
+void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
+{
+ QRect rect = option.rect;
+
+ // Make sure the editor doesn't get squashed.
+ editor->adjustSize();
+ rect.setHeight(qMax(option.rect.height(), editor->height()));
+ editor->setGeometry(rect);
+}
+
+void PathChooserDelegate::browse_button_clicked()
+{
+ char *open_dir = NULL;
+
+ switch ( prefs.gui_fileopen_style )
+ {
+
+ case FO_STYLE_LAST_OPENED:
+ open_dir = get_last_open_dir();
+ break;
+
+ case FO_STYLE_SPECIFIED:
+ if ( prefs.gui_fileopen_dir[0] != '\0' )
+ open_dir = prefs.gui_fileopen_dir;
+ break;
+ }
+
+ QString file_name = QFileDialog::getOpenFileName(new QWidget(), tr("Open Pipe"), open_dir);
+ if ( !file_name.isEmpty() )
+ {
+ QWidget * parent = ((QPushButton *)sender())->parentWidget();
+ QLineEdit * lineEdit = parent->findChild<QLineEdit*>();
+ if ( lineEdit )
+ {
+ lineEdit->setText(file_name);
+ emit commitData(parent);
+
+ }
+ }
+}
+
+void PathChooserDelegate::setEditorData(QWidget *editor, const QModelIndex &idx) const
+{
+ if ( idx.isValid() )
+ {
+ QString content = idx.data().toString();
+ QLineEdit * lineEdit = editor->findChild<QLineEdit*>();
+ if ( lineEdit )
+ {
+ lineEdit->setText(content);
+ }
+ }
+ else
+ QStyledItemDelegate::setEditorData(editor, idx);
+}
+
+void PathChooserDelegate::setModelData(QWidget *editor, QAbstractItemModel * model, const QModelIndex &idx) const
+{
+ if ( idx.isValid() )
+ {
+ QLineEdit * lineEdit = editor->findChild<QLineEdit*>();
+ if ( lineEdit )
+ {
+ model->setData(idx, lineEdit->text());
+ }
+ }
+ else
+ {
+ QStyledItemDelegate::setModelData(editor, model, idx);
+ }
+}
+
+/*
+ * 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/path_chooser_delegate.h b/ui/qt/path_chooser_delegate.h
new file mode 100644
index 0000000000..32ecd96eab
--- /dev/null
+++ b/ui/qt/path_chooser_delegate.h
@@ -0,0 +1,58 @@
+/* path_chooser_delegate.h
+ * Delegate to select a file path for a treeview entry
+ *
+ * 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 PATH_CHOOSER_DELEGATE_H_
+#define PATH_CHOOSER_DELEGATE_H_
+
+#include <QStyledItemDelegate>
+
+class PathChooserDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ PathChooserDelegate(QObject *parent = 0);
+
+protected:
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &idx) const;
+ void updateEditorGeometry (QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & idx) const;
+ void setEditorData(QWidget *editor, const QModelIndex &idx) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &idx) const;
+
+private slots:
+ void browse_button_clicked();
+};
+
+#endif /* PATH_CHOOSER_DELEGATE_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:
+ */