2007-01-16 [colin] 2.7.1cvs8
authorColin Leroy <colin@colino.net>
Tue, 16 Jan 2007 20:41:20 +0000 (20:41 +0000)
committerColin Leroy <colin@colino.net>
Tue, 16 Jan 2007 20:41:20 +0000 (20:41 +0000)
* src/filtering.c
Bigger buffer for errors
* src/imap.c
* src/imap.h
* src/imap_gtk.c
* src/prefs_account.c
* src/prefs_account.h
* src/wizard.c
* src/etpan/imap-thread.c
* src/etpan/imap-thread.h
* manual/handling.xml
Add subscriptions management. What it changes:
Creating a folder subscribes to it
Deleting a folder unsubscribes it
New contextual menu item allowing to switch between
All folders and Subscribed folders, subscribe, and
unsubscribe. "Creating" an existing but unsubscribed
folder will subscribe it.
By default for new accounts, only subscribed folders
are shown.

13 files changed:
ChangeLog
PATCHSETS
configure.ac
manual/handling.xml
src/etpan/imap-thread.c
src/etpan/imap-thread.h
src/filtering.c
src/imap.c
src/imap.h
src/imap_gtk.c
src/prefs_account.c
src/prefs_account.h
src/wizard.c

index 6ab12ee8f1d2642f2245d84a7387e38ee405190b..777210e7a5152e4d47e16d5a5a872688b5515446 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2007-01-16 [colin]     2.7.1cvs8
+
+       * src/filtering.c
+               Bigger buffer for errors
+       * src/imap.c
+       * src/imap.h
+       * src/imap_gtk.c
+       * src/prefs_account.c
+       * src/prefs_account.h
+       * src/wizard.c
+       * src/etpan/imap-thread.c
+       * src/etpan/imap-thread.h
+       * manual/handling.xml
+               Add subscriptions management. What it changes:
+               Creating a folder subscribes to it
+               Deleting a folder unsubscribes it
+               New contextual menu item allowing to switch between
+               All folders and Subscribed folders, subscribe, and
+               unsubscribe. "Creating" an existing but unsubscribed
+               folder will subscribe it.
+               By default for new accounts, only subscribed folders 
+               are shown.
+
+
 2007-01-16 [paul]      2.7.1cvs7
 
        * src/summaryview.c
index 8e37f754932a253d05c6f3c69bc93c0519548129..f324b76f2a4ad80c15d640f762f60532aac6b150 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.179.2.149 -r 1.179.2.150 src/imap.c;  ) > 2.7.1cvs5.patchset
 ( cvs diff -u -r 1.12.2.41 -r 1.12.2.42 src/action.c;  cvs diff -u -r 1.382.2.351 -r 1.382.2.352 src/compose.c;  cvs diff -u -r 1.83.2.98 -r 1.83.2.99 src/mimeview.c;  cvs diff -u -r 1.49.2.86 -r 1.49.2.87 src/procmime.c;  cvs diff -u -r 1.96.2.164 -r 1.96.2.165 src/textview.c;  ) > 2.7.1cvs6.patchset
 ( cvs diff -u -r 1.395.2.276 -r 1.395.2.277 src/summaryview.c;  ) > 2.7.1cvs7.patchset
+( cvs diff -u -r 1.60.2.24 -r 1.60.2.25 src/filtering.c;  cvs diff -u -r 1.179.2.150 -r 1.179.2.151 src/imap.c;  cvs diff -u -r 1.34.2.10 -r 1.34.2.11 src/imap.h;  cvs diff -u -r 1.1.2.38 -r 1.1.2.39 src/imap_gtk.c;  cvs diff -u -r 1.105.2.79 -r 1.105.2.80 src/prefs_account.c;  cvs diff -u -r 1.49.2.24 -r 1.49.2.25 src/prefs_account.h;  cvs diff -u -r 1.1.2.46 -r 1.1.2.47 src/wizard.c;  cvs diff -u -r 1.1.4.70 -r 1.1.4.71 src/etpan/imap-thread.c;  cvs diff -u -r 1.1.4.12 -r 1.1.4.13 src/etpan/imap-thread.h;  cvs diff -u -r 1.1.2.14 -r 1.1.2.15 manual/handling.xml;  ) > 2.7.1cvs8.patchset
index c29c2f75ac53e9909a3db8573d8a288d90acd777..1e3dd2fd375a7d16189772b384fef04bbf8d06e9 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=7
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=7
+EXTRA_VERSION=8
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index a022c5cb24f75bc5002dae894be4845e0b4dd835..0bd766138a25ba12df723644a417e21ef529ff8f 100644 (file)
     </para>
   </section>
 
