We can't trust "cf->current_frame" to refer to the frame that was
authorGuy Harris <guy@alum.mit.edu>
Mon, 15 May 2000 01:50:16 +0000 (01:50 -0000)
committerGuy Harris <guy@alum.mit.edu>
Mon, 15 May 2000 01:50:16 +0000 (01:50 -0000)
selected before we started re-colorizing or re-filtering the display, as
when the first row is added to the clist, that may be selected and thus
made the current frame.

This means that we can't find the row corresponding to the
previously-selected frame, if any, by checking as each packet is
colorized/filtered and see whether its "frame_data" structure is equal
to "cf->current_frame", as that'll always say that the first frame in
the display is the selected frame.

Instead, we recored the value of "cf->current_frame" before we do
anything to the clist, have "add_packet_to_packet_list()" return either
the row number of the frame (if it passed the filter and thus was added
to the clist) or -1 (if it didn't pass the filter and thus wasn't added
to the clist), and, after "add_packet_to_packet_list()", if the current
frame is the one that was the selected row, remember its row number (if
any), and, when we're finished colorizing/filtering the display, make
that row the current row if it's not -1 (-1 means that the selected row
didn't pass the filter).

Also, don't do that until after we've thawed the clist, as the vertical
adjustment for the clist doesn't reflect reality until then, and
attempting to go to a given row won't work right until the vertical
adjustment for the clist reflects reality.

Shove all the code to set the selected and focus rows, and to make said
row visible, into a routine, so the "Find Frame" and "Go To Frame" code
can use it as well.

svn path=/trunk/; revision=1959

file.c
file.h

diff --git a/file.c b/file.c
index b79c6d83ff42be16474e38cb57ccb91561fdbe80..662da0b5282177de3f65f752a27fea1d3eec6ca2 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
 /* file.c
  * File I/O routines
  *
- * $Id: file.c,v 1.185 2000/05/12 22:03:59 gram Exp $
+ * $Id: file.c,v 1.186 2000/05/15 01:50:14 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -96,6 +96,8 @@ static guint32 prevsec, prevusec;
 static void wtap_dispatch_cb(u_char *, const struct wtap_pkthdr *, int,
     const u_char *);
 
+static void set_selected_row(int row);
+
 static void freeze_clist(capture_file *cf);
 static void thaw_clist(capture_file *cf);
 
@@ -507,7 +509,7 @@ apply_color_filter(gpointer filter_arg, gpointer argp)
   }
 }
 
-static void
+static int
 add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf)
 {
   apply_color_filter_args args;
@@ -571,6 +573,8 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
   }
 
   if (fdata->flags.passed_dfilter) {
+    /* This frame passed the display filter, so add it to the clist. */
+
     /* If we don't have the time stamp of the previous displayed packet,
        it's because this is the first displayed packet.  Save the time
        stamp of this packet as the time stamp of the previous displayed
@@ -620,11 +624,6 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
     row = gtk_clist_append(GTK_CLIST(packet_list), fdata->cinfo->col_data);
     gtk_clist_set_row_data(GTK_CLIST(packet_list), row, fdata);
 
-    /* If this was the current frame, remember the row it's in, so
-       we can arrange that it's on the screen when we're done. */
-    if (cf->current_frame == fdata)
-      cf->current_row = row;
-
     if (filter_list != NULL && (args.colorf != NULL)) {
         gtk_clist_set_background(GTK_CLIST(packet_list), row,
                    &args.colorf->bg_color);
@@ -634,13 +633,19 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
         gtk_clist_set_background(GTK_CLIST(packet_list), row, &WHITE);
         gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &BLACK);
     }
+  } else {
+    /* This frame didn't pass the display filter, so it's not being added
+       to the clist, and thus has no row. */
+    row = -1;
   }
   fdata->cinfo = NULL;
+  return row;
 }
 
 static void
 wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
-  const u_char *buf) {
+  const u_char *buf)
+{
   frame_data   *fdata;
   capture_file *cf = (capture_file *) user;
   int           passed;
@@ -768,6 +773,19 @@ colorize_packets(capture_file *cf)
   guint32 progbar_quantum;
   guint32 progbar_nextstep;
   int count;
+  frame_data *selected_frame;
+  int selected_row;
+  int row;
+
+  /* Which frame, if any, is the currently selected frame?
+     XXX - should the selected frame or the focus frame be the "current"
+     frame, that frame being the one from which "Find Frame" searches
+     start? */
+  selected_frame = cf->current_frame;
+
+  /* We don't yet know what row that frame will be on, if any, after we
+     rebuild the clist, however. */
+  selected_row = -1;
 
   /* We need to re-initialize all the state information that protocols
      keep, because we're making a fresh pass through all the packets. */
@@ -791,10 +809,6 @@ colorize_packets(capture_file *cf)
   cf->first_displayed = NULL;
   cf->last_displayed = NULL;
 
-  /* If a packet was selected, we don't know yet what row, if any, it'll
-     get. */
-  cf->current_row = -1;
-
   /* Iterate through the list of packets, calling a routine
      to run the filter on the packet, see if it matches, and
      put it in the display list if so.  */
@@ -839,29 +853,27 @@ colorize_packets(capture_file *cf)
 
     wtap_seek_read (cf->cd_t, cf->fh, fdata->file_off, cf->pd, fdata->cap_len);
 
-    add_packet_to_packet_list(fdata, cf, cf->pd);
+    row = add_packet_to_packet_list(fdata, cf, cf->pd);
+    if (fdata == selected_frame)
+      selected_row = row;
   }
  
   gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
 
