add camel-nntp-grouplist.h (libcamelnntp_la_SOURCES): add
authorChris Toshok <toshok@helixcode.com>
Fri, 6 Oct 2000 08:25:36 +0000 (08:25 +0000)
committerChris Toshok <toshok@src.gnome.org>
Fri, 6 Oct 2000 08:25:36 +0000 (08:25 +0000)
2000-10-06  Chris Toshok  <toshok@helixcode.com>

* providers/nntp/Makefile.am (libcamelnntpinclude_HEADERS): add
camel-nntp-grouplist.h
(libcamelnntp_la_SOURCES): add camel-nntp-grouplist.c

* providers/nntp/camel-nntp-provider.c: add our own hash functions
for nntp urls.

* providers/nntp/camel-nntp-newsrc.c
(camel_nntp_newsrc_group_is_subscribed): new function.
(camel_nntp_newsrc_subscribe_group): new function.
(camel_nntp_newsrc_unsubscribe_group): new function.

* providers/nntp/camel-nntp-newsrc.h: add prototypes for
_group_is_subscribed, _subscribe_group, and _unsubscribe_group.

* providers/nntp/camel-nntp-store.c
(build_folder_info_from_grouplist): new function.
(nntp_store_get_folder_info): add subscribed_only_parameter.  if
it's FALSE, load the grouplist and call
build_folder_info_from_grouplist.
(nntp_store_folder_subscribed): implement.
(nntp_store_subscribe_folder): implement.
(nntp_store_unsubscribe_folder): implement.
(camel_nntp_store_init): add CAMEL_STORE_SUBSCRIPTIONS to the
store's flags.

* providers/mh/camel-mh-store.c (get_folder_info): add
subscribed_only parameter.

* providers/mbox/camel-mbox-store.c (get_folder_info): add
subscribed_only parameter.

* providers/imap/camel-imap-store.c (get_folder_info): add
subscribed_only parameter.

* camel-store.c (camel_store_supports_subscriptions): new function.
(camel_store_folder_subscribed): new function.
(camel_store_subscribe_folder): new function.
(camel_store_unsubscribe_folder): new function.

* camel-store.h: add prototypes and virtual functions for the
subscribe implementation.  also, add a subscribed_only argument to
camel_store_get_folder_info.

camel/ChangeLog
camel/camel-store.c
camel/camel-store.h
camel/providers/imap/camel-imap-store.c
camel/providers/mbox/camel-mbox-store.c
camel/providers/nntp/Makefile.am
camel/providers/nntp/camel-nntp-newsrc.c
camel/providers/nntp/camel-nntp-newsrc.h
camel/providers/nntp/camel-nntp-provider.c
camel/providers/nntp/camel-nntp-store.c
camel/providers/nntp/camel-nntp-store.h

