#include "gtk/main_packet_list.h"
#include "gtk/main_statusbar.h"
#include "gtk/packet_win.h"
+#include "gtk/prefs_column.h"
+#include "gtk/prefs_dlg.h"
+#include "gtk/dlg_utils.h"
#include "image/clist_ascend.xpm"
#include "image/clist_descend.xpm"
typedef struct column_arrows {
GtkWidget *table;
+ GtkWidget *label;
GtkWidget *ascend_pm;
GtkWidget *descend_pm;
} column_arrows;
}
}
+static gboolean
+right_justify_column (gint col)
+{
+ header_field_info *hfi;
+ gboolean right_justify = FALSE;
+
+ switch (cfile.cinfo.col_fmt[col]) {
+
+ case COL_NUMBER:
+ case COL_PACKET_LENGTH:
+ case COL_CUMULATIVE_BYTES:
+ case COL_DCE_CALL:
+ right_justify = TRUE;
+ break;
+
+ case COL_CUSTOM:
+ hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[col]);
+ /* Check if this is a valid field and we have no strings lookup table */
+ if ((hfi != NULL) && (hfi->strings == NULL)) {
+ /* Check for bool, framenum and decimal/octal integer types */
+ if ((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)))) {
+ right_justify = TRUE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return right_justify;
+}
+
+static void
+col_title_change_ok (GtkWidget *w, gpointer parent_w)
+{
+ GtkWidget *column_lb = g_object_get_data (G_OBJECT(w), "column");
+ gint col_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(packet_list), E_MPACKET_LIST_COL_KEY));
+ GtkWidget *entry = g_object_get_data (G_OBJECT(w), "entry");
+ const gchar *title = gtk_entry_get_text(GTK_ENTRY(entry));
+
+ gtk_label_set_text (GTK_LABEL(column_lb), title);
+ column_prefs_rename(col_id, title);
+
+ if (!prefs.gui_use_pref_save) {
+ prefs_main_write();
+ }
+
+ window_destroy(GTK_WIDGET(parent_w));
+}
+
+static void
+col_title_change_cancel (GtkWidget *w _U_, gpointer parent_w)
+{
+ window_destroy(GTK_WIDGET(parent_w));
+}
+
+static void
+col_title_edit_dlg (gint col_id, gpointer data)
+{
+ column_arrows *col_arrows = (column_arrows *) data;
+ const gchar *value = gtk_label_get_text (GTK_LABEL(col_arrows[col_id].label));
+
+ GtkWidget *win, *main_tb, *main_vb, *bbox, *cancel_bt, *ok_bt;
+ GtkWidget *entry, *label;
+
+ win = dlg_window_new("Column Title");
+
+ gtk_window_set_resizable(GTK_WINDOW(win),FALSE);
+ gtk_window_resize(GTK_WINDOW(win), 400, 100);
+
+ main_vb = gtk_vbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(win), main_vb);
+ gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
+
+ main_tb = gtk_table_new(2, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
+ gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10);
+
+ label = gtk_label_new(ep_strdup_printf("Title:"));
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, 1, 2);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
+
+ entry = gtk_entry_new();
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), entry, 1, 2, 1, 2);
+ gtk_entry_set_text(GTK_ENTRY(entry), value);
+
+ bbox = dlg_button_row_new(GTK_STOCK_CANCEL,GTK_STOCK_OK, NULL);
+ gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
+
+ ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
+ g_object_set_data (G_OBJECT(ok_bt), "column", col_arrows[col_id].label);
+ g_object_set_data (G_OBJECT(ok_bt), "entry", entry);
+ g_signal_connect(ok_bt, "clicked", G_CALLBACK(col_title_change_ok), win);
+
+ dlg_set_activate(entry, ok_bt);
+
+ cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
+ g_signal_connect(cancel_bt, "clicked", G_CALLBACK(col_title_change_cancel), win);
+ window_set_cancel_button(win, cancel_bt, NULL);
+
+ gtk_widget_grab_default(ok_bt);
+ gtk_widget_show_all(win);
+}
+
+
+static void
+packet_list_resize_column (gint col_id)
+{
+ gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), col_id, TRUE);
+ gtk_clist_set_column_resizeable(GTK_CLIST(packet_list), col_id, TRUE);
+}
+
+static void
+packet_list_remove_column (gint col_id)
+{
+ column_prefs_remove(col_id);
+
+ if (!prefs.gui_use_pref_save) {
+ prefs_main_write();
+ }
+
+ packet_list_recreate();
+}
+
/* What to do when a column is clicked */
static void
-packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
+packet_list_sort_column(gint column, gpointer data, GtkSortType order)
{
column_arrows *col_arrows = (column_arrows *) data;
+ GtkCList *clist = GTK_CLIST(packet_list);
int i;
gtk_clist_freeze(clist);
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);
- }
+ clist->sort_type = order;
+ if (clist->sort_type == GTK_SORT_ASCENDING) {
+ gtk_widget_show(col_arrows[column].ascend_pm);
+ } else {
+ gtk_widget_show(col_arrows[column].descend_pm);
}
- else {
- clist->sort_type = GTK_SORT_ASCENDING;
- gtk_widget_show(col_arrows[column].ascend_pm);
+ if (column != clist->sort_column) {
gtk_clist_set_sort_column(clist, column);
}
gtk_clist_thaw(clist);
gtk_clist_sort(clist);
}
+static GtkJustification
+get_xalign_value (gchar xalign, gboolean right_justify)
+{
+ GtkJustification value;
+
+ switch (xalign) {
+ case COLUMN_XALIGN_RIGHT:
+ value = GTK_JUSTIFY_RIGHT;
+ break;
+ case COLUMN_XALIGN_CENTER:
+ value = GTK_JUSTIFY_CENTER;
+ break;
+ case COLUMN_XALIGN_LEFT:
+ value = GTK_JUSTIFY_LEFT;
+ break;
+ case COLUMN_XALIGN_DEFAULT:
+ default:
+ if (right_justify) {
+ value = GTK_JUSTIFY_RIGHT;
+ } else {
+ value = GTK_JUSTIFY_LEFT;
+ }
+ break;
+ }
+
+ return value;
+}
+
+static void
+packet_list_xalign_column (gint col_id, gchar xalign)
+{
+ gboolean right_justify = right_justify_column(col_id);
+ GtkJustification justify = get_xalign_value (xalign, right_justify);
+
+ if ((xalign == COLUMN_XALIGN_LEFT && !right_justify) ||
+ (xalign == COLUMN_XALIGN_RIGHT && right_justify)) {
+ /* Default value selected, save default in the recent settings */
+ xalign = COLUMN_XALIGN_DEFAULT;
+ }
+
+ gtk_clist_set_column_justification (GTK_CLIST(packet_list), col_id, justify);
+ recent_set_column_xalign (col_id, xalign);
+}
+
+void
+packet_list_column_menu_cb (GtkWidget *w _U_, gpointer user_data _U_, COLUMN_SELECTED_E action)
+{
+ gint col_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(packet_list), E_MPACKET_LIST_COL_KEY));
+ gpointer data = g_object_get_data (G_OBJECT(packet_list), E_MPACKET_LIST_COL_ARROWS_KEY);
+
+ switch (action) {
+ case COLUMN_SELECTED_SORT_ASCENDING:
+ packet_list_sort_column (col_id, data, GTK_SORT_ASCENDING);
+ break;
+ case COLUMN_SELECTED_SORT_DESCENDING:
+ packet_list_sort_column (col_id, data, GTK_SORT_DESCENDING);
+ break;
+ case COLUMN_SELECTED_SORT_NONE:
+ packet_list_sort_column (0, data, GTK_SORT_ASCENDING);
+ break;
+ case COLUMN_SELECTED_ALIGN_LEFT:
+ packet_list_xalign_column (col_id, COLUMN_XALIGN_LEFT);
+ break;
+ case COLUMN_SELECTED_ALIGN_CENTER:
+ packet_list_xalign_column (col_id, COLUMN_XALIGN_CENTER);
+ break;
+ case COLUMN_SELECTED_ALIGN_RIGHT:
+ packet_list_xalign_column (col_id, COLUMN_XALIGN_RIGHT);
+ break;
+ case COLUMN_SELECTED_RESIZE:
+ packet_list_resize_column (col_id);
+ break;
+ case COLUMN_SELECTED_RENAME:
+ col_title_edit_dlg (col_id, data);
+ break;
+ case COLUMN_SELECTED_REMOVE:
+ packet_list_remove_column (col_id);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void
+packet_list_click_column_cb (GtkCList *clist, gint column, gpointer data)
+{
+ GtkWidget *menu;
+ gboolean right_justify = right_justify_column (column);
+
+ menus_set_column_align_default (right_justify);
+
+ menu = g_object_get_data (G_OBJECT(popup_menu_object), PM_PACKET_LIST_COL_KEY);
+ g_object_set_data(G_OBJECT(clist), E_MPACKET_LIST_COL_KEY, GINT_TO_POINTER(column));
+ g_object_set_data(G_OBJECT(clist), E_MPACKET_LIST_COL_ARROWS_KEY, data);
+ gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time());
+}
+
+
static void
packet_list_resize_column_cb(GtkCList *clist _U_, gint column, gint width, gpointer data _U_)
{
}
}
+/* ignore packet */
+static void
+set_frame_ignore(gboolean set, frame_data *frame, gint row)
+{
+ GdkColor fg, bg;
+
+ if (row == -1)
+ return;
+ if (set) {
+ cf_ignore_frame(&cfile, frame);
+ color_t_to_gdkcolor(&fg, &prefs.gui_ignored_fg);
+ color_t_to_gdkcolor(&bg, &prefs.gui_ignored_bg);
+ gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
+ gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
+ } else {
+ const color_filter_t *cfilter = frame->color_filter;
+
+ cf_unignore_frame(&cfile, frame);
+ /* 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);
+ gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
+ gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
+ } else { /* No color filter match */
+ gtk_clist_set_foreground(GTK_CLIST(packet_list), row, NULL);
+ gtk_clist_set_background(GTK_CLIST(packet_list), row, NULL);
+ }
+ }
+}
+
/* call this after last set_frame_mark is done */
static void mark_frames_ready(void)
{
mark_all_frames(FALSE);
}
-#ifndef NEW_PACKET_LIST
+void packet_list_ignore_frame_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+ if (cfile.current_frame) {
+ set_frame_ignore(!cfile.current_frame->flags.ignored,
+ cfile.current_frame, cfile.current_row);
+ redissect_packets();
+ }
+}
+
+void packet_list_unignore_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+ frame_data *fdata;
+
+ /* XXX: we might need a progressbar here */
+ for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+ set_frame_ignore(FALSE,
+ fdata,
+ gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));
+ }
+ redissect_packets();
+}
+
+void packet_list_update_ignored_frames(void)
+{
+ frame_data *fdata;
+
+ if (cfile.plist_start == NULL) return;
+
+ /* XXX: we might need a progressbar here */
+ for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+ if (fdata->flags.ignored)
+ set_frame_ignore(TRUE, fdata,
+ gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
+ fdata));
+ }
+}
+
gboolean
packet_list_get_event_row_column(GtkWidget *w, GdkEventButton *event_button,
gint *row, gint *column)
(gint) event_button->x, (gint) event_button->y,
row, column);
}
-#endif /* NEW_PACKET_LIST */
static gint
packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_)
packet_list_new(e_prefs *prefs)
{
GtkWidget *pkt_scrollw;
- header_field_info *hfi;
- gboolean custom_right_justify;
+ GtkJustification justify;
int i;
/* Packet list */
gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, FALSE);
gtk_clist_set_column_resizeable(GTK_CLIST(packet_list), i, TRUE);
- 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) &&
- ((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))))) {
- custom_right_justify = TRUE;
- }
- }
-
- /* 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 ||
- cfile.cinfo.col_fmt[i] == COL_DCE_CALL ||
- custom_right_justify)
- gtk_clist_set_column_justification(GTK_CLIST(packet_list), i,
- GTK_JUSTIFY_RIGHT);
+ /* Justify columns. */
+ justify = get_xalign_value (recent_get_column_xalign(i), right_justify_column(i));
+ if (justify != GTK_JUSTIFY_LEFT)
+ gtk_clist_set_column_justification(GTK_CLIST(packet_list), i, justify);
}
g_signal_connect(packet_list, "button_press_event", G_CALLBACK(popup_menu_handler),
g_object_get_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
GdkPixmap *ascend_pm, *descend_pm;
GdkBitmap *ascend_bm, *descend_bm;
column_arrows *col_arrows;
+ gchar *tooltip_text;
+ header_field_info *hfi;
+ GtkTooltips *tooltips = gtk_tooltips_new ();
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,
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,
+ col_arrows[i].label = gtk_label_new(cfile.cinfo.col_title[i]);
+ gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].label, 0, 1, 0, 2,
GTK_SHRINK, GTK_SHRINK, 0, 0);
- gtk_widget_show(column_lb);
+ if (cfile.cinfo.col_fmt[i] == COL_CUSTOM) {
+ hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[i]);
+ if (hfi->parent != -1) {
+ /* Prefix with protocol name */
+ tooltip_text = g_strdup_printf("%s\n%s (%s)", proto_get_protocol_name(hfi->parent), hfi->name, hfi->abbrev);
+ } else {
+ tooltip_text = g_strdup_printf("%s (%s)", hfi->name, hfi->abbrev);
+ }
+ } else {
+ tooltip_text = g_strdup(col_format_desc(cfile.cinfo.col_fmt[i]));
+ }
+ gtk_tooltips_set_tip(tooltips, col_arrows[i].label, tooltip_text, NULL);
+ g_free(tooltip_text);
+ gtk_widget_show(col_arrows[i].label);
col_arrows[i].ascend_pm = gtk_image_new_from_pixmap(ascend_pm, ascend_bm);
gtk_table_attach(GTK_TABLE(col_arrows[i].table),
col_arrows[i].ascend_pm,
packet_list_recent_write_all(FILE *rf)
{
gint col;
+ gchar xalign;
fprintf (rf, "%s:", RECENT_KEY_COL_WIDTH);
for (col = 0; col < cfile.cinfo.num_cols; col++) {
fprintf (rf, " %s,", col_format_to_string(cfile.cinfo.col_fmt[col]));
}
fprintf (rf, " %d", GTK_CLIST(packet_list)->column[col].width);
+ xalign = recent_get_column_xalign (col);
+ if (xalign != COLUMN_XALIGN_DEFAULT) {
+ fprintf (rf, ":%c", xalign);
+ }
if (col != cfile.cinfo.num_cols-1) {
fprintf (rf, ",");
}