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.
This commit is contained in:
Colin Leroy 2005-10-08 10:38:28 +00:00
parent fdebe80d60
commit ee21670e16
7 changed files with 166 additions and 24 deletions

View file

@ -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

View file

@ -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

View file

@ -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=

View file

@ -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;

View file

@ -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__ */

View file

@ -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;

View file

@ -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",