2015-06-03 23:26:00 +00:00
|
|
|
/* 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>
|
|
|
|
|
2014-12-20 22:13:05 +00:00
|
|
|
#include <filter_files.h>
|
2015-06-03 23:26:00 +00:00
|
|
|
|
|
|
|
#include <wsutil/filesystem.h>
|
|
|
|
|
|
|
|
#include "filter_dialog.h"
|
2015-06-25 16:17:03 +00:00
|
|
|
#include <ui_filter_dialog.h>
|
2015-06-03 23:26:00 +00:00
|
|
|
|
|
|
|
#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_
|
|
|
|
};
|
|
|
|
|
2015-09-02 21:51:33 +00:00
|
|
|
FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, const QString new_filter) :
|
2016-02-28 18:23:20 +00:00
|
|
|
GeometryStateDialog(parent),
|
2015-06-03 23:26:00 +00:00
|
|
|
ui(new Ui::FilterDialog),
|
|
|
|
filter_type_(filter_type),
|
|
|
|
// syntax_worker_(NULL),
|
2015-09-02 21:51:33 +00:00
|
|
|
filter_tree_delegate_(new FilterTreeDelegate(this, filter_type)),
|
|
|
|
new_filter_(new_filter)
|
2015-06-03 23:26:00 +00:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2016-02-28 18:23:20 +00:00
|
|
|
if (parent) loadGeometry(parent->width() * 2 / 3, parent->height() * 2 / 3);
|
2015-06-03 23:26:00 +00:00
|
|
|
setWindowIcon(wsApp->normalIcon());
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-09-02 21:51:33 +00:00
|
|
|
if (!new_filter_.isEmpty()) {
|
|
|
|
addFilter(tr("New filter"), new_filter_, true);
|
|
|
|
new_filter_.clear();
|
|
|
|
}
|
|
|
|
|
2015-06-03 23:26:00 +00:00
|
|
|
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);
|
|
|
|
}
|
2016-01-27 20:30:52 +00:00
|
|
|
|
2016-01-27 20:33:24 +00:00
|
|
|
if (filter_type_ == CaptureFilter) {
|
|
|
|
wsApp->emitAppSignal(WiresharkApplication::CaptureFilterListChanged);
|
|
|
|
} else {
|
2016-01-27 20:30:52 +00:00
|
|
|
wsApp->emitAppSignal(WiresharkApplication::DisplayFilterListChanged);
|
|
|
|
}
|
2015-06-03 23:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2015-11-16 19:00:32 +00:00
|
|
|
w = new DisplayFilterEdit(parent, DisplayFilterToEnter);
|
2015-06-03 23:26:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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:
|
|
|
|
*/
|