2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <gdk/gdkkeysyms.h>
37 #include "prefs_matcher.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
46 #include "alertpanel.h"
49 static struct Matcher {
54 GtkWidget *criteria_entry;
55 GtkWidget *header_entry;
56 GtkWidget *header_label;
57 GtkWidget *value_entry;
58 GtkWidget *value_label;
59 GtkWidget *predicate_label;
60 GtkWidget *predicate_entry;
61 GtkWidget *case_chkbtn;
62 GtkWidget *regexp_chkbtn;
63 GtkWidget *bool_op_entry;
65 GtkWidget *cond_clist;
68 /* choice in the list */
76 CRITERIA_TO_OR_CC = 5,
77 CRITERIA_NEWSGROUPS = 6,
78 CRITERIA_AGE_GREATER = 7,
79 CRITERIA_AGE_LOWER = 8,
81 CRITERIA_HEADERS_PART = 10,
82 CRITERIA_BODY_PART = 11,
86 gchar * bool_op_text [] = {
90 gchar * predicate_text [] = {
91 "contains", "does not contain"
94 gchar * criteria_text [] = {
95 "All messages", "Subject",
96 "From", "To", "Cc", "To or Cc",
98 "Age greater than", "Age lower than",
99 "Header", "Headers part",
100 "Body part", "Whole message"
103 gint criteria_get_from_string(gchar * text)
107 for(i = 0 ; i < (gint) (sizeof(criteria_text) / sizeof(gchar *)) ;
109 if (strcmp(_(criteria_text[i]), text) == 0)
115 gint predicate_get_from_string(gchar * text)
119 for(i = 0 ; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)) ;
121 if (strcmp(_(predicate_text[i]), text) == 0)
128 PREDICATE_CONTAINS = 0,
129 PREDICATE_DOES_NOT_CONTAIN = 1
132 /* static MatcherList * tmp_list; */
133 /* static MatcherProp * tmp_matcher; */
136 parameter name, default value, pointer to the prefs variable, data type,
137 pointer to the widget pointer,
138 pointer to the function for data setting,
139 pointer to the function for widget setting
143 #define VSPACING_NARROW 4
144 #define DEFAULT_ENTRY_WIDTH 80
145 #define PREFSBUFSIZE 1024
147 /* widget creating functions */
148 static void prefs_matcher_create (void);
150 static void prefs_matcher_set_dialog (void);
153 static void prefs_matcher_set_list (void);
154 static gint prefs_matcher_clist_set_row (gint row);
157 /* callback functions */
160 static void prefs_matcher_select_dest_cb (void);
162 static void prefs_matcher_register_cb (void);
163 static void prefs_matcher_substitute_cb (void);
164 static void prefs_matcher_delete_cb (void);
165 static void prefs_matcher_up (void);
166 static void prefs_matcher_down (void);
168 static void prefs_matcher_select (GtkCList *clist,
175 static void prefs_matcher_dest_radio_button_toggled (void);
176 static void prefs_matcher_notrecv_radio_button_toggled (void);
179 static void prefs_matcher_key_pressed (GtkWidget *widget,
182 static void prefs_matcher_close (void);
183 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
185 static void prefs_matcher_criteria_select(GtkEditable *editable,
188 void prefs_matcher_open(MatcherList * matchers)
190 inc_autocheck_timer_remove();
192 if (!matcher.window) {
193 prefs_matcher_create();
196 manage_window_set_transient(GTK_WINDOW(matcher.window));
197 gtk_widget_grab_focus(matcher.close_btn);
199 /* tmp_matchers = matchers; */
200 prefs_matcher_set_dialog();
202 gtk_widget_show(matcher.window);
205 static void prefs_matcher_create(void)
209 GtkWidget *close_btn;
210 GtkWidget *confirm_area;
219 GtkWidget *header_combo;
220 GtkWidget *header_entry;
221 GtkWidget *header_label;
222 GtkWidget *criteria_combo;
223 GtkWidget *criteria_entry;
224 GtkWidget *criteria_label;
225 GtkWidget *value_label;
226 GtkWidget *value_entry;
227 GtkWidget *predicate_combo;
228 GtkWidget *predicate_entry;
229 GtkWidget *predicate_label;
230 GtkWidget *bool_op_combo;
231 GtkWidget *bool_op_entry;
232 GtkWidget *bool_op_label;
234 GtkWidget *regexp_chkbtn;
235 GtkWidget *case_chkbtn;
241 GtkWidget *subst_btn;
244 GtkWidget *cond_hbox;
245 GtkWidget *cond_scrolledwin;
246 GtkWidget *cond_clist;
255 gchar *title[] = {_("Registered rules")};
257 debug_print(_("Creating matcher setting window...\n"));
259 window = gtk_window_new (GTK_WINDOW_DIALOG);
260 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
261 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
262 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
263 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
265 vbox = gtk_vbox_new (FALSE, 6);
266 gtk_widget_show (vbox);
267 gtk_container_add (GTK_CONTAINER (window), vbox);
269 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
270 NULL, NULL, NULL, NULL);
271 gtk_widget_show (confirm_area);
272 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
273 gtk_widget_grab_default (close_btn);
275 gtk_window_set_title (GTK_WINDOW(window),
276 _("Condition setting"));
277 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
278 GTK_SIGNAL_FUNC(prefs_matcher_deleted), NULL);
279 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
280 GTK_SIGNAL_FUNC(prefs_matcher_key_pressed), NULL);
281 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
282 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
283 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
284 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
285 gtk_signal_connect (GTK_OBJECT(close_btn), "clicked",
286 GTK_SIGNAL_FUNC(prefs_matcher_close), NULL);
288 vbox1 = gtk_vbox_new (FALSE, VSPACING);
289 gtk_widget_show (vbox1);
290 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
291 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
293 table1 = gtk_table_new (2, 3, FALSE);
294 gtk_widget_show (table1);
296 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, TRUE, 0);
297 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
298 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
300 /* criteria combo box */
302 criteria_label = gtk_label_new (_("Match type"));
303 gtk_widget_show (criteria_label);
304 gtk_misc_set_alignment (GTK_MISC (criteria_label), 0, 0.5);
305 gtk_table_attach (GTK_TABLE (table1), criteria_label, 0, 1, 0, 1,
308 criteria_combo = gtk_combo_new ();
309 gtk_widget_show (criteria_combo);
313 for(i = 0 ; i < (gint) (sizeof(criteria_text) / sizeof(gchar *)) ;
315 combo_items = g_list_append(combo_items,
316 (gpointer) _(criteria_text[i]));
318 gtk_combo_set_popdown_strings(GTK_COMBO(criteria_combo), combo_items);
320 g_list_free(combo_items);
322 gtk_widget_set_usize (criteria_combo, 120, -1);
323 gtk_table_attach (GTK_TABLE (table1), criteria_combo, 0, 1, 1, 2,
325 criteria_entry = GTK_COMBO(criteria_combo)->entry;
326 gtk_signal_connect (GTK_OBJECT (criteria_entry), "changed",
327 GTK_SIGNAL_FUNC (prefs_matcher_criteria_select),
330 criteria_entry = GTK_COMBO (criteria_combo)->entry;
331 gtk_entry_set_editable (GTK_ENTRY (criteria_entry), FALSE);
335 header_label = gtk_label_new (_("Header name"));
336 gtk_widget_show (header_label);
337 gtk_misc_set_alignment (GTK_MISC (header_label), 0, 0.5);
338 gtk_table_attach (GTK_TABLE (table1), header_label, 1, 2, 0, 1,
341 header_combo = gtk_combo_new ();
342 gtk_widget_show (header_combo);
343 gtk_widget_set_usize (header_combo, 96, -1);
344 gtkut_combo_set_items (GTK_COMBO (header_combo),
345 "Subject", "From", "To", "Cc", "Reply-To",
346 "Sender", "X-ML-Name", "X-List", "X-Sequence",
349 gtk_table_attach (GTK_TABLE (table1), header_combo, 1, 2, 1, 2,
351 header_entry = GTK_COMBO (header_combo)->entry;
352 gtk_entry_set_editable (GTK_ENTRY (header_entry), TRUE);
356 value_label = gtk_label_new (_("Value"));
357 gtk_widget_show (value_label);
358 gtk_misc_set_alignment (GTK_MISC (value_label), 0, 0.5);
359 gtk_table_attach (GTK_TABLE (table1), value_label, 2, 3, 0, 1,
362 value_entry = gtk_entry_new ();
363 gtk_widget_show (value_entry);
364 gtk_widget_set_usize (value_entry, 200, -1);
365 gtk_table_attach (GTK_TABLE (table1), value_entry, 2, 3, 1, 2,
371 vbox2 = gtk_vbox_new (FALSE, VSPACING);
372 gtk_widget_show (vbox2);
373 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
375 hbox1 = gtk_hbox_new (FALSE, 8);
376 gtk_widget_show (hbox1);
377 gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, TRUE, 0);
379 predicate_label = gtk_label_new (_("Predicate"));
380 gtk_widget_show (predicate_label);
381 gtk_box_pack_start (GTK_BOX (hbox1), predicate_label,
384 predicate_combo = gtk_combo_new ();
385 gtk_widget_show (predicate_combo);
386 gtk_widget_set_usize (predicate_combo, 120, -1);
387 predicate_entry = GTK_COMBO(predicate_combo)->entry;
388 gtk_entry_set_editable (GTK_ENTRY (predicate_entry), FALSE);
392 for(i = 0 ; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)) ;
394 combo_items = g_list_append(combo_items,
395 (gpointer) _(predicate_text[i]));
397 gtk_combo_set_popdown_strings(GTK_COMBO(predicate_combo), combo_items);
399 g_list_free(combo_items);
401 gtk_box_pack_start (GTK_BOX (hbox1), predicate_combo,
404 vbox3 = gtk_vbox_new (FALSE, 0);
405 gtk_widget_show (vbox3);
406 gtk_box_pack_start (GTK_BOX (hbox1), vbox3, TRUE, TRUE, 0);
408 PACK_CHECK_BUTTON (vbox3, case_chkbtn, _("Case sensitive"));
409 PACK_CHECK_BUTTON (vbox3, regexp_chkbtn, _("Use regexp"));
411 /* register / substitute / delete */
413 reg_hbox = gtk_hbox_new (FALSE, 4);
414 gtk_widget_show (reg_hbox);
415 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
417 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
418 gtk_widget_show (arrow);
419 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
420 gtk_widget_set_usize (arrow, -1, 16);
422 btn_hbox = gtk_hbox_new (TRUE, 4);
423 gtk_widget_show (btn_hbox);
424 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
426 reg_btn = gtk_button_new_with_label (_("Register"));
427 gtk_widget_show (reg_btn);
428 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
429 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
430 GTK_SIGNAL_FUNC (prefs_matcher_register_cb), NULL);
432 subst_btn = gtk_button_new_with_label (_(" Substitute "));
433 gtk_widget_show (subst_btn);
434 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
435 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
436 GTK_SIGNAL_FUNC (prefs_matcher_substitute_cb),
439 del_btn = gtk_button_new_with_label (_("Delete"));
440 gtk_widget_show (del_btn);
441 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
442 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
443 GTK_SIGNAL_FUNC (prefs_matcher_delete_cb), NULL);
445 /* boolean operation */
448 hbox1 = gtk_hbox_new (TRUE, 4);
449 gtk_widget_show (btn_hbox);
450 gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, FALSE, 0);
453 bool_op_label = gtk_label_new (_("Boolean Op"));
454 gtk_misc_set_alignment (GTK_MISC (value_label), 0, 0.5);
455 gtk_widget_show (bool_op_label);
456 gtk_box_pack_start (GTK_BOX (btn_hbox), bool_op_label,
459 bool_op_combo = gtk_combo_new ();
460 gtk_widget_show (bool_op_combo);
461 gtk_widget_set_usize (bool_op_combo, 50, -1);
462 bool_op_entry = GTK_COMBO(bool_op_combo)->entry;
463 gtk_entry_set_editable (GTK_ENTRY (bool_op_entry), FALSE);
467 for(i = 0 ; i < (gint) (sizeof(bool_op_text) / sizeof(gchar *)) ;
469 combo_items = g_list_append(combo_items,
470 (gpointer) _(bool_op_text[i]));
472 gtk_combo_set_popdown_strings(GTK_COMBO(bool_op_combo), combo_items);
474 g_list_free(combo_items);
476 gtk_box_pack_start (GTK_BOX (btn_hbox), bool_op_combo,
479 cond_hbox = gtk_hbox_new (FALSE, 8);
480 gtk_widget_show (cond_hbox);
481 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
483 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
484 gtk_widget_show (cond_scrolledwin);
485 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
486 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
488 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
489 GTK_POLICY_AUTOMATIC,
490 GTK_POLICY_AUTOMATIC);
492 cond_clist = gtk_clist_new_with_titles(1, title);
493 gtk_widget_show (cond_clist);
494 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
495 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
496 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
497 GTK_SELECTION_BROWSE);
498 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
501 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
502 GTK_SIGNAL_FUNC (prefs_matcher_select), NULL);
505 btn_vbox = gtk_vbox_new (FALSE, 8);
506 gtk_widget_show (btn_vbox);
507 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
509 up_btn = gtk_button_new_with_label (_("Up"));
510 gtk_widget_show (up_btn);
511 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
512 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
513 GTK_SIGNAL_FUNC (prefs_matcher_up), NULL);
515 down_btn = gtk_button_new_with_label (_("Down"));
516 gtk_widget_show (down_btn);
517 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
518 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
519 GTK_SIGNAL_FUNC (prefs_matcher_down), NULL);
521 gtk_widget_show_all(window);
523 matcher.window = window;
524 matcher.close_btn = close_btn;
526 matcher.criteria_entry = criteria_entry;
527 matcher.header_entry = header_entry;
528 matcher.header_label = header_label;
529 matcher.value_entry = value_entry;
530 matcher.value_label = value_label;
531 matcher.predicate_label = predicate_label;
532 matcher.predicate_entry = predicate_entry;
533 matcher.case_chkbtn = case_chkbtn;
534 matcher.regexp_chkbtn = regexp_chkbtn;
536 matcher.cond_clist = cond_clist;
540 void prefs_matcher_read_config(void)
544 gchar buf[PREFSBUFSIZE];
547 debug_print(_("Reading matcher configuration...\n"));
549 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
550 if ((fp = fopen(rcpath, "r")) == NULL) {
551 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
558 /* remove all previous matcher list */
561 while (prefs_common.fltlist != NULL) {
562 flt = (Matcher *)prefs_common.fltlist->data;
564 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
568 while (fgets(buf, sizeof(buf), fp) != NULL) {
570 flt = filter_read_str(buf);
572 prefs_common.fltlist =
573 g_slist_append(prefs_common.fltlist, flt);
580 void prefs_filter_write_config(void)
586 debug_print(_("Writing filter configuration...\n"));
588 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
589 if ((pfile = prefs_write_open(rcpath)) == NULL) {
590 g_warning(_("failed to write configuration to file\n"));
595 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
596 Filter *flt = (Filter *)cur->data;
599 fstr = filter_get_str(flt);
600 if (fputs(fstr, pfile->fp) == EOF ||
601 fputc('\n', pfile->fp) == EOF) {
602 FILE_OP_ERROR(rcpath, "fputs || fputc");
603 prefs_write_close_revert(pfile);
613 if (prefs_write_close(pfile) < 0) {
614 g_warning(_("failed to write configuration to file\n"));
620 static void prefs_matcher_set_dialog(void)
623 GtkCList *clist = GTK_CLIST(filter.cond_clist);
628 gtk_clist_freeze(clist);
629 gtk_clist_clear(clist);
631 cond_str[0] = _("(New)");
632 row = gtk_clist_append(clist, cond_str);
633 gtk_clist_set_row_data(clist, row, NULL);
635 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
636 Filter *flt = (Filter *)cur->data;
638 cond_str[0] = filter_get_str(flt);
639 subst_char(cond_str[0], '\t', ':');
640 row = gtk_clist_append(clist, cond_str);
641 gtk_clist_set_row_data(clist, row, flt);
646 gtk_clist_thaw(clist);
649 gtk_entry_set_text(GTK_ENTRY(matcher.criteria_entry),
650 _(criteria_text[0]));
651 gtk_entry_set_text(GTK_ENTRY(matcher.predicate_entry),
652 _(predicate_text[0]));
653 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), "");
656 static void prefs_filter_set_list(void)
661 g_slist_free(prefs_common.fltlist);
662 prefs_common.fltlist = NULL;
664 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
666 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
672 #define GET_ENTRY(entry) \
673 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
675 static gint prefs_filter_clist_set_row(gint row)
677 GtkCList *clist = GTK_CLIST(filter.cond_clist);
682 g_return_val_if_fail(row != 0, -1);
684 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
685 GET_ENTRY(filter.dest_entry);
687 entry_text = FILTER_NOT_RECEIVE;
688 if (entry_text[0] == '\0') {
689 alertpanel_error(_("Destination is not set."));
692 GET_ENTRY(filter.hdr_entry1);
693 if (entry_text[0] == '\0') {
694 alertpanel_error(_("Header name is not set."));
698 flt = g_new0(Filter, 1);
700 flt->name1 = g_strdup(entry_text);
702 GET_ENTRY(filter.key_entry1);
703 if (entry_text[0] != '\0')
704 flt->body1 = g_strdup(entry_text);
706 GET_ENTRY(filter.hdr_entry2);
707 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
708 flt->name2 = g_strdup(entry_text);
710 GET_ENTRY(filter.key_entry2);
711 if (entry_text[0] != '\0')
712 flt->body2 = g_strdup(entry_text);
715 GET_ENTRY(filter.pred_entry1);
716 if (!strcmp(entry_text, _("contains")))
717 flt->flag1 = FLT_CONTAIN;
718 GET_ENTRY(filter.pred_entry2);
719 if (!strcmp(entry_text, _("contains")))
720 flt->flag2 = FLT_CONTAIN;
722 GET_ENTRY(filter.op_entry);
723 if (!strcmp(entry_text, "and"))
728 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
729 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
730 flt->dest = g_strdup(entry_text);
731 flt->action = FLT_MOVE;
733 flt->action = FLT_NOTRECV;
735 cond_str[0] = filter_get_str(flt);
736 subst_char(cond_str[0], '\t', ':');
739 row = gtk_clist_append(clist, cond_str);
743 gtk_clist_set_text(clist, row, 0, cond_str[0]);
744 tmpflt = gtk_clist_get_row_data(clist, row);
749 gtk_clist_set_row_data(clist, row, flt);
753 prefs_filter_set_list();
759 static gint prefs_matcher_get_scoring_from_criteria(gint criteria_id)
761 switch (criteria_id) {
764 case CRITERIA_SUBJECT:
765 return MATCHING_SUBJECT;
767 return MATCHING_FROM;
772 case CRITERIA_TO_OR_CC:
773 return MATCHING_TO_OR_CC;
774 case CRITERIA_NEWSGROUPS:
775 return MATCHING_NEWSGROUPS;
776 case CRITERIA_AGE_GREATER:
777 return MATCHING_AGE_GREATER;
778 case CRITERIA_AGE_LOWER:
779 return MATCHING_AGE_LOWER;
780 case CRITERIA_HEADER:
781 return MATCHING_HEADER;
782 case CRITERIA_HEADERS_PART:
783 return MATCHING_HEADERS_PART;
784 case CRITERIA_BODY_PART:
785 return MATCHING_BODY_PART;
786 case CRITERIA_MESSAGE:
787 return MATCHING_MESSAGE;
793 static gint prefs_matcher_not_criteria(gint matcher_criteria)
795 switch(matcher_criteria) {
796 case MATCHING_SUBJECT:
797 return MATCHING_NOT_SUBJECT;
799 return MATCHING_NOT_FROM;
801 return MATCHING_NOT_TO;
803 return MATCHING_NOT_CC;
804 case MATCHING_TO_OR_CC:
805 return MATCHING_NOT_TO_AND_NOT_CC;
806 case MATCHING_NEWSGROUPS:
807 return MATCHING_NOT_NEWSGROUPS;
808 case MATCHING_HEADER:
809 return MATCHING_NOT_HEADER;
810 case MATCHING_HEADERS_PART:
811 return MATCHING_NOT_HEADERS_PART;
812 case MATCHING_MESSAGE:
813 return MATCHING_NOT_MESSAGE;
814 case MATCHING_BODY_PART:
815 return MATCHING_NOT_BODY_PART;
817 return matcher_criteria;
821 static MatcherProp * prefs_match_dialog_to_matcher()
823 MatcherProp * matcherprop;
829 gboolean case_sensitive;
834 value_criteria = criteria_get_from_string(gtk_entry_get_text(GTK_ENTRY(matcher.criteria_entry)));
835 criteria = prefs_matcher_get_scoring_from_criteria(value_criteria);
837 value_pred = predicate_get_from_string(gtk_entry_get_text(GTK_ENTRY(matcher.predicate_entry)));
839 use_regexp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn));
840 case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn));
842 if (value_pred != PREDICATE_CONTAINS)
843 criteria = prefs_matcher_not_criteria(criteria);
847 matchtype = MATCHING_REGEXP;
849 matchtype = MATCHING_REGEXPCASE;
853 matchtype = MATCHING_MATCH;
855 matchtype = MATCHING_MATCHCASE;
862 switch (value_criteria) {
866 case CRITERIA_SUBJECT:
870 case CRITERIA_TO_OR_CC:
871 case CRITERIA_NEWSGROUPS:
872 case CRITERIA_HEADERS_PART:
873 case CRITERIA_BODY_PART:
874 case CRITERIA_MESSAGE:
875 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
878 case CRITERIA_AGE_GREATER:
879 case CRITERIA_AGE_LOWER:
880 age = atoi(gtk_entry_get_text(GTK_ENTRY(matcher.value_entry)));
883 case CRITERIA_HEADER:
884 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_entry));
885 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
889 matcherprop = matcherprop_new(criteria, header, matchtype, expr, age);
894 static void prefs_matcher_register_cb(void)
897 MatcherProp * matcherprop;
898 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
902 matcherprop = prefs_match_dialog_to_matcher();
903 matcher_str = matcherprop_to_string(matcherprop);
904 matcherprop_free(matcherprop);
906 cond_str[0] = matcher_str;
907 row = gtk_clist_append(clist, cond_str);
911 static void prefs_matcher_substitute_cb(void)
914 GtkCList *clist = GTK_CLIST(filter.cond_clist);
918 if (!clist->selection) return;
920 row = GPOINTER_TO_INT(clist->selection->data);
921 if (row == 0) return;
923 flt = gtk_clist_get_row_data(clist, row);
926 prefs_filter_clist_set_row(row);
930 static void prefs_matcher_delete_cb(void)
933 GtkCList *clist = GTK_CLIST(filter.cond_clist);
937 if (!clist->selection) return;
938 row = GPOINTER_TO_INT(clist->selection->data);
939 if (row == 0) return;
941 if (alertpanel(_("Delete rule"),
942 _("Do you really want to delete this rule?"),
943 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
946 flt = gtk_clist_get_row_data(clist, row);
948 gtk_clist_remove(clist, row);
949 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
953 static void prefs_matcher_up(void)
956 GtkCList *clist = GTK_CLIST(filter.cond_clist);
959 if (!clist->selection) return;
961 row = GPOINTER_TO_INT(clist->selection->data);
963 gtk_clist_row_move(clist, row, row - 1);
964 prefs_filter_set_list();
969 static void prefs_matcher_down(void)
972 GtkCList *clist = GTK_CLIST(filter.cond_clist);
975 if (!clist->selection) return;
977 row = GPOINTER_TO_INT(clist->selection->data);
978 if (row > 0 && row < clist->rows - 1) {
979 gtk_clist_row_move(clist, row, row + 1);
980 prefs_filter_set_list();
986 #define ENTRY_SET_TEXT(entry, str) \
987 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
989 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
993 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
994 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
997 flt = gtk_clist_get_row_data(clist, row);
1001 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
1002 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
1003 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
1004 ENTRY_SET_TEXT(filter.hdr_entry2,
1005 flt->name2 ? flt->name2 : _("(none)"));
1006 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
1008 ENTRY_SET_TEXT(filter.pred_entry1,
1009 FLT_IS_CONTAIN(flt->flag1)
1010 ? _("contains") : _("not contain"));
1011 ENTRY_SET_TEXT(filter.pred_entry2,
1012 FLT_IS_CONTAIN(flt->flag2)
1013 ? _("contains") : _("not contain"));
1015 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
1016 flt->cond == FLT_OR ? "or" : "and");
1017 if (flt->action == FLT_NOTRECV)
1018 gtk_toggle_button_set_active
1019 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
1021 gtk_toggle_button_set_active
1022 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
1025 static void prefs_filter_dest_radio_button_toggled(void)
1027 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
1028 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
1031 static void prefs_filter_notrecv_radio_button_toggled(void)
1033 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
1034 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
1039 static void prefs_matcher_criteria_select(GtkEditable *editable,
1044 value = criteria_get_from_string(gtk_entry_get_text(GTK_ENTRY(matcher.criteria_entry)));
1048 gtk_widget_set_sensitive(matcher.header_entry, FALSE);
1049 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1050 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1051 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1052 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1053 gtk_widget_set_sensitive(matcher.predicate_entry, FALSE);
1054 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1055 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1058 case CRITERIA_SUBJECT:
1062 case CRITERIA_TO_OR_CC:
1063 case CRITERIA_NEWSGROUPS:
1064 case CRITERIA_HEADERS_PART:
1065 case CRITERIA_BODY_PART:
1066 case CRITERIA_MESSAGE:
1067 gtk_widget_set_sensitive(matcher.header_entry, FALSE);
1068 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1069 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1070 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1071 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1072 gtk_widget_set_sensitive(matcher.predicate_entry, TRUE);
1073 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1074 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1077 case CRITERIA_AGE_GREATER:
1078 case CRITERIA_AGE_LOWER:
1079 gtk_widget_set_sensitive(matcher.header_entry, FALSE);
1080 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1081 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1082 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1083 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1084 gtk_widget_set_sensitive(matcher.predicate_entry, FALSE);
1085 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1086 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1089 case CRITERIA_HEADER:
1090 gtk_widget_set_sensitive(matcher.header_entry, TRUE);
1091 gtk_widget_set_sensitive(matcher.header_label, TRUE);
1092 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1093 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1094 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1095 gtk_widget_set_sensitive(matcher.predicate_entry, TRUE);
1096 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1097 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1102 static void prefs_matcher_key_pressed(GtkWidget *widget, GdkEventKey *event,
1105 if (event && event->keyval == GDK_Escape)
1106 prefs_matcher_close();
1109 static void prefs_matcher_close(void)
1111 /* prefs_filter_write_config(); */
1112 gtk_widget_hide(matcher.window);
1114 inc_autocheck_timer_set();
1118 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
1121 prefs_matcher_close();