2006-07-31 [wwp] 2.4.0cvs2

* src/account.c
	* src/filtering.c
	* src/filtering.h
	* src/folder.c
	* src/folderview.c
	* src/inc.c
	* src/mainwindow.c
	* src/matcher.c
	* src/matcher_parser_lex.l
	* src/matcher_parser_parse.y
	* src/mbox.c
	* src/prefs_filtering.c
	* src/prefs_filtering.h
	* src/procmsg.c
	* src/procmsg.h
	* src/summaryview.c
		introduce per-account filtering rules. Each filtering rule can now be assigned
		to a specific account (by default it's "All"), works w/ POP3/IMAP. Take care
		when applying filtering rules manually, as all rules will apply - even the ones
		assigned to an account. This issue will be addressed soon.
This commit is contained in:
Tristan Chabredier 2006-07-31 11:44:30 +00:00
parent 6894eacfc4
commit 5a4b92f4d0
19 changed files with 311 additions and 58 deletions

View file

@ -1,3 +1,28 @@
2006-07-31 [wwp] 2.4.0cvs2
* src/account.c
* src/filtering.c
* src/filtering.h
* src/folder.c
* src/folderview.c
* src/inc.c
* src/mainwindow.c
* src/matcher.c
* src/matcher_parser_lex.l
* src/matcher_parser_parse.y
* src/mbox.c
* src/prefs_filtering.c
* src/prefs_filtering.h
* src/procmsg.c
* src/procmsg.h
* src/summaryview.c
introduce per-account filtering rules. Each filtering rule can now be assigned
to a specific account (by default it's "All"), works w/ POP3/IMAP. Take care
when applying filtering rules manually, as all rules will apply - even the ones
assigned to an account. This issue will be addressed soon.
2006-07-31 [wwp] 2.4.0cvs1
* src/quote_fmt.c

View file

@ -1693,3 +1693,4 @@
( cvs diff -u -r 1.58.2.23 -r 1.58.2.24 po/de.po; cvs diff -u -r 1.9.2.6 -r 1.9.2.7 po/el.po; cvs diff -u -r 1.42.2.25 -r 1.42.2.26 po/fr.po; cvs diff -u -r 1.34.2.19 -r 1.34.2.20 po/it.po; cvs diff -u -r 1.10.2.10 -r 1.10.2.11 po/pl.po; cvs diff -u -r 1.50.2.19 -r 1.50.2.20 po/pt_BR.po; cvs diff -u -r 1.17.2.22 -r 1.17.2.23 po/sr.po; cvs diff -u -r 1.5.2.16 -r 1.5.2.17 po/zh_CN.po; ) > 2.3.1cvs90.patchset
( cvs diff -u -r 1.1.2.9 -r 1.1.2.10 po/ca.po; ) > 2.3.1cvs91.patchset
( cvs diff -u -r 1.8.2.8 -r 1.8.2.9 src/quote_fmt.c; ) > 2.4.0cvs1.patchset
( cvs diff -u -r 1.61.2.48 -r 1.61.2.49 src/account.c; cvs diff -u -r 1.60.2.19 -r 1.60.2.20 src/filtering.c; cvs diff -u -r 1.21.2.7 -r 1.21.2.8 src/filtering.h; cvs diff -u -r 1.213.2.105 -r 1.213.2.106 src/folder.c; cvs diff -u -r 1.207.2.110 -r 1.207.2.111 src/folderview.c; cvs diff -u -r 1.149.2.54 -r 1.149.2.55 src/inc.c; cvs diff -u -r 1.274.2.127 -r 1.274.2.128 src/mainwindow.c; cvs diff -u -r 1.75.2.26 -r 1.75.2.27 src/matcher.c; cvs diff -u -r 1.16.2.6 -r 1.16.2.7 src/matcher_parser_lex.l; cvs diff -u -r 1.25.2.14 -r 1.25.2.15 src/matcher_parser_parse.y; cvs diff -u -r 1.28.2.22 -r 1.28.2.23 src/mbox.c; cvs diff -u -r 1.59.2.36 -r 1.59.2.37 src/prefs_filtering.c; cvs diff -u -r 1.6.2.4 -r 1.6.2.5 src/prefs_filtering.h; cvs diff -u -r 1.150.2.69 -r 1.150.2.70 src/procmsg.c; cvs diff -u -r 1.60.2.29 -r 1.60.2.30 src/procmsg.h; cvs diff -u -r 1.395.2.223 -r 1.395.2.224 src/summaryview.c; ) > 2.4.0cvs2.patchset

View file

@ -11,7 +11,7 @@ MINOR_VERSION=4
MICRO_VERSION=0
INTERFACE_AGE=0
BINARY_AGE=0
EXTRA_VERSION=1
EXTRA_VERSION=2
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=

View file

@ -50,6 +50,7 @@
#include "customheader.h"
#include "remotefolder.h"
#include "manual.h"
#include "filtering.h"
enum {
ACCOUNT_IS_DEFAULT, /* GDK_TYPE_PIXMAP! */
@ -1003,6 +1004,7 @@ 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)
@ -1039,6 +1041,22 @@ static void account_delete(GtkWidget *widget, gpointer data)
account_delete_references_func,
GINT_TO_POINTER(ac_prefs->account_id));
}
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);
}
}
}
static void account_up(GtkWidget *widget, gpointer data)

