1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
/** @file
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef IO_GRAPH_DIALOG_H
#define IO_GRAPH_DIALOG_H
#include <config.h>
#include "epan/epan_dissect.h"
#include "epan/prefs.h"
#include "ui/preference_utils.h"
#include "ui/io_graph_item.h"
#include "wireshark_dialog.h"
#include <ui/qt/models/uat_model.h>
#include <ui/qt/models/uat_delegate.h>
#include <wsutil/str_util.h>
#include <QPointer>
#include <QIcon>
#include <QMenu>
#include <QTextStream>
#include <QItemSelection>
#include <vector>
class QRubberBand;
class QTimer;
class QAbstractButton;
class CopyFromProfileButton;
class QCPBars;
class QCPGraph;
class QCPItemTracer;
class QCustomPlot;
class QCPAxisTicker;
class QCPAxisTickerDateTime;
// GTK+ set this to 100000 (NUM_IO_ITEMS) before raising it to unlimited
// in commit 524583298beb671f43e972476693866754d38a38.
// This is the maximum index returned from get_io_graph_index that will
// be added to the graph. Thus, for a minimum interval size of 1 μs no
// more than 33.55 s.
// Each io_graph_item_t is 88 bytes on a system with 64 bit time_t, so
// the max size we'll attempt to allocate for the array of items is 2.75 GiB
// (plus a tiny amount extra for the std::vector bookkeeping.)
// 2^25 = 16777216
const int max_io_items_ = 1 << 25;
// XXX - Move to its own file?
class IOGraph : public QObject {
Q_OBJECT
public:
// COUNT_TYPE_* in gtk/io_graph.c
enum PlotStyles { psLine, psDotLine, psStepLine, psDotStepLine, psImpulse, psBar, psStackedBar, psDot, psSquare, psDiamond, psCross, psPlus, psCircle };
explicit IOGraph(QCustomPlot *parent);
~IOGraph();
QString configError() const { return config_err_; }
QString name() const { return name_; }
void setName(const QString &name);
QString filter() const { return filter_; }
bool setFilter(const QString &filter);
void applyCurrentColor();
bool visible() const { return visible_; }
void setVisible(bool visible);
bool needRetap() const { return need_retap_; }
void setNeedRetap(bool retap);
QRgb color() const;
void setColor(const QRgb color);
void setPlotStyle(int style);
QString valueUnitLabel() const;
format_size_units_e formatUnits() const;
io_graph_item_unit_t valueUnits() const { return val_units_; }
void setValueUnits(int val_units);
QString valueUnitField() const { return vu_field_; }
void setValueUnitField(const QString &vu_field);
unsigned int movingAveragePeriod() const { return moving_avg_period_; }
void setInterval(int interval);
bool addToLegend();
bool removeFromLegend();
QCPGraph *graph() const { return graph_; }
QCPBars *bars() const { return bars_; }
double startOffset() const;
nstime_t startTime() const;
int packetFromTime(double ts) const;
bool hasItemToShow(int idx, double value) const;
double getItemValue(int idx, const capture_file *cap_file) const;
int maxInterval () const { return cur_idx_; }
void clearAllData();
unsigned int moving_avg_period_;
unsigned int y_axis_factor_;
public slots:
void recalcGraphData(capture_file *cap_file);
void captureEvent(CaptureEvent e);
void reloadValueUnitField();
signals:
void requestReplot();
void requestRecalc();
void requestRetap();
private:
// Callbacks for register_tap_listener
static void tapReset(void *iog_ptr);
static tap_packet_status tapPacket(void *iog_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *data, tap_flags_t flags);
static void tapDraw(void *iog_ptr);
void removeTapListener();
bool showsZero() const;
template<class DataMap> double maxValueFromGraphData(const DataMap &map);
template<class DataMap> void scaleGraphData(DataMap &map, int scalar);
QCustomPlot *parent_;
QString config_err_;
QString name_;
bool tap_registered_;
bool visible_;
bool need_retap_;
QCPGraph *graph_;
QCPBars *bars_;
QString filter_;
QString full_filter_; // Includes vu_field_ if used
QBrush color_;
io_graph_item_unit_t val_units_;
QString vu_field_;
int hf_index_;
int interval_;
nstime_t start_time_;
// Cached data. We should be able to change the Y axis without retapping as
// much as is feasible.
std::vector<io_graph_item_t> items_;
int cur_idx_;
};
namespace Ui {
class IOGraphDialog;
}
class IOGraphDialog : public WiresharkDialog
{
Q_OBJECT
public:
explicit IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFilter = QString(), io_graph_item_unit_t value_units = IOG_ITEM_UNIT_PACKETS, QString yfield = QString());
~IOGraphDialog();
enum UatColumns { colEnabled = 0, colName, colDFilter, colColor, colStyle, colYAxis, colYField, colSMAPeriod, colYAxisFactor, colMaxNum};
void addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style,
io_graph_item_unit_t value_units, QString yfield, int moving_average, int yaxisfactor);
void addGraph(bool checked, QString dfilter, io_graph_item_unit_t value_units, QString yfield);
void addGraph(bool copy_from_current = false);
void addDefaultGraph(bool enabled, int idx = 0);
void syncGraphSettings(int row);
qsizetype graphCount() const;
public slots:
void scheduleReplot(bool now = false);
void scheduleRecalc(bool now = false);
void scheduleRetap(bool now = false);
void reloadFields();
protected:
void captureFileClosing();
void keyPressEvent(QKeyEvent *event);
void reject();
protected slots:
void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
void modelRowsReset();
void modelRowsInserted(const QModelIndex &parent, int first, int last);
void modelRowsRemoved(const QModelIndex &parent, int first, int last);
void modelRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow);
signals:
void goToPacket(int packet_num);
void recalcGraphData(capture_file *cap_file);
void intervalChanged(int interval);
void reloadValueUnitFields();
private:
Ui::IOGraphDialog *ui;
CopyFromProfileButton *copy_profile_bt_;
//Model and delegate were chosen over UatFrame because add/remove/copy
//buttons would need realignment (UatFrame has its own)
QPointer<UatModel> uat_model_;
UatDelegate *uat_delegate_;
// XXX - This needs to stay synced with UAT index
QVector<IOGraph*> ioGraphs_;
QString hint_err_;
QCPGraph *base_graph_;
QCPItemTracer *tracer_;
uint32_t packet_num_;
nstime_t start_time_;
bool mouse_drags_;
QRubberBand *rubber_band_;
QPoint rb_origin_;
QMenu ctx_menu_;
QTimer *stat_timer_;
bool need_replot_; // Light weight: tell QCP to replot existing data
bool need_recalc_; // Medium weight: recalculate values, then replot
bool need_retap_; // Heavy weight: re-read packet data
bool auto_axes_;
int precision_;
QSharedPointer<QCPAxisTicker> number_ticker_;
QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
// void fillGraph();
void zoomAxes(bool in);
void zoomXAxis(bool in);
void zoomYAxis(bool in);
void panAxes(int x_pixels, int y_pixels);
void toggleTracerStyle(bool force_default = false);
void getGraphInfo();
void updateHint();
void updateLegend();
QRectF getZoomRanges(QRect zoom_rect);
void createIOGraph(int currentRow);
void loadProfileGraphs();
void makeCsv(QTextStream &stream) const;
bool saveCsv(const QString &file_name) const;
IOGraph *currentActiveGraph() const;
bool graphIsEnabled(int row) const;
private slots:
static void applyChanges();
void copyFromProfile(QString filename);
void updateWidgets();
void showContextMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void mouseMoved(QMouseEvent *event);
void mouseReleased(QMouseEvent *event);
void selectedFrameChanged(QList<int> frames);
void moveLegend();
void resetAxes();
void updateStatistics(void);
void copyAsCsvClicked();
void graphUatSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_intervalComboBox_currentIndexChanged(int index);
void on_todCheckBox_toggled(bool checked);
void on_graphUat_currentItemChanged(const QModelIndex ¤t, const QModelIndex &previous);
void on_logCheckBox_toggled(bool checked);
void on_automaticUpdateCheckBox_toggled(bool checked);
void on_enableLegendCheckBox_toggled(bool checked);
void on_newToolButton_clicked();
void on_deleteToolButton_clicked();
void on_copyToolButton_clicked();
void on_clearToolButton_clicked();
void on_moveUpwardsToolButton_clicked();
void on_moveDownwardsToolButton_clicked();
void on_dragRadioButton_toggled(bool checked);
void on_zoomRadioButton_toggled(bool checked);
void on_actionReset_triggered();
void on_actionZoomIn_triggered();
void on_actionZoomInX_triggered();
void on_actionZoomInY_triggered();
void on_actionZoomOut_triggered();
void on_actionZoomOutX_triggered();
void on_actionZoomOutY_triggered();
void on_actionMoveUp10_triggered();
void on_actionMoveLeft10_triggered();
void on_actionMoveRight10_triggered();
void on_actionMoveDown10_triggered();
void on_actionMoveUp1_triggered();
void on_actionMoveLeft1_triggered();
void on_actionMoveRight1_triggered();
void on_actionMoveDown1_triggered();
void on_actionGoToPacket_triggered();
void on_actionDragZoom_triggered();
void on_actionToggleTimeOrigin_triggered();
void on_actionCrosshairs_triggered();
void on_buttonBox_helpRequested();
void on_buttonBox_accepted();
void buttonBoxClicked(QAbstractButton *button);
};
#endif // IO_GRAPH_DIALOG_H
|