Revert "tap: change glib functions to wmem."
[jlayton/wireshark.git] / ui / qt / lbm_lbtrm_transport_dialog.cpp
1 /* lbm_lbtrm_transport_dialog.cpp
2  *
3  * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "lbm_lbtrm_transport_dialog.h"
25 #include <ui_lbm_lbtrm_transport_dialog.h>
26
27 #include "file.h"
28
29 #include "qt_ui_utils.h"
30 #include "wireshark_application.h"
31
32 #include <QClipboard>
33 #include <QMenu>
34 #include <QMessageBox>
35 #include <QTreeWidget>
36 #include <QTreeWidgetItemIterator>
37 #include <QMenu>
38
39 #include <epan/packet_info.h>
40 #include <epan/tap.h>
41 #include <epan/to_str.h>
42 #include <epan/dissectors/packet-lbm.h>
43 #include <wsutil/nstime.h>
44
45 namespace
46 {
47     static const int Source_AddressTransport_Column = 0;
48     static const int Source_DataFrames_Column = 1;
49     static const int Source_DataBytes_Column = 2;
50     static const int Source_DataFramesBytes_Column = 3;
51     static const int Source_DataRate_Column = 4;
52     static const int Source_RXDataFrames_Column = 5;
53     static const int Source_RXDataBytes_Column = 6;
54     static const int Source_RXDataFramesBytes_Column = 7;
55     static const int Source_RXDataRate_Column = 8;
56     static const int Source_NCFFrames_Column = 9;
57     static const int Source_NCFCount_Column = 10;
58     static const int Source_NCFBytes_Column = 11;
59     static const int Source_NCFFramesBytes_Column = 12;
60     static const int Source_NCFCountBytes_Column = 13;
61     static const int Source_NCFFramesCount_Column = 14;
62     static const int Source_NCFFramesCountBytes_Column = 15;
63     static const int Source_NCFRate_Column = 16;
64     static const int Source_SMFrames_Column = 17;
65     static const int Source_SMBytes_Column = 18;
66     static const int Source_SMFramesBytes_Column = 19;
67     static const int Source_SMRate_Column = 20;
68
69     static const int Receiver_AddressTransport_Column = 0;
70     static const int Receiver_NAKFrames_Column = 1;
71     static const int Receiver_NAKCount_Column = 2;
72     static const int Receiver_NAKBytes_Column = 3;
73     static const int Receiver_NAKRate_Column = 4;
74
75     static const int Detail_SQN_Column = 0;
76     static const int Detail_Count_Column = 1;
77     static const int Detail_Frame_Column = 2;
78
79     static const double OneKilobit = 1000.0;
80     static const double OneMegabit = OneKilobit * OneKilobit;
81     static const double OneGigabit = OneMegabit * OneKilobit;
82 }
83
84 static QString format_rate(const nstime_t & elapsed, guint64 bytes)
85 {
86     QString result;
87     double elapsed_sec;
88     double rate;
89
90     if (((elapsed.secs == 0) && (elapsed.nsecs == 0)) || (bytes == 0))
91     {
92         return (QString("0"));
93     }
94
95     elapsed_sec = elapsed.secs + (((double)elapsed.nsecs) / 1000000000.0);
96     rate = ((double)(bytes * 8)) / elapsed_sec;
97
98     // Currently rate is in bps
99     if (rate >= OneGigabit)
100     {
101         rate /= OneGigabit;
102         result = QString("%1G").arg(rate, 0, 'f', 2);
103     }
104     else if (rate >= OneMegabit)
105     {
106         rate /= OneMegabit;
107         result = QString("%1M").arg(rate, 0, 'f', 2);
108     }
109     else if (rate >= OneKilobit)
110     {
111         rate /= OneKilobit;
112         result = QString("%1K").arg(rate, 0, 'f', 2);
113     }
114     else
115     {
116         result = QString("%1").arg(rate, 0, 'f', 2);
117     }
118     return (result);
119 }
120
121 // Note:
122 // LBMLBTRMFrameEntry, LBMLBTRMSQNEntry, LBMLBTRMNCFReasonEntry, LBMLBTRMNCFSQNEntry, LBMLBTRMSourceTransportEntry, LBMLBTRMSourceEntry,
123 // LBMLBTRMReceiverTransportEntry, and LBMLBTRMReceiverEntry are all derived from  a QTreeWidgetItem. Each instantiation can exist
124 // in two places: in a QTreeWidget, and in a containing QMap.
125 //
126 // For example:
127 // - LBMLBTRMTransportDialogInfo contains a QMap of the sources (LBMLBTRMSourceEntry) and receivers (LBMLBTRMReceiverEntry)
128 // - A source (LBMLBTRMSourceEntry) contains a QMap of the source transports originating from it (LBMLBTRMSourceTransportEntry)
129 // - A source transport (LBMLBTRMSourceTransportEntry) contains QMaps of data, RX data, and SM SQNs (LBMLBTRMSQNEntry) and NCF SQNs
130 //   (LBMLBTRMNCFSQNEntry)
131 // - A data SQN (LBMLBTRMSQNEntry) contains a QMap of the frames (LBMLBTRMFrameEntry) in which that SQN appears
132 //
133 // Not all of the entries actually appear in a QTreeWidget at one time. For example, in the source details, if no specific source
134 // transport is selected, nothing is in the source details tree. If Data SQNs is selected, then those details appear in the source
135 // details tree. Switching to RX Data SQNs removes whatever is currently in the source details tree, and adds the RX details for
136 // the selected transport.
137 //
138 // The actual owner of one of the above QTreeWidgetItem-derived items is the QMap container in its parent. The item is "loaned" to
139 // the QTreeWidget for display.
140 //
141 // All of this is to explain why
142 // 1) we are frequently adding things to a QTreeWidget
143 // 2) things are removed (takeTopLevelItem) from a QTreeWidget
144 // 3) destruction involves removing all items from all QTreeWidgets (rather than letting QTreeWidget delete them)
145 // 4) the destructor for each item has the form
146 //    <for each QMap container>
147 //      for (XXXMapIterator it = m_xxx.begin(); it != m_xxx.end(); it++)
148 //      {
149 //          delete *it;
150 //      }
151 //      m_xxx.clear();
152 //    The for-loop calls the destructor for each item, while the clear() cleans up the space used by the QMap itself.
153
154 // A frame entry
155 class LBMLBTRMFrameEntry : public QTreeWidgetItem
156 {
157     public:
158         LBMLBTRMFrameEntry(guint32 frame);
159         virtual ~LBMLBTRMFrameEntry(void) { }
160         guint32 getFrame(void) { return (m_frame); }
161
162     private:
163         LBMLBTRMFrameEntry(void) { }
164         guint32 m_frame;
165 };
166
167 LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(guint32 frame) :
168     QTreeWidgetItem(),
169     m_frame(frame)
170 {
171     setText(Detail_SQN_Column, QString(" "));
172     setText(Detail_Count_Column, QString(" "));
173     setText(Detail_Frame_Column, QString("%1").arg(m_frame));
174 }
175
176 typedef QMap<guint32, LBMLBTRMFrameEntry *> LBMLBTRMFrameMap;
177 typedef QMap<guint32, LBMLBTRMFrameEntry *>::iterator LBMLBTRMFrameMapIterator;
178
179 // A SQN (SeQuence Number) entry
180 class LBMLBTRMSQNEntry : public QTreeWidgetItem
181 {
182     public:
183         LBMLBTRMSQNEntry(guint32 sqn);
184         virtual ~LBMLBTRMSQNEntry(void);
185         void processFrame(guint32 frame);
186
187     private:
188         LBMLBTRMSQNEntry(void);
189         guint32 m_sqn;
190         guint32 m_count;
191         LBMLBTRMFrameMap m_frames;
192 };
193
194 LBMLBTRMSQNEntry::LBMLBTRMSQNEntry(guint32 sqn) :
195     QTreeWidgetItem(),
196     m_sqn(sqn),
197     m_count(0),
198     m_frames()
199 {
200     setText(Detail_SQN_Column, QString("%1").arg(m_sqn));
201     setTextAlignment(Detail_SQN_Column, Qt::AlignRight);
202     setText(Detail_Count_Column, QString("%1").arg(m_count));
203     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
204     setText(Detail_Frame_Column, QString(" "));
205 }
206
207 LBMLBTRMSQNEntry::~LBMLBTRMSQNEntry(void)
208 {
209     for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
210     {
211         delete *it;
212     }
213     m_frames.clear();
214 }
215
216 void LBMLBTRMSQNEntry::processFrame(guint32 frame)
217 {
218     LBMLBTRMFrameMapIterator it;
219
220     it = m_frames.find(frame);
221     if (m_frames.end() == it)
222     {
223         LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame);
224         m_frames.insert(frame, entry);
225         addChild(entry);
226         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
227     }
228     m_count++;
229     setText(Detail_Count_Column, QString("%1").arg(m_count));
230     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
231 }
232
233 // An NCF (Nak ConFirmation) Reason entry
234 class LBMLBTRMNCFReasonEntry : public QTreeWidgetItem
235 {
236     public:
237         LBMLBTRMNCFReasonEntry(guint8 reason);
238         virtual ~LBMLBTRMNCFReasonEntry(void);
239         void processFrame(guint32 frame);
240
241     private:
242         LBMLBTRMNCFReasonEntry(void);
243         guint8 m_reason;
244         QString m_reason_string;
245         guint32 m_count;
246         LBMLBTRMFrameMap m_frames;
247 };
248
249 LBMLBTRMNCFReasonEntry::LBMLBTRMNCFReasonEntry(guint8 reason) :
250     QTreeWidgetItem(),
251     m_reason(reason),
252     m_reason_string(),
253     m_count(0),
254     m_frames()
255 {
256     switch (m_reason)
257     {
258         case LBTRM_NCF_REASON_NO_RETRY:
259             m_reason_string = "No Retry";
260             break;
261         case LBTRM_NCF_REASON_IGNORED:
262             m_reason_string = "Ignored";
263             break;
264         case LBTRM_NCF_REASON_RX_DELAY:
265             m_reason_string = "Retransmit Delay";
266             break;
267         case LBTRM_NCF_REASON_SHED:
268             m_reason_string = "Shed";
269             break;
270         default:
271             m_reason_string = QString("Unknown (%1)").arg(m_reason);
272             break;
273     }
274     setText(Detail_SQN_Column, m_reason_string);
275     setText(Detail_Count_Column, QString("%1").arg(m_count));
276     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
277     setText(Detail_Frame_Column, QString(" "));
278 }
279
280 LBMLBTRMNCFReasonEntry::~LBMLBTRMNCFReasonEntry(void)
281 {
282     for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
283     {
284         delete *it;
285     }
286     m_frames.clear();
287 }
288
289 void LBMLBTRMNCFReasonEntry::processFrame(guint32 frame)
290 {
291     LBMLBTRMFrameMapIterator it;
292
293     it = m_frames.find(frame);
294     if (m_frames.end() == it)
295     {
296         LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame);
297         m_frames.insert(frame, entry);
298         addChild(entry);
299         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
300     }
301     m_count++;
302     setText(Detail_Count_Column, QString("%1").arg(m_count));
303     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
304 }
305
306 typedef QMap<guint32, LBMLBTRMNCFReasonEntry *> LBMLBTRMNCFReasonMap;
307 typedef QMap<guint32, LBMLBTRMNCFReasonEntry *>::iterator LBMLBTRMNCFReasonMapIterator;
308
309 // An NCF SQN entry
310 class LBMLBTRMNCFSQNEntry : public QTreeWidgetItem
311 {
312     public:
313         LBMLBTRMNCFSQNEntry(guint32 sqn);
314         virtual ~LBMLBTRMNCFSQNEntry(void);
315         void processFrame(guint8 reason, guint32 frame);
316
317     private:
318         LBMLBTRMNCFSQNEntry(void);
319         guint32 m_sqn;
320         guint32 m_count;
321         LBMLBTRMNCFReasonMap m_reasons;
322 };
323
324 LBMLBTRMNCFSQNEntry::LBMLBTRMNCFSQNEntry(guint32 sqn) :
325     QTreeWidgetItem(),
326     m_sqn(sqn),
327     m_count(0),
328     m_reasons()
329 {
330     setText(Detail_SQN_Column, QString("%1").arg(m_sqn));
331     setTextAlignment(Detail_SQN_Column, Qt::AlignRight);
332     setText(Detail_Count_Column, QString("%1").arg(m_count));
333     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
334     setText(Detail_Frame_Column, QString(" "));
335 }
336
337 LBMLBTRMNCFSQNEntry::~LBMLBTRMNCFSQNEntry(void)
338 {
339     for (LBMLBTRMNCFReasonMapIterator it = m_reasons.begin(); it != m_reasons.end(); it++)
340     {
341         delete *it;
342     }
343     m_reasons.clear();
344 }
345
346 void LBMLBTRMNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
347 {
348     LBMLBTRMNCFReasonMapIterator it;
349     LBMLBTRMNCFReasonEntry * entry = NULL;
350
351     it = m_reasons.find(reason);
352     if (m_reasons.end() == it)
353     {
354         entry = new LBMLBTRMNCFReasonEntry(reason);
355         m_reasons.insert(reason, entry);
356         addChild(entry);
357         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
358     }
359     else
360     {
361         entry = it.value();
362     }
363     m_count++;
364     setText(Detail_Count_Column, QString("%1").arg(m_count));
365     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
366     entry->processFrame(frame);
367 }
368
369 typedef QMap<guint32, LBMLBTRMSQNEntry *> LBMLBTRMSQNMap;
370 typedef QMap<guint32, LBMLBTRMSQNEntry *>::iterator LBMLBTRMSQNMapIterator;
371 typedef QMap<guint32, LBMLBTRMNCFSQNEntry *> LBMLBTRMNCFSQNMap;
372 typedef QMap<guint32, LBMLBTRMNCFSQNEntry *>::iterator LBMLBTRMNCFSQNMapIterator;
373
374 // A source transport entry
375 class LBMLBTRMSourceTransportEntry : public QTreeWidgetItem
376 {
377         friend class LBMLBTRMTransportDialog;
378
379     public:
380         LBMLBTRMSourceTransportEntry(const QString & transport);
381         virtual ~LBMLBTRMSourceTransportEntry(void);
382         void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
383
384     protected:
385         QString m_transport;
386
387     private:
388         LBMLBTRMSourceTransportEntry(void) { }
389         void fillItem(void);
390         guint64 m_data_frames;
391         guint64 m_data_bytes;
392         guint64 m_rx_data_frames;
393         guint64 m_rx_data_bytes;
394         guint64 m_ncf_frames;
395         guint64 m_ncf_count;
396         guint64 m_ncf_bytes;
397         guint64 m_sm_frames;
398         guint64 m_sm_bytes;
399         nstime_t m_first_frame_timestamp;
400         bool m_first_frame_timestamp_valid;
401         nstime_t m_last_frame_timestamp;
402
403     protected:
404         LBMLBTRMSQNMap m_data_sqns;
405         LBMLBTRMSQNMap m_rx_data_sqns;
406         LBMLBTRMNCFSQNMap m_ncf_sqns;
407         LBMLBTRMSQNMap m_sm_sqns;
408 };
409
410 LBMLBTRMSourceTransportEntry::LBMLBTRMSourceTransportEntry(const QString & transport) :
411     QTreeWidgetItem(),
412     m_transport(transport),
413     m_data_frames(0),
414     m_data_bytes(0),
415     m_rx_data_frames(0),
416     m_rx_data_bytes(0),
417     m_ncf_frames(0),
418     m_ncf_count(0),
419     m_ncf_bytes(0),
420     m_sm_frames(0),
421     m_sm_bytes(0),
422     m_first_frame_timestamp_valid(false),
423     m_data_sqns(),
424     m_rx_data_sqns(),
425     m_ncf_sqns(),
426     m_sm_sqns()
427 {
428     m_first_frame_timestamp.secs = 0;
429     m_first_frame_timestamp.nsecs = 0;
430     m_last_frame_timestamp.secs = 0;
431     m_last_frame_timestamp.nsecs = 0;
432     setText(Source_AddressTransport_Column, m_transport);
433 }
434
435 LBMLBTRMSourceTransportEntry::~LBMLBTRMSourceTransportEntry(void)
436 {
437     for (LBMLBTRMSQNMapIterator it = m_data_sqns.begin(); it != m_data_sqns.end(); ++it)
438     {
439         delete *it;
440     }
441     m_data_sqns.clear();
442
443     for (LBMLBTRMSQNMapIterator it = m_rx_data_sqns.begin(); it != m_rx_data_sqns.end(); ++it)
444     {
445         delete *it;
446     }
447     m_rx_data_sqns.clear();
448
449     for (LBMLBTRMNCFSQNMapIterator it = m_ncf_sqns.begin(); it != m_ncf_sqns.end(); ++it)
450     {
451         delete *it;
452     }
453     m_ncf_sqns.clear();
454
455     for (LBMLBTRMSQNMapIterator it = m_sm_sqns.begin(); it != m_sm_sqns.end(); ++it)
456     {
457         delete *it;
458     }
459     m_sm_sqns.clear();
460 }
461
462 void LBMLBTRMSourceTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
463 {
464     if (m_first_frame_timestamp_valid)
465     {
466         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
467         {
468             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
469         }
470     }
471     else
472     {
473         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
474         m_first_frame_timestamp_valid = true;
475     }
476     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
477     {
478         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
479     }
480     if (tap_info->type == LBTRM_PACKET_TYPE_DATA)
481     {
482         LBMLBTRMSQNEntry * sqn = NULL;
483         LBMLBTRMSQNMapIterator it;
484
485         if (tap_info->retransmission)
486         {
487             m_rx_data_frames++;
488             m_rx_data_bytes += pinfo->fd->pkt_len;
489             it = m_rx_data_sqns.find(tap_info->sqn);
490             if (m_rx_data_sqns.end() == it)
491             {
492                 sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
493                 m_rx_data_sqns.insert(tap_info->sqn, sqn);
494             }
495             else
496             {
497                 sqn = it.value();
498             }
499         }
500         else
501         {
502             m_data_frames++;
503             m_data_bytes += pinfo->fd->pkt_len;
504             it = m_data_sqns.find(tap_info->sqn);
505             if (m_data_sqns.end() == it)
506             {
507                 sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
508                 m_data_sqns.insert(tap_info->sqn, sqn);
509             }
510             else
511             {
512                 sqn = it.value();
513             }
514         }
515         sqn->processFrame(pinfo->num);
516     }
517     else if (tap_info->type == LBTRM_PACKET_TYPE_NCF)
518     {
519         guint16 idx;
520         LBMLBTRMNCFSQNMapIterator it;
521         LBMLBTRMNCFSQNEntry * sqn = NULL;
522
523         m_ncf_frames++;
524         m_ncf_bytes += pinfo->fd->pkt_len;
525         m_ncf_count += (guint64)tap_info->num_sqns;
526         for (idx = 0; idx < tap_info->num_sqns; idx++)
527         {
528             it = m_ncf_sqns.find(tap_info->sqns[idx]);
529             if (m_ncf_sqns.end() == it)
530             {
531                 sqn = new LBMLBTRMNCFSQNEntry(tap_info->sqns[idx]);
532                 m_ncf_sqns.insert(tap_info->sqns[idx], sqn);
533             }
534             else
535             {
536                 sqn = it.value();
537             }
538             sqn->processFrame(tap_info->ncf_reason, pinfo->num);
539         }
540     }
541     else if (tap_info->type == LBTRM_PACKET_TYPE_SM)
542     {
543         LBMLBTRMSQNEntry * sqn = NULL;
544         LBMLBTRMSQNMapIterator it;
545
546         m_sm_frames++;
547         m_sm_bytes += pinfo->fd->pkt_len;
548         it = m_sm_sqns.find(tap_info->sqn);
549         if (m_sm_sqns.end() == it)
550         {
551             sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
552             m_sm_sqns.insert(tap_info->sqn, sqn);
553         }
554         else
555         {
556             sqn = it.value();
557         }
558         sqn->processFrame(pinfo->num);
559     }
560     else
561     {
562         return;
563     }
564     fillItem();
565 }
566
567 void LBMLBTRMSourceTransportEntry::fillItem(void)
568 {
569     nstime_t delta;
570
571     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
572     setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
573     setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
574     setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
575     setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
576     setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
577     setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
578     setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
579     setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
580     setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
581     setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
582     setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
583     setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
584     setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
585     setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
586     setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
587     setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
588     setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
589     setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
590     setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
591     setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
592     setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
593     setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
594     setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
595     setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
596     setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
597     setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
598     setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_count));
599     setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
600     setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
601     setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
602     setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
603     setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
604     setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
605     setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
606     setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
607     setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
608     setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
609     setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignHCenter);
610     setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
611     setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
612 }
613
614 typedef QMap<QString, LBMLBTRMSourceTransportEntry *> LBMLBTRMSourceTransportMap;
615 typedef QMap<QString, LBMLBTRMSourceTransportEntry *>::iterator LBMLBTRMSourceTransportMapIterator;
616
617 // A source (address) entry
618 class LBMLBTRMSourceEntry : public QTreeWidgetItem
619 {
620     public:
621         LBMLBTRMSourceEntry(const QString & source_address);
622         virtual ~LBMLBTRMSourceEntry(void);
623         void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
624
625     private:
626         LBMLBTRMSourceEntry(void) { }
627         void fillItem(void);
628         QString m_address;
629         QString m_transport;
630         guint64 m_data_frames;
631         guint64 m_data_bytes;
632         guint64 m_rx_data_frames;
633         guint64 m_rx_data_bytes;
634         guint64 m_ncf_frames;
635         guint64 m_ncf_count;
636         guint64 m_ncf_bytes;
637         guint64 m_sm_frames;
638         guint64 m_sm_bytes;
639         nstime_t m_first_frame_timestamp;
640         bool m_first_frame_timestamp_valid;
641         nstime_t m_last_frame_timestamp;
642         LBMLBTRMSourceTransportMap m_transports;
643 };
644
645 LBMLBTRMSourceEntry::LBMLBTRMSourceEntry(const QString & source_address) :
646     QTreeWidgetItem(),
647     m_address(source_address),
648     m_data_frames(0),
649     m_data_bytes(0),
650     m_rx_data_frames(0),
651     m_rx_data_bytes(0),
652     m_ncf_frames(0),
653     m_ncf_count(0),
654     m_ncf_bytes(0),
655     m_sm_frames(0),
656     m_sm_bytes(0),
657     m_first_frame_timestamp_valid(false),
658     m_transports()
659 {
660     m_first_frame_timestamp.secs = 0;
661     m_first_frame_timestamp.nsecs = 0;
662     m_last_frame_timestamp.secs = 0;
663     m_last_frame_timestamp.nsecs = 0;
664     setText(Source_AddressTransport_Column, m_address);
665 }
666
667 LBMLBTRMSourceEntry::~LBMLBTRMSourceEntry(void)
668 {
669     for (LBMLBTRMSourceTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it)
670     {
671         delete *it;
672     }
673     m_transports.clear();
674 }
675
676 void LBMLBTRMSourceEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
677 {
678     LBMLBTRMSourceTransportEntry * transport = NULL;
679     LBMLBTRMSourceTransportMapIterator it;
680
681     if (m_first_frame_timestamp_valid)
682     {
683         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
684         {
685             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
686         }
687     }
688     else
689     {
690         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
691         m_first_frame_timestamp_valid = true;
692     }
693     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
694     {
695         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
696     }
697     if (tap_info->type == LBTRM_PACKET_TYPE_DATA)
698     {
699         if (tap_info->retransmission)
700         {
701             m_rx_data_frames++;
702             m_rx_data_bytes += pinfo->fd->pkt_len;
703         }
704         else
705         {
706             m_data_frames++;
707             m_data_bytes += pinfo->fd->pkt_len;
708         }
709     }
710     else if (tap_info->type == LBTRM_PACKET_TYPE_NCF)
711     {
712         m_ncf_frames++;
713         m_ncf_bytes += pinfo->fd->pkt_len;
714         m_ncf_count += tap_info->num_sqns;
715     }
716     else if (tap_info->type == LBTRM_PACKET_TYPE_SM)
717     {
718         m_sm_frames++;
719         m_sm_bytes += pinfo->fd->pkt_len;
720     }
721
722     it = m_transports.find(tap_info->transport);
723     if (m_transports.end() == it)
724     {
725         transport = new LBMLBTRMSourceTransportEntry(tap_info->transport);
726         m_transports.insert(tap_info->transport, transport);
727         addChild(transport);
728         sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
729     }
730     else
731     {
732         transport = it.value();
733     }
734     fillItem();
735     transport->processPacket(pinfo, tap_info);
736 }
737
738 void LBMLBTRMSourceEntry::fillItem(void)
739 {
740     nstime_t delta;
741
742     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
743     setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
744     setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
745     setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
746     setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
747     setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
748     setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
749     setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
750     setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
751     setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
752     setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
753     setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
754     setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
755     setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
756     setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
757     setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
758     setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
759     setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
760     setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
761     setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
762     setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
763     setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
764     setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
765     setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
766     setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
767     setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
768     setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
769     setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_count));
770     setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
771     setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
772     setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
773     setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
774     setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
775     setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
776     setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
777     setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
778     setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
779     setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
780     setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignRight);
781     setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
782     setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
783 }
784
785 typedef QMap<QString, LBMLBTRMSourceEntry *> LBMLBTRMSourceMap;
786 typedef QMap<QString, LBMLBTRMSourceEntry *>::iterator LBMLBTRMSourceMapIterator;
787
788 // A receiver transport entry
789 class LBMLBTRMReceiverTransportEntry : public QTreeWidgetItem
790 {
791         friend class LBMLBTRMTransportDialog;
792
793     public:
794         LBMLBTRMReceiverTransportEntry(const QString & transport);
795         virtual ~LBMLBTRMReceiverTransportEntry(void);
796         void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
797
798     private:
799         LBMLBTRMReceiverTransportEntry(void) { }
800         void fillItem(void);
801         QString m_transport;
802         guint64 m_nak_frames;
803         guint64 m_nak_count;
804         guint64 m_nak_bytes;
805         nstime_t m_first_frame_timestamp;
806         bool m_first_frame_timestamp_valid;
807         nstime_t m_last_frame_timestamp;
808
809     protected:
810         LBMLBTRMSQNMap m_nak_sqns;
811 };
812
813 LBMLBTRMReceiverTransportEntry::LBMLBTRMReceiverTransportEntry(const QString & transport) :
814     QTreeWidgetItem(),
815     m_transport(transport),
816     m_nak_frames(0),
817     m_nak_count(0),
818     m_nak_bytes(0),
819     m_first_frame_timestamp_valid(false),
820     m_nak_sqns()
821 {
822     m_first_frame_timestamp.secs = 0;
823     m_first_frame_timestamp.nsecs = 0;
824     m_last_frame_timestamp.secs = 0;
825     m_last_frame_timestamp.nsecs = 0;
826     setText(Receiver_AddressTransport_Column, m_transport);
827 }
828
829 LBMLBTRMReceiverTransportEntry::~LBMLBTRMReceiverTransportEntry(void)
830 {
831     for (LBMLBTRMSQNMapIterator it = m_nak_sqns.begin(); it != m_nak_sqns.end(); ++it)
832     {
833         delete *it;
834     }
835     m_nak_sqns.clear();
836 }
837
838 void LBMLBTRMReceiverTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
839 {
840     if (m_first_frame_timestamp_valid)
841     {
842         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
843         {
844             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
845         }
846     }
847     else
848     {
849         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
850         m_first_frame_timestamp_valid = true;
851     }
852     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
853     {
854         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
855     }
856     if (tap_info->type == LBTRM_PACKET_TYPE_NAK)
857     {
858         guint16 idx;
859         LBMLBTRMSQNEntry * sqn = NULL;
860         LBMLBTRMSQNMapIterator it;
861
862         m_nak_frames++;
863         m_nak_bytes += pinfo->fd->pkt_len;
864         m_nak_count += tap_info->num_sqns;
865         for (idx = 0; idx < tap_info->num_sqns; idx++)
866         {
867             it = m_nak_sqns.find(tap_info->sqns[idx]);
868             if (m_nak_sqns.end() == it)
869             {
870                 sqn = new LBMLBTRMSQNEntry(tap_info->sqns[idx]);
871                 m_nak_sqns.insert(tap_info->sqns[idx], sqn);
872             }
873             else
874             {
875                 sqn = it.value();
876             }
877             sqn->processFrame(pinfo->num);
878         }
879     }
880     else
881     {
882         return;
883     }
884     fillItem();
885 }
886
887 void LBMLBTRMReceiverTransportEntry::fillItem(void)
888 {
889     nstime_t delta;
890
891     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
892     setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
893     setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
894     setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
895     setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
896     setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
897     setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
898     setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
899     setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
900 }
901
902 typedef QMap<QString, LBMLBTRMReceiverTransportEntry *> LBMLBTRMReceiverTransportMap;
903 typedef QMap<QString, LBMLBTRMReceiverTransportEntry *>::iterator LBMLBTRMReceiverTransportMapIterator;
904
905 // A receiver (address) entry
906 class LBMLBTRMReceiverEntry : public QTreeWidgetItem
907 {
908     public:
909         LBMLBTRMReceiverEntry(const QString & receiver_address);
910         virtual ~LBMLBTRMReceiverEntry(void);
911         void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
912
913     private:
914         LBMLBTRMReceiverEntry(void);
915         void fillItem(void);
916         QString m_address;
917         QString m_transport;
918         guint64 m_nak_frames;
919         guint64 m_nak_count;
920         guint64 m_nak_bytes;
921         nstime_t m_first_frame_timestamp;
922         bool m_first_frame_timestamp_valid;
923         nstime_t m_last_frame_timestamp;
924         LBMLBTRMReceiverTransportMap m_transports;
925 };
926
927 LBMLBTRMReceiverEntry::LBMLBTRMReceiverEntry(const QString & receiver_address) :
928     QTreeWidgetItem(),
929     m_address(receiver_address),
930     m_nak_frames(0),
931     m_nak_count(0),
932     m_nak_bytes(0),
933     m_first_frame_timestamp_valid(false),
934     m_transports()
935 {
936     m_first_frame_timestamp.secs = 0;
937     m_first_frame_timestamp.nsecs = 0;
938     m_last_frame_timestamp.secs = 0;
939     m_last_frame_timestamp.nsecs = 0;
940     setText(Receiver_AddressTransport_Column, m_address);
941 }
942
943 LBMLBTRMReceiverEntry::~LBMLBTRMReceiverEntry(void)
944 {
945     for (LBMLBTRMReceiverTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it)
946     {
947         delete *it;
948     }
949     m_transports.clear();
950 }
951
952 void LBMLBTRMReceiverEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
953 {
954     LBMLBTRMReceiverTransportEntry * transport = NULL;
955     LBMLBTRMReceiverTransportMapIterator it;
956
957     if (m_first_frame_timestamp_valid)
958     {
959         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
960         {
961             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
962         }
963     }
964     else
965     {
966         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
967         m_first_frame_timestamp_valid = true;
968     }
969     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
970     {
971         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
972     }
973     if (tap_info->type == LBTRM_PACKET_TYPE_NAK)
974     {
975         m_nak_frames++;
976         m_nak_bytes += pinfo->fd->pkt_len;
977         m_nak_count += tap_info->num_sqns;
978     }
979
980     it = m_transports.find(tap_info->transport);
981     if (m_transports.end() == it)
982     {
983         transport = new LBMLBTRMReceiverTransportEntry(tap_info->transport);
984         m_transports.insert(tap_info->transport, transport);
985         addChild(transport);
986         sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
987     }
988     else
989     {
990         transport = it.value();
991     }
992     fillItem();
993     transport->processPacket(pinfo, tap_info);
994 }
995
996 void LBMLBTRMReceiverEntry::fillItem(void)
997 {
998     nstime_t delta;
999
1000     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
1001     setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
1002     setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
1003     setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
1004     setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
1005     setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
1006     setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
1007     setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
1008     setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
1009 }
1010
1011 typedef QMap<QString, LBMLBTRMReceiverEntry *> LBMLBTRMReceiverMap;
1012 typedef QMap<QString, LBMLBTRMReceiverEntry *>::iterator LBMLBTRMReceiverMapIterator;
1013
1014 class LBMLBTRMTransportDialogInfo
1015 {
1016     public:
1017         LBMLBTRMTransportDialogInfo(void);
1018         ~LBMLBTRMTransportDialogInfo(void);
1019         void setDialog(LBMLBTRMTransportDialog * dialog);
1020         LBMLBTRMTransportDialog * getDialog(void);
1021         void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
1022         void clearMaps(void);
1023
1024     private:
1025         LBMLBTRMTransportDialog * m_dialog;
1026         LBMLBTRMSourceMap m_sources;
1027         LBMLBTRMReceiverMap m_receivers;
1028 };
1029
1030 LBMLBTRMTransportDialogInfo::LBMLBTRMTransportDialogInfo(void) :
1031     m_dialog(NULL),
1032     m_sources(),
1033     m_receivers()
1034 {
1035 }
1036
1037 LBMLBTRMTransportDialogInfo::~LBMLBTRMTransportDialogInfo(void)
1038 {
1039     clearMaps();
1040 }
1041
1042 void LBMLBTRMTransportDialogInfo::setDialog(LBMLBTRMTransportDialog * dialog)
1043 {
1044     m_dialog = dialog;
1045 }
1046
1047 LBMLBTRMTransportDialog * LBMLBTRMTransportDialogInfo::getDialog(void)
1048 {
1049     return (m_dialog);
1050 }
1051
1052 void LBMLBTRMTransportDialogInfo::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
1053 {
1054     switch (tap_info->type)
1055     {
1056         case LBTRM_PACKET_TYPE_DATA:
1057         case LBTRM_PACKET_TYPE_SM:
1058         case LBTRM_PACKET_TYPE_NCF:
1059             {
1060                 LBMLBTRMSourceEntry * source = NULL;
1061                 LBMLBTRMSourceMapIterator it;
1062                 QString src_address = address_to_qstring(&(pinfo->src));
1063
1064                 it = m_sources.find(src_address);
1065                 if (m_sources.end() == it)
1066                 {
1067                     QTreeWidgetItem * parent = NULL;
1068                     Ui::LBMLBTRMTransportDialog * ui = NULL;
1069
1070                     source = new LBMLBTRMSourceEntry(src_address);
1071                     it = m_sources.insert(src_address, source);
1072                     ui = m_dialog->getUI();
1073                     ui->sources_TreeWidget->addTopLevelItem(source);
1074                     parent = ui->sources_TreeWidget->invisibleRootItem();
1075                     parent->sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
1076                     ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
1077                 }
1078                 else
1079                 {
1080                     source = it.value();
1081                 }
1082                 source->processPacket(pinfo, tap_info);
1083             }
1084             break;
1085         case LBTRM_PACKET_TYPE_NAK:
1086             {
1087                 LBMLBTRMReceiverEntry * receiver = NULL;
1088                 LBMLBTRMReceiverMapIterator it;
1089                 QString src_address = address_to_qstring(&(pinfo->src));
1090
1091                 it = m_receivers.find(src_address);
1092                 if (m_receivers.end() == it)
1093                 {
1094                     QTreeWidgetItem * parent = NULL;
1095                     Ui::LBMLBTRMTransportDialog * ui = NULL;
1096
1097                     receiver = new LBMLBTRMReceiverEntry(src_address);
1098                     it = m_receivers.insert(src_address, receiver);
1099                     ui = m_dialog->getUI();
1100                     ui->receivers_TreeWidget->addTopLevelItem(receiver);
1101                     parent = ui->receivers_TreeWidget->invisibleRootItem();
1102                     parent->sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
1103                     ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
1104                 }
1105                 else
1106                 {
1107                     receiver = it.value();
1108                 }
1109                 receiver->processPacket(pinfo, tap_info);
1110             }
1111             break;
1112         default:
1113             break;
1114     }
1115 }
1116
1117 void LBMLBTRMTransportDialogInfo::clearMaps(void)
1118 {
1119     for (LBMLBTRMSourceMapIterator it = m_sources.begin(); it != m_sources.end(); ++it)
1120     {
1121         delete *it;
1122     }
1123     m_sources.clear();
1124
1125     for (LBMLBTRMReceiverMapIterator it = m_receivers.begin(); it != m_receivers.end(); ++it)
1126     {
1127         delete *it;
1128     }
1129     m_receivers.clear();
1130 }
1131
1132 LBMLBTRMTransportDialog::LBMLBTRMTransportDialog(QWidget * parent, capture_file * cfile) :
1133     QDialog(parent),
1134     m_ui(new Ui::LBMLBTRMTransportDialog),
1135     m_dialog_info(NULL),
1136     m_capture_file(cfile),
1137     m_current_source_transport(NULL),
1138     m_current_receiver_transport(NULL),
1139     m_source_context_menu(NULL),
1140     m_source_header(NULL)
1141 {
1142     m_ui->setupUi(this);
1143     m_dialog_info = new LBMLBTRMTransportDialogInfo();
1144
1145     m_ui->tabWidget->setCurrentIndex(0);
1146     m_ui->sources_detail_ComboBox->setCurrentIndex(0);
1147     m_ui->sources_detail_transport_Label->setText(QString(" "));
1148     m_ui->receivers_detail_transport_Label->setText(QString(" "));
1149     m_ui->stackedWidget->setCurrentIndex(0);
1150
1151     m_source_header = m_ui->sources_TreeWidget->header();
1152     m_source_context_menu = new QMenu(m_source_header);
1153
1154     m_source_context_menu->addAction(m_ui->action_SourceAutoResizeColumns);
1155     connect(m_ui->action_SourceAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionSourceAutoResizeColumns_triggered()));
1156     m_source_context_menu->addSeparator();
1157
1158     m_ui->action_SourceDataFrames->setChecked(true);
1159     m_source_context_menu->addAction(m_ui->action_SourceDataFrames);
1160     connect(m_ui->action_SourceDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFrames_triggered(bool)));
1161     m_ui->action_SourceDataBytes->setChecked(true);
1162     m_source_context_menu->addAction(m_ui->action_SourceDataBytes);
1163     connect(m_ui->action_SourceDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataBytes_triggered(bool)));
1164     m_ui->action_SourceDataFramesBytes->setChecked(false);
1165     m_source_context_menu->addAction(m_ui->action_SourceDataFramesBytes);
1166     connect(m_ui->action_SourceDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFramesBytes_triggered(bool)));
1167     m_ui->action_SourceDataRate->setChecked(true);
1168     m_source_context_menu->addAction(m_ui->action_SourceDataRate);
1169     connect(m_ui->action_SourceDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataRate_triggered(bool)));
1170
1171     m_ui->action_SourceRXDataFrames->setChecked(true);
1172     m_source_context_menu->addAction(m_ui->action_SourceRXDataFrames);
1173     connect(m_ui->action_SourceRXDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFrames_triggered(bool)));
1174     m_ui->action_SourceRXDataBytes->setChecked(true);
1175     m_source_context_menu->addAction(m_ui->action_SourceRXDataBytes);
1176     connect(m_ui->action_SourceRXDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataBytes_triggered(bool)));
1177     m_ui->action_SourceRXDataFramesBytes->setChecked(false);
1178     m_source_context_menu->addAction(m_ui->action_SourceRXDataFramesBytes);
1179     connect(m_ui->action_SourceRXDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFramesBytes_triggered(bool)));
1180     m_ui->action_SourceRXDataRate->setChecked(true);
1181     m_source_context_menu->addAction(m_ui->action_SourceRXDataRate);
1182     connect(m_ui->action_SourceRXDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataRate_triggered(bool)));
1183
1184     m_ui->action_SourceNCFFrames->setChecked(true);
1185     m_source_context_menu->addAction(m_ui->action_SourceNCFFrames);
1186     connect(m_ui->action_SourceNCFFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFrames_triggered(bool)));
1187     m_ui->action_SourceNCFCount->setChecked(true);
1188     m_source_context_menu->addAction(m_ui->action_SourceNCFCount);
1189     connect(m_ui->action_SourceNCFCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCount_triggered(bool)));
1190     m_ui->action_SourceNCFBytes->setChecked(true);
1191     m_source_context_menu->addAction(m_ui->action_SourceNCFBytes);
1192     connect(m_ui->action_SourceNCFBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFBytes_triggered(bool)));
1193     m_ui->action_SourceNCFFramesBytes->setChecked(false);
1194     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesBytes);
1195     connect(m_ui->action_SourceNCFFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesBytes_triggered(bool)));
1196     m_ui->action_SourceNCFCountBytes->setChecked(false);
1197     m_source_context_menu->addAction(m_ui->action_SourceNCFCountBytes);
1198     connect(m_ui->action_SourceNCFCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCountBytes_triggered(bool)));
1199     m_ui->action_SourceNCFFramesCount->setChecked(false);
1200     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCount);
1201     connect(m_ui->action_SourceNCFFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCount_triggered(bool)));
1202     m_ui->action_SourceNCFFramesCountBytes->setChecked(false);
1203     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCountBytes);
1204     connect(m_ui->action_SourceNCFFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCountBytes_triggered(bool)));
1205     m_ui->action_SourceNCFRate->setChecked(true);
1206     m_source_context_menu->addAction(m_ui->action_SourceNCFRate);
1207     connect(m_ui->action_SourceNCFRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFRate_triggered(bool)));
1208
1209     m_ui->action_SourceSMFrames->setChecked(true);
1210     m_source_context_menu->addAction(m_ui->action_SourceSMFrames);
1211     connect(m_ui->action_SourceSMFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFrames_triggered(bool)));
1212     m_ui->action_SourceSMBytes->setChecked(true);
1213     m_source_context_menu->addAction(m_ui->action_SourceSMBytes);
1214     connect(m_ui->action_SourceSMBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMBytes_triggered(bool)));
1215     m_ui->action_SourceSMFramesBytes->setChecked(false);
1216     m_source_context_menu->addAction(m_ui->action_SourceSMFramesBytes);
1217     connect(m_ui->action_SourceSMFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFramesBytes_triggered(bool)));
1218     m_ui->action_SourceSMRate->setChecked(true);
1219     m_source_context_menu->addAction(m_ui->action_SourceSMRate);
1220     connect(m_ui->action_SourceSMRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMRate_triggered(bool)));
1221
1222     m_source_header->setContextMenuPolicy(Qt::CustomContextMenu);
1223     connect(m_source_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_source_context_menuRequested(const QPoint &)));
1224
1225     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, true);
1226     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, true);
1227     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, true);
1228     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, true);
1229     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, true);
1230     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, true);
1231     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, true);
1232
1233     connect(this, SIGNAL(accepted()), this, SLOT(closeDialog()));
1234     connect(this, SIGNAL(rejected()), this, SLOT(closeDialog()));
1235     fillTree();
1236 }
1237
1238 LBMLBTRMTransportDialog::~LBMLBTRMTransportDialog(void)
1239 {
1240     resetSourcesDetail();
1241     resetSources();
1242     resetReceiversDetail();
1243     resetReceivers();
1244     if (m_dialog_info != NULL)
1245     {
1246         delete m_dialog_info;
1247         m_dialog_info = NULL;
1248     }
1249     delete m_source_context_menu;
1250     m_source_context_menu = NULL;
1251     delete m_ui;
1252     m_ui = NULL;
1253     m_capture_file = NULL;
1254 }
1255
1256 void LBMLBTRMTransportDialog::setCaptureFile(capture_file * cfile)
1257 {
1258     if (cfile == NULL) // We only want to know when the file closes.
1259     {
1260         m_capture_file = NULL;
1261         m_ui->displayFilterLineEdit->setEnabled(false);
1262         m_ui->applyFilterButton->setEnabled(false);
1263     }
1264 }
1265
1266 void LBMLBTRMTransportDialog::resetSources(void)
1267 {
1268     while (m_ui->sources_TreeWidget->takeTopLevelItem(0) != NULL)
1269     {}
1270 }
1271
1272 void LBMLBTRMTransportDialog::resetReceivers(void)
1273 {
1274     while (m_ui->receivers_TreeWidget->takeTopLevelItem(0) != NULL)
1275     {}
1276 }
1277
1278 void LBMLBTRMTransportDialog::resetSourcesDetail(void)
1279 {
1280     while (m_ui->sources_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
1281     {}
1282     while (m_ui->sources_detail_ncf_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
1283     {}
1284     m_ui->sources_detail_transport_Label->setText(QString(" "));
1285     m_current_source_transport = NULL;
1286 }
1287
1288 void LBMLBTRMTransportDialog::resetReceiversDetail(void)
1289 {
1290     while (m_ui->receivers_detail_TreeWidget->takeTopLevelItem(0) != NULL)
1291     {}
1292     m_ui->receivers_detail_transport_Label->setText(QString(" "));
1293     m_current_receiver_transport = NULL;
1294 }
1295
1296 void LBMLBTRMTransportDialog::fillTree(void)
1297 {
1298     GString * error_string;
1299
1300     if (m_capture_file == NULL)
1301     {
1302         return;
1303     }
1304     m_dialog_info->setDialog(this);
1305
1306     error_string = register_tap_listener("lbm_lbtrm",
1307         (void *)m_dialog_info,
1308         m_ui->displayFilterLineEdit->text().toUtf8().constData(),
1309         TL_REQUIRES_COLUMNS,
1310         resetTap,
1311         tapPacket,
1312         drawTreeItems);
1313     if (error_string)
1314     {
1315         QMessageBox::critical(this, tr("LBT-RM Statistics failed to attach to tap"),
1316             error_string->str);
1317         g_string_free(error_string, TRUE);
1318         reject();
1319     }
1320
1321     cf_retap_packets(m_capture_file);
1322     drawTreeItems(&m_dialog_info);
1323     remove_tap_listener((void *)m_dialog_info);
1324 }
1325
1326 void LBMLBTRMTransportDialog::resetTap(void * tap_data)
1327 {
1328     LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *) tap_data;
1329     LBMLBTRMTransportDialog * dialog = info->getDialog();
1330     if (dialog == NULL)
1331     {
1332         return;
1333     }
1334     dialog->resetSourcesDetail();
1335     dialog->resetSources();
1336     dialog->resetReceiversDetail();
1337     dialog->resetReceivers();
1338     info->clearMaps();
1339 }
1340
1341 gboolean LBMLBTRMTransportDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t *, const void * tap_info)
1342 {
1343     if (pinfo->fd->flags.passed_dfilter == 1)
1344     {
1345         const lbm_lbtrm_tap_info_t * tapinfo = (const lbm_lbtrm_tap_info_t *)tap_info;
1346         LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *)tap_data;
1347
1348         info->processPacket(pinfo, tapinfo);
1349     }
1350     return (TRUE);
1351 }
1352
1353 void LBMLBTRMTransportDialog::drawTreeItems(void *)
1354 {
1355 }
1356
1357 void LBMLBTRMTransportDialog::on_applyFilterButton_clicked(void)
1358 {
1359     fillTree();
1360 }
1361
1362 void LBMLBTRMTransportDialog::closeDialog(void)
1363 {
1364     delete this;
1365 }
1366
1367 void LBMLBTRMTransportDialog::sourcesDetailCurrentChanged(int index)
1368 {
1369     // Index 0: Data
1370     // Index 1: RX data
1371     // Index 2: NCF
1372     // Index 3: SM
1373     switch (index)
1374     {
1375         case 0:
1376         case 1:
1377         case 3:
1378             m_ui->stackedWidget->setCurrentIndex(0);
1379             break;
1380         case 2:
1381             m_ui->stackedWidget->setCurrentIndex(1);
1382             break;
1383         default:
1384             return;
1385     }
1386     sourcesItemClicked(m_current_source_transport, 0);
1387 }
1388
1389 void LBMLBTRMTransportDialog::sourcesItemClicked(QTreeWidgetItem * item, int)
1390 {
1391     LBMLBTRMSourceTransportEntry * transport = dynamic_cast<LBMLBTRMSourceTransportEntry *>(item);
1392
1393     resetSourcesDetail();
1394     if (transport == NULL)
1395     {
1396         // Must be a source item, ignore it?
1397         return;
1398     }
1399     m_current_source_transport = transport;
1400     m_ui->sources_detail_transport_Label->setText(transport->m_transport);
1401     int cur_idx = m_ui->sources_detail_ComboBox->currentIndex();
1402     switch (cur_idx)
1403     {
1404         case 0:
1405             loadSourceDataDetails(transport);
1406             break;
1407         case 1:
1408             loadSourceRXDataDetails(transport);
1409             break;
1410         case 2:
1411             loadSourceNCFDetails(transport);
1412             break;
1413         case 3:
1414             loadSourceSMDetails(transport);
1415             break;
1416         default:
1417             break;
1418     }
1419 }
1420
1421 void LBMLBTRMTransportDialog::loadSourceDataDetails(LBMLBTRMSourceTransportEntry * transport)
1422 {
1423     for (LBMLBTRMSQNMapIterator it = transport->m_data_sqns.begin(); it != transport->m_data_sqns.end(); ++it)
1424     {
1425         LBMLBTRMSQNEntry * sqn = it.value();
1426         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1427     }
1428 }
1429
1430 void LBMLBTRMTransportDialog::loadSourceRXDataDetails(LBMLBTRMSourceTransportEntry * transport)
1431 {
1432     for (LBMLBTRMSQNMapIterator it = transport->m_rx_data_sqns.begin(); it != transport->m_rx_data_sqns.end(); ++it)
1433     {
1434         LBMLBTRMSQNEntry * sqn = it.value();
1435         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1436     }
1437 }
1438
1439 void LBMLBTRMTransportDialog::loadSourceNCFDetails(LBMLBTRMSourceTransportEntry * transport)
1440 {
1441     for (LBMLBTRMNCFSQNMapIterator it = transport->m_ncf_sqns.begin(); it != transport->m_ncf_sqns.end(); ++it)
1442     {
1443         LBMLBTRMNCFSQNEntry * sqn = it.value();
1444         m_ui->sources_detail_ncf_sqn_TreeWidget->addTopLevelItem(sqn);
1445     }
1446 }
1447
1448 void LBMLBTRMTransportDialog::loadSourceSMDetails(LBMLBTRMSourceTransportEntry * transport)
1449 {
1450     for (LBMLBTRMSQNMapIterator it = transport->m_sm_sqns.begin(); it != transport->m_sm_sqns.end(); ++it)
1451     {
1452         LBMLBTRMSQNEntry * sqn = it.value();
1453         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1454     }
1455 }
1456
1457 void LBMLBTRMTransportDialog::receiversItemClicked(QTreeWidgetItem * item, int)
1458 {
1459     LBMLBTRMReceiverTransportEntry * transport = dynamic_cast<LBMLBTRMReceiverTransportEntry *>(item);
1460
1461     resetReceiversDetail();
1462     if (transport == NULL)
1463     {
1464         // Must be a receiver item, ignore it?
1465         return;
1466     }
1467     m_current_receiver_transport = transport;
1468     m_ui->receivers_detail_transport_Label->setText(transport->m_transport);
1469     loadReceiverNAKDetails(transport);
1470 }
1471
1472 void LBMLBTRMTransportDialog::loadReceiverNAKDetails(LBMLBTRMReceiverTransportEntry * transport)
1473 {
1474     for (LBMLBTRMSQNMapIterator it = transport->m_nak_sqns.begin(); it != transport->m_nak_sqns.end(); ++it)
1475     {
1476         LBMLBTRMSQNEntry * sqn = it.value();
1477         m_ui->receivers_detail_TreeWidget->addTopLevelItem(sqn);
1478     }
1479 }
1480
1481 void LBMLBTRMTransportDialog::sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int)
1482 {
1483     LBMLBTRMFrameEntry * frame = dynamic_cast<LBMLBTRMFrameEntry *>(item);
1484     if (frame == NULL)
1485     {
1486         // Must have double-clicked on something other than an expanded frame entry
1487         return;
1488     }
1489     emit goToPacket((int)frame->getFrame());
1490 }
1491
1492 void LBMLBTRMTransportDialog::receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int)
1493 {
1494     LBMLBTRMFrameEntry * frame = dynamic_cast<LBMLBTRMFrameEntry *>(item);
1495     if (frame == NULL)
1496     {
1497         // Must have double-clicked on something other than an expanded frame entry
1498         return;
1499     }
1500     emit goToPacket((int)frame->getFrame());
1501 }
1502
1503 void LBMLBTRMTransportDialog::custom_source_context_menuRequested(const QPoint & pos)
1504 {
1505     m_source_context_menu->exec(m_source_header->mapToGlobal(pos));
1506 }
1507
1508 void LBMLBTRMTransportDialog::actionSourceDataFrames_triggered(bool checked)
1509 {
1510     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFrames_Column, !checked);
1511 }
1512
1513 void LBMLBTRMTransportDialog::actionSourceDataBytes_triggered(bool checked)
1514 {
1515     m_ui->sources_TreeWidget->setColumnHidden(Source_DataBytes_Column, !checked);
1516 }
1517
1518 void LBMLBTRMTransportDialog::actionSourceDataFramesBytes_triggered(bool checked)
1519 {
1520     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, !checked);
1521 }
1522
1523 void LBMLBTRMTransportDialog::actionSourceDataRate_triggered(bool checked)
1524 {
1525     m_ui->sources_TreeWidget->setColumnHidden(Source_DataRate_Column, !checked);
1526 }
1527
1528 void LBMLBTRMTransportDialog::actionSourceRXDataFrames_triggered(bool checked)
1529 {
1530     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFrames_Column, !checked);
1531 }
1532
1533 void LBMLBTRMTransportDialog::actionSourceRXDataBytes_triggered(bool checked)
1534 {
1535     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataBytes_Column, !checked);
1536 }
1537
1538 void LBMLBTRMTransportDialog::actionSourceRXDataFramesBytes_triggered(bool checked)
1539 {
1540     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, !checked);
1541 }
1542
1543 void LBMLBTRMTransportDialog::actionSourceRXDataRate_triggered(bool checked)
1544 {
1545     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataRate_Column, !checked);
1546 }
1547
1548 void LBMLBTRMTransportDialog::actionSourceNCFFrames_triggered(bool checked)
1549 {
1550     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
1551 }
1552
1553 void LBMLBTRMTransportDialog::actionSourceNCFCount_triggered(bool checked)
1554 {
1555     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCount_Column, !checked);
1556 }
1557
1558 void LBMLBTRMTransportDialog::actionSourceNCFBytes_triggered(bool checked)
1559 {
1560     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
1561 }
1562
1563 void LBMLBTRMTransportDialog::actionSourceNCFFramesBytes_triggered(bool checked)
1564 {
1565     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, !checked);
1566 }
1567
1568 void LBMLBTRMTransportDialog::actionSourceNCFCountBytes_triggered(bool checked)
1569 {
1570     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, !checked);
1571 }
1572
1573 void LBMLBTRMTransportDialog::actionSourceNCFFramesCount_triggered(bool checked)
1574 {
1575     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, !checked);
1576 }
1577
1578 void LBMLBTRMTransportDialog::actionSourceNCFFramesCountBytes_triggered(bool checked)
1579 {
1580     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, !checked);
1581 }
1582
1583 void LBMLBTRMTransportDialog::actionSourceNCFRate_triggered(bool checked)
1584 {
1585     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFRate_Column, !checked);
1586 }
1587
1588 void LBMLBTRMTransportDialog::actionSourceSMFrames_triggered(bool checked)
1589 {
1590     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFrames_Column, !checked);
1591 }
1592
1593 void LBMLBTRMTransportDialog::actionSourceSMBytes_triggered(bool checked)
1594 {
1595     m_ui->sources_TreeWidget->setColumnHidden(Source_SMBytes_Column, !checked);
1596 }
1597
1598 void LBMLBTRMTransportDialog::actionSourceSMFramesBytes_triggered(bool checked)
1599 {
1600     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, !checked);
1601 }
1602
1603 void LBMLBTRMTransportDialog::actionSourceSMRate_triggered(bool checked)
1604 {
1605     m_ui->sources_TreeWidget->setColumnHidden(Source_SMRate_Column, !checked);
1606 }
1607
1608 void LBMLBTRMTransportDialog::actionSourceAutoResizeColumns_triggered(void)
1609 {
1610     m_ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
1611     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFrames_Column);
1612     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataBytes_Column);
1613     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFramesBytes_Column);
1614     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataRate_Column);
1615     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFrames_Column);
1616     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataBytes_Column);
1617     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFramesBytes_Column);
1618     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataRate_Column);
1619     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFrames_Column);
1620     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCount_Column);
1621     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFBytes_Column);
1622     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesBytes_Column);
1623     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCountBytes_Column);
1624     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCount_Column);
1625     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCountBytes_Column);
1626     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFRate_Column);
1627     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFrames_Column);
1628     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMBytes_Column);
1629     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFramesBytes_Column);
1630     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMRate_Column);
1631 }
1632
1633 /*
1634  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1635  *
1636  * Local variables:
1637  * c-basic-offset: 4
1638  * tab-width: 8
1639  * indent-tabs-mode: nil
1640  * End:
1641  *
1642  * vi: set shiftwidth=4 tabstop=8 expandtab:
1643  * :indentSize=4:tabSize=8:noTabs=true:
1644  */