diff options
author | Guy Harris <guy@alum.mit.edu> | 2012-06-04 18:40:45 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2012-06-04 18:40:45 +0000 |
commit | 1899e6ee344d7a292e4ee1bbd6fc64d352b10f54 (patch) | |
tree | 4949850fe7bb36ea0ba6fe1809edca647db8e5e3 | |
parent | a0c9661fa50c7872072b22c63a55320dd64b36b2 (diff) |
Do with the open dialog what we've done with the save and "export
selected packets" dialog.
svn path=/trunk/; revision=43074
-rw-r--r-- | ui/gtk/capture_file_dlg.c | 241 | ||||
-rw-r--r-- | ui/gtk/gui_utils.c | 24 | ||||
-rw-r--r-- | ui/gtk/gui_utils.h | 10 |
3 files changed, 135 insertions, 140 deletions
diff --git a/ui/gtk/capture_file_dlg.c b/ui/gtk/capture_file_dlg.c index c6aa5deb18..067ff44c2a 100644 --- a/ui/gtk/capture_file_dlg.c +++ b/ui/gtk/capture_file_dlg.c @@ -76,9 +76,6 @@ #include "ui/win32/file_dlg_win32.h" #endif - -static void file_open_ok_cb(GtkWidget *w, gpointer fs); -static void file_open_destroy_cb(GtkWidget *win, gpointer user_data); static void file_merge_ok_cb(GtkWidget *w, gpointer fs); static void file_merge_destroy_cb(GtkWidget *win, gpointer user_data); static void do_file_save(capture_file *cf, gboolean dont_reopen); @@ -95,10 +92,6 @@ static void set_file_type_list(GtkWidget *combo_box, capture_file *cf); #define E_FILE_TYPE_COMBO_BOX_KEY "file_type_combo_box" #define E_COMPRESSED_CB_KEY "compressed_cb" -#define E_FILE_M_RESOLVE_KEY "file_dlg_mac_resolve_key" -#define E_FILE_N_RESOLVE_KEY "file_dlg_network_resolve_key" -#define E_FILE_T_RESOLVE_KEY "file_dlg_transport_resolve_key" - #define E_MERGE_PREPEND_KEY "merge_dlg_prepend_key" #define E_MERGE_CHRONO_KEY "merge_dlg_chrono_key" #define E_MERGE_APPEND_KEY "merge_dlg_append_key" @@ -432,14 +425,6 @@ preview_new(void) return table; } -/* - * Keep a static pointer to the current "Open Capture File" window, if - * any, so that if somebody tries to do "File:Open" while there's already - * an "Open Capture File" window up, we just pop up the existing one, - * rather than creating a new one. - */ -static GtkWidget *file_open_w; - /* Open a file */ static void file_open_cmd(GtkWidget *w) @@ -447,6 +432,7 @@ file_open_cmd(GtkWidget *w) #if _WIN32 win32_open_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level))); #else /* _WIN32 */ + GtkWidget *file_open_w; GtkWidget *main_hb, *main_vb, *filter_hbox, *filter_bt, *filter_te, *m_resolv_cb, *n_resolv_cb, *t_resolv_cb, *prev; /* No Apply button, and "OK" just sets our text widget, it doesn't @@ -457,12 +443,10 @@ file_open_cmd(GtkWidget *w) FALSE, TRUE }; - - if (file_open_w != NULL) { - /* There's already an "Open Capture File" dialog box; reactivate it. */ - reactivate_window(file_open_w); - return; - } + gchar *cf_name, *s; + const gchar *rfilter; + dfilter_t *rfcode = NULL; + int err; file_open_w = file_selection_new("Wireshark: Open Capture File", FILE_SELECTION_OPEN); @@ -490,7 +474,6 @@ file_open_cmd(GtkWidget *w) break; } - main_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); file_selection_set_extra_widget(file_open_w, main_hb); gtk_widget_show(main_hb); @@ -535,8 +518,6 @@ file_open_cmd(GtkWidget *w) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_resolv_cb), gbl_resolv_flags & RESOLV_MAC); gtk_box_pack_start(GTK_BOX(main_vb), m_resolv_cb, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(file_open_w), - E_FILE_M_RESOLVE_KEY, m_resolv_cb); gtk_widget_show(m_resolv_cb); n_resolv_cb = gtk_check_button_new_with_mnemonic("Enable _network name resolution"); @@ -544,16 +525,11 @@ file_open_cmd(GtkWidget *w) gbl_resolv_flags & RESOLV_NETWORK); gtk_box_pack_start(GTK_BOX(main_vb), n_resolv_cb, FALSE, FALSE, 0); gtk_widget_show(n_resolv_cb); - g_object_set_data(G_OBJECT(file_open_w), E_FILE_N_RESOLVE_KEY, n_resolv_cb); t_resolv_cb = gtk_check_button_new_with_mnemonic("Enable _transport name resolution"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_resolv_cb), gbl_resolv_flags & RESOLV_TRANSPORT); gtk_box_pack_start(GTK_BOX(main_vb), t_resolv_cb, FALSE, FALSE, 0); gtk_widget_show(t_resolv_cb); - g_object_set_data(G_OBJECT(file_open_w), E_FILE_T_RESOLVE_KEY, t_resolv_cb); - - g_signal_connect(file_open_w, "destroy", - G_CALLBACK(file_open_destroy_cb), NULL); /* preview widget */ prev = preview_new(); @@ -567,128 +543,112 @@ file_open_cmd(GtkWidget *w) g_object_set_data(G_OBJECT(file_open_w), E_DFILTER_TE_KEY, g_object_get_data(G_OBJECT(w), E_DFILTER_TE_KEY)); - if (gtk_dialog_run(GTK_DIALOG(file_open_w)) == GTK_RESPONSE_ACCEPT) - { - file_open_ok_cb(file_open_w, file_open_w); - } - else window_destroy(file_open_w); -#endif /* _WIN32 */ -} - -void -file_open_cmd_cb(GtkWidget *widget, gpointer data _U_) { - /* If there's unsaved data, let the user save it first. - If they cancel out of it, don't quit. */ - if (do_file_close(&cfile, FALSE, " before opening a new capture file")) - file_open_cmd(widget); -} - -/* user pressed "open" button */ -static void -file_open_ok_cb(GtkWidget *w, gpointer fs) { - gchar *cf_name, *s; - const gchar *rfilter; - GtkWidget *filter_te, *m_resolv_cb, *n_resolv_cb, *t_resolv_cb; - dfilter_t *rfcode = NULL; - int err; - - cf_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); - filter_te = (GtkWidget *)g_object_get_data(G_OBJECT(w), E_RFILTER_TE_KEY); - rfilter = gtk_entry_get_text(GTK_ENTRY(filter_te)); - if (!dfilter_compile(rfilter, &rfcode)) { - bad_dfilter_alert_box(rfilter); - g_free(cf_name); - return; - } - /* Perhaps the user specified a directory instead of a file. - Check whether they did. */ - if (test_for_directory(cf_name) == EISDIR) { - /* It's a directory - set the file selection box to display that - directory, don't try to open the directory as a capture file. */ - set_last_open_dir(cf_name); - g_free(cf_name); - file_selection_set_current_folder(fs, get_last_open_dir()); - return; - } - - /* Try to open the capture file. */ - if (cf_open(&cfile, cf_name, FALSE, &err) != CF_OK) { - /* We couldn't open it; don't dismiss the open dialog box, - just leave it around so that the user can, after they - dismiss the alert box popped up for the open error, - try again. */ - if (rfcode != NULL) - dfilter_free(rfcode); - g_free(cf_name); - - /* XXX - as we cannot start a new event loop (using gtk_dialog_run()), - * as this will prevent the user from closing the now existing error - * message, simply close the dialog (this is the best we can do here). */ - if (file_open_w) + /* + * Loop until the user either selects a file or gives up. + */ + for (;;) { + if (gtk_dialog_run(GTK_DIALOG(file_open_w)) != GTK_RESPONSE_ACCEPT) { + /* They clicked "Cancel" or closed the dialog or.... */ window_destroy(file_open_w); + return; + } - return; - } + cf_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_open_w)); - /* Attach the new read filter to "cf" ("cf_open()" succeeded, so - it closed the previous capture file, and thus destroyed any - previous read filter attached to "cf"). */ - cfile.rfcode = rfcode; + /* Perhaps the user specified a directory instead of a file. + Check whether they did. */ + if (test_for_directory(cf_name) == EISDIR) { + /* It's a directory - set the file selection box to display that + directory, and go back and re-run it; don't try to open the + directory as a capture file. */ + set_last_open_dir(cf_name); + g_free(cf_name); + file_selection_set_current_folder(file_open_w, get_last_open_dir()); + continue; + } - /* Set the global resolving variable */ - gbl_resolv_flags = prefs.name_resolve; - m_resolv_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), E_FILE_M_RESOLVE_KEY); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (m_resolv_cb))) - gbl_resolv_flags |= RESOLV_MAC; - else - gbl_resolv_flags &= ~RESOLV_MAC; - n_resolv_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), E_FILE_N_RESOLVE_KEY); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (n_resolv_cb))) - gbl_resolv_flags |= RESOLV_NETWORK; - else - gbl_resolv_flags &= ~RESOLV_NETWORK; - t_resolv_cb = (GtkWidget *)g_object_get_data(G_OBJECT(w), E_FILE_T_RESOLVE_KEY); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (t_resolv_cb))) - gbl_resolv_flags |= RESOLV_TRANSPORT; - else - gbl_resolv_flags &= ~RESOLV_TRANSPORT; + /* Get the specified read filter and try to compile it. */ + rfilter = gtk_entry_get_text(GTK_ENTRY(filter_te)); + if (!dfilter_compile(rfilter, &rfcode)) { + /* Not valid. Tell the user, and go back and run the file + selection box again once they dismiss the alert. */ + bad_dfilter_alert_box_modal(file_open_w, rfilter); + g_free(cf_name); + continue; + } - /* We've crossed the Rubicon; get rid of the file selection box. */ - window_destroy(GTK_WIDGET (fs)); + /* Try to open the capture file. */ + if (cf_open(&cfile, cf_name, FALSE, &err) != CF_OK) { + /* We couldn't open it; don't dismiss the open dialog box, + just leave it around so that the user can, after they + dismiss the alert box popped up for the open error, + try again. */ + if (rfcode != NULL) + dfilter_free(rfcode); + g_free(cf_name); + continue; + } - switch (cf_read(&cfile, FALSE)) { + /* Attach the new read filter to "cf" ("cf_open()" succeeded, so + it closed the previous capture file, and thus destroyed any + previous read filter attached to "cf"). */ + cfile.rfcode = rfcode; + + /* Set the global resolving variable */ + gbl_resolv_flags = prefs.name_resolve; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (m_resolv_cb))) + gbl_resolv_flags |= RESOLV_MAC; + else + gbl_resolv_flags &= ~RESOLV_MAC; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (n_resolv_cb))) + gbl_resolv_flags |= RESOLV_NETWORK; + else + gbl_resolv_flags &= ~RESOLV_NETWORK; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (t_resolv_cb))) + gbl_resolv_flags |= RESOLV_TRANSPORT; + else + gbl_resolv_flags &= ~RESOLV_TRANSPORT; + + /* We've crossed the Rubicon; get rid of the file selection box. */ + window_destroy(GTK_WIDGET(file_open_w)); + + switch (cf_read(&cfile, FALSE)) { + + case CF_READ_OK: + case CF_READ_ERROR: + /* Just because we got an error, that doesn't mean we were unable + to read any of the file; we handle what we could get from the + file. */ + break; + + case CF_READ_ABORTED: + /* The user bailed out of re-reading the capture file; the + capture file has been closed - just free the capture file name + string and return (without changing the last containing + directory). */ + g_free(cf_name); + return; + } - case CF_READ_OK: - case CF_READ_ERROR: - /* Just because we got an error, that doesn't mean we were unable - to read any of the file; we handle what we could get from the - file. */ - break; + /* Save the name of the containing directory specified in the path name, + if any; we can write over cf_name, which is a good thing, given that + "get_dirname()" does write over its argument. */ + s = get_dirname(cf_name); + set_last_open_dir(s); - case CF_READ_ABORTED: - /* The user bailed out of re-reading the capture file; the - capture file has been closed - just free the capture file name - string and return (without changing the last containing - directory). */ g_free(cf_name); return; } - - /* Save the name of the containing directory specified in the path name, - if any; we can write over cf_name, which is a good thing, given that - "get_dirname()" does write over its argument. */ - s = get_dirname(cf_name); - set_last_open_dir(s); - - g_free(cf_name); +#endif /* _WIN32 */ } -static void -file_open_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_) -{ - /* Note that we no longer have a "Open Capture File" dialog box. */ - file_open_w = NULL; +void +file_open_cmd_cb(GtkWidget *widget, gpointer data _U_) { + /* If there's unsaved data, let the user save it first. + If they cancel out of it, don't quit. */ + if (do_file_close(&cfile, FALSE, " before opening a new capture file")) + file_open_cmd(widget); } /* @@ -1022,8 +982,8 @@ file_merge_ok_cb(GtkWidget *w, gpointer fs) { /* XXX - as we cannot start a new event loop (using gtk_dialog_run()), * as this will prevent the user from closing the now existing error * message, simply close the dialog (this is the best we can do here). */ - if (file_open_w) - window_destroy(file_open_w); + if (file_merge_w) + window_destroy(file_merge_w); return; } g_free(tmpname); @@ -1382,7 +1342,8 @@ do_file_save_as(capture_file *cf) Check whether they did. */ if (test_for_directory(cf_name) == EISDIR) { /* It's a directory - set the file selection box to display that - directory, and go back and re-run it. */ + directory, and go back and re-run it; don't try to write onto + the directory (which won't work anyway). */ set_last_open_dir(cf_name); g_free(cf_name); file_selection_set_current_folder(file_save_as_w, get_last_open_dir()); diff --git a/ui/gtk/gui_utils.c b/ui/gtk/gui_utils.c index bb6487f013..72c22a0733 100644 --- a/ui/gtk/gui_utils.c +++ b/ui/gtk/gui_utils.c @@ -578,6 +578,30 @@ GtkWidget *pixbuf_to_widget(const char * pb_data) { return gtk_image_new_from_pixbuf(pixbuf); } +/* + * Alert box for an invalid display filter expression. + * Assumes "dfilter_error_msg" has been set by "dfilter_compile()" to the + * error message for the filter. + * + * XXX - should this have a "Help" button that pops up the display filter + * help? + */ +void +bad_dfilter_alert_box_modal(GtkWidget *parent, const char *dftext) +{ + GtkWidget *msg_dialog; + + msg_dialog = gtk_message_dialog_new(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "The filter expression \"%s\" isn't a valid display filter. (%s)", + dftext, dfilter_error_msg); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msg_dialog), + "See the help for a description of the display filter syntax."); + gtk_dialog_run(GTK_DIALOG(msg_dialog)); + gtk_widget_destroy(msg_dialog); +} /* update the main window */ void main_window_update(void) diff --git a/ui/gtk/gui_utils.h b/ui/gtk/gui_utils.h index 79fa7b6ce4..5669a0fc65 100644 --- a/ui/gtk/gui_utils.h +++ b/ui/gtk/gui_utils.h @@ -167,6 +167,7 @@ extern gboolean window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpoi * @todo if main uses the window_new_with_geom() to save size and such, make this function static */ extern void window_get_geometry(GtkWidget *win, window_geometry_t *geom); + /** Set the geometry of a window. * * @param win the window from window_new() @@ -187,6 +188,15 @@ extern void reactivate_window(GtkWidget *win); /** @} */ +/** Alert box for an invalid display filter expression. + * Assumes "dfilter_error_msg" has been set by "dfilter_compile()" to the + * error message for the filter. + * + * @param parent parent window from which the display filter came + * @param dftext text of the display filter + */ +extern void bad_dfilter_alert_box_modal(GtkWidget *parent, const char *dftext); + /** Create a GtkScrolledWindow, set its scrollbar placement appropriately, * and remember it. * |