diff --git a/file.c b/file.c index f9c895e0e7..80d5154b1f 100644 --- a/file.c +++ b/file.c @@ -1,7 +1,7 @@ /* file.c * File I/O routines * - * $Id: file.c,v 1.197 2000/07/09 03:29:26 guy Exp $ + * $Id: file.c,v 1.198 2000/07/09 23:22:18 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -1203,6 +1203,11 @@ void change_time_formats(capture_file *cf) { frame_data *fdata; + progdlg_t *progbar; + gboolean stop_flag; + guint32 progbar_quantum; + guint32 progbar_nextstep; + int count; int row; int i; GtkStyle *pl_style; @@ -1211,11 +1216,49 @@ change_time_formats(capture_file *cf) screen updates while it happens. */ freeze_clist(cf); + /* 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 = cf->count/N_PROGBAR_UPDATES; + /* Count of packets at which we've looked. */ + count = 0; + + stop_flag = FALSE; + progbar = create_progress_dlg("Changing time display", "Stop", &stop_flag); + /* Iterate through the list of packets, checking whether the packet is in a row of the summary list and, if so, whether there are any columns that show the time in the "command-line-specified" format and, if so, update that row. */ for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) { + /* Update the progress bar, but do it only N_PROGBAR_UPDATES times; + when we update it, we have to run the GTK+ main loop to get it + to repaint what's pending, and doing so may involve an "ioctl()" + to see if there's any pending input from an X server, and doing + that for every packet can be costly, especially on a big file. */ + if (count >= progbar_nextstep) { + /* let's not divide by zero. I should never be started + * with count == 0, so let's assert that + */ + g_assert(cf->count > 0); + + update_progress_dlg(progbar, (gfloat) count / cf->count); + + progbar_nextstep += progbar_quantum; + } + + if (stop_flag) { + /* Well, the user decided to abort the redisplay. Just stop. + + XXX - this leaves the time field in the old format in + frames we haven't yet processed. So it goes; should we + simply not offer them the option of stopping? */ + break; + } + + count++; + /* Find what row this packet is in. */ row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata); @@ -1244,6 +1287,9 @@ change_time_formats(capture_file *cf) } } + /* We're done redisplaying the packets; destroy the progress bar. */ + destroy_progress_dlg(progbar); + /* Set the column widths of those columns that show the time in "command-line-specified" format. */ pl_style = gtk_widget_get_style(packet_list); diff --git a/gtk/display_opts.c b/gtk/display_opts.c index a500e461c5..2901695081 100644 --- a/gtk/display_opts.c +++ b/gtk/display_opts.c @@ -1,7 +1,7 @@ /* display_opts.c * Routines for packet display windows * - * $Id: display_opts.c,v 1.12 2000/07/09 20:59:23 guy Exp $ + * $Id: display_opts.c,v 1.13 2000/07/09 23:22:33 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -79,6 +79,7 @@ extern GtkWidget *packet_list; static void display_opt_ok_cb(GtkWidget *, gpointer); static void display_opt_apply_cb(GtkWidget *, gpointer); static void get_display_options(GtkWidget *); +static void update_display(void); static void display_opt_close_cb(GtkWidget *, gpointer); static void display_opt_destroy_cb(GtkWidget *, gpointer); @@ -93,6 +94,9 @@ static GtkWidget *display_opt_w; static ts_type initial_timestamp_type; static ts_type current_timestamp_type; +static gboolean initial_g_ip_dscp_actif; +static gboolean current_g_ip_dscp_actif; + void display_opt_cb(GtkWidget *w, gpointer d) { GtkWidget *button, *main_vb, *bbox, *ok_bt, *apply_bt, *cancel_bt; @@ -104,16 +108,21 @@ display_opt_cb(GtkWidget *w, gpointer d) { return; } - /* Save the timestamp type as of when the dialog box was first popped - up, so that "Cancel" can put it back if we've changed it with "Apply". */ + /* Save the timestamp type and "Display TOS as DiffServ" values as of + when the dialog box was first popped up, so that "Cancel" can put + them back if we've changed either of them with "Apply". */ initial_timestamp_type = timestamp_type; + initial_g_ip_dscp_actif = g_ip_dscp_actif; - /* Save the current timestamp type, so that we know whether it was - changed; we don't want to redisplay the time fields unless we've - changed it (as redisplaying the time fields could be expensive - - we have to scan through all the packets and rebuild the packet - list). */ + /* Save the current timestamp type and "Display TOS as DiffServ" values, + so that we know whether they were changed; we don't want to redisplay + the time fields unless we've changed the way they should be displayed + (as redisplaying the time fields could be expensive - we have to scan + through all the packets and rebuild the packet list), and we don't + want to reconstruct the packet list if we've changed the "Display + TOS as DiffServ" value (as that is also expensive). */ current_timestamp_type = timestamp_type; + current_g_ip_dscp_actif = g_ip_dscp_actif; display_opt_w = dlg_window_new(); gtk_window_set_title(GTK_WINDOW(display_opt_w), "Ethereal: Display Options"); @@ -229,29 +238,20 @@ display_opt_ok_cb(GtkWidget *ok_bt, gpointer parent_w) { gtk_widget_destroy(GTK_WIDGET(parent_w)); - if (timestamp_type != current_timestamp_type) { - /* Time stamp format changed; update the display. */ - current_timestamp_type = timestamp_type; - change_time_formats(&cfile); - } + update_display(); } static void display_opt_apply_cb(GtkWidget *ok_bt, gpointer parent_w) { get_display_options(GTK_WIDGET(parent_w)); - if (timestamp_type != current_timestamp_type) { - /* Time stamp format changed; update the display. */ - current_timestamp_type = timestamp_type; - change_time_formats(&cfile); - } + update_display(); } static void get_display_options(GtkWidget *parent_w) { GtkWidget *button; - gboolean bval; button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_DISPLAY_TIME_ABS_KEY); @@ -278,9 +278,13 @@ get_display_options(GtkWidget *parent_w) button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_DISPLAY_IP_DSCP_KEY); - bval = (GTK_TOGGLE_BUTTON (button)->active); - if (g_ip_dscp_actif != bval) { - g_ip_dscp_actif = bval; + g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active); +} + +static void +update_display(void) +{ + if (g_ip_dscp_actif != current_g_ip_dscp_actif) { /* XXX - we "know" here that the IP dissector doesn't need to be notified if this preference changed. @@ -289,19 +293,43 @@ get_display_options(GtkWidget *parent_w) "Display options" dialog box, as it can be changed from the "IP" tab in the "Preferences" dialog box. */ - /* Redissect all the packets, and re-evaluate the display filter. */ + current_g_ip_dscp_actif = g_ip_dscp_actif; + current_timestamp_type = timestamp_type; /* in case it changed too */ + + /* Redissect all the packets, and re-evaluate the display filter. + This will also change the time stamp display, as we're completely + regenerating the display list. */ redissect_packets(&cfile); + } else { + if (timestamp_type != current_timestamp_type) { + /* Time stamp format changed; update the display. + + XXX - redissecting the packets could actually be faster; + we have to find the row number for each frame, in order to + update the time stamp columns, and doing that is linear in + the row number, which means the whole process is N^2 in + the number of rows, whilst redissecting the packets is only + linear in the number of rows (assuming you're using our + CList code, or the GTK+ 1.2.8 CList code, or other CList + code which doesn't have to scan the entire list to find the + last element), even though the latter involves doing more work + per packet. */ + current_timestamp_type = timestamp_type; + change_time_formats(&cfile); + } } } static void display_opt_close_cb(GtkWidget *close_bt, gpointer parent_w) { - /* Revert the timestamp type to the value it had when we started. */ - if (timestamp_type != initial_timestamp_type) { - timestamp_type = initial_timestamp_type; - change_time_formats(&cfile); - } + /* Revert the timestamp type and "Display TOS as DiffServ" flag + to the values they had when we started. */ + g_ip_dscp_actif = initial_g_ip_dscp_actif; + timestamp_type = initial_timestamp_type; + + /* Update the display if either of those changed. */ + update_display(); gtk_grab_remove(GTK_WIDGET(parent_w)); gtk_widget_destroy(GTK_WIDGET(parent_w));