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 6ab12ee..777210e 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 8e37f75..f324b76 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 c29c2f7..1e3dd2f 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 a022c5c..0bd7661 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 22d2388..c03e9c6 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 d16c0ca..3e33f31 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 5d55c17..2f018e1 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 7f76e85..29453ef 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 1a59b56..cf24e8a 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 5a80b5d..6383b92 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 636baf4..23b1b87 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 34c49c5..c4b7f92 100644 (file)
@@ -167,6 +167,7 @@ struct _PrefsAccount
        gchar     *tunnelcmd;
 
        gchar *imap_dir;
+       gboolean imap_subsonly;
 
        gboolean set_sent_folder;
        gchar *sent_folder;
index 9c81fa8..9affa83 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);