+  <section id="imap_subscriptions">
+    <title>IMAP subscriptions</title>
+    <para>
+       The IMAP protocol allows one to store a list of subscribed folders. Most
+       mail user agents hide the unsubscribed folders away from the GUI, and have
+       a little window allowing to subscribe to these unsubscribed folders. In
+       Claws Mail, subscriptions are respected by default, and only subscribed
+       folders will be displayed. If you want to see all your folders, you can just
+       uncheck <quote>Show subscribed folders only</quote> in the IMAP mailbox'
+       contextual menu or the account preferences. You'll be able to subscribe and 
+       unsubscribe folders from this contextual menu too. If the unsubscribed 
+       folders are hidden from the list, you will have two ways to subscribe to 
+       a folder: either show all folders, subscribe the ones you want, and hide 
+       unsubscribed folders again; or, if you know the folder's name, use 
+       "Create new folder" in its parent's contextual menu.
+    </para>
+  </section>
   <section id="handling_filters">
     <title>Filtering</title>
     <para>
index 22d238842517de20dc0e8077c3e8f9415e63d258..c03e9c6fb55ea6b01d9c22179a32b5b4bb4e6c1c 100644 (file)
@@ -656,6 +656,7 @@ struct list_param {
        mailimap * imap;
        const char * base;
        const char * wildcard;
+       gboolean sub_only;
 };
 
 struct list_result {
@@ -676,9 +677,19 @@ static void list_run(struct etpan_thread_op * op)
        CHECK_IMAP();
 
        list = NULL;
-       r = mailimap_list(param->imap, param->base,
-                         param->wildcard, &list);
        
+       if (param->base == NULL || param->wildcard == NULL) {
+               result->list = list;
+               result->error = -1;
+               debug_print("no base or wildcard (%p %p)\n", param->base, param->wildcard);
+               return;
+       }
+       if (param->sub_only)
+               r = mailimap_lsub(param->imap, param->base,
+                         param->wildcard, &list);
+       else
+               r = mailimap_list(param->imap, param->base,
+                         param->wildcard, &list);
        result->error = r;
        result->list = list;
        debug_print("imap list run - end\n");
@@ -696,7 +707,8 @@ int imap_threaded_list(Folder * folder, const char * base,
        param.imap = get_imap(folder);
        param.base = base;
        param.wildcard = wildcard;
-       
+       param.sub_only = FALSE;
+
        threaded_run(folder, &param, &result, list_run);
        
        * p_result = result.list;
@@ -706,7 +718,79 @@ int imap_threaded_list(Folder * folder, const char * base,
        return result.error;
 }
 
+int imap_threaded_lsub(Folder * folder, const char * base,
+                      const char * wildcard,
+                      clist ** p_result)
+{
+       struct list_param param;
+       struct list_result result;
+       
+       debug_print("imap lsub - begin\n");
+       
+       param.imap = get_imap(folder);
+       param.base = base;
+       param.wildcard = wildcard;
+       param.sub_only = TRUE;
+       
+       threaded_run(folder, &param, &result, list_run);
+       
+       * p_result = result.list;
+       
+       debug_print("imap lsub - end %p\n", result.list);
+       
+       return result.error;
+}
 
+struct subscribe_param {
+       mailimap * imap;
+       const char * mb;
+       gboolean subscribe;
+};
+
+struct subscribe_result {
+       int error;
+};
+
+static void subscribe_run(struct etpan_thread_op * op)
+{
+       struct subscribe_param * param;
+       struct subscribe_result * result;
+       int r;
+       
+       param = op->param;
+       result = op->result;
+
+       CHECK_IMAP();
+
+       if (param->mb == NULL) {
+               result->error = -1;
+               debug_print("no mb\n");
+               return;
+       }
+       if (param->subscribe)
+               r = mailimap_subscribe(param->imap, param->mb);
+       else
+               r = mailimap_unsubscribe(param->imap, param->mb);
+       result->error = r;
+       debug_print("imap %ssubscribe run - end %d\n", param->subscribe?"":"un", r);
+}
+
+int imap_threaded_subscribe(Folder * folder, const char * mb,
+                      gboolean subscribe)
+{
+       struct subscribe_param param;
+       struct subscribe_result result;
+       
+       debug_print("imap list - begin\n");
+       
+       param.imap = get_imap(folder);
+       param.mb = mb;
+       param.subscribe = subscribe;
+
+       threaded_run(folder, &param, &result, subscribe_run);
+       
+       return result.error;
+}
 
 struct login_param {
        mailimap * imap;
index d16c0ca4761bc3c3c61ba44f0541dee5431fd871..3e33f316678db664a8a8308ab50f9128050d2fe0 100644 (file)
@@ -25,6 +25,9 @@ void imap_threaded_disconnect(Folder * folder);
 int imap_threaded_list(Folder * folder, const char * base,
                       const char * wildcard,
                       clist ** p_result);
+int imap_threaded_lsub(Folder * folder, const char * base,
+                      const char * wildcard,
+                      clist ** p_result);
 int imap_threaded_login(Folder * folder,
                        const char * login, const char * password,
                        const char * type);
@@ -44,6 +47,8 @@ int imap_threaded_select(Folder * folder, const char * mb,
 int imap_threaded_examine(Folder * folder, const char * mb,
                          gint * exists, gint * recent, gint * unseen,
                          guint32 * uid_validity);
+int imap_threaded_subscribe(Folder * folder, const char * mb,
+                      gboolean subscribe);
 
 enum {
        IMAP_SEARCH_TYPE_SIMPLE,
index 5d55c17738a378f3057168346621b84c8c204501..2f018e17e34a4563defc5a4adbf74fbc02a03716 100644 (file)
@@ -454,7 +454,7 @@ static gboolean filtering_apply_rule(FilteringProp *filtering, MsgInfo *info,
     gboolean * final)
 {
        gboolean result = TRUE;
-       gchar    buf[50];
+       gchar    buf[256];
         GSList * tmp;
         
         * final = FALSE;
index 7f76e8553a3a70652004b9245ce2fe98e0d77034..29453efd865aab6801270406ce27e6f268f7b48b 100644 (file)
@@ -254,7 +254,8 @@ static gint imap_auth                       (IMAPSession    *session,
                                         IMAPAuthType    type);
 
 static gint imap_scan_tree_recursive   (IMAPSession    *session,
-                                        FolderItem     *item);
+                                        FolderItem     *item,
+                                        gboolean        subs_only);
 
 static void imap_create_missing_folders        (Folder         *folder);
 static FolderItem *imap_create_special_folder
@@ -1492,7 +1493,7 @@ static gint imap_close(Folder *folder, FolderItem *item)
        return 0;
 }
 
-static gint imap_scan_tree(Folder *folder)
+gint imap_scan_tree_real(Folder *folder, gboolean subs_only)
 {
        FolderItem *item = NULL;
        IMAPSession *session;
@@ -1543,7 +1544,7 @@ static gint imap_scan_tree(Folder *folder)
                        return -1;
                }
                mailimap_list_result_free(lep_list);
-               
+                               
                g_free(real_path);
        }
 
@@ -1562,14 +1563,24 @@ static gint imap_scan_tree(Folder *folder)
                folder->node = item->node = g_node_new(item);
        }
 
-       imap_scan_tree_recursive(session, FOLDER_ITEM(folder->node->data));
+       imap_scan_tree_recursive(session, FOLDER_ITEM(folder->node->data), subs_only);
        imap_create_missing_folders(folder);
        unlock_session();
 
        return 0;
 }
 
-static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
+static gint imap_scan_tree(Folder *folder)
+{
+       gboolean subs_only = FALSE;
+       if (folder->account) {
+               printf(" scanning only subs %d\n", folder->account->imap_subsonly);
+               subs_only = folder->account->imap_subsonly;
+       }
+       return imap_scan_tree_real(folder, subs_only);
+}
+
+static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item, gboolean subs_only)
 {
        Folder *folder;
        IMAPFolder *imapfolder;
@@ -1609,7 +1620,12 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
        Xstrcat_a(wildcard_path, real_path, wildcard,
                  {g_free(real_path); return IMAP_ERROR;});
        lep_list = NULL;
-       r = imap_threaded_list(folder, "", wildcard_path, &lep_list);
+       
+       if (subs_only)
+               r = imap_threaded_lsub(folder, "", wildcard_path, &lep_list);
+       else
+               r = imap_threaded_list(folder, "", wildcard_path, &lep_list);
+
        if (r != MAILIMAP_NO_ERROR) {
                item_list = NULL;
        }
@@ -1701,7 +1717,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
                }
 
                if (new_item->no_sub == FALSE)