View file

@ -84,6 +84,7 @@ void filteringaction_free(FilteringAction * action)
FilteringProp * filteringprop_new(gboolean enabled,
const gchar *name,
gint account_id,
MatcherList * matchers,
GSList * action_list)
{
@ -92,6 +93,7 @@ FilteringProp * filteringprop_new(gboolean enabled,
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 = action_list;
@ -405,9 +407,18 @@ gboolean filteringaction_apply_action_list(GSList *action_list, MsgInfo *info)
return TRUE;
}
static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info)
static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *info,
PrefsAccount *ac_prefs)
{
return matcherlist_match(filtering->matchers, info);
gboolean matches = FALSE;
if (ac_prefs != NULL)
matches = ((filtering->account_id == 0)
|| (filtering->account_id == ac_prefs->account_id));
else
matches = TRUE;
return matches && matcherlist_match(filtering->matchers, info);
}
/*!
@ -467,7 +478,7 @@ static gboolean filtering_is_final_action(FilteringAction *filtering_action)
}
}
static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info, PrefsAccount* ac_prefs)
{
GSList *l;
gboolean final;
@ -478,7 +489,7 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
for (l = filtering_list, final = FALSE, apply_next = FALSE; l != NULL; l = g_slist_next(l)) {
FilteringProp * filtering = (FilteringProp *) l->data;
if (filtering->enabled && filtering_match_condition(filtering, info)) {
if (filtering->enabled && filtering_match_condition(filtering, info, ac_prefs)) {
apply_next = filtering_apply_rule(filtering, info, &final);
if (final)
break;
@ -507,9 +518,9 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
* processing. E.g. \ref inc.c::inc_start moves the
* message to the inbox.
*/
gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info)
gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount* ac_prefs)
{
return filter_msginfo(flist, info);
return filter_msginfo(flist, info, ac_prefs);
}
gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *action)

View file

@ -38,6 +38,7 @@ typedef struct _FilteringAction FilteringAction;
struct _FilteringProp {
gboolean enabled;
gchar *name;
gint account_id;
MatcherList * matchers;
GSList * action_list;
};
@ -56,6 +57,7 @@ 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);
@ -63,7 +65,7 @@ void filteringprop_free(FilteringProp *prop);
FilteringProp * filteringprop_parse(gchar **str);
void filter_msginfo_move_or_delete(GSList *filtering_list, MsgInfo *info);
gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info);
gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info, PrefsAccount *ac_prefs);
gchar * filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *action);
void prefs_filtering_write_config(void);

View file