index 719a759..a6df955 100644 (file)
@@ -1,3 +1,49 @@
+2000-10-06  Chris Toshok  <toshok@helixcode.com>
+
+       * providers/nntp/Makefile.am (libcamelnntpinclude_HEADERS): add
+       camel-nntp-grouplist.h
+       (libcamelnntp_la_SOURCES): add camel-nntp-grouplist.c
+
+       * providers/nntp/camel-nntp-provider.c: add our own hash functions
+       for nntp urls.
+
+       * providers/nntp/camel-nntp-newsrc.c
+       (camel_nntp_newsrc_group_is_subscribed): new function.
+       (camel_nntp_newsrc_subscribe_group): new function.
+       (camel_nntp_newsrc_unsubscribe_group): new function.
+
+       * providers/nntp/camel-nntp-newsrc.h: add prototypes for
+       _group_is_subscribed, _subscribe_group, and _unsubscribe_group.
+
+       * providers/nntp/camel-nntp-store.c
+       (build_folder_info_from_grouplist): new function.
+       (nntp_store_get_folder_info): add subscribed_only_parameter.  if
+       it's FALSE, load the grouplist and call
+       build_folder_info_from_grouplist.
+       (nntp_store_folder_subscribed): implement.
+       (nntp_store_subscribe_folder): implement.
+       (nntp_store_unsubscribe_folder): implement.
+       (camel_nntp_store_init): add CAMEL_STORE_SUBSCRIPTIONS to the
+       store's flags.
+
+       * providers/mh/camel-mh-store.c (get_folder_info): add
+       subscribed_only parameter.
+
+       * providers/mbox/camel-mbox-store.c (get_folder_info): add
+       subscribed_only parameter.
+
+       * providers/imap/camel-imap-store.c (get_folder_info): add
+       subscribed_only parameter.
+
+       * camel-store.c (camel_store_supports_subscriptions): new function.
+       (camel_store_folder_subscribed): new function.
+       (camel_store_subscribe_folder): new function.
+       (camel_store_unsubscribe_folder): new function.
+
+       * camel-store.h: add prototypes and virtual functions for the
+       subscribe implementation.  also, add a subscribed_only argument to
+       camel_store_get_folder_info.
+
 2000-10-05  Jeffrey Stedfast  <fejj@helixcode.com>
 
        * camel-mime-utils.c (header_address_list_format_append): Encode
index 15698ee..cb2f73f 100644 (file)
@@ -50,6 +50,7 @@ static char *get_default_folder_name (CamelStore *store, CamelException *ex);
 
 static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
                                         gboolean fast, gboolean recursive,
+                                        gboolean subscribed_only,
                                         CamelException *ex);
 static void free_folder_info (CamelStore *store, CamelFolderInfo *tree);
 
@@ -58,6 +59,10 @@ static void cache_folder (CamelStore *store, const char *folder_name,
                          CamelFolder *folder);
 static void uncache_folder (CamelStore *store, CamelFolder *folder);
 
+static gboolean folder_subscribed (CamelStore *store, const char *folder_name);
+static void subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
+static void unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
+
 static void
 camel_store_class_init (CamelStoreClass *camel_store_class)
 {
@@ -75,6 +80,9 @@ camel_store_class_init (CamelStoreClass *camel_store_class)
        camel_store_class->lookup_folder = lookup_folder;
        camel_store_class->cache_folder = cache_folder;
        camel_store_class->uncache_folder = uncache_folder;
+       camel_store_class->folder_subscribed = folder_subscribed;
+       camel_store_class->subscribe_folder = subscribe_folder;
+       camel_store_class->unsubscribe_folder = unsubscribe_folder;
 }
 
 static void
@@ -83,6 +91,7 @@ camel_store_init (void *o, void *k)
        CamelStore *store = o;
 
        store->folders = g_hash_table_new (g_str_hash, g_str_equal);
+       store->flags = 0;
 }
 
 static void
@@ -384,6 +393,7 @@ camel_store_get_default_folder (CamelStore *store, CamelException *ex)
 static CamelFolderInfo *
 get_folder_info (CamelStore *store, const char *top,
                 gboolean fast, gboolean recursive,
+                gboolean subscribed_only,
                 CamelException *ex)
 {
        g_warning ("CamelStore::get_folder_info not implemented for `%s'",
@@ -414,12 +424,14 @@ get_folder_info (CamelStore *store, const char *top,
 CamelFolderInfo *
 camel_store_get_folder_info (CamelStore *store, const char *top,
                             gboolean fast, gboolean recursive,
+                            gboolean subscribed_only,
                             CamelException *ex)
 {
        g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
 
        return CS_CLASS (store)->get_folder_info (store, top, fast,
-                                                 recursive, ex);
+                                                 recursive, subscribed_only,
+                                                 ex);
 }
 
 
@@ -558,3 +570,79 @@ camel_folder_info_build (GPtrArray *folders, CamelFolderInfo *top,
                }
        }
 }