-                       imap_scan_tree_recursive(session, new_item);
+                       imap_scan_tree_recursive(session, new_item, subs_only);
        }
 
        g_slist_free(item_list);
@@ -1709,6 +1725,14 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
        return IMAP_SUCCESS;
 }
 
+gint imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only)
+{
+       IMAPSession *session = imap_session_get(folder);
+       if (!session)
+               return -1;
+       return imap_scan_tree_recursive(session, item, subs_only);
+}
+
 static gint imap_create_tree(Folder *folder)
 {
        g_return_val_if_fail(folder != NULL, -1);
@@ -1831,6 +1855,7 @@ static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
        const gchar *p;
        gint ok;
        gboolean no_select = FALSE, no_sub = FALSE;
+       gboolean exist = FALSE;
        
        g_return_val_if_fail(folder != NULL, NULL);
        g_return_val_if_fail(folder->account != NULL, NULL);
@@ -1877,7 +1902,6 @@ static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
 
        if (strcmp(dirpath, "INBOX") != 0) {
                GPtrArray *argbuf;
-               gboolean exist = FALSE;
                int r;
                clist * lep_list;
                
@@ -1918,8 +1942,8 @@ static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
                                } 
                                mailimap_list_result_free(lep_list);
                        }
-
                }
+               imap_threaded_subscribe(folder, imap_path, TRUE);
        } else {
                clist *lep_list;
                int r;
@@ -1950,6 +1974,12 @@ static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
                make_dir_hier(dirpath);
        g_free(dirpath);
        unlock_session();
+
+       if (exist) {
+               /* folder existed, scan it */
+               folder_item_scan_full(new_item, FALSE);
+       }
+
        return new_item;
 }
 
