From: Colin Leroy Date: Sat, 8 Oct 2005 10:38:28 +0000 (+0000) Subject: 2005-10-08 [colin] 1.9.15cvs21 X-Git-Tag: rel_1_9_99~116 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=ee21670e16aa4f220908f17230d88b176e700d67 2005-10-08 [colin] 1.9.15cvs21 * src/folder.c * src/folder.h Add a processing_pending indicator, set on folder_item_open and cleared after folder_item_process_open * src/folderview.c * src/summaryview.c wrap procmsg_msginfo_*_flags, and in the wrapper check that there's no folder processing pending. If there is, defer the flags change until processing is done to avoid stepping over each other's toes. Freeze during processing, but not during scanning. --- diff --git a/ChangeLog-gtk2.claws b/ChangeLog-gtk2.claws index 73584b1e0..949fa724f 100644 --- a/ChangeLog-gtk2.claws +++ b/ChangeLog-gtk2.claws @@ -1,3 +1,19 @@ +2005-10-08 [colin] 1.9.15cvs21 + + * src/folder.c + * src/folder.h + Add a processing_pending indicator, set on + folder_item_open and cleared after + folder_item_process_open + * src/folderview.c + * src/summaryview.c + wrap procmsg_msginfo_*_flags, and in the + wrapper check that there's no folder processing + pending. If there is, defer the flags change until + processing is done to avoid stepping over each + other's toes. + Freeze during processing, but not during scanning. + 2005-10-07 [colin] 1.9.15cvs20 * src/plugins/pgpcore/passphrase.c diff --git a/PATCHSETS b/PATCHSETS index f68c38fa2..d99e5bf65 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -857,3 +857,4 @@ ( cvs diff -u -r 1.1 -r 1.2 src/pixmaps/address.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/address_book.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/book.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/check_spelling.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/checkbox_off.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/checkbox_on.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/close.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/complete.xpm; cvs diff -u -r 1.1.16.1 -r 1.1.16.2 src/pixmaps/continue.xpm; cvs diff -u -r 1.1.1.1 -r 1.1.1.2 src/pixmaps/deleted.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/down_arrow.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/exec.xpm; cvs diff -u -r 1.1.1.1 -r 1.1.1.2 src/pixmaps/forwarded.xpm; cvs diff -u -r 1.1.1.1.16.1 -r 1.1.1.1.16.2 src/pixmaps/group.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/ignorethread.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/interface.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/jpilot.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/ldap.xpm; cvs diff -u -r 1.1.1.1 -r 1.1.1.2 src/pixmaps/linewrap.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/linewrapcurrent.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_attach.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_compose.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_forward.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_receive.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_receive_all.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_reply.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_reply_to_all.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_reply_to_author.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_send.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mail_send_queue.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mime_application.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mime_audio.xpm; cvs diff -u -r 1.2 -r 1.3 src/pixmaps/mime_image.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/mime_message.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mime_text_enriched.xpm; cvs diff -u -r 1.2 -r 1.3 src/pixmaps/mime_text_html.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mime_text_plain.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/mime_unknown.xpm; cvs diff -u -r 1.2 -r 1.3 src/pixmaps/new.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/news_compose.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/offline.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/online.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/paste.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/preferences.xpm; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/pixmaps/privacy_emblem_encrypted.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_expired.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_failed.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_passed.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_signed.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_unknown.xpm; cvs diff -u -r 1.1.4.1 -r 1.1.4.2 src/pixmaps/privacy_warn.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/properties.xpm; cvs diff -u -r 1.1.1.1 -r 1.1.1.2 src/pixmaps/replied.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/search.xpm; cvs diff -u -r 1.2.16.1 -r 1.2.16.2 src/pixmaps/unread.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/up_arrow.xpm; cvs diff -u -r 1.1 -r 1.2 src/pixmaps/vcard.xpm; ) > 1.9.15cvs18.patchset ( cvs diff -u -r 1.382.2.179 -r 1.382.2.180 src/compose.c; ) > 1.9.15cvs19.patchset ( cvs diff -u -r 1.1.2.4 -r 1.1.2.5 src/plugins/pgpcore/passphrase.c; ) > 1.9.15cvs20.patchset +( cvs diff -u -r 1.213.2.62 -r 1.213.2.63 src/folder.c; cvs diff -u -r 1.87.2.21 -r 1.87.2.22 src/folder.h; cvs diff -u -r 1.207.2.69 -r 1.207.2.70 src/folderview.c; cvs diff -u -r 1.395.2.132 -r 1.395.2.133 src/summaryview.c; ) > 1.9.15cvs21.patchset diff --git a/configure.ac b/configure.ac index 8420b31f8..fdb000388 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=15 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=20 +EXTRA_VERSION=21 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/folder.c b/src/folder.c index f5a5998f5..b060a17d9 100644 --- a/src/folder.c +++ b/src/folder.c @@ -1459,7 +1459,10 @@ static gint folder_sort_folder_list(gconstpointer a, gconstpointer b) return (gint_a - gint_b); } -void folder_item_process_open(FolderItem *item) +void folder_item_process_open (FolderItem *item, + void (*before_proc_func)(gpointer data), + void (*after_proc_func)(gpointer data), + gpointer data) { gchar *buf; if (item == NULL) @@ -1476,10 +1479,17 @@ void folder_item_process_open(FolderItem *item) item->path ? item->path : item->name); debug_print("%s\n", buf); g_free(buf); - + + if (before_proc_func) + before_proc_func(data); + folder_item_apply_processing(item); + if (after_proc_func) + after_proc_func(data); + debug_print("done.\n"); + item->processing_pending = FALSE; return; } @@ -1487,6 +1497,10 @@ gint folder_item_open(FolderItem *item) { g_return_val_if_fail(item->no_select == FALSE, -1); + /* caller of folder_item_open *must* call + * folder_item_process_open after ! */ + item->processing_pending = TRUE; + item->opened = TRUE; return 0; diff --git a/src/folder.h b/src/folder.h index 4487f239e..834320ecc 100644 --- a/src/folder.h +++ b/src/folder.h @@ -627,6 +627,7 @@ struct _FolderItem /* for faster search of special parents */ SpecialFolderItemType parent_stype; + gboolean processing_pending; }; struct _PersistPrefs @@ -811,5 +812,8 @@ void folder_item_set_batch (FolderItem *item, gboolean batch); gboolean folder_has_parent_of_type (FolderItem *item, SpecialFolderItemType type); void folder_synchronise (Folder *folder); gboolean folder_want_synchronise (Folder *folder); -void folder_item_process_open (FolderItem *item); +void folder_item_process_open (FolderItem *item, + void (*before_proc_func)(gpointer data), + void (*after_proc_func)(gpointer data), + gpointer data); #endif /* __FOLDER_H__ */ diff --git a/src/folderview.c b/src/folderview.c index 36052805c..47a4d140d 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -1791,6 +1791,20 @@ static gboolean folderview_key_pressed(GtkWidget *widget, GdkEventKey *event, return FALSE; } +static void summary_freeze_for_proc(gpointer data) +{ + FolderView *folderview = (FolderView *)data; + debug_print("freezing during processing...\n"); + gtk_clist_freeze(GTK_CLIST(folderview->summaryview->ctree)); +} + +static void summary_thaw_for_proc(gpointer data) +{ + FolderView *folderview = (FolderView *)data; + debug_print("thawing after processing\n"); + gtk_clist_thaw(GTK_CLIST(folderview->summaryview->ctree)); +} + gboolean folderview_process_open(gpointer data) { FolderView *folderview = (FolderView *)data; @@ -1808,7 +1822,10 @@ gboolean folderview_process_open(gpointer data) return FALSE; folder_item_update_freeze(); - folder_item_process_open(item); + folder_item_process_open(item, + summary_freeze_for_proc, + summary_thaw_for_proc, + folderview); folder_item_update_thaw(); return FALSE; diff --git a/src/summaryview.c b/src/summaryview.c index a2a327653..4520c7727 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -2435,6 +2435,96 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row) summary_display_msg_full(summaryview, row, FALSE, FALSE); } +static gboolean defer_change(gpointer data); +typedef struct _ChangeData { + MsgInfo *info; + gint op; /* 0, 1, 2 for unset, set, change */ + MsgPermFlags set_flags; + MsgTmpFlags set_tmp_flags; + MsgPermFlags unset_flags; + MsgTmpFlags unset_tmp_flags; +} ChangeData; + +static void summary_msginfo_unset_flags(MsgInfo *msginfo, MsgPermFlags flags, MsgTmpFlags tmp_flags) +{ + if (!msginfo->folder || !msginfo->folder->processing_pending) { + debug_print("flags: doing unset now\n"); + procmsg_msginfo_unset_flags(msginfo, flags, tmp_flags); + } else { + ChangeData *unset_data = g_new0(ChangeData, 1); + unset_data->info = msginfo; + unset_data->op = 0; + unset_data->unset_flags = flags; + unset_data->unset_tmp_flags = tmp_flags; + debug_print("flags: deferring unset\n"); + g_timeout_add(100, defer_change, unset_data); + } +} + +static void summary_msginfo_set_flags(MsgInfo *msginfo, MsgPermFlags flags, MsgTmpFlags tmp_flags) +{ + if (!msginfo->folder || !msginfo->folder->processing_pending) { + debug_print("flags: doing set now\n"); + procmsg_msginfo_set_flags(msginfo, flags, tmp_flags); + } else { + ChangeData *set_data = g_new0(ChangeData, 1); + set_data->info = msginfo; + set_data->op = 1; + set_data->set_flags = flags; + set_data->set_tmp_flags = tmp_flags; + debug_print("flags: deferring set\n"); + g_timeout_add(100, defer_change, set_data); + } +} + +static void summary_msginfo_change_flags(MsgInfo *msginfo, + MsgPermFlags add_flags, MsgTmpFlags add_tmp_flags, + MsgPermFlags rem_flags, MsgTmpFlags rem_tmp_flags) +{ + if (!msginfo->folder || !msginfo->folder->processing_pending) { + debug_print("flags: doing change now\n"); + procmsg_msginfo_change_flags(msginfo, add_flags, add_tmp_flags, + rem_flags, rem_tmp_flags); + } else { + ChangeData *change_data = g_new0(ChangeData, 1); + change_data->info = msginfo; + change_data->op = 2; + change_data->set_flags = add_flags; + change_data->set_tmp_flags = add_tmp_flags; + change_data->unset_flags = rem_flags; + change_data->unset_tmp_flags = rem_tmp_flags; + debug_print("flags: deferring change\n"); + g_timeout_add(100, defer_change, change_data); + } +} + +gboolean defer_change(gpointer data) +{ + ChangeData *chg = (ChangeData *)data; + if (chg->info->folder && chg->info->folder->processing_pending) { + debug_print("flags: trying later\n"); + return TRUE; /* try again */ + } else { + debug_print("flags: finally doing it\n"); + switch(chg->op) { + case 0: + procmsg_msginfo_unset_flags(chg->info, chg->unset_flags, chg->unset_tmp_flags); + break; + case 1: + procmsg_msginfo_set_flags(chg->info, chg->set_flags, chg->set_tmp_flags); + break; + case 2: + procmsg_msginfo_change_flags(chg->info, chg->set_flags, chg->set_tmp_flags, + chg->unset_flags, chg->unset_tmp_flags); + break; + default: + g_warning("shouldn't happen\n"); + } + g_free(chg); + } + return FALSE; +} + static void msginfo_mark_as_read (SummaryView *summaryview, MsgInfo *msginfo, GtkCTreeNode *row) { @@ -2443,7 +2533,7 @@ static void msginfo_mark_as_read (SummaryView *summaryview, MsgInfo *msginfo, g_return_if_fail(row != NULL); if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { - procmsg_msginfo_unset_flags + summary_msginfo_unset_flags (msginfo, MSG_NEW | MSG_UNREAD, 0); summary_set_row_marks(summaryview, row); gtk_clist_thaw(GTK_CLIST(summaryview->ctree)); @@ -2819,7 +2909,7 @@ static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row) summaryview->copied--; procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_change_flags(msginfo, MSG_MARKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY); + summary_msginfo_change_flags(msginfo, MSG_MARKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY); summary_set_row_marks(summaryview, row); debug_print("Message %s/%d is marked\n", msginfo->folder->path, msginfo->msgnum); } @@ -2842,7 +2932,7 @@ static void summary_lock_row(SummaryView *summaryview, GtkCTreeNode *row) changed = TRUE; } procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_change_flags(msginfo, MSG_LOCKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY); + summary_msginfo_change_flags(msginfo, MSG_LOCKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY); summary_set_row_marks(summaryview, row); debug_print("Message %d is locked\n", msginfo->msgnum); @@ -2857,7 +2947,7 @@ static void summary_unlock_row(SummaryView *summaryview, GtkCTreeNode *row) if (!MSG_IS_LOCKED(msginfo->flags)) return; procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_unset_flags(msginfo, MSG_LOCKED, 0); + summary_msginfo_unset_flags(msginfo, MSG_LOCKED, 0); summary_set_row_marks(summaryview, row); debug_print("Message %d is unlocked\n", msginfo->msgnum); } @@ -2888,7 +2978,7 @@ static void summary_mark_row_as_read(SummaryView *summaryview, if(!(MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags))) return; - procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0); + summary_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0); summary_set_row_marks(summaryview, row); debug_print("Message %d is marked as read\n", msginfo->msgnum); @@ -2968,11 +3058,11 @@ static void summary_mark_row_as_unread(SummaryView *summaryview, msginfo = gtk_ctree_node_get_row_data(ctree, row); if (MSG_IS_DELETED(msginfo->flags)) { procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, 0); + summary_msginfo_unset_flags(msginfo, MSG_DELETED, 0); summaryview->deleted--; } - procmsg_msginfo_set_flags(msginfo, MSG_UNREAD, 0); + summary_msginfo_set_flags(msginfo, MSG_UNREAD, 0); debug_print("Message %d is marked as unread\n", msginfo->msgnum); @@ -3065,7 +3155,7 @@ static void summary_delete_row(SummaryView *summaryview, GtkCTreeNode *row) summaryview->copied--; procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_change_flags(msginfo, MSG_DELETED, 0, MSG_MARKED, MSG_MOVE | MSG_COPY); + summary_msginfo_change_flags(msginfo, MSG_DELETED, 0, MSG_MARKED, MSG_MOVE | MSG_COPY); summaryview->deleted++; if (!prefs_common.immediate_exec && @@ -3201,7 +3291,7 @@ static void summary_unmark_row(SummaryView *summaryview, GtkCTreeNode *row) summaryview->copied--; procmsg_msginfo_set_to_folder(msginfo, NULL); - procmsg_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_MOVE | MSG_COPY); + summary_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_MOVE | MSG_COPY); summary_set_row_marks(summaryview, row); debug_print("Message %s/%d is unmarked\n", @@ -3242,10 +3332,10 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCTreeNode *row, summaryview->copied--; } if (!MSG_IS_MOVE(msginfo->flags)) { - procmsg_msginfo_change_flags(msginfo, 0, MSG_MOVE, MSG_DELETED, MSG_COPY); + summary_msginfo_change_flags(msginfo, 0, MSG_MOVE, MSG_DELETED, MSG_COPY); summaryview->moved++; } else { - procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_COPY); + summary_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_COPY); } if (!prefs_common.immediate_exec) { @@ -3324,10 +3414,10 @@ static void summary_copy_row_to(SummaryView *summaryview, GtkCTreeNode *row, } if (!MSG_IS_COPY(msginfo->flags)) { - procmsg_msginfo_change_flags(msginfo, 0, MSG_COPY, MSG_DELETED, MSG_MOVE); + summary_msginfo_change_flags(msginfo, 0, MSG_COPY, MSG_DELETED, MSG_MOVE); summaryview->copied++; } else { - procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_MOVE); + summary_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_MOVE); } if (!prefs_common.immediate_exec) { summary_set_row_marks(summaryview, row); @@ -3740,7 +3830,7 @@ static void summary_execute_copy_func(GtkCTree *ctree, GtkCTreeNode *node, summaryview->mlist = g_slist_prepend(summaryview->mlist, msginfo); - procmsg_msginfo_unset_flags(msginfo, 0, MSG_COPY); + summary_msginfo_unset_flags(msginfo, 0, MSG_COPY); summary_set_row_marks(summaryview, node); } } @@ -4195,7 +4285,7 @@ static void summary_set_row_colorlabel(SummaryView *summaryview, GtkCTreeNode *r msginfo = gtk_ctree_node_get_row_data(ctree, row); - procmsg_msginfo_change_flags(msginfo, MSG_COLORLABEL_TO_FLAGS(labelcolor), 0, + summary_msginfo_change_flags(msginfo, MSG_COLORLABEL_TO_FLAGS(labelcolor), 0, MSG_CLABEL_FLAG_MASK, 0); } @@ -4754,7 +4844,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row, break; case S_COL_LOCKED: if (MSG_IS_LOCKED(msginfo->flags)) { - procmsg_msginfo_unset_flags(msginfo, MSG_LOCKED, 0); + summary_msginfo_unset_flags(msginfo, MSG_LOCKED, 0); summary_set_row_marks(summaryview, row); } else @@ -5171,7 +5261,7 @@ static void news_flag_crosspost(MsgInfo *msginfo) g_hash_table_lookup_extended(mff->newsart, line->str, &key, &value)) { debug_print(" <%s>", (gchar *)value); if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { - procmsg_msginfo_change_flags(msginfo, + summary_msginfo_change_flags(msginfo, mff->account->crosspost_col, 0, MSG_NEW | MSG_UNREAD, 0); } g_hash_table_remove(mff->newsart, key); @@ -5189,7 +5279,7 @@ static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpoin msginfo = gtk_ctree_node_get_row_data(ctree, row); - procmsg_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0); + summary_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0); summary_set_row_marks(summaryview, row); debug_print("Message %d is marked as ignore thread\n", @@ -5219,7 +5309,7 @@ static void summary_unignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpo msginfo = gtk_ctree_node_get_row_data(ctree, row); - procmsg_msginfo_unset_flags(msginfo, MSG_IGNORE_THREAD, 0); + summary_msginfo_unset_flags(msginfo, MSG_IGNORE_THREAD, 0); summary_set_row_marks(summaryview, row); debug_print("Message %d is marked as unignore thread\n",