Use file_selection_run() for dialogs created with file_selection_new().
authorGuy Harris <guy@alum.mit.edu>
Wed, 15 May 2013 22:03:14 +0000 (22:03 -0000)
committerGuy Harris <guy@alum.mit.edu>
Wed, 15 May 2013 22:03:14 +0000 (22:03 -0000)
svn path=/trunk/; revision=49320

ui/gtk/export_object_dlg.c
ui/gtk/export_sslkeys.c
ui/gtk/firewall_dlg.c
ui/gtk/follow_stream.c
ui/gtk/follow_stream.h
ui/gtk/packet_panes.c

index 9cc8a855e7f7f4c861789234748b081dae232d1f..8d0051bff00c8476cb53882d8054595f2ddbe960 100644 (file)
@@ -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
index 67a9db992431ad1af437bda965c0dcbb8aa6b5ba..57f4fc6a233d5e1d845203c3d87d8e3b628b33d4 100644 (file)
 #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
index 167751f3e62234c37e296e68bce2dc24749fc2c4..cfa83a0a2cd4aa32c85688ca463d175525e7088c 100644 (file)
@@ -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);
+    }
 }
index f6c7905a7e3fef6403fa1ac54e0e360bdd9e8e53..2537cb4b591dc4b368d36fd8823ca3d6c71c2344 100644 (file)
@@ -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
index f41ea2405a473c350abc7f45b105dc23c004bf39..5636438359f75138ec210aa8f2c6f6e06cfef2f1 100644 (file)
@@ -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;
index 2c1f18fd4a7c9e339049c5f93c14e8602e683ac3..7e760b6b037652a946116d84f7a94ab6dbd4ef15 100644 (file)
@@ -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