Convert Dissector Tables dialog to use model

Now with searchability!

Change-Id: I6ab4e89d4080d3599d522807d39de80cc46e7360
Reviewed-on: https://code.wireshark.org/review/24898
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Michael Mann 2017-12-19 08:32:23 -05:00
parent c781cc38fd
commit 8521dbbe67
9 changed files with 723 additions and 280 deletions

View File

@ -30,6 +30,7 @@ set(WIRESHARK_WIDGET_HEADERS
widgets/clickable_label.h
widgets/display_filter_combo.h
widgets/display_filter_edit.h
widgets/dissector_tables_view.h
widgets/drag_drop_toolbar.h
widgets/drag_label.h
widgets/editor_color_dialog.h
@ -66,6 +67,7 @@ set(WIRESHARK_MODEL_HEADERS
models/cache_proxy_model.h
models/decode_as_delegate.h
models/decode_as_model.h
models/dissector_tables_model.h
models/enabled_protocols_model.h
models/expert_info_model.h
models/expert_info_proxy_model.h
@ -246,6 +248,7 @@ set(WIRESHARK_WIDGET_SRCS
widgets/clickable_label.cpp
widgets/display_filter_combo.cpp
widgets/display_filter_edit.cpp
widgets/dissector_tables_view.cpp
widgets/drag_drop_toolbar.cpp
widgets/drag_label.cpp
widgets/editor_color_dialog.cpp
@ -280,6 +283,7 @@ set(WIRESHARK_MODEL_SRCS
models/cache_proxy_model.cpp
models/decode_as_delegate.cpp
models/decode_as_model.cpp
models/dissector_tables_model.cpp
models/enabled_protocols_model.cpp
models/expert_info_model.cpp
models/expert_info_proxy_model.cpp

View File

@ -160,6 +160,9 @@ MOC_WIDGET_HDRS = \
widgets/clickable_label.h \
widgets/display_filter_combo.h \
widgets/display_filter_edit.h \
widgets/dissector_tables_view.h \
widgets/drag_drop_toolbar.h \
widgets/drag_label.h \
widgets/editor_color_dialog.h \
widgets/editor_file_dialog.h \
widgets/elided_label.h \
@ -173,8 +176,6 @@ MOC_WIDGET_HDRS = \
widgets/syntax_line_edit.h \
widgets/stock_icon_tool_button.h \
widgets/tabnav_tree_view.h \
widgets/drag_drop_toolbar.h \
widgets/drag_label.h \
widgets/qcustomplot.h
# Files that are utility classes with multi-purpose, but no widgets
@ -195,6 +196,7 @@ MOC_MODELS_HDRS = \
models/cache_proxy_model.h \
models/decode_as_delegate.h \
models/decode_as_model.h \
models/dissector_tables_model.h \
models/enabled_protocols_model.h \
models/expert_info_model.h \
models/expert_info_proxy_model.h \
@ -490,6 +492,9 @@ WIRESHARK_QT_WIDGET_SRC = \
widgets/clickable_label.cpp \
widgets/display_filter_combo.cpp \
widgets/display_filter_edit.cpp \
widgets/dissector_tables_view.cpp \
widgets/drag_drop_toolbar.cpp \
widgets/drag_label.cpp \
widgets/editor_color_dialog.cpp \
widgets/editor_file_dialog.cpp \
widgets/elided_label.cpp \
@ -503,8 +508,6 @@ WIRESHARK_QT_WIDGET_SRC = \
widgets/stock_icon_tool_button.cpp \
widgets/syntax_line_edit.cpp \
widgets/tabnav_tree_view.cpp \
widgets/drag_drop_toolbar.cpp \
widgets/drag_label.cpp \
widgets/qcustomplot.cpp
WIRESHARK_QT_UTILS_SRC = \
@ -522,6 +525,7 @@ WIRESHARK_QT_MODELS_SRCS = \
models/cache_proxy_model.cpp \
models/decode_as_delegate.cpp \
models/decode_as_model.cpp \
models/dissector_tables_model.cpp \
models/enabled_protocols_model.cpp \
models/expert_info_model.cpp \
models/expert_info_proxy_model.cpp \

View File

@ -4,277 +4,60 @@
* 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.
* SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h"
#include "dissector_tables_dialog.h"
#include <ui_dissector_tables_dialog.h>
#include "config.h"
#include <epan/packet.h>
#include <QTreeWidgetItem>
#include <QElapsedTimer>
#include "wireshark_application.h"
enum {
col_table_name_,
col_short_name_
};
enum {
top_level_type_ = 1000,
table_type_,
string_type_,
integer_type_,
custom_type_,
heuristic_type_
};
class DissectorTableTreeWidgetItem : public QTreeWidgetItem
{
public:
DissectorTableTreeWidgetItem(QString table_name, QString short_name) : QTreeWidgetItem (table_type_) {
setText(col_table_name_, table_name);
setText(col_short_name_, short_name);
}
};
class IntegerTableTreeWidgetItem : public QTreeWidgetItem
{
public:
IntegerTableTreeWidgetItem(unsigned port, QString proto_name) :
QTreeWidgetItem (integer_type_),
port_(port)
{
setText(col_table_name_, QString::number(port_));
setText(col_short_name_, proto_name);
}
bool operator< (const QTreeWidgetItem &other) const
{
if (other.type() != integer_type_) return QTreeWidgetItem::operator< (other);
const IntegerTableTreeWidgetItem *other_row = static_cast<const IntegerTableTreeWidgetItem *>(&other);
if (treeWidget()->sortColumn() == col_table_name_) {
return port_ < other_row->port_;
}
return QTreeWidgetItem::operator< (other);
}
private:
unsigned port_;
};
DissectorTablesDialog::DissectorTablesDialog(QWidget *parent) :
GeometryStateDialog(parent),
ui(new Ui::DissectorTablesDialog)
ui(new Ui::DissectorTablesDialog),
dissector_tables_model_(new DissectorTablesModel()),
proxyModel_(new DissectorTablesProxyModel(this))
{
ui->setupUi(this);
if (parent) loadGeometry(parent->width() * 3 / 4, parent->height() * 3 / 4);
setAttribute(Qt::WA_DeleteOnClose, true);
setWindowTitle(wsApp->windowTitleString(tr("Dissector Tables")));
on_tableTreeWidget_itemSelectionChanged();
proxyModel_->setSourceModel(dissector_tables_model_);
ui->tableTree->setModel(proxyModel_);
QTreeWidgetItem *string_ti = new QTreeWidgetItem(ui->tableTreeWidget, top_level_type_);
string_ti->setText(col_table_name_, tr("String Tables"));
string_ti->setFirstColumnSpanned(true);
string_ti->setExpanded(true);
QTreeWidgetItem *integer_ti = new QTreeWidgetItem(ui->tableTreeWidget, top_level_type_);
integer_ti->setText(col_table_name_, tr("Integer Tables"));
integer_ti->setFirstColumnSpanned(true);
integer_ti->setExpanded(true);
QTreeWidgetItem *custom_ti = new QTreeWidgetItem(ui->tableTreeWidget, top_level_type_);
custom_ti->setText(col_table_name_, tr("Custom Tables"));
custom_ti->setFirstColumnSpanned(true);
custom_ti->setExpanded(true);
dissector_all_tables_foreach_table(gatherTableNames, this, NULL);
string_ti->addChildren(string_dissectors_);
integer_ti->addChildren(integer_dissectors_);
integer_ti->addChildren(custom_dissectors_);
QTreeWidgetItem *heuristic_ti = new QTreeWidgetItem(ui->tableTreeWidget, top_level_type_);
heuristic_ti->setText(col_table_name_, tr("Heuristic Tables"));
heuristic_ti->setFirstColumnSpanned(true);
heuristic_ti->setExpanded(true);
dissector_all_heur_tables_foreach_table(gatherHeurTableNames, this, NULL);
heuristic_ti->addChildren(heuristic_dissectors_);
ui->tableTreeWidget->sortByColumn(col_table_name_, Qt::AscendingOrder);
ui->tableTreeWidget->resizeColumnToContents(col_table_name_);
QTimer::singleShot(0, this, SLOT(fillTree()));
}
DissectorTablesDialog::~DissectorTablesDialog()
{
delete ui;
delete proxyModel_;
delete dissector_tables_model_;
}
void DissectorTablesDialog::gatherTableNames(const char *short_name, const char *table_name, gpointer dlg_ptr)
void DissectorTablesDialog::fillTree()
{
DissectorTablesDialog *dt_dlg = qobject_cast<DissectorTablesDialog *>((DissectorTablesDialog *)dlg_ptr);
if (!dt_dlg) return;
dissector_tables_model_->populate();
ftenum_t selector_type = get_dissector_table_selector_type(short_name);
DissectorTableTreeWidgetItem *dt_ti = new DissectorTableTreeWidgetItem(table_name, short_name);
//it's recommended to sort after list is populated
proxyModel_->sort(DissectorTablesModel::colTableName);
switch (selector_type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
dt_dlg->integer_dissectors_ << dt_ti;
break;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
dt_dlg->string_dissectors_ << dt_ti;
break;
case FT_BYTES:
dt_dlg->custom_dissectors_ << dt_ti;
break;
default:
// Assert?
delete dt_ti;
return;
//expand the "type" tables
for (int row = 0; row < proxyModel_->rowCount(); row++) {
ui->tableTree->setExpanded(proxyModel_->index(row, DissectorTablesModel::colTableName), true);
}
QList<QTreeWidgetItem *> proto_decode_list;
dissector_table_foreach(short_name, gatherProtocolDecodes, &proto_decode_list);
dt_ti->addChildren(proto_decode_list);
ui->tableTree->resizeColumnToContents(DissectorTablesModel::colTableName);
}
void DissectorTablesDialog::gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer list_ptr)
void DissectorTablesDialog::on_search_line_edit__textChanged(const QString &search_re)
{
QList<QTreeWidgetItem *> *pdl_ptr = dynamic_cast<QList<QTreeWidgetItem *> *>((QList<QTreeWidgetItem *> *)list_ptr);
if (!pdl_ptr) return;
dtbl_entry_t *dtbl_entry;
dissector_handle_t handle;
dtbl_entry = (dtbl_entry_t*)value;
handle = dtbl_entry_get_handle(dtbl_entry);
const QString proto_name = dissector_handle_get_short_name(handle);
QTreeWidgetItem *ti = NULL;
switch (selector_type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
{
ti = new IntegerTableTreeWidgetItem(GPOINTER_TO_UINT(key), proto_name);
break;
}
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
{
ti = new QTreeWidgetItem(string_type_);
ti->setText(col_table_name_, (const char *)key);
ti->setText(col_short_name_, proto_name);
break;
}
case FT_BYTES:
{
const QString dissector_name = dissector_handle_get_dissector_name(handle);
ti = new QTreeWidgetItem(string_type_);
ti->setText(col_table_name_, dissector_name);
ti->setText(col_short_name_, proto_name);
break;
}
default:
g_assert_not_reached();
}
if (ti) *pdl_ptr << ti;
}
void DissectorTablesDialog::gatherHeurTableNames(const char *table_name, heur_dissector_list *list, gpointer dlg_ptr)
{
DissectorTablesDialog *dt_dlg = qobject_cast<DissectorTablesDialog *>((DissectorTablesDialog *)dlg_ptr);
if (!dt_dlg) return;
QTreeWidgetItem *ti = new QTreeWidgetItem(heuristic_type_);
ti->setText(col_table_name_, table_name);
ti->setFirstColumnSpanned(true);
dt_dlg->heuristic_dissectors_ << ti;
if (list) {
QList<QTreeWidgetItem *> heur_decode_list;
heur_dissector_table_foreach(table_name, gatherHeurProtocolDecodes, &heur_decode_list);
ti->addChildren(heur_decode_list);
}
}
void DissectorTablesDialog::gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr)
{
QList<QTreeWidgetItem *> *hdl_ptr = dynamic_cast<QList<QTreeWidgetItem *> *>((QList<QTreeWidgetItem *> *)list_ptr);
if (!hdl_ptr) return;
if (dtbl_entry->protocol) {
QTreeWidgetItem *ti = new QTreeWidgetItem(heuristic_type_);
ti->setText(col_table_name_, proto_get_protocol_long_name(dtbl_entry->protocol));
ti->setText(col_short_name_, proto_get_protocol_short_name(dtbl_entry->protocol));
*hdl_ptr << ti;
}
}
void DissectorTablesDialog::on_tableTreeWidget_itemSelectionChanged()
{
int type = top_level_type_;
QStringList header_labels;
if (ui->tableTreeWidget->currentItem()) {
type = ui->tableTreeWidget->currentItem()->type();
}
switch (type) {
case table_type_:
header_labels << tr("Table Name") << tr("Selector Name");
break;
case string_type_:
header_labels << tr("String") << tr("Dissector");
break;
case integer_type_:
header_labels << tr("Port") << tr("Dissector");
break;
case custom_type_:
header_labels << tr("String") << tr("Dissector");
break;
case heuristic_type_:
header_labels << tr("Protocol") << tr("Short Name");
break;
case top_level_type_:
header_labels << tr("Table Type") << QString();
break;
}
ui->tableTreeWidget->setHeaderLabels(header_labels);
proxyModel_->setFilter(search_re);
}
/*

View File

@ -4,29 +4,14 @@
* 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.
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef DISSECTOR_TABLES_DIALOG_H
#define DISSECTOR_TABLES_DIALOG_H
#include <glib.h>
#include <epan/ftypes/ftypes.h>
#include "geometry_state_dialog.h"
#include <ui/qt/models/dissector_tables_model.h>
namespace Ui {
class DissectorTablesDialog;
@ -43,19 +28,14 @@ public:
~DissectorTablesDialog();
private slots:
void on_tableTreeWidget_itemSelectionChanged();
void on_search_line_edit__textChanged(const QString &search_re);
void fillTree();
private:
Ui::DissectorTablesDialog *ui;
QList<QTreeWidgetItem *> string_dissectors_;
QList<QTreeWidgetItem *> integer_dissectors_;
QList<QTreeWidgetItem *> custom_dissectors_;
QList<QTreeWidgetItem *> heuristic_dissectors_;
static void gatherTableNames(const char *short_name, const char *table_name, gpointer dlg_ptr);
static void gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer list_ptr);
static void gatherHeurTableNames(const char *table_name, struct heur_dissector_list *list, gpointer dlg_ptr);
static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr);
DissectorTablesModel* dissector_tables_model_;
DissectorTablesProxyModel* proxyModel_;
};
#endif // DISSECTOR_TABLES_DIALOG_H

View File

@ -15,22 +15,26 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeWidget" name="tableTreeWidget">
<widget class="DissectorTablesTreeView" name="tableTree">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Table Name</string>
</property>
</column>
<column>
<property name="text">
<string>Short Name</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="search_line_edit_"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
@ -43,6 +47,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>DissectorTablesTreeView</class>
<extends>QTreeView</extends>
<header>widgets/dissector_tables_view.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

View File

@ -0,0 +1,497 @@
/* dissector_tables_model.cpp
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <ui/qt/models/dissector_tables_model.h>
#include <epan/ftypes/ftypes.h>
#include <epan/packet.h>
#include <ui/qt/utils/variant_pointer.h>
#include "wireshark_application.h"
static const char* CUSTOM_TABLE_NAME = "Custom Tables";
static const char* INTEGER_TABLE_NAME = "Integer Tables";
static const char* STRING_TABLE_NAME = "String Tables";
static const char* HEURISTIC_TABLE_NAME = "Heuristic Tables";
class DissectorTablesItem
{
public:
DissectorTablesItem(QString tableName, QString shortName, DissectorTablesItem* parent);
virtual ~DissectorTablesItem();
QString tableName() const {return tableName_;}
QString shortName() const {return shortName_;}
void appendChild(DissectorTablesItem* child);
DissectorTablesItem* child(int row) const;
int childCount() const;
int row() const;
DissectorTablesItem* parentItem() const {return parent_; }
virtual bool lessThan(DissectorTablesItem &right) const;
protected:
QString tableName_;
QString shortName_;
DissectorTablesItem* parent_;
QList<QVariant> childItems_;
};
class IntegerTablesItem : public DissectorTablesItem
{
public:
IntegerTablesItem(unsigned int value, QString shortName, DissectorTablesItem* parent);
virtual ~IntegerTablesItem();
virtual bool lessThan(DissectorTablesItem &right) const;
protected:
unsigned int value_;
};
DissectorTablesItem::DissectorTablesItem(QString tableName, QString shortName, DissectorTablesItem* parent) :
tableName_(tableName),
shortName_(shortName),
parent_(parent)
{
}
DissectorTablesItem::~DissectorTablesItem()
{
for (int row = 0; row < childItems_.count(); row++)
{
delete VariantPointer<DissectorTablesItem>::asPtr(childItems_.value(row));
}
childItems_.clear();
}
void DissectorTablesItem::appendChild(DissectorTablesItem* child)
{
childItems_.prepend(VariantPointer<DissectorTablesItem>::asQVariant(child));
}
DissectorTablesItem* DissectorTablesItem::child(int row) const
{
return VariantPointer<DissectorTablesItem>::asPtr(childItems_.value(row));
}
int DissectorTablesItem::childCount() const
{
return childItems_.count();
}
int DissectorTablesItem::row() const
{
if (parent_)
return parent_->childItems_.indexOf(VariantPointer<DissectorTablesItem>::asQVariant((DissectorTablesItem*)this));
return 0;
}
bool DissectorTablesItem::lessThan(DissectorTablesItem &right) const
{
if (tableName().compare(right.tableName(), Qt::CaseInsensitive) < 0)
return true;
return false;
}
IntegerTablesItem::IntegerTablesItem(unsigned int value, QString shortName, DissectorTablesItem* parent)
: DissectorTablesItem(QString("%1").arg(value), shortName, parent)
, value_(value)
{
}
IntegerTablesItem::~IntegerTablesItem()
{
}
bool IntegerTablesItem::lessThan(DissectorTablesItem &right) const
{
if (value_ == ((IntegerTablesItem&)right).value_) {
return DissectorTablesItem::lessThan(right);
}
if (value_ < ((IntegerTablesItem&)right).value_) {
return true;
}
return false;
}
DissectorTablesModel::DissectorTablesModel(QObject *parent) :
QAbstractItemModel(parent),
root_(new DissectorTablesItem(QString("ROOT"), QString("ROOT"), NULL))
{
}
DissectorTablesModel::~DissectorTablesModel()
{
delete root_;
}
int DissectorTablesModel::rowCount(const QModelIndex &parent) const
{
DissectorTablesItem *parent_item;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parent_item = root_;
else
parent_item = static_cast<DissectorTablesItem*>(parent.internalPointer());
if (parent_item == NULL)
return 0;
return parent_item->childCount();
}
int DissectorTablesModel::columnCount(const QModelIndex&) const
{
return colLast;
}
QModelIndex DissectorTablesModel::parent(const QModelIndex& index) const
{
if (!index.isValid())
return QModelIndex();
DissectorTablesItem* item = static_cast<DissectorTablesItem*>(index.internalPointer());
if (item != NULL) {
DissectorTablesItem* parent_item = item->parentItem();
if (parent_item != NULL) {
if (parent_item == root_)
return QModelIndex();
return createIndex(parent_item->row(), 0, parent_item);
}
}
return QModelIndex();
}
QModelIndex DissectorTablesModel::index(int row, int column, const QModelIndex& parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
DissectorTablesItem *parent_item, *child_item;
if (!parent.isValid())
parent_item = root_;
else
parent_item = static_cast<DissectorTablesItem*>(parent.internalPointer());
Q_ASSERT(parent_item);
child_item = parent_item->child(row);
if (child_item) {
return createIndex(row, column, child_item);
}
return QModelIndex();
}
QVariant DissectorTablesModel::data(const QModelIndex &index, int role) const
{
if ((!index.isValid()) || (role != Qt::DisplayRole))
return QVariant();
DissectorTablesItem* item = static_cast<DissectorTablesItem*>(index.internalPointer());
if (item == NULL)
return QVariant();
switch ((enum DissectorTablesColumn)index.column())
{
case colTableName:
return item->tableName();
case colShortName:
return item->shortName();
default:
break;
}
return QVariant();
}
static void gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer item_ptr)
{
DissectorTablesItem* pdl_ptr = (DissectorTablesItem*)item_ptr;
if (pdl_ptr == NULL)
return;
dtbl_entry_t *dtbl_entry = (dtbl_entry_t*)value;
dissector_handle_t handle = dtbl_entry_get_handle(dtbl_entry);
const QString proto_name = dissector_handle_get_short_name(handle);
DissectorTablesItem *ti = NULL;
switch (selector_type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
ti = new IntegerTablesItem(GPOINTER_TO_UINT(key), proto_name, pdl_ptr);
pdl_ptr->appendChild(ti);
break;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
ti = new DissectorTablesItem((const char *)key, proto_name, pdl_ptr);
pdl_ptr->appendChild(ti);
break;
case FT_BYTES:
ti = new DissectorTablesItem(dissector_handle_get_dissector_name(handle), proto_name, pdl_ptr);
pdl_ptr->appendChild(ti);
break;
default:
break;
}
}
struct tables_root
{
DissectorTablesItem* custom_table;
DissectorTablesItem* integer_table;
DissectorTablesItem* string_table;
};
static void gatherTableNames(const char *short_name, const char *table_name, gpointer model_ptr)
{
struct tables_root* tables = (struct tables_root*)model_ptr;
if (model_ptr == NULL)
return;
ftenum_t selector_type = get_dissector_table_selector_type(short_name);
DissectorTablesItem *dt_ti = NULL;
switch (selector_type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
dt_ti = new DissectorTablesItem(table_name, short_name, tables->integer_table);
tables->integer_table->appendChild(dt_ti);
break;
case FT_STRING:
case FT_STRINGZ:
case FT_UINT_STRING:
case FT_STRINGZPAD:
dt_ti = new DissectorTablesItem(table_name, short_name, tables->string_table);
tables->string_table->appendChild(dt_ti);
break;
case FT_BYTES:
dt_ti = new DissectorTablesItem(table_name, short_name, tables->custom_table);
tables->custom_table->appendChild(dt_ti);
break;
default:
// Assert?
return;
}
dissector_table_foreach(short_name, gatherProtocolDecodes, dt_ti);
}
static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr)
{
DissectorTablesItem* hdl_ptr = (DissectorTablesItem*)list_ptr;
if (hdl_ptr == NULL)
return;
if (dtbl_entry->protocol) {
DissectorTablesItem *heur = new DissectorTablesItem(proto_get_protocol_long_name(dtbl_entry->protocol), proto_get_protocol_short_name(dtbl_entry->protocol), hdl_ptr);
hdl_ptr->appendChild(heur);
}
}
static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, gpointer heur_tables)
{
DissectorTablesItem* table = (DissectorTablesItem*)heur_tables;
if (table == NULL)
return;
DissectorTablesItem *heur = new DissectorTablesItem(table_name, QString(""), table);
table->appendChild(heur);
if (list) {
heur_dissector_table_foreach(table_name, gatherHeurProtocolDecodes, heur);
}
}
void DissectorTablesModel::populate()
{
emit beginResetModel();
struct tables_root tables;
tables.custom_table = new DissectorTablesItem(tr(CUSTOM_TABLE_NAME), QString(""), root_);
root_->appendChild(tables.custom_table);
tables.integer_table = new DissectorTablesItem(tr(INTEGER_TABLE_NAME), QString(""), root_);
root_->appendChild(tables.integer_table);
tables.string_table = new DissectorTablesItem(tr(STRING_TABLE_NAME), QString(""), root_);
root_->appendChild(tables.string_table);
dissector_all_tables_foreach_table(gatherTableNames, &tables, NULL);
DissectorTablesItem* heuristic_table = new DissectorTablesItem(tr(HEURISTIC_TABLE_NAME), QString(""), root_);
root_->appendChild(heuristic_table);
dissector_all_heur_tables_foreach_table(gatherHeurTableNames, heuristic_table, NULL);
emit endResetModel();
}
DissectorTablesProxyModel::DissectorTablesProxyModel(QObject * parent)
: QSortFilterProxyModel(parent),
tableName_(tr("Table Type")),
shortName_(),
filter_()
{
}
QVariant DissectorTablesProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch ((enum DissectorTablesModel::DissectorTablesColumn)section) {
case DissectorTablesModel::colTableName:
return tableName_;
case DissectorTablesModel::colShortName:
return shortName_;
default:
break;
}
}
return QVariant();
}
bool DissectorTablesProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
//Use DissectorTablesItem directly for better performance
DissectorTablesItem* left_item = static_cast<DissectorTablesItem*>(left.internalPointer());
DissectorTablesItem* right_item = static_cast<DissectorTablesItem*>(right.internalPointer());
if ((left_item != NULL) && (right_item != NULL)) {
return left_item->lessThan(*right_item);
}
return false;
}
bool DissectorTablesProxyModel::filterAcceptItem(DissectorTablesItem& item) const
{
QRegExp regex(filter_, Qt::CaseInsensitive);
if (item.tableName().contains(regex))
return true;
if (item.shortName().contains(regex))
return true;
DissectorTablesItem *child_item;
for (int child_row = 0; child_row < item.childCount(); child_row++)
{
child_item = item.child(child_row);
if ((child_item != NULL) && (filterAcceptItem(*child_item)))
return true;
}
return false;
}
bool DissectorTablesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex nameIdx = sourceModel()->index(sourceRow, DissectorTablesModel::colTableName, sourceParent);
DissectorTablesItem* item = static_cast<DissectorTablesItem*>(nameIdx.internalPointer());
if (item == NULL)
return true;
if (!filter_.isEmpty()) {
if (filterAcceptItem(*item))
return true;
}
return true;
}
void DissectorTablesProxyModel::setFilter(const QString& filter)
{
filter_ = filter;
invalidateFilter();
}
void DissectorTablesProxyModel::adjustHeader(const QModelIndex &currentIndex)
{
tableName_ = tr("Table Type");
shortName_ = QString();
if (currentIndex.isValid() && currentIndex.parent().isValid()) {
QString table;
if (currentIndex.parent().parent().isValid()) {
table = data(index(currentIndex.parent().parent().row(), DissectorTablesModel::colTableName), Qt::DisplayRole).toString();
if ((table.compare(CUSTOM_TABLE_NAME) == 0) ||
(table.compare(STRING_TABLE_NAME) == 0)) {
tableName_ = tr("String");
shortName_ = tr("Dissector");
} else if (table.compare(INTEGER_TABLE_NAME) == 0) {
tableName_ = tr("Integer");
shortName_ = tr("Dissector");
} else if (table.compare(HEURISTIC_TABLE_NAME) == 0) {
tableName_ = tr("Protocol");
shortName_ = tr("Short Name");
}
} else {
table = data(index(currentIndex.parent().row(), DissectorTablesModel::colTableName), Qt::DisplayRole).toString();
if ((table.compare(CUSTOM_TABLE_NAME) == 0) ||
(table.compare(INTEGER_TABLE_NAME) == 0) ||
(table.compare(STRING_TABLE_NAME) == 0)) {
tableName_ = tr("Table Name");
shortName_ = tr("Selector Name");
} else if (table.compare(HEURISTIC_TABLE_NAME) == 0) {
tableName_ = tr("Protocol");
shortName_ = tr("Short Name");
}
}
}
emit headerDataChanged(Qt::Vertical, 0, 1);
}
/*
* 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:
*/

View File

@ -0,0 +1,87 @@
/* dissector_tables_model.h
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef DISSECTOR_TABLES_MODEL_H
#define DISSECTOR_TABLES_MODEL_H
#include <config.h>
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
class DissectorTablesItem;
class DissectorTablesModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit DissectorTablesModel(QObject * parent = Q_NULLPTR);
virtual ~DissectorTablesModel();
enum DissectorTablesColumn {
colTableName = 0,
colShortName,
colLast
};
QModelIndex index(int row, int column,
const QModelIndex & = QModelIndex()) const;
QModelIndex parent(const QModelIndex &) const;
QVariant data(const QModelIndex &index, int role) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
void populate();
private:
DissectorTablesItem* root_;
};
class DissectorTablesProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit DissectorTablesProxyModel(QObject * parent = Q_NULLPTR);
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
void adjustHeader(const QModelIndex &currentIndex);
void setFilter(const QString& filter);
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
bool filterAcceptItem(DissectorTablesItem& item) const;
private:
QString tableName_;
QString shortName_;
QString filter_;
};
#endif // DISSECTOR_TABLES_MODEL_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:
*/

View File

@ -0,0 +1,38 @@
/* dissector_tables_view.cpp
* Tree view of Dissector Table data.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "dissector_tables_view.h"
#include <ui/qt/models/dissector_tables_model.h>
DissectorTablesTreeView::DissectorTablesTreeView(QWidget *parent) : QTreeView(parent)
{
}
void DissectorTablesTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
if (current.isValid())
{
((DissectorTablesProxyModel*)model())->adjustHeader(current);
}
QTreeView::currentChanged(current, previous);
}
/* * 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:
*/

View File

@ -0,0 +1,39 @@
/* dissector_tables_view.h
* Tree view of Dissector Table data.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef DISSECTOR_TABLES_VIEW_H
#define DISSECTOR_TABLES_VIEW_H
#include <config.h>
#include <QTreeView>
class DissectorTablesTreeView : public QTreeView
{
Q_OBJECT
public:
DissectorTablesTreeView(QWidget *parent = 0);
protected slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous);
};
#endif // DISSECTOR_TABLES_VIEW_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:
*/