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_update_hscrollbar(void)
619 gint optwidth = gtk_clist_optimal_column_width(GTK_CLIST(matcher.cond_clist), 0);
620 gtk_clist_set_column_width(GTK_CLIST(matcher.cond_clist), 0, optwidth);
623 static void prefs_matcher_set_dialog(MatcherList * matchers)
625 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
627 gboolean bool_op = 0;
629 gtk_clist_freeze(clist);
630 gtk_clist_clear(clist);
632 prefs_matcher_clist_set_row(-1, NULL);
633 if (matchers != NULL) {
634 for (cur = matchers->matchers ; cur != NULL ;
635 cur = g_slist_next(cur)) {
637 prop = (MatcherProp *) cur->data;
638 prefs_matcher_clist_set_row(-1, prop);
641 bool_op = matchers->bool_and;
644 prefs_matcher_update_hscrollbar();
646 gtk_clist_thaw(clist);
648 gtk_list_select_item(GTK_LIST(matcher.bool_op_list), bool_op);
650 prefs_matcher_reset_condition();
653 static MatcherList * prefs_matcher_get_list(void)
660 GSList * matcher_list;
661 MatcherList * matchers;
665 while (gtk_clist_get_text(GTK_CLIST(matcher.cond_clist),
666 row, 0, &matcher_str)) {
668 if (strcmp(matcher_str, _("(New)")) != 0) {
670 prop = matcherprop_parse(&tmp);
675 matcher_list = g_slist_append(matcher_list, prop);
680 bool_and = get_sel_from_list(GTK_LIST(matcher.bool_op_list));
682 matchers = matcherlist_new(matcher_list, bool_and);
687 static gint prefs_matcher_get_criteria_from_matching(gint matching_id)
689 switch(matching_id) {
692 case MATCHING_NOT_UNREAD:
693 case MATCHING_UNREAD:
694 return CRITERIA_UNREAD;
695 case MATCHING_NOT_NEW:
698 case MATCHING_NOT_MARKED:
699 case MATCHING_MARKED:
700 return CRITERIA_MARKED;
701 case MATCHING_NOT_DELETED:
702 case MATCHING_DELETED:
703 return CRITERIA_DELETED;
705 case MATCHING_NOT_REPLIED:
706 case MATCHING_REPLIED:
707 return CRITERIA_REPLIED;
708 case MATCHING_NOT_FORWARDED:
709 case MATCHING_FORWARDED:
710 return CRITERIA_FORWARDED;
711 case MATCHING_NOT_SUBJECT:
712 case MATCHING_SUBJECT:
713 return CRITERIA_SUBJECT;
714 case MATCHING_NOT_FROM:
716 return CRITERIA_FROM;
717 case MATCHING_NOT_TO:
720 case MATCHING_NOT_CC:
723 case MATCHING_NOT_NEWSGROUPS:
724 case MATCHING_NEWSGROUPS:
725 return CRITERIA_NEWSGROUPS;
726 case MATCHING_NOT_INREPLYTO:
727 case MATCHING_INREPLYTO:
728 return CRITERIA_INREPLYTO;
729 case MATCHING_NOT_REFERENCES:
730 case MATCHING_REFERENCES:
731 return CRITERIA_REFERENCES;
732 case MATCHING_NOT_TO_AND_NOT_CC:
733 case MATCHING_TO_OR_CC:
734 return CRITERIA_TO_OR_CC;
735 case MATCHING_NOT_BODY_PART:
736 case MATCHING_BODY_PART:
737 return CRITERIA_BODY_PART;
738 case MATCHING_NOT_MESSAGE:
739 case MATCHING_MESSAGE:
740 return CRITERIA_MESSAGE;
742 case MATCHING_NOT_HEADERS_PART:
743 case MATCHING_HEADERS_PART:
744 return CRITERIA_HEADERS_PART;
745 case MATCHING_NOT_HEADER:
746 case MATCHING_HEADER:
747 return CRITERIA_HEADER;
748 case MATCHING_AGE_GREATER:
749 return CRITERIA_AGE_GREATER;
750 case MATCHING_AGE_LOWER:
751 return CRITERIA_AGE_LOWER;
752 case MATCHING_SCORE_GREATER:
753 return CRITERIA_SCORE_GREATER;
754 case MATCHING_SCORE_LOWER:
755 return CRITERIA_SCORE_LOWER;
761 static gint prefs_matcher_get_matching_from_criteria(gint criteria_id)
763 switch (criteria_id) {
766 case CRITERIA_UNREAD:
767 return MATCHING_UNREAD;
770 case CRITERIA_MARKED:
771 return MATCHING_MARKED;
772 case CRITERIA_DELETED:
773 return MATCHING_DELETED;
774 case CRITERIA_REPLIED:
775 return MATCHING_REPLIED;
776 case CRITERIA_FORWARDED:
777 return MATCHING_FORWARDED;
778 case CRITERIA_SUBJECT:
779 return MATCHING_SUBJECT;
781 return MATCHING_FROM;
786 case CRITERIA_TO_OR_CC:
787 return MATCHING_TO_OR_CC;
788 case CRITERIA_NEWSGROUPS:
789 return MATCHING_NEWSGROUPS;
790 case CRITERIA_INREPLYTO:
791 return MATCHING_INREPLYTO;
792 case CRITERIA_REFERENCES:
793 return MATCHING_REFERENCES;
794 case CRITERIA_AGE_GREATER:
795 return MATCHING_AGE_GREATER;
796 case CRITERIA_AGE_LOWER:
797 return MATCHING_AGE_LOWER;
798 case CRITERIA_SCORE_GREATER:
799 return MATCHING_SCORE_GREATER;
800 case CRITERIA_SCORE_LOWER:
801 return MATCHING_SCORE_LOWER;
802 case CRITERIA_HEADER:
803 return MATCHING_HEADER;
804 case CRITERIA_HEADERS_PART:
805 return MATCHING_HEADERS_PART;
806 case CRITERIA_BODY_PART:
807 return MATCHING_BODY_PART;
808 case CRITERIA_MESSAGE:
809 return MATCHING_MESSAGE;
815 static gint prefs_matcher_not_criteria(gint matcher_criteria)
817 switch(matcher_criteria) {
818 case MATCHING_UNREAD:
819 return MATCHING_NOT_UNREAD;
821 return MATCHING_NOT_NEW;
822 case MATCHING_MARKED:
823 return MATCHING_NOT_MARKED;
824 case MATCHING_DELETED:
825 return MATCHING_NOT_DELETED;
826 case MATCHING_REPLIED:
827 return MATCHING_NOT_REPLIED;
828 case MATCHING_FORWARDED:
829 return MATCHING_NOT_FORWARDED;
830 case MATCHING_SUBJECT:
831 return MATCHING_NOT_SUBJECT;
833 return MATCHING_NOT_FROM;
835 return MATCHING_NOT_TO;
837 return MATCHING_NOT_CC;
838 case MATCHING_TO_OR_CC:
839 return MATCHING_NOT_TO_AND_NOT_CC;
840 case MATCHING_NEWSGROUPS:
841 return MATCHING_NOT_NEWSGROUPS;
842 case MATCHING_INREPLYTO:
843 return MATCHING_NOT_INREPLYTO;
844 case MATCHING_REFERENCES:
845 return MATCHING_NOT_REFERENCES;
846 case MATCHING_HEADER:
847 return MATCHING_NOT_HEADER;
848 case MATCHING_HEADERS_PART:
849 return MATCHING_NOT_HEADERS_PART;
850 case MATCHING_MESSAGE:
851 return MATCHING_NOT_MESSAGE;
852 case MATCHING_BODY_PART:
853 return MATCHING_NOT_BODY_PART;
855 return matcher_criteria;
859 static MatcherProp * prefs_matcher_dialog_to_matcher()
861 MatcherProp * matcherprop;
865 gint value_pred_flag;
868 gboolean case_sensitive;
874 value_criteria = get_sel_from_list(GTK_LIST(matcher.criteria_list));
876 criteria = prefs_matcher_get_matching_from_criteria(value_criteria);
878 value_pred = get_sel_from_list(GTK_LIST(matcher.predicate_list));
879 value_pred_flag = get_sel_from_list(GTK_LIST(matcher.predicate_flag_list));
881 use_regexp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn));
882 case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn));
884 switch (value_criteria) {
885 case CRITERIA_UNREAD:
887 case CRITERIA_MARKED:
888 case CRITERIA_DELETED:
889 case CRITERIA_REPLIED:
890 case CRITERIA_FORWARDED:
891 if (value_pred_flag == PREDICATE_FLAG_DISABLED)
892 criteria = prefs_matcher_not_criteria(criteria);
894 case CRITERIA_SUBJECT:
898 case CRITERIA_TO_OR_CC:
899 case CRITERIA_NEWSGROUPS:
900 case CRITERIA_INREPLYTO:
901 case CRITERIA_REFERENCES:
902 case CRITERIA_HEADERS_PART:
903 case CRITERIA_BODY_PART:
904 case CRITERIA_MESSAGE:
905 case CRITERIA_AGE_GREATER:
906 case CRITERIA_AGE_LOWER:
907 case CRITERIA_HEADER:
908 if (value_pred == PREDICATE_DOES_NOT_CONTAIN)
909 criteria = prefs_matcher_not_criteria(criteria);
915 matchtype = MATCHING_REGEXP;
917 matchtype = MATCHING_REGEXPCASE;
921 matchtype = MATCHING_MATCH;
923 matchtype = MATCHING_MATCHCASE;
930 switch (value_criteria) {
932 case CRITERIA_UNREAD:
934 case CRITERIA_MARKED:
935 case CRITERIA_DELETED:
936 case CRITERIA_REPLIED:
937 case CRITERIA_FORWARDED:
940 case CRITERIA_SUBJECT:
944 case CRITERIA_TO_OR_CC:
945 case CRITERIA_NEWSGROUPS:
946 case CRITERIA_INREPLYTO:
947 case CRITERIA_REFERENCES:
948 case CRITERIA_HEADERS_PART:
949 case CRITERIA_BODY_PART:
950 case CRITERIA_MESSAGE:
951 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
955 alertpanel_error(_("Match string is not set."));
961 case CRITERIA_AGE_GREATER:
962 case CRITERIA_AGE_LOWER:
963 case CRITERIA_SCORE_GREATER:
964 case CRITERIA_SCORE_LOWER:
965 value_str = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
967 if (*value_str == '\0') {
968 alertpanel_error(_("Value is not set."));
972 value = atoi(value_str);
976 case CRITERIA_HEADER:
978 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_entry));
979 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
981 if (*header == '\0') {
982 alertpanel_error(_("Header name is not set."));
987 alertpanel_error(_("Match string is not set."));
994 matcherprop = matcherprop_new(criteria, header, matchtype,
1000 static void prefs_matcher_register_cb(void)
1002 MatcherProp * matcherprop;
1004 matcherprop = prefs_matcher_dialog_to_matcher();
1005 if (matcherprop == NULL)
1008 prefs_matcher_clist_set_row(-1, matcherprop);
1010 matcherprop_free(matcherprop);
1012 prefs_matcher_reset_condition();
1013 prefs_matcher_update_hscrollbar();
1016 static void prefs_matcher_substitute_cb(void)
1018 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1020 MatcherProp * matcherprop;
1022 row = GPOINTER_TO_INT(clist->selection->data);
1026 matcherprop = prefs_matcher_dialog_to_matcher();
1027 if (matcherprop == NULL)
1030 prefs_matcher_clist_set_row(row, matcherprop);
1032 matcherprop_free(matcherprop);
1034 prefs_matcher_reset_condition();
1036 prefs_matcher_update_hscrollbar();
1039 static void prefs_matcher_delete_cb(void)
1041 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1044 if (!clist->selection) return;
1045 row = GPOINTER_TO_INT(clist->selection->data);
1049 gtk_clist_remove(clist, row);
1051 prefs_matcher_update_hscrollbar();
1054 static void prefs_matcher_up(void)
1056 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1059 if (!clist->selection) return;
1061 row = GPOINTER_TO_INT(clist->selection->data);
1063 gtk_clist_row_move(clist, row, row - 1);
1066 static void prefs_matcher_down(void)
1068 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
1071 if (!clist->selection) return;
1073 row = GPOINTER_TO_INT(clist->selection->data);
1074 if (row >= 1 && row < clist->rows - 1)
1075 gtk_clist_row_move(clist, row, row + 1);
1078 static void prefs_matcher_select(GtkCList *clist, gint row, gint column,
1081 gchar * matcher_str;
1084 gboolean negative_cond;
1087 if (!gtk_clist_get_text(GTK_CLIST(matcher.cond_clist),
1088 row, 0, &matcher_str))
1091 negative_cond = FALSE;
1094 prefs_matcher_reset_condition();
1099 prop = matcherprop_parse(&tmp);
1103 criteria = prefs_matcher_get_criteria_from_matching(prop->criteria);
1105 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1108 switch(prop->criteria) {
1109 case MATCHING_NOT_UNREAD:
1110 case MATCHING_NOT_NEW:
1111 case MATCHING_NOT_MARKED:
1112 case MATCHING_NOT_DELETED:
1113 case MATCHING_NOT_REPLIED:
1114 case MATCHING_NOT_FORWARDED:
1115 case MATCHING_NOT_SUBJECT:
1116 case MATCHING_NOT_FROM:
1117 case MATCHING_NOT_TO:
1118 case MATCHING_NOT_CC:
1119 case MATCHING_NOT_NEWSGROUPS:
1120 case MATCHING_NOT_INREPLYTO:
1121 case MATCHING_NOT_REFERENCES:
1122 case MATCHING_NOT_TO_AND_NOT_CC:
1123 case MATCHING_NOT_BODY_PART:
1124 case MATCHING_NOT_MESSAGE:
1125 case MATCHING_NOT_HEADERS_PART:
1126 case MATCHING_NOT_HEADER:
1127 negative_cond = TRUE;
1131 switch(prop->criteria) {
1135 case MATCHING_NOT_SUBJECT:
1136 case MATCHING_NOT_FROM:
1137 case MATCHING_NOT_TO:
1138 case MATCHING_NOT_CC:
1139 case MATCHING_NOT_TO_AND_NOT_CC:
1140 case MATCHING_NOT_NEWSGROUPS:
1141 case MATCHING_NOT_INREPLYTO:
1142 case MATCHING_NOT_REFERENCES:
1143 case MATCHING_NOT_HEADERS_PART:
1144 case MATCHING_NOT_BODY_PART:
1145 case MATCHING_NOT_MESSAGE:
1146 case MATCHING_SUBJECT:
1150 case MATCHING_TO_OR_CC:
1151 case MATCHING_NEWSGROUPS:
1152 case MATCHING_INREPLYTO:
1153 case MATCHING_REFERENCES:
1154 case MATCHING_HEADERS_PART:
1155 case MATCHING_BODY_PART:
1156 case MATCHING_MESSAGE:
1157 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1160 case MATCHING_AGE_GREATER:
1161 case MATCHING_AGE_LOWER:
1162 case MATCHING_SCORE_GREATER:
1163 case MATCHING_SCORE_LOWER:
1164 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), itos(prop->value));
1167 case MATCHING_NOT_HEADER:
1168 case MATCHING_HEADER:
1169 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), prop->header);
1170 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1175 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 1);
1177 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
1179 switch(prop->matchtype) {
1180 case MATCHING_MATCH:
1181 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1182 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1185 case MATCHING_MATCHCASE:
1186 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1187 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1190 case MATCHING_REGEXP:
1191 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1192 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1195 case MATCHING_REGEXPCASE:
1196 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1197 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1202 static void prefs_matcher_criteria_select(GtkList *list,
1208 value = get_sel_from_list(GTK_LIST(matcher.criteria_list));
1212 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1213 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1214 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1215 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1216 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1217 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1218 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1219 gtk_widget_hide(matcher.predicate_combo);
1220 gtk_widget_show(matcher.predicate_flag_combo);
1221 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1222 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1225 case CRITERIA_UNREAD:
1227 case CRITERIA_MARKED:
1228 case CRITERIA_DELETED:
1229 case CRITERIA_REPLIED:
1230 case CRITERIA_FORWARDED:
1231 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1232 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1233 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1234 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1235 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1236 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1237 gtk_widget_set_sensitive(matcher.predicate_flag_combo, TRUE);
1238 gtk_widget_hide(matcher.predicate_combo);
1239 gtk_widget_show(matcher.predicate_flag_combo);
1240 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1241 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1244 case CRITERIA_SUBJECT:
1248 case CRITERIA_TO_OR_CC:
1249 case CRITERIA_NEWSGROUPS:
1250 case CRITERIA_INREPLYTO:
1251 case CRITERIA_REFERENCES:
1252 case CRITERIA_HEADERS_PART:
1253 case CRITERIA_BODY_PART:
1254 case CRITERIA_MESSAGE:
1255 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1256 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1257 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1258 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1259 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1260 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1261 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1262 gtk_widget_show(matcher.predicate_combo);
1263 gtk_widget_hide(matcher.predicate_flag_combo);
1264 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1265 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1268 case CRITERIA_AGE_GREATER:
1269 case CRITERIA_AGE_LOWER:
1270 case CRITERIA_SCORE_GREATER:
1271 case CRITERIA_SCORE_LOWER:
1272 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1273 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1274 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1275 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1276 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1277 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1278 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1279 gtk_widget_show(matcher.predicate_combo);
1280 gtk_widget_hide(matcher.predicate_flag_combo);
1281 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1282 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1285 case CRITERIA_HEADER:
1286 gtk_widget_set_sensitive(matcher.header_combo, TRUE);
1287 gtk_widget_set_sensitive(matcher.header_label, TRUE);
1288 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1289 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1290 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1291 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1292 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1293 gtk_widget_show(matcher.predicate_combo);
1294 gtk_widget_hide(matcher.predicate_flag_combo);
1295 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1296 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1301 static void prefs_matcher_key_pressed(GtkWidget *widget, GdkEventKey *event,
1304 if (event && event->keyval == GDK_Escape)
1305 prefs_matcher_cancel();
1308 static void prefs_matcher_cancel(void)
1310 gtk_widget_hide(matcher.window);
1313 static void prefs_matcher_ok(void)
1315 MatcherList * matchers;
1317 matchers = prefs_matcher_get_list();
1318 if (matchers != NULL) {
1319 gtk_widget_hide(matcher.window);
1320 if (matchers_callback != NULL)
1321 matchers_callback(matchers);
1322 matcherlist_free(matchers);
1325 gtk_widget_hide(matcher.window);
1329 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
1332 prefs_matcher_cancel();