forked from osmocom/wireshark
Qt: Update selected interface filter behavior.
Change the selected interface behavior in the main window and the capture interfaces dialog to better handle multiple selections. Attempt to document this at the top of interface_tree.cpp. Move the default capture filter code from CaptureFilterEdit to MainWelcome. Add a "conflicting filter" check to CaptureEdit which updates the placeholder text. Handle conflicting filters in the main welcome screen and the capture interfaces dialog. Propagate interface selections and filter updates in the capture interfaces dialog to the main welcome screen. Consolidate some of the interface handling code in InterfaceTree and CaptureInterfacesDialog. Make sure CaptureInterfacesDialog manages the global capture options by device name instead numeric index. Start deprecating prefs.capture_devices_filter and capture_dev_user_cfilter_find. Change some member function names so that they're hopefully more clear and consistent. Ping-Bug: 11886 Change-Id: I63b06dbae29c2c45ee9252092ad54bdcbacae6e6 Reviewed-on: https://code.wireshark.org/review/14129 Petri-Dish: Gerald Combs <gerald@wireshark.org> Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
parent
10358a2f14
commit
070fc33e85
|
@ -98,6 +98,8 @@ gboolean capture_dev_user_pmode_find(const gchar *if_name, gboolean *pmode);
|
|||
* Find user-specified capture filter that matches interface
|
||||
* name, if any.
|
||||
*
|
||||
* This is deprecated and should not be used in new code.
|
||||
*
|
||||
* @param if_name The name of the interface.
|
||||
*
|
||||
* @return The capture filter (must be g_free'd later) or NULL if not found.
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
explicit CaptureFilterCombo(QWidget *parent = 0, bool plain = false);
|
||||
bool addRecentCapture(const char *filter);
|
||||
void writeRecent(FILE *rf);
|
||||
void setConflict(bool conflict = false) { cf_edit_->setConflict(conflict); }
|
||||
|
||||
signals:
|
||||
void interfacesChanged();
|
||||
|
|
|
@ -126,10 +126,7 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
|||
setCompleter(new QCompleter(completion_model_, this));
|
||||
setCompletionTokenChars(libpcap_primitive_chars_);
|
||||
|
||||
placeholder_text_ = QString(tr("Enter a capture filter %1")).arg(UTF8_HORIZONTAL_ELLIPSIS);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
|
||||
setPlaceholderText(placeholder_text_);
|
||||
#endif
|
||||
setConflict(false);
|
||||
|
||||
if (!plain_) {
|
||||
bookmark_button_ = new StockIconToolButton(this, "x-capture-filter-bookmark");
|
||||
|
@ -215,7 +212,7 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
|||
QThread *syntax_thread = new QThread;
|
||||
syntax_worker_ = new CaptureFilterSyntaxWorker;
|
||||
syntax_worker_->moveToThread(syntax_thread);
|
||||
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initCaptureFilter()));
|
||||
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(updateBookmarkMenu()));
|
||||
connect(wsApp, SIGNAL(captureFilterListChanged()), this, SLOT(updateBookmarkMenu()));
|
||||
connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start()));
|
||||
connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter()));
|
||||
|
@ -294,12 +291,55 @@ void CaptureFilterEdit::resizeEvent(QResizeEvent *)
|
|||
}
|
||||
}
|
||||
|
||||
void CaptureFilterEdit::setConflict(bool conflict)
|
||||
{
|
||||
if (conflict) {
|
||||
//: This is a very long concept that needs to fit into a short space.
|
||||
placeholder_text_ = tr("Multiple filters selected. Override them here or leave this blank to preserve them.");
|
||||
setToolTip(tr("<p>The interfaces you have selected have different capture filters."
|
||||
" Typing a filter here will override them. Doing nothing will"
|
||||
" preserve them.</p>"));
|
||||
} else {
|
||||
placeholder_text_ = QString(tr("Enter a capture filter %1")).arg(UTF8_HORIZONTAL_ELLIPSIS);
|
||||
setToolTip(QString());
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
|
||||
setPlaceholderText(placeholder_text_);
|
||||
#endif
|
||||
}
|
||||
|
||||
// XXX Make this private along with setConflict.
|
||||
QPair<const QString, bool> CaptureFilterEdit::getSelectedFilter()
|
||||
{
|
||||
QString user_filter;
|
||||
bool filter_conflict = false;
|
||||
#ifdef HAVE_LIBPCAP
|
||||
int selected_devices = 0;
|
||||
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
if (device.selected) {
|
||||
selected_devices++;
|
||||
if (selected_devices == 1) {
|
||||
user_filter = device.cfilter;
|
||||
} else {
|
||||
if (user_filter.compare(device.cfilter)) {
|
||||
filter_conflict = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HAVE_LIBPCAP
|
||||
return QPair<const QString, bool>(user_filter, filter_conflict);
|
||||
}
|
||||
|
||||
void CaptureFilterEdit::checkFilter(const QString& filter)
|
||||
{
|
||||
setSyntaxState(Busy);
|
||||
popFilterSyntaxStatus();
|
||||
bool empty = filter.isEmpty();
|
||||
|
||||
setConflict(false);
|
||||
if (bookmark_button_) {
|
||||
bool match = false;
|
||||
|
||||
|
@ -385,15 +425,6 @@ void CaptureFilterEdit::updateBookmarkMenu()
|
|||
checkFilter();
|
||||
}
|
||||
|
||||
void CaptureFilterEdit::initCaptureFilter()
|
||||
{
|
||||
#ifdef HAVE_LIBPCAP
|
||||
setText(global_capture_opts.default_options.cfilter);
|
||||
#endif // HAVE_LIBPCAP
|
||||
|
||||
updateBookmarkMenu();
|
||||
}
|
||||
|
||||
void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString err_msg)
|
||||
{
|
||||
if (filter.compare(text()) == 0) { // The user hasn't changed the filter
|
||||
|
|
|
@ -34,6 +34,11 @@ class CaptureFilterEdit : public SyntaxLineEdit
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit CaptureFilterEdit(QWidget *parent = 0, bool plain = false);
|
||||
void setConflict(bool conflict = false);
|
||||
// No selections: (QString(), false)
|
||||
// Selections, same filter: (filter, false)
|
||||
// Selections, different filters (QString(), true)
|
||||
static QPair<const QString, bool> getSelectedFilter();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *evt);
|
||||
|
@ -50,7 +55,6 @@ public slots:
|
|||
void prepareFilter();
|
||||
|
||||
private slots:
|
||||
void initCaptureFilter();
|
||||
void applyCaptureFilter();
|
||||
void checkFilter(const QString &filter);
|
||||
void setFilterSyntaxState(QString filter, int state, QString err_msg);
|
||||
|
|
|
@ -152,16 +152,19 @@ CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) :
|
|||
ui->filenameLineEdit->setPlaceholderText(tr("Leave blank to use a temporary file"));
|
||||
#endif
|
||||
|
||||
connect(ui->interfaceTree,SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(interfaceClicked(QTreeWidgetItem*,int)));
|
||||
connect(ui->interfaceTree, SIGNAL(itemSelectionChanged()), this, SLOT(interfaceSelected()));
|
||||
// Changes in interface selections or capture filters should be propagated
|
||||
// to the main welcome screen where they will be applied to the global
|
||||
// capture options.
|
||||
connect(this, SIGNAL(interfacesChanged()), ui->captureFilterComboBox, SIGNAL(interfacesChanged()));
|
||||
connect(ui->captureFilterComboBox, SIGNAL(captureFilterSyntaxChanged(bool)), this, SLOT(updateWidgets()));
|
||||
connect(ui->captureFilterComboBox->lineEdit(), SIGNAL(textEdited(QString)),
|
||||
this, SLOT(filterEdited()));
|
||||
connect(ui->captureFilterComboBox, SIGNAL(activated(QString)),
|
||||
this, SLOT(filterEdited()));
|
||||
connect(ui->captureFilterComboBox->lineEdit(), SIGNAL(textEdited(QString)),
|
||||
this, SIGNAL(captureFilterTextEdited(QString)));
|
||||
connect(&interface_item_delegate_, SIGNAL(filterChanged(QString)),
|
||||
ui->captureFilterComboBox->lineEdit(), SLOT(setText(QString)));
|
||||
connect(this, SIGNAL(interfacesChanged()), ui->captureFilterComboBox, SIGNAL(interfacesChanged()));
|
||||
connect(&interface_item_delegate_, SIGNAL(filterChanged(QString)),
|
||||
this, SIGNAL(captureFilterTextEdited(QString)));
|
||||
connect(this, SIGNAL(ifsChanged()), this, SLOT(refreshInterfaceList()));
|
||||
connect(wsApp, SIGNAL(localInterfaceListChanged()), this, SLOT(updateLocalInterfaces()));
|
||||
connect(ui->browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
|
||||
|
@ -169,29 +172,20 @@ CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) :
|
|||
|
||||
void CaptureInterfacesDialog::interfaceSelected()
|
||||
{
|
||||
interface_t *device;
|
||||
InterfaceTree::updateGlobalDeviceSelections(ui->interfaceTree, col_interface_);
|
||||
|
||||
start_bt_->setEnabled((global_capture_opts.num_selected > 0) ? true: false);
|
||||
|
||||
emit interfacesChanged();
|
||||
|
||||
updateSelectedFilter();
|
||||
|
||||
if (ui->interfaceTree->selectedItems().isEmpty()) {
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
device->selected = false;
|
||||
device->locked = true;
|
||||
}
|
||||
global_capture_opts.num_selected = 0;
|
||||
start_bt_->setEnabled(false);
|
||||
emit setSelectedInterfaces();
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
device->locked = false;
|
||||
}
|
||||
}
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::filterEdited()
|
||||
{
|
||||
QList<QTreeWidgetItem*> si = ui->interfaceTree->selectedItems();
|
||||
if (si.isEmpty()) return;
|
||||
|
||||
foreach (QTreeWidgetItem *ti, si) {
|
||||
ti->setText(col_filter_, ui->captureFilterComboBox->lineEdit()->text());
|
||||
|
@ -218,41 +212,6 @@ void CaptureInterfacesDialog::updateWidgets()
|
|||
start_bt_->setEnabled(can_capture);
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::interfaceClicked(QTreeWidgetItem *, int)
|
||||
{
|
||||
guint i;
|
||||
QString filter = ui->captureFilterComboBox->currentText();
|
||||
|
||||
global_capture_opts.num_selected = 0;
|
||||
for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
device->selected = FALSE;
|
||||
}
|
||||
|
||||
foreach (QTreeWidgetItem *ti, ui->interfaceTree->selectedItems())
|
||||
{
|
||||
QString interface_name = ti->text(col_interface_);
|
||||
|
||||
for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
if (interface_name.compare(device->display_name)) {
|
||||
continue;
|
||||
} else {
|
||||
device->selected = TRUE;
|
||||
global_capture_opts.num_selected++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start_bt_->setEnabled((global_capture_opts.num_selected > 0) ? true: false);
|
||||
|
||||
if (filter.compare(QString(""))) {
|
||||
emit interfacesChanged();
|
||||
}
|
||||
emit setSelectedInterfaces();
|
||||
}
|
||||
}
|
||||
|
||||
CaptureInterfacesDialog::~CaptureInterfacesDialog()
|
||||
{
|
||||
delete ui;
|
||||
|
@ -269,8 +228,9 @@ void CaptureInterfacesDialog::on_capturePromModeCheckBox_toggled(bool checked)
|
|||
prefs.capture_prom_mode = checked;
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
int device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device) continue;
|
||||
// QString device_name = ui->interfaceTree->topLevelItem(row)->text(col_interface_);
|
||||
device->pmode = checked;
|
||||
ti->setText(col_pmode_, checked? tr("enabled"):tr("disabled"));
|
||||
|
@ -460,6 +420,8 @@ void CaptureInterfacesDialog::updateInterfaces()
|
|||
ui->cbResolveNetworkNames->setChecked(gbl_resolv_flags.network_name);
|
||||
ui->cbResolveTransportNames->setChecked(gbl_resolv_flags.transport_name);
|
||||
|
||||
// Rebuild the interface list without disturbing the main welcome screen.
|
||||
disconnect(ui->interfaceTree, SIGNAL(itemSelectionChanged()), this, SLOT(interfaceSelected()));
|
||||
ui->interfaceTree->clear();
|
||||
|
||||
GList *list;
|
||||
|
@ -469,6 +431,7 @@ void CaptureInterfacesDialog::updateInterfaces()
|
|||
#endif
|
||||
gint snaplen;
|
||||
gboolean hassnap, pmode;
|
||||
QList<QTreeWidgetItem *> selected_interfaces;
|
||||
|
||||
if (global_capture_opts.all_ifaces->len > 0) {
|
||||
interface_t *device;
|
||||
|
@ -484,7 +447,7 @@ void CaptureInterfacesDialog::updateInterfaces()
|
|||
// Traffic sparklines
|
||||
InterfaceTreeWidgetItem *ti = new InterfaceTreeWidgetItem(ui->interfaceTree);
|
||||
ti->setFlags(ti->flags() | Qt::ItemIsEditable);
|
||||
ti->setData(col_interface_, Qt::UserRole, qVariantFromValue(device_idx));
|
||||
ti->setData(col_interface_, Qt::UserRole, QString(device->name));
|
||||
ti->setData(col_traffic_, Qt::UserRole, qVariantFromValue(&ti->points));
|
||||
|
||||
ti->setText(col_interface_, device->display_name);
|
||||
|
@ -562,34 +525,20 @@ void CaptureInterfacesDialog::updateInterfaces()
|
|||
#ifdef HAVE_EXTCAP
|
||||
}
|
||||
#endif
|
||||
// If the capture filter column has text, assume that the user
|
||||
// has filled it in via selectedIfaceCaptureFilterComboBox.
|
||||
if (ti->text(col_filter_).isEmpty()) {
|
||||
gchar* user_cfilter = capture_dev_user_cfilter_find(device->name);
|
||||
if (user_cfilter) {
|
||||
g_free(device->cfilter);
|
||||
device->cfilter = user_cfilter;
|
||||
}
|
||||
ti->setText(col_filter_, device->cfilter);
|
||||
}
|
||||
ti->setText(col_filter_, device->cfilter);
|
||||
|
||||
if (prefs.capture_device && strstr(prefs.capture_device, device->name) != NULL) {
|
||||
device->selected = TRUE;
|
||||
global_capture_opts.num_selected++;
|
||||
if (device->selected) {
|
||||
selected_interfaces << ti;
|
||||
}
|
||||
ti->setSelected(device->selected);
|
||||
}
|
||||
}
|
||||
|
||||
// col_interface_ = 0,
|
||||
// col_traffic_,
|
||||
// col_link_,
|
||||
// col_pmode_,
|
||||
// col_snaplen_,
|
||||
// col_buffer_,
|
||||
// col_monitor_,
|
||||
// col_filter_,
|
||||
// col_num_columns_
|
||||
foreach (QTreeWidgetItem *ti, selected_interfaces) {
|
||||
ti->setSelected(true);
|
||||
}
|
||||
connect(ui->interfaceTree, SIGNAL(itemSelectionChanged()), this, SLOT(interfaceSelected()));
|
||||
updateSelectedFilter();
|
||||
|
||||
// Manually or automatically size some columns as needed.
|
||||
int one_em = fontMetrics().height();
|
||||
for (int col = 0; col < ui->interfaceTree->topLevelItemCount(); col++) {
|
||||
|
@ -622,6 +571,11 @@ void CaptureInterfacesDialog::updateInterfaces()
|
|||
}
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::showEvent(QShowEvent *)
|
||||
{
|
||||
updateInterfaces();
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::refreshInterfaceList()
|
||||
{
|
||||
updateInterfaces();
|
||||
|
@ -802,12 +756,6 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
interface_t *device;
|
||||
|
||||
// Close the editor if it's open.
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->currentItem();
|
||||
if (ti) {
|
||||
ui->interfaceTree->setCurrentItem(ti, col_interface_);
|
||||
}
|
||||
|
||||
for (int col = col_link_; col <= col_filter_; col++) {
|
||||
if (ui->interfaceTree->isColumnHidden(col)) {
|
||||
continue;
|
||||
|
@ -821,9 +769,9 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
if (device->active_dlt == -1) {
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device || device->active_dlt == -1) {
|
||||
continue;
|
||||
}
|
||||
link_list << QString("%1(%2)").arg(device->name).arg(device->active_dlt);
|
||||
|
@ -839,9 +787,9 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
if (device->buffer == -1) {
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device || device->buffer == -1) {
|
||||
continue;
|
||||
}
|
||||
buffer_size_list << QString("%1(%2)").arg(device->name).arg(device->buffer);
|
||||
|
@ -857,8 +805,9 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device) continue;
|
||||
snaplen_list << QString("%1:%2(%3)")
|
||||
.arg(device->name)
|
||||
.arg(device->has_snaplen)
|
||||
|
@ -874,9 +823,9 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
if (device->pmode == -1) {
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device || device->pmode == -1) {
|
||||
continue;
|
||||
}
|
||||
pmode_list << QString("%1(%2)").arg(device->name).arg(device->pmode);
|
||||
|
@ -892,9 +841,9 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
if (!device->monitor_mode_supported || (device->monitor_mode_supported && !device->monitor_mode_enabled)) {
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device || !device->monitor_mode_supported || (device->monitor_mode_supported && !device->monitor_mode_enabled)) {
|
||||
continue;
|
||||
}
|
||||
monitor_list << device->name;
|
||||
|
@ -904,13 +853,18 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
break;
|
||||
}
|
||||
#endif // HAVE_MONITOR_SETTING
|
||||
|
||||
#if 0
|
||||
// The device cfilter should have been applied at this point.
|
||||
// We shouldn't change it here.
|
||||
case col_filter_:
|
||||
{
|
||||
// XXX Update selected interfaces only?
|
||||
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
|
||||
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
|
||||
guint device_idx = ti->data(col_interface_, Qt::UserRole).toUInt();
|
||||
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
|
||||
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
|
||||
device = getDeviceByName(device_name);
|
||||
if (!device) continue;
|
||||
g_free(device->cfilter);
|
||||
if (ti->text(col_filter_).isEmpty()) {
|
||||
device->cfilter = NULL;
|
||||
|
@ -919,6 +873,7 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!prefs.gui_use_pref_save) {
|
||||
|
@ -927,6 +882,21 @@ bool CaptureInterfacesDialog::saveOptionsToPreferences()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::updateSelectedFilter()
|
||||
{
|
||||
// Should match MainWelcome::interfaceSelected.
|
||||
QPair <const QString, bool> sf_pair = CaptureFilterEdit::getSelectedFilter();
|
||||
const QString user_filter = sf_pair.first;
|
||||
bool conflict = sf_pair.second;
|
||||
|
||||
if (conflict) {
|
||||
ui->captureFilterComboBox->lineEdit()->clear();
|
||||
ui->captureFilterComboBox->setConflict(true);
|
||||
} else {
|
||||
ui->captureFilterComboBox->lineEdit()->setText(user_filter);
|
||||
}
|
||||
}
|
||||
|
||||
void CaptureInterfacesDialog::on_manage_clicked()
|
||||
{
|
||||
if (saveOptionsToPreferences()) {
|
||||
|
@ -951,6 +921,17 @@ void CaptureInterfacesDialog::changeEvent(QEvent* event)
|
|||
QDialog::changeEvent(event);
|
||||
}
|
||||
|
||||
interface_t *CaptureInterfacesDialog::getDeviceByName(const QString device_name)
|
||||
{
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
if (device_name.compare(QString().fromUtf8(device->name)) == 0) {
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// InterfaceTreeItem
|
||||
//
|
||||
|
|
|
@ -79,6 +79,9 @@ public:
|
|||
void SetTab(int index);
|
||||
void updateInterfaces();
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent *);
|
||||
|
||||
private slots:
|
||||
void on_capturePromModeCheckBox_toggled(bool checked);
|
||||
void on_gbStopCaptureAuto_toggled(bool checked);
|
||||
|
@ -94,7 +97,6 @@ private slots:
|
|||
void start_button_clicked();
|
||||
void on_buttonBox_rejected();
|
||||
void on_buttonBox_helpRequested();
|
||||
void interfaceClicked(QTreeWidgetItem *item, int column);
|
||||
void interfaceSelected();
|
||||
void filterEdited();
|
||||
void updateWidgets();
|
||||
|
@ -113,6 +115,7 @@ signals:
|
|||
void interfacesChanged();
|
||||
void ifsChanged();
|
||||
void interfaceListChanged();
|
||||
void captureFilterTextEdited(const QString & text);
|
||||
|
||||
private:
|
||||
Ui::CaptureInterfacesDialog *ui;
|
||||
|
@ -124,7 +127,9 @@ private:
|
|||
QTimer *stat_timer_;
|
||||
InterfaceTreeDelegate interface_item_delegate_;
|
||||
|
||||
interface_t *getDeviceByName(const QString device_name);
|
||||
bool saveOptionsToPreferences();
|
||||
void updateSelectedFilter();
|
||||
};
|
||||
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
|
|
@ -45,7 +45,21 @@
|
|||
#include <QHeaderView>
|
||||
#include <QTimer>
|
||||
|
||||
// To do:
|
||||
// The interface list and capture filter editor in the main window and
|
||||
// the capture interfaces dialog should have the following behavior:
|
||||
//
|
||||
// - The global capture options are the source of truth for selected
|
||||
// interfaces.
|
||||
// - The global capture options are the source of truth for the capture
|
||||
// filter for an interface.
|
||||
// - If multiple interfaces with different filters are selected, the
|
||||
// CaptureFilterEdit should be cleared and show a corresponding
|
||||
// placeholder message. Device cfilters should not be changed.
|
||||
// - Entering a filter in a CaptureFilterEdit should update the device
|
||||
// cfilter for each selected interface. This should happen even when
|
||||
// conflicting filters are selected, as described above.
|
||||
// - Interface selections and cfilter changes in CaptureInterfacesDialog
|
||||
// should be reflected in MainWelcome.
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
const int stat_update_interval_ = 1000; // ms
|
||||
|
@ -81,7 +95,7 @@ InterfaceTree::InterfaceTree(QWidget *parent) :
|
|||
|
||||
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(getInterfaceList()));
|
||||
connect(wsApp, SIGNAL(localInterfaceListChanged()), this, SLOT(interfaceListChanged()));
|
||||
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateSelectedInterfaces()));
|
||||
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(selectedInterfaceChanged()));
|
||||
}
|
||||
|
||||
InterfaceTree::~InterfaceTree() {
|
||||
|
@ -181,6 +195,7 @@ void InterfaceTree::display()
|
|||
QList<QTreeWidgetItem *> phys_ifaces;
|
||||
QList<QTreeWidgetItem *> virt_ifaces;
|
||||
|
||||
global_capture_opts.num_selected = 0;
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
|
||||
|
@ -192,31 +207,6 @@ void InterfaceTree::display()
|
|||
InterfaceTreeWidgetItem *ti = new InterfaceTreeWidgetItem();
|
||||
ti->setText(IFTREE_COL_NAME, QString().fromUtf8(device.display_name));
|
||||
|
||||
// To do:
|
||||
// - Sync with code in CaptureInterfacesDialog.
|
||||
// - Add more information to the tooltip.
|
||||
QString tt_str = "<p>";
|
||||
if (device.no_addresses > 0) {
|
||||
tt_str += QString("%1: %2").arg(device.no_addresses > 1 ? tr("Addresses") : tr("Address")).arg(device.addresses);
|
||||
tt_str.replace('\n', ", ");
|
||||
} else {
|
||||
tt_str = tr("No addresses");
|
||||
}
|
||||
tt_str += "<br/>";
|
||||
QString cfilter = gchar_free_to_qstring(capture_dev_user_cfilter_find(device.name));
|
||||
if (cfilter.isEmpty()) {
|
||||
tt_str += tr("No capture filter");
|
||||
} else {
|
||||
tt_str += QString("%1: %2")
|
||||
.arg(tr("Capture filter"))
|
||||
.arg(cfilter);
|
||||
}
|
||||
tt_str += "</p>";
|
||||
|
||||
for (int col = 0; col < columnCount(); col++) {
|
||||
ti->setToolTip(col, tt_str);
|
||||
}
|
||||
|
||||
ti->setData(IFTREE_COL_NAME, Qt::UserRole, QString(device.name));
|
||||
ti->setData(IFTREE_COL_STATS, Qt::UserRole, qVariantFromValue(&ti->points));
|
||||
#if HAVE_EXTCAP
|
||||
|
@ -251,7 +241,8 @@ void InterfaceTree::display()
|
|||
|
||||
if (!phys_ifaces.isEmpty()) addTopLevelItems(phys_ifaces);
|
||||
if (!virt_ifaces.isEmpty()) addTopLevelItems(virt_ifaces);
|
||||
setSelectedInterfaces();
|
||||
updateSelectedInterfaces();
|
||||
updateToolTips();
|
||||
|
||||
// XXX Add other device information
|
||||
resizeColumnToContents(IFTREE_COL_NAME);
|
||||
|
@ -358,15 +349,19 @@ void InterfaceTree::updateStatistics(void) {
|
|||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
void InterfaceTree::updateSelectedInterfaces()
|
||||
// Update our global device selections based on the given TreeWidget.
|
||||
// This is shared with CaptureInterfacesDialog.
|
||||
// Column name_col UserRole data MUST be set to the interface name.
|
||||
void InterfaceTree::updateGlobalDeviceSelections(QTreeWidget *if_tree, int name_col)
|
||||
{
|
||||
if (!if_tree) return;
|
||||
#ifdef HAVE_LIBPCAP
|
||||
QTreeWidgetItemIterator iter(this);
|
||||
QTreeWidgetItemIterator iter(if_tree);
|
||||
|
||||
global_capture_opts.num_selected = 0;
|
||||
|
||||
while (*iter) {
|
||||
QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
|
||||
QString device_name = (*iter)->data(name_col, Qt::UserRole).value<QString>();
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
|
||||
|
@ -388,18 +383,21 @@ void InterfaceTree::updateSelectedInterfaces()
|
|||
break;
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
++iter;
|
||||
}
|
||||
|
||||
emit interfacesUpdated();
|
||||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
void InterfaceTree::setSelectedInterfaces()
|
||||
// Update selected interfaces based on the global interface list..
|
||||
// Must not change any interface data.
|
||||
// Must not emit itemSelectionChanged.
|
||||
void InterfaceTree::updateSelectedInterfaces()
|
||||
{
|
||||
#ifdef HAVE_LIBPCAP
|
||||
interface_t *device;
|
||||
QTreeWidgetItemIterator iter(this);
|
||||
bool blocking = blockSignals(true);
|
||||
|
||||
while (*iter) {
|
||||
QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
|
||||
|
@ -412,6 +410,50 @@ void InterfaceTree::setSelectedInterfaces()
|
|||
}
|
||||
iter++;
|
||||
}
|
||||
blockSignals(blocking);
|
||||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
// Update the tooltip for each interface based on the global interface list..
|
||||
// Must not change any interface data.
|
||||
void InterfaceTree::updateToolTips()
|
||||
{
|
||||
#ifdef HAVE_LIBPCAP
|
||||
QTreeWidgetItemIterator iter(this);
|
||||
|
||||
while (*iter) {
|
||||
QString device_name = (*iter)->data(IFTREE_COL_NAME, Qt::UserRole).value<QString>();
|
||||
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
|
||||
interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
|
||||
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
|
||||
// To do:
|
||||
// - Sync with code in CaptureInterfacesDialog.
|
||||
// - Add more information to the tooltip.
|
||||
QString tt_str = "<p>";
|
||||
if (device.no_addresses > 0) {
|
||||
tt_str += QString("%1: %2").arg(device.no_addresses > 1 ? tr("Addresses") : tr("Address")).arg(device.addresses);
|
||||
tt_str.replace('\n', ", ");
|
||||
} else {
|
||||
tt_str = tr("No addresses");
|
||||
}
|
||||
tt_str += "<br/>";
|
||||
QString cfilter = device.cfilter;
|
||||
if (cfilter.isEmpty()) {
|
||||
tt_str += tr("No capture filter");
|
||||
} else {
|
||||
tt_str += QString("%1: %2")
|
||||
.arg(tr("Capture filter"))
|
||||
.arg(cfilter);
|
||||
}
|
||||
tt_str += "</p>";
|
||||
|
||||
for (int col = 0; col < columnCount(); col++) {
|
||||
(*iter)->setToolTip(col, tt_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
#endif // HAVE_LIBPCAP
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ public:
|
|||
|
||||
void resetColumnCount();
|
||||
|
||||
// Used by CaptureInterfacesDialog.
|
||||
static void updateGlobalDeviceSelections(QTreeWidget *if_tree, int name_col);
|
||||
|
||||
protected:
|
||||
void hideEvent(QHideEvent *evt);
|
||||
void showEvent(QShowEvent *evt);
|
||||
|
@ -71,7 +74,6 @@ private:
|
|||
#endif // HAVE_LIBPCAP
|
||||
|
||||
signals:
|
||||
void interfacesUpdated();
|
||||
|
||||
public slots:
|
||||
// add_interface_to_list
|
||||
|
@ -79,13 +81,14 @@ public slots:
|
|||
// change_interface_selection_for_all
|
||||
//void getPoints(int row, QList<int> *pts);
|
||||
void getPoints(int row, PointList *pts);
|
||||
void setSelectedInterfaces();
|
||||
void interfaceListChanged();
|
||||
void selectedInterfaceChanged() { updateGlobalDeviceSelections(this, IFTREE_COL_NAME); }
|
||||
void updateSelectedInterfaces();
|
||||
void updateToolTips();
|
||||
|
||||
private slots:
|
||||
void getInterfaceList();
|
||||
void updateStatistics(void);
|
||||
void updateSelectedInterfaces();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -171,8 +171,9 @@ MainWelcome::MainWelcome(QWidget *parent) :
|
|||
connect(welcome_ui_->interfaceTree, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
|
||||
this, SLOT(interfaceClicked(QTreeWidgetItem*,int)));
|
||||
#endif
|
||||
connect(welcome_ui_->interfaceTree, SIGNAL(interfacesUpdated()),
|
||||
connect(welcome_ui_->interfaceTree, SIGNAL(itemSelectionChanged()),
|
||||
welcome_ui_->captureFilterComboBox, SIGNAL(interfacesChanged()));
|
||||
connect(welcome_ui_->interfaceTree, SIGNAL(itemSelectionChanged()), this, SLOT(interfaceSelected()));
|
||||
connect(welcome_ui_->captureFilterComboBox->lineEdit(), SIGNAL(textEdited(QString)),
|
||||
this, SLOT(captureFilterTextEdited(QString)));
|
||||
connect(welcome_ui_->captureFilterComboBox, SIGNAL(pushFilterSyntaxStatus(const QString&)),
|
||||
|
@ -242,6 +243,13 @@ void MainWelcome::appInitialized()
|
|||
welcome_ui_->childContainer->setGraphicsEffect(NULL);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
welcome_ui_->captureFilterComboBox->lineEdit()->setText(global_capture_opts.default_options.cfilter);
|
||||
#endif // HAVE_LIBPCAP
|
||||
|
||||
// Trigger interfacesUpdated.
|
||||
welcome_ui_->interfaceTree->selectedInterfaceChanged();
|
||||
|
||||
delete splash_overlay_;
|
||||
splash_overlay_ = NULL;
|
||||
}
|
||||
|
@ -275,6 +283,26 @@ void MainWelcome::captureFilterTextEdited(const QString capture_filter)
|
|||
// update_filter_string(device.name, filter_text);
|
||||
}
|
||||
}
|
||||
welcome_ui_->interfaceTree->updateToolTips();
|
||||
}
|
||||
|
||||
// The interface list selection has changed. At this point the user might
|
||||
// have entered a filter or we might have pre-filled one from a number of
|
||||
// sources such as our remote connection, the command line, or a previous
|
||||
// selection.
|
||||
// Must not change any interface data.
|
||||
void MainWelcome::interfaceSelected()
|
||||
{
|
||||
QPair <const QString, bool> sf_pair = CaptureFilterEdit::getSelectedFilter();
|
||||
const QString user_filter = sf_pair.first;
|
||||
bool conflict = sf_pair.second;
|
||||
|
||||
if (conflict) {
|
||||
welcome_ui_->captureFilterComboBox->lineEdit()->clear();
|
||||
welcome_ui_->captureFilterComboBox->setConflict(true);
|
||||
} else {
|
||||
welcome_ui_->captureFilterComboBox->lineEdit()->setText(user_filter);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWelcome::interfaceDoubleClicked(QTreeWidgetItem *item, int)
|
||||
|
@ -382,6 +410,12 @@ void MainWelcome::resizeEvent(QResizeEvent *event)
|
|||
QFrame::resizeEvent(event);
|
||||
}
|
||||
|
||||
void MainWelcome::setCaptureFilterText(const QString capture_filter)
|
||||
{
|
||||
welcome_ui_->captureFilterComboBox->lineEdit()->setText(capture_filter);
|
||||
captureFilterTextEdited(capture_filter);
|
||||
}
|
||||
|
||||
void MainWelcome::changeEvent(QEvent* event)
|
||||
{
|
||||
if (0 != event)
|
||||
|
|
|
@ -45,6 +45,9 @@ public:
|
|||
const QString captureFilter();
|
||||
void setCaptureFilter(const QString capture_filter);
|
||||
|
||||
public slots:
|
||||
void interfaceSelected();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
|
||||
|
@ -69,6 +72,9 @@ signals:
|
|||
void showExtcapOptions(QString &device_name);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void setCaptureFilterText(const QString capture_filter);
|
||||
|
||||
private slots:
|
||||
void appInitialized();
|
||||
void captureFilterTextEdited(const QString capture_filter);
|
||||
|
|
|
@ -653,10 +653,19 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
|
||||
this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(setSelectedInterfaces()),
|
||||
this->main_welcome_->getInterfaceTree(), SLOT(setSelectedInterfaces()));
|
||||
// Changes in interface selections or capture filters should be propagated
|
||||
// to the main welcome screen where they will be applied to the global
|
||||
// capture options.
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(interfaceListChanged()),
|
||||
this->main_welcome_->getInterfaceTree(), SLOT(interfaceListChanged()));
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
|
||||
this->main_welcome_, SLOT(interfaceSelected()));
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
|
||||
this->main_welcome_->getInterfaceTree(), SLOT(updateSelectedInterfaces()));
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(interfacesChanged()),
|
||||
this->main_welcome_->getInterfaceTree(), SLOT(updateToolTips()));
|
||||
connect(&capture_interfaces_dialog_, SIGNAL(captureFilterTextEdited(QString)),
|
||||
this->main_welcome_, SLOT(setCaptureFilterText(QString)));
|
||||
#endif
|
||||
|
||||
/* Create plugin_if hooks */
|
||||
|
|
Loading…
Reference in New Issue