@ -1944,7 +1944,7 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering)
(item->stype == F_INBOX) &&
(item->folder->account != NULL) &&
(item->folder->account->filter_on_recv) &&
procmsg_msginfo_filter(msginfo))
procmsg_msginfo_filter(msginfo, item->folder->account))
to_filter = g_slist_prepend(to_filter, msginfo);
else {
exists_list = g_slist_prepend(exists_list, msginfo);
@ -3749,13 +3749,13 @@ void folder_item_apply_processing(FolderItem *item)
statusbar_progress_all(curmsg++,total, 10);
/* apply pre global rules */
filter_message_by_msginfo(pre_global_processing, msginfo);
filter_message_by_msginfo(pre_global_processing, msginfo, NULL);
/* apply rules of the folder */
filter_message_by_msginfo(processing_list, msginfo);
filter_message_by_msginfo(processing_list, msginfo, NULL);
/* apply post global rules */
filter_message_by_msginfo(post_global_processing, msginfo);
filter_message_by_msginfo(post_global_processing, msginfo, NULL);
}
if (pre_global_processing || processing_list

View file

@ -2469,7 +2469,7 @@ static void folderview_processing_cb(FolderView *folderview, guint action,
g_free (id);
prefs_filtering_open(&item->prefs->processing, title,
MANUAL_ANCHOR_PROCESSING, NULL, NULL);
MANUAL_ANCHOR_PROCESSING, NULL, NULL, FALSE);
g_free (title);
}

View file

@ -645,7 +645,7 @@ static gint inc_start(IncProgressDialog *inc_dialog)
statusbar_progress_all(cur++,total, prefs_common.statusbar_update_step);
if (!pop3_session->ac_prefs->filter_on_recv ||
!procmsg_msginfo_filter(msginfo))
!procmsg_msginfo_filter(msginfo, pop3_session->ac_prefs))
folder_item_move_msg(inbox, msginfo);
}
filtering_move_and_copy_msgs(msglist);

View file

