From 831c54c4f5b15e8d8fce18bd6f6d08974d689d56 Mon Sep 17 00:00:00 2001 From: Ulf Lamping Date: Tue, 20 Sep 2005 08:42:35 +0000 Subject: add two new callbacks: cf_cb_file_closing (called before closing a capture file) cf_cb_file_closed will be called afterwards, but both only if a file is really closed as cf_close is called more often ... If we are closing large capture files (~20MB), the screen looks ugly while the file is closed. Change this so the screen will immediately go back to initial state and a dialog (without buttons) is shown that the file is currently closed. As the operation which takes most of the time to close the file is a single eth_clist_clear call, we can't use a progress bar here. cf_cb_live_capture_stopping: called when the user wants to stop the capture (toolbar or menu clicked). At least on Win32, the time between this and the actual stop completed can be noticeable (1-2 seconds), so the user doesn't know if the button press did anything at all. Do something similar as above, show a dialog box without buttons to inform that the close is in progress. svn path=/trunk/; revision=15891 --- capture.c | 3 +++ file.c | 20 +++++++++++--------- file.h | 2 ++ gtk/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/capture.c b/capture.c index 12f9cbe3f3..c89feea5f9 100644 --- a/capture.c +++ b/capture.c @@ -119,6 +119,8 @@ capture_stop(capture_options *capture_opts) { g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ..."); + cf_callback_invoke(cf_cb_live_capture_stopping, capture_opts); + /* stop the capture child gracefully */ sync_pipe_stop(capture_opts); } @@ -310,6 +312,7 @@ capture_input_new_packets(capture_options *capture_opts, int to_read) XXX - abort on a read error? */ cf_callback_invoke(cf_cb_live_capture_update_continue, capture_opts->cf); + /* update the main window, so we get events (e.g. from the stop toolbar button) */ main_window_update(); break; diff --git a/file.c b/file.c index 9b4f9977e6..aa8dc3d1f9 100644 --- a/file.c +++ b/file.c @@ -347,11 +347,17 @@ cf_reset_state(capture_file *cf) void cf_close(capture_file *cf) { - cf_reset_state(cf); + /* close things, if not already closed before */ + if(cf->state != FILE_CLOSED) { + + cf_callback_invoke(cf_cb_file_closing, cf); - cleanup_dissection(); + cf_reset_state(cf); - cf_callback_invoke(cf_cb_file_closed, cf); + cleanup_dissection(); + + cf_callback_invoke(cf_cb_file_closed, cf); + } } cf_read_status_t @@ -557,13 +563,13 @@ cf_continue_tail(capture_file *cf, int to_read, int *err) to_read--; } - packet_list_thaw(); - /* XXX - this cheats and looks inside the packet list to find the final row number. */ if (auto_scroll_live && cf->plist_end != NULL) packet_list_moveto_end(); + packet_list_thaw(); + if (cf->state == FILE_READ_ABORTED) { /* Well, the user decided to exit Ethereal. Return CF_READ_ABORTED so that our caller can kill off the capture child process; @@ -3104,10 +3110,6 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f packet_range_process_init(range); - /* Used to be : - * if (!save_filtered && !save_marked && !save_manual_range && - * !save_marked_range && !save_curr && save_format == cf->cd_t) { - */ if (packet_range_process_all(range) && save_format == cf->cd_t) { /* We're not filtering packets, and we're saving it in the format diff --git a/file.h b/file.h index 3eadec354d..f479ff5f6a 100644 --- a/file.h +++ b/file.h @@ -56,6 +56,7 @@ typedef enum { } cf_print_status_t; typedef enum { + cf_cb_file_closing, cf_cb_file_closed, cf_cb_file_read_start, cf_cb_file_read_finished, @@ -66,6 +67,7 @@ typedef enum { cf_cb_live_capture_update_finished, cf_cb_live_capture_fixed_started, cf_cb_live_capture_fixed_finished, + cf_cb_live_capture_stopping, #endif cf_cb_packet_selected, cf_cb_packet_unselected, diff --git a/gtk/main.c b/gtk/main.c index bb54ad893b..f3cdd20c25 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1229,10 +1229,26 @@ set_display_filename(capture_file *cf) g_free(win_name); } +GtkWidget *close_dlg = NULL; static void -main_cf_cb_file_closed(capture_file *cf) +main_cf_cb_file_closing(capture_file *cf) { + + /* if we have more than 10000 packets, show a splash screen while closing */ + /* XXX - don't know a better way to decide wether to show or not, + * as most of the time is spend in a single eth_clist_clear function, + * so we can't use a progress bar here! */ + if(cf->count > 10000) { + close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sClosing file!%s\n\nPlease wait ...", + simple_dialog_primary_start(), simple_dialog_primary_end()); +#if GTK_MAJOR_VERSION >= 2 + gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT); +#else + gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER); +#endif + } + /* Destroy all windows, which refer to the capture file we're closing. */ destroy_cfile_wins(); @@ -1258,6 +1274,17 @@ main_cf_cb_file_closed(capture_file *cf) /* Set up main window for no capture file. */ main_set_for_capture_file(FALSE); + + main_window_update(); +} + +static void +main_cf_cb_file_closed(capture_file *cf) +{ + if(close_dlg != NULL) { + splash_destroy(close_dlg); + close_dlg = NULL; + } } static void @@ -1370,9 +1397,16 @@ main_cf_cb_live_capture_update_continue(capture_file *cf) statusbar_push_file_msg(capture_msg); } +GtkWidget * stop_dlg = NULL; + static void main_cf_cb_live_capture_update_finished(capture_file *cf) { + if(stop_dlg != NULL) { + simple_dialog_close(stop_dlg); + stop_dlg = NULL; + } + /* Pop the "" message off the status bar. */ statusbar_pop_file_msg(); @@ -1419,6 +1453,11 @@ main_cf_cb_live_capture_fixed_started(capture_options *capture_opts) static void main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_) { + if(stop_dlg != NULL) { + simple_dialog_close(stop_dlg); + stop_dlg = NULL; + } + /* Pop the "" message off the status bar. */ statusbar_pop_file_msg(); @@ -1434,6 +1473,19 @@ main_cf_cb_live_capture_fixed_finished(capture_file *cf _U_) /* We don't have loaded the capture file, this will be done later. * For now we still have simply a blank screen. */ } + +static void +main_cf_cb_live_capture_stopping(capture_file *cf _U_) +{ + stop_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE, "%sCapture stop!%s\n\nPlease wait ...", + simple_dialog_primary_start(), simple_dialog_primary_end()); +#if GTK_MAJOR_VERSION >= 2 + gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER_ON_PARENT); +#else + gtk_window_set_position(GTK_WINDOW(stop_dlg), GTK_WIN_POS_CENTER); +#endif +} + #endif static void @@ -1505,6 +1557,9 @@ main_cf_cb_file_safe_reload_finished(gpointer data _U_) static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_) { switch(event) { + case(cf_cb_file_closing): + main_cf_cb_file_closing(data); + break; case(cf_cb_file_closed): main_cf_cb_file_closed(data); break; @@ -1533,6 +1588,9 @@ static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_) case(cf_cb_live_capture_fixed_finished): main_cf_cb_live_capture_fixed_finished(data); break; + case(cf_cb_live_capture_stopping): + main_cf_cb_live_capture_stopping(data); + break; #endif case(cf_cb_packet_selected): main_cf_cb_packet_selected(data); -- cgit v1.2.3