Added "Ignore Packet" menu items to the main menu.
[metze/wireshark/wip.git] / gtk / main_packet_list.c
index 2859114a623f3ead2204b7cff5a423fd0ecf5ce6..cf7ee439ebb9f5afae4ad49c99ead03987f56a1c 100644 (file)
 # include "config.h"
 #endif
 
+#ifndef NEW_PACKET_LIST
+
 #include <gtk/gtk.h>
+
+#include <stdio.h>
 #include <string.h>
 
 #include <epan/epan.h>
 #include "gtk/packet_history.h"
 #include "gtk/recent.h"
 #include "gtk/main.h"
-#include "gtk/main_menu.h"
+#include "gtk/menus.h"
 #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"
@@ -62,6 +69,7 @@
 
 typedef struct column_arrows {
   GtkWidget *table;
+  GtkWidget *label;
   GtkWidget *ascend_pm;
   GtkWidget *descend_pm;
 } column_arrows;
@@ -71,27 +79,6 @@ static gboolean last_at_end = FALSE;
 
 /* GtkClist compare routine, overrides default to allow numeric comparison */
 
-#define COMPARE_FRAME_NUM()     ((fdata1->num < fdata2->num) ? -1 : \
-                                 (fdata1->num > fdata2->num) ? 1 : \
-                                 0)
-
-#define COMPARE_NUM(f)  ((fdata1->f < fdata2->f) ? -1 : \
-                         (fdata1->f > fdata2->f) ? 1 : \
-                         COMPARE_FRAME_NUM())
-
-/* 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. */
-#define COMPARE_TS(ts) \
-                ((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())
 static gint
 packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
 {
@@ -122,53 +109,20 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
   switch (col_fmt) {
 
   case COL_NUMBER:
-    return COMPARE_FRAME_NUM();
-
   case COL_CLS_TIME:
-    switch (timestamp_get_type()) {
-
-    case TS_ABSOLUTE:
-    case TS_ABSOLUTE_WITH_DATE:
-    case TS_EPOCH:
-      return COMPARE_TS(abs_ts);
-
-    case TS_RELATIVE:
-      return COMPARE_TS(rel_ts);
-
-    case TS_DELTA:
-      return COMPARE_TS(del_cap_ts);
-
-    case TS_DELTA_DIS:
-      return COMPARE_TS(del_dis_ts);
-
-    case TS_NOT_SET:
-      return 0;
-    }
-    return 0;
-
   case COL_ABS_TIME:
   case COL_ABS_DATE_TIME:
-    return COMPARE_TS(abs_ts);
-
   case COL_REL_TIME:
-    return COMPARE_TS(rel_ts);
-
   case COL_DELTA_TIME:
-    return COMPARE_TS(del_cap_ts);
-
   case COL_DELTA_TIME_DIS:
-    return COMPARE_TS(del_dis_ts);
-
   case COL_PACKET_LENGTH:
-    return COMPARE_NUM(pkt_len);
-
   case COL_CUMULATIVE_BYTES:
-    return COMPARE_NUM(cum_bytes);
+    return frame_data_compare(fdata1, fdata2, col_fmt);
 
   case COL_CUSTOM:
     hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[clist->sort_column]);
     if (hfi == NULL) {
-        return COMPARE_FRAME_NUM();
+        return frame_data_compare(fdata1, fdata2, COL_NUMBER);
     } else if ((hfi->strings == NULL) &&
                (((IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)) &&
                  ((hfi->display == BASE_DEC) || (hfi->display == BASE_DEC_HEX) ||
@@ -176,7 +130,7 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
                 (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;
     }
@@ -185,9 +139,9 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
     num1 = atof(text1);
     num2 = atof(text2);
     if ((col_fmt == COL_UNRES_SRC_PORT) || (col_fmt == COL_UNRES_DST_PORT) ||
-        (custom_numeric) || 
+        (custom_numeric) ||
         ((num1 != 0) && (num2 != 0) && ((col_fmt == COL_DEF_SRC_PORT) ||
-                                        (col_fmt == COL_RES_SRC_PORT) || 
+                                        (col_fmt == COL_RES_SRC_PORT) ||
                                         (col_fmt == COL_DEF_DST_PORT) ||
                                         (col_fmt == COL_RES_DST_PORT)))) {
 
@@ -198,7 +152,7 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
       else if (num1 > num2)
         return 1;
       else
-        return COMPARE_FRAME_NUM();
+        return frame_data_compare(fdata1, fdata2, COL_NUMBER);
     }
 
     else {
@@ -208,7 +162,7 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
         if (text1)
           return 1;
         else
-          return COMPARE_FRAME_NUM();
+          return frame_data_compare(fdata1, fdata2, COL_NUMBER);
       }
 
       if (!text1)
@@ -216,18 +170,146 @@ packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
 
       ret = strcmp(text1, text2);
       if (ret == 0)
-        return COMPARE_FRAME_NUM();
+        return frame_data_compare(fdata1, fdata2, COL_NUMBER);
       else
         return ret;
     }
   }
 }
 
+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);
@@ -237,18 +319,13 @@ packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
     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);
