diff options
author | Roland Knall <rknall@gmail.com> | 2022-06-08 14:33:51 +0200 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2022-06-14 09:36:30 +0000 |
commit | a4f25e51150d81a76e6cf8644b60fdd000cd15ee (patch) | |
tree | 0f94a3dc68be55a5fafbe0a9edc099f255953e0b /ui/qt/widgets/traffic_tab.cpp | |
parent | f1cbc6b6623074ad6f403993e9f0cfee9bee4300 (diff) |
Qt: Redesign TrafficTree Dialogs UI
The new UI should better group functionality and as well as better
showing which taps are available and can be used.
Diffstat (limited to 'ui/qt/widgets/traffic_tab.cpp')
-rw-r--r-- | ui/qt/widgets/traffic_tab.cpp | 240 |
1 files changed, 101 insertions, 139 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()); } |