2012-01-04 22:13:01 +00:00
|
|
|
/* packet_list.cpp
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-06-28 22:56:06 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2012-01-04 22:13:01 +00:00
|
|
|
*/
|
|
|
|
|
2012-09-20 02:03:38 +00:00
|
|
|
#include "config.h"
|
2012-01-04 22:13:01 +00:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
2015-02-12 23:35:59 +00:00
|
|
|
#include "file.h"
|
|
|
|
|
2012-01-04 22:13:01 +00:00
|
|
|
#include <epan/epan.h>
|
|
|
|
#include <epan/epan_dissect.h>
|
|
|
|
|
2013-10-18 13:06:05 +00:00
|
|
|
#include <epan/column-info.h>
|
2012-01-04 22:13:01 +00:00
|
|
|
#include <epan/column.h>
|
|
|
|
#include <epan/packet.h>
|
2014-06-17 22:38:29 +00:00
|
|
|
#include <epan/prefs.h>
|
2012-01-04 22:13:01 +00:00
|
|
|
|
|
|
|
#include "packet_list.h"
|
|
|
|
#include "proto_tree.h"
|
2013-01-24 01:10:12 +00:00
|
|
|
#include "wireshark_application.h"
|
2013-12-13 07:25:30 +00:00
|
|
|
#include "epan/ipproto.h"
|
2012-01-04 22:13:01 +00:00
|
|
|
|
|
|
|
#include "qt_ui_utils.h"
|
2012-01-16 01:18:56 +00:00
|
|
|
|
|
|
|
#include "ui/main_statusbar.h"
|
2015-01-01 19:41:03 +00:00
|
|
|
#include "ui/packet_list_utils.h"
|
|
|
|
#include "ui/preference_utils.h"
|
2012-01-18 19:59:13 +00:00
|
|
|
#include "ui/recent.h"
|
2012-08-23 17:29:05 +00:00
|
|
|
#include "ui/recent_utils.h"
|
2012-01-16 01:18:56 +00:00
|
|
|
#include "ui/ui_util.h"
|
2015-01-01 19:41:03 +00:00
|
|
|
#include "ui/utf8_entities.h"
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-12-23 04:37:58 +00:00
|
|
|
#include "wsutil/str_util.h"
|
|
|
|
|
2013-07-11 05:47:02 +00:00
|
|
|
#include "frame_tvbuff.h"
|
|
|
|
|
2015-01-01 19:41:03 +00:00
|
|
|
#include <QAction>
|
|
|
|
#include <QActionGroup>
|
2012-12-07 01:46:20 +00:00
|
|
|
#include <QContextMenuEvent>
|
2014-10-05 19:23:33 +00:00
|
|
|
#include <QHeaderView>
|
2012-12-17 23:03:21 +00:00
|
|
|
#include <QMessageBox>
|
2014-10-05 19:23:33 +00:00
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QTabWidget>
|
|
|
|
#include <QTextEdit>
|
2015-02-20 14:30:23 +00:00
|
|
|
#include <QTimerEvent>
|
2014-10-05 19:23:33 +00:00
|
|
|
#include <QTreeWidget>
|
|
|
|
|
|
|
|
// To do:
|
|
|
|
// - Catch column reordering and rebuild the column list accoringly.
|
2015-02-20 14:30:23 +00:00
|
|
|
// - Use a timer to trigger automatic scrolling.
|
2012-01-04 22:13:01 +00:00
|
|
|
|
|
|
|
// If we ever add the ability to open multiple capture files we might be
|
|
|
|
// able to use something like QMap<capture_file *, PacketList *> to match
|
|
|
|
// capture files against packet lists and models.
|
2012-08-23 17:29:05 +00:00
|
|
|
static PacketList *gbl_cur_packet_list = NULL;
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-12-23 04:37:58 +00:00
|
|
|
const int max_comments_to_fetch_ = 20000000; // Arbitrary
|
2015-02-20 14:30:23 +00:00
|
|
|
const int tail_update_interval_ = 100; // Milliseconds.
|
2012-12-23 04:37:58 +00:00
|
|
|
|
2012-01-04 22:13:01 +00:00
|
|
|
guint
|
2013-11-24 12:49:50 +00:00
|
|
|
packet_list_append(column_info *cinfo, frame_data *fdata)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-01-14 00:16:16 +00:00
|
|
|
Q_UNUSED(cinfo);
|
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
if (!gbl_cur_packet_list)
|
2012-01-04 22:13:01 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* fdata should be filled with the stuff we need
|
|
|
|
* strings are built at display time.
|
|
|
|
*/
|
|
|
|
guint visible_pos;
|
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
visible_pos = gbl_cur_packet_list->packetListModel()->appendPacket(fdata);
|
2012-01-04 22:13:01 +00:00
|
|
|
return visible_pos;
|
|
|
|
}
|
|
|
|
|
2012-09-04 01:57:36 +00:00
|
|
|
// Copied from ui/gtk/packet_list.c
|
2012-09-04 02:35:25 +00:00
|
|
|
void packet_list_resize_column(gint col)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2015-02-19 01:18:27 +00:00
|
|
|
if (!gbl_cur_packet_list) return;
|
|
|
|
gbl_cur_packet_list->resizeColumnToContents(col);
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_select_first_row(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (!gbl_cur_packet_list)
|
2012-08-13 01:50:14 +00:00
|
|
|
return;
|
2012-08-23 17:29:05 +00:00
|
|
|
gbl_cur_packet_list->goFirstPacket();
|
|
|
|
gbl_cur_packet_list->setFocus();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_select_last_row(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (!gbl_cur_packet_list)
|
2012-08-13 01:50:14 +00:00
|
|
|
return;
|
2012-08-23 17:29:05 +00:00
|
|
|
gbl_cur_packet_list->goLastPacket();
|
|
|
|
gbl_cur_packet_list->setFocus();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Given a frame_data structure, scroll to and select the row in the
|
|
|
|
* packet list corresponding to that frame. If there is no such
|
|
|
|
* row, return FALSE, otherwise return TRUE.
|
|
|
|
*/
|
|
|
|
gboolean
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_select_row_from_data(frame_data *fdata_needle)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
int row = gbl_cur_packet_list->packetListModel()->visibleIndexOf(fdata_needle);
|
2012-01-04 22:13:01 +00:00
|
|
|
if (row >= 0) {
|
2012-08-23 17:29:05 +00:00
|
|
|
gbl_cur_packet_list->setCurrentIndex(gbl_cur_packet_list->packetListModel()->index(row,0));
|
2012-01-04 22:13:01 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_check_end(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2015-02-20 14:30:23 +00:00
|
|
|
return FALSE; // GTK+ only.
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_clear(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list) {
|
|
|
|
gbl_cur_packet_list->clear();
|
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_enable_color(gboolean enable)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2014-09-22 23:33:05 +00:00
|
|
|
Q_UNUSED(enable);
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list && gbl_cur_packet_list->packetListModel()) {
|
2014-09-22 23:33:05 +00:00
|
|
|
gbl_cur_packet_list->packetListModel()->resetColorized();
|
2012-08-23 17:29:05 +00:00
|
|
|
gbl_cur_packet_list->update();
|
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_freeze(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list) {
|
2013-11-15 20:24:56 +00:00
|
|
|
gbl_cur_packet_list->freeze();
|
2012-08-23 17:29:05 +00:00
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_thaw(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list) {
|
2013-11-15 20:24:56 +00:00
|
|
|
gbl_cur_packet_list->thaw();
|
2012-08-23 17:29:05 +00:00
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
packets_bar_update();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_recreate_visible_rows(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list && gbl_cur_packet_list->packetListModel()) {
|
|
|
|
gbl_cur_packet_list->packetListModel()->recreateVisibleRows();
|
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
frame_data *
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_get_row_data(gint row)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list && gbl_cur_packet_list->packetListModel()) {
|
|
|
|
return gbl_cur_packet_list->packetListModel()->getRowFdata(row);
|
|
|
|
}
|
|
|
|
return NULL;
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_moveto_end(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list)
|
|
|
|
gbl_cur_packet_list->goLastPacket();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Redraw the packet list *and* currently-selected detail */
|
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_queue_draw(void)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-08-23 17:29:05 +00:00
|
|
|
if (gbl_cur_packet_list)
|
2014-10-21 20:36:10 +00:00
|
|
|
gbl_cur_packet_list->redrawVisiblePackets();
|
2012-08-23 17:29:05 +00:00
|
|
|
}
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
void
|
2012-09-04 02:35:25 +00:00
|
|
|
packet_list_recent_write_all(FILE *rf) {
|
2012-08-23 17:29:05 +00:00
|
|
|
if (!gbl_cur_packet_list)
|
|
|
|
return;
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
gbl_cur_packet_list->writeRecent(rf);
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MIN_COL_WIDTH_STR "...."
|
|
|
|
|
2015-01-26 07:46:34 +00:00
|
|
|
Q_DECLARE_METATYPE(PacketList::ColumnActions)
|
2015-01-01 19:41:03 +00:00
|
|
|
|
2012-01-04 22:13:01 +00:00
|
|
|
PacketList::PacketList(QWidget *parent) :
|
2012-10-30 19:21:24 +00:00
|
|
|
QTreeView(parent),
|
|
|
|
proto_tree_(NULL),
|
|
|
|
byte_view_tab_(NULL),
|
2012-12-07 20:08:00 +00:00
|
|
|
cap_file_(NULL),
|
2013-12-10 21:07:26 +00:00
|
|
|
decode_as_(NULL),
|
2015-02-20 14:30:23 +00:00
|
|
|
ctx_column_(-1),
|
|
|
|
capture_in_progress_(false),
|
|
|
|
tail_timer_id_(0)
|
2012-01-04 22:13:01 +00:00
|
|
|
{
|
2012-12-07 20:08:00 +00:00
|
|
|
QMenu *submenu, *subsubmenu;
|
2013-12-21 16:55:43 +00:00
|
|
|
QAction *action;
|
2012-12-07 20:08:00 +00:00
|
|
|
|
2014-10-05 19:23:33 +00:00
|
|
|
setItemsExpandable(false);
|
|
|
|
setRootIsDecorated(false);
|
|
|
|
setSortingEnabled(true);
|
|
|
|
setUniformRowHeights(true);
|
2012-01-04 22:13:01 +00:00
|
|
|
setAccessibleName("Packet list");
|
2013-07-08 16:54:18 +00:00
|
|
|
setItemDelegateForColumn(0, &related_packet_delegate_);
|
2012-12-07 20:08:00 +00:00
|
|
|
|
2012-10-30 19:21:24 +00:00
|
|
|
packet_list_model_ = new PacketListModel(this, cap_file_);
|
2012-08-19 23:52:08 +00:00
|
|
|
setModel(packet_list_model_);
|
2014-10-05 19:23:33 +00:00
|
|
|
sortByColumn(-1, Qt::AscendingOrder);
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2013-10-14 16:54:41 +00:00
|
|
|
// XXX We might want to reimplement setParent() and fill in the context
|
|
|
|
// menu there.
|
2012-12-17 23:03:21 +00:00
|
|
|
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditMarkPacket"));
|
|
|
|
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditIgnorePacket"));
|
|
|
|
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditSetTimeReference"));
|
2012-12-21 19:21:34 +00:00
|
|
|
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditTimeShift"));
|
2012-12-23 04:37:58 +00:00
|
|
|
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditPacketComment"));
|
|
|
|
|
2013-09-09 19:30:30 +00:00
|
|
|
ctx_menu_.addSeparator();
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionFollow");
|
|
|
|
submenu = new QMenu();
|
|
|
|
action->setMenu(submenu);
|
|
|
|
ctx_menu_.addAction(action);
|
2013-09-09 19:30:30 +00:00
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSSLStream"));
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionSCTP");
|
|
|
|
submenu = new QMenu();
|
|
|
|
action->setMenu(submenu);
|
|
|
|
ctx_menu_.addAction(action);
|
2013-12-13 07:25:30 +00:00
|
|
|
ctx_menu_.addMenu(submenu);
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionSCTPAnalyseThisAssociation"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionSCTPShowAllAssociations"));
|
2013-12-18 13:49:10 +00:00
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionSCTPFilterThisAssociation"));
|
2013-12-21 16:55:43 +00:00
|
|
|
|
2012-12-07 20:08:00 +00:00
|
|
|
ctx_menu_.addSeparator();
|
2013-12-21 16:55:43 +00:00
|
|
|
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menuitem name='ManuallyResolveAddress' action='/ManuallyResolveAddress'/>\n"
|
2013-12-21 16:55:43 +00:00
|
|
|
// ctx_menu_.addSeparator();
|
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionApply_as_Filter");
|
|
|
|
submenu = new QMenu();
|
|
|
|
action->setMenu(submenu);
|
|
|
|
ctx_menu_.addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFNotSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFAndSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFOrSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFAndNotSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFOrNotSelected"));
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionPrepare_a_Filter");
|
|
|
|
submenu = new QMenu();
|
|
|
|
action->setMenu(submenu);
|
|
|
|
ctx_menu_.addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFNotSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFAndSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFOrSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFAndNotSelected"));
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFOrNotSelected"));
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
// action = window()->findChild<QAction *>("actionColorize_with_Filter");
|
|
|
|
// submenu = new QMenu();
|
|
|
|
// action->setMenu(submenu);
|
|
|
|
// ctx_menu_.addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menu name= 'ConversationFilter' action='/Conversation Filter'>\n"
|
|
|
|
// " <menuitem name='Ethernet' action='/Conversation Filter/Ethernet'/>\n"
|
|
|
|
// " <menuitem name='IP' action='/Conversation Filter/IP'/>\n"
|
|
|
|
// " <menuitem name='TCP' action='/Conversation Filter/TCP'/>\n"
|
|
|
|
// " <menuitem name='UDP' action='/Conversation Filter/UDP'/>\n"
|
|
|
|
// " <menuitem name='PN-CBA' action='/Conversation Filter/PN-CBA'/>\n"
|
|
|
|
// " <menu name= 'ColorizeConversation' action='/Colorize Conversation'>\n"
|
|
|
|
// " <menu name= 'Ethernet' action='/Colorize Conversation/Ethernet'>\n"
|
|
|
|
// " <menuitem name='Color1' action='/Colorize Conversation/Ethernet/Color 1'/>\n"
|
|
|
|
// " <menuitem name='Color2' action='/Colorize Conversation/Ethernet/Color 2'/>\n"
|
|
|
|
// " <menuitem name='Color3' action='/Colorize Conversation/Ethernet/Color 3'/>\n"
|
|
|
|
// " <menuitem name='Color4' action='/Colorize Conversation/Ethernet/Color 4'/>\n"
|
|
|
|
// " <menuitem name='Color5' action='/Colorize Conversation/Ethernet/Color 5'/>\n"
|
|
|
|
// " <menuitem name='Color6' action='/Colorize Conversation/Ethernet/Color 6'/>\n"
|
|
|
|
// " <menuitem name='Color7' action='/Colorize Conversation/Ethernet/Color 7'/>\n"
|
|
|
|
// " <menuitem name='Color8' action='/Colorize Conversation/Ethernet/Color 8'/>\n"
|
|
|
|
// " <menuitem name='Color9' action='/Colorize Conversation/Ethernet/Color 9'/>\n"
|
|
|
|
// " <menuitem name='Color10' action='/Colorize Conversation/Ethernet/Color 10'/>\n"
|
|
|
|
// " <menuitem name='NewColoringRule' action='/Colorize Conversation/Ethernet/New Coloring Rule'/>\n"
|
|
|
|
// " <menu name= 'IP' action='/Colorize Conversation/IP'>\n"
|
|
|
|
// " <menuitem name='Color1' action='/Colorize Conversation/IP/Color 1'/>\n"
|
|
|
|
// " <menuitem name='Color2' action='/Colorize Conversation/IP/Color 2'/>\n"
|
|
|
|
// " <menuitem name='Color3' action='/Colorize Conversation/IP/Color 3'/>\n"
|
|
|
|
// " <menuitem name='Color4' action='/Colorize Conversation/IP/Color 4'/>\n"
|
|
|
|
// " <menuitem name='Color5' action='/Colorize Conversation/IP/Color 5'/>\n"
|
|
|
|
// " <menuitem name='Color6' action='/Colorize Conversation/IP/Color 6'/>\n"
|
|
|
|
// " <menuitem name='Color7' action='/Colorize Conversation/IP/Color 7'/>\n"
|
|
|
|
// " <menuitem name='Color8' action='/Colorize Conversation/IP/Color 8'/>\n"
|
|
|
|
// " <menuitem name='Color9' action='/Colorize Conversation/IP/Color 9'/>\n"
|
|
|
|
// " <menuitem name='Color10' action='/Colorize Conversation/IP/Color 10'/>\n"
|
|
|
|
// " <menuitem name='NewColoringRule' action='/Colorize Conversation/IP/New Coloring Rule'/>\n"
|
|
|
|
// " <menu name= 'TCP' action='/Colorize Conversation/TCP'>\n"
|
|
|
|
// " <menuitem name='Color1' action='/Colorize Conversation/TCP/Color 1'/>\n"
|
|
|
|
// " <menuitem name='Color2' action='/Colorize Conversation/TCP/Color 2'/>\n"
|
|
|
|
// " <menuitem name='Color3' action='/Colorize Conversation/TCP/Color 3'/>\n"
|
|
|
|
// " <menuitem name='Color4' action='/Colorize Conversation/TCP/Color 4'/>\n"
|
|
|
|
// " <menuitem name='Color5' action='/Colorize Conversation/TCP/Color 5'/>\n"
|
|
|
|
// " <menuitem name='Color6' action='/Colorize Conversation/TCP/Color 6'/>\n"
|
|
|
|
// " <menuitem name='Color7' action='/Colorize Conversation/TCP/Color 7'/>\n"
|
|
|
|
// " <menuitem name='Color8' action='/Colorize Conversation/TCP/Color 8'/>\n"
|
|
|
|
// " <menuitem name='Color9' action='/Colorize Conversation/TCP/Color 9'/>\n"
|
|
|
|
// " <menuitem name='Color10' action='/Colorize Conversation/TCP/Color 10'/>\n"
|
|
|
|
// " <menuitem name='NewColoringRule' action='/Colorize Conversation/TCP/New Coloring Rule'/>\n"
|
|
|
|
// " <menu name= 'UDP' action='/Colorize Conversation/UDP'>\n"
|
|
|
|
// " <menuitem name='Color1' action='/Colorize Conversation/UDP/Color 1'/>\n"
|
|
|
|
// " <menuitem name='Color2' action='/Colorize Conversation/UDP/Color 2'/>\n"
|
|
|
|
// " <menuitem name='Color3' action='/Colorize Conversation/UDP/Color 3'/>\n"
|
|
|
|
// " <menuitem name='Color4' action='/Colorize Conversation/UDP/Color 4'/>\n"
|
|
|
|
// " <menuitem name='Color5' action='/Colorize Conversation/UDP/Color 5'/>\n"
|
|
|
|
// " <menuitem name='Color6' action='/Colorize Conversation/UDP/Color 6'/>\n"
|
|
|
|
// " <menuitem name='Color7' action='/Colorize Conversation/UDP/Color 7'/>\n"
|
|
|
|
// " <menuitem name='Color8' action='/Colorize Conversation/UDP/Color 8'/>\n"
|
|
|
|
// " <menuitem name='Color9' action='/Colorize Conversation/UDP/Color 9'/>\n"
|
|
|
|
// " <menuitem name='Color10' action='/Colorize Conversation/UDP/Color 10'/>\n"
|
|
|
|
// " <menuitem name='NewColoringRule' action='/Colorize Conversation/UDP/New Coloring Rule'/>\n"
|
|
|
|
// " <menu name= 'PN-CBA' action='/Colorize Conversation/PN-CBA'>\n"
|
|
|
|
// " <menuitem name='Color1' action='/Colorize Conversation/PN-CBA/Color 1'/>\n"
|
|
|
|
// " <menuitem name='Color2' action='/Colorize Conversation/PN-CBA/Color 2'/>\n"
|
|
|
|
// " <menuitem name='Color3' action='/Colorize Conversation/PN-CBA/Color 3'/>\n"
|
|
|
|
// " <menuitem name='Color4' action='/Colorize Conversation/PN-CBA/Color 4'/>\n"
|
|
|
|
// " <menuitem name='Color5' action='/Colorize Conversation/PN-CBA/Color 5'/>\n"
|
|
|
|
// " <menuitem name='Color6' action='/Colorize Conversation/PN-CBA/Color 6'/>\n"
|
|
|
|
// " <menuitem name='Color7' action='/Colorize Conversation/PN-CBA/Color 7'/>\n"
|
|
|
|
// " <menuitem name='Color8' action='/Colorize Conversation/PN-CBA/Color 8'/>\n"
|
|
|
|
// " <menuitem name='Color9' action='/Colorize Conversation/PN-CBA/Color 9'/>\n"
|
|
|
|
// " <menuitem name='Color10' action='/Colorize Conversation/PN-CBA/Color 10'/>\n"
|
|
|
|
// " <menuitem name='NewColoringRule' action='/Colorize Conversation/PN-CBA/New Coloring Rule'/>\n"
|
|
|
|
// " <menu name= 'SCTP' action='/SCTP'>\n"
|
|
|
|
// " <menuitem name='AnalysethisAssociation' action='/SCTP/Analyse this Association'/>\n"
|
|
|
|
// " <menuitem name='PrepareFilterforthisAssociation' action='/SCTP/Prepare Filter for this Association'/>\n"
|
|
|
|
// " <menuitem name='FollowTCPStream' action='/Follow TCP Stream'/>\n"
|
|
|
|
// " <menuitem name='FollowUDPStream' action='/Follow UDP Stream'/>\n"
|
|
|
|
// " <menuitem name='FollowSSLStream' action='/Follow SSL Stream'/>\n"
|
|
|
|
ctx_menu_.addSeparator();
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionCopy");
|
|
|
|
submenu = new QMenu();
|
|
|
|
action->setMenu(submenu);
|
|
|
|
ctx_menu_.addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menuitem name='SummaryTxt' action='/Copy/SummaryTxt'/>\n"
|
|
|
|
// " <menuitem name='SummaryCSV' action='/Copy/SummaryCSV'/>\n"
|
|
|
|
submenu->addAction(window()->findChild<QAction *>("actionEditCopyAsFilter"));
|
|
|
|
submenu->addSeparator();
|
2013-12-21 16:55:43 +00:00
|
|
|
|
|
|
|
action = window()->findChild<QAction *>("actionBytes");
|
|
|
|
subsubmenu = new QMenu();
|
|
|
|
action->setMenu(subsubmenu);
|
|
|
|
submenu->addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menuitem name='OffsetHexText' action='/Copy/Bytes/OffsetHexText'/>\n"
|
|
|
|
// " <menuitem name='OffsetHex' action='/Copy/Bytes/OffsetHex'/>\n"
|
|
|
|
// " <menuitem name='PrintableTextOnly' action='/Copy/Bytes/PrintableTextOnly'/>\n"
|
2013-12-21 16:55:43 +00:00
|
|
|
// ctx_menu_.addSeparator();
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menuitem name='HexStream' action='/Copy/Bytes/HexStream'/>\n"
|
|
|
|
// " <menuitem name='BinaryStream' action='/Copy/Bytes/BinaryStream'/>\n"
|
|
|
|
ctx_menu_.addSeparator();
|
|
|
|
// " <menuitem name='ProtocolPreferences' action='/ProtocolPreferences'/>\n"
|
2013-12-10 21:07:26 +00:00
|
|
|
decode_as_ = window()->findChild<QAction *>("actionAnalyzeDecodeAs");
|
|
|
|
ctx_menu_.addAction(decode_as_);
|
2015-02-11 23:00:27 +00:00
|
|
|
// "Print" not ported intentionally
|
2012-12-07 20:08:00 +00:00
|
|
|
// " <menuitem name='ShowPacketinNewWindow' action='/ShowPacketinNewWindow'/>\n"
|
2015-02-11 23:00:27 +00:00
|
|
|
action = window()->findChild<QAction *>("actionViewShowPacketInNewWindow");
|
|
|
|
ctx_menu_.addAction(action);
|
2012-12-07 20:08:00 +00:00
|
|
|
|
2015-01-01 19:41:03 +00:00
|
|
|
initHeaderContextMenu();
|
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
g_assert(gbl_cur_packet_list == NULL);
|
|
|
|
gbl_cur_packet_list = this;
|
2014-04-29 15:10:27 +00:00
|
|
|
|
2014-10-05 19:23:33 +00:00
|
|
|
connect(packet_list_model_, SIGNAL(goToPacket(int)), this, SLOT(goToPacket(int)));
|
2014-10-21 20:36:10 +00:00
|
|
|
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(redrawVisiblePackets()));
|
2015-02-19 01:18:27 +00:00
|
|
|
|
2015-01-01 19:41:03 +00:00
|
|
|
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(header(), SIGNAL(customContextMenuRequested(QPoint)),
|
|
|
|
SLOT(showHeaderMenu(QPoint)));
|
2015-02-19 01:18:27 +00:00
|
|
|
connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(sectionResized(int,int,int)));
|
2015-02-20 14:30:23 +00:00
|
|
|
|
|
|
|
connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vScrollBarActionTriggered(int)));
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
2012-08-23 02:59:31 +00:00
|
|
|
void PacketList::setProtoTree (ProtoTree *proto_tree) {
|
|
|
|
proto_tree_ = proto_tree;
|
2012-08-19 23:52:08 +00:00
|
|
|
|
2015-02-13 16:36:53 +00:00
|
|
|
connect(proto_tree_, SIGNAL(goToPacket(int)), this, SLOT(goToPacket(int)));
|
2015-02-24 01:56:14 +00:00
|
|
|
connect(proto_tree_, SIGNAL(relatedFrame(int,ft_framenum_type_t)),
|
|
|
|
&related_packet_delegate_, SLOT(addRelatedFrame(int,ft_framenum_type_t)));
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
2012-08-23 02:59:31 +00:00
|
|
|
void PacketList::setByteViewTab (ByteViewTab *byte_view_tab) {
|
|
|
|
byte_view_tab_ = byte_view_tab;
|
2012-11-06 23:20:07 +00:00
|
|
|
|
|
|
|
connect(proto_tree_, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
|
|
|
|
byte_view_tab_, SLOT(protoTreeItemChanged(QTreeWidgetItem*)));
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PacketListModel *PacketList::packetListModel() const {
|
2012-08-19 23:52:08 +00:00
|
|
|
return packet_list_model_;
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
2015-02-19 01:18:27 +00:00
|
|
|
void PacketList::showEvent (QShowEvent *) {
|
2014-06-16 23:54:57 +00:00
|
|
|
setColumnVisibility();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::selectionChanged (const QItemSelection & selected, const QItemSelection & deselected) {
|
|
|
|
QTreeView::selectionChanged(selected, deselected);
|
|
|
|
|
2012-10-30 19:21:24 +00:00
|
|
|
if (!cap_file_) return;
|
|
|
|
|
2013-07-08 16:54:18 +00:00
|
|
|
int row = selected.first().top();
|
|
|
|
cf_select_packet(cap_file_, row);
|
|
|
|
related_packet_delegate_.clear();
|
2013-11-22 17:59:15 +00:00
|
|
|
emit packetSelectionChanged();
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2013-07-08 16:54:18 +00:00
|
|
|
if (!cap_file_->edt) return;
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2013-07-08 16:54:18 +00:00
|
|
|
if (proto_tree_ && cap_file_->edt->tree) {
|
|
|
|
packet_info *pi = &cap_file_->edt->pi;
|
2015-02-24 01:56:14 +00:00
|
|
|
related_packet_delegate_.setCurrentFrame(pi->fd->num);
|
|
|
|
proto_tree_->fillProtocolTree(cap_file_->edt->tree);
|
2013-07-08 16:54:18 +00:00
|
|
|
conversation_t *conv = find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype,
|
|
|
|
pi->srcport, pi->destport, 0);
|
|
|
|
if (conv) {
|
2015-02-24 01:56:14 +00:00
|
|
|
related_packet_delegate_.setConversation(conv);
|
2013-07-08 16:54:18 +00:00
|
|
|
}
|
|
|
|
viewport()->update();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 16:54:18 +00:00
|
|
|
if (byte_view_tab_) {
|
2012-01-04 22:13:01 +00:00
|
|
|
GSList *src_le;
|
2012-10-20 19:54:56 +00:00
|
|
|
struct data_source *source;
|
2015-01-18 02:17:24 +00:00
|
|
|
char* source_name;
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-11-06 21:49:16 +00:00
|
|
|
byte_view_tab_->clear();
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-10-30 19:21:24 +00:00
|
|
|
for (src_le = cap_file_->edt->pi.data_src; src_le != NULL; src_le = src_le->next) {
|
2012-10-20 19:54:56 +00:00
|
|
|
source = (struct data_source *)src_le->data;
|
2015-01-18 02:17:24 +00:00
|
|
|
source_name = get_data_source_name(source);
|
2015-02-11 23:00:27 +00:00
|
|
|
byte_view_tab_->addTab(source_name, get_data_source_tvb(source), cap_file_->edt->tree, proto_tree_, cap_file_->current_frame->flags.encoding);
|
2015-01-18 02:17:24 +00:00
|
|
|
wmem_free(NULL, source_name);
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
2012-11-06 21:49:16 +00:00
|
|
|
byte_view_tab_->setCurrentIndex(0);
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-07 01:46:20 +00:00
|
|
|
void PacketList::contextMenuEvent(QContextMenuEvent *event)
|
|
|
|
{
|
2014-11-04 17:47:11 +00:00
|
|
|
QAction *action;
|
2014-11-16 01:35:51 +00:00
|
|
|
gboolean is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE;
|
2012-12-07 20:08:00 +00:00
|
|
|
|
2013-11-21 16:42:10 +00:00
|
|
|
/* walk the list of a available protocols in the packet to see what we have */
|
2014-11-04 17:47:11 +00:00
|
|
|
if (cap_file_ != NULL && cap_file_->edt != NULL)
|
2014-11-16 01:35:51 +00:00
|
|
|
proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, &is_udp, &is_sctp, NULL);
|
2013-09-09 19:30:30 +00:00
|
|
|
|
2014-11-04 17:47:11 +00:00
|
|
|
action = window()->findChild<QAction *>("actionSCTP");
|
2014-11-16 01:35:51 +00:00
|
|
|
if (cap_file_ != NULL && cap_file_->edt != NULL && is_sctp)
|
2014-11-04 17:47:11 +00:00
|
|
|
action->setEnabled(TRUE);
|
|
|
|
else
|
|
|
|
action->setEnabled(FALSE);
|
2013-09-09 19:30:30 +00:00
|
|
|
|
2014-11-04 17:47:11 +00:00
|
|
|
action = window()->findChild<QAction *>("actionAnalyzeFollowTCPStream");
|
|
|
|
action->setEnabled(is_tcp);
|
2013-09-09 19:30:30 +00:00
|
|
|
|
2014-11-04 17:47:11 +00:00
|
|
|
action = window()->findChild<QAction *>("actionAnalyzeFollowUDPStream");
|
|
|
|
action->setEnabled(is_udp);
|
2013-09-09 19:30:30 +00:00
|
|
|
|
2014-11-04 17:47:11 +00:00
|
|
|
action = window()->findChild<QAction *>("actionAnalyzeFollowSSLStream");
|
|
|
|
|
|
|
|
if (cap_file_ != NULL && cap_file_->edt != NULL &&
|
|
|
|
epan_dissect_packet_contains_field(cap_file_->edt, "ssl"))
|
|
|
|
action->setEnabled(TRUE);
|
|
|
|
else
|
|
|
|
action->setEnabled(FALSE);
|
2013-09-09 19:30:30 +00:00
|
|
|
|
2013-12-10 21:07:26 +00:00
|
|
|
decode_as_->setData(qVariantFromValue(true));
|
2012-12-07 20:08:00 +00:00
|
|
|
ctx_column_ = columnAt(event->x());
|
2012-12-07 01:46:20 +00:00
|
|
|
ctx_menu_.exec(event->globalPos());
|
2012-12-07 20:08:00 +00:00
|
|
|
ctx_column_ = -1;
|
2013-12-10 21:07:26 +00:00
|
|
|
decode_as_->setData(QVariant());
|
2012-12-07 01:46:20 +00:00
|
|
|
}
|
|
|
|
|
2015-02-20 14:30:23 +00:00
|
|
|
// Auto scroll if:
|
|
|
|
// - We're not at the end
|
|
|
|
// - We are capturing
|
|
|
|
// - actionGoAutoScroll in the main UI is checked.
|
|
|
|
// - It's been more than tail_update_interval_ ms since we last scrolled
|
|
|
|
// - The last user-set vertical scrollbar position was at the end.
|
|
|
|
|
|
|
|
// Using a timer assumes that we can save CPU overhead by updating
|
|
|
|
// periodically. If that's not the case we can dispense with it and call
|
|
|
|
// scrollToBottom() from rowsInserted().
|
|
|
|
void PacketList::timerEvent(QTimerEvent *event)
|
|
|
|
{
|
|
|
|
if (rows_inserted_
|
|
|
|
&& event->timerId() == tail_timer_id_
|
|
|
|
&& capture_in_progress_
|
|
|
|
&& tail_at_end_) {
|
|
|
|
scrollToBottom();
|
|
|
|
rows_inserted_ = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-17 23:03:21 +00:00
|
|
|
void PacketList::markFramesReady()
|
|
|
|
{
|
|
|
|
packets_bar_update();
|
2014-10-21 20:36:10 +00:00
|
|
|
redrawVisiblePackets();
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::setFrameMark(gboolean set, frame_data *fdata)
|
|
|
|
{
|
|
|
|
if (set)
|
|
|
|
cf_mark_frame(cap_file_, fdata);
|
|
|
|
else
|
|
|
|
cf_unmark_frame(cap_file_, fdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::setFrameIgnore(gboolean set, frame_data *fdata)
|
|
|
|
{
|
|
|
|
if (set)
|
|
|
|
cf_ignore_frame(cap_file_, fdata);
|
|
|
|
else
|
|
|
|
cf_unignore_frame(cap_file_, fdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::setFrameReftime(gboolean set, frame_data *fdata)
|
|
|
|
{
|
|
|
|
if (!fdata || !cap_file_) return;
|
|
|
|
if (set) {
|
|
|
|
fdata->flags.ref_time=1;
|
|
|
|
cap_file_->ref_time_count++;
|
|
|
|
} else {
|
|
|
|
fdata->flags.ref_time=0;
|
|
|
|
cap_file_->ref_time_count--;
|
|
|
|
}
|
|
|
|
cf_reftime_packets(cap_file_);
|
|
|
|
if (!fdata->flags.ref_time && !fdata->flags.passed_dfilter) {
|
|
|
|
cap_file_->displayed_count--;
|
|
|
|
packet_list_model_->recreateVisibleRows();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-16 23:54:57 +00:00
|
|
|
void PacketList::setColumnVisibility()
|
|
|
|
{
|
2014-06-17 22:38:29 +00:00
|
|
|
for (int i = 0; i < prefs.num_cols; i++) {
|
2014-06-16 23:54:57 +00:00
|
|
|
setColumnHidden(i, get_column_visible(i) ? false : true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-01 19:41:03 +00:00
|
|
|
void PacketList::initHeaderContextMenu()
|
|
|
|
{
|
|
|
|
header_ctx_menu_.clear();
|
|
|
|
header_actions_.clear();
|
|
|
|
|
|
|
|
// Leave these out for now since Qt doesn't have a "no sort" option
|
|
|
|
// and the user can sort by left-clicking on the header.
|
|
|
|
// header_actions_[] = header_ctx_menu_.addAction(tr("Sort Ascending"));
|
|
|
|
// header_actions_[] = header_ctx_menu_.addAction(tr("Sort Descending"));
|
|
|
|
// header_actions_[] = header_ctx_menu_.addAction(tr("Do Not Sort"));
|
|
|
|
// header_ctx_menu_.addSeparator();
|
|
|
|
header_actions_[caAlignLeft] = header_ctx_menu_.addAction(tr("Align Left"));
|
|
|
|
header_actions_[caAlignCenter] = header_ctx_menu_.addAction(tr("Align Center"));
|
|
|
|
header_actions_[caAlignRight] = header_ctx_menu_.addAction(tr("Align Right"));
|
|
|
|
header_ctx_menu_.addSeparator();
|
|
|
|
header_actions_[caColumnPreferences] = header_ctx_menu_.addAction(tr("Column Preferences" UTF8_HORIZONTAL_ELLIPSIS));
|
|
|
|
header_actions_[caEditColumn] = header_ctx_menu_.addAction(tr("Edit Column")); // XXX Create frame instead of dialog
|
|
|
|
header_actions_[caResizeToContents] = header_ctx_menu_.addAction(tr("Resize To Contents"));
|
|
|
|
header_actions_[caResolveNames] = header_ctx_menu_.addAction(tr("Resolve Names"));
|
|
|
|
header_ctx_menu_.addSeparator();
|
|
|
|
// header_actions_[caDisplayedColumns] = header_ctx_menu_.addAction(tr("Displayed Columns"));
|
|
|
|
show_hide_separator_ = header_ctx_menu_.addSeparator();
|
|
|
|
// header_actions_[caHideColumn] = header_ctx_menu_.addAction(tr("Hide This Column"));
|
|
|
|
header_actions_[caRemoveColumn] = header_ctx_menu_.addAction(tr("Remove This Column"));
|
|
|
|
|
|
|
|
foreach (ColumnActions ca, header_actions_.keys()) {
|
|
|
|
header_actions_[ca]->setData(qVariantFromValue(ca));
|
|
|
|
connect(header_actions_[ca], SIGNAL(triggered()), this, SLOT(headerMenuTriggered()));
|
|
|
|
}
|
|
|
|
|
|
|
|
checkable_actions_ = QList<ColumnActions>() << caAlignLeft << caAlignCenter << caAlignRight << caResolveNames;
|
|
|
|
foreach (ColumnActions ca, checkable_actions_) {
|
|
|
|
header_actions_[ca]->setCheckable(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
// Redraw the packet list and detail
|
2014-10-21 20:36:10 +00:00
|
|
|
void PacketList::redrawVisiblePackets() {
|
2012-12-23 04:37:58 +00:00
|
|
|
if (!cap_file_) return;
|
|
|
|
|
|
|
|
if (cap_file_->edt && cap_file_->edt->tree) {
|
|
|
|
proto_tree_->fillProtocolTree(cap_file_->edt->tree);
|
|
|
|
}
|
2013-07-23 08:56:20 +00:00
|
|
|
|
2014-10-21 20:36:10 +00:00
|
|
|
int row = currentIndex().row();
|
2015-01-01 19:41:03 +00:00
|
|
|
|
|
|
|
prefs.num_cols = g_list_length(prefs.col_list);
|
2015-02-19 01:18:27 +00:00
|
|
|
col_cleanup(&cap_file_->cinfo);
|
2015-01-01 19:41:03 +00:00
|
|
|
build_column_format_array(&cap_file_->cinfo, prefs.num_cols, FALSE);
|
|
|
|
|
2013-07-23 08:56:20 +00:00
|
|
|
packet_list_model_->resetColumns();
|
2015-02-22 22:56:38 +00:00
|
|
|
if (row >= 0) {
|
2014-10-21 20:36:10 +00:00
|
|
|
setCurrentIndex(packet_list_model_->index(row, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
update();
|
2015-01-01 19:41:03 +00:00
|
|
|
header()->update();
|
2012-08-23 17:29:05 +00:00
|
|
|
}
|
|
|
|
|
2015-02-19 01:18:27 +00:00
|
|
|
// Column widths should
|
|
|
|
// - Load from recent when we load a new profile (including at starting up).
|
|
|
|
// - Persist across freezes and thaws.
|
|
|
|
// - Persist across file closing and opening.
|
|
|
|
// - Save to recent when we save our profile (including shutting down).
|
|
|
|
|
|
|
|
void PacketList::applyRecentColumnWidths()
|
|
|
|
{
|
|
|
|
// Either we've just started up or a profile has changed. Read
|
|
|
|
// the recent settings, apply them, and save the header state.
|
|
|
|
for (int i = 0; i < prefs.num_cols; i++) {
|
|
|
|
int col_width = recent_get_column_width(i);
|
|
|
|
|
|
|
|
if (col_width < 1) {
|
|
|
|
int fmt;
|
|
|
|
const char *long_str;
|
|
|
|
|
|
|
|
fmt = get_column_format(i);
|
|
|
|
long_str = get_column_width_string(fmt, i);
|
|
|
|
if (long_str) {
|
|
|
|
col_width = packet_list_model_->columnTextSize(long_str);
|
|
|
|
} else {
|
|
|
|
col_width = packet_list_model_->columnTextSize(MIN_COL_WIDTH_STR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setColumnWidth(i, col_width);
|
|
|
|
}
|
|
|
|
column_state_ = header()->saveState();
|
|
|
|
redrawVisiblePackets();
|
|
|
|
}
|
|
|
|
|
2015-02-05 00:36:19 +00:00
|
|
|
void PacketList::recolorPackets()
|
|
|
|
{
|
|
|
|
packet_list_model_->resetColorized();
|
|
|
|
redrawVisiblePackets();
|
|
|
|
}
|
|
|
|
|
2015-02-20 14:30:23 +00:00
|
|
|
void PacketList::setAutoScroll(bool enabled)
|
|
|
|
{
|
|
|
|
tail_at_end_ = enabled;
|
2015-03-01 17:18:34 +00:00
|
|
|
if (enabled && capture_in_progress_) {
|
2015-02-20 14:30:23 +00:00
|
|
|
scrollToBottom();
|
|
|
|
if (tail_timer_id_ < 1) tail_timer_id_ = startTimer(tail_update_interval_);
|
|
|
|
} else if (tail_timer_id_ > 0) {
|
|
|
|
killTimer(tail_timer_id_);
|
|
|
|
tail_timer_id_ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-15 20:24:56 +00:00
|
|
|
void PacketList::freeze()
|
|
|
|
{
|
|
|
|
setUpdatesEnabled(false);
|
|
|
|
setModel(NULL);
|
2015-01-27 17:25:29 +00:00
|
|
|
// It looks like GTK+ sends a cursor-changed signal at this point but Qt doesn't
|
|
|
|
// call selectionChanged.
|
|
|
|
related_packet_delegate_.clear();
|
|
|
|
proto_tree_->clear();
|
|
|
|
byte_view_tab_->clear();
|
2013-11-15 20:24:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::thaw()
|
|
|
|
{
|
|
|
|
setModel(packet_list_model_);
|
2013-11-22 17:59:15 +00:00
|
|
|
setUpdatesEnabled(true);
|
2015-02-19 01:18:27 +00:00
|
|
|
|
|
|
|
// Resetting the model resets our column widths so we restore them here.
|
|
|
|
// We don't reapply the recent settings because the user could have
|
|
|
|
// resized the columns manually since they were initially loaded.
|
|
|
|
header()->restoreState(column_state_);
|
|
|
|
|
2014-06-16 23:54:57 +00:00
|
|
|
setColumnVisibility();
|
2013-11-15 20:24:56 +00:00
|
|
|
}
|
|
|
|
|
2012-01-04 22:13:01 +00:00
|
|
|
void PacketList::clear() {
|
|
|
|
// packet_history_clear();
|
2013-07-08 16:54:18 +00:00
|
|
|
related_packet_delegate_.clear();
|
2012-10-30 19:21:24 +00:00
|
|
|
packet_list_model_->clear();
|
2012-08-19 23:52:08 +00:00
|
|
|
proto_tree_->clear();
|
2012-11-06 21:49:16 +00:00
|
|
|
byte_view_tab_->clear();
|
2012-01-04 22:13:01 +00:00
|
|
|
|
2012-08-23 17:29:05 +00:00
|
|
|
/* XXX is this correct in all cases?
|
|
|
|
* Reset the sort column, use packetlist as model in case the list is frozen.
|
|
|
|
*/
|
2014-10-05 19:23:33 +00:00
|
|
|
sortByColumn(-1, Qt::AscendingOrder);
|
2014-06-17 22:38:29 +00:00
|
|
|
setColumnVisibility();
|
2012-01-04 22:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::writeRecent(FILE *rf) {
|
|
|
|
gint col, width, col_fmt;
|
|
|
|
gchar xalign;
|
|
|
|
|
|
|
|
fprintf (rf, "%s:", RECENT_KEY_COL_WIDTH);
|
2015-02-19 01:18:27 +00:00
|
|
|
for (col = 0; col < prefs.num_cols; col++) {
|
2012-01-04 22:13:01 +00:00
|
|
|
if (col > 0) {
|
|
|
|
fprintf (rf, ",");
|
|
|
|
}
|
|
|
|
col_fmt = get_column_format(col);
|
|
|
|
if (col_fmt == COL_CUSTOM) {
|
|
|
|
fprintf (rf, " %%Cus:%s,", get_column_custom_field(col));
|
|
|
|
} else {
|
|
|
|
fprintf (rf, " %s,", col_format_to_string(col_fmt));
|
|
|
|
}
|
|
|
|
width = columnWidth(col);
|
|
|
|
xalign = recent_get_column_xalign (col);
|
|
|
|
if (width == 0) {
|
|
|
|
/* We have not initialized the packet list yet, use old values */
|
|
|
|
width = recent_get_column_width (col);
|
|
|
|
}
|
|
|
|
fprintf (rf, " %d", width);
|
|
|
|
if (xalign != COLUMN_XALIGN_DEFAULT) {
|
|
|
|
fprintf (rf, ":%c", xalign);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf (rf, "\n");
|
|
|
|
|
|
|
|
}
|
2012-08-13 01:50:14 +00:00
|
|
|
|
2012-12-07 01:46:20 +00:00
|
|
|
bool PacketList::contextMenuActive()
|
|
|
|
{
|
2012-12-07 20:08:00 +00:00
|
|
|
return ctx_column_ >= 0 ? true : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString &PacketList::getFilterFromRowAndColumn()
|
|
|
|
{
|
|
|
|
frame_data *fdata;
|
|
|
|
QString &filter = *new QString();
|
|
|
|
int row = currentIndex().row();
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_ || ctx_column_ < 0 || ctx_column_ >= cap_file_->cinfo.num_cols) return filter;
|
|
|
|
|
2012-12-17 23:03:21 +00:00
|
|
|
fdata = packet_list_model_->getRowFdata(row);
|
2012-12-07 20:08:00 +00:00
|
|
|
|
|
|
|
if (fdata != NULL) {
|
|
|
|
epan_dissect_t edt;
|
|
|
|
|
2014-05-24 18:28:30 +00:00
|
|
|
if (!cf_read_record(cap_file_, fdata))
|
|
|
|
return filter; /* error reading the record */
|
2012-12-07 20:08:00 +00:00
|
|
|
/* proto tree, visible. We need a proto tree if there's custom columns */
|
2013-07-21 18:38:03 +00:00
|
|
|
epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), FALSE);
|
2012-12-07 20:08:00 +00:00
|
|
|
col_custom_prime_edt(&edt, &cap_file_->cinfo);
|
|
|
|
|
2014-05-25 00:04:44 +00:00
|
|
|
epan_dissect_run(&edt, cap_file_->cd_t, &cap_file_->phdr, frame_tvbuff_new_buffer(fdata, &cap_file_->buf), fdata, &cap_file_->cinfo);
|
2012-12-07 20:08:00 +00:00
|
|
|
epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
|
|
|
|
|
|
|
|
if ((cap_file_->cinfo.col_custom_occurrence[ctx_column_]) ||
|
|
|
|
(strchr (cap_file_->cinfo.col_expr.col_expr_val[ctx_column_], ',') == NULL))
|
|
|
|
{
|
|
|
|
/* Only construct the filter when a single occurrence is displayed
|
|
|
|
* otherwise we might end up with a filter like "ip.proto==1,6".
|
|
|
|
*
|
|
|
|
* Or do we want to be able to filter on multiple occurrences so that
|
|
|
|
* the filter might be calculated as "ip.proto==1 && ip.proto==6"
|
|
|
|
* instead?
|
|
|
|
*/
|
|
|
|
if (strlen(cap_file_->cinfo.col_expr.col_expr[ctx_column_]) != 0 &&
|
|
|
|
strlen(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]) != 0) {
|
|
|
|
if (cap_file_->cinfo.col_fmt[ctx_column_] == COL_CUSTOM) {
|
|
|
|
header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_custom_field[ctx_column_]);
|
|
|
|
if (hfi->parent == -1) {
|
|
|
|
/* Protocol only */
|
|
|
|
filter.append(cap_file_->cinfo.col_expr.col_expr[ctx_column_]);
|
|
|
|
} else if (hfi->type == FT_STRING) {
|
|
|
|
/* Custom string, add quotes */
|
|
|
|
filter.append(QString("%1 == \"%2\"")
|
|
|
|
.arg(cap_file_->cinfo.col_expr.col_expr[ctx_column_])
|
|
|
|
.arg(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (filter.isEmpty()) {
|
|
|
|
filter.append(QString("%1 == %2")
|
|
|
|
.arg(cap_file_->cinfo.col_expr.col_expr[ctx_column_])
|
|
|
|
.arg(cap_file_->cinfo.col_expr.col_expr_val[ctx_column_]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
epan_dissect_cleanup(&edt);
|
|
|
|
}
|
|
|
|
|
|
|
|
return filter;
|
2012-12-07 01:46:20 +00:00
|
|
|
}
|
|
|
|
|
2012-12-23 04:37:58 +00:00
|
|
|
QString PacketList::packetComment()
|
|
|
|
{
|
|
|
|
int row = currentIndex().row();
|
2014-10-05 19:23:33 +00:00
|
|
|
const frame_data *fdata;
|
2013-08-01 20:59:38 +00:00
|
|
|
char *pkt_comment;
|
2012-12-23 04:37:58 +00:00
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return NULL;
|
|
|
|
|
|
|
|
fdata = packet_list_model_->getRowFdata(row);
|
|
|
|
|
|
|
|
if (!fdata) return NULL;
|
|
|
|
|
2013-08-01 20:59:38 +00:00
|
|
|
pkt_comment = cf_get_comment(cap_file_, fdata);
|
|
|
|
|
|
|
|
return QString(pkt_comment);
|
|
|
|
|
|
|
|
/* XXX, g_free(pkt_comment) */
|
2012-12-23 04:37:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::setPacketComment(QString new_comment)
|
|
|
|
{
|
|
|
|
int row = currentIndex().row();
|
|
|
|
frame_data *fdata;
|
|
|
|
gchar *new_packet_comment = new_comment.toUtf8().data();
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return;
|
|
|
|
|
|
|
|
fdata = packet_list_model_->getRowFdata(row);
|
|
|
|
|
|
|
|
if (!fdata) return;
|
|
|
|
|
|
|
|
/* Check if we are clearing the comment */
|
|
|
|
if(new_comment.isEmpty()) {
|
|
|
|
new_packet_comment = NULL;
|
|
|
|
}
|
|
|
|
|
2013-08-01 20:59:38 +00:00
|
|
|
cf_set_user_packet_comment(cap_file_, fdata, new_packet_comment);
|
2012-12-23 04:37:58 +00:00
|
|
|
|
2014-10-21 20:36:10 +00:00
|
|
|
redrawVisiblePackets();
|
2012-12-23 04:37:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString PacketList::allPacketComments()
|
|
|
|
{
|
|
|
|
guint32 framenum;
|
|
|
|
frame_data *fdata;
|
|
|
|
QString buf_str;
|
|
|
|
|
|
|
|
if (!cap_file_) return buf_str;
|
|
|
|
|
|
|
|
for (framenum = 1; framenum <= cap_file_->count ; framenum++) {
|
|
|
|
fdata = frame_data_sequence_find(cap_file_->frames, framenum);
|
2013-08-01 20:59:38 +00:00
|
|
|
|
|
|
|
char *pkt_comment = cf_get_comment(cap_file_, fdata);
|
|
|
|
|
|
|
|
if (pkt_comment) {
|
2015-02-26 13:00:22 +00:00
|
|
|
buf_str.append(QString(tr("Frame %1: %2\n\n")).arg(framenum).arg(pkt_comment));
|
2013-08-01 20:59:38 +00:00
|
|
|
g_free(pkt_comment);
|
2012-12-23 04:37:58 +00:00
|
|
|
}
|
|
|
|
if (buf_str.length() > max_comments_to_fetch_) {
|
2013-01-20 18:33:06 +00:00
|
|
|
buf_str.append(QString(tr("[ Comment text exceeds %1. Stopping. ]"))
|
2012-12-23 04:37:58 +00:00
|
|
|
.arg(format_size(max_comments_to_fetch_, format_size_unit_bytes|format_size_prefix_si)));
|
|
|
|
return buf_str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return buf_str;
|
|
|
|
}
|
|
|
|
|
2012-10-30 19:21:24 +00:00
|
|
|
// Slots
|
|
|
|
|
|
|
|
void PacketList::setCaptureFile(capture_file *cf)
|
|
|
|
{
|
2015-02-19 01:18:27 +00:00
|
|
|
if (cf) {
|
|
|
|
// We're opening. Restore our column widths.
|
|
|
|
header()->restoreState(column_state_);
|
|
|
|
}
|
2012-10-30 19:21:24 +00:00
|
|
|
cap_file_ = cf;
|
|
|
|
packet_list_model_->setCaptureFile(cf);
|
|
|
|
}
|
|
|
|
|
2014-09-23 20:35:10 +00:00
|
|
|
void PacketList::setMonospaceFont(const QFont &mono_font)
|
|
|
|
{
|
|
|
|
packet_list_model_->setMonospaceFont(mono_font);
|
2014-10-21 20:36:10 +00:00
|
|
|
redrawVisiblePackets();
|
2014-09-23 20:35:10 +00:00
|
|
|
}
|
|
|
|
|
2012-08-14 04:12:56 +00:00
|
|
|
void PacketList::goNextPacket(void) {
|
2012-08-13 01:50:14 +00:00
|
|
|
setCurrentIndex(moveCursor(MoveDown, Qt::NoModifier));
|
|
|
|
}
|
|
|
|
|
2012-08-14 04:12:56 +00:00
|
|
|
void PacketList::goPreviousPacket(void) {
|
2012-08-13 01:50:14 +00:00
|
|
|
setCurrentIndex(moveCursor(MoveUp, Qt::NoModifier));
|
|
|
|
}
|
|
|
|
|
2012-08-14 04:12:56 +00:00
|
|
|
void PacketList::goFirstPacket(void) {
|
2012-08-13 01:50:14 +00:00
|
|
|
setCurrentIndex(moveCursor(MoveHome, Qt::NoModifier));
|
|
|
|
}
|
|
|
|
|
2012-08-14 04:12:56 +00:00
|
|
|
void PacketList::goLastPacket(void) {
|
2012-08-13 01:50:14 +00:00
|
|
|
setCurrentIndex(moveCursor(MoveEnd, Qt::NoModifier));
|
|
|
|
}
|
2012-08-19 23:52:08 +00:00
|
|
|
|
2013-09-06 19:07:57 +00:00
|
|
|
// XXX We can jump to the wrong packet if a display filter is applied
|
2012-08-19 23:52:08 +00:00
|
|
|
void PacketList::goToPacket(int packet) {
|
2013-09-07 00:33:41 +00:00
|
|
|
int row = packet_list_model_->packetNumberToRow(packet);
|
2015-02-22 22:56:38 +00:00
|
|
|
if (row >= 0) {
|
2013-09-07 00:33:41 +00:00
|
|
|
setCurrentIndex(packet_list_model_->index(row, 0));
|
2012-08-20 04:34:23 +00:00
|
|
|
}
|
2012-08-19 23:52:08 +00:00
|
|
|
}
|
2012-09-04 08:18:31 +00:00
|
|
|
|
2012-12-17 23:03:21 +00:00
|
|
|
void PacketList::markFrame()
|
|
|
|
{
|
|
|
|
int row = currentIndex().row();
|
|
|
|
frame_data *fdata;
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return;
|
|
|
|
|
|
|
|
fdata = packet_list_model_->getRowFdata(row);
|
|
|
|
|
2014-10-21 20:36:10 +00:00
|
|
|
if (!fdata) return;
|
|
|
|
|
2012-12-17 23:03:21 +00:00
|
|
|
setFrameMark(!fdata->flags.marked, fdata);
|
|
|
|
markFramesReady();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::markAllDisplayedFrames(bool set)
|
|
|
|
{
|
|
|
|
guint32 framenum;
|
|
|
|
frame_data *fdata;
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return;
|
|
|
|
|
|
|
|
for (framenum = 1; framenum <= cap_file_->count; framenum++) {
|
|
|
|
fdata = frame_data_sequence_find(cap_file_->frames, framenum);
|
|
|
|
if (fdata->flags.passed_dfilter)
|
|
|
|
setFrameMark(set, fdata);
|
|
|
|
}
|
|
|
|
markFramesReady();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::ignoreFrame()
|
|
|
|
{
|
|
|
|
int row = currentIndex().row();
|
|
|
|
frame_data *fdata;
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return;
|
|
|
|
|
|
|
|
fdata = packet_list_model_->getRowFdata(row);
|
|
|
|
|
|
|
|
setFrameIgnore(!fdata->flags.ignored, fdata);
|
2013-01-18 00:50:14 +00:00
|
|
|
emit packetDissectionChanged();
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::ignoreAllDisplayedFrames(bool set)
|
|
|
|
{
|
|
|
|
guint32 framenum;
|
|
|
|
frame_data *fdata;
|
|
|
|
|
|
|
|
if (!cap_file_ || !packet_list_model_) return;
|
|
|
|
|
|
|
|
for (framenum = 1; framenum <= cap_file_->count; framenum++) {
|
|
|
|
fdata = frame_data_sequence_find(cap_file_->frames, framenum);
|
|
|
|
if (!set || fdata->flags.passed_dfilter)
|
|
|
|
setFrameIgnore(set, fdata);
|
|
|
|
}
|
2013-01-18 00:50:14 +00:00
|
|
|
emit packetDissectionChanged();
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::setTimeReference()
|
|
|
|
{
|
|
|
|
if (!cap_file_) return;
|
|
|
|
|
|
|
|
if (cap_file_->current_frame) {
|
|
|
|
if(recent.gui_time_format != TS_RELATIVE && cap_file_->current_frame->flags.ref_time==0) {
|
|
|
|
int ret = QMessageBox::question(
|
|
|
|
this,
|
|
|
|
tr("Change Time Display Format?"),
|
|
|
|
tr("Time References don't work well with the currently selected Time Display Format.\n"
|
|
|
|
"Do you want to switch to \"Seconds Since Beginning of Capture\" now?"),
|
|
|
|
QMessageBox::Yes | QMessageBox::No
|
|
|
|
);
|
|
|
|
if (ret == QMessageBox::Yes) {
|
|
|
|
timestamp_set_type(TS_RELATIVE);
|
|
|
|
recent.gui_time_format = TS_RELATIVE;
|
|
|
|
cf_timestamp_auto_precision(cap_file_);
|
2014-10-21 20:36:10 +00:00
|
|
|
setFrameReftime(!cap_file_->current_frame->flags.ref_time,
|
|
|
|
cap_file_->current_frame);
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
setFrameReftime(!cap_file_->current_frame->flags.ref_time,
|
|
|
|
cap_file_->current_frame);
|
|
|
|
}
|
|
|
|
}
|
2014-10-21 20:36:10 +00:00
|
|
|
redrawVisiblePackets();
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::unsetAllTimeReferences()
|
|
|
|
{
|
|
|
|
if (!cap_file_) return;
|
|
|
|
|
|
|
|
/* XXX: we might need a progressbar here */
|
|
|
|
guint32 framenum;
|
|
|
|
frame_data *fdata;
|
|
|
|
for (framenum = 1; framenum <= cap_file_->count && cap_file_->ref_time_count > 0; framenum++) {
|
|
|
|
fdata = frame_data_sequence_find(cap_file_->frames, framenum);
|
|
|
|
if (fdata->flags.ref_time == 1) {
|
|
|
|
setFrameReftime(FALSE, fdata);
|
|
|
|
}
|
|
|
|
}
|
2014-10-21 20:36:10 +00:00
|
|
|
redrawVisiblePackets();
|
2012-12-17 23:03:21 +00:00
|
|
|
}
|
|
|
|
|
2015-01-01 19:41:03 +00:00
|
|
|
void PacketList::showHeaderMenu(QPoint pos)
|
|
|
|
{
|
|
|
|
header_ctx_column_ = header()->logicalIndexAt(pos);
|
|
|
|
foreach (ColumnActions ca, checkable_actions_) {
|
|
|
|
header_actions_[ca]->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (recent_get_column_xalign(header_ctx_column_)) {
|
|
|
|
case COLUMN_XALIGN_LEFT:
|
|
|
|
header_actions_[caAlignLeft]->setChecked(true);
|
|
|
|
break;
|
|
|
|
case COLUMN_XALIGN_CENTER:
|
2015-02-19 01:18:27 +00:00
|
|
|
header_actions_[caAlignCenter]->setChecked(true);
|
2015-01-01 19:41:03 +00:00
|
|
|
break;
|
|
|
|
case COLUMN_XALIGN_RIGHT:
|
|
|
|
header_actions_[caAlignRight]->setChecked(true);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool can_resolve = resolve_column(header_ctx_column_, cap_file_);
|
|
|
|
header_actions_[caResolveNames]->setChecked(can_resolve && get_column_resolved(header_ctx_column_));
|
|
|
|
header_actions_[caResolveNames]->setEnabled(can_resolve);
|
|
|
|
|
|
|
|
foreach (QAction *action, show_hide_actions_) {
|
|
|
|
header_ctx_menu_.removeAction(action);
|
|
|
|
delete action;
|
|
|
|
}
|
|
|
|
show_hide_actions_.clear();
|
|
|
|
for (int i = 0; i < prefs.num_cols; i++) {
|
|
|
|
QAction *action = new QAction(get_column_title(i), &header_ctx_menu_);
|
|
|
|
action->setCheckable(true);
|
|
|
|
action->setChecked(get_column_visible(i));
|
|
|
|
action->setData(qVariantFromValue(i));
|
|
|
|
connect(action, SIGNAL(triggered()), this, SLOT(columnVisibilityTriggered()));
|
|
|
|
header_ctx_menu_.insertAction(show_hide_separator_, action);
|
|
|
|
show_hide_actions_ << action;
|
|
|
|
}
|
|
|
|
|
|
|
|
header_ctx_menu_.popup(header()->viewport()->mapToGlobal(pos));
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::headerMenuTriggered()
|
|
|
|
{
|
|
|
|
QAction *ha = qobject_cast<QAction*>(sender());
|
|
|
|
if (!ha) return;
|
|
|
|
|
|
|
|
bool checked = ha->isChecked();
|
|
|
|
bool redraw = false;
|
|
|
|
|
|
|
|
switch(ha->data().value<ColumnActions>()) {
|
|
|
|
case caAlignLeft:
|
|
|
|
recent_set_column_xalign(header_ctx_column_, checked ? COLUMN_XALIGN_LEFT : COLUMN_XALIGN_DEFAULT);
|
|
|
|
break;
|
|
|
|
case caAlignCenter:
|
|
|
|
recent_set_column_xalign(header_ctx_column_, checked ? COLUMN_XALIGN_CENTER : COLUMN_XALIGN_DEFAULT);
|
|
|
|
break;
|
|
|
|
case caAlignRight:
|
|
|
|
recent_set_column_xalign(header_ctx_column_, checked ? COLUMN_XALIGN_RIGHT : COLUMN_XALIGN_DEFAULT);
|
|
|
|
break;
|
|
|
|
case caColumnPreferences:
|
|
|
|
emit showPreferences(PreferencesDialog::ppColumn);
|
|
|
|
break;
|
|
|
|
case caEditColumn:
|
|
|
|
emit editColumn(header_ctx_column_);
|
|
|
|
break;
|
|
|
|
case caResolveNames:
|
|
|
|
set_column_resolved(header_ctx_column_, checked);
|
|
|
|
redraw = true;
|
2015-01-15 18:38:25 +00:00
|
|
|
break;
|
2015-01-01 19:41:03 +00:00
|
|
|
case caResizeToContents:
|
|
|
|
resizeColumnToContents(header_ctx_column_);
|
|
|
|
break;
|
|
|
|
case caDisplayedColumns:
|
|
|
|
// No-op
|
|
|
|
break;
|
|
|
|
case caHideColumn:
|
|
|
|
set_column_visible(header_ctx_column_, FALSE);
|
|
|
|
hideColumn(header_ctx_column_);
|
|
|
|
break;
|
|
|
|
case caRemoveColumn:
|
|
|
|
column_prefs_remove_nth(header_ctx_column_);
|
|
|
|
if (!prefs.gui_use_pref_save) {
|
|
|
|
prefs_main_write();
|
|
|
|
}
|
|
|
|
setColumnVisibility();
|
|
|
|
redraw = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (redraw) {
|
|
|
|
redrawVisiblePackets();
|
|
|
|
} else {
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::columnVisibilityTriggered()
|
|
|
|
{
|
|
|
|
QAction *ha = qobject_cast<QAction*>(sender());
|
|
|
|
if (!ha) return;
|
|
|
|
|
|
|
|
set_column_visible(ha->data().toInt(), ha->isChecked());
|
|
|
|
setColumnVisibility();
|
|
|
|
}
|
|
|
|
|
2015-02-19 01:18:27 +00:00
|
|
|
void PacketList::sectionResized(int, int, int)
|
|
|
|
{
|
|
|
|
// For some reason the width of column 1 gets set to 32 when we open a file after
|
|
|
|
// closing a previous one. I (Gerald) am not sure if this is a bug in Qt or if it's
|
|
|
|
// our doing. Either way this catches that and fixes it.
|
|
|
|
if (isVisible()) {
|
|
|
|
column_state_ = header()->saveState();
|
2015-03-05 02:08:35 +00:00
|
|
|
redrawVisiblePackets();
|
2015-02-19 01:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-20 14:30:23 +00:00
|
|
|
// We need to tell when the user has scrolled the packet list, either to
|
|
|
|
// the end or anywhere other than the end.
|
|
|
|
void PacketList::vScrollBarActionTriggered(int)
|
|
|
|
{
|
|
|
|
// If we're scrolling with a mouse wheel or trackpad sliderPosition can end up
|
|
|
|
// past the end.
|
|
|
|
tail_at_end_ = (verticalScrollBar()->sliderPosition() >= verticalScrollBar()->maximum());
|
|
|
|
|
|
|
|
if (capture_in_progress_ && prefs.capture_auto_scroll) {
|
|
|
|
emit packetListScrolled(tail_at_end_);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PacketList::rowsInserted(const QModelIndex &parent, int start, int end)
|
|
|
|
{
|
|
|
|
QTreeView::rowsInserted(parent, start, end);
|
|
|
|
rows_inserted_ = true;
|
|
|
|
}
|
|
|
|
|
2012-09-04 08:18:31 +00:00
|
|
|
/*
|
|
|
|
* Editor modelines
|
|
|
|
*
|
|
|
|
* Local Variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|