2008-05-12 [wwp] 3.4.0cvs30
[claws.git] / src / filtering.c
index 52eb9b2472c795d6bd95b9e12771382cd9e3c97f..732d2f95194e9d0d75b1e94d53dc246b9df2699c 100644 (file)
@@ -185,7 +185,8 @@ void filtering_move_and_copy_msgs(GSList *msgs)
 {
        GSList *messages = g_slist_copy(msgs);
        FolderItem *last_item = NULL;
-       gboolean is_copy = FALSE, is_move = FALSE;
+       FiltOp cur_op = IS_NOTHING;
+
        debug_print("checking %d messages\n", g_slist_length(msgs));
        while (messages) {
                GSList *batch = NULL, *cur;
@@ -193,44 +194,61 @@ void filtering_move_and_copy_msgs(GSList *msgs)
                for (cur = messages; cur; cur = cur->next) {
                        MsgInfo *info = (MsgInfo *)cur->data;
                        if (last_item == NULL) {
-                               last_item = info->to_filter_folder;
+                               if (info->filter_op == IS_COPY || info->filter_op == IS_MOVE)
+                                       last_item = info->to_filter_folder;
+                               else if (info->filter_op == IS_DELE)
+                                       last_item = info->folder;
                        }
                        if (last_item == NULL)
                                continue;
-                       if (!is_copy && !is_move) {
-                               if (info->is_copy)
-                                       is_copy = TRUE;
-                               else if (info->is_move)
-                                       is_move = TRUE;
+                       if (cur_op == IS_NOTHING) {
+                               if (info->filter_op == IS_COPY)
+                                       cur_op = IS_COPY;
+                               else if (info->filter_op == IS_MOVE)
+                                       cur_op = IS_MOVE;
+                               else if (info->filter_op == IS_DELE)
+                                       cur_op = IS_DELE;
                        }
-                       found++;
-                       if (info->to_filter_folder == last_item 
-                       &&  info->is_copy == is_copy
-                       &&  info->is_move == is_move) {
-                               batch = g_slist_prepend(batch, info);
+                       if (info->filter_op == IS_COPY || info->filter_op == IS_MOVE) {
+                               if (info->to_filter_folder == last_item 
+                               &&  cur_op == info->filter_op) {
+                                       found++;
+                                       batch = g_slist_prepend(batch, info);
+                               }
+                       } else if (info->filter_op == IS_DELE) {
+                               if (info->folder == last_item 
+                               &&  cur_op == info->filter_op) {
+                                       found++;
+                                       batch = g_slist_prepend(batch, info);
+                               }
                        }
                }
                if (found == 0) {
-                       debug_print("no more messages to move/copy\n");
+                       debug_print("no more messages to move/copy/del\n");
                        break;
                } else {
                        debug_print("%d messages to %s in %s\n", found,
-                               is_copy ? "copy":"move", last_item->name ? last_item->name:"(noname)");
+                               cur_op==IS_COPY ? "copy":(cur_op==IS_DELE ?"delete":"move"), 
+                               last_item?(last_item->name ? last_item->name:"(noname)"):"nowhere");
                }
                for (cur = batch; cur; cur = cur->next) {
                        MsgInfo *info = (MsgInfo *)cur->data;
                        messages = g_slist_remove(messages, info);
+                       info->to_filter_folder = NULL;
+                       info->filter_op = IS_NOTHING;
                }
                batch = g_slist_reverse(batch);
                if (g_slist_length(batch)) {
                        MsgInfo *info = (MsgInfo *)batch->data;
-                       if (is_copy && last_item != info->folder) {
+                       if (cur_op == IS_COPY && last_item != info->folder) {
                                folder_item_copy_msgs(last_item, batch);
-                       } else if (is_move && last_item != info->folder) {
+                       } else if (cur_op == IS_MOVE && last_item != info->folder) {
                                if (folder_item_move_msgs(last_item, batch) < 0)
                                        folder_item_move_msgs(
                                                folder_get_default_inbox(), 
                                                batch);
+                       } else if (cur_op == IS_DELE && last_item == info->folder) {
+                               folder_item_remove_msgs(last_item, batch);
                        }
                        /* we don't reference the msginfos, because caller will do */
                        if (prefs_common.real_time_sync)
@@ -240,8 +258,7 @@ void filtering_move_and_copy_msgs(GSList *msgs)
                        GTK_EVENTS_FLUSH();
                }
                last_item = NULL;
-               is_copy = FALSE;
-               is_move = FALSE;
+               cur_op = IS_NOTHING;
        }
        /* we don't reference the msginfos, because caller will do */
        g_slist_free(messages);
@@ -253,6 +270,14 @@ void filtering_move_and_copy_msgs(GSList *msgs)
   return value : return TRUE if the action could be applied
 */
 
+#define FLUSH_COPY_IF_NEEDED(info) {                                   \
+       if (info->filter_op == IS_COPY && info->to_filter_folder) {     \
+               debug_print("must debatch pending copy\n");             \
+               folder_item_copy_msg(info->to_filter_folder, info);     \
+               info->filter_op = IS_NOTHING;                           \
+       }                                                               \
+}
+
 static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
 {
        FolderItem * dest_folder;
@@ -271,15 +296,9 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                        return FALSE;
                }
                
-               /* check if mail is set to copy already, 
-                * in which case we have to do it */
-               if (info->is_copy && info->to_filter_folder) {
-                       debug_print("should cp and mv !\n");
-                       folder_item_copy_msg(info->to_filter_folder, info);
-                       info->is_copy = FALSE;
-               }
+               FLUSH_COPY_IF_NEEDED(info);
                /* mark message to be moved */          
-               info->is_move = TRUE;
+               info->filter_op = IS_MOVE;
                info->to_filter_folder = dest_folder;
                return TRUE;
 
@@ -293,15 +312,9 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                        return FALSE;
                }
 
-               /* check if mail is set to copy already, 
-                * in which case we have to do it */
-               if (info->is_copy && info->to_filter_folder) {
-                       debug_print("should cp and mv !\n");
-                       folder_item_copy_msg(info->to_filter_folder, info);
-                       info->is_copy = FALSE;
-               }
+               FLUSH_COPY_IF_NEEDED(info);
                /* mark message to be copied */         
-               info->is_copy = TRUE;
+               info->filter_op = IS_COPY;
                info->to_filter_folder = dest_folder;
                return TRUE;
 
@@ -313,58 +326,68 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                                action->destination ?action->destination :"(null)");
                        return FALSE;
                }
