diff options
-rw-r--r-- | ui/qt/CMakeLists.txt | 5 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/models/supported_protocols_model.cpp | 301 | ||||
-rw-r--r-- | ui/qt/models/supported_protocols_model.h | 119 | ||||
-rw-r--r-- | ui/qt/supported_protocols_dialog.cpp | 122 | ||||
-rw-r--r-- | ui/qt/supported_protocols_dialog.h | 19 | ||||
-rw-r--r-- | ui/qt/supported_protocols_dialog.ui | 22 |
7 files changed, 455 insertions, 135 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 568611ae99..6c5465d4a0 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -80,8 +80,9 @@ set(WIRESHARK_MODEL_HEADERS models/percent_bar_delegate.h models/proto_tree_model.h models/related_packet_delegate.h - models/timeline_delegate.h models/sparkline_delegate.h + models/supported_protocols_model.h + models/timeline_delegate.h models/uat_delegate.h models/uat_model.h models/url_link_delegate.h @@ -293,7 +294,7 @@ set(WIRESHARK_MODEL_SRCS models/proto_tree_model.cpp models/related_packet_delegate.cpp models/sparkline_delegate.cpp - models/sparkline_delegate.cpp + models/supported_protocols_model.cpp models/timeline_delegate.cpp models/uat_delegate.cpp models/uat_model.cpp diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index 4812892bb7..bc9b8dd2f9 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -211,6 +211,7 @@ MOC_MODELS_HDRS = \ models/related_packet_delegate.h \ models/timeline_delegate.h \ models/sparkline_delegate.h \ + models/supported_protocols_model.h \ models/uat_delegate.h \ models/uat_model.h \ models/url_link_delegate.h \ @@ -535,6 +536,7 @@ WIRESHARK_QT_MODELS_SRCS = \ models/proto_tree_model.cpp \ models/related_packet_delegate.cpp \ models/sparkline_delegate.cpp \ + models/supported_protocols_model.cpp \ models/timeline_delegate.cpp \ models/uat_model.cpp \ models/uat_delegate.cpp \ diff --git a/ui/qt/models/supported_protocols_model.cpp b/ui/qt/models/supported_protocols_model.cpp new file mode 100644 index 0000000000..d6480afa74 --- /dev/null +++ b/ui/qt/models/supported_protocols_model.cpp @@ -0,0 +1,301 @@ +/* astringlist_list_model.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <QSortFilterProxyModel> +#include <QStringList> +#include <QPalette> +#include <QApplication> +#include <QBrush> + +#include <ui/qt/models/supported_protocols_model.h> + +SupportedProtocolsItem::SupportedProtocolsItem(protocol_t* proto, const char *name, const char* filter, ftenum_t ftype, const char* descr, SupportedProtocolsItem* parent) + : parent_(parent), + proto_(proto), + name_(name), + filter_(filter), + ftype_(ftype), + descr_(descr) +{ +} + +SupportedProtocolsItem::~SupportedProtocolsItem() +{ + for (int row = 0; row < childItems_.count(); row++) + { + delete childItems_.value(row); + } + + childItems_.clear(); +} + +void SupportedProtocolsItem::appendChild(SupportedProtocolsItem* child) +{ + childItems_.prepend(child); +} + +SupportedProtocolsItem* SupportedProtocolsItem::child(int row) +{ + return childItems_.value(row); +} + +int SupportedProtocolsItem::childCount() const +{ + return childItems_.count(); +} + +int SupportedProtocolsItem::row() const +{ + if (parent_) + return parent_->childItems_.indexOf(const_cast<SupportedProtocolsItem*>(this)); + + return 0; +} + + +SupportedProtocolsModel::SupportedProtocolsModel(QObject *parent) : + QAbstractItemModel(parent), + root_(new SupportedProtocolsItem(NULL, NULL, NULL, FT_NONE, NULL, NULL)), + field_count_(0) +{ +} + +SupportedProtocolsModel::~SupportedProtocolsModel() +{ + delete root_; +} + +int SupportedProtocolsModel::rowCount(const QModelIndex &parent) const +{ + SupportedProtocolsItem *parent_item; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parent_item = root_; + else + parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); + + if (parent_item == NULL) + return 0; + + return parent_item->childCount(); +} + +int SupportedProtocolsModel::columnCount(const QModelIndex&) const +{ + return colLast; +} + +QVariant SupportedProtocolsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + + switch ((enum SupportedProtocolsColumn)section) { + case colName: + return tr("Name"); + case colFilter: + return tr("Filter"); + case colType: + return tr("Type"); + case colDescription: + return tr("Description"); + default: + break; + } + } + return QVariant(); +} + +QModelIndex SupportedProtocolsModel::parent(const QModelIndex& index) const +{ + if (!index.isValid()) + return QModelIndex(); + + SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); + if (item != NULL) { + SupportedProtocolsItem* 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 SupportedProtocolsModel::index(int row, int column, const QModelIndex& parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + SupportedProtocolsItem *parent_item, *child_item; + + if (!parent.isValid()) + parent_item = root_; + else + parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); + + Q_ASSERT(parent_item); + + child_item = parent_item->child(row); + if (child_item) { + return createIndex(row, column, child_item); + } + + return QModelIndex(); +} + +QVariant SupportedProtocolsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || role != Qt::DisplayRole) + return QVariant(); + + SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); + if (item == NULL) + return QVariant(); + + switch ((enum SupportedProtocolsColumn)index.column()) { + case colName: + return item->name(); + case colFilter: + return item->filter(); + case colType: + if (index.parent().isValid()) + return QString(ftype_pretty_name(item->type())); + + return QVariant(); + case colDescription: + return item->description(); + default: + break; + } + + return QVariant(); +} + +void SupportedProtocolsModel::populate() +{ + void *proto_cookie; + void *field_cookie; + + emit beginResetModel(); + + SupportedProtocolsItem *protoItem, *fieldItem; + protocol_t *protocol; + + for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; + proto_id = proto_get_next_protocol(&proto_cookie)) { + + protocol = find_protocol_by_id(proto_id); + protoItem = new SupportedProtocolsItem(protocol, proto_get_protocol_short_name(protocol), proto_get_protocol_filter_name(proto_id), FT_PROTOCOL, proto_get_protocol_long_name(protocol), root_); + root_->appendChild(protoItem); + + for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; + hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) { + if (hfinfo->same_name_prev_id != -1) + continue; + + fieldItem = new SupportedProtocolsItem(protocol, hfinfo->name, hfinfo->abbrev, hfinfo->type, hfinfo->blurb, protoItem); + protoItem->appendChild(fieldItem); + field_count_++; + } + } + + emit endResetModel(); +} + + + +SupportedProtocolsProxyModel::SupportedProtocolsProxyModel(QObject * parent) +: QSortFilterProxyModel(parent), +filter_() +{ +} + +bool SupportedProtocolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + //Use SupportedProtocolsItem directly for better performance + SupportedProtocolsItem* left_item = static_cast<SupportedProtocolsItem*>(left.internalPointer()); + SupportedProtocolsItem* right_item = static_cast<SupportedProtocolsItem*>(right.internalPointer()); + + if ((left_item != NULL) && (right_item != NULL)) { + int compare_ret = left_item->name().compare(right_item->name()); + if (compare_ret < 0) + return true; + } + + return false; +} + +bool SupportedProtocolsProxyModel::filterAcceptItem(SupportedProtocolsItem& item) const +{ + QRegExp regex(filter_, Qt::CaseInsensitive); + + if (item.name().contains(regex)) + return true; + + if (item.filter().contains(regex)) + return true; + + if (item.description().contains(regex)) + return true; + + return false; +} + +bool SupportedProtocolsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex nameIdx = sourceModel()->index(sourceRow, SupportedProtocolsModel::colName, sourceParent); + SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(nameIdx.internalPointer()); + if (item == NULL) + return true; + + if (!filter_.isEmpty()) { + if (filterAcceptItem(*item)) + return true; + + if (!nameIdx.parent().isValid()) + { + SupportedProtocolsItem* child_item; + for (int row = 0; row < item->childCount(); row++) + { + child_item = item->child(row); + if ((child_item != NULL) && (filterAcceptItem(*child_item))) + return true; + } + } + + return false; + } + + return true; +} + +void SupportedProtocolsProxyModel::setFilter(const QString& filter) +{ + filter_ = filter; + invalidateFilter(); +} + + +/* + * 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/models/supported_protocols_model.h b/ui/qt/models/supported_protocols_model.h new file mode 100644 index 0000000000..dce988aca8 --- /dev/null +++ b/ui/qt/models/supported_protocols_model.h @@ -0,0 +1,119 @@ +/* supported_protocols_model.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef SUPPORTED_PROTOCOLS_MODEL_H +#define SUPPORTED_PROTOCOLS_MODEL_H + +#include <config.h> + +#include <epan/proto.h> + +#include <QAbstractItemModel> +#include <QSortFilterProxyModel> + +class SupportedProtocolsItem +{ +public: + SupportedProtocolsItem(protocol_t* proto, const char *name, const char* filter, ftenum_t ftype, const char* descr, SupportedProtocolsItem* parent); + virtual ~SupportedProtocolsItem(); + + protocol_t* protocol() const {return proto_; } + QString name() const { return name_; } + ftenum_t type() const {return ftype_; } + QString filter() const { return filter_; } + QString description() const { return descr_; } + + void appendChild(SupportedProtocolsItem* child); + SupportedProtocolsItem* child(int row); + int childCount() const; + int row() const; + SupportedProtocolsItem* parentItem() {return parent_; } + +private: + SupportedProtocolsItem* parent_; + QList<SupportedProtocolsItem*> childItems_; + + protocol_t* proto_; + QString name_; + QString filter_; + ftenum_t ftype_; + QString descr_; +}; + + +class SupportedProtocolsModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit SupportedProtocolsModel(QObject * parent = Q_NULLPTR); + virtual ~SupportedProtocolsModel(); + + enum SupportedProtocolsColumn { + colName = 0, + colFilter, + colType, + colDescription, + colLast + }; + + int fieldCount() {return field_count_;} + + QModelIndex index(int row, int column, + const QModelIndex & = QModelIndex()) const; + QModelIndex parent(const QModelIndex &) const; + QVariant data(const QModelIndex &index, int role) const; + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + void populate(); + +private: + SupportedProtocolsItem* root_; + int field_count_; +}; + +class SupportedProtocolsProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + + explicit SupportedProtocolsProxyModel(QObject * parent = Q_NULLPTR); + + virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + + void setFilter(const QString& filter); + +protected: + bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; + bool filterAcceptItem(SupportedProtocolsItem& item) const; + +private: + + QString filter_; +}; + +#endif // SUPPORTED_PROTOCOLS_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: + */ diff --git a/ui/qt/supported_protocols_dialog.cpp b/ui/qt/supported_protocols_dialog.cpp index a49a89c7b1..726f713c16 100644 --- a/ui/qt/supported_protocols_dialog.cpp +++ b/ui/qt/supported_protocols_dialog.cpp @@ -4,64 +4,44 @@ * 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+ */ -// warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4267) -#endif +#include "config.h" #include "supported_protocols_dialog.h" #include <ui_supported_protocols_dialog.h> -#include "config.h" - -#include <algorithm> -#include <glib.h> - -#include <epan/proto.h> - -#include <QTreeWidgetItem> #include <QElapsedTimer> #include "wireshark_application.h" -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -enum { name_col_, filter_col_, type_col_, descr_col_ }; - SupportedProtocolsDialog::SupportedProtocolsDialog(QWidget *parent) : GeometryStateDialog(parent), ui(new Ui::SupportedProtocolsDialog), - field_count_(0) + supported_protocols_model_(new SupportedProtocolsModel()), + proxyModel_(new SupportedProtocolsProxyModel(this)) { ui->setupUi(this); - if (parent) loadGeometry(parent->width() * 3 / 4, parent->height()); + + proxyModel_->setSourceModel(supported_protocols_model_); + ui->supportedProtocolsTreeView->setModel(proxyModel_); + + //always sort by protocol/field name + proxyModel_->sort(SupportedProtocolsModel::colName); + + if (parent) + loadGeometry(parent->width() * 3 / 4, parent->height()); setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(wsApp->windowTitleString(tr("Supported Protocols"))); // Some of our names are unreasonably long. int one_em = fontMetrics().height(); - ui->protoTreeWidget->setColumnWidth(name_col_, one_em * 15); - ui->protoTreeWidget->setColumnWidth(filter_col_, one_em * 10); - ui->protoTreeWidget->setColumnWidth(type_col_, one_em * 12); - ui->protoTreeWidget->setColumnWidth(descr_col_, one_em * 30); + ui->supportedProtocolsTreeView->setColumnWidth(SupportedProtocolsModel::colName, one_em * 15); + ui->supportedProtocolsTreeView->setColumnWidth(SupportedProtocolsModel::colFilter, one_em * 10); + ui->supportedProtocolsTreeView->setColumnWidth(SupportedProtocolsModel::colType, one_em * 12); + ui->supportedProtocolsTreeView->setColumnWidth(SupportedProtocolsModel::colDescription, one_em * 30); QTimer::singleShot(0, this, SLOT(fillTree())); } @@ -69,80 +49,26 @@ SupportedProtocolsDialog::SupportedProtocolsDialog(QWidget *parent) : SupportedProtocolsDialog::~SupportedProtocolsDialog() { delete ui; + delete supported_protocols_model_; + delete proxyModel_; } void SupportedProtocolsDialog::updateStatistics() { QLocale locale = QLocale::system(); QString hint = tr("%1 protocols, %2 fields.") - .arg(locale.toString(ui->protoTreeWidget->topLevelItemCount())) - .arg(locale.toString(field_count_)); + .arg(locale.toString(supported_protocols_model_->rowCount())) + .arg(locale.toString(supported_protocols_model_->fieldCount())); ui->hintLabel->setText(hint); - wsApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers, 1); } -// Nearly identical to DisplayFilterExpressionDialog::fillTree. void SupportedProtocolsDialog::fillTree() { - void *proto_cookie; - QList <QTreeWidgetItem *> proto_list; - - 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); - QTreeWidgetItem *proto_ti = new QTreeWidgetItem(); - proto_ti->setText(name_col_, proto_get_protocol_short_name(protocol)); - proto_ti->setText(filter_col_, proto_get_protocol_filter_name(proto_id)); - // type_col_ empty - proto_ti->setText(descr_col_, proto_get_protocol_long_name(protocol)); - proto_ti->setData(name_col_, Qt::UserRole, proto_id); - proto_list << proto_ti; - } - - updateStatistics(); - ui->protoTreeWidget->invisibleRootItem()->addChildren(proto_list); - ui->protoTreeWidget->sortByColumn(name_col_, Qt::AscendingOrder); - - foreach (QTreeWidgetItem *proto_ti, proto_list) { - void *field_cookie; - int proto_id = proto_ti->data(name_col_, Qt::UserRole).toInt(); - QList <QTreeWidgetItem *> field_list; - for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; - hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) { - if (hfinfo->same_name_prev_id != -1) continue; - - QTreeWidgetItem *field_ti = new QTreeWidgetItem(); - field_ti->setText(name_col_, hfinfo->name); - field_ti->setText(filter_col_, hfinfo->abbrev); - field_ti->setText(type_col_, ftype_pretty_name(hfinfo->type)); - field_ti->setText(descr_col_, hfinfo->blurb); - field_list << field_ti; - - field_count_++; - if (field_count_ % 10000 == 0) updateStatistics(); - } - std::sort(field_list.begin(), field_list.end()); - proto_ti->addChildren(field_list); - } - + supported_protocols_model_->populate(); updateStatistics(); - ui->protoTreeWidget->sortByColumn(name_col_, Qt::AscendingOrder); } -// Copied from DisplayFilterExpressionDialog void SupportedProtocolsDialog::on_searchLineEdit_textChanged(const QString &search_re) { - QTreeWidgetItemIterator it(ui->protoTreeWidget); - QRegExp regex(search_re, Qt::CaseInsensitive); - while (*it) { - bool hidden = true; - if (search_re.isEmpty() || (*it)->text(0).contains(regex)) { - hidden = false; - } - (*it)->setHidden(hidden); - if (!hidden && (*it)->parent()) { - (*it)->parent()->setHidden(false); - } - ++it; - } + proxyModel_->setFilter(search_re); } diff --git a/ui/qt/supported_protocols_dialog.h b/ui/qt/supported_protocols_dialog.h index a305cf72a0..585da1898f 100644 --- a/ui/qt/supported_protocols_dialog.h +++ b/ui/qt/supported_protocols_dialog.h @@ -4,25 +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 SUPPORTED_PROTOCOLS_DIALOG_H #define SUPPORTED_PROTOCOLS_DIALOG_H #include "geometry_state_dialog.h" +#include <ui/qt/models/supported_protocols_model.h> namespace Ui { class SupportedProtocolsDialog; @@ -39,7 +28,9 @@ public: private: Ui::SupportedProtocolsDialog *ui; - int field_count_; + SupportedProtocolsModel* supported_protocols_model_; + SupportedProtocolsProxyModel* proxyModel_; + void updateStatistics(); private slots: diff --git a/ui/qt/supported_protocols_dialog.ui b/ui/qt/supported_protocols_dialog.ui index 7883665a9b..deb34ef753 100644 --- a/ui/qt/supported_protocols_dialog.ui +++ b/ui/qt/supported_protocols_dialog.ui @@ -15,27 +15,7 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QTreeWidget" name="protoTreeWidget"> - <column> - <property name="text"> - <string>Name</string> - </property> - </column> - <column> - <property name="text"> - <string>Filter</string> - </property> - </column> - <column> - <property name="text"> - <string>Type</string> - </property> - </column> - <column> - <property name="text"> - <string>Description</string> - </property> - </column> + <widget class="QTreeView" name="supportedProtocolsTreeView"> </widget> </item> <item> |