summaryrefslogtreecommitdiffstats
path: root/ui/qt/packet_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/packet_list.cpp')
-rw-r--r--ui/qt/packet_list.cpp213
1 files changed, 123 insertions, 90 deletions
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index ae6f0f51..896c66fe 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -11,8 +11,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include <epan/epan.h>
@@ -36,6 +34,7 @@
#include "ui/util.h"
#include "wiretap/wtap_opttypes.h"
+#include "wsutil/filesystem.h"
#include "wsutil/str_util.h"
#include <wsutil/wslog.h>
@@ -49,6 +48,7 @@
#include "main_application.h"
#include <ui/qt/utils/data_printer.h>
#include <ui/qt/utils/frame_information.h>
+#include <ui/qt/utils/profile_switcher.h>
#include <ui/qt/utils/variant_pointer.h>
#include <ui/qt/models/pref_models.h>
#include <ui/qt/widgets/packet_list_header.h>
@@ -93,7 +93,7 @@
// 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.
-static PacketList *gbl_cur_packet_list = NULL;
+static PacketList *gbl_cur_packet_list;
const int max_comments_to_fetch_ = 20000000; // Arbitrary
const int overlay_update_interval_ = 100; // 250; // Milliseconds.
@@ -102,18 +102,18 @@ const int overlay_update_interval_ = 100; // 250; // Milliseconds.
/*
* 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.
+ * row, return false, otherwise return true.
*/
-gboolean
+bool
packet_list_select_row_from_data(frame_data *fdata_needle)
{
if (! gbl_cur_packet_list || ! gbl_cur_packet_list->model())
- return FALSE;
+ return false;
PacketListModel * model = qobject_cast<PacketListModel *>(gbl_cur_packet_list->model());
if (! model)
- return FALSE;
+ return false;
model->flushVisibleRows();
int row = -1;
@@ -132,10 +132,32 @@ packet_list_select_row_from_data(frame_data *fdata_needle)
gbl_cur_packet_list->selectionModel()->clearSelection();
gbl_cur_packet_list->selectionModel()->setCurrentIndex(model->index(row, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
gbl_cur_packet_list->scrollTo(gbl_cur_packet_list->currentIndex(), PacketList::PositionAtCenter);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
+}
+
+/*
+ * Given a field_info, select the field (which will scroll to it in
+ * the main ProtoTree, etc.) This is kind of an odd place for it,
+ * but we call this when performing Find Packet in lieu of changing the
+ * selected frame (the function above), because we found a match in the
+ * same frame as the currently selected one.
+ */
+bool
+packet_list_select_finfo(field_info *fi)
+{
+ if (! gbl_cur_packet_list || ! gbl_cur_packet_list->model())
+ return false;
+
+ if (fi) {
+ FieldInformation finfo(fi, gbl_cur_packet_list);
+ emit gbl_cur_packet_list->fieldSelected(&finfo);
+ } else {
+ emit gbl_cur_packet_list->fieldSelected(0);
+ }
+ return true;
}
void
@@ -180,21 +202,21 @@ packet_list_recent_write_all(FILE *rf) {
gbl_cur_packet_list->writeRecent(rf);
}
-gboolean
+bool
packet_list_multi_select_active(void)
{
if (gbl_cur_packet_list) {
return gbl_cur_packet_list->multiSelectActive();
}
- return FALSE;
+ return false;
}
#define MIN_COL_WIDTH_STR "MMMMMM"
PacketList::PacketList(QWidget *parent) :
QTreeView(parent),
- proto_tree_(NULL),
- cap_file_(NULL),
+ proto_tree_(nullptr),
+ cap_file_(nullptr),
ctx_column_(-1),
overlay_timer_id_(0),
create_near_overlay_(true),
@@ -209,7 +231,8 @@ PacketList::PacketList(QWidget *parent) :
frozen_selected_rows_(QModelIndexList()),
cur_history_(-1),
in_history_(false),
- finfo_array(NULL)
+ finfo_array(nullptr),
+ profile_switcher_(nullptr)
{
setItemsExpandable(false);
setRootIsDecorated(false);
@@ -227,9 +250,7 @@ PacketList::PacketList(QWidget *parent) :
connect(packet_list_header_, &PacketListHeader::columnsChanged, this, &PacketList::columnsChanged);
setHeader(packet_list_header_);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
header()->setFirstSectionMovable(true);
-#endif
setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -276,10 +297,23 @@ PacketList::~PacketList()
{
if (finfo_array)
{
- g_ptr_array_free(finfo_array, TRUE);
+ g_ptr_array_free(finfo_array, true);
}
}
+void PacketList::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint)
+{
+ /* QAbstractItemView doesn't have a way to indicate "auto scroll, but
+ * only vertically." So just restore the horizontal scroll value whenever
+ * it scrolls.
+ */
+ setUpdatesEnabled(false);
+ int horizVal = horizontalScrollBar()->value();
+ QTreeView::scrollTo(index, hint);
+ horizontalScrollBar()->setValue(horizVal);
+ setUpdatesEnabled(true);
+}
+
void PacketList::colorsChanged()
{
const QString c_active = "active";
@@ -550,7 +584,6 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
selection_history_.resize(cur_history_);
selection_history_.append(cap_file_->current_frame->num);
}
- in_history_ = false;
related_packet_delegate_.clear();
@@ -567,7 +600,7 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
if (cap_file_->edt->tree) {
packet_info *pi = &cap_file_->edt->pi;
related_packet_delegate_.setCurrentFrame(pi->num);
- conversation_t *conv = find_conversation_pinfo(pi, 0);
+ conversation_t *conv = find_conversation_pinfo_ro(pi, 0);
if (conv) {
related_packet_delegate_.setConversation(conv);
}
@@ -581,9 +614,17 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
// The tree where the target string matched one of the labels was discarded in
// match_protocol_tree() so we have to search again in the latest tree.
fi = cf_find_string_protocol_tree(cap_file_, cap_file_->edt->tree);
- } else if (cap_file_->search_pos != 0) {
+ } else if (cap_file_->search_len != 0) {
// Find the finfo that corresponds to our byte.
- fi = proto_find_field_from_offset(cap_file_->edt->tree, cap_file_->search_pos,
+ // The match can span multiple fields (and a single byte can
+ // match more than one field.) Our behavior is to find the last
+ // field in the tree (so hopefully spanning fewer bytes) that
+ // matches the last byte in the search match.
+ // (regex search can find a zero length match not at the
+ // start of the frame if lookbehind is used, but
+ // proto_find_field_from_offset doesn't match such a field
+ // and it's not clear which field we would want to match.)
+ fi = proto_find_field_from_offset(cap_file_->edt->tree, cap_file_->search_pos + cap_file_->search_len - 1,
cap_file_->edt->tvb);
}
@@ -606,16 +647,16 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
if (finfo_array)
{
- g_ptr_array_free(finfo_array, TRUE);
+ g_ptr_array_free(finfo_array, true);
finfo_array = NULL;
}
if (cap_file_ && cap_file_->edt && cap_file_->edt->tree) {
finfo_array = proto_all_finfos(cap_file_->edt->tree);
QList<QString> added_proto_prefs;
- for (guint i = 0; i < finfo_array->len; i++) {
+ for (unsigned i = 0; i < finfo_array->len; i++) {
field_info *fi = (field_info *)g_ptr_array_index (finfo_array, i);
- header_field_info *hfinfo = fi->hfinfo;
+ const header_field_info *hfinfo = fi->hfinfo;
if (prefs_is_registered_protocol(hfinfo->abbrev)) {
if (hfinfo->parent == -1) {
@@ -654,8 +695,8 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
ctx_menu->setAttribute(Qt::WA_DeleteOnClose);
// XXX We might want to reimplement setParent() and fill in the context
// menu there.
- ctx_menu->addAction(window()->findChild<QAction *>("actionEditMarkPacket"));
- ctx_menu->addAction(window()->findChild<QAction *>("actionEditIgnorePacket"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionEditMarkSelected"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionEditIgnoreSelected"));
ctx_menu->addAction(window()->findChild<QAction *>("actionEditSetTimeReference"));
ctx_menu->addAction(window()->findChild<QAction *>("actionEditTimeShift"));
ctx_menu->addMenu(window()->findChild<QMenu *>("menuPacketComment"));
@@ -728,6 +769,7 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
main_menu_item = window()->findChild<QMenu *>("menuEditCopy");
submenu = new QMenu(main_menu_item->title(), ctx_menu);
+ submenu->setToolTipsVisible(true);
ctx_menu->addMenu(submenu);
QAction * action = submenu->addAction(tr("Summary as Text"));
@@ -749,15 +791,16 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
copyEntries->setParent(submenu);
frameData->setParent(submenu);
- ctx_menu->addSeparator();
- ctx_menu->addMenu(&proto_prefs_menus_);
- action = ctx_menu->addAction(tr("Decode As…"));
- action->setProperty("create_new", QVariant(true));
- connect(action, &QAction::triggered, this, &PacketList::ctxDecodeAsDialog);
- // "Print" not ported intentionally
- action = window()->findChild<QAction *>("actionViewShowPacketInNewWindow");
- ctx_menu->addAction(action);
-
+ if (is_packet_configuration_namespace()) {
+ ctx_menu->addSeparator();
+ ctx_menu->addMenu(&proto_prefs_menus_);
+ action = ctx_menu->addAction(tr("Decode As…"));
+ action->setProperty("create_new", QVariant(true));
+ connect(action, &QAction::triggered, this, &PacketList::ctxDecodeAsDialog);
+ // "Print" not ported intentionally
+ action = window()->findChild<QAction *>("actionViewShowPacketInNewWindow");
+ ctx_menu->addAction(action);
+ }
// Set menu sensitivity for the current column and set action data.
if (frameData)
@@ -805,9 +848,7 @@ void PacketList::paintEvent(QPaintEvent *event)
void PacketList::mousePressEvent (QMouseEvent *event)
{
- setAutoScroll(false);
QTreeView::mousePressEvent(event);
- setAutoScroll(true);
QModelIndex curIndex = indexAt(event->pos());
mouse_pressed_at_ = curIndex;
@@ -918,23 +959,7 @@ void PacketList::mouseMoveEvent (QMouseEvent *event)
void PacketList::keyPressEvent(QKeyEvent *event)
{
- bool handled = false;
- // If scrolling up/down, want to preserve horizontal scroll extent.
- if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Up ||
- event->key() == Qt::Key_PageDown || event->key() == Qt::Key_PageUp ||
- event->key() == Qt::Key_End || event->key() == Qt::Key_Home )
- {
- // XXX: Why allow jumping to the left if the first column is current?
- if (currentIndex().isValid() && currentIndex().column() > 0) {
- int pos = horizontalScrollBar()->value();
- QTreeView::keyPressEvent(event);
- horizontalScrollBar()->setValue(pos);
- handled = true;
- }
- }
-
- if (!handled)
- QTreeView::keyPressEvent(event);
+ QTreeView::keyPressEvent(event);
if (event->matches(QKeySequence::Copy))
{
@@ -1008,19 +1033,11 @@ void PacketList::setRecentColumnWidth(int col)
const char *long_str = get_column_width_string(fmt, col);
QFontMetrics fm = QFontMetrics(mainApp->monospaceFont());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
if (long_str) {
col_width = fm.horizontalAdvance(long_str);
} else {
col_width = fm.horizontalAdvance(MIN_COL_WIDTH_STR);
}
-#else
- if (long_str) {
- col_width = fm.width(long_str);
- } else {
- col_width = fm.width(MIN_COL_WIDTH_STR);
- }
-#endif
// Custom delegate padding
if (itemDelegateForColumn(col)) {
QStyleOptionViewItem option;
@@ -1102,6 +1119,14 @@ bool PacketList::havePreviousHistory(bool update_cur)
return false;
}
+void PacketList::setProfileSwitcher(ProfileSwitcher *profile_switcher)
+{
+ profile_switcher_ = profile_switcher;
+ if (profile_switcher) {
+ connect(packet_list_model_, &PacketListModel::packetAppended, profile_switcher_, &ProfileSwitcher::checkPacket);
+ }
+}
+
frame_data *PacketList::getFDataForRow(int row) const
{
return packet_list_model_->getRowFdata(row);
@@ -1120,7 +1145,7 @@ void PacketList::columnsChanged()
prefs.num_cols = g_list_length(prefs.col_list);
col_cleanup(&cap_file_->cinfo);
- build_column_format_array(&cap_file_->cinfo, prefs.num_cols, FALSE);
+ build_column_format_array(&cap_file_->cinfo, prefs.num_cols, false);
create_far_overlay_ = true;
resetColumns();
applyRecentColumnWidths();
@@ -1133,7 +1158,7 @@ void PacketList::fieldsChanged(capture_file *cf)
{
prefs.num_cols = g_list_length(prefs.col_list);
col_cleanup(&cf->cinfo);
- build_column_format_array(&cf->cinfo, prefs.num_cols, FALSE);
+ build_column_format_array(&cf->cinfo, prefs.num_cols, false);
resetColumns();
}
@@ -1163,9 +1188,6 @@ void PacketList::applyRecentColumnWidths()
void PacketList::preferencesChanged()
{
- // Update color style changes
- colorsChanged();
-
// Related packet delegate
if (prefs.gui_packet_list_show_related) {
setItemDelegateForColumn(0, &related_packet_delegate_);
@@ -1329,8 +1351,8 @@ void PacketList::clear() {
}
void PacketList::writeRecent(FILE *rf) {
- gint col, width, col_fmt;
- gchar xalign;
+ int col, width, col_fmt;
+ char xalign;
fprintf (rf, "%s:\n", RECENT_KEY_COL_WIDTH);
for (col = 0; col < prefs.num_cols; col++) {
@@ -1387,7 +1409,7 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
return filter; /* error reading the record */
}
/* proto tree, visible. We need a proto tree if there's custom columns */
- epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), FALSE);
+ epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), false);
col_custom_prime_edt(&edt, &cap_file_->cinfo);
epan_dissect_run(&edt, cap_file_->cd_t, &rec,
@@ -1400,14 +1422,14 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
/* We don't need to fill in the custom columns, as we get their
* filters above.
*/
- col_fill_in(&edt.pi, TRUE, TRUE);
+ col_fill_in(&edt.pi, true, true);
if (strlen(cap_file_->cinfo.col_expr.col_expr[column]) != 0 &&
strlen(cap_file_->cinfo.col_expr.col_expr_val[column]) != 0) {
- gboolean is_string_value = FALSE;
+ bool is_string_value = false;
header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_expr.col_expr[column]);
- if (hfi && hfi->type == FT_STRING) {
+ if (hfi && FT_IS_STRING(hfi->type)) {
/* Could be an address type such as usb.src which must be quoted. */
- is_string_value = TRUE;
+ is_string_value = true;
}
if (filter.isEmpty()) {
@@ -1438,7 +1460,7 @@ void PacketList::resetColorized()
update();
}
-QString PacketList::getPacketComment(guint c_number)
+QString PacketList::getPacketComment(unsigned c_number)
{
int row = currentIndex().row();
const frame_data *fdata;
@@ -1487,7 +1509,7 @@ void PacketList::addPacketComment(QString new_comment)
}
}
-void PacketList::setPacketComment(guint c_number, QString new_comment)
+void PacketList::setPacketComment(unsigned c_number, QString new_comment)
{
QModelIndex curIndex = currentIndex();
@@ -1513,7 +1535,7 @@ void PacketList::setPacketComment(guint c_number, QString new_comment)
QString PacketList::allPacketComments()
{
- guint32 framenum;
+ uint32_t framenum;
frame_data *fdata;
QString buf_str;
@@ -1525,8 +1547,8 @@ QString PacketList::allPacketComments()
wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata);
if (pkt_block) {
- guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
- for (guint i = 0; i < n_comments; i++) {
+ unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ for (unsigned i = 0; i < n_comments; i++) {
char *comment_text;
if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, i, &comment_text)) {
buf_str.append(QString(tr("Frame %1: %2\n\n")).arg(framenum).arg(comment_text));
@@ -1584,7 +1606,12 @@ void PacketList::setCaptureFile(capture_file *cf)
void PacketList::setMonospaceFont(const QFont &mono_font)
{
setFont(mono_font);
- header()->setFont(mainApp->font());
+}
+
+void PacketList::setRegularFont(const QFont &regular_font)
+{
+ header()->setFont(regular_font);
+ header()->viewport()->setFont(regular_font);
}
void PacketList::goNextPacket(void)
@@ -1644,16 +1671,14 @@ void PacketList::goLastPacket(void) {
scrollViewChanged(false);
}
-// XXX We can jump to the wrong packet if a display filter is applied
void PacketList::goToPacket(int packet, int hf_id)
{
- if (!cf_goto_frame(cap_file_, packet))
+ if (!cf_goto_frame(cap_file_, packet, false))
return;
- int row = packet_list_model_->packetNumberToRow(packet);
- if (row >= 0) {
- selectionModel()->setCurrentIndex(packet_list_model_->index(row, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
- scrollTo(currentIndex(), PositionAtCenter);
+ // cf_goto_frame only returns true if packet_list_select_row_from_data
+ // succeeds, the latter has already selected and scrolled to the frame.
+ if (hf_id > 0) {
proto_tree_->goToHfid(hf_id);
}
@@ -1810,7 +1835,7 @@ void PacketList::sectionResized(int col, int, int new_width)
// visible.
//
// Don't set column width when columns changed or setting column
- // visibility because we may get a sectionReized() from QTreeView
+ // visibility because we may get a sectionResized() from QTreeView
// with values from a old columns layout.
//
// Don't set column width when hiding a column.
@@ -1825,6 +1850,7 @@ void PacketList::sectionResized(int col, int, int new_width)
void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
{
GList *new_col_list = NULL;
+ GList *new_recent_col_list = NULL;
QList<int> saved_sizes;
int sort_idx;
@@ -1849,9 +1875,14 @@ void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisua
saved_sizes << header()->sectionSize(log_idx);
void *pref_data = g_list_nth_data(prefs.col_list, log_idx);
- if (!pref_data) continue;
+ if (pref_data) {
+ new_col_list = g_list_append(new_col_list, pref_data);
+ }
- new_col_list = g_list_append(new_col_list, pref_data);
+ pref_data = g_list_nth_data(recent.col_width_list, log_idx);
+ if (pref_data) {
+ new_recent_col_list = g_list_append(new_recent_col_list, pref_data);
+ }
}
// Undo move to ensure that the logical indices map to the visual indices,
@@ -1869,6 +1900,8 @@ void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisua
g_list_free(prefs.col_list);
prefs.col_list = new_col_list;
+ g_list_free(recent.col_width_list);
+ recent.col_width_list = new_recent_col_list;
thaw(true);
@@ -1988,7 +2021,7 @@ void PacketList::scrollViewChanged(bool at_end)
// out colors.
// Try 3: One packet per vertical scroll bar pixel. This seems to work best
// but has the smallest window.
-// Try 4: Use a multiple of the scroll bar heigh and scale the image down
+// Try 4: Use a multiple of the scroll bar height and scale the image down
// using Qt::SmoothTransformation. This gives us more packets per raster
// line.