diff options
Diffstat (limited to 'ui/qt/widgets')
-rw-r--r-- | ui/qt/widgets/traffic_tab.cpp | 240 | ||||
-rw-r--r-- | ui/qt/widgets/traffic_tab.h | 21 | ||||
-rw-r--r-- | ui/qt/widgets/traffic_tree.cpp | 3 | ||||
-rw-r--r-- | ui/qt/widgets/traffic_types_list.cpp | 236 | ||||
-rw-r--r-- | ui/qt/widgets/traffic_types_list.h | 100 |
5 files changed, 448 insertions, 152 deletions
diff --git a/ui/qt/widgets/traffic_tab.cpp b/ui/qt/widgets/traffic_tab.cpp index 8cfaeb5316..d517e46529 100644 --- a/ui/qt/widgets/traffic_tab.cpp +++ b/ui/qt/widgets/traffic_tab.cpp @@ -16,8 +16,6 @@ #include <wsutil/utf8_entities.h> #include <wsutil/filesystem.h> -#include "ui/recent.h" - #include <ui/qt/main_application.h> #include <ui/qt/filter_action.h> #include <ui/qt/models/atap_data_model.h> @@ -26,7 +24,6 @@ #include <ui/qt/widgets/traffic_tree.h> #include <ui/qt/widgets/detachable_tabwidget.h> -#include <QVector> #include <QStringList> #include <QTreeView> #include <QList> @@ -175,103 +172,26 @@ bool TrafficDataFilterProxy::lessThan(const QModelIndex &source_left, const QMod } -static gboolean iterateProtocols(const void *key, void *value, void *userdata) -{ - QMap<int, QString> *protocols = (QMap<int, QString> *)userdata; - register_ct_t* ct = (register_ct_t*)value; - const QString title = (const gchar*)key; - int proto_id = get_conversation_proto_id(ct); - protocols->insert(proto_id, title); - - return FALSE; -} - TrafficTab::TrafficTab(QWidget * parent) : DetachableTabWidget(parent) { _createModel = nullptr; _disableTaps = false; _nameResolution = false; - _recentList = nullptr; setTabBasename(QString()); - } TrafficTab::~TrafficTab() -{ - prefs_clear_string_list(*_recentList); - *_recentList = NULL; - _protocolButtons.clear(); - - foreach (int protoId, _tabs.keys()) - { - char *title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(protoId))); - *_recentList = g_list_append(*_recentList, title); - } -} +{} -void TrafficTab::setProtocolInfo(QString tableName, GList ** recentList, ATapModelCallback createModel) +void TrafficTab::setProtocolInfo(QString tableName, QList<int> allProtocols, QList<int> openTabs, ATapModelCallback createModel) { setTabBasename(tableName); - _recentList = recentList; + _allProtocols = allProtocols; if (createModel) _createModel = createModel; - for (GList * endTab = *_recentList; endTab; endTab = endTab->next) { - int protoId = proto_get_id_by_short_name((const char *)endTab->data); - if (protoId > -1 && ! _protocols.contains(protoId)) - _protocols.append(protoId); - } - - if (_protocols.isEmpty()) { - QStringList protoNames = QStringList() << "eth" << "ip" << "ipv6" << "tcp" << "udp"; - foreach(QString name, protoNames) - _protocols << proto_get_id_by_filter_name(name.toStdString().c_str()); - } - - QWidget * container = new QWidget(this); - container->setFixedHeight(tabBar()->height()); - container->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); - - QHBoxLayout * layout = new QHBoxLayout(container); - layout->setContentsMargins(1, 0, 1, 0); - - QPushButton * cornerButton = new QPushButton(tr("%1 Types").arg(tableName)); - cornerButton->setFixedHeight(tabBar()->height()); - cornerButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - QMenu * cornerMenu = new QMenu(); - conversation_table_iterate_tables(iterateProtocols, &_allTaps); - foreach (int protoId, _allTaps.keys()) - { - QAction * endPoint = new QAction(_allTaps[protoId], this); - endPoint->setProperty("protocol", QVariant::fromValue(protoId)); - endPoint->setCheckable(true); - endPoint->setChecked(_protocols.contains(protoId)); - connect(endPoint, &QAction::triggered, this, &TrafficTab::toggleTab); - _protocolButtons.insert(protoId, endPoint); - cornerMenu->addAction(endPoint); - } - cornerButton->setMenu(cornerMenu); - - layout->addWidget(cornerButton); - setCornerWidget(container, Qt::TopRightCorner); - - updateTabs(); -} - -void TrafficTab::toggleTab(bool checked) -{ - QAction * orig = qobject_cast<QAction *>(sender()); - if (!orig || ! orig->property("protocol").isValid()) - return; - - int protocol = orig->property("protocol").toInt(); - if (!checked && _protocols.contains(protocol)) - _protocols.removeAll(protocol); - else if (checked && ! _protocols.contains(protocol)) - _protocols.append(protocol); - - updateTabs(); + setOpenTabs(openTabs); } void TrafficTab::setDelegate(int column, ATapCreateDelegate createDelegate) @@ -376,61 +296,79 @@ void TrafficTab::disableTap() emit disablingTaps(); } -void TrafficTab::updateTabs() +void TrafficTab::setOpenTabs(QList<int> protocols) { - QList<int> keys = _tabs.keys(); - QList<int> allProtocols = _allTaps.keys(); - - /* Adding new Tabs, and keeping the same order they are in the drop-down menu */ - foreach (int proto, _protocols) { - if (!keys.contains(proto)) { - - int insertIndex = -1; - auto bIdx = allProtocols.indexOf(proto); - int idx = 0; - while (insertIndex < 0 && idx < keys.count()) - { - auto aIdx = allProtocols.indexOf(keys[idx]); - if (aIdx < 0) /* Key not in all protocols. This would be a fluke */ - break; - if (aIdx > bIdx) /* Should never be equal, as proto is not yet in keys */ - insertIndex = _tabs[keys[idx]]; - idx++; - } + QList<int> tabs = _tabs.keys(); + QList<int> remove; + blockSignals(true); - QTreeView * tree = createTree(proto); - QString tableName = proto_get_protocol_short_name(find_protocol_by_id(proto)); - TabData tabData(tableName, proto); - QVariant storage; - storage.setValue(tabData); - if (tree->model()->rowCount() > 0) - tableName += QString(" %1 %2").arg(UTF8_MIDDLE_DOT).arg(tree->model()->rowCount()); - - int tabId = insertTab(insertIndex, tree, tableName); - _protocolButtons[proto]->setChecked(true); - tabBar()->setTabData(tabId, storage); + foreach(int protocol, protocols) + { + if (! tabs.contains(protocol)) { + insertProtoTab(protocol, false); } + tabs.removeAll(protocol); } - /* Removing tabs no longer required. First filter the key array, for all tabs which - * are still being displayed */ - foreach(int key, keys) + foreach(int protocol, tabs) + removeProtoTab(protocol, false); + + blockSignals(false); + + emit tabsChanged(_tabs.keys()); + emit retapRequired(); +} + +void TrafficTab::insertProtoTab(int protoId, bool emitSignals) +{ + QList<int> lUsed = _tabs.keys(); + + if (lUsed.contains(protoId) && lUsed.count() != count()) { - if ( _protocols.contains(key)) { - _protocolButtons[key]->setChecked(true); - keys.removeAll(key); + _tabs.clear(); + for (int idx = 0; idx < count(); idx++) { + TabData tabData = qvariant_cast<TabData>(tabBar()->tabData(idx)); + _tabs.insert(tabData.protoId(), idx); } + lUsed = _tabs.keys(); } - /* Removal step 2, now actually remove all elements. Counting down, otherwise removing - * a tab will shift the indeces */ - for(int idx = count(); idx > 0; idx--) { - TabData tabData = qvariant_cast<TabData>(tabBar()->tabData(idx - 1)); - if (keys.contains(tabData.protoId())) { - removeTab(idx - 1); - _protocolButtons[tabData.protoId()]->setChecked(false); + + if (protoId <= 0 || lUsed.contains(protoId)) + return; + + QList<int> lFull = _allProtocols; + int idx = lFull.indexOf(protoId); + if (idx < 0) + return; + + QList<int> part = lFull.mid(0, idx); + int insertAt = 0; + if (part.count() > 0) { + for (int cnt = idx - 1; cnt >= 0; cnt--) { + if (lUsed.contains(part[cnt]) && part[cnt] != protoId) { + insertAt = lUsed.indexOf(part[cnt]) + 1; + break; + } } } + QTreeView * tree = createTree(protoId); + QString tableName = proto_get_protocol_short_name(find_protocol_by_id(protoId)); + TabData tabData(tableName, protoId); + QVariant storage; + storage.setValue(tabData); + if (tree->model()->rowCount() > 0) + tableName += QString(" %1 %2").arg(UTF8_MIDDLE_DOT).arg(tree->model()->rowCount()); + + int tabId = -1; + if (insertAt > -1) + tabId = insertTab(insertAt, tree, tableName); + else + tabId = addTab(tree, tableName); + if (tabId >= 0) + tabBar()->setTabData(tabId, storage); + + /* We reset the correct tab idxs. That operations is costly, but it is only * called during this operation and ensures, that other operations do not * need to iterate, but rather can lookup the indeces. */ @@ -440,7 +378,37 @@ void TrafficTab::updateTabs() _tabs.insert(tabData.protoId(), idx); } - emit retapRequired(); + if (emitSignals) { + emit tabsChanged(_tabs.keys()); + emit retapRequired(); + } +} + +void TrafficTab::removeProtoTab(int protoId, bool emitSignals) +{ + if (_tabs.keys().contains(protoId)) { + for(int idx = 0; idx < count(); idx++) { + TabData tabData = qvariant_cast<TabData>(tabBar()->tabData(idx)); + if (protoId == tabData.protoId()) { + removeTab(idx); + break; + } + } + } + + /* We reset the correct tab idxs. That operations is costly, but it is only + * called during this operation and ensures, that other operations do not + * need to iterate, but rather can lookup the indeces. */ + _tabs.clear(); + for (int idx = 0; idx < count(); idx++) { + TabData tabData = qvariant_cast<TabData>(tabBar()->tabData(idx)); + _tabs.insert(tabData.protoId(), idx); + } + + if (emitSignals) { + emit tabsChanged(_tabs.keys()); + emit retapRequired(); + } } void TrafficTab::doCurrentIndexChange(const QModelIndex & cur, const QModelIndex &) @@ -484,7 +452,7 @@ void TrafficTab::modelReset() return; TrafficDataFilterProxy * qsfpm = qobject_cast<TrafficDataFilterProxy *>(sender()); - if (! qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) + if (!qsfpm || ! qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) return; ATapDataModel * atdm = qobject_cast<ATapDataModel *>(qsfpm->sourceModel()); @@ -519,7 +487,7 @@ ATapDataModel * TrafficTab::modelForWidget(QWidget * searchWidget) QTreeView * tree = qobject_cast<QTreeView *>(searchWidget); if (qobject_cast<TrafficDataFilterProxy *>(tree->model())) { TrafficDataFilterProxy * qsfpm = qobject_cast<TrafficDataFilterProxy *>(tree->model()); - if (qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) { + if (qsfpm && qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) { return qobject_cast<ATapDataModel *>(qsfpm->sourceModel()); } } @@ -736,9 +704,6 @@ void TrafficTab::detachTab(int tabIdx, QPoint pos) { if (!model) return; - int protocol = model->protoId(); - _protocols.removeAll(protocol); - TrafficTree * tree = qobject_cast<TrafficTree *>(widget(tabIdx)); if (!tree) return; @@ -746,7 +711,7 @@ void TrafficTab::detachTab(int tabIdx, QPoint pos) { connect(this, &TrafficTab::disablingTaps ,tree , &TrafficTree::disableTap); DetachableTabWidget::detachTab(tabIdx, pos); - updateTabs(); + removeProtoTab(model->protoId()); } void TrafficTab::attachTab(QWidget * content, QString name) @@ -757,8 +722,5 @@ void TrafficTab::attachTab(QWidget * content, QString name) return; } - int protocol = model->protoId(); - _protocols.append(protocol); - - updateTabs(); + insertProtoTab(model->protoId()); } diff --git a/ui/qt/widgets/traffic_tab.h b/ui/qt/widgets/traffic_tab.h index 6a47984fec..c58a7ed592 100644 --- a/ui/qt/widgets/traffic_tab.h +++ b/ui/qt/widgets/traffic_tab.h @@ -12,8 +12,6 @@ #include "config.h" -#include <ui/recent.h> - #include <ui/qt/models/atap_data_model.h> #include <ui/qt/filter_action.h> #include <ui/qt/widgets/detachable_tabwidget.h> @@ -99,12 +97,13 @@ public: * without having to removing the predefined object during setup of the UI. * * @param tableName The name for the table. Used for the protocol selection button - * @param recentList The list to store the selected protocols in + * @param allProtocols a list of all possible protocols. It's order will set the tab oder + * @param openTabs a list of protocol ids to open at start of dialog * @param createModel A callback, which will create the correct model for the trees * * @see ATapModelCallback */ - void setProtocolInfo(QString tableName, GList ** recentList, ATapModelCallback createModel); + void setProtocolInfo(QString tableName, QList<int> allProtocols, QList<int> openTabs, ATapModelCallback createModel); /** * @brief Set the Delegate object for a specific column @@ -212,11 +211,14 @@ public slots: */ void useAbsoluteTime(bool absolute); + void setOpenTabs(QList<int> protocols); + signals: void filterAction(QString filter, FilterAction::Action action, FilterAction::ActionType type); void tabDataChanged(int idx); void retapRequired(); void disablingTaps(); + void tabsChanged(QList<int> protocols); protected slots: @@ -224,29 +226,26 @@ protected slots: virtual void attachTab(QWidget * content, QString name) override; private: - QVector<int> _protocols; - QMap<int, QString> _allTaps; - QMap<int, QAction *> _protocolButtons; + QList<int> _allProtocols; QMap<int, int> _tabs; - GList ** _recentList; ATapModelCallback _createModel; QMap<int, ATapCreateDelegate> _createDelegates; bool _disableTaps; bool _nameResolution; - void updateTabs(); QTreeView * createTree(int protoId); ATapDataModel * modelForTabIndex(int tabIdx = -1); ATapDataModel * modelForWidget(QWidget * widget); + void insertProtoTab(int protoId, bool emitSignals = true); + void removeProtoTab(int protoId, bool emitSignals = true); + #ifdef HAVE_MAXMINDDB bool writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataModel); #endif private slots: - void toggleTab(bool checked = false); - void modelReset(); void doCurrentIndexChange(const QModelIndex & cur, const QModelIndex & prev); diff --git a/ui/qt/widgets/traffic_tree.cpp b/ui/qt/widgets/traffic_tree.cpp index 31a1ab2bc6..3e370da83c 100644 --- a/ui/qt/widgets/traffic_tree.cpp +++ b/ui/qt/widgets/traffic_tree.cpp @@ -27,7 +27,6 @@ #include <ui/qt/utils/variant_pointer.h> #include <ui/qt/widgets/traffic_tree.h> -#include <QVector> #include <QStringList> #include <QTreeView> #include <QList> @@ -53,7 +52,7 @@ TrafficTree::TrafficTree(QString baseName, QWidget *parent) : setRootIsDecorated(false); setSortingEnabled(true); setContextMenuPolicy(Qt::CustomContextMenu); - + connect(this, &QTreeView::customContextMenuRequested, this, &TrafficTree::customContextMenu); } diff --git a/ui/qt/widgets/traffic_types_list.cpp b/ui/qt/widgets/traffic_types_list.cpp new file mode 100644 index 0000000000..031f8c0295 --- /dev/null +++ b/ui/qt/widgets/traffic_types_list.cpp @@ -0,0 +1,236 @@ +/** @file + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <glib.h> + +#include <epan/conversation_table.h> + +#include <ui/qt/widgets/traffic_types_list.h> + +#include <QStringList> + +TrafficTypesRowData::TrafficTypesRowData(int protocol, QString name) : + _protocol(protocol), + _name(name), + _checked(false) +{} + +int TrafficTypesRowData::protocol() const +{ + return _protocol; +} + +QString TrafficTypesRowData::name() const +{ + return _name; +} + +bool TrafficTypesRowData::checked() const +{ + return _checked; +} + +void TrafficTypesRowData::setChecked(bool checked) +{ + _checked = checked; +} + +static gboolean iterateProtocols(const void *key, void *value, void *userdata) +{ + QList<TrafficTypesRowData> * protocols = (QList<TrafficTypesRowData> *)userdata; + + register_ct_t* ct = (register_ct_t*)value; + const QString title = (const gchar*)key; + int proto_id = get_conversation_proto_id(ct); + TrafficTypesRowData entry(proto_id, title); + protocols->append(entry); + + return FALSE; +} + +TrafficTypesModel::TrafficTypesModel(GList ** recentList, QObject *parent) : + QAbstractListModel(parent), + _recentList(recentList) +{ + conversation_table_iterate_tables(iterateProtocols, &_allTaps); + + QList<int> _protocols; + + for (GList * endTab = *_recentList; endTab; endTab = endTab->next) { + int protoId = proto_get_id_by_short_name((const char *)endTab->data); + if (protoId > -1 && ! _protocols.contains(protoId)) + _protocols.append(protoId); + } + + if (_protocols.isEmpty()) { + QStringList protoNames = QStringList() << "eth" << "ip" << "ipv6" << "tcp" << "udp"; + foreach(QString name, protoNames) + _protocols << proto_get_id_by_filter_name(name.toStdString().c_str()); + } + + for(int cnt = 0; cnt < _allTaps.count(); cnt++) + { + _allTaps[cnt].setChecked(false); + if (_protocols.contains(_allTaps[cnt].protocol())) + _allTaps[cnt].setChecked(true); + } + +} + +int TrafficTypesModel::rowCount(const QModelIndex &) const +{ + return _allTaps.count(); +} + +int TrafficTypesModel::columnCount(const QModelIndex &) const +{ + return TrafficTypesModel::COL_NUM; +} + +QVariant TrafficTypesModel::data(const QModelIndex &idx, int role) const +{ + if (!idx.isValid()) + return QVariant(); + + TrafficTypesRowData data = _allTaps[idx.row()]; + if (role == Qt::DisplayRole) + { + switch(idx.column()) + { + case(TrafficTypesModel::COL_NAME): + return data.name(); + case(TrafficTypesModel::COL_PROTOCOL): + return data.protocol(); + } + } else if (role == Qt::CheckStateRole && idx.column() == TrafficTypesModel::COL_CHECKED) { + return data.checked() ? Qt::Checked : Qt::Unchecked; + } else if (role == TrafficTypesModel::TRAFFIC_PROTOCOL) { + return data.protocol(); + } else if (role == TrafficTypesModel::TRAFFIC_IS_CHECKED) { + return (bool)data.checked(); + } + + return QVariant(); +} + +QVariant TrafficTypesModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (section < 0 || role != Qt::DisplayRole || orientation != Qt::Horizontal) + return QVariant(); + + if (section == TrafficTypesModel::COL_NAME) + return tr("Protocol"); + return QVariant(); +} + +Qt::ItemFlags TrafficTypesModel::flags (const QModelIndex & idx) const +{ + Qt::ItemFlags defaultFlags = QAbstractListModel::flags(idx); + if (idx.isValid()) + return defaultFlags | Qt::ItemIsUserCheckable; + + return defaultFlags; +} + +bool TrafficTypesModel::setData(const QModelIndex &idx, const QVariant &value, int role) +{ + if(!idx.isValid() || role != Qt::CheckStateRole) + return false; + + if (_allTaps.count() <= idx.row()) + return false; + + _allTaps[idx.row()].setChecked(value == Qt::Checked); + + QList<int> selected; + prefs_clear_string_list(*_recentList); + *_recentList = NULL; + + for (int cnt = 0; cnt < _allTaps.count(); cnt++) { + if (_allTaps[cnt].checked()) { + int protoId = _allTaps[cnt].protocol(); + selected.append(protoId); + char *title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(protoId))); + *_recentList = g_list_append(*_recentList, title); + } + } + + emit protocolsChanged(selected); + + emit dataChanged(idx, idx); + return true; +} + +void TrafficTypesModel::selectProtocols(QList<int> protocols) +{ + beginResetModel(); + for (int cnt = 0; cnt < _allTaps.count(); cnt++) { + _allTaps[cnt].setChecked(false); + if (protocols.contains(_allTaps[cnt].protocol())) + _allTaps[cnt].setChecked(true); + } + endResetModel(); +} + +TrafficTypesList::TrafficTypesList(QWidget *parent) : + QTreeView(parent) +{ + _name = QString(); + _model = nullptr; + + setAlternatingRowColors(true); + setRootIsDecorated(false); +} + +void TrafficTypesList::setProtocolInfo(QString name, GList ** recentList) +{ + _name = name; + + _model = new TrafficTypesModel(recentList); + setModel(_model); + + connect(_model, &TrafficTypesModel::protocolsChanged, this, &TrafficTypesList::protocolsChanged); + + resizeColumnToContents(0); + resizeColumnToContents(1); +} + +void TrafficTypesList::selectProtocols(QList<int> protocols) +{ + if (_model) + _model->selectProtocols(protocols); +} + +QList<int> TrafficTypesList::protocols() const +{ + QList<int> entries; + for (int cnt = 0; cnt < _model->rowCount(); cnt++) { + QModelIndex idx = _model->index(cnt, TrafficTypesModel::COL_CHECKED); + int protoId = _model->data(idx, TrafficTypesModel::TRAFFIC_PROTOCOL).toInt(); + if (protoId > 0 && ! entries.contains(protoId)) + entries.append(protoId); + } + + return entries; +} + +QList<int> TrafficTypesList::selectedProtocols() const +{ + QList<int> entries; + for (int cnt = 0; cnt < _model->rowCount(); cnt++) { + QModelIndex idx = _model->index(cnt, TrafficTypesModel::COL_CHECKED); + int protoId = _model->data(idx, TrafficTypesModel::TRAFFIC_PROTOCOL).toInt(); + if (protoId > 0 && ! entries.contains(protoId) && _model->data(idx, TrafficTypesModel::TRAFFIC_IS_CHECKED).toBool()) + entries.append(protoId); + } + + return entries; +} diff --git a/ui/qt/widgets/traffic_types_list.h b/ui/qt/widgets/traffic_types_list.h new file mode 100644 index 0000000000..fece2ef86a --- /dev/null +++ b/ui/qt/widgets/traffic_types_list.h @@ -0,0 +1,100 @@ +/** @file + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef TRAFFIC_TYPES_LIST_H +#define TRAFFIC_TYPES_LIST_H + +#include "config.h" + +#include <QTreeView> +#include <QAbstractListModel> +#include <QMap> +#include <QString> + +class TrafficTypesRowData +{ + +public: + TrafficTypesRowData(int protocol, QString name); + + int protocol() const; + QString name() const; + bool checked() const; + void setChecked(bool checked); + +private: + int _protocol; + QString _name; + bool _checked; +}; + +class TrafficTypesModel : public QAbstractListModel +{ + Q_OBJECT +public: + + enum { + TRAFFIC_PROTOCOL = Qt::UserRole, + TRAFFIC_IS_CHECKED, + } eTrafficUserData; + + enum { + COL_CHECKED, + COL_NAME, + COL_NUM, + COL_PROTOCOL, + } eTrafficColumnNames; + + TrafficTypesModel(GList ** recentList, QObject *parent = nullptr); + + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + virtual bool setData(const QModelIndex &idx, const QVariant &value, int role) override; + virtual Qt::ItemFlags flags (const QModelIndex & idx) const override; + + QList<int> protocols() const; + +public slots: + void selectProtocols(QList<int> protocols); + +signals: + void protocolsChanged(QList<int> protocols); + +private: + QList<TrafficTypesRowData> _allTaps; + GList ** _recentList; + +}; + +class TrafficTypesList : public QTreeView +{ + Q_OBJECT +public: + + TrafficTypesList(QWidget *parent = nullptr); + + void setProtocolInfo(QString name, GList ** recentList); + QList<int> protocols() const; + QList<int> selectedProtocols() const; + +public slots: + void selectProtocols(QList<int> protocols); + +signals: + void protocolsChanged(QList<int> protocols); + +private: + QString _name; + TrafficTypesModel * _model; +}; + +#endif // TRAFFIC_TYPES_LIST_H
\ No newline at end of file |