remove some warnings
[obnox/wireshark/wip.git] / gtk / packet_list.c
index 4ed93e3f936aab9a5c47beb02f9879afaa4f03cc..34c97257781b6788191c66712ece599b72d84e13 100644 (file)
@@ -3,8 +3,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -43,7 +43,7 @@
 #include "epan/column_info.h"
 #include "compat_macros.h"
 #include <epan/prefs.h>
-#include "file_dlg.h"
+#include "capture_file_dlg.h"
 #include "packet_list.h"
 #include "keys.h"
 #include "font_utils.h"
@@ -162,6 +162,7 @@ packet_list_compare(EthCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
 
     case TS_ABSOLUTE:
     case TS_ABSOLUTE_WITH_DATE:
+    case TS_EPOCH:
       return COMPARE_TS(abs_ts);
 
     case TS_RELATIVE:
@@ -169,6 +170,9 @@ packet_list_compare(EthCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
 
     case TS_DELTA:
       return COMPARE_TS(del_ts);
+
+    case TS_NOT_SET:
+      return 0;
     }
     return 0;
 
@@ -311,11 +315,11 @@ set_frame_mark(gboolean set, frame_data *frame, gint row) {
 
 /* call this after last set_frame_mark is done */
 static void mark_frames_ready(void) {
-  file_set_save_marked_sensitive();
+  file_save_update_dynamics();
   packets_bar_update();
 }
 
-void 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) {
     /* XXX hum, should better have a "cfile->current_row" here ... */
     set_frame_mark(!cfile.current_frame->flags.marked,
@@ -328,7 +332,7 @@ void mark_frame_cb(GtkWidget *w _U_, gpointer data _U_) {
 
 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) {
     set_frame_mark(set,
@@ -338,7 +342,7 @@ static void mark_all_frames(gboolean set) {
   mark_frames_ready();
 }
 
-void update_marked_frames(void) {
+void packet_list_update_marked_frames(void) {
   frame_data *fdata;
 
   if (cfile.plist == NULL) return;
@@ -354,11 +358,11 @@ void update_marked_frames(void) {
   mark_frames_ready();
 }
 
-void 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 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);
 }
 
@@ -366,8 +370,8 @@ gboolean
 packet_list_get_event_row_column(GtkWidget *w, GdkEventButton *event_button,
                                 gint *row, gint *column)
 {
-    return eth_clist_get_selection_info(ETH_CLIST(w), 
-                                 (gint) event_button->x, (gint) event_button->y, 
+    return eth_clist_get_selection_info(ETH_CLIST(w),
+                                 (gint) event_button->x, (gint) event_button->y,
                                   row, column);
 }
 
@@ -416,7 +420,7 @@ packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_)
 
 /* Set the selection mode of the packet list window. */
 void
-set_plist_sel_browse(gboolean val)
+packet_list_set_sel_browse(gboolean val)
 {
         GtkSelectionMode new_mode;
         /* initialize with a mode we don't use, so that the mode == new_mode
@@ -424,7 +428,7 @@ set_plist_sel_browse(gboolean val)
         static GtkSelectionMode mode = GTK_SELECTION_MULTIPLE;
 
         /* Yeah, GTK uses "browse" in the case where we do not, but oh well. I
-         * think "browse" in Ethereal makes more sense than "SINGLE" in GTK+ */
+         * think "browse" in Wireshark makes more sense than "SINGLE" in GTK+ */
         new_mode = val ? GTK_SELECTION_SINGLE : GTK_SELECTION_BROWSE;
 
        if (mode == new_mode) {
@@ -454,7 +458,7 @@ set_plist_sel_browse(gboolean val)
 
 /* Set the font of the packet list window. */
 void
-set_plist_font(FONT_TYPE *font)
+packet_list_set_font(FONT_TYPE *font)
 {
        int i;
        gint col_width;
@@ -501,14 +505,14 @@ packet_list_new(e_prefs *prefs)
      * 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
-     * (see http://bugs.ethereal.com/bugzilla/show_bug.cgi?id=220),
+     * (see http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=220),
      * we show that scrollbar always. */
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(pkt_scrollw),
                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
 #if GTK_MAJOR_VERSION >= 2
-    /* the eth_clist will have it's own GTK_SHADOW_IN, so don't use a shadow 
+    /* the eth_clist will have it's own GTK_SHADOW_IN, so don't use a shadow
      * for both widgets */
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pkt_scrollw), 
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(pkt_scrollw),
                                     GTK_SHADOW_NONE);
 #endif
 
@@ -516,13 +520,13 @@ packet_list_new(e_prefs *prefs)
     /* Column titles are filled in below */
     gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list);
 
-    set_plist_sel_browse(prefs->gui_plist_sel_browse);
-    set_plist_font(user_font_get_regular());
+    packet_list_set_sel_browse(prefs->gui_plist_sel_browse);
+    packet_list_set_font(user_font_get_regular());
     gtk_widget_set_name(packet_list, "packet list");
     SIGNAL_CONNECT(packet_list, "select-row", packet_list_select_cb, NULL);
     SIGNAL_CONNECT(packet_list, "unselect-row", packet_list_unselect_cb, NULL);
     for (i = 0; i < cfile.cinfo.num_cols; i++) {
-        /* For performance reasons, columns do not automatically resize, 
+        /* For performance reasons, columns do not automatically resize,
            but are resizeable by the user. */
         eth_clist_set_column_auto_resize(ETH_CLIST(packet_list), i, FALSE);
         eth_clist_set_column_resizeable(ETH_CLIST(packet_list), i, TRUE);
@@ -531,7 +535,8 @@ packet_list_new(e_prefs *prefs)
         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_CALL ||
+            cfile.cinfo.col_fmt[i] == COL_DCE_CTX)
             eth_clist_set_column_justification(ETH_CLIST(packet_list), i,
                                                GTK_JUSTIFY_RIGHT);
     }
@@ -611,58 +616,64 @@ packet_list_resize_columns(void) {
     int         i;
     int         progbar_nextstep;
     int         progbar_quantum;
-    gboolean    stop_flag;
-    GTimeVal    start_time;
-    float       prog_val;
+    gboolean    progbar_stop_flag;
+    GTimeVal    progbar_start_time;
+    float       progbar_val;
     progdlg_t  *progbar = NULL;
     gchar       status_str[100];
 
-
+    /* Update the progress bar when it gets to this value. */
     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;
+    /* Progress so far. */
+    progbar_val = 0.0;
 
-    stop_flag = FALSE;
-    g_get_current_time(&start_time);
+    progbar_stop_flag = FALSE;
+    g_get_current_time(&progbar_start_time);
 
 
     main_window_update();
 
     for (i = 0; i < cfile.cinfo.num_cols; i++) {
+      /* 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)
+         progbar = delayed_create_progress_dlg("Resizing", "Resize Columns",
+           TRUE, &progbar_stop_flag, &progbar_start_time, progbar_val);
+
       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);
 
-        prog_val = (gfloat) i / cfile.cinfo.num_cols;
-
-        /* Create the progress bar if necessary */
-        if (progbar == NULL)
-           progbar = delayed_create_progress_dlg("Resizing", "Resize Columns", 
-             &stop_flag, &start_time, prog_val);
+        progbar_val = (gfloat) i / cfile.cinfo.num_cols;
 
         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]);
-          update_progress_dlg(progbar, prog_val, status_str);
+          update_progress_dlg(progbar, progbar_val, status_str);
         }
 
         progbar_nextstep += progbar_quantum;
       }
 
-      if (stop_flag) {
+      if (progbar_stop_flag) {
         /* Well, the user decided to abort the resizing... */
         break;
       }
 
-        /* auto resize the current column */
-        eth_clist_set_column_auto_resize(ETH_CLIST(packet_list), i, TRUE);
+      /* auto resize the current column */
+      eth_clist_set_column_auto_resize(ETH_CLIST(packet_list), i, TRUE);
 
-        /* the current column should be resizeable by the user again */
-        /* (will turn off auto resize again) */
-        eth_clist_set_column_resizeable(ETH_CLIST(packet_list), i, TRUE);
+      /* the current column should be resizeable by the user again */
+      /* (will turn off auto resize again) */
+      eth_clist_set_column_resizeable(ETH_CLIST(packet_list), i, TRUE);
     }
 
     /* We're done resizing the columns; destroy the progress bar if it
@@ -690,6 +701,33 @@ packet_list_select_row(gint row)
     SIGNAL_EMIT_BY_NAME(packet_list, "select_row", row);
 }
 
+static void
+packet_list_next_prev(gboolean next)
+{
+#if GTK_MAJOR_VERSION >= 2
+    GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(top_level));
+#endif
+    SIGNAL_EMIT_BY_NAME(packet_list, "scroll_vertical",
+        next ? GTK_SCROLL_STEP_FORWARD : GTK_SCROLL_STEP_BACKWARD, 0.0);
+#if GTK_MAJOR_VERSION >= 2
+    /* Set the focus back where it was */
+    if (focus)
+        gtk_window_set_focus(GTK_WINDOW(top_level), focus);
+#endif
+}
+
+void
+packet_list_next()
+{
+    packet_list_next_prev(TRUE);
+}
+
+void
+packet_list_prev()
+{
+    packet_list_next_prev(FALSE);
+}
+
 void
 packet_list_moveto_end(void)
 {
@@ -765,14 +803,49 @@ packet_list_get_row_data(gint row)
     return eth_clist_get_row_data(ETH_CLIST(packet_list), row);
 }
 
+
+/* get the first fully visible row number, given row MUST be visible */
+static gint
+packet_list_first_full_visible_row(gint row) {
+
+       g_assert(eth_clist_row_is_visible(ETH_CLIST(packet_list), row) ==
+        GTK_VISIBILITY_FULL);
+
+       while(eth_clist_row_is_visible(ETH_CLIST(packet_list), row) ==
+        GTK_VISIBILITY_FULL) {
+               row--;
+       }
+
+       return ++row;
+}
+
+/* get the last fully visible row number, given row MUST be visible */
+static gint
+packet_list_last_full_visible_row(gint row) {
+
+       g_assert(eth_clist_row_is_visible(ETH_CLIST(packet_list), row) ==
+        GTK_VISIBILITY_FULL);
+
+       while(eth_clist_row_is_visible(ETH_CLIST(packet_list), row) ==
+        GTK_VISIBILITY_FULL) {
+               row++;
+       }
+
+       return --row;
+}
+
 /* 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)
 {
-    if (eth_clist_row_is_visible(ETH_CLIST(packet_list), row) !=
-        GTK_VISIBILITY_FULL)
-        eth_clist_moveto(ETH_CLIST(packet_list), row, -1, 0.0, 0.0);
+       gint visible_rows;
+       gint first_row;
+       gboolean full_visible;
+
+
+       full_visible = eth_clist_row_is_visible(ETH_CLIST(packet_list), row) ==
+        GTK_VISIBILITY_FULL;
 
     /* XXX - why is there no "eth_clist_set_focus_row()", so that we
      * can make the row for the frame we found the focus row?
@@ -782,6 +855,36 @@ packet_list_set_selected_row(gint row)
     ETH_CLIST(packet_list)->focus_row = row;
 
     eth_clist_select_row(ETH_CLIST(packet_list), row, -1);
+
+    if (!full_visible) {
+
+        eth_clist_freeze(ETH_CLIST(packet_list));
+
+        eth_clist_moveto(ETH_CLIST(packet_list), row, -1, 0.0, 0.0);
+
+               /* even after move still invisible (happens with empty list) -> give up */
+               if(eth_clist_row_is_visible(ETH_CLIST(packet_list), row) !=
+                       GTK_VISIBILITY_FULL) {
+                       eth_clist_thaw(ETH_CLIST(packet_list));
+                       return;
+               }
+
+               /* 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;
+
+               eth_clist_moveto(ETH_CLIST(packet_list), first_row >= 0 ? first_row : 0, -1, 0.0, 0.0);
+
+               eth_clist_thaw(ETH_CLIST(packet_list));
+       }
 }
 
 /* Return the column number that the clist is currently sorted by */