io_stat save & filewall rule save: rework "save dialog" slightly:
authorwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 2 Jun 2009 19:16:08 +0000 (19:16 +0000)
committerwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 2 Jun 2009 19:16:08 +0000 (19:16 +0000)
     - Prevent "dead" save-as window if error opening/writing file
        or if a directory is entered as the filename;
        Work-around is to always kill save-as window whether success
         or an error causing alert-box popup;
     - Enable "check for file overwrite" (if GTK 2.8 or greater);
     - Fix some memory leaks.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@28608 f5534014-38df-0310-8fa8-9805f1628bb7

gtk/firewall_dlg.c
gtk/pixmap_save.c

index 7ff2b6657f16804b6210a720eeaedf7777fce884..64bb82e92edd056ca31704732cb92eb0fe5abf30 100644 (file)
@@ -181,7 +181,7 @@ 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 void firewall_save_as_ok_cb(GtkWidget * w, gpointer fs);
+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"
@@ -692,31 +692,57 @@ firewall_save_as_cmd_cb(GtkWidget *w _U_, gpointer data)
     GtkWidget          *new_win;
     rule_info_t        *rule_info = data;
 
+#if 0  /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */
     if (rule_info->firewall_save_as_w != NULL) {
        /* There's already a dialog box; reactivate it. */
        reactivate_window(rule_info->firewall_save_as_w);
        return;
     }
-
+#endif
     new_win = file_selection_new("Wireshark: Save Firewall ACL Rule",
                                  FILE_SELECTION_SAVE);
     rule_info->firewall_save_as_w = new_win;
+#if GTK_CHECK_VERSION(2,8,0)
+    gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(new_win), TRUE);
+#endif
 
     /* 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 void
+static gboolean
 firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs)
 {
     gchar      *to_name, *rule;
@@ -727,7 +753,7 @@ firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs)
     GtkTextIter start, end;
     GtkTextBuffer *buf;
 
-    to_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)));
+    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. */
@@ -737,7 +763,8 @@ firewall_save_as_ok_cb(GtkWidget * w _U_, gpointer fs)
         set_last_open_dir(to_name);
         g_free(to_name);
         file_selection_set_current_folder(fs, get_last_open_dir());
-        return;
+        gtk_file_chooser_set_current_name(fs, "");
+        return FALSE; /* run the dialog again */
     }
 
     rule_info = g_object_get_data(G_OBJECT(fs), WS_RULE_INFO_KEY);
@@ -745,7 +772,7 @@ firewall_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;
+        return TRUE;
     }
 
     buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(rule_info->text));
@@ -756,13 +783,16 @@ 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
index ec244941a252d84196239352ffa3fded4c33c916..a728df763eec944a80a091f5f7c75bd6dcb270c5 100644 (file)
@@ -51,7 +51,7 @@ pixbuf_save_destroy_cb(GtkWidget *window _U_, gpointer data _U_)
        save_as_w = NULL;
 }
 
-static void
+static gboolean
 pixbuf_save_button_cb(GtkWidget *save_as_w, GdkPixbuf *pixbuf)
 {
        gchar *filename, *file_type;
@@ -59,7 +59,7 @@ pixbuf_save_button_cb(GtkWidget *save_as_w, GdkPixbuf *pixbuf)
         GError *error = NULL;
        gboolean ret;
 
-       filename = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)));
+       filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w));
        type_cm = g_object_get_data(G_OBJECT(save_as_w), "type_cm");
        file_type = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_cm));
        
@@ -73,7 +73,8 @@ pixbuf_save_button_cb(GtkWidget *save_as_w, GdkPixbuf *pixbuf)
                g_free(file_type);
                file_selection_set_current_folder(save_as_w,
                                                  get_last_open_dir());
-               return;
+               gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w), "");
+               return FALSE;
        }
 
        ret = gdk_pixbuf_save(pixbuf, filename, file_type, &error, NULL);
@@ -89,6 +90,7 @@ pixbuf_save_button_cb(GtkWidget *save_as_w, GdkPixbuf *pixbuf)
                gtk_window_set_transient_for(GTK_WINDOW(simple_w),
                                             GTK_WINDOW(save_as_w));
        }
+       return TRUE;
 }
 
 void
@@ -112,14 +114,19 @@ pixmap_save_cb(GtkWidget *w, gpointer pixmap_ptr _U_)
                return;
        }
 
+#if 0  /* XXX: GtkFileChooserDialog/gtk_dialog_run currently being used is effectively modal so this is not req'd */
        if(save_as_w != NULL) {
                /* If this save as window is already open, re-open it */
                reactivate_window(save_as_w);
                return;
        }
+#endif
 
        save_as_w = file_selection_new("Wireshark: Save Graph As ...",
                                       FILE_SELECTION_SAVE);
+#if GTK_CHECK_VERSION(2,8,0)
+       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(save_as_w), TRUE);
+#endif
 
        /* Container for each row of widgets */
        main_vb = gtk_vbox_new(FALSE, 0);
@@ -161,10 +168,32 @@ pixmap_save_cb(GtkWidget *w, gpointer pixmap_ptr _U_)
        parent = gtk_widget_get_parent_window(w);
        gdk_window_set_transient_for(save_as_w->window, parent);
        
+#if 0
        if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT)
                pixbuf_save_button_cb(save_as_w, pixbuf);
 
        window_destroy(save_as_w);
+#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(save_as_w)) == GTK_RESPONSE_ACCEPT) {
+               if (pixbuf_save_button_cb(save_as_w, pixbuf)) {
+                    break; /* we're done */
+               }
+       }
+       window_destroy(save_as_w);
+#endif
 }
 
 #endif /* GTK_CHECK_VERSION(2,6,0) */