aboutsummaryrefslogtreecommitdiffstats
path: root/ui
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
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')
-rw-r--r--ui/qt/protocol_hierarchy_dialog.cpp131
-rw-r--r--ui/qt/protocol_hierarchy_dialog.h7
-rw-r--r--ui/qt/protocol_hierarchy_dialog.ui16
3 files changed, 144 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);
diff --git a/ui/qt/protocol_hierarchy_dialog.h b/ui/qt/protocol_hierarchy_dialog.h
index e7d6e7aced..1c0fb47c59 100644
--- a/ui/qt/protocol_hierarchy_dialog.h
+++ b/ui/qt/protocol_hierarchy_dialog.h
@@ -27,6 +27,9 @@
#include <QMenu>
+class QPushButton;
+class QTreeWidgetItem;
+
namespace Ui {
class ProtocolHierarchyDialog;
}
@@ -63,10 +66,13 @@ signals:
private slots:
void showProtoHierMenu(QPoint pos);
void filterActionTriggered();
+ void on_actionCopyAsCsv_triggered();
+ void on_actionCopyAsYaml_triggered();
void on_buttonBox_helpRequested();
private:
Ui::ProtocolHierarchyDialog *ui;
+ QPushButton *copy_button_;
QMenu ctx_menu_;
PercentBarDelegate percent_bar_delegate_;
QString display_filter_;
@@ -74,6 +80,7 @@ private:
// Callback for g_node_children_foreach
static void addTreeNode(GNode *node, gpointer data);
void updateWidgets();
+ QList<QVariant> protoHierRowData(QTreeWidgetItem *item) const;
};
#endif // PROTOCOL_HIERARCHY_DIALOG_H
diff --git a/ui/qt/protocol_hierarchy_dialog.ui b/ui/qt/protocol_hierarchy_dialog.ui
index ea066ce916..2ae192f7ed 100644
--- a/ui/qt/protocol_hierarchy_dialog.ui
+++ b/ui/qt/protocol_hierarchy_dialog.ui
@@ -87,6 +87,22 @@
</widget>
</item>
</layout>
+ <action name="actionCopyAsCsv">
+ <property name="text">
+ <string>Copy as CSV</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy stream list as CSV.</string>
+ </property>
+ </action>
+ <action name="actionCopyAsYaml">
+ <property name="text">
+ <string>Copy as YAML</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy stream list as YAML.</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections>