[PATCH] Folder properties dialog



The attached patch (against current cvs HEAD) restores non-modal behavior to the folder-properties dialog, which is popped up by File - New - Remote IMAP Folder or Subfolder, and also Mailbox - Edit (or Properties... on the context menu) with an IMAP mailbox selected.

But...it uses a strategy (destroying a dialog window in its "response" signal-handler) that might cause problems with some versions of the Gtk libs; I've tested it with 2.4.0 (FC2), but I'd be grateful if it could be tested on other versions.

Thanks!

Peter
Index: src/folder-conf.c
===================================================================
RCS file: /cvs/gnome/balsa/src/folder-conf.c,v
retrieving revision 1.47
diff -u -r1.47 folder-conf.c
--- src/folder-conf.c	21 Jul 2004 14:23:01 -0000	1.47
+++ src/folder-conf.c	21 Jul 2004 20:48:00 -0000
@@ -88,6 +88,12 @@
 {
     GError *err = NULL;
 
+    /* If mbnode's parent gets rescanned, mbnode will be finalized,
+     * which triggers folder_conf_destroy_cdd, and recursively calls
+     * folder_conf_response, which results in cdd being freed before
+     * we're done with it; we ref mbnode to avoid that. */
+    if (cdd->mbnode)
+	g_object_ref(cdd->mbnode);
     switch (response) {
     case GTK_RESPONSE_HELP:
         gnome_help_display("balsa", folder_config_section, &err);
@@ -97,11 +103,28 @@
                     err->message);
             g_error_free(err);
         }
+	if (cdd->mbnode)
+	    g_object_unref(cdd->mbnode);
         return;
     case GTK_RESPONSE_OK:
         cdd->ok(cdd);
         /* Fall over */
     default:
+        gtk_widget_destroy(GTK_WIDGET(cdd->dialog));
+        cdd->dialog = NULL;
+        if (cdd->mbnode) {
+            /* Clearing the data signifies that the dialog has been
+             * destroyed. It also triggers a call to
+             * folder_conf_destroy_cdd, which will free cdd, so we cache
+             * cdd->mbnode. */
+	    BalsaMailboxNode *mbnode = cdd->mbnode;
+            g_object_set_data(G_OBJECT(mbnode),
+                              BALSA_FOLDER_CONF_IMAP_KEY, NULL);
+	    g_object_unref(mbnode);
+	} else
+            /* Cancelling, without creating a mailbox node. Nobody owns
+             * the xDialogData, so we'll free it here. */
+            g_free(cdd);
         break;
     }
 }
@@ -131,20 +154,6 @@
 }
 
 static void
-folder_cleanup_key(GObject *dialog, BalsaMailboxNode *mn)
-{
-    CommonDialogData *cdd = 
-        g_object_get_data(G_OBJECT(mn),
-                          BALSA_FOLDER_CONF_IMAP_KEY);
-    if(cdd) {
-        cdd->dialog = NULL; /* dialog has already been destroyed */
-        /* set data will call folder_conf_destroy_cdd(cdd); */
-        g_object_set_data(G_OBJECT(mn),
-                          BALSA_FOLDER_CONF_IMAP_KEY, NULL);
-    }
-}
-
-static void
 folder_conf_clicked_ok(FolderDialogData * fcw)
 {
     gboolean insert;
@@ -177,10 +186,10 @@
 
     if (!fcw->mbnode) {
         fcw->mbnode = balsa_mailbox_node_new_imap_folder(s, NULL);
+	/* mbnode will be unrefed in folder_conf_response. */
+	g_object_ref(fcw->mbnode);
         /* The mailbox node takes over ownership of the
          * FolderDialogData. */
-        g_signal_connect(G_OBJECT(fcw->dialog), "destroy",
-                         (GCallback)folder_cleanup_key, fcw->mbnode);
         g_object_set_data_full(G_OBJECT(fcw->mbnode),
                                BALSA_FOLDER_CONF_IMAP_KEY, fcw,
                                (GDestroyNotify) folder_conf_destroy_cdd);
@@ -219,7 +228,6 @@
     static FolderDialogData *fcw_new;
     LibBalsaServer *s;
     gchar *default_server;
-    int response;
 
     /* Allow only one dialog per mailbox node, and one with mn == NULL
      * for creating a new folder. */
@@ -246,8 +254,6 @@
     gtk_window_set_wmclass(GTK_WINDOW(fcw->dialog), 
 			   "folder_config_dialog", "Balsa");
     if (mn) {
-        g_signal_connect(G_OBJECT(fcw->dialog), "destroy",
-                         (GCallback)folder_cleanup_key, mn);
         g_object_set_data_full(G_OBJECT(mn),
                                BALSA_FOLDER_CONF_IMAP_KEY, fcw, 
                                (GDestroyNotify) folder_conf_destroy_cdd);
@@ -317,12 +323,9 @@
                                     : GTK_RESPONSE_CANCEL);
     gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
 
-    do {
-        folder_conf_response(fcw->dialog, 
-                             response = gtk_dialog_run(fcw->dialog),
-                             (CommonDialogData*)fcw);
-    } while(response == GTK_RESPONSE_HELP);
-    gtk_widget_destroy(GTK_WIDGET(fcw->dialog));
+    g_signal_connect(G_OBJECT(fcw->dialog), "response",
+                     G_CALLBACK(folder_conf_response), fcw);
+    gtk_widget_show_all(GTK_WIDGET(fcw->dialog));
 }
 
 /* folder_conf_imap_sub_node:
@@ -402,6 +405,7 @@
     }
 
     gtk_widget_set_sensitive(bbd->button, TRUE);
+    gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
 static gboolean
@@ -493,11 +497,9 @@
     gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
                                       GTK_RESPONSE_OK, FALSE);
 
+    g_signal_connect(G_OBJECT(dialog), "response",
+                     G_CALLBACK(browse_button_response), bbd);
     gtk_widget_show_all(GTK_WIDGET(dialog));
-    browse_button_response(GTK_DIALOG(dialog),
-                           gtk_dialog_run(GTK_DIALOG(dialog)),
-                           bbd);
-    gtk_widget_destroy(dialog);
 }
 
 static void
@@ -617,7 +619,6 @@
     GtkWidget *frame, *table, *subtable, *button, *label;
     SubfolderDialogData *sdd;
     static SubfolderDialogData *sdd_new = NULL;
-    int response;
 
     /* Allow only one dialog per mailbox node, and one with mn == NULL
      * for creating a new subfolder. */
@@ -663,8 +664,6 @@
 			   "subfolder_config_dialog", "Balsa");
 
     if (sdd->mbnode) {
-        g_signal_connect(G_OBJECT(sdd->dialog), "destroy",
-                         (GCallback)folder_cleanup_key, sdd->mbnode);
         g_object_set_data_full(G_OBJECT(sdd->mbnode),
                                BALSA_FOLDER_CONF_IMAP_KEY, sdd, 
                                (GDestroyNotify) folder_conf_destroy_cdd);
@@ -711,12 +710,9 @@
     validate_sub_folder(NULL, sdd);
     gtk_widget_grab_focus(sdd->folder_name);
 
-    do {
-        folder_conf_response(sdd->dialog, 
-                             response = gtk_dialog_run(sdd->dialog),
-                             (CommonDialogData*)sdd);
-    } while(response == GTK_RESPONSE_HELP);
-    gtk_widget_destroy(GTK_WIDGET(sdd->dialog));
+    g_signal_connect(G_OBJECT(sdd->dialog), "response",
+                     G_CALLBACK(folder_conf_response), sdd);
+    gtk_widget_show_all(GTK_WIDGET(sdd->dialog));
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]