@@ -2048,6 +2078,29 @@ static gint imap_rename_folder(Folder *folder, FolderItem *item,
        return 0;
 }
 
+gint imap_subscribe(Folder *folder, FolderItem *item, gboolean sub)
+{
+       gchar *path;
+       gint r;
+       IMAPSession *session;
+       debug_print("getting session...\n");
+
+       session = imap_session_get(folder);
+       if (!session || !item->path) {
+               return -1;
+       }
+
+       path = imap_get_real_path(session, IMAP_FOLDER(folder), item->path);
+       if (!path)
+               return -1;
+       if (!strcmp(path, "INBOX") && sub == FALSE)
+               return -1;
+       debug_print("%ssubscribing %s\n", sub?"":"un", path);
+       r = imap_threaded_subscribe(folder, path, sub);
+       g_free(path);
+       return r;
+}
+
 static gint imap_remove_folder_real(Folder *folder, FolderItem *item)
 {
        gint ok;
@@ -2066,6 +2119,7 @@ static gint imap_remove_folder_real(Folder *folder, FolderItem *item)
        }
        path = imap_get_real_path(session, IMAP_FOLDER(folder), item->path);
 
+       imap_threaded_subscribe(folder, path, FALSE);
        ok = imap_cmd_delete(session, path);
        if (ok != IMAP_SUCCESS) {
                gchar *tmp = g_strdup_printf("%s%c", path, 
@@ -4441,6 +4495,20 @@ void imap_disconnect_all(void)
 {
 }
 
+gint imap_scan_tree_real(Folder *folder, gboolean subs_only)
+{
+       return -1;
+}
+
+gint imap_subscribe(Folder *folder, FolderItem *item, gboolean sub)
+{
+       return -1;
+}
+
+gint imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only)
+{
+       return -1;
+}
 #endif
 
 void imap_synchronise(FolderItem *item) 
index 1a59b56c03e7aeb383d09a98b3920b424b8a7f2f..cf24e8a2c38acb75ea324522bbafcf9bc13ce3c0 100644 (file)
@@ -36,4 +36,7 @@ void imap_folder_ref(Folder *folder);
 void imap_folder_unref(Folder *folder);
 gchar imap_get_path_separator_for_item (FolderItem *item);
 void imap_disconnect_all(void);
+gint imap_scan_tree_real(Folder *folder, gboolean subs_only);
+gint imap_subscribe(Folder *folder, FolderItem *item, gboolean sub);
+gint imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only);
 #endif /* __IMAP_H__ */
