2008-04-12 19:59:05 +00:00
|
|
|
/* main_packet_list.c
|
2002-09-21 11:36:30 +00:00
|
|
|
* packet list related functions 2002 Olivier Abad
|
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
2002-09-21 11:36:30 +00:00
|
|
|
*
|
2006-05-21 05:12:17 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2002-09-21 11:36:30 +00:00
|
|
|
* 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
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
2004-01-09 20:36:47 +00:00
|
|
|
#include <string.h>
|
2002-09-21 11:36:30 +00:00
|
|
|
|
2008-04-12 19:38:29 +00:00
|
|
|
#include <epan/epan.h>
|
2004-09-29 02:54:22 +00:00
|
|
|
#include <epan/column.h>
|
2008-04-12 19:38:29 +00:00
|
|
|
#include <epan/column_info.h>
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2008-04-12 19:38:29 +00:00
|
|
|
#include <epan/timestamp.h>
|
2008-04-12 23:34:44 +00:00
|
|
|
|
|
|
|
#include "../globals.h"
|
|
|
|
#include "../color.h"
|
|
|
|
#include "../color_filters.h"
|
|
|
|
#include "../ui_util.h"
|
|
|
|
#include "../progress_dlg.h"
|
|
|
|
|
|
|
|
#include "gtk/gtkglobals.h"
|
|
|
|
#include "gtk/gui_utils.h"
|
2008-04-13 12:41:22 +00:00
|
|
|
#include "gtk/color_utils.h"
|
2008-04-12 23:34:44 +00:00
|
|
|
#include "gtk/capture_file_dlg.h"
|
|
|
|
#include "gtk/keys.h"
|
|
|
|
#include "gtk/font_utils.h"
|
|
|
|
#include "gtk/packet_history.h"
|
|
|
|
#include "gtk/recent.h"
|
|
|
|
#include "gtk/main.h"
|
|
|
|
#include "gtk/main_menu.h"
|
|
|
|
#include "gtk/main_packet_list.h"
|
|
|
|
#include "gtk/main_statusbar.h"
|
2008-11-17 23:03:58 +00:00
|
|
|
#include "gtk/packet_win.h"
|
2004-01-09 08:36:23 +00:00
|
|
|
|
|
|
|
#include "image/clist_ascend.xpm"
|
|
|
|
#include "image/clist_descend.xpm"
|
|
|
|
|
2005-01-29 02:14:25 +00:00
|
|
|
#define N_PROGBAR_UPDATES 100
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
typedef struct column_arrows {
|
|
|
|
GtkWidget *table;
|
|
|
|
GtkWidget *ascend_pm;
|
|
|
|
GtkWidget *descend_pm;
|
|
|
|
} column_arrows;
|
|
|
|
|
|
|
|
GtkWidget *packet_list;
|
2007-12-05 23:50:28 +00:00
|
|
|
static gboolean last_at_end = FALSE;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
/* GtkClist compare routine, overrides default to allow numeric comparison */
|
2004-01-28 10:19:36 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
#define COMPARE_FRAME_NUM() ((fdata1->num < fdata2->num) ? -1 : \
|
|
|
|
(fdata1->num > fdata2->num) ? 1 : \
|
|
|
|
0)
|
2004-01-28 10:19:36 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
#define COMPARE_NUM(f) ((fdata1->f < fdata2->f) ? -1 : \
|
|
|
|
(fdata1->f > fdata2->f) ? 1 : \
|
|
|
|
COMPARE_FRAME_NUM())
|
2004-01-31 04:26:23 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
/* Compare time stamps.
|
|
|
|
A packet whose time is a reference time is considered to have
|
|
|
|
a lower time stamp than any frame with a non-reference time;
|
|
|
|
if both packets' times are reference times, we compare the
|
|
|
|
times of the packets. */
|
2005-08-24 21:31:56 +00:00
|
|
|
#define COMPARE_TS(ts) \
|
2008-12-09 00:03:09 +00:00
|
|
|
((fdata1->flags.ref_time && !fdata2->flags.ref_time) ? -1 : \
|
|
|
|
(!fdata1->flags.ref_time && fdata2->flags.ref_time) ? 1 : \
|
|
|
|
(fdata1->ts.secs < fdata2->ts.secs) ? -1 : \
|
|
|
|
(fdata1->ts.secs > fdata2->ts.secs) ? 1 : \
|
|
|
|
(fdata1->ts.nsecs < fdata2->ts.nsecs) ? -1 :\
|
|
|
|
(fdata1->ts.nsecs > fdata2->ts.nsecs) ? 1 : \
|
|
|
|
COMPARE_FRAME_NUM())
|
2004-01-09 08:36:23 +00:00
|
|
|
static gint
|
2008-04-05 05:39:07 +00:00
|
|
|
packet_list_compare(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
2004-01-28 09:53:09 +00:00
|
|
|
/* Get row data structures */
|
2008-04-05 05:39:07 +00:00
|
|
|
const GtkCListRow *row1 = (const GtkCListRow *)ptr1;
|
|
|
|
const GtkCListRow *row2 = (const GtkCListRow *)ptr2;
|
2004-01-28 09:53:09 +00:00
|
|
|
|
|
|
|
/* Get the frame data structures for the rows */
|
|
|
|
const frame_data *fdata1 = row1->data;
|
|
|
|
const frame_data *fdata2 = row2->data;
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
/* Get row text strings */
|
2004-01-28 09:53:09 +00:00
|
|
|
const char *text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
|
|
|
|
const char *text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
|
|
|
/* Attempt to convert to numbers */
|
2004-01-28 10:19:36 +00:00
|
|
|
double num1;
|
|
|
|
double num2;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-02-24 12:37:37 +00:00
|
|
|
/* For checking custom column type */
|
|
|
|
header_field_info *hfi;
|
|
|
|
gboolean custom_numeric = FALSE;
|
|
|
|
|
2004-01-31 04:26:23 +00:00
|
|
|
int ret;
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
gint col_fmt = cfile.cinfo.col_fmt[clist->sort_column];
|
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
switch (col_fmt) {
|
2004-01-28 09:53:09 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
case COL_NUMBER:
|
2004-01-31 04:26:23 +00:00
|
|
|
return COMPARE_FRAME_NUM();
|
2004-01-28 09:53:09 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
case COL_CLS_TIME:
|
2005-08-25 21:29:54 +00:00
|
|
|
switch (timestamp_get_type()) {
|
2004-01-28 09:53:09 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
case TS_ABSOLUTE:
|
|
|
|
case TS_ABSOLUTE_WITH_DATE:
|
2006-12-05 03:19:51 +00:00
|
|
|
case TS_EPOCH:
|
2005-08-24 21:31:56 +00:00
|
|
|
return COMPARE_TS(abs_ts);
|
2004-01-28 09:53:09 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
case TS_RELATIVE:
|
2005-08-24 21:31:56 +00:00
|
|
|
return COMPARE_TS(rel_ts);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
|
|
|
case TS_DELTA:
|
2007-03-23 18:08:17 +00:00
|
|
|
return COMPARE_TS(del_cap_ts);
|
|
|
|
|
|
|
|
case TS_DELTA_DIS:
|
|
|
|
return COMPARE_TS(del_dis_ts);
|
2005-09-26 07:08:42 +00:00
|
|
|
|
|
|
|
case TS_NOT_SET:
|
|
|
|
return 0;
|
2004-01-28 09:53:09 +00:00
|
|
|
}
|
2004-01-28 10:19:36 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
case COL_ABS_TIME:
|
2005-01-13 17:31:33 +00:00
|
|
|
case COL_ABS_DATE_TIME:
|
2005-08-24 21:31:56 +00:00
|
|
|
return COMPARE_TS(abs_ts);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
|
|
|
case COL_REL_TIME:
|
2005-08-24 21:31:56 +00:00
|
|
|
return COMPARE_TS(rel_ts);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
|
|
|
case COL_DELTA_TIME:
|
2007-03-23 18:08:17 +00:00
|
|
|
return COMPARE_TS(del_cap_ts);
|
|
|
|
|
|
|
|
case COL_DELTA_TIME_DIS:
|
|
|
|
return COMPARE_TS(del_dis_ts);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
|
|
|
case COL_PACKET_LENGTH:
|
2004-01-31 04:26:23 +00:00
|
|
|
return COMPARE_NUM(pkt_len);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
2004-01-31 04:10:05 +00:00
|
|
|
case COL_CUMULATIVE_BYTES:
|
2004-01-31 04:26:23 +00:00
|
|
|
return COMPARE_NUM(cum_bytes);
|
2004-01-28 10:19:36 +00:00
|
|
|
|
2008-02-24 12:37:37 +00:00
|
|
|
case COL_CUSTOM:
|
|
|
|
hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[clist->sort_column]);
|
|
|
|
if (hfi == NULL) {
|
|
|
|
return COMPARE_FRAME_NUM();
|
|
|
|
} else if ((hfi->strings == NULL) &&
|
|
|
|
(((IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)) &&
|
|
|
|
((hfi->display == BASE_DEC) || (hfi->display == BASE_DEC_HEX) ||
|
|
|
|
(hfi->display == BASE_OCT))) ||
|
|
|
|
(hfi->type == FT_DOUBLE) || (hfi->type == FT_FLOAT) ||
|
|
|
|
(hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
|
|
|
|
(hfi->type == FT_RELATIVE_TIME))) {
|
|
|
|
|
|
|
|
/* Compare numeric column */
|
|
|
|
custom_numeric = TRUE;
|
|
|
|
}
|
|
|
|
/* FALLTHRU */
|
2004-01-28 10:19:36 +00:00
|
|
|
default:
|
|
|
|
num1 = atof(text1);
|
|
|
|
num2 = atof(text2);
|
|
|
|
if ((col_fmt == COL_UNRES_SRC_PORT) || (col_fmt == COL_UNRES_DST_PORT) ||
|
2008-12-09 00:03:09 +00:00
|
|
|
(custom_numeric) ||
|
2008-02-20 05:47:39 +00:00
|
|
|
((num1 != 0) && (num2 != 0) && ((col_fmt == COL_DEF_SRC_PORT) ||
|
2008-02-24 12:37:37 +00:00
|
|
|
(col_fmt == COL_RES_SRC_PORT) ||
|
|
|
|
(col_fmt == COL_DEF_DST_PORT) ||
|
|
|
|
(col_fmt == COL_RES_DST_PORT)))) {
|
2004-01-28 09:53:09 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
/* Compare numeric column */
|
|
|
|
|
|
|
|
if (num1 < num2)
|
2004-01-28 09:53:09 +00:00
|
|
|
return -1;
|
2004-01-28 10:19:36 +00:00
|
|
|
else if (num1 > num2)
|
2004-01-28 09:53:09 +00:00
|
|
|
return 1;
|
|
|
|
else
|
2004-01-31 04:26:23 +00:00
|
|
|
return COMPARE_FRAME_NUM();
|
2004-01-28 09:53:09 +00:00
|
|
|
}
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
else {
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
/* Compare text column */
|
2004-01-31 04:26:23 +00:00
|
|
|
if (!text2) {
|
2008-02-24 12:37:37 +00:00
|
|
|
if (text1)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return COMPARE_FRAME_NUM();
|
2004-01-31 04:26:23 +00:00
|
|
|
}
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2004-01-28 10:19:36 +00:00
|
|
|
if (!text1)
|
|
|
|
return -1;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2004-01-31 04:26:23 +00:00
|
|
|
ret = strcmp(text1, text2);
|
|
|
|
if (ret == 0)
|
|
|
|
return COMPARE_FRAME_NUM();
|
|
|
|
else
|
|
|
|
return ret;
|
2004-01-28 10:19:36 +00:00
|
|
|
}
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* What to do when a column is clicked */
|
|
|
|
static void
|
2008-04-05 05:39:07 +00:00
|
|
|
packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
|
|
|
column_arrows *col_arrows = (column_arrows *) data;
|
|
|
|
int i;
|
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_freeze(clist);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
|
|
|
for (i = 0; i < cfile.cinfo.num_cols; i++) {
|
|
|
|
gtk_widget_hide(col_arrows[i].ascend_pm);
|
|
|
|
gtk_widget_hide(col_arrows[i].descend_pm);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (column == clist->sort_column) {
|
|
|
|
if (clist->sort_type == GTK_SORT_ASCENDING) {
|
|
|
|
clist->sort_type = GTK_SORT_DESCENDING;
|
|
|
|
gtk_widget_show(col_arrows[column].descend_pm);
|
|
|
|
} else {
|
|
|
|
clist->sort_type = GTK_SORT_ASCENDING;
|
|
|
|
gtk_widget_show(col_arrows[column].ascend_pm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
clist->sort_type = GTK_SORT_ASCENDING;
|
|
|
|
gtk_widget_show(col_arrows[column].ascend_pm);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_sort_column(clist, column);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_thaw(clist);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_sort(clist);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2008-06-14 16:45:06 +00:00
|
|
|
static void
|
|
|
|
packet_list_resize_column_cb(GtkCList *clist _U_, gint column, gint width, gpointer data _U_)
|
|
|
|
{
|
|
|
|
recent_set_column_width (column, width);
|
|
|
|
}
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
/* What to do when a list item is selected/unselected */
|
|
|
|
static void
|
2008-12-09 00:03:09 +00:00
|
|
|
packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_)
|
|
|
|
{
|
2007-05-04 11:21:03 +00:00
|
|
|
frame_data *fdata;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-11-18 14:36:48 +00:00
|
|
|
/* Check if already selected */
|
2008-11-18 14:50:51 +00:00
|
|
|
if (cfile.current_frame && cfile.current_row == row)
|
2008-11-18 14:36:48 +00:00
|
|
|
return;
|
|
|
|
|
2007-05-04 11:21:03 +00:00
|
|
|
/* Remove the hex display tabbed pages */
|
2004-01-09 08:36:23 +00:00
|
|
|
while( (gtk_notebook_get_nth_page( GTK_NOTEBOOK(byte_nb_ptr), 0)))
|
|
|
|
gtk_notebook_remove_page( GTK_NOTEBOOK(byte_nb_ptr), 0);
|
|
|
|
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_select_packet(&cfile, row);
|
2004-01-09 08:36:23 +00:00
|
|
|
gtk_widget_grab_focus(packet_list);
|
2007-05-04 11:21:03 +00:00
|
|
|
|
|
|
|
/* Lookup the frame number that corresponds to the list row number */
|
|
|
|
fdata = (frame_data *)packet_list_get_row_data(row);
|
|
|
|
if (fdata != NULL) {
|
|
|
|
packet_history_add(fdata->num);
|
|
|
|
}
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-12-09 00:03:09 +00:00
|
|
|
packet_list_unselect_cb(GtkWidget *w _U_, gint row _U_, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_)
|
|
|
|
{
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_unselect_packet(&cfile);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* mark packets */
|
|
|
|
static void
|
2008-12-09 00:03:09 +00:00
|
|
|
set_frame_mark(gboolean set, frame_data *frame, gint row)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
GdkColor fg, bg;
|
|
|
|
|
|
|
|
if (row == -1)
|
|
|
|
return;
|
|
|
|
if (set) {
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_mark_frame(&cfile, frame);
|
2004-01-09 08:36:23 +00:00
|
|
|
color_t_to_gdkcolor(&fg, &prefs.gui_marked_fg);
|
|
|
|
color_t_to_gdkcolor(&bg, &prefs.gui_marked_bg);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
|
|
|
|
gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
|
2004-01-09 08:36:23 +00:00
|
|
|
} else {
|
|
|
|
color_filter_t *cfilter = frame->color_filter;
|
|
|
|
|
2005-02-04 18:44:44 +00:00
|
|
|
cf_unmark_frame(&cfile, frame);
|
2004-01-09 08:36:23 +00:00
|
|
|
/* Restore the color from the matching color filter if any */
|
|
|
|
if (cfilter) { /* The packet matches a color filter */
|
|
|
|
color_t_to_gdkcolor(&fg, &cfilter->fg_color);
|
|
|
|
color_t_to_gdkcolor(&bg, &cfilter->bg_color);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
|
|
|
|
gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
|
2004-01-09 08:36:23 +00:00
|
|
|
} else { /* No color filter match */
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_foreground(GTK_CLIST(packet_list), row, NULL);
|
|
|
|
gtk_clist_set_background(GTK_CLIST(packet_list), row, NULL);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
}
|
2004-02-03 00:16:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* call this after last set_frame_mark is done */
|
2008-12-09 00:03:09 +00:00
|
|
|
static void mark_frames_ready(void)
|
|
|
|
{
|
In "Save As", support only file types we can write to; that simplifies
the logic, making it easier to get it right (fewer interactions between
components of the dialog - the file type doesn't affect whether we can
save some but not all packets). It also means we don't offer a file
type for saving, only to take it away if you choose anything other than
saving all packets.
If the capture file is a temporary file from a capture done in the
current Ethereal session, it's libpcap format, which we can write to, so
you would be able to save it.
If it's a saved file we read in, saving the file in its entirety in its
own format is just copying the file, and it's not clear supporting that
adds enough useful functionality to justify the extra complication.
Fix "range_update_dynamics()" to update all the rows of the range
button/count table properly (make the button active iff there's
a non-zero count in the currently-selected column, make a count active
iff the column is selected), to select the "Captured" column if the
count of displayed packets goes to zero, and to select the "Save all
packets" row if the count of packets in the currently-selected row and
column goes to zero. (XXX - we should perhaps do that with the
"user-defined range" counts as well, which would involve updating the
counts on every change to the range field.)
svn path=/trunk/; revision=17251
2006-02-11 11:21:38 +00:00
|
|
|
file_save_update_dynamics();
|
2004-02-03 00:16:59 +00:00
|
|
|
packets_bar_update();
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
void packet_list_mark_frame_cb(GtkWidget *w _U_, gpointer data _U_)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
if (cfile.current_frame) {
|
|
|
|
set_frame_mark(!cfile.current_frame->flags.marked,
|
2008-12-09 00:03:09 +00:00
|
|
|
cfile.current_frame, cfile.current_row);
|
2004-02-03 00:16:59 +00:00
|
|
|
mark_frames_ready();
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
static void mark_all_frames(gboolean set)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
frame_data *fdata;
|
2006-11-18 01:47:49 +00:00
|
|
|
|
2004-02-03 00:16:59 +00:00
|
|
|
/* XXX: we might need a progressbar here */
|
2004-01-09 08:36:23 +00:00
|
|
|
for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
|
|
|
|
set_frame_mark(set,
|
2008-12-09 00:03:09 +00:00
|
|
|
fdata,
|
|
|
|
gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
2004-02-03 00:16:59 +00:00
|
|
|
mark_frames_ready();
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
void packet_list_update_marked_frames(void)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
frame_data *fdata;
|
2004-02-03 00:16:59 +00:00
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
if (cfile.plist == NULL) return;
|
2004-02-03 00:16:59 +00:00
|
|
|
|
|
|
|
/* XXX: we might need a progressbar here */
|
2004-01-09 08:36:23 +00:00
|
|
|
for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
|
|
|
|
if (fdata->flags.marked)
|
2008-12-09 00:03:09 +00:00
|
|
|
set_frame_mark(TRUE, fdata,
|
|
|
|
gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
|
|
|
|
fdata));
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
2004-02-03 00:16:59 +00:00
|
|
|
mark_frames_ready();
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
void packet_list_mark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
mark_all_frames(TRUE);
|
|
|
|
}
|
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
void packet_list_unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
|
|
|
|
{
|
2004-01-09 08:36:23 +00:00
|
|
|
mark_all_frames(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
packet_list_get_event_row_column(GtkWidget *w, GdkEventButton *event_button,
|
2008-12-09 00:03:09 +00:00
|
|
|
gint *row, gint *column)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
return gtk_clist_get_selection_info(GTK_CLIST(w),
|
2006-11-18 01:47:49 +00:00
|
|
|
(gint) event_button->x, (gint) event_button->y,
|
2004-01-09 08:36:23 +00:00
|
|
|
row, column);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_)
|
|
|
|
{
|
|
|
|
GdkEventButton *event_button = (GdkEventButton *)event;
|
|
|
|
gint row, column;
|
|
|
|
|
|
|
|
if (w == NULL || event == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (event->type == GDK_BUTTON_PRESS && event_button->button == 2 &&
|
2008-04-05 05:39:07 +00:00
|
|
|
event_button->window == GTK_CLIST(w)->clist_window &&
|
|
|
|
gtk_clist_get_selection_info(GTK_CLIST(w), (gint) event_button->x,
|
2004-01-09 08:36:23 +00:00
|
|
|
(gint) event_button->y, &row, &column)) {
|
2008-12-09 00:03:09 +00:00
|
|
|
frame_data *fdata = (frame_data *)gtk_clist_get_row_data(GTK_CLIST(w), row);
|
2004-01-09 08:36:23 +00:00
|
|
|
set_frame_mark(!fdata->flags.marked, fdata, row);
|
2004-02-03 00:16:59 +00:00
|
|
|
mark_frames_ready();
|
2004-01-09 08:36:23 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2008-11-17 23:03:58 +00:00
|
|
|
|
|
|
|
if (event->type == GDK_2BUTTON_PRESS && event_button->button == 1 &&
|
|
|
|
event_button->window == GTK_CLIST(w)->clist_window ) {
|
|
|
|
|
|
|
|
new_window_cb(w);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the selection mode of the packet list window. */
|
|
|
|
void
|
2007-06-04 20:15:10 +00:00
|
|
|
packet_list_set_sel_browse(gboolean val, gboolean force_set)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
2008-12-09 00:03:09 +00:00
|
|
|
GtkSelectionMode new_mode;
|
|
|
|
/* initialize with a mode we don't use, so that the mode == new_mode
|
|
|
|
* test will fail the first time */
|
|
|
|
static GtkSelectionMode mode = GTK_SELECTION_MULTIPLE;
|
|
|
|
|
|
|
|
/* Yeah, GTK uses "browse" in the case where we do not, but oh well. I
|
|
|
|
* think "browse" in Wireshark makes more sense than "SINGLE" in GTK+ */
|
|
|
|
new_mode = val ? GTK_SELECTION_SINGLE : GTK_SELECTION_BROWSE;
|
|
|
|
|
|
|
|
if ((mode == new_mode) && !force_set) {
|
|
|
|
/*
|
|
|
|
* The mode isn't changing, so don't do anything.
|
|
|
|
* In particular, don't gratuitiously unselect the
|
|
|
|
* current packet.
|
|
|
|
*
|
|
|
|
* XXX - why do we have to unselect the current packet
|
|
|
|
* ourselves? The documentation for the GtkCList at
|
|
|
|
*
|
|
|
|
* http://developer.gnome.org/doc/API/gtk/gtkclist.html
|
|
|
|
*
|
|
|
|
* says "Note that setting the widget's selection mode to
|
|
|
|
* one of GTK_SELECTION_BROWSE or GTK_SELECTION_SINGLE will
|
|
|
|
* cause all the items in the GtkCList to become deselected."
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cfile.finfo_selected)
|
|
|
|
cf_unselect_field(&cfile);
|
|
|
|
|
|
|
|
mode = new_mode;
|
|
|
|
gtk_clist_set_selection_mode(GTK_CLIST(packet_list), mode);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the font of the packet list window. */
|
|
|
|
void
|
2008-08-09 16:14:34 +00:00
|
|
|
packet_list_set_font(PangoFontDescription *font)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
2008-12-09 00:03:09 +00:00
|
|
|
int i;
|
|
|
|
gint col_width;
|
|
|
|
PangoLayout *layout;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
/* Manually set the font so it can be used right away in the
|
|
|
|
* pango_layout_get_pixel_size call below. The gtk_widget_modify_font
|
|
|
|
* function only takes effect after the widget is displayed. */
|
|
|
|
packet_list->style->font_desc = pango_font_description_copy(font);
|
2007-01-20 23:23:50 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
gtk_widget_modify_font(packet_list, font);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
/* Compute default column sizes. */
|
|
|
|
for (i = 0; i < cfile.cinfo.num_cols; i++) {
|
|
|
|
col_width = recent_get_column_width(i);
|
|
|
|
if (col_width == -1) {
|
|
|
|
layout = gtk_widget_create_pango_layout(packet_list, get_column_width_string(get_column_format(i), i));
|
|
|
|
pango_layout_get_pixel_size(layout, &col_width, NULL);
|
|
|
|
g_object_unref(G_OBJECT(layout));
|
|
|
|
}
|
|
|
|
gtk_clist_set_column_width(GTK_CLIST(packet_list), i, col_width);
|
|
|
|
}
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2004-01-19 00:42:12 +00:00
|
|
|
GtkWidget *
|
|
|
|
packet_list_new(e_prefs *prefs)
|
2004-01-09 08:36:23 +00:00
|
|
|
{
|
|
|
|
GtkWidget *pkt_scrollw;
|
2008-02-24 12:37:37 +00:00
|
|
|
header_field_info *hfi;
|
|
|
|
gboolean custom_right_justify;
|
2008-12-09 00:03:09 +00:00
|
|
|
int i;
|
2004-01-09 08:36:23 +00:00
|
|
|
|
|
|
|
/* Packet list */
|
|
|
|
pkt_scrollw = scrolled_window_new(NULL, NULL);
|
2005-06-04 02:06:16 +00:00
|
|
|
/* The usual policy for scrolled windows is to set both scrollbars to automatic,
|
|
|
|
* meaning they'll only appear if the content doesn't fit into the window.
|
|
|
|
*
|
|
|
|
* As this doesn't seem to work in some cases for the vertical scrollbar
|
2006-05-28 17:19:08 +00:00
|
|
|
* (see http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=220),
|
2005-06-04 02:06:16 +00:00
|
|
|
* we show that scrollbar always. */
|
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pkt_scrollw),
|
|
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
|
2008-04-05 05:39:07 +00:00
|
|
|
/* the gtk_clist will have it's own GTK_SHADOW_IN, so don't use a shadow
|
2004-02-06 19:19:12 +00:00
|
|
|
* for both widgets */
|
2006-11-18 01:47:49 +00:00
|
|
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pkt_scrollw),
|
2004-02-06 19:19:12 +00:00
|
|
|
GTK_SHADOW_NONE);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
packet_list = gtk_clist_new(cfile.cinfo.num_cols);
|
2004-01-09 08:36:23 +00:00
|
|
|
/* Column titles are filled in below */
|
|
|
|
gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list);
|
|
|
|
|
2007-06-04 20:15:10 +00:00
|
|
|
packet_list_set_sel_browse(prefs->gui_plist_sel_browse, FALSE);
|
2008-08-09 16:14:34 +00:00
|
|
|
packet_list_set_font(user_font_get_regular());
|
2004-01-09 08:36:23 +00:00
|
|
|
gtk_widget_set_name(packet_list, "packet list");
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(packet_list, "select-row", G_CALLBACK(packet_list_select_cb), NULL);
|
|
|
|
g_signal_connect(packet_list, "unselect-row", G_CALLBACK(packet_list_unselect_cb), NULL);
|
2004-01-09 08:36:23 +00:00
|
|
|
for (i = 0; i < cfile.cinfo.num_cols; i++) {
|
2006-11-18 01:47:49 +00:00
|
|
|
/* For performance reasons, columns do not automatically resize,
|
2005-01-29 02:14:25 +00:00
|
|
|
but are resizeable by the user. */
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, FALSE);
|
|
|
|
gtk_clist_set_column_resizeable(GTK_CLIST(packet_list), i, TRUE);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
2008-02-24 12:37:37 +00:00
|
|
|
custom_right_justify = FALSE;
|
|
|
|
if (cfile.cinfo.col_fmt[i] == COL_CUSTOM) {
|
|
|
|
hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[i]);
|
|
|
|
if ((hfi != NULL) && (hfi->strings == NULL) &&
|
2008-12-09 00:03:09 +00:00
|
|
|
((hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
|
|
|
|
(((hfi->display == BASE_DEC) || (hfi->display == BASE_OCT)) &&
|
|
|
|
(IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type) ||
|
|
|
|
(hfi->type == FT_INT64) || (hfi->type == FT_UINT64))))) {
|
2008-02-24 12:37:37 +00:00
|
|
|
custom_right_justify = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-30 22:46:19 +00:00
|
|
|
/* Right-justify some special columns. */
|
|
|
|
if (cfile.cinfo.col_fmt[i] == COL_NUMBER ||
|
|
|
|
cfile.cinfo.col_fmt[i] == COL_PACKET_LENGTH ||
|
|
|
|
cfile.cinfo.col_fmt[i] == COL_CUMULATIVE_BYTES ||
|
2006-06-26 20:46:15 +00:00
|
|
|
cfile.cinfo.col_fmt[i] == COL_DCE_CALL ||
|
2008-02-24 12:37:37 +00:00
|
|
|
cfile.cinfo.col_fmt[i] == COL_DCE_CTX ||
|
|
|
|
custom_right_justify)
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_justification(GTK_CLIST(packet_list), i,
|
2004-01-09 08:36:23 +00:00
|
|
|
GTK_JUSTIFY_RIGHT);
|
|
|
|
}
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(packet_list, "button_press_event", G_CALLBACK(popup_menu_handler),
|
2008-04-11 17:14:11 +00:00
|
|
|
g_object_get_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
|
2008-04-11 23:16:06 +00:00
|
|
|
g_signal_connect(packet_list, "button_press_event",
|
|
|
|
G_CALLBACK(packet_list_button_pressed_cb), NULL);
|
2008-06-15 18:29:22 +00:00
|
|
|
g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, packet_list);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_compare_func(GTK_CLIST(packet_list), packet_list_compare);
|
2004-01-09 08:36:23 +00:00
|
|
|
gtk_widget_show(packet_list);
|
2004-01-19 00:42:12 +00:00
|
|
|
|
|
|
|
return pkt_scrollw;
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
|
|
|
|
2007-06-04 20:15:10 +00:00
|
|
|
void
|
|
|
|
packet_list_recreate(void)
|
|
|
|
{
|
|
|
|
gtk_widget_destroy(pkt_scrollw);
|
|
|
|
|
|
|
|
prefs.num_cols = g_list_length(prefs.col_list);
|
|
|
|
|
2008-04-12 23:34:44 +00:00
|
|
|
build_column_format_array(&cfile.cinfo, FALSE);
|
2007-06-04 20:15:10 +00:00
|
|
|
|
|
|
|
pkt_scrollw = packet_list_new(&prefs);
|
|
|
|
gtk_widget_show(pkt_scrollw);
|
|
|
|
packet_list_set_column_titles();
|
|
|
|
packet_list_set_sel_browse(prefs.gui_plist_sel_browse, TRUE);
|
|
|
|
|
|
|
|
main_widgets_rearrange();
|
2007-07-09 16:31:39 +00:00
|
|
|
|
2007-06-04 20:15:10 +00:00
|
|
|
if(cfile.state != FILE_CLOSED)
|
2009-05-04 21:13:14 +00:00
|
|
|
redissect_packets();
|
2007-06-04 20:15:10 +00:00
|
|
|
}
|
|
|
|
|
2004-01-09 08:36:23 +00:00
|
|
|
void
|
|
|
|
packet_list_set_column_titles(void)
|
|
|
|
{
|
|
|
|
GtkStyle *win_style;
|
|
|
|
GdkPixmap *ascend_pm, *descend_pm;
|
|
|
|
GdkBitmap *ascend_bm, *descend_bm;
|
|
|
|
column_arrows *col_arrows;
|
|
|
|
int i;
|
|
|
|
GtkWidget *column_lb;
|
|
|
|
|
|
|
|
win_style = gtk_widget_get_style(top_level);
|
|
|
|
ascend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &ascend_bm,
|
|
|
|
&win_style->bg[GTK_STATE_NORMAL],
|
2005-08-10 19:49:45 +00:00
|
|
|
(gchar **) clist_ascend_xpm);
|
2004-01-09 08:36:23 +00:00
|
|
|
descend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &descend_bm,
|
|
|
|
&win_style->bg[GTK_STATE_NORMAL],
|
2005-08-10 19:49:45 +00:00
|
|
|
(gchar **) clist_descend_xpm);
|
2004-01-09 08:36:23 +00:00
|
|
|
|
|
|
|
col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) *
|
|
|
|
cfile.cinfo.num_cols);
|
|
|
|
for (i = 0; i < cfile.cinfo.num_cols; i++) {
|
|
|
|
col_arrows[i].table = gtk_table_new(2, 2, FALSE);
|
|
|
|
gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
|
|
|
|
column_lb = gtk_label_new(cfile.cinfo.col_title[i]);
|
|
|
|
gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2,
|
|
|
|
GTK_SHRINK, GTK_SHRINK, 0, 0);
|
|
|
|
gtk_widget_show(column_lb);
|
|
|
|
col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
|
|
|
|
gtk_table_attach(GTK_TABLE(col_arrows[i].table),
|
|
|
|
col_arrows[i].ascend_pm,
|
|
|
|
1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
|
|
|
|
if (i == 0) {
|
|
|
|
gtk_widget_show(col_arrows[i].ascend_pm);
|
|
|
|
}
|
|
|
|
col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm);
|
|
|
|
gtk_table_attach(GTK_TABLE(col_arrows[i].table),
|
|
|
|
col_arrows[i].descend_pm,
|
|
|
|
1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_widget(GTK_CLIST(packet_list), i,
|
2004-01-09 08:36:23 +00:00
|
|
|
col_arrows[i].table);
|
|
|
|
gtk_widget_show(col_arrows[i].table);
|
|
|
|
}
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_column_titles_show(GTK_CLIST(packet_list));
|
2008-12-09 00:03:09 +00:00
|
|
|
g_signal_connect(packet_list, "click-column", G_CALLBACK(packet_list_click_column_cb), col_arrows);
|
|
|
|
g_signal_connect(packet_list, "resize-column", G_CALLBACK(packet_list_resize_column_cb), NULL);
|
2004-01-09 08:36:23 +00:00
|
|
|
}
|
2002-09-21 11:36:30 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_clear(void)
|
|
|
|
{
|
2004-11-01 11:42:08 +00:00
|
|
|
packet_history_clear();
|
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_clear(GTK_CLIST(packet_list));
|
2007-05-17 17:38:11 +00:00
|
|
|
gtk_widget_queue_draw(packet_list);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_freeze(void)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_freeze(GTK_CLIST(packet_list));
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
2005-08-02 04:47:15 +00:00
|
|
|
static void
|
2008-12-09 00:03:09 +00:00
|
|
|
packet_list_resize_columns(void)
|
|
|
|
{
|
2005-01-29 02:14:25 +00:00
|
|
|
int i;
|
|
|
|
int progbar_nextstep;
|
|
|
|
int progbar_quantum;
|
2005-10-27 20:18:50 +00:00
|
|
|
gboolean progbar_stop_flag;
|
|
|
|
GTimeVal progbar_start_time;
|
|
|
|
float progbar_val;
|
2005-01-29 02:14:25 +00:00
|
|
|
progdlg_t *progbar = NULL;
|
|
|
|
gchar status_str[100];
|
|
|
|
|
2005-10-27 20:18:50 +00:00
|
|
|
/* Update the progress bar when it gets to this value. */
|
2005-01-29 02:14:25 +00:00
|
|
|
progbar_nextstep = 0;
|
|
|
|
/* When we reach the value that triggers a progress bar update,
|
|
|
|
bump that value by this amount. */
|
|
|
|
progbar_quantum = cfile.cinfo.num_cols/N_PROGBAR_UPDATES;
|
2005-10-27 20:18:50 +00:00
|
|
|
/* Progress so far. */
|
2009-04-21 16:57:52 +00:00
|
|
|
progbar_val = 0.0f;
|
2005-01-29 02:14:25 +00:00
|
|
|
|
2005-10-27 20:18:50 +00:00
|
|
|
progbar_stop_flag = FALSE;
|
|
|
|
g_get_current_time(&progbar_start_time);
|
2005-01-29 02:14:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
main_window_update();
|
|
|
|
|
|
|
|
for (i = 0; i < cfile.cinfo.num_cols; i++) {
|
2005-10-27 06:45:37 +00:00
|
|
|
/* Create the progress bar if necessary.
|
|
|
|
We check on every iteration of the loop, so that it takes no
|
|
|
|
longer than the standard time to create it (otherwise, for a
|
|
|
|
large file, we might take considerably longer than that standard
|
|
|
|
time in order to get to the next progress bar step). */
|
|
|
|
if (progbar == NULL)
|
2006-11-18 01:47:49 +00:00
|
|
|
progbar = delayed_create_progress_dlg("Resizing", "Resize Columns",
|
2005-11-12 11:05:02 +00:00
|
|
|
TRUE, &progbar_stop_flag, &progbar_start_time, progbar_val);
|
2005-10-27 06:45:37 +00:00
|
|
|
|
2005-01-29 02:14:25 +00:00
|
|
|
if (i >= progbar_nextstep) {
|
|
|
|
/* let's not divide by zero. I should never be started
|
|
|
|
* with count == 0, so let's assert that
|
|
|
|
*/
|
|
|
|
g_assert(cfile.cinfo.num_cols > 0);
|
|
|
|
|
2005-10-27 20:18:50 +00:00
|
|
|
progbar_val = (gfloat) i / cfile.cinfo.num_cols;
|
2005-01-29 02:14:25 +00:00
|
|
|
|
|
|
|
if (progbar != NULL) {
|
|
|
|
g_snprintf(status_str, sizeof(status_str),
|
|
|
|
"%u of %u columns (%s)", i+1, cfile.cinfo.num_cols, cfile.cinfo.col_title[i]);
|
2005-10-27 20:18:50 +00:00
|
|
|
update_progress_dlg(progbar, progbar_val, status_str);
|
2005-01-29 02:14:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
progbar_nextstep += progbar_quantum;
|
|
|
|
}
|
|
|
|
|
2005-10-27 20:18:50 +00:00
|
|
|
if (progbar_stop_flag) {
|
2005-01-29 02:14:25 +00:00
|
|
|
/* Well, the user decided to abort the resizing... */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-10-27 06:45:37 +00:00
|
|
|
/* auto resize the current column */
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, TRUE);
|
2005-04-14 20:54:01 +00:00
|
|
|
|
2005-10-27 06:45:37 +00:00
|
|
|
/* the current column should be resizeable by the user again */
|
|
|
|
/* (will turn off auto resize again) */
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_resizeable(GTK_CLIST(packet_list), i, TRUE);
|
2005-01-29 02:14:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We're done resizing the columns; destroy the progress bar if it
|
|
|
|
was created. */
|
|
|
|
if (progbar != NULL)
|
|
|
|
destroy_progress_dlg(progbar);
|
|
|
|
}
|
|
|
|
|
2005-01-29 20:35:42 +00:00
|
|
|
void packet_list_resize_columns_cb(GtkWidget *widget _U_, gpointer data _U_)
|
2005-01-29 02:14:25 +00:00
|
|
|
{
|
|
|
|
packet_list_resize_columns();
|
|
|
|
}
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
void
|
|
|
|
packet_list_thaw(void)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_thaw(GTK_CLIST(packet_list));
|
2004-02-03 00:16:59 +00:00
|
|
|
packets_bar_update();
|
2005-01-29 02:14:25 +00:00
|
|
|
/*packet_list_resize_columns();*/
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_select_row(gint row)
|
|
|
|
{
|
2008-04-11 05:03:33 +00:00
|
|
|
g_signal_emit_by_name(G_OBJECT(packet_list), "select_row", row);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
2006-11-18 01:47:49 +00:00
|
|
|
static void
|
|
|
|
packet_list_next_prev(gboolean next)
|
|
|
|
{
|
|
|
|
GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(top_level));
|
2008-04-11 05:03:33 +00:00
|
|
|
g_signal_emit_by_name(G_OBJECT(packet_list), "scroll_vertical",
|
2006-11-18 01:47:49 +00:00
|
|
|
next ? GTK_SCROLL_STEP_FORWARD : GTK_SCROLL_STEP_BACKWARD, 0.0);
|
|
|
|
/* Set the focus back where it was */
|
2006-11-18 05:19:40 +00:00
|
|
|
if (focus)
|
|
|
|
gtk_window_set_focus(GTK_WINDOW(top_level), focus);
|
2006-11-18 01:47:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-03-21 04:54:20 +00:00
|
|
|
packet_list_next(void)
|
2006-11-18 01:47:49 +00:00
|
|
|
{
|
|
|
|
packet_list_next_prev(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-03-21 04:54:20 +00:00
|
|
|
packet_list_prev(void)
|
2006-11-18 01:47:49 +00:00
|
|
|
{
|
|
|
|
packet_list_next_prev(FALSE);
|
|
|
|
}
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
void
|
|
|
|
packet_list_moveto_end(void)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_moveto(GTK_CLIST(packet_list),
|
2009-04-21 16:57:52 +00:00
|
|
|
GTK_CLIST(packet_list)->rows - 1, -1, 1.0f, 1.0f);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
2007-07-09 16:31:39 +00:00
|
|
|
gboolean
|
2007-12-05 23:50:28 +00:00
|
|
|
packet_list_check_end(void)
|
2007-07-09 16:31:39 +00:00
|
|
|
{
|
2007-12-05 23:50:28 +00:00
|
|
|
gboolean at_end = FALSE;
|
|
|
|
GtkAdjustment *adj;
|
|
|
|
|
2007-07-09 16:31:39 +00:00
|
|
|
g_return_val_if_fail (packet_list != NULL, FALSE);
|
2008-04-05 05:39:07 +00:00
|
|
|
adj = gtk_clist_get_vadjustment(GTK_CLIST(packet_list));
|
2007-12-05 23:50:28 +00:00
|
|
|
g_return_val_if_fail (adj != NULL, FALSE);
|
2007-07-09 16:31:39 +00:00
|
|
|
|
2007-12-05 23:50:28 +00:00
|
|
|
if (adj->value >= adj->upper - adj->page_size) {
|
|
|
|
at_end = TRUE;
|
2007-07-09 16:31:39 +00:00
|
|
|
}
|
2008-02-22 04:56:26 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
2007-12-05 23:50:28 +00:00
|
|
|
if (adj->value > 0 && at_end != last_at_end && at_end != auto_scroll_live) {
|
|
|
|
menu_auto_scroll_live_changed(at_end);
|
|
|
|
}
|
2008-02-22 04:56:26 +00:00
|
|
|
#endif
|
2007-12-05 23:50:28 +00:00
|
|
|
last_at_end = at_end;
|
|
|
|
return at_end;
|
2007-07-09 16:31:39 +00:00
|
|
|
}
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
gint
|
2004-12-31 00:12:25 +00:00
|
|
|
packet_list_append(const gchar *text[], gpointer data)
|
2002-09-21 11:36:30 +00:00
|
|
|
{
|
|
|
|
gint row;
|
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
row = gtk_clist_append(GTK_CLIST(packet_list), (gchar **) text);
|
|
|
|
gtk_clist_set_row_data(GTK_CLIST(packet_list), row, data);
|
2002-09-21 11:36:30 +00:00
|
|
|
return row;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-09-23 19:09:52 +00:00
|
|
|
packet_list_set_colors(gint row, color_t *fg, color_t *bg)
|
2002-09-21 11:36:30 +00:00
|
|
|
{
|
2002-09-23 19:09:52 +00:00
|
|
|
GdkColor gdkfg, gdkbg;
|
|
|
|
|
|
|
|
if (fg)
|
|
|
|
{
|
|
|
|
color_t_to_gdkcolor(&gdkfg, fg);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &gdkfg);
|
2002-09-23 19:09:52 +00:00
|
|
|
}
|
|
|
|
if (bg)
|
|
|
|
{
|
|
|
|
color_t_to_gdkcolor(&gdkbg, bg);
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_background(GTK_CLIST(packet_list), row, &gdkbg);
|
2002-09-23 19:09:52 +00:00
|
|
|
}
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
packet_list_find_row_from_data(gpointer data)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
return gtk_clist_find_row_from_data(GTK_CLIST(packet_list), data);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_set_text(gint row, gint column, const gchar *text)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_text(GTK_CLIST(packet_list), row, column, text);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the column widths of those columns that show the time in
|
|
|
|
* "command-line-specified" format. */
|
|
|
|
void
|
2008-06-14 16:51:11 +00:00
|
|
|
packet_list_set_time_width(gint col_fmt, gint column)
|
2002-09-21 11:36:30 +00:00
|
|
|
{
|
2008-04-12 19:53:54 +00:00
|
|
|
gint width = -1;
|
2002-11-15 22:21:15 +00:00
|
|
|
PangoLayout *layout;
|
|
|
|
|
2008-08-09 16:14:34 +00:00
|
|
|
width = recent_get_column_width(column);
|
2008-04-12 19:53:54 +00:00
|
|
|
if (width == -1) {
|
|
|
|
layout = gtk_widget_create_pango_layout(packet_list,
|
2008-06-14 16:51:11 +00:00
|
|
|
get_column_longest_string(col_fmt));
|
2008-12-09 00:03:09 +00:00
|
|
|
pango_layout_get_pixel_size(layout, &width, NULL);
|
|
|
|
g_object_unref(G_OBJECT(layout));
|
2008-04-12 19:53:54 +00:00
|
|
|
}
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_column_width(GTK_CLIST(packet_list), column, width);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gpointer
|
|
|
|
packet_list_get_row_data(gint row)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
return gtk_clist_get_row_data(GTK_CLIST(packet_list), row);
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
|
|
|
|
2005-09-12 20:10:44 +00:00
|
|
|
|
|
|
|
/* get the first fully visible row number, given row MUST be visible */
|
|
|
|
static gint
|
2008-12-09 00:03:09 +00:00
|
|
|
packet_list_first_full_visible_row(gint row)
|
|
|
|
{
|
|
|
|
g_assert(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL);
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
while(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL) {
|
|
|
|
row--;
|
|
|
|
}
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
return ++row;
|
2005-09-12 20:10:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get the last fully visible row number, given row MUST be visible */
|
|
|
|
static gint
|
2008-12-09 00:03:09 +00:00
|
|
|
packet_list_last_full_visible_row(gint row)
|
|
|
|
{
|
|
|
|
g_assert(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL);
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
while(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL) {
|
|
|
|
row++;
|
|
|
|
}
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
return --row;
|
2005-09-12 20:10:44 +00:00
|
|
|
}
|
|
|
|
|
2002-09-21 11:36:30 +00:00
|
|
|
/* Set the selected row and the focus row of the packet list to the specified
|
|
|
|
* row, and make it visible if it's not currently visible. */
|
|
|
|
void
|
|
|
|
packet_list_set_selected_row(gint row)
|
|
|
|
{
|
2008-12-09 00:03:09 +00:00
|
|
|
gint visible_rows;
|
|
|
|
gint first_row;
|
|
|
|
gboolean full_visible;
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
full_visible = gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL;
|
2002-09-21 11:36:30 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
/* XXX - why is there no "gtk_clist_set_focus_row()", so that we
|
2002-09-21 11:36:30 +00:00
|
|
|
* can make the row for the frame we found the focus row?
|
|
|
|
*
|
|
|
|
* See http://www.gnome.org/mailing-lists/archives/gtk-list/2000-January/0038.shtml
|
|
|
|
*/
|
2008-04-05 05:39:07 +00:00
|
|
|
GTK_CLIST(packet_list)->focus_row = row;
|
2002-09-21 11:36:30 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
|
2005-09-12 20:10:44 +00:00
|
|
|
|
|
|
|
if (!full_visible) {
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_freeze(GTK_CLIST(packet_list));
|
2005-09-22 21:14:39 +00:00
|
|
|
|
2009-04-21 16:57:52 +00:00
|
|
|
gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0f, 0.0f);
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
/* even after move still invisible (happens with empty list) -> give up */
|
|
|
|
if(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) != GTK_VISIBILITY_FULL) {
|
|
|
|
gtk_clist_thaw(GTK_CLIST(packet_list));
|
|
|
|
return;
|
|
|
|
}
|
2005-09-12 20:10:44 +00:00
|
|
|
|
2008-12-09 00:03:09 +00:00
|
|
|
/* The now selected row will be the first visible row in the list.
|
|
|
|
* This is inconvenient, as the user is usually interested in some
|
|
|
|
* packets *before* the currently selected one too.
|
|
|
|
*
|
|
|
|
* Try to adjust the visible rows, so the currently selected row will
|
|
|
|
* be shown around the first third of the list screen.
|
|
|
|
*
|
|
|
|
* (This won't even do any harm if the current row is the first or the
|
|
|
|
* last in the list) */
|
|
|
|
visible_rows = packet_list_last_full_visible_row(row) - packet_list_first_full_visible_row(row);
|
|
|
|
first_row = row - visible_rows / 3;
|
|
|
|
|
2009-04-21 16:57:52 +00:00
|
|
|
gtk_clist_moveto(GTK_CLIST(packet_list), first_row >= 0 ? first_row : 0, -1, 0.0f, 0.0f);
|
2008-12-09 00:03:09 +00:00
|
|
|
|
|
|
|
gtk_clist_thaw(GTK_CLIST(packet_list));
|
|
|
|
}
|
2002-09-21 11:36:30 +00:00
|
|
|
}
|
2003-12-06 04:05:02 +00:00
|
|
|
|
|
|
|
/* Return the column number that the clist is currently sorted by */
|
|
|
|
gint
|
|
|
|
packet_list_get_sort_column(void)
|
|
|
|
{
|
2008-04-05 05:39:07 +00:00
|
|
|
return GTK_CLIST(packet_list)->sort_column;
|
2003-12-06 04:05:02 +00:00
|
|
|
}
|
2007-01-11 19:50:19 +00:00
|
|
|
|
2007-01-28 02:49:50 +00:00
|
|
|
void packet_list_copy_summary_cb(GtkWidget * w _U_, gpointer data _U_, copy_summary_type copy_type)
|
|
|
|
{
|
|
|
|
gint col;
|
|
|
|
gchar* celltext = NULL;
|
2007-02-12 05:10:52 +00:00
|
|
|
GString* text;
|
|
|
|
|
2008-11-18 14:50:51 +00:00
|
|
|
if(CS_CSV == copy_type) {
|
|
|
|
text = g_string_new("\"");
|
|
|
|
} else {
|
|
|
|
text = g_string_new("");
|
|
|
|
}
|
2007-01-28 02:49:50 +00:00
|
|
|
|
|
|
|
if (cfile.current_frame) {
|
|
|
|
for(col = 0; col < cfile.cinfo.num_cols; ++col) {
|
|
|
|
if(col != 0) {
|
2008-12-09 00:03:09 +00:00
|
|
|
if(CS_CSV == copy_type) {
|
|
|
|
g_string_append(text,"\",\"");
|
|
|
|
} else {
|
|
|
|
g_string_append_c(text, '\t');
|
|
|
|
}
|
2007-01-28 02:49:50 +00:00
|
|
|
}
|
2008-11-18 14:50:51 +00:00
|
|
|
if(0 != gtk_clist_get_text(GTK_CLIST(packet_list),cfile.current_row,col,&celltext)) {
|
2007-01-28 02:49:50 +00:00
|
|
|
g_string_append(text,celltext);
|
|
|
|
}
|
|
|
|
}
|
2008-12-09 00:03:09 +00:00
|
|
|
if(CS_CSV == copy_type) {
|
|
|
|
g_string_append_c(text,'"');
|
|
|
|
}
|
2007-01-28 02:49:50 +00:00
|
|
|
copy_to_clipboard(text);
|
|
|
|
}
|
|
|
|
g_string_free(text,TRUE);
|
|
|
|
}
|
|
|
|
|
2007-01-11 19:50:19 +00:00
|
|
|
/* Re-sort the clist by the previously selected sort */
|
|
|
|
void
|
|
|
|
packet_list_set_sort_column(void)
|
|
|
|
{
|
|
|
|
packet_list_freeze();
|
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_set_sort_column(GTK_CLIST(packet_list), packet_list_get_sort_column());
|
2007-01-11 19:50:19 +00:00
|
|
|
|
2008-04-05 05:39:07 +00:00
|
|
|
gtk_clist_sort(GTK_CLIST(packet_list));
|
2007-01-11 19:50:19 +00:00
|
|
|
|
|
|
|
packet_list_thaw();
|
|
|
|
}
|
2008-04-12 19:53:54 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
packet_list_recent_write_all(FILE *rf)
|
|
|
|
{
|
|
|
|
gint col;
|
|
|
|
|
|
|
|
fprintf (rf, "%s:", RECENT_KEY_COL_WIDTH);
|
|
|
|
for (col = 0; col < cfile.cinfo.num_cols; col++) {
|
|
|
|
if (cfile.cinfo.col_fmt[col] == COL_CUSTOM) {
|
|
|
|
fprintf (rf, " %%Cus:%s,", get_column_custom_field(col));
|
|
|
|
} else {
|
|
|
|
fprintf (rf, " %s,", col_format_to_string(cfile.cinfo.col_fmt[col]));
|
|
|
|
}
|
|
|
|
fprintf (rf, " %d", GTK_CLIST(packet_list)->column[col].width);
|
|
|
|
if (col != cfile.cinfo.num_cols-1) {
|
|
|
|
fprintf (rf, ",");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf (rf, "\n");
|
|
|
|
}
|