talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 94b0007b0a27c51fa47aee576a067411303b66d2
parent 811daf73de8faae068f1881551ddb92dedad8c8f
Author: Oliver Lowe <o@olowe.co>
Date:   Sat, 16 Aug 2025 14:24:55 +1000

Start removing client-side filtering

Diffstat:
Msrc/Makefile.am | 6------
Msrc/account.c | 19-------------------
Msrc/action.c | 12+-----------
Dsrc/filtering.c | 1234-------------------------------------------------------------------------------
Dsrc/filtering.h | 114-------------------------------------------------------------------------------
Msrc/folder.c | 208++++----------------------------------------------------------------------------
Msrc/folder.h | 38++++++++++++++++++--------------------
Msrc/folder_item_prefs.c | 8--------
Msrc/folderview.c | 24++----------------------
Msrc/imap_gtk.c | 4----
Msrc/inc.c | 2--
Msrc/main.c | 2--
Msrc/mainwindow.c | 178+------------------------------------------------------------------------------
Msrc/matcher.c | 486+++----------------------------------------------------------------------------
Msrc/matcher_parser.h | 4+---
Msrc/matcher_parser_parse.y | 112-------------------------------------------------------------------------------
Msrc/mbox.c | 67+++++++++++++------------------------------------------------------
Msrc/messageview.c | 74--------------------------------------------------------------------------
Msrc/mh_gtk.c | 2--
Msrc/prefs_account.c | 2--
Msrc/prefs_actions.c | 83+------------------------------------------------------------------------------
Dsrc/prefs_filtering.c | 1921-------------------------------------------------------------------------------
Dsrc/prefs_filtering.h | 55-------------------------------------------------------
Msrc/prefs_folder_item.c | 1-
Msrc/procmsg.c | 181+------------------------------------------------------------------------------
Msrc/procmsg.h | 38++++++++++++++++----------------------
Msrc/summaryview.c | 233-------------------------------------------------------------------------------
Msrc/summaryview.h | 9---------
Msrc/toolbar.c | 2--
29 files changed, 75 insertions(+), 5044 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am @@ -69,7 +69,6 @@ claws_mail_SOURCES = \ edittags.c \ entity.c \ export.c \ - filtering.c \ folder.c \ folder_item_prefs.c \ foldersel.c \ @@ -110,8 +109,6 @@ claws_mail_SOURCES = \ prefs_customheader.c \ prefs_display_header.c \ prefs_ext_prog.c \ - prefs_filtering_action.c \ - prefs_filtering.c \ prefs_folder_item.c \ prefs_fonts.c \ prefs_gtk.c \ @@ -176,7 +173,6 @@ claws_mailinclude_HEADERS = \ edittags.h \ entity.h \ export.h \ - filtering.h \ folder.h \ folder_item_prefs.h \ foldersel.h \ @@ -219,8 +215,6 @@ claws_mailinclude_HEADERS = \ prefs_customheader.h \ prefs_display_header.h \ prefs_ext_prog.h \ - prefs_filtering_action.h \ - prefs_filtering.h \ prefs_folder_item.h \ prefs_fonts.h \ prefs_gtk.h \ diff --git a/src/account.c b/src/account.c @@ -50,7 +50,6 @@ #include "customheader.h" #include "remotefolder.h" #include "manual.h" -#include "filtering.h" #include "prefs_actions.h" #include "hooks.h" #include "passwordstore.h" @@ -496,7 +495,6 @@ void account_open(PrefsAccount *ac_prefs, gboolean called_from_acc_list) new_prefix = folder_get_identifier(FOLDER(ac_prefs->folder)); account_rename_path(old_prefix, new_prefix); - prefs_filtering_rename_path(old_prefix, new_prefix); prefs_actions_rename_path(old_prefix, new_prefix); g_free(old_prefix); @@ -1123,7 +1121,6 @@ static void account_delete(GtkWidget *widget, gpointer data) gchar buf[BUFFSIZE]; GList *list; Folder *folder; - GSList *cur; ac_prefs = account_list_view_get_selected_account(edit_account.list_view); if (ac_prefs == NULL) @@ -1170,22 +1167,6 @@ static void account_delete(GtkWidget *widget, gpointer data) passwd_store_delete_block(PWS_ACCOUNT, uid); g_free(uid); - debug_print("Removing filter rules relative to this account...\n"); - for(cur = filtering_rules ; cur != NULL ;) { - FilteringProp * prop = (FilteringProp *) cur->data; - - if (prop && (prop->account_id == ac_prefs->account_id)) { - /* get next item before we kill the current one */ - cur = g_slist_next(cur); - - /* unallocate filteringprop and unchain it from the list */ - filteringprop_free(prop); - filtering_rules = g_slist_remove(filtering_rules, prop); - } else { - cur = g_slist_next(cur); - } - } - debug_print("Removing cache directory of this account...\n"); account_empty_cache(ac_prefs); diff --git a/src/action.c b/src/action.c @@ -57,7 +57,6 @@ #include "msgcache.h" #include "textview.h" #include "matcher_parser.h" /* CLAWS */ -#include "filtering.h" #include "procheader.h" typedef struct _Children Children; @@ -698,7 +697,7 @@ static void message_actions_execute(MessageView *msgview, guint action_nb, static gboolean execute_filtering_actions(gchar *action, GSList *msglist) { - GSList *action_list, *p; + GSList *action_list; const gchar *sbegin, *send; gchar *action_string; SummaryView *summaryview = NULL; @@ -731,11 +730,6 @@ static gboolean execute_filtering_actions(gchar *action, GSList *msglist) } g_free(action_string); - /* apply actions on each message info */ - for (p = msglist; p && p->data; p = g_slist_next(p)) { - filteringaction_apply_action_list(action_list, (MsgInfo *) p->data); - } - if (summaryview) { summary_lock(summaryview); main_window_cursor_wait(mainwin); @@ -743,8 +737,6 @@ static gboolean execute_filtering_actions(gchar *action, GSList *msglist) folder_item_update_freeze(); } - filtering_move_and_copy_msgs(msglist); - if (summaryview) { folder_item_update_thaw(); summary_thaw(summaryview); @@ -752,8 +744,6 @@ static gboolean execute_filtering_actions(gchar *action, GSList *msglist) summary_unlock(summaryview); summary_show(summaryview, summaryview->folder_item, FALSE); } - for (p = action_list; p; p = g_slist_next(p)) - if (p->data) filteringaction_free(p->data); g_slist_free(action_list); return TRUE; } diff --git a/src/filtering.c b/src/filtering.c @@ -1,1234 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 1999-2020 the Claws Mail Team and Hiroyuki Yamamoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" -#include "defs.h" -#include <glib.h> -#include <glib/gi18n.h> -#include <ctype.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <gtk/gtk.h> -#include <stdio.h> - -#include "utils.h" -#include "procheader.h" -#include "matcher.h" -#include "filtering.h" -#include "prefs_gtk.h" -#include "compose.h" -#include "prefs_common.h" -#include "addritem.h" -#include "addrbook.h" -#include "addressbook.h" -#include "addr_compl.h" -#include "tags.h" -#include "log.h" -#include "account.h" -#include "addrindex.h" -#include "folder_item_prefs.h" - -GSList * pre_global_processing = NULL; -GSList * post_global_processing = NULL; -GSList * filtering_rules = NULL; - -gboolean debug_filtering_session = FALSE; - -static gboolean filtering_is_final_action(FilteringAction *filtering_action); - -FilteringAction * filteringaction_new(int type, int account_id, - gchar * destination, - gint labelcolor, gint score, gchar * header) -{ - FilteringAction * action; - - action = g_new0(FilteringAction, 1); - - action->type = type; - action->account_id = account_id; - if (destination) { - action->destination = g_strdup(destination); - } else { - action->destination = NULL; - } - if (header) { - action->header = g_strdup(header); - } else { - action->header = NULL; - } - action->labelcolor = labelcolor; - action->score = score; - return action; -} - -void filteringaction_free(FilteringAction * action) -{ - cm_return_if_fail(action); - g_free(action->header); - g_free(action->destination); - g_free(action); -} - -static gint action_list_sort(gconstpointer a, gconstpointer b) -{ - int first = filtering_is_final_action((FilteringAction *) a) ? 1 : 0; - int second = filtering_is_final_action((FilteringAction *) b) ? 1 : 0; - - return (first - second); -} - -GSList *filtering_action_list_sort(GSList *action_list) -{ - return g_slist_sort(action_list, action_list_sort); -} - -FilteringProp * filteringprop_new(gboolean enabled, - const gchar *name, - gint account_id, - MatcherList * matchers, - GSList * action_list) -{ - FilteringProp * filtering; - - filtering = g_new0(FilteringProp, 1); - filtering->enabled = enabled; - filtering->name = name ? g_strdup(name): NULL; - filtering->account_id = account_id; - filtering->matchers = matchers; - filtering->action_list = filtering_action_list_sort(action_list); - - return filtering; -} - -static FilteringAction * filteringaction_copy(FilteringAction * src) -{ - FilteringAction * new; - - new = g_new0(FilteringAction, 1); - - new->type = src->type; - new->account_id = src->account_id; - if (src->destination) - new->destination = g_strdup(src->destination); - else - new->destination = NULL; - new->labelcolor = src->labelcolor; - new->score = src->score; - - return new; -} - -FilteringProp * filteringprop_copy(FilteringProp *src) -{ - FilteringProp * new; - GSList *tmp; - - new = g_new0(FilteringProp, 1); - new->matchers = g_new0(MatcherList, 1); - - for (tmp = src->matchers->matchers; tmp != NULL && tmp->data != NULL;) { - MatcherProp *matcher = (MatcherProp *)tmp->data; - - new->matchers->matchers = g_slist_append(new->matchers->matchers, - matcherprop_copy(matcher)); - tmp = tmp->next; - } - - new->matchers->bool_and = src->matchers->bool_and; - - new->action_list = NULL; - - for (tmp = src->action_list ; tmp != NULL ; tmp = tmp->next) { - FilteringAction *filtering_action; - - filtering_action = tmp->data; - - new->action_list = g_slist_append(new->action_list, - filteringaction_copy(filtering_action)); - } - - new->enabled = src->enabled; - new->name = g_strdup(src->name); - - return new; -} - -void filteringprop_free(FilteringProp * prop) -{ - GSList * tmp; - - cm_return_if_fail(prop); - matcherlist_free(prop->matchers); - - for (tmp = prop->action_list ; tmp != NULL ; tmp = tmp->next) { - filteringaction_free(tmp->data); - } - g_slist_free(prop->action_list); - g_free(prop->name); - g_free(prop); -} - -/* move and copy messages by batches to be faster on IMAP */ -void filtering_move_and_copy_msgs(GSList *msgs) -{ - GSList *messages = g_slist_copy(msgs); - FolderItem *last_item = NULL; - FiltOp cur_op = IS_NOTHING; - - debug_print("checking %d messages\n", g_slist_length(msgs)); - while (messages) { - GSList *batch = NULL, *cur; - gint found = 0; - for (cur = messages; cur; cur = cur->next) { - MsgInfo *info = (MsgInfo *)cur->data; - if (last_item == NULL) { - 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 (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; - } - 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/del\n"); - break; - } else { - debug_print("%d messages to %s in %s\n", found, - cur_op==IS_COPY ? "copy":(cur_op==IS_DELE ?"delete":"move"), - last_item->name ? last_item->name:"(noname)"); - } - 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 (cur_op == IS_COPY && last_item != info->folder) { - folder_item_copy_msgs(last_item, batch); - } 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) - folder_item_synchronise(last_item); - g_slist_free(batch); - batch = NULL; - GTK_EVENTS_FLUSH(); - } - last_item = NULL; - cur_op = IS_NOTHING; - } - /* we don't reference the msginfos, because caller will do */ - g_slist_free(messages); -} - -/* - fitleringaction_apply - runs the action on one MsgInfo - 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; - gint val; - Compose * compose; - PrefsAccount * account; - gchar * cmd; - - switch(action->type) { - case MATCHACTION_MOVE: - if (MSG_IS_LOCKED(info->flags)) - return FALSE; - - dest_folder = - folder_find_item_from_identifier(action->destination); - if (!dest_folder) { - debug_print("*** folder not found '%s'\n", - action->destination ?action->destination :"(null)"); - return FALSE; - } - - FLUSH_COPY_IF_NEEDED(info); - /* mark message to be moved */ - info->filter_op = IS_MOVE; - info->to_filter_folder = dest_folder; - return TRUE; - - case MATCHACTION_COPY: - dest_folder = - folder_find_item_from_identifier(action->destination); - - if (!dest_folder) { - debug_print("*** folder not found '%s'\n", - action->destination ?action->destination :"(null)"); - return FALSE; - } - - FLUSH_COPY_IF_NEEDED(info); - /* mark message to be copied */ - info->filter_op = IS_COPY; - info->to_filter_folder = dest_folder; - return TRUE; - - case MATCHACTION_DELETE: - 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_change_flags(info, MSG_UNREAD, 0, MSG_NEW, 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); - 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; - - case MATCHACTION_FORWARD: - case MATCHACTION_FORWARD_AS_ATTACHMENT: - account = account_find_from_id(action->account_id); - compose = compose_forward(account, info, - action->type == MATCHACTION_FORWARD ? FALSE : TRUE, - NULL, TRUE, TRUE); - compose_entry_append(compose, action->destination, - compose->account->protocol == A_NNTP - ? COMPOSE_NEWSGROUPS - : COMPOSE_TO, PREF_NONE); - - val = compose_send(compose); - - return val == 0 ? TRUE : FALSE; - - case MATCHACTION_REDIRECT: - account = account_find_from_id(action->account_id); - compose = compose_redirect(account, info, TRUE); - if (compose->account->protocol == A_NNTP) - break; - else - compose_entry_append(compose, action->destination, - COMPOSE_TO, PREF_NONE); - - val = compose_send(compose); - - return val == 0 ? TRUE : FALSE; - - case MATCHACTION_EXECUTE: - cmd = matching_build_command(action->destination, info); - if (cmd == NULL) - return FALSE; - else { - if (system(cmd) == -1) - g_warning("couldn't run %s", cmd); - g_free(cmd); - } - 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; - - case MATCHACTION_STOP: - 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; - - case MATCHACTION_ADD_TO_ADDRESSBOOK: - { - AddressDataSource *book = NULL; - AddressBookFile *abf = NULL; - ItemFolder *folder = NULL; - gchar *buf = NULL; - Header *header = NULL; - gint errors = 0; - - if (!addressbook_peek_folder_exists(action->destination, &book, &folder)) { - g_warning("addressbook folder not found '%s'", action->destination?action->destination:"(null)"); - return FALSE; - } - if (!book) { - g_warning("addressbook_peek_folder_exists returned NULL book"); - return FALSE; - } - - abf = book->rawDataSource; - /* get the header */ - if (procheader_get_header_from_msginfo(info, &buf, action->header) < 0) - return FALSE; - - header = procheader_parse_header(buf); - g_free(buf); - - /* add all addresses that are not already in */ - if (header && *header->body && (*header->body != '\0')) { - GSList *address_list = NULL; - GSList *walk = NULL; - gchar *path = NULL; - - if (action->destination == NULL || - strcasecmp(action->destination, "Any") == 0 || - *(action->destination) == '\0') - path = NULL; - else - path = action->destination; - start_address_completion(path); - - address_list = g_slist_append(address_list, header->body); - for (walk = address_list; walk != NULL; walk = walk->next) { - gchar *stripped_addr = g_strdup(walk->data); - extract_address(stripped_addr); - - if (complete_matches_found(walk->data) == 0) { - gchar *name = procheader_get_fromname(walk->data); - debug_print("adding '%s <%s>' to addressbook '%s'\n", - name, stripped_addr, action->destination); - if (!addrbook_add_contact(abf, folder, name, stripped_addr, NULL)) { - g_warning("contact could not be added"); - errors++; - } - g_free(name); - } else { - debug_print("address '%s' already found in addressbook '%s', skipping\n", - stripped_addr, action->destination); - } - g_free(stripped_addr); - } - - g_slist_free(address_list); - end_address_completion(); - } else { - g_warning("header '%s' not set or empty", action->header?action->header:"(null)"); - } - if (header) - procheader_header_free(header); - return (errors == 0); - } - default: - break; - } - return FALSE; -} - -gboolean filteringaction_apply_action_list(GSList *action_list, MsgInfo *info) -{ - GSList *p; - cm_return_val_if_fail(action_list, FALSE); - cm_return_val_if_fail(info, FALSE); - for (p = action_list; p && p->data; p = g_slist_next(p)) { - FilteringAction *a = (FilteringAction *) p->data; - if (filteringaction_apply(a, info)) { - if (filtering_is_final_action(a)) - break; - } else - return FALSE; - - } - return TRUE; -} - -static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info, - PrefsAccount *ac_prefs) - -/* this function returns true if a filtering rule applies regarding to its account - data and if it does, if the conditions list match. - - per-account data of a filtering rule is either matched against current account - when filtering is done manually, or against the account currently used for - retrieving messages when it's an manual or automatic fetching of messages. - per-account data match doesn't apply to pre-/post-/folder-processing rules. - - when filtering messages manually: - - either the filtering rule is not account-based and it will be processed - - or it's per-account and we check if we HAVE TO match it against the current - account (according to user-land settings, per-account rules might have to - be skipped, or only the rules that match the current account have to be - applied, or all rules will have to be applied regardless to if they are - account-based or not) - - notes about debugging output in that function: - when not matching, log_status_skip() is used, otherwise log_status_ok() is used - no debug output is done when filtering_debug_level is low -*/ -{ - gboolean matches = FALSE; - - if (ac_prefs != NULL) { - matches = ((filtering->account_id == 0) - || (filtering->account_id == ac_prefs->account_id)); - - /* debug output */ - if (debug_filtering_session) { - if (matches) { - /* either because rule is not account-based */ - if (filtering->account_id == 0) { - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is not account-based\n")); - } - } else { - /* or because it is account-based, and matching current account */ - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is OK */ - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "matching the account currently used to retrieve messages\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_HIGH) { - /* with more detail when rule is OK */ - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "matching the account currently used to retrieve messages\n"), - ac_prefs->account_id, ac_prefs?ac_prefs->account_name:_("NON_EXISTENT")); - } - } - } - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is skipped */ - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "not matching the account currently used to retrieve messages\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_HIGH) { - /* with more detail when rule is skipped */ - PrefsAccount *account = account_find_from_id(filtering->account_id); - - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "not matching the account currently used to retrieve messages [id=%d, name='%s']\n"), - filtering->account_id, account?account->account_name:_("NON_EXISTENT"), - ac_prefs->account_id, ac_prefs?ac_prefs->account_name:_("NON_EXISTENT")); - } - } - } - } - } else { - switch (prefs_common.apply_per_account_filtering_rules) { - case FILTERING_ACCOUNT_RULES_FORCE: - /* apply filtering rules regardless to the account info */ - matches = TRUE; - - /* debug output */ - if (debug_filtering_session) { - if (filtering->account_id == 0) { - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is not account-based, " - "but all rules are applied on user request anyway\n")); - } - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is OK */ - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "but all rules are applied on user request anyway\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with more detail when rule is OK */ - PrefsAccount *account = account_find_from_id(filtering->account_id); - - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "but all rules are applied on user request anyway\n"), - filtering->account_id, account?account->account_name:_("NON_EXISTENT")); - } - } - } - } - break; - case FILTERING_ACCOUNT_RULES_SKIP: - /* don't apply filtering rules that belong to an account */ - matches = (filtering->account_id == 0); - - /* debug output */ - if (debug_filtering_session) { - if (matches) { - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is not account-based\n")); - } - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is skipped */ - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "skipped on user request\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_HIGH) { - /* with more detail when rule is skipped */ - PrefsAccount *account = account_find_from_id(filtering->account_id); - - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "skipped on user request\n"), - filtering->account_id, account?account->account_name:_("NON_EXISTENT")); - } - } - } - } - break; - case FILTERING_ACCOUNT_RULES_USE_CURRENT: - matches = ((filtering->account_id == 0) - || (filtering->account_id == cur_account->account_id)); - - /* debug output */ - if (debug_filtering_session) { - if (matches) { - if (filtering->account_id == 0) { - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is not account-based\n")); - } - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is OK */ - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "matching current account\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with more detail when rule is OK */ - PrefsAccount *account = account_find_from_id(filtering->account_id); - - log_status_ok(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "matching current account [id=%d, name='%s']\n"), - account->account_id, account?account->account_name:_("NON_EXISTENT"), - cur_account->account_id, cur_account?cur_account->account_name:_("NON_EXISTENT")); - } - } - } - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_MED) { - /* with fewer detail when rule is skipped */ - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based, " - "not matching current account\n")); - } else { - if (prefs_common.filtering_debug_level == FILTERING_DEBUG_LEVEL_HIGH) { - /* with more detail when rule is skipped */ - PrefsAccount *account = account_find_from_id(filtering->account_id); - - log_status_skip(LOG_DEBUG_FILTERING, - _("rule is account-based [id=%d, name='%s'], " - "not matching current account [id=%d, name='%s']\n"), - filtering->account_id, account?account->account_name:_("NON_EXISTENT"), - cur_account->account_id, cur_account?cur_account->account_name:_("NON_EXISTENT")); - } - } - } - } - break; - } - } - - return matches && matcherlist_match(filtering->matchers, info); -} - -/*! - *\brief Apply a rule on message. - * - *\param filtering List of filtering rules. - *\param info Message to apply rules on. - *\param final Variable returning TRUE or FALSE if one of the - * encountered actions was final. - * See also \ref filtering_is_final_action. - * - *\return gboolean TRUE to continue applying rules. - */ -static gboolean filtering_apply_rule(FilteringProp *filtering, MsgInfo *info, - gboolean * final) -{ - gboolean result = TRUE; - gchar *buf; - GSList * tmp; - - * final = FALSE; - for (tmp = filtering->action_list ; tmp != NULL ; tmp = tmp->next) { - FilteringAction * action; - - action = tmp->data; - buf = filteringaction_to_string(action); - if (debug_filtering_session) - log_print(LOG_DEBUG_FILTERING, _("applying action [ %s ]\n"), buf); - - if (FALSE == (result = filteringaction_apply(action, info))) { - if (debug_filtering_session) { - if (action->type != MATCHACTION_STOP) - log_warning(LOG_DEBUG_FILTERING, _("action could not apply\n")); - log_print(LOG_DEBUG_FILTERING, - _("no further processing after action [ %s ]\n"), buf); - } - debug_print("No further processing after rule %s\n", buf); - } - g_free(buf); - if (filtering_is_final_action(action)) { - * final = TRUE; - break; - } - - } - return result; -} - -/*! - *\brief Check if an action is "final", i.e. should break further - * processing. - * - *\param filtering_action Action to check. - * - *\return gboolean TRUE if \a filtering_action is final. - */ -static gboolean filtering_is_final_action(FilteringAction *filtering_action) -{ - switch(filtering_action->type) { - case MATCHACTION_MOVE: - case MATCHACTION_DELETE: - case MATCHACTION_STOP: - return TRUE; /* MsgInfo invalid for message */ - default: - return FALSE; - } -} - -gboolean processing_enabled(GSList *filtering_list) -{ - GSList *l; - for (l = filtering_list; l != NULL; l = g_slist_next(l)) { - FilteringProp * filtering = (FilteringProp *) l->data; - if (filtering->enabled) - return TRUE; - } - return FALSE; -} - -static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info, PrefsAccount* ac_prefs) -{ - GSList *l; - gboolean final; - gboolean apply_next; - - cm_return_val_if_fail(info != NULL, TRUE); - - for (l = filtering_list, final = FALSE, apply_next = FALSE; l != NULL; l = g_slist_next(l)) { - FilteringProp * filtering = (FilteringProp *) l->data; - - if (filtering->enabled) { - if (debug_filtering_session) { - gchar *buf = filteringprop_to_string(filtering); - if (filtering->name && *filtering->name != '\0') { - log_print(LOG_DEBUG_FILTERING, - _("processing rule '%s' [ %s ]\n"), - filtering->name, buf); - } else { - log_print(LOG_DEBUG_FILTERING, - _("processing rule <unnamed> [ %s ]\n"), - buf); - } - g_free(buf); - } - - if (filtering_match_condition(filtering, info, ac_prefs)) { - apply_next = filtering_apply_rule(filtering, info, &final); - if (final) - break; - } - - } else { - if (debug_filtering_session) { - gchar *buf = filteringprop_to_string(filtering); - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - if (filtering->name && *filtering->name != '\0') { - log_status_skip(LOG_DEBUG_FILTERING, - _("disabled rule '%s' [ %s ]\n"), - filtering->name, buf); - } else { - log_status_skip(LOG_DEBUG_FILTERING, - _("disabled rule <unnamed> [ %s ]\n"), - buf); - } - } - g_free(buf); - } - } - } - - /* put in inbox if the last rule was not a final one, or - * a final rule could not be applied. - * Either of these cases is likely. */ - if (!final || !apply_next) { - return FALSE; - } - - return TRUE; -} - -/*! - *\brief Filter a message against a list of rules. - * - *\param flist List of filter rules. - *\param info Message. - * - *\return gboolean TRUE if filter rules handled the message. - * - *\note Returning FALSE means the message was not handled, - * and that the calling code should do the default - * processing. E.g. \ref inc.c::inc_start moves the - * message to the inbox. - */ -gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount* ac_prefs, - FilteringInvocationType context, gchar *extra_info) -{ - gboolean ret; - - if (prefs_common.enable_filtering_debug) { - gchar *tmp = _("undetermined"); - - switch (context) { - case FILTERING_INCORPORATION: - tmp = _("incorporation"); - debug_filtering_session = prefs_common.enable_filtering_debug_inc; - break; - case FILTERING_MANUALLY: - tmp = _("manually"); - debug_filtering_session = prefs_common.enable_filtering_debug_manual; - break; - case FILTERING_FOLDER_PROCESSING: - tmp = _("folder processing"); - debug_filtering_session = prefs_common.enable_filtering_debug_folder_proc; - break; - case FILTERING_PRE_PROCESSING: - tmp = _("pre-processing"); - debug_filtering_session = prefs_common.enable_filtering_debug_pre_proc; - break; - case FILTERING_POST_PROCESSING: - tmp = _("post-processing"); - debug_filtering_session = prefs_common.enable_filtering_debug_post_proc; - break; - default: - debug_filtering_session = FALSE; - break; - } - - if (debug_filtering_session) { - gchar *file = procmsg_get_message_file_path(info); - gchar *spc = g_strnfill(LOG_TIME_LEN + 1, ' '); - - /* show context info and essential info about the message */ - if (prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_MED) { - log_print(LOG_DEBUG_FILTERING, - _("filtering message (%s%s%s)\n" - "%smessage file: %s\n%s%s %s\n%s%s %s\n%s%s %s\n%s%s %s\n"), - tmp, extra_info ? _(": ") : "", extra_info ? extra_info : "", - spc, file, spc, prefs_common_translated_header_name("Date:"), info->date, - spc, prefs_common_translated_header_name("From:"), info->from, - spc, prefs_common_translated_header_name("To:"), info->to, - spc, prefs_common_translated_header_name("Subject:"), info->subject); - } else { - log_print(LOG_DEBUG_FILTERING, - _("filtering message (%s%s%s)\n" - "%smessage file: %s\n"), - tmp, extra_info ? _(": ") : "", extra_info ? extra_info : "", - spc, file); - } - g_free(file); - g_free(spc); - } - } else - debug_filtering_session = FALSE; - - ret = filter_msginfo(flist, info, ac_prefs); - debug_filtering_session = FALSE; - return ret; -} - -gchar *filteringaction_to_string(FilteringAction *action) -{ - const gchar *command_str; - gchar * quoted_dest; - gchar * quoted_header; - GString *dest = g_string_new(""); - - command_str = get_matchparser_tab_str(action->type); - - if (command_str == NULL) { - g_string_free(dest, TRUE); - return NULL; - } - - switch(action->type) { - case MATCHACTION_MOVE: - case MATCHACTION_COPY: - case MATCHACTION_EXECUTE: - case MATCHACTION_SET_TAG: - case MATCHACTION_UNSET_TAG: - quoted_dest = matcher_quote_str(action->destination); - g_string_append_printf(dest, "%s \"%s\"", command_str, quoted_dest); - g_free(quoted_dest); - break; - - case MATCHACTION_DELETE: - case MATCHACTION_MARK: - case MATCHACTION_UNMARK: - case MATCHACTION_LOCK: - case MATCHACTION_UNLOCK: - case MATCHACTION_MARK_AS_READ: - case MATCHACTION_MARK_AS_UNREAD: - case MATCHACTION_MARK_AS_SPAM: - case MATCHACTION_MARK_AS_HAM: - case MATCHACTION_STOP: - case MATCHACTION_HIDE: - case MATCHACTION_IGNORE: - case MATCHACTION_WATCH: - case MATCHACTION_CLEAR_TAGS: - g_string_append_printf(dest, "%s", command_str); - break; - - case MATCHACTION_REDIRECT: - case MATCHACTION_FORWARD: - case MATCHACTION_FORWARD_AS_ATTACHMENT: - quoted_dest = matcher_quote_str(action->destination); - g_string_append_printf(dest, "%s %d \"%s\"", command_str, action->account_id, quoted_dest); - g_free(quoted_dest); - break; - - case MATCHACTION_COLOR: - g_string_append_printf(dest, "%s %d", command_str, action->labelcolor); - break; - - case MATCHACTION_CHANGE_SCORE: - case MATCHACTION_SET_SCORE: - g_string_append_printf(dest, "%s %d", command_str, action->score); - break; - - case MATCHACTION_ADD_TO_ADDRESSBOOK: - quoted_header = matcher_quote_str(action->header); - quoted_dest = matcher_quote_str(action->destination); - g_string_append_printf(dest, "%s \"%s\" \"%s\"", command_str, quoted_header, quoted_dest); - g_free(quoted_dest); - g_free(quoted_header); - break; - - default: - g_string_free(dest, TRUE); - return NULL; - } - return g_string_free(dest, FALSE); -} - -gchar * filteringaction_list_to_string(GSList * action_list) -{ - gchar *action_list_str; - GSList * tmp; - gchar *list_str; - - action_list_str = NULL; - for (tmp = action_list ; tmp != NULL ; tmp = tmp->next) { - gchar *action_str; - FilteringAction * action; - - action = tmp->data; - - action_str = filteringaction_to_string(action); - - if (action_list_str != NULL) { - list_str = g_strconcat(action_list_str, " ", action_str, NULL); - g_free(action_list_str); - } - else { - list_str = g_strdup(action_str); - } - g_free(action_str); - action_list_str = list_str; - } - - return action_list_str; -} - -gchar * filteringprop_to_string(FilteringProp * prop) -{ - gchar *list_str; - gchar *action_list_str; - gchar *filtering_str; - - if (prop == NULL) - return NULL; - - action_list_str = filteringaction_list_to_string(prop->action_list); - - if (action_list_str == NULL) - return NULL; - - list_str = matcherlist_to_string(prop->matchers); - - if (list_str == NULL) { - g_free(action_list_str); - return NULL; - } - - filtering_str = g_strconcat(list_str, " ", action_list_str, NULL); - g_free(action_list_str); - g_free(list_str); - - return filtering_str; -} - -static void prefs_filtering_free(GSList * prefs_filtering) -{ - while (prefs_filtering != NULL) { - FilteringProp * filtering = (FilteringProp *) - prefs_filtering->data; - prefs_filtering = g_slist_remove(prefs_filtering, filtering); - filteringprop_free(filtering); - } -} - -static gboolean prefs_filtering_free_func(GNode *node, gpointer data) -{ - FolderItem *item = node->data; - - cm_return_val_if_fail(item, FALSE); - cm_return_val_if_fail(item->prefs, FALSE); - - prefs_filtering_free(item->prefs->processing); - item->prefs->processing = NULL; - - return FALSE; -} - -void prefs_filtering_clear(void) -{ - GList * cur; - - for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) { - Folder *folder; - - folder = (Folder *) cur->data; - g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - prefs_filtering_free_func, NULL); - } - - prefs_filtering_free(filtering_rules); - filtering_rules = NULL; - prefs_filtering_free(pre_global_processing); - pre_global_processing = NULL; - prefs_filtering_free(post_global_processing); - post_global_processing = NULL; -} - -void prefs_filtering_clear_folder(Folder *folder) -{ - cm_return_if_fail(folder); - cm_return_if_fail(folder->node); - - g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - prefs_filtering_free_func, NULL); - /* FIXME: Note folder settings were changed, where the updates? */ -} - -gboolean filtering_peek_per_account_rules(GSList *filtering_list) -/* return TRUE if there's at least one per-account filtering rule */ -{ - GSList *l; - - for (l = filtering_list; l != NULL; l = g_slist_next(l)) { - FilteringProp * filtering = (FilteringProp *) l->data; - - if (filtering->enabled && (filtering->account_id != 0)) { - return TRUE; - } - } - - return FALSE; -} - -gboolean filtering_action_list_rename_path(GSList *action_list, const gchar *old_path, - const gchar *new_path) -{ - gchar *base; - gchar *prefix; - gchar *suffix; - gchar *dest_path; - gchar *old_path_with_sep; - gint destlen; - gint prefixlen; - gint oldpathlen; - GSList * action_cur; - const gchar *separator=G_DIR_SEPARATOR_S; - gboolean matched = FALSE; - - oldpathlen = strlen(old_path); - old_path_with_sep = g_strconcat(old_path,separator,NULL); - - for(action_cur = action_list ; action_cur != NULL ; - action_cur = action_cur->next) { - - FilteringAction *action = action_cur->data; - - if (action->type == MATCHACTION_SET_TAG || - action->type == MATCHACTION_UNSET_TAG) - continue; - if (!action->destination) - continue; - - destlen = strlen(action->destination); - - if (destlen > oldpathlen) { - prefixlen = destlen - oldpathlen; - suffix = action->destination + prefixlen; - - if (!strncmp(old_path, suffix, oldpathlen)) { - prefix = g_malloc0(prefixlen + 1); - strncpy2(prefix, action->destination, prefixlen); - - base = suffix + oldpathlen; - while (*base == G_DIR_SEPARATOR) - base++; - if (*base == '\0') - dest_path = g_strconcat(prefix, separator, new_path, NULL); - else - dest_path = g_strconcat(prefix, separator, new_path, separator, base, NULL); - - g_free(prefix); - g_free(action->destination); - action->destination = dest_path; - matched = TRUE; - } else { /* for non-leaf folders */ - /* compare with trailing slash */ - if (!strncmp(old_path_with_sep, action->destination, oldpathlen+1)) { - - suffix = action->destination + oldpathlen + 1; - dest_path = g_strconcat(new_path, separator, - suffix, NULL); - g_free(action->destination); - action->destination = dest_path; - matched = TRUE; - } - } - } else { - /* folder-moving a leaf */ - if (!strcmp(old_path, action->destination)) { - dest_path = g_strdup(new_path); - g_free(action->destination); - action->destination = dest_path; - matched = TRUE; - } - } - } - - g_free(old_path_with_sep); - - return matched; -} diff --git a/src/filtering.h b/src/filtering.h @@ -1,114 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 1999-2020 the Claws Mail Team and Hiroyuki Yamamoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef FILTER_NEW_H - -#define FILTER_NEW_H - -#include <glib.h> -#include "matcher.h" -#include "procmsg.h" - -struct _FilteringAction { - gint type; - gint account_id; - gchar *destination; - gint labelcolor; - gint score; - gchar *header; -}; - -typedef struct _FilteringAction FilteringAction; - -struct _FilteringProp { - gboolean enabled; - gchar *name; - gint account_id; - MatcherList * matchers; - GSList * action_list; -}; - -typedef struct _FilteringProp FilteringProp; - -enum { - FILTERING_ACCOUNT_RULES_SKIP = 0, - FILTERING_ACCOUNT_RULES_FORCE = 1, - FILTERING_ACCOUNT_RULES_USE_CURRENT = 2 -}; - -typedef enum { - FILTERING_INCORPORATION, - FILTERING_MANUALLY, - FILTERING_FOLDER_PROCESSING, - FILTERING_PRE_PROCESSING, - FILTERING_POST_PROCESSING -} FilteringInvocationType; - -typedef enum { - FILTERING_DEBUG_LEVEL_LOW, - FILTERING_DEBUG_LEVEL_MED, - FILTERING_DEBUG_LEVEL_HIGH -} FilteringDebugLevel; - -/* extern GSList * prefs_filtering; */ - - -FilteringAction * filteringaction_new(int type, int account_id, - gchar * destination, - gint labelcolor, gint score, gchar *header); -void filteringaction_free(FilteringAction *action); -FilteringAction * filteringaction_parse(gchar **str); -gboolean filteringaction_apply_action_list (GSList *action_list, MsgInfo *info); - -FilteringProp * filteringprop_new(gboolean enabled, - const gchar *name, - gint account_id, - MatcherList *matchers, - GSList *action_list); -void filteringprop_free(FilteringProp *prop); - -FilteringProp * filteringprop_parse(gchar **str); - -void filter_msginfo_move_or_delete(GSList *filtering_list, MsgInfo *info); -gboolean processing_enabled(GSList *filtering_list); -gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount *ac_prefs, - FilteringInvocationType context, gchar *extra_info); - -gchar * filteringaction_to_string(FilteringAction *action); -void prefs_filtering_write_config(void); -void prefs_filtering_read_config(void); -gchar * filteringaction_list_to_string(GSList * action_list); -gchar * filteringprop_to_string(FilteringProp *prop); - -void prefs_filtering_clear(void); -void prefs_filtering_clear_folder(Folder *folder); - -FilteringProp * filteringprop_copy(FilteringProp *src); -void filtering_move_and_copy_msgs(GSList *msglist); -extern GSList * filtering_rules; -extern GSList * pre_global_processing; -extern GSList * post_global_processing; - -gboolean filtering_peek_per_account_rules(GSList *filtering_list); - -GSList *filtering_action_list_sort(GSList *action_list); -gboolean filtering_action_list_rename_path(GSList *action_list, const gchar *old_path, - const gchar *new_path); - -#endif diff --git a/src/folder.c b/src/folder.c @@ -44,7 +44,6 @@ #include "codeconv.h" #include "prefs_gtk.h" #include "account.h" -#include "filtering.h" #include "procheader.h" #include "hooks.h" #include "log.h" @@ -759,9 +758,6 @@ void folder_tree_destroy(Folder *folder) cm_return_if_fail(folder != NULL); node = folder->node; - - prefs_filtering_clear_folder(folder); - if (node != NULL) { g_node_traverse(node, G_POST_ORDER, G_TRAVERSE_ALL, -1, folder_tree_destroy_func, NULL); @@ -1976,71 +1972,6 @@ static gint syncronize_flags(FolderItem *item, MsgInfoList *msglist) return ret; } -static gint folder_item_syncronize_flags(FolderItem *item) -{ - MsgInfoList *msglist = NULL; - GSList *cur; - gint ret = 0; - - cm_return_val_if_fail(item != NULL, -1); - cm_return_val_if_fail(item->folder != NULL, -1); - cm_return_val_if_fail(item->folder->klass != NULL, -1); - if (item->no_select) - return -1; - - item->scanning = ITEM_SCANNING_WITH_FLAGS; - - if (item->cache == NULL) - folder_item_read_cache(item); - - msglist = msgcache_get_msg_list(item->cache); - - ret = syncronize_flags(item, msglist); - - for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) { - procmsg_msginfo_free((MsgInfo **)&(cur->data)); - } - - g_slist_free(msglist); - - item->scanning = ITEM_NOT_SCANNING; - - return ret; -} - -static 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) - return; - if((item->folder->klass->scan_required != NULL) && - (item->folder->klass->scan_required(item->folder, item))) { - folder_item_scan_full(item, TRUE); - } else { - folder_item_syncronize_flags(item); - } - - /* Processing */ - if (item->prefs->enable_processing_when_opening) { - buf = g_strdup_printf(_("Processing (%s)...\n"), - item->path ? item->path : item->name); - g_free(buf); - - if (before_proc_func) - before_proc_func(data); - - folder_item_apply_processing(item); - - if (after_proc_func) - after_proc_func(data); - } - item->processing_pending = FALSE; - return; -} - gint folder_item_open(FolderItem *item) { if (item->no_select) @@ -2051,9 +1982,7 @@ gint folder_item_open(FolderItem *item) return -2; } - item->processing_pending = TRUE; - folder_item_process_open (item, NULL, NULL, NULL); - + item->processing_pending = FALSE; item->opened = TRUE; return 0; } @@ -2354,65 +2283,22 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering) item->scanning = ITEM_SCANNING; if (newmsg_list != NULL) { - GSList *elem, *to_filter = NULL; - gboolean do_filter = (filtering == TRUE) && - (item->folder->account != NULL) && - (item->folder->account->filter_on_recv) && - ((item->stype == F_INBOX) || - ((item->stype == F_NORMAL) && - (FOLDER_TYPE(item->folder) == F_NEWS))); - + GSList *elem = NULL; for (elem = newmsg_list; elem != NULL; elem = g_slist_next(elem)) { MsgInfo *msginfo = (MsgInfo *) elem->data; msgcache_add_msg(item->cache, msginfo); - if (!do_filter) { - exists_list = g_slist_prepend(exists_list, msginfo); + exists_list = g_slist_prepend(exists_list, msginfo); - if(prefs_common.thread_by_subject && - MSG_IS_IGNORE_THREAD(msginfo->flags) && - !subject_table_lookup(subject_table, msginfo->subject)) { - subject_table_insert(subject_table, msginfo->subject, msginfo); - } + if(prefs_common.thread_by_subject && + MSG_IS_IGNORE_THREAD(msginfo->flags) && + !subject_table_lookup(subject_table, msginfo->subject)) { + subject_table_insert(subject_table, msginfo->subject, msginfo); } } - if (do_filter) { - GSList *unfiltered; - - folder_item_set_batch(item, TRUE); - procmsg_msglist_filter(newmsg_list, item->folder->account, - &to_filter, &unfiltered, - TRUE); - folder_item_set_batch(item, FALSE); - - filtering_move_and_copy_msgs(newmsg_list); - if (to_filter != NULL) { - for (elem = to_filter; elem; elem = g_slist_next(elem)) { - MsgInfo *msginfo = (MsgInfo *)elem->data; - procmsg_msginfo_free(&msginfo); - } - g_slist_free(to_filter); - } - if (unfiltered != NULL) { - for (elem = unfiltered; elem; elem = g_slist_next(elem)) { - MsgInfo *msginfo = (MsgInfo *)elem->data; - exists_list = g_slist_prepend(exists_list, msginfo); - - if(prefs_common.thread_by_subject && - MSG_IS_IGNORE_THREAD(msginfo->flags) && - !subject_table_lookup(subject_table, msginfo->subject)) { - subject_table_insert(subject_table, msginfo->subject, msginfo); - } - } - g_slist_free(unfiltered); - } - if (prefs_common.real_time_sync) + if (prefs_common.real_time_sync) folder_item_synchronise(item); - } else { - if (prefs_common.real_time_sync) - folder_item_synchronise(item); - } g_slist_free(newmsg_list); @@ -3342,7 +3228,6 @@ static FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest, if (!copy) { debug_print("updating rules : %s => %s\n", old_id, new_id); if (old_id != NULL && new_id != NULL) { - prefs_filtering_rename_path(old_id, new_id); account_rename_path(old_id, new_id); } } @@ -4431,83 +4316,6 @@ static gboolean persist_prefs_free(gpointer key, gpointer val, gpointer data) return TRUE; } -void folder_item_apply_processing(FolderItem *item) -{ - GSList *processing_list; - GSList *mlist, *cur; - guint total = 0, curmsg = 0; - gint last_apply_per_account; - - cm_return_if_fail(item != NULL); - - if (item->no_select) - return; - - processing_list = item->prefs->processing; - - if (!processing_enabled(pre_global_processing) && - !processing_enabled(processing_list) && - !processing_enabled(post_global_processing)) - return; - - debug_print("processing %s\n", item->name); - folder_item_update_freeze(); - - inc_lock(); - - mlist = folder_item_get_msg_list(item); - total = g_slist_length(mlist); - statusbar_print_all(_("Processing messages...")); - - last_apply_per_account = prefs_common.apply_per_account_filtering_rules; - prefs_common.apply_per_account_filtering_rules = FILTERING_ACCOUNT_RULES_SKIP; - - folder_item_set_batch(item, TRUE); - for (cur = mlist ; cur != NULL ; cur = cur->next) { - MsgInfo * msginfo; - - msginfo = (MsgInfo *) cur->data; - - /* reset parameters that can be modified by processing */ - msginfo->hidden = 0; - msginfo->score = 0; - - statusbar_progress_all(curmsg++,total, 10); - - /* apply pre global rules */ - filter_message_by_msginfo(pre_global_processing, msginfo, NULL, - FILTERING_PRE_PROCESSING, NULL); - - /* apply rules of the folder */ - filter_message_by_msginfo(processing_list, msginfo, NULL, - FILTERING_FOLDER_PROCESSING, item->name); - - /* apply post global rules */ - filter_message_by_msginfo(post_global_processing, msginfo, NULL, - FILTERING_POST_PROCESSING, NULL); - if (curmsg % 1000 == 0) - GTK_EVENTS_FLUSH(); - } - folder_item_set_batch(item, FALSE); - - prefs_common.apply_per_account_filtering_rules = last_apply_per_account; - - if (pre_global_processing || processing_list - || post_global_processing) - filtering_move_and_copy_msgs(mlist); - for (cur = mlist ; cur != NULL ; cur = cur->next) { - procmsg_msginfo_free((MsgInfo **)&(cur->data)); - } - g_slist_free(mlist); - - statusbar_progress_all(0,0,0); - statusbar_pop_all(); - - inc_unlock(); - - folder_item_update_thaw(); -} - /* * functions for handling FolderItem content changes */ diff --git a/src/folder.h b/src/folder.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * */ #ifndef __FOLDER_H__ @@ -204,7 +204,7 @@ struct _FolderClass /** * Klass-specific prefs pages */ - + GSList *prefs_pages; /* virtual functions */ @@ -215,7 +215,7 @@ struct _FolderClass * * \param name The name of the new Folder * \param path The path of the new Folder - * \return The new \c Folder, or \c NULL when creating the \c Folder + * \return The new \c Folder, or \c NULL when creating the \c Folder * failed */ Folder *(*new_folder) (const gchar *name, @@ -310,9 +310,9 @@ struct _FolderClass * Get an \c XMLTag for the attributes of the \c FolderItem If \c NULL * the default implementation for the basic \c FolderClass will be used, * so it must not be \c NULL if one of the parent \c FolderClasses has - * it's own implementation for \c item_get_xml. In that case the parent + * it's own implementation for \c item_get_xml. In that case the parent * FolderClass' \c item_get_xml function can be used or the \c XMLTag - * has to be fetched from the parent's \c item_get_xml function and + * has to be fetched from the parent's \c item_get_xml function and * then the \c FolderClass specific attributes can be added to it. * * \param folder The \c Folder of the \c FolderItem @@ -371,7 +371,7 @@ struct _FolderClass /** * Close a \c FolderItem. Called when the user deselects a * \c FolderItem. - * + * * \attention In Claws Mail, operations can be done any time on any * folder and you should not expect that all * \c FolderItems get closed after operations @@ -432,7 +432,7 @@ struct _FolderClass * \param folder The \c Folder containing the message * \param item The \c FolderItem containing the message * \param num The message number of the message - * \return A pointer to a \c MsgInfo decribing the message or \c + * \return A pointer to a \c MsgInfo decribing the message or \c * NULL in case of an error */ MsgInfo *(*get_msginfo) (Folder *folder, @@ -658,35 +658,35 @@ struct _FolderClass FolderItem *item, MsgInfoList *msglist, GHashTable *msgflags); - + /* Sets batch mode for a FolderItem. It means that numerous flags updates * could follow, and the FolderClass implementation can cache them in order * to process them later when set_false will be called again with the - * batch parameter set to FALSE. + * batch parameter set to FALSE. */ void (*set_batch) (Folder *folder, FolderItem *item, gboolean batch); /* Called when switching offline or asking for synchronisation. the imple * mentation should do what's necessary to be able to read mails present - * in the FolderItem at this time with no network connectivity. + * in the FolderItem at this time with no network connectivity. * Days: max number of days of mail to fetch. */ void (*synchronise) (FolderItem *item, gint days); - + /* Passed from claws-mail --subscribe scheme://uri. Implementations * should check if they handle this type of URI, and return TRUE in this * case after having subscribed it. */ gboolean (*subscribe) (Folder *folder, const gchar *uri); - + /* Gets the preferred sort key and type for a folderclass. */ void (*get_sort_type) (Folder *folder, FolderSortKey *sort_key, FolderSortType *sort_type); - + /* Copies internal FolderItem data from one folderItem to another. Used * when moving folders (this move is in reality a folder creation, content * move, folder delettion). @@ -769,13 +769,13 @@ struct _FolderItem PrefsAccount *account; gboolean apply_sub; - + GSList *mark_queue; gpointer data; struct _FolderItemPrefs * prefs; - + /* for faster search of special parents */ SpecialFolderItemType parent_stype; gboolean processing_pending; @@ -863,7 +863,7 @@ gint folder_item_rename (FolderItem *item, gchar *newname); void folder_update_op_count (void); void folder_func_to_all_folders (FolderItemFunc function, gpointer data); -void folder_count_total_msgs(guint *new_msgs, guint *unread_msgs, +void folder_count_total_msgs(guint *new_msgs, guint *unread_msgs, guint *unreadmarked_msgs, guint *marked_msgs, guint *total_msgs, guint *replied_msgs, guint *forwarded_msgs, guint *locked_msgs, @@ -908,7 +908,7 @@ gchar *folder_item_get_path (FolderItem *item); gint folder_item_open (FolderItem *item); gint folder_item_close (FolderItem *item); gint folder_item_scan (FolderItem *item); -gint folder_item_scan_full (FolderItem *item, +gint folder_item_scan_full (FolderItem *item, gboolean filtering); MsgInfo *folder_item_get_msginfo (FolderItem *item, gint num); @@ -921,7 +921,7 @@ MsgNumberList *folder_item_get_number_list(FolderItem *item); gchar *folder_item_fetch_msg (FolderItem *item, gint num); gchar *folder_item_fetch_msg_full (FolderItem *item, - gint num, + gint num, gboolean get_headers, gboolean get_body); gint folder_item_add_msg (FolderItem *dest, @@ -966,8 +966,6 @@ void folder_clean_cache_memory (FolderItem *protected_item); void folder_clean_cache_memory_force (void); void folder_item_write_cache (FolderItem *item); -void folder_item_apply_processing (FolderItem *item); - void folder_item_update (FolderItem *item, FolderItemUpdateFlags update_flags); void folder_item_update_recursive (FolderItem *item, diff --git a/src/folder_item_prefs.c b/src/folder_item_prefs.c @@ -29,7 +29,6 @@ #include "folder.h" #include "utils.h" #include "prefs_gtk.h" -#include "filtering.h" #include "folder_item_prefs.h" #include "prefs_migration.h" @@ -294,13 +293,6 @@ void folder_item_prefs_copy_prefs(FolderItem * src, FolderItem * dest) prefs_matcher_read_config(); - for (tmp = src->prefs->processing; tmp != NULL && tmp->data != NULL;) { - FilteringProp *prop = (FilteringProp *)tmp->data; - - tmp_prop_list = g_slist_append(tmp_prop_list, - filteringprop_copy(prop)); - tmp = tmp->next; - } tmp_prefs.processing = tmp_prop_list; tmp_prefs.request_return_receipt = src->prefs->request_return_receipt; diff --git a/src/folderview.c b/src/folderview.c @@ -42,7 +42,6 @@ #include "gtkutils.h" #include "prefs_common.h" #include "prefs_account.h" -#include "prefs_filtering.h" #include "prefs_folder_item.h" #include "account.h" #include "folder.h" @@ -53,7 +52,6 @@ #include "folderutils.h" #include "partial_download.h" #include "prefs_folder_column.h" -#include "filtering.h" #include "quicksearch.h" #include "manual.h" #include "log.h" @@ -2579,9 +2577,6 @@ void folderview_run_processing(FolderItem *item) { cm_return_if_fail(item != NULL); cm_return_if_fail(item->folder != NULL); - - item->processing_pending = TRUE; - folder_item_apply_processing(item); item->processing_pending = FALSE; } @@ -2728,23 +2723,8 @@ static gint folderview_clist_compare(GtkCMCList *clist, static void folderview_processing_cb(GtkAction *action, gpointer data) { - FolderView *folderview = (FolderView *)data; - FolderItem *item; - gchar *id, *title; - - if (!folderview->selected) return; - - item = folderview_get_selected_item(folderview); - cm_return_if_fail(item != NULL); - cm_return_if_fail(item->folder != NULL); - - id = folder_item_get_identifier(item); - title = g_strdup_printf (_("Processing configuration for folder %s"), id); - g_free (id); - - prefs_filtering_open(&item->prefs->processing, title, - MANUAL_ANCHOR_PROCESSING, NULL, NULL, FALSE); - g_free (title); + fprintf(stderr, "delete folderview_processing_cb\n"); + return; } void folderview_set_target_folder_color(GdkRGBA color_op) diff --git a/src/imap_gtk.c b/src/imap_gtk.c @@ -294,7 +294,6 @@ static void rename_folder_cb(GtkAction *action, gpointer data) } new_id = folder_item_get_identifier(item); - prefs_filtering_rename_path(old_id, new_id); account_rename_path(old_id, new_id); prefs_actions_rename_path(old_id, new_id); g_free(old_id); @@ -388,10 +387,7 @@ static void delete_folder_cb(GtkAction *action, gpointer data) } folder_write_list(); - - prefs_filtering_delete_path(old_id); g_free(old_id); - } #define DO_ACTION(name, act) { if (!strcmp(a_name, name)) act; } diff --git a/src/inc.c b/src/inc.c @@ -55,7 +55,6 @@ #include "inputdialog.h" #include "alertpanel.h" #include "folder.h" -#include "filtering.h" #include "log.h" #include "hooks.h" #include "logwindow.h" @@ -760,7 +759,6 @@ static gint inc_start(IncProgressDialog *inc_dialog) &filtered, &unfiltered, pop3_session->ac_prefs->filter_on_recv); - filtering_move_and_copy_msgs(msglist); if (unfiltered != NULL) folder_item_move_msgs(inbox, unfiltered); diff --git a/src/main.c b/src/main.c @@ -1332,8 +1332,6 @@ static void initial_processing(FolderItem *item, gpointer data) g_free(buf); if (folder_item_parent(item) != NULL && item->prefs->enable_processing) { - item->processing_pending = TRUE; - folder_item_apply_processing(item); item->processing_pending = FALSE; } diff --git a/src/mainwindow.c b/src/mainwindow.c @@ -50,7 +50,6 @@ #include "password.h" #include "prefs_common.h" #include "prefs_actions.h" -#include "prefs_filtering.h" #include "prefs_account.h" #include "prefs_summary_column.h" #include "prefs_folder_column.h" @@ -75,7 +74,6 @@ #include "hooks.h" #include "progressindicator.h" #include "localfolder.h" -#include "filtering.h" #include "folderutils.h" #include "foldersort.h" #include "icon_legend.h" @@ -166,8 +164,6 @@ static void addressbook_open_cb (GtkAction *action, gpointer data); static void log_window_show_cb (GtkAction *action, gpointer data); -static void filtering_debug_window_show_cb (GtkAction *action, - gpointer data); static void inc_cancel_cb (GtkAction *action, gpointer data); @@ -270,12 +266,6 @@ static void delete_duplicated_cb (GtkAction *action, gpointer data); static void delete_duplicated_all_cb (GtkAction *action, gpointer data); -static void filter_cb (GtkAction *action, - gpointer data); -static void filter_list_cb (GtkAction *action, - gpointer data); -static void process_cb (GtkAction *action, - gpointer data); static void execute_summary_cb (GtkAction *action, gpointer data); static void expunge_summary_cb (GtkAction *action, @@ -327,11 +317,6 @@ static void trash_thread_cb (GtkAction *action, static void delete_thread_cb (GtkAction *action, gpointer data); -static void create_filter_cb (GtkAction *action, - gpointer data); -static void create_processing_cb (GtkAction *action, - gpointer data); - static void prefs_template_open_cb (GtkAction *action, gpointer data); static void prefs_actions_open_cb (GtkAction *action, @@ -339,14 +324,6 @@ static void prefs_actions_open_cb (GtkAction *action, static void prefs_account_open_cb (GtkAction *action, gpointer data); -static void prefs_pre_processing_open_cb (GtkAction *action, - gpointer data); - -static void prefs_post_processing_open_cb (GtkAction *action, - gpointer data); - -static void prefs_filtering_open_cb (GtkAction *action, - gpointer data); #ifdef USE_GNUTLS static void ssl_manager_open_cb (GtkAction *action, gpointer data); @@ -680,24 +657,6 @@ static GtkActionEntry mainwin_entries[] = {"Tools/CollectAddresses/FromSelected", NULL, N_("From selected _messages..."), NULL, NULL, G_CALLBACK(addr_harvest_msg_cb) }, {"Tools/---", NULL, "---", NULL, NULL, NULL }, - {"Tools/FilterFolder", NULL, N_("_Filter all messages in folder"), NULL, NULL, G_CALLBACK(filter_cb) }, - {"Tools/FilterSelected", NULL, N_("Filter _selected messages"), NULL, NULL, G_CALLBACK(filter_list_cb) }, - {"Tools/RunProcessing", NULL, N_("Run folder pr_ocessing rules"), NULL, NULL, G_CALLBACK(process_cb) }, - - {"Tools/CreateFilterRule", NULL, N_("_Create filter rule"), NULL, NULL, NULL }, - {"Tools/CreateFilterRule/Automatically", NULL, N_("_Automatically"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_AUTO */ - {"Tools/CreateFilterRule/ByFrom", NULL, N_("By _From"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_FROM */ - {"Tools/CreateFilterRule/ByTo", NULL, N_("By _To"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_TO */ - {"Tools/CreateFilterRule/BySubject", NULL, N_("By _Subject"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_SUBJECT */ - {"Tools/CreateFilterRule/BySender", NULL, N_("By S_ender"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_SENDER */ - - {"Tools/CreateProcessingRule", NULL, N_("Create processing rule"), NULL, NULL, NULL }, - {"Tools/CreateProcessingRule/Automatically", NULL, N_("_Automatically"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/ByFrom", NULL, N_("By _From"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/ByTo", NULL, N_("By _To"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/BySubject", NULL, N_("By _Subject"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/BySender", NULL, N_("By S_ender"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - /* {"Tools/---", NULL, "---", NULL, NULL, NULL }, */ {"Tools/Actions", NULL, N_("Actio_ns"), NULL, NULL, NULL }, {"Tools/Actions/PlaceHolder", NULL, "Placeholder", NULL, NULL, G_CALLBACK(mainwindow_nothing_cb) }, @@ -716,7 +675,6 @@ static GtkActionEntry mainwin_entries[] = {"Tools/TLSCertificates", NULL, N_("TLS cer_tificates"), NULL, NULL, G_CALLBACK(ssl_manager_open_cb) }, #endif /* {"Tools/---", NULL, "---", NULL, NULL, NULL }, */ - {"Tools/FilteringLog", NULL, N_("Filtering Lo_g"), NULL, NULL, G_CALLBACK(filtering_debug_window_show_cb) }, {"Tools/NetworkLog", NULL, N_("Network _Log"), "<shift><control>L", NULL, G_CALLBACK(log_window_show_cb) }, /* {"Tools/---", NULL, "---", NULL, NULL, NULL }, */ @@ -732,9 +690,6 @@ static GtkActionEntry mainwin_entries[] = {"Configuration/---", NULL, "---", NULL, NULL, NULL }, {"Configuration/Preferences", NULL, N_("P_references..."), NULL, NULL, G_CALLBACK(prefs_open_cb) }, - {"Configuration/PreProcessing", NULL, N_("Pre-pr_ocessing..."), NULL, NULL, G_CALLBACK(prefs_pre_processing_open_cb) }, - {"Configuration/PostProcessing", NULL, N_("Post-pro_cessing..."), NULL, NULL, G_CALLBACK(prefs_post_processing_open_cb) }, - {"Configuration/Filtering", NULL, N_("_Filtering..."), NULL, NULL, G_CALLBACK(prefs_filtering_open_cb) }, {"Configuration/Templates", NULL, N_("_Templates..."), NULL, NULL, G_CALLBACK(prefs_template_open_cb) }, {"Configuration/Actions", NULL, N_("_Actions..."), NULL, NULL, G_CALLBACK(prefs_actions_open_cb) }, @@ -1342,28 +1297,6 @@ MainWindow *main_window_create() MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CollectAddresses", "FromSelected", "Tools/CollectAddresses/FromSelected", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Separator1", "Tools/---", GTK_UI_MANAGER_SEPARATOR) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "FilterFolder", "Tools/FilterFolder", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "FilterSelected", "Tools/FilterSelected", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "RunProcessing", "Tools/RunProcessing", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "CreateFilterRule", "Tools/CreateFilterRule", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateFilterRule", "Automatically", "Tools/CreateFilterRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateFilterRule", "ByFrom", "Tools/CreateFilterRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateFilterRule", "ByTo", "Tools/CreateFilterRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateFilterRule", "BySubject", "Tools/CreateFilterRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateFilterRule", "BySender", "Tools/CreateFilterRule/BySender", GTK_UI_MANAGER_MENUITEM) - - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "CreateProcessingRule", "Tools/CreateProcessingRule", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateProcessingRule", "Automatically", "Tools/CreateProcessingRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateProcessingRule", "ByFrom", "Tools/CreateProcessingRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateProcessingRule", "ByTo", "Tools/CreateProcessingRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateProcessingRule", "BySubject", "Tools/CreateProcessingRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/CreateProcessingRule", "BySender", "Tools/CreateProcessingRule/BySender", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Separator2", "Tools/---", GTK_UI_MANAGER_SEPARATOR) - - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Actions", "Tools/Actions", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/Actions", "PlaceHolder", "Tools/Actions/PlaceHolder", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Separator4", "Tools/---", GTK_UI_MANAGER_SEPARATOR) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "CheckNewMessages", "Tools/CheckNewMessages", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "DeleteDuplicates", "Tools/DeleteDuplicates", GTK_UI_MANAGER_MENU) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools/DeleteDuplicates", "SelFolder", "Tools/DeleteDuplicates/SelFolder", GTK_UI_MANAGER_MENUITEM) @@ -1377,7 +1310,6 @@ MainWindow *main_window_create() MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "TLSCertificates", "Tools/TLSCertificates", GTK_UI_MANAGER_MENUITEM) #endif MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Separator7", "Tools/---", GTK_UI_MANAGER_SEPARATOR) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "FilteringLog", "Tools/FilteringLog", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "NetworkLog", "Tools/NetworkLog", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "Separator8", "Tools/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Tools", "ForgetSessionPasswords", "Tools/ForgetSessionPasswords", GTK_UI_MANAGER_MENUITEM) @@ -1393,9 +1325,6 @@ MainWindow *main_window_create() MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "Separator1", "Configuration/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "Preferences", "Configuration/Preferences", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "PreProcessing", "Configuration/PreProcessing", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "PostProcessing", "Configuration/PostProcessing", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "Filtering", "Configuration/Filtering", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "Templates", "Configuration/Templates", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/Configuration", "Actions", "Configuration/Actions", GTK_UI_MANAGER_MENUITEM) @@ -1523,29 +1452,10 @@ MainWindow *main_window_create() set_log_prefs(LOG_PROTOCOL, &prefs_common.logwin_width, &prefs_common.logwin_height); - set_log_title(LOG_DEBUG_FILTERING, _("Filtering/Processing debug log")); - set_log_prefs(LOG_DEBUG_FILTERING, - &prefs_common.filtering_debugwin_width, - &prefs_common.filtering_debugwin_height); - /* setup log windows */ mainwin->logwin = log_window_create(LOG_PROTOCOL); log_window_init(mainwin->logwin); - mainwin->filtering_debugwin = log_window_create(LOG_DEBUG_FILTERING); - log_window_set_clipping(mainwin->logwin, - prefs_common.cliplog, - prefs_common.loglength); - - log_window_init(mainwin->filtering_debugwin); - log_window_set_clipping(mainwin->filtering_debugwin, - prefs_common.filtering_debug_cliplog, - prefs_common.filtering_debug_loglength); - if (prefs_common.enable_filtering_debug) - log_message(LOG_DEBUG_FILTERING, _("filtering log enabled\n")); - else - log_message(LOG_DEBUG_FILTERING, _("filtering log disabled\n")); - folderview->mainwin = mainwin; folderview->summaryview = summaryview; @@ -2627,12 +2537,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin) SET_SENSITIVE("Menu/Tools/CollectAddresses", M_FOLDER_SELECTED); SET_SENSITIVE("Menu/Tools/CollectAddresses/FromFolder", M_FOLDER_SELECTED); SET_SENSITIVE("Menu/Tools/CollectAddresses/FromSelected", M_TARGET_EXIST); - SET_SENSITIVE("Menu/Tools/FilterFolder", M_MSG_EXIST, M_EXEC); - SET_SENSITIVE("Menu/Tools/FilterSelected", M_TARGET_EXIST, M_EXEC); - SET_SENSITIVE("Menu/Tools/RunProcessing", M_HAVE_PROCESSING); - SET_SENSITIVE("Menu/Tools/CreateFilterRule", M_SINGLE_TARGET_EXIST, M_UNLOCKED); - SET_SENSITIVE("Menu/Tools/CreateProcessingRule", M_SINGLE_TARGET_EXIST, M_UNLOCKED); - SET_SENSITIVE("Menu/Tools/Actions", M_TARGET_EXIST, M_ACTIONS_EXIST); + SET_SENSITIVE("Menu/Tools/Execute", M_DELAY_EXEC); SET_SENSITIVE("Menu/Tools/Expunge", M_DELETED_EXISTS); SET_SENSITIVE("Menu/Tools/ForgetSessionPasswords", M_SESSION_PASSWORDS); @@ -3671,12 +3576,6 @@ static void log_window_show_cb(GtkAction *action, gpointer data) log_window_show(mainwin->logwin); } -static void filtering_debug_window_show_cb(GtkAction *action, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - log_window_show(mainwin->filtering_debugwin); -} - static void inc_cancel_cb(GtkAction *action, gpointer data) { inc_cancel_all(); @@ -4117,29 +4016,6 @@ static void delete_duplicated_all_cb(GtkAction *action, gpointer mw) mainwindow_delete_duplicated_all(mainwin); } -static void filter_cb(GtkAction *action, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - summary_filter(mainwin->summaryview, FALSE); -} - -static void filter_list_cb(GtkAction *action, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - summary_filter(mainwin->summaryview, TRUE); -} - -static void process_cb(GtkAction *action, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - FolderItem *item = mainwin->summaryview->folder_item; - cm_return_if_fail(item != NULL); - - item->processing_pending = TRUE; - folder_item_apply_processing(item); - item->processing_pending = FALSE; -} - static void execute_summary_cb(GtkAction *action, gpointer data) { MainWindow *mainwin = (MainWindow *)data; @@ -4316,58 +4192,6 @@ static void delete_thread_cb(GtkAction *action, gpointer data) summary_select_thread(mainwin->summaryview, TRUE, FALSE); } -static void create_filter_cb(GtkAction *gaction, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - const gchar *a_name = gtk_action_get_name(gaction); - gint action = -1; - - DO_ACTION("Tools/CreateFilterRule/Automatically", FILTER_BY_AUTO); - DO_ACTION("Tools/CreateFilterRule/ByFrom", FILTER_BY_FROM); - DO_ACTION("Tools/CreateFilterRule/ByTo", FILTER_BY_TO); - DO_ACTION("Tools/CreateFilterRule/BySubject", FILTER_BY_SUBJECT); - DO_ACTION("Tools/CreateFilterRule/BySender", FILTER_BY_SENDER); - summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 0); -} - -static void create_processing_cb(GtkAction *gaction, gpointer data) -{ - MainWindow *mainwin = (MainWindow *)data; - const gchar *a_name = gtk_action_get_name(gaction); - gint action = -1; - - DO_ACTION("Tools/CreateProcessingRule/Automatically", FILTER_BY_AUTO); - DO_ACTION("Tools/CreateProcessingRule/ByFrom", FILTER_BY_FROM); - DO_ACTION("Tools/CreateProcessingRule/ByTo", FILTER_BY_TO); - DO_ACTION("Tools/CreateProcessingRule/BySubject", FILTER_BY_SUBJECT); - DO_ACTION("Tools/CreateProcessingRule/BySender", FILTER_BY_SENDER); - summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 1); -} - -static void prefs_pre_processing_open_cb(GtkAction *action, gpointer data) -{ - prefs_filtering_open(&pre_global_processing, - _("Processing rules to apply before folder rules"), - MANUAL_ANCHOR_PROCESSING, - NULL, NULL, FALSE); -} - -static void prefs_post_processing_open_cb(GtkAction *action, gpointer data) -{ - prefs_filtering_open(&post_global_processing, - _("Processing rules to apply after folder rules"), - MANUAL_ANCHOR_PROCESSING, - NULL, NULL, FALSE); -} - -static void prefs_filtering_open_cb(GtkAction *action, gpointer data) -{ - prefs_filtering_open(&filtering_rules, - _("Filtering configuration"), - MANUAL_ANCHOR_FILTERING, - NULL, NULL, TRUE); -} - static void prefs_template_open_cb(GtkAction *action, gpointer data) { prefs_template_open(); diff --git a/src/matcher.c b/src/matcher.c @@ -396,48 +396,20 @@ static gboolean match_with_addresses_in_addressbook extract_address(addr); if (strcasecmp(addr, walk->data) == 0) { found = TRUE; - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - log_print(LOG_DEBUG_FILTERING, - "address [ %s ] matches\n", - (gchar *)walk->data); - } } g_free(addr); } } - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH - && !found) { - log_print(LOG_DEBUG_FILTERING, - "address [ %s ] does NOT match\n", - (gchar *)walk->data); - } g_free(walk->data); if (match == MATCH_ALL) { /* if matching all addresses, stop if one doesn't match */ if (!found) { - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - log_print(LOG_DEBUG_FILTERING, - "not all address match (matching all)\n"); - } break; } } else if (match == MATCH_ANY) { /* if matching any address, stop if one does match */ if (found) { - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - log_print(LOG_DEBUG_FILTERING, - "at least one address matches (matching any)\n"); - } break; } } @@ -508,52 +480,11 @@ static gboolean matcherprop_string_match(MatcherProp *prop, const gchar *str, ret = TRUE; else ret = FALSE; - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - gchar *stripped = g_strdup(str); - - strretchomp(stripped); - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "%s value [ %s ] matches regular expression [ %s ] (%s)\n", - debug_context, stripped, prop->expr, - prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case insensitive")); - } else { - log_print(LOG_DEBUG_FILTERING, - "%s value [ %s ] does NOT match regular expression [ %s ] (%s)\n", - debug_context, stripped, prop->expr, - prop->matchtype == MATCHTYPE_REGEXP ? _("Case sensitive"):_("Case insensitive")); - } - g_free(stripped); - } break; case MATCHTYPE_MATCHCASE: case MATCHTYPE_MATCH: ret = (strstr(str1, down_expr) != NULL); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - gchar *stripped = g_strdup(str); - - strretchomp(stripped); - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "%s value [ %s ] contains [ %s ] (%s)\n", - debug_context, stripped, prop->expr, - prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case insensitive")); - } else { - log_print(LOG_DEBUG_FILTERING, - "%s value [ %s ] does NOT contain [ %s ] (%s)\n", - debug_context, stripped, prop->expr, - prop->matchtype == MATCHTYPE_MATCH ? _("Case sensitive"):_("Case insensitive")); - } - g_free(stripped); - } break; - default: break; } @@ -696,14 +627,6 @@ static gboolean matcherprop_match_test(const MatcherProp *prop, return FALSE; } - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - log_print(LOG_DEBUG_FILTERING, - "starting threaded command [ %s ]\n", - cmd); - } - td->cmd = cmd; td->done = FALSE; if (pthread_create(&pt, NULL, matcher_test_thread, td) != 0) @@ -728,14 +651,6 @@ static gboolean matcherprop_match_test(const MatcherProp *prop, g_free(td); debug_print("Command exit code: %d\n", retval); - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - log_print(LOG_DEBUG_FILTERING, - "command returned [ %d ]\n", - retval); - } - g_free(cmd); return (retval == 0); } @@ -753,6 +668,7 @@ static gboolean matcherprop_match(MatcherProp *prop, MsgInfo *info) { time_t t; + gint age; gint age_mult_hours = 1; switch(prop->criteria) { @@ -798,46 +714,6 @@ static gboolean matcherprop_match(MatcherProp *prop, return MSG_IS_SIGNED(info->flags); case MATCHCRITERIA_NOT_SIGNED: return !MSG_IS_SIGNED(info->flags); - case MATCHCRITERIA_COLORLABEL: - { - gint color = MSG_GET_COLORLABEL_VALUE(info->flags); - gboolean ret = (color == prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message color value [ %d ] matches color value [ %d ]\n", - color, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message color value [ %d ] does NOT match color value [ %d ]\n", - color, prop->value); - } - } - return ret; - } - case MATCHCRITERIA_NOT_COLORLABEL: - { - gint color = MSG_GET_COLORLABEL_VALUE(info->flags); - gboolean ret = (color != prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message color value [ %d ] matches color value [ %d ]\n", - color, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message color value [ %d ] does NOT match color value [ %d ]\n", - color, prop->value); - } - } - return ret; - } case MATCHCRITERIA_IGNORE_THREAD: return MSG_IS_IGNORE_THREAD(info->flags); case MATCHCRITERIA_NOT_IGNORE_THREAD: @@ -880,253 +756,41 @@ static gboolean matcherprop_match(MatcherProp *prop, age_mult_hours = 24; /* Fallthrough intended */ case MATCHCRITERIA_AGE_GREATER_HOURS: - { - gboolean ret; - gint age; - t = time(NULL); age = ((t - info->date_t) / (60 * 60 * age_mult_hours)); - ret = (age >= prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message age [ %d ] is greater than [ %d ]\n", - age, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message age [ %d ] is not greater than [ %d ]\n", - age, prop->value); - } - } - return ret; - } + return (age >= prop->value); case MATCHCRITERIA_DATE_AFTER: - { - gboolean ret; - - ret = prop->value < info->date_t; - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message date [ %" CM_TIME_FORMAT " ] is after [ %d ]\n", - info->date_t, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message date [ %" CM_TIME_FORMAT " ] is not after [ %d ]\n", - info->date_t, prop->value); - } - } - return ret; - } + return prop->value < info->date_t; case MATCHCRITERIA_AGE_LOWER: age_mult_hours = 24; /* Fallthrough intended */ case MATCHCRITERIA_AGE_LOWER_HOURS: - { - gboolean ret; - gint age; - t = time(NULL); age = ((t - info->date_t) / (60 * 60 * age_mult_hours)); - ret = (age < prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message age [ %d ] is lower than [ %d ]\n", - age, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message age [ %d ] is not lower than [ %d ]\n", - age, prop->value); - } - } - return ret; - } + return (age < prop->value); case MATCHCRITERIA_DATE_BEFORE: - { - gboolean ret; - - ret = prop->value > info->date_t; - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message date [ %" CM_TIME_FORMAT " ] is before [ %d ]\n", - info->date_t, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message date [ %" CM_TIME_FORMAT " ] is not before [ %d ]\n", - info->date_t, prop->value); - } - } - return ret; - } + return prop->value > info->date_t; case MATCHCRITERIA_SCORE_GREATER: - { - gboolean ret = (info->score > prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is greater than [ %d ]\n", - info->score, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is not greater than [ %d ]\n", - info->score, prop->value); - } - } - return ret; - } + return (info->score > prop->value); case MATCHCRITERIA_SCORE_LOWER: - { - gboolean ret = (info->score < prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is lower than [ %d ]\n", - info->score, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is not lower than [ %d ]\n", - info->score, prop->value); - } - } - return ret; - } + return (info->score < prop->value); case MATCHCRITERIA_SCORE_EQUAL: - { - gboolean ret = (info->score == prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is equal to [ %d ]\n", - info->score, prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message score [ %d ] is not equal to [ %d ]\n", - info->score, prop->value); - } - } - return ret; - } + return (info->score == prop->value); case MATCHCRITERIA_SIZE_GREATER: - { /* FIXME: info->size is a goffset */ - gboolean ret = (info->size > (goffset) prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message size is greater than [ %d ]\n", - prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message size is not greater than [ %d ]\n", - prop->value); - } - } - return ret; - } + return (info->size > (goffset) prop->value); case MATCHCRITERIA_SIZE_SMALLER: - { /* FIXME: info->size is a goffset */ - gboolean ret = (info->size < (goffset) prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message size is smaller than [ %d ]\n", - prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message size is not smaller than [ %d ]\n", - prop->value); - } - } - return ret; - } + return (info->size < (goffset) prop->value); case MATCHCRITERIA_SIZE_EQUAL: - { /* FIXME: info->size is a goffset */ - gboolean ret = (info->size == (goffset) prop->value); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message size is equal to [ %d ]\n", - prop->value); - } else { - log_print(LOG_DEBUG_FILTERING, - "message size is not equal to [ %d ]\n", - prop->value); - } - } - return ret; - } + return (info->size == (goffset) prop->value); case MATCHCRITERIA_PARTIAL: - { /* FIXME: info->size is a goffset */ - gboolean ret = (info->total_size != 0 && info->size != (goffset)info->total_size); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message is partially downloaded, size is less than total size [ %d ])\n", - info->total_size); - } else { - log_print(LOG_DEBUG_FILTERING, - "message is not partially downloaded\n"); - } - } - return ret; - } + return (info->total_size != 0 && info->size != (goffset)info->total_size); case MATCHCRITERIA_NOT_PARTIAL: - { /* FIXME: info->size is a goffset */ - gboolean ret = (info->total_size == 0 || info->size == (goffset)info->total_size); - - /* debug output */ - if (debug_filtering_session - && prefs_common.filtering_debug_level >= FILTERING_DEBUG_LEVEL_HIGH) { - if (ret) { - log_print(LOG_DEBUG_FILTERING, - "message is not partially downloaded\n"); - } else { - log_print(LOG_DEBUG_FILTERING, - "message is partially downloaded, size is less than total size [ %d ])\n", - info->total_size); - } - } - return ret; - } + return (info->total_size == 0 || info->size == (goffset)info->total_size); case MATCHCRITERIA_NEWSGROUPS: return matcherprop_string_match(prop, info->newsgroups, context_str[CONTEXT_NEWSGROUPS]); case MATCHCRITERIA_NOT_NEWSGROUPS: @@ -1860,12 +1524,6 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info) for (l = matchers->matchers; l != NULL ;l = g_slist_next(l)) { MatcherProp *matcher = (MatcherProp *) l->data; - if (debug_filtering_session) { - gchar *buf = matcherprop_to_string(matcher); - log_print(LOG_DEBUG_FILTERING, _("checking if message matches [ %s ]\n"), buf); - g_free(buf); - } - switch(matcher->criteria) { case MATCHCRITERIA_ALL: case MATCHCRITERIA_UNREAD: @@ -1888,8 +1546,6 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info) case MATCHCRITERIA_HAS_NO_ATTACHMENT: case MATCHCRITERIA_SIGNED: case MATCHCRITERIA_NOT_SIGNED: - case MATCHCRITERIA_COLORLABEL: - case MATCHCRITERIA_NOT_COLORLABEL: case MATCHCRITERIA_IGNORE_THREAD: case MATCHCRITERIA_NOT_IGNORE_THREAD: case MATCHCRITERIA_WATCH_THREAD: @@ -1934,15 +1590,11 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info) case MATCHCRITERIA_NOT_PARTIAL: if (matcherprop_match(matcher, info)) { if (!matchers->bool_and) { - if (debug_filtering_session) - log_status_ok(LOG_DEBUG_FILTERING, _("message matches\n")); return TRUE; } } else { if (matchers->bool_and) { - if (debug_filtering_session) - log_status_nok(LOG_DEBUG_FILTERING, _("message does not match\n")); return FALSE; } } @@ -1953,24 +1605,13 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info) if (matcherlist_match_file(matchers, info, result)) { if (!matchers->bool_and) { - if (debug_filtering_session) - log_status_ok(LOG_DEBUG_FILTERING, _("message matches\n")); return TRUE; } } else { if (matchers->bool_and) { - if (debug_filtering_session) - log_status_nok(LOG_DEBUG_FILTERING, _("message does not match\n")); return FALSE; } } - - if (debug_filtering_session) { - if (result) - log_status_ok(LOG_DEBUG_FILTERING, _("message matches\n")); - else - log_status_nok(LOG_DEBUG_FILTERING, _("message does not match\n")); - } return result; } @@ -2071,8 +1712,6 @@ gchar *matcherprop_to_string(MatcherProp *matcher) case MATCHCRITERIA_SIZE_GREATER: case MATCHCRITERIA_SIZE_SMALLER: case MATCHCRITERIA_SIZE_EQUAL: - case MATCHCRITERIA_COLORLABEL: - case MATCHCRITERIA_NOT_COLORLABEL: return g_strdup_printf("%s %i", criteria_str, matcher->value); case MATCHCRITERIA_ALL: case MATCHCRITERIA_UNREAD: @@ -2378,84 +2017,6 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info) */ static int prefs_filtering_write(FILE *fp, GSList *prefs_filtering) { - GSList *cur = NULL; - - for (cur = prefs_filtering; cur != NULL; cur = cur->next) { - gchar *filtering_str = NULL; - gchar *tmp_name = NULL; - FilteringProp *prop = NULL; - - if (NULL == (prop = (FilteringProp *) cur->data)) - continue; - - if (NULL == (filtering_str = filteringprop_to_string(prop))) - continue; - - if (prop->enabled) { - if (fputs("enabled ", fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs"); - g_free(filtering_str); - return -1; - } - } else { - if (fputs("disabled ", fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs"); - g_free(filtering_str); - return -1; - } - } - - if (fputs("rulename \"", fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs"); - g_free(filtering_str); - return -1; - } - tmp_name = prop->name; - while (tmp_name && *tmp_name != '\0') { - if (*tmp_name != '"') { - if (fputc(*tmp_name, fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs || fputc"); - g_free(filtering_str); - return -1; - } - } else if (*tmp_name == '"') { - if (fputc('\\', fp) == EOF || - fputc('"', fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs || fputc"); - g_free(filtering_str); - return -1; - } - } - tmp_name ++; - } - if (fputs("\" ", fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs"); - g_free(filtering_str); - return -1; - } - - if (prop->account_id != 0) { - gchar *tmp = NULL; - - tmp = g_strdup_printf("account %d ", prop->account_id); - if (fputs(tmp, fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs"); - g_free(filtering_str); - g_free(tmp); - return -1; - } - g_free(tmp); - } - - if(fputs(filtering_str, fp) == EOF || - fputc('\n', fp) == EOF) { - FILE_OP_ERROR("filtering config", "fputs || fputc"); - g_free(filtering_str); - return -1; - } - g_free(filtering_str); - } - return 0; } @@ -2531,25 +2092,6 @@ static int prefs_matcher_save(FILE *fp) if (data.error == TRUE) return -1; - - /* pre global rules */ - if (fprintf(fp, "[preglobal]\n") < 0 || - prefs_filtering_write(fp, pre_global_processing) < 0 || - fputc('\n', fp) == EOF) - return -1; - - /* post global rules */ - if (fprintf(fp, "[postglobal]\n") < 0 || - prefs_filtering_write(fp, post_global_processing) < 0 || - fputc('\n', fp) == EOF) - return -1; - - /* filtering rules */ - if (fprintf(fp, "[filtering]\n") < 0 || - prefs_filtering_write(fp, filtering_rules) < 0 || - fputc('\n', fp) == EOF) - return -1; - return 0; } @@ -2591,8 +2133,6 @@ void prefs_matcher_read_config(void) FILE *f; create_matchparser_hashtab(); - prefs_filtering_clear(); - rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MATCHER_RC, NULL); f = g_fopen(rcpath, "rb"); diff --git a/src/matcher_parser.h b/src/matcher_parser.h @@ -14,13 +14,12 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * */ #ifndef MATCHER_PARSER_H #define MATCHER_PARSER_H -#include "filtering.h" #include <glib.h> extern FILE *matcher_parserin; @@ -32,7 +31,6 @@ int matcher_parserparse (void); MatcherList *matcher_parser_get_cond (gchar *str, gboolean *is_fast); MatcherProp *matcher_parser_get_prop (gchar *str); -FilteringProp *matcher_parser_get_filtering (gchar *str); GSList *matcher_parser_get_action_list(gchar *str); #endif diff --git a/src/matcher_parser_parse.y b/src/matcher_parser_parse.y @@ -24,7 +24,6 @@ #include <glib/gi18n.h> #include "utils.h" -#include "filtering.h" #include "procheader.h" #include "matcher.h" #include "matcher_parser.h" @@ -45,11 +44,9 @@ static gchar *name = NULL; static gint account_id = 0; static MatcherList *cond; static GSList *action_list = NULL; -static FilteringAction *action = NULL; static gboolean matcher_is_fast = TRUE; static gboolean disable_warnings = FALSE; -static FilteringProp *filtering; static gboolean filtering_ptr_externally_managed = FALSE; static GSList **prefs_filtering = NULL; @@ -93,39 +90,6 @@ void matcher_parser_start_parsing(FILE *f) void * matcher_parser_scan_string(const char * str); -FilteringProp *matcher_parser_get_filtering(gchar *str) -{ - void *bufstate; - void *tmp_str = NULL; - - /* little hack to allow passing rules with no names */ - if (!strncmp(str, "rulename ", 9)) - tmp_str = g_strdup(str); - else - tmp_str = g_strconcat("rulename \"\" ", str, NULL); - - /* bad coding to enable the sub-grammar matching - in yacc */ - matcher_parserlineno = 1; - matcher_parse_op = MATCHER_PARSE_NO_EOL; - matcher_parserrestart(NULL); - matcher_parserpop_buffer_state(); - matcher_parser_init(); - bufstate = matcher_parser_scan_string((const char *) tmp_str); - matcher_parser_switch_to_buffer(bufstate); - /* Indicate that we will be using the global "filtering" pointer, - * so that yyparse does not free it in "filtering_action_list" - * section. */ - filtering_ptr_externally_managed = TRUE; - if (matcher_parserparse() != 0) - filtering = NULL; - matcher_parse_op = MATCHER_PARSE_FILE; - matcher_parser_delete_buffer(bufstate); - g_free(tmp_str); - filtering_ptr_externally_managed = FALSE; /* Return to normal. */ - return filtering; -} - static gboolean check_quote_symetry(gchar *str) { const gchar *walk; @@ -373,9 +337,6 @@ int matcher_parserwrap(void) file: { - if (matcher_parse_op == MATCHER_PARSE_FILE) { - prefs_filtering = &pre_global_processing; - } } file_line_list; @@ -407,15 +368,6 @@ MATCHER_SECTION MATCHER_EOL /* backward compatibility */ enable_compatibility = 1; } - else if (!strcmp(folder, "preglobal")) { - prefs_filtering = &pre_global_processing; - } - else if (!strcmp(folder, "postglobal")) { - prefs_filtering = &post_global_processing; - } - else if (!strcmp(folder, "filtering")) { - prefs_filtering = &filtering_rules; - } else { item = folder_find_item_from_identifier(folder); if (item != NULL) { @@ -519,41 +471,12 @@ MATCHER_ACCOUNT MATCHER_INTEGER filtering: filtering_action_list { - filtering = filteringprop_new(enabled, name, account_id, cond, action_list); enabled = TRUE; account_id = 0; g_free(name); name = NULL; - if (enable_compatibility) { - prefs_filtering = &filtering_rules; - if (action_list != NULL) { - FilteringAction * first_action; - - first_action = action_list->data; - - if (first_action->type == MATCHACTION_CHANGE_SCORE) - prefs_filtering = &pre_global_processing; - } - } - cond = NULL; action_list = NULL; - - if ((matcher_parse_op == MATCHER_PARSE_FILE) && - (prefs_filtering != NULL)) { - *prefs_filtering = g_slist_append(*prefs_filtering, - filtering); - filtering = NULL; - } else if (!filtering_ptr_externally_managed) { - /* If filtering_ptr_externally_managed was TRUE, it - * would mean that some function higher in the stack is - * interested in the data "filtering" is pointing at, so - * we would not free it. That function has to free it itself. - * At the time of writing this, the only function that - * does this is matcher_parser_get_filtering(). */ - filteringprop_free(filtering); - filtering = NULL; - } } ; @@ -565,8 +488,6 @@ filtering_action_b filtering_action_list filtering_action_b: filtering_action { - action_list = g_slist_append(action_list, action); - action = NULL; } ; @@ -1265,7 +1186,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_EXECUTE; cmd = $2; - action = filteringaction_new(action_type, 0, cmd, 0, 0, NULL); } | MATCHER_MOVE MATCHER_STRING { @@ -1274,7 +1194,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_MOVE; destination = $2; - action = filteringaction_new(action_type, 0, destination, 0, 0, NULL); } | MATCHER_SET_TAG MATCHER_STRING { @@ -1283,7 +1202,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_SET_TAG; destination = $2; - action = filteringaction_new(action_type, 0, destination, 0, 0, NULL); } | MATCHER_UNSET_TAG MATCHER_STRING { @@ -1292,14 +1210,12 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_UNSET_TAG; destination = $2; - action = filteringaction_new(action_type, 0, destination, 0, 0, NULL); } | MATCHER_CLEAR_TAGS { gint action_type = 0; action_type = MATCHACTION_CLEAR_TAGS; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_COPY MATCHER_STRING { @@ -1308,70 +1224,60 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_COPY; destination = $2; - action = filteringaction_new(action_type, 0, destination, 0, 0, NULL); } | MATCHER_DELETE { gint action_type = 0; action_type = MATCHACTION_DELETE; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_MARK { gint action_type = 0; action_type = MATCHACTION_MARK; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_UNMARK { gint action_type = 0; action_type = MATCHACTION_UNMARK; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_LOCK { gint action_type = 0; action_type = MATCHACTION_LOCK; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_UNLOCK { gint action_type = 0; action_type = MATCHACTION_UNLOCK; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_MARK_AS_READ { gint action_type = 0; action_type = MATCHACTION_MARK_AS_READ; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_MARK_AS_UNREAD { gint action_type = 0; action_type = MATCHACTION_MARK_AS_UNREAD; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_MARK_AS_SPAM { gint action_type = 0; action_type = MATCHACTION_MARK_AS_SPAM; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_MARK_AS_HAM { gint action_type = 0; action_type = MATCHACTION_MARK_AS_HAM; - action = filteringaction_new(action_type, 0, NULL, 0, 0, NULL); } | MATCHER_FORWARD MATCHER_INTEGER MATCHER_STRING { @@ -1382,8 +1288,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_FORWARD; account_id = strtol($2, NULL, 10); destination = $3; - action = filteringaction_new(action_type, - account_id, destination, 0, 0, NULL); } | MATCHER_FORWARD_AS_ATTACHMENT MATCHER_INTEGER MATCHER_STRING { @@ -1394,8 +1298,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_FORWARD_AS_ATTACHMENT; account_id = strtol($2, NULL, 10); destination = $3; - action = filteringaction_new(action_type, - account_id, destination, 0, 0, NULL); } | MATCHER_REDIRECT MATCHER_INTEGER MATCHER_STRING { @@ -1406,8 +1308,6 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_REDIRECT; account_id = strtol($2, NULL, 10); destination = $3; - action = filteringaction_new(action_type, - account_id, destination, 0, 0, NULL); } | MATCHER_COLOR MATCHER_INTEGER { @@ -1416,15 +1316,12 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_COLOR; color = strtol($2, NULL, 10); - action = filteringaction_new(action_type, 0, NULL, color, 0, NULL); } | MATCHER_CHANGE_SCORE MATCHER_INTEGER { gint score = 0; score = strtol($2, NULL, 10); - action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0, - NULL, 0, score, NULL); } /* backward compatibility */ | MATCHER_SCORE MATCHER_INTEGER @@ -1432,28 +1329,21 @@ MATCHER_EXECUTE MATCHER_STRING gint score = 0; score = strtol($2, NULL, 10); - action = filteringaction_new(MATCHACTION_CHANGE_SCORE, 0, - NULL, 0, score, NULL); } | MATCHER_SET_SCORE MATCHER_INTEGER { gint score = 0; score = strtol($2, NULL, 10); - action = filteringaction_new(MATCHACTION_SET_SCORE, 0, - NULL, 0, score, NULL); } | MATCHER_HIDE { - action = filteringaction_new(MATCHACTION_HIDE, 0, NULL, 0, 0, NULL); } | MATCHER_IGNORE { - action = filteringaction_new(MATCHACTION_IGNORE, 0, NULL, 0, 0, NULL); } | MATCHER_WATCH { - action = filteringaction_new(MATCHACTION_WATCH, 0, NULL, 0, 0, NULL); } | MATCHER_ADD_TO_ADDRESSBOOK MATCHER_STRING { @@ -1465,11 +1355,9 @@ MATCHER_EXECUTE MATCHER_STRING action_type = MATCHACTION_ADD_TO_ADDRESSBOOK; addressbook = $2; - action = filteringaction_new(action_type, 0, addressbook, 0, 0, header); g_free(header); } | MATCHER_STOP { - action = filteringaction_new(MATCHACTION_STOP, 0, NULL, 0, 0, NULL); } ; diff --git a/src/mbox.c b/src/mbox.c @@ -42,7 +42,6 @@ #include "prefs_account.h" #include "account.h" #include "utils.h" -#include "filtering.h" #include "alertpanel.h" #include "statusbar.h" #include "file-utils.h" @@ -71,9 +70,8 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, gchar *tmp_file; gint msgs = 0; gint lines; - MsgInfo *msginfo; gboolean more; - GSList *to_filter = NULL, *filtered = NULL, *unfiltered = NULL, *cur, *to_add = NULL; + GSList *to_add = NULL; gboolean printed = FALSE; FolderItem *dropfolder; GStatBuf src_stat; @@ -114,15 +112,11 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, folder_item_update_freeze(); - if (apply_filter) - dropfolder = folder_get_default_processing(account->account_id); - else - dropfolder = dest; + dropfolder = dest; do { FILE *tmp_fp; gint empty_lines; - gint msgnum; if (msgs%10 == 0) { long cur_offset_mb = ftell(mbox_fp) / (1024 * 1024); @@ -228,28 +222,18 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, return -1; } - if (apply_filter) { - if ((msgnum = folder_item_add_msg(dropfolder, tmp_file, NULL, TRUE)) < 0) { - fclose(mbox_fp); - unlink(tmp_file); - g_free(tmp_file); - return -1; - } - msginfo = folder_item_get_msginfo(dropfolder, msgnum); - to_filter = g_slist_prepend(to_filter, msginfo); - } else { - MsgFileInfo *finfo = g_new0(MsgFileInfo, 1); - finfo->file = tmp_file; - to_add = g_slist_prepend(to_add, finfo); - tmp_file = get_tmp_file(); + MsgFileInfo *finfo = g_new0(MsgFileInfo, 1); + finfo->file = tmp_file; - /* flush every 500 */ - if (msgs > 0 && msgs % 500 == 0) { - folder_item_add_msgs(dropfolder, to_add, TRUE); - procmsg_message_file_list_free(to_add); - to_add = NULL; - } + to_add = g_slist_prepend(to_add, finfo); + tmp_file = get_tmp_file(); + + /* flush every 500 */ + if (msgs > 0 && msgs % 500 == 0) { + folder_item_add_msgs(dropfolder, to_add, TRUE); + procmsg_message_file_list_free(to_add); + to_add = NULL; } msgs++; } while (more); @@ -259,32 +243,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter, statusbar_progress_all(0, 0, 0); } - if (apply_filter) { - - folder_item_set_batch(dropfolder, FALSE); - procmsg_msglist_filter(to_filter, account, - &filtered, &unfiltered, TRUE); - folder_item_set_batch(dropfolder, TRUE); - - filtering_move_and_copy_msgs(to_filter); - for (cur = filtered; cur; cur = g_slist_next(cur)) { - MsgInfo *info = (MsgInfo *)cur->data; - procmsg_msginfo_free(&info); - } - - unfiltered = g_slist_reverse(unfiltered); - if (unfiltered) { - folder_item_move_msgs(dest, unfiltered); - for (cur = unfiltered; cur; cur = g_slist_next(cur)) { - MsgInfo *info = (MsgInfo *)cur->data; - procmsg_msginfo_free(&info); - } - } - - g_slist_free(unfiltered); - g_slist_free(filtered); - g_slist_free(to_filter); - } else if (to_add) { + if (to_add) { folder_item_add_msgs(dropfolder, to_add, TRUE); procmsg_message_file_list_free(to_add); to_add = NULL; diff --git a/src/messageview.c b/src/messageview.c @@ -55,7 +55,6 @@ #include "send_message.h" #include "stock_pixmap.h" #include "hooks.h" -#include "filtering.h" #include "partial_download.h" #include "inc.h" #include "log.h" @@ -162,10 +161,6 @@ static void addressbook_open_cb (GtkAction *action, gpointer data); static void add_address_cb (GtkAction *action, gpointer data); -static void create_filter_cb (GtkAction *action, - gpointer data); -static void create_processing_cb (GtkAction *action, - gpointer data); static void about_cb (GtkAction *action, gpointer data); @@ -183,7 +178,6 @@ static void goto_prev_part_cb(GtkAction *action, gpointer data); static void messageview_nothing_cb (GtkAction *action, gpointer data) { - } static GList *msgview_list = NULL; @@ -292,21 +286,6 @@ static GtkActionEntry msgview_entries[] = {"Tools/AddSenderToAB", NULL, N_("Add sender to address boo_k"), NULL, NULL, G_CALLBACK(add_address_cb) }, {"Tools/---", NULL, "---", NULL, NULL, NULL }, - {"Tools/CreateFilterRule", NULL, N_("_Create filter rule"), NULL, NULL, NULL }, - {"Tools/CreateFilterRule/Automatically", NULL, N_("_Automatically"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_AUTO */ - {"Tools/CreateFilterRule/ByFrom", NULL, N_("By _From"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_FROM */ - {"Tools/CreateFilterRule/ByTo", NULL, N_("By _To"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_TO */ - {"Tools/CreateFilterRule/BySubject", NULL, N_("By _Subject"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_SUBJECT */ - {"Tools/CreateFilterRule/BySender", NULL, N_("By S_ender"), NULL, NULL, G_CALLBACK(create_filter_cb) }, /* FILTER_BY_SENDER */ - - {"Tools/CreateProcessingRule", NULL, N_("Create processing rule"), NULL, NULL, NULL }, - {"Tools/CreateProcessingRule/Automatically", NULL, N_("_Automatically"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/ByFrom", NULL, N_("By _From"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/ByTo", NULL, N_("By _To"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/BySubject", NULL, N_("By _Subject"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - {"Tools/CreateProcessingRule/BySender", NULL, N_("By S_ender"), NULL, NULL, G_CALLBACK(create_processing_cb) }, - /* {"Tools/---", NULL, "---", NULL, NULL, NULL }, */ - /* {"Tools/---", NULL, "---", NULL, NULL, NULL }, */ {"Tools/Actions", NULL, N_("Actio_ns"), NULL, NULL, NULL }, {"Tools/Actions/PlaceHolder", NULL, "Placeholder", NULL, NULL, G_CALLBACK(messageview_nothing_cb) }, @@ -606,19 +585,6 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window) MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "AddSenderToAB", "Tools/AddSenderToAB", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "Separator1", "Tools/---", GTK_UI_MANAGER_SEPARATOR) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "CreateFilterRule", "Tools/CreateFilterRule", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateFilterRule", "Automatically", "Tools/CreateFilterRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateFilterRule", "ByFrom", "Tools/CreateFilterRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateFilterRule", "ByTo", "Tools/CreateFilterRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateFilterRule", "BySubject", "Tools/CreateFilterRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateFilterRule", "BySender", "Tools/CreateFilterRule/BySender", GTK_UI_MANAGER_MENUITEM) - - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "CreateProcessingRule", "Tools/CreateProcessingRule", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateProcessingRule", "Automatically", "Tools/CreateProcessingRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateProcessingRule", "ByFrom", "Tools/CreateProcessingRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateProcessingRule", "ByTo", "Tools/CreateProcessingRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateProcessingRule", "BySubject", "Tools/CreateProcessingRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools/CreateProcessingRule", "BySender", "Tools/CreateProcessingRule/BySender", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "Separator2", "Tools/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "Actions", "Tools/Actions", GTK_UI_MANAGER_MENU) @@ -2836,46 +2802,6 @@ static void add_address_cb(GtkAction *action, gpointer data) avatars_avatarrender_free(avatarr); } -static void create_filter_cb(GtkAction *gaction, gpointer data) -{ - MessageView *messageview = (MessageView *)data; - FolderItem * item; - gint action = -1; - const gchar *a_name = gtk_action_get_name(gaction); - - if (!messageview->msginfo) return; - - DO_ACTION("Tools/CreateFilterRule/Automatically", FILTER_BY_AUTO); - DO_ACTION("Tools/CreateFilterRule/ByFrom", FILTER_BY_FROM); - DO_ACTION("Tools/CreateFilterRule/ByTo", FILTER_BY_TO); - DO_ACTION("Tools/CreateFilterRule/BySubject", FILTER_BY_SUBJECT); - DO_ACTION("Tools/CreateFilterRule/BySender", FILTER_BY_SENDER); - - item = messageview->msginfo->folder; - summary_msginfo_filter_open(item, messageview->msginfo, - (PrefsFilterType)action, 0); -} - -static void create_processing_cb(GtkAction *gaction, gpointer data) -{ - MessageView *messageview = (MessageView *)data; - FolderItem * item; - gint action = -1; - const gchar *a_name = gtk_action_get_name(gaction); - - if (!messageview->msginfo) return; - - DO_ACTION("Tools/CreateProcessingRule/Automatically", FILTER_BY_AUTO); - DO_ACTION("Tools/CreateProcessingRule/ByFrom", FILTER_BY_FROM); - DO_ACTION("Tools/CreateProcessingRule/ByTo", FILTER_BY_TO); - DO_ACTION("Tools/CreateProcessingRule/BySubject", FILTER_BY_SUBJECT); - DO_ACTION("Tools/CreateProcessingRule/BySender", FILTER_BY_SENDER); - - item = messageview->msginfo->folder; - summary_msginfo_filter_open(item, messageview->msginfo, - (PrefsFilterType)action, 1); -} - static void about_cb(GtkAction *gaction, gpointer data) { about_show(); diff --git a/src/mh_gtk.c b/src/mh_gtk.c @@ -228,7 +228,6 @@ static void delete_folder_cb(GtkAction *action, gpointer data) folder_write_list(); - prefs_filtering_delete_path(old_id); g_free(old_id); } @@ -285,7 +284,6 @@ static void rename_folder_cb(GtkAction *action, gpointer data) } new_id = folder_item_get_identifier(item); - prefs_filtering_rename_path(old_id, new_id); account_rename_path(old_id, new_id); prefs_actions_rename_path(old_id, new_id); g_free(old_id); diff --git a/src/prefs_account.c b/src/prefs_account.c @@ -3608,8 +3608,6 @@ static gint prefs_basic_apply(void) new_id = g_strdup_printf("#%s/%s", protocol == A_IMAP4 ? "imap":"news", tmp_ac_prefs.account_name); - if (old_id != NULL && new_id != NULL) - prefs_filtering_rename_path(old_id, new_id); if (old_id) g_free(old_id); if (new_id) diff --git a/src/prefs_actions.c b/src/prefs_actions.c @@ -45,7 +45,6 @@ #include "description_window.h" #include "manual.h" #include "menu.h" -#include "filtering.h" #include "prefs_filtering_action.h" #include "matcher_parser.h" #include "prefs_toolbar.h" @@ -127,8 +126,6 @@ static void prefs_actions_select_row(GtkTreeView *list_view, GtkTreePath *path); static void prefs_action_filter_radiobtn_cb(GtkWidget *widget, gpointer data); static void prefs_action_shell_radiobtn_cb(GtkWidget *widget, gpointer data); static void prefs_action_filterbtn_cb(GtkWidget *widget, gpointer data); -static void prefs_action_define_filter_done(GSList * action_list); - void prefs_actions_open(MainWindow *mainwin) { @@ -287,21 +284,6 @@ static void prefs_actions_create(MainWindow *mainwin) g_signal_connect(G_OBJECT(shell_radiobtn), "clicked", G_CALLBACK(prefs_action_shell_radiobtn_cb), NULL); - filter_radiobtn = - gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(shell_radiobtn), - _("Filter action")); - gtk_box_pack_start(GTK_BOX(filter_hbox), filter_radiobtn, FALSE, FALSE, 0); - gtk_widget_show(filter_radiobtn); - g_signal_connect(G_OBJECT(filter_radiobtn), "clicked", - G_CALLBACK(prefs_action_filter_radiobtn_cb), NULL); - - filter_btn = gtk_button_new_with_label(_("Edit filter action")); - gtk_box_pack_start(GTK_BOX(filter_hbox), filter_btn, FALSE, FALSE, 0); - gtk_widget_set_sensitive(filter_btn, FALSE); - g_signal_connect(G_OBJECT(filter_btn), "clicked", - G_CALLBACK(prefs_action_filterbtn_cb), NULL); - gtk_widget_show(filter_btn); - /* register / substitute / delete */ reg_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); @@ -1303,7 +1285,6 @@ static void prefs_action_shell_radiobtn_cb(GtkWidget *widget, gpointer data) static void prefs_action_filterbtn_cb(GtkWidget *widget, gpointer data) { gchar *action_str, **tokens; - GSList *action_list = NULL, *cur; action_str = gtk_editable_get_chars(GTK_EDITABLE(actions.cmd_entry), 0, -1); if(modified && @@ -1316,74 +1297,12 @@ static void prefs_action_filterbtn_cb(GtkWidget *widget, gpointer data) return; } tokens = g_strsplit_set(action_str, "{}", 5); - - if (tokens[0] && tokens[1] && *tokens[1] != '\0') { - action_list = matcher_parser_get_action_list(tokens[1]); - if (action_list == NULL) - alertpanel_error(_("Action string is not valid.")); - } - - prefs_filtering_action_open(action_list, prefs_action_define_filter_done); - - if (action_list != NULL) { - for(cur = action_list ; cur != NULL ; cur = cur->next) - filteringaction_free(cur->data); - } - g_free(action_str); g_strfreev(tokens); } -static void prefs_action_define_filter_done(GSList * action_list) -{ - gchar *str; - - if (action_list == NULL) - return; - - action_list = filtering_action_list_sort(action_list); - str = filteringaction_list_to_string(action_list); - - if (str != NULL) { - gchar *cmd; - cmd = g_strdup_printf("%%as{%s}",str); - g_free(str); - gtk_entry_set_text(GTK_ENTRY(actions.cmd_entry), cmd); - g_free(cmd); - modified = TRUE; - } -} - void prefs_actions_rename_path(const gchar *old_path, const gchar *new_path) -{ - gchar **tokens, *action_str; - GSList *action, *action_list; - - for (action = prefs_common.actions_list; action != NULL; - action = action->next) { - action_str = (gchar *)action->data; - tokens = g_strsplit_set(action_str, "{}", 5); - - if (tokens[0] && tokens[1] && *tokens[1] != '\0') - action_list = matcher_parser_get_action_list(tokens[1]); - else - action_list = NULL; - - if (action_list && - filtering_action_list_rename_path(action_list, - old_path, new_path)) { - gchar *str = filteringaction_list_to_string(action_list); - g_free(action->data); - action->data = g_strconcat(tokens[0], "{", - str ? str : "", "}", NULL); - if (str) - g_free(str); - } - - g_strfreev(tokens); - } - prefs_actions_write_config(); -} +{ } gint prefs_actions_find_by_name(const gchar *name) { diff --git a/src/prefs_filtering.c b/src/prefs_filtering.c @@ -1,1921 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 1999-2025 the Claws Mail team and Hiroyuki Yamamoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#include "claws-features.h" -#endif - -#include "defs.h" - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "main.h" -#include "prefs_gtk.h" -#include "prefs_matcher.h" -#include "prefs_filtering.h" -#include "prefs_common.h" -#include "mainwindow.h" -#include "foldersel.h" -#include "manage_window.h" -#include "inc.h" -#include "utils.h" -#include "gtkutils.h" -#include "alertpanel.h" -#include "folder.h" -#include "folder_item_prefs.h" -#include "filtering.h" -#include "addr_compl.h" -#include "manual.h" -#include "combobox.h" -#include "menu.h" -#include "account.h" - -#include "matcher_parser.h" -#include "matcher.h" -#include "prefs_filtering_action.h" - -enum { - PREFS_FILTERING_ENABLED, - PREFS_FILTERING_NAME, - PREFS_FILTERING_ACCOUNT_ID, - PREFS_FILTERING_ACCOUNT_NAME, - PREFS_FILTERING_RULE, - PREFS_FILTERING_PROP, - N_PREFS_FILTERING_COLUMNS -}; - -struct _Filtering { - GtkWidget *window; - - GtkWidget *help_btn; - GtkWidget *ok_btn; - GtkWidget *name_entry; - GtkWidget *account_label; - GtkWidget *account_combobox; - GtkListStore *account_combobox_list; - GtkWidget *cond_entry; - GtkWidget *action_entry; - - GtkWidget *cond_list_view; - - GtkTreeViewColumn *account_name_column; -}; - -typedef struct _Filtering Filtering; - -static Filtering filtering; - -static GSList ** p_processing_list = NULL; - -/* widget creating functions */ -static void prefs_filtering_create (void); - -static void prefs_filtering_set_dialog (const gchar *header, - const gchar *key); -static void prefs_filtering_set_list (void); - -/* callback functions */ -static gboolean prefs_filtering_search_func_cb (GtkTreeModel *model, gint column, - const gchar *key, GtkTreeIter *iter, - gpointer search_data); -static void prefs_filtering_register_cb (gpointer action, gpointer data); -static void prefs_filtering_substitute_cb (gpointer action, gpointer data); -static void prefs_filtering_delete_cb (gpointer action, gpointer data); -static void prefs_filtering_delete_all_cb(gpointer action, gpointer data); -static void prefs_filtering_clear_cb(gpointer action, gpointer data); -static void prefs_filtering_duplicate_cb(gpointer action, gpointer data); -static void prefs_filtering_top (gpointer action, gpointer data); -static void prefs_filtering_page_up (gpointer action, gpointer data); -static void prefs_filtering_up (gpointer action, gpointer data); -static void prefs_filtering_down (gpointer action, gpointer data); -static void prefs_filtering_page_down (gpointer action, gpointer data); -static void prefs_filtering_bottom (gpointer action, gpointer data); -static gint prefs_filtering_deleted (GtkWidget *widget, - GdkEventAny *event, - gpointer data); -static void prefs_filtering_row_selected(GtkTreeSelection *selection, - GtkTreeView *list_view); -static gboolean prefs_filtering_key_pressed(GtkWidget *widget, - GdkEventKey *event, - gpointer data); -static void prefs_filtering_cancel (gpointer action, gpointer data); -static void prefs_filtering_ok (gpointer action, gpointer data); - -static void prefs_filtering_condition_define (gpointer action, gpointer data); -static void prefs_filtering_action_define (gpointer action, gpointer data); -static gint prefs_filtering_list_view_set_row (gint row, FilteringProp * prop); - -static void prefs_filtering_reset_dialog (void); -static gboolean prefs_filtering_rename_tag_func(GNode *node, gpointer data); -static gboolean prefs_filtering_rename_path_func(GNode *node, gpointer data); -static gboolean prefs_filtering_delete_path_func(GNode *node, gpointer data); - -static void delete_path(GSList ** p_filters, const gchar * path); - - -static GtkListStore* prefs_filtering_create_data_store (void); -static gint prefs_filtering_list_view_insert_rule (GtkListStore *list_store, - gint row, - gboolean enabled, - const gchar *name, - gint account_id, - const gchar *account_name, - const gchar *rule, - gboolean prop); -static gchar *prefs_filtering_list_view_get_rule (GtkWidget *list, - gint row); -static void prefs_filtering_list_view_get_rule_info (GtkWidget *list, - gint row, - gboolean *enabled, - gchar **name, - gint *account_id); - -static GtkWidget *prefs_filtering_list_view_create (void); -static void prefs_filtering_create_list_view_columns (GtkWidget *list_view); - -static void prefs_filtering_select_row(GtkTreeView *list_view, GtkTreePath *path); - -static void prefs_filtering_account_option_menu_populate(void); - -static gulong signal_id = 0; /* filtering.help_btn clicked signal */ - -static int modified = FALSE; - -void prefs_filtering_open(GSList ** p_processing, - const gchar *title, - const gchar *help_url_anchor, - const gchar *header, - const gchar *key, - gboolean per_account_filtering) -{ - if (prefs_rc_is_readonly(FILTERING_RC)) - return; - - inc_lock(); - - if (!filtering.window) { - prefs_filtering_create(); - } else { - gtk_list_store_clear(filtering.account_combobox_list); - prefs_filtering_account_option_menu_populate(); - } - - gtk_tree_view_column_set_visible(filtering.account_name_column, - per_account_filtering); - - manage_window_set_transient(GTK_WINDOW(filtering.window)); - gtk_widget_grab_focus(filtering.ok_btn); - - if (title != NULL) - gtk_window_set_title(GTK_WINDOW(filtering.window), title); - else - gtk_window_set_title (GTK_WINDOW(filtering.window), - _("Filtering/Processing configuration")); - - if (help_url_anchor != NULL) { - if (signal_id != 0) { - g_signal_handler_disconnect( - G_OBJECT(filtering.help_btn), - signal_id); - } - - signal_id = g_signal_connect(G_OBJECT(filtering.help_btn), - "clicked", - G_CALLBACK(manual_open_with_anchor_cb), - (gchar*)help_url_anchor); - } - else { - gtk_widget_set_sensitive(filtering.help_btn, FALSE); - } - - p_processing_list = p_processing; - - prefs_filtering_set_dialog(header, key); - if (per_account_filtering) { - gtk_widget_show(filtering.account_label); - gtk_widget_show(filtering.account_combobox); - } else { - gtk_widget_hide(filtering.account_label); - gtk_widget_hide(filtering.account_combobox); - combobox_select_by_data(GTK_COMBO_BOX(filtering.account_combobox), 0); - } - - gtk_widget_show(filtering.window); - gtk_window_set_modal(GTK_WINDOW(filtering.window), TRUE); - - start_address_completion(NULL); -} - -static void prefs_filtering_size_allocate_cb(GtkWidget *widget, - GtkAllocation *allocation) -{ - cm_return_if_fail(allocation != NULL); - - gtk_window_get_size(GTK_WINDOW(widget), - &prefs_common.filteringwin_width, &prefs_common.filteringwin_height); -} - -/* prefs_filtering_close() - just to have one common exit point */ -static void prefs_filtering_close(void) -{ - GtkListStore *store; - - end_address_completion(); - - store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW - (filtering.cond_list_view))); - gtk_list_store_clear(store); - gtk_widget_hide(filtering.window); - gtk_window_set_modal(GTK_WINDOW(filtering.window), FALSE); - inc_unlock(); -} - -static void prefs_filtering_account_option_menu_populate(void) -{ - GList *accounts = NULL; - GtkTreeIter iter; - - accounts = account_get_list(); - - cm_return_if_fail(accounts != NULL); - - COMBOBOX_ADD(filtering.account_combobox_list, C_("Filtering Account Menu", "All"), 0); - COMBOBOX_ADD(filtering.account_combobox_list, NULL, 0); - for (; accounts != NULL; accounts = accounts->next) { - PrefsAccount *ac = (PrefsAccount *)accounts->data; - - COMBOBOX_ADD_ESCAPED(filtering.account_combobox_list, ac->account_name, ac->account_id); - } -} - -static GtkWidget *prefs_filtering_account_option_menu(Filtering *filtering) -{ - GtkWidget *optmenu = NULL; - GtkWidget *optmenubox = NULL; - GtkListStore *menu = NULL; - - optmenubox = gtk_event_box_new(); - optmenu = gtkut_sc_combobox_create(optmenubox, FALSE); - menu = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu))); - - filtering->account_combobox = optmenu; - filtering->account_combobox_list = menu; - - prefs_filtering_account_option_menu_populate(); - - return optmenubox; -} - -static void prefs_filtering_create(void) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *help_btn; - GtkWidget *cancel_btn; - GtkWidget *ok_btn; - GtkWidget *confirm_area; - - GtkWidget *vbox1; - GtkWidget *reg_hbox; - GtkWidget *arrow; - GtkWidget *btn_hbox; - - GtkWidget *name_label; - GtkWidget *name_entry; - GtkWidget *account_label; - GtkWidget *account_opt_menu; - GtkWidget *cond_label; - GtkWidget *cond_entry; - GtkWidget *cond_btn; - GtkWidget *action_label; - GtkWidget *action_entry; - GtkWidget *action_btn; - - GtkWidget *reg_btn; - GtkWidget *subst_btn; - GtkWidget *del_btn; - GtkWidget *clear_btn; - - GtkWidget *cond_hbox; - GtkWidget *cond_scrolledwin; - GtkWidget *cond_list_view; - - GtkWidget *btn_vbox; - GtkWidget *top_btn; - GtkWidget *up_btn; - GtkWidget *down_btn; - GtkWidget *page_up_btn; - GtkWidget *page_down_btn; - GtkWidget *bottom_btn; - GtkWidget *table; - static GdkGeometry geometry; - - debug_print("Creating filtering configuration window...\n"); - - window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_filtering"); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); - gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); - gtk_window_set_resizable(GTK_WINDOW (window), TRUE); - gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG); - - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_widget_show (vbox); - gtk_container_add (GTK_CONTAINER (window), vbox); - - gtkut_stock_button_set_create_with_help(&confirm_area, &help_btn, - &cancel_btn, NULL, _("_Cancel"), - &ok_btn, NULL, _("_OK"), - NULL, NULL, NULL); - gtk_widget_show (confirm_area); - gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0); - gtk_widget_grab_default (ok_btn); - - gtk_window_set_title (GTK_WINDOW(window), - _("Filtering/Processing configuration")); - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(prefs_filtering_deleted), NULL); - g_signal_connect(G_OBJECT(window), "size_allocate", - G_CALLBACK(prefs_filtering_size_allocate_cb), NULL); - g_signal_connect(G_OBJECT(window), "key_press_event", - G_CALLBACK(prefs_filtering_key_pressed), NULL); - MANAGE_WINDOW_SIGNALS_CONNECT (window); - g_signal_connect(G_OBJECT(ok_btn), "clicked", - G_CALLBACK(prefs_filtering_ok), NULL); - g_signal_connect(G_OBJECT(cancel_btn), "clicked", - G_CALLBACK(prefs_filtering_cancel), NULL); - - vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING); - gtk_widget_show (vbox1); - gtk_box_pack_start (GTK_BOX (vbox), vbox1, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2); - - table = gtk_grid_new(); - gtk_widget_show(table); - gtk_grid_set_row_spacing(GTK_GRID(table), VSPACING_NARROW_2); - gtk_grid_set_column_spacing(GTK_GRID(table), 4); - gtk_box_pack_start (GTK_BOX (vbox1), table, TRUE, TRUE, 0); - - name_label = gtk_label_new (_("Name")); - gtk_widget_show (name_label); - gtk_label_set_xalign (GTK_LABEL (name_label), 1.0); - gtk_grid_attach(GTK_GRID(table), name_label, 0, 0, 1, 1); - - name_entry = gtk_entry_new (); - gtk_widget_show (name_entry); - gtk_grid_attach(GTK_GRID(table), name_entry, 1, 0, 1, 1); - gtk_widget_set_hexpand(name_entry, TRUE); - gtk_widget_set_halign(name_entry, GTK_ALIGN_FILL); - - account_label = gtk_label_new (_("Account")); - gtk_widget_show (account_label); - gtk_label_set_xalign (GTK_LABEL (account_label), 1.0); - gtk_grid_attach(GTK_GRID(table), account_label, 0, 1, 1, 1); - - account_opt_menu = prefs_filtering_account_option_menu(&filtering); - gtk_widget_show (account_opt_menu); - gtk_grid_attach(GTK_GRID(table), account_opt_menu, 1, 1, 1, 1); - combobox_select_by_data(GTK_COMBO_BOX(filtering.account_combobox), 0); - - cond_label = gtk_label_new (_("Condition")); - gtk_widget_show (cond_label); - gtk_label_set_xalign (GTK_LABEL (cond_label), 1.0); - gtk_grid_attach(GTK_GRID(table), cond_label, 0, 2, 1, 1); - - cond_entry = gtk_entry_new (); - gtk_widget_show (cond_entry); - gtk_grid_attach(GTK_GRID(table), cond_entry, 1, 2, 1, 1); - gtk_widget_set_hexpand(cond_entry, TRUE); - gtk_widget_set_halign(cond_entry, GTK_ALIGN_FILL); - - cond_btn = gtk_button_new_with_mnemonic (_(" Def_ine... ")); - gtk_widget_show (cond_btn); - gtk_grid_attach(GTK_GRID(table), cond_btn, 2, 2, 1, 1); - g_signal_connect(G_OBJECT (cond_btn), "clicked", - G_CALLBACK(prefs_filtering_condition_define), - NULL); - - action_label = gtk_label_new (_("Action")); - gtk_widget_show (action_label); - gtk_label_set_xalign (GTK_LABEL (action_label), 1.0); - gtk_grid_attach(GTK_GRID(table), action_label, 0, 3, 1, 1); - - action_entry = gtk_entry_new (); - gtk_widget_show (action_entry); - gtk_grid_attach(GTK_GRID(table), action_entry, 1, 3, 1, 1); - gtk_widget_set_hexpand(action_entry, TRUE); - gtk_widget_set_halign(action_entry, GTK_ALIGN_FILL); - - action_btn = gtk_button_new_with_mnemonic (_(" De_fine... ")); - gtk_widget_show (action_btn); - gtk_grid_attach(GTK_GRID(table), action_btn, 2, 3, 1, 1); - g_signal_connect(G_OBJECT (action_btn), "clicked", - G_CALLBACK(prefs_filtering_action_define), - NULL); - - /* register / substitute / delete */ - reg_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); - gtk_widget_show (reg_hbox); - gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0); - - arrow = gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU); - gtk_widget_show (arrow); - gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0); - gtk_widget_set_size_request (arrow, -1, 16); - - btn_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); - gtk_widget_show (btn_hbox); - gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0); - - reg_btn = gtkut_stock_button("list-add", _("_Add")); - gtk_widget_show (reg_btn); - gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0); - g_signal_connect(G_OBJECT (reg_btn), "clicked", - G_CALLBACK(prefs_filtering_register_cb), NULL); - CLAWS_SET_TIP(reg_btn, - _("Append the new rule above to the list")); - - subst_btn = gtkut_stock_button("edit-redo", _("_Replace")); - gtk_widget_show (subst_btn); - gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0); - g_signal_connect(G_OBJECT (subst_btn), "clicked", - G_CALLBACK(prefs_filtering_substitute_cb), - NULL); - CLAWS_SET_TIP(subst_btn, - _("Replace the selected rule in list with the rule above")); - - del_btn = gtkut_stock_button("edit-delete", _("D_elete")); - gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0); - g_signal_connect(G_OBJECT (del_btn), "clicked", - G_CALLBACK(prefs_filtering_delete_cb), NULL); - CLAWS_SET_TIP(del_btn, - _("Delete the selected rule from the list")); - - clear_btn = gtkut_stock_button("edit-clear", _("C_lear")); - gtk_widget_show (clear_btn); - gtk_box_pack_start (GTK_BOX (btn_hbox), clear_btn, FALSE, TRUE, 0); - g_signal_connect(G_OBJECT (clear_btn), "clicked", - G_CALLBACK(prefs_filtering_clear_cb), NULL); - CLAWS_SET_TIP(clear_btn, - _("Clear all the input fields in the dialog")); - - cond_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); - gtk_widget_show (cond_hbox); - gtk_box_pack_start (GTK_BOX (vbox), cond_hbox, TRUE, TRUE, 0); - - cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (cond_scrolledwin); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(cond_scrolledwin), - GTK_SHADOW_ETCHED_IN); - gtk_widget_set_size_request (cond_scrolledwin, -1, 150); - gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin, - TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - cond_list_view = prefs_filtering_list_view_create(); - gtk_widget_show (cond_list_view); - gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_list_view); - - btn_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); - gtk_widget_show (btn_vbox); - gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0); - - top_btn = gtkut_stock_button("go-top", _("_Top")); - gtk_widget_show (top_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), top_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (top_btn), "clicked", - G_CALLBACK(prefs_filtering_top), NULL); - CLAWS_SET_TIP(top_btn, - _("Move the selected rule to the top")); - - page_up_btn = gtk_button_new_with_mnemonic (_("Page u_p")); - gtk_button_set_image(GTK_BUTTON(page_up_btn), - gtk_image_new_from_icon_name("go-up-symbolic",GTK_ICON_SIZE_BUTTON)); - gtk_widget_show (page_up_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), page_up_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (page_up_btn), "clicked", - G_CALLBACK(prefs_filtering_page_up), NULL); - CLAWS_SET_TIP(page_up_btn, - _("Move the selected rule one page up")); - - up_btn = gtkut_stock_button("go-up", _("_Up")); - gtk_widget_show (up_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (up_btn), "clicked", - G_CALLBACK(prefs_filtering_up), NULL); - CLAWS_SET_TIP(up_btn, - _("Move the selected rule up")); - - down_btn = gtkut_stock_button("go-down", _("_Down")); - gtk_widget_show (down_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (down_btn), "clicked", - G_CALLBACK(prefs_filtering_down), NULL); - CLAWS_SET_TIP(down_btn, - _("Move the selected rule down")); - - page_down_btn = gtk_button_new_with_mnemonic (_("Page dow_n")); - gtk_button_set_image(GTK_BUTTON(page_down_btn), - gtk_image_new_from_icon_name("go-down-symbolic",GTK_ICON_SIZE_BUTTON)); - gtk_widget_show (page_down_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), page_down_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (page_down_btn), "clicked", - G_CALLBACK(prefs_filtering_page_down), NULL); - CLAWS_SET_TIP(page_down_btn, - _("Move the selected rule one page down")); - - bottom_btn = gtkut_stock_button("go-bottom", _("_Bottom")); - gtk_widget_show (bottom_btn); - gtk_box_pack_start (GTK_BOX (btn_vbox), bottom_btn, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT (bottom_btn), "clicked", - G_CALLBACK(prefs_filtering_bottom), NULL); - CLAWS_SET_TIP(bottom_btn, - _("Move the selected rule to the bottom")); - - if (!geometry.min_height) { - geometry.min_width = 500; - geometry.min_height = 460; - } - - gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry, - GDK_HINT_MIN_SIZE); - gtk_window_set_default_size(GTK_WINDOW(window), prefs_common.filteringwin_width, - prefs_common.filteringwin_height); - - gtk_widget_show_all(window); - - filtering.window = window; - filtering.help_btn = help_btn; - filtering.ok_btn = ok_btn; - - filtering.name_entry = name_entry; - filtering.cond_entry = cond_entry; - filtering.action_entry = action_entry; - filtering.cond_list_view = cond_list_view; - filtering.account_label = account_label; -} - -static void rename_tag(GSList * filters, - const gchar * old_tag, const gchar * new_tag); - -void prefs_filtering_rename_tag(const gchar *old_tag, const gchar *new_tag) -{ - GList * cur; - const gchar *tags[2] = {NULL, NULL}; - tags[0] = old_tag; - tags[1] = new_tag; - for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) { - Folder *folder; - folder = (Folder *) cur->data; - g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - prefs_filtering_rename_tag_func, tags); - } - - rename_tag(pre_global_processing, old_tag, new_tag); - rename_tag(post_global_processing, old_tag, new_tag); - rename_tag(filtering_rules, old_tag, new_tag); - - prefs_matcher_write_config(); -} - - -static void rename_path(GSList * filters, - const gchar * old_path, const gchar * new_path); - -void prefs_filtering_rename_path(const gchar *old_path, const gchar *new_path) -{ - GList * cur; - const gchar *paths[2] = {NULL, NULL}; - paths[0] = old_path; - paths[1] = new_path; - for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) { - Folder *folder; - folder = (Folder *) cur->data; - g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - prefs_filtering_rename_path_func, paths); - } - - rename_path(pre_global_processing, old_path, new_path); - rename_path(post_global_processing, old_path, new_path); - rename_path(filtering_rules, old_path, new_path); - - prefs_matcher_write_config(); -} - -static void rename_path(GSList * filters, - const gchar * old_path, const gchar * new_path) -{ - GSList * cur; - - for (cur = filters; cur != NULL; cur = cur->next) { - FilteringProp *filtering = (FilteringProp *)cur->data; - filtering_action_list_rename_path(filtering->action_list, - old_path, new_path); - } -} - -static gboolean prefs_filtering_rename_path_func(GNode *node, gpointer data) -{ - GSList *filters; - const gchar * old_path; - const gchar * new_path; - const gchar ** paths; - FolderItem *item; - - paths = data; - old_path = paths[0]; - new_path = paths[1]; - - cm_return_val_if_fail(old_path != NULL, FALSE); - cm_return_val_if_fail(new_path != NULL, FALSE); - cm_return_val_if_fail(node != NULL, FALSE); - - item = node->data; - if (!item || !item->prefs) - return FALSE; - filters = item->prefs->processing; - - rename_path(filters, old_path, new_path); - - return FALSE; -} - -static void rename_tag(GSList * filters, - const gchar * old_tag, const gchar * new_tag) -{ - GSList * action_cur; - GSList * cur; - - for (cur = filters; cur != NULL; cur = cur->next) { - FilteringProp *filtering = (FilteringProp *)cur->data; - - for(action_cur = filtering->action_list ; action_cur != NULL ; - action_cur = action_cur->next) { - - FilteringAction *action = action_cur->data; - - if (action->type != MATCHACTION_SET_TAG && - action->type != MATCHACTION_UNSET_TAG) - continue; - if (!action->destination) - continue; - if (!strcmp(action->destination, old_tag)) { - g_free(action->destination); - action->destination = g_strdup(new_tag); - } - } - } -} - -static gboolean prefs_filtering_rename_tag_func(GNode *node, gpointer data) -{ - GSList *filters; - const gchar * old_tag; - const gchar * new_tag; - const gchar ** tags; - FolderItem *item; - - tags = data; - old_tag = tags[0]; - new_tag = tags[1]; - - cm_return_val_if_fail(old_tag != NULL, FALSE); - cm_return_val_if_fail(new_tag != NULL, FALSE); - cm_return_val_if_fail(node != NULL, FALSE); - - item = node->data; - if (!item || !item->prefs) - return FALSE; - filters = item->prefs->processing; - - rename_tag(filters, old_tag, new_tag); - - return FALSE; -} - -void prefs_filtering_delete_path(const gchar *path) -{ - GList * cur; - for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) { - Folder *folder; - folder = (Folder *) cur->data; - g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - prefs_filtering_delete_path_func, (gchar *)path); - } - delete_path(&pre_global_processing, path); - delete_path(&post_global_processing, path); - delete_path(&filtering_rules, path); - - prefs_matcher_write_config(); -} - -static void delete_path(GSList ** p_filters, const gchar * path) -{ - GSList * filters; - GSList * duplist; - gchar *suffix; - gint destlen; - gint prefixlen; - gint pathlen; - GSList * action_cur; - GSList * cur; - - filters = *p_filters; - pathlen = strlen(path); - duplist = g_slist_copy(filters); - for (cur = duplist ; cur != NULL; cur = g_slist_next(cur)) { - FilteringProp *filtering = (FilteringProp *) cur->data; - - for(action_cur = filtering->action_list ; action_cur != NULL ; - action_cur = action_cur->next) { - - FilteringAction *action; - - action = action_cur->data; - - if (action->type == MATCHACTION_SET_TAG || - action->type == MATCHACTION_UNSET_TAG) - continue; - if (!action->destination) - continue; - - destlen = strlen(action->destination); - - if (destlen > pathlen) { - prefixlen = destlen - pathlen; - suffix = action->destination + prefixlen; - - if ((suffix && !strncmp(path, suffix, pathlen)) && filtering) { - filters = g_slist_remove(filters, filtering); - filteringprop_free(filtering); - filtering = NULL; - } - } else if ((strcmp(action->destination, path) == 0) && filtering) { - filters = g_slist_remove(filters, filtering); - filteringprop_free(filtering); - filtering = NULL; - } - } - } - g_slist_free(duplist); - - * p_filters = filters; -} - -static gboolean prefs_filtering_delete_path_func(GNode *node, gpointer data) -{ - const gchar *path = data; - FolderItem *item; - GSList ** p_filters; - - cm_return_val_if_fail(path != NULL, FALSE); - cm_return_val_if_fail(node != NULL, FALSE); - - item = node->data; - if (!item || !item->prefs) - return FALSE; - p_filters = &item->prefs->processing; - - delete_path(p_filters, path); - - return FALSE; -} - -static void prefs_filtering_clear_list(GtkListStore *list_store) -{ - gtk_list_store_clear(list_store); - - /* add the place holder (New) at row 0 */ - prefs_filtering_list_view_insert_rule(list_store, -1, - FALSE, - _("(New)"), - 0, - _("(New)"), - _("(New)"), - FALSE); -} - -static void prefs_filtering_set_dialog(const gchar *header, const gchar *key) -{ - GtkTreeView *list_view = GTK_TREE_VIEW(filtering.cond_list_view); - GSList *cur; - GSList * prefs_filtering; - gchar *cond_str; - GtkListStore *list_store; - - list_store = GTK_LIST_STORE(gtk_tree_view_get_model(list_view)); - prefs_filtering_clear_list(list_store); - - prefs_filtering = *p_processing_list; - - for(cur = prefs_filtering ; cur != NULL ; cur = g_slist_next(cur)) { - FilteringProp * prop = (FilteringProp *) cur->data; - gchar *account_name = NULL; - - if (prop->account_id > 0) { - PrefsAccount *ac_prefs = account_find_from_id(prop->account_id); - - if (ac_prefs) - account_name = ac_prefs->account_name; - } - if (account_name == NULL) - account_name = (gchar *)C_("Filtering Account Menu", "All"); - - cond_str = filteringprop_to_string(prop); - subst_char(cond_str, '\t', ':'); - - prefs_filtering_list_view_insert_rule(list_store, -1, - prop->enabled, - prop->name, - prop->account_id, - account_name, - cond_str, TRUE); - - g_free(cond_str); - } - - prefs_filtering_reset_dialog(); - - if (header && key) { - gchar * quoted_key; - gchar *match_str; - - quoted_key = matcher_quote_str(key); - - match_str = g_strconcat(header, " ", get_matchparser_tab_str(MATCHTYPE_MATCHCASE), - " \"", quoted_key, "\"", NULL); - g_free(quoted_key); - - gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), match_str); - g_free(match_str); - } -} - -static void prefs_filtering_reset_dialog(void) -{ - gtk_entry_set_text(GTK_ENTRY(filtering.name_entry), ""); - combobox_select_by_data(GTK_COMBO_BOX(filtering.account_combobox), 0); - gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), ""); - gtk_entry_set_text(GTK_ENTRY(filtering.action_entry), ""); -} - -static gboolean prefs_filtering_search_func_cb (GtkTreeModel *model, gint column, const gchar *key, - GtkTreeIter *iter, gpointer search_data) -{ - gchar *store_string; - gboolean retval; - GtkTreePath *path; - - gtk_tree_model_get (model, iter, column, &store_string, -1); - - if (!store_string || !key) return FALSE; - - - retval = (g_ascii_strncasecmp (key, store_string, strlen(key)) != 0); - - g_free(store_string); - debug_print("selecting row\n"); - path = gtk_tree_model_get_path(model, iter); - prefs_filtering_select_row(GTK_TREE_VIEW(filtering.cond_list_view), path); - gtk_tree_path_free(path); - - return retval; -} - -static void prefs_filtering_set_list(void) -{ - gint row = 1; - FilteringProp *prop; - GSList * cur; - gchar * filtering_str; - GSList * prefs_filtering; - - prefs_filtering = *p_processing_list; - for (cur = prefs_filtering ; cur != NULL ; cur = g_slist_next(cur)) - filteringprop_free((FilteringProp *) cur->data); - g_slist_free(prefs_filtering); - prefs_filtering = NULL; - - - while (NULL != (filtering_str = prefs_filtering_list_view_get_rule - (filtering.cond_list_view, row))) { - /* FIXME: this strcmp() is bogus: "(New)" should never - * be inserted in the storage */ - if (strcmp(filtering_str, _("(New)")) != 0) { - gboolean enabled; - gchar *name; - gint account_id = 0; - - prefs_filtering_list_view_get_rule_info( - filtering.cond_list_view, row, - &enabled, &name, &account_id); - prop = matcher_parser_get_filtering(filtering_str); - if (prop) { - prop->enabled = enabled; - if (prop->name != NULL) - g_free(prop->name); - prop->name = name; - prop->account_id = account_id; - prefs_filtering = - g_slist_append(prefs_filtering, prop); - } - } - - g_free(filtering_str); - row++; - } - - *p_processing_list = prefs_filtering; -} - -static gint prefs_filtering_list_view_set_row(gint row, FilteringProp * prop) -{ - GtkTreeView *list_view = GTK_TREE_VIEW(filtering.cond_list_view); - gchar *str = NULL; - GtkListStore *list_store; - gchar *name = NULL; - gint account_id = 0; - gchar *account_name = (gchar *)C_("Filtering Account Menu", "All"); - gboolean enabled = TRUE; - - if (prop) - str = filteringprop_to_string(prop); - if (str == NULL) - return -1; - - if (prop) { - if (prop->name) - name = prop->name; - account_id = prop->account_id; - if (account_id > 0) - account_name = account_find_from_id(account_id)->account_name; - enabled = prop->enabled; - } - - list_store = GTK_LIST_STORE(gtk_tree_view_get_model(list_view)); - - row = prefs_filtering_list_view_insert_rule(list_store, row, - enabled, - name, - account_id, - account_name, - str, - prop != NULL); - - g_free(str); - - return row; -} - -static void prefs_filtering_condition_define_done(MatcherList * matchers) -{ - gchar * str; - - if (matchers == NULL) - return; - - str = matcherlist_to_string(matchers); - - if (str != NULL) { - gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), str); - g_free(str); - } -} - -static void prefs_filtering_condition_define(gpointer action, gpointer data) -{ - gchar * cond_str; - MatcherList * matchers = NULL; - - cond_str = gtk_editable_get_chars(GTK_EDITABLE(filtering.cond_entry), 0, -1); - - if (*cond_str != '\0') { - matchers = matcher_parser_get_cond(cond_str, NULL); - if (matchers == NULL) - alertpanel_error(_("Condition string is not valid.")); - } - - g_free(cond_str); - - prefs_matcher_open(matchers, prefs_filtering_condition_define_done); - - if (matchers != NULL) - matcherlist_free(matchers); -} - -static void prefs_filtering_action_define_done(GSList * action_list) -{ - gchar * str; - - if (action_list == NULL) - return; - - str = filteringaction_list_to_string(action_list); - - if (str != NULL) { - gtk_entry_set_text(GTK_ENTRY(filtering.action_entry), str); - g_free(str); - } -} - -static void prefs_filtering_action_define(gpointer action, gpointer data) -{ - gchar * action_str; - GSList * action_list = NULL; - - action_str = gtk_editable_get_chars(GTK_EDITABLE(filtering.action_entry), 0, -1); - - if (*action_str != '\0') { - action_list = matcher_parser_get_action_list(action_str); - if (action_list == NULL) - alertpanel_error(_("Action string is not valid.")); - } - - g_free(action_str); - - prefs_filtering_action_open(action_list, - prefs_filtering_action_define_done); - - if (action_list != NULL) { - GSList * cur; - for(cur = action_list ; cur != NULL ; cur = cur->next) { - filteringaction_free(cur->data); - } - } -} - - -/* register / substitute delete buttons */ - - -static FilteringProp * prefs_filtering_dialog_to_filtering(gboolean alert) -{ - MatcherList * cond; - gboolean enabled = TRUE; - gchar * name = NULL; - gint account_id = 0; - gchar * cond_str = NULL; - gchar * action_str = NULL; - FilteringProp * prop = NULL; - GSList * action_list; - - name = gtk_editable_get_chars(GTK_EDITABLE(filtering.name_entry), 0, -1); - - account_id = combobox_get_active_data(GTK_COMBO_BOX(filtering.account_combobox)); - - cond_str = gtk_editable_get_chars(GTK_EDITABLE(filtering.cond_entry), 0, -1); - if (*cond_str == '\0') { - if(alert == TRUE) alertpanel_error(_("Condition string is empty.")); - goto fail; - } - - action_str = gtk_editable_get_chars(GTK_EDITABLE(filtering.action_entry), 0, -1); - if (*action_str == '\0') { - if(alert == TRUE) alertpanel_error(_("Action string is empty.")); - goto fail; - } - - cond = matcher_parser_get_cond(cond_str, NULL); - - if (cond == NULL) { - if(alert == TRUE) alertpanel_error(_("Condition string is not valid.")); - goto fail; - } - - action_list = matcher_parser_get_action_list(action_str); - - - if (action_list == NULL) { - if(alert == TRUE) alertpanel_error(_("Action string is not valid.")); - goto fail; - } - - prop = filteringprop_new(enabled, name, account_id, cond, action_list); - -fail: - g_free(name); - g_free(cond_str); - g_free(action_str); - return prop; -} - -static void prefs_filtering_register_cb(gpointer action, gpointer data) -{ - FilteringProp *prop; - - prop = prefs_filtering_dialog_to_filtering(TRUE); - if (prop == NULL) - return; - prefs_filtering_list_view_set_row(-1, prop); - - filteringprop_free(prop); - - prefs_filtering_reset_dialog(); - modified = TRUE; -} - -static void prefs_filtering_substitute_cb(gpointer action, gpointer data) -{ - gint selected_row = gtkut_list_view_get_selected_row - (filtering.cond_list_view); - FilteringProp *prop; - gboolean enabled; - gchar *name; - gint account_id; - - if (selected_row <= 0) - return; - - prop = prefs_filtering_dialog_to_filtering(TRUE); - - if (prop == NULL) - return; - - /* prop->emabled is always TRUE here, re-use the value from the selected row - as we don't substitute this value from dialog */ - prefs_filtering_list_view_get_rule_info( - filtering.cond_list_view, selected_row, - &enabled, &name, &account_id); - g_free(name); /* We're not using this. */ - prop->enabled = enabled; - - prefs_filtering_list_view_set_row(selected_row, prop); - - filteringprop_free(prop); - - prefs_filtering_row_selected(gtk_tree_view_get_selection( - GTK_TREE_VIEW(filtering.cond_list_view)), - GTK_TREE_VIEW(filtering.cond_list_view)); - modified = TRUE; -} - -static void prefs_filtering_delete_cb(gpointer action, gpointer data) -{ - GtkTreeView *list_view = GTK_TREE_VIEW(filtering.cond_list_view); - GtkTreeModel *model; - GtkTreeIter iter; - gint selected_row; - - selected_row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (selected_row <= 0) - return; - - if (alertpanel(_("Delete rule"), - _("Do you really want to delete this rule?"), - NULL, _("_Cancel"), "edit-delete", _("D_elete"), NULL, NULL, - ALERTFOCUS_SECOND) == G_ALERTDEFAULT) - return; - - model = gtk_tree_view_get_model(list_view); - if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, selected_row)) - return; - - gtk_list_store_remove(GTK_LIST_STORE(model), &iter); - - prefs_filtering_reset_dialog(); - modified = TRUE; -} - -static void prefs_filtering_delete_all_cb(gpointer action, gpointer data) -{ - GtkListStore *list_store; - - if (alertpanel(_("Delete all rules"), - _("Do you really want to delete all the rules?"), - NULL, _("_Cancel"), "edit-delete", _("D_elete"), NULL, NULL, - ALERTFOCUS_SECOND) == G_ALERTDEFAULT) - return; - - list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view))); - prefs_filtering_clear_list(list_store); - - prefs_filtering_reset_dialog(); - modified = TRUE; -} - -static void prefs_filtering_clear_cb(gpointer action, gpointer data) -{ - prefs_filtering_reset_dialog(); -} - -static void prefs_filtering_duplicate_cb(gpointer action, gpointer data) -{ - gint selected_row = gtkut_list_view_get_selected_row - (filtering.cond_list_view); - FilteringProp *prop; - gboolean enabled; - gchar *name; - gint account_id; - - if (selected_row <= 0) - return; - - prop = prefs_filtering_dialog_to_filtering(TRUE); - if (prop == NULL) - return; - - /* prop->emabled is always TRUE here, re-use the value from the selected row - as we don't substitute this value from dialog */ - prefs_filtering_list_view_get_rule_info( - filtering.cond_list_view, selected_row, - &enabled, &name, &account_id); - g_free(name); /* We're not using this. */ - prop->enabled = enabled; - - prefs_filtering_list_view_set_row(-selected_row-2, prop); - - filteringprop_free(prop); - - prefs_filtering_reset_dialog(); - modified = TRUE; -} - -static void prefs_filtering_top(gpointer action, gpointer data) -{ - gint row; - GtkTreeIter top, sel; - GtkTreeModel *model; - - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row <= 1) - return; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - - if (!gtk_tree_model_iter_nth_child(model, &top, NULL, 0) - || !gtk_tree_model_iter_nth_child(model, &sel, NULL, row)) - return; - - gtk_list_store_move_after(GTK_LIST_STORE(model), &sel, &top); - gtkut_list_view_select_row(filtering.cond_list_view, 1); - modified = TRUE; -} - -static void prefs_filtering_page_up(gpointer action, gpointer data) -{ - gint row, target_row; - GtkTreeIter selected, target; - GtkTreeModel *model; - GtkTreePath *path; - GdkRectangle cell_rect, view_rect; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row <= 1) - return; - - if (!gtk_tree_model_iter_nth_child(model, &selected, NULL, row)) - return; - - /* compute number of rows per page (approximation) */ - path = gtk_tree_model_get_path(model, &selected); - gtk_tree_view_get_cell_area(GTK_TREE_VIEW(filtering.cond_list_view), path, NULL, &cell_rect); - gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(filtering.cond_list_view), &view_rect); - gtk_tree_path_free(path); - target_row = row - (view_rect.height/cell_rect.height); - if (target_row < 1) - target_row = 1; - - if (!gtk_tree_model_iter_nth_child(model, &target, NULL, target_row)) - return; - gtk_list_store_move_before(GTK_LIST_STORE(model), &selected, &target); - gtkut_list_view_select_row(filtering.cond_list_view, target_row); - modified = TRUE; -} -static void prefs_filtering_up(gpointer action, gpointer data) -{ - gint row; - GtkTreeIter top, sel; - GtkTreeModel *model; - - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row <= 1) - return; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - - if (!gtk_tree_model_iter_nth_child(model, &top, NULL, row - 1) - || !gtk_tree_model_iter_nth_child(model, &sel, NULL, row)) - return; - - gtk_list_store_swap(GTK_LIST_STORE(model), &top, &sel); - gtkut_list_view_select_row(filtering.cond_list_view, row - 1); - modified = TRUE; -} - -static void prefs_filtering_down(gpointer action, gpointer data) -{ - gint row, n_rows; - GtkTreeIter top, sel; - GtkTreeModel *model; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - n_rows = gtk_tree_model_iter_n_children(model, NULL); - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row < 1 || row >= n_rows - 1) - return; - - if (!gtk_tree_model_iter_nth_child(model, &top, NULL, row) - || !gtk_tree_model_iter_nth_child(model, &sel, NULL, row + 1)) - return; - - gtk_list_store_swap(GTK_LIST_STORE(model), &top, &sel); - gtkut_list_view_select_row(filtering.cond_list_view, row + 1); - modified = TRUE; -} - -static void prefs_filtering_page_down(gpointer action, gpointer data) -{ - gint row, target_row, n_rows; - GtkTreeIter selected, target; - GtkTreeModel *model; - GtkTreePath *path; - GdkRectangle cell_rect, view_rect; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - n_rows = gtk_tree_model_iter_n_children(model, NULL); - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row < 1 || row >= n_rows -1) - return; - - if (!gtk_tree_model_iter_nth_child(model, &selected, NULL, row)) - return; - - /* compute number of rows per page (approximation) */ - path = gtk_tree_model_get_path(model, &selected); - gtk_tree_view_get_cell_area(GTK_TREE_VIEW(filtering.cond_list_view), path, NULL, &cell_rect); - gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(filtering.cond_list_view), &view_rect); - gtk_tree_path_free(path); - target_row = row + (view_rect.height/cell_rect.height); - if (target_row > n_rows-1) - target_row = n_rows-1; - - if (!gtk_tree_model_iter_nth_child(model, &target, NULL, target_row)) - return; - gtk_list_store_move_after(GTK_LIST_STORE(model), &selected, &target); - gtkut_list_view_select_row(filtering.cond_list_view, target_row); - modified = TRUE; -} - -static void prefs_filtering_bottom(gpointer action, gpointer data) -{ - gint row, n_rows; - GtkTreeIter top, sel; - GtkTreeModel *model; - - model = gtk_tree_view_get_model(GTK_TREE_VIEW(filtering.cond_list_view)); - n_rows = gtk_tree_model_iter_n_children(model, NULL); - row = gtkut_list_view_get_selected_row(filtering.cond_list_view); - if (row < 1 || row >= n_rows - 1) - return; - - if (!gtk_tree_model_iter_nth_child(model, &top, NULL, row) - || !gtk_tree_model_iter_nth_child(model, &sel, NULL, n_rows - 1)) - return; - - gtk_list_store_move_after(GTK_LIST_STORE(model), &top, &sel); - gtkut_list_view_select_row(filtering.cond_list_view, n_rows - 1); - modified = TRUE; -} - -static void prefs_filtering_select_set(FilteringProp *prop) -{ - gchar *matcher_str; - gchar *action_str; - - prefs_filtering_reset_dialog(); - - matcher_str = matcherlist_to_string(prop->matchers); - if (matcher_str == NULL) { - return; - } - - if (prop->name != NULL) - gtk_entry_set_text(GTK_ENTRY(filtering.name_entry), prop->name); - - combobox_select_by_data(GTK_COMBO_BOX(filtering.account_combobox), prop->account_id); - - gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), matcher_str); - - action_str = filteringaction_list_to_string(prop->action_list); - if (action_str != NULL) - gtk_entry_set_text(GTK_ENTRY(filtering.action_entry), action_str); - - g_free(action_str); - g_free(matcher_str); -} - -static gint prefs_filtering_deleted(GtkWidget *widget, GdkEventAny *event, - gpointer data) -{ - prefs_filtering_cancel(NULL, NULL); - return TRUE; -} - -static gboolean prefs_filtering_key_pressed(GtkWidget *widget, GdkEventKey *event, - gpointer data) -{ - if (event && event->keyval == GDK_KEY_Escape) { - prefs_filtering_cancel(NULL, NULL); - return TRUE; - } - return FALSE; -} - -static gboolean prefs_filtering_check_mod(gboolean check_changed_list) -{ - FilteringProp * prop; - gchar * str; - gchar * filtering_str; - gint row = 1; - AlertValue val; - - prop = prefs_filtering_dialog_to_filtering(FALSE); - - if (check_changed_list) { - if (modified && alertpanel(_("Filtering rules not saved"), - _("The list of filtering rules have been modified. Close anyway?"), - "window-close", _("_Close"), NULL, _("_Continue editing"), - NULL, NULL, ALERTFOCUS_SECOND) != G_ALERTDEFAULT) { - if (prop != NULL) - filteringprop_free(prop); - return TRUE; - } - } - - /* check if a rule is being edited */ - if (prop != NULL) { - str = filteringprop_to_string(prop); - - while (NULL != (filtering_str = (prefs_filtering_list_view_get_rule - (filtering.cond_list_view, - row)))) { - if (strcmp(filtering_str, str) == 0) - break; - row++; - g_free(filtering_str); - } - - if (!filtering_str) { - val = alertpanel(_("Entry not saved"), - _("The entry was not saved. Close anyway?"), - "window-close", _("_Close"), NULL, _("_Continue editing"), - NULL, NULL, ALERTFOCUS_SECOND); - if (G_ALERTDEFAULT != val) { - g_free(filtering_str); - g_free(str); /* fixed two leaks: huzzah! */ - filteringprop_free(prop); - return TRUE; - } - } - - g_free(filtering_str); - g_free(str); - filteringprop_free(prop); /* fixed a leak: huzzah! */ - } else { - gchar *name, *condition, *action; - name = gtk_editable_get_chars(GTK_EDITABLE(filtering.name_entry), 0, -1); - condition = gtk_editable_get_chars(GTK_EDITABLE(filtering.cond_entry), 0, -1); - action = gtk_editable_get_chars(GTK_EDITABLE(filtering.action_entry), 0, -1); - if (strlen(name) || - strlen(condition) || - strlen(action)) { - val = alertpanel(_("Entry not saved"), - _("The entry was not saved. Close anyway?"), - "window-close", _("_Close"), NULL, _("_Continue editing"), - NULL, NULL, ALERTFOCUS_SECOND); - if (G_ALERTDEFAULT != val) { - g_free(name); - g_free(condition); - g_free(action); - return TRUE; - } - } - g_free(name); - g_free(condition); - g_free(action); - } - return FALSE; -} - -static void prefs_filtering_ok(gpointer action, gpointer data) -{ - if (prefs_filtering_check_mod(FALSE)) - return; - modified = FALSE; - prefs_filtering_set_list(); - prefs_matcher_write_config(); - prefs_filtering_close(); -} - -static void prefs_filtering_cancel(gpointer action, gpointer data) -{ - if (prefs_filtering_check_mod(TRUE)) - return; - modified = FALSE; - prefs_matcher_read_config(); - prefs_filtering_close(); -} - -static GtkListStore* prefs_filtering_create_data_store(void) -{ - return gtk_list_store_new(N_PREFS_FILTERING_COLUMNS, - G_TYPE_BOOLEAN, - G_TYPE_STRING, - G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_BOOLEAN, - -1); -} - -/*! - *\brief Insert filtering rule into store. Note that we access the - * tree view / store by index, which is a bit suboptimal, but - * at least it made GTK 2 porting easier. - * - *\param list_store Store to operate on - *\param row -1 to add a new rule to store, - row >=0 to change an existing row - row <-1 insert a new row after (-row-2) - *\param enabled TRUE if rule is enabled - *\param name The Name of rule - *\param account_id The account ID - *\param account_name The account name or All or (New) - *\param rule String representation of rule - *\param prop TRUE if valid filtering rule; if FALSE it's the first - * entry in the store ("(New)"). - * - *\return int Row of inserted / changed rule. - */ -static gint prefs_filtering_list_view_insert_rule(GtkListStore *list_store, - gint row, - gboolean enabled, - const gchar *name, - gint account_id, - const gchar *account_name, - const gchar *rule, - gboolean prop) -{ - GtkTreeIter iter; - GtkTreeIter sibling; - - /* check if valid row at all */ - if (row >= 0) { - if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), - &iter, NULL, row)) - row = -1; - } else if (row < -1) { - if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), - &sibling, NULL, -row-2)) - row = -1; - } - - if (row == -1 ) { - /* append new */ - gtk_list_store_append(list_store, &iter); - gtk_list_store_set(list_store, &iter, - PREFS_FILTERING_ENABLED, enabled, - PREFS_FILTERING_NAME, name, - PREFS_FILTERING_ACCOUNT_ID, account_id, - PREFS_FILTERING_ACCOUNT_NAME, account_name, - PREFS_FILTERING_RULE, rule, - PREFS_FILTERING_PROP, prop, - -1); - return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), - NULL) - 1; - } else if (row < -1) { - /* duplicate */ - gtk_list_store_insert_after(list_store, &iter, &sibling); - gtk_list_store_set(list_store, &iter, - PREFS_FILTERING_ENABLED, enabled, - PREFS_FILTERING_NAME, name, - PREFS_FILTERING_ACCOUNT_ID, account_id, - PREFS_FILTERING_ACCOUNT_NAME, account_name, - PREFS_FILTERING_RULE, rule, - PREFS_FILTERING_PROP, prop, - -1); - return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), - NULL) - 1; - } else { - /* change existing */ - gtk_list_store_set(list_store, &iter, - PREFS_FILTERING_ENABLED, enabled, - PREFS_FILTERING_NAME, name, - PREFS_FILTERING_ACCOUNT_ID, account_id, - PREFS_FILTERING_ACCOUNT_NAME, account_name, - PREFS_FILTERING_RULE, rule, - -1); - return row; - } -} - -/*! - *\return gchar * Rule at specified row - should be freed. - */ -static gchar *prefs_filtering_list_view_get_rule(GtkWidget *list, gint row) -{ - GtkTreeView *list_view = GTK_TREE_VIEW(list); - GtkTreeModel *model = gtk_tree_view_get_model(list_view); - GtkTreeIter iter; - gchar *result; - - if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) - return NULL; - - gtk_tree_model_get(model, &iter, - PREFS_FILTERING_RULE, &result, - -1); - - return result; -} - -static void prefs_filtering_list_view_get_rule_info(GtkWidget *list, gint row, - gboolean *enabled, gchar **name, gint *account_id) -{ - GtkTreeView *list_view = GTK_TREE_VIEW(list); - GtkTreeModel *model = gtk_tree_view_get_model(list_view); - GtkTreeIter iter; - - *enabled = TRUE; - *name = NULL; - - if (gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) { - gtk_tree_model_get(model, &iter, - PREFS_FILTERING_ENABLED, enabled, - PREFS_FILTERING_NAME, name, - PREFS_FILTERING_ACCOUNT_ID, account_id, - -1); - } -} - -static GtkActionGroup *prefs_filtering_popup_action = NULL; -static GtkWidget *prefs_filtering_popup_menu = NULL; - -static GtkActionEntry prefs_filtering_popup_entries[] = -{ - {"PrefsFilteringPopup", NULL, "PrefsFilteringPopup", NULL, NULL, NULL }, - {"PrefsFilteringPopup/Delete", NULL, N_("_Delete"), NULL, NULL, G_CALLBACK(prefs_filtering_delete_cb) }, - {"PrefsFilteringPopup/DeleteAll", NULL, N_("Delete _all"), NULL, NULL, G_CALLBACK(prefs_filtering_delete_all_cb) }, - {"PrefsFilteringPopup/Duplicate", NULL, N_("D_uplicate"), NULL, NULL, G_CALLBACK(prefs_filtering_duplicate_cb) }, -}; - -static void prefs_filtering_row_selected(GtkTreeSelection *selection, - GtkTreeView *list_view) -{ - GtkTreePath *path; - GtkTreeIter iter; - GtkTreeModel *model; - - if (!gtk_tree_selection_get_selected(selection, &model, &iter)) - return; - - path = gtk_tree_model_get_path(model, &iter); - prefs_filtering_select_row(list_view, path); - gtk_tree_path_free(path); -} - -static gint prefs_filtering_list_btn_pressed(GtkWidget *widget, GdkEventButton *event, - GtkTreeView *list_view) -{ - if (event) { - /* left- or right-button click */ - if (event->button == 1 || event->button == 3) { - GtkTreePath *path = NULL; - - if (gtk_tree_view_get_path_at_pos( list_view, event->x, event->y, - &path, NULL, NULL, NULL)) { - prefs_filtering_select_row(list_view, path); - } - if (path) - gtk_tree_path_free(path); - } - - /* right-button click */ - if (event->button == 3) { - GtkTreeModel *model = gtk_tree_view_get_model(list_view); - GtkTreeIter iter; - gboolean non_empty; - gint row; - - if (!prefs_filtering_popup_menu) { - prefs_filtering_popup_action = cm_menu_create_action_group("PrefsFilteringPopup", prefs_filtering_popup_entries, - G_N_ELEMENTS(prefs_filtering_popup_entries), (gpointer)list_view); - MENUITEM_ADDUI("/Menus", "PrefsFilteringPopup", "PrefsFilteringPopup", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI("/Menus/PrefsFilteringPopup", "Delete", "PrefsFilteringPopup/Delete", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI("/Menus/PrefsFilteringPopup", "DeleteAll", "PrefsFilteringPopup/DeleteAll", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI("/Menus/PrefsFilteringPopup", "Duplicate", "PrefsFilteringPopup/Duplicate", GTK_UI_MANAGER_MENUITEM) - prefs_filtering_popup_menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM( - gtk_ui_manager_get_widget(gtkut_ui_manager(), "/Menus/PrefsFilteringPopup")) ); - } - - /* grey out some popup menu items if there is no selected row */ - row = gtkut_list_view_get_selected_row(GTK_WIDGET(list_view)); - cm_menu_set_sensitive("PrefsFilteringPopup/Delete", (row > 0)); - cm_menu_set_sensitive("PrefsFilteringPopup/Duplicate", (row > 0)); - - /* grey out seom popup menu items if there is no row - (not counting the (New) one at row 0) */ - non_empty = gtk_tree_model_get_iter_first(model, &iter); - if (non_empty) - non_empty = gtk_tree_model_iter_next(model, &iter); - cm_menu_set_sensitive("PrefsFilteringPopup/DeleteAll", non_empty); - - gtk_menu_popup_at_pointer(GTK_MENU(prefs_filtering_popup_menu), NULL); - } - } - return FALSE; -} - -static gboolean prefs_filtering_list_popup_menu(GtkWidget *widget, gpointer data) -{ - GtkTreeView *list_view = (GtkTreeView *)data; - GdkEventButton event; - - event.button = 3; - event.time = gtk_get_current_event_time(); - - prefs_filtering_list_btn_pressed(NULL, &event, list_view); - - return TRUE; -} - -/*! - *\brief Create list view for filtering - */ -static GtkWidget *prefs_filtering_list_view_create(void) -{ - GtkTreeView *list_view; - GtkTreeSelection *selector; - GtkListStore *store = prefs_filtering_create_data_store(); - - list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model( - GTK_TREE_MODEL(store))); - g_object_unref(store); - - g_signal_connect(G_OBJECT(list_view), "popup-menu", - G_CALLBACK(prefs_filtering_list_popup_menu), list_view); - g_signal_connect(G_OBJECT(list_view), "button-press-event", - G_CALLBACK(prefs_filtering_list_btn_pressed), list_view); - - gtk_tree_view_set_reorderable(list_view, TRUE); - - selector = gtk_tree_view_get_selection(list_view); - gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE); - g_signal_connect(G_OBJECT(selector), "changed", - G_CALLBACK(prefs_filtering_row_selected), list_view); - - /* create the columns */ - prefs_filtering_create_list_view_columns(GTK_WIDGET(list_view)); - - return GTK_WIDGET(list_view); -} - -static void prefs_filtering_enable_toggled(GtkCellRendererToggle *widget, - gchar *path, - GtkWidget *list_view) -{ - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view)); - gboolean enabled = TRUE; - - if (!gtk_tree_model_get_iter_from_string(model, &iter, path)) - return; - - gtk_tree_model_get(model, &iter, - PREFS_FILTERING_ENABLED, &enabled, - -1); - - gtk_list_store_set(GTK_LIST_STORE(model), &iter, - PREFS_FILTERING_ENABLED, !enabled, - -1); -} - -static void prefs_filtering_create_list_view_columns(GtkWidget *list_view) -{ - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - renderer = gtk_cell_renderer_toggle_new(); - g_object_set(renderer, - "radio", FALSE, - "activatable", TRUE, - NULL); - column = gtk_tree_view_column_new_with_attributes - (_("Enable"), /* FIXME : Enable, Enabled, or 'E' ? */ - renderer, - "active", PREFS_FILTERING_ENABLED, - NULL); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column); - g_signal_connect(G_OBJECT(renderer), "toggled", - G_CALLBACK(prefs_filtering_enable_toggled), - list_view); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes - (_("Name"), - renderer, - "text", PREFS_FILTERING_NAME, - NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column); - gtk_tree_view_column_set_resizable(column, TRUE); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes - (_("Account"), - renderer, - "text", PREFS_FILTERING_ACCOUNT_NAME, - NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column); - gtk_tree_view_column_set_resizable(column, TRUE); - - filtering.account_name_column = column; - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes - (_("Rule"), - renderer, - "text", PREFS_FILTERING_RULE, - NULL); - - gtk_tree_view_set_search_column(GTK_TREE_VIEW(list_view), PREFS_FILTERING_NAME); - gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(list_view), prefs_filtering_search_func_cb , NULL, NULL); - - gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column); -} - -/*! - *\brief Triggered when a row has to be selected - */ -static void prefs_filtering_select_row(GtkTreeView *list_view, GtkTreePath *path) -{ - GtkTreeModel *model = gtk_tree_view_get_model(list_view); - - if (path && model) { - GtkTreeSelection *selection; - gboolean has_prop = FALSE; - GtkTreeIter iter; - - /* select row */ - selection = gtk_tree_view_get_selection(list_view); - gtk_tree_selection_select_path(selection, path); - - /* update dialog from selection */ - gtk_tree_model_get_iter(model, &iter, path); - gtk_tree_model_get(model, &iter, - PREFS_FILTERING_PROP, &has_prop, - -1); - - if (has_prop) { - FilteringProp *prop; - gchar *filtering_str = NULL; - gchar *name = NULL; - gint account_id = 0; - - gtk_tree_model_get(model, &iter, - PREFS_FILTERING_RULE, &filtering_str, - PREFS_FILTERING_NAME, &name, - PREFS_FILTERING_ACCOUNT_ID, &account_id, - -1); - - prop = matcher_parser_get_filtering(filtering_str); - if (prop) { - if (prop->name != NULL) - g_free(prop->name); - prop->name = g_strdup(name); - prop->account_id = account_id; - prefs_filtering_select_set(prop); - filteringprop_free(prop); - } - g_free(name); - g_free(filtering_str); - } else - prefs_filtering_reset_dialog(); - } -} diff --git a/src/prefs_filtering.h b/src/prefs_filtering.h @@ -1,55 +0,0 @@ -/* - * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 1999-2012 Hiroyuki Yamamoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef __PREFS_FILTERING_H__ -#define __PREFS_FILTERING_H__ - -#include <glib.h> - -/* -void prefs_scoring_read_config (void); -void prefs_scoring_write_config (void); -*/ - -typedef enum -{ - FILTER_BY_NONE, - FILTER_BY_AUTO, - FILTER_BY_FROM, - FILTER_BY_TO, - FILTER_BY_SUBJECT, - FILTER_BY_SENDER -} PrefsFilterType; - -#include "folder.h" - -void prefs_filtering_open(GSList ** p_processing, - const gchar *title, - const gchar *help_url_anchor, - const gchar *header, - const gchar *key, - gboolean per_account_filtering); - -void prefs_filtering_rename_path (const gchar *old_path, - const gchar *new_path); -void prefs_filtering_delete_path (const gchar *path); - -void prefs_filtering_rename_tag(const gchar *old_tag, const gchar *new_tag); - -#endif /* __PREFS_FILTERING_H__ */ diff --git a/src/prefs_folder_item.c b/src/prefs_folder_item.c @@ -42,7 +42,6 @@ #include "addr_compl.h" #include "prefs_common.h" #include "gtkutils.h" -#include "filtering.h" #include "folder_item_prefs.h" #include "string_match.h" #include "quote_fmt.h" diff --git a/src/procmsg.c b/src/procmsg.c @@ -33,8 +33,6 @@ #include "send_message.h" #include "procmime.h" #include "statusbar.h" -#include "prefs_filtering.h" -#include "filtering.h" #include "folder.h" #include "foldersel.h" #include "prefs_common.h" @@ -536,149 +534,6 @@ gboolean procmsg_msg_exist(MsgInfo *msginfo) return ret; } -void procmsg_get_filter_keyword(MsgInfo *msginfo, gchar **header, gchar **key, - PrefsFilterType type) -{ - static HeaderEntry hentry[] = {{"X-BeenThere:", NULL, TRUE}, - {"X-ML-Name:", NULL, TRUE}, - {"X-List:", NULL, TRUE}, - {"X-Mailing-list:", NULL, TRUE}, - {"List-Id:", NULL, TRUE}, - {"X-Sequence:", NULL, TRUE}, - {"Sender:", NULL, TRUE}, - {"List-Post:", NULL, TRUE}, - {NULL, NULL, FALSE}}; - enum - { - H_X_BEENTHERE = 0, - H_X_ML_NAME = 1, - H_X_LIST = 2, - H_X_MAILING_LIST = 3, - H_LIST_ID = 4, - H_X_SEQUENCE = 5, - H_SENDER = 6, - H_LIST_POST = 7 - }; - - FILE *fp; - - cm_return_if_fail(msginfo != NULL); - cm_return_if_fail(header != NULL); - cm_return_if_fail(key != NULL); - - *header = NULL; - *key = NULL; - - switch (type) { - case FILTER_BY_NONE: - return; - case FILTER_BY_AUTO: - if ((fp = procmsg_open_message(msginfo, FALSE)) == NULL) - return; - procheader_get_header_fields(fp, hentry); - fclose(fp); - -#define SET_FILTER_KEY(hstr, idx) \ -{ \ - *header = g_strdup(hstr); \ - *key = hentry[idx].body; \ - hentry[idx].body = NULL; \ -} - - if (hentry[H_LIST_ID].body != NULL) { - SET_FILTER_KEY("header \"List-Id\"", H_LIST_ID); - extract_list_id_str(*key); - } else if (hentry[H_X_BEENTHERE].body != NULL) { - SET_FILTER_KEY("header \"X-BeenThere\"", H_X_BEENTHERE); - } else if (hentry[H_X_ML_NAME].body != NULL) { - SET_FILTER_KEY("header \"X-ML-Name\"", H_X_ML_NAME); - } else if (hentry[H_X_LIST].body != NULL) { - SET_FILTER_KEY("header \"X-List\"", H_X_LIST); - } else if (hentry[H_X_MAILING_LIST].body != NULL) { - SET_FILTER_KEY("header \"X-Mailing-List\"", H_X_MAILING_LIST); - } else if (hentry[H_X_SEQUENCE].body != NULL) { - gchar *p; - - SET_FILTER_KEY("X-Sequence", H_X_SEQUENCE); - p = *key; - while (*p != '\0') { - while (*p != '\0' && !g_ascii_isspace(*p)) p++; - while (g_ascii_isspace(*p)) p++; - if (g_ascii_isdigit(*p)) { - *p = '\0'; - break; - } - } - g_strstrip(*key); - } else if (hentry[H_SENDER].body != NULL) { - SET_FILTER_KEY("header \"Sender\"", H_SENDER); - } else if (hentry[H_LIST_POST].body != NULL) { - SET_FILTER_KEY("header \"List-Post\"", H_LIST_POST); - } else if (msginfo->to) { - *header = g_strdup("to"); - *key = g_strdup(msginfo->to); - } else if (msginfo->subject) { - *header = g_strdup("subject"); - *key = g_strdup(msginfo->subject); - } - - g_free(hentry[H_X_BEENTHERE].body); - hentry[H_X_BEENTHERE].body = NULL; - g_free(hentry[H_X_ML_NAME].body); - hentry[H_X_ML_NAME].body = NULL; - g_free(hentry[H_X_LIST].body); - hentry[H_X_LIST].body = NULL; - g_free(hentry[H_X_MAILING_LIST].body); - hentry[H_X_MAILING_LIST].body = NULL; - g_free(hentry[H_LIST_ID].body); - hentry[H_LIST_ID].body = NULL; - g_free(hentry[H_SENDER].body); - hentry[H_SENDER].body = NULL; - g_free(hentry[H_LIST_POST].body); - hentry[H_LIST_POST].body = NULL; - - break; - case FILTER_BY_FROM: - *header = g_strdup("from"); - *key = g_strdup(msginfo->from); - break; - case FILTER_BY_TO: - *header = g_strdup("to"); - *key = g_strdup(msginfo->to); - break; - case FILTER_BY_SUBJECT: - *header = g_strdup("subject"); - *key = g_strdup(msginfo->subject); - break; - case FILTER_BY_SENDER: - if ((fp = procmsg_open_message(msginfo, FALSE)) == NULL) - return; - procheader_get_header_fields(fp, hentry); - fclose(fp); - - if (hentry[H_SENDER].body != NULL) - SET_FILTER_KEY("header \"Sender\"", H_SENDER); - - g_free(hentry[H_X_BEENTHERE].body); - hentry[H_X_BEENTHERE].body = NULL; - g_free(hentry[H_X_ML_NAME].body); - hentry[H_X_ML_NAME].body = NULL; - g_free(hentry[H_X_LIST].body); - hentry[H_X_LIST].body = NULL; - g_free(hentry[H_X_MAILING_LIST].body); - hentry[H_X_MAILING_LIST].body = NULL; - g_free(hentry[H_LIST_ID].body); - hentry[H_LIST_ID].body = NULL; - g_free(hentry[H_SENDER].body); - hentry[H_SENDER].body = NULL; - -#undef SET_FILTER_KEY - break; - default: - break; - } -} - static void procmsg_empty_trash(FolderItem *trash) { GNode *node, *next; @@ -2179,37 +2034,6 @@ void procmsg_msginfo_set_to_folder(MsgInfo *msginfo, FolderItem *to_folder) } } -/** - * Apply filtering actions to the msginfo - * - * \param msginfo The MsgInfo describing the message that should be filtered - * \return TRUE if the message was moved and MsgInfo is now invalid, - * FALSE otherwise - */ -static gboolean procmsg_msginfo_filter(MsgInfo *msginfo, PrefsAccount* ac_prefs) -{ - MailFilteringData mail_filtering_data; - - mail_filtering_data.msginfo = msginfo; - mail_filtering_data.msglist = NULL; - mail_filtering_data.filtered = NULL; - mail_filtering_data.unfiltered = NULL; - mail_filtering_data.account = ac_prefs; - - if (!ac_prefs || ac_prefs->filterhook_on_recv) - if (hooks_invoke(MAIL_FILTERING_HOOKLIST, &mail_filtering_data)) - return TRUE; - - /* filter if enabled in prefs or move to inbox if not */ - if((filtering_rules != NULL) && - filter_message_by_msginfo(filtering_rules, msginfo, ac_prefs, - FILTERING_INCORPORATION, NULL)) { - return TRUE; - } - - return FALSE; -} - void procmsg_msglist_filter(GSList *list, PrefsAccount *ac, GSList **filtered, GSList **unfiltered, gboolean do_filter) @@ -2273,10 +2097,7 @@ void procmsg_msglist_filter(GSList *list, PrefsAccount *ac, for (cur = to_do; cur; cur = cur->next) { MsgInfo *info = (MsgInfo *)cur->data; - if (procmsg_msginfo_filter(info, ac)) - *filtered = g_slist_prepend(*filtered, info); - else - *unfiltered = g_slist_prepend(*unfiltered, info); + *unfiltered = g_slist_prepend(*unfiltered, info); statusbar_progress_all(curnum++, total, prefs_common.statusbar_update_step); } diff --git a/src/procmsg.h b/src/procmsg.h @@ -73,20 +73,20 @@ #define MSG_IGNORE_THREAD (1U << 10) /* ignore threads */ #define MSG_LOCKED (1U << 11) /* msg is locked */ -#define MSG_RETRCPT_SENT (1U << 12) /* new one */ -#define MSG_SPAM (1U << 13) /* new one */ +#define MSG_RETRCPT_SENT (1U << 12) /* new one */ +#define MSG_SPAM (1U << 13) /* new one */ #define MSG_POSTFILTERED (1U << 14) #define MSG_WATCH_THREAD (1U << 15) /* watch threads */ #define MSG_FULLY_CACHED (1U << 16) /* IMAP: fully cached */ #define MSG_RETRCPT_GOT (1U << 17) /* got return receipt */ - + /* RESERVED */ #define MSG_RESERVED_CLAWS (1U << 30) /* for Claws Mail */ #define MSG_RESERVED (1U << 31) #define MSG_MOVE (1U << 0) #define MSG_COPY (1U << 1) -#define MSG_MOVE_DONE (1U << 15) +#define MSG_MOVE_DONE (1U << 15) #define MSG_QUEUED (1U << 16) #define MSG_DRAFT (1U << 17) #define MSG_ENCRYPTED (1U << 18) @@ -161,7 +161,6 @@ typedef enum { } MsgInfoUpdateFlags; #include "prefs_account.h" -#include "prefs_filtering.h" #include "folder.h" struct _MsgFlags @@ -211,7 +210,7 @@ struct _MsgInfo FolderItem *folder; FolderItem *to_folder; - FolderItem *to_filter_folder; + FolderItem *to_filter_folder; FiltOp filter_op; GSList *references; @@ -221,7 +220,7 @@ struct _MsgInfo /* used only for encrypted messages */ gchar *plaintext_file; - + gint hidden; /* used only for partially received messages */ @@ -311,7 +310,7 @@ void procmsg_copy_messages (GSList *mlist); /* return path is locale charset */ gchar *procmsg_get_message_file_path (MsgInfo *msginfo); gchar *procmsg_get_message_file (MsgInfo *msginfo); -gchar *procmsg_get_message_file_full (MsgInfo *msginfo, +gchar *procmsg_get_message_file_full (MsgInfo *msginfo, gboolean get_headers, gboolean get_body); GSList *procmsg_get_message_file_list (MsgInfoList *mlist); @@ -320,11 +319,6 @@ FILE *procmsg_open_message (MsgInfo *msginfo, gboolean skip_special_headers); gboolean procmsg_msg_exist (MsgInfo *msginfo); -void procmsg_get_filter_keyword (MsgInfo *msginfo, - gchar **header, - gchar **key, - PrefsFilterType type); - void procmsg_empty_all_trash (void); gint procmsg_send_queue (FolderItem *queue, @@ -339,7 +333,7 @@ MsgInfo *procmsg_msginfo_new_ref (MsgInfo *msginfo); MsgInfo *procmsg_msginfo_copy (MsgInfo *msginfo); MsgInfo *procmsg_msginfo_get_full_info (MsgInfo *msginfo); MsgInfo *procmsg_msginfo_get_full_info_from_file - (MsgInfo *msginfo, + (MsgInfo *msginfo, const gchar *file); void procmsg_msginfo_free (MsgInfo **msginfo); guint procmsg_msginfo_memusage (MsgInfo *msginfo); @@ -352,7 +346,7 @@ gint procmsg_send_message_queue_with_lock(const gchar *file, gint procmsg_send_message_queue (const gchar *file, gchar **errstr, - FolderItem *queue, + FolderItem *queue, gint msgnum, gboolean *queued_removed); @@ -362,12 +356,12 @@ void procmsg_msginfo_set_flags (MsgInfo *msginfo, void procmsg_msginfo_unset_flags (MsgInfo *msginfo, MsgPermFlags perm_flags, MsgTmpFlags tmp_flags); -void procmsg_msginfo_change_flags (MsgInfo *msginfo, - MsgPermFlags add_perm_flags, +void procmsg_msginfo_change_flags (MsgInfo *msginfo, + MsgPermFlags add_perm_flags, MsgTmpFlags add_tmp_flags, - MsgPermFlags rem_perm_flags, + MsgPermFlags rem_perm_flags, MsgTmpFlags rem_tmp_flags); -gint procmsg_remove_special_headers (const gchar *in, +gint procmsg_remove_special_headers (const gchar *in, const gchar *out); gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file); @@ -376,14 +370,14 @@ gboolean procmsg_msg_has_flagged_parent (MsgInfo *info, gboolean procmsg_msg_has_marked_parent (MsgInfo *info); void procmsg_msginfo_set_to_folder (MsgInfo *msginfo, FolderItem *to_folder); -void procmsg_msglist_filter (GSList *list, - PrefsAccount *ac, +void procmsg_msglist_filter (GSList *list, + PrefsAccount *ac, GSList **filtered, GSList **unfiltered, gboolean do_filter); MsgInfo *procmsg_msginfo_new_from_mimeinfo - (MsgInfo *src_msginfo, + (MsgInfo *src_msginfo, MimeInfo *mimeinfo); void procmsg_register_spam_learner (int (*learn_func)(MsgInfo *info, GSList *list, gboolean spam)); diff --git a/src/summaryview.c b/src/summaryview.c @@ -44,7 +44,6 @@ #include "prefs_common.h" #include "prefs_summary_column.h" #include "prefs_summary_open.h" -#include "prefs_filtering.h" #include "account.h" #include "compose.h" #include "file-utils.h" @@ -61,7 +60,6 @@ #include "addressbook.h" #include "addr_compl.h" #include "folder_item_prefs.h" -#include "filtering.h" #include "string_match.h" #include "toolbar.h" #include "news.h" @@ -214,9 +212,6 @@ static void summary_unthread_for_exec_func (GtkCMCTree *ctree, void summary_simplify_subject(SummaryView *summaryview, gchar * rexp, GSList * mlist); -static void summary_filter_func (MsgInfo *msginfo, - PrefsAccount *ac_prefs); - static GtkWidget *summary_ctree_create (SummaryView *summaryview); /* callback functions */ @@ -392,10 +387,6 @@ static GtkActionEntry summary_popup_entries[] = {"SummaryViewPopup/ForwardAtt", NULL, N_("For_ward as attachment"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_FORWARD_AS_ATTACH */ {"SummaryViewPopup/Redirect", NULL, N_("R_edirect"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REDIRECT */ {"SummaryViewPopup/Marks", NULL, N_("_Marks"), NULL, NULL, NULL }, - {"SummaryViewPopup/ColorLabel", NULL, N_("Color la_bel"), NULL, NULL, NULL }, - {"SummaryViewPopup/Tags", NULL, N_("Ta_gs"), NULL, NULL, NULL }, - {"SummaryViewPopup/CreateFilterRule", NULL, N_("Create _filter rule"), NULL, NULL, NULL }, - {"SummaryViewPopup/CreateProcessingRule", NULL, N_("Create processing rule"), NULL, NULL, NULL }, {"SummaryViewPopup/View", NULL, N_("_View"), NULL, NULL, NULL }, }; @@ -655,13 +646,9 @@ SummaryView *summary_create(MainWindow *mainwin) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Delete", "Message/Delete", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator3", "Message/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Marks", "SummaryViewPopup/Marks", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "ColorLabel", "SummaryViewPopup/ColorLabel", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Tags", "SummaryViewPopup/Tags", GTK_UI_MANAGER_MENU) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator4", "Message/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "AddSenderToAB", "Tools/AddSenderToAB", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "CreateFilterRule", "SummaryViewPopup/CreateFilterRule", GTK_UI_MANAGER_MENU) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "CreateProcessingRule", "SummaryViewPopup/CreateProcessingRule", GTK_UI_MANAGER_MENU) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator5", "Tools/---", GTK_UI_MANAGER_SEPARATOR) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "View", "SummaryViewPopup/View", GTK_UI_MANAGER_MENU) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "SaveAs", "File/SaveAs", GTK_UI_MANAGER_MENUITEM) @@ -693,21 +680,6 @@ SummaryView *summary_create(MainWindow *mainwin) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Marks", "Lock", "Message/Marks/Lock", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Marks", "Unlock", "Message/Marks/Unlock", GTK_UI_MANAGER_MENUITEM) - /* submenus - tags are dynamic */ - /* submenus - createfilterrule */ - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateFilterRule", "Automatically", "Tools/CreateFilterRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateFilterRule", "ByFrom", "Tools/CreateFilterRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateFilterRule", "ByTo", "Tools/CreateFilterRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateFilterRule", "BySubject", "Tools/CreateFilterRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateFilterRule", "BySender", "Tools/CreateFilterRule/BySender", GTK_UI_MANAGER_MENUITEM) - - /* submenus - createprocessingrule */ - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateProcessingRule", "Automatically", "Tools/CreateProcessingRule/Automatically", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateProcessingRule", "ByFrom", "Tools/CreateProcessingRule/ByFrom", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateProcessingRule", "ByTo", "Tools/CreateProcessingRule/ByTo", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateProcessingRule", "BySubject", "Tools/CreateProcessingRule/BySubject", GTK_UI_MANAGER_MENUITEM) - MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/CreateProcessingRule", "BySender", "Tools/CreateProcessingRule/BySender", GTK_UI_MANAGER_MENUITEM) - /* submenus - view */ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/View", "OpenNewWindow", "View/OpenNewWindow", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/View", "MessageSource", "View/MessageSource", GTK_UI_MANAGER_MENUITEM) @@ -1750,12 +1722,6 @@ void summary_set_menu_sensitive(SummaryView *summaryview) SET_SENSITIVE("Menus/SummaryViewPopup/Marks/Unlock", M_TARGET_EXIST); SET_SENSITIVE("Menus/SummaryViewPopup/Marks/MarkSpam", M_TARGET_EXIST, M_CAN_LEARN_SPAM); SET_SENSITIVE("Menus/SummaryViewPopup/Marks/MarkHam", M_TARGET_EXIST, M_CAN_LEARN_SPAM); - SET_SENSITIVE("Menus/SummaryViewPopup/ColorLabel", M_TARGET_EXIST); - SET_SENSITIVE("Menus/SummaryViewPopup/Tags", M_TARGET_EXIST); - - SET_SENSITIVE("Menus/SummaryViewPopup/AddSenderToAB", M_SINGLE_TARGET_EXIST); - SET_SENSITIVE("Menus/SummaryViewPopup/CreateFilterRule", M_SINGLE_TARGET_EXIST, M_UNLOCKED); - SET_SENSITIVE("Menus/SummaryViewPopup/CreateProcessingRule", M_SINGLE_TARGET_EXIST, M_UNLOCKED); SET_SENSITIVE("Menus/SummaryViewPopup/View", M_SINGLE_TARGET_EXIST); SET_SENSITIVE("Menus/SummaryViewPopup/View/OpenNewWindow", M_SINGLE_TARGET_EXIST); @@ -5577,205 +5543,6 @@ static void account_rules_radio_button_toggled_cb(GtkToggleButton *btn, gpointer prefs_common.apply_per_account_filtering_rules = GPOINTER_TO_INT(data); } -static gboolean summary_filter_get_mode(void) -/* ask what to do w/ them: skip them, apply them regardless to the account, - use the current account */ -{ - /* TODO: eventually also propose to use the current folder's default account, - if it is set */ - /* TODO: eventually allow to select the account to use from a optmenu */ - - GtkWidget *vbox; - GtkWidget *account_rules_skip; - GtkWidget *account_rules_force; - GtkWidget *account_rules_user_current; - AlertValue val; - - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - - account_rules_skip = gtk_radio_button_new_with_label - (NULL, _("Skip these rules")); - account_rules_force = gtk_radio_button_new_with_label_from_widget - (GTK_RADIO_BUTTON(account_rules_skip), - _("Apply these rules regardless of the account they belong to")); - account_rules_user_current = gtk_radio_button_new_with_label_from_widget - (GTK_RADIO_BUTTON(account_rules_skip), - _("Apply these rules if they apply to the current account")); - gtk_box_pack_start (GTK_BOX (vbox), account_rules_skip, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), account_rules_force, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), account_rules_user_current, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(account_rules_skip), "toggled", - G_CALLBACK(account_rules_radio_button_toggled_cb), - GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_SKIP)); - g_signal_connect(G_OBJECT(account_rules_force), "toggled", - G_CALLBACK(account_rules_radio_button_toggled_cb), - GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_FORCE)); - g_signal_connect(G_OBJECT(account_rules_user_current), "toggled", - G_CALLBACK(account_rules_radio_button_toggled_cb), - GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_USE_CURRENT)); - switch (prefs_common.apply_per_account_filtering_rules) { - case FILTERING_ACCOUNT_RULES_SKIP: - gtk_toggle_button_set_active( - GTK_TOGGLE_BUTTON(account_rules_skip), TRUE); - break; - case FILTERING_ACCOUNT_RULES_FORCE: - gtk_toggle_button_set_active( - GTK_TOGGLE_BUTTON(account_rules_force), TRUE); - break; - case FILTERING_ACCOUNT_RULES_USE_CURRENT: - gtk_toggle_button_set_active( - GTK_TOGGLE_BUTTON(account_rules_user_current), TRUE); - break; - } - - val = alertpanel_with_widget( - _("Filtering"), - _("There are some filtering rules that belong to an account.\n" - "Please choose what to do with these rules:"), - NULL, _("_Cancel"), NULL, _("_Filter"), NULL, NULL, - ALERTFOCUS_SECOND, TRUE, vbox); - - if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE) { - return FALSE; - } else if (val & G_ALERTDISABLE) - prefs_common.ask_apply_per_account_filtering_rules = FALSE; - - return TRUE; -} - -void summary_filter(SummaryView *summaryview, gboolean selected_only) -{ - GSList *mlist = NULL, *cur_list; - PrefsAccount *ac_prefs = NULL; - summary_lock(summaryview); - - /* are there any per-account filtering rules? */ - if (prefs_common.ask_apply_per_account_filtering_rules == TRUE && - filtering_peek_per_account_rules(filtering_rules)) { - - if (summary_filter_get_mode() == FALSE) { - summary_unlock(summaryview); - return; - } - } - - folder_item_update_freeze(); - - debug_print("filtering...\n"); - STATUSBAR_PUSH(summaryview->mainwin, _("Filtering...")); - main_window_cursor_wait(summaryview->mainwin); - - summary_freeze(summaryview); - - if (selected_only) { - GList *cur; - - for (cur = GTK_CMCLIST(summaryview->ctree)->selection; - cur != NULL && cur->data != NULL; cur = cur->next) { - mlist = g_slist_prepend(mlist, - procmsg_msginfo_new_ref( - GTKUT_CTREE_NODE_GET_ROW_DATA(cur->data))); - } - mlist = g_slist_reverse(mlist); - } else { - mlist = folder_item_get_msg_list(summaryview->folder_item); - } - - ac_prefs = ((summaryview->folder_item->folder != NULL) && - (summaryview->folder_item->folder->account != NULL)) - ? summaryview->folder_item->folder->account : NULL; - - folder_item_set_batch(summaryview->folder_item, TRUE); - for (cur_list = mlist; cur_list; cur_list = cur_list->next) { - summary_filter_func((MsgInfo *)cur_list->data, ac_prefs); - } - folder_item_set_batch(summaryview->folder_item, FALSE); - - filtering_move_and_copy_msgs(mlist); - - for (cur_list = mlist; cur_list; cur_list = cur_list->next) { - procmsg_msginfo_free((MsgInfo **)&(cur_list->data)); - } - g_slist_free(mlist); - - summary_thaw(summaryview); - - folder_item_update_thaw(); - debug_print("filtering done.\n"); - STATUSBAR_POP(summaryview->mainwin); - main_window_cursor_normal(summaryview->mainwin); - - summary_unlock(summaryview); - - /* - * CLAWS: summary_show() only valid after having a lock. ideally - * we want the lock to be context aware... - */ - summary_show(summaryview, summaryview->folder_item, TRUE); -} - -static void summary_filter_func(MsgInfo *msginfo, PrefsAccount *ac_prefs) -{ - MailFilteringData mail_filtering_data; - - mail_filtering_data.msginfo = msginfo; - mail_filtering_data.msglist = NULL; - mail_filtering_data.filtered = NULL; - mail_filtering_data.unfiltered = NULL; - if (hooks_invoke(MAIL_MANUAL_FILTERING_HOOKLIST, &mail_filtering_data)) - return; - - filter_message_by_msginfo(filtering_rules, msginfo, ac_prefs, - FILTERING_MANUALLY, NULL); -} - -void summary_msginfo_filter_open(FolderItem * item, MsgInfo *msginfo, - PrefsFilterType type, gint processing_rule) -{ - gchar *header = NULL; - gchar *key = NULL; - - procmsg_get_filter_keyword(msginfo, &header, &key, type); - - if (processing_rule) { - if (item == NULL) - prefs_filtering_open(&pre_global_processing, - _("Processing rules to apply before folder rules"), - MANUAL_ANCHOR_PROCESSING, - header, key, FALSE); - else - prefs_filtering_open(&item->prefs->processing, - _("Processing configuration"), - MANUAL_ANCHOR_PROCESSING, - header, key, FALSE); - } - else { - prefs_filtering_open(&filtering_rules, - _("Filtering configuration"), - MANUAL_ANCHOR_FILTERING, - header, key, TRUE); - } - - g_free(header); - g_free(key); -} - -void summary_filter_open(SummaryView *summaryview, PrefsFilterType type, - gint processing_rule) -{ - MsgInfo *msginfo; - FolderItem * item; - - if (!summaryview->selected) return; - - msginfo = gtk_cmctree_node_get_row_data(GTK_CMCTREE(summaryview->ctree), - summaryview->selected); - if (!msginfo) return; - - item = summaryview->folder_item; - summary_msginfo_filter_open(item, msginfo, type, processing_rule); -} - void summaryview_destroy(SummaryView *summaryview) { if(summaryview->simplify_subject_preg) { diff --git a/src/summaryview.h b/src/summaryview.h @@ -68,7 +68,6 @@ typedef enum #include "compose.h" #include "folder.h" #include "gtksctree.h" -#include "prefs_filtering.h" #include "quicksearch.h" extern GtkTargetEntry summary_drag_types[3]; @@ -222,14 +221,6 @@ void summary_collapse_threads (SummaryView *summaryview); void summary_toggle_ignore_thread (SummaryView *summaryview); void summary_toggle_watch_thread (SummaryView *summaryview); -void summary_filter (SummaryView *summaryview, - gboolean selected_only); -void summary_filter_open (SummaryView *summaryview, - PrefsFilterType type, - gint processing_rule); -void summary_msginfo_filter_open (FolderItem * item, MsgInfo *msginfo, - PrefsFilterType type, gint processing_rule); - void summary_sort (SummaryView *summaryview, FolderSortKey sort_key, FolderSortType sort_type); diff --git a/src/toolbar.c b/src/toolbar.c @@ -1722,8 +1722,6 @@ static void toolbar_run_processing_cb(GtkWidget *widget, gpointer data) mainwin = (MainWindow *) toolbar_item->parent; item = mainwin->summaryview->folder_item; cm_return_if_fail(item != NULL); - item->processing_pending = TRUE; - folder_item_apply_processing(item); item->processing_pending = FALSE; break; default: