From 401f8b205321741d723ed7baa64c8d28d0dd9acd Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Wed, 17 Jan 2007 17:35:04 +0000 Subject: [PATCH] 2007-01-17 [colin] 2.7.1cvs16 * src/folder.c * src/folder.h * src/folderview.c * src/folderview.h * src/imap.c * src/imap.h * src/imap_gtk.c Manage recursive search of unsubscribed folders Rescan tree without checking for new messages after subscriptions changed --- ChangeLog | 13 +++++++++++ PATCHSETS | 1 + configure.ac | 2 +- src/folder.c | 38 +++++++++++++++++++++++++++++++ src/folder.h | 1 + src/folderview.c | 40 ++++++++++++++++++++++++++++++++ src/folderview.h | 2 +- src/imap.c | 59 +++++++++++++++++++++++++++++++++++++++++------- src/imap.h | 2 +- src/imap_gtk.c | 41 ++++++++++++++++++++++----------- 10 files changed, 175 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 635e275c0..33019a890 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-01-17 [colin] 2.7.1cvs16 + + * src/folder.c + * src/folder.h + * src/folderview.c + * src/folderview.h + * src/imap.c + * src/imap.h + * src/imap_gtk.c + Manage recursive search of unsubscribed folders + Rescan tree without checking for new messages + after subscriptions changed + 2007-01-17 [paul] 2.7.1cvs15 * src/prefs_common.c diff --git a/PATCHSETS b/PATCHSETS index 1e23aa801..a21253b4e 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -2273,3 +2273,4 @@ ( cvs diff -u -r 1.9.2.33 -r 1.9.2.34 src/common/defs.h; cvs diff -u -r 1.1.4.2 -r 1.1.4.3 src/etpan/etpan-errors.h; cvs diff -u -r 1.1.4.4 -r 1.1.4.5 src/etpan/etpan-log.c; cvs diff -u -r 1.1.4.2 -r 1.1.4.3 src/etpan/etpan-log.h; cvs diff -u -r 1.1.4.3 -r 1.1.4.4 src/etpan/etpan-thread-manager-types.h; cvs diff -u -r 1.1.4.3 -r 1.1.4.4 src/etpan/etpan-thread-manager.c; cvs diff -u -r 1.1.4.2 -r 1.1.4.3 src/etpan/etpan-thread-manager.h; cvs diff -u -r 1.1.4.71 -r 1.1.4.72 src/etpan/imap-thread.c; cvs diff -u -r 1.1.4.13 -r 1.1.4.14 src/etpan/imap-thread.h; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 tools/make.themes.project; ) > 2.7.1cvs13.patchset ( cvs diff -u -r 1.49.2.87 -r 1.49.2.88 src/procmime.c; ) > 2.7.1cvs14.patchset ( cvs diff -u -r 1.204.2.117 -r 1.204.2.118 src/prefs_common.c; cvs diff -u -r 1.5.2.42 -r 1.5.2.43 src/gtk/pluginwindow.c; ) > 2.7.1cvs15.patchset +( cvs diff -u -r 1.213.2.130 -r 1.213.2.131 src/folder.c; cvs diff -u -r 1.87.2.35 -r 1.87.2.36 src/folder.h; cvs diff -u -r 1.207.2.143 -r 1.207.2.144 src/folderview.c; cvs diff -u -r 1.20.2.16 -r 1.20.2.17 src/folderview.h; cvs diff -u -r 1.179.2.153 -r 1.179.2.154 src/imap.c; cvs diff -u -r 1.34.2.12 -r 1.34.2.13 src/imap.h; cvs diff -u -r 1.1.2.40 -r 1.1.2.41 src/imap_gtk.c; ) > 2.7.1cvs16.patchset diff --git a/configure.ac b/configure.ac index 35ffb15b9..e51cc20d6 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=7 MICRO_VERSION=1 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=15 +EXTRA_VERSION=16 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/folder.c b/src/folder.c index b126fa7d0..7ecf5631e 100644 --- a/src/folder.c +++ b/src/folder.c @@ -861,6 +861,44 @@ void folder_scan_tree(Folder *folder, gboolean rebuild) folder_write_list(); } +gboolean folder_restore_prefs_func(GNode *node, gpointer data) +{ + GHashTable *pptable = (GHashTable *)data; + FolderItem *item = (FolderItem *)node->data; + + folder_item_restore_persist_prefs(item, pptable); + + return FALSE; +} + +void folder_fast_scan_tree(Folder *folder) +{ + GHashTable *pptable; + FolderUpdateData hookdata; + Folder *old_folder = folder; + + if (!folder->klass->scan_tree) + return; + + pptable = folder_persist_prefs_new(folder); + + if (folder->klass->scan_tree(folder) < 0) { + return; + } + + hookdata.folder = folder; + hookdata.update_flags = FOLDER_TREE_CHANGED; + hookdata.item = NULL; + hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata); + + g_node_traverse(folder->node, G_POST_ORDER, G_TRAVERSE_ALL, -1, folder_restore_prefs_func, pptable); + folder_persist_prefs_free(pptable); + + prefs_matcher_read_config(); + + folder_write_list(); +} + FolderItem *folder_create_folder(FolderItem *parent, const gchar *name) { FolderItem *new_item; diff --git a/src/folder.h b/src/folder.h index b4b85776f..57acfee4b 100644 --- a/src/folder.h +++ b/src/folder.h @@ -733,6 +733,7 @@ GList *folder_get_list (void); gint folder_read_list (void); void folder_write_list (void); void folder_scan_tree (Folder *folder, gboolean rebuild); +void folder_fast_scan_tree (Folder *folder); FolderItem *folder_create_folder(FolderItem *parent, const gchar *name); gint folder_item_rename (FolderItem *item, gchar *newname); void folder_update_op_count (void); diff --git a/src/folderview.c b/src/folderview.c index 4ecb0fc75..5761d83d5 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -1131,6 +1131,46 @@ void folderview_rescan_tree(Folder *folder, gboolean rebuild) inc_unlock(); } +void folderview_fast_rescan_tree(Folder *folder) +{ + GtkWidget *window; + MainWindow *mainwin = mainwindow_get_mainwindow(); + FolderView *folderview = NULL; + GtkAdjustment *pos = NULL; + gint height = 0; + + g_return_if_fail(folder != NULL); + + if (!folder->klass->scan_tree) return; + + inc_lock(); + + window = label_window_create(_("Scanning folder tree...")); + + if (mainwin) + folderview = mainwin->folderview; + + if (folderview) { + pos = gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(folderview->scrolledwin)); + height = pos->value; + } + + folder_set_ui_func(folder, folderview_scan_tree_func, NULL); + folder_fast_scan_tree(folder); + folder_set_ui_func(folder, NULL, NULL); + + folderview_set_all(); + + if (folderview) { + pos = gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(folderview->scrolledwin)); + gtk_adjustment_set_value(pos, height); + } + gtk_widget_destroy(window); + inc_unlock(); +} + /** folderview_check_new() * Scan and update the folder and return the * count the number of new messages since last check. diff --git a/src/folderview.h b/src/folderview.h index 845acc723..698fb8574 100644 --- a/src/folderview.h +++ b/src/folderview.h @@ -112,7 +112,7 @@ void folderview_append_item (FolderItem *item); void folderview_rescan_tree (Folder *folder, gboolean rebuild); -void folderview_rescan_all (void); +void folderview_fast_rescan_tree (Folder *folder); gint folderview_check_new (Folder *folder); void folderview_check_new_all (void); diff --git a/src/imap.c b/src/imap.c index de91783db..7ea2a4477 100644 --- a/src/imap.c +++ b/src/imap.c @@ -1725,7 +1725,7 @@ static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item, gbo return IMAP_SUCCESS; } -GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only) +GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean unsubs_only, gboolean recursive) { IMAPSession *session = imap_session_get(folder); gchar *real_path; @@ -1734,7 +1734,8 @@ GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only) gchar wildcard[3]; clist * lep_list; GSList *item_list = NULL, *cur; - GList *child_list = NULL; + GList *child_list = NULL, *tmplist = NULL; + GSList *sub_list = NULL; int r; if (!session) @@ -1757,26 +1758,68 @@ GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only) {g_free(real_path); return NULL;}); lep_list = NULL; - if (subs_only) - r = imap_threaded_lsub(folder, "", wildcard_path, &lep_list); + if (unsubs_only) + statusbar_print_all(_("Looking for unsubscribed folders in %s..."), + item->path?item->path:item->name); else - r = imap_threaded_list(folder, "", wildcard_path, &lep_list); - if (r) - return NULL; + statusbar_print_all(_("Looking for subfolders of %s..."), + item->path?item->path:item->name); + r = imap_threaded_list(folder, "", wildcard_path, &lep_list); + if (r) { + statusbar_pop_all(); + return NULL; + } item_list = imap_list_from_lep(IMAP_FOLDER(folder), lep_list, real_path, FALSE); mailimap_list_result_free(lep_list); for (cur = item_list; cur != NULL; cur = cur->next) { FolderItem *cur_item = FOLDER_ITEM(cur->data); + if (recursive) { + tmplist = imap_scan_subtree(folder, cur_item, + unsubs_only, recursive); + if (tmplist) + child_list = g_list_concat(child_list, tmplist); + } child_list = g_list_prepend(child_list, imap_get_real_path(session, IMAP_FOLDER(folder), cur_item->path)); + folder_item_destroy(cur_item); } child_list = g_list_reverse(child_list); g_slist_free(item_list); + + if (unsubs_only) { + r = imap_threaded_lsub(folder, "", wildcard_path, &lep_list); + if (r) { + statusbar_pop_all(); + return NULL; + } + sub_list = imap_list_from_lep(IMAP_FOLDER(folder), + lep_list, real_path, FALSE); + mailimap_list_result_free(lep_list); + + for (cur = sub_list; cur != NULL; cur = cur->next) { + FolderItem *cur_item = FOLDER_ITEM(cur->data); + GList *oldlitem = NULL; + gchar *tmp = imap_get_real_path(session, + IMAP_FOLDER(folder), cur_item->path); + folder_item_destroy(cur_item); + oldlitem = g_list_find_custom( + child_list, tmp, (GCompareFunc)strcmp2); + if (oldlitem) { + child_list = g_list_remove_link(child_list, oldlitem); + g_free(oldlitem->data); + g_list_free(oldlitem); + } + g_free(tmp); + } + } + + statusbar_pop_all(); + return child_list; } @@ -4555,7 +4598,7 @@ gint imap_subscribe(Folder *folder, FolderItem *item, gchar *rpath, gboolean sub return -1; } -GList * imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only) +GList * imap_scan_subtree(Folder *folder, FolderItem *item, gboolean unsubs_only, gboolean recursive) { return -1; } diff --git a/src/imap.h b/src/imap.h index 1bcc90317..d329fceca 100644 --- a/src/imap.h +++ b/src/imap.h @@ -38,5 +38,5 @@ 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, gchar *rpath, gboolean sub); -GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean subs_only); +GList *imap_scan_subtree(Folder *folder, FolderItem *item, gboolean unsubs_only, gboolean recursive); #endif /* __IMAP_H__ */ diff --git a/src/imap_gtk.c b/src/imap_gtk.c index dcd2f1d74..fc118ed23 100644 --- a/src/imap_gtk.c +++ b/src/imap_gtk.c @@ -426,13 +426,33 @@ static void subscribe_cb(FolderView *folderview, guint action, AUTORELEASE_STR(name, {g_free(name); return;}); if (action && item->folder->account->imap_subsonly) { - GList *child_list = imap_scan_subtree(item->folder, item, FALSE); + GList *child_list = NULL; + + message = g_strdup_printf + (_("Do you want to look for unsubscribed subfolders of '%s'?"), + name); + + rec_chk = gtk_check_button_new_with_label(_("Look recursively")); + + g_signal_connect(G_OBJECT(rec_chk), "toggled", + G_CALLBACK(chk_update_val), &recurse); + + avalue = alertpanel_full(_("Subscriptions"), message, + GTK_STOCK_CANCEL, _("+_Search"), NULL, FALSE, + rec_chk, ALERT_QUESTION, G_ALERTDEFAULT); + g_free(message); + if (avalue != G_ALERTALTERNATE) return; + + child_list = imap_scan_subtree(item->folder, item, TRUE, recurse); if (child_list) { GList *cur; int r = -1; + gchar *msg = g_strdup_printf(_("Choose a subfolder of %s to subscribe to: "), + item->name); gchar *child_folder = input_dialog_combo(_("Subscribe"), - _("Choose a subfolder to subscribe to: "), - _("All of them"), child_list, TRUE); + msg, + child_list->next?_("All of them"):child_list->data, child_list, TRUE); + g_free(msg); if (child_folder && strcmp(child_folder, _("All of them"))) { r = imap_subscribe(item->folder, NULL, child_folder, TRUE); } else if (child_folder) { @@ -443,15 +463,10 @@ static void subscribe_cb(FolderView *folderview, guint action, for (cur = child_list; cur; cur = cur->next) g_free((gchar *)cur->data); if (r == 0) - folderview_rescan_tree(item->folder, FALSE); + folderview_fast_rescan_tree(item->folder); } else { alertpanel_notice(_("This folder is already subscribed to and " - "has no subfolders. 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.")); + "has no unsubscribed subfolders.")); } g_list_free(child_list); return; @@ -466,7 +481,7 @@ static void subscribe_cb(FolderView *folderview, guint action, G_CALLBACK(chk_update_val), &recurse); avalue = alertpanel_full(_("Subscriptions"), message, - GTK_STOCK_CANCEL, action?_("Subscribe"):_("Unsubscribe"), NULL, FALSE, + GTK_STOCK_CANCEL, action?_("+_Subscribe"):_("+_Unsubscribe"), NULL, FALSE, rec_chk, ALERT_QUESTION, G_ALERTDEFAULT); g_free(message); if (avalue != G_ALERTALTERNATE) return; @@ -479,7 +494,7 @@ static void subscribe_cb(FolderView *folderview, guint action, } if (!action && item->folder->account->imap_subsonly) - folderview_rescan_tree(item->folder, FALSE); + folderview_fast_rescan_tree(item->folder); } static void subscribed_cb(FolderView *folderview, guint action, @@ -494,7 +509,7 @@ static void subscribed_cb(FolderView *folderview, guint action, return; item->folder->account->imap_subsonly = GTK_CHECK_MENU_ITEM(widget)->active; - folderview_rescan_tree(item->folder, FALSE); + folderview_fast_rescan_tree(item->folder); } static void download_cb(FolderView *folderview, guint action, -- 2.25.1