+
+gboolean
+camel_store_supports_subscriptions (CamelStore *store)
+{
+       return (store->flags & CAMEL_STORE_SUBSCRIPTIONS);
+}
+
+
+static gboolean
+folder_subscribed (CamelStore *store, const char *folder_name)
+{
+       g_warning ("CamelStore::folder_subscribed not implemented for `%s'",
+                  camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)));
+       return FALSE;
+}
+
+/**
+ * camel_store_folder_subscribed: Tell whether or not a folder has been subscribed to.
+ * @store: a CamelStore
+ * @folder_name: the folder on which we're querying subscribed status.
+ * Return value: TRUE if folder is subscribed, FALSE if not.
+ **/
+gboolean
+camel_store_folder_subscribed (CamelStore *store,
+                              const char *folder_name)
+{
+       g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+
+       return CS_CLASS (store)->folder_subscribed (store, folder_name);
+}
+
+static void
+subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
+{
+       g_warning ("CamelStore::subscribe_folder not implemented for `%s'",
+                  camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)));
+}
+
+/**
+ * camel_store_subscribe_folder: marks a folder as subscribed.
+ * @store: a CamelStore
+ * @folder_name: the folder to subscribe to.
+ **/
+void
+camel_store_subscribe_folder (CamelStore *store,
+                             const char *folder_name,
+                             CamelException *ex)
+{
+       g_return_if_fail (CAMEL_IS_STORE (store));
+
+       CS_CLASS (store)->subscribe_folder (store, folder_name, ex);
+}
+
+static void
+unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex)
+{
+       g_warning ("CamelStore::unsubscribe_folder not implemented for `%s'",
+                  camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store)));
+}
+
+
+/**
+ * camel_store_unsubscribe_folder: marks a folder as unsubscribed.
+ * @store: a CamelStore
+ * @folder_name: the folder to unsubscribe from.
+ **/
+void
+camel_store_unsubscribe_folder (CamelStore *store,
+                               const char *folder_name,
+                               CamelException *ex)
+{
+       g_return_if_fail (CAMEL_IS_STORE (store));
+
+       CS_CLASS (store)->unsubscribe_folder (store, folder_name, ex);
+}
+
index 07ee939..57c45f4 100644 (file)
@@ -51,12 +51,16 @@ typedef struct _CamelFolderInfo {
 #define CAMEL_IS_STORE(o)    (CAMEL_CHECK_TYPE((o), CAMEL_STORE_TYPE))
 
 
+/* Flags for store flags */
+#define CAMEL_STORE_SUBSCRIPTIONS (1 << 0)
+
 struct _CamelStore
 {
        CamelService parent_object;
 
        GHashTable *folders;
 
+       int flags;
 };
 
 
@@ -94,12 +98,21 @@ typedef struct {
 
        CamelFolderInfo *(*get_folder_info)         (CamelStore *store,
                                                     const char *top,
-                                                    gboolean fase,
+                                                    gboolean fast,
                                                     gboolean recursive,
+                                                    gboolean subscribed_only,
                                                     CamelException *ex);
        void            (*free_folder_info)         (CamelStore *store,
                                                     CamelFolderInfo *fi);
 
+       gboolean        (*folder_subscribed)        (CamelStore *store,
+                                                    const char *folder_name);
+       void            (*subscribe_folder)         (CamelStore *store,
+                                                    const char *folder_name,
+                                                    CamelException *ex);
+       void            (*unsubscribe_folder)       (CamelStore *store,
+                                                    const char *folder_name,
+                                                    CamelException *ex);
 } CamelStoreClass;
 
 
@@ -126,13 +139,13 @@ void             camel_store_rename_folder      (CamelStore *store,
 
 CamelFolderInfo *camel_store_get_folder_info    (CamelStore *store,
                                                 const char *top,
-                                                gboolean fase,
+                                                gboolean fast,
                                                 gboolean recursive,
+                                                gboolean subscribed_only,
                                                 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,
@@ -144,6 +157,17 @@ void             camel_folder_info_build           (GPtrArray *folders,
                                                    char separator,
                                                    gboolean short_names);
 
+gboolean         camel_store_supports_subscriptions   (CamelStore *store);
+
+gboolean         camel_store_folder_subscribed        (CamelStore *store,
+                                                      const char *folder_name);
+void             camel_store_subscribe_folder         (CamelStore *store,
+                                                      const char *folder_name,
+                                                      CamelException *ex);
+void             camel_store_unsubscribe_folder       (CamelStore *store,
+                                                      const char *folder_name,
+                                                      CamelException *ex);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index bcc8b6d..c985946 100644 (file)
@@ -63,6 +63,7 @@ static char *get_folder_name (CamelStore *store, const char *folder_name,
 static char *get_root_folder_name (CamelStore *store, CamelException *ex);
 static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
                                         gboolean fast, gboolean recursive,
+                                        gboolean subscribed_only,
                                         CamelException *ex);
 static void imap_keepalive (CamelRemoteStore *store);
 
@@ -489,7 +490,8 @@ parse_list_response_as_folder_info (const char *response,
 
 static CamelFolderInfo *
 get_folder_info (CamelStore *store, const char *top, gboolean fast,
-                gboolean recursive, CamelException *ex)
+                gboolean recursive, gboolean subscribed_only,
+                CamelException *ex)
 {
        CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
        CamelURL *url = CAMEL_SERVICE (store)->url;
index 7ad9333..6ad729c 100644 (file)
@@ -49,6 +49,7 @@ 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,
+                                        gboolean subscribed_only,
                                         CamelException *ex);
 
 static void
@@ -287,6 +288,7 @@ get_name (CamelService *service, gboolean brief)
 static CamelFolderInfo *
 get_folder_info (CamelStore *store, const char *top,
                 gboolean fast, gboolean recursive,
+                gboolean subscribed_only,
                 CamelException *ex)
 {
        /* FIXME: This is broken, but it corresponds to what was
index 6e304d8..7feccd8 100644 (file)
@@ -20,6 +20,7 @@ INCLUDES = -I../..                            \
 libcamelnntp_la_SOURCES =                      \
        camel-nntp-auth.c                       \
        camel-nntp-folder.c                     \
+       camel-nntp-grouplist.c                  \
        camel-nntp-newsrc.c                     \
        camel-nntp-provider.c                   \
        camel-nntp-store.c                      \
@@ -29,6 +30,7 @@ libcamelnntpinclude_HEADERS =                 \
        camel-nntp-auth.h                       \
        camel-nntp-resp-codes.h                 \
        camel-nntp-folder.h                     \
+       camel-nntp-grouplist.h                  \
        camel-nntp-newsrc.h                     \
        camel-nntp-store.h                      \
        camel-nntp-utils.h
index a44e42c..5c92074 100644 (file)
@@ -45,12 +45,11 @@ typedef struct {
 struct CamelNNTPNewsrc {
        gchar *filename;
        GHashTable *groups;
-       GHashTable *subscribed_groups;
        gboolean dirty;
 } ;
 
 static NewsrcGroup *
-camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, char *group_name, gboolean subscribed)
+camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, const char *group_name, gboolean subscribed)
 {
        NewsrcGroup *new_group = g_malloc(sizeof(NewsrcGroup));
 
@@ -59,8 +58,6 @@ camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, char *group_name, gboolean
        new_group->ranges = g_array_new (FALSE, FALSE, sizeof (ArticleRange));
 
        g_hash_table_insert (newsrc->groups, new_group->name, new_group);
-       if (subscribed)
-               g_hash_table_insert (newsrc->subscribed_groups, new_group->name, new_group);
 
        newsrc->dirty = TRUE;
 
@@ -162,7 +159,7 @@ camel_nntp_newsrc_group_mark_range_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *gr
 }
 
 int
-camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group_name)
+camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name)
 {
        NewsrcGroup *group;
 
@@ -172,13 +169,13 @@ camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group
 }
 
 void
-camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, char *group_name, int num)
+camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, const char *group_name, int num)
 {
        camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num);
 }
 
 void
-camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, char *group_name, long low, long high)
+camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, const char *group_name, long low, long high)
 {
        NewsrcGroup *group;
 
@@ -197,7 +194,7 @@ camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, char *group_name, lon
 }
 
 gboolean
-camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, char *group_name, long num)
+camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, const char *group_name, long num)
 {
        int i;
        NewsrcGroup *group;
@@ -214,6 +211,49 @@ camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, char *group_name, lo
        return FALSE;
 }
 
+gboolean  
+camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+       NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+       if (group) {
+               return group->subscribed;
+       }
+       else {
+               return FALSE;
+       }
+}
+
+void
+camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+       NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+       if (group) {
+               if (!group->subscribed)
+                       newsrc->dirty = TRUE;
+               group->subscribed = TRUE;
+       }
+       else {
+               camel_nntp_newsrc_group_add (newsrc, group_name, TRUE);
+       }
+}
+
+void
+camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+       NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+       if (group) {
+               if (group->subscribed)
+                       newsrc->dirty = TRUE;
+               group->subscribed = FALSE;
+       }
+       else {
+               camel_nntp_newsrc_group_add (newsrc, group_name, FALSE);
+       }
+}
+
 struct newsrc_ptr_array {
        GPtrArray *ptr_array;
        gboolean subscribed_only;
@@ -237,7 +277,7 @@ camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc)
        npa.ptr_array = g_ptr_array_new();
        npa.subscribed_only = TRUE;
 
-       g_hash_table_foreach (newsrc->subscribed_groups,
+       g_hash_table_foreach (newsrc->groups,
                              (GHFunc)get_group_foreach, &npa);
 
        return npa.ptr_array;
@@ -451,7 +491,6 @@ camel_nntp_newsrc_read_for_server (const char *server)
        newsrc = g_new0(CamelNNTPNewsrc, 1);
        newsrc->filename = filename;
        newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal);
-       newsrc->subscribed_groups = g_hash_table_new (g_str_hash, g_str_equal);
 
        if ((fp = fopen(filename, "r")) == NULL) {
                g_warning ("~/.newsrc-%s not present.\n", server);
index 47539a6..6a202f8 100644 (file)
@@ -7,14 +7,18 @@
 
 typedef struct CamelNNTPNewsrc CamelNNTPNewsrc;
 
-int       camel_nntp_newsrc_get_highest_article_read    (CamelNNTPNewsrc *newsrc, char *group_name);
+int       camel_nntp_newsrc_get_highest_article_read    (CamelNNTPNewsrc *newsrc, const char *group_name);
 void      camel_nntp_newsrc_mark_article_read           (CamelNNTPNewsrc *newsrc,
-                                                        char *group_name, int num);
+                                                        const char *group_name, int num);
 void      camel_nntp_newsrc_mark_range_read             (CamelNNTPNewsrc *newsrc,
-                                                        char *group_name, long low, long high);
+                                                        const char *group_name, long low, long high);
 
 gboolean  camel_nntp_newsrc_article_is_read             (CamelNNTPNewsrc *newsrc,
-                                                        char *group_name, long num);
+                                                        const char *group_name, long num);
+
+gboolean   camel_nntp_newsrc_group_is_subscribed        (CamelNNTPNewsrc *newsrc, const char *group_name);
+void       camel_nntp_newsrc_subscribe_group            (CamelNNTPNewsrc *newsrc, const char *group_name);
+void       camel_nntp_newsrc_unsubscribe_group          (CamelNNTPNewsrc *newsrc, const char *group_name);
 
 GPtrArray *camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc);
 GPtrArray *camel_nntp_newsrc_get_all_group_names        (CamelNNTPNewsrc *newsrc);
index f8e8916..7041c81 100644 (file)
 #include "camel-provider.h"
 #include "camel-session.h"
 
+static void add_hash (guint *hash, char *s);
+static guint nntp_url_hash (gconstpointer key);
+static gint check_equal (char *s1, char *s2);
+static gint nntp_url_equal (gconstpointer a, gconstpointer b);
+
 static CamelProvider news_provider = {
        "nntp",
        "USENET news",
@@ -50,10 +55,53 @@ camel_provider_module_init (CamelSession *session)
        news_provider.object_types[CAMEL_PROVIDER_STORE] =
                camel_nntp_store_get_type();
 
-       news_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal);
+       news_provider.service_cache = g_hash_table_new (nntp_url_hash, nntp_url_equal);
 
        camel_session_register_provider (session, &news_provider);
 }
 
+static void
+add_hash (guint *hash, char *s)
+{
+       if (s)
+               *hash ^= g_str_hash(s);
+}
+
+static guint
+nntp_url_hash (gconstpointer key)
+{
+       const CamelURL *u = (CamelURL *)key;
+       guint hash = 0;
+
+       add_hash (&hash, u->user);
+       add_hash (&hash, u->host);
+       hash ^= u->port;
+       
+       return hash;
+}
+
+static gint
+check_equal (char *s1, char *s2)
+{
+       if (s1 == NULL) {
+               if (s2 == NULL)
+                       return TRUE;
+               else
+                       return FALSE;
+       }
+       
+       if (s2 == NULL)
+               return FALSE;
 
+       return strcmp (s1, s2) == 0;
+}
 
+static gint
+nntp_url_equal (gconstpointer a, gconstpointer b)
+{
+       const CamelURL *u1 = a, *u2 = b;
+       
+       return check_equal (u1->user, u2->user)
+               && check_equal (u1->host, u2->host)
+               && u1->port == u2->port;
+}
index 52ed2d4..7f0f09e 100644 (file)
@@ -38,6 +38,7 @@
 #include "camel-nntp-resp-codes.h"
 #include "camel-folder-summary.h"
 #include "camel-nntp-store.h"
+#include "camel-nntp-grouplist.h"
 #include "camel-nntp-folder.h"
 #include "camel-nntp-auth.h"
 #include "camel-exception.h"
@@ -336,8 +337,39 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
 }
 
 static CamelFolderInfo *
+build_folder_info_from_grouplist (CamelNNTPStore *nntp_store)
+{
+       CamelURL *url = CAMEL_SERVICE (nntp_store)->url;
+       CamelFolderInfo *groups = NULL, *last = NULL, *fi;
+       GList *g;
+
+       for (g = nntp_store->group_list->group_list; g; g = g_list_next (g)) {
+               CamelNNTPGroupListEntry *entry = g->data;
+
+               fi = g_new0 (CamelFolderInfo, 1);
+               fi->name = g_strdup (entry->group_name);
+               fi->full_name = g_strdup (entry->group_name);
+               fi->url = g_strdup_printf ("nntp://%s%s%s/%s",
+                                          url->user ? url->user : "",
+                                          url->user ? "@" : "",
+                                          url->host, (char *)entry->group_name);
+               /* FIXME */
+               fi->message_count = fi->unread_message_count = -1;
+
+               if (last)
+                       last->sibling = fi;
+               else
+                       groups = fi;
+               last = fi;
+       }
+
+       return groups;
+}
+
+static CamelFolderInfo *
 nntp_store_get_folder_info (CamelStore *store, const char *top,
                            gboolean fast, gboolean recursive,
+                           gboolean subscribed_only,
                            CamelException *ex)
 {
        CamelURL *url = CAMEL_SERVICE (store)->url;
@@ -359,6 +391,19 @@ nntp_store_get_folder_info (CamelStore *store, const char *top,
                return NULL;
        }
 
+       if (top == NULL && !subscribed_only) {
+               if (!nntp_store->group_list)
+                       nntp_store->group_list = camel_nntp_grouplist_fetch (nntp_store, ex);
+               if (camel_exception_is_set (ex)) {
+                       return NULL;
+               }
+               else {
+                       fi = build_folder_info_from_grouplist (nntp_store);
+                       return fi;
+               }
+
+       }
+
        if (top == NULL) {
                /* return the list of groups */
                names = camel_nntp_newsrc_get_subscribed_group_names (nntp_store->newsrc);
@@ -403,6 +448,32 @@ nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex)
        return g_strdup ("");
 }
 
+static gboolean
+nntp_store_folder_subscribed (CamelStore *store, const char *folder_name)
+{
+       CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+       return camel_nntp_newsrc_group_is_subscribed (nntp_store->newsrc, folder_name);
+}
+
+static void
+nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
+                            CamelException *ex)
+{
+       CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+       camel_nntp_newsrc_subscribe_group (nntp_store->newsrc, folder_name);
+}
+
+static void
+nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
+                              CamelException *ex)
+{
+       CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+       camel_nntp_newsrc_unsubscribe_group (nntp_store->newsrc, folder_name);
+}
+
 static void
 finalize (CamelObject *object)
 {
@@ -437,6 +508,10 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
        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;
+
+       camel_store_class->folder_subscribed = nntp_store_folder_subscribed;
+       camel_store_class->subscribe_folder = nntp_store_subscribe_folder;
+       camel_store_class->unsubscribe_folder = nntp_store_unsubscribe_folder;
 }
 
 
