diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 113 | ||||
-rw-r--r-- | mail/component-factory.c | 220 | ||||
-rw-r--r-- | mail/folder-browser-factory.c | 8 | ||||
-rw-r--r-- | mail/folder-browser-factory.h | 3 | ||||
-rw-r--r-- | mail/folder-browser.c | 3 | ||||
-rw-r--r-- | mail/folder-browser.h | 2 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 163 | ||||
-rw-r--r-- | mail/mail-config-gui.c | 56 | ||||
-rw-r--r-- | mail/mail-config-gui.h | 6 | ||||
-rw-r--r-- | mail/mail-display.c | 37 | ||||
-rw-r--r-- | mail/mail-local.c | 4 | ||||
-rw-r--r-- | mail/mail-ops.c | 3 | ||||
-rw-r--r-- | mail/mail-threads.c | 90 | ||||
-rw-r--r-- | mail/mail-tools.c | 5 | ||||
-rw-r--r-- | mail/mail-tools.h | 1 | ||||
-rw-r--r-- | mail/mail.h | 16 | ||||
-rw-r--r-- | mail/session.c | 9 |
17 files changed, 512 insertions, 227 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index cfb4d1bbbf..b1f43688ba 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,116 @@ +2000-08-24 Peter Williams <peterw@helixcode.com> + + * component-factory.c (mail_load_storages): New function. + Loads a list of URI's as mail storages, and inserts them + into the shell's folder tree if appropriate (really, only + puts them into the folder tree.) + (mail_add_new_storage): Insert a storage into the folder + tree. Not always appropriate (eg, /var/spool/mail/user is + a storage that shouldn't be in the folder tree.) + (create_view): Generate the Evolution_Shell and pass it + to folder_browser_factor_new_control so that its member + 'shell' can be set. + (owner_set_cb): Instead of create_news_storage and + creating the imap storages, load the news storages and + mail storages via mail_load_storages(). + + * folder-browser-factory.c (control_activate): Change to + use providers_config again instead of mail_config. Pass + the folderbrowser so that the config code knows where + to insert the new storages if any are created. Pass + forget_passwords the folderbriwser, too, for good luck. + (folder_browser_factory_new_control): Take a new parameter, + the Evolution_Shell that we belong to. The field in + FolderBrowser has been there but was never getting set by + anything, and we need this to be able to insert new storages + into the shell's folder list. + + * folder-browser.c (folder_browser_new): Accept the + new Evolution_Shell parameter. Set it. (Should we + ref it or something?) + + * mail-config-gui.c (struct MailDruidDialog): Store an + Evolution_Shell. With this we can insert the stores into + the shell's folder list. + (struct MailDialog): Same. + (service_page_item_changed): Close a leak. + (identity_dialog): Unswitch the Add/Edit identity titles. + (news_dialog): Analogous to above. + (mail_druid_finish): Add the new mail source to the shell + view. + (mail_config_druid): Take a new Evolution_Shell parameter + for later use. + (mail_config_apply_clicked): Add all the mail sources to + the shell view. + (mail_config): Take a new Evolution_Shell parameter. + + * mail-callbacks.c (check_configured): Accept a FolderBrowser + so that we know where to put the new storages if any are + created. Almost all the callbacks are passed a FB * anyway + so this isn't a big deal. + (check_send_configuration): Make sure that we're configured + enough to be able to send mail. composer_send_cb() used to + do this, but it would need a FolderBrowser *, and there are + too many entry points to composer_send_cb to make this + feasible. + (fetch_mail): Pass the extra parm to check_configured(). + (free_psd): Move so that composer_send_cb can call this + directly. + (composer_send_cb): Don't check for proper configuration + here -- it is the caller's responsiblity to call + check_send_configuration(). Call free_psd() directly. + (compose_msg): Call check_send_configuration(). + (send_to_url): Same. This is called from mail-display.c, + though, and cannot reasonably be passed a FB. So: we can't + start up the config dialog directly; the user must do it + manually. Oh well. + (mail_reply): Same as above. + (forward_msg): Same as compose_msg(). + (edit_msg): Same as above. + (providers_config): Reenable so that we can pass mail_config + its FolderBrowser. + + * mail-display.c (write_data_to_file): Use the much more + straightforward run_and_close to retrieve the user's answer, + instead of the reply callback stuff. + + * mail-threads.c (mail_dialog_run): New wrapper for + gnome_dialog_run that will take care of the GDK lock correctly. + Far far more complicated than it should be. + (mail_dialog_run_and_close): Analogous to above. + (read_msg): Set inside_read_msg and unset it for the benefit + of the two above functions. Don't bracket ourselves in + GDK_THREADS_ENTER/_LEAVE anymore. + (mail_operation_queue): Use mail_dialog_run_and_close. + (show_error): As above. + (get_password): As above. + + * mail-display.c (write_data_to_file): This has the only + exception to the rule that "use mail_dialog_run(_and_close) + instead of the gnome equivalent always." Not quite sure why + it doesn't work here (the file selection window?). + + * mail-config-gui.c (identity_dialog): Change to + mail_dialog_run_and_close. + (source_dialog): Same as above. + (news_dialog): Same as above. + (cleanup_test_service): Same as above. + (mail_config): Change to mail_dialog_run(). + + * session.c (mail_request_dialog): Change to + mail_dialog_run_and_close. + + * mail-tools.c (mail_tool_uri_to_folder_noex): As above. + + * mail-ops.c (cleanup_fetch_mail): As above. + + * mail-local.c (local_reconfigure_folder): As above. + + * mail-callbacks.c (check_send_configuration): As above. + (ask_confirm_for_empty_subject): As above. + (edit_msg): As above. + (filter_edit): As above. + 2000-08-23 Dan Winship <danw@helixcode.com> * folder-browser-factory.c (control_activate): Reformat a bit, diff --git a/mail/component-factory.c b/mail/component-factory.c index eaabce8e38..47153ad530 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -46,9 +46,6 @@ CamelFolder *drafts_folder = NULL; char *evolution_dir; static void create_vfolder_storage (EvolutionShellComponent *shell_component); -static void create_imap_storage (EvolutionShellComponent *shell_component, - const char *source); -static void create_news_storage (EvolutionShellComponent *shell_component); #define COMPONENT_FACTORY_ID "OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" @@ -69,13 +66,18 @@ create_view (EvolutionShellComponent *shell_component, BonoboControl **control_return, void *closure) { + EvolutionShellClient *shell_client; + Evolution_Shell corba_shell; BonoboControl *control; GtkWidget *folder_browser_widget; if (g_strcasecmp (folder_type, "mail") != 0) return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; - control = folder_browser_factory_new_control (physical_uri); + shell_client = evolution_shell_component_get_owner (shell_component); + corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); + + control = folder_browser_factory_new_control (physical_uri, corba_shell); if (!control) return EVOLUTION_SHELL_COMPONENT_NOTFOUND; @@ -106,7 +108,7 @@ owner_set_cb (EvolutionShellComponent *shell_component, gpointer user_data) { GSList *sources; - MailConfigService *s; + Evolution_Shell corba_shell; g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */ @@ -115,15 +117,13 @@ owner_set_cb (EvolutionShellComponent *shell_component, mail_config_init (); mail_do_setup_draftbox (); create_vfolder_storage (shell_component); - create_news_storage (shell_component); + + corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); sources = mail_config_get_sources (); - while (sources) { - s = sources->data; - if (!g_strncasecmp (s->url, "imap:", 5)) - create_imap_storage (shell_component, s->url); - sources = sources->next; - } + mail_load_storages (corba_shell, sources); + sources = mail_config_get_news (); + mail_load_storages (corba_shell, sources); } static void @@ -198,79 +198,155 @@ create_vfolder_storage (EvolutionShellComponent *shell_component) vfolder_create_storage(shell_component); } -static void -create_imap_storage (EvolutionShellComponent *shell_component, - const char *source) +void +mail_load_storages (Evolution_Shell corba_shell, GSList *sources) { - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *server, *p; + CamelException ex; + GList *providers; + GSList *iter; + MailConfigService *svc; + GPtrArray *protos; + int i; + + camel_exception_init (&ex); + protos = g_ptr_array_new(); + + /* First, open all the storages so that camel + * loads only the providers that we're going + * to need. + * + * We don't open the storage per se but we + * slurp its protocol so that we don't try + * to connect to it just yet. + * + * We remember the protocol associated with + * each URI for the second pass. + */ - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); - return; + for (iter = sources; iter; iter = iter->next) { + CamelService *temp; + gchar *p; + gchar *proto; + + svc = (MailConfigService *) iter->data; + if (svc->url == NULL || svc->url[0] == '\0') + continue; + + p = strchr (svc->url, ':'); + if (!p || *p == '\0') { + g_warning ("Bad url (no protocol): %s", svc->url); + continue; + } + + p++; /* we're on the char after the colon */ + + proto = g_strndup (svc->url, p - svc->url); + g_ptr_array_add (protos, proto); + + temp = camel_session_get_service (session, proto, + CAMEL_PROVIDER_STORE, &ex); + if (temp == NULL) { + /* FIXME: real error dialog */ + + g_warning ("couldn't get service %s: %s\n", + svc->url, camel_exception_get_description (&ex)); + } else + camel_object_unref (CAMEL_OBJECT (temp)); } - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - if (!(server = strchr (source, '@'))) - return; - - server++; - for (p = server; *p && *p != '/'; p++); - - server = g_strndup (server, (gint)(p - server)); - - storage = evolution_storage_new (server); - g_free (server); - - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); - return; + + /* Okay. All the providers we need are loaded. + * Now get the list of them. + */ + + providers = camel_session_list_providers (session, FALSE); + + /* Now zip through the sources a second time. This time + * we check to see if its provider is a storage or not. + * If so, add it to the shell. + */ + + for (iter = sources, i = 0; iter; iter = iter->next, i++) { + CamelProvider *prov = NULL; + GList *prov_iter; + gchar *proto; + + svc = (MailConfigService *) iter->data; + + proto = g_ptr_array_index (protos, i); + + /* find its provider */ + for (prov_iter = providers; prov_iter; prov_iter = prov_iter->next) { + CamelProvider *thisone = (CamelProvider *) prov_iter->data; + + if (!g_strncasecmp (proto, thisone->protocol, strlen (thisone->protocol))) { + prov = thisone; + break; + } + } + + g_free (proto); + + if (prov == NULL) { + g_warning ("No provider for loaded URL \"%s\"?", svc->url); + continue; + } + + /* FIXME: this case is ambiguous for things like the mbox provider, + * which can really be a spool (/var/spool/mail/user) or a storage + * (~/mail/, eg). That issue can't be resolved on the provider + * level -- it's a per-URL problem. + */ + + if (prov->flags & CAMEL_PROVIDER_IS_STORAGE && prov->flags & CAMEL_PROVIDER_IS_REMOTE) { + mail_add_new_storage (svc->url, corba_shell, &ex); + + if (camel_exception_is_set (&ex)) { + /* FIXME: real error dialog */ + g_warning ("Cannot load storage: %s", + camel_exception_get_description (&ex)); + } + } } - - mail_do_scan_subfolders (source, storage); + + g_ptr_array_free (protos, TRUE); + camel_exception_clear (&ex); } -static void -create_news_storage (EvolutionShellComponent *shell_component) +void +mail_add_new_storage (const char *uri, Evolution_Shell corba_shell, CamelException *ex) { - const MailConfigService *s; - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; EvolutionStorage *storage; - char *source = NULL, *server, *p; - - s = mail_config_get_default_news (); - if (s) - source = s->url; + EvolutionStorageResult res; + CamelURL *url; + + g_return_if_fail (uri && uri[0] != '\0'); - if (!source || g_strncasecmp (source, "news://", 7)) + url = camel_url_new (uri, ex); + if (url == NULL) return; - - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); + + if (url->host == NULL) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + "Bad storage URL (no server): %s", + uri); return; } - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - server = source + 7; - for (p = server; *p && *p != '/'; p++); - - server = g_strndup (server, (gint)(p - server)); - - storage = evolution_storage_new (server); - g_free (server); - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); + storage = evolution_storage_new (url->host); + camel_url_free (url); + + res = evolution_storage_register_on_shell (storage, corba_shell); + + switch (res) { + case EVOLUTION_STORAGE_OK: + mail_do_scan_subfolders (uri, storage); + /* falllll */ + case EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED: + case EVOLUTION_STORAGE_ERROR_EXISTS: return; + default: + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, + "mail_tool_add_new_storage: Cannot register storage on shell"); + break; } - - mail_do_scan_subfolders (source, storage); } - diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index 99a95fc04a..6c4bd13bbd 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -159,12 +159,12 @@ control_activate (BonoboControl *control, BonoboUIHandler *uih, uih, "/Settings/Mail Configuration...", _("_Mail Configuration..."), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, NULL, 0, 0, - (void *) mail_config, NULL); + providers_config, folder_browser); bonobo_ui_handler_menu_new_item ( uih, "/Settings/Forget Passwords", _("Forget _Passwords"), NULL, -1, BONOBO_UI_HANDLER_PIXMAP_NONE, NULL, 0, 0, - forget_passwords, NULL); + forget_passwords, folder_browser); /* Message Menu */ bonobo_ui_handler_menu_new_subtree ( @@ -332,12 +332,12 @@ control_destroy_cb (BonoboControl *control, } BonoboControl * -folder_browser_factory_new_control (const char *uri) +folder_browser_factory_new_control (const char *uri, Evolution_Shell shell) { BonoboControl *control; GtkWidget *folder_browser; - folder_browser = folder_browser_new (); + folder_browser = folder_browser_new (shell); if (folder_browser == NULL) return NULL; diff --git a/mail/folder-browser-factory.h b/mail/folder-browser-factory.h index 7af5028ada..e4e26a83d7 100644 --- a/mail/folder-browser-factory.h +++ b/mail/folder-browser-factory.h @@ -12,8 +12,9 @@ #define _FOLDER_BROWSER_FACTORY_H #include <bonobo.h> +#include "Evolution.h" -BonoboControl *folder_browser_factory_new_control (const char *uri); +BonoboControl *folder_browser_factory_new_control (const char *uri, Evolution_Shell shell); GList *folder_browser_factory_get_control_list (void); #endif /* _FOLDER_BROWSER_FACTORY_H */ diff --git a/mail/folder-browser.c b/mail/folder-browser.c index 44da49e0e4..9932498c0b 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -430,7 +430,7 @@ my_folder_browser_init (GtkObject *object) } GtkWidget * -folder_browser_new (void) +folder_browser_new (Evolution_Shell shell) { static int serial; FolderBrowser *folder_browser = gtk_type_new (folder_browser_get_type ()); @@ -438,6 +438,7 @@ folder_browser_new (void) my_folder_browser_init (GTK_OBJECT (folder_browser)); folder_browser->uri = NULL; folder_browser->serial = serial++; + folder_browser->shell = shell; return GTK_WIDGET (folder_browser); } diff --git a/mail/folder-browser.h b/mail/folder-browser.h index 86c1c6f149..70667077c9 100644 --- a/mail/folder-browser.h +++ b/mail/folder-browser.h @@ -63,7 +63,7 @@ struct fb_ondemand_closure { }; GtkType folder_browser_get_type (void); -GtkWidget *folder_browser_new (void); +GtkWidget *folder_browser_new (Evolution_Shell shell); gboolean folder_browser_set_uri (FolderBrowser *folder_browser, const char *uri); void folder_browser_set_message_preview (FolderBrowser *folder_browser, diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index 2739c40c93..3942b86a41 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -58,14 +58,64 @@ struct post_send_data { }; static gboolean -check_configured (void) +check_configured (FolderBrowser *fb) { if (mail_config_is_configured ()) return TRUE; - mail_config_druid (); + if (fb) { + mail_config_druid (fb->shell); + return mail_config_is_configured (); + } else + return FALSE; +} + +static gboolean +check_send_configuration (FolderBrowser *fb) +{ + MailConfigService *xport = NULL; - return mail_config_is_configured (); + /* Check general */ + + if (!check_configured (fb)) { + GtkWidget *message; + + message = gnome_warning_dialog_parented (_("You need to configure the mail client\n" + "before you can compose mail."), + GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), + GTK_TYPE_WINDOW))); + mail_dialog_run_and_close (GNOME_DIALOG (message)); + return FALSE; + } + + /* Check for an identity */ + + if (!mail_config_get_default_identity ()) { + GtkWidget *message; + + message = gnome_warning_dialog_parented (_("You need to configure an identity\n" + "before you can compose mail."), + GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), + GTK_TYPE_WINDOW))); + mail_dialog_run_and_close (GNOME_DIALOG (message)); + return FALSE; + } + + /* Check for a transport */ + + xport = mail_config_get_transport (); + if (!xport || !xport->url) { + GtkWidget *message; + + message = gnome_warning_dialog_parented (_("You need to configure a mail transport\n" + "before you can compose mail."), + GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), + GTK_TYPE_WINDOW))); + mail_dialog_run_and_close (GNOME_DIALOG (message)); + return FALSE; + } + + return TRUE; } static void @@ -89,7 +139,7 @@ fetch_mail (GtkWidget *button, gpointer user_data) { GSList *sources; - if (!check_configured ()) { + if (!check_configured (FOLDER_BROWSER (user_data))) { GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), GTK_TYPE_WINDOW); @@ -136,9 +186,7 @@ ask_confirm_for_empty_subject (EMsgComposer *composer) GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL); - /*GDK_THREADS_ENTER ();*/ - button = gnome_dialog_run_and_close (GNOME_DIALOG (message_box)); - /*GDK_THREADS_LEAVE ();*/ + button = mail_dialog_run_and_close (GNOME_DIALOG (message_box)); if (button == 0) return TRUE; @@ -146,6 +194,19 @@ ask_confirm_for_empty_subject (EMsgComposer *composer) return FALSE; } +static void +free_psd (struct post_send_data *psd) +{ + if (!psd) + return; + + if (psd->folder) + camel_object_unref (CAMEL_OBJECT (psd->folder)); + if (psd->uid) + g_free (psd->uid); + g_free (psd); +} + void composer_send_cb (EMsgComposer *composer, gpointer data) { @@ -157,37 +218,10 @@ composer_send_cb (EMsgComposer *composer, gpointer data) struct post_send_data *psd = data; - /* Check for an identity */ + /* Config info */ id = mail_config_get_default_identity (); - if (!check_configured () || !id) { - GtkWidget *message; - - message = gnome_warning_dialog_parented (_("You need to configure an identity\n" - "before you can send mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (composer), - GTK_TYPE_WINDOW))); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); - return; - } - - /* Check for a transport */ - xport = mail_config_get_transport (); - if (!xport || !xport->url) { - GtkWidget *message; - - message = gnome_warning_dialog_parented (_("You need to configure a mail transport\n" - "before you can send mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (composer), - GTK_TYPE_WINDOW))); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); - return; - } /* Generate our from address */ @@ -211,6 +245,7 @@ composer_send_cb (EMsgComposer *composer, gpointer data) if (subject == NULL || subject[0] == '\0') { if (! ask_confirm_for_empty_subject (composer)) { camel_object_unref (CAMEL_OBJECT (message)); + free_psd (psd); /* will take care of psd == NULL */ return; } } @@ -219,24 +254,15 @@ composer_send_cb (EMsgComposer *composer, gpointer data) mail_do_send_mail (xport->url, message, from, psd->folder, psd->uid, psd->flags, GTK_WIDGET (composer)); - g_free (psd->uid); } else { mail_do_send_mail (xport->url, message, from, NULL, NULL, 0, GTK_WIDGET (composer)); } -} -static void -free_psd (GtkWidget *composer, gpointer user_data) -{ - struct post_send_data *psd = user_data; - - camel_object_unref (CAMEL_OBJECT (psd->folder)); - g_free (psd); + free_psd (psd); } - static GtkWidget * create_msg_composer (const char *url) { @@ -267,7 +293,7 @@ compose_msg (GtkWidget *widget, gpointer user_data) { GtkWidget *composer; - if (!check_configured ()) + if (!check_send_configuration (FOLDER_BROWSER (user_data))) return; composer = create_msg_composer (NULL); @@ -283,7 +309,9 @@ send_to_url (const char *url) { GtkWidget *composer; - if (!check_configured ()) + /* FIXME: no way to get folder browser? Not without + * big pain in the ass, as far as I can tell */ + if (!check_send_configuration (NULL)) return; composer = create_msg_composer (url); @@ -299,7 +327,9 @@ mail_reply (CamelFolder *folder, CamelMimeMessage *msg, const char *uid, gboolea EMsgComposer *composer; struct post_send_data *psd; - if (!check_configured () || !folder || + /* FIXME: I just don't feel like implementing the folder-browser-passing + * garbage. */ + if (!check_send_configuration (NULL) || !folder || !msg || !uid) return; @@ -313,8 +343,6 @@ mail_reply (CamelFolder *folder, CamelMimeMessage *msg, const char *uid, gboolea gtk_signal_connect (GTK_OBJECT (composer), "send", GTK_SIGNAL_FUNC (composer_send_cb), psd); - gtk_signal_connect (GTK_OBJECT (composer), "destroy", - GTK_SIGNAL_FUNC (free_psd), psd); gtk_widget_show (GTK_WIDGET (composer)); } @@ -351,9 +379,9 @@ forward_msg (GtkWidget *widget, gpointer user_data) EMsgComposer *composer; CamelMimeMessage *cursor_msg; GPtrArray *uids; - + cursor_msg = fb->mail_display->current_message; - if (!check_configured () || !cursor_msg) + if (!check_send_configuration (fb) || !cursor_msg) return; composer = E_MSG_COMPOSER (e_msg_composer_new ()); @@ -447,14 +475,16 @@ edit_msg (GtkWidget *widget, gpointer user_data) message = gnome_warning_dialog (_("You may only edit messages saved\n" "in the Drafts folder.")); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); + mail_dialog_run_and_close (GNOME_DIALOG (message)); return; } + if (!check_send_configuration (fb)) + return; + uids = g_ptr_array_new(); message_list_foreach (fb->message_list, enumerate_msg, uids); + mail_do_edit_messages (fb->folder, uids, (GtkSignalFunc) composer_send_cb); } @@ -538,16 +568,7 @@ filter_edit (BonoboUIHandler *uih, void *user_data, const char *path) dialog = gnome_warning_dialog (err); g_free (err); - /* These are necessary because gtk_main, called by - * g_d_r_a_c, does a LEAVE/ENTER pair when running - * a main loop recursively. I don't know why the threads - * lock isn't being held at this point, as we're in a - * callback, but I don't ask questions. It works, and - * threads are enabled so we know that it works. - */ - GDK_THREADS_ENTER(); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - GDK_THREADS_LEAVE(); + mail_dialog_run_and_close (GNOME_DIALOG (dialog)); return; } @@ -565,13 +586,11 @@ vfolder_edit_vfolders (BonoboUIHandler *uih, void *user_data, const char *path) vfolder_edit(); } -/* - *void - *providers_config (BonoboUIHandler *uih, void *user_data, const char *path) - *{ - * mail_config(); - *} - */ +void +providers_config (BonoboUIHandler *uih, void *user_data, const char *path) +{ + mail_config ((FOLDER_BROWSER (user_data))->shell); +} void mail_print_msg (MailDisplay *md) diff --git a/mail/mail-config-gui.c b/mail/mail-config-gui.c index c757c65904..abb0fc317d 100644 --- a/mail/mail-config-gui.c +++ b/mail/mail-config-gui.c @@ -141,6 +141,7 @@ typedef struct typedef struct { + Evolution_Shell shell; GladeXML *gui; GtkWidget *dialog; GtkWidget *druid; @@ -154,6 +155,7 @@ typedef struct typedef struct { + Evolution_Shell shell; GladeXML *gui; GtkWidget *dialog; GtkWidget *notebook; @@ -790,6 +792,7 @@ service_page_item_changed (GtkWidget *item, MailDialogServicePage *page) data = gtk_editable_get_chars (GTK_EDITABLE (spitem->path), 0, -1); if (!data || !*data) complete = FALSE; + g_free (data); } } @@ -1194,9 +1197,9 @@ identity_dialog (const MailConfigIdentity *id, GtkWidget *parent) iddialog = g_new0 (MailDialogIdentity, 1); if (new) - iddialog->dialog = gnome_dialog_new (_("Edit Identity"), NULL); - else iddialog->dialog = gnome_dialog_new (_("Add Identity"), NULL); + else + iddialog->dialog = gnome_dialog_new (_("Edit Identity"), NULL); gtk_window_set_modal (GTK_WINDOW (iddialog->dialog), TRUE); gtk_window_set_policy (GTK_WINDOW (iddialog->dialog), @@ -1241,9 +1244,7 @@ identity_dialog (const MailConfigIdentity *id, GtkWidget *parent) GTK_SIGNAL_FUNC (iddialog_ok_clicked), iddialog); - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (iddialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ + mail_dialog_run_and_close (GNOME_DIALOG (iddialog->dialog)); returnid = iddialog->id; g_free (iddialog); @@ -1290,9 +1291,9 @@ source_dialog (MailConfigService *source, GtkWidget *parent) provider_list (&sources, &news, &transports); if (new) - sdialog->dialog = gnome_dialog_new (_("Edit Source"), NULL); - else sdialog->dialog = gnome_dialog_new (_("Add Source"), NULL); + else + sdialog->dialog = gnome_dialog_new (_("Edit Source"), NULL); gtk_window_set_modal (GTK_WINDOW (sdialog->dialog), TRUE); gtk_window_set_policy (GTK_WINDOW (sdialog->dialog), @@ -1340,9 +1341,7 @@ source_dialog (MailConfigService *source, GtkWidget *parent) GTK_SIGNAL_FUNC (sdialog_ok_clicked), sdialog); - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (sdialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ + mail_dialog_run_and_close (GNOME_DIALOG (sdialog->dialog)); returnsource = sdialog->source; g_free (sdialog); @@ -1389,9 +1388,9 @@ news_dialog (MailConfigService *source, GtkWidget *parent) provider_list (&sources, &news, &transports); if (new) - ndialog->dialog = gnome_dialog_new (_("Edit News Server"), NULL); - else ndialog->dialog = gnome_dialog_new (_("Add News Server"), NULL); + else + ndialog->dialog = gnome_dialog_new (_("Edit News Server"), NULL); gtk_window_set_modal (GTK_WINDOW (ndialog->dialog), TRUE); gtk_window_set_policy (GTK_WINDOW (ndialog->dialog), @@ -1438,9 +1437,7 @@ news_dialog (MailConfigService *source, GtkWidget *parent) GTK_SIGNAL_FUNC (ndialog_ok_clicked), ndialog); - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (ndialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ + mail_dialog_run_and_close (GNOME_DIALOG (ndialog->dialog)); returnsource = ndialog->source; g_free (ndialog); @@ -1532,7 +1529,8 @@ mail_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, MailConfigIdentity *id; MailConfigService *source; MailConfigService *transport; - + GSList *mini; + mail_config_clear (); /* Identity */ @@ -1542,7 +1540,11 @@ mail_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, /* Source */ source = service_page_extract (dialog->spage->page); mail_config_add_source (source); - + + mini = g_slist_prepend (NULL, source); + mail_load_storages (dialog->shell, mini); + g_slist_free (mini); + /* Transport */ transport = service_page_extract (dialog->tpage->page); mail_config_set_transport (transport); @@ -1553,7 +1555,7 @@ mail_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, } void -mail_config_druid (void) +mail_config_druid (Evolution_Shell shell) { MailDruidDialog *dialog; GnomeDruidPageStart *spage; @@ -1571,6 +1573,7 @@ mail_config_druid (void) transport_logo = load_image ("envelope.png"); dialog = g_new0 (MailDruidDialog, 1); + dialog->shell = shell; /*should ref this somewhere*/ dialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config-druid.glade", NULL); dialog->dialog = glade_xml_get_widget (dialog->gui, "dialog"); @@ -1953,10 +1956,16 @@ mail_config_apply_clicked (GnomePropertyBox *property_box, /* Sources */ for (i = 0; i <= dialog->maxsrow; i++) { + GSList *mini; + clist = GTK_CLIST (dialog->clistSources); data = gtk_clist_get_row_data (clist, i); mail_config_add_source ((MailConfigService *) data); + + mini = g_slist_prepend (NULL, data); + mail_load_storages (dialog->shell, mini); + g_slist_free (mini); } /* Transport */ @@ -1985,7 +1994,7 @@ mail_config_apply_clicked (GnomePropertyBox *property_box, } void -mail_config (void) +mail_config (Evolution_Shell shell) { MailDialog *dialog; GladeXML *gui; @@ -1999,6 +2008,9 @@ mail_config (void) dialog = g_new0 (MailDialog, 1); gui = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", NULL); + dialog->shell = shell; + /*gtk_object_ref (GTK_OBJECT (dialog->fb)); no place to unref it*/ + dialog->dialog = glade_xml_get_widget (gui, "dialog"); dialog->notebook = glade_xml_get_widget (gui, "notebook"); @@ -2160,9 +2172,7 @@ mail_config (void) GTK_SIGNAL_FUNC (mail_config_apply_clicked), dialog); - GDK_THREADS_ENTER (); - gnome_dialog_run (GNOME_DIALOG (dialog->dialog)); - GDK_THREADS_LEAVE (); + mail_dialog_run (GNOME_DIALOG (dialog->dialog)); /* Clean up */ gtk_object_unref (GTK_OBJECT (gui)); @@ -2242,7 +2252,7 @@ static void cleanup_test_service (gpointer in_data, gpointer op_data, CamelExcep if (data->success) { dlg = gnome_ok_dialog (_("The connection was successful!")); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); + mail_dialog_run_and_close (GNOME_DIALOG (dlg)); } g_free (input->url); diff --git a/mail/mail-config-gui.h b/mail/mail-config-gui.h index be122966fc..6579a5cc61 100644 --- a/mail/mail-config-gui.h +++ b/mail/mail-config-gui.h @@ -23,7 +23,9 @@ #include <glib.h> -void mail_config (void); -void mail_config_druid (void); +#include <Evolution.h> + +void mail_config (Evolution_Shell shell); +void mail_config_druid (Evolution_Shell shell); #endif diff --git a/mail/mail-display.c b/mail/mail-display.c index 760c45c92e..ab42452cf3 100644 --- a/mail/mail-display.c +++ b/mail/mail-display.c @@ -35,15 +35,6 @@ static void redisplay (MailDisplay *md); * Callbacks *----------------------------------------------------------------------*/ -static void -save_data_eexist_cb (int reply, gpointer user_data) -{ - gboolean *ok = user_data; - - *ok = reply == 0; - gtk_main_quit (); -} - static gboolean write_data_to_file (CamelMimePart *part, const char *name, gboolean unique) { @@ -56,16 +47,26 @@ write_data_to_file (CamelMimePart *part, const char *name, gboolean unique) fd = open (name, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1 && errno == EEXIST && !unique) { - gboolean ok = FALSE; - - gnome_ok_cancel_dialog_modal ( - "A file by that name already exists.\nOverwrite it?", - save_data_eexist_cb, &ok); - GDK_THREADS_ENTER(); - gtk_main (); - GDK_THREADS_LEAVE(); - if (!ok) + GtkWidget *dlg; + GtkWidget *text; + + dlg = gnome_dialog_new (_("Overwrite file?"), + GNOME_STOCK_BUTTON_YES, + GNOME_STOCK_BUTTON_NO, + NULL); + text = gtk_label_new (_("A file by that name already exists.\nOverwrite it?")); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), text, TRUE, TRUE, 4); + gtk_widget_show (text); + + /* This should be mail_dialog_run_and_close, but for some reason this + * particular dialog will deadlock as it tries to GDK_THREADS_ENTER + * (gtk_main_level is indeed 1). I think it has to do with being in + * the file selection window. God this sucks. + */ + if (gnome_dialog_run_and_close (GNOME_DIALOG (dlg)) != 0) /* !!! */ return FALSE; + gtk_widget_destroy (dlg); + fd = open (name, O_WRONLY | O_TRUNC); } diff --git a/mail/mail-local.c b/mail/mail-local.c index eb03db0dd4..fe36fdcf3b 100644 --- a/mail/mail-local.c +++ b/mail/mail-local.c @@ -498,7 +498,5 @@ local_reconfigure_folder(FolderBrowser *fb) gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, data); gtk_object_unref((GtkObject *)gui); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (gd)); - GDK_THREADS_LEAVE (); + mail_dialog_run_and_close (GNOME_DIALOG (gd)); } diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 0047b5966b..55d392786d 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -60,7 +60,6 @@ static gchar * describe_fetch_mail (gpointer in_data, gboolean gerund) { fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - CamelStore *source; char *name; /*source = camel_session_get_store (session, input->source_url, NULL); @@ -164,7 +163,7 @@ cleanup_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) GtkWidget *dialog; dialog = gnome_ok_dialog (_("There is no new mail.")); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); + mail_dialog_run_and_close (GNOME_DIALOG (dialog)); } g_free (input->source_url); diff --git a/mail/mail-threads.c b/mail/mail-threads.c index 8fe170eea2..6643b75615 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -278,11 +278,7 @@ mail_operation_queue (const mail_operation_spec * spec, gpointer input, g_free (msg); gnome_dialog_set_close (GNOME_DIALOG (err_dialog), TRUE); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - GDK_THREADS_LEAVE (); - /*gtk_widget_destroy (err_dialog); */ - /*gtk_widget_show (GTK_WIDGET (err_dialog));*/ + mail_dialog_run_and_close (GNOME_DIALOG (err_dialog)); g_warning ("Setup failed for `%s': %s", clur->infinitive, @@ -522,6 +518,77 @@ mail_operations_get_status (int *busy_return, *message_return = current_message; } +/** + * mail_dialog_run_and_close: + * + * A wrapper for gnome_dialog... that will Do The Right Thing + * wrt the GDK lock. + **/ + +gint +mail_dialog_run_and_close (GnomeDialog *dlg) +{ + gint ret; + gboolean unlock = FALSE; + + /*g_message ("DLG: IN: r_a_c");*/ + + /*if (inside_read_msg || gtk_main_level() == 1) + * GDK_THREADS_ENTER (); + */ + + if (gdk_threads_mutex && g_mutex_trylock (gdk_threads_mutex)) + unlock = TRUE; + + ret = gnome_dialog_run_and_close (dlg); + + /*if (inside_read_msg || gtk_main_level() == 1) + * GDK_THREADS_LEAVE(); + */ + + if (unlock) + g_mutex_unlock (gdk_threads_mutex); + + /*g_message ("DLG: OUT: r_a_c");*/ + + return ret; +} + +/** + * mail_dialog_run: + * + * Analogous to above. + **/ + +gint +mail_dialog_run (GnomeDialog *dlg) +{ + gint ret; + gboolean unlock = FALSE; + + /*g_message ("DLG: IN: run");*/ + + /*if (inside_read_msg || gtk_main_level() == 1) + * GDK_THREADS_ENTER(); + */ + + if (gdk_threads_mutex && g_mutex_trylock (gdk_threads_mutex)) + unlock = TRUE; + + ret = gnome_dialog_run (dlg); + + /*if (inside_read_msg || gtk_main_level() == 1) + * GDK_THREADS_LEAVE(); + */ + + if (unlock) + g_mutex_unlock (gdk_threads_mutex); + + /*g_message ("DLG: OUT: run");*/ + + return ret; +} + /* ** Static functions **************************************************** */ static void check_dispatcher (void) @@ -688,7 +755,7 @@ read_msg (GIOChannel * source, GIOCondition condition, gpointer userdata) * it is as we are in the main thread right now. */ - GDK_THREADS_ENTER (); + /*g_message ("DLG: IN: read_msg");*/ switch (msg->type) { case STARTING: @@ -750,8 +817,9 @@ read_msg (GIOChannel * source, GIOCondition condition, gpointer userdata) break; } - GDK_THREADS_LEAVE (); + /*g_message ("DLG: OUT: read_msg");*/ g_free (msg); + return TRUE; } @@ -822,9 +890,7 @@ show_error (com_msg_t * msg) * only GDK_THREADS_ENTER were recursive... */ - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - /*GDK_THREADS_LEAVE ();*/ + mail_dialog_run_and_close (GNOME_DIALOG (err_dialog)); /* Allow the other thread to proceed */ @@ -862,9 +928,7 @@ get_password (com_msg_t * msg) button = -1; } else { *(msg->reply) = NULL; - /*GDK_THREADS_ENTER ();*/ - button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - /*GDK_THREADS_LEAVE ();*/ + button = mail_dialog_run_and_close (GNOME_DIALOG (dialog)); } if (button == 1 || *(msg->reply) == NULL) { diff --git a/mail/mail-tools.c b/mail/mail-tools.c index 97bc4259af..d082409468 100644 --- a/mail/mail-tools.c +++ b/mail/mail-tools.c @@ -657,12 +657,9 @@ mail_tool_uri_to_folder_noex (const char *uri) camel_exception_get_description (&ex)); dialog = gnome_error_dialog (msg); g_free (msg); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - GDK_THREADS_LEAVE (); + mail_dialog_run_and_close (GNOME_DIALOG (dialog)); gtk_widget_destroy (dialog); } return result; } - diff --git a/mail/mail-tools.h b/mail/mail-tools.h index 3aba7dde2c..ea89916a90 100644 --- a/mail/mail-tools.h +++ b/mail/mail-tools.h @@ -111,5 +111,4 @@ mail_lookup_url_table (CamelMimeMessage *mime_message); CamelFolder * mail_tool_filter_get_folder_func (FilterDriver *d, const char *uri, void *data); - #endif diff --git a/mail/mail.h b/mail/mail.h index 8a67d745fb..2a3f54530e 100644 --- a/mail/mail.h +++ b/mail/mail.h @@ -26,9 +26,6 @@ extern char *evolution_dir; -/* mail-config */ -void mail_config_druid (void); - /* mail-crypto */ char *mail_crypto_openpgp_decrypt (const char *ciphertext, CamelException *ex); @@ -85,6 +82,11 @@ void run_filter_ondemand (BonoboUIHandler *uih, gpointer user_data, const char * /* mail view */ GtkWidget *mail_view_create (CamelFolder *source, const char *uid, CamelMimeMessage *msg); +/* component factory for lack of a better place */ +/*takes a GSList of MailConfigServices */ +void mail_load_storages (Evolution_Shell corba_shell, GSList *sources); +void mail_add_new_storage (const char *uri, Evolution_Shell corba_shell, CamelException *ex); + /* session */ void session_init (void); char *mail_request_dialog (const char *prompt, gboolean secret, @@ -92,3 +94,11 @@ char *mail_request_dialog (const char *prompt, gboolean secret, void forget_passwords (BonoboUIHandler *uih, void *user_data, const char *path); extern CamelSession *session; + +/* mail-threads */ +/* These are NOT for the async thread. They handle locking + * of GDK, which is a bit wacky when threads are enabled. + */ +gint mail_dialog_run_and_close (GnomeDialog *dlg); +gint mail_dialog_run (GnomeDialog *dlg); + diff --git a/mail/session.c b/mail/session.c index b76e096abb..2d5a01a9d2 100644 --- a/mail/session.c +++ b/mail/session.c @@ -45,14 +45,9 @@ mail_request_dialog (const char *prompt, gboolean secret, const char *key, request_callback, &ans, NULL); if (!dialog) return NULL; - GDK_THREADS_ENTER (); - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 || - ans == NULL) { - GDK_THREADS_LEAVE (); + if (mail_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 || + ans == NULL) return NULL; - } - - GDK_THREADS_LEAVE (); } else { if (!mail_op_get_password ((char *) prompt, secret, &ans)) return NULL; |