index 5a80b5dd0d66c1cc166c6f53d6ed8ec5b86f1120..6383b92d648017048d9ebfd022839413cdfd0d1f 100644 (file)
@@ -49,6 +49,8 @@ static void delete_folder_cb(FolderView *folderview, guint action, GtkWidget *wi
 static void update_tree_cb(FolderView *folderview, guint action, GtkWidget *widget);
 static void download_cb(FolderView *folderview, guint action, GtkWidget *widget);
 static void sync_cb(FolderView *folderview, guint action, GtkWidget *widget);
+static void subscribed_cb(FolderView *folderview, guint action, GtkWidget *widget);
+static void subscribe_cb(FolderView *folderview, guint action, GtkWidget *widget);
 
 static GtkItemFactoryEntry imap_popup_entries[] =
 {
@@ -60,9 +62,17 @@ static GtkItemFactoryEntry imap_popup_entries[] =
        {"/---",                         NULL, NULL,             0, "<Separator>"},
        {N_("/_Delete folder..."),       NULL, delete_folder_cb, 0, NULL},
        {"/---",                         NULL, NULL,             0, "<Separator>"},
-       {N_("/Synchronise"),             NULL, sync_cb,         0, NULL},
+       {N_("/_Synchronise"),            NULL, sync_cb,          0, NULL},
        {N_("/Down_load messages"),      NULL, download_cb,      0, NULL},
        {"/---",                         NULL, NULL,             0, "<Separator>"},
+       {N_("/S_ubscriptions"),          NULL, NULL,             0, "<Branch>"},
+       {N_("/Subscriptions/Show only subscribed _folders"),    
+                                        NULL, subscribed_cb,    0, "<ToggleItem>"},
+       {N_("/Subscriptions/---"),       NULL, NULL,             0, "<Separator>"},
+       {N_("/Subscriptions/_Subscribe..."),NULL, subscribe_cb,          1, NULL},
+       {N_("/Subscriptions/_Unsubscribe..."),    
+                                        NULL, subscribe_cb,     0, NULL},
+       {"/---",                         NULL, NULL,             0, "<Separator>"},
        {N_("/_Check for new messages"), NULL, update_tree_cb,   0, NULL},
        {N_("/C_heck for new folders"),  NULL, update_tree_cb,   1, NULL},
        {N_("/R_ebuild folder tree"),    NULL, update_tree_cb,   2, NULL},
@@ -100,6 +110,7 @@ static void set_sensitivity(GtkItemFactory *factory, FolderItem *item)
                        !folder_has_parent_of_type(item, F_DRAFT) &&
                        !folder_has_parent_of_type(item, F_QUEUE) &&
                        !folder_has_parent_of_type(item, F_TRASH);
+
 #define SET_SENS(name, sens) \
        menu_set_sensitive(factory, name, sens)
 
@@ -113,6 +124,10 @@ static void set_sensitivity(GtkItemFactory *factory, FolderItem *item)
        SET_SENS("/Check for new messages", folder_item_parent(item) == NULL);
        SET_SENS("/Check for new folders",  folder_item_parent(item) == NULL);
        SET_SENS("/Rebuild folder tree",    folder_item_parent(item) == NULL);
+       
+       SET_SENS("/Subscriptions/Unsubscribe...",    item->stype == F_NORMAL && folder_item_parent(item) != NULL);
+       SET_SENS("/Subscriptions/Subscribe...",    TRUE);
+       menu_set_active(factory, "/Subscriptions/Show only subscribed folders", item->folder->account->imap_subsonly);
 
 #undef SET_SENS
 }
@@ -373,6 +388,93 @@ void imap_gtk_synchronise(FolderItem *item)
        main_window_cursor_normal(mainwin);
 
 }
