forked from osmocom/wireshark
Create a FieldFilterEdit class and apply it to custom column preference field.
DisplayFilterEdit deals with entire filters and some edit boxes just need a single protocol field. This control will do the trick. Bug: 12321 Change-Id: I8e5837ea9a6955ada29b7e516ea022ab1dd46f0d Reviewed-on: https://code.wireshark.org/review/15595 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
374266296d
commit
697996a8b0
|
@ -60,6 +60,7 @@ set(WIRESHARK_QT_HEADERS
|
|||
export_dissection_dialog.h
|
||||
export_object_dialog.h
|
||||
export_pdu_dialog.h
|
||||
field_filter_edit.h
|
||||
file_set_dialog.h
|
||||
filter_action.h
|
||||
filter_dialog.h
|
||||
|
@ -214,6 +215,7 @@ set(WIRESHARK_QT_SRC
|
|||
export_dissection_dialog.cpp
|
||||
export_object_dialog.cpp
|
||||
export_pdu_dialog.cpp
|
||||
field_filter_edit.cpp
|
||||
file_set_dialog.cpp
|
||||
filter_action.cpp
|
||||
filter_dialog.cpp
|
||||
|
|
|
@ -180,6 +180,7 @@ MOC_HDRS = \
|
|||
export_dissection_dialog.h \
|
||||
export_object_dialog.h \
|
||||
export_pdu_dialog.h \
|
||||
field_filter_edit.h \
|
||||
file_set_dialog.h \
|
||||
filter_action.h \
|
||||
filter_dialog.h \
|
||||
|
@ -447,6 +448,7 @@ WIRESHARK_QT_SRC = \
|
|||
export_dissection_dialog.cpp \
|
||||
export_object_dialog.cpp \
|
||||
export_pdu_dialog.cpp \
|
||||
field_filter_edit.cpp \
|
||||
file_set_dialog.cpp \
|
||||
filter_action.cpp \
|
||||
filter_dialog.cpp \
|
||||
|
|
|
@ -636,6 +636,7 @@ HEADERS += \
|
|||
color_utils.h \
|
||||
display_filter_combo.h \
|
||||
display_filter_edit.h \
|
||||
field_filter_edit.h \
|
||||
file_set_dialog.h \
|
||||
filter_dialog.h \
|
||||
geometry_state_dialog.h \
|
||||
|
@ -714,6 +715,7 @@ SOURCES += \
|
|||
extcap_argument_file.cpp \
|
||||
extcap_argument_multiselect.cpp \
|
||||
extcap_options_dialog.cpp \
|
||||
field_filter_edit.cpp \
|
||||
file_set_dialog.cpp \
|
||||
filter_action.cpp \
|
||||
filter_dialog.cpp \
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "column_preferences_frame.h"
|
||||
#include <ui_column_preferences_frame.h>
|
||||
#include "syntax_line_edit.h"
|
||||
#include "field_filter_edit.h"
|
||||
#include "wireshark_application.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
@ -282,12 +283,12 @@ void ColumnPreferencesFrame::on_columnTreeWidget_itemActivated(QTreeWidgetItem *
|
|||
}
|
||||
case custom_fields_col_:
|
||||
{
|
||||
SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
|
||||
FieldFilterEdit *field_filter_edit = new FieldFilterEdit();
|
||||
saved_col_string_ = item->text(custom_fields_col_);
|
||||
connect(syntax_edit, SIGNAL(textChanged(QString)),
|
||||
syntax_edit, SLOT(checkCustomColumn(QString)));
|
||||
connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(customFieldsEditingFinished()));
|
||||
editor = cur_line_edit_ = syntax_edit;
|
||||
connect(field_filter_edit, SIGNAL(textChanged(QString)),
|
||||
field_filter_edit, SLOT(checkCustomColumn(QString)));
|
||||
connect(field_filter_edit, SIGNAL(editingFinished()), this, SLOT(customFieldsEditingFinished()));
|
||||
editor = cur_line_edit_ = field_filter_edit;
|
||||
|
||||
//Save off the current column type in case it needs to be restored
|
||||
if ((item->text(custom_fields_col_) == "") && (item->text(custom_occurrence_col_) == "")) {
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
/* field_filter_edit.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 <glib.h>
|
||||
|
||||
#include <epan/dfilter/dfilter.h>
|
||||
|
||||
#include <filter_files.h>
|
||||
|
||||
#include <wsutil/utf8_entities.h>
|
||||
|
||||
#include "field_filter_edit.h"
|
||||
#include "filter_dialog.h"
|
||||
#include "stock_icon_tool_button.h"
|
||||
#include "syntax_line_edit.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QAbstractItemView>
|
||||
#include <QComboBox>
|
||||
#include <QCompleter>
|
||||
#include <QEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
#include <QStringListModel>
|
||||
|
||||
#include <wsutil/utf8_entities.h>
|
||||
|
||||
// To do:
|
||||
// - Get rid of shortcuts and replace them with "n most recently applied filters"?
|
||||
// - We need simplified (button- and dropdown-free) versions for use in dialogs and field-only checking.
|
||||
// - Add a separator or otherwise distinguish between recent items and fields
|
||||
// in the completion dropdown.
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define DEFAULT_MODIFIER UTF8_PLACE_OF_INTEREST_SIGN
|
||||
#else
|
||||
#define DEFAULT_MODIFIER "Ctrl-"
|
||||
#endif
|
||||
|
||||
// proto.c:fld_abbrev_chars
|
||||
static const QString fld_abbrev_chars_ = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
FieldFilterEdit::FieldFilterEdit(QWidget *parent) :
|
||||
SyntaxLineEdit(parent),
|
||||
save_action_(NULL),
|
||||
remove_action_(NULL)
|
||||
{
|
||||
setAccessibleName(tr("Display filter entry"));
|
||||
|
||||
completion_model_ = new QStringListModel(this);
|
||||
setCompleter(new QCompleter(completion_model_, this));
|
||||
setCompletionTokenChars(fld_abbrev_chars_);
|
||||
|
||||
setDefaultPlaceholderText();
|
||||
|
||||
// DFCombo
|
||||
// Bookmark
|
||||
// DisplayFilterEdit
|
||||
// Clear button
|
||||
// Apply (right arrow)
|
||||
// Combo drop-down
|
||||
|
||||
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(checkFilter(const QString&)));
|
||||
// connect(this, SIGNAL(returnPressed()), this, SLOT(applyDisplayFilter()));
|
||||
}
|
||||
|
||||
void FieldFilterEdit::setDefaultPlaceholderText()
|
||||
{
|
||||
placeholder_text_ = QString(tr("Enter a field %1")).arg(UTF8_HORIZONTAL_ELLIPSIS);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
|
||||
setPlaceholderText(placeholder_text_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FieldFilterEdit::paintEvent(QPaintEvent *evt) {
|
||||
SyntaxLineEdit::paintEvent(evt);
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
||||
// http://wiki.forum.nokia.com/index.php/Custom_QLineEdit
|
||||
if (text().isEmpty() && ! this->hasFocus()) {
|
||||
QPainter p(this);
|
||||
QFont f = font();
|
||||
f.setItalic(true);
|
||||
p.setFont(f);
|
||||
|
||||
QColor color(palette().color(foregroundRole()));
|
||||
color.setAlphaF(0.5);
|
||||
p.setPen(color);
|
||||
|
||||
QStyleOptionFrame opt;
|
||||
initStyleOption(&opt);
|
||||
QRect cr = style()->subElementRect(QStyle::SE_LineEditContents, &opt, this);
|
||||
cr.setLeft(cr.left() + 2);
|
||||
cr.setRight(cr.right() - 2);
|
||||
|
||||
p.drawText(cr, Qt::AlignLeft|Qt::AlignVCenter, placeholder_text_);
|
||||
}
|
||||
// else check filter syntax and set the background accordingly
|
||||
// XXX - Should we add little warning/error icons as well?
|
||||
#endif // QT < 4.7
|
||||
}
|
||||
|
||||
void FieldFilterEdit::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
if (syntaxState() == Valid)
|
||||
emit popFilterSyntaxStatus();
|
||||
SyntaxLineEdit::focusOutEvent(event);
|
||||
}
|
||||
|
||||
bool FieldFilterEdit::checkFilter()
|
||||
{
|
||||
checkFilter(text());
|
||||
|
||||
return syntaxState() != Invalid;
|
||||
}
|
||||
|
||||
void FieldFilterEdit::checkFilter(const QString& filter_text)
|
||||
{
|
||||
popFilterSyntaxStatus();
|
||||
checkDisplayFilter(filter_text);
|
||||
|
||||
switch (syntaxState()) {
|
||||
case Deprecated:
|
||||
{
|
||||
emit pushFilterSyntaxWarning(syntaxErrorMessage());
|
||||
break;
|
||||
}
|
||||
case Invalid:
|
||||
{
|
||||
QString invalidMsg(tr("Invalid filter: "));
|
||||
invalidMsg.append(syntaxErrorMessage());
|
||||
emit pushFilterSyntaxStatus(invalidMsg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// GTK+ behavior:
|
||||
// - Operates on words (proto.c:fld_abbrev_chars).
|
||||
// - Popup appears when you enter or remove text.
|
||||
|
||||
// Our behavior:
|
||||
// - Operates on words (fld_abbrev_chars_).
|
||||
// - Popup appears when you enter or remove text.
|
||||
// - Popup appears when you move the cursor.
|
||||
// - Popup does not appear when text is selected.
|
||||
// - Recent and saved display filters in popup when editing first word.
|
||||
|
||||
// ui/gtk/filter_autocomplete.c:build_autocompletion_list
|
||||
void FieldFilterEdit::buildCompletionList(const QString &field_word)
|
||||
{
|
||||
// Push a hint about the current field.
|
||||
if (syntaxState() == Valid) {
|
||||
emit popFilterSyntaxStatus();
|
||||
|
||||
header_field_info *hfinfo = proto_registrar_get_byname(field_word.toUtf8().constData());
|
||||
if (hfinfo) {
|
||||
QString cursor_field_msg = QString("%1: %2")
|
||||
.arg(hfinfo->name)
|
||||
.arg(ftype_pretty_name(hfinfo->type));
|
||||
emit pushFilterSyntaxStatus(cursor_field_msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (field_word.length() < 1) {
|
||||
completion_model_->setStringList(QStringList());
|
||||
return;
|
||||
}
|
||||
|
||||
void *proto_cookie;
|
||||
QStringList field_list;
|
||||
int field_dots = field_word.count('.'); // Some protocol names (_ws.expert) contain periods.
|
||||
for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie)) {
|
||||
protocol_t *protocol = find_protocol_by_id(proto_id);
|
||||
if (!proto_is_protocol_enabled(protocol)) continue;
|
||||
|
||||
// Don't complete the current word.
|
||||
const QString pfname = proto_get_protocol_filter_name(proto_id);
|
||||
if (field_word.compare(pfname)) field_list << pfname;
|
||||
|
||||
// Add fields only if we're past the protocol name and only for the
|
||||
// current protocol.
|
||||
if (field_dots > pfname.count('.')) {
|
||||
void *field_cookie;
|
||||
const QByteArray fw_ba = field_word.toUtf8(); // or toLatin1 or toStdString?
|
||||
const char *fw_utf8 = fw_ba.constData();
|
||||
gsize fw_len = (gsize) strlen(fw_utf8);
|
||||
for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
|
||||
if (hfinfo->same_name_prev_id != -1) continue; // Ignore duplicate names.
|
||||
|
||||
if (!g_ascii_strncasecmp(fw_utf8, hfinfo->abbrev, fw_len)) {
|
||||
if ((gsize) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
field_list.sort();
|
||||
|
||||
completion_model_->setStringList(field_list);
|
||||
completer()->setCompletionPrefix(field_word);
|
||||
}
|
||||
|
||||
void FieldFilterEdit::clearFilter()
|
||||
{
|
||||
clear();
|
||||
QString new_filter;
|
||||
emit filterPackets(new_filter, true);
|
||||
}
|
||||
|
||||
void FieldFilterEdit::applyDisplayFilter()
|
||||
{
|
||||
if (syntaxState() == Invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString new_filter = text();
|
||||
emit filterPackets(new_filter, true);
|
||||
}
|
||||
|
||||
void FieldFilterEdit::changeEvent(QEvent* event)
|
||||
{
|
||||
if (0 != event)
|
||||
{
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::LanguageChange:
|
||||
setDefaultPlaceholderText();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
SyntaxLineEdit::changeEvent(event);
|
||||
}
|
||||
|
||||
void FieldFilterEdit::showFilters()
|
||||
{
|
||||
FilterDialog display_filter_dlg(window(), FilterDialog::DisplayFilter);
|
||||
display_filter_dlg.exec();
|
||||
}
|
||||
|
||||
void FieldFilterEdit::prepareFilter()
|
||||
{
|
||||
QAction *pa = qobject_cast<QAction*>(sender());
|
||||
if (!pa || pa->data().toString().isEmpty()) return;
|
||||
|
||||
setText(pa->data().toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*/
|
|
@ -0,0 +1,82 @@
|
|||
/* display_filter_edit.h
|
||||
*
|
||||
* 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 FIELDFILTEREDIT_H
|
||||
#define FIELDFILTEREDIT_H
|
||||
|
||||
#include "syntax_line_edit.h"
|
||||
|
||||
class QEvent;
|
||||
class StockIconToolButton;
|
||||
|
||||
class FieldFilterEdit : public SyntaxLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FieldFilterEdit(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *evt);
|
||||
void keyPressEvent(QKeyEvent *event) { completionKeyPressEvent(event); }
|
||||
void focusInEvent(QFocusEvent *event) { completionFocusInEvent(event); }
|
||||
void focusOutEvent(QFocusEvent *event);
|
||||
|
||||
public slots:
|
||||
bool checkFilter();
|
||||
void applyDisplayFilter();
|
||||
|
||||
private slots:
|
||||
void checkFilter(const QString &filter_text);
|
||||
void clearFilter();
|
||||
void changeEvent(QEvent* event);
|
||||
|
||||
void showFilters();
|
||||
void prepareFilter();
|
||||
|
||||
private:
|
||||
QString placeholder_text_;
|
||||
QAction *save_action_;
|
||||
QAction *remove_action_;
|
||||
|
||||
void setDefaultPlaceholderText();
|
||||
void buildCompletionList(const QString& field_word);
|
||||
|
||||
signals:
|
||||
void pushFilterSyntaxStatus(const QString&);
|
||||
void popFilterSyntaxStatus();
|
||||
void pushFilterSyntaxWarning(const QString&);
|
||||
void filterPackets(QString new_filter, bool force);
|
||||
};
|
||||
|
||||
#endif // FIELDFILTEREDIT_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:
|
||||
*/
|
Loading…
Reference in New Issue