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 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_matching_from_criteria(gint criteria_id)
681 switch (criteria_id) {
684 case CRITERIA_UNREAD:
685 return MATCHING_UNREAD;
688 case CRITERIA_MARKED:
689 return MATCHING_MARKED;
690 case CRITERIA_DELETED:
691 return MATCHING_DELETED;
692 case CRITERIA_REPLIED:
693 return MATCHING_REPLIED;
694 case CRITERIA_FORWARDED:
695 return MATCHING_FORWARDED;
696 case CRITERIA_SUBJECT:
697 return MATCHING_SUBJECT;
699 return MATCHING_FROM;
704 case CRITERIA_TO_OR_CC:
705 return MATCHING_TO_OR_CC;
706 case CRITERIA_NEWSGROUPS:
707 return MATCHING_NEWSGROUPS;
708 case CRITERIA_INREPLYTO:
709 return MATCHING_INREPLYTO;
710 case CRITERIA_REFERENCES:
711 return MATCHING_REFERENCES;
712 case CRITERIA_AGE_GREATER:
713 return MATCHING_AGE_GREATER;
714 case CRITERIA_AGE_LOWER:
715 return MATCHING_AGE_LOWER;
716 case CRITERIA_SCORE_GREATER:
717 return MATCHING_SCORE_GREATER;
718 case CRITERIA_SCORE_LOWER:
719 return MATCHING_SCORE_LOWER;
720 case CRITERIA_HEADER:
721 return MATCHING_HEADER;
722 case CRITERIA_HEADERS_PART:
723 return MATCHING_HEADERS_PART;
724 case CRITERIA_BODY_PART:
725 return MATCHING_BODY_PART;
726 case CRITERIA_MESSAGE:
727 return MATCHING_MESSAGE;
733 static gint prefs_matcher_not_criteria(gint matcher_criteria)
735 switch(matcher_criteria) {
736 case MATCHING_UNREAD:
737 return MATCHING_NOT_UNREAD;
739 return MATCHING_NOT_NEW;
740 case MATCHING_MARKED:
741 return MATCHING_NOT_MARKED;
742 case MATCHING_DELETED:
743 return MATCHING_NOT_DELETED;
744 case MATCHING_REPLIED:
745 return MATCHING_NOT_REPLIED;
746 case MATCHING_FORWARDED:
747 return MATCHING_NOT_FORWARDED;
748 case MATCHING_SUBJECT:
749 return MATCHING_NOT_SUBJECT;
751 return MATCHING_NOT_FROM;
753 return MATCHING_NOT_TO;
755 return MATCHING_NOT_CC;
756 case MATCHING_TO_OR_CC:
757 return MATCHING_NOT_TO_AND_NOT_CC;
758 case MATCHING_NEWSGROUPS:
759 return MATCHING_NOT_NEWSGROUPS;
760 case MATCHING_INREPLYTO:
761 return MATCHING_NOT_INREPLYTO;
762 case MATCHING_REFERENCES:
763 return MATCHING_NOT_REFERENCES;
764 case MATCHING_HEADER:
765 return MATCHING_NOT_HEADER;
766 case MATCHING_HEADERS_PART:
767 return MATCHING_NOT_HEADERS_PART;
768 case MATCHING_MESSAGE:
769 return MATCHING_NOT_MESSAGE;
770 case MATCHING_BODY_PART:
771 return MATCHING_NOT_BODY_PART;
773 return matcher_criteria;
777 static MatcherProp * prefs_matcher_dialog_to_matcher()
779 MatcherProp * matcherprop;
783 gint value_pred_flag;
786 gboolean case_sensitive;
792 value_criteria = get_sel_from_list(GTK_LIST(matcher.criteria_list));
794 criteria = prefs_matcher_get_matching_from_criteria(value_criteria);
796 value_pred = get_sel_from_list(GTK_LIST(matcher.predicate_list));
797 value_pred_flag = get_sel_from_list(GTK_LIST(matcher.predicate_flag_list));
799 use_regexp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn));
800 case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn));
802 switch (value_criteria) {
803 case CRITERIA_UNREAD:
805 case CRITERIA_MARKED:
806 case CRITERIA_DELETED:
807 case CRITERIA_REPLIED:
808 case CRITERIA_FORWARDED:
809 if (value_pred_flag == PREDICATE_FLAG_DISABLED)
810 criteria = prefs_matcher_not_criteria(criteria);
812 case CRITERIA_SUBJECT:
816 case CRITERIA_TO_OR_CC:
817 case CRITERIA_NEWSGROUPS:
818 case CRITERIA_INREPLYTO:
819 case CRITERIA_REFERENCES:
820 case CRITERIA_HEADERS_PART:
821 case CRITERIA_BODY_PART:
822 case CRITERIA_MESSAGE:
823 case CRITERIA_AGE_GREATER:
824 case CRITERIA_AGE_LOWER:
825 case CRITERIA_HEADER:
826 if (value_pred == PREDICATE_DOES_NOT_CONTAIN)
827 criteria = prefs_matcher_not_criteria(criteria);
833 matchtype = MATCHING_REGEXP;
835 matchtype = MATCHING_REGEXPCASE;
839 matchtype = MATCHING_MATCH;
841 matchtype = MATCHING_MATCHCASE;
848 switch (value_criteria) {
850 case CRITERIA_UNREAD:
852 case CRITERIA_MARKED:
853 case CRITERIA_DELETED:
854 case CRITERIA_REPLIED:
855 case CRITERIA_FORWARDED:
858 case CRITERIA_SUBJECT:
862 case CRITERIA_TO_OR_CC:
863 case CRITERIA_NEWSGROUPS:
864 case CRITERIA_INREPLYTO:
865 case CRITERIA_REFERENCES:
866 case CRITERIA_HEADERS_PART:
867 case CRITERIA_BODY_PART:
868 case CRITERIA_MESSAGE:
869 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
873 alertpanel_error(_("Match string is not set."));
879 case CRITERIA_AGE_GREATER:
880 case CRITERIA_AGE_LOWER:
881 case CRITERIA_SCORE_GREATER:
882 case CRITERIA_SCORE_LOWER:
883 value_str = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
885 if (*value_str == '\0') {
886 alertpanel_error(_("Value is not set."));
890 value = atoi(value_str);
894 case CRITERIA_HEADER:
896 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_entry));
897 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
899 if (*header == '\0') {
900 alertpanel_error(_("Header name is not set."));
905 alertpanel_error(_("Match string is not set."));
912 matcherprop = matcherprop_new(criteria, header, matchtype,
918 static void prefs_matcher_register_cb(void)
920 MatcherProp * matcherprop;
922 matcherprop = prefs_matcher_dialog_to_matcher();
923 if (matcherprop == NULL)
926 prefs_matcher_clist_set_row(-1, matcherprop);
928 matcherprop_free(matcherprop);
930 prefs_matcher_reset_condition();
933 static void prefs_matcher_substitute_cb(void)
935 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
937 MatcherProp * matcherprop;
939 row = GPOINTER_TO_INT(clist->selection->data);
943 matcherprop = prefs_matcher_dialog_to_matcher();
944 if (matcherprop == NULL)
947 prefs_matcher_clist_set_row(row, matcherprop);
949 matcherprop_free(matcherprop);
951 prefs_matcher_reset_condition();
954 static void prefs_matcher_delete_cb(void)
956 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
959 if (!clist->selection) return;
960 row = GPOINTER_TO_INT(clist->selection->data);
964 gtk_clist_remove(clist, row);
967 static void prefs_matcher_up(void)
969 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
972 if (!clist->selection) return;
974 row = GPOINTER_TO_INT(clist->selection->data);
976 gtk_clist_row_move(clist, row, row - 1);
979 static void prefs_matcher_down(void)
981 GtkCList *clist = GTK_CLIST(matcher.cond_clist);
984 if (!clist->selection) return;
986 row = GPOINTER_TO_INT(clist->selection->data);
987 if (row >= 1 && row < clist->rows - 1)
988 gtk_clist_row_move(clist, row, row + 1);
991 static void prefs_matcher_select(GtkCList *clist, gint row, gint column,
997 gboolean negative_cond;
999 if (!gtk_clist_get_text(GTK_CLIST(matcher.cond_clist),
1000 row, 0, &matcher_str))
1003 negative_cond = FALSE;
1006 prefs_matcher_reset_condition();
1011 prop = matcherprop_parse(&tmp);
1015 switch(prop->criteria) {
1017 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1021 case MATCHING_NOT_UNREAD:
1022 negative_cond = TRUE;
1023 case MATCHING_UNREAD:
1024 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1028 case MATCHING_NOT_NEW:
1029 negative_cond = TRUE;
1031 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1035 case MATCHING_NOT_MARKED:
1036 negative_cond = TRUE;
1037 case MATCHING_MARKED:
1038 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1042 case MATCHING_NOT_DELETED:
1043 negative_cond = TRUE;
1044 case MATCHING_DELETED:
1045 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1049 case MATCHING_NOT_REPLIED:
1050 negative_cond = TRUE;
1051 case MATCHING_REPLIED:
1052 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1056 case MATCHING_NOT_FORWARDED:
1057 negative_cond = TRUE;
1058 case MATCHING_FORWARDED:
1059 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1060 CRITERIA_FORWARDED);
1063 case MATCHING_NOT_SUBJECT:
1064 negative_cond = TRUE;
1065 case MATCHING_SUBJECT:
1066 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1070 case MATCHING_NOT_FROM:
1071 negative_cond = TRUE;
1073 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1077 case MATCHING_NOT_TO:
1078 negative_cond = TRUE;
1080 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1084 case MATCHING_NOT_CC:
1085 negative_cond = TRUE;
1087 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1091 case MATCHING_NOT_NEWSGROUPS:
1092 negative_cond = TRUE;
1093 case MATCHING_NEWSGROUPS:
1094 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1095 CRITERIA_NEWSGROUPS);
1098 case MATCHING_NOT_INREPLYTO:
1099 negative_cond = TRUE;
1100 case MATCHING_INREPLYTO:
1101 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1102 CRITERIA_INREPLYTO);
1105 case MATCHING_NOT_REFERENCES:
1106 negative_cond = TRUE;
1107 case MATCHING_REFERENCES:
1108 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1109 CRITERIA_REFERENCES);
1112 case MATCHING_NOT_TO_AND_NOT_CC:
1113 negative_cond = TRUE;
1114 case MATCHING_TO_OR_CC:
1115 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1119 case MATCHING_NOT_BODY_PART:
1120 negative_cond = TRUE;
1121 case MATCHING_BODY_PART:
1122 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1123 CRITERIA_BODY_PART);
1126 case MATCHING_NOT_MESSAGE:
1127 negative_cond = TRUE;
1128 case MATCHING_MESSAGE:
1129 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1133 case MATCHING_NOT_HEADERS_PART:
1134 negative_cond = TRUE;
1135 case MATCHING_HEADERS_PART:
1136 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1137 CRITERIA_HEADERS_PART);
1140 case MATCHING_NOT_HEADER:
1141 negative_cond = TRUE;
1142 case MATCHING_HEADER:
1143 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1147 case MATCHING_AGE_GREATER:
1148 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1149 CRITERIA_AGE_GREATER);
1152 case MATCHING_AGE_LOWER:
1153 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1154 CRITERIA_AGE_LOWER);
1157 case MATCHING_SCORE_GREATER:
1158 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1159 CRITERIA_SCORE_GREATER);
1162 case MATCHING_SCORE_LOWER:
1163 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
1164 CRITERIA_SCORE_LOWER);
1168 switch(prop->criteria) {
1172 case MATCHING_NOT_SUBJECT:
1173 case MATCHING_NOT_FROM:
1174 case MATCHING_NOT_TO:
1175 case MATCHING_NOT_CC:
1176 case MATCHING_NOT_TO_AND_NOT_CC:
1177 case MATCHING_NOT_NEWSGROUPS:
1178 case MATCHING_NOT_INREPLYTO:
1179 case MATCHING_NOT_REFERENCES:
1180 case MATCHING_NOT_HEADERS_PART:
1181 case MATCHING_NOT_BODY_PART:
1182 case MATCHING_NOT_MESSAGE:
1183 case MATCHING_SUBJECT:
1187 case MATCHING_TO_OR_CC:
1188 case MATCHING_NEWSGROUPS:
1189 case MATCHING_INREPLYTO:
1190 case MATCHING_REFERENCES:
1191 case MATCHING_HEADERS_PART:
1192 case MATCHING_BODY_PART:
1193 case MATCHING_MESSAGE:
1194 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1197 case MATCHING_AGE_GREATER:
1198 case MATCHING_AGE_LOWER:
1199 case MATCHING_SCORE_GREATER:
1200 case MATCHING_SCORE_LOWER:
1201 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), itos(prop->value));
1204 case MATCHING_NOT_HEADER:
1205 case MATCHING_HEADER:
1206 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), prop->header);
1207 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
1212 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 1);
1214 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
1216 switch(prop->matchtype) {
1217 case MATCHING_MATCH:
1218 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1219 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1222 case MATCHING_MATCHCASE:
1223 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), FALSE);
1224 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1227 case MATCHING_REGEXP:
1228 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1229 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), TRUE);
1232 case MATCHING_REGEXPCASE:
1233 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_chkbtn), TRUE);
1234 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_chkbtn), FALSE);
1239 static void prefs_matcher_criteria_select(GtkList *list,
1245 value = get_sel_from_list(GTK_LIST(matcher.criteria_list));
1249 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1250 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1251 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1252 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1253 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1254 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1255 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1256 gtk_widget_hide(matcher.predicate_combo);
1257 gtk_widget_show(matcher.predicate_flag_combo);
1258 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1259 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1262 case CRITERIA_UNREAD:
1264 case CRITERIA_MARKED:
1265 case CRITERIA_DELETED:
1266 case CRITERIA_REPLIED:
1267 case CRITERIA_FORWARDED:
1268 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1269 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1270 gtk_widget_set_sensitive(matcher.value_label, FALSE);
1271 gtk_widget_set_sensitive(matcher.value_entry, FALSE);
1272 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1273 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1274 gtk_widget_set_sensitive(matcher.predicate_flag_combo, TRUE);
1275 gtk_widget_hide(matcher.predicate_combo);
1276 gtk_widget_show(matcher.predicate_flag_combo);
1277 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1278 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1281 case CRITERIA_SUBJECT:
1285 case CRITERIA_TO_OR_CC:
1286 case CRITERIA_NEWSGROUPS:
1287 case CRITERIA_INREPLYTO:
1288 case CRITERIA_REFERENCES:
1289 case CRITERIA_HEADERS_PART:
1290 case CRITERIA_BODY_PART:
1291 case CRITERIA_MESSAGE:
1292 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1293 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1294 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1295 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1296 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1297 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1298 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1299 gtk_widget_show(matcher.predicate_combo);
1300 gtk_widget_hide(matcher.predicate_flag_combo);
1301 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1302 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1305 case CRITERIA_AGE_GREATER:
1306 case CRITERIA_AGE_LOWER:
1307 case CRITERIA_SCORE_GREATER:
1308 case CRITERIA_SCORE_LOWER:
1309 gtk_widget_set_sensitive(matcher.header_combo, FALSE);
1310 gtk_widget_set_sensitive(matcher.header_label, FALSE);
1311 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1312 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1313 gtk_widget_set_sensitive(matcher.predicate_label, FALSE);
1314 gtk_widget_set_sensitive(matcher.predicate_combo, FALSE);
1315 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1316 gtk_widget_show(matcher.predicate_combo);
1317 gtk_widget_hide(matcher.predicate_flag_combo);
1318 gtk_widget_set_sensitive(matcher.case_chkbtn, FALSE);
1319 gtk_widget_set_sensitive(matcher.regexp_chkbtn, FALSE);
1322 case CRITERIA_HEADER:
1323 gtk_widget_set_sensitive(matcher.header_combo, TRUE);
1324 gtk_widget_set_sensitive(matcher.header_label, TRUE);
1325 gtk_widget_set_sensitive(matcher.value_label, TRUE);
1326 gtk_widget_set_sensitive(matcher.value_entry, TRUE);
1327 gtk_widget_set_sensitive(matcher.predicate_label, TRUE);
1328 gtk_widget_set_sensitive(matcher.predicate_combo, TRUE);
1329 gtk_widget_set_sensitive(matcher.predicate_flag_combo, FALSE);
1330 gtk_widget_show(matcher.predicate_combo);
1331 gtk_widget_hide(matcher.predicate_flag_combo);
1332 gtk_widget_set_sensitive(matcher.case_chkbtn, TRUE);
1333 gtk_widget_set_sensitive(matcher.regexp_chkbtn, TRUE);
1338 static void prefs_matcher_key_pressed(GtkWidget *widget, GdkEventKey *event,
1341 if (event && event->keyval == GDK_Escape)
1342 prefs_matcher_cancel();
1345 static void prefs_matcher_cancel(void)
1347 gtk_widget_hide(matcher.window);
1350 static void prefs_matcher_ok(void)
1352 MatcherList * matchers;
1354 matchers = prefs_matcher_get_list();
1355 if (matchers != NULL) {
1356 gtk_widget_hide(matcher.window);
1357 if (matchers_callback != NULL)
1358 matchers_callback(matchers);
1359 matcherlist_free(matchers);
1362 gtk_widget_hide(matcher.window);
1366 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
1369 prefs_matcher_cancel();