** See bug #53553.
authorNot Zed <NotZed@Ximian.com>
Thu, 5 Feb 2004 05:14:04 +0000 (05:14 +0000)
committerMichael Zucci <zucchi@src.gnome.org>
Thu, 5 Feb 2004 05:14:04 +0000 (05:14 +0000)
2004-02-05  Not Zed  <NotZed@Ximian.com>

        ** See bug #53553.

        * camel-provider.c (camel_provider_init): changed to return a
        hashtable of url protocols to CamelProviderModule structs, rather
        than simple strings.

        * camel-session.c (get_provider): if we load a provider module,
        mark it as loaded.
        (ensure_loaded): Check the module loaded flag before trying to
        load it.

        * providers/local/libcamellocal.urls: Remove spoold from the list,
        since it doesn't exist anymore.  Actually fixes #53553, the rest
        is to robustify the code.

2004-02-05  Not Zed  <NotZed@Ximian.com>

        * camel-session.c (CS_CLASS): dont typecheck cast.

        * camel-store.c (camel_vjunk_folder_new): removed, use
        vtrash_new(junk).
        (setup_special): changed to get_special, with a type now, and
        dont add vtrash folders to the sources.
        (get_trash, get_junk): down to 1 liners, call get_special

        * camel-vtrash-folder.c (CF_CLASS): dont use cast typecheck macros
        here, makes debugging easier and removes redundant checks.
        (camel_vtrash_folder_init): dont set flags here.
        (camel_vtrash_folder_new): takes a new argument, type, for junk
        folders too, removed name arg (taken from type).
        (vtrash_transfer_messages_to): parameterise flag processing.

camel/ChangeLog
camel/camel-provider.c
camel/camel-provider.h
camel/camel-service.c
camel/camel-session.c
camel/camel-store.c
camel/camel-vtrash-folder.c
camel/camel-vtrash-folder.h
camel/providers/local/camel-local-provider.c
camel/providers/local/libcamellocal.urls

index c048f2f..1e5cda0 100644 (file)
@@ -1,3 +1,37 @@
+2004-02-05  Not Zed  <NotZed@Ximian.com>
+
+       ** See bug #53553.
+       
+       * camel-provider.c (camel_provider_init): changed to return a
+       hashtable of url protocols to CamelProviderModule structs, rather
+       than simple strings.
+
+       * camel-session.c (get_provider): if we load a provider module,
+       mark it as loaded.
+       (ensure_loaded): Check the module loaded flag before trying to
+       load it.
+
+       * providers/local/libcamellocal.urls: Remove spoold from the list,
+       since it doesn't exist anymore.  Actually fixes #53553, the rest
+       is to robustify the code.
+
+2004-02-05  Not Zed  <NotZed@Ximian.com>
+
+       * camel-session.c (CS_CLASS): dont typecheck cast.
+
+       * camel-store.c (camel_vjunk_folder_new): removed, use
+       vtrash_new(junk).
+       (setup_special): changed to get_special, with a type now, and
+       dont add vtrash folders to the sources.
+       (get_trash, get_junk): down to 1 liners, call get_special
+
+       * camel-vtrash-folder.c (CF_CLASS): dont use cast typecheck macros
+       here, makes debugging easier and removes redundant checks.
+       (camel_vtrash_folder_init): dont set flags here.
+       (camel_vtrash_folder_new): takes a new argument, type, for junk
+       folders too, removed name arg (taken from type).
+       (vtrash_transfer_messages_to): parameterise flag processing.
+
 2004-02-04  Jeffrey Stedfast  <fejj@ximian.com>
 
        * providers/imap/camel-imap-store.c: Get rid of some unnecessary
index 321b307..ccbb286 100644 (file)
@@ -65,7 +65,8 @@ camel_provider_init (void)
        DIR *dir;
        struct dirent *d;
        char *p, *name, buf[80];
-       
+       CamelProviderModule *m;
+
        providers = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
        
        dir = opendir (CAMEL_PROVIDERDIR);
@@ -93,17 +94,24 @@ camel_provider_init (void)
                
                p = strrchr (name, '.');
                strcpy (p, ".so");
+
+               m = g_malloc0(sizeof(*m));
+               m->path = name;
+
                while ((fgets (buf, sizeof (buf), fp))) {
                        buf[sizeof (buf) - 1] = '\0';
                        p = strchr (buf, '\n');
                        if (p)
                                *p = '\0';
                        
-                       if (*buf)
-                               g_hash_table_insert (providers, g_strdup (buf), g_strdup (name));
+                       if (*buf) {
+                               char *protocol = g_strdup(buf);
+
+                               m->types = g_slist_prepend(m->types, protocol);
+                               g_hash_table_insert(providers, protocol, m);
+                       }
                }
