aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt/protocol_hierarchy_dialog.cpp
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2015-02-04 08:53:44 -0800
committerGerald Combs <gerald@wireshark.org>2015-02-04 18:26:01 +0000
commita748e831438c52be7d40f1a28874d4f04ac2cda5 (patch)
treeb09573600c09fd3321923a9be01f90917521bb52 /ui/qt/protocol_hierarchy_dialog.cpp
parenta8cc3318b18c60fa713123c56fa35d2b49b12351 (diff)
Qt: Add "Copy As..." to the Protocol Hierarchy stats.
This implementation is slightly different compared to other dialogs since we have nested items. Tweak the bar highlight color look better on Windows while we're here. Change-Id: If0607c4624f304042fe3d6c8a941756b342e703d Reviewed-on: https://code.wireshark.org/review/6953 Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'ui/qt/protocol_hierarchy_dialog.cpp')
-rw-r--r--ui/qt/protocol_hierarchy_dialog.cpp131
1 files changed, 121 insertions, 10 deletions
diff --git a/ui/qt/protocol_hierarchy_dialog.cpp b/ui/qt/protocol_hierarchy_dialog.cpp
index 86c828b600..833029ce8b 100644
--- a/ui/qt/protocol_hierarchy_dialog.cpp
+++ b/ui/qt/protocol_hierarchy_dialog.cpp
@@ -29,10 +29,11 @@
#include "qt_ui_utils.h"
#include "wireshark_application.h"
-#include <QRect>
+#include <QClipboard>
#include <QPainter>
-#include <QTreeWidget>
-#include <QTreeWidgetItem>
+#include <QPushButton>
+#include <QTextStream>
+#include <QTreeWidgetItemIterator>
/*
* @file Protocol Hierarchy Statistics dialog
@@ -42,7 +43,7 @@
*/
// To do:
-// - Copy as... YAML?
+// - Make "Copy as YAML" output a tree?
// - Add time series data to ph_stats_node_t and draw sparklines.
const int protocol_col_ = 0;
@@ -55,8 +56,6 @@ const int end_packets_col_ = 6;
const int end_bytes_col_ = 7;
const int end_bandwidth_col_ = 8;
-#include <QDebug>
-
const int bar_em_width_ = 8;
const double bar_blend_ = 0.15;
void PercentBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
@@ -85,7 +84,7 @@ void PercentBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
cg = QPalette::Inactive;
if (optv4.state & QStyle::State_Selected) {
painter->setPen(optv4.palette.color(cg, QPalette::HighlightedText));
- bar_color = ColorUtils::alphaBlend(optv4.palette.color(cg, QPalette::HighlightedText),
+ bar_color = ColorUtils::alphaBlend(optv4.palette.color(cg, QPalette::Window),
optv4.palette.color(cg, QPalette::Highlight),
bar_blend_);
} else {
@@ -144,15 +143,42 @@ public:
setText(protocol_col_, ph_stats_node->hfinfo->name);
setData(pct_packets_col_, Qt::UserRole, percent_packets_);
- setText(packets_col_, QString::number(ph_stats_node->num_pkts_total));
+ setText(packets_col_, QString::number(total_packets_));
setData(pct_bytes_col_, Qt::UserRole, percent_bytes_);
- setText(bytes_col_, QString::number(ph_stats_node->num_bytes_total));
+ setText(bytes_col_, QString::number(total_bytes_));
setText(bandwidth_col_, seconds > 0.0 ? bits_s_to_qstring(bits_s_) : UTF8_EM_DASH);
setText(end_packets_col_, QString::number(last_packets_));
setText(end_bytes_col_, QString::number(last_bytes_));
setText(end_bandwidth_col_, seconds > 0.0 ? bits_s_to_qstring(end_bits_s_) : UTF8_EM_DASH);
}
+ // Return a QString, int, double, or invalid QVariant representing the raw column data.
+ QVariant colData(int col) const {
+ switch(col) {
+ case protocol_col_:
+ return text(col);
+ case (pct_packets_col_):
+ return percent_packets_;
+ case (packets_col_):
+ return total_packets_;
+ case (pct_bytes_col_):
+ return percent_bytes_;
+ case (bytes_col_):
+ return total_bytes_;
+ case (bandwidth_col_):
+ return bits_s_;
+ case (end_packets_col_):
+ return last_packets_;
+ case (end_bytes_col_):
+ return last_bytes_;
+ case (end_bandwidth_col_):
+ return end_bits_s_;
+ default:
+ break;
+ }
+ return QVariant();
+ }
+
bool operator< (const QTreeWidgetItem &other) const
{
const ProtocolHierarchyTreeWidgetItem &other_phtwi = dynamic_cast<const ProtocolHierarchyTreeWidgetItem&>(other);
@@ -252,6 +278,23 @@ ProtocolHierarchyDialog::ProtocolHierarchyDialog(QWidget &parent, CaptureFile &c
fa = new FilterAction(&ctx_menu_, FilterAction::ActionColorize);
ctx_menu_.addAction(fa);
+ ctx_menu_.addSeparator();
+ ctx_menu_.addAction(ui->actionCopyAsCsv);
+ ctx_menu_.addAction(ui->actionCopyAsYaml);
+
+ copy_button_ = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ApplyRole);
+
+ QMenu *copy_menu = new QMenu();
+ QAction *ca;
+ ca = copy_menu->addAction(tr("as CSV"));
+ ca->setToolTip(ui->actionCopyAsCsv->toolTip());
+ connect(ca, SIGNAL(triggered()), this, SLOT(on_actionCopyAsCsv_triggered()));
+ ca = copy_menu->addAction(tr("as YAML"));
+ ca->setToolTip(ui->actionCopyAsYaml->toolTip());
+ connect(ca, SIGNAL(triggered()), this, SLOT(on_actionCopyAsYaml_triggered()));
+ copy_button_->setMenu(copy_menu);
+
+
display_filter_ = cap_file_.capFile()->dfilter;
updateWidgets();
}
@@ -269,7 +312,9 @@ void ProtocolHierarchyDialog::showProtoHierMenu(QPoint pos)
submenu->setEnabled(enable);
}
foreach (QAction *action, ctx_menu_.actions()) {
- action->setEnabled(enable);
+ if (action != ui->actionCopyAsCsv && action != ui->actionCopyAsYaml) {
+ action->setEnabled(enable);
+ }
}
ctx_menu_.popup(ui->hierStatsTreeWidget->viewport()->mapToGlobal(pos));
@@ -314,6 +359,72 @@ void ProtocolHierarchyDialog::updateWidgets()
ui->hintLabel->setText(hint);
}
+QList<QVariant> ProtocolHierarchyDialog::protoHierRowData(QTreeWidgetItem *item) const
+{
+ QList<QVariant> row_data;
+
+ for (int col = 0; col < ui->hierStatsTreeWidget->columnCount(); col++) {
+ if (!item) {
+ row_data << ui->hierStatsTreeWidget->headerItem()->text(col);
+ } else {
+ ProtocolHierarchyTreeWidgetItem *phti = static_cast<ProtocolHierarchyTreeWidgetItem*>(item);
+ if (phti) {
+ row_data << phti->colData(col);
+ }
+ }
+ }
+ return row_data;
+}
+
+void ProtocolHierarchyDialog::on_actionCopyAsCsv_triggered()
+{
+ QString csv;
+ QTextStream stream(&csv, QIODevice::Text);
+ QTreeWidgetItemIterator iter(ui->hierStatsTreeWidget);
+ bool first = true;
+
+ while (*iter) {
+ QStringList separated_value;
+ QTreeWidgetItem *item = first ? NULL : (*iter);
+
+ foreach (QVariant v, protoHierRowData(item)) {
+ if (!v.isValid()) {
+ separated_value << "\"\"";
+ } else if ((int) v.type() == (int) QMetaType::QString) {
+ separated_value << QString("\"%1\"").arg(v.toString());
+ } else {
+ separated_value << v.toString();
+ }
+ }
+ stream << separated_value.join(",") << endl;
+
+ if (!first) iter++;
+ first = false;
+ }
+ wsApp->clipboard()->setText(stream.readAll());
+}
+
+void ProtocolHierarchyDialog::on_actionCopyAsYaml_triggered()
+{
+ QString yaml;
+ QTextStream stream(&yaml, QIODevice::Text);
+ QTreeWidgetItemIterator iter(ui->hierStatsTreeWidget);
+ bool first = true;
+
+ stream << "---" << endl;
+ while (*iter) {
+ QTreeWidgetItem *item = first ? NULL : (*iter);
+
+ stream << "-" << endl;
+ foreach (QVariant v, protoHierRowData(item)) {
+ stream << " - " << v.toString() << endl;
+ }
+ if (!first) iter++;
+ first = false;
+ }
+ wsApp->clipboard()->setText(stream.readAll());
+}
+
void ProtocolHierarchyDialog::on_buttonBox_helpRequested()
{
wsApp->helpTopicAction(HELP_STATS_PROTO_HIERARCHY_DIALOG);