2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
36 #include "prefs_gtk.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"
48 #include "description_window.h"
50 #include "matcher_parser.h"
51 #include "colorlabel.h"
55 PREFS_MATCHER_COND_VALID,
56 N_PREFS_MATCHER_COLUMNS
60 *\brief UI data for matcher dialog
62 static struct Matcher {
67 GtkWidget *predicate_combo;
68 GtkWidget *predicate_flag_combo;
69 GtkWidget *header_combo;
70 GtkWidget *header_addr_combo;
72 GtkWidget *criteria_list;
74 GtkWidget *predicate_list;
75 GtkWidget *predicate_label;
76 GtkWidget *predicate_flag_list;
78 GtkWidget *bool_op_list;
80 GtkWidget *header_entry;
81 GtkWidget *header_label;
82 GtkWidget *header_addr_entry;
83 GtkWidget *header_addr_label;
84 GtkWidget *value_entry;
85 GtkWidget *value_label;
86 GtkWidget *addressbook_folder_label;
87 GtkWidget *addressbook_folder_combo;
88 GtkWidget *case_checkbtn;
89 GtkWidget *regexp_checkbtn;
90 GtkWidget *color_optmenu;
93 GtkWidget *addressbook_select_btn;
95 GtkWidget *cond_list_view;
97 GtkWidget *criteria_table;
99 gint selected_criteria; /*!< selected criteria in combobox */
103 *\brief Conditions with a negate counterpart (like unread and ~unread)
104 * have the same CRITERIA_XXX id). I.e. both unread and ~unread
105 * have criteria id CRITERIA_UNREAD. This id is passed as the
106 * first parameter to #matcherprop_new and #matcherprop_unquote_new.
108 *\warning Currently the enum constants should have the same order as the
114 CRITERIA_SUBJECT = 1,
118 CRITERIA_TO_OR_CC = 5,
119 CRITERIA_NEWSGROUPS = 6,
120 CRITERIA_INREPLYTO = 7,
121 CRITERIA_REFERENCES = 8,
122 CRITERIA_AGE_GREATER = 9,
123 CRITERIA_AGE_LOWER = 10,
124 CRITERIA_HEADER = 11,
125 CRITERIA_HEADERS_PART = 12,
126 CRITERIA_BODY_PART = 13,
127 CRITERIA_MESSAGE = 14,
129 CRITERIA_UNREAD = 15,
131 CRITERIA_MARKED = 17,
132 CRITERIA_DELETED = 18,
133 CRITERIA_REPLIED = 19,
134 CRITERIA_FORWARDED = 20,
135 CRITERIA_LOCKED = 21,
137 CRITERIA_COLORLABEL = 23,
138 CRITERIA_IGNORE_THREAD = 24,
140 CRITERIA_SCORE_GREATER = 25,
141 CRITERIA_SCORE_LOWER = 26,
142 CRITERIA_SCORE_EQUAL = 27,
146 CRITERIA_SIZE_GREATER = 29,
147 CRITERIA_SIZE_SMALLER = 30,
148 CRITERIA_SIZE_EQUAL = 31,
150 CRITERIA_PARTIAL = 32,
152 CRITERIA_FOUND_IN_ADDRESSBOOK = 33,
156 *\brief Descriptive text for conditions
158 static const gchar *criteria_text [] = {
159 N_("All messages"), N_("Subject"),
160 N_("From"), N_("To"), N_("Cc"), N_("To or Cc"),
161 N_("Newsgroups"), N_("In reply to"), N_("References"),
162 N_("Age greater than"), N_("Age lower than"),
163 N_("Header"), N_("Headers part"),
164 N_("Body part"), N_("Whole message"),
165 N_("Unread flag"), N_("New flag"),
166 N_("Marked flag"), N_("Deleted flag"),
167 N_("Replied flag"), N_("Forwarded flag"),
171 N_("Ignored thread"),
172 N_("Score greater than"), N_("Score lower than"),
173 N_("Score equal to"),
175 N_("Size greater than"),
176 N_("Size smaller than"),
178 N_("Partially downloaded"),
179 N_("Found in addressbook")
183 *\brief Boolean / predicate constants
185 *\warning Same order as #bool_op_text!
193 *\brief Descriptive text in UI
195 static const gchar *bool_op_text [] = {
200 *\brief Contains predicate
202 *\warning Same order as in #predicate_text
205 PREDICATE_CONTAINS = 0,
206 PREDICATE_DOES_NOT_CONTAIN = 1
210 *\brief Descriptive text in UI for predicate
212 static const gchar *predicate_text [] = {
213 N_("contains"), N_("does not contain")
217 *\brief Preset addressbook book/folder items
219 static const gchar *addressbook_folder_text [] = {
224 *\brief Enabled predicate
226 *\warning Same order as in #predicate_flag_text
229 PREDICATE_FLAG_ENABLED = 0,
230 PREDICATE_FLAG_DISABLED = 1
234 *\brief Descriptive text in UI for enabled flag
236 static const gchar *predicate_flag_text [] = {
243 static PrefsMatcherSignal *matchers_callback;
245 /* widget creating functions */
246 static void prefs_matcher_create (void);
248 static void prefs_matcher_set_dialog (MatcherList *matchers);
249 static void prefs_matcher_list_view_set_row (GtkTreeIter *row,
252 /* callback functions */
254 static void prefs_matcher_register_cb (void);
255 static void prefs_matcher_substitute_cb (void);
256 static void prefs_matcher_delete_cb (void);
257 static void prefs_matcher_up (void);
258 static void prefs_matcher_down (void);
259 static gboolean prefs_matcher_key_pressed(GtkWidget *widget,
262 static void prefs_matcher_ok (void);
263 static void prefs_matcher_cancel (void);
264 static gint prefs_matcher_deleted (GtkWidget *widget, GdkEventAny *event,
266 static void prefs_matcher_criteria_select (GtkList *list,
269 static MatcherList *prefs_matcher_get_list (void);
271 static GtkListStore* prefs_matcher_create_data_store (void);
273 static void prefs_matcher_list_view_insert_matcher (GtkWidget *list_view,
274 GtkTreeIter *row_iter,
275 const gchar *matcher,
278 static GtkWidget *prefs_matcher_list_view_create (void);
280 static void prefs_matcher_create_list_view_columns (GtkWidget *list_view);
282 static gboolean prefs_matcher_selected (GtkTreeSelection *selector,
285 gboolean currently_selected,
289 *\brief Find index of list selection
291 *\param list GTK list widget
293 *\return gint Selection index
295 static gint get_sel_from_list(GtkList *list)
301 sel = list->selection->data;
302 for (child = list->children; child != NULL; child = g_list_next(child)) {
303 if (child->data == sel)
312 *\brief Opens the matcher dialog with a list of conditions
314 *\param matchers List of conditions
318 void prefs_matcher_open(MatcherList *matchers, PrefsMatcherSignal *cb)
322 if (!matcher.window) {
323 prefs_matcher_create();
325 /* update color label menu */
326 gtk_option_menu_set_menu(GTK_OPTION_MENU(matcher.color_optmenu),
327 colorlabel_create_color_menu());
330 manage_window_set_transient(GTK_WINDOW(matcher.window));
331 gtk_widget_grab_focus(matcher.ok_btn);
333 matchers_callback = cb;
335 prefs_matcher_set_dialog(matchers);
337 gtk_widget_show(matcher.window);
341 *\brief Save Gtk object size to prefs dataset
343 static void prefs_matcher_size_allocate_cb(GtkWidget *widget,
344 GtkAllocation *allocation)
346 g_return_if_fail(allocation != NULL);
348 prefs_common.matcherwin_width = allocation->width;
349 prefs_common.matcherwin_height = allocation->height;
353 *\brief Create the matcher dialog
355 static void prefs_matcher_create(void)
360 GtkWidget *cancel_btn;
361 GtkWidget *confirm_area;
366 GtkWidget *criteria_table;
370 GtkWidget *header_combo;
371 GtkWidget *header_entry;
372 GtkWidget *header_label;
373 GtkWidget *header_addr_combo;
374 GtkWidget *header_addr_entry;
375 GtkWidget *header_addr_label;
376 GtkWidget *criteria_combo;
377 GtkWidget *criteria_list;
378 GtkWidget *criteria_label;
379 GtkWidget *value_label;
380 GtkWidget *value_entry;
381 GtkWidget *addressbook_folder_label;
382 GtkWidget *addressbook_folder_combo;
383 GtkWidget *predicate_combo;
384 GtkWidget *predicate_list;
385 GtkWidget *predicate_flag_combo;
386 GtkWidget *predicate_flag_list;
387 GtkWidget *predicate_label;
388 GtkWidget *bool_op_combo;
389 GtkWidget *bool_op_list;
390 GtkWidget *bool_op_label;
392 GtkWidget *regexp_checkbtn;
393 GtkWidget *case_checkbtn;
399 GtkWidget *subst_btn;
402 GtkWidget *cond_hbox;
403 GtkWidget *cond_scrolledwin;
404 GtkWidget *cond_list_view;
411 GtkWidget *addressbook_select_btn;
413 GtkWidget *color_optmenu;
417 static GdkGeometry geometry;
419 debug_print("Creating matcher configuration window...\n");
421 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "prefs_matcher");
422 gtk_container_set_border_width(GTK_CONTAINER(window), 8);
423 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
424 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
425 gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
427 vbox = gtk_vbox_new(FALSE, 6);
428 gtk_widget_show(vbox);
429 gtk_container_add(GTK_CONTAINER(window), vbox);
431 gtkut_stock_button_set_create(&confirm_area, &cancel_btn, GTK_STOCK_CANCEL,
432 &ok_btn, GTK_STOCK_OK, NULL, NULL);
433 gtk_widget_show(confirm_area);
434 gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
435 gtk_widget_grab_default(ok_btn);
437 gtk_window_set_title(GTK_WINDOW(window),
438 _("Condition configuration"));
439 g_signal_connect(G_OBJECT(window), "delete_event",
440 G_CALLBACK(prefs_matcher_deleted), NULL);
441 g_signal_connect(G_OBJECT(window), "size_allocate",
442 G_CALLBACK(prefs_matcher_size_allocate_cb), NULL);
443 g_signal_connect(G_OBJECT(window), "key_press_event",
444 G_CALLBACK(prefs_matcher_key_pressed), NULL);
445 MANAGE_WINDOW_SIGNALS_CONNECT(window);
446 g_signal_connect(G_OBJECT(ok_btn), "clicked",
447 G_CALLBACK(prefs_matcher_ok), NULL);
448 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
449 G_CALLBACK(prefs_matcher_cancel), NULL);
451 vbox1 = gtk_vbox_new(FALSE, VSPACING);
452 gtk_widget_show(vbox1);
453 gtk_box_pack_start(GTK_BOX(vbox), vbox1, TRUE, TRUE, 0);
454 gtk_container_set_border_width(GTK_CONTAINER (vbox1), 2);
456 criteria_table = gtk_table_new(2, 4, FALSE);
457 gtk_widget_show(criteria_table);
459 gtk_box_pack_start(GTK_BOX(vbox1), criteria_table, FALSE, FALSE, 0);
460 gtk_table_set_row_spacings(GTK_TABLE(criteria_table), 8);
461 gtk_table_set_col_spacings(GTK_TABLE(criteria_table), 8);
463 /* criteria combo box */
465 criteria_label = gtk_label_new(_("Match type"));
466 gtk_widget_show(criteria_label);
467 gtk_misc_set_alignment(GTK_MISC(criteria_label), 0, 0.5);
468 gtk_table_attach(GTK_TABLE(criteria_table), criteria_label, 0, 1, 0, 1,
471 criteria_combo = gtk_combo_new();
472 gtk_widget_show(criteria_combo);
476 for (i = 0; i < (gint) (sizeof(criteria_text) / sizeof(gchar *)); i++) {
477 combo_items = g_list_append(combo_items,
478 (gpointer) _(criteria_text[i]));
480 gtk_combo_set_popdown_strings(GTK_COMBO(criteria_combo), combo_items);
482 g_list_free(combo_items);
484 gtk_widget_set_size_request(criteria_combo, 170, -1);
485 gtk_table_attach(GTK_TABLE(criteria_table), criteria_combo, 0, 1, 1, 2,
487 criteria_list = GTK_COMBO(criteria_combo)->list;
488 g_signal_connect(G_OBJECT(criteria_list), "select-child",
489 G_CALLBACK(prefs_matcher_criteria_select),
492 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(criteria_combo)->entry),
497 header_label = gtk_label_new(_("Header name"));
498 gtk_widget_show(header_label);
499 gtk_misc_set_alignment(GTK_MISC(header_label), 0, 0.5);
500 gtk_table_attach(GTK_TABLE(criteria_table), header_label, 1, 2, 0, 1,
503 header_combo = gtk_combo_new();
504 gtk_widget_show(header_combo);
505 gtk_widget_set_size_request(header_combo, 120, -1);
506 gtkut_combo_set_items(GTK_COMBO (header_combo),
507 "Subject", "From", "To", "Cc", "Reply-To",
508 "Sender", "X-ML-Name", "X-List", "X-Sequence",
509 "X-Mailer","X-BeenThere",
511 gtk_table_attach(GTK_TABLE(criteria_table), header_combo, 1, 2, 1, 2,
513 header_entry = GTK_COMBO(header_combo)->entry;
514 gtk_entry_set_editable(GTK_ENTRY(header_entry), TRUE);
516 /* address header name */
518 header_addr_label = gtk_label_new(_("Address header"));
519 gtk_misc_set_alignment(GTK_MISC(header_addr_label), 0, 0.5);
520 gtk_table_attach(GTK_TABLE(criteria_table), header_addr_label, 1, 2, 0, 1,
523 header_addr_combo = gtk_combo_new();
524 gtk_widget_set_size_request(header_addr_combo, 120, -1);
525 gtkut_combo_set_items(GTK_COMBO (header_addr_combo),
526 Q_("Filtering Matcher Menu|All"),
527 _("Any"), "From", "To", "Cc", "Reply-To", "Sender",
529 gtk_table_attach(GTK_TABLE(criteria_table), header_addr_combo, 1, 2, 1, 2,
531 header_addr_entry = GTK_COMBO(header_addr_combo)->entry;
532 gtk_entry_set_editable(GTK_ENTRY(header_addr_entry), TRUE);
536 value_label = gtk_label_new(_("Value"));
537 gtk_widget_show(value_label);
538 gtk_misc_set_alignment(GTK_MISC (value_label), 0, 0.5);
539 gtk_table_attach(GTK_TABLE(criteria_table), value_label, 2, 3, 0, 1,
540 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
542 value_entry = gtk_entry_new();
543 gtk_widget_show(value_entry);
544 gtk_widget_set_size_request(value_entry, 200, -1);
545 gtk_table_attach(GTK_TABLE(criteria_table), value_entry, 2, 3, 1, 2,
546 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
548 /* book/folder value */
550 addressbook_folder_label = gtk_label_new(_("Book/folder"));
551 gtk_misc_set_alignment(GTK_MISC (addressbook_folder_label), 0, 0.5);
552 gtk_table_attach(GTK_TABLE(criteria_table), addressbook_folder_label, 2, 3, 0, 1,
553 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
555 addressbook_folder_combo = gtk_combo_new();
556 gtk_widget_show(addressbook_folder_combo);
557 gtk_widget_set_size_request(addressbook_folder_combo, 200, -1);
558 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(addressbook_folder_combo)->entry),
562 for (i = 0; i < (gint) (sizeof(addressbook_folder_text) / sizeof(gchar *)); i++) {
563 combo_items = g_list_append(combo_items,
564 (gpointer) _(addressbook_folder_text[i]));
566 gtk_combo_set_popdown_strings(GTK_COMBO(addressbook_folder_combo), combo_items);
567 g_list_free(combo_items);
569 gtk_table_attach(GTK_TABLE(criteria_table), addressbook_folder_combo, 2, 3, 1, 2,
570 GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0, 0);
572 #if GTK_CHECK_VERSION(2, 8, 0)
573 test_btn = gtk_button_new_from_stock(GTK_STOCK_INFO);
575 test_btn = gtk_button_new_with_label(_("Info..."));
577 gtk_widget_show(test_btn);
578 gtk_table_attach(GTK_TABLE (criteria_table), test_btn, 3, 4, 1, 2,
580 g_signal_connect(G_OBJECT (test_btn), "clicked",
581 G_CALLBACK(prefs_matcher_test_info),
584 addressbook_select_btn = gtk_button_new_with_label(_("Select ..."));
585 gtk_table_attach(GTK_TABLE (criteria_table), addressbook_select_btn, 3, 4, 1, 2,
587 g_signal_connect(G_OBJECT (addressbook_select_btn), "clicked",
588 G_CALLBACK(prefs_matcher_addressbook_select),
591 color_optmenu = gtk_option_menu_new();
592 gtk_option_menu_set_menu(GTK_OPTION_MENU(color_optmenu),
593 colorlabel_create_color_menu());
597 vbox2 = gtk_vbox_new(FALSE, VSPACING);
598 gtk_widget_show(vbox2);
599 gtk_box_pack_start(GTK_BOX(vbox1), vbox2, FALSE, FALSE, 0);
601 hbox1 = gtk_hbox_new(FALSE, 8);
602 gtk_widget_show(hbox1);
603 gtk_box_pack_start(GTK_BOX(vbox2), hbox1, FALSE, FALSE, 0);
605 predicate_label = gtk_label_new(_("Predicate"));
606 gtk_widget_show(predicate_label);
607 gtk_box_pack_start(GTK_BOX(hbox1), predicate_label,
610 predicate_combo = gtk_combo_new();
611 gtk_widget_show(predicate_combo);
612 gtk_widget_set_size_request(predicate_combo, 120, -1);
613 predicate_list = GTK_COMBO(predicate_combo)->list;
614 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(predicate_combo)->entry),
619 for (i = 0; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)); i++) {
620 combo_items = g_list_append(combo_items,
621 (gpointer) _(predicate_text[i]));
623 gtk_combo_set_popdown_strings(GTK_COMBO(predicate_combo), combo_items);
625 g_list_free(combo_items);
627 gtk_box_pack_start(GTK_BOX(hbox1), predicate_combo,
632 predicate_flag_combo = gtk_combo_new();
633 gtk_widget_hide(predicate_flag_combo);
634 gtk_widget_set_size_request(predicate_flag_combo, 120, -1);
635 predicate_flag_list = GTK_COMBO(predicate_flag_combo)->list;
636 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(predicate_flag_combo)->entry), FALSE);
640 for (i = 0; i < (gint) (sizeof(predicate_text) / sizeof(gchar *)); i++) {
641 combo_items = g_list_append(combo_items, (gpointer) _(predicate_flag_text[i]));
643 gtk_combo_set_popdown_strings(GTK_COMBO(predicate_flag_combo),
646 g_list_free(combo_items);
648 gtk_box_pack_start(GTK_BOX(hbox1), predicate_flag_combo,
651 vbox3 = gtk_vbox_new(FALSE, 0);
652 gtk_widget_show (vbox3);
653 gtk_box_pack_start(GTK_BOX(hbox1), vbox3, FALSE, FALSE, 0);
655 PACK_CHECK_BUTTON(vbox3, case_checkbtn, _("Case sensitive"));
656 PACK_CHECK_BUTTON(vbox3, regexp_checkbtn, _("Use regexp"));
658 /* register / substitute / delete */
660 reg_hbox = gtk_hbox_new(FALSE, 4);
661 gtk_widget_show(reg_hbox);
662 gtk_box_pack_start(GTK_BOX(vbox1), reg_hbox, FALSE, FALSE, 0);
664 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
665 gtk_widget_show(arrow);
666 gtk_box_pack_start(GTK_BOX(reg_hbox), arrow, FALSE, FALSE, 0);
667 gtk_widget_set_size_request(arrow, -1, 16);
669 btn_hbox = gtk_hbox_new(FALSE, 4);
670 gtk_widget_show(btn_hbox);
671 gtk_box_pack_start(GTK_BOX(reg_hbox), btn_hbox, FALSE, FALSE, 0);
673 reg_btn = gtk_button_new_from_stock(GTK_STOCK_ADD);
674 gtk_widget_show(reg_btn);
675 gtk_box_pack_start(GTK_BOX(btn_hbox), reg_btn, FALSE, TRUE, 0);
676 g_signal_connect(G_OBJECT(reg_btn), "clicked",
677 G_CALLBACK(prefs_matcher_register_cb), NULL);
679 subst_btn = gtkut_get_replace_btn(_("Replace"));
680 gtk_widget_show(subst_btn);
681 gtk_box_pack_start(GTK_BOX(btn_hbox), subst_btn, FALSE, TRUE, 0);
682 g_signal_connect(G_OBJECT(subst_btn), "clicked",
683 G_CALLBACK(prefs_matcher_substitute_cb),
686 del_btn = gtk_button_new_from_stock(GTK_STOCK_DELETE);
687 gtk_widget_show(del_btn);
688 gtk_box_pack_start(GTK_BOX(btn_hbox), del_btn, FALSE, TRUE, 0);
689 g_signal_connect(G_OBJECT(del_btn), "clicked",
690 G_CALLBACK(prefs_matcher_delete_cb), NULL);
692 /* boolean operation */
694 bool_op_label = gtk_label_new(_("Boolean Op"));
695 gtk_misc_set_alignment(GTK_MISC(value_label), 0, 0.5);
696 gtk_widget_show(bool_op_label);
697 gtk_box_pack_start(GTK_BOX(btn_hbox), bool_op_label,
700 bool_op_combo = gtk_combo_new();
701 gtk_widget_show(bool_op_combo);
702 gtk_widget_set_size_request(bool_op_combo, 60, -1);
703 bool_op_list = GTK_COMBO(bool_op_combo)->list;
704 gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(bool_op_combo)->entry),
709 for (i = 0; i < (gint) (sizeof(bool_op_text) / sizeof(gchar *)); i++) {
710 combo_items = g_list_append(combo_items,
711 (gpointer) _(bool_op_text[i]));
713 gtk_combo_set_popdown_strings(GTK_COMBO(bool_op_combo), combo_items);
715 g_list_free(combo_items);
717 gtk_box_pack_start(GTK_BOX(btn_hbox), bool_op_combo,
720 cond_hbox = gtk_hbox_new(FALSE, 8);
721 gtk_widget_show(cond_hbox);
722 gtk_box_pack_start(GTK_BOX(vbox1), cond_hbox, TRUE, TRUE, 0);
724 cond_scrolledwin = gtk_scrolled_window_new(NULL, NULL);
725 gtk_widget_show(cond_scrolledwin);
726 gtk_widget_set_size_request(cond_scrolledwin, -1, 150);
727 gtk_box_pack_start(GTK_BOX(cond_hbox), cond_scrolledwin,
729 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolledwin),
730 GTK_POLICY_AUTOMATIC,
731 GTK_POLICY_AUTOMATIC);
733 cond_list_view = prefs_matcher_list_view_create();
734 gtk_widget_show(cond_list_view);
735 gtk_container_add(GTK_CONTAINER(cond_scrolledwin), cond_list_view);
737 btn_vbox = gtk_vbox_new(FALSE, 8);
738 gtk_widget_show(btn_vbox);
739 gtk_box_pack_start(GTK_BOX(cond_hbox), btn_vbox, FALSE, FALSE, 0);
741 up_btn = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
742 gtk_widget_show(up_btn);
743 gtk_box_pack_start(GTK_BOX(btn_vbox), up_btn, FALSE, FALSE, 0);
744 g_signal_connect(G_OBJECT(up_btn), "clicked",
745 G_CALLBACK(prefs_matcher_up), NULL);
747 down_btn = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
748 gtk_widget_show(down_btn);
749 gtk_box_pack_start(GTK_BOX(btn_vbox), down_btn, FALSE, FALSE, 0);
750 g_signal_connect(G_OBJECT(down_btn), "clicked",
751 G_CALLBACK(prefs_matcher_down), NULL);
753 if (!geometry.min_height) {
754 geometry.min_width = 520;
755 geometry.min_height = 368;
758 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
760 gtk_widget_set_size_request(window, prefs_common.matcherwin_width,
761 prefs_common.matcherwin_height);
763 gtk_widget_show_all(window);
764 gtk_widget_hide(header_addr_label);
765 gtk_widget_hide(header_addr_combo);
766 gtk_widget_hide(addressbook_select_btn);
767 gtk_widget_hide(addressbook_folder_label);
769 matcher.window = window;
771 matcher.ok_btn = ok_btn;
773 matcher.criteria_list = criteria_list;
774 matcher.header_combo = header_combo;
775 matcher.header_entry = header_entry;
776 matcher.header_label = header_label;
777 matcher.header_addr_combo = header_addr_combo;
778 matcher.header_addr_entry = header_addr_entry;
779 matcher.header_addr_label = header_addr_label;
780 matcher.value_entry = value_entry;
781 matcher.value_label = value_label;
782 matcher.addressbook_folder_label = addressbook_folder_label;
783 matcher.addressbook_folder_combo = addressbook_folder_combo;
784 matcher.predicate_label = predicate_label;
785 matcher.predicate_list = predicate_list;
786 matcher.predicate_combo = predicate_combo;
787 matcher.predicate_flag_list = predicate_flag_list;
788 matcher.predicate_flag_combo = predicate_flag_combo;
789 matcher.case_checkbtn = case_checkbtn;
790 matcher.regexp_checkbtn = regexp_checkbtn;
791 matcher.bool_op_list = bool_op_list;
792 matcher.test_btn = test_btn;
793 matcher.addressbook_select_btn = addressbook_select_btn;
794 matcher.color_optmenu = color_optmenu;
795 matcher.criteria_table = criteria_table;
797 matcher.cond_list_view = cond_list_view;
799 matcher.selected_criteria = -1;
800 prefs_matcher_criteria_select(GTK_LIST(criteria_list), NULL, NULL);
804 *\brief Set the contents of a row
806 *\param row Index of row to set
807 *\param prop Condition to set
809 *\return gint Row index \a prop has been added
811 static void prefs_matcher_list_view_set_row(GtkTreeIter *row, MatcherProp *prop)
816 prefs_matcher_list_view_insert_matcher(matcher.cond_list_view,
817 NULL, _("(New)"), FALSE);
821 matcher_str = matcherprop_to_string(prop);
823 prefs_matcher_list_view_insert_matcher(matcher.cond_list_view,
827 prefs_matcher_list_view_insert_matcher(matcher.cond_list_view,
834 *\brief Clears a condition in the list widget
836 static void prefs_matcher_reset_condition(void)
838 gtk_list_select_item(GTK_LIST(matcher.criteria_list), 0);
839 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
840 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), "");
841 gtk_entry_set_text(GTK_ENTRY(matcher.header_addr_entry), "");
842 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), "");
843 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(matcher.addressbook_folder_combo)->entry), "");
847 *\brief Initializes dialog with a set of conditions
849 *\param matchers List of conditions
851 static void prefs_matcher_set_dialog(MatcherList *matchers)
854 gboolean bool_op = 1;
855 GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
856 (GTK_TREE_VIEW(matcher.cond_list_view)));
858 gtk_list_store_clear(store);
860 prefs_matcher_list_view_set_row(NULL, NULL);
861 if (matchers != NULL) {
862 for (cur = matchers->matchers; cur != NULL;
863 cur = g_slist_next(cur)) {
865 prop = (MatcherProp *) cur->data;
866 prefs_matcher_list_view_set_row(NULL, prop);
869 bool_op = matchers->bool_and;
872 gtk_list_select_item(GTK_LIST(matcher.bool_op_list), bool_op);
874 prefs_matcher_reset_condition();
878 *\brief Converts current conditions in list box in
879 * a matcher list used by the matcher.
881 *\return MatcherList * List of conditions.
883 static MatcherList *prefs_matcher_get_list(void)
888 GSList *matcher_list;
889 MatcherList *matchers;
893 model = gtk_tree_view_get_model(GTK_TREE_VIEW(matcher.cond_list_view));
894 if (!gtk_tree_model_get_iter_first(model, &iter))
902 gtk_tree_model_get(model, &iter,
903 PREFS_MATCHER_COND, &matcher_str,
904 PREFS_MATCHER_COND_VALID, &is_valid,
908 /* tmp = matcher_str; */
909 prop = matcher_parser_get_prop(matcher_str);
914 matcher_list = g_slist_append(matcher_list, prop);
916 } while (gtk_tree_model_iter_next(model, &iter));
918 bool_and = get_sel_from_list(GTK_LIST(matcher.bool_op_list));
920 matchers = matcherlist_new(matcher_list, bool_and);
926 *\brief Maps a keyword id (see #get_matchparser_tab_id) to a
927 * criteria type (see first parameter of #matcherprop_new
928 * or #matcherprop_unquote_new)
930 *\param matching_id Id returned by the matcher parser.
932 *\return gint One of the CRITERIA_xxx constants.
934 static gint prefs_matcher_get_criteria_from_matching(gint matching_id)
936 switch(matching_id) {
937 case MATCHCRITERIA_ALL:
939 case MATCHCRITERIA_NOT_UNREAD:
940 case MATCHCRITERIA_UNREAD:
941 return CRITERIA_UNREAD;
942 case MATCHCRITERIA_NOT_NEW:
943 case MATCHCRITERIA_NEW:
945 case MATCHCRITERIA_NOT_MARKED:
946 case MATCHCRITERIA_MARKED:
947 return CRITERIA_MARKED;
948 case MATCHCRITERIA_NOT_DELETED:
949 case MATCHCRITERIA_DELETED:
950 return CRITERIA_DELETED;
951 case MATCHCRITERIA_NOT_REPLIED:
952 case MATCHCRITERIA_REPLIED:
953 return CRITERIA_REPLIED;
954 case MATCHCRITERIA_NOT_FORWARDED:
955 case MATCHCRITERIA_FORWARDED:
956 return CRITERIA_FORWARDED;
957 case MATCHCRITERIA_LOCKED:
958 case MATCHCRITERIA_NOT_LOCKED:
959 return CRITERIA_LOCKED;
960 case MATCHCRITERIA_NOT_SPAM:
961 case MATCHCRITERIA_SPAM:
962 return CRITERIA_SPAM;
963 case MATCHCRITERIA_PARTIAL:
964 case MATCHCRITERIA_NOT_PARTIAL:
965 return CRITERIA_PARTIAL;
966 case MATCHCRITERIA_COLORLABEL:
967 case MATCHCRITERIA_NOT_COLORLABEL:
968 return CRITERIA_COLORLABEL;
969 case MATCHCRITERIA_IGNORE_THREAD:
970 case MATCHCRITERIA_NOT_IGNORE_THREAD:
971 return CRITERIA_IGNORE_THREAD;
972 case MATCHCRITERIA_NOT_SUBJECT:
973 case MATCHCRITERIA_SUBJECT:
974 return CRITERIA_SUBJECT;
975 case MATCHCRITERIA_NOT_FROM:
976 case MATCHCRITERIA_FROM:
977 return CRITERIA_FROM;
978 case MATCHCRITERIA_NOT_TO:
979 case MATCHCRITERIA_TO:
981 case MATCHCRITERIA_NOT_CC:
982 case MATCHCRITERIA_CC:
984 case MATCHCRITERIA_NOT_NEWSGROUPS:
985 case MATCHCRITERIA_NEWSGROUPS:
986 return CRITERIA_NEWSGROUPS;
987 case MATCHCRITERIA_NOT_INREPLYTO:
988 case MATCHCRITERIA_INREPLYTO:
989 return CRITERIA_INREPLYTO;
990 case MATCHCRITERIA_NOT_REFERENCES:
991 case MATCHCRITERIA_REFERENCES:
992 return CRITERIA_REFERENCES;
993 case MATCHCRITERIA_NOT_TO_AND_NOT_CC:
994 case MATCHCRITERIA_TO_OR_CC:
995 return CRITERIA_TO_OR_CC;
996 case MATCHCRITERIA_NOT_BODY_PART:
997 case MATCHCRITERIA_BODY_PART:
998 return CRITERIA_BODY_PART;
999 case MATCHCRITERIA_NOT_MESSAGE:
1000 case MATCHCRITERIA_MESSAGE:
1001 return CRITERIA_MESSAGE;
1002 case MATCHCRITERIA_NOT_HEADERS_PART:
1003 case MATCHCRITERIA_HEADERS_PART:
1004 return CRITERIA_HEADERS_PART;
1005 case MATCHCRITERIA_NOT_HEADER:
1006 case MATCHCRITERIA_HEADER:
1007 return CRITERIA_HEADER;
1008 case MATCHCRITERIA_AGE_GREATER:
1009 return CRITERIA_AGE_GREATER;
1010 case MATCHCRITERIA_AGE_LOWER:
1011 return CRITERIA_AGE_LOWER;
1012 case MATCHCRITERIA_SCORE_GREATER:
1013 return CRITERIA_SCORE_GREATER;
1014 case MATCHCRITERIA_SCORE_LOWER:
1015 return CRITERIA_SCORE_LOWER;
1016 case MATCHCRITERIA_SCORE_EQUAL:
1017 return CRITERIA_SCORE_EQUAL;
1018 case MATCHCRITERIA_NOT_TEST:
1019 case MATCHCRITERIA_TEST:
1020 return CRITERIA_TEST;
1021 case MATCHCRITERIA_SIZE_GREATER:
1022 return CRITERIA_SIZE_GREATER;
1023 case MATCHCRITERIA_SIZE_SMALLER:
1024 return CRITERIA_SIZE_SMALLER;
1025 case MATCHCRITERIA_SIZE_EQUAL:
1026 return CRITERIA_SIZE_EQUAL;
1027 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK:
1028 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK:
1029 return CRITERIA_FOUND_IN_ADDRESSBOOK;
1036 *\brief Returns the matcher keyword id from a criteria id
1038 *\param criteria_id Criteria id (should not be the negate
1041 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1043 static gint prefs_matcher_get_matching_from_criteria(gint criteria_id)
1045 switch (criteria_id) {
1047 return MATCHCRITERIA_ALL;
1048 case CRITERIA_UNREAD:
1049 return MATCHCRITERIA_UNREAD;
1051 return MATCHCRITERIA_NEW;
1052 case CRITERIA_MARKED:
1053 return MATCHCRITERIA_MARKED;
1054 case CRITERIA_DELETED:
1055 return MATCHCRITERIA_DELETED;
1056 case CRITERIA_REPLIED:
1057 return MATCHCRITERIA_REPLIED;
1058 case CRITERIA_FORWARDED:
1059 return MATCHCRITERIA_FORWARDED;
1060 case CRITERIA_LOCKED:
1061 return MATCHCRITERIA_LOCKED;
1063 return MATCHCRITERIA_SPAM;
1064 case CRITERIA_PARTIAL:
1065 return MATCHCRITERIA_PARTIAL;
1066 case CRITERIA_COLORLABEL:
1067 return MATCHCRITERIA_COLORLABEL;
1068 case CRITERIA_IGNORE_THREAD:
1069 return MATCHCRITERIA_IGNORE_THREAD;
1070 case CRITERIA_SUBJECT:
1071 return MATCHCRITERIA_SUBJECT;
1073 return MATCHCRITERIA_FROM;
1075 return MATCHCRITERIA_TO;
1077 return MATCHCRITERIA_CC;
1078 case CRITERIA_TO_OR_CC:
1079 return MATCHCRITERIA_TO_OR_CC;
1080 case CRITERIA_NEWSGROUPS:
1081 return MATCHCRITERIA_NEWSGROUPS;
1082 case CRITERIA_INREPLYTO:
1083 return MATCHCRITERIA_INREPLYTO;
1084 case CRITERIA_REFERENCES:
1085 return MATCHCRITERIA_REFERENCES;
1086 case CRITERIA_AGE_GREATER:
1087 return MATCHCRITERIA_AGE_GREATER;
1088 case CRITERIA_AGE_LOWER:
1089 return MATCHCRITERIA_AGE_LOWER;
1090 case CRITERIA_SCORE_GREATER:
1091 return MATCHCRITERIA_SCORE_GREATER;
1092 case CRITERIA_SCORE_LOWER:
1093 return MATCHCRITERIA_SCORE_LOWER;
1094 case CRITERIA_SCORE_EQUAL:
1095 return MATCHCRITERIA_SCORE_EQUAL;
1096 case CRITERIA_HEADER:
1097 return MATCHCRITERIA_HEADER;
1098 case CRITERIA_HEADERS_PART:
1099 return MATCHCRITERIA_HEADERS_PART;
1100 case CRITERIA_BODY_PART:
1101 return MATCHCRITERIA_BODY_PART;
1102 case CRITERIA_MESSAGE:
1103 return MATCHCRITERIA_MESSAGE;
1105 return MATCHCRITERIA_TEST;
1106 case CRITERIA_SIZE_GREATER:
1107 return MATCHCRITERIA_SIZE_GREATER;
1108 case CRITERIA_SIZE_SMALLER:
1109 return MATCHCRITERIA_SIZE_SMALLER;
1110 case CRITERIA_SIZE_EQUAL:
1111 return MATCHCRITERIA_SIZE_EQUAL;
1112 case CRITERIA_FOUND_IN_ADDRESSBOOK:
1113 return MATCHCRITERIA_FOUND_IN_ADDRESSBOOK;
1120 *\brief Returns the negate matcher keyword id from a matcher keyword
1123 *\param matcher_criteria Matcher keyword id.
1125 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1127 static gint prefs_matcher_not_criteria(gint matcher_criteria)
1129 switch(matcher_criteria) {
1130 case MATCHCRITERIA_UNREAD:
1131 return MATCHCRITERIA_NOT_UNREAD;
1132 case MATCHCRITERIA_NEW:
1133 return MATCHCRITERIA_NOT_NEW;
1134 case MATCHCRITERIA_MARKED:
1135 return MATCHCRITERIA_NOT_MARKED;
1136 case MATCHCRITERIA_DELETED:
1137 return MATCHCRITERIA_NOT_DELETED;
1138 case MATCHCRITERIA_REPLIED:
1139 return MATCHCRITERIA_NOT_REPLIED;
1140 case MATCHCRITERIA_FORWARDED:
1141 return MATCHCRITERIA_NOT_FORWARDED;
1142 case MATCHCRITERIA_LOCKED:
1143 return MATCHCRITERIA_NOT_LOCKED;
1144 case MATCHCRITERIA_SPAM:
1145 return MATCHCRITERIA_NOT_SPAM;
1146 case MATCHCRITERIA_PARTIAL:
1147 return MATCHCRITERIA_NOT_PARTIAL;
1148 case MATCHCRITERIA_COLORLABEL:
1149 return MATCHCRITERIA_NOT_COLORLABEL;
1150 case MATCHCRITERIA_IGNORE_THREAD:
1151 return MATCHCRITERIA_NOT_IGNORE_THREAD;
1152 case MATCHCRITERIA_SUBJECT:
1153 return MATCHCRITERIA_NOT_SUBJECT;
1154 case MATCHCRITERIA_FROM:
1155 return MATCHCRITERIA_NOT_FROM;
1156 case MATCHCRITERIA_TO:
1157 return MATCHCRITERIA_NOT_TO;
1158 case MATCHCRITERIA_CC:
1159 return MATCHCRITERIA_NOT_CC;
1160 case MATCHCRITERIA_TO_OR_CC:
1161 return MATCHCRITERIA_NOT_TO_AND_NOT_CC;
1162 case MATCHCRITERIA_NEWSGROUPS:
1163 return MATCHCRITERIA_NOT_NEWSGROUPS;
1164 case MATCHCRITERIA_INREPLYTO:
1165 return MATCHCRITERIA_NOT_INREPLYTO;
1166 case MATCHCRITERIA_REFERENCES:
1167 return MATCHCRITERIA_NOT_REFERENCES;
1168 case MATCHCRITERIA_HEADER:
1169 return MATCHCRITERIA_NOT_HEADER;
1170 case MATCHCRITERIA_HEADERS_PART:
1171 return MATCHCRITERIA_NOT_HEADERS_PART;
1172 case MATCHCRITERIA_MESSAGE:
1173 return MATCHCRITERIA_NOT_MESSAGE;
1174 case MATCHCRITERIA_TEST:
1175 return MATCHCRITERIA_NOT_TEST;
1176 case MATCHCRITERIA_BODY_PART:
1177 return MATCHCRITERIA_NOT_BODY_PART;
1178 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK:
1179 return MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK;
1181 return matcher_criteria;
1186 *\brief Converts the text in the selected row to a
1189 *\return MatcherProp * Newly allocated matcher structure.
1191 static MatcherProp *prefs_matcher_dialog_to_matcher(void)
1193 MatcherProp *matcherprop;
1197 gint value_pred_flag;
1198 gint value_criteria;
1199 gboolean use_regexp;
1200 gboolean case_sensitive;
1201 const gchar *header;
1204 const gchar *value_str;
1206 value_criteria = get_sel_from_list(GTK_LIST(matcher.criteria_list));
1208 criteria = prefs_matcher_get_matching_from_criteria(value_criteria);
1210 value_pred = get_sel_from_list(GTK_LIST(matcher.predicate_list));
1211 value_pred_flag = get_sel_from_list(GTK_LIST(matcher.predicate_flag_list));
1213 use_regexp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn));
1214 case_sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn));
1216 switch (value_criteria) {
1217 case CRITERIA_UNREAD:
1219 case CRITERIA_MARKED:
1220 case CRITERIA_DELETED:
1221 case CRITERIA_REPLIED:
1222 case CRITERIA_FORWARDED:
1223 case CRITERIA_LOCKED:
1225 case CRITERIA_PARTIAL:
1227 case CRITERIA_COLORLABEL:
1228 case CRITERIA_IGNORE_THREAD:
1229 case CRITERIA_FOUND_IN_ADDRESSBOOK:
1230 if (value_pred_flag == PREDICATE_FLAG_DISABLED)
1231 criteria = prefs_matcher_not_criteria(criteria);
1233 case CRITERIA_SUBJECT:
1237 case CRITERIA_TO_OR_CC:
1238 case CRITERIA_NEWSGROUPS:
1239 case CRITERIA_INREPLYTO:
1240 case CRITERIA_REFERENCES:
1241 case CRITERIA_HEADERS_PART:
1242 case CRITERIA_BODY_PART:
1243 case CRITERIA_MESSAGE:
1244 case CRITERIA_AGE_GREATER:
1245 case CRITERIA_AGE_LOWER:
1246 case CRITERIA_HEADER:
1247 if (value_pred == PREDICATE_DOES_NOT_CONTAIN)
1248 criteria = prefs_matcher_not_criteria(criteria);
1254 matchtype = MATCHTYPE_REGEXP;
1256 matchtype = MATCHTYPE_REGEXPCASE;
1260 matchtype = MATCHTYPE_MATCH;
1262 matchtype = MATCHTYPE_MATCHCASE;
1269 switch (value_criteria) {
1271 case CRITERIA_UNREAD:
1273 case CRITERIA_MARKED:
1274 case CRITERIA_DELETED:
1275 case CRITERIA_REPLIED:
1276 case CRITERIA_FORWARDED:
1277 case CRITERIA_LOCKED:
1279 case CRITERIA_PARTIAL:
1280 case CRITERIA_IGNORE_THREAD:
1283 case CRITERIA_SUBJECT:
1287 case CRITERIA_TO_OR_CC:
1288 case CRITERIA_NEWSGROUPS:
1289 case CRITERIA_INREPLYTO:
1290 case CRITERIA_REFERENCES:
1291 case CRITERIA_HEADERS_PART:
1292 case CRITERIA_BODY_PART:
1293 case CRITERIA_MESSAGE:
1295 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
1298 case CRITERIA_AGE_GREATER:
1299 case CRITERIA_AGE_LOWER:
1300 case CRITERIA_SCORE_GREATER:
1301 case CRITERIA_SCORE_LOWER:
1302 case CRITERIA_SCORE_EQUAL:
1303 case CRITERIA_SIZE_GREATER:
1304 case CRITERIA_SIZE_SMALLER:
1305 case CRITERIA_SIZE_EQUAL:
1306 value_str = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
1308 if (*value_str == '\0') {
1309 alertpanel_error(_("Value is not set."));
1313 value = atoi(value_str);
1316 case CRITERIA_COLORLABEL:
1317 value = colorlabel_get_color_menu_active_item
1318 (gtk_option_menu_get_menu(GTK_OPTION_MENU
1319 (matcher.color_optmenu)));
1322 case CRITERIA_HEADER:
1323 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_entry));
1324 expr = gtk_entry_get_text(GTK_ENTRY(matcher.value_entry));
1326 if (*header == '\0') {
1327 alertpanel_error(_("Header name is not set."));
1332 case CRITERIA_FOUND_IN_ADDRESSBOOK:
1333 header = gtk_entry_get_text(GTK_ENTRY(matcher.header_addr_entry));
1334 expr = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(matcher.addressbook_folder_combo)->entry));
1336 if (*header == '\0') {
1337 alertpanel_error(_("Header name is not set."));
1340 if (*expr == '\0') {
1344 if (strcasecmp(header, Q_("Filtering Matcher Menu|All")) == 0)
1345 tmp = g_strdup(_("all addresses in all headers"));
1347 if (strcasecmp(header, _("Any")) == 0)
1348 tmp = g_strdup(_("any address in any header"));
1350 tmp = g_strdup_printf(_("the address(es) in header '%s'"), header);
1351 msg = g_strdup_printf(_("Book/folder path is not set.\n\n"
1352 "If you want to match %s against the whole address book, "
1353 "you have to select 'Any' from the book/folder drop-down list."),
1355 alertpanel_error(msg);
1360 /* don't store translated "Any"/"All" in matcher expressions */
1361 if (strcasecmp(header, Q_("Filtering Matcher Menu|All")) == 0)
1364 if (strcasecmp(header, _("Any")) == 0)
1366 if (strcasecmp(expr, _("Any")) == 0)
1371 matcherprop = matcherprop_new(criteria, header, matchtype,
1378 *\brief Signal handler for register button
1380 static void prefs_matcher_register_cb(void)
1382 MatcherProp *matcherprop;
1384 matcherprop = prefs_matcher_dialog_to_matcher();
1385 if (matcherprop == NULL)
1388 prefs_matcher_list_view_set_row(NULL, matcherprop);
1390 matcherprop_free(matcherprop);
1392 prefs_matcher_reset_condition();
1396 *\brief Signal handler for substitute button
1398 static void prefs_matcher_substitute_cb(void)
1400 MatcherProp *matcherprop;
1402 GtkTreeSelection *selection;
1403 GtkTreeModel *model;
1406 selection = gtk_tree_view_get_selection
1407 (GTK_TREE_VIEW(matcher.cond_list_view));
1409 if (!gtk_tree_selection_get_selected(selection, &model, &row))
1412 gtk_tree_model_get(model, &row,
1413 PREFS_MATCHER_COND_VALID, &is_valid,
1418 matcherprop = prefs_matcher_dialog_to_matcher();
1419 if (matcherprop == NULL)
1422 prefs_matcher_list_view_set_row(&row, matcherprop);
1424 matcherprop_free(matcherprop);
1426 prefs_matcher_reset_condition();
1430 *\brief Signal handler for delete button
1432 static void prefs_matcher_delete_cb(void)
1435 GtkTreeSelection *selection;
1436 GtkTreeModel *model;
1439 selection = gtk_tree_view_get_selection
1440 (GTK_TREE_VIEW(matcher.cond_list_view));
1442 if (!gtk_tree_selection_get_selected(selection, &model, &row))
1445 gtk_tree_model_get(model, &row,
1446 PREFS_MATCHER_COND_VALID, &is_valid,
1452 gtk_list_store_remove(GTK_LIST_STORE(model), &row);
1454 prefs_matcher_reset_condition();
1458 *\brief Signal handler for 'move up' button
1460 static void prefs_matcher_up(void)
1462 GtkTreePath *prev, *sel, *try;
1464 GtkListStore *store = NULL;
1465 GtkTreeModel *model = NULL;
1468 if (!gtk_tree_selection_get_selected
1469 (gtk_tree_view_get_selection
1470 (GTK_TREE_VIEW(matcher.cond_list_view)),
1474 store = (GtkListStore *)model;
1475 sel = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &isel);
1479 /* no move if we're at row 0 or 1, looks phony, but other
1480 * solutions are more convoluted... */
1481 try = gtk_tree_path_copy(sel);
1482 if (!gtk_tree_path_prev(try) || !gtk_tree_path_prev(try)) {
1483 gtk_tree_path_free(try);
1484 gtk_tree_path_free(sel);
1487 gtk_tree_path_free(try);
1489 prev = gtk_tree_path_copy(sel);
1490 if (gtk_tree_path_prev(prev)) {
1491 gtk_tree_model_get_iter(GTK_TREE_MODEL(store),
1493 gtk_list_store_swap(store, &iprev, &isel);
1494 /* XXX: GTK2 select row?? */
1497 gtk_tree_path_free(sel);
1498 gtk_tree_path_free(prev);
1502 *\brief Signal handler for 'move down' button
1504 static void prefs_matcher_down(void)
1506 GtkListStore *store = NULL;
1507 GtkTreeModel *model = NULL;
1508 GtkTreeIter next, sel;
1511 if (!gtk_tree_selection_get_selected
1512 (gtk_tree_view_get_selection
1513 (GTK_TREE_VIEW(matcher.cond_list_view)),
1517 store = (GtkListStore *)model;
1518 try = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &sel);
1522 /* move when not at row 0 ... */
1523 if (gtk_tree_path_prev(try)) {
1525 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &next))
1526 gtk_list_store_swap(store, &next, &sel);
1529 gtk_tree_path_free(try);
1533 *\brief Helper function that allows us to replace the 'Value' entry box
1534 * by another widget.
1536 *\param old_widget Widget that needs to be removed.
1537 *\param new_widget Replacement widget
1539 static void prefs_matcher_set_value_widget(GtkWidget *old_widget,
1540 GtkWidget *new_widget)
1542 /* TODO: find out why the following spews harmless "parent errors" */
1544 /* NOTE: we first need to bump up the refcount of the old_widget,
1545 * because the gtkut_container_remove() will otherwise destroy it */
1546 gtk_widget_ref(old_widget);
1547 gtkut_container_remove(GTK_CONTAINER(matcher.criteria_table), old_widget);
1548 gtk_widget_show(new_widget);
1549 gtk_widget_set_size_request(new_widget, 200, -1);
1550 gtk_table_attach(GTK_TABLE(matcher.criteria_table), new_widget,
1552 GTK_FILL | GTK_SHRINK | GTK_EXPAND,
1556 static void prefs_matcher_disable_widget(GtkWidget* widget)
1558 g_return_if_fail( widget != NULL);
1560 gtk_widget_set_sensitive(widget, FALSE);
1561 gtk_widget_hide(widget);
1564 static void prefs_matcher_enable_widget(GtkWidget* widget)
1566 g_return_if_fail( widget != NULL);
1568 gtk_widget_set_sensitive(widget, TRUE);
1569 gtk_widget_show(widget);
1573 *\brief Change widgets depending on the selected condition
1575 *\param list List widget
1576 *\param widget Not used
1577 *\param user_data Not used
1579 static void prefs_matcher_criteria_select(GtkList *list,
1583 gint value, old_value;
1585 old_value = matcher.selected_criteria;
1586 matcher.selected_criteria = value = get_sel_from_list
1587 (GTK_LIST(matcher.criteria_list));
1589 if (old_value == matcher.selected_criteria)
1592 /* CLAWS: the value widget is currently either the color label combo box,
1593 * or a GtkEntry, so kiss for now */
1594 if (matcher.selected_criteria == CRITERIA_COLORLABEL) {
1595 prefs_matcher_set_value_widget(matcher.value_entry,
1596 matcher.color_optmenu);
1597 } else if (old_value == CRITERIA_COLORLABEL) {
1598 prefs_matcher_set_value_widget(matcher.color_optmenu,
1599 matcher.value_entry);
1604 prefs_matcher_disable_widget(matcher.header_combo);
1605 prefs_matcher_disable_widget(matcher.header_label);
1606 prefs_matcher_disable_widget(matcher.header_addr_combo);
1607 prefs_matcher_disable_widget(matcher.header_addr_label);
1608 prefs_matcher_disable_widget(matcher.value_label);
1609 prefs_matcher_disable_widget(matcher.value_entry);
1610 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1611 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1612 prefs_matcher_disable_widget(matcher.predicate_label);
1613 prefs_matcher_disable_widget(matcher.predicate_combo);
1614 prefs_matcher_disable_widget(matcher.predicate_flag_combo);
1615 prefs_matcher_disable_widget(matcher.case_checkbtn);
1616 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1617 prefs_matcher_disable_widget(matcher.test_btn);
1618 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1621 case CRITERIA_UNREAD:
1623 case CRITERIA_MARKED:
1624 case CRITERIA_DELETED:
1625 case CRITERIA_REPLIED:
1626 case CRITERIA_FORWARDED:
1627 case CRITERIA_LOCKED:
1629 case CRITERIA_PARTIAL:
1630 case CRITERIA_IGNORE_THREAD:
1631 prefs_matcher_disable_widget(matcher.header_combo);
1632 prefs_matcher_disable_widget(matcher.header_label);
1633 prefs_matcher_disable_widget(matcher.header_addr_combo);
1634 prefs_matcher_disable_widget(matcher.header_addr_label);
1635 prefs_matcher_disable_widget(matcher.value_label);
1636 prefs_matcher_disable_widget(matcher.value_entry);
1637 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1638 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1639 prefs_matcher_enable_widget(matcher.predicate_label);
1640 prefs_matcher_disable_widget(matcher.predicate_combo);
1641 prefs_matcher_enable_widget(matcher.predicate_flag_combo);
1642 prefs_matcher_disable_widget(matcher.case_checkbtn);
1643 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1644 prefs_matcher_disable_widget(matcher.test_btn);
1645 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1648 case CRITERIA_COLORLABEL:
1649 prefs_matcher_disable_widget(matcher.header_combo);
1650 prefs_matcher_disable_widget(matcher.header_label);
1651 prefs_matcher_disable_widget(matcher.header_addr_combo);
1652 prefs_matcher_disable_widget(matcher.header_addr_label);
1653 prefs_matcher_enable_widget(matcher.value_label);
1654 prefs_matcher_disable_widget(matcher.value_entry);
1655 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1656 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1657 prefs_matcher_enable_widget(matcher.predicate_label);
1658 prefs_matcher_disable_widget(matcher.predicate_combo);
1659 prefs_matcher_enable_widget(matcher.predicate_flag_combo);
1660 prefs_matcher_disable_widget(matcher.case_checkbtn);
1661 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1662 prefs_matcher_disable_widget(matcher.test_btn);
1663 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1666 case CRITERIA_SUBJECT:
1670 case CRITERIA_TO_OR_CC:
1671 case CRITERIA_NEWSGROUPS:
1672 case CRITERIA_INREPLYTO:
1673 case CRITERIA_REFERENCES:
1674 case CRITERIA_HEADERS_PART:
1675 case CRITERIA_BODY_PART:
1676 case CRITERIA_MESSAGE:
1677 prefs_matcher_disable_widget(matcher.header_combo);
1678 prefs_matcher_disable_widget(matcher.header_label);
1679 prefs_matcher_disable_widget(matcher.header_addr_combo);
1680 prefs_matcher_disable_widget(matcher.header_addr_label);
1681 prefs_matcher_enable_widget(matcher.value_label);
1682 prefs_matcher_enable_widget(matcher.value_entry);
1683 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1684 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1685 prefs_matcher_enable_widget(matcher.predicate_label);
1686 prefs_matcher_enable_widget(matcher.predicate_combo);
1687 prefs_matcher_disable_widget(matcher.predicate_flag_combo);
1688 prefs_matcher_enable_widget(matcher.case_checkbtn);
1689 prefs_matcher_enable_widget(matcher.regexp_checkbtn);
1690 prefs_matcher_disable_widget(matcher.test_btn);
1691 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1695 prefs_matcher_disable_widget(matcher.header_combo);
1696 prefs_matcher_disable_widget(matcher.header_label);
1697 prefs_matcher_disable_widget(matcher.header_addr_combo);
1698 prefs_matcher_disable_widget(matcher.header_addr_label);
1699 prefs_matcher_enable_widget(matcher.value_label);
1700 prefs_matcher_enable_widget(matcher.value_entry);
1701 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1702 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1703 prefs_matcher_enable_widget(matcher.predicate_label);
1704 prefs_matcher_disable_widget(matcher.predicate_combo);
1705 prefs_matcher_enable_widget(matcher.predicate_flag_combo);
1706 prefs_matcher_disable_widget(matcher.case_checkbtn);
1707 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1708 prefs_matcher_enable_widget(matcher.test_btn);
1709 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1712 case CRITERIA_AGE_GREATER:
1713 case CRITERIA_AGE_LOWER:
1714 case CRITERIA_SCORE_GREATER:
1715 case CRITERIA_SCORE_LOWER:
1716 case CRITERIA_SCORE_EQUAL:
1717 case CRITERIA_SIZE_GREATER:
1718 case CRITERIA_SIZE_SMALLER:
1719 case CRITERIA_SIZE_EQUAL:
1720 prefs_matcher_disable_widget(matcher.header_combo);
1721 prefs_matcher_disable_widget(matcher.header_label);
1722 prefs_matcher_disable_widget(matcher.header_addr_combo);
1723 prefs_matcher_disable_widget(matcher.header_addr_label);
1724 prefs_matcher_enable_widget(matcher.value_label);
1725 prefs_matcher_enable_widget(matcher.value_entry);
1726 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1727 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1728 prefs_matcher_disable_widget(matcher.predicate_label);
1729 prefs_matcher_disable_widget(matcher.predicate_combo);
1730 prefs_matcher_disable_widget(matcher.predicate_flag_combo);
1731 prefs_matcher_disable_widget(matcher.case_checkbtn);
1732 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1733 prefs_matcher_disable_widget(matcher.test_btn);
1734 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1737 case CRITERIA_HEADER:
1738 prefs_matcher_enable_widget(matcher.header_combo);
1739 prefs_matcher_enable_widget(matcher.header_label);
1740 prefs_matcher_disable_widget(matcher.header_addr_combo);
1741 prefs_matcher_disable_widget(matcher.header_addr_label);
1742 prefs_matcher_enable_widget(matcher.value_label);
1743 prefs_matcher_enable_widget(matcher.value_entry);
1744 prefs_matcher_disable_widget(matcher.addressbook_folder_label);
1745 prefs_matcher_disable_widget(matcher.addressbook_folder_combo);
1746 prefs_matcher_enable_widget(matcher.predicate_label);
1747 prefs_matcher_enable_widget(matcher.predicate_combo);
1748 prefs_matcher_disable_widget(matcher.predicate_flag_combo);
1749 prefs_matcher_enable_widget(matcher.case_checkbtn);
1750 prefs_matcher_enable_widget(matcher.regexp_checkbtn);
1751 prefs_matcher_disable_widget(matcher.test_btn);
1752 prefs_matcher_disable_widget(matcher.addressbook_select_btn);
1755 case CRITERIA_FOUND_IN_ADDRESSBOOK:
1756 prefs_matcher_disable_widget(matcher.header_combo);
1757 prefs_matcher_disable_widget(matcher.header_label);
1758 prefs_matcher_enable_widget(matcher.header_addr_combo);
1759 prefs_matcher_enable_widget(matcher.header_addr_label);
1760 prefs_matcher_disable_widget(matcher.value_label);
1761 prefs_matcher_disable_widget(matcher.value_entry);
1762 prefs_matcher_enable_widget(matcher.addressbook_folder_label);
1763 prefs_matcher_enable_widget(matcher.addressbook_folder_combo);
1764 prefs_matcher_enable_widget(matcher.predicate_label);
1765 prefs_matcher_disable_widget(matcher.predicate_combo);
1766 prefs_matcher_enable_widget(matcher.predicate_flag_combo);
1767 prefs_matcher_disable_widget(matcher.case_checkbtn);
1768 prefs_matcher_disable_widget(matcher.regexp_checkbtn);
1769 prefs_matcher_disable_widget(matcher.test_btn);
1770 prefs_matcher_enable_widget(matcher.addressbook_select_btn);
1776 *\brief Handle key press
1778 *\param widget Widget receiving key press
1779 *\param event Key event
1780 *\param data User data
1782 static gboolean prefs_matcher_key_pressed(GtkWidget *widget, GdkEventKey *event,
1785 if (event && event->keyval == GDK_Escape) {
1786 prefs_matcher_cancel();
1793 *\brief Cancel matcher dialog
1795 static void prefs_matcher_cancel(void)
1797 gtk_widget_hide(matcher.window);
1802 *\brief Accept current matchers
1804 static void prefs_matcher_ok(void)
1806 MatcherList *matchers;
1807 MatcherProp *matcherprop;
1809 gchar *matcher_str = NULL;
1812 GtkTreeModel *model;
1815 matchers = prefs_matcher_get_list();
1817 if (matchers != NULL) {
1818 matcherprop = prefs_matcher_dialog_to_matcher();
1819 if (matcherprop != NULL) {
1820 str = matcherprop_to_string(matcherprop);
1821 matcherprop_free(matcherprop);
1822 if (strcmp(str, "all") != 0) {
1823 model = gtk_tree_view_get_model(GTK_TREE_VIEW
1824 (matcher.cond_list_view));
1826 while (gtk_tree_model_iter_nth_child(model, &iter, NULL, row)) {
1827 gtk_tree_model_get(model, &iter,
1828 PREFS_MATCHER_COND, &matcher_str,
1830 if (matcher_str && strcmp(matcher_str, str) == 0)
1833 g_free(matcher_str);
1837 if (!matcher_str || strcmp(matcher_str, str) != 0) {
1838 val = alertpanel(_("Entry not saved"),
1839 _("The entry was not saved.\nClose anyway?"),
1840 GTK_STOCK_CLOSE, _("+_Continue editing"), NULL);
1841 if (G_ALERTDEFAULT != val) {
1842 g_free(matcher_str);
1847 g_free(matcher_str);
1851 gtk_widget_hide(matcher.window);
1853 if (matchers_callback != NULL)
1854 matchers_callback(matchers);
1855 matcherlist_free(matchers);
1860 *\brief Called when closing dialog box
1862 *\param widget Dialog widget
1863 *\param event Event info
1864 *\param data User data
1868 static gint prefs_matcher_deleted(GtkWidget *widget, GdkEventAny *event,
1871 prefs_matcher_cancel();
1876 * Strings describing test format strings
1878 * When adding new lines, remember to put 2 strings for each line
1880 static gchar *test_desc_strings[] = {
1881 "%%", N_("literal %"),
1882 "%s", N_("Subject"),
1887 "%i", N_("Message-ID"),
1888 "%n", N_("Newsgroups"),
1889 "%r", N_("References"),
1890 "%F", N_("filename (should not be modified)"),
1891 "\\n", N_("new line"),
1892 "\\", N_("escape character for quotes"),
1893 "\\\"", N_("quote character"),
1897 static DescriptionWindow test_desc_win = {
1901 N_("Match Type: 'Test'"),
1902 N_("'Test' allows you to test a message or message element "
1903 "using an external program or script. The program will "
1904 "return either 0 or 1.\n\n"
1905 "The following symbols can be used:"),
1912 *\brief Show Test action's info
1914 void prefs_matcher_test_info(void)
1916 description_window_create(&test_desc_win);
1919 void prefs_matcher_addressbook_select(void)
1921 gchar *folderpath = NULL;
1922 gboolean ret = FALSE;
1924 folderpath = (gchar *) gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(matcher.addressbook_folder_combo)->entry));
1925 ret = addressbook_folder_selection(&folderpath);
1926 if ( ret != FALSE && folderpath != NULL)
1927 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(matcher.addressbook_folder_combo)->entry), folderpath);
1935 static GtkListStore* prefs_matcher_create_data_store(void)
1937 return gtk_list_store_new(N_PREFS_MATCHER_COLUMNS,
1943 static void prefs_matcher_list_view_insert_matcher(GtkWidget *list_view,
1944 GtkTreeIter *row_iter,
1945 const gchar *matcher,
1949 GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model
1950 (GTK_TREE_VIEW(list_view)));
1952 if (row_iter == NULL) {
1954 gtk_list_store_append(list_store, &iter);
1956 /* change existing */
1960 gtk_list_store_set(list_store, &iter,
1961 PREFS_MATCHER_COND, matcher,
1962 PREFS_MATCHER_COND_VALID, is_valid,
1966 static GtkWidget *prefs_matcher_list_view_create(void)
1968 GtkTreeView *list_view;
1969 GtkTreeSelection *selector;
1970 GtkTreeModel *model;
1972 model = GTK_TREE_MODEL(prefs_matcher_create_data_store());
1973 list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
1974 g_object_unref(model);
1976 gtk_tree_view_set_rules_hint(list_view, prefs_common.use_stripes_everywhere);
1978 selector = gtk_tree_view_get_selection(list_view);
1979 gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
1980 gtk_tree_selection_set_select_function(selector, prefs_matcher_selected,
1983 /* create the columns */
1984 prefs_matcher_create_list_view_columns(GTK_WIDGET(list_view));
1986 return GTK_WIDGET(list_view);
1989 static void prefs_matcher_create_list_view_columns(GtkWidget *list_view)
1991 GtkTreeViewColumn *column;
1992 GtkCellRenderer *renderer;
1994 renderer = gtk_cell_renderer_text_new();
1995 column = gtk_tree_view_column_new_with_attributes
1996 (_("Current condition rules"),
1998 "text", PREFS_MATCHER_COND,
2000 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);
2003 static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
2004 GtkTreeModel *model,
2006 gboolean currently_selected,
2011 gboolean negative_cond;
2016 if (currently_selected)
2019 if (!gtk_tree_model_get_iter(model, &iter, path))
2022 gtk_tree_model_get(model, &iter,
2023 PREFS_MATCHER_COND_VALID, &is_valid,
2024 PREFS_MATCHER_COND, &matcher_str,
2028 g_free(matcher_str);
2029 prefs_matcher_reset_condition();
2033 negative_cond = FALSE;
2035 prop = matcher_parser_get_prop(matcher_str);
2037 g_free(matcher_str);
2041 criteria = prefs_matcher_get_criteria_from_matching(prop->criteria);
2043 gtk_list_select_item(GTK_LIST(matcher.criteria_list),
2046 switch(prop->criteria) {
2047 case MATCHCRITERIA_NOT_UNREAD:
2048 case MATCHCRITERIA_NOT_NEW:
2049 case MATCHCRITERIA_NOT_MARKED:
2050 case MATCHCRITERIA_NOT_DELETED:
2051 case MATCHCRITERIA_NOT_REPLIED:
2052 case MATCHCRITERIA_NOT_FORWARDED:
2053 case MATCHCRITERIA_NOT_LOCKED:
2054 case MATCHCRITERIA_NOT_SPAM:
2055 case MATCHCRITERIA_NOT_PARTIAL:
2056 case MATCHCRITERIA_NOT_COLORLABEL:
2057 case MATCHCRITERIA_NOT_IGNORE_THREAD:
2058 case MATCHCRITERIA_NOT_SUBJECT:
2059 case MATCHCRITERIA_NOT_FROM:
2060 case MATCHCRITERIA_NOT_TO:
2061 case MATCHCRITERIA_NOT_CC:
2062 case MATCHCRITERIA_NOT_TO_AND_NOT_CC:
2063 case MATCHCRITERIA_NOT_NEWSGROUPS:
2064 case MATCHCRITERIA_NOT_INREPLYTO:
2065 case MATCHCRITERIA_NOT_REFERENCES:
2066 case MATCHCRITERIA_NOT_HEADER:
2067 case MATCHCRITERIA_NOT_HEADERS_PART:
2068 case MATCHCRITERIA_NOT_MESSAGE:
2069 case MATCHCRITERIA_NOT_BODY_PART:
2070 case MATCHCRITERIA_NOT_TEST:
2071 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK:
2072 negative_cond = TRUE;
2076 switch(prop->criteria) {
2077 case MATCHCRITERIA_ALL:
2080 case MATCHCRITERIA_NOT_SUBJECT:
2081 case MATCHCRITERIA_NOT_FROM:
2082 case MATCHCRITERIA_NOT_TO:
2083 case MATCHCRITERIA_NOT_CC:
2084 case MATCHCRITERIA_NOT_TO_AND_NOT_CC:
2085 case MATCHCRITERIA_NOT_NEWSGROUPS:
2086 case MATCHCRITERIA_NOT_INREPLYTO:
2087 case MATCHCRITERIA_NOT_REFERENCES:
2088 case MATCHCRITERIA_NOT_HEADERS_PART:
2089 case MATCHCRITERIA_NOT_BODY_PART:
2090 case MATCHCRITERIA_NOT_MESSAGE:
2091 case MATCHCRITERIA_NOT_TEST:
2092 case MATCHCRITERIA_SUBJECT:
2093 case MATCHCRITERIA_FROM:
2094 case MATCHCRITERIA_TO:
2095 case MATCHCRITERIA_CC:
2096 case MATCHCRITERIA_TO_OR_CC:
2097 case MATCHCRITERIA_NEWSGROUPS:
2098 case MATCHCRITERIA_INREPLYTO:
2099 case MATCHCRITERIA_REFERENCES:
2100 case MATCHCRITERIA_HEADERS_PART:
2101 case MATCHCRITERIA_BODY_PART:
2102 case MATCHCRITERIA_MESSAGE:
2103 case MATCHCRITERIA_TEST:
2104 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
2107 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK:
2108 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK:
2113 /* matcher expressions contain UNtranslated "Any"/"All",
2114 select the relevant translated combo item */
2115 if (strcasecmp(prop->header, "All") == 0)
2116 header = (gchar*)Q_("Filtering Matcher Menu|All");
2118 if (strcasecmp(prop->header, "Any") == 0)
2121 header = prop->header;
2122 if (strcasecmp(prop->expr, "Any") == 0)
2127 gtk_entry_set_text(GTK_ENTRY(matcher.header_addr_entry), header);
2128 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(matcher.addressbook_folder_combo)->entry), expr);
2132 case MATCHCRITERIA_AGE_GREATER:
2133 case MATCHCRITERIA_AGE_LOWER:
2134 case MATCHCRITERIA_SCORE_GREATER:
2135 case MATCHCRITERIA_SCORE_LOWER:
2136 case MATCHCRITERIA_SCORE_EQUAL:
2137 case MATCHCRITERIA_SIZE_GREATER:
2138 case MATCHCRITERIA_SIZE_SMALLER:
2139 case MATCHCRITERIA_SIZE_EQUAL:
2140 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), itos(prop->value));
2143 case MATCHCRITERIA_NOT_COLORLABEL:
2144 case MATCHCRITERIA_COLORLABEL:
2145 gtk_option_menu_set_history(GTK_OPTION_MENU(matcher.color_optmenu),
2149 case MATCHCRITERIA_NOT_HEADER:
2150 case MATCHCRITERIA_HEADER:
2151 gtk_entry_set_text(GTK_ENTRY(matcher.header_entry), prop->header);
2152 gtk_entry_set_text(GTK_ENTRY(matcher.value_entry), prop->expr);
2156 if (negative_cond) {
2157 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 1);
2158 gtk_list_select_item(GTK_LIST(matcher.predicate_flag_list), 1);
2160 gtk_list_select_item(GTK_LIST(matcher.predicate_list), 0);
2161 gtk_list_select_item(GTK_LIST(matcher.predicate_flag_list), 0);
2164 switch(prop->matchtype) {
2165 case MATCHTYPE_MATCH:
2166 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn), FALSE);
2167 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn), TRUE);
2170 case MATCHTYPE_MATCHCASE:
2171 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn), FALSE);
2172 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn), FALSE);
2175 case MATCHTYPE_REGEXP:
2176 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn), TRUE);
2177 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn), TRUE);
2180 case MATCHTYPE_REGEXPCASE:
2181 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.regexp_checkbtn), TRUE);
2182 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher.case_checkbtn), FALSE);
2186 g_free(matcher_str);