-               
-               g_free (name);
+
                fclose (fp);
        }
 
index 98c5a3e..fb64143 100644 (file)
@@ -184,6 +184,14 @@ typedef struct {
        char *translation_domain;
 } CamelProvider;
 
+typedef struct _CamelProviderModule CamelProviderModule;
+
+struct _CamelProviderModule {
+       char *path;
+       GSList *types;
+       int loaded:1;
+};
+
 GHashTable *camel_provider_init (void);
 void camel_provider_load (CamelSession *session, const char *path, CamelException *ex);
 
index b5f5b4b..bb43b60 100644 (file)
@@ -102,7 +102,7 @@ static void
 camel_service_finalize (CamelObject *object)
 {
        CamelService *service = CAMEL_SERVICE (object);
-       
+
        if (service->status == CAMEL_SERVICE_CONNECTED) {
                CamelException ex;
                
index 8b22689..2672c0a 100644 (file)
@@ -47,7 +47,7 @@
 
 #define d(x)
 
-#define CS_CLASS(so) CAMEL_SESSION_CLASS (CAMEL_OBJECT_GET_CLASS (so))
+#define CS_CLASS(so) ((CamelSessionClass *)((CamelObject *)so)->klass)
 
 static void register_provider (CamelSession *session, CamelProvider *provider);
 static GList *list_providers (CamelSession *session, gboolean load);
@@ -254,16 +254,16 @@ static void
 ensure_loaded (gpointer key, gpointer value, gpointer user_data)
 {
        CamelSession *session = user_data;
-       char *name = key;
-       char *path = value;
+       CamelProviderModule *m = value;
+       CamelException ex;
 
-       if (!g_hash_table_lookup (session->providers, name)) {
-               CamelException ex;
+       if (m->loaded)
+               return;
 
-               camel_exception_init (&ex);
-               camel_provider_load (session, path, &ex);
-               camel_exception_clear (&ex);
-       }
+       m->loaded = 1;
+       camel_exception_init(&ex);
+       camel_provider_load(session, m->path, &ex);
+       camel_exception_clear(&ex);
 }
 
 static gint
@@ -333,11 +333,12 @@ get_provider (CamelSession *session, const char *url_string, CamelException *ex)
        provider = g_hash_table_lookup (session->providers, protocol);
        if (!provider) {
                /* See if there's one we can load. */
-               char *path;
+               CamelProviderModule *m;
 
-               path = g_hash_table_lookup (session->modules, protocol);
-               if (path) {
-                       camel_provider_load (session, path, ex);
+               m = g_hash_table_lookup (session->modules, protocol);
+               if (m && !m->loaded) {
+                       m->loaded = 1;
+                       camel_provider_load (session, m->path, ex);
                        if (camel_exception_is_set (ex)) {
                                g_free (protocol);
                                return NULL;
@@ -407,7 +408,7 @@ get_service (CamelSession *session, const char *url_string,
                camel_url_free (url);
                return NULL;
        }
-       
+
        /* If the provider doesn't use paths but the URL contains one,
         * ignore it.
         */
@@ -429,7 +430,7 @@ get_service (CamelSession *session, const char *url_string,
                        camel_object_bag_add(provider->service_cache[type], url, service);
                }
        }
-done:
+
        camel_url_free (url);
 
        return service;
index 556d8da..d4ebdc8 100644 (file)
@@ -517,53 +517,35 @@ camel_store_get_inbox (CamelStore *store, CamelException *ex)
        return folder;
 }
 
-/* FIXME: derive vjunk folder object from vee_folder */
-#include "camel-vee-store.h"
 static CamelFolder *
-camel_vjunk_folder_new (CamelStore *parent_store, const char *name)
+get_special(CamelStore *store, enum _camel_vtrash_folder_t type)
 {
-       CamelFolder *vjunk;
-       
-       vjunk = (CamelFolder *)camel_object_new (camel_vee_folder_get_type ());
-       vjunk->folder_flags |= CAMEL_FOLDER_IS_JUNK;
-       camel_vee_folder_construct (CAMEL_VEE_FOLDER (vjunk), parent_store, name,
-                                   CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO);
-       camel_vee_folder_set_expression((CamelVeeFolder *)vjunk, "(match-all (system-flag \"Junk\"))");
-
-       return vjunk;
-}
-
-static void
-setup_special(CamelStore *store, CamelFolder *folder)
-{
-       GPtrArray *folders = camel_object_bag_list(store->folders);
+       CamelFolder *folder;
+       GPtrArray *folders;
        int i;
 
+       folder = camel_vtrash_folder_new(store, type);
+       folders = camel_object_bag_list(store->folders);
        for (i=0;i<folders->len;i++) {
-               camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]);
+               if (!CAMEL_IS_VTRASH_FOLDER(folders->pdata[i]))
+                       camel_vee_folder_add_folder((CamelVeeFolder *)folder, (CamelFolder *)folders->pdata[i]);
                camel_object_unref(folders->pdata[i]);
        }
        g_ptr_array_free(folders, TRUE);
+
+       return folder;
 }
 
 static CamelFolder *
 get_trash(CamelStore *store, CamelException *ex)
 {
-       CamelFolder *folder = camel_vtrash_folder_new(store, CAMEL_VTRASH_NAME);
-
-       setup_special(store, folder);
-
-       return folder;
+       return get_special(store, CAMEL_VTRASH_FOLDER_TRASH);
 }
 
 static CamelFolder *
 get_junk(CamelStore *store, CamelException *ex)
 {
-       CamelFolder *folder = camel_vjunk_folder_new(store, CAMEL_VJUNK_NAME);
-
-       setup_special(store, folder);
-
-       return folder;
+       return get_special(store, CAMEL_VTRASH_FOLDER_JUNK);
 }
 
 /** 
index aa21ce3..cd5df81 100644 (file)
 #include <string.h>
 
 /* Returns the class for a CamelFolder */
-#define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so))
+#define CF_CLASS(so) ((CamelFolderClass *)((CamelObject *)(so))->klass)
+
+static struct {
+       const char *name;
+       const char *expr;
+       guint32 bit;
+       guint32 flags;
+} vdata[] = {
+       { CAMEL_VTRASH_NAME, "(match-all (system-flag \"Deleted\"))", CAMEL_MESSAGE_DELETED, CAMEL_FOLDER_IS_TRASH },
+       { CAMEL_VJUNK_NAME, "(match-all (system-flag \"Junk\"))", CAMEL_MESSAGE_JUNK, CAMEL_FOLDER_IS_JUNK },
+};
 
 static CamelVeeFolderClass *camel_vtrash_folder_parent;
 
@@ -56,9 +66,7 @@ camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass)
 static void
 camel_vtrash_folder_init (CamelVTrashFolder *vtrash)
 {
-       CamelFolder *folder = CAMEL_FOLDER (vtrash);
-
-       folder->folder_flags |= CAMEL_FOLDER_IS_TRASH;
+       /*CamelFolder *folder = CAMEL_FOLDER (vtrash);*/
 }
 
 CamelType
@@ -83,7 +91,7 @@ camel_vtrash_folder_get_type (void)
 /**
  * camel_vtrash_folder_new:
  * @parent_store: the parent CamelVeeStore
- * @name: the vfolder name
+ * @type: type of vfolder, CAMEL_VTRASH_FOLDER_TRASH or CAMEL_VTRASH_FOLDER_JUNK currently.
  * @ex: a CamelException
  *
  * Create a new CamelVeeFolder object.
@@ -91,16 +99,21 @@ camel_vtrash_folder_get_type (void)
  * Return value: A new CamelVeeFolder widget.
  **/
 CamelFolder *
-camel_vtrash_folder_new (CamelStore *parent_store, const char *name)
+camel_vtrash_folder_new (CamelStore *parent_store, enum _camel_vtrash_folder_t type)
 {
-       CamelFolder *vtrash;
+       CamelVTrashFolder *vtrash;
        
-       vtrash = (CamelFolder *)camel_object_new (camel_vtrash_folder_get_type ());
-       camel_vee_folder_construct (CAMEL_VEE_FOLDER (vtrash), parent_store, name,
-                                   CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO);
-       camel_vee_folder_set_expression((CamelVeeFolder *)vtrash, "(match-all (system-flag \"Deleted\"))");
+       g_assert(type < CAMEL_VTRASH_FOLDER_LAST);
+
+       vtrash = (CamelVTrashFolder *)camel_object_new(camel_vtrash_folder_get_type());
+       camel_vee_folder_construct(CAMEL_VEE_FOLDER (vtrash), parent_store, vdata[type].name,
+                                  CAMEL_STORE_FOLDER_PRIVATE|CAMEL_STORE_FOLDER_CREATE|CAMEL_STORE_VEE_FOLDER_AUTO);
 
-       return vtrash;
+       ((CamelFolder *)vtrash)->folder_flags |= vdata[type].flags;
+       camel_vee_folder_set_expression((CamelVeeFolder *)vtrash, vdata[type].expr);
+       vtrash->bit = vdata[type].bit;
+
+       return (CamelFolder *)vtrash;
 }
 
 static void
@@ -143,6 +156,7 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
        GHashTable *batch = NULL;
        const char *tuid;
        struct _transfer_data *md;
+       guint32 sbit = ((CamelVTrashFolder *)source)->bit;
 
        /* This is a special case of transfer_messages_to: Either the
         * source or the destination is a vtrash folder (but not both
@@ -157,14 +171,12 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
                if (!delete_originals)
                        return;
 
-               /* Move to trash is the same as deleting the message */
+               /* Move to trash is the same as setting the message flag */
                for (i = 0; i < uids->len; i++)
-                       camel_folder_delete_message (source, uids->pdata[i]);
+                       camel_folder_set_message_flags(source, uids->pdata[i], sbit, ~0);
                return;
        }
 
