diff options
author | Not Zed <NotZed@HelixCode.com> | 2000-12-11 12:14:45 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2000-12-11 12:14:45 +0800 |
commit | ffc70650c181db4dcfaf85d319cad74aaa6ee8d2 (patch) | |
tree | 997e6da962c5783bc89d7f6fb4ed3ece6542fa64 | |
parent | 154f1347bdec7a894ba253bc0b5f8d33e3bc4b24 (diff) | |
download | gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar.gz gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar.bz2 gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar.lz gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar.xz gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.tar.zst gsoc2013-evolution-ffc70650c181db4dcfaf85d319cad74aaa6ee8d2.zip |
reordered the options and added maildir, mbox, maildir, mh, in that order.
2000-12-11 Not Zed <NotZed@HelixCode.com>
* local-config.glade: reordered the options and added maildir,
mbox, maildir, mh, in that order.
* mail-local.c (reconfigure_clicked): Added maildir, re-ordered to
match the changed xml file too.
(do_reconfigure_folder): WHoever 'threaded' this code forgot to
check that folder_browser functions shouldn't be called here.
(cleanup_reconfigure_folder): Call it here instead.
(lookup_folder): Blah blah, we have to lookup the folder and
verify its still the same format, joy. Becaause someone thought
it would be wise to make the code 5x more complicated for no
reason, and totally break 'mail reconfigure' in the process. i'm
really happy about that one.
(cleanup_register_folder): Uh, yeah, so like, the
local_store->folders hashtable is supposed to point to like,
LocalFolders, not CamelFolders.
(free_local_folder): Free the localfolder struct properly.
(free_folder): Call above to free data properly.
(get_folder): Fix for fixing folders hashtable.
(local_storage_removed_folder_cb): Same here.
(local_storage_new_folder_cb): Ref the local_store when putting it
in the local_folder.
(cleanup_register_folder): Properly free the local_folder if the
op failed.
(free_local_folder): Unhook events also.
svn path=/trunk/; revision=6898
-rw-r--r-- | mail/ChangeLog | 28 | ||||
-rw-r--r-- | mail/local-config.glade | 5 | ||||
-rw-r--r-- | mail/mail-local.c | 197 |
3 files changed, 181 insertions, 49 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index 38b605ffd8..d346ca6e74 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,31 @@ +2000-12-11 Not Zed <NotZed@HelixCode.com> + + * local-config.glade: reordered the options and added maildir, + mbox, maildir, mh, in that order. + + * mail-local.c (reconfigure_clicked): Added maildir, re-ordered to + match the changed xml file too. + (do_reconfigure_folder): WHoever 'threaded' this code forgot to + check that folder_browser functions shouldn't be called here. + (cleanup_reconfigure_folder): Call it here instead. + (lookup_folder): Blah blah, we have to lookup the folder and + verify its still the same format, joy. Becaause someone thought + it would be wise to make the code 5x more complicated for no + reason, and totally break 'mail reconfigure' in the process. i'm + really happy about that one. + (cleanup_register_folder): Uh, yeah, so like, the + local_store->folders hashtable is supposed to point to like, + LocalFolders, not CamelFolders. + (free_local_folder): Free the localfolder struct properly. + (free_folder): Call above to free data properly. + (get_folder): Fix for fixing folders hashtable. + (local_storage_removed_folder_cb): Same here. + (local_storage_new_folder_cb): Ref the local_store when putting it + in the local_folder. + (cleanup_register_folder): Properly free the local_folder if the + op failed. + (free_local_folder): Unhook events also. + 2000-12-09 Christopher James Lahey <clahey@helixcode.com> * message-list.c (message_list_init): Change the "drawfocus" diff --git a/mail/local-config.glade b/mail/local-config.glade index 8f3a1a4cda..890f55144d 100644 --- a/mail/local-config.glade +++ b/mail/local-config.glade @@ -174,8 +174,9 @@ <class>GtkOptionMenu</class> <name>option_format</name> <can_focus>True</can_focus> - <items>mh -mbox + <items>mbox +maildir +mh </items> <initial_choice>0</initial_choice> <child> diff --git a/mail/mail-local.c b/mail/mail-local.c index 0eff59e77d..ad80f11e64 100644 --- a/mail/mail-local.c +++ b/mail/mail-local.c @@ -52,7 +52,7 @@ #include "mail-threads.h" #include "folder-browser.h" -#define d(x) +#define d(x) x /* Local folder metainfo */ @@ -231,7 +231,6 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) char *metapath; char *tmpname; - char *uri; CamelURL *url = NULL; struct _local_meta *meta; guint32 flags; @@ -338,12 +337,6 @@ do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) } free_metainfo(meta); - /* 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); - /* and unref our copy of the new folder ... */ cleanup: if (tofolder) @@ -364,6 +357,7 @@ 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); @@ -371,6 +365,12 @@ cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException "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); + gtk_object_unref (GTK_OBJECT (input->fb)); g_free (input->newtype); } @@ -390,12 +390,12 @@ reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data if (button == 0) { GtkMenu *menu; int type; - char *types[] = { "mh", "mbox" }; + 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 > 1) - type = 1; + if (type < 0 || type > 2) + type = 0; gtk_widget_set_sensitive(data->frame, FALSE); gtk_widget_set_sensitive(data->apply, FALSE); @@ -409,6 +409,9 @@ reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data gnome_dialog_close(d); } +/* kills a very annoying warning */ +void local_reconfigure_folder(FolderBrowser *fb); + void local_reconfigure_folder(FolderBrowser *fb) { @@ -448,7 +451,6 @@ local_reconfigure_folder(FolderBrowser *fb) /* 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)) #define MAIL_LOCAL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), MAIL_LOCAL_STORE_TYPE, MailLocalStoreClass)) @@ -462,7 +464,8 @@ typedef struct { char *local_path; int local_pathlen; - GHashTable *folders, *unread; + GHashTable *folders, /* points to MailLocalFolder */ + *unread; } MailLocalStore; typedef struct { @@ -476,17 +479,18 @@ typedef struct { int last_unread; } MailLocalFolder; +static void local_folder_changed_proxy (CamelObject *folder, gpointer event_data, gpointer user_data); + CamelType mail_local_store_get_type (void); -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 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; static void mail_local_store_class_init (MailLocalStoreClass *mail_local_store_class) @@ -503,6 +507,9 @@ mail_local_store_class_init (MailLocalStoreClass *mail_local_store_class) 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 ()); } static void @@ -514,13 +521,29 @@ mail_local_store_init (gpointer object, gpointer klass) } static void +free_local_folder(MailLocalFolder *lf) +{ + if (lf->folder) { + camel_object_unhook_event((CamelObject *)lf->folder, + "folder_changed", local_folder_changed_proxy, + lf); + camel_object_unhook_event((CamelObject *)lf->folder, + "message_changed", local_folder_changed_proxy, + lf); + camel_object_unref((CamelObject *)lf->folder); + } + g_free(lf->path); + g_free(lf->name); + camel_object_unref((CamelObject *)lf->local_store); +} + +static void free_folder (gpointer key, gpointer data, gpointer user_data) { MailLocalFolder *lf = data; - g_free (key); - camel_object_unref (CAMEL_OBJECT (lf->folder)); - g_free (lf->path); + g_free(key); + free_local_folder(lf); } static void @@ -564,19 +587,103 @@ 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) { MailLocalStore *local_store = (MailLocalStore *)store; CamelFolder *folder; + MailLocalFolder *local_folder; - folder = g_hash_table_lookup (local_store->folders, folder_name); - if (folder) + local_folder = g_hash_table_lookup (local_store->folders, folder_name); + if (local_folder) { + folder = local_folder->folder; camel_object_ref (CAMEL_OBJECT (folder)); - else { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - "No such folder %s", folder_name); + } else { + folder = NULL; + camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, "No such folder %s", folder_name); } return folder; } @@ -632,8 +739,7 @@ local_folder_changed (CamelObject *object, gpointer event_data, CORBA_exception_init (&ev); if (unread > 0) { - display = g_strdup_printf ("%s (%d)", - local_folder->name, unread); + display = g_strdup_printf ("%s (%d)", local_folder->name, unread); GNOME_Evolution_LocalStorage_updateFolder ( local_folder->local_store->corba_local_storage, local_folder->path, display, TRUE, &ev); @@ -651,8 +757,7 @@ local_folder_changed (CamelObject *object, gpointer event_data, } static void -local_folder_changed_proxy (CamelObject *folder, gpointer event_data, - gpointer user_data) +local_folder_changed_proxy (CamelObject *folder, gpointer event_data, gpointer user_data) { int unread; @@ -685,6 +790,7 @@ do_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) name = g_strdup_printf ("%s:/%s", meta->format, local_folder->name); store = camel_session_get_store (session, name, ex); + printf("getting new store %s = %p\n", name, store); g_free (name); if (!store) { free_metainfo (meta); @@ -695,26 +801,23 @@ 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); + local_folder->last_unread = camel_folder_get_unread_message_count(local_folder->folder); camel_object_unref (CAMEL_OBJECT (store)); free_metainfo (meta); } static void -cleanup_register_folder (gpointer in_data, gpointer op_data, - CamelException *ex) +cleanup_register_folder (gpointer in_data, gpointer op_data, CamelException *ex) { MailLocalFolder *local_folder = in_data; int unread; if (!local_folder->folder) { - g_free (local_folder); + free_local_folder(local_folder); return; } - g_hash_table_insert (local_folder->local_store->folders, - local_folder->name, local_folder->folder); + g_hash_table_insert (local_folder->local_store->folders, local_folder->name, local_folder); local_folder->name = strrchr (local_folder->path, '/') + 1; camel_object_hook_event (CAMEL_OBJECT (local_folder->folder), @@ -725,8 +828,7 @@ cleanup_register_folder (gpointer in_data, gpointer op_data, 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); + local_folder_changed (CAMEL_OBJECT (local_folder->folder), GINT_TO_POINTER (unread), local_folder); } static const mail_operation_spec op_register_folder = @@ -757,6 +859,7 @@ local_storage_new_folder_cb (EvolutionStorageListener *storage_listener, local_folder->name = g_strdup (folder->physical_uri + 8); local_folder->path = g_strdup (path); local_folder->local_store = local_store; + camel_object_ref((CamelObject *)local_store); mail_operation_queue (&op_register_folder, local_folder, FALSE); } @@ -766,7 +869,7 @@ local_storage_removed_folder_cb (EvolutionStorageListener *storage_listener, void *data) { MailLocalStore *local_store = data; - CamelFolder *folder; + MailLocalFolder *local_folder; if (strncmp (path, "file://", 7) != 0 || strncmp (path + 7, local_store->local_path, @@ -775,10 +878,10 @@ local_storage_removed_folder_cb (EvolutionStorageListener *storage_listener, path += 7 + local_store->local_pathlen; - folder = g_hash_table_lookup (local_store->folders, path); - if (folder) { - camel_object_unref (CAMEL_OBJECT (folder)); + local_folder = g_hash_table_lookup (local_store->folders, path); + if (local_folder) { g_hash_table_remove (local_store->folders, path); + free_local_folder(local_folder); } } |