From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- ui/qt/stats_tree_dialog.cpp | 208 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 ui/qt/stats_tree_dialog.cpp (limited to 'ui/qt/stats_tree_dialog.cpp') diff --git a/ui/qt/stats_tree_dialog.cpp b/ui/qt/stats_tree_dialog.cpp new file mode 100644 index 00000000..1ec66b7e --- /dev/null +++ b/ui/qt/stats_tree_dialog.cpp @@ -0,0 +1,208 @@ +/* stats_tree_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "stats_tree_dialog.h" + +#include "file.h" + +#include "epan/stats_tree_priv.h" + +#include + +#include + +#include +#include +#include +#include + +const int item_col_ = 0; + +const int sn_type_ = 1000; +class StatsTreeWidgetItem : public QTreeWidgetItem +{ +public: + StatsTreeWidgetItem(int type = sn_type_) : QTreeWidgetItem (type) + { + for (int col = 1; col < columnCount(); col++) { + setTextAlignment(col, Qt::AlignRight); + } + } + bool operator< (const QTreeWidgetItem &other) const + { + stat_node *thisnode = VariantPointer::asPtr(data(item_col_, Qt::UserRole)); + stat_node *othernode = VariantPointer::asPtr(other.data(item_col_, Qt::UserRole)); + Qt::SortOrder order = treeWidget()->header()->sortIndicatorOrder(); + int result; + + result = stats_tree_sort_compare(thisnode, othernode, treeWidget()->sortColumn(), + order==Qt::DescendingOrder); + if (order==Qt::DescendingOrder) { + result = -result; + } + return result < 0; + } +}; + +StatsTreeDialog::StatsTreeDialog(QWidget &parent, CaptureFile &cf, const char *cfg_abbr) : + TapParameterDialog(parent, cf), + st_(NULL), + st_cfg_(NULL) +{ + loadGeometry(800, height(), cfg_abbr); + st_cfg_ = stats_tree_get_cfg_by_abbr(cfg_abbr); + memset(&cfg_pr_, 0, sizeof(struct _tree_cfg_pres)); + + addTreeCollapseAllActions(); + + if (!st_cfg_) { + QMessageBox::critical(this, tr("Configuration not found"), + tr("Unable to find configuration for %1.").arg(cfg_abbr)); + QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection); + } +} + +StatsTreeDialog::~StatsTreeDialog() +{ + if (st_) { + stats_tree_free(st_); + } +} + +// Adds a node to the QTreeWidget +// Note: We're passing QTreeWidgetItem pointers as st_node_pres pointers +void StatsTreeDialog::setupNode(stat_node* node) +{ + if (!node || !node->st || !node->st->cfg || !node->st->cfg->pr + || !node->st->cfg->pr->st_dlg) return; + StatsTreeDialog *st_dlg = node->st->cfg->pr->st_dlg; + + QTreeWidgetItem *ti = new StatsTreeWidgetItem(), *parent = NULL; + + ti->setText(item_col_, node->name); + ti->setData(item_col_, Qt::UserRole, VariantPointer::asQVariant(node)); + node->pr = (st_node_pres *) ti; + if (node->parent && node->parent->pr) { + parent = (QTreeWidgetItem *) node->parent->pr; + parent->setExpanded(true); + } + if (parent) { + parent->addChild(ti); + } else { + st_dlg->statsTreeWidget()->addTopLevelItem(ti); + } + st_dlg->statsTreeWidget()->resizeColumnToContents(item_col_); +} + +void StatsTreeDialog::fillTree() +{ + if (!st_cfg_ || file_closed_) return; + + QString display_name = gchar_free_to_qstring(stats_tree_get_displayname(st_cfg_->name)); + + // The GTK+ UI appends "Stats Tree" to the window title. If we do the same + // here we should expand the name completely, e.g. to "Statistics Tree". + setWindowSubtitle(display_name); + + st_cfg_->pr = &cfg_pr_; + cfg_pr_.st_dlg = this; + + if (st_) { + stats_tree_free(st_); + } + QString display_filter = displayFilter(); + st_ = stats_tree_new(st_cfg_, NULL, display_filter.toUtf8().constData()); + + // Add number of columns for this stats_tree + QStringList header_labels; + for (int count = 0; countnum_columns; count++) { + header_labels.push_back(stats_tree_get_column_name(count)); + } + statsTreeWidget()->setColumnCount(static_cast(header_labels.count())); + statsTreeWidget()->setHeaderLabels(header_labels); + statsTreeWidget()->setSortingEnabled(false); + + if (!registerTapListener(st_cfg_->tapname, + st_, + st_->filter, + st_cfg_->flags, + resetTap, + stats_tree_packet, + drawTreeItems)) { + reject(); // XXX Stay open instead? + return; + } + + cap_file_.retapPackets(); + drawTreeItems(st_); + + statsTreeWidget()->setSortingEnabled(true); + removeTapListeners(); + + st_cfg_->pr = NULL; +} + +void StatsTreeDialog::resetTap(void *st_ptr) +{ + stats_tree *st = (stats_tree *) st_ptr; + if (!st || !st->cfg || !st->cfg->pr || !st->cfg->pr->st_dlg) return; + + st->cfg->pr->st_dlg->statsTreeWidget()->clear(); + st->cfg->init(st); +} + +void StatsTreeDialog::drawTreeItems(void *st_ptr) +{ + stats_tree *st = (stats_tree *) st_ptr; + if (!st || !st->cfg || !st->cfg->pr || !st->cfg->pr->st_dlg) return; + TapParameterDialog *st_dlg = st->cfg->pr->st_dlg; + QTreeWidgetItemIterator iter(st_dlg->statsTreeWidget()); + + while (*iter) { + stat_node *node = VariantPointer::asPtr((*iter)->data(item_col_, Qt::UserRole)); + if (node) { + gchar **valstrs = stats_tree_get_values_from_node(node); + for (int count = 0; countnum_columns; count++) { + (*iter)->setText(count,valstrs[count]); + g_free(valstrs[count]); + } + (*iter)->setExpanded((node->parent==(&st->root)) && + (!(node->st_flags&ST_FLG_DEF_NOEXPAND))); + g_free(valstrs); + } + ++iter; + } + + st_dlg->drawTreeItems(); +} + +QByteArray StatsTreeDialog::getTreeAsString(st_format_type format) +{ + GString *str_tree; + + // produce output in selected format using current sort information + str_tree = stats_tree_format_as_str(st_, format, statsTreeWidget()->sortColumn(), + statsTreeWidget()->header()->sortIndicatorOrder()==Qt::DescendingOrder); + + return gstring_free_to_qbytearray(str_tree); +} + +extern "C" { + +void register_tap_listener_qt_stats_tree_stat(void); + +void +register_tap_listener_qt_stats_tree_stat(void) +{ + stats_tree_presentation(NULL, + StatsTreeDialog::setupNode, + NULL, NULL); +} + +} -- cgit v1.2.3