-       g_return_if_fail (CAMEL_IS_VTRASH_FOLDER (source));
-
        /* Moving/Copying from the trash to the original folder = undelete.
         * Moving/Copying from the trash to a different folder = move/copy.
         *
@@ -179,8 +191,8 @@ vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
                }
                
                if (dest == mi->folder) {
-                       /* Just undelete the original message */
-                       camel_folder_set_message_flags (source, uids->pdata[i], CAMEL_MESSAGE_DELETED, 0);
+                       /* Just unset the flag on the original message */
+                       camel_folder_set_message_flags (source, uids->pdata[i], sbit, 0);
                } else {
                        if (batch == NULL)
                                batch = g_hash_table_new(NULL, NULL);
index 089c969..a640569 100644 (file)
@@ -32,9 +32,6 @@ extern "C" {
 #include <camel/camel-folder.h>
 #include <camel/camel-vee-folder.h>
 
-#define CAMEL_VTRASH_NAME "Trash"
-#define CAMEL_VJUNK_NAME "Junk"
-
 #define CAMEL_VTRASH_FOLDER(obj)         CAMEL_CHECK_CAST (obj, camel_vtrash_folder_get_type (), CamelVTrashFolder)
 #define CAMEL_VTRASH_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vtrash_folder_get_type (), CamelVTrashFolderClass)
 #define CAMEL_IS_VTRASH_FOLDER(obj)      CAMEL_CHECK_TYPE (obj, camel_vtrash_folder_get_type ())
@@ -42,9 +39,19 @@ extern "C" {
 typedef struct _CamelVTrashFolder      CamelVTrashFolder;
 typedef struct _CamelVTrashFolderClass CamelVTrashFolderClass;
 
+#define CAMEL_VTRASH_NAME "Trash"
+#define CAMEL_VJUNK_NAME "Junk"
+
+enum _camel_vtrash_folder_t {
+       CAMEL_VTRASH_FOLDER_TRASH,
+       CAMEL_VTRASH_FOLDER_JUNK,
+       CAMEL_VTRASH_FOLDER_LAST
+};
+
 struct _CamelVTrashFolder {
        CamelVeeFolder parent;
-       
+
+       guint32 bit;
 };
 
 struct _CamelVTrashFolderClass {
@@ -54,7 +61,7 @@ struct _CamelVTrashFolderClass {
 
 CamelType       camel_vtrash_folder_get_type    (void);
 
-CamelFolder    *camel_vtrash_folder_new                (CamelStore *parent_store, const char *name);
+CamelFolder    *camel_vtrash_folder_new                (CamelStore *parent_store, enum _camel_vtrash_folder_t type);
 
 #ifdef __cplusplus
 }
index a52dfbd..fc33f34 100644 (file)
@@ -192,7 +192,12 @@ local_url_equal(const void *v, const void *v2)
 void camel_provider_module_init(CamelSession * session)
 {
        char *path;
-       
+       static int init = 0;
+
+       if (init)
+               abort();
+       init = 1;
+
        mh_conf_entries[0].value = "";  /* default path */
        mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type ();
        mh_provider.url_hash = local_url_hash;