diff options
author | Guy Harris <guy@alum.mit.edu> | 2013-05-15 22:03:14 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2013-05-15 22:03:14 +0000 |
commit | b658db4ba21bf6437ba40f2993834d1762555bb0 (patch) | |
tree | 469cb03b83cbe94cf51005d7a2b3f19a128ed365 | |
parent | 6cc09403059f7eb09c0d503326f1a9513f5b6104 (diff) |
Use file_selection_run() for dialogs created with file_selection_new().
svn path=/trunk/; revision=49320
-rw-r--r-- | ui/gtk/export_object_dlg.c | 57 | ||||
-rw-r--r-- | ui/gtk/export_sslkeys.c | 136 | ||||
-rw-r--r-- | ui/gtk/firewall_dlg.c | 142 | ||||
-rw-r--r-- | ui/gtk/follow_stream.c | 131 | ||||
-rw-r--r-- | ui/gtk/follow_stream.h | 1 | ||||
-rw-r--r-- | ui/gtk/packet_panes.c | 168 |
6 files changed, 243 insertions, 392 deletions
diff --git a/ui/gtk/export_object_dlg.c b/ui/gtk/export_object_dlg.c index 9cc8a855e7..8d0051bff0 100644 --- a/ui/gtk/export_object_dlg.c +++ b/ui/gtk/export_object_dlg.c @@ -152,14 +152,37 @@ guint nparts,i; return saveable_pathname; } +static char * +gtk_eo_save_object_as_file(export_object_list_t *object_list, char *auxfilename) +{ + GtkWidget *save_as_w; + char *pathname; + + save_as_w = file_selection_new("Wireshark: Save Object As ...", + GTK_WINDOW(object_list->dlg), + FILE_SELECTION_SAVE); + + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w), + auxfilename); + pathname = file_selection_run(save_as_w); + if (pathname == NULL) { + /* User cancelled or closed the dialog. */ + return NULL; + } + + /* We've crosed the Rubicon; get rid of the dialog box. */ + window_destroy(save_as_w); + + return pathname; +} + static void eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) { - GtkWidget *save_as_w; export_object_list_t *object_list = (export_object_list_t *)arg; export_object_entry_t *entry; - gchar *filename = NULL; gchar *auxfilename = NULL; + char *pathname; entry =(export_object_entry_t *) g_slist_nth_data(object_list->entries, object_list->row_selected); @@ -169,24 +192,28 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) return; } - save_as_w = file_selection_new("Wireshark: Save Object As ...", - GTK_WINDOW(object_list->dlg), - FILE_SELECTION_SAVE); - auxfilename = eo_saveable_pathname(entry->filename); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w), - auxfilename); - - - if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT) { - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)); - eo_save_entry(filename, entry, TRUE); + /* + * Loop until the user either selects a file or gives up. + */ + for (;;) { + pathname = gtk_eo_save_object_as_file(object_list, auxfilename); + if (pathname == NULL) { + /* User gave up. */ + break; + } + if (eo_save_entry(pathname, entry, TRUE)) { + /* We succeeded. */ + g_free(pathname); + break; + } + /* Dump failed; let the user select another file + or give up. */ + g_free(pathname); } g_free(auxfilename); - g_free(filename); - window_destroy(save_as_w); } #define MAXFILELEN 255 diff --git a/ui/gtk/export_sslkeys.c b/ui/gtk/export_sslkeys.c index 67a9db9924..57f4fc6a23 100644 --- a/ui/gtk/export_sslkeys.c +++ b/ui/gtk/export_sslkeys.c @@ -78,54 +78,16 @@ #include "ui/win32/file_dlg_win32.h" #endif -static GtkWidget *savesslkeys_dlg=NULL; - -static void -savesslkeys_dlg_destroy_cb(GtkWidget *w _U_, gpointer user_data _U_) -{ - savesslkeys_dlg = NULL; -} - /* save the SSL Session Keys */ static gboolean -savesslkeys_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_) +savesslkeys_save_clicked_cb(char *file, gchar *keylist) { int fd; - char *file; - gchar *keylist; - - file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(savesslkeys_dlg)); - - if (test_for_directory(file) == EISDIR) { - /* It's a directory - set the file selection box to display that - directory, and leave the selection box displayed. */ - set_last_open_dir(file); - g_free(file); - file_selection_set_current_folder(savesslkeys_dlg, get_last_open_dir()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(savesslkeys_dlg), ""); - return FALSE; /* do gtk_dialog_run again */ - } - - /* XXX: Must check if file name exists first */ - - if (ssl_session_key_count() < 1) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "No SSL Session Keys to export."); - g_free(file); - return TRUE; - } - - /* - * Retrieve the info we need - */ - keylist = ssl_export_sessions(); fd = ws_open(file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); if (fd == -1) { open_failure_alert_box(file, errno, TRUE); - g_free(keylist); - g_free(file); - return TRUE; + return FALSE; } /* * Thanks, Microsoft, for not using size_t for the third argument to @@ -134,20 +96,14 @@ savesslkeys_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_) if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) { write_failure_alert_box(file, errno); ws_close(fd); - g_free(keylist); - g_free(file); - return TRUE; + return FALSE; } if (ws_close(fd) < 0) { write_failure_alert_box(file, errno); - g_free(keylist); - g_free(file); - return TRUE; + return FALSE; } - /* Get rid of the dialog box */ g_free(keylist); - g_free(file); return TRUE; } @@ -161,21 +117,13 @@ savesslkeys_cb(GtkWidget * w _U_, gpointer data _U_) return; } #else -void -savesslkeys_cb(GtkWidget * w _U_, gpointer data _U_) +static char * +gtk_export_sslkeys_file(guint keylist_len) { + GtkWidget *savesslkeys_dlg; gchar *label; - GtkWidget *dlg_lb; - guint keylist_len; - - keylist_len = ssl_session_key_count(); - /* don't show up the dialog, if no data has to be saved */ - if (keylist_len==0) { - /* shouldn't happen as the menu item should have been greyed out */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "There are no SSL Session Keys to save."); - return; - } - + GtkWidget *dlg_lb; + char *pathname; /* * Build the dialog box we need. @@ -192,26 +140,54 @@ savesslkeys_cb(GtkWidget * w _U_, gpointer data _U_) file_selection_set_extra_widget(savesslkeys_dlg, dlg_lb); gtk_widget_show(dlg_lb); - g_signal_connect(savesslkeys_dlg, "destroy", G_CALLBACK(savesslkeys_dlg_destroy_cb), NULL); - - /* "Run" the GtkFileChooserDialog. */ - /* Upon exit: If "Accept" run the OK callback. */ - /* If the OK callback returns with a FALSE status, re-run the dialog.*/ - /* If not accept (ie: cancel) destroy the window. */ - /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must* */ - /* return with a TRUE status so that the dialog window will be destroyed. */ - /* Trying to re-run the dialog after popping up an alert box will not work */ - /* since the user will not be able to dismiss the alert box. */ - /* The (somewhat unfriendly) effect: the user must re-invoke the */ - /* GtkFileChooserDialog whenever the OK callback pops up an alert box. */ - /* */ - /* ToDo: use GtkFileChooserWidget in a dialog window instead of */ - /* GtkFileChooserDialog. */ - while (gtk_dialog_run(GTK_DIALOG(savesslkeys_dlg)) == GTK_RESPONSE_ACCEPT) { - if (savesslkeys_save_clicked_cb(NULL, savesslkeys_dlg)) { - break; /* we're done */ - } + pathname = file_selection_run(savesslkeys_dlg); + if (pathname == NULL) { + /* User cancelled or closed the dialog. */ + return NULL; } + + /* We've crosed the Rubicon; get rid of the dialog box. */ window_destroy(savesslkeys_dlg); + + return pathname; +} + +void +savesslkeys_cb(GtkWidget * w _U_, gpointer data _U_) +{ + char *pathname; + guint keylist_len; + gchar *keylist; + + keylist_len = ssl_session_key_count(); + /* don't show up the dialog, if no data has to be saved */ + if (keylist_len==0) { + /* shouldn't happen as the menu item should have been greyed out */ + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "There are no SSL Session Keys to save."); + return; + } + + /* + * Retrieve the info we need + */ + keylist = ssl_export_sessions(); + + /* + * Loop until the user either selects a file or gives up. + */ + for (;;) { + pathname = gtk_export_sslkeys_file(keylist_len); + if (pathname == NULL) { + /* User gave up. */ + break; + } + if (savesslkeys_save_clicked_cb(pathname, keylist)) { + /* We succeeded. */ + g_free(pathname); + break; + } + /* Dump failed; let the user select another file or give up. */ + g_free(pathname); + } } #endif diff --git a/ui/gtk/firewall_dlg.c b/ui/gtk/firewall_dlg.c index 167751f3e6..cfa83a0a2c 100644 --- a/ui/gtk/firewall_dlg.c +++ b/ui/gtk/firewall_dlg.c @@ -99,7 +99,6 @@ typedef struct _rule_info_t { GtkWidget *filter_combo_box; GtkWidget *deny_cb; GtkWidget *inbound_cb; - GtkWidget *firewall_save_as_w; gboolean inbound; gboolean deny; rule_type_t rule_type; @@ -172,8 +171,6 @@ static void set_rule_text(rule_info_t *rule_info); static void firewall_destroy_cb(GtkWidget * win, gpointer data); static void firewall_copy_cmd_cb(GtkWidget * w, gpointer data); static void firewall_save_as_cmd_cb(GtkWidget * w, gpointer data); -static gboolean firewall_save_as_ok_cb(GtkWidget * w, gpointer fs); -static void firewall_save_as_destroy_cb(GtkWidget * win, gpointer user_data); #define WS_RULE_INFO_KEY "rule_info_key" @@ -195,7 +192,7 @@ firewall_rule_cb(GtkWidget *w _U_, gpointer data _U_) GtkWidget *rule_w, *vbox, *txt_scrollw, *text; GtkWidget *label, *product_combo_box; GtkWidget *hbox, *button_hbox, *button; - rule_info_t *rule_info; + rule_info_t *rule_info; packet_info *pinfo = &cfile.edt->pi; guint i; @@ -652,7 +649,7 @@ firewall_destroy_cb(GtkWidget *w, gpointer data _U_) forget_rule_info(rule_info); #endif g_free(rule_info); - gtk_widget_destroy(w); + gtk_widget_destroy(w); } static void @@ -670,91 +667,20 @@ firewall_copy_cmd_cb(GtkWidget *w _U_, gpointer data) gtk_text_buffer_copy_clipboard(buf, gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); } -/* - * Keep a static pointer to the current "Save SSL Follow Stream As" window, if - * any, so that if somebody tries to do "Save" - * while there's already a "Save SSL Follow Stream" window up, we just pop - * up the existing one, rather than creating a new one. - */ -static void -firewall_save_as_cmd_cb(GtkWidget *w _U_, gpointer data) -{ - GtkWidget *caller = gtk_widget_get_toplevel(w); - GtkWidget *new_win; - rule_info_t *rule_info = (rule_info_t *)data; - - new_win = file_selection_new("Wireshark: Save Firewall ACL Rule", - GTK_WINDOW(caller), - FILE_SELECTION_SAVE); - rule_info->firewall_save_as_w = new_win; - - /* Tuck away the rule_info object into the window */ - g_object_set_data(G_OBJECT(new_win), WS_RULE_INFO_KEY, rule_info); - - g_signal_connect(new_win, "destroy", G_CALLBACK(firewall_save_as_destroy_cb), rule_info); - -#if 0 - if (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT) - { - firewall_save_as_ok_cb(new_win, new_win); - } else { - window_destroy(new_win); - } -#else - /* "Run" the GtkFileChooserDialog. */ - /* Upon exit: If "Accept" run the OK callback. */ - /* If the OK callback returns with a FALSE status, re-run the dialog.*/ - /* If not accept (ie: cancel) destroy the window. */ - /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must* */ - /* return with a TRUE status so that the dialog window will be destroyed. */ - /* Trying to re-run the dialog after popping up an alert box will not work */ - /* since the user will not be able to dismiss the alert box. */ - /* The (somewhat unfriendly) effect: the user must re-invoke the */ - /* GtkFileChooserDialog whenever the OK callback pops up an alert box. */ - /* */ - /* ToDo: use GtkFileChooserWidget in a dialog window instead of */ - /* GtkFileChooserDialog. */ - while (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT) { - if (firewall_save_as_ok_cb(NULL, new_win)) { - break; /* we're done */ - } - } - window_destroy(new_win); -#endif -} - - static gboolean -firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs) +firewall_save_as_ok_cb(char *to_name, rule_info_t *rule_info) { - gchar *to_name, *rule; - rule_info_t *rule_info; FILE *fh; - gchar *dirname; + gchar *rule; GtkTextIter start, end; GtkTextBuffer *buf; - to_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); - - /* Perhaps the user specified a directory instead of a file. - Check whether they did. */ - if (test_for_directory(to_name) == EISDIR) { - /* It's a directory - set the file selection box to display that - directory, and leave the selection box displayed. */ - set_last_open_dir(to_name); - g_free(to_name); - file_selection_set_current_folder((GtkWidget *)fs, get_last_open_dir()); - gtk_file_chooser_set_current_name((GtkFileChooser *)fs, ""); - return FALSE; /* run the dialog again */ - } - - rule_info = (rule_info_t *)g_object_get_data(G_OBJECT(fs), WS_RULE_INFO_KEY); fh = ws_fopen(to_name, "w"); if (fh == NULL) { open_failure_alert_box(to_name, errno, TRUE); g_free(to_name); - return TRUE; + return FALSE; } buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text)); @@ -765,23 +691,53 @@ firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs) fputs(rule, fh); fclose(fh); -#if 0 /* handled by caller (for now) */ - gtk_widget_hide(GTK_WIDGET(fs)); - window_destroy(GTK_WIDGET(fs)); -#endif - /* Save the directory name for future file dialogs. */ - dirname = get_dirname(to_name); /* Overwrites to_name */ - set_last_open_dir(dirname); - g_free(to_name); - return TRUE; } -static void -firewall_save_as_destroy_cb(GtkWidget * win _U_, gpointer data) +static char * +gtk_firewall_save_as_file(GtkWidget *caller) { - rule_info_t *rule_info = (rule_info_t *)data; + GtkWidget *new_win; + char *pathname; + + new_win = file_selection_new("Wireshark: Save Firewall ACL Rule", + GTK_WINDOW(caller), + FILE_SELECTION_SAVE); - /* Note that we no longer have a dialog box. */ - rule_info->firewall_save_as_w = NULL; + pathname = file_selection_run(new_win); + if (pathname == NULL) { + /* User cancelled or closed the dialog. */ + return NULL; + } + + /* We've crosed the Rubicon; get rid of the dialog box. */ + window_destroy(new_win); + + return pathname; +} + +static void +firewall_save_as_cmd_cb(GtkWidget *w, gpointer data) +{ + GtkWidget *caller = gtk_widget_get_toplevel(w); + rule_info_t *rule_info = (rule_info_t *)data; + char *pathname; + + /* + * Loop until the user either selects a file or gives up. + */ + for (;;) { + pathname = gtk_firewall_save_as_file(caller); + if (pathname == NULL) { + /* User gave up. */ + break; + } + if (firewall_save_as_ok_cb(pathname, rule_info)) { + /* We succeeded. */ + g_free(pathname); + break; + } + /* Dump failed; let the user select another file or give up. */ + g_free(pathname); + } } diff --git a/ui/gtk/follow_stream.c b/ui/gtk/follow_stream.c index f6c7905a7e..2537cb4b59 100644 --- a/ui/gtk/follow_stream.c +++ b/ui/gtk/follow_stream.c @@ -73,9 +73,7 @@ static GtkTextTag *server_tag, *client_tag; static void follow_find_destroy_cb(GtkWidget * win _U_, gpointer data); static void follow_find_button_cb(GtkWidget * w, gpointer data); -static gboolean follow_save_as_ok_cb(GtkWidget * w _U_, gpointer fs); static void follow_destroy_cb(GtkWidget *w, gpointer data _U_); -static void follow_save_as_destroy_cb(GtkWidget * win _U_, gpointer data); GList *follow_infos = NULL; @@ -516,85 +514,32 @@ follow_print_stream(GtkWidget * w _U_, gpointer data) #endif } -/* - * Keep a static pointer to the current "Save Follow Stream As" window, if - * any, so that if somebody tries to do "Save" - * while there's already a "Save Follow Stream" window up, we just pop - * up the existing one, rather than creating a new one. - */ - -static void -follow_save_as_cmd_cb(GtkWidget *w, gpointer data) +static char * +gtk_follow_save_as_file(GtkWidget *caller) { - GtkWidget *caller = gtk_widget_get_toplevel(w); GtkWidget *new_win; - follow_info_t *follow_info = (follow_info_t *)data; + char *pathname; new_win = file_selection_new("Wireshark: Save Follow Stream As", GTK_WINDOW(caller), FILE_SELECTION_SAVE); - follow_info->follow_save_as_w = new_win; - - /* Tuck away the follow_info object into the window */ - g_object_set_data(G_OBJECT(new_win), E_FOLLOW_INFO_KEY, follow_info); - - g_signal_connect(new_win, "destroy", G_CALLBACK(follow_save_as_destroy_cb), - follow_info); - -#if 0 - if (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT) - { - follow_save_as_ok_cb(new_win, new_win); - } else { - window_destroy(new_win); - } -#endif - /* "Run" the GtkFileChooserDialog. */ - /* Upon exit: If "Accept" run the OK callback. */ - /* If the OK callback returns with a FALSE status, re-run the dialog.*/ - /* If not accept (ie: cancel) destroy the window. */ - /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must* */ - /* return with a TRUE status so that the dialog window will be destroyed. */ - /* Trying to re-run the dialog after popping up an alert box will not work */ - /* since the user will not be able to dismiss the alert box. */ - /* The (somewhat unfriendly) effect: the user must re-invoke the */ - /* GtkFileChooserDialog whenever the OK callback pops up an alert box. */ - /* */ - /* ToDo: use GtkFileChooserWidget in a dialog window instead of */ - /* GtkFileChooserDialog. */ - while (gtk_dialog_run(GTK_DIALOG(new_win)) == GTK_RESPONSE_ACCEPT) { - if (follow_save_as_ok_cb(NULL, new_win)) { - break; /* we're done */ - } + pathname = file_selection_run(new_win); + if (pathname == NULL) { + /* User cancelled or closed the dialog. */ + return NULL; } + + /* We've crosed the Rubicon; get rid of the dialog box. */ window_destroy(new_win); -} + return pathname; +} static gboolean -follow_save_as_ok_cb(GtkWidget * w _U_, gpointer fs) +follow_save_as_ok_cb(gchar *to_name, follow_info_t *follow_info) { - gchar *to_name; - follow_info_t *follow_info; FILE *fh; - print_stream_t *stream = NULL; - gchar *dirname; - - to_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); - - /* Perhaps the user specified a directory instead of a file. - Check whether they did. */ - if (test_for_directory(to_name) == EISDIR) { - /* It's a directory - set the file selection box to display that - directory, and leave the selection box displayed. */ - set_last_open_dir(to_name); - g_free(to_name); - file_selection_set_current_folder((GtkWidget *)fs, get_last_open_dir()); - gtk_file_chooser_set_current_name((GtkFileChooser *)fs, ""); - return FALSE; /* do gtk_dialog_run again */ - } - - follow_info = (follow_info_t *)g_object_get_data(G_OBJECT(fs), E_FOLLOW_INFO_KEY); + print_stream_t *stream; if (follow_info->show_type == SHOW_RAW) { /* Write the data out as raw binary data */ @@ -605,66 +550,78 @@ follow_save_as_ok_cb(GtkWidget * w _U_, gpointer fs) } if (fh == NULL) { open_failure_alert_box(to_name, errno, TRUE); - g_free(to_name); - return TRUE; + return FALSE; } -#if 0 /* handled by caller (for now) .... */ - gtk_widget_hide(GTK_WIDGET(fs)); - window_destroy(GTK_WIDGET(fs)); -#endif if (follow_info->show_type == SHOW_RAW) { switch (follow_read_stream(follow_info, follow_write_raw, fh)) { case FRS_OK: - if (fclose(fh) == EOF) + if (fclose(fh) == EOF) { write_failure_alert_box(to_name, errno); + return FALSE; + } break; case FRS_OPEN_ERROR: case FRS_READ_ERROR: fclose(fh); - break; + return FALSE; case FRS_PRINT_ERROR: write_failure_alert_box(to_name, errno); fclose(fh); - break; + return FALSE; } } else { stream = print_stream_text_stdio_new(fh); switch (follow_read_stream(follow_info, follow_print_text, stream)) { case FRS_OK: - if (!destroy_print_stream(stream)) + if (!destroy_print_stream(stream)) { write_failure_alert_box(to_name, errno); + return FALSE; + } break; case FRS_OPEN_ERROR: case FRS_READ_ERROR: destroy_print_stream(stream); - break; + return FALSE; case FRS_PRINT_ERROR: write_failure_alert_box(to_name, errno); destroy_print_stream(stream); - break; + return FALSE; } } - /* Save the directory name for future file dialogs. */ - dirname = get_dirname(to_name); /* Overwrites to_name */ - set_last_open_dir(dirname); - g_free(to_name); return TRUE; } static void -follow_save_as_destroy_cb(GtkWidget * win _U_, gpointer data) +follow_save_as_cmd_cb(GtkWidget *w, gpointer data) { + GtkWidget *caller = gtk_widget_get_toplevel(w); follow_info_t *follow_info = (follow_info_t *)data; + char *pathname; - /* Note that we no longer have a dialog box. */ - follow_info->follow_save_as_w = NULL; + /* + * Loop until the user either selects a file or gives up. + */ + for (;;) { + pathname = gtk_follow_save_as_file(caller); + if (pathname == NULL) { + /* User gave up. */ + break; + } + if (follow_save_as_ok_cb(pathname, follow_info)) { + /* We succeeded. */ + g_free(pathname); + break; + } + /* Dump failed; let the user select another file or give up. */ + g_free(pathname); + } } static void diff --git a/ui/gtk/follow_stream.h b/ui/gtk/follow_stream.h index f41ea2405a..5636438359 100644 --- a/ui/gtk/follow_stream.h +++ b/ui/gtk/follow_stream.h @@ -74,7 +74,6 @@ typedef struct { GtkWidget *hexdump_bt; GtkWidget *carray_bt; GtkWidget *raw_bt; - GtkWidget *follow_save_as_w; GtkWidget *find_dlg_w; gboolean is_ipv6; char *filter_out_filter; diff --git a/ui/gtk/packet_panes.c b/ui/gtk/packet_panes.c index 2c1f18fd4a..7e760b6b03 100644 --- a/ui/gtk/packet_panes.c +++ b/ui/gtk/packet_panes.c @@ -523,17 +523,6 @@ add_byte_views(epan_dissect_t *edt, GtkWidget *tree_view, gtk_notebook_set_current_page(GTK_NOTEBOOK(byte_nb_ptr), 0); } - - -static GtkWidget *savehex_dlg=NULL; - -static void -savehex_dlg_destroy_cb(GtkWidget *w _U_, gpointer user_data _U_) -{ - savehex_dlg = NULL; -} - - static void copy_hex_all_info(GString* copy_buffer, const guint8* data_p, int data_len, gboolean append_text) { @@ -706,79 +695,25 @@ copy_hex_cb(GtkWidget * w _U_, gpointer data _U_, copy_data_type data_type) /* save the current highlighted hex data */ static gboolean -savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_) +savehex_save_clicked_cb(gchar *file, int start, int end, const guint8 *data_p) { - GtkWidget *bv; - int fd, start, end; - guint len; - const guint8 *data_p = NULL; - char *file; - - file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(savehex_dlg)); - -#if 0 /* Not req'd: GtkFileChooserWidget currently being used won't return with a Null filename */ - if (!file ||! *file) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please enter a filename."); - g_free(file); - return TRUE; - } -#endif - if (test_for_directory(file) == EISDIR) { - /* It's a directory - set the file selection box to display that - directory, and leave the selection box displayed. */ - set_last_open_dir(file); - g_free(file); - file_selection_set_current_folder(savehex_dlg, get_last_open_dir()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(savehex_dlg), ""); - return FALSE; /* do gtk_dialog_run again */ - } - - /* XXX: Must check if file name exists first */ - - bv = get_notebook_bv_ptr(byte_nb_ptr_gbl); - if (bv == NULL) { - /* shouldn't happen */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window."); - g_free(file); - return TRUE; - } - /* - * Retrieve the info we need - */ - start = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(bv), E_BYTE_VIEW_START_KEY)); - end = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(bv), E_BYTE_VIEW_END_KEY)); - data_p = get_byte_view_data_and_length(bv, &len); - - if (data_p == NULL || start == -1 || start > end) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "No data selected to save."); - g_free(file); - return TRUE; - } + int fd; fd = ws_open(file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); if (fd == -1) { open_failure_alert_box(file, errno, TRUE); - g_free(file); - return TRUE; + return FALSE; } if (ws_write(fd, data_p + start, end - start) < 0) { write_failure_alert_box(file, errno); ws_close(fd); - g_free(file); - return TRUE; + return FALSE; } if (ws_close(fd) < 0) { write_failure_alert_box(file, errno); - g_free(file); - return TRUE; + return FALSE; } - /* Get rid of the dialog box */ - g_free(file); -#if 0 /* being handled by caller (for now) */ - window_destroy(GTK_WIDGET(savehex_dlg)); -#endif return TRUE; } @@ -791,15 +726,47 @@ savehex_cb(GtkWidget * w _U_, gpointer data _U_) return; } #else +static char * +gtk_export_raw_file(int start, int end) +{ + GtkWidget *savehex_dlg; + gchar *label; + GtkWidget *dlg_lb; + char *pathname; + + /* + * Build the dialog box we need. + */ + savehex_dlg = file_selection_new("Wireshark: Export Selected Packet Bytes", GTK_WINDOW(top_level), FILE_SELECTION_SAVE); + + /* label */ + label = g_strdup_printf("Will save %u %s of raw binary data to specified file.", + end - start, plurality(end - start, "byte", "bytes")); + dlg_lb = gtk_label_new(label); + g_free(label); + file_selection_set_extra_widget(savehex_dlg, dlg_lb); + gtk_widget_show(dlg_lb); + + pathname = file_selection_run(savehex_dlg); + if (pathname == NULL) { + /* User cancelled or closed the dialog. */ + return NULL; + } + + /* We've crosed the Rubicon; get rid of the dialog box. */ + window_destroy(savehex_dlg); + + return pathname; +} + void savehex_cb(GtkWidget * w _U_, gpointer data _U_) { int start, end; guint len; const guint8 *data_p = NULL; - gchar *label; GtkWidget *bv; - GtkWidget *dlg_lb; + char *pathname; /* don't show up the dialog, if no data has to be saved */ bv = get_notebook_bv_ptr(byte_nb_ptr_gbl); @@ -817,54 +784,23 @@ savehex_cb(GtkWidget * w _U_, gpointer data _U_) return; } -#if 0 /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */ - /* if the window is already open, bring it to front */ - if(savehex_dlg){ - reactivate_window(savehex_dlg); - return; - } -#endif /* - * Build the dialog box we need. + * Loop until the user either selects a file or gives up. */ - savehex_dlg = file_selection_new("Wireshark: Export Selected Packet Bytes", GTK_WINDOW(top_level), FILE_SELECTION_SAVE); - - /* label */ - label = g_strdup_printf("Will save %u %s of raw binary data to specified file.", - end - start, plurality(end - start, "byte", "bytes")); - dlg_lb = gtk_label_new(label); - g_free(label); - file_selection_set_extra_widget(savehex_dlg, dlg_lb); - gtk_widget_show(dlg_lb); - - g_signal_connect(savehex_dlg, "destroy", G_CALLBACK(savehex_dlg_destroy_cb), NULL); - -#if 0 - if (gtk_dialog_run(GTK_DIALOG(savehex_dlg)) == GTK_RESPONSE_ACCEPT) { - savehex_save_clicked_cb(savehex_dlg, savehex_dlg); - } else { - window_destroy(savehex_dlg); - } -#endif - /* "Run" the GtkFileChooserDialog. */ - /* Upon exit: If "Accept" run the OK callback. */ - /* If the OK callback returns with a FALSE status, re-run the dialog.*/ - /* If not accept (ie: cancel) destroy the window. */ - /* XXX: If the OK callback pops up an alert box (eg: for an error) it *must* */ - /* return with a TRUE status so that the dialog window will be destroyed. */ - /* Trying to re-run the dialog after popping up an alert box will not work */ - /* since the user will not be able to dismiss the alert box. */ - /* The (somewhat unfriendly) effect: the user must re-invoke the */ - /* GtkFileChooserDialog whenever the OK callback pops up an alert box. */ - /* */ - /* ToDo: use GtkFileChooserWidget in a dialog window instead of */ - /* GtkFileChooserDialog. */ - while (gtk_dialog_run(GTK_DIALOG(savehex_dlg)) == GTK_RESPONSE_ACCEPT) { - if (savehex_save_clicked_cb(NULL, savehex_dlg)) { - break; /* we're done */ + for (;;) { + pathname = gtk_export_raw_file(start, end); + if (pathname == NULL) { + /* User gave up. */ + break; } + if (savehex_save_clicked_cb(pathname, start, end, data_p)) { + /* We succeeded. */ + g_free(pathname); + break; + } + /* Dump failed; let the user select another file or give up. */ + g_free(pathname); } - window_destroy(savehex_dlg); } #endif |