+
+static void chk_update_val(GtkWidget *widget, gpointer data)
+{
+        gboolean *val = (gboolean *)data;
+       *val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+
+static gboolean imap_gtk_subscribe_func(GNode *node, gpointer data)
+{
+       FolderItem *item = node->data;
+       gboolean action = GPOINTER_TO_INT(data);
+       
+       if (item->path)
+               imap_subscribe(item->folder, item, action);
+
+       return FALSE;
+}
+
+static void subscribe_cb(FolderView *folderview, guint action,
+                          GtkWidget *widget)
+{
+       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+       FolderItem *item;
+       gchar *message, *name;
+       AlertValue avalue;
+       GtkWidget *rec_chk;
+       gboolean recurse = FALSE;
+
+       if (!folderview->selected) return;
+
+       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
+       g_return_if_fail(item != NULL);
+       g_return_if_fail(item->folder != NULL);
+
+       name = trim_string(item->name, 32);
+       AUTORELEASE_STR(name, {g_free(name); return;});
+       
+       if (action && item->folder->account->imap_subsonly) {
+               alertpanel_notice(_("This folder is already subscribed to. To "
+                                 "subscribe to other folders, you must first "
+                                 "disable \"Show subscribed folders only\".\n"
+                                 "\n"
+                                 "Alternatively, you can use \"Create new folder\" "
+                                 "to subscribe to a known folder."));
+               return;
+       }
+       message = g_strdup_printf
+               (_("Do you want to %s the '%s' folder?"),
+                  action?_("subscribe"):_("unsubscribe"), name);
+       
+       rec_chk = gtk_check_button_new_with_label(_("Apply to subfolders"));
+       
+       g_signal_connect(G_OBJECT(rec_chk), "toggled", 
+                       G_CALLBACK(chk_update_val), &recurse);
+
+       avalue = alertpanel_full(_("Subscriptions"), message,
+                                GTK_STOCK_CANCEL, action?_("Subscribe"):_("Unsubscribe"), NULL, FALSE,
+                                rec_chk, ALERT_QUESTION, G_ALERTDEFAULT);
+       g_free(message);
+       if (avalue != G_ALERTALTERNATE) return;
+       
+       if (recurse) {
+               g_node_traverse(item->node, G_PRE_ORDER,
+                       G_TRAVERSE_ALL, -1, imap_gtk_subscribe_func, GINT_TO_POINTER(action));
+       } else {
+               imap_subscribe(item->folder, item, action);
+       }
+
+       if (!action && item->folder->account->imap_subsonly)
+               folderview_rescan_tree(item->folder, FALSE);
+}
+
+static void subscribed_cb(FolderView *folderview, guint action,
+                          GtkWidget *widget)
+{
+       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+       FolderItem *item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
+       
+       if (!item || !item->folder || !item->folder->account)
+               return;
+       if (item->folder->account->imap_subsonly == GTK_CHECK_MENU_ITEM(widget)->active)
+               return;
+
+       item->folder->account->imap_subsonly = GTK_CHECK_MENU_ITEM(widget)->active;
+       folderview_rescan_tree(item->folder, FALSE);
+}
+
 static void download_cb(FolderView *folderview, guint action,
                        GtkWidget *widget)
 {
index 636baf40d9bed5c003fa0f5316ade8617ce5e3ea..23b1b87b81665e4a0f22d854009325e42d01f2b9 100644 (file)
@@ -132,6 +132,7 @@ static struct Receive {
        GtkWidget *imap_auth_type_optmenu;
        GtkWidget *imapdir_label;
        GtkWidget *imapdir_entry;
+       GtkWidget *subsonly_chkbtn;
 
        GtkWidget *frame_maxarticle;
        GtkWidget *maxarticle_label;
@@ -593,6 +594,10 @@ static PrefParam param[] = {
        {"imap_directory", NULL, &tmp_ac_prefs.imap_dir, P_STRING,
         &receive.imapdir_entry, prefs_set_data_from_entry, prefs_set_entry},
 
+       {"imap_subsonly", "TRUE", &tmp_ac_prefs.imap_subsonly, P_BOOL,
+        &receive.subsonly_chkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
+
        {"set_sent_folder", "FALSE", &tmp_ac_prefs.set_sent_folder, P_BOOL,
         &advanced.sent_folder_chkbtn,
         prefs_set_data_from_toggle, prefs_set_toggle},
@@ -1014,10 +1019,20 @@ static gint prefs_account_get_new_id(void)
 void destroy_dialog(gpointer data)
 {
        PrefsAccount *ac_prefs = (PrefsAccount *) data;
-       if (!cancelled)
+       if (!cancelled) {
+               gboolean update_fld_list = FALSE;
+               if (ac_prefs->protocol == A_IMAP4 && !new_account) {
+                       if ((&tmp_ac_prefs)->imap_subsonly != ac_prefs->imap_subsonly) {
+                               update_fld_list = TRUE;
+                       } 
+               }
                *ac_prefs = tmp_ac_prefs;
-       else /* the customhdr_list may have changed, update it anyway */
+               if (update_fld_list)
+                       folderview_rescan_tree(ac_prefs->folder, FALSE);
+       } else /* the customhdr_list may have changed, update it anyway */
                ac_prefs->customhdr_list = (&tmp_ac_prefs)->customhdr_list;
+
+       
        gtk_main_quit();
 }
 
@@ -1439,6 +1454,7 @@ static void prefs_account_receive_create(void)
        GtkWidget *imap_frame;
        GtkWidget *imapdir_label;
        GtkWidget *imapdir_entry;
+       GtkWidget *subsonly_chkbtn;
        GtkWidget *local_frame;
        GtkWidget *local_vbox;
        GtkWidget *local_hbox;
@@ -1650,6 +1666,13 @@ static void prefs_account_receive_create(void)
        gtk_widget_show (imapdir_entry);
        gtk_box_pack_start (GTK_BOX (hbox1), imapdir_entry, FALSE, FALSE, 0);
 
+       hbox1 = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (hbox1);
+       gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 4);
+
+       PACK_CHECK_BUTTON (hbox1, subsonly_chkbtn,
+                          _("Show only subscribed folders"));
+
        PACK_CHECK_BUTTON (vbox1, filter_on_recv_chkbtn,
                           _("Filter messages on receiving"));
 
@@ -1674,7 +1697,7 @@ static void prefs_account_receive_create(void)
 
        receive.imapdir_label           = imapdir_label;
        receive.imapdir_entry           = imapdir_entry;
-
+       receive.subsonly_chkbtn         = subsonly_chkbtn;
        receive.local_frame             = local_frame;
        receive.local_inbox_label       = local_inbox_label;
        receive.local_inbox_entry       = local_inbox_entry;
@@ -2545,6 +2568,7 @@ static gint prefs_account_apply(void)
        gchar *new_id = NULL;
        struct BasicProtocol *protocol_optmenu = (struct BasicProtocol *) basic.protocol_optmenu;
        GtkWidget *optmenu = protocol_optmenu->combobox;
+       gboolean old_subsonly = TRUE;
 
        protocol = combobox_get_active_data(GTK_COMBO_BOX(optmenu));
 
@@ -2620,6 +2644,7 @@ static gint prefs_account_apply(void)
                g_free(old_id);
                g_free(new_id);
        }
+       
        return 0;
 }
 
@@ -3026,6 +3051,7 @@ static void prefs_account_protocol_changed(GtkComboBox *combobox, gpointer data)
                gtk_widget_hide(advanced.tunnelcmd_entry);
                gtk_widget_hide(receive.imapdir_label);
                gtk_widget_hide(receive.imapdir_entry);
+               gtk_widget_hide(receive.subsonly_chkbtn);
                break;
        case A_LOCAL:
                gtk_widget_hide(protocol_optmenu->no_imap_warn_icon);
@@ -3110,6 +3136,7 @@ static void prefs_account_protocol_changed(GtkComboBox *combobox, gpointer data)
                gtk_widget_hide(advanced.tunnelcmd_entry);
                gtk_widget_hide(receive.imapdir_label);
                gtk_widget_hide(receive.imapdir_entry);
+               gtk_widget_hide(receive.subsonly_chkbtn);
                break;
        case A_IMAP4:
 #ifndef HAVE_LIBETPAN
@@ -3199,6 +3226,7 @@ static void prefs_account_protocol_changed(GtkComboBox *combobox, gpointer data)
                gtk_widget_show(advanced.tunnelcmd_entry);
                gtk_widget_show(receive.imapdir_label);
                gtk_widget_show(receive.imapdir_entry);
+               gtk_widget_show(receive.subsonly_chkbtn);
                break;
        case A_NONE:
                gtk_widget_hide(protocol_optmenu->no_imap_warn_icon);
@@ -3282,6 +3310,7 @@ static void prefs_account_protocol_changed(GtkComboBox *combobox, gpointer data)
                gtk_widget_hide(advanced.tunnelcmd_entry);
                gtk_widget_hide(receive.imapdir_label);
                gtk_widget_hide(receive.imapdir_entry);
+               gtk_widget_hide(receive.subsonly_chkbtn);
                break;
        case A_POP3:
        default:
@@ -3370,6 +3399,7 @@ static void prefs_account_protocol_changed(GtkComboBox *combobox, gpointer data)
                gtk_widget_hide(advanced.tunnelcmd_entry);
                gtk_widget_hide(receive.imapdir_label);
                gtk_widget_hide(receive.imapdir_entry);
+               gtk_widget_hide(receive.subsonly_chkbtn);
                break;
        }
 
index 34c49c5a561bde1e57f3078adcd785e8b6ee8a78..c4b7f9251a83e6833e827b159c9dfbe53306a2a6 100644 (file)
@@ -167,6 +167,7 @@ struct _PrefsAccount
        gchar     *tunnelcmd;
 
        gchar *imap_dir;
+       gboolean imap_subsonly;
 
        gboolean set_sent_folder;
        gchar *sent_folder;
index 9c81fa85b4b30e0428135107901b63f58df3bd9d..9affa8333373e7550f862c2c82cb4b955ff51643 100644 (file)
@@ -107,6 +107,7 @@ typedef struct
        GtkWidget *recv_password_label;
        GtkWidget *recv_imap_label;
        GtkWidget *recv_imap_subdir;
+       GtkWidget *subsonly_chkbtn;
        GtkWidget *no_imap_warning;
 #ifdef USE_OPENSSL
        GtkWidget *smtp_use_ssl;
@@ -135,6 +136,7 @@ typedef struct _AccountTemplate {
        gchar *recvuser;
        gchar *recvpass;
        gchar *imapdir;
+       gboolean subsonly;
        gchar *mboxfile;
        gchar *mailbox;
        gboolean smtpssl;
@@ -170,6 +172,8 @@ static PrefParam template_params[] = {
         &tmpl.recvpass, P_STRING, NULL, NULL, NULL},
        {"imapdir", "",
         &tmpl.imapdir, P_STRING, NULL, NULL, NULL},
+       {"subsonly", "TRUE",
+        &tmpl.subsonly, P_BOOL, NULL, NULL, NULL},
        {"mboxfile", "/var/mail/$LOGIN",
         &tmpl.mboxfile, P_STRING, NULL, NULL, NULL},
        {"mailbox", "Mail",
@@ -236,10 +240,14 @@ static gchar *accountrc_tmpl =
        "#default is empty\n"
        "#recvpass=\n"
        "\n"
-       "#imap dir if imap (relative to the home on the server\n"
+       "#imap dir if imap (relative to the home on the server)\n"
        "#default is empty\n"
        "#imapdir=\n"
        "\n"
+       "#show subscribed folders only, if imap\n"
+       "#default is TRUE\n"
+       "#subsonly=\n"
+       "\n"
        "#mbox file if local\n"
        "#you can use $LOGIN here\n"
        "#default is /var/mail/$LOGIN\n"
@@ -729,6 +737,9 @@ static gboolean wizard_write_config(WizardWindow *wizard)
                if (directory && strlen(directory)) {
                        prefs_account->imap_dir = g_strdup(directory);
                }
+               prefs_account->imap_subsonly = 
+                       gtk_toggle_button_get_active(
+                               GTK_TOGGLE_BUTTON(wizard->subsonly_chkbtn));
                g_free(directory);
        }
 
@@ -1025,6 +1036,7 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
                gtk_entry_set_text(GTK_ENTRY(wizard->recv_server), text);
                gtk_widget_hide(wizard->recv_imap_label);
                gtk_widget_hide(wizard->recv_imap_subdir);
+               gtk_widget_hide(wizard->subsonly_chkbtn);
                gtk_widget_show(wizard->recv_username);
                gtk_widget_show(wizard->recv_password);
                gtk_widget_show(wizard->recv_username_label);
@@ -1044,6 +1056,7 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
                gtk_entry_set_text(GTK_ENTRY(wizard->recv_server), text);
                gtk_widget_show(wizard->recv_imap_label);
                gtk_widget_show(wizard->recv_imap_subdir);
+               gtk_widget_show(wizard->subsonly_chkbtn);
                gtk_widget_show(wizard->recv_username);
                gtk_widget_show(wizard->recv_password);
                gtk_widget_show(wizard->recv_username_label);
@@ -1060,6 +1073,7 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
 #else
                gtk_widget_hide(wizard->recv_imap_label);
                gtk_widget_hide(wizard->recv_imap_subdir);
+               gtk_widget_hide(wizard->subsonly_chkbtn);
                gtk_widget_hide(wizard->recv_username);
                gtk_widget_hide(wizard->recv_password);
                gtk_widget_hide(wizard->recv_username_label);
@@ -1078,6 +1092,7 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
                gtk_widget_hide(wizard->no_imap_warning);
                gtk_widget_hide(wizard->recv_imap_label);
                gtk_widget_hide(wizard->recv_imap_subdir);
+               gtk_widget_hide(wizard->subsonly_chkbtn);
                gtk_widget_hide(wizard->recv_username);
                gtk_widget_hide(wizard->recv_password);
                gtk_widget_hide(wizard->recv_username_label);
@@ -1103,9 +1118,9 @@ static void wizard_protocol_changed(GtkMenuItem *menuitem, gpointer data)
 static GtkWidget* recv_page (WizardWindow * wizard)
 {
 #ifdef USE_OPENSSL
-       GtkWidget *table = gtk_table_new(7,2, FALSE);
+       GtkWidget *table = gtk_table_new(8,2, FALSE);
 #else
-       GtkWidget *table = gtk_table_new(5,2, FALSE);
+       GtkWidget *table = gtk_table_new(6,2, FALSE);
 #endif
        GtkWidget *menu = gtk_menu_new();
        GtkWidget *menuitem;
@@ -1212,6 +1227,16 @@ static GtkWidget* recv_page (WizardWindow * wizard)
 
        i++;
        
+       wizard->subsonly_chkbtn = gtk_check_button_new_with_label(
+                       _("Show subscribed folders only"));
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wizard->subsonly_chkbtn),
+                       tmpl.subsonly);
+       gtk_table_attach(GTK_TABLE(table), wizard->subsonly_chkbtn,                           
+                        0,1,i,i+1, GTK_EXPAND|GTK_FILL, 0, 0, 0);            
+
+       i++;
+       
+       
        wizard->no_imap_warning = gtk_label_new(_(
                          "<span weight=\"bold\">Warning: this version of Claws Mail\n"
                          "has been built without IMAP support.</span>"));
@@ -1461,6 +1486,7 @@ gboolean run_wizard(MainWindow *mainwin, gboolean create_mailbox) {
 
        gtk_widget_hide(wizard->recv_imap_label);
        gtk_widget_hide(wizard->recv_imap_subdir);
+       gtk_widget_hide(wizard->subsonly_chkbtn);
 
        wizard_protocol_change(wizard, tmpl.recvtype);