diff options
author | Gerald Combs <gerald@wireshark.org> | 2015-06-03 16:26:00 -0700 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2015-06-05 19:19:46 +0000 |
commit | c2b713c0935de91f07faf0674dbb024391531a90 (patch) | |
tree | 77242b065cf28f40ec0d3fb59df22b18efabe171 | |
parent | 198ef94073326ae7f75ce02784e797e1e0fd0fd0 (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>
-rw-r--r-- | ui/filters.h | 6 | ||||
-rw-r--r-- | ui/gtk/filter_dlg.c | 2 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 4 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 4 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 3 | ||||
-rw-r--r-- | ui/qt/capture_filter_edit.cpp | 78 | ||||
-rw-r--r-- | ui/qt/capture_filter_edit.h | 3 | ||||
-rw-r--r-- | ui/qt/capture_filter_syntax_worker.cpp | 5 | ||||
-rw-r--r-- | ui/qt/coloring_rules_dialog.cpp | 1 | ||||
-rw-r--r-- | ui/qt/coloring_rules_dialog.h | 2 | ||||
-rw-r--r-- | ui/qt/coloring_rules_dialog.ui | 3 | ||||
-rw-r--r-- | ui/qt/display_filter_expression_dialog.cpp | 1 | ||||
-rw-r--r-- | ui/qt/filter_dialog.cpp | 280 | ||||
-rw-r--r-- | ui/qt/filter_dialog.h | 108 | ||||
-rw-r--r-- | ui/qt/filter_dialog.ui | 174 | ||||
-rw-r--r-- | ui/qt/main_window.h | 2 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 6 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 23 |
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 &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_); |