diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 26 | ||||
-rw-r--r-- | mail/evolution-mbox-importer.c | 3 | ||||
-rw-r--r-- | mail/evolution-outlook-importer.c | 3 | ||||
-rw-r--r-- | mail/local-config.glade | 2 | ||||
-rw-r--r-- | mail/mail-importer.c | 36 | ||||
-rw-r--r-- | mail/mail-importer.h | 2 | ||||
-rw-r--r-- | mail/mail-local.c | 774 | ||||
-rw-r--r-- | mail/mail-local.h | 2 | ||||
-rw-r--r-- | mail/mail-threads.c | 9 | ||||
-rw-r--r-- | mail/mail-tools.c | 55 | ||||
-rw-r--r-- | mail/mail-tools.h | 4 | ||||
-rw-r--r-- | mail/message-list.c | 93 |
12 files changed, 443 insertions, 566 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index ff8ee843e7..1d3e2c6640 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,29 @@ +2001-02-09 Dan Winship <danw@ximian.com> + + * mail-local.c: Updates for CamelStore changes, small memory leak + fixes. + (lookup_folder): Removed (and moved into the reconfigure code) + since this method no longer exists in CamelStore. + (do_reconfigure_folder, etc): Update the info in the + MailLocalStore after reconfiguring. + (mail_local_lookup_folder): Removed + + * local-config.glade: fix padding of the label_format + + * message-list.c (ml_tree_value_at): Don't keep message infos + reffed across calls, since this can cause badness after a + reconfigure. Instead, just strdup the needed values and free those + on the next call. + + * mail-tools.c (mail_tool_get_root_of_store): Unused, remove. + (mail_tool_get_inbox): use camel_store_get_inbox. + + * evolution-outlook-importer.c (load_file_fn): + * evolution-mbox-importer.c (load_file_fn): Use + mail_tool_get_local_inbox() instead of mail_importer_get_folder() + + * mail-importer.c (mail_importer_get_folder): Removed + 2001-02-08 Jeffrey Stedfast <fejj@ximian.com> * mail-callbacks.c (mail_generate_reply): New location for this diff --git a/mail/evolution-mbox-importer.c b/mail/evolution-mbox-importer.c index 84837ccb9b..0e18fb6732 100644 --- a/mail/evolution-mbox-importer.c +++ b/mail/evolution-mbox-importer.c @@ -33,6 +33,7 @@ #include <importer/GNOME_Evolution_Importer.h> #include "mail-importer.h" +#include "mail-tools.h" #include <camel/camel.h> @@ -183,7 +184,7 @@ load_file_fn (EvolutionImporter *eimporter, } importer->mstream = NULL; - importer->folder = mail_importer_get_folder ("Inbox", NULL); + importer->folder = mail_tool_get_local_inbox (NULL); if (importer->folder == NULL) { g_print ("Bad folder\n"); diff --git a/mail/evolution-outlook-importer.c b/mail/evolution-outlook-importer.c index 35fa2e7315..d78f2ad7f8 100644 --- a/mail/evolution-outlook-importer.c +++ b/mail/evolution-outlook-importer.c @@ -34,6 +34,7 @@ #include <importer/GNOME_Evolution_Importer.h> #include "mail-importer.h" +#include "mail-tools.h" #include <camel/camel-exception.h> @@ -253,7 +254,7 @@ load_file_fn (EvolutionImporter *eimporter, importer->mstream = NULL; - importer->folder = mail_importer_get_folder ("Inbox", NULL); + importer->folder = mail_tool_get_local_inbox (NULL); if (importer->folder == NULL){ g_warning ("Bad folder"); diff --git a/mail/local-config.glade b/mail/local-config.glade index 890f55144d..7a2dbc2862 100644 --- a/mail/local-config.glade +++ b/mail/local-config.glade @@ -152,7 +152,7 @@ <wrap>False</wrap> <xalign>7.45058e-09</xalign> <yalign>0.5</yalign> - <xpad>0</xpad> + <xpad>8</xpad> <ypad>0</ypad> <child> <left_attach>1</left_attach> diff --git a/mail/mail-importer.c b/mail/mail-importer.c index 3c02576599..b46c4ccc50 100644 --- a/mail/mail-importer.c +++ b/mail/mail-importer.c @@ -88,42 +88,6 @@ mail_importer_add_line (MailImporter *importer, } /** - * mail_importer_get_folder: - * @name: The folder name. - * *opt_ex: A #CamelException, or NULL if you don't care about errors. - * - * Gets the local folder called @name. - * - * Returns: A CamelFolder (which needs to be unrefed when you are done with it) - * on success, or NULL on fail. A more detailed error is given in @opt_ex, if - * @opt_ex is not NULL. - */ -CamelFolder * -mail_importer_get_folder (const char *name, - CamelException *opt_ex) -{ - CamelFolder *folder; - CamelException *real_ex; - char *path, *tmp; - - if (opt_ex != NULL) - real_ex = opt_ex; - else - real_ex = camel_exception_new (); - - g_print ("Evolution_dir: %s\n", evolution_dir); - tmp = g_concat_dir_and_file (evolution_dir, "local"); - path = g_concat_dir_and_file (tmp, name); - g_free (tmp); - - folder = mail_local_lookup_folder (path + 1, real_ex); - if (opt_ex == NULL) - camel_exception_free (real_ex); - - return folder; -} - -/** * mail_importer_init: * * Initialises all the importers diff --git a/mail/mail-importer.h b/mail/mail-importer.h index 0c46c7c78c..cc9c189eef 100644 --- a/mail/mail-importer.h +++ b/mail/mail-importer.h @@ -40,6 +40,4 @@ void mail_importer_init (void); void mail_importer_add_line (MailImporter *importer, const char *str, gboolean finished); -CamelFolder *mail_importer_get_folder (const char *name, - CamelException *opt_ex); #endif diff --git a/mail/mail-local.c b/mail/mail-local.c index 1559418a83..7b5b744018 100644 --- a/mail/mail-local.c +++ b/mail/mail-local.c @@ -162,315 +162,6 @@ save_metainfo(struct _local_meta *meta) } -/* Local folder reconfiguration stuff */ - -/* - open new - copy old->new - close old - rename old oldsave - rename new old - open oldsave - delete oldsave - - close old - rename oldtmp - open new - open oldtmp - copy oldtmp new - close oldtmp - close oldnew - -*/ - -static void -update_progress(char *fmt, float percent) -{ - if (fmt) - mail_status(fmt); - /*mail_op_set_percentage (percent);*/ -} - -/* ******************** */ - -typedef struct reconfigure_folder_input_s { - FolderBrowser *fb; - gchar *newtype; - GtkWidget *frame; - GtkWidget *apply; - GtkWidget *cancel; - GtkOptionMenu *optionlist; -} reconfigure_folder_input_t; - -static gchar * -describe_reconfigure_folder (gpointer in_data, gboolean gerund) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - if (gerund) - return g_strdup_printf (_("Changing folder \"%s\" to \"%s\" format"), - input->fb->uri, - input->newtype); - else - return g_strdup_printf (_("Change folder \"%s\" to \"%s\" format"), - input->fb->uri, - input->newtype); -} - -static void -setup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - if (!IS_FOLDER_BROWSER (input->fb)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "Input has a bad FolderBrowser in reconfigure_folder"); - return; - } - - if (!input->newtype) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No new folder type in reconfigure_folder"); - return; - } - - gtk_object_ref (GTK_OBJECT (input->fb)); -} - -static void -do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - CamelStore *fromstore = NULL, *tostore = NULL; - char *fromurl = NULL, *tourl = NULL; - CamelFolder *fromfolder = NULL, *tofolder = NULL; - GPtrArray *uids; - int i; - char *metapath; - char *tmpname; - CamelURL *url = NULL; - struct _local_meta *meta; - guint32 flags; - - d(printf("reconfiguring folder: %s to type %s\n", input->fb->uri, input->newtype)); - - mail_status_start(_("Reconfiguring folder")); - - /* NOTE: This var is cleared by the folder_browser via the set_uri method */ - input->fb->reconfigure = TRUE; - - /* get the actual location of the mailbox */ - url = camel_url_new(input->fb->uri, ex); - if (camel_exception_is_set(ex)) { - g_warning("%s is not a workable url!", input->fb->uri); - goto cleanup; - } - - metapath = g_strdup_printf("%s/local-metadata.xml", url->path); - meta = load_metainfo(metapath); - g_free(metapath); - - /* first, 'close' the old folder */ - if (input->fb->folder != NULL) { - update_progress(_("Closing current folder"), 0.0); - - camel_folder_sync(input->fb->folder, FALSE, ex); - camel_object_unref (CAMEL_OBJECT (input->fb->folder)); - input->fb->folder = NULL; - } - - camel_url_set_protocol (url, meta->format); - fromurl = camel_url_to_string (url, FALSE); - camel_url_set_protocol (url, input->newtype); - tourl = camel_url_to_string (url, FALSE); - - d(printf("opening stores %s and %s\n", fromurl, tourl)); - - fromstore = camel_session_get_store(session, fromurl, ex); - - if (camel_exception_is_set(ex)) - goto cleanup; - - tostore = camel_session_get_store(session, tourl, ex); - if (camel_exception_is_set(ex)) - goto cleanup; - - /* rename the old mbox and open it again, without indexing */ - tmpname = g_strdup_printf("%s_reconfig", meta->name); - d(printf("renaming %s to %s, and opening it\n", meta->name, tmpname)); - update_progress(_("Renaming old folder and opening"), 0.0); - - camel_store_rename_folder(fromstore, meta->name, tmpname, ex); - if (camel_exception_is_set(ex)) { - goto cleanup; - } - - /* we dont need to set the create flag ... or need an index if it has one */ - fromfolder = camel_store_get_folder(fromstore, tmpname, 0, ex); - if (fromfolder == NULL || camel_exception_is_set(ex)) { - /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); - goto cleanup; - } - - /* create a new mbox */ - d(printf("Creating the destination mbox\n")); - update_progress(_("Creating new folder"), 0.0); - - flags = CAMEL_STORE_FOLDER_CREATE; - if (meta->indexed) - flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - tofolder = camel_store_get_folder(tostore, meta->name, flags, ex); - if (tofolder == NULL || camel_exception_is_set(ex)) { - d(printf("cannot open destination folder\n")); - /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); - goto cleanup; - } - - update_progress(_("Copying messages"), 0.0); - uids = camel_folder_get_uids(fromfolder); - for (i=0;i<uids->len;i++) { - mail_statusf("Copying message %d of %d", i, uids->len); - camel_folder_move_message_to(fromfolder, uids->pdata[i], tofolder, ex); - if (camel_exception_is_set(ex)) { - camel_folder_free_uids(fromfolder, uids); - goto cleanup; - } - } - camel_folder_free_uids(fromfolder, uids); - camel_folder_expunge(fromfolder, ex); - - d(printf("delete old mbox ...\n")); - camel_store_delete_folder(fromstore, tmpname, ex); - - /* switch format */ - g_free(meta->format); - meta->format = g_strdup(input->newtype); - if (save_metainfo(meta) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot save folder metainfo; " - "you'll probably find you can't\n" - "open this folder anymore: %s"), - tourl); - } - free_metainfo(meta); - - /* and unref our copy of the new folder ... */ - cleanup: - if (tofolder) - camel_object_unref (CAMEL_OBJECT (tofolder)); - if (fromfolder) - camel_object_unref (CAMEL_OBJECT (fromfolder)); - if (fromstore) - camel_object_unref (CAMEL_OBJECT (fromstore)); - if (tostore) - camel_object_unref (CAMEL_OBJECT (tostore)); - g_free(fromurl); - g_free(tourl); - if (url) - camel_url_free (url); -} - -static void -cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - char *uri; - - if (camel_exception_is_set(ex)) { - GtkWidget *win = gtk_widget_get_ancestor((GtkWidget *)input->frame, GTK_TYPE_WINDOW); - gnome_error_dialog_parented (_("If you can no longer open this mailbox, then\n" - "you may need to repair it manually."), GTK_WINDOW (win)); - } - - /* force a reload of the newly formatted folder */ - d(printf("opening new source\n")); - uri = g_strdup(input->fb->uri); - folder_browser_set_uri(input->fb, uri); - g_free(uri); - - mail_status_end(); - - gtk_object_unref (GTK_OBJECT (input->fb)); - g_free (input->newtype); -} - -static const mail_operation_spec op_reconfigure_folder = -{ - describe_reconfigure_folder, - 0, - setup_reconfigure_folder, - do_reconfigure_folder, - cleanup_reconfigure_folder -}; - -static void -reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data) -{ - if (button == 0) { - GtkMenu *menu; - int type; - char *types[] = { "mbox", "maildir", "mh" }; - - menu = (GtkMenu *)gtk_option_menu_get_menu(data->optionlist); - type = g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(menu)); - if (type < 0 || type > 2) - type = 0; - - gtk_widget_set_sensitive(data->frame, FALSE); - gtk_widget_set_sensitive(data->apply, FALSE); - gtk_widget_set_sensitive(data->cancel, FALSE); - - data->newtype = g_strdup (types[type]); - mail_operation_queue (&op_reconfigure_folder, data, TRUE); - } - - if (button != -1) - gnome_dialog_close(d); -} - -void -mail_local_reconfigure_folder(FolderBrowser *fb) -{ - CamelStore *store; - GladeXML *gui; - GnomeDialog *gd; - reconfigure_folder_input_t *data; - - if (fb->folder == NULL) { - g_warning("Trying to reconfigure nonexistant folder"); - return; - } - - data = g_new (reconfigure_folder_input_t, 1); - - store = camel_folder_get_parent_store(fb->folder); - - gui = glade_xml_new(EVOLUTION_GLADEDIR "/local-config.glade", "dialog_format"); - gd = (GnomeDialog *)glade_xml_get_widget (gui, "dialog_format"); - - data->frame = glade_xml_get_widget (gui, "frame_format"); - data->apply = glade_xml_get_widget (gui, "apply_format"); - data->cancel = glade_xml_get_widget (gui, "cancel_format"); - data->optionlist = (GtkOptionMenu *)glade_xml_get_widget (gui, "option_format"); - data->newtype = NULL; - data->fb = fb; - - gtk_label_set_text((GtkLabel *)glade_xml_get_widget (gui, "label_format"), - ((CamelService *)store)->url->protocol); - - gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, data); - gtk_object_unref((GtkObject *)gui); - - gnome_dialog_run_and_close (GNOME_DIALOG (gd)); -} - - - /* MailLocalStore implementation */ #define MAIL_LOCAL_STORE_TYPE (mail_local_store_get_type ()) #define MAIL_LOCAL_STORE(obj) (CAMEL_CHECK_CAST((obj), MAIL_LOCAL_STORE_TYPE, MailLocalStore)) @@ -496,20 +187,20 @@ typedef struct { typedef struct { CamelFolder *folder; MailLocalStore *local_store; - char *path, *name; + char *path, *name, *uri; int last_unread; } MailLocalFolder; -static void local_folder_changed_proxy (CamelObject *folder, gpointer event_data, gpointer user_data); +static MailLocalStore *local_store; CamelType mail_local_store_get_type (void); +static void local_folder_changed_proxy (CamelObject *folder, gpointer event_data, gpointer user_data); + static char *get_name(CamelService *service, gboolean brief); static CamelFolder *get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name(CamelStore *store, const char *folder_name, CamelException *ex); -static CamelFolder *lookup_folder(CamelStore *store, const char *folder_name); static CamelStoreClass *local_parent_class; @@ -524,11 +215,13 @@ mail_local_store_class_init (MailLocalStoreClass *mail_local_store_class) /* virtual method overload */ camel_service_class->get_name = get_name; + /* Don't cache folders */ + camel_store_class->hash_folder_name = NULL; + camel_store_class->compare_folder_name = NULL; + camel_store_class->get_folder = get_folder; camel_store_class->delete_folder = delete_folder; camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->lookup_folder = lookup_folder; local_parent_class = (CamelStoreClass *)camel_type_get_global_classfuncs(camel_store_get_type ()); } @@ -555,6 +248,7 @@ free_local_folder(MailLocalFolder *lf) } g_free(lf->path); g_free(lf->name); + g_free(lf->uri); camel_object_unref((CamelObject *)lf->local_store); } @@ -608,88 +302,6 @@ mail_local_store_get_type (void) return mail_local_store_type; } -/* sigh, - because of all this LocalStore nonsense, we have to snoop cache hits to find out - if our local folder type has changed under us (sort of the whole point of most - of this file, is the storage type of the folder), and then reload the new folder - to match. - - The only other way would be to poke it even more directly, which seems worse. - - Not sure if the ref stuff is 100%, but its probably no worse than it was. -*/ -static CamelFolder * -lookup_folder (CamelStore *store, const char *folder_name) -{ - char *name, *type; - struct _local_meta *meta; - MailLocalFolder *local_folder; - CamelStore *newstore; - MailLocalStore *local_store = (MailLocalStore *)store; - CamelFolder *folder; - CamelException *ex; - - folder = local_parent_class->lookup_folder(store, folder_name); - - d(printf("looking up local folder: %s = %p\n", folder_name, folder)); - - if (folder != NULL) { - type = ((CamelService *)folder->parent_store)->url->protocol; - name = g_strdup_printf("/%s/local-metadata.xml", folder_name); - meta = load_metainfo(name); - g_free(name); - d(printf("found folder, checking type '%s' against meta '%s'\n", type, meta->format)); - if (strcmp(meta->format, type) != 0) { - d(printf("ok, mismatch, checking ...\n")); - local_parent_class->uncache_folder(store, folder); - local_folder = g_hash_table_lookup(local_store->folders, folder_name); - if (local_folder) { - d(printf("we have to update the old folder ...\n")); - camel_object_unhook_event(CAMEL_OBJECT (local_folder->folder), - "folder_changed", local_folder_changed_proxy, - local_folder); - camel_object_unhook_event(CAMEL_OBJECT (local_folder->folder), - "message_changed", local_folder_changed_proxy, - local_folder); - camel_object_unref((CamelObject *)local_folder->folder); - folder = local_folder->folder = NULL; - - ex = camel_exception_new(); - name = g_strdup_printf ("%s:/%s", meta->format, folder_name); - newstore = camel_session_get_store (session, name, ex); - d(printf("getting new store %s = %p\n", name, newstore)); - g_free (name); - if (newstore) { - guint32 flags = CAMEL_STORE_FOLDER_CREATE; - if (meta->indexed) - flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - folder = local_folder->folder = - camel_store_get_folder(newstore, meta->name, flags, ex); - camel_object_unref((CamelObject *)newstore); - - d(printf("we got the new folder: %s : %p\n", folder_name, folder)); - camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), - "folder_changed", local_folder_changed_proxy, - local_folder); - camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), - "message_changed", local_folder_changed_proxy, - local_folder); - } - if (folder) - local_parent_class->cache_folder(store, folder_name, folder); - - camel_exception_free(ex); - } - } - free_metainfo(meta); - } - - if (folder) - camel_object_ref((CamelObject *)folder); - - return folder; -} - static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) @@ -723,13 +335,6 @@ rename_folder (CamelStore *store, const char *old, const char *new, } static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - return g_strdup (folder_name); -} - -static char * get_name (CamelService *service, gboolean brief) { return g_strdup ("Local mail folders"); @@ -800,16 +405,16 @@ static void do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) { MailLocalFolder *local_folder = in_data; - char *name; + char *name, *path = local_folder->uri + 7; struct _local_meta *meta; CamelStore *store; guint32 flags; - name = g_strdup_printf ("/%s/local-metadata.xml", local_folder->name); + name = g_strdup_printf ("%s/local-metadata.xml", path); meta = load_metainfo (name); g_free (name); - name = g_strdup_printf ("%s:/%s", meta->format, local_folder->name); + name = g_strdup_printf ("%s:%s", meta->format, path); store = camel_session_get_store (session, name, ex); g_free (name); if (!store) { @@ -821,7 +426,16 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) if (meta->indexed) flags |= CAMEL_STORE_FOLDER_BODY_INDEX; local_folder->folder = camel_store_get_folder (store, meta->name, flags, ex); - local_folder->last_unread = camel_folder_get_unread_message_count(local_folder->folder); + if (local_folder->folder) { + camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), + "folder_changed", local_folder_changed_proxy, + local_folder); + camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), + "message_changed", local_folder_changed_proxy, + local_folder); + local_folder->last_unread = camel_folder_get_unread_message_count(local_folder->folder); + } + camel_object_unref (CAMEL_OBJECT (store)); free_metainfo (meta); } @@ -837,15 +451,8 @@ cleanup_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) return; } - g_hash_table_insert (local_folder->local_store->folders, local_folder->name, local_folder); - local_folder->name = strrchr (local_folder->path, '/') + 1; + g_hash_table_insert (local_folder->local_store->folders, local_folder->uri + 8, local_folder); - camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), - "folder_changed", local_folder_changed_proxy, - local_folder); - camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), - "message_changed", local_folder_changed_proxy, - local_folder); unread = local_folder->last_unread; local_folder->last_unread = 0; local_folder_changed (CAMEL_OBJECT (local_folder->folder), GINT_TO_POINTER (unread), local_folder); @@ -876,8 +483,9 @@ local_storage_new_folder_cb (EvolutionStorageListener *storage_listener, return; local_folder = g_new0 (MailLocalFolder, 1); - local_folder->name = g_strdup (folder->physical_uri + 8); + local_folder->name = g_strdup (strrchr (path, '/') + 1); local_folder->path = g_strdup (path); + local_folder->uri = g_strdup (folder->physical_uri); local_folder->local_store = local_store; camel_object_ref((CamelObject *)local_store); @@ -921,9 +529,7 @@ local_storage_removed_folder_cb (EvolutionStorageListener *storage_listener, local_store->local_pathlen) != 0) return; - path += 7 + local_store->local_pathlen; - - local_folder = g_hash_table_lookup (local_store->folders, path); + local_folder = g_hash_table_lookup (local_store->folders, path + 8); if (local_folder) { g_hash_table_remove (local_store->folders, path); free_local_folder(local_folder); @@ -949,24 +555,10 @@ non_equal (gconstpointer a, gconstpointer b) return TRUE; } -CamelFolder * -mail_local_lookup_folder (const char *name, - CamelException *ev) -{ - MailLocalStore *local_store; - - local_store = (MailLocalStore *)camel_session_get_service (session, - "file:/", - CAMEL_PROVIDER_STORE, NULL); - - return get_folder (CAMEL_STORE(local_store), name, 0, ev); -} - void mail_local_storage_startup (EvolutionShellClient *shellclient, const char *evolution_path) { - MailLocalStore *local_store; GNOME_Evolution_StorageListener corba_local_storage_listener; CORBA_Environment ev; @@ -1029,3 +621,317 @@ mail_local_storage_startup (EvolutionShellClient *shellclient, } CORBA_exception_free (&ev); } + + +/* Local folder reconfiguration stuff */ + +/* + open new + copy old->new + close old + rename old oldsave + rename new old + open oldsave + delete oldsave + + close old + rename oldtmp + open new + open oldtmp + copy oldtmp new + close oldtmp + close oldnew + +*/ + +static void +update_progress(char *fmt, float percent) +{ + if (fmt) + mail_status(fmt); + /*mail_op_set_percentage (percent);*/ +} + +/* ******************** */ + +typedef struct reconfigure_folder_input_s { + FolderBrowser *fb; + gchar *newtype; + GtkWidget *frame; + GtkWidget *apply; + GtkWidget *cancel; + GtkOptionMenu *optionlist; +} reconfigure_folder_input_t; + +static gchar * +describe_reconfigure_folder (gpointer in_data, gboolean gerund) +{ + reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + + if (gerund) + return g_strdup_printf (_("Changing folder \"%s\" to \"%s\" format"), + input->fb->uri, + input->newtype); + else + return g_strdup_printf (_("Change folder \"%s\" to \"%s\" format"), + input->fb->uri, + input->newtype); +} + +static void +setup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) +{ + reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + + gtk_object_ref (GTK_OBJECT (input->fb)); +} + +static void +do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) +{ + reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + MailLocalFolder *local_folder; + CamelStore *fromstore = NULL, *tostore = NULL; + char *fromurl = NULL, *tourl = NULL; + CamelFolder *fromfolder = NULL, *tofolder = NULL; + GPtrArray *uids; + int i; + char *metapath; + char *tmpname; + CamelURL *url = NULL; + struct _local_meta *meta; + guint32 flags; + + d(printf("reconfiguring folder: %s to type %s\n", input->fb->uri, input->newtype)); + + mail_status_start(_("Reconfiguring folder")); + + /* NOTE: This var is cleared by the folder_browser via the set_uri method */ + input->fb->reconfigure = TRUE; + + /* get the actual location of the mailbox */ + url = camel_url_new(input->fb->uri, ex); + if (camel_exception_is_set(ex)) { + g_warning("%s is not a workable url!", input->fb->uri); + goto cleanup; + } + + tmpname = strchr (input->fb->uri, '/'); + if (tmpname) { + while (*tmpname == '/') + tmpname++; + local_folder = g_hash_table_lookup (local_store->folders, tmpname); + } else + local_folder = NULL; + if (!local_folder) { + g_warning("%s is not a registered local folder!", input->fb->uri); + goto cleanup; + } + + metapath = g_strdup_printf("%s/local-metadata.xml", url->path); + meta = load_metainfo(metapath); + g_free(metapath); + + /* first, 'close' the old folder */ + update_progress(_("Closing current folder"), 0.0); + camel_folder_sync(local_folder->folder, FALSE, ex); + camel_object_unhook_event(CAMEL_OBJECT (local_folder->folder), + "folder_changed", local_folder_changed_proxy, + local_folder); + camel_object_unhook_event(CAMEL_OBJECT (local_folder->folder), + "message_changed", local_folder_changed_proxy, + local_folder); + /* Once for the FolderBrowser, once for the local store */ + camel_object_unref(CAMEL_OBJECT(local_folder->folder)); + camel_object_unref(CAMEL_OBJECT(local_folder->folder)); + local_folder->folder = input->fb->folder = NULL; + + camel_url_set_protocol (url, meta->format); + fromurl = camel_url_to_string (url, FALSE); + camel_url_set_protocol (url, input->newtype); + tourl = camel_url_to_string (url, FALSE); + + d(printf("opening stores %s and %s\n", fromurl, tourl)); + + fromstore = camel_session_get_store(session, fromurl, ex); + + if (camel_exception_is_set(ex)) + goto cleanup; + + tostore = camel_session_get_store(session, tourl, ex); + if (camel_exception_is_set(ex)) + goto cleanup; + + /* rename the old mbox and open it again, without indexing */ + tmpname = g_strdup_printf("%s_reconfig", meta->name); + d(printf("renaming %s to %s, and opening it\n", meta->name, tmpname)); + update_progress(_("Renaming old folder and opening"), 0.0); + + camel_store_rename_folder(fromstore, meta->name, tmpname, ex); + if (camel_exception_is_set(ex)) { + goto cleanup; + } + + /* we dont need to set the create flag ... or need an index if it has one */ + fromfolder = camel_store_get_folder(fromstore, tmpname, 0, ex); + if (fromfolder == NULL || camel_exception_is_set(ex)) { + /* try and recover ... */ + camel_exception_clear (ex); + camel_store_rename_folder(fromstore, tmpname, meta->name, ex); + goto cleanup; + } + + /* create a new mbox */ + d(printf("Creating the destination mbox\n")); + update_progress(_("Creating new folder"), 0.0); + + flags = CAMEL_STORE_FOLDER_CREATE; + if (meta->indexed) + flags |= CAMEL_STORE_FOLDER_BODY_INDEX; + tofolder = camel_store_get_folder(tostore, meta->name, flags, ex); + if (tofolder == NULL || camel_exception_is_set(ex)) { + d(printf("cannot open destination folder\n")); + /* try and recover ... */ + camel_exception_clear (ex); + camel_store_rename_folder(fromstore, tmpname, meta->name, ex); + goto cleanup; + } + + update_progress(_("Copying messages"), 0.0); + uids = camel_folder_get_uids(fromfolder); + for (i=0;i<uids->len;i++) { + mail_statusf("Copying message %d of %d", i, uids->len); + camel_folder_move_message_to(fromfolder, uids->pdata[i], tofolder, ex); + if (camel_exception_is_set(ex)) { + camel_folder_free_uids(fromfolder, uids); + goto cleanup; + } + } + camel_folder_free_uids(fromfolder, uids); + camel_folder_expunge(fromfolder, ex); + + d(printf("delete old mbox ...\n")); + camel_store_delete_folder(fromstore, tmpname, ex); + + /* switch format */ + g_free(meta->format); + meta->format = g_strdup(input->newtype); + if (save_metainfo(meta) == -1) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Cannot save folder metainfo; " + "you'll probably find you can't\n" + "open this folder anymore: %s"), + tourl); + } + + cleanup: + if (!local_folder->folder) + do_register_folder (local_folder, NULL, ex); + if (tofolder) + camel_object_unref (CAMEL_OBJECT (tofolder)); + if (fromfolder) + camel_object_unref (CAMEL_OBJECT (fromfolder)); + if (fromstore) + camel_object_unref (CAMEL_OBJECT (fromstore)); + if (tostore) + camel_object_unref (CAMEL_OBJECT (tostore)); + free_metainfo(meta); + g_free(fromurl); + g_free(tourl); + if (url) + camel_url_free (url); +} + +static void +cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) +{ + reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; + char *uri; + + if (camel_exception_is_set(ex)) { + gnome_error_dialog (_("If you can no longer open this mailbox, then\n" + "you may need to repair it manually.")); + } + + /* force a reload of the newly formatted folder */ + d(printf("opening new source\n")); + uri = g_strdup(input->fb->uri); + folder_browser_set_uri(input->fb, uri); + g_free(uri); + + mail_status_end(); + + gtk_object_unref (GTK_OBJECT (input->fb)); + g_free (input->newtype); +} + +static const mail_operation_spec op_reconfigure_folder = +{ + describe_reconfigure_folder, + 0, + setup_reconfigure_folder, + do_reconfigure_folder, + cleanup_reconfigure_folder +}; + +static void +reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data) +{ + if (button == 0) { + GtkMenu *menu; + int type; + char *types[] = { "mbox", "maildir", "mh" }; + + menu = (GtkMenu *)gtk_option_menu_get_menu(data->optionlist); + type = g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(menu)); + if (type < 0 || type > 2) + type = 0; + + gtk_widget_set_sensitive(data->frame, FALSE); + gtk_widget_set_sensitive(data->apply, FALSE); + gtk_widget_set_sensitive(data->cancel, FALSE); + + data->newtype = g_strdup (types[type]); + mail_operation_queue (&op_reconfigure_folder, data, TRUE); + } else + g_free (data); + + if (button != -1) + gnome_dialog_close(d); +} + +void +mail_local_reconfigure_folder(FolderBrowser *fb) +{ + CamelStore *store; + GladeXML *gui; + GnomeDialog *gd; + reconfigure_folder_input_t *data; + + if (fb->folder == NULL) { + g_warning("Trying to reconfigure nonexistant folder"); + return; + } + + data = g_new (reconfigure_folder_input_t, 1); + + store = camel_folder_get_parent_store(fb->folder); + + gui = glade_xml_new(EVOLUTION_GLADEDIR "/local-config.glade", "dialog_format"); + gd = (GnomeDialog *)glade_xml_get_widget (gui, "dialog_format"); + + data->frame = glade_xml_get_widget (gui, "frame_format"); + data->apply = glade_xml_get_widget (gui, "apply_format"); + data->cancel = glade_xml_get_widget (gui, "cancel_format"); + data->optionlist = (GtkOptionMenu *)glade_xml_get_widget (gui, "option_format"); + data->newtype = NULL; + data->fb = fb; + + gtk_label_set_text((GtkLabel *)glade_xml_get_widget (gui, "label_format"), + ((CamelService *)store)->url->protocol); + + gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, data); + gtk_object_unref((GtkObject *)gui); + + gnome_dialog_run_and_close (GNOME_DIALOG (gd)); +} diff --git a/mail/mail-local.h b/mail/mail-local.h index 808c2cdf18..254fcbe4f6 100644 --- a/mail/mail-local.h +++ b/mail/mail-local.h @@ -35,6 +35,4 @@ void mail_local_storage_startup (EvolutionShellClient *shellclient, void mail_local_reconfigure_folder (FolderBrowser *fb); -CamelFolder *mail_local_lookup_folder (const char *name, - CamelException *ex); #endif diff --git a/mail/mail-threads.c b/mail/mail-threads.c index 4b989bb762..8f0e263765 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -557,9 +557,14 @@ mail_operations_terminate (void) memset (&clur, 0, sizeof (closure_t)); clur.spec = NULL; - pipe_write (DISPATCH_WRITER, &clur, sizeof (closure_t)); + /* DISPATCH_WRITER will only have been initialized if any + * calls have been made using the old thread system. + */ + if (DISPATCH_WRITER != -1) { + pipe_write (DISPATCH_WRITER, &clur, sizeof (closure_t)); - close (DISPATCH_WRITER); + close (DISPATCH_WRITER); + } close (MAIN_READER); } diff --git a/mail/mail-tools.c b/mail/mail-tools.c index 1dc13c5f2e..cb4325ca70 100644 --- a/mail/mail-tools.c +++ b/mail/mail-tools.c @@ -106,14 +106,6 @@ mail_tool_get_folder_from_urlname (const gchar *url, const gchar *name, return NULL; } - /*camel_service_connect (CAMEL_SERVICE (store), ex); - *if (camel_exception_is_set (ex)) { - * camel_object_unref (CAMEL_OBJECT (store)); - * mail_tool_camel_lock_down(); - * return NULL; - *} - */ - folder = camel_store_get_folder (store, name, flags, ex); camel_object_unref (CAMEL_OBJECT (store)); mail_tool_camel_lock_down(); @@ -161,8 +153,22 @@ mail_tool_get_local_inbox (CamelException *ex) CamelFolder * mail_tool_get_inbox (const gchar *url, CamelException *ex) { - /* FIXME: should be smarter? get_default_folder, etc */ - return mail_tool_get_folder_from_urlname (url, "inbox", 0, ex); + CamelStore *store; + CamelFolder *folder; + + mail_tool_camel_lock_up(); + + store = camel_session_get_store (session, url, ex); + if (!store) { + mail_tool_camel_lock_down(); + return NULL; + } + + folder = camel_store_get_inbox (store, ex); + camel_object_unref (CAMEL_OBJECT (store)); + mail_tool_camel_lock_down(); + + return folder; } @@ -296,35 +302,6 @@ mail_tool_filter_get_folder_func (CamelFilterDriver *d, const char *uri, void *d } CamelFolder * -mail_tool_get_root_of_store (const char *source_uri, CamelException *ex) -{ - CamelStore *store; - CamelFolder *folder; - - mail_tool_camel_lock_up(); - - store = camel_session_get_store (session, source_uri, ex); - if (!store) { - mail_tool_camel_lock_down (); - return NULL; - } - - /*camel_service_connect (CAMEL_SERVICE (store), ex); - *if (camel_exception_is_set (ex)) { - * camel_object_unref (CAMEL_OBJECT (store)); - * mail_tool_camel_lock_down(); - * return NULL; - *} - */ - - folder = camel_store_get_root_folder (store, ex); - camel_object_unref (CAMEL_OBJECT (store)); - mail_tool_camel_lock_down(); - - return folder; -} - -CamelFolder * mail_tool_uri_to_folder (const char *uri, CamelException *ex) { CamelURL *url; diff --git a/mail/mail-tools.h b/mail/mail-tools.h index 4601b71dc1..87fd6a5f79 100644 --- a/mail/mail-tools.h +++ b/mail/mail-tools.h @@ -75,10 +75,6 @@ mail_tool_generate_forward_subject (CamelMimeMessage *msg); CamelMimePart * mail_tool_make_message_attachment (CamelMimeMessage *message); -/* Get the root folder of the store specified by @source_uri */ -CamelFolder * -mail_tool_get_root_of_store (const char *source_uri, CamelException *ex); - /* Parse the ui into a real CamelFolder any way we know how. */ CamelFolder * mail_tool_uri_to_folder (const char *uri, CamelException *ex); diff --git a/mail/message-list.c b/mail/message-list.c index f4cefc8788..1344fd381c 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -774,8 +774,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) MessageList *message_list = model_data; char *uid; static char *saved; - CamelMessageInfo *info; - static CamelMessageInfo *msg_info; + CamelMessageInfo *msg_info; + void *value; /* simlated(tm) static dynamic memory (sigh) */ if (saved) { @@ -795,23 +795,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) } uid = id_uid(uid); - /* we need ot keep the msg_info ref'd as we return the data, sigh. - - Well, since we have it around, also check to see if its the same - one each call, and save the folder lookup */ - if (msg_info == NULL || strcmp(camel_message_info_uid(msg_info), uid) != 0) { - /* FIXME: what if the folder changes? Nothing sets the folder - yet, but this probably means we need to cache this inside the ml itself */ - if (msg_info) - camel_folder_free_message_info(message_list->folder, msg_info); + msg_info = camel_folder_get_message_info (message_list->folder, uid); - msg_info = camel_folder_get_message_info (message_list->folder, uid); - if (msg_info == NULL) { - g_warning("UID for message-list not found in folder: %s", uid); - return NULL; - } - } - switch (col){ case COL_MESSAGE_STATUS: { ETreePath *child; @@ -826,15 +811,17 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) } if (msg_info->flags & CAMEL_MESSAGE_ANSWERED) - return GINT_TO_POINTER (2); + value = GINT_TO_POINTER (2); else if (msg_info->flags & CAMEL_MESSAGE_SEEN) - return GINT_TO_POINTER (1); + value = GINT_TO_POINTER (1); else - return GINT_TO_POINTER (0); + value = GINT_TO_POINTER (0); + break; } case COL_FLAGGED: - return (void *)((msg_info->flags & CAMEL_MESSAGE_FLAGGED) != 0); + value = GINT_TO_POINTER ((msg_info->flags & CAMEL_MESSAGE_FLAGGED) != 0); + break; case COL_SCORE: { @@ -845,32 +832,44 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) if (tag) score = atoi (tag); - return GINT_TO_POINTER (score); + value = GINT_TO_POINTER (score); + break; } case COL_ATTACHMENT: - return (void *)((msg_info->flags & CAMEL_MESSAGE_ATTACHMENTS) != 0); - + value = GINT_TO_POINTER ((msg_info->flags & CAMEL_MESSAGE_ATTACHMENTS) != 0); + break; + case COL_FROM: - return (char *)camel_message_info_from(msg_info); + saved = g_strdup (camel_message_info_from(msg_info)); + value = saved; + break; case COL_SUBJECT: - return (char *)camel_message_info_subject(msg_info); + saved = g_strdup (camel_message_info_subject(msg_info)); + value = saved; + break; case COL_SENT: - return GINT_TO_POINTER (msg_info->date_sent); + value = GINT_TO_POINTER (msg_info->date_sent); + break; case COL_RECEIVED: - return GINT_TO_POINTER (msg_info->date_received); + value = GINT_TO_POINTER (msg_info->date_received); + break; case COL_TO: - return (char *)camel_message_info_to(msg_info); + saved = g_strdup (camel_message_info_to(msg_info)); + value = saved; + break; case COL_SIZE: - return GINT_TO_POINTER (msg_info->size); + value = GINT_TO_POINTER (msg_info->size); + break; case COL_DELETED: - return (void *)((msg_info->flags & CAMEL_MESSAGE_DELETED) != 0); + value = GINT_TO_POINTER ((msg_info->flags & CAMEL_MESSAGE_DELETED) != 0); + break; case COL_UNREAD: { ETreePath *child; @@ -881,7 +880,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) return (void *)subtree_unread(message_list, child); } - return GINT_TO_POINTER (!(msg_info->flags & CAMEL_MESSAGE_SEEN)); + value = GINT_TO_POINTER (!(msg_info->flags & CAMEL_MESSAGE_SEEN)); + break; } case COL_COLOUR: { @@ -889,16 +889,21 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) colour = camel_tag_get ((CamelTag **) &msg_info->user_tags, "colour"); - if (colour) - return (void *)colour; - else if (msg_info->flags & CAMEL_MESSAGE_FLAGGED) + if (colour) { + saved = g_strdup (colour); + value = saved; + } else if (msg_info->flags & CAMEL_MESSAGE_FLAGGED) /* FIXME: extract from the xpm somehow. */ - return "#A7453E"; + value = "#A7453E"; else - return NULL; + value = NULL; + break; } } + camel_folder_free_message_info(message_list->folder, msg_info); + return value; + g_assert_not_reached (); fake: @@ -940,10 +945,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) if ( (child = e_tree_model_node_get_first_child(etm, path)) && (uid = e_tree_model_node_get_data (etm, child)) && id_is_uid(uid) - && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { + && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { /* well, we could scan more children, build up a (more accurate) list, but this should do ok */ - saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(info)); - camel_folder_free_message_info(message_list->folder, info); + saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(msg_info)); + camel_folder_free_message_info(message_list->folder, msg_info); } else { return _("<unknown>"); } @@ -956,10 +961,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) if ( (child = e_tree_model_node_get_first_child(etm, path)) && (uid = e_tree_model_node_get_data (etm, child)) && id_is_uid(uid) - && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { + && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { /* well, we could scan more children, build up a (more accurate) list, but this should do ok */ - saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(info)); - camel_folder_free_message_info(message_list->folder, info); + saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(msg_info)); + camel_folder_free_message_info(message_list->folder, msg_info); } else { return _("<unknown>"); } |