@@ -256,6 +333,105 @@ packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
   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_)
 {
@@ -264,7 +440,7 @@ packet_list_resize_column_cb(GtkCList *clist _U_, gint column, gint width, gpoin
 
 /* What to do when a list item is selected/unselected */
 static void
-packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_) 
+packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_)
 {
   frame_data *fdata;
 
@@ -287,7 +463,7 @@ packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, GdkEventButton *
 }
 
 static void
-packet_list_unselect_cb(GtkWidget *w _U_, gint row _U_, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_) 
+packet_list_unselect_cb(GtkWidget *w _U_, gint row _U_, gint col _U_, GdkEventButton *event _U_, gpointer evt _U_)
 {
   cf_unselect_packet(&cfile);
 }
@@ -307,7 +483,7 @@ set_frame_mark(gboolean set, frame_data *frame, gint row)
     gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
     gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
   } else {
-    color_filter_t *cfilter = frame->color_filter;
+    const color_filter_t *cfilter = frame->color_filter;
 
     cf_unmark_frame(&cfile, frame);
     /* Restore the color from the matching color filter if any */
@@ -323,14 +499,45 @@ set_frame_mark(gboolean set, frame_data *frame, gint row)
   }
 }
 
+/* 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) 
+static void mark_frames_ready(void)
 {
   file_save_update_dynamics();
   packets_bar_update();
 }
 
-void packet_list_mark_frame_cb(GtkWidget *w _U_, gpointer data _U_) 
+void packet_list_mark_frame_cb(GtkWidget *w _U_, gpointer data _U_)
 {
   if (cfile.current_frame) {
     set_frame_mark(!cfile.current_frame->flags.marked,
@@ -339,12 +546,12 @@ void packet_list_mark_frame_cb(GtkWidget *w _U_, gpointer data _U_)
   }
 }
 
-static void mark_all_frames(gboolean set) 
+static void mark_all_frames(gboolean set)
 {
   frame_data *fdata;
 
   /* XXX: we might need a progressbar here */
-  for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
     set_frame_mark(set,
                    fdata,
                    gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));
@@ -352,14 +559,14 @@ static void mark_all_frames(gboolean set)
   mark_frames_ready();
 }
 
-void packet_list_update_marked_frames(void) 
+void packet_list_update_marked_frames(void)
 {
   frame_data *fdata;
 
-  if (cfile.plist == NULL) return;
+  if (cfile.plist_start == NULL) return;
 
   /* XXX: we might need a progressbar here */
-  for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
     if (fdata->flags.marked)
       set_frame_mark(TRUE, fdata,
                      gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
@@ -368,16 +575,53 @@ void packet_list_update_marked_frames(void)
   mark_frames_ready();
 }
 
-void packet_list_mark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) 
+void packet_list_mark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
 {
   mark_all_frames(TRUE);
 }
 
-void packet_list_unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) 
+void packet_list_unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_)
 {
   mark_all_frames(FALSE);
 }
 