-               
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_update_tags(info, (action->type == MATCHACTION_SET_TAG), val);
                return TRUE;
 
        case MATCHACTION_CLEAR_TAGS:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_clear_tags(info);
                return TRUE;
 
        case MATCHACTION_DELETE:
-               if (folder_item_remove_msg(info->folder, info->msgnum) == -1)
-                       return FALSE;
+               FLUSH_COPY_IF_NEEDED(info);
+               info->filter_op = IS_DELE;
                return TRUE;
 
        case MATCHACTION_MARK:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_set_flags(info, MSG_MARKED, 0);
                return TRUE;
 
        case MATCHACTION_UNMARK:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_unset_flags(info, MSG_MARKED, 0);
                return TRUE;
 
        case MATCHACTION_LOCK:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_set_flags(info, MSG_LOCKED, 0);
                return TRUE;
 
        case MATCHACTION_UNLOCK:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_unset_flags(info, MSG_LOCKED, 0);       
                return TRUE;
                
        case MATCHACTION_MARK_AS_READ:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_unset_flags(info, MSG_UNREAD | MSG_NEW, 0);
                return TRUE;
 
        case MATCHACTION_MARK_AS_UNREAD:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_set_flags(info, MSG_UNREAD, 0);
                return TRUE;
        
        case MATCHACTION_MARK_AS_SPAM:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_spam_learner_learn(info, NULL, TRUE);
                procmsg_msginfo_change_flags(info, MSG_SPAM, 0, MSG_NEW|MSG_UNREAD, 0);
                if (procmsg_spam_get_folder(info)) {
-                       info->is_move = TRUE;
+                       info->filter_op = IS_MOVE;
                        info->to_filter_folder = procmsg_spam_get_folder(info);
                }
                return TRUE;
 
        case MATCHACTION_MARK_AS_HAM:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_spam_learner_learn(info, NULL, FALSE);
                procmsg_msginfo_unset_flags(info, MSG_SPAM, 0);
                return TRUE;
        
        case MATCHACTION_COLOR:
+               FLUSH_COPY_IF_NEEDED(info);
                procmsg_msginfo_unset_flags(info, MSG_CLABEL_FLAG_MASK, 0); 
                procmsg_msginfo_set_flags(info, MSG_COLORLABEL_TO_FLAGS(action->labelcolor), 0);
                return TRUE;
@@ -408,10 +431,12 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                return TRUE;
 
        case MATCHACTION_SET_SCORE:
+               FLUSH_COPY_IF_NEEDED(info);
                info->score = action->score;
                return TRUE;
 
        case MATCHACTION_CHANGE_SCORE:
+               FLUSH_COPY_IF_NEEDED(info);
                info->score += action->score;
                return TRUE;
 
@@ -419,14 +444,17 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                 return FALSE;
 
        case MATCHACTION_HIDE:
+               FLUSH_COPY_IF_NEEDED(info);
                 info->hidden = TRUE;
                 return TRUE;
 
        case MATCHACTION_IGNORE:
+               FLUSH_COPY_IF_NEEDED(info);
                 procmsg_msginfo_set_flags(info, MSG_IGNORE_THREAD, 0);
                 return TRUE;
 
        case MATCHACTION_WATCH:
+               FLUSH_COPY_IF_NEEDED(info);
                 procmsg_msginfo_set_flags(info, MSG_WATCH_THREAD, 0);
                 return TRUE;
 
@@ -461,7 +489,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                                gchar *path = NULL;
 
                                if (action->destination == NULL ||
-                                               strcasecmp(action->destination, _("Any")) == 0 ||
+                                               strcasecmp(action->destination, "Any") == 0 ||
                                                *(action->destination) == '\0')
                                        path = NULL;
                                else