1 /* enabled_protocols_model.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
10 #include <QSortFilterProxyModel>
12 #include <ui/qt/models/enabled_protocols_model.h>
13 #include <epan/packet.h>
14 #include <epan/disabled_protos.h>
16 #include <ui/qt/utils/variant_pointer.h>
17 #include "wireshark_application.h"
19 class ProtocolTreeItem : public EnabledProtocolItem
22 ProtocolTreeItem(protocol_t* proto, EnabledProtocolItem* parent)
23 : EnabledProtocolItem(proto_get_protocol_short_name(proto), proto_get_protocol_long_name(proto), proto_is_protocol_enabled(proto), parent),
29 virtual ~ProtocolTreeItem() {}
32 virtual void applyValuePrivate(gboolean value)
34 proto_set_decoding(proto_get_id(proto_), value);
41 class HeuristicTreeItem : public EnabledProtocolItem
44 HeuristicTreeItem(heur_dtbl_entry_t *heuristic, EnabledProtocolItem* parent)
45 : EnabledProtocolItem(heuristic->short_name, heuristic->display_name, heuristic->enabled, parent),
50 virtual ~HeuristicTreeItem() {}
53 virtual void applyValuePrivate(gboolean value)
55 heuristic_->enabled = value;
59 heur_dtbl_entry_t *heuristic_;
63 EnabledProtocolItem::EnabledProtocolItem(QString name, QString description, bool enabled, EnabledProtocolItem* parent) :
64 ModelHelperTreeItem<EnabledProtocolItem>(parent),
66 description_(description),
72 EnabledProtocolItem::~EnabledProtocolItem()
76 bool EnabledProtocolItem::applyValue()
78 if (enabledInit_ != enabled_) {
79 applyValuePrivate(enabled_);
89 EnabledProtocolsModel::EnabledProtocolsModel(QObject *parent) :
90 QAbstractItemModel(parent),
91 root_(new ProtocolTreeItem(NULL, NULL))
95 EnabledProtocolsModel::~EnabledProtocolsModel()
100 int EnabledProtocolsModel::rowCount(const QModelIndex &parent) const
102 EnabledProtocolItem *parent_item;
103 if (parent.column() > 0)
106 if (!parent.isValid())
109 parent_item = static_cast<EnabledProtocolItem*>(parent.internalPointer());
111 if (parent_item == NULL)
114 return parent_item->childCount();
117 int EnabledProtocolsModel::columnCount(const QModelIndex&) const
122 QVariant EnabledProtocolsModel::headerData(int section, Qt::Orientation orientation, int role) const
124 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
126 switch ((enum EnabledProtocolsColumn)section) {
128 return tr("Protocol");
130 return tr("Description");
138 QModelIndex EnabledProtocolsModel::parent(const QModelIndex& index) const
140 if (!index.isValid())
141 return QModelIndex();
143 EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer());
145 EnabledProtocolItem* parent_item = item->parentItem();
146 if (parent_item != NULL) {
147 if (parent_item == root_)
148 return QModelIndex();
150 return createIndex(parent_item->row(), 0, parent_item);
154 return QModelIndex();
157 QModelIndex EnabledProtocolsModel::index(int row, int column, const QModelIndex& parent) const
159 if (!hasIndex(row, column, parent))
160 return QModelIndex();
162 EnabledProtocolItem *parent_item, *child_item;
164 if (!parent.isValid())
167 parent_item = static_cast<EnabledProtocolItem*>(parent.internalPointer());
169 Q_ASSERT(parent_item);
171 child_item = parent_item->child(row);
173 return createIndex(row, column, child_item);
176 return QModelIndex();
179 Qt::ItemFlags EnabledProtocolsModel::flags(const QModelIndex &index) const
181 if (!index.isValid())
184 Qt::ItemFlags flags = QAbstractItemModel::flags(index);
185 switch(index.column())
188 flags |= Qt::ItemIsUserCheckable;
197 QVariant EnabledProtocolsModel::data(const QModelIndex &index, int role) const
199 if (!index.isValid())
202 EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer());
208 case Qt::DisplayRole:
209 switch ((enum EnabledProtocolsColumn)index.column())
214 return item->description();
219 case Qt::CheckStateRole:
220 switch ((enum EnabledProtocolsColumn)index.column())
223 return item->enabled() ? Qt::Checked : Qt::Unchecked;
232 bool EnabledProtocolsModel::setData(const QModelIndex &index, const QVariant &value, int role)
234 if (!index.isValid())
237 if ((role != Qt::EditRole) &&
238 ((index.column() == colProtocol) && (role != Qt::CheckStateRole)))
241 if (data(index, role) == value) {
242 // Data appears unchanged, do not do additional checks.
246 EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(index.internalPointer());
250 item->setEnabled(value == Qt::Checked ? true : false);
255 emit dataChanged(index, index
256 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
264 static void addHeuristicItem(gpointer data, gpointer user_data)
266 heur_dtbl_entry_t* heur = (heur_dtbl_entry_t*)data;
267 ProtocolTreeItem* protocol_item = (ProtocolTreeItem*)user_data;
269 HeuristicTreeItem* heuristic_row = new HeuristicTreeItem(heur, protocol_item);
270 protocol_item->appendChild(heuristic_row);
273 void EnabledProtocolsModel::populate()
276 protocol_t *protocol;
278 emit beginResetModel();
280 // Iterate over all the protocols
281 for (int i = proto_get_first_protocol(&cookie); i != -1; i = proto_get_next_protocol(&cookie))
283 if (proto_can_toggle_protocol(i))
285 protocol = find_protocol_by_id(i);
286 ProtocolTreeItem* protocol_row = new ProtocolTreeItem(protocol, root_);
287 root_->appendChild(protocol_row);
289 proto_heuristic_dissector_foreach(protocol, addHeuristicItem, protocol_row);
293 emit endResetModel();
296 void EnabledProtocolsModel::invertEnabled()
298 emit beginResetModel();
300 for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) {
301 EnabledProtocolItem* proto = root_->child(proto_index);
302 proto->setEnabled(!proto->enabled());
303 for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) {
304 EnabledProtocolItem* heur = proto->child(heur_index);
305 heur->setEnabled(!heur->enabled());
309 emit endResetModel();
312 void EnabledProtocolsModel::enableAll()
314 emit beginResetModel();
316 for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) {
317 EnabledProtocolItem* proto = root_->child(proto_index);
318 proto->setEnabled(true);
319 for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) {
320 EnabledProtocolItem* heur = proto->child(heur_index);
321 heur->setEnabled(true);
325 emit endResetModel();
328 void EnabledProtocolsModel::disableAll()
330 emit beginResetModel();
332 for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) {
333 EnabledProtocolItem* proto = root_->child(proto_index);
334 proto->setEnabled(false);
335 for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) {
336 EnabledProtocolItem* heur = proto->child(heur_index);
337 heur->setEnabled(false);
341 emit endResetModel();
344 void EnabledProtocolsModel::applyChanges(bool writeChanges)
346 bool redissect = false;
348 for (int proto_index = 0; proto_index < root_->childCount(); proto_index++) {
349 EnabledProtocolItem* proto = root_->child(proto_index);
350 redissect |= proto->applyValue();
351 for (int heur_index = 0; heur_index < proto->childCount(); heur_index++) {
352 EnabledProtocolItem* heur = proto->child(heur_index);
353 redissect |= heur->applyValue();
358 saveChanges(writeChanges);
362 void EnabledProtocolsModel::disableProtocol(struct _protocol *protocol)
364 ProtocolTreeItem disabled_proto(protocol, NULL);
365 disabled_proto.setEnabled(false);
366 if (disabled_proto.applyValue()) {
371 void EnabledProtocolsModel::saveChanges(bool writeChanges)
374 save_enabled_and_disabled_lists();
376 wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged);
382 EnabledProtocolsProxyModel::EnabledProtocolsProxyModel(QObject * parent)
383 : QSortFilterProxyModel(parent),
388 bool EnabledProtocolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
390 //Use EnabledProtocolItem directly for better performance
391 EnabledProtocolItem* left_item = static_cast<EnabledProtocolItem*>(left.internalPointer());
392 EnabledProtocolItem* right_item = static_cast<EnabledProtocolItem*>(right.internalPointer());
394 if ((left_item != NULL) && (right_item != NULL)) {
398 if (left.column() == EnabledProtocolsModel::colProtocol )
399 compare_ret = left_item->name().compare(right_item->name(), Qt::CaseInsensitive);
400 else if ( left.column() == EnabledProtocolsModel::colDescription )
401 compare_ret = left_item->description().compare(right_item->description(), Qt::CaseInsensitive);
410 bool EnabledProtocolsProxyModel::filterAcceptItem(EnabledProtocolItem& item) const
412 QRegExp regex(filter_, Qt::CaseInsensitive);
414 if (item.name().contains(regex))
417 if (item.description().contains(regex))
423 bool EnabledProtocolsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
426 QModelIndex nameIdx = sourceModel()->index(sourceRow, EnabledProtocolsModel::colProtocol, sourceParent);
427 EnabledProtocolItem* item = static_cast<EnabledProtocolItem*>(nameIdx.internalPointer());
431 if (!filter_.isEmpty()) {
432 if (filterAcceptItem(*item))
435 if (!nameIdx.parent().isValid())
437 EnabledProtocolItem* child_item;
438 for (int row = 0; row < item->childCount(); row++)
440 child_item = item->child(row);
441 if ((child_item != NULL) && (filterAcceptItem(*child_item)))
452 void EnabledProtocolsProxyModel::setFilter(const QString& filter)
465 * indent-tabs-mode: nil
468 * ex: set shiftwidth=4 tabstop=8 expandtab:
469 * :indentSize=4:tabSize=8:noTabs=true: