diff options
author | Dan Winship <danw@src.gnome.org> | 2000-10-03 03:08:20 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2000-10-03 03:08:20 +0800 |
commit | e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2 (patch) | |
tree | e70ca64851c0167f959a9e6c0c38179cd0de102b | |
parent | 46d07e9e465e336a5c39d8c27c846cb380fbc6fb (diff) | |
download | gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.gz gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.bz2 gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.lz gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.xz gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.zst gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.zip |
Remove camel_folder_{get,free}_subfolder_info, as we want to be able to
* camel-folder.[ch]: Remove
camel_folder_{get,free}_subfolder_info, as we want to be able to
scan the whole subfolder tree without having to open any folders,
so this needs to be in CamelStore. Remove can_hold_folders and
can_hold_messages flags; things that don't hold messages are no
longer considered CamelFolders.
* camel-folder-summary.[ch]: Remove CamelFolderInfo stuff.
* camel-store.[ch]: Add camel_store_{get,free}_folder_info, as
well as camel_store_free_folder_info_full and ..._nop for default
implementations, and camel_folder_info_free and
camel_folder_info_build as convenience functions. Turn
CamelFolderInfo into a tree structure and also add an "url"
member.
* providers/*/camel-*-folder.c: Remove subfolder_info and can_hold
stuff.
* providers/*/camel-*-store.c: Add folder_info stuff.
* providers/imap/camel-imap-folder.c (imap_summary_free): Free the
summary elements with camel_message_info_free, not
camel_folder_info_free. Oops.
* providers/imap/camel-imap-utils.c: const poison
svn path=/trunk/; revision=5663
-rw-r--r-- | camel/ChangeLog | 28 | ||||
-rw-r--r-- | camel/camel-folder-summary.c | 14 | ||||
-rw-r--r-- | camel/camel-folder-summary.h | 8 | ||||
-rw-r--r-- | camel/camel-folder.c | 86 | ||||
-rw-r--r-- | camel/camel-folder.h | 13 | ||||
-rw-r--r-- | camel/camel-store.c | 188 | ||||
-rw-r--r-- | camel/camel-store.h | 36 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 117 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.h | 2 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 194 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.c | 10 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-utils.h | 4 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 12 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.c | 24 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-folder.c | 12 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-store.c | 17 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-folder.c | 46 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 46 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-folder.c | 2 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-folder.c | 2 |
20 files changed, 511 insertions, 350 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index c39f93262d..958476ed03 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,31 @@ +2000-10-02 Dan Winship <danw@helixcode.com> + + * camel-folder.[ch]: Remove + camel_folder_{get,free}_subfolder_info, as we want to be able to + scan the whole subfolder tree without having to open any folders, + so this needs to be in CamelStore. Remove can_hold_folders and + can_hold_messages flags; things that don't hold messages are no + longer considered CamelFolders. + + * camel-folder-summary.[ch]: Remove CamelFolderInfo stuff. + + * camel-store.[ch]: Add camel_store_{get,free}_folder_info, as + well as camel_store_free_folder_info_full and ..._nop for default + implementations, and camel_folder_info_free and + camel_folder_info_build as convenience functions. Turn + CamelFolderInfo into a tree structure and also add an "url" + member. + + * providers/*/camel-*-folder.c: Remove subfolder_info and can_hold + stuff. + * providers/*/camel-*-store.c: Add folder_info stuff. + + * providers/imap/camel-imap-folder.c (imap_summary_free): Free the + summary elements with camel_message_info_free, not + camel_folder_info_free. Oops. + + * providers/imap/camel-imap-utils.c: const poison + 2000-09-28 Jeffrey Stedfast <fejj@helixcode.com> * providers/smtp/camel-smtp-transport.c: Fixed some memory leaks. diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index bde3059ab3..2653836b13 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -1505,20 +1505,6 @@ camel_message_info_free(CamelMessageInfo *mi) g_free(mi); } -/** - * camel_folder_info_free: - * @fi: the folder info - * - * Frees a CamelFolderInfo and its contents. - **/ -void -camel_folder_info_free(CamelFolderInfo *fi) -{ - g_free(fi->name); - g_free(fi->full_name); - g_free(fi); -} - #if 0 static void content_info_dump(CamelMessageContentInfo *ci, int depth) diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index d5bcbe5ee3..cebaaa7066 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -35,11 +35,6 @@ /*typedef struct _CamelFolderSummary CamelFolderSummary;*/ typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass; -typedef struct { - char *full_name, *name; - int message_count, unread_message_count; -} CamelFolderInfo; - /* A tree of message content info structures describe the content structure of the message (if it has any) */ typedef struct _CamelMessageContentInfo { @@ -231,7 +226,4 @@ void camel_tag_list_free(CamelTag **list); void camel_message_info_dup_to(const CamelMessageInfo *from, CamelMessageInfo *to); void camel_message_info_free(CamelMessageInfo *mi); -/* folder info utils */ -void camel_folder_info_free(CamelFolderInfo *fi); - #endif /* ! _CAMEL_FOLDER_SUMMARY_H */ diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 2904ac26d9..9b38f79e53 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -47,8 +47,6 @@ static const gchar *get_name (CamelFolder *folder); static const gchar *get_full_name (CamelFolder *folder); static CamelStore *get_parent_store (CamelFolder *folder); -static gboolean can_hold_folders (CamelFolder *folder); -static gboolean can_hold_messages (CamelFolder *folder); static guint32 get_permanent_flags (CamelFolder *folder); static guint32 get_message_flags (CamelFolder *folder, const char *uid); static void set_message_flags (CamelFolder *folder, const char *uid, @@ -59,10 +57,6 @@ static void set_message_user_flag (CamelFolder *folder, const char *uid, static const char *get_message_user_tag(CamelFolder *folder, const char *uid, const char *name); static void set_message_user_tag(CamelFolder *folder, const char *uid, const char *name, const char *value); -static GPtrArray *get_subfolder_info (CamelFolder *folder); -static void free_subfolder_info (CamelFolder *folder, - GPtrArray *array); - static gint get_message_count (CamelFolder *folder); static gint get_unread_message_count (CamelFolder *folder); @@ -126,10 +120,6 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_name = get_name; camel_folder_class->get_full_name = get_full_name; camel_folder_class->get_parent_store = get_parent_store; - camel_folder_class->can_hold_folders = can_hold_folders; - camel_folder_class->can_hold_messages = can_hold_messages; - camel_folder_class->get_subfolder_info = get_subfolder_info; - camel_folder_class->free_subfolder_info = free_subfolder_info; camel_folder_class->expunge = expunge; camel_folder_class->get_message_count = get_message_count; camel_folder_class->get_unread_message_count = get_unread_message_count; @@ -330,67 +320,6 @@ camel_folder_get_full_name (CamelFolder *folder) } -static gboolean -can_hold_folders (CamelFolder * folder) -{ - return folder->can_hold_folders; -} - -static gboolean -can_hold_messages (CamelFolder * folder) -{ - return folder->can_hold_messages; -} - - -static GPtrArray * -get_subfolder_info (CamelFolder *folder) -{ - g_warning ("CamelFolder::get_subfolder_info not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))); - return NULL; -} - -/** - * camel_folder_get_subfolder_info: - * @folder: the folder - * - * Return value: an array containing a CamelFolderInfo for each of - * @folder's subfolders. The array should not be modified and must be - * freed with camel_folder_free_subfolder_info(). - **/ -GPtrArray * -camel_folder_get_subfolder_info (CamelFolder *folder) -{ - g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL); - - return CF_CLASS (folder)->get_subfolder_info (folder); -} - - -static void -free_subfolder_info (CamelFolder *folder, GPtrArray *array) -{ - g_warning ("CamelFolder::free_subfolder_info not implemented " - "for `%s'", camel_type_to_name (CAMEL_OBJECT_GET_TYPE (folder))); -} - -/** - * camel_folder_free_subfolder_info: - * @folder: folder object - * @array: the array of subfolder info to free - * - * Frees the array of info returned by camel_folder_get_subfolder_info(). - **/ -void -camel_folder_free_subfolder_info (CamelFolder *folder, GPtrArray *array) -{ - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - CF_CLASS (folder)->free_subfolder_info (folder, array); -} - - static CamelStore * get_parent_store (CamelFolder * folder) { @@ -1152,12 +1081,11 @@ message_changed (CamelObject *obj, /*const char *uid*/gpointer event_data) /** * camel_folder_free_nop: * @folder: a folder - * @array: an array of uids, CamelFolderInfo, or CamelMessageInfo + * @array: an array of uids or CamelMessageInfo * * "Frees" the provided array by doing nothing. Used by CamelFolder - * subclasses as an implementation for free_uids, free_summary, - * or free_subfolder_info when the returned array is "static" - * information and should not be freed. + * subclasses as an implementation for free_uids, or free_summary when + * the returned array is "static" information and should not be freed. **/ void camel_folder_free_nop (CamelFolder *folder, GPtrArray *array) @@ -1168,12 +1096,12 @@ camel_folder_free_nop (CamelFolder *folder, GPtrArray *array) /** * camel_folder_free_shallow: * @folder: a folder - * @array: an array of uids, CamelFolderInfo, or CamelMessageInfo + * @array: an array of uids or CamelMessageInfo * * Frees the provided array but not its contents. Used by CamelFolder - * subclasses as an implementation for free_uids, free_summary, or - * free_subfolder_info when the returned array needs to be freed - * but its contents come from "static" information. + * subclasses as an implementation for free_uids or free_summary when + * the returned array needs to be freed but its contents come from + * "static" information. **/ void camel_folder_free_shallow (CamelFolder *folder, GPtrArray *array) diff --git a/camel/camel-folder.h b/camel/camel-folder.h index fe1ed75f0c..8e307cbe1b 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -54,8 +54,6 @@ struct _CamelFolder CamelStore *parent_store; guint32 permanent_flags; - gboolean can_hold_folders:1; - gboolean can_hold_messages:1; gboolean has_summary_capability:1; gboolean has_search_capability:1; }; @@ -74,13 +72,6 @@ typedef struct { CamelStore * (*get_parent_store) (CamelFolder *folder); - gboolean (*can_hold_folders) (CamelFolder *folder); - gboolean (*can_hold_messages) (CamelFolder *folder); - - GPtrArray * (*get_subfolder_info)(CamelFolder *folder); - void (*free_subfolder_info) (CamelFolder *folder, - GPtrArray *subfolders); - void (*expunge) (CamelFolder *folder, CamelException *ex); @@ -164,10 +155,6 @@ void camel_folder_construct (CamelFolder *folder, const char *full_name, const char *name); -GPtrArray * camel_folder_get_subfolder_info (CamelFolder *folder); -void camel_folder_free_subfolder_info (CamelFolder *folder, - GPtrArray *array); - void camel_folder_refresh_info (CamelFolder * folder, CamelException * ex); void camel_folder_sync (CamelFolder *folder, diff --git a/camel/camel-store.c b/camel/camel-store.c index 039490c088..15698ee4b3 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -25,6 +25,8 @@ * USA */ #include <config.h> +#include <string.h> + #include "camel-store.h" #include "camel-folder.h" #include "camel-exception.h" @@ -46,6 +48,11 @@ static char *get_folder_name (CamelStore *store, const char *folder_name, static char *get_root_folder_name (CamelStore *store, CamelException *ex); static char *get_default_folder_name (CamelStore *store, CamelException *ex); +static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex); +static void free_folder_info (CamelStore *store, CamelFolderInfo *tree); + static CamelFolder *lookup_folder (CamelStore *store, const char *folder_name); static void cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder); @@ -63,6 +70,8 @@ camel_store_class_init (CamelStoreClass *camel_store_class) camel_store_class->get_folder_name = get_folder_name; camel_store_class->get_root_folder_name = get_root_folder_name; camel_store_class->get_default_folder_name = get_default_folder_name; + camel_store_class->get_folder_info = get_folder_info; + camel_store_class->free_folder_info = free_folder_info; camel_store_class->lookup_folder = lookup_folder; camel_store_class->cache_folder = cache_folder; camel_store_class->uncache_folder = uncache_folder; @@ -370,3 +379,182 @@ camel_store_get_default_folder (CamelStore *store, CamelException *ex) } return folder; } + + +static CamelFolderInfo * +get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex) +{ + g_warning ("CamelStore::get_folder_info not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); + return NULL; +} + +/** + * camel_store_get_folder_info: + * @store: a CamelStore + * @top: the name of the folder to start from + * @fast: whether or not to do a "fast" scan. + * @recursive: whether to include information for subfolders + * @ex: a CamelException + * + * This fetches information about the folder structure of @store, + * starting with @top, and returns a tree of CamelFolderInfo + * structures. If @fast is %TRUE, the message_count or + * unread_message_count fields of some or all of the structures may be + * set to -1, if the store cannot determine that information quickly. + * If @recursive is %TRUE, the returned tree will include all levels of + * hierarchy below @top. If it is %FALSE, it will only include the + * immediate subfolders of @top. + * + * Return value: a CamelFolderInfo tree, which must be freed with + * camel_store_free_folder_info. + **/ +CamelFolderInfo * +camel_store_get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex) +{ + g_return_val_if_fail (CAMEL_IS_STORE (store), NULL); + + return CS_CLASS (store)->get_folder_info (store, top, fast, + recursive, ex); +} + + +static void +free_folder_info (CamelStore *store, CamelFolderInfo *fi) +{ + g_warning ("CamelStore::free_folder_info not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); +} + +/** + * camel_store_free_folder_info: + * @store: a CamelStore + * @tree: the tree returned by camel_store_get_folder_info() + * + * Frees the data returned by camel_store_get_folder_info(). + **/ +void +camel_store_free_folder_info (CamelStore *store, CamelFolderInfo *fi) +{ + g_return_if_fail (CAMEL_IS_STORE (store)); + + CS_CLASS (store)->free_folder_info (store, fi); +} + +/** + * camel_store_free_folder_info_full: + * @store: a CamelStore + * @tree: the tree returned by camel_store_get_folder_info() + * + * An implementation for CamelStore::free_folder_info. Frees all + * of the data. + **/ +void +camel_store_free_folder_info_full (CamelStore *store, CamelFolderInfo *fi) +{ + camel_folder_info_free (fi); +} + +/** + * camel_store_free_folder_info_nop: + * @store: a CamelStore + * @tree: the tree returned by camel_store_get_folder_info() + * + * An implementation for CamelStore::free_folder_info. Does nothing. + **/ +void +camel_store_free_folder_info_nop (CamelStore *store, CamelFolderInfo *fi) +{ + ; +} + + +/** + * camel_folder_info_free: + * @fi: the CamelFolderInfo + * + * Frees @fi. + **/ +void +camel_folder_info_free (CamelFolderInfo *fi) +{ + if (fi) { + camel_folder_info_free (fi->sibling); + camel_folder_info_free (fi->child); + g_free (fi->name); + g_free (fi->full_name); + g_free (fi->url); + g_free (fi); + } +} + + +/** + * camel_folder_info_build: + * @folders: an array of CamelFolderInfo + * @top: the top of the folder tree + * @separator: the hieararchy separator character + * @short_names: %TRUE if the (short) name of a folder is the part after + * the last @separator in the full name. %FALSE if it is the full name. + * + * This takes an array of folders and attaches them together. @top points + * to the (or at least, "a") top-level element of the tree: it may or may + * not also be an element of @folders. If necessary, camel_folder_info_build + * will create additional CamelFolderInfo with %NULL urls to fill in gaps + * in the tree. The value of @short_names is used in constructing the + * names of these intermediate folders. + **/ +void +camel_folder_info_build (GPtrArray *folders, CamelFolderInfo *top, + char separator, gboolean short_names) +{ + CamelFolderInfo *fi, *pfi; + GHashTable *hash; + char *p, *pname; + int i; + + /* Hash the folders. */ + hash = g_hash_table_new (g_str_hash, g_str_equal); + for (i = 0; i < folders->len; i++) { + fi = folders->pdata[i]; + g_hash_table_insert (hash, fi->full_name, fi); + } + + /* Now find parents. */ + for (i = 0; i < folders->len; i++) { + fi = folders->pdata[i]; + if (fi == top) + continue; + + p = strrchr (fi->full_name, separator); + if (p) { + pname = g_strndup (fi->full_name, p - fi->full_name); + pfi = g_hash_table_lookup (hash, pname); + if (pfi) { + g_free (pname); + } else { + pfi = g_new0 (CamelFolderInfo, 1); + pfi->full_name = pname; + if (short_names) { + pfi->name = strrchr (pname, separator); + if (pfi->name) + pfi->name = g_strdup (pfi->name + 1); + else + pfi->name = g_strdup (pname); + } else + pfi->name = g_strdup (pname); + g_hash_table_insert (hash, pname, pfi); + g_ptr_array_add (folders, pfi); + } + fi->sibling = pfi->child; + pfi->child = fi; + } else { + fi->sibling = top->child; + top->child = fi; + } + } +} diff --git a/camel/camel-store.h b/camel/camel-store.h index 1ba2ff9869..07ee939c6f 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -37,6 +37,14 @@ extern "C" { #include <camel/camel-object.h> #include <camel/camel-service.h> + +typedef struct _CamelFolderInfo { + struct _CamelFolderInfo *sibling, *child; + char *url, *full_name, *name; + int message_count, unread_message_count; +} CamelFolderInfo; + + #define CAMEL_STORE_TYPE (camel_store_get_type ()) #define CAMEL_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_STORE_TYPE, CamelStore)) #define CAMEL_STORE_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_STORE_TYPE, CamelStoreClass)) @@ -84,6 +92,14 @@ typedef struct { void (*uncache_folder) (CamelStore *store, CamelFolder *folder); + CamelFolderInfo *(*get_folder_info) (CamelStore *store, + const char *top, + gboolean fase, + gboolean recursive, + CamelException *ex); + void (*free_folder_info) (CamelStore *store, + CamelFolderInfo *fi); + } CamelStoreClass; @@ -108,6 +124,26 @@ void camel_store_rename_folder (CamelStore *store, const char *new_name, CamelException *ex); +CamelFolderInfo *camel_store_get_folder_info (CamelStore *store, + const char *top, + gboolean fase, + gboolean recursive, + CamelException *ex); +void camel_store_free_folder_info (CamelStore *store, + CamelFolderInfo *fi); + + +void camel_store_free_folder_info_full (CamelStore *store, + CamelFolderInfo *fi); +void camel_store_free_folder_info_nop (CamelStore *store, + CamelFolderInfo *fi); + +void camel_folder_info_free (CamelFolderInfo *fi); +void camel_folder_info_build (GPtrArray *folders, + CamelFolderInfo *top, + char separator, + gboolean short_names); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index 63ef5b31d1..ab2d7f88b9 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -79,10 +79,6 @@ static void imap_copy_message_to (CamelFolder *source, const char *uid, static void imap_move_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex); -/* subfolder listing */ -static GPtrArray *imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex); -static GPtrArray *imap_get_subfolder_info (CamelFolder *folder); - /* summary info */ static GPtrArray *imap_get_uids (CamelFolder *folder); static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex); @@ -116,8 +112,6 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) camel_folder_class->get_uids = imap_get_uids; camel_folder_class->free_uids = camel_folder_free_nop; - camel_folder_class->get_subfolder_info = imap_get_subfolder_info; - camel_folder_class->free_subfolder_info = camel_folder_free_nop; camel_folder_class->get_message_count = imap_get_message_count; camel_folder_class->get_unread_message_count = imap_get_unread_message_count; @@ -144,14 +138,11 @@ camel_imap_folder_init (gpointer object, gpointer klass) CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object); CamelFolder *folder = CAMEL_FOLDER (object); - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; folder->has_summary_capability = TRUE; folder->has_search_capability = TRUE; imap_folder->summary = NULL; imap_folder->summary_hash = NULL; - imap_folder->lsub = NULL; /* some IMAP daemons support user-flags * * I would not, however, rely on this feature as * @@ -197,9 +188,6 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name) short_name = folder_name; camel_folder_construct (folder, parent, folder_name, short_name); - if (!*folder_name) - folder->can_hold_messages = FALSE; - return folder; } @@ -211,7 +199,7 @@ imap_summary_free (GPtrArray **summary) if (array) { for (i = 0; i < array->len; i++) - camel_folder_info_free (array->pdata[i]); + camel_message_info_free (array->pdata[i]); g_ptr_array_free (array, TRUE); *summary = NULL; @@ -233,25 +221,14 @@ static void imap_finalize (CamelObject *object) { CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object); - gint i; - + imap_folder_summary_free (imap_folder); - - if (imap_folder->lsub) { - for (i = 0; i < imap_folder->lsub->len; i++) - camel_folder_info_free (imap_folder->lsub->pdata[i]); - - g_ptr_array_free (imap_folder->lsub, TRUE); - } } static void imap_refresh_info (CamelFolder *folder, CamelException *ex) { - imap_get_subfolder_info_internal (folder, ex); - - if (folder->can_hold_messages) - imap_get_summary_internal (folder, ex); + imap_get_summary_internal (folder, ex); } static void @@ -308,8 +285,6 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex) GPtrArray *response; gint status, count = 0; - g_return_val_if_fail (folder->can_hold_messages, 0); - folder_path = camel_imap_store_folder_path (store, folder->full_name); if (store->has_status_capability) @@ -501,92 +476,6 @@ imap_get_uids (CamelFolder *folder) return array; } -static GPtrArray * -imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); - GPtrArray *response, *listing; - gboolean found_inbox = FALSE; - gint status, i; - gchar *namespace; - CamelFolderInfo *fi; - - g_return_val_if_fail (folder != NULL, g_ptr_array_new ()); - - namespace = camel_imap_store_folder_path (store, folder->full_name); - status = camel_imap_command_extended (store, NULL, &response, ex, - "LIST \"\" \"%s%s*\"", namespace, - *namespace ? store->dir_sep : ""); - - if (status != CAMEL_IMAP_OK) { - g_free (namespace); - - imap_folder->lsub = g_ptr_array_new (); - return imap_folder->lsub; - } - - /* parse out the subfolders */ - listing = g_ptr_array_new (); - if (response) { - for (i = 0; i < response->len; i++) { - gchar *resp, *flags, *sep, *dir; - - resp = response->pdata[i]; - if (!imap_parse_list_response (resp, namespace, &flags, &sep, &dir)) { - g_free (flags); - g_free (sep); - g_free (dir); - continue; - } - - g_free (flags); - - if (*dir) { - d(fprintf (stderr, "adding folder: %s\n", dir)); - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = dir; - fi->name = strrchr (dir, *sep); - if (fi->name) - fi->name = g_strdup (fi->name + 1); - else - fi->name = g_strdup (dir); - /* FIXME: read/unread msg count */ - - if (!g_strcasecmp (dir, "INBOX")) - found_inbox = TRUE; - g_ptr_array_add (listing, fi); - } - - g_free (sep); - } - camel_imap_response_free (response); - } - - if (!*folder->name && !found_inbox) { - fi = g_new0 (CamelFolderInfo, 1); - fi->full_name = g_strdup ("INBOX"); - fi->name = g_strdup ("INBOX"); - /* FIXME: read/unread msg count */ - - g_ptr_array_add (listing, fi); - } - - g_free (namespace); - - imap_folder->lsub = listing; - - return listing; -} - -static GPtrArray * -imap_get_subfolder_info (CamelFolder *folder) -{ - CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); - - return imap_folder->lsub; -} - static CamelMimeMessage * imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex) { diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h index d4d960b2a8..41170ce698 100644 --- a/camel/providers/imap/camel-imap-folder.h +++ b/camel/providers/imap/camel-imap-folder.h @@ -48,8 +48,6 @@ typedef struct { GPtrArray *summary; GHashTable *summary_hash; - - GPtrArray *lsub; } CamelImapFolder; diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index d5fc59b33e..eab33b308f 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -60,6 +60,9 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboo static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); static char *get_root_folder_name (CamelStore *store, CamelException *ex); +static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex); static void imap_keepalive (CamelRemoteStore *store); /*static gboolean stream_is_alive (CamelStream *istream);*/ static int camel_imap_status (char *cmdid, char *respbuf); @@ -87,6 +90,8 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) camel_store_class->get_folder = get_folder; camel_store_class->get_folder_name = get_folder_name; camel_store_class->get_root_folder_name = get_root_folder_name; + camel_store_class->get_folder_info = get_folder_info; + camel_store_class->free_folder_info = camel_store_free_folder_info_full; camel_remote_store_class->keepalive = imap_keepalive; } @@ -393,33 +398,35 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelEx CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelFolder *new_folder; char *folder_path; - gboolean exists = FALSE; gboolean selectable; - new_folder = camel_imap_folder_new (store, folder_name); - - /* this is the top-level dir, we already know it exists - it has to! */ - if (!*folder_name) { - camel_folder_refresh_info (new_folder, ex); - return new_folder; - } - folder_path = camel_imap_store_folder_path (imap_store, folder_name); - if (imap_folder_exists (imap_store, folder_path, &selectable, ex)) { - exists = TRUE; - if (!selectable) - new_folder->can_hold_messages = FALSE; - } + if (!imap_folder_exists (imap_store, folder_path, &selectable, ex)) { + if (!create) { + g_free (folder_path); + return NULL; + } - if (!exists && create && !imap_create (imap_store, folder_path, ex)) { + if (!imap_create (imap_store, folder_path, ex)) { + g_free (folder_path); + return NULL; + } + } else if (!selectable) { + camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "%s is not a selectable folder", + folder_name); g_free (folder_path); - camel_object_unref (CAMEL_OBJECT (new_folder)); return NULL; } + g_free (folder_path); - /* this is where we *should refresh_info, not in imap_folder_new() */ + new_folder = camel_imap_folder_new (store, folder_name); camel_folder_refresh_info (new_folder, ex); - + if (camel_exception_is_set (ex)) { + camel_object_unref (CAMEL_OBJECT (new_folder)); + return NULL; + } + return new_folder; } @@ -440,32 +447,145 @@ get_root_folder_name (CamelStore *store, CamelException *ex) return g_strdup (""); } -static void -imap_keepalive (CamelRemoteStore *store) +static CamelFolderInfo * +parse_list_response_as_folder_info (const char *response, + const char *namespace, + const char *base_url) +{ + CamelFolderInfo *fi; + char *flags, *sep, *dir; + + if (!imap_parse_list_response (response, namespace, + &flags, &sep, &dir)) + return NULL; + + fi = g_new0 (CamelFolderInfo, 1); + fi->full_name = dir; + fi->name = strrchr (dir, *sep); + if (fi->name) + fi->name = g_strdup (fi->name + 1); + else + fi->name = g_strdup (dir); + g_free (sep); + if (!e_strstrcase (flags, "\\NoSelect")) + fi->url = g_strdup_printf ("%s%s", base_url, dir); + g_free (flags); + /* FIXME: read/unread msg count */ + + return fi; +} + +static CamelFolderInfo * +get_folder_info (CamelStore *store, const char *top, gboolean fast, + gboolean recursive, CamelException *ex) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - - camel_imap_command_extended (imap_store, NULL, NULL, NULL, "NOOP"); + CamelURL *url = CAMEL_SERVICE (store)->url; + gboolean found_inbox = FALSE; + int status, len, i; + GPtrArray *response; + char *dir_sep, *namespace, *base_url, *list; + CamelFolderInfo *topfi, *fi; + + if (!top) + top = ""; + dir_sep = imap_store->dir_sep; + namespace = camel_imap_store_folder_path (imap_store, top); + + /* Yah! I am complicated! */ + base_url = camel_url_to_string (url, FALSE); + len = strlen (base_url); + if (url->path && base_url[len - 1] != *dir_sep) { + base_url = g_realloc (base_url, len + 2); + base_url[len] = *dir_sep; + base_url[len + 1] = '\0'; + } else if (!url->path) { + base_url = g_realloc (base_url, len + 2); + base_url[len] = '/'; + base_url[len + 1] = '\0'; + } + + status = camel_imap_command_extended (imap_store, NULL, &response, ex, + "LIST \"\" \"%s\"", namespace); + if (status != CAMEL_IMAP_OK) { + g_free (namespace); + g_free (base_url); + return NULL; + } + list = camel_imap_response_extract (response, "LIST", ex); + if (!list) { + g_free (namespace); + g_free (base_url); + return NULL; + } + topfi = parse_list_response_as_folder_info (list, namespace, base_url); + g_free (list); + + status = camel_imap_command_extended (imap_store, NULL, &response, ex, + "LIST \"\" \"%s%s%c\"", + namespace, + *namespace ? dir_sep : "", + recursive ? '*' : '%'); + if (status != CAMEL_IMAP_OK) { + g_free (namespace); + g_free (base_url); + return NULL; + } + + /* Turn responses into CamelFolderInfo and remove any + * extraneous responses. + */ + for (i = 0; i < response->len; i++) { + list = response->pdata[i]; + response->pdata[i] = fi = + parse_list_response_as_folder_info (list, namespace, + base_url); + g_free (list); + + if (!response->pdata[i]) { + g_ptr_array_remove_index_fast (response, i--); + continue; + } + + if (!g_strcasecmp (fi->full_name, "INBOX")) + found_inbox = TRUE; + } + + /* Add INBOX, if necessary */ + if (!*top && !found_inbox) { + fi = g_new0 (CamelFolderInfo, 1); + fi->full_name = g_strdup ("INBOX"); + fi->name = g_strdup ("INBOX"); + fi->url = g_strdup_printf ("%sINBOX", base_url); + /* FIXME: read/unread msg count */ + + g_ptr_array_add (response, fi); + } + + /* And assemble */ + camel_folder_info_build (response, topfi, *dir_sep, TRUE); + g_ptr_array_free (response, FALSE); + + /* Remove the top if it's the root of the store. */ + if (!*top && !topfi->sibling) { + fi = topfi; + topfi = topfi->child; + fi->child = NULL; + camel_folder_info_free (fi); + } + + g_free (namespace); + g_free (base_url); + return topfi; } -#if 0 -static gboolean -stream_is_alive (CamelStream *istream) +static void +imap_keepalive (CamelRemoteStore *store) { - CamelStreamFs *fs_stream; - char buf; - - g_return_val_if_fail (istream != NULL, FALSE); - - fs_stream = CAMEL_STREAM_FS (CAMEL_STREAM_BUFFER (istream)->stream); - g_return_val_if_fail (fs_stream->fd != -1, FALSE); - - if (read (fs_stream->fd, (void *) &buf, 0) == 0) - return TRUE; + CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - return FALSE; + camel_imap_command_extended (imap_store, NULL, NULL, NULL, "NOOP"); } -#endif static int camel_imap_status (char *cmdid, char *respbuf) diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index bb110f1f90..4658341e6a 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -33,12 +33,12 @@ #define d(x) x char * -imap_next_word (char *buf) +imap_next_word (const char *buf) { char *word; /* skip over current word */ - for (word = buf; *word && *word != ' '; word++); + for (word = (char *)buf; *word && *word != ' '; word++); /* skip over white space */ for ( ; *word && *word == ' '; word++); @@ -47,7 +47,7 @@ imap_next_word (char *buf) } gboolean -imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder) +imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder) { char *word, *ep, *f; @@ -96,7 +96,9 @@ imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, /* chop out the folder prefix */ if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) { - f = *folder + strlen (namespace) + strlen (*sep); + f = *folder + strlen (namespace); + if (!strncmp (f, *sep, strlen (*sep))) + f += strlen (*sep); memmove (*folder, f, strlen (f) + 1); } diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h index 6f450fc8e8..b08c179926 100644 --- a/camel/providers/imap/camel-imap-utils.h +++ b/camel/providers/imap/camel-imap-utils.h @@ -30,9 +30,9 @@ extern "C" { #include <glib.h> -char *imap_next_word (char *buf); +char *imap_next_word (const char *buf); -gboolean imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder); +gboolean imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder); char *imap_translate_sexp (const char *expression); diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 7aaf9d8593..163de6784f 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -64,7 +64,6 @@ static void mbox_append_message(CamelFolder *folder, CamelMimeMessage * message, CamelException *ex); static GPtrArray *mbox_get_uids(CamelFolder *folder); -static GPtrArray *mbox_get_subfolder_info(CamelFolder *folder); static GPtrArray *mbox_get_summary(CamelFolder *folder); static CamelMimeMessage *mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex); @@ -102,8 +101,6 @@ camel_mbox_folder_class_init(CamelMboxFolderClass * camel_mbox_folder_class) camel_folder_class->append_message = mbox_append_message; camel_folder_class->get_uids = mbox_get_uids; camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_subfolder_info = mbox_get_subfolder_info; - camel_folder_class->free_subfolder_info = camel_folder_free_shallow; camel_folder_class->get_summary = mbox_get_summary; camel_folder_class->free_summary = camel_folder_free_nop; camel_folder_class->expunge = mbox_expunge; @@ -129,8 +126,6 @@ mbox_init(gpointer object, gpointer klass) CamelFolder *folder = object; CamelMboxFolder *mbox_folder = object; - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; folder->has_summary_capability = TRUE; folder->has_search_capability = TRUE; @@ -438,13 +433,6 @@ mbox_get_uids(CamelFolder *folder) return array; } -static GPtrArray * -mbox_get_subfolder_info(CamelFolder *folder) -{ - /* No subfolders. */ - return g_ptr_array_new(); -} - static CamelMimeMessage * mbox_get_message(CamelFolder *folder, const gchar * uid, CamelException *ex) { diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c index 0a6c7c2ce1..8bf77c9774 100644 --- a/camel/providers/mbox/camel-mbox-store.c +++ b/camel/providers/mbox/camel-mbox-store.c @@ -47,6 +47,9 @@ static void delete_folder (CamelStore *store, const char *folder_name, 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 CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex); static void camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class) @@ -61,6 +64,8 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_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->get_folder_info = get_folder_info; + camel_store_class->free_folder_info = camel_store_free_folder_info_full; } static void @@ -117,8 +122,8 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, if (errno != ENOENT) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not open folder `%s':" - "\n%s", folder_name, + "Could not open file `%s':" + "\n%s", name, g_strerror (errno)); g_free (name); return NULL; @@ -135,8 +140,8 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, g_free (name); if (fd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not create folder `%s':" - "\n%s", folder_name, + "Could not create file `%s':" + "\n%s", name, g_strerror (errno)); return NULL; } @@ -277,3 +282,14 @@ get_name (CamelService *service, gboolean brief) else return g_strdup_printf ("Local mail file %s", service->url->path); } + +static CamelFolderInfo * +get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex) +{ + /* FIXME: This is broken, but it corresponds to what was + * there before. + */ + return NULL; +} diff --git a/camel/providers/mh/camel-mh-folder.c b/camel/providers/mh/camel-mh-folder.c index ec434bbcf0..c8b0503e95 100644 --- a/camel/providers/mh/camel-mh-folder.c +++ b/camel/providers/mh/camel-mh-folder.c @@ -58,7 +58,6 @@ static gint mh_get_message_count(CamelFolder * folder); static gint mh_get_unread_message_count(CamelFolder * folder); static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, const CamelMessageInfo *info, CamelException * ex); static GPtrArray *mh_get_uids(CamelFolder * folder); -static GPtrArray *mh_get_subfolder_info(CamelFolder * folder); static GPtrArray *mh_get_summary(CamelFolder * folder); static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex); @@ -93,8 +92,6 @@ static void camel_mh_folder_class_init(CamelObjectClass * camel_mh_folder_class) camel_folder_class->append_message = mh_append_message; camel_folder_class->get_uids = mh_get_uids; camel_folder_class->free_uids = camel_folder_free_deep; - camel_folder_class->get_subfolder_info = mh_get_subfolder_info; - camel_folder_class->free_subfolder_info = camel_folder_free_deep; camel_folder_class->get_summary = mh_get_summary; camel_folder_class->free_summary = camel_folder_free_nop; camel_folder_class->expunge = mh_expunge; @@ -119,8 +116,6 @@ static void mh_init(gpointer object, gpointer klass) CamelFolder *folder = object; CamelMhFolder *mh_folder = object; - folder->can_hold_messages = TRUE; - folder->can_hold_folders = TRUE; folder->has_summary_capability = TRUE; folder->has_search_capability = TRUE; @@ -356,13 +351,6 @@ static GPtrArray *mh_get_uids(CamelFolder * folder) return array; } -static GPtrArray *mh_get_subfolder_info(CamelFolder * folder) -{ - /* FIXME: scan for sub-folders */ - /* No subfolders. */ - return g_ptr_array_new(); -} - static CamelMimeMessage *mh_get_message(CamelFolder * folder, const gchar * uid, CamelException * ex) { CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder); diff --git a/camel/providers/mh/camel-mh-store.c b/camel/providers/mh/camel-mh-store.c index e45a5b72e2..32b01eefa1 100644 --- a/camel/providers/mh/camel-mh-store.c +++ b/camel/providers/mh/camel-mh-store.c @@ -45,6 +45,9 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo 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 CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex); static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class) { @@ -58,6 +61,8 @@ static void camel_mh_store_class_init(CamelObjectClass * camel_mh_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->get_folder_info = get_folder_info; + camel_store_class->free_folder_info = camel_store_free_folder_info_full; } static void camel_mh_store_init(CamelObject * object) @@ -207,3 +212,15 @@ static char *get_name(CamelService * service, gboolean brief) else return g_strdup_printf("Local mail file %s", service->url->path); } + + +static CamelFolderInfo * +get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex) +{ + /* FIXME: This is broken, but it corresponds to what was + * there before. + */ + return NULL; +} diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index 2206064289..e04571ef36 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -262,37 +262,6 @@ nntp_folder_get_summary (CamelFolder *folder) return nntp_folder->summary->messages; } -static GPtrArray * -nntp_folder_get_subfolder_info (CamelFolder *folder) -{ - CamelNNTPNewsrc *newsrc; - GPtrArray *names, *info; - CamelFolderInfo *fi; - int i; - - /* Only top-level folder has subfolders. */ - if (*folder->name) - return NULL; - - newsrc = CAMEL_NNTP_STORE (camel_folder_get_parent_store (folder))->newsrc; - if (!newsrc) - return NULL; - - info = g_ptr_array_new (); - names = camel_nntp_newsrc_get_subscribed_group_names (newsrc); - for (i = 0; i < names->len; i++) { - fi = g_new (CamelFolderInfo, 1); - fi->name = fi->full_name = names->pdata[i]; - /* FIXME */ - fi->message_count = 0; - fi->unread_message_count = 0; - g_ptr_array_add (info, fi); - } - camel_nntp_newsrc_free_group_names (newsrc, names); - - return info; -} - static GPtrArray* nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) { @@ -336,8 +305,6 @@ camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class) camel_folder_class->free_uids = camel_folder_free_deep; camel_folder_class->get_summary = nntp_folder_get_summary; camel_folder_class->free_summary = camel_folder_free_nop; - camel_folder_class->get_subfolder_info = nntp_folder_get_subfolder_info; - camel_folder_class->free_subfolder_info = camel_folder_free_deep; camel_folder_class->search_by_expression = nntp_folder_search_by_expression; camel_folder_class->get_message_info = nntp_folder_get_message_info; } @@ -366,18 +333,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti CamelFolder *folder = CAMEL_FOLDER (camel_object_new (CAMEL_NNTP_FOLDER_TYPE)); camel_folder_construct (folder, parent, folder_name, folder_name); - - /* set flags */ - if (!*folder->name) { - /* the root folder is the only folder that has "subfolders" */ - folder->can_hold_folders = TRUE; - folder->can_hold_messages = FALSE; - } - else { - folder->can_hold_folders = FALSE; - folder->can_hold_messages = TRUE; - folder->has_summary_capability = TRUE; - } + folder->has_summary_capability = TRUE; camel_folder_refresh_info (folder, ex); if (camel_exception_is_set (ex)) { diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 609520251b..1e6ccd53c1 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -296,6 +296,50 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name, return camel_nntp_folder_new (store, folder_name, ex); } +static CamelFolderInfo * +nntp_store_get_folder_info (CamelStore *store, const char *top, + gboolean fast, gboolean recursive, + CamelException *ex) +{ + CamelNNTPStore *nntp_store = (CamelNNTPStore *)store; + GPtrArray *names; + CamelFolderInfo *topfi, *last = NULL, *fi; + int i; + + if (!nntp_store->newsrc) + return NULL; + + topfi = g_new0 (CamelFolderInfo, 1); + topfi->name = g_strdup (top); + topfi->full_name = g_strdup (top); + if (*top) + topfi->url = g_strdup_printf ("news:%s", top); + /* FIXME: message_count if top != "" */ + topfi->message_count = topfi->unread_message_count = -1; + + if (!recursive || *top) + return topfi; + + names = camel_nntp_newsrc_get_subscribed_group_names (nntp_store->newsrc); + for (i = 0; i < names->len; i++) { + fi = g_new0 (CamelFolderInfo, 1); + fi->name = g_strdup (names->pdata[i]); + fi->full_name = g_strdup (names->pdata[i]); + fi->url = g_strdup_printf ("news:%s", (char *)names->pdata[i]); + /* FIXME */ + fi->message_count = fi->unread_message_count = -1; + + if (last) + last->sibling = fi; + else + topfi->child = fi; + last = fi; + } + camel_nntp_newsrc_free_group_names (nntp_store->newsrc, names); + + return topfi; +} + static char * nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex) { @@ -332,6 +376,8 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class) camel_store_class->get_folder = nntp_store_get_folder; camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name; + camel_store_class->get_folder_info = nntp_store_get_folder_info; + camel_store_class->free_folder_info = camel_store_free_folder_info_full; } diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c index d367cac1ab..7b66c87f26 100644 --- a/camel/providers/pop3/camel-pop3-folder.c +++ b/camel/providers/pop3/camel-pop3-folder.c @@ -78,8 +78,6 @@ camel_pop3_folder_init (gpointer object) CamelFolder *folder = CAMEL_FOLDER (object); CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object); - folder->can_hold_messages = TRUE; - folder->can_hold_folders = FALSE; folder->has_summary_capability = FALSE; folder->has_search_capability = FALSE; diff --git a/camel/providers/vee/camel-vee-folder.c b/camel/providers/vee/camel-vee-folder.c index 0be1f152d1..da47761754 100644 --- a/camel/providers/vee/camel-vee-folder.c +++ b/camel/providers/vee/camel-vee-folder.c @@ -119,8 +119,6 @@ camel_vee_folder_init (CamelVeeFolder *obj) p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); - folder->can_hold_messages = TRUE; - folder->can_hold_folders = FALSE; folder->has_summary_capability = TRUE; folder->has_search_capability = TRUE; |