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
10 #ifndef IO_GRAPH_DIALOG_H
11 #define IO_GRAPH_DIALOG_H
15 #include "epan/epan_dissect.h"
16 #include "epan/prefs.h"
17 #include "ui/preference_utils.h"
19 #include "ui/io_graph_item.h"
21 #include "wireshark_dialog.h"
23 #include <ui/qt/models/uat_model.h>
24 #include <ui/qt/models/uat_delegate.h>
26 #include <wsutil/str_util.h>
31 #include <QTextStream>
32 #include <QItemSelection>
38 class QAbstractButton
;
39 class CopyFromProfileButton
;
46 class QCPAxisTickerDateTime
;
48 // GTK+ set this to 100000 (NUM_IO_ITEMS) before raising it to unlimited
49 // in commit 524583298beb671f43e972476693866754d38a38.
50 // This is the maximum index returned from get_io_graph_index that will
51 // be added to the graph. Thus, for a minimum interval size of 1 μs no
53 // Each io_graph_item_t is 88 bytes on a system with 64 bit time_t, so
54 // the max size we'll attempt to allocate for the array of items is 2.75 GiB
55 // (plus a tiny amount extra for the std::vector bookkeeping.)
57 const int max_io_items_
= 1 << 25;
59 /* define I/O Graph specific UAT columns */
60 enum UatColumnsIOG
{colEnabled
= 0, colAOT
, colName
, colDFilter
, colColor
, colStyle
, colYAxis
, colYField
, colSMAPeriod
, colYAxisFactor
, colMaxNum
};
62 // XXX - Move to its own file?
63 class IOGraph
: public QObject
{
66 // COUNT_TYPE_* in gtk/io_graph.c
67 enum PlotStyles
{ psLine
, psDotLine
, psStepLine
, psDotStepLine
, psImpulse
, psBar
, psStackedBar
, psDot
, psSquare
, psDiamond
, psCross
, psPlus
, psCircle
};
69 explicit IOGraph(QCustomPlot
*parent
);
71 QString
configError() const { return config_err_
; }
72 QString
name() const { return name_
; }
73 void setName(const QString
&name
);
74 void setAOT(bool asAOT
);
75 bool getAOT() const { return asAOT_
; }
76 QString
filter() const { return filter_
; }
77 bool setFilter(const QString
&filter
);
78 void applyCurrentColor();
79 bool visible() const { return visible_
; }
80 void setVisible(bool visible
);
81 bool needRetap() const { return need_retap_
; }
82 void setNeedRetap(bool retap
);
84 void setColor(const QRgb color
);
85 void setPlotStyle(int style
);
86 QString
valueUnitLabel() const;
87 format_size_units_e
formatUnits() const;
88 io_graph_item_unit_t
valueUnits() const { return val_units_
; }
89 void setValueUnits(int val_units
);
90 QString
valueUnitField() const { return vu_field_
; }
91 void setValueUnitField(const QString
&vu_field
);
92 unsigned int movingAveragePeriod() const { return moving_avg_period_
; }
93 void setInterval(int interval
);
95 bool removeFromLegend();
96 QCPGraph
*graph() const { return graph_
; }
97 QCPBars
*bars() const { return bars_
; }
98 double startOffset() const;
99 nstime_t
startTime() const;
100 int packetFromTime(double ts
) const;
101 bool hasItemToShow(int idx
, double value
) const;
102 double getItemValue(int idx
, const capture_file
*cap_file
) const;
103 int maxInterval () const { return cur_idx_
; }
107 unsigned int moving_avg_period_
;
108 unsigned int y_axis_factor_
;
111 void recalcGraphData(capture_file
*cap_file
);
112 void captureEvent(CaptureEvent e
);
113 void reloadValueUnitField();
116 void requestReplot();
117 void requestRecalc();
121 // Callbacks for register_tap_listener
122 static void tapReset(void *iog_ptr
);
123 static tap_packet_status
tapPacket(void *iog_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *data
, tap_flags_t flags
);
124 static void tapDraw(void *iog_ptr
);
126 void removeTapListener();
128 bool showsZero() const;
130 template<class DataMap
> double maxValueFromGraphData(const DataMap
&map
);
131 template<class DataMap
> void scaleGraphData(DataMap
&map
, int scalar
);
133 QCustomPlot
*parent_
;
136 bool tap_registered_
;
142 QString full_filter_
; // Includes vu_field_ if used
144 io_graph_item_unit_t val_units_
;
148 nstime_t start_time_
;
149 bool asAOT_
; // Average Over Time interpretation
151 // Cached data. We should be able to change the Y axis without retapping as
152 // much as is feasible.
153 std::vector
<io_graph_item_t
> items_
;
161 class IOGraphDialog
: public WiresharkDialog
166 explicit IOGraphDialog(QWidget
&parent
, CaptureFile
&cf
, QString displayFilter
= QString(), io_graph_item_unit_t value_units
= IOG_ITEM_UNIT_PACKETS
, QString yfield
= QString());
169 void addGraph(bool checked
, bool asAOT
, QString name
, QString dfilter
, QRgb color_idx
, IOGraph::PlotStyles style
,
170 io_graph_item_unit_t value_units
, QString yfield
, int moving_average
, int yaxisfactor
);
171 void addGraph(bool checked
, bool asAOT
, QString dfilter
, io_graph_item_unit_t value_units
, QString yfield
);
172 void addGraph(bool copy_from_current
= false);
173 void addDefaultGraph(bool enabled
, int idx
= 0);
174 void syncGraphSettings(int row
);
175 qsizetype
graphCount() const;
178 void scheduleReplot(bool now
= false);
179 void scheduleRecalc(bool now
= false);
180 void scheduleRetap(bool now
= false);
184 void captureFileClosing();
185 void keyPressEvent(QKeyEvent
*event
);
189 void modelDataChanged(const QModelIndex
&topLeft
, const QModelIndex
&bottomRight
, const QVector
<int> &roles
);
190 void modelRowsReset();
191 void modelRowsInserted(const QModelIndex
&parent
, int first
, int last
);
192 void modelRowsRemoved(const QModelIndex
&parent
, int first
, int last
);
193 void modelRowsMoved(const QModelIndex
&sourceParent
, int sourceStart
, int sourceEnd
, const QModelIndex
&destinationParent
, int destinationRow
);
196 void goToPacket(int packet_num
);
197 void recalcGraphData(capture_file
*cap_file
);
198 void intervalChanged(int interval
);
199 void reloadValueUnitFields();
202 Ui::IOGraphDialog
*ui
;
203 CopyFromProfileButton
*copy_profile_bt_
;
205 //Model and delegate were chosen over UatFrame because add/remove/copy
206 //buttons would need realignment (UatFrame has its own)
207 QPointer
<UatModel
> uat_model_
;
208 UatDelegate
*uat_delegate_
;
210 // XXX - This needs to stay synced with UAT index
211 QVector
<IOGraph
*> ioGraphs_
;
214 QCPGraph
*base_graph_
;
215 QCPItemTracer
*tracer_
;
216 uint32_t packet_num_
;
217 nstime_t start_time_
;
219 QRubberBand
*rubber_band_
;
223 bool need_replot_
; // Light weight: tell QCP to replot existing data
224 bool need_recalc_
; // Medium weight: recalculate values, then replot
225 bool need_retap_
; // Heavy weight: re-read packet data
229 QSharedPointer
<QCPAxisTicker
> number_ticker_
;
230 QSharedPointer
<QCPAxisTickerDateTime
> datetime_ticker_
;
234 void zoomAxes(bool in
);
235 void zoomXAxis(bool in
);
236 void zoomYAxis(bool in
);
237 void panAxes(int x_pixels
, int y_pixels
);
238 void toggleTracerStyle(bool force_default
= false);
242 QRectF
getZoomRanges(QRect zoom_rect
);
243 void createIOGraph(int currentRow
);
244 void loadProfileGraphs();
245 void makeCsv(QTextStream
&stream
) const;
246 bool saveCsv(const QString
&file_name
) const;
247 IOGraph
*currentActiveGraph() const;
248 bool graphIsEnabled(int row
) const;
249 bool graphAsAOT(int row
) const;
252 static void applyChanges();
254 void copyFromProfile(QString filename
);
255 void updateWidgets();
256 void showContextMenu(const QPoint
&pos
);
257 void graphClicked(QMouseEvent
*event
);
258 void mouseMoved(QMouseEvent
*event
);
259 void mouseReleased(QMouseEvent
*event
);
260 void selectedFrameChanged(QList
<int> frames
);
264 void updateStatistics(void);
265 void copyAsCsvClicked();
267 void graphUatSelectionChanged(const QItemSelection
&selected
, const QItemSelection
&deselected
);
268 void on_intervalComboBox_currentIndexChanged(int index
);
269 void on_todCheckBox_toggled(bool checked
);
270 void on_graphUat_currentItemChanged(const QModelIndex
¤t
, const QModelIndex
&previous
);
272 void on_logCheckBox_toggled(bool checked
);
273 void on_automaticUpdateCheckBox_toggled(bool checked
);
274 void on_newToolButton_clicked();
275 void on_deleteToolButton_clicked();
276 void on_copyToolButton_clicked();
277 void on_clearToolButton_clicked();
278 void on_moveUpwardsToolButton_clicked();
279 void on_moveDownwardsToolButton_clicked();
280 void on_dragRadioButton_toggled(bool checked
);
281 void on_zoomRadioButton_toggled(bool checked
);
282 void on_actionReset_triggered();
283 void on_actionZoomIn_triggered();
284 void on_actionZoomInX_triggered();
285 void on_actionZoomInY_triggered();
286 void on_actionZoomOut_triggered();
287 void on_actionZoomOutX_triggered();
288 void on_actionZoomOutY_triggered();
289 void on_actionMoveUp10_triggered();
290 void on_actionMoveLeft10_triggered();
291 void on_actionMoveRight10_triggered();
292 void on_actionMoveDown10_triggered();
293 void on_actionMoveUp1_triggered();
294 void on_actionMoveLeft1_triggered();
295 void on_actionMoveRight1_triggered();
296 void on_actionMoveDown1_triggered();
297 void on_actionGoToPacket_triggered();
298 void on_actionDragZoom_triggered();
299 void on_actionToggleTimeOrigin_triggered();
300 void on_actionCrosshairs_triggered();
301 void on_buttonBox_helpRequested();
302 void on_buttonBox_accepted();
303 void buttonBoxClicked(QAbstractButton
*button
);
304 void actionLegendTriggered(bool checked
);
305 void actionTimeOfDayTriggered(bool checked
);
306 void actionLogScaleTriggered(bool checked
);
309 #endif // IO_GRAPH_DIALOG_H