@ -3579,7 +3579,7 @@ static void prefs_pre_processing_open_cb(MainWindow *mainwin, guint action,
prefs_filtering_open(&pre_global_processing,
_("Processing rules to apply before folder rules"),
MANUAL_ANCHOR_PROCESSING,
NULL, NULL);
NULL, NULL, FALSE);
}
static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
@ -3588,7 +3588,7 @@ static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
prefs_filtering_open(&post_global_processing,
_("Processing rules to apply after folder rules"),
MANUAL_ANCHOR_PROCESSING,
NULL, NULL);
NULL, NULL, FALSE);
}
static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
@ -3597,7 +3597,7 @@ static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
prefs_filtering_open(&filtering_rules,
_("Filtering configuration"),
MANUAL_ANCHOR_FILTERING,
NULL, NULL);
NULL, NULL, TRUE);
}
static void prefs_template_open_cb(MainWindow *mainwin, guint action,

View file

@ -1488,12 +1488,12 @@ gchar *matching_build_command(const gchar *cmd, MsgInfo *info)
*/
static void prefs_filtering_write(FILE *fp, GSList *prefs_filtering)
{
GSList *cur;
GSList *cur = NULL;
for (cur = prefs_filtering; cur != NULL; cur = cur->next) {
gchar *filtering_str;
gchar *filtering_str = NULL;
gchar *tmp_name = NULL;
FilteringProp *prop;
FilteringProp *prop = NULL;
if (NULL == (prop = (FilteringProp *) cur->data))
continue;
@ -1503,18 +1503,18 @@ static void prefs_filtering_write(FILE *fp, GSList *prefs_filtering)
if (prop->enabled) {
if (fputs("enabled ", fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs || fputc");
FILE_OP_ERROR("filtering config", "fputs");
return;
}
} else {
if (fputs("disabled ", fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs || fputc");
FILE_OP_ERROR("filtering config", "fputs");
return;
}
}
if (fputs("rulename \"", fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs || fputc");
FILE_OP_ERROR("filtering config", "fputs");
g_free(filtering_str);
return;
}
@ -1522,22 +1522,39 @@ static void prefs_filtering_write(FILE *fp, GSList *prefs_filtering)
while (tmp_name && *tmp_name != '\0') {
if (*tmp_name != '"') {
if (fputc(*tmp_name, fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputc");
FILE_OP_ERROR("filtering config", "fputs || fputc");
g_free(filtering_str);
return;
}
} else if (*tmp_name == '"') {
if (fputc('\\', fp) == EOF ||
fputc('"', fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputc");
FILE_OP_ERROR("filtering config", "fputs || fputc");
g_free(filtering_str);
return;
}
}
tmp_name ++;
}
if(fputs("\" ", fp) == EOF ||
fputs(filtering_str, fp) == EOF ||
if (fputs("\" ", fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs");
g_free(filtering_str);
return;
}
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(tmp);
return;
}
g_free(tmp);
}
if(fputs(filtering_str, fp) == EOF ||
fputc('\n', fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs || fputc");
g_free(filtering_str);
@ -1708,7 +1725,7 @@ void prefs_matcher_read_config(void)
fclose(matcher_parserin);
}
else {
/* previous version compatibily */
/* previous version compatibility */
/* printf("reading filtering\n"); */
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,

View file

@ -116,6 +116,9 @@ rulename {
disabled {
return MATCHER_DISABLED;
}
account {
return MATCHER_ACCOUNT;
}
enabled {
return MATCHER_ENABLED;
}

View file

@ -45,6 +45,7 @@ static GSList *matchers_list = NULL;
static gboolean enabled = TRUE;
static gchar *name = NULL;
static gint account_id = 0;
static MatcherList *cond;
static GSList *action_list = NULL;
static FilteringAction *action = NULL;
@ -59,6 +60,7 @@ enum {
MATCHER_PARSE_NO_EOL,
MATCHER_PARSE_ENABLED,
MATCHER_PARSE_NAME,
MATCHER_PARSE_ACCOUNT,
MATCHER_PARSE_CONDITION,
MATCHER_PARSE_FILTERING_ACTION,
};
@ -77,6 +79,7 @@ int matcher_parserlex(void);
void matcher_parser_start_parsing(FILE *f)
{
matcher_parserrestart(f);
account_id = 0;
matcher_parserparse();
}
@ -151,6 +154,50 @@ MatcherList *matcher_parser_get_name(gchar *str)
return cond;
}
MatcherList *matcher_parser_get_enabled(gchar *str)
{
void *bufstate;
if (!check_quote_symetry(str)) {
cond = NULL;
return cond;
}
/* bad coding to enable the sub-grammar matching
in yacc */
matcher_parserlineno = 1;
matcher_parse_op = MATCHER_PARSE_ENABLED;
matcher_parserrestart(NULL);
matcher_parser_init();
bufstate = matcher_parser_scan_string(str);
matcher_parserparse();
matcher_parse_op = MATCHER_PARSE_FILE;
matcher_parser_delete_buffer(bufstate);
return cond;
}
MatcherList *matcher_parser_get_account(gchar *str)
{
void *bufstate;
if (!check_quote_symetry(str)) {
cond = NULL;
return cond;
}
/* bad coding to enable the sub-grammar matching
in yacc */
matcher_parserlineno = 1;
matcher_parse_op = MATCHER_PARSE_ACCOUNT;
matcher_parserrestart(NULL);
matcher_parser_init();
bufstate = matcher_parser_scan_string(str);
matcher_parserparse();
matcher_parse_op = MATCHER_PARSE_FILE;
matcher_parser_delete_buffer(bufstate);
return cond;
}
MatcherList *matcher_parser_get_cond(gchar *str)
{
void *bufstate;
@ -283,6 +330,7 @@ int matcher_parserwrap(void)
%token MATCHER_ENABLED MATCHER_DISABLED
%token MATCHER_RULENAME
%token MATCHER_ACCOUNT
%token <str> MATCHER_STRING
%token <str> MATCHER_SECTION
%token <str> MATCHER_INTEGER
@ -347,7 +395,9 @@ MATCHER_SECTION MATCHER_EOL
;
instruction:
enabled name condition filtering MATCHER_EOL
enabled name account condition filtering MATCHER_EOL
| enabled name account condition filtering
| enabled name condition filtering MATCHER_EOL
| enabled name condition filtering
| name condition filtering MATCHER_EOL
| name condition filtering
@ -355,7 +405,7 @@ enabled name condition filtering MATCHER_EOL
if (matcher_parse_op == MATCHER_PARSE_NO_EOL)
YYACCEPT;
else {
matcher_parsererror("parse error a");
matcher_parsererror("parse error [no eol]");
YYERROR;
}
}
@ -364,7 +414,16 @@ enabled name condition filtering MATCHER_EOL
if (matcher_parse_op == MATCHER_PARSE_ENABLED)
YYACCEPT;
else {
matcher_parsererror("parse error enabled");
matcher_parsererror("parse error [enabled]");
YYERROR;
}
}
| account
{
if (matcher_parse_op == MATCHER_PARSE_ACCOUNT)
YYACCEPT;
else {
matcher_parsererror("parse error [account]");
YYERROR;
}
}
@ -373,7 +432,7 @@ enabled name condition filtering MATCHER_EOL
if (matcher_parse_op == MATCHER_PARSE_NAME)
YYACCEPT;
else {
matcher_parsererror("parse error b");
matcher_parsererror("parse error [name]");
YYERROR;
}
}
@ -382,7 +441,7 @@ enabled name condition filtering MATCHER_EOL
if (matcher_parse_op == MATCHER_PARSE_CONDITION)
YYACCEPT;
else {
matcher_parsererror("parse error c");
matcher_parsererror("parse error [condition]");
YYERROR;
}
}
@ -391,7 +450,7 @@ enabled name condition filtering MATCHER_EOL
if (matcher_parse_op == MATCHER_PARSE_FILTERING_ACTION)
YYACCEPT;
else {
matcher_parsererror("parse error d");
matcher_parsererror("parse error [filtering action]");
YYERROR;
}
}
@ -416,11 +475,21 @@ MATCHER_RULENAME MATCHER_STRING
}
;
account:
MATCHER_ACCOUNT MATCHER_INTEGER
{
account_id = strtol($2, NULL, 10);
fprintf(stderr, "parser %d\n", account_id);
fflush(stderr);
}
;
filtering:
filtering_action_list
{
filtering = filteringprop_new(enabled, name, cond, 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) {

View file

@ -226,7 +226,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter)
return -1;
}
msginfo = folder_item_get_msginfo(dropfolder, msgnum);
if (!procmsg_msginfo_filter(msginfo))
if (!procmsg_msginfo_filter(msginfo, NULL))
to_drop = g_slist_prepend(to_drop, msginfo);
else
to_filter = g_slist_prepend(to_filter, msginfo);

View file

@ -50,6 +50,7 @@
#include "addr_compl.h"
#include "colorlabel.h"
#include "manual.h"
#include "combobox.h"
#include "matcher_parser.h"
#include "matcher.h"
@ -58,22 +59,30 @@
enum {
PREFS_FILTERING_ENABLED,
PREFS_FILTERING_NAME,
PREFS_FILTERING_ACCOUNT,
PREFS_FILTERING_RULE,
PREFS_FILTERING_PROP,
N_PREFS_FILTERING_COLUMNS
};
static struct Filtering {
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;
} filtering;
};
typedef struct _Filtering Filtering;
static Filtering filtering;
static GSList ** p_processing_list = NULL;
@ -117,6 +126,7 @@ static gint prefs_filtering_list_view_insert_rule (GtkListStore *list_store,
gint row,
gboolean enabled,
const gchar *name,
gint account_id,
const gchar *rule,
gboolean prop);
static gchar *prefs_filtering_list_view_get_rule (GtkWidget *list,
@ -124,7 +134,8 @@ static gchar *prefs_filtering_list_view_get_rule (GtkWidget *list,
static void prefs_filtering_list_view_get_rule_name (GtkWidget *list,
gint row,
gboolean *enabled,
gchar **name);
gchar **name,
gint *account_id);
static GtkWidget *prefs_filtering_list_view_create (void);
static void prefs_filtering_create_list_view_columns (GtkWidget *list_view);
@ -137,13 +148,16 @@ static gboolean prefs_filtering_selected (GtkTreeSelection *selector,
gboolean currently_selected,
gpointer data);
static void prefs_filtering_account_option_menu_populate(void);
static gulong signal_id = 0; /* filtering.help_btn clicked signal */
void prefs_filtering_open(GSList ** p_processing,
const gchar *title,
const gchar *help_url_anchor,
const gchar *header,
const gchar *key)
const gchar *key,
gboolean per_account_filtering)
{
if (prefs_rc_is_readonly(FILTERING_RC))
return;
@ -152,6 +166,9 @@ void prefs_filtering_open(GSList ** p_processing,
if (!filtering.window) {
prefs_filtering_create();
} else {
gtk_list_store_clear(filtering.account_combobox_list);
prefs_filtering_account_option_menu_populate();
}
manage_window_set_transient(GTK_WINDOW(filtering.window));
@ -182,6 +199,14 @@ void prefs_filtering_open(GSList ** p_processing,
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);
@ -206,6 +231,41 @@ static void prefs_filtering_close(void)
inc_unlock();
}
static void prefs_filtering_account_option_menu_populate(void)
{
GList *accounts = NULL;
GtkTreeIter iter;
accounts = account_get_list();
g_return_val_if_fail(accounts != NULL, NULL);
COMBOBOX_ADD(filtering.account_combobox_list, _("All"), 0);
for (; accounts != NULL; accounts = accounts->next) {
PrefsAccount *ac = (PrefsAccount *)accounts->data;
COMBOBOX_ADD(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;
@ -222,6 +282,8 @@ static void prefs_filtering_create(void)
GtkWidget *name_label;
GtkWidget *name_entry;
GtkWidget *account_label;
GtkWidget *account_opt_menu;
GtkWidget *cond_label;
GtkWidget *cond_entry;
GtkWidget *cond_btn;
@ -286,7 +348,7 @@ static void prefs_filtering_create(void)
gtk_box_pack_start (GTK_BOX (vbox), vbox1, FALSE, TRUE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
table = gtk_table_new(3, 3, FALSE);
table = gtk_table_new(3, 4, FALSE);
gtk_widget_show(table);
gtk_box_pack_start (GTK_BOX (vbox1), table, TRUE, TRUE, 0);
@ -304,22 +366,36 @@ static void prefs_filtering_create(void)
(GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
(GtkAttachOptions) (0), 0, 0);
account_label = gtk_label_new (_("Account:"));
gtk_widget_show (account_label);
gtk_misc_set_alignment (GTK_MISC (account_label), 1, 0.5);
gtk_table_attach (GTK_TABLE (table), account_label, 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
account_opt_menu = prefs_filtering_account_option_menu(&filtering);
gtk_widget_show (account_opt_menu);
gtk_table_attach (GTK_TABLE (table), account_opt_menu, 1, 2, 1, 2,
(GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
(GtkAttachOptions) (0), 0, 0);
combobox_select_by_data(GTK_COMBO_BOX(filtering.account_combobox), 0);
cond_label = gtk_label_new (_("Condition: "));
gtk_widget_show (cond_label);
gtk_misc_set_alignment (GTK_MISC (cond_label), 1, 0.5);
gtk_table_attach (GTK_TABLE (table), cond_label, 0, 1, 1, 2,
gtk_table_attach (GTK_TABLE (table), cond_label, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
cond_entry = gtk_entry_new ();
gtk_widget_show (cond_entry);
gtk_table_attach (GTK_TABLE (table), cond_entry, 1, 2, 1, 2,
gtk_table_attach (GTK_TABLE (table), cond_entry, 1, 2, 2, 3,
(GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
(GtkAttachOptions) (0), 0, 0);
cond_btn = gtk_button_new_with_label (_(" Define... "));
gtk_widget_show (cond_btn);
gtk_table_attach (GTK_TABLE (table), cond_btn, 2, 3, 1, 2,
gtk_table_attach (GTK_TABLE (table), cond_btn, 2, 3, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 2, 2);
g_signal_connect(G_OBJECT (cond_btn), "clicked",
@ -329,19 +405,19 @@ static void prefs_filtering_create(void)
action_label = gtk_label_new (_("Action: "));
gtk_widget_show (action_label);
gtk_misc_set_alignment (GTK_MISC (action_label), 1, 0.5);
gtk_table_attach (GTK_TABLE (table), action_label, 0, 1, 2, 3,
gtk_table_attach (GTK_TABLE (table), action_label, 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
action_entry = gtk_entry_new ();
gtk_widget_show (action_entry);
gtk_table_attach (GTK_TABLE (table), action_entry, 1, 2, 2, 3,
gtk_table_attach (GTK_TABLE (table), action_entry, 1, 2, 3, 4,
(GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
(GtkAttachOptions) (0), 0, 0);
action_btn = gtk_button_new_with_label (_(" Define... "));
gtk_widget_show (action_btn);
gtk_table_attach (GTK_TABLE (table), action_btn, 2, 3, 2, 3,
gtk_table_attach (GTK_TABLE (table), action_btn, 2, 3, 3, 4,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 2, 2);
g_signal_connect(G_OBJECT (action_btn), "clicked",
@ -450,6 +526,7 @@ static void prefs_filtering_create(void)
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_path(GSList * filters,
@ -675,6 +752,7 @@ static void prefs_filtering_set_dialog(const gchar *header, const gchar *key)
prefs_filtering_list_view_insert_rule(list_store, -1,
FALSE,
_("(New)"),
0,
_("(New)"),
FALSE);
@ -689,6 +767,7 @@ static void prefs_filtering_set_dialog(const gchar *header, const gchar *key)
prefs_filtering_list_view_insert_rule(list_store, -1,
prop->enabled,
prop->name,
prop->account_id,
cond_str, TRUE);
g_free(cond_str);
@ -714,6 +793,7 @@ static void prefs_filtering_set_dialog(const gchar *header, const gchar *key)
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), "");
}
@ -740,15 +820,17 @@ static void prefs_filtering_set_list(void)
if (strcmp(filtering_str, _("(New)")) != 0) {
gboolean enabled;
gchar *name;
gint account_id = 0;
prefs_filtering_list_view_get_rule_name(
filtering.cond_list_view, row,
&enabled, &name);
&enabled, &name, &account_id);
prop = matcher_parser_get_filtering(filtering_str);
g_free(filtering_str);
if (prop) {
prop->enabled = enabled;
prop->name = name;
prop->account_id = account_id;
prefs_filtering =
g_slist_append(prefs_filtering, prop);
}
@ -766,6 +848,7 @@ static gint prefs_filtering_list_view_set_row(gint row, FilteringProp * prop)
gchar *str;
GtkListStore *list_store;
gchar *name = NULL;
gint account_id = 0;
gboolean enabled = TRUE;
str = filteringprop_to_string(prop);
@ -775,6 +858,7 @@ static gint prefs_filtering_list_view_set_row(gint row, FilteringProp * prop)
if (prop) {
if (prop->name)
name = prop->name;
account_id = prop->account_id;
enabled = prop->enabled;
}
@ -783,6 +867,7 @@ static gint prefs_filtering_list_view_set_row(gint row, FilteringProp * prop)
row = prefs_filtering_list_view_insert_rule(list_store, row,
enabled,
name,
account_id,
str,
prop != NULL);
@ -877,6 +962,7 @@ 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;
@ -884,6 +970,8 @@ static FilteringProp * prefs_filtering_dialog_to_filtering(gboolean alert)
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."));
@ -911,7 +999,7 @@ static FilteringProp * prefs_filtering_dialog_to_filtering(gboolean alert)
goto fail;
}
prop = filteringprop_new(enabled, name, cond, action_list);
prop = filteringprop_new(enabled, name, account_id, cond, action_list);
fail:
g_free(name);
@ -1073,6 +1161,8 @@ static void prefs_filtering_select_set(FilteringProp *prop)
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);
@ -1176,6 +1266,7 @@ 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_BOOLEAN,
-1);
@ -1191,6 +1282,7 @@ static GtkListStore* prefs_filtering_create_data_store(void)
* row
*\param enabled TRUE if rule is enabled
*\param name The Name of rule
*\param account_id The account ID
*\param rule String representation of rule
*\param prop TRUE if valid filtering rule; if FALSE it's the first
* entry in the store ("(New)").
@ -1201,6 +1293,7 @@ static gint prefs_filtering_list_view_insert_rule(GtkListStore *list_store,
gint row,
gboolean enabled,
const gchar *name,
gint account_id,
const gchar *rule,
gboolean prop)
{
@ -1219,6 +1312,7 @@ static gint prefs_filtering_list_view_insert_rule(GtkListStore *list_store,
gtk_list_store_set(list_store, &iter,
PREFS_FILTERING_ENABLED, enabled,
PREFS_FILTERING_NAME, name,
PREFS_FILTERING_ACCOUNT, account_id,
PREFS_FILTERING_RULE, rule,
PREFS_FILTERING_PROP, prop,
-1);
@ -1229,6 +1323,7 @@ static gint prefs_filtering_list_view_insert_rule(GtkListStore *list_store,
gtk_list_store_set(list_store, &iter,
PREFS_FILTERING_ENABLED, enabled,
PREFS_FILTERING_NAME, name,
PREFS_FILTERING_ACCOUNT, account_id,
PREFS_FILTERING_RULE, rule,
-1);
return row;
@ -1255,7 +1350,8 @@ static gchar *prefs_filtering_list_view_get_rule(GtkWidget *list, gint row)
return result;
}
static void prefs_filtering_list_view_get_rule_name(GtkWidget *list, gint row, gboolean *enabled, gchar **name)
static void prefs_filtering_list_view_get_rule_name(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);
@ -1268,6 +1364,7 @@ static void prefs_filtering_list_view_get_rule_name(GtkWidget *list, gint row, g
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_ENABLED, enabled,
PREFS_FILTERING_NAME, name,
PREFS_FILTERING_ACCOUNT, account_id,
-1);
}
}
@ -1446,6 +1543,7 @@ static gboolean prefs_filtering_selected(GtkTreeSelection *selector,
FilteringProp *prop;
gchar *filtering_str = NULL;
gchar *name = NULL;
gint account_id = 0;
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_RULE, &filtering_str,
@ -1453,10 +1551,17 @@ static gboolean prefs_filtering_selected(GtkTreeSelection *selector,
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_NAME, &name,
-1);
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_ACCOUNT, &account_id,
-1);
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_ACCOUNT, &account_id,
-1);
prop = matcher_parser_get_filtering(filtering_str);
if (prop) {
prop->name = g_strdup(name);
prop->account_id = account_id;
prefs_filtering_select_set(prop);
filteringprop_free(prop);
}

View file

@ -42,7 +42,8 @@ void prefs_filtering_open(GSList ** p_processing,
const gchar *title,
const gchar *help_url_anchor,
const gchar *header,
const gchar *key);
const gchar *key,
gboolean per_account_filtering);
void prefs_filtering_rename_path (const gchar *old_path,
const gchar *new_path);

View file

@ -2067,7 +2067,7 @@ void procmsg_msginfo_set_to_folder(MsgInfo *msginfo, FolderItem *to_folder)
* \return TRUE if the message was moved and MsgInfo is now invalid,
* FALSE otherwise
*/
gboolean procmsg_msginfo_filter(MsgInfo *msginfo)
gboolean procmsg_msginfo_filter(MsgInfo *msginfo, PrefsAccount* ac_prefs)
{
MailFilteringData mail_filtering_data;
@ -2078,7 +2078,7 @@ gboolean procmsg_msginfo_filter(MsgInfo *msginfo)
/* filter if enabled in prefs or move to inbox if not */
if((filtering_rules != NULL) &&
filter_message_by_msginfo(filtering_rules, msginfo)) {
filter_message_by_msginfo(filtering_rules, msginfo, ac_prefs)) {
return TRUE;
}

View file

@ -330,7 +330,8 @@ void procmsg_update_unread_children (MsgInfo *info,
gboolean newly_marked);
void procmsg_msginfo_set_to_folder (MsgInfo *msginfo,
FolderItem *to_folder);
gboolean procmsg_msginfo_filter (MsgInfo *msginfo);
gboolean procmsg_msginfo_filter (MsgInfo *msginfo,
PrefsAccount *ac_prefs);
MsgInfo *procmsg_msginfo_new_from_mimeinfo
(MsgInfo *src_msginfo,
MimeInfo *mimeinfo);

View file

@ -4510,7 +4510,7 @@ static void summary_filter_func(MsgInfo *msginfo)
if (hooks_invoke(MAIL_MANUAL_FILTERING_HOOKLIST, &mail_filtering_data))
return;
filter_message_by_msginfo(filtering_rules, msginfo);
filter_message_by_msginfo(filtering_rules, msginfo, NULL);
}
void summary_msginfo_filter_open(FolderItem * item, MsgInfo *msginfo,
@ -4526,18 +4526,18 @@ void summary_msginfo_filter_open(FolderItem * item, MsgInfo *msginfo,
prefs_filtering_open(&pre_global_processing,
_("Processing rules to apply before folder rules"),
MANUAL_ANCHOR_PROCESSING,
header, key);
header, key, FALSE);
else
prefs_filtering_open(&item->prefs->processing,
_("Processing configuration"),
MANUAL_ANCHOR_PROCESSING,
header, key);
header, key, FALSE);
}
else {
prefs_filtering_open(&filtering_rules,
_("Filtering configuration"),
MANUAL_ANCHOR_FILTERING,
header, key);
header, key, TRUE);
}
g_free(header);