update epan/dissectors/pidl/drsuapi/drsuapi.idl from samba
[wireshark-sm.git] / ui / qt / capture_info_dialog.cpp
blobe171ba3d389b349e1b6780f695754006b082c9a7
1 /* capture_info_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10 #include "config.h"
12 #include "wireshark.h"
14 #include "ui/capture_info.h"
16 #include "epan/capture_dissectors.h"
17 #include "epan/proto.h"
19 #include "ui/capture.h"
21 #include "capture_info_dialog.h"
22 #include <ui_capture_info_dialog.h>
24 #include "main_application.h"
26 #include "ui/qt/models/sparkline_delegate.h"
28 #include "utils/qt_ui_utils.h"
30 #include <QMainWindow>
31 #include <QPushButton>
33 // The GTK+ version of this dialog showed a list of protocols and a simple bar graph
34 // (progress bars) showing their portion of the total number of packets. We show a
35 // a time series for each protocol using a sparkline. If we wanted to show bar graphs
36 // instead we could do so using QProgressBars or using PercentBarDelegates.
38 extern "C" {
40 // Callbacks defined in ui/capture_info.h.
42 /* create the capture info dialog */
43 /* will keep pointers to the fields in the counts parameter */
44 void capture_info_ui_create(
45 capture_info *cinfo,
46 capture_session *cap_session)
48 // cinfo->ui should have three values:
49 // - The main window, set in MainWindow::startCapture.
50 // - This dialog, set below.
51 // - NULL, set in our destructor.
53 if (!cinfo || !cinfo->ui) return;
54 if (!cap_session) return;
55 QMainWindow *main_window = qobject_cast<QMainWindow *>((QObject *)cinfo->ui);
56 if (!main_window) return;
58 // ...and we take it over from here.
59 CaptureInfoDialog *ci_dlg = new CaptureInfoDialog(cinfo, cap_session, main_window);
60 cinfo->ui = ci_dlg;
61 ci_dlg->show();
64 /* update the capture info dialog */
65 /* As this function is a bit time critical while capturing, */
66 /* prepare everything possible in the capture_info_ui_create() function above! */
67 void capture_info_ui_update(
68 capture_info *cinfo)
70 CaptureInfoDialog *ci_dlg = qobject_cast<CaptureInfoDialog *>((QObject *)cinfo->ui);
71 if (!ci_dlg) return;
72 ci_dlg->updateInfo();
75 /* destroy the capture info dialog again */
76 void capture_info_ui_destroy(
77 capture_info *cinfo)
79 CaptureInfoDialog *ci_dlg = qobject_cast<CaptureInfoDialog *>((QObject *)cinfo->ui);
80 if (!ci_dlg) return;
81 cinfo->ui = NULL;
82 delete ci_dlg;
85 } // extern "C"
87 CaptureInfoDialog::CaptureInfoDialog(struct _capture_info *cap_info, struct _capture_session *cap_session, QWidget *parent) :
88 GeometryStateDialog(parent),
89 ui(new Ui::CaptureInfoDialog),
90 cap_info_(cap_info),
91 cap_session_(cap_session)
93 ui->setupUi(this);
94 loadGeometry();
95 setWindowTitle(mainApp->windowTitleString(tr("Capture Information")));
97 QPushButton *button = ui->buttonBox->button(QDialogButtonBox::Abort);
98 button->setText(tr("Stop Capture"));
99 connect(button, &QPushButton::clicked, this, &CaptureInfoDialog::stopCapture);
101 ci_model_ = new CaptureInfoModel(cap_info, this);
102 ui->treeView->setModel(ci_model_);
104 ui->treeView->setItemDelegateForColumn(1, new SparkLineDelegate(this));
106 duration_.start();
109 CaptureInfoDialog::~CaptureInfoDialog()
111 delete ui;
112 cap_info_->ui = NULL;
115 void CaptureInfoDialog::updateInfo()
117 int secs = int(duration_.elapsed() / 1000);
118 QString duration = tr("%1 packets, %2:%3:%4")
119 .arg(cap_info_->counts->total)
120 .arg(secs / 3600, 2, 10, QChar('0'))
121 .arg(secs % 3600 / 60, 2, 10, QChar('0'))
122 .arg(secs % 60, 2, 10, QChar('0'));
123 ui->infoLabel->setText(duration);
125 ci_model_->updateInfo();
126 ui->treeView->resizeColumnToContents(0);
129 void CaptureInfoDialog::stopCapture()
131 #ifdef HAVE_LIBPCAP
132 capture_stop(cap_session_); // ...or we could connect to MainWindow::stopCapture.
133 #endif // HAVE_LIBPCAP
136 CaptureInfoModel::CaptureInfoModel(struct _capture_info *cap_info, QObject *parent) :
137 QAbstractTableModel(parent),
138 cap_info_(cap_info),
139 samples_(0),
140 last_other_(0)
144 void CaptureInfoModel::updateInfo()
146 if (!cap_info_) return;
148 GHashTableIter iter;
149 void *key, *value;
151 samples_++;
152 other_points_.append(cap_info_->counts->other - last_other_);
153 last_other_ = cap_info_->counts->other;
155 g_hash_table_iter_init (&iter, cap_info_->counts->counts_hash);
156 while (g_hash_table_iter_next (&iter, &key, &value)) {
157 int proto_id = GPOINTER_TO_INT(key);
158 int cur_count = (int) capture_dissector_get_count(cap_info_->counts, proto_id);
159 if (!points_.contains(proto_id)) {
160 emit beginInsertRows(QModelIndex(), rowCount(), rowCount());
161 QVector<int> zeroes = QVector<int>(samples_, 0);
162 points_[proto_id] = zeroes.toList();
163 last_count_[proto_id] = 0;
164 emit endInsertRows();
165 } else {
166 points_[proto_id].append(cur_count - last_count_[proto_id]);
167 last_count_[proto_id] = cur_count;
170 emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
173 int CaptureInfoModel::rowCount(const QModelIndex &) const
175 if (!cap_info_) return 0;
176 return static_cast<int>(points_.keys().size()) + 1;
179 int CaptureInfoModel::columnCount(const QModelIndex &) const
181 return 2;
184 QVariant CaptureInfoModel::data(const QModelIndex &index, int role) const
186 QList<int> proto_ids = points_.keys();
187 int row = index.row();
189 if (role == Qt::DisplayRole && index.column() == 0) {
190 if (row < proto_ids.size()) {
191 int proto_id = proto_ids.at(row);
192 return QString(proto_get_protocol_short_name(find_protocol_by_id(proto_id)));
193 } else {
194 return tr("Other");
196 } else if (role == Qt::UserRole && index.column() == 1) {
197 if (row < proto_ids.size()) {
198 int proto_id = proto_ids.at(row);
199 return QVariant::fromValue(points_[proto_id]);
200 } else {
201 return QVariant::fromValue(other_points_);
204 return QVariant();