-  if (cf->current_row != -1) {
-    /* The current frame passed the filter; make sure it's visible. */
-    if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), cf->current_row))
-      gtk_clist_moveto(GTK_CLIST(packet_list), cf->current_row, -1, 0.0, 0.0);
-    if (cf->current_frame_is_selected) {
-      /* It was selected, so re-select it. */
-      gtk_clist_select_row(GTK_CLIST(packet_list), cf->current_row, -1);
-    }
+  /* Unfreeze the packet list. */
+  gtk_clist_thaw(GTK_CLIST(packet_list));
+
+  if (selected_row != -1) {
+    /* The frame that was selected passed the filter; select it, make it
+       the focus row, and make it visible. */
+    set_selected_row(selected_row);
     finfo_selected = NULL;
   } else {
-    /* The current frame didn't pass the filter; make the first frame
+    /* The selected frame didn't pass the filter; make the first frame
        the current frame, and leave it unselected. */
     unselect_packet(cf);
     cf->current_frame = cf->first_displayed;
   }
-
-  /* Unfreeze the packet list. */
-  gtk_clist_thaw(GTK_CLIST(packet_list));
 }
 
 int
@@ -1228,20 +1240,8 @@ find_packet(capture_file *cf, dfilter *sfcode)
     row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), new_fd);
     g_assert(row != -1);
 
-    /* Make it visible, and select it. */
-    if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), row))
-      gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
-
-    /* XXX - why is there no "gtk_clist_set_focus_row()", so that we
-       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
-
-       */
-    GTK_CLIST(packet_list)->focus_row = row;
-    gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
+    /* Select that row, make it the focus row, and make it visible. */
+    set_selected_row(row);
     return TRUE;       /* success */
   } else
     return FALSE;      /* failure */
@@ -1266,13 +1266,8 @@ goto_frame(capture_file *cf, guint fnumber)
   row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata);
   g_assert(row != -1);
 
-  /* Make it visible, and select it. */
-  if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), row))
-    gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
-
-  /* See above complaint about the lack of "gtk_clist_set_focus_row()". */
-  GTK_CLIST(packet_list)->focus_row = row;
-  gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
+  /* Select that row, make it the focus row, and make it visible. */
+  set_selected_row(row);
   return FOUND_FRAME;
 }
 
@@ -1316,9 +1311,8 @@ select_packet(capture_file *cf, int row)
          fdata = cf->first_displayed;
   }
 
-  /* Record that this frame is the current frame, and that it's selected. */
+  /* Record that this frame is the current frame. */
   cf->current_frame = fdata;
-  cf->current_frame_is_selected = TRUE;
 
   /* Get the data in that frame. */
   wtap_seek_read (cf->cd_t, cf->fh, fdata->file_off, cf->pd, fdata->cap_len);
@@ -1344,8 +1338,6 @@ select_packet(capture_file *cf, int row)
 void
 unselect_packet(capture_file *cf)
 {
-  cf->current_frame_is_selected = FALSE;
-
   /* Destroy the protocol tree for that packet. */
   if (cf->protocol_tree != NULL) {
     proto_tree_free(cf->protocol_tree);
@@ -1361,6 +1353,27 @@ unselect_packet(capture_file *cf)
   set_menus_for_selected_packet(FALSE);
 }
 
+/* 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. */
+static void
+set_selected_row(int row)
+{
+  if (gtk_clist_row_is_visible(GTK_CLIST(packet_list), row) != GTK_VISIBILITY_FULL)
+    gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
+
+  /* XXX - why is there no "gtk_clist_set_focus_row()", so that we
+     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
+
+     */
+  GTK_CLIST(packet_list)->focus_row = row;
+
+  gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
+}
+
 static void
 freeze_clist(capture_file *cf)
 {
diff --git a/file.h b/file.h
index dff9d580cffb3d998dae0a485c65dd8b4aa5047c..4ae6cfc77ebd7e547c87ec69fcbaa83b97fead2a 100644 (file)
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
 /* file.h
  * Definitions for file structures and routines
  *
- * $Id: file.h,v 1.65 2000/04/03 08:42:45 guy Exp $
+ * $Id: file.h,v 1.66 2000/05/15 01:50:16 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -109,8 +109,6 @@ typedef struct _capture_file {
   frame_data  *last_displayed;  /* Last frame displayed */
   column_info  cinfo;    /* Column formatting information */
   frame_data  *current_frame;  /* Frame data for current frame */
-  int          current_row;    /* Row in packet display of current frame */
-  gboolean     current_frame_is_selected; /* TRUE if that frame is selected */
   proto_tree  *protocol_tree; /* Protocol tree for currently selected packet */
   FILE        *print_fh;  /* File we're printing to */
 } capture_file;