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 *predicate_combo;
55 GtkWidget *predicate_flag_combo;
56 GtkWidget *header_combo;
58 GtkWidget *criteria_list;
60 GtkWidget *predicate_list;
61 GtkWidget *predicate_label;
62 GtkWidget *predicate_flag_list;
64 GtkWidget *bool_op_list;
66 GtkWidget *header_entry;
67 GtkWidget *header_label;
68 GtkWidget *value_entry;
69 GtkWidget *value_label;
70 GtkWidget *case_chkbtn;
71 GtkWidget *regexp_chkbtn;
73 GtkWidget *cond_clist;
76 /* choice in the list */
85 CRITERIA_TO_OR_CC = 5,
86 CRITERIA_NEWSGROUPS = 6,
87 CRITERIA_INREPLYTO = 7,
88 CRITERIA_REFERENCES = 8,
89 CRITERIA_AGE_GREATER = 9,
90 CRITERIA_AGE_LOWER = 10,
92 CRITERIA_HEADERS_PART = 12,
93 CRITERIA_BODY_PART = 13,
94 CRITERIA_MESSAGE = 14,
99 CRITERIA_DELETED = 18,
100 CRITERIA_REPLIED = 19,
101 CRITERIA_FORWARDED = 20,
103 CRITERIA_SCORE_GREATER = 21,
104 CRITERIA_SCORE_LOWER = 22
112 gchar * bool_op_text [] = {
117 PREDICATE_CONTAINS = 0,
118 PREDICATE_DOES_NOT_CONTAIN = 1
121 gchar * predicate_text [] = {
122 "contains", "does not contain"
126 PREDICATE_FLAG_ENABLED = 0,
127 PREDICATE_FLAG_DISABLED = 1
130 gchar * predicate_flag_text [] = {
131 "flag enabled", "flag disabled"
134 gchar * criteria_text [] = {
135 "All messages", "Subject",
136 "From", "To", "Cc", "To or Cc",
137 "Newsgroups", "In reply to", "References",
138 "Age greater than", "Age lower than",
139 "Header", "Headers part",
140 "Body part", "Whole message",
141 "Unread flag", "New flag",
142 "Marked flag", "Deleted flag",
143 "Replied flag", "Forwarded flag",
144 "Score greater than", "Score lower than"
147 static gint get_sel_from_list(GtkList * list)
153 sel = list->selection->data;
154 for(child = list->children ; child != NULL ;
155 child = g_list_next(child)) {
156 if (child->data == sel)
164 static PrefsMatcherSignal * matchers_callback;
167 #define VSPACING_NARROW 4
168 #define DEFAULT_ENTRY_WIDTH 80
169 #define PREFSBUFSIZE 1024
171 /* widget creating functions */
172 static void prefs_matcher_create (void);
174 static void prefs_matcher_set_dialog (MatcherList * matchers);
177 static void prefs_matcher_set_list (void);
178 static gint prefs_matcher_clist_set_row (gint row);
181 /* callback functions */
184 static void prefs_matcher_select_dest_cb (void);
186 static void prefs_matcher_register_cb (void);
187 static void prefs_matcher_substitute_cb (void);
188 static void prefs_matcher_delete_cb (void);
189 static void prefs_matcher_up (void);
190 static void prefs_matcher_down (void);
191 static void prefs_matcher_select (GtkCList *clist,
196 static void prefs_matcher_key_pressed (GtkWidget *widget,
199 static void prefs_matcher_ok (void);
200 static void prefs_matcher_cancel (void);
201 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
203 static void prefs_matcher_criteria_select(GtkList *list,
206 static MatcherList * prefs_matcher_get_list(void);
208 void prefs_matcher_open(MatcherList * matchers, PrefsMatcherSignal * cb)
210 inc_autocheck_timer_remove();
212 if (!matcher.window) {
213 prefs_matcher_create();
216 manage_window_set_transient(GTK_WINDOW(matcher.window));
217 gtk_widget_grab_focus(matcher.ok_btn);
219 matchers_callback = cb;
221 prefs_matcher_set_dialog(matchers);
223 gtk_widget_show(matcher.window);
226 static void prefs_matcher_create(void)
231 GtkWidget *cancel_btn;
232 GtkWidget *confirm_area;
241 GtkWidget *header_combo;
242 GtkWidget *header_entry;
243 GtkWidget *header_label;
244 GtkWidget *criteria_combo;
245 GtkWidget *criteria_list;
246 GtkWidget *criteria_label;
247 GtkWidget *value_label;
248 GtkWidget *value_entry;
249 GtkWidget *predicate_combo;
250 GtkWidget *predicate_list;
251 GtkWidget *predicate_flag_combo;
252 GtkWidget *predicate_flag_list;
253 GtkWidget *predicate_label;
254 GtkWidget *bool_op_combo;
255 GtkWidget *bool_op_list;
256 GtkWidget *bool_op_label;
258 GtkWidget *regexp_chkbtn;
259 GtkWidget *case_chkbtn;
265 GtkWidget *subst_btn;
268 GtkWidget *cond_hbox;
269 GtkWidget *cond_scrolledwin;
270 GtkWidget *cond_clist;
279 gchar *title[] = {_("Registered rules")};
281 debug_print(_("Creating matcher setting window...\n"));
283 window = gtk_window_new (GTK_WINDOW_DIALOG);
284 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
285 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
286 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
287 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
289 vbox = gtk_vbox_new (FALSE, 6);
290 gtk_widget_show (vbox);
291 gtk_container_add (GTK_CONTAINER (window), vbox);
293 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
294 &cancel_btn, _("Cancel"), NULL, NULL);
295 gtk_widget_show (confirm_area);
296 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
297 gtk_widget_grab_default (ok_btn);
299 gtk_window_set_title (GTK_WINDOW(window),
300 _("Condition setting"));
301 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
302 GTK_SIGNAL_FUNC(prefs_matcher_deleted), NULL);
303 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
304 GTK_SIGNAL_FUNC(prefs_matcher_key_pressed), NULL);
305 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
306 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
307 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
308 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
309 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
310 GTK_SIGNAL_FUNC(prefs_matcher_ok), NULL);
311 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
312 GTK_SIGNAL_FUNC(prefs_matcher_cancel), NULL);
314 vbox1 = gtk_vbox_new (FALSE, VSPACING);
315 gtk_widget_show (vbox1);
316 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
317 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
319 table1 = gtk_table_new (2, 3, FALSE);
320 gtk_widget_show (table1);
322 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
323 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
324 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
326 /* criteria combo box */
328 criteria_label = gtk_label_new (_("Match type"));
329 gtk_widget_show (criteria_label);
330 gtk_misc_set_alignment (GTK_MISC (criteria_label), 0, 0.5);
331 gtk_table_attach (GTK_TABLE (table1), criteria_label, 0, 1, 0, 1,
334 criteria_combo = gtk_combo_new ();
335 gtk_widget_show (criteria_combo);
339 for(i = 0 ; i < (gint) (sizeof(criteria_text) / sizeof(gchar *)) ;
341 combo_items = g_list_append(combo_items,
342 (gpointer) _(criteria_text[i]));
344 gtk_combo_set_popdown_strings(GTK_COMBO(criteria_combo), combo_items);
346 g_list_free(combo_items);
348 gtk_widget_set_usize (criteria_combo, 120, -1);
349 gtk_table_attach (GTK_TABLE (table1), criteria_combo, 0, 1, 1, 2,
351 criteria_list = GTK_COMBO(criteria_combo)->list;
352 gtk_signal_connect (GTK_OBJECT (criteria_list), "select-child",
353 GTK_SIGNAL_FUNC (prefs_matcher_criteria_select),
356 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(criteria_combo)->entry),
361 header_label = gtk_label_new (_("Header name"));
362 gtk_widget_show (header_label);
363 gtk_misc_set_alignment (GTK_MISC (header_label), 0, 0.5);
364 gtk_table_attach (GTK_TABLE (table1), header_label, 1, 2, 0, 1,
367 header_combo = gtk_combo_new ();
368 gtk_widget_show (header_combo);
369 gtk_widget_set_usize (header_combo, 96, -1);
370 gtkut_combo_set_items (GTK_COMBO (header_combo),
371 "Subject", "From", "To", "Cc", "Reply-To",
372 "Sender", "X-ML-Name", "X-List", "X-Sequence",
375 gtk_table_attach (GTK_TABLE (table1), header_combo, 1, 2, 1, 2,
377 header_entry = GTK_COMBO (header_combo)->entry;
378 gtk_entry_set_editable (GTK_ENTRY (header_entry), TRUE);
382 value_label = gtk_label_new (_("Value"));
383 gtk_widget_show (value_label);
384 gtk_misc_set_alignment (GTK_MISC (value_label), 0, 0.5);
385 gtk_table_attach (GTK_TABLE (table1), value_label, 2, 3, 0, 1,
386 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
388 value_entry = gtk_entry_new ();
389 gtk_widget_show (value_entry);
390 gtk_widget_set_usize (value_entry, 200, -1);
391 gtk_table_attach (GTK_TABLE (table1), value_entry, 2, 3, 1, 2,
392 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
397 vbox2 = gtk_vbox_new (FALSE, VSPACING);
398 gtk_widget_show (vbox2);
399 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
401 hbox1 = gtk_hbox_new (FALSE, 8);
402 gtk_widget_show (hbox1);
403 gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0);
405 predicate_label = gtk_label_new (_("Predicate"));
406 gtk_widget_show (predicate_label);
407 gtk_box_pack_start (GTK_BOX (hbox1), predicate_label,
410 predicate_combo = gtk_combo_new ();
411 gtk_widget_show (predicate_combo);
412 gtk_widget_set_usize (predicate_combo, 120, -1);
413 predicate_list = GTK_COMBO(predicate_combo)->list;
414 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(predicate_combo)->entry),
419 for(i = 0 ; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)) ;
421 combo_items = g_list_append(combo_items,
422 (gpointer) _(predicate_text[i]));
424 gtk_combo_set_popdown_strings(GTK_COMBO(predicate_combo), combo_items);
426 g_list_free(combo_items);
428 gtk_box_pack_start (GTK_BOX (hbox1), predicate_combo,
433 predicate_flag_combo = gtk_combo_new ();
434 gtk_widget_hide (predicate_flag_combo);
435 gtk_widget_set_usize (predicate_flag_combo, 120, -1);
436 predicate_flag_list = GTK_COMBO(predicate_flag_combo)->list;
437 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(predicate_flag_combo)->entry), FALSE);
441 for(i = 0 ; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)) ;
443 combo_items = g_list_append(combo_items, (gpointer) _(predicate_flag_text[i]));
445 gtk_combo_set_popdown_strings(GTK_COMBO(predicate_flag_combo),
448 g_list_free(combo_items);
450 gtk_box_pack_start (GTK_BOX (hbox1), predicate_flag_combo,
453 vbox3 = gtk_vbox_new (FALSE, 0);
454 gtk_widget_show (vbox3);
455 gtk_box_pack_start (GTK_BOX (hbox1), vbox3, FALSE, FALSE, 0);
457 PACK_CHECK_BUTTON (vbox3, case_chkbtn, _("Case sensitive"));
458 PACK_CHECK_BUTTON (vbox3, regexp_chkbtn, _("Use regexp"));
460 /* register / substitute / delete */
462 reg_hbox = gtk_hbox_new (FALSE, 4);
463 gtk_widget_show (reg_hbox);
464 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
466 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
467 gtk_widget_show (arrow);
468 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
469 gtk_widget_set_usize (arrow, -1, 16);
471 btn_hbox = gtk_hbox_new (TRUE, 4);
472 gtk_widget_show (btn_hbox);
473 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
475 reg_btn = gtk_button_new_with_label (_("Register"));
476 gtk_widget_show (reg_btn);
477 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
478 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
479 GTK_SIGNAL_FUNC (prefs_matcher_register_cb), NULL);
481 subst_btn = gtk_button_new_with_label (_(" Substitute "));
482 gtk_widget_show (subst_btn);
483 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
484 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
485 GTK_SIGNAL_FUNC (prefs_matcher_substitute_cb),
488 del_btn = gtk_button_new_with_label (_("Delete"));
489 gtk_widget_show (del_btn);
490 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
491 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
492 GTK_SIGNAL_FUNC (prefs_matcher_delete_cb), NULL);
494 /* boolean operation */
496 bool_op_label = gtk_label_new (_("Boolean Op"));
497 gtk_misc_set_alignment (GTK_MISC (value_label), 0, 0.5);
498 gtk_widget_show (bool_op_label);
499 gtk_box_pack_start (GTK_BOX (btn_hbox), bool_op_label,
502 bool_op_combo = gtk_combo_new ();
503 gtk_widget_show (bool_op_combo);
504 gtk_widget_set_usize (bool_op_combo, 50, -1);
505 bool_op_list = GTK_COMBO(bool_op_combo)->list;
506 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(bool_op_combo)->entry),
511 for(i = 0 ; i < (gint) (sizeof(bool_op_text) / sizeof(gchar *)) ;
513 combo_items = g_list_append(combo_items,
514 (gpointer) _(bool_op_text[i]));
516 gtk_combo_set_popdown_strings(GTK_COMBO(bool_op_combo), combo_items);
518 g_list_free(combo_items);
520 gtk_box_pack_start (GTK_BOX (btn_hbox), bool_op_combo,
523 cond_hbox = gtk_hbox_new (FALSE, 8);
524 gtk_widget_show (cond_hbox);
525 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
527 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
528 gtk_widget_show (cond_scrolledwin);
529 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
530 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
532 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
533 GTK_POLICY_AUTOMATIC,
534 GTK_POLICY_AUTOMATIC);
536 cond_clist = gtk_clist_new_with_titles(1, title);
537 gtk_widget_show (cond_clist);
538 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
539 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
540 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
541 GTK_SELECTION_BROWSE);
542 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
544 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
545 GTK_SIGNAL_FUNC (prefs_matcher_select), NULL);
547 btn_vbox = gtk_vbox_new (FALSE, 8);
548 gtk_widget_show (btn_vbox);
549 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
551 up_btn = gtk_button_new_with_label (_("Up"));
552 gtk_widget_show (up_btn);
553 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
554 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
555 GTK_SIGNAL_FUNC (prefs_matcher_up), NULL);
557 down_btn = gtk_button_new_with_label (_("Down"));
558 gtk_widget_show (down_btn);
559 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
560 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
561 GTK_SIGNAL_FUNC (prefs_matcher_down), NULL);
563 gtk_widget_show_all(window);
565 matcher.window = window;
567 matcher.ok_btn = ok_btn;
569 matcher.criteria_list = criteria_list;
570 matcher.header_combo = header_combo;
571 matcher.header_entry = header_entry;
572 matcher.header_label = header_label;
573 matcher.value_entry = value_entry;
574 matcher.value_label = value_label;
575 matcher.predicate_label = predicate_label;
576 matcher.predicate_list = predicate_list;
577 matcher.predicate_combo = predicate_combo;
578 matcher.predicate_flag_list = predicate_flag_list;
579 matcher.predicate_flag_combo = predicate_flag_combo;
580 matcher.case_chkbtn = case_chkbtn;
581 matcher.regexp_chkbtn = regexp_chkbtn;
582 matcher.bool_op_list = bool_op_list;
584 matcher.cond_clist = cond_clist;
587 static gint prefs_matcher_clist_set_row(gint row, MatcherProp * prop)
589 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
594 cond_str[0] = _("(New)");
595 return gtk_clist_append(clist, cond_str);
598 matcher_str = matcherprop_to_string(prop);
599 cond_str[0] = matcher_str;
601 row = gtk_clist_append(clist, cond_str);
603 gtk_clist_set_text(clist, row, 0, cond_str[0]);
609 static void prefs_matcher_reset_condition(void)
611 gtk_list_select_item(GTK_LIST(matcher.criteria_list), 0);
612 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
613 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), "");
614 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), "");
617 static void prefs_matcher_set_dialog(MatcherList * matchers)
619 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
621 gboolean bool_op = 0;
623 gtk_clist_freeze(clist);
624 gtk_clist_clear(clist);
626 prefs_matcher_clist_set_row(-1, NULL);
627 if (matchers != NULL) {
628 for (cur = matchers->matchers ; cur != NULL ;
629 cur = g_slist_next(cur)) {
631 prop = (MatcherProp *) cur->data;
632 prefs_matcher_clist_set_row(-1, prop);
635 bool_op = matchers->bool_and;
638 gtk_clist_thaw(clist);
640 gtk_list_select_item(GTK_LIST(matcher.bool_op_list), bool_op);
642 prefs_matcher_reset_condition();
645 static MatcherList * prefs_matcher_get_list(void)
652 GSList * matcher_list;
653 MatcherList * matchers;
657 while (gtk_clist_get_text(GTK_CLIST(matcher.cond_clist),
658 row, 0, &matcher_str)) {
660 if (strcmp(matcher_str, _("(New)")) != 0) {
662 prop = matcherprop_parse(&tmp);
667 matcher_list = g_slist_append(matcher_list, prop);
672 bool_and = get_sel_from_list(GTK_LIST(matcher.bool_op_list));
674 matchers = matcherlist_new(matcher_list, bool_and);
679 static gint prefs_matcher_get_criteria_from_matching(gint matching_id)
681 switch(matching_id) {
684 case MATCHING_NOT_UNREAD:
685 case MATCHING_UNREAD:
686 return CRITERIA_UNREAD;
687 case MATCHING_NOT_NEW:
690 case MATCHING_NOT_MARKED:
691 case MATCHING_MARKED:
692 return CRITERIA_MARKED;
693 case MATCHING_NOT_DELETED:
694 case MATCHING_DELETED:
695 return CRITERIA_DELETED;
697 case MATCHING_NOT_REPLIED:
698 case MATCHING_REPLIED:
699 return CRITERIA_REPLIED;
700 case MATCHING_NOT_FORWARDED:
701 case MATCHING_FORWARDED:
702 return CRITERIA_FORWARDED;
703 case MATCHING_NOT_SUBJECT:
704 case MATCHING_SUBJECT:
705 return CRITERIA_SUBJECT;
706 case MATCHING_NOT_FROM:
708 return CRITERIA_FROM;
709 case MATCHING_NOT_TO:
712 case MATCHING_NOT_CC:
715 case MATCHING_NOT_NEWSGROUPS:
716 case MATCHING_NEWSGROUPS:
717 return CRITERIA_NEWSGROUPS;
718 case MATCHING_NOT_INREPLYTO:
719 case MATCHING_INREPLYTO:
720 return CRITERIA_INREPLYTO;
721 case MATCHING_NOT_REFERENCES:
722 case MATCHING_REFERENCES:
723 return CRITERIA_REFERENCES;
724 case MATCHING_NOT_TO_AND_NOT_CC:
725 case MATCHING_TO_OR_CC:
726 return CRITERIA_TO_OR_CC;
727 case MATCHING_NOT_BODY_PART:
728 case MATCHING_BODY_PART:
729 return CRITERIA_BODY_PART;
730 case MATCHING_NOT_MESSAGE:
731 case MATCHING_MESSAGE:
732 return CRITERIA_MESSAGE;
734 case MATCHING_NOT_HEADERS_PART:
735 case MATCHING_HEADERS_PART:
736 return CRITERIA_HEADERS_PART;
737 case MATCHING_NOT_HEADER:
738 case MATCHING_HEADER:
739 return CRITERIA_HEADER;
740 case MATCHING_AGE_GREATER:
741 return CRITERIA_AGE_GREATER;
742 case MATCHING_AGE_LOWER:
743 return CRITERIA_AGE_LOWER;
744 case MATCHING_SCORE_GREATER:
745 return CRITERIA_SCORE_GREATER;
746 case MATCHING_SCORE_LOWER:
747 return CRITERIA_SCORE_LOWER;
753 static gint prefs_matcher_get_matching_from_criteria(gint criteria_id)
755 switch (criteria_id) {
758 case CRITERIA_UNREAD:
759 return MATCHING_UNREAD;
762 case CRITERIA_MARKED:
763 return MATCHING_MARKED;
764 case CRITERIA_DELETED:
765 return MATCHING_DELETED;
766 case CRITERIA_REPLIED:
767 return MATCHING_REPLIED;
768 case CRITERIA_FORWARDED:
769 return MATCHING_FORWARDED;
770 case CRITERIA_SUBJECT:
771 return MATCHING_SUBJECT;
773 return MATCHING_FROM;
778 case CRITERIA_TO_OR_CC:
779 return MATCHING_TO_OR_CC;
780 case CRITERIA_NEWSGROUPS:
781 return MATCHING_NEWSGROUPS;
782 case CRITERIA_INREPLYTO:
783 return MATCHING_INREPLYTO;
784 case CRITERIA_REFERENCES:
785 return MATCHING_REFERENCES;
786 case CRITERIA_AGE_GREATER:
787 return MATCHING_AGE_GREATER;
788 case CRITERIA_AGE_LOWER:
789 return MATCHING_AGE_LOWER;
790 case CRITERIA_SCORE_GREATER:
791 return MATCHING_SCORE_GREATER;
792 case CRITERIA_SCORE_LOWER:
793 return MATCHING_SCORE_LOWER;
794 case CRITERIA_HEADER:
795 return MATCHING_HEADER;
796 case CRITERIA_HEADERS_PART:
797 return MATCHING_HEADERS_PART;
798 case CRITERIA_BODY_PART:
799 return MATCHING_BODY_PART;
800 case CRITERIA_MESSAGE:
801 return MATCHING_MESSAGE;
807 static gint prefs_matcher_not_criteria(gint matcher_criteria)
809 switch(matcher_criteria) {
810 case MATCHING_UNREAD:
811 return MATCHING_NOT_UNREAD;
813 return MATCHING_NOT_NEW;
814 case MATCHING_MARKED:
815 return MATCHING_NOT_MARKED;
816 case MATCHING_DELETED:
817 return MATCHING_NOT_DELETED;
818 case MATCHING_REPLIED:
819 return MATCHING_NOT_REPLIED;
820 case MATCHING_FORWARDED:
821 return MATCHING_NOT_FORWARDED;
822 case MATCHING_SUBJECT:
823 return MATCHING_NOT_SUBJECT;
825 return MATCHING_NOT_FROM;
827 return MATCHING_NOT_TO;
829 return MATCHING_NOT_CC;
830 case MATCHING_TO_OR_CC:
831 return MATCHING_NOT_TO_AND_NOT_CC;
832 case MATCHING_NEWSGROUPS:
833 return MATCHING_NOT_NEWSGROUPS;
834 case MATCHING_INREPLYTO:
835 return MATCHING_NOT_INREPLYTO;
836 case MATCHING_REFERENCES:
837 return MATCHING_NOT_REFERENCES;
838 case MATCHING_HEADER:
839 return MATCHING_NOT_HEADER;
840 case MATCHING_HEADERS_PART:
841 return MATCHING_NOT_HEADERS_PART;
842 case MATCHING_MESSAGE:
843 return MATCHING_NOT_MESSAGE;
844 case MATCHING_BODY_PART:
845 return MATCHING_NOT_BODY_PART;
847 return matcher_criteria;
851 static MatcherProp * prefs_matcher_dialog_to_matcher()
853 MatcherProp * matcherprop;
857 gint value_pred_flag;
860 gboolean case_sensitive;
866 value_criteria = get_sel_from_list(GTK_LIST(matcher.criteria_list));
868 criteria = prefs_matcher_get_matching_from_criteria(value_criteria);
870 value_pred = get_sel_from_list(GTK_LIST(matcher.predicate_list));
871 value_pred_flag = get_sel_from_list(GTK_LIST(matcher.predicate_flag_list));
873 use_regexp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn));
874 case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn));
876 switch (value_criteria) {
877 case CRITERIA_UNREAD:
879 case CRITERIA_MARKED:
880 case CRITERIA_DELETED:
881 case CRITERIA_REPLIED:
882 case CRITERIA_FORWARDED:
883 if (value_pred_flag == PREDICATE_FLAG_DISABLED)
884 criteria = prefs_matcher_not_criteria(criteria);
886 case CRITERIA_SUBJECT:
890 case CRITERIA_TO_OR_CC:
891 case CRITERIA_NEWSGROUPS:
892 case CRITERIA_INREPLYTO:
893 case CRITERIA_REFERENCES:
894 case CRITERIA_HEADERS_PART:
895 case CRITERIA_BODY_PART:
896 case CRITERIA_MESSAGE:
897 case CRITERIA_AGE_GREATER:
898 case CRITERIA_AGE_LOWER:
899 case CRITERIA_HEADER:
900 if (value_pred == PREDICATE_DOES_NOT_CONTAIN)
901 criteria = prefs_matcher_not_criteria(criteria);
907 matchtype = MATCHING_REGEXP;
909 matchtype = MATCHING_REGEXPCASE;
913 matchtype = MATCHING_MATCH;
915 matchtype = MATCHING_MATCHCASE;
922 switch (value_criteria) {
924 case CRITERIA_UNREAD:
926 case CRITERIA_MARKED:
927 case CRITERIA_DELETED:
928 case CRITERIA_REPLIED:
929 case CRITERIA_FORWARDED:
932 case CRITERIA_SUBJECT:
936 case CRITERIA_TO_OR_CC:
937 case CRITERIA_NEWSGROUPS:
938 case CRITERIA_INREPLYTO:
939 case CRITERIA_REFERENCES:
940 case CRITERIA_HEADERS_PART:
941 case CRITERIA_BODY_PART:
942 case CRITERIA_MESSAGE:
943 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
947 alertpanel_error(_("Match string is not set."));
953 case CRITERIA_AGE_GREATER:
954 case CRITERIA_AGE_LOWER:
955 case CRITERIA_SCORE_GREATER:
956 case CRITERIA_SCORE_LOWER:
957 value_str = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
959 if (*value_str == '\0') {
960 alertpanel_error(_("Value is not set."));
964 value = atoi(value_str);
968 case CRITERIA_HEADER:
970 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_entry));
971 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
973 if (*header == '\0') {
974 alertpanel_error(_("Header name is not set."));
979 alertpanel_error(_("Match string is not set."));
986 matcherprop = matcherprop_new(criteria, header, matchtype,
992 static void prefs_matcher_register_cb(void)
994 MatcherProp * matcherprop;
996 matcherprop = prefs_matcher_dialog_to_matcher();
997 if (matcherprop == NULL)
1000 prefs_matcher_clist_set_row(-1, matcherprop);
1002 matcherprop_free(matcherprop);
1004 prefs_matcher_reset_condition();
1007 static void prefs_matcher_substitute_cb(void)
1009 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1011 MatcherProp * matcherprop;
1013 row = GPOINTER_TO_INT(clist->selection->data);
1017 matcherprop = prefs_matcher_dialog_to_matcher();
1018 if (matcherprop == NULL)
1021 prefs_matcher_clist_set_row(row, matcherprop);
1023 matcherprop_free(matcherprop);
1025 prefs_matcher_reset_condition();
1028 static void prefs_matcher_delete_cb(void)
1030 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1033 if (!clist->selection) return;
1034 row = GPOINTER_TO_INT(clist->selection->data);
1038 gtk_clist_remove(clist, row);
1041 static void prefs_matcher_up(void)
1043 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1046 if (!clist->selection) return;
1048 row = GPOINTER_TO_INT(clist->selection->data);
1050 gtk_clist_row_move(clist, row, row - 1);
1053 static void prefs_matcher_down(void)
1055 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1058 if (!clist->selection) return;
1060 row = GPOINTER_TO_INT(clist->selection->data);
1061 if (row >= 1 && row < clist->rows - 1)
1062 gtk_clist_row_move(clist, row, row + 1);
1065 static void prefs_matcher_select(GtkCList *clist, gint row, gint column,
1068 gchar * matcher_str;
1071 gboolean negative_cond;
1074 if (!gtk_clist_get_text(GTK_CLIST(matcher.cond_clist),
1075 row, 0, &matcher_str))
1078 negative_cond = FALSE;
1081 prefs_matcher_reset_condition();
1086 prop = matcherprop_parse(&tmp);
1090 criteria = prefs_matcher_get_criteria_from_matching(prop->criteria);
1092 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1095 switch(prop->criteria) {
1096 case MATCHING_NOT_UNREAD:
1097 case MATCHING_NOT_NEW:
1098 case MATCHING_NOT_MARKED:
1099 case MATCHING_NOT_DELETED:
1100 case MATCHING_NOT_REPLIED:
1101 case MATCHING_NOT_FORWARDED:
1102 case MATCHING_NOT_SUBJECT:
1103 case MATCHING_NOT_FROM:
1104 case MATCHING_NOT_TO:
1105 case MATCHING_NOT_CC:
1106 case MATCHING_NOT_NEWSGROUPS:
1107 case MATCHING_NOT_INREPLYTO:
1108 case MATCHING_NOT_REFERENCES:
1109 case MATCHING_NOT_TO_AND_NOT_CC:
1110 case MATCHING_NOT_BODY_PART:
1111 case MATCHING_NOT_MESSAGE:
1112 case MATCHING_NOT_HEADERS_PART:
1113 case MATCHING_NOT_HEADER:
1114 negative_cond = TRUE;
1118 switch(prop->criteria) {
1122 case MATCHING_NOT_SUBJECT:
1123 case MATCHING_NOT_FROM:
1124 case MATCHING_NOT_TO:
1125 case MATCHING_NOT_CC:
1126 case MATCHING_NOT_TO_AND_NOT_CC:
1127 case MATCHING_NOT_NEWSGROUPS:
1128 case MATCHING_NOT_INREPLYTO:
1129 case MATCHING_NOT_REFERENCES:
1130 case MATCHING_NOT_HEADERS_PART:
1131 case MATCHING_NOT_BODY_PART:
1132 case MATCHING_NOT_MESSAGE:
1133 case MATCHING_SUBJECT:
1137 case MATCHING_TO_OR_CC:
1138 case MATCHING_NEWSGROUPS:
1139 case MATCHING_INREPLYTO:
1140 case MATCHING_REFERENCES:
1141 case MATCHING_HEADERS_PART:
1142 case MATCHING_BODY_PART:
1143 case MATCHING_MESSAGE:
1144 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1147 case MATCHING_AGE_GREATER:
1148 case MATCHING_AGE_LOWER:
1149 case MATCHING_SCORE_GREATER:
1150 case MATCHING_SCORE_LOWER:
1151 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), itos(prop->value));
1154 case MATCHING_NOT_HEADER:
1155 case MATCHING_HEADER:
1156 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), prop->header);
1157 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1162 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 1);
1164 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
1166 switch(prop->matchtype) {
1167 case MATCHING_MATCH:
1168 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1169 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1172 case MATCHING_MATCHCASE:
1173 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1174 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1177 case MATCHING_REGEXP:
1178 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1179 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1182 case MATCHING_REGEXPCASE:
1183 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1184 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1189 static void prefs_matcher_criteria_select(GtkList *list,
1195 value = get_sel_from_list(GTK_LIST(matcher.criteria_list));
1199 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1200 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1201 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1202 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1203 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1204 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1205 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1206 gtk_widget_hide(matcher.predicate_combo);
1207 gtk_widget_show(matcher.predicate_flag_combo);
1208 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1209 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1212 case CRITERIA_UNREAD:
1214 case CRITERIA_MARKED:
1215 case CRITERIA_DELETED:
1216 case CRITERIA_REPLIED:
1217 case CRITERIA_FORWARDED:
1218 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1219 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1220 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1221 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1222 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1223 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1224 gtk_widget_set_sensitive(matcher.predicate_flag_combo, TRUE);
1225 gtk_widget_hide(matcher.predicate_combo);
1226 gtk_widget_show(matcher.predicate_flag_combo);
1227 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1228 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1231 case CRITERIA_SUBJECT:
1235 case CRITERIA_TO_OR_CC:
1236 case CRITERIA_NEWSGROUPS:
1237 case CRITERIA_INREPLYTO:
1238 case CRITERIA_REFERENCES:
1239 case CRITERIA_HEADERS_PART:
1240 case CRITERIA_BODY_PART:
1241 case CRITERIA_MESSAGE:
1242 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1243 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1244 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1245 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1246 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1247 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1248 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1249 gtk_widget_show(matcher.predicate_combo);
1250 gtk_widget_hide(matcher.predicate_flag_combo);
1251 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1252 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1255 case CRITERIA_AGE_GREATER:
1256 case CRITERIA_AGE_LOWER:
1257 case CRITERIA_SCORE_GREATER:
1258 case CRITERIA_SCORE_LOWER:
1259 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1260 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1261 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1262 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1263 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1264 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1265 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1266 gtk_widget_show(matcher.predicate_combo);
1267 gtk_widget_hide(matcher.predicate_flag_combo);
1268 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1269 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1272 case CRITERIA_HEADER:
1273 gtk_widget_set_sensitive(matcher.header_combo, TRUE);
1274 gtk_widget_set_sensitive(matcher.header_label, TRUE);
1275 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1276 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1277 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1278 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1279 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1280 gtk_widget_show(matcher.predicate_combo);
1281 gtk_widget_hide(matcher.predicate_flag_combo);
1282 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1283 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1288 static void prefs_matcher_key_pressed(GtkWidget *widget, GdkEventKey *event,
1291 if (event && event->keyval == GDK_Escape)
1292 prefs_matcher_cancel();
1295 static void prefs_matcher_cancel(void)
1297 gtk_widget_hide(matcher.window);
1300 static void prefs_matcher_ok(void)
1302 MatcherList * matchers;
1304 matchers = prefs_matcher_get_list();
1305 if (matchers != NULL) {
1306 gtk_widget_hide(matcher.window);
1307 if (matchers_callback != NULL)
1308 matchers_callback(matchers);
1309 matcherlist_free(matchers);
1312 gtk_widget_hide(matcher.window);
1316 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
1319 prefs_matcher_cancel();