aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2015-06-03 16:26:00 -0700
committerGerald Combs <gerald@wireshark.org>2015-06-05 19:19:46 +0000
commitc2b713c0935de91f07faf0674dbb024391531a90 (patch)
tree77242b065cf28f40ec0d3fb59df22b18efabe171 /ui
parent198ef94073326ae7f75ce02784e797e1e0fd0fd0 (diff)
Qt: Add the capture and display filter dialog.
Use a single overloaded dialog, similar to the GTK+ UI. Change-Id: If85db14a7101770f115bef725f5145e0010c518d Reviewed-on: https://code.wireshark.org/review/8776 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'ui')
-rw-r--r--ui/filters.h6
-rw-r--r--ui/gtk/filter_dlg.c2
-rw-r--r--ui/qt/CMakeLists.txt4
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common4
-rw-r--r--ui/qt/Wireshark.pro3
-rw-r--r--ui/qt/capture_filter_edit.cpp78
-rw-r--r--ui/qt/capture_filter_edit.h3
-rw-r--r--ui/qt/capture_filter_syntax_worker.cpp5
-rw-r--r--ui/qt/coloring_rules_dialog.cpp1
-rw-r--r--ui/qt/coloring_rules_dialog.h2
-rw-r--r--ui/qt/coloring_rules_dialog.ui3
-rw-r--r--ui/qt/display_filter_expression_dialog.cpp1
-rw-r--r--ui/qt/filter_dialog.cpp280
-rw-r--r--ui/qt/filter_dialog.h108
-rw-r--r--ui/qt/filter_dialog.ui174
-rw-r--r--ui/qt/main_window.h2
-rw-r--r--ui/qt/main_window.ui6
-rw-r--r--ui/qt/main_window_slots.cpp23
19 files changed, 661 insertions, 46 deletions
diff --git a/ui/filters.h b/ui/filters.h
index 330150f515..b63ddca2ba 100644
--- a/ui/filters.h
+++ b/ui/filters.h
@@ -33,8 +33,8 @@ extern "C" {
typedef enum {
CFILTER_LIST, /* capture filter list - saved */
DFILTER_LIST, /* display filter list - saved */
- CFILTER_EDITED_LIST, /* capture filter list - currently edited */
- DFILTER_EDITED_LIST /* display filter list - currently edited */
+ CFILTER_EDITED_LIST, /* capture filter list - currently edited. GTK+ only. */
+ DFILTER_EDITED_LIST /* display filter list - currently edited. GTK+ only. */
} filter_list_type_t;
/*
@@ -85,7 +85,7 @@ void save_filter_list(filter_list_type_t list_type, char **pref_path_return,
int *errno_return);
/*
- * Clone the filter list so it can be edited.
+ * Clone the filter list so it can be edited. GTK+ only.
*/
void copy_filter_list(filter_list_type_t dest_type, filter_list_type_t src_type);
diff --git a/ui/gtk/filter_dlg.c b/ui/gtk/filter_dlg.c
index a12a7bfd9c..941da3aec6 100644
--- a/ui/gtk/filter_dlg.c
+++ b/ui/gtk/filter_dlg.c
@@ -799,7 +799,7 @@ filter_dlg_save(filter_list_type_t list_type)
char *pf_dir_path;
char *f_path;
int f_save_errno;
- const char *filter_type;
+ const char *filter_type;
switch (list_type) {
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 8ad40bf071..60b93f8f77 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -54,6 +54,8 @@ set(WIRESHARK_QT_HEADERS
export_pdu_dialog.h
file_set_dialog.h
filter_action.h
+ filter_dialog.h
+ filter_dialog.h
filter_expressions_preferences_frame.h
follow_stream_dialog.h
follow_stream_text.h
@@ -166,6 +168,7 @@ set(WIRESHARK_QT_SRC
export_pdu_dialog.cpp
file_set_dialog.cpp
filter_action.cpp
+ filter_dialog.cpp
filter_expressions_preferences_frame.cpp
follow_stream_dialog.cpp
follow_stream_text.cpp
@@ -271,6 +274,7 @@ set(WIRESHARK_QT_UI
export_object_dialog.ui
export_pdu_dialog.ui
file_set_dialog.ui
+ filter_dialog.ui
filter_expressions_preferences_frame.ui
follow_stream_dialog.ui
font_color_preferences_frame.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index b5362ad66c..678b58a4a3 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -152,6 +152,8 @@ 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_dialog.cpp filter_dialog.h: ui_filter_dialog.h
+
filter_expressions_preferences_frame.cpp filter_expressions_preferences_frame.h: ui_filter_expressions_preferences_frame.h
follow_stream_dialog.cpp: ui_follow_stream_dialog.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index fe136da9c7..a93f3ebcea 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -45,6 +45,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_export_pdu_dialog.h \
ui_extcap_options_dialog.h \
ui_file_set_dialog.h \
+ ui_filter_dialog.h \
ui_filter_expressions_preferences_frame.h \
ui_follow_stream_dialog.h \
ui_font_color_preferences_frame.h \
@@ -156,6 +157,7 @@ MOC_HDRS = \
extcap_options_dialog.h \
file_set_dialog.h \
filter_action.h \
+ filter_dialog.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
follow_stream_text.h \
@@ -236,6 +238,7 @@ UI_FILES = \
export_pdu_dialog.ui \
extcap_options_dialog.ui \
file_set_dialog.ui \
+ filter_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
font_color_preferences_frame.ui \
@@ -363,6 +366,7 @@ WIRESHARK_QT_SRC = \
extcap_options_dialog.cpp \
file_set_dialog.cpp \
filter_action.cpp \
+ filter_dialog.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
follow_stream_text.cpp \
diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro
index d781395a31..2dd409fae2 100644
--- a/ui/qt/Wireshark.pro
+++ b/ui/qt/Wireshark.pro
@@ -221,6 +221,7 @@ FORMS += \
export_pdu_dialog.ui \
extcap_options_dialog.ui \
file_set_dialog.ui \
+ filter_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
font_color_preferences_frame.ui \
@@ -578,6 +579,7 @@ HEADERS += \
display_filter_combo.h \
display_filter_edit.h \
file_set_dialog.h \
+ filter_dialog.h \
import_text_dialog.h \
interface_tree.h \
io_graph_dialog.h \
@@ -642,6 +644,7 @@ SOURCES += \
extcap_options_dialog.cpp \
file_set_dialog.cpp \
filter_action.cpp \
+ filter_dialog.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
follow_stream_text.cpp \
diff --git a/ui/qt/capture_filter_edit.cpp b/ui/qt/capture_filter_edit.cpp
index 45707e6f6f..bfd7c8b747 100644
--- a/ui/qt/capture_filter_edit.cpp
+++ b/ui/qt/capture_filter_edit.cpp
@@ -32,6 +32,7 @@
#include <ui/utf8_entities.h>
#include "capture_filter_edit.h"
+#include "capture_filter_syntax_worker.h"
#include "wireshark_application.h"
#include <QComboBox>
@@ -108,6 +109,8 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
SyntaxLineEdit(parent),
plain_(plain),
field_name_only_(false),
+ bookmark_button_(NULL),
+ clear_button_(NULL),
apply_button_(NULL)
{
setAccessibleName(tr("Capture filter entry"));
@@ -131,9 +134,10 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
// XXX - Move bookmark and apply buttons to the toolbar a la Firefox, Chrome & Safari?
// XXX - Use native buttons on OS X?
- bookmark_button_ = new QToolButton(this);
- bookmark_button_->setCursor(Qt::ArrowCursor);
- bookmark_button_->setStyleSheet(QString(
+ if (!plain_) {
+ bookmark_button_ = new QToolButton(this);
+ bookmark_button_->setCursor(Qt::ArrowCursor);
+ bookmark_button_->setStyleSheet(QString(
"QToolButton { /* all types of tool button */"
" border 0 0 0 0;"
#ifdef Q_OS_MAC
@@ -156,15 +160,15 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
"QToolButton:disabled {"
" image: url(:/dfilter/dfilter_bookmark_disabled.png) center;"
"}"
-
-
).arg(plain_ ? 0 : 1)
);
- connect(bookmark_button_, SIGNAL(clicked()), this, SLOT(bookmarkClicked()));
+ connect(bookmark_button_, SIGNAL(clicked()), this, SLOT(bookmarkClicked()));
+ }
- clear_button_ = new QToolButton(this);
- clear_button_->setCursor(Qt::ArrowCursor);
- clear_button_->setStyleSheet(
+ if (!plain_) {
+ clear_button_ = new QToolButton(this);
+ clear_button_->setCursor(Qt::ArrowCursor);
+ clear_button_->setStyleSheet(
"QToolButton {"
" image: url(:/dfilter/dfilter_erase_normal.png) center;"
" border: none;"
@@ -177,8 +181,10 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
" image: url(:/dfilter/dfilter_erase_selected.png) center;"
"}"
);
- clear_button_->hide();
- connect(clear_button_, SIGNAL(clicked()), this, SLOT(clear()));
+ clear_button_->hide();
+ connect(clear_button_, SIGNAL(clicked()), this, SLOT(clear()));
+ }
+
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&)));
if (!plain_) {
@@ -209,14 +215,13 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
}
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- QSize bksz = bookmark_button_->sizeHint();
- QSize cbsz = clear_button_->sizeHint();
+ QSize bksz;
+ if (bookmark_button_) bksz = bookmark_button_->sizeHint();
+ QSize cbsz;
+ if (clear_button_) cbsz = clear_button_->sizeHint();
QSize apsz;
- if (apply_button_) {
- apsz = apply_button_->sizeHint();
- } else {
- apsz.setHeight(0); apsz.setWidth(0);
- }
+ if (apply_button_) apsz = apply_button_->sizeHint();
+
setStyleSheet(QString(
"CaptureFilterEdit {"
" padding-left: %1px;"
@@ -271,23 +276,25 @@ void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
void CaptureFilterEdit::resizeEvent(QResizeEvent *)
{
- QSize cbsz = clear_button_->sizeHint();
+ QSize cbsz;
+ if (clear_button_) cbsz = clear_button_->sizeHint();
QSize apsz;
- if (apply_button_) {
- apsz = apply_button_->sizeHint();
- } else {
- apsz.setHeight(0); apsz.setWidth(0);
- }
+ if (apply_button_) apsz = apply_button_->sizeHint();
+
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- clear_button_->move(contentsRect().right() - frameWidth - cbsz.width() - apsz.width(),
- contentsRect().top());
- clear_button_->setMaximumHeight(contentsRect().height());
+ if (clear_button_) {
+ clear_button_->move(contentsRect().right() - frameWidth - cbsz.width() - apsz.width(),
+ contentsRect().top());
+ clear_button_->setMaximumHeight(contentsRect().height());
+ }
if (apply_button_) {
apply_button_->move(contentsRect().right() - frameWidth - apsz.width(),
contentsRect().top());
apply_button_->setMaximumHeight(contentsRect().height());
}
- bookmark_button_->setMaximumHeight(contentsRect().height());
+ if (bookmark_button_) {
+ bookmark_button_->setMaximumHeight(contentsRect().height());
+ }
}
void CaptureFilterEdit::checkFilter(const QString& text)
@@ -296,16 +303,21 @@ void CaptureFilterEdit::checkFilter(const QString& text)
popFilterSyntaxStatus();
bool empty = text.isEmpty();
- bookmark_button_->setEnabled(false);
+ if (bookmark_button_) {
+ bookmark_button_->setEnabled(false);
+ }
+
if (apply_button_) {
apply_button_->setEnabled(false);
}
+ if (clear_button_) {
+ clear_button_->setVisible(!empty);
+ }
+
if (empty) {
- clear_button_->setVisible(false);
setFilterSyntaxState(text, true, QString());
} else {
- clear_button_->setVisible(true);
syntax_worker_->checkFilter(text);
}
}
@@ -335,7 +347,9 @@ void CaptureFilterEdit::setFilterSyntaxState(QString filter, bool valid, QString
#ifdef HAVE_LIBPCAP
if (syntaxState() != Invalid) {
- bookmark_button_->setEnabled(true);
+ if (bookmark_button_) {
+ bookmark_button_->setEnabled(true);
+ }
if (apply_button_) {
apply_button_->setEnabled(true);
}
diff --git a/ui/qt/capture_filter_edit.h b/ui/qt/capture_filter_edit.h
index a4d61076e4..c6372db408 100644
--- a/ui/qt/capture_filter_edit.h
+++ b/ui/qt/capture_filter_edit.h
@@ -25,7 +25,8 @@
#include <QThread>
#include <QToolButton>
#include "syntax_line_edit.h"
-#include "capture_filter_syntax_worker.h"
+
+class CaptureFilterSyntaxWorker;
class CaptureFilterEdit : public SyntaxLineEdit
{
diff --git a/ui/qt/capture_filter_syntax_worker.cpp b/ui/qt/capture_filter_syntax_worker.cpp
index 8aa7dd05fa..f19d6f0b2a 100644
--- a/ui/qt/capture_filter_syntax_worker.cpp
+++ b/ui/qt/capture_filter_syntax_worker.cpp
@@ -33,7 +33,10 @@
#include <QMutexLocker>
#include <QSet>
-// Must be global
+// We use a global mutex to protect pcap_compile since it calls gethostbyname.
+// This probably isn't needed on Windows (where pcap_comple calls
+// EnterCriticalSection + LeaveCriticalSection) or *BSD or OS X where
+// gethostbyname(3) claims that it's thread safe.
static QMutex pcap_compile_mtx_;
#if 0
diff --git a/ui/qt/coloring_rules_dialog.cpp b/ui/qt/coloring_rules_dialog.cpp
index e9c736d4be..b1b89ff575 100644
--- a/ui/qt/coloring_rules_dialog.cpp
+++ b/ui/qt/coloring_rules_dialog.cpp
@@ -162,7 +162,6 @@ void ColoringRulesDialog::updateWidgets()
ui->bGPushButton->setStyleSheet(color_button_ss.arg(one_em).arg(fg_color).arg(bg_color));
}
-
ui->copyToolButton->setEnabled(num_selected == 1);
ui->deleteToolButton->setEnabled(num_selected > 0);
ui->fGPushButton->setVisible(num_selected == 1);
diff --git a/ui/qt/coloring_rules_dialog.h b/ui/qt/coloring_rules_dialog.h
index 737c31daca..9e25d4d838 100644
--- a/ui/qt/coloring_rules_dialog.h
+++ b/ui/qt/coloring_rules_dialog.h
@@ -28,7 +28,7 @@ class QAbstractButton;
class QTreeWidget;
struct _color_filter;
-struct _GSList; // This is a completely and toltally safe forward declaration, right?
+struct _GSList; // This is a completely and totally safe forward declaration, right?
namespace Ui {
class ColoringRulesDialog;
diff --git a/ui/qt/coloring_rules_dialog.ui b/ui/qt/coloring_rules_dialog.ui
index 8f94b7e7a6..6c613c0ed0 100644
--- a/ui/qt/coloring_rules_dialog.ui
+++ b/ui/qt/coloring_rules_dialog.ui
@@ -19,6 +19,9 @@
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
+ <property name="textElideMode">
+ <enum>Qt::ElideMiddle</enum>
+ </property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
diff --git a/ui/qt/display_filter_expression_dialog.cpp b/ui/qt/display_filter_expression_dialog.cpp
index 45ed9d6a50..c843890f65 100644
--- a/ui/qt/display_filter_expression_dialog.cpp
+++ b/ui/qt/display_filter_expression_dialog.cpp
@@ -68,6 +68,7 @@ DisplayFilterExpressionDialog::DisplayFilterExpressionDialog(QWidget *parent) :
{
ui->setupUi(this);
setWindowTitle(wsApp->windowTitleString(tr("Display Filter Expression")));
+ setWindowIcon(wsApp->normalIcon());
// XXX Use recent settings instead
resize(parent->width() * 2 / 3, parent->height());
diff --git a/ui/qt/filter_dialog.cpp b/ui/qt/filter_dialog.cpp
new file mode 100644
index 0000000000..02d5d49b86
--- /dev/null
+++ b/ui/qt/filter_dialog.cpp
@@ -0,0 +1,280 @@
+/* filter_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 <errno.h>
+
+#include <glib.h>
+
+#include <ui/filters.h>
+
+#include <wsutil/filesystem.h>
+
+#include "filter_dialog.h"
+#include "ui_filter_dialog.h"
+
+#include <QMessageBox>
+#include <QThread>
+
+#include "capture_filter_edit.h"
+//#include "capture_filter_syntax_worker.h"
+#include "display_filter_edit.h"
+#include "wireshark_application.h"
+
+// To do:
+// - Add filter expression button. The right thing to do might be to add an
+// action inside DisplayFilterEdit.
+// - Show syntax state of each filter? A partial implementation is in place
+// for capture filters.
+
+enum {
+ name_col_,
+ filter_col_
+};
+
+FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type) :
+ QDialog(parent),
+ ui(new Ui::FilterDialog),
+ filter_type_(filter_type),
+// syntax_worker_(NULL),
+ filter_tree_delegate_(new FilterTreeDelegate(this, filter_type))
+{
+ ui->setupUi(this);
+ setWindowIcon(wsApp->normalIcon());
+
+ // XXX Use recent settings instead
+ resize(parent->width() * 2 / 3, parent->height() * 2 / 3);
+
+ ui->filterTreeWidget->setDragEnabled(true);
+ ui->filterTreeWidget->viewport()->setAcceptDrops(true);
+ ui->filterTreeWidget->setDropIndicatorShown(true);
+ ui->filterTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
+
+ if (filter_type == CaptureFilter) {
+ setWindowTitle(wsApp->windowTitleString(tr("Capture Filters")));
+
+// QThread *syntax_thread = new QThread;
+// syntax_worker_ = new CaptureFilterSyntaxWorker;
+// syntax_worker_->moveToThread(syntax_thread);
+// connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start()));
+// // connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter()));
+// connect(syntax_worker_, SIGNAL(syntaxResult(QString, bool, QString)),
+// this, SLOT(setFilterSyntaxState(QString, bool, QString)));
+// connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater()));
+// syntax_thread->start();
+ } else {
+ setWindowTitle(wsApp->windowTitleString(tr("Display Filters")));
+ }
+
+ ui->filterTreeWidget->setItemDelegateForColumn(filter_col_, filter_tree_delegate_);
+
+}
+
+FilterDialog::~FilterDialog()
+{
+ delete ui;
+}
+
+void FilterDialog::showEvent(QShowEvent *event)
+{
+ ui->filterTreeWidget->clear();
+
+ GList *filter_list;
+ if (filter_type_ == CaptureFilter) {
+ filter_list = get_filter_list_first(CFILTER_LIST);
+ } else {
+ filter_list = get_filter_list_first(DFILTER_LIST);
+ }
+ for (GList *fl_item = filter_list; fl_item; fl_item = g_list_next(fl_item)) {
+ if (!fl_item->data) continue;
+ filter_def *fl_data = (filter_def *) fl_item->data;
+ if (!fl_data->name || !fl_data->strval) continue;
+
+ addFilter(fl_data->name, fl_data->strval);
+ }
+
+ ui->filterTreeWidget->resizeColumnToContents(name_col_);
+ ui->filterTreeWidget->resizeColumnToContents(filter_col_);
+
+ QDialog::showEvent(event);
+}
+
+void FilterDialog::addFilter(QString name, QString filter, bool start_editing)
+{
+ QTreeWidgetItem *ti = new QTreeWidgetItem(ui->filterTreeWidget);
+ ti->setFlags(ti->flags() | Qt::ItemIsEditable);
+ ti->setFlags(ti->flags() & ~(Qt::ItemIsDropEnabled));
+ ti->setText(name_col_, name);
+ ti->setText(filter_col_, filter);
+
+ if (start_editing) {
+ ui->filterTreeWidget->setCurrentItem(ti);
+ updateWidgets();
+ ui->filterTreeWidget->editItem(ti, filter_col_);
+ }
+}
+
+void FilterDialog::updateWidgets()
+{
+ int num_selected = ui->filterTreeWidget->selectedItems().count();
+
+ ui->copyToolButton->setEnabled(num_selected == 1);
+ ui->deleteToolButton->setEnabled(num_selected > 0);
+}
+
+//void FilterDialog::setFilterSyntaxState(QString filter, bool valid, QString err_msg)
+//{
+
+//}
+
+void FilterDialog::on_filterTreeWidget_itemSelectionChanged()
+{
+ updateWidgets();
+}
+
+void FilterDialog::on_newToolButton_clicked()
+{
+ QString name;
+ QString filter;
+
+ if (filter_type_ == CaptureFilter) {
+ //: This text is automatically filled in when a new filter is created
+ name = tr("New capture filter");
+ filter = "ip host host.example.com";
+ } else {
+ //: This text is automatically filled in when a new filter is created
+ name = tr("New display filter");
+ filter = "ip.addr == host.example.com";
+ }
+
+ addFilter(name, filter, true);
+}
+
+void FilterDialog::on_deleteToolButton_clicked()
+{
+ QList<QTreeWidgetItem*> selected = ui->filterTreeWidget->selectedItems();
+ foreach (QTreeWidgetItem *ti, selected) {
+ delete ti;
+ }
+}
+
+void FilterDialog::on_copyToolButton_clicked()
+{
+ if (!ui->filterTreeWidget->currentItem()) return;
+ QTreeWidgetItem *ti = ui->filterTreeWidget->currentItem();
+
+ addFilter(ti->text(name_col_), ti->text(filter_col_), true);
+}
+
+void FilterDialog::on_buttonBox_accepted()
+{
+ filter_list_type_t fl_type = filter_type_ == CaptureFilter ? CFILTER_LIST : DFILTER_LIST;
+
+ while (GList *fl_item = get_filter_list_first(fl_type)) {
+ remove_from_filter_list(fl_type, fl_item);
+ }
+
+ QTreeWidgetItemIterator it(ui->filterTreeWidget);
+ while (*it) {
+ add_to_filter_list(fl_type, (*it)->text(name_col_).toUtf8().constData(),
+ (*it)->text(filter_col_).toUtf8().constData());
+ ++it;
+ }
+
+ char *pf_dir_path;
+ char *f_path;
+ int f_save_errno;
+
+ /* Create the directory that holds personal configuration files,
+ if necessary. */
+ if (create_persconffile_dir(&pf_dir_path) == -1) {
+ QMessageBox::warning(this, tr("Unable to create profile directory."),
+ tr("Unable to create directory\n\"%1\"\nfor filter files: %2.")
+ .arg(pf_dir_path)
+ .arg(g_strerror(errno)),
+ QMessageBox::Ok);
+ g_free(pf_dir_path);
+ return;
+ }
+
+ save_filter_list(fl_type, &f_path, &f_save_errno);
+ if (f_path != NULL) {
+ /* We had an error saving the filter. */
+ QString warning_title;
+ QString warning_msg;
+ if (fl_type == CFILTER_LIST) {
+ warning_title = tr("Unable to save capture filter settings.");
+ warning_msg = tr("Could not save to your capture filter file\n\"%1\": %2.")
+ .arg(f_path).arg(g_strerror(f_save_errno));
+ } else {
+ warning_title = tr("Unable to save display filter settings.");
+ warning_msg = tr("Could not save to your display filter file\n\"%1\": %2.")
+ .arg(f_path).arg(g_strerror(f_save_errno));
+ }
+ QMessageBox::warning(this, warning_title, warning_msg, QMessageBox::Ok);
+ g_free(f_path);
+ }
+}
+
+void FilterDialog::on_buttonBox_helpRequested()
+{
+ if (filter_type_ == CaptureFilter) {
+ wsApp->helpTopicAction(HELP_CAPTURE_FILTERS_DIALOG);
+ } else {
+ wsApp->helpTopicAction(HELP_DISPLAY_FILTERS_DIALOG);
+ }
+}
+
+//
+// FilterTreeDelegate
+// Delegate for editing capture and display filters.
+//
+
+QWidget *FilterTreeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ if (index.column() != filter_col_) {
+ return QStyledItemDelegate::createEditor(parent, option, index);
+ }
+
+ QWidget *w;
+
+ if (filter_type_ == FilterDialog::CaptureFilter) {
+ w = new CaptureFilterEdit(parent, true);
+ } else {
+ w = new DisplayFilterEdit(parent, true);
+ }
+
+ return w;
+}
+
+/*
+ * 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/filter_dialog.h b/ui/qt/filter_dialog.h
new file mode 100644
index 0000000000..21a7d049d6
--- /dev/null
+++ b/ui/qt/filter_dialog.h
@@ -0,0 +1,108 @@
+/* filter_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.
+ */
+
+#ifndef FILTER_DIALOG_H
+#define FILTER_DIALOG_H
+
+#include <QDialog>
+
+//class CaptureFilterSyntaxWorker;
+class FilterTreeDelegate;
+
+namespace Ui {
+class FilterDialog;
+}
+
+class FilterDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ enum FilterType { CaptureFilter, DisplayFilter };
+ explicit FilterDialog(QWidget *parent = 0, FilterType filter_type = CaptureFilter);
+ ~FilterDialog();
+
+protected:
+ void showEvent(QShowEvent * event);
+
+private:
+ Ui::FilterDialog *ui;
+
+ enum FilterType filter_type_;
+// CaptureFilterSyntaxWorker *syntax_worker_;
+ FilterTreeDelegate *filter_tree_delegate_;
+
+ void addFilter(QString name, QString filter, bool start_editing = false);
+
+
+private slots:
+ void updateWidgets();
+// void setFilterSyntaxState(QString filter, bool valid, QString err_msg);
+
+ void on_filterTreeWidget_itemSelectionChanged();
+ void on_newToolButton_clicked();
+ void on_deleteToolButton_clicked();
+ void on_copyToolButton_clicked();
+ void on_buttonBox_accepted();
+ void on_buttonBox_helpRequested();
+};
+
+
+//
+// FilterTreeDelegate
+// Delegate for editing capture and display filters.
+//
+
+#include <QStyledItemDelegate>
+
+class FilterTreeDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ FilterTreeDelegate(QObject *parent, FilterDialog::FilterType filter_type) :
+ QStyledItemDelegate(parent),
+ filter_type_(filter_type)
+ {}
+ ~FilterTreeDelegate() {}
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private:
+ FilterDialog::FilterType filter_type_;
+
+private slots:
+};
+
+#endif // FILTER_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/filter_dialog.ui b/ui/qt/filter_dialog.ui
new file mode 100644
index 0000000000..a0a2883e0c
--- /dev/null
+++ b/ui/qt/filter_dialog.ui
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FilterDialog</class>
+ <widget class="QDialog" name="FilterDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>584</width>
+ <height>390</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeWidget" name="filterTreeWidget">
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideMiddle</enum>
+ </property>
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Filter</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,1">
+ <item>
+ <widget class="QToolButton" name="newToolButton">
+ <property name="toolTip">
+ <string>Create a new profile using default settings.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/plus-8.png</normaloff>:/stock/plus-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteToolButton">
+ <property name="toolTip">
+ <string>Remove this profile.</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/minus-8.png</normaloff>:/stock/minus-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="copyToolButton">
+ <property name="toolTip">
+ <string>Copy this profile.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../../image/toolbar.qrc">
+ <normaloff>:/stock/copy-8.png</normaloff>:/stock/copy-8.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="ElidedLabel" name="pathLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ElidedLabel</class>
+ <extends>QLabel</extends>
+ <header>elided_label.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="../../image/toolbar.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>FilterDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>FilterDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 33182dbc39..a93394a447 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -360,7 +360,9 @@ private slots:
void on_actionCaptureOptions_triggered();
void on_actionCaptureRefreshInterfaces_triggered();
#endif
+ void on_actionCaptureCaptureFilters_triggered();
+ void on_actionAnalyzeDisplayFilters_triggered();
void matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type);
void on_actionAnalyzeCreateAColumn_triggered();
void on_actionAnalyzeAAFSelected_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 060096e4ae..017722e6fe 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -995,9 +995,6 @@
</property>
</action>
<action name="actionCaptureCaptureFilters">
- <property name="enabled">
- <bool>false</bool>
- </property>
<property name="text">
<string>Capture &amp;Filters...</string>
</property>
@@ -1197,9 +1194,6 @@
</property>
</action>
<action name="actionAnalyzeDisplayFilters">
- <property name="enabled">
- <bool>false</bool>
- </property>
<property name="text">
<string>Display Filters...</string>
</property>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 400ef01fa5..a7a0f5afb0 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -89,6 +89,7 @@
#if HAVE_EXTCAP
#include "extcap_options_dialog.h"
#endif
+#include "filter_dialog.h"
#include "io_graph_dialog.h"
#include "lbm_stream_dialog.h"
#include "lbm_uimflow_dialog.h"
@@ -2232,6 +2233,17 @@ void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::Act
filterAction(field_filter, action, filter_type);
}
+static FilterDialog *display_filter_dlg_ = NULL;
+void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
+{
+ if (!display_filter_dlg_) {
+ display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
+ }
+ display_filter_dlg_->show();
+ display_filter_dlg_->raise();
+ display_filter_dlg_->activateWindow();
+}
+
void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
{
gint colnr = 0;
@@ -2984,6 +2996,17 @@ void MainWindow::on_actionCaptureRestart_triggered()
startCapture();
}
+static FilterDialog *capture_filter_dlg_ = NULL;
+void MainWindow::on_actionCaptureCaptureFilters_triggered()
+{
+ if (!capture_filter_dlg_) {
+ capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
+ }
+ capture_filter_dlg_->show();
+ capture_filter_dlg_->raise();
+ capture_filter_dlg_->activateWindow();
+}
+
void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
{
CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);