for (cur = prefs_filtering; cur != NULL; cur = cur->next) {
gchar *filtering_str;
+ gchar *tmp_name = NULL;
FilteringProp *prop;
if (NULL == (prop = (FilteringProp *) cur->data))
if (NULL == (filtering_str = filteringprop_to_string(prop)))
continue;
-
- if (fputs(filtering_str, fp) == EOF ||
+
+ if (fputs("rulename \"", fp) == EOF) {
+ FILE_OP_ERROR("filtering config", "fputs || fputc");
+ g_free(filtering_str);
+ return;
+ }
+ tmp_name = prop->name;
+ while (tmp_name && *tmp_name != '\0') {
+ if (*tmp_name != '"') {
+ if (fputc(*tmp_name, fp) == EOF) {
+ FILE_OP_ERROR("filtering config", "fputc");
+ g_free(filtering_str);
+ return;
+ }
+ } else if (*tmp_name == '"') {
+ if (fputc('\\', fp) == EOF ||
+ fputc('"', fp) == EOF) {
+ FILE_OP_ERROR("filtering config", "fputc");
+ g_free(filtering_str);
+ return;
+ }
+ }
+ tmp_name ++;
+ }
+ if(fputs("\" ", fp) == EOF ||
+ fputs(filtering_str, fp) == EOF ||
fputc('\n', fp) == EOF) {
FILE_OP_ERROR("filtering config", "fputs || fputc");
g_free(filtering_str);
/* ******************************************************************* */
+void matcher_add_rulenames(const gchar *rcpath)
+{
+ gchar *newpath = g_strconcat(rcpath, ".new", NULL);
+ FILE *src = g_fopen(rcpath, "rb");
+ FILE *dst = g_fopen(newpath, "wb");
+ gchar buf[BUFFSIZE];
+
+ if (dst == NULL) {
+ perror("fopen");
+ g_free(newpath);
+ return;
+ }
+
+ while (fgets (buf, sizeof(buf), src) != NULL) {
+ if (strlen(buf) > 2 && buf[0] != '['
+ && strncmp(buf, "rulename \"", 10)) {
+ fwrite("rulename \"\" ",
+ strlen("rulename \"\" "), 1, dst);
+ }
+ fwrite(buf, strlen(buf), 1, dst);
+ }
+ fclose(dst);
+ fclose(src);
+ move_file(newpath, rcpath, TRUE);
+ g_free(newpath);
+}
+
/*!
*\brief Read matcher configuration
*/
void prefs_matcher_read_config(void)
{
gchar *rcpath;
+ gchar *rc_old_format;
FILE *f;
create_matchparser_hashtab();
prefs_filtering_clear();
rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MATCHER_RC, NULL);
+ rc_old_format = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MATCHER_RC,
+ ".pre_names", NULL);
+
+ if (!is_file_exist(rc_old_format) && is_file_exist(rcpath)) {
+ /* backup file with no rules names, in case
+ * anything goes wrong */
+ copy_file(rcpath, rc_old_format, FALSE);
+ /* now hack the file in order to have it to the new format */
+ matcher_add_rulenames(rcpath);
+ }
f = g_fopen(rcpath, "rb");
g_free(rcpath);
static GSList *matchers_list = NULL;
+static gchar *name = NULL;
static MatcherList *cond;
static GSList *action_list = NULL;
static FilteringAction *action = NULL;
enum {
MATCHER_PARSE_FILE,
MATCHER_PARSE_NO_EOL,
+ MATCHER_PARSE_NAME,
MATCHER_PARSE_CONDITION,
MATCHER_PARSE_FILTERING_ACTION,
};
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_parse_op = MATCHER_PARSE_NO_EOL;
matcher_parserrestart(NULL);
matcher_parser_init();
- bufstate = matcher_parser_scan_string((const char *) str);
+ bufstate = matcher_parser_scan_string((const char *) tmp_str);
matcher_parser_switch_to_buffer(bufstate);
if (matcher_parserparse() != 0)
filtering = NULL;
matcher_parse_op = MATCHER_PARSE_FILE;
matcher_parser_delete_buffer(bufstate);
+ g_free(tmp_str);
return filtering;
}
return !(ret % 2);
}
+MatcherList *matcher_parser_get_name(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_NAME;
+ 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;
char *str;
int value;
}
-
%token MATCHER_ALL MATCHER_UNREAD MATCHER_NOT_UNREAD
%token MATCHER_NEW MATCHER_NOT_NEW MATCHER_MARKED
%token MATCHER_NOT_MARKED MATCHER_DELETED MATCHER_NOT_DELETED
%start file
+%token MATCHER_RULENAME
%token <str> MATCHER_STRING
%token <str> MATCHER_SECTION
%token <str> MATCHER_INTEGER
;
instruction:
-condition filtering MATCHER_EOL
-| condition filtering
+name condition filtering MATCHER_EOL
+| name condition filtering
{
if (matcher_parse_op == MATCHER_PARSE_NO_EOL)
YYACCEPT;
else {
- matcher_parsererror("parse error");
+ matcher_parsererror("parse error a");
+ YYERROR;
+ }
+}
+| name
+{
+ if (matcher_parse_op == MATCHER_PARSE_NAME)
+ YYACCEPT;
+ else {
+ matcher_parsererror("parse error b");
YYERROR;
}
}
if (matcher_parse_op == MATCHER_PARSE_CONDITION)
YYACCEPT;
else {
- matcher_parsererror("parse error");
+ matcher_parsererror("parse error c");
YYERROR;
}
}
if (matcher_parse_op == MATCHER_PARSE_FILTERING_ACTION)
YYACCEPT;
else {
- matcher_parsererror("parse error");
+ matcher_parsererror("parse error d");
YYERROR;
}
}
| MATCHER_EOL
;
+name:
+MATCHER_RULENAME MATCHER_STRING
+{
+ name = g_strdup($2);
+}
+
filtering:
filtering_action_list
{
- filtering = filteringprop_new(cond, action_list);
-
+ filtering = filteringprop_new(name, cond, action_list);
+ g_free(name);
+ name = NULL;
if (enable_compatibility) {
prefs_filtering = &filtering_rules;
if (action_list != NULL) {
#include "prefs_filtering_action.h"
enum {
+ PREFS_FILTERING_NAME,
PREFS_FILTERING_RULE,
PREFS_FILTERING_PROP,
N_PREFS_FILTERING_COLUMNS
GtkWidget *window;
GtkWidget *ok_btn;
+ GtkWidget *name_entry;
GtkWidget *cond_entry;
GtkWidget *action_entry;
static GtkListStore* prefs_filtering_create_data_store (void);
static gint prefs_filtering_list_view_insert_rule (GtkListStore *list_store,
gint row,
+ const gchar *name,
const gchar *rule,
gboolean prop);
static gchar *prefs_filtering_list_view_get_rule (GtkWidget *list,
gint row);
+static gchar *prefs_filtering_list_view_get_rule_name (GtkWidget *list,
+ gint row);
static GtkWidget *prefs_filtering_list_view_create (void);
static void prefs_filtering_create_list_view_columns (GtkWidget *list_view);
GtkWidget *confirm_area;
GtkWidget *vbox1;
- GtkWidget *hbox1;
GtkWidget *reg_hbox;
GtkWidget *arrow;
GtkWidget *btn_hbox;
+ GtkWidget *name_label;
+ GtkWidget *name_entry;
GtkWidget *cond_label;
GtkWidget *cond_entry;
GtkWidget *cond_btn;
GtkWidget *up_btn;
GtkWidget *down_btn;
GtkWidget *bottom_btn;
+ GtkWidget *table;
static GdkGeometry geometry;
debug_print("Creating filtering configuration window...\n");
vbox1 = gtk_vbox_new (FALSE, VSPACING);
gtk_widget_show (vbox1);
- gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox1, FALSE, TRUE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
- cond_label = gtk_label_new (_("Condition"));
- gtk_widget_show (cond_label);
- gtk_misc_set_alignment (GTK_MISC (cond_label), 0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox1), cond_label, FALSE, FALSE, 0);
+ table = gtk_table_new(3, 3, FALSE);
+ gtk_widget_show(table);
+ gtk_box_pack_start (GTK_BOX (vbox1), table, TRUE, TRUE, 0);
+
- hbox1 = gtk_hbox_new (FALSE, VSPACING);
- gtk_widget_show (hbox1);
- gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
+ name_label = gtk_label_new (_("Name: "));
+ gtk_widget_show (name_label);
+ gtk_misc_set_alignment (GTK_MISC (name_label), 1, 0.5);
+ gtk_table_attach (GTK_TABLE (table), name_label, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ name_entry = gtk_entry_new ();
+ gtk_widget_show (name_entry);
+ gtk_table_attach (GTK_TABLE (table), name_entry, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
+ (GtkAttachOptions) (0), 0, 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,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
cond_entry = gtk_entry_new ();
gtk_widget_show (cond_entry);
- gtk_box_pack_start (GTK_BOX (hbox1), cond_entry, TRUE, TRUE, 0);
+ gtk_table_attach (GTK_TABLE (table), cond_entry, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
+ (GtkAttachOptions) (0), 0, 0);
cond_btn = gtk_button_new_with_label (_("Define ..."));
gtk_widget_show (cond_btn);
- gtk_box_pack_start (GTK_BOX (hbox1), cond_btn, FALSE, FALSE, 0);
+ gtk_table_attach (GTK_TABLE (table), cond_btn, 2, 3, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 2, 2);
g_signal_connect(G_OBJECT (cond_btn), "clicked",
G_CALLBACK(prefs_filtering_condition_define),
NULL);
- action_label = gtk_label_new (_("Action"));
+ action_label = gtk_label_new (_("Action: "));
gtk_widget_show (action_label);
- gtk_misc_set_alignment (GTK_MISC (action_label), 0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox1), action_label, FALSE, FALSE, 0);
-
- hbox1 = gtk_hbox_new (FALSE, VSPACING);
- gtk_widget_show (hbox1);
- gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
+ gtk_misc_set_alignment (GTK_MISC (action_label), 1, 0.5);
+ gtk_table_attach (GTK_TABLE (table), action_label, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
action_entry = gtk_entry_new ();
gtk_widget_show (action_entry);
- gtk_box_pack_start (GTK_BOX (hbox1), action_entry, TRUE, TRUE, 0);
+ gtk_table_attach (GTK_TABLE (table), action_entry, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_FILL|GTK_EXPAND),
+ (GtkAttachOptions) (0), 0, 0);
action_btn = gtk_button_new_with_label (_("Define ..."));
gtk_widget_show (action_btn);
- gtk_box_pack_start (GTK_BOX (hbox1), action_btn, FALSE, FALSE, 0);
+ gtk_table_attach (GTK_TABLE (table), action_btn, 2, 3, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 2, 2);
g_signal_connect(G_OBJECT (action_btn), "clicked",
G_CALLBACK(prefs_filtering_action_define),
NULL);
-
+
/* register / substitute / delete */
-
reg_hbox = gtk_hbox_new (FALSE, 4);
gtk_widget_show (reg_hbox);
gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
cond_hbox = gtk_hbox_new (FALSE, 8);
gtk_widget_show (cond_hbox);
- gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
+ 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);
filtering.window = window;
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;
/* add the place holder (New) at row 0 */
prefs_filtering_list_view_insert_rule(list_store, -1,
+ _("(New)"),
_("(New)"),
FALSE);
subst_char(cond_str, '\t', ':');
prefs_filtering_list_view_insert_rule(list_store, -1,
+ prop->name,
cond_str, TRUE);
g_free(cond_str);
static void prefs_filtering_reset_dialog(void)
{
+ gtk_entry_set_text(GTK_ENTRY(filtering.name_entry), "");
gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), "");
gtk_entry_set_text(GTK_ENTRY(filtering.action_entry), "");
}
/* FIXME: this strcmp() is bogus: "(New)" should never
* be inserted in the storage */
if (strcmp(filtering_str, _("(New)")) != 0) {
+ gchar *name = prefs_filtering_list_view_get_rule_name(filtering.cond_list_view, row);
prop = matcher_parser_get_filtering(filtering_str);
g_free(filtering_str);
- if (prop)
+ if (prop) {
+ prop->name = name;
prefs_filtering =
g_slist_append(prefs_filtering, prop);
+ }
}
row++;
GtkTreeView *list_view = GTK_TREE_VIEW(filtering.cond_list_view);
gchar *str;
GtkListStore *list_store;
-
+ gchar *name = NULL;
+
str = filteringprop_to_string(prop);
if (str == NULL)
return -1;
+
+ if (prop && prop->name)
+ name = prop->name;
list_store = GTK_LIST_STORE(gtk_tree_view_get_model(list_view));
- row = prefs_filtering_list_view_insert_rule(list_store, row, str, prop != NULL);
+ row = prefs_filtering_list_view_insert_rule(list_store, row, name, str, prop != NULL);
g_free(str);
static FilteringProp * prefs_filtering_dialog_to_filtering(gboolean alert)
{
MatcherList * cond;
+ gchar * name = NULL;
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);
+
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;
}
- prop = filteringprop_new(cond, action_list);
+ prop = filteringprop_new(name, cond, action_list);
fail:
+ g_free(name);
g_free(cond_str);
g_free(action_str);
return prop;
if (matcher_str == NULL) {
return;
}
+
+ if (prop->name != NULL)
+ gtk_entry_set_text(GTK_ENTRY(filtering.name_entry), prop->name);
gtk_entry_set_text(GTK_ENTRY(filtering.cond_entry), matcher_str);
static GtkListStore* prefs_filtering_create_data_store(void)
{
return gtk_list_store_new(N_PREFS_FILTERING_COLUMNS,
+ G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
-1);
*/
static gint prefs_filtering_list_view_insert_rule(GtkListStore *list_store,
gint row,
+ const gchar *name,
const gchar *rule,
gboolean prop)
{
/* append new */
gtk_list_store_append(list_store, &iter);
gtk_list_store_set(list_store, &iter,
+ PREFS_FILTERING_NAME, name,
PREFS_FILTERING_RULE, rule,
PREFS_FILTERING_PROP, prop,
-1);
} else {
/* change existing */
gtk_list_store_set(list_store, &iter,
+ PREFS_FILTERING_NAME, name,
PREFS_FILTERING_RULE, rule,
-1);
return row;
return result;
}
+static gchar *prefs_filtering_list_view_get_rule_name(GtkWidget *list, gint row)
+{
+ GtkTreeView *list_view = GTK_TREE_VIEW(list);
+ GtkTreeModel *model = gtk_tree_view_get_model(list_view);
+ GtkTreeIter iter;
+ gchar *result = NULL;
+
+ if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, row))
+ return NULL;
+
+ gtk_tree_model_get(model, &iter,
+ PREFS_FILTERING_NAME, &result,
+ -1);
+
+ return result;
+}
+
/*!
*\brief Create list view for filtering
*/
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes
- (_("Current filtering/processing rules"),
+ (_("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
+ (_("Rule"),
renderer,
"text", PREFS_FILTERING_RULE,
NULL);
if (has_prop) {
FilteringProp *prop;
gchar *filtering_str = NULL;
-
+ gchar *name = NULL;
+
gtk_tree_model_get(model, &iter,
PREFS_FILTERING_RULE, &filtering_str,
-1);
+ gtk_tree_model_get(model, &iter,
+ PREFS_FILTERING_NAME, &name,
+ -1);
prop = matcher_parser_get_filtering(filtering_str);
if (prop) {
+ prop->name = g_strdup(name);
prefs_filtering_select_set(prop);
filteringprop_free(prop);
}
-
+ g_free(name);
g_free(filtering_str);
} else
prefs_filtering_reset_dialog();