Qt: Enable capture filter bookmarks
Update the code handling capture filter bookmarks and enable the bookmark button and clear button in CaptureFilterEdit(). Disable the apply button (which starts a capture) for now. Bug: 11836 Change-Id: Ia33cbb8c9bb839be037112eef26daf744c4ea8f8 Reviewed-on: https://code.wireshark.org/review/13568 Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
This commit is contained in:
parent
268c0e56fb
commit
3c1d05d5a0
|
@ -34,7 +34,7 @@ CaptureFilterCombo::CaptureFilterCombo(QWidget *parent) :
|
||||||
QComboBox(parent),
|
QComboBox(parent),
|
||||||
cf_edit_(NULL)
|
cf_edit_(NULL)
|
||||||
{
|
{
|
||||||
cf_edit_ = new CaptureFilterEdit(this, true);
|
cf_edit_ = new CaptureFilterEdit(this, false);
|
||||||
|
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
// Enabling autocompletion here gives us two simultaneous completions:
|
// Enabling autocompletion here gives us two simultaneous completions:
|
||||||
|
|
|
@ -33,11 +33,14 @@
|
||||||
|
|
||||||
#include "capture_filter_edit.h"
|
#include "capture_filter_edit.h"
|
||||||
#include "capture_filter_syntax_worker.h"
|
#include "capture_filter_syntax_worker.h"
|
||||||
|
#include "filter_dialog.h"
|
||||||
#include "stock_icon_tool_button.h"
|
#include "stock_icon_tool_button.h"
|
||||||
#include "wireshark_application.h"
|
#include "wireshark_application.h"
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
#include <QStyleOptionFrame>
|
#include <QStyleOptionFrame>
|
||||||
|
@ -110,6 +113,9 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
SyntaxLineEdit(parent),
|
SyntaxLineEdit(parent),
|
||||||
plain_(plain),
|
plain_(plain),
|
||||||
field_name_only_(false),
|
field_name_only_(false),
|
||||||
|
enable_save_action_(false),
|
||||||
|
save_action_(NULL),
|
||||||
|
remove_action_(NULL),
|
||||||
bookmark_button_(NULL),
|
bookmark_button_(NULL),
|
||||||
clear_button_(NULL),
|
clear_button_(NULL),
|
||||||
apply_button_(NULL)
|
apply_button_(NULL)
|
||||||
|
@ -125,11 +131,10 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
setPlaceholderText(placeholder_text_);
|
setPlaceholderText(placeholder_text_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These are fully implemented in DisplayFilterEdit but not here.
|
|
||||||
|
|
||||||
if (!plain_) {
|
if (!plain_) {
|
||||||
bookmark_button_ = new StockIconToolButton(this, "x-filter-bookmark");
|
bookmark_button_ = new StockIconToolButton(this, "x-filter-bookmark");
|
||||||
bookmark_button_->setCursor(Qt::ArrowCursor);
|
bookmark_button_->setCursor(Qt::ArrowCursor);
|
||||||
|
bookmark_button_->setMenu(new QMenu());
|
||||||
bookmark_button_->setPopupMode(QToolButton::InstantPopup);
|
bookmark_button_->setPopupMode(QToolButton::InstantPopup);
|
||||||
bookmark_button_->setToolTip(tr("Manage saved bookmarks."));
|
bookmark_button_->setToolTip(tr("Manage saved bookmarks."));
|
||||||
bookmark_button_->setIconSize(QSize(14, 14));
|
bookmark_button_->setIconSize(QSize(14, 14));
|
||||||
|
@ -162,6 +167,8 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
|
|
||||||
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&)));
|
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&)));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Disable the apply button for now
|
||||||
if (!plain_) {
|
if (!plain_) {
|
||||||
apply_button_ = new StockIconToolButton(this, "x-filter-apply");
|
apply_button_ = new StockIconToolButton(this, "x-filter-apply");
|
||||||
apply_button_->setCursor(Qt::ArrowCursor);
|
apply_button_->setCursor(Qt::ArrowCursor);
|
||||||
|
@ -177,6 +184,7 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
);
|
);
|
||||||
connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter()));
|
connect(apply_button_, SIGNAL(clicked()), this, SLOT(applyCaptureFilter()));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter()));
|
connect(this, SIGNAL(returnPressed()), this, SLOT(applyCaptureFilter()));
|
||||||
|
|
||||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||||||
|
@ -203,20 +211,34 @@ CaptureFilterEdit::CaptureFilterEdit(QWidget *parent, bool plain) :
|
||||||
syntax_worker_ = new CaptureFilterSyntaxWorker;
|
syntax_worker_ = new CaptureFilterSyntaxWorker;
|
||||||
syntax_worker_->moveToThread(syntax_thread);
|
syntax_worker_->moveToThread(syntax_thread);
|
||||||
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initCaptureFilter()));
|
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initCaptureFilter()));
|
||||||
|
connect(wsApp, SIGNAL(captureFilterListChanged()), this, SLOT(updateBookmarkMenu()));
|
||||||
connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start()));
|
connect(syntax_thread, SIGNAL(started()), syntax_worker_, SLOT(start()));
|
||||||
connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter()));
|
connect(syntax_thread, SIGNAL(started()), this, SLOT(checkFilter()));
|
||||||
connect(syntax_worker_, SIGNAL(syntaxResult(QString,int,QString)),
|
connect(syntax_worker_, SIGNAL(syntaxResult(QString,int,QString)),
|
||||||
this, SLOT(setFilterSyntaxState(QString,int,QString)));
|
this, SLOT(setFilterSyntaxState(QString,int,QString)));
|
||||||
connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater()));
|
connect(syntax_thread, SIGNAL(finished()), syntax_worker_, SLOT(deleteLater()));
|
||||||
syntax_thread->start();
|
syntax_thread->start();
|
||||||
|
|
||||||
checkFilter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
|
||||||
void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
|
void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
|
||||||
SyntaxLineEdit::paintEvent(evt);
|
SyntaxLineEdit::paintEvent(evt);
|
||||||
|
|
||||||
|
if (bookmark_button_) {
|
||||||
|
// Draw the right border by hand. We could try to do this in the
|
||||||
|
// style sheet but it's a pain.
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QColor divider_color = Qt::gray;
|
||||||
|
#else
|
||||||
|
QColor divider_color = palette().shadow().color();
|
||||||
|
#endif
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setPen(divider_color);
|
||||||
|
QRect cr = contentsRect();
|
||||||
|
QSize bksz = bookmark_button_->size();
|
||||||
|
painter.drawLine(bksz.width(), cr.top(), bksz.width(), cr.bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
||||||
// http://wiki.forum.nokia.com/index.php/Custom_QLineEdit
|
// http://wiki.forum.nokia.com/index.php/Custom_QLineEdit
|
||||||
if (text().isEmpty() && ! this->hasFocus()) {
|
if (text().isEmpty() && ! this->hasFocus()) {
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
|
@ -238,8 +260,8 @@ void CaptureFilterEdit::paintEvent(QPaintEvent *evt) {
|
||||||
}
|
}
|
||||||
// else check filter syntax and set the background accordingly
|
// else check filter syntax and set the background accordingly
|
||||||
// XXX - Should we add little warning/error icons as well?
|
// XXX - Should we add little warning/error icons as well?
|
||||||
}
|
|
||||||
#endif // QT < 4.7
|
#endif // QT < 4.7
|
||||||
|
}
|
||||||
|
|
||||||
void CaptureFilterEdit::resizeEvent(QResizeEvent *)
|
void CaptureFilterEdit::resizeEvent(QResizeEvent *)
|
||||||
{
|
{
|
||||||
|
@ -274,7 +296,35 @@ void CaptureFilterEdit::checkFilter(const QString& filter)
|
||||||
bool empty = filter.isEmpty();
|
bool empty = filter.isEmpty();
|
||||||
|
|
||||||
if (bookmark_button_) {
|
if (bookmark_button_) {
|
||||||
bookmark_button_->setEnabled(false);
|
bool match = false;
|
||||||
|
|
||||||
|
for (GList *cf_item = get_filter_list_first(CFILTER_LIST); cf_item; cf_item = g_list_next(cf_item)) {
|
||||||
|
if (!cf_item->data) continue;
|
||||||
|
filter_def *cf_def = (filter_def *) cf_item->data;
|
||||||
|
if (!cf_def->name || !cf_def->strval) continue;
|
||||||
|
|
||||||
|
if (filter.compare(cf_def->strval) == 0) {
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
bookmark_button_->setStockIcon("x-filter-matching-bookmark");
|
||||||
|
if (remove_action_) {
|
||||||
|
remove_action_->setData(text());
|
||||||
|
remove_action_->setVisible(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bookmark_button_->setStockIcon("x-filter-bookmark");
|
||||||
|
if (remove_action_) {
|
||||||
|
remove_action_->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_save_action_ = (!match && !filter.isEmpty());
|
||||||
|
if (save_action_) {
|
||||||
|
save_action_->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apply_button_) {
|
if (apply_button_) {
|
||||||
|
@ -297,11 +347,46 @@ void CaptureFilterEdit::checkFilter()
|
||||||
checkFilter(text());
|
checkFilter(text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CaptureFilterEdit::updateBookmarkMenu()
|
||||||
|
{
|
||||||
|
if (!bookmark_button_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMenu *bb_menu = bookmark_button_->menu();
|
||||||
|
bb_menu->clear();
|
||||||
|
|
||||||
|
save_action_ = bb_menu->addAction(tr("Save this filter"));
|
||||||
|
connect(save_action_, SIGNAL(triggered(bool)), this, SLOT(saveFilter()));
|
||||||
|
remove_action_ = bb_menu->addAction(tr("Remove this filter"));
|
||||||
|
connect(remove_action_, SIGNAL(triggered(bool)), this, SLOT(removeFilter()));
|
||||||
|
QAction *manage_action = bb_menu->addAction(tr("Manage Capture Filters"));
|
||||||
|
connect(manage_action, SIGNAL(triggered(bool)), this, SLOT(showFilters()));
|
||||||
|
bb_menu->addSeparator();
|
||||||
|
|
||||||
|
for (GList *cf_item = get_filter_list_first(CFILTER_LIST); cf_item; cf_item = g_list_next(cf_item)) {
|
||||||
|
if (!cf_item->data) continue;
|
||||||
|
filter_def *cf_def = (filter_def *) cf_item->data;
|
||||||
|
if (!cf_def->name || !cf_def->strval) continue;
|
||||||
|
|
||||||
|
int one_em = bb_menu->fontMetrics().height();
|
||||||
|
QString prep_text = QString("%1: %2").arg(cf_def->name).arg(cf_def->strval);
|
||||||
|
prep_text = bb_menu->fontMetrics().elidedText(prep_text, Qt::ElideRight, one_em * 40);
|
||||||
|
|
||||||
|
QAction *prep_action = bb_menu->addAction(prep_text);
|
||||||
|
prep_action->setData(cf_def->strval);
|
||||||
|
connect(prep_action, SIGNAL(triggered(bool)), this, SLOT(prepareFilter()));
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFilter();
|
||||||
|
}
|
||||||
|
|
||||||
void CaptureFilterEdit::initCaptureFilter()
|
void CaptureFilterEdit::initCaptureFilter()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBPCAP
|
#ifdef HAVE_LIBPCAP
|
||||||
setText(global_capture_opts.default_options.cfilter);
|
setText(global_capture_opts.default_options.cfilter);
|
||||||
#endif // HAVE_LIBPCAP
|
#endif // HAVE_LIBPCAP
|
||||||
|
|
||||||
|
updateBookmarkMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString err_msg)
|
void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString err_msg)
|
||||||
|
@ -316,8 +401,8 @@ void CaptureFilterEdit::setFilterSyntaxState(QString filter, int state, QString
|
||||||
bool valid = (state != Invalid);
|
bool valid = (state != Invalid);
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (bookmark_button_) {
|
if (save_action_) {
|
||||||
bookmark_button_->setEnabled(true);
|
save_action_->setEnabled(enable_save_action_);
|
||||||
}
|
}
|
||||||
if (apply_button_) {
|
if (apply_button_) {
|
||||||
apply_button_->setEnabled(true);
|
apply_button_->setEnabled(true);
|
||||||
|
@ -381,6 +466,61 @@ void CaptureFilterEdit::applyCaptureFilter()
|
||||||
emit startCapture();
|
emit startCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CaptureFilterEdit::saveFilter()
|
||||||
|
{
|
||||||
|
FilterDialog capture_filter_dlg(window(), FilterDialog::CaptureFilter, text());
|
||||||
|
capture_filter_dlg.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureFilterEdit::removeFilter()
|
||||||
|
{
|
||||||
|
QAction *ra = qobject_cast<QAction*>(sender());
|
||||||
|
if (!ra || ra->data().toString().isEmpty()) return;
|
||||||
|
|
||||||
|
QString remove_filter = ra->data().toString();
|
||||||
|
|
||||||
|
for (GList *cf_item = get_filter_list_first(CFILTER_LIST); cf_item; cf_item = g_list_next(cf_item)) {
|
||||||
|
if (!cf_item->data) continue;
|
||||||
|
filter_def *cf_def = (filter_def *) cf_item->data;
|
||||||
|
if (!cf_def->name || !cf_def->strval) continue;
|
||||||
|
|
||||||
|
if (remove_filter.compare(cf_def->strval) == 0) {
|
||||||
|
remove_from_filter_list(CFILTER_LIST, cf_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *f_path;
|
||||||
|
int f_save_errno;
|
||||||
|
|
||||||
|
save_filter_list(CFILTER_LIST, &f_path, &f_save_errno);
|
||||||
|
if (f_path != NULL) {
|
||||||
|
// We had an error saving the filter.
|
||||||
|
QString warning_title = tr("Unable to save capture filter settings.");
|
||||||
|
QString warning_msg = tr("Could not save to your capture 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBookmarkMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureFilterEdit::showFilters()
|
||||||
|
{
|
||||||
|
FilterDialog capture_filter_dlg(window(), FilterDialog::CaptureFilter);
|
||||||
|
capture_filter_dlg.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureFilterEdit::prepareFilter()
|
||||||
|
{
|
||||||
|
QAction *pa = qobject_cast<QAction*>(sender());
|
||||||
|
if (!pa || pa->data().toString().isEmpty()) return;
|
||||||
|
|
||||||
|
QString filter(pa->data().toString());
|
||||||
|
setText(filter);
|
||||||
|
emit textEdited(filter);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Editor modelines
|
* Editor modelines
|
||||||
*
|
*
|
||||||
|
|
|
@ -36,15 +36,18 @@ public:
|
||||||
explicit CaptureFilterEdit(QWidget *parent = 0, bool plain = false);
|
explicit CaptureFilterEdit(QWidget *parent = 0, bool plain = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
|
||||||
void paintEvent(QPaintEvent *evt);
|
void paintEvent(QPaintEvent *evt);
|
||||||
#endif
|
|
||||||
void resizeEvent(QResizeEvent *);
|
void resizeEvent(QResizeEvent *);
|
||||||
void keyPressEvent(QKeyEvent *event) { completionKeyPressEvent(event); }
|
void keyPressEvent(QKeyEvent *event) { completionKeyPressEvent(event); }
|
||||||
void focusInEvent(QFocusEvent *event) { completionFocusInEvent(event); }
|
void focusInEvent(QFocusEvent *event) { completionFocusInEvent(event); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void checkFilter();
|
void checkFilter();
|
||||||
|
void updateBookmarkMenu();
|
||||||
|
void saveFilter();
|
||||||
|
void removeFilter();
|
||||||
|
void showFilters();
|
||||||
|
void prepareFilter();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void initCaptureFilter();
|
void initCaptureFilter();
|
||||||
|
@ -56,7 +59,10 @@ private slots:
|
||||||
private:
|
private:
|
||||||
bool plain_;
|
bool plain_;
|
||||||
bool field_name_only_;
|
bool field_name_only_;
|
||||||
|
bool enable_save_action_;
|
||||||
QString placeholder_text_;
|
QString placeholder_text_;
|
||||||
|
QAction *save_action_;
|
||||||
|
QAction *remove_action_;
|
||||||
StockIconToolButton *bookmark_button_;
|
StockIconToolButton *bookmark_button_;
|
||||||
StockIconToolButton *clear_button_;
|
StockIconToolButton *clear_button_;
|
||||||
StockIconToolButton *apply_button_;
|
StockIconToolButton *apply_button_;
|
||||||
|
|
|
@ -239,7 +239,9 @@ void FilterDialog::on_buttonBox_accepted()
|
||||||
g_free(f_path);
|
g_free(f_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter_type_ == DisplayFilter) {
|
if (filter_type_ == CaptureFilter) {
|
||||||
|
wsApp->emitAppSignal(WiresharkApplication::CaptureFilterListChanged);
|
||||||
|
} else {
|
||||||
wsApp->emitAppSignal(WiresharkApplication::DisplayFilterListChanged);
|
wsApp->emitAppSignal(WiresharkApplication::DisplayFilterListChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,6 +385,7 @@ void WiresharkApplication::setConfigurationProfile(const gchar *profile_name)
|
||||||
emit recentFilesRead();
|
emit recentFilesRead();
|
||||||
emit filterExpressionsChanged();
|
emit filterExpressionsChanged();
|
||||||
emit checkDisplayFilter();
|
emit checkDisplayFilter();
|
||||||
|
emit captureFilterListChanged();
|
||||||
emit displayFilterListChanged();
|
emit displayFilterListChanged();
|
||||||
|
|
||||||
/* Enable all protocols and disable from the disabled list */
|
/* Enable all protocols and disable from the disabled list */
|
||||||
|
@ -704,6 +705,9 @@ void WiresharkApplication::emitAppSignal(AppSignal signal)
|
||||||
case ColumnsChanged:
|
case ColumnsChanged:
|
||||||
emit columnsChanged();
|
emit columnsChanged();
|
||||||
break;
|
break;
|
||||||
|
case CaptureFilterListChanged:
|
||||||
|
emit captureFilterListChanged();
|
||||||
|
break;
|
||||||
case DisplayFilterListChanged:
|
case DisplayFilterListChanged:
|
||||||
emit displayFilterListChanged();
|
emit displayFilterListChanged();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
|
|
||||||
enum AppSignal {
|
enum AppSignal {
|
||||||
ColumnsChanged,
|
ColumnsChanged,
|
||||||
|
CaptureFilterListChanged,
|
||||||
DisplayFilterListChanged,
|
DisplayFilterListChanged,
|
||||||
FilterExpressionsChanged,
|
FilterExpressionsChanged,
|
||||||
PacketDissectionChanged,
|
PacketDissectionChanged,
|
||||||
|
@ -149,6 +150,7 @@ signals:
|
||||||
void profileNameChanged(const gchar *profile_name);
|
void profileNameChanged(const gchar *profile_name);
|
||||||
|
|
||||||
void columnsChanged(); // XXX This recreates the packet list. We might want to rename it accordingly.
|
void columnsChanged(); // XXX This recreates the packet list. We might want to rename it accordingly.
|
||||||
|
void captureFilterListChanged();
|
||||||
void displayFilterListChanged();
|
void displayFilterListChanged();
|
||||||
void filterExpressionsChanged();
|
void filterExpressionsChanged();
|
||||||
void packetDissectionChanged();
|
void packetDissectionChanged();
|
||||||
|
|
Loading…
Reference in New Issue