diff options
author | Michael Mann <mmann78@netscape.net> | 2017-12-16 21:51:33 -0500 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2017-12-19 08:21:19 +0000 |
commit | 0d6eb9631f26176d00d6bef69569d1d2911bd233 (patch) | |
tree | 97ae18832c54a74ed94ecc17e3f102d45e7a5680 | |
parent | 6e4a6364154f4e880f2bb6111d6759e51a686bb4 (diff) |
Convert Enabled protocols dialog to use model.
Change-Id: I618df2f2608adcd1be5da02262c5296e4d86cfba
Reviewed-on: https://code.wireshark.org/review/24866
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r-- | epan/proto.c | 3 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/enabled_protocols_dialog.cpp | 247 | ||||
-rw-r--r-- | ui/qt/enabled_protocols_dialog.h | 18 | ||||
-rw-r--r-- | ui/qt/enabled_protocols_dialog.ui | 23 | ||||
-rw-r--r-- | ui/qt/models/enabled_protocols_model.cpp | 522 | ||||
-rw-r--r-- | ui/qt/models/enabled_protocols_model.h | 97 | ||||
-rw-r--r-- | ui/qt/protocol_preferences_menu.cpp | 11 |
9 files changed, 661 insertions, 264 deletions
diff --git a/epan/proto.c b/epan/proto.c index e3864f7304..ac653c23c8 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -6886,6 +6886,9 @@ proto_is_pino(const protocol_t *protocol) gboolean proto_is_protocol_enabled(const protocol_t *protocol) { + if (protocol == NULL) + return FALSE; + //parent protocol determines enable/disable for helper dissectors if (proto_is_pino(protocol)) return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id)); diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 6c5465d4a0..3a254c5fa8 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -66,6 +66,7 @@ set(WIRESHARK_MODEL_HEADERS models/cache_proxy_model.h models/decode_as_delegate.h models/decode_as_model.h + models/enabled_protocols_model.h models/expert_info_model.h models/expert_info_proxy_model.h models/fileset_entry_model.h @@ -279,6 +280,7 @@ set(WIRESHARK_MODEL_SRCS models/cache_proxy_model.cpp models/decode_as_delegate.cpp models/decode_as_model.cpp + models/enabled_protocols_model.cpp models/expert_info_model.cpp models/expert_info_proxy_model.cpp models/fileset_entry_model.cpp diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index bc9b8dd2f9..11d2c37b39 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -195,6 +195,7 @@ MOC_MODELS_HDRS = \ models/cache_proxy_model.h \ models/decode_as_delegate.h \ models/decode_as_model.h \ + models/enabled_protocols_model.h \ models/expert_info_model.h \ models/expert_info_proxy_model.h \ models/fileset_entry_model.h \ @@ -521,6 +522,7 @@ WIRESHARK_QT_MODELS_SRCS = \ models/cache_proxy_model.cpp \ models/decode_as_delegate.cpp \ models/decode_as_model.cpp \ + models/enabled_protocols_model.cpp \ models/expert_info_model.cpp \ models/expert_info_proxy_model.cpp \ models/fileset_entry_model.cpp \ diff --git a/ui/qt/enabled_protocols_dialog.cpp b/ui/qt/enabled_protocols_dialog.cpp index 1f1703f051..98f56b4b8f 100644 --- a/ui/qt/enabled_protocols_dialog.cpp +++ b/ui/qt/enabled_protocols_dialog.cpp @@ -22,269 +22,76 @@ #include "enabled_protocols_dialog.h" #include <ui_enabled_protocols_dialog.h> -#include <errno.h> +#include <QElapsedTimer> -#include <epan/proto.h> -#include <epan/packet.h> #include <epan/prefs.h> -#include <epan/disabled_protos.h> -#include <wsutil/filesystem.h> #include "wireshark_application.h" -#include "ui/simple_dialog.h" - -enum -{ - PROTOCOL_COLUMN, - DESCRIPTION_COLUMN -}; - -enum -{ - enable_type_ = 1000, - protocol_type_ = 1001, - heuristic_type_ = 1002 -}; - -#include <QDebug> -class EnableProtocolTreeWidgetItem : public QTreeWidgetItem -{ -public: - EnableProtocolTreeWidgetItem(QTreeWidgetItem *parent, QString proto_name, QString short_name, bool enable, int type = enable_type_) : - QTreeWidgetItem (parent, type), - short_name_(short_name), - proto_name_(proto_name), - enable_(enable) - { - setCheckState(PROTOCOL_COLUMN, enable_ ? Qt::Checked : Qt::Unchecked); - setText(PROTOCOL_COLUMN, short_name_); - setText(DESCRIPTION_COLUMN, proto_name_); - } - - virtual bool applyValue(bool value) - { - bool change = (value != enable_); - enable_ = value; - applyValuePrivate(value); - return change; - } - - // Useful if we ever add "save as" / "copy as". -// QList<QVariant> rowData() { -// return QList<QVariant>() << short_name_ << proto_name_ << enable_; -// } - -protected: - virtual void applyValuePrivate(gboolean value) = 0; - -private: - QString short_name_; - QString proto_name_; - bool enable_; -}; - -class ProtocolTreeWidgetItem : public EnableProtocolTreeWidgetItem -{ -public: - ProtocolTreeWidgetItem(QTreeWidgetItem *parent, const protocol_t *protocol) : - EnableProtocolTreeWidgetItem (parent, proto_get_protocol_long_name(protocol), proto_get_protocol_short_name(protocol), proto_is_protocol_enabled(protocol), protocol_type_), - protocol_(protocol) - { - } - const protocol_t *protocol() { return protocol_; } - -protected: - virtual void applyValuePrivate(gboolean value) - { - proto_set_decoding(proto_get_id(protocol_), value); - } - -private: - const protocol_t *protocol_; -}; - -class HeuristicTreeWidgetItem : public EnableProtocolTreeWidgetItem -{ -public: - HeuristicTreeWidgetItem(QTreeWidgetItem *parent, heur_dtbl_entry_t *heuristic) : - EnableProtocolTreeWidgetItem (parent, heuristic->display_name, heuristic->short_name, heuristic->enabled, heuristic_type_), - heuristic_(heuristic) - { - } - -protected: - virtual void applyValuePrivate(gboolean value) - { - heuristic_->enabled = value; - } - -private: - heur_dtbl_entry_t *heuristic_; -}; EnabledProtocolsDialog::EnabledProtocolsDialog(QWidget *parent) : GeometryStateDialog(parent), - ui(new Ui::EnabledProtocolsDialog) + ui(new Ui::EnabledProtocolsDialog), + enabled_protocols_model_(new EnabledProtocolsModel()), + proxyModel_(new EnabledProtocolsProxyModel(this)) { ui->setupUi(this); loadGeometry(); - setWindowTitle(wsApp->windowTitleString(tr("Enabled Protocols"))); - - void *cookie; - protocol_t *protocol; - - //Remove "original" item - ui->protocol_tree_->takeTopLevelItem(0); - - // Iterate over all the protocols - for (gint i = proto_get_first_protocol(&cookie); - i != -1; - i = proto_get_next_protocol(&cookie)) - { - if (proto_can_toggle_protocol(i)) - { - protocol = find_protocol_by_id(i); - ProtocolTreeWidgetItem* protocol_row = new ProtocolTreeWidgetItem(ui->protocol_tree_->invisibleRootItem(), protocol); - proto_heuristic_dissector_foreach(protocol, addHeuristicItem, protocol_row); - } - } - - ui->protocol_tree_->expandAll(); + proxyModel_->setSourceModel(enabled_protocols_model_); + ui->protocol_tree_->setModel(proxyModel_); - //make sortable - ui->protocol_tree_->setSortingEnabled(true); - ui->protocol_tree_->sortByColumn(PROTOCOL_COLUMN, Qt::AscendingOrder); + setWindowTitle(wsApp->windowTitleString(tr("Enabled Protocols"))); // Some protocols have excessively long names. Instead of calling // resizeColumnToContents, pick a reasonable-ish em width and apply it. int one_em = ui->protocol_tree_->fontMetrics().height(); - ui->protocol_tree_->setColumnWidth(PROTOCOL_COLUMN, one_em * 18); + ui->protocol_tree_->setColumnWidth(EnabledProtocolsModel::colProtocol, one_em * 18); //"Remove" Save button if (!prefs.gui_use_pref_save) ui->buttonBox->button(QDialogButtonBox::Save)->setHidden(true); + + QTimer::singleShot(0, this, SLOT(fillTree())); } EnabledProtocolsDialog::~EnabledProtocolsDialog() { delete ui; + delete proxyModel_; + delete enabled_protocols_model_; } -void EnabledProtocolsDialog::selectProtocol(_protocol *protocol) -{ - QTreeWidgetItemIterator it(ui->protocol_tree_->invisibleRootItem()); - while (*it) - { - if ((*it)->type() == protocol_type_) - { - ProtocolTreeWidgetItem* protocol_item = dynamic_cast<ProtocolTreeWidgetItem*>((ProtocolTreeWidgetItem*)(*it)); - if (protocol_item && protocol_item->protocol() == protocol) { - protocol_item->setSelected(true); - ui->protocol_tree_->scrollToItem((*it)); - return; - } - } - - ++it; - } -} - -void EnabledProtocolsDialog::addHeuristicItem(gpointer data, gpointer user_data) +void EnabledProtocolsDialog::fillTree() { - heur_dtbl_entry_t* heur = (heur_dtbl_entry_t*)data; - ProtocolTreeWidgetItem* protocol_item = (ProtocolTreeWidgetItem*)user_data; - - new HeuristicTreeWidgetItem(protocol_item, heur); + enabled_protocols_model_->populate(); + //it's recommended to sort after list is populated + proxyModel_->sort(EnabledProtocolsModel::colProtocol); + ui->protocol_tree_->expandAll(); } void EnabledProtocolsDialog::on_invert_button__clicked() { - QTreeWidgetItemIterator it(ui->protocol_tree_->invisibleRootItem()); - while (*it) - { - if ((*it)->checkState(PROTOCOL_COLUMN) == Qt::Unchecked) - { - (*it)->setCheckState(PROTOCOL_COLUMN, Qt::Checked); - } - else - { - (*it)->setCheckState(PROTOCOL_COLUMN, Qt::Unchecked); - } - - ++it; - } + enabled_protocols_model_->invertEnabled(); } void EnabledProtocolsDialog::on_enable_all_button__clicked() { - QTreeWidgetItemIterator it(ui->protocol_tree_->invisibleRootItem()); - while (*it) - { - (*it)->setCheckState(PROTOCOL_COLUMN, Qt::Checked); - ++it; - } + enabled_protocols_model_->enableAll(); } void EnabledProtocolsDialog::on_disable_all_button__clicked() { - QTreeWidgetItemIterator it(ui->protocol_tree_->invisibleRootItem()); - while (*it) - { - (*it)->setCheckState(PROTOCOL_COLUMN, Qt::Unchecked); - ++it; - } -} - -bool EnabledProtocolsDialog::applyChanges() -{ - bool redissect = false; - - QTreeWidgetItemIterator it(ui->protocol_tree_); - while (*it) - { - EnableProtocolTreeWidgetItem* it_cast = dynamic_cast<EnableProtocolTreeWidgetItem *>(*it); - - if ((*it)->checkState(PROTOCOL_COLUMN) == Qt::Checked) - { - redissect |= it_cast->applyValue(true); - } - else - { - redissect |= it_cast->applyValue(false); - } - ++it; - } - - return redissect; -} - -void EnabledProtocolsDialog::writeChanges() -{ - save_enabled_and_disabled_lists(); + enabled_protocols_model_->disableAll(); } void EnabledProtocolsDialog::on_search_line_edit__textChanged(const QString &search_re) { - QTreeWidgetItemIterator it(ui->protocol_tree_); - QRegExp regex(search_re, Qt::CaseInsensitive); - while (*it) { - bool hidden = true; - if (search_re.isEmpty() || (*it)->text(PROTOCOL_COLUMN).contains(regex) || (*it)->text(DESCRIPTION_COLUMN).contains(regex)) { - hidden = false; - } - (*it)->setHidden(hidden); - ++it; - } + proxyModel_->setFilter(search_re); } void EnabledProtocolsDialog::on_buttonBox_accepted() { - if (applyChanges()) - { - writeChanges(); - wsApp->queueAppSignal(WiresharkApplication::PacketDissectionChanged); - } + enabled_protocols_model_->applyChanges(); } #if 0 @@ -294,14 +101,8 @@ void EnabledProtocolsDialog::on_buttonBox_clicked(QAbstractButton *button) { if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) { - if (applyChanges()) - { - // if we don't have a Save button, just save the settings now - if (!prefs.gui_use_pref_save) - writeChanges(); - - wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged); - } + // if we don't have a Save button, just save the settings now + applyChanges(!prefs.gui_use_pref_save); } } #endif diff --git a/ui/qt/enabled_protocols_dialog.h b/ui/qt/enabled_protocols_dialog.h index 6b44bd49e7..cf2aa74514 100644 --- a/ui/qt/enabled_protocols_dialog.h +++ b/ui/qt/enabled_protocols_dialog.h @@ -24,23 +24,19 @@ #include "geometry_state_dialog.h" #include "wireshark_dialog.h" +#include <ui/qt/models/enabled_protocols_model.h> namespace Ui { class EnabledProtocolsDialog; } -struct _protocol; - -class QAbstractButton; - class EnabledProtocolsDialog : public GeometryStateDialog { Q_OBJECT public: explicit EnabledProtocolsDialog(QWidget *parent); - ~EnabledProtocolsDialog(); - void selectProtocol(struct _protocol *protocol); + virtual ~EnabledProtocolsDialog(); private slots: void on_invert_button__clicked(); @@ -48,18 +44,14 @@ private slots: void on_disable_all_button__clicked(); void on_search_line_edit__textChanged(const QString &search_re); void on_buttonBox_accepted(); -#if 0 - void on_buttonBox_clicked(QAbstractButton *button); -#endif void on_buttonBox_helpRequested(); + void fillTree(); private: Ui::EnabledProtocolsDialog *ui; - static void addHeuristicItem(gpointer data, gpointer user_data); - bool applyChanges(); - void writeChanges(); - + EnabledProtocolsModel* enabled_protocols_model_; + EnabledProtocolsProxyModel* proxyModel_; }; #endif // ENABLED_PROTOCOLS_DIALOG_H diff --git a/ui/qt/enabled_protocols_dialog.ui b/ui/qt/enabled_protocols_dialog.ui index 6740f808a2..2e9cfc1e3c 100644 --- a/ui/qt/enabled_protocols_dialog.ui +++ b/ui/qt/enabled_protocols_dialog.ui @@ -15,25 +15,10 @@ </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QTreeWidget" name="protocol_tree_"> - <column> - <property name="text"> - <string>Protocol</string> - </property> - </column> - <column> - <property name="text"> - <string>Description</string> - </property> - </column> - <item> - <property name="text"> - <string/> - </property> - <property name="text"> - <string/> - </property> - </item> + <widget class="QTreeView" name="protocol_tree_"> + <property name="sortingEnabled"> + <bool>true</bool> + </property> </widget> </item> <item> diff --git a/ui/qt/models/enabled_protocols_model.cpp b/ui/qt/models/enabled_protocols_model.cpp new file mode 100644 index 0000000000..c807975dd5 --- /dev/null +++ b/ui/qt/models/enabled_protocols_model.cpp @@ -0,0 +1,522 @@ +/* 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 <ui/qt/models/enabled_protocols_model.h> +#include <epan/packet.h> +#include <epan/disabled_protos.h> + +#include <ui/qt/utils/variant_pointer.h> +#include "wireshark_application.h" + +class EnabledProtocolItem +{ +public: + EnabledProtocolItem(QString name, QString description, bool enabled, EnabledProtocolItem* parent); + virtual ~EnabledProtocolItem(); + + QString name() const {return name_;} + QString description() const {return description_;} + bool enabled() const {return enabled_;} + void setEnabled(bool enable) {enabled_ = enable;} + + void appendChild(EnabledProtocolItem* child); + EnabledProtocolItem* child(int row) const; + int childCount() const; + int row() const; + + EnabledProtocolItem* parentItem() const {return parent_; } + + bool applyValue(); + +protected: + virtual void applyValuePrivate(gboolean value) = 0; + + QString name_; + QString description_; + bool enabled_; + bool enabledInit_; //value that model starts with to determine change + EnabledProtocolItem* parent_; + QList<QVariant> childItems_; +}; + +class ProtocolTreeItem : public EnabledProtocolItem +{ +public: + ProtocolTreeItem(protocol_t* proto, EnabledProtocolItem* parent) + : EnabledProtocolItem(proto_get_protocol_short_name(proto), proto_get_protocol_long_name(proto), proto_is_protocol_enabled(proto), parent), + proto_(proto) + { + + } + + virtual ~ProtocolTreeItem() {} + +protected: + virtual void applyValuePrivate(gboolean value) + { + proto_set_decoding(proto_get_id(proto_), value); + } + +private: + protocol_t* proto_; +}; + +class HeuristicTreeItem : public EnabledProtocolItem +{ +public: + HeuristicTreeItem(heur_dtbl_entry_t *heuristic, EnabledProtocolItem* parent) + : EnabledProtocolItem(heuristic->short_name, heuristic->display_name, heuristic->enabled, parent), + heuristic_(heuristic) + { + } + + virtual ~HeuristicTreeItem() {} + +protected: + virtual void applyValuePrivate(gboolean value) + { + heuristic_->enabled = value; + } + +private: + heur_dtbl_entry_t *heuristic_; +}; + + +EnabledProtocolItem::EnabledProtocolItem(QString name, QString description, bool enabled, EnabledProtocolItem* parent) : + name_(name), + description_(description), + enabled_(enabled), + enabledInit_(enabled), + parent_(parent) +{ +} + +EnabledProtocolItem::~EnabledProtocolItem() +{ + for (int row = 0; row < childItems_.count(); row++) + { + delete VariantPointer<EnabledProtocolItem>::asPtr(childItems_.value(row)); + } + + childItems_.clear(); +} + +void EnabledProtocolItem::appendChild(EnabledProtocolItem* child) +{ + childItems_.prepend(VariantPointer<EnabledProtocolItem>::asQVariant(child)); +} + +EnabledProtocolItem* EnabledProtocolItem::child(int row) const +{ + return VariantPointer<EnabledProtocolItem>::asPtr(childItems_.value(row)); +} + +int EnabledProtocolItem::childCount() const +{ + return childItems_.count(); +} + +int EnabledProtocolItem::row() const +{ + if (parent_) + return parent_->childItems_.indexOf(VariantPointer<EnabledProtocolItem>::asQVariant((EnabledProtocolItem*)this)); + + return 0; +} + + +bool EnabledProtocolItem::applyValue() +{ + if (enabledInit_ != enabled_) { + applyValuePrivate(enabled_); + return true; + } + + return false; +} + + + + +EnabledProtocolsModel::EnabledProtocolsModel(QObject *parent) : + QAbstractItemModel(parent), + root_(new ProtocolTreeItem(NULL, NULL)) +{ +} + +EnabledProtocolsModel::~EnabledProtocolsModel() +{ + delete root_; +} + +int EnabledProtocolsModel::rowCount(const QModelIndex &parent) const +{ + EnabledProtocolItem *parent_item; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parent_item = root_; + else + parent_item = static_cast<EnabledProtocolItem*>(parent.internalPointer()); + + if (parent_item == NULL) + return 0; + + return parent_item->childCount(); +} + +int EnabledProtocolsModel::columnCount(const QModelIndex&) const +{ + return colLast; +} + +QVariant EnabledProtocolsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + + switch ((enum EnabledProtocolsColumn)section) { + case colProtocol: + return tr("Protocol"); + case colDescription: + return tr("Description"); + default: + break; + } + } + return QVariant(); +} + +QModelIndex EnabledProtocolsModel::parent(const QModelIndex& index) const +{ + if (!index.isValid()) + return QModelIndex(); + + EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer()); + if (item != NULL) { + EnabledProtocolItem* 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 EnabledProtocolsModel::index(int row, int column, const QModelIndex& parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + EnabledProtocolItem *parent_item, *child_item; + + if (!parent.isValid()) + parent_item = root_; + else + parent_item = static_cast<EnabledProtocolItem*>(parent.internalPointer()); + + Q_ASSERT(parent_item); + + child_item = parent_item->child(row); + if (child_item) { + return createIndex(row, column, child_item); + } + + return QModelIndex(); +} + +Qt::ItemFlags EnabledProtocolsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + switch(index.column()) + { + case colProtocol: + flags |= Qt::ItemIsUserCheckable; + break; + default: + break; + } + + return flags; +} + +QVariant EnabledProtocolsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer()); + if (item == NULL) + return QVariant(); + + switch (role) + { + case Qt::DisplayRole: + switch ((enum EnabledProtocolsColumn)index.column()) + { + case colProtocol: + return item->name(); + case colDescription: + return item->description(); + default: + break; + } + case Qt::CheckStateRole: + switch ((enum EnabledProtocolsColumn)index.column()) + { + case colProtocol: + return item->enabled() ? Qt::Checked : Qt::Unchecked; + default: + break; + } + } + return QVariant(); +} + +bool EnabledProtocolsModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + + if ((role != Qt::EditRole) && + ((index.column() == colProtocol) && (role != Qt::CheckStateRole))) + return false; + + if (data(index, role) == value) { + // Data appears unchanged, do not do additional checks. + return true; + } + + EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer()); + if (item == NULL) + return false; + + item->setEnabled(value == Qt::Checked ? true : false); + + QVector<int> roles; + roles << role; + + emit dataChanged(index, index +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + , roles +#endif + ); + + return true; +} + +static void addHeuristicItem(gpointer data, gpointer user_data) +{ + heur_dtbl_entry_t* heur = (heur_dtbl_entry_t*)data; + ProtocolTreeItem* protocol_item = (ProtocolTreeItem*)user_data; + + HeuristicTreeItem* heuristic_row = new HeuristicTreeItem(heur, protocol_item); + protocol_item->appendChild(heuristic_row); +} + +void EnabledProtocolsModel::populate() +{ + void *cookie; + protocol_t *protocol; + + emit beginResetModel(); + + // Iterate over all the protocols + for (int i = proto_get_first_protocol(&cookie); i != -1; i = proto_get_next_protocol(&cookie)) + { + if (proto_can_toggle_protocol(i)) + { + protocol = find_protocol_by_id(i); + ProtocolTreeItem* protocol_row = new ProtocolTreeItem(protocol, root_); + root_->appendChild(protocol_row); + + proto_heuristic_dissector_foreach(protocol, addHeuristicItem, protocol_row); + } + } + + emit endResetModel(); +} + +void EnabledProtocolsModel::invertEnabled() +{ + emit beginResetModel(); + + for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) { + EnabledProtocolItem* proto = root_->child(proto_index); + proto->setEnabled(!proto->enabled()); + for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) { + EnabledProtocolItem* heur = proto->child(heur_index); + heur->setEnabled(!heur->enabled()); + } + } + + emit endResetModel(); +} + +void EnabledProtocolsModel::enableAll() +{ + emit beginResetModel(); + + for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) { + EnabledProtocolItem* proto = root_->child(proto_index); + proto->setEnabled(true); + for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) { + EnabledProtocolItem* heur = proto->child(heur_index); + heur->setEnabled(true); + } + } + + emit endResetModel(); +} + +void EnabledProtocolsModel::disableAll() +{ + emit beginResetModel(); + + for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) { + EnabledProtocolItem* proto = root_->child(proto_index); + proto->setEnabled(false); + for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) { + EnabledProtocolItem* heur = proto->child(heur_index); + heur->setEnabled(false); + } + } + + emit endResetModel(); +} + +void EnabledProtocolsModel::applyChanges(bool writeChanges) +{ + bool redissect = false; + + for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) { + EnabledProtocolItem* proto = root_->child(proto_index); + redissect |= proto->applyValue(); + for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) { + EnabledProtocolItem* heur = proto->child(heur_index); + redissect |= heur->applyValue(); + } + } + + if (redissect) { + saveChanges(writeChanges); + } +} + +void EnabledProtocolsModel::disableProtocol(struct _protocol *protocol) +{ + ProtocolTreeItem disabled_proto(protocol, NULL); + disabled_proto.setEnabled(false); + if (disabled_proto.applyValue()) { + saveChanges(); + } +} + +void EnabledProtocolsModel::saveChanges(bool writeChanges) +{ + if (writeChanges) { + save_enabled_and_disabled_lists(); + } + wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged); +} + + + + +EnabledProtocolsProxyModel::EnabledProtocolsProxyModel(QObject * parent) +: QSortFilterProxyModel(parent), +filter_() +{ +} + +bool EnabledProtocolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + //Use EnabledProtocolItem directly for better performance + EnabledProtocolItem* left_item = static_cast<EnabledProtocolItem*>(left.internalPointer()); + EnabledProtocolItem* right_item = static_cast<EnabledProtocolItem*>(right.internalPointer()); + + if ((left_item != NULL) && (right_item != NULL)) { + int compare_ret = left_item->name().compare(right_item->name(), Qt::CaseInsensitive); + if (compare_ret < 0) + return true; + } + + return false; +} + +bool EnabledProtocolsProxyModel::filterAcceptItem(EnabledProtocolItem& item) const +{ + QRegExp regex(filter_, Qt::CaseInsensitive); + + if (item.name().contains(regex)) + return true; + + if (item.description().contains(regex)) + return true; + + return false; +} + +bool EnabledProtocolsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + + QModelIndex nameIdx = sourceModel()->index(sourceRow, EnabledProtocolsModel::colProtocol, sourceParent); + EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(nameIdx.internalPointer()); + if (item == NULL) + return true; + + if (!filter_.isEmpty()) { + if (filterAcceptItem(*item)) + return true; + + if (!nameIdx.parent().isValid()) + { + EnabledProtocolItem* 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 EnabledProtocolsProxyModel::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/enabled_protocols_model.h b/ui/qt/models/enabled_protocols_model.h new file mode 100644 index 0000000000..09f3c18c64 --- /dev/null +++ b/ui/qt/models/enabled_protocols_model.h @@ -0,0 +1,97 @@ +/* enabled_protocols_model.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ENABLED_PROTOCOLS_MODEL_H +#define ENABLED_PROTOCOLS_MODEL_H + +#include <config.h> + +#include <epan/proto.h> + +#include <QAbstractItemModel> +#include <QSortFilterProxyModel> + +class EnabledProtocolItem; + +class EnabledProtocolsModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit EnabledProtocolsModel(QObject * parent = Q_NULLPTR); + virtual ~EnabledProtocolsModel(); + + enum EnabledProtocolsColumn { + colProtocol = 0, + colDescription, + colLast + }; + + QModelIndex index(int row, int column, + const QModelIndex & = QModelIndex()) const; + QModelIndex parent(const QModelIndex &) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + 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(); + void invertEnabled(); + void enableAll(); + void disableAll(); + + void applyChanges(bool writeChanges = true); + static void disableProtocol(struct _protocol *protocol); + +protected: + static void saveChanges(bool writeChanges = true); + +private: + EnabledProtocolItem* root_; +}; + +class EnabledProtocolsProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + + explicit EnabledProtocolsProxyModel(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(EnabledProtocolItem& item) const; + +private: + + QString filter_; +}; + +#endif // ENABLED_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/protocol_preferences_menu.cpp b/ui/qt/protocol_preferences_menu.cpp index 134b303d0c..87d0a16c76 100644 --- a/ui/qt/protocol_preferences_menu.cpp +++ b/ui/qt/protocol_preferences_menu.cpp @@ -20,7 +20,7 @@ #include "protocol_preferences_menu.h" -#include "enabled_protocols_dialog.h" +#include <ui/qt/models/enabled_protocols_model.h> #include <ui/qt/utils/qt_ui_utils.h> #include "uat_dialog.h" #include "wireshark_application.h" @@ -244,14 +244,7 @@ void ProtocolPreferencesMenu::addMenuItem(preference *pref) void ProtocolPreferencesMenu::disableProtocolTriggered() { - EnabledProtocolsDialog enable_proto_dialog(this); - enable_proto_dialog.selectProtocol(protocol_); - hide(); - enable_proto_dialog.exec(); - - // Emitting PacketDissectionChanged directly from a QDialog can cause - // problems on macOS. - wsApp->flushAppSignals(); + EnabledProtocolsModel::disableProtocol(protocol_); } void ProtocolPreferencesMenu::modulePreferencesTriggered() |