@@ -446,12 +521,15 @@ camel_nntp_store_init (gpointer object, gpointer klass)
 {
        CamelService *service = CAMEL_SERVICE (object);
        CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object);
+       CamelStore *store = CAMEL_STORE (object);
 
        service->url_flags = (CAMEL_SERVICE_URL_NEED_HOST
                              | CAMEL_SERVICE_URL_ALLOW_USER
                              | CAMEL_SERVICE_URL_ALLOW_PASSWORD
                              | CAMEL_SERVICE_URL_ALLOW_AUTH);
        remote_store->default_port = NNTP_PORT;
+
+       store->flags = CAMEL_STORE_SUBSCRIPTIONS;
 }
 
 CamelType
index 0d30a38..0566967 100644 (file)
@@ -33,6 +33,7 @@ extern "C" {
 
 #include "camel-remote-store.h"
 #include "camel-nntp-newsrc.h"
+#include "camel-nntp-types.h"
 
 #define CAMEL_NNTP_STORE_TYPE     (camel_nntp_store_get_type ())
 #define CAMEL_NNTP_STORE(obj)     (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_STORE_TYPE, CamelNNTPStore))
@@ -51,13 +52,13 @@ enum {
        CAMEL_NNTP_OVER_LAST
 };
 
-typedef struct {
+struct CamelNNTPOverField {
        int index;
        gboolean full; /* full in the OVER sense - the field name
                           precedes the ':' in the XOVER list. */
-} CamelNNTPOverField;
+};
 
-typedef struct {
+struct CamelNNTPStore {
        CamelRemoteStore parent_object; 
 
 #define CAMEL_NNTP_EXT_SEARCH     (1<<0)
@@ -76,15 +77,14 @@ typedef struct {
        CamelNNTPOverField overview_field[ CAMEL_NNTP_OVER_LAST ];
 
        CamelNNTPNewsrc *newsrc;
+       CamelNNTPGroupList *group_list;
 
-} CamelNNTPStore;
-
-
+};
 
-typedef struct {
+struct CamelNNTPStoreClass {
        CamelRemoteStoreClass parent_class;
 
-} CamelNNTPStoreClass;
+};
 
 
 /* public methods */