+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)
@@ -485,8 +729,7 @@ GtkWidget *
 packet_list_new(e_prefs *prefs)
 {
     GtkWidget *pkt_scrollw;
-    header_field_info *hfi;
-    gboolean custom_right_justify;
+    GtkJustification justify;
     int      i;
 
     /* Packet list */
@@ -519,27 +762,10 @@ packet_list_new(e_prefs *prefs)
         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 ||
-            cfile.cinfo.col_fmt[i] == COL_DCE_CTX ||
-            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));
@@ -559,7 +785,7 @@ packet_list_recreate(void)
 
     prefs.num_cols = g_list_length(prefs.col_list);
 
-    build_column_format_array(&cfile.cinfo, FALSE);
+    build_column_format_array(&cfile.cinfo, prefs.num_cols, FALSE);
 
     pkt_scrollw = packet_list_new(&prefs);
     gtk_widget_show(pkt_scrollw);
@@ -569,7 +795,7 @@ packet_list_recreate(void)
     main_widgets_rearrange();
 
     if(cfile.state != FILE_CLOSED)
-        cf_redissect_packets(&cfile);
+       redissect_packets();
 }
 
 void
@@ -579,8 +805,10 @@ packet_list_set_column_titles(void)
     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,
@@ -595,18 +823,31 @@ packet_list_set_column_titles(void)
     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);
-        col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
+        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,
                          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);
+        col_arrows[i].descend_pm = gtk_image_new_from_pixmap(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);
@@ -635,7 +876,7 @@ packet_list_freeze(void)
 }
 
 static void
-packet_list_resize_columns(void) 
+packet_list_resize_columns(void)
 {
     int         i;
     int         progbar_nextstep;
@@ -652,7 +893,7 @@ packet_list_resize_columns(void)
        bump that value by this amount. */
     progbar_quantum = cfile.cinfo.num_cols/N_PROGBAR_UPDATES;
     /* Progress so far. */
-    progbar_val = 0.0;
+    progbar_val = 0.0f;
 
     progbar_stop_flag = FALSE;
     g_get_current_time(&progbar_start_time);
@@ -752,7 +993,7 @@ void
 packet_list_moveto_end(void)
 {
     gtk_clist_moveto(GTK_CLIST(packet_list),
-                     GTK_CLIST(packet_list)->rows - 1, -1, 1.0, 1.0);
+                     GTK_CLIST(packet_list)->rows - 1, -1, 1.0f, 1.0f);
 }
 
 gboolean
@@ -843,7 +1084,7 @@ packet_list_get_row_data(gint row)
 
 /* get the first fully visible row number, given row MUST be visible */
 static gint
-packet_list_first_full_visible_row(gint row) 
+packet_list_first_full_visible_row(gint row)
 {
         g_assert(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL);
 
@@ -856,7 +1097,7 @@ packet_list_first_full_visible_row(gint row)
 
 /* get the last fully visible row number, given row MUST be visible */
 static gint
-packet_list_last_full_visible_row(gint row) 
+packet_list_last_full_visible_row(gint row)
 {
         g_assert(gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) == GTK_VISIBILITY_FULL);
 
@@ -890,7 +1131,7 @@ packet_list_set_selected_row(gint row)
     if (!full_visible) {
         gtk_clist_freeze(GTK_CLIST(packet_list));
 
-        gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
+        gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0f, 0.0f);
 
         /* 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) {
@@ -910,7 +1151,7 @@ packet_list_set_selected_row(gint row)
         visible_rows = packet_list_last_full_visible_row(row) - packet_list_first_full_visible_row(row);
         first_row = row - visible_rows / 3;
 
-        gtk_clist_moveto(GTK_CLIST(packet_list), first_row >= 0 ? first_row : 0, -1, 0.0, 0.0);
+        gtk_clist_moveto(GTK_CLIST(packet_list), first_row >= 0 ? first_row : 0, -1, 0.0f, 0.0f);
 
         gtk_clist_thaw(GTK_CLIST(packet_list));
     }
@@ -973,6 +1214,7 @@ void
 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++) {
@@ -982,9 +1224,15 @@ packet_list_recent_write_all(FILE *rf)
        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, ",");
      }
    }
    fprintf (rf, "\n");
 }
+
+#endif /* NEW_PACKET_LIST */