1 /* traffic_table_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "traffic_table_dialog.h"
23 #include <ui_traffic_table_dialog.h>
25 #include <epan/addr_resolv.h>
26 #include <epan/prefs.h>
28 //#include <epan/dissectors/packet-tcp.h>
30 #include "ui/recent.h"
31 //#include "ui/tap-tcp-stream.h"
33 #include "wireshark_application.h"
37 #include <QContextMenuEvent>
38 #include <QDialogButtonBox>
41 #include <QMessageBox>
42 #include <QPushButton>
44 #include <QTreeWidget>
45 #include <QTextStream>
46 #include <QToolButton>
49 // - Add "copy" items to the menu.
52 // - Name resolution doesn't do anything if its preference is disabled.
53 // - Columns don't resize correctly.
54 // - Closing the capture file clears conversation data.
56 TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const char *filter, const QString &table_name) :
57 WiresharkDialog(parent, cf),
58 ui(new Ui::TrafficTableDialog),
65 ui->enabledTypesPushButton->setText(tr("%1 Types").arg(table_name));
66 setWindowSubtitle(QString("%1s").arg(table_name));
68 // XXX Use recent settings instead
69 resize(parent.width(), parent.height() * 3 / 4);
71 QMenu *copy_menu = new QMenu();
73 copy_bt_ = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
74 ca = copy_menu->addAction(tr("as CSV"));
75 ca->setToolTip(tr("Copy all values of this page to the clipboard in CSV (Comma Separated Values) format."));
76 connect(ca, SIGNAL(triggered()), this, SLOT(copyAsCsv()));
77 ca = copy_menu->addAction(tr("as YAML"));
78 ca->setToolTip(tr("Copy all values of this page to the clipboard in the YAML data serialization format."));
79 connect(ca, SIGNAL(triggered()), this, SLOT(copyAsYaml()));
80 copy_bt_->setMenu(copy_menu);
82 ui->enabledTypesPushButton->setMenu(&traffic_type_menu_);
83 ui->nameResolutionCheckBox->setChecked(gbl_resolv_flags.network_name);
84 ui->trafficTableTabWidget->setFocus();
86 connect(ui->trafficTableTabWidget, SIGNAL(currentChanged(int)),
87 this, SLOT(itemSelectionChanged()));
88 connect(&cap_file_, SIGNAL(captureFileClosing()), this, SLOT(captureFileClosing()));
91 TrafficTableDialog::~TrafficTableDialog()
96 const QList<int> TrafficTableDialog::defaultProtos() const
98 // Reasonable defaults?
99 return QList<int>() << proto_get_id_by_filter_name( "tcp" ) << proto_get_id_by_filter_name( "eth" )
100 << proto_get_id_by_filter_name( "ip" ) << proto_get_id_by_filter_name( "ipv6" )
101 << proto_get_id_by_filter_name( "udp" );
104 void TrafficTableDialog::fillTypeMenu(QList<int> &enabled_protos)
106 for (guint i = 0; i < conversation_table_get_num(); i++) {
107 int proto_id = get_conversation_proto_id(get_conversation_table_by_num(i));
111 QString title = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
113 QAction *endp_action = new QAction(title, this);
114 endp_action->setData(qVariantFromValue(proto_id));
115 endp_action->setCheckable(true);
116 endp_action->setChecked(enabled_protos.contains(proto_id));
117 connect(endp_action, SIGNAL(triggered()), this, SLOT(toggleTable()));
118 traffic_type_menu_.addAction(endp_action);
122 QDialogButtonBox *TrafficTableDialog::buttonBox() const
124 return ui->buttonBox;
127 QTabWidget *TrafficTableDialog::trafficTableTabWidget() const
129 return ui->trafficTableTabWidget;
132 QCheckBox *TrafficTableDialog::displayFilterCheckBox() const
134 return ui->displayFilterCheckBox;
137 QCheckBox *TrafficTableDialog::nameResolutionCheckBox() const
139 return ui->nameResolutionCheckBox;
142 QPushButton *TrafficTableDialog::enabledTypesPushButton() const
144 return ui->enabledTypesPushButton;
147 void TrafficTableDialog::on_nameResolutionCheckBox_toggled(bool checked)
153 void TrafficTableDialog::on_displayFilterCheckBox_toggled(bool checked)
155 if (!cap_file_.isValid()) {
159 QByteArray filter_utf8;
160 const char *filter = NULL;
162 filter = cap_file_.capFile()->dfilter;
163 } else if (!filter_.isEmpty()) {
164 filter_utf8 = filter_.toUtf8();
165 filter = filter_utf8.constData();
168 for (int i = 0; i < ui->trafficTableTabWidget->count(); i++) {
169 TrafficTableTreeWidget *cur_tree = qobject_cast<TrafficTableTreeWidget *>(ui->trafficTableTabWidget->widget(i));
170 set_tap_dfilter(cur_tree->trafficTreeHash(), filter);
173 cap_file_.retapPackets();
176 void TrafficTableDialog::setTabText(QWidget *tree, const QString &text)
178 // Could use QObject::sender as well
179 int index = ui->trafficTableTabWidget->indexOf(tree);
181 ui->trafficTableTabWidget->setTabText(index, text);
185 void TrafficTableDialog::toggleTable()
187 QAction *ca = qobject_cast<QAction *>(QObject::sender());
192 int proto_id = ca->data().value<int>();
193 register_ct_t* table = get_conversation_by_proto_id(proto_id);
195 bool new_table = addTrafficTable(table);
198 if (ca->isChecked()) {
199 ui->trafficTableTabWidget->setCurrentWidget(proto_id_to_tree_[proto_id]);
203 cap_file_.retapPackets();
207 void TrafficTableDialog::updateWidgets()
209 QWidget *cur_w = ui->trafficTableTabWidget->currentWidget();
210 ui->trafficTableTabWidget->setUpdatesEnabled(false);
211 ui->trafficTableTabWidget->clear();
212 foreach (QAction *ca, traffic_type_menu_.actions()) {
213 int proto_id = ca->data().value<int>();
214 if (proto_id_to_tree_.contains(proto_id) && ca->isChecked()) {
215 ui->trafficTableTabWidget->addTab(proto_id_to_tree_[proto_id],
216 proto_id_to_tree_[proto_id]->trafficTreeTitle());
217 proto_id_to_tree_[proto_id]->setNameResolutionEnabled(ui->nameResolutionCheckBox->isChecked());
220 ui->trafficTableTabWidget->setCurrentWidget(cur_w);
221 ui->trafficTableTabWidget->setUpdatesEnabled(true);
224 QList<QVariant> TrafficTableDialog::curTreeRowData(int row) const
226 TrafficTableTreeWidget *cur_tree = qobject_cast<TrafficTableTreeWidget *>(ui->trafficTableTabWidget->currentWidget());
228 return QList<QVariant>();
231 return cur_tree->rowData(row);
234 void TrafficTableDialog::copyAsCsv()
236 QTreeWidget *cur_tree = qobject_cast<QTreeWidget *>(ui->trafficTableTabWidget->currentWidget());
242 QTextStream stream(&csv, QIODevice::Text);
243 for (int row = -1; row < cur_tree->topLevelItemCount(); row ++) {
245 foreach (QVariant v, curTreeRowData(row)) {
248 } else if ((int) v.type() == (int) QMetaType::QString) {
249 rdsl << QString("\"%1\"").arg(v.toString());
251 rdsl << v.toString();
254 stream << rdsl.join(",") << endl;
256 wsApp->clipboard()->setText(stream.readAll());
259 void TrafficTableDialog::copyAsYaml()
261 QTreeWidget *cur_tree = qobject_cast<QTreeWidget *>(ui->trafficTableTabWidget->currentWidget());
267 QTextStream stream(&yaml, QIODevice::Text);
268 stream << "---" << endl;
269 for (int row = -1; row < cur_tree->topLevelItemCount(); row ++) {
270 stream << "-" << endl;
271 foreach (QVariant v, curTreeRowData(row)) {
272 stream << " - " << v.toString() << endl;
275 wsApp->clipboard()->setText(stream.readAll());
279 TrafficTableTreeWidget::TrafficTableTreeWidget(QWidget *parent, register_ct_t *table) :
283 resolve_names_(false)
285 setRootIsDecorated(false);
286 sortByColumn(0, Qt::AscendingOrder);
288 connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateItems()));
291 TrafficTableTreeWidget::~TrafficTableTreeWidget()
293 remove_tap_listener(&hash_);
296 QList<QVariant> TrafficTableTreeWidget::rowData(int row) const
298 QList<QVariant> row_data;
300 if (row >= topLevelItemCount()) {
304 for (int col = 0; col < columnCount(); col++) {
305 if (isColumnHidden(col)) {
309 row_data << headerItem()->text(col);
311 TrafficTableTreeWidgetItem *ti = static_cast<TrafficTableTreeWidgetItem *>(topLevelItem(row));
313 row_data << ti->colData(col, resolve_names_);
320 void TrafficTableTreeWidget::setNameResolutionEnabled(bool enable)
322 if (resolve_names_ != enable) {
323 resolve_names_ = enable;
328 void TrafficTableTreeWidget::contextMenuEvent(QContextMenuEvent *event)
330 bool enable = currentItem() != NULL ? true : false;
332 foreach (QMenu *submenu, ctx_menu_.findChildren<QMenu*>()) {
333 submenu->setEnabled(enable);
336 ctx_menu_.exec(event->globalPos());
345 * indent-tabs-mode: nil
348 * ex: set shiftwidth=4 tabstop=8 expandtab:
349 * :indentSize=4:tabSize=8:noTabs=true: