2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2018 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 3 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, see <http://www.gnu.org/licenses/>.
21 #include "claws-features.h"
27 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
35 #include "gtkcmoptionmenu.h"
37 #include "prefs_gtk.h"
38 #include "prefs_matcher.h"
39 #include "prefs_common.h"
40 #include "procheader.h"
41 #include "mainwindow.h"
42 #include "foldersel.h"
43 #include "manage_window.h"
48 #include "alertpanel.h"
50 #include "description_window.h"
53 #include "matcher_parser.h"
54 #include "colorlabel.h"
56 #ifndef USE_ALT_ADDRBOOK
57 #include "addressbook.h"
60 #ifndef USE_ALT_ADDRBOOK
61 static void prefs_matcher_addressbook_select(void);
63 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
);
67 PREFS_MATCHER_COND_VALID
,
68 N_PREFS_MATCHER_COLUMNS
72 *\brief UI data for matcher dialog
74 static struct Matcher
{
79 GtkWidget
*match_combo
;
80 GtkWidget
*header_addr_combo
;
81 GtkWidget
*bool_op_combo
;
82 GtkWidget
*criteria_label2
;
83 GtkWidget
*criteria_combo
;
84 GtkWidget
*criteria_combo2
;
85 GtkWidget
*match_combo2
;
86 GtkWidget
*match_label
;
87 GtkWidget
*match_label2
;
88 GtkWidget
*headers_combo
;
89 GtkWidget
*upper_filler
;
90 GtkWidget
*lower_filler
;
92 GtkWidget
*header_entry
;
93 GtkWidget
*header_addr_entry
;
94 GtkWidget
*string_entry
;
95 GtkWidget
*numeric_entry
;
96 GtkWidget
*numeric_label
;
97 GtkWidget
*addressbook_folder_combo
;
98 GtkWidget
*case_checkbtn
;
99 GtkWidget
*regexp_checkbtn
;
100 GtkWidget
*color_optmenu
;
102 GtkWidget
*time_label
;
103 GtkWidget
*time_entry
;
106 GtkWidget
*addressbook_select_btn
;
108 GtkTreeModel
*model_age
;
109 GtkTreeModel
*model_date
;
110 GtkTreeModel
*model_age_units
;
111 GtkTreeModel
*model_contain
;
112 GtkTreeModel
*model_found
;
113 GtkTreeModel
*model_flags
;
114 GtkTreeModel
*model_headers
;
115 GtkTreeModel
*model_partial
;
116 GtkTreeModel
*model_phrase
;
117 GtkTreeModel
*model_score
;
118 GtkTreeModel
*model_set
;
119 GtkTreeModel
*model_size
;
120 GtkTreeModel
*model_size_units
;
121 GtkTreeModel
*model_tags
;
122 GtkTreeModel
*model_test
;
123 GtkTreeModel
*model_thread
;
125 GtkWidget
*cond_list_view
;
127 gint selected_criteria
; /*!< selected criteria in combobox */
131 *\brief Conditions with a negate counterpart (like unread and ~unread)
132 * have the same CRITERIA_XXX id). I.e. both unread and ~unread
133 * have criteria id CRITERIA_UNREAD. This id is passed as the
134 * first parameter to #matcherprop_new and #matcherprop_unquote_new.
139 CRITERIA_SUBJECT
= 1,
143 CRITERIA_TO_OR_CC
= 5,
144 CRITERIA_NEWSGROUPS
= 6,
145 CRITERIA_INREPLYTO
= 7,
146 CRITERIA_REFERENCES
= 8,
147 CRITERIA_AGE_GREATER
= 9,
148 CRITERIA_AGE_LOWER
= 10,
149 CRITERIA_HEADER
= 11,
150 CRITERIA_HEADERS_PART
= 12,
151 CRITERIA_BODY_PART
= 13,
152 CRITERIA_MESSAGE
= 14,
154 CRITERIA_UNREAD
= 15,
156 CRITERIA_MARKED
= 17,
157 CRITERIA_DELETED
= 18,
158 CRITERIA_REPLIED
= 19,
159 CRITERIA_FORWARDED
= 20,
160 CRITERIA_LOCKED
= 21,
162 CRITERIA_COLORLABEL
= 23,
163 CRITERIA_IGNORE_THREAD
= 24,
164 CRITERIA_WATCH_THREAD
= 25,
166 CRITERIA_SCORE_GREATER
= 26,
167 CRITERIA_SCORE_LOWER
= 27,
168 CRITERIA_SCORE_EQUAL
= 28,
172 CRITERIA_SIZE_GREATER
= 30,
173 CRITERIA_SIZE_SMALLER
= 31,
174 CRITERIA_SIZE_EQUAL
= 32,
176 CRITERIA_PARTIAL
= 33,
178 CRITERIA_FOUND_IN_ADDRESSBOOK
= 34,
181 CRITERIA_TAGGED
= 36,
183 CRITERIA_HAS_ATTACHMENT
= 37,
184 CRITERIA_SIGNED
= 38,
186 CRITERIA_AGE_GREATER_HOURS
= 39,
187 CRITERIA_AGE_LOWER_HOURS
= 40,
189 CRITERIA_MESSAGEID
= 41,
190 CRITERIA_HEADERS_CONT
= 42,
192 CRITERIA_DATE_AFTER
= 43,
193 CRITERIA_DATE_BEFORE
= 44
221 SIZE_UNIT_KBYTES
= 1,
225 #define MB_SIZE 0x100000
226 #define KB_SIZE 0x000400
230 THREAD_NOT_IGNORED
= 1,
232 THREAD_NOT_WATCHED
= 3
236 *\brief Contains predicate
239 PREDICATE_CONTAINS
= 0,
240 PREDICATE_DOES_NOT_CONTAIN
= 1
244 *\brief Enabled predicate
247 PREDICATE_FLAG_ENABLED
= 0,
248 PREDICATE_FLAG_DISABLED
= 1
254 static PrefsMatcherSignal
*matchers_callback
;
256 /* widget creating functions */
257 static void prefs_matcher_create (void);
259 static void prefs_matcher_set_dialog (MatcherList
*matchers
);
260 static void prefs_matcher_list_view_set_row (GtkTreeIter
*row
,
263 /* callback functions */
265 static void prefs_matcher_register_cb (void);
266 static void prefs_matcher_substitute_cb (void);
267 static void prefs_matcher_delete_cb (void);
268 static void prefs_matcher_up (void);
269 static void prefs_matcher_down (void);
270 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
,
273 static void prefs_matcher_ok (void);
274 static void prefs_matcher_cancel (void);
275 static gint
prefs_matcher_deleted (GtkWidget
*widget
, GdkEventAny
*event
,
277 static void prefs_matcher_criteria_select (GtkWidget
*widget
,
279 static void prefs_matcher_second_criteria_sel (GtkWidget
*widget
,
281 static void prefs_matcher_set_model (GtkWidget
*wiget
,
282 GtkTreeModel
*model
);
283 static MatcherList
*prefs_matcher_get_list (void);
285 static GtkListStore
* prefs_matcher_create_data_store (void);
287 static void prefs_matcher_list_view_insert_matcher (GtkWidget
*list_view
,
288 GtkTreeIter
*row_iter
,
289 const gchar
*matcher
,
292 static GtkWidget
*prefs_matcher_list_view_create (void);
294 static void prefs_matcher_create_list_view_columns (GtkWidget
*list_view
);
296 static gboolean
prefs_matcher_selected (GtkTreeSelection
*selector
,
299 gboolean currently_selected
,
302 static int header_name_to_crit(const gchar
*header
)
305 return CRITERIA_HEADER
;
307 if (!strcasecmp(header
, "Subject"))
308 return CRITERIA_SUBJECT
;
309 if (!strcasecmp(header
, "From"))
310 return CRITERIA_FROM
;
311 if (!strcasecmp(header
, "To"))
313 if (!strcasecmp(header
, "Cc"))
315 if (!strcasecmp(header
, "To or Cc"))
316 return CRITERIA_TO_OR_CC
;
317 if (!strcasecmp(header
, "Message-ID"))
318 return CRITERIA_MESSAGEID
;
319 if (!strcasecmp(header
, "In-Reply-To"))
320 return CRITERIA_INREPLYTO
;
321 if (!strcasecmp(header
, "Newsgroups"))
322 return CRITERIA_NEWSGROUPS
;
323 if (!strcasecmp(header
, "References"))
324 return CRITERIA_REFERENCES
;
326 return CRITERIA_HEADER
;
329 static void prefs_matcher_models_create(void)
334 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
335 COMBOBOX_ADD(store
, _("more than"), CRITERIA_AGE_GREATER
);
336 COMBOBOX_ADD(store
, _("less than"), CRITERIA_AGE_LOWER
);
337 matcher
.model_age
= GTK_TREE_MODEL(store
);
339 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
340 COMBOBOX_ADD(store
, _("hours"), AGE_HOURS
);
341 COMBOBOX_ADD(store
, _("days"), AGE_DAYS
);
342 COMBOBOX_ADD(store
, _("weeks"), AGE_WEEKS
);
343 matcher
.model_age_units
= GTK_TREE_MODEL(store
);
345 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
346 COMBOBOX_ADD(store
, _("after"), CRITERIA_DATE_AFTER
);
347 COMBOBOX_ADD(store
, _("before"), CRITERIA_DATE_BEFORE
);
348 matcher
.model_date
= GTK_TREE_MODEL(store
);
350 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
351 COMBOBOX_ADD(store
, _("higher than"), CRITERIA_SCORE_GREATER
);
352 COMBOBOX_ADD(store
, _("lower than"), CRITERIA_SCORE_LOWER
);
353 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SCORE_EQUAL
);
354 matcher
.model_score
= GTK_TREE_MODEL(store
);
356 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
357 COMBOBOX_ADD(store
, _("greater than"), CRITERIA_SIZE_GREATER
);
358 COMBOBOX_ADD(store
, _("smaller than"), CRITERIA_SIZE_SMALLER
);
359 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SIZE_EQUAL
);
360 matcher
.model_size
= GTK_TREE_MODEL(store
);
362 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
363 COMBOBOX_ADD(store
, _("bytes"), SIZE_UNIT_BYTES
);
364 COMBOBOX_ADD(store
, _("kilobytes"), SIZE_UNIT_KBYTES
);
365 COMBOBOX_ADD(store
, _("megabytes"), SIZE_UNIT_MBYTES
);
366 matcher
.model_size_units
= GTK_TREE_MODEL(store
);
368 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
369 COMBOBOX_ADD(store
, _("contains"), 0);
370 COMBOBOX_ADD(store
, _("doesn't contain"), 0);
371 matcher
.model_contain
= GTK_TREE_MODEL(store
);
373 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
374 COMBOBOX_ADD(store
, "Subject", CRITERIA_SUBJECT
);
375 COMBOBOX_ADD(store
, "From", CRITERIA_FROM
);
376 COMBOBOX_ADD(store
, "To", CRITERIA_TO
);
377 COMBOBOX_ADD(store
, "Cc", CRITERIA_CC
);
378 COMBOBOX_ADD(store
, "To or Cc", CRITERIA_TO_OR_CC
);
379 COMBOBOX_ADD(store
, "Message-ID", CRITERIA_MESSAGEID
);
380 COMBOBOX_ADD(store
, "In-Reply-To", CRITERIA_INREPLYTO
);
381 COMBOBOX_ADD(store
, "Newsgroups", CRITERIA_NEWSGROUPS
);
382 COMBOBOX_ADD(store
, "References", CRITERIA_REFERENCES
);
383 COMBOBOX_ADD(store
, "Sender", CRITERIA_HEADER
);
384 COMBOBOX_ADD(store
, "X-ML-Name", CRITERIA_HEADER
);
385 COMBOBOX_ADD(store
, "X-List", CRITERIA_HEADER
);
386 COMBOBOX_ADD(store
, "X-Sequence", CRITERIA_HEADER
);
387 COMBOBOX_ADD(store
, "X-Mailer", CRITERIA_HEADER
);
388 COMBOBOX_ADD(store
, "X-BeenThere", CRITERIA_HEADER
);
389 COMBOBOX_ADD(store
, "List-Post", CRITERIA_HEADER
);
390 COMBOBOX_ADD(store
, "List-Id", CRITERIA_HEADER
);
391 matcher
.model_headers
= GTK_TREE_MODEL(store
);
393 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
394 COMBOBOX_ADD(store
, _("headers part"), CRITERIA_HEADERS_PART
);
395 COMBOBOX_ADD(store
, _("headers values"), CRITERIA_HEADERS_CONT
);
396 COMBOBOX_ADD(store
, _("body part"), CRITERIA_BODY_PART
);
397 COMBOBOX_ADD(store
, _("whole message"), CRITERIA_MESSAGE
);
398 matcher
.model_phrase
= GTK_TREE_MODEL(store
);
400 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
401 COMBOBOX_ADD(store
, _("Unread"), CRITERIA_UNREAD
);
402 COMBOBOX_ADD(store
, _("New"), CRITERIA_NEW
);
403 COMBOBOX_ADD(store
, _("Marked"), CRITERIA_MARKED
);
404 COMBOBOX_ADD(store
, _("Deleted"), CRITERIA_DELETED
);
405 COMBOBOX_ADD(store
, _("Replied"), CRITERIA_REPLIED
);
406 COMBOBOX_ADD(store
, _("Forwarded"), CRITERIA_FORWARDED
);
407 COMBOBOX_ADD(store
, _("Locked"), CRITERIA_LOCKED
);
408 COMBOBOX_ADD(store
, _("Spam"), CRITERIA_SPAM
);
409 COMBOBOX_ADD(store
, _("Has attachment"), CRITERIA_HAS_ATTACHMENT
);
410 COMBOBOX_ADD(store
, _("Signed"), CRITERIA_SIGNED
);
411 matcher
.model_flags
= GTK_TREE_MODEL(store
);
413 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
414 COMBOBOX_ADD(store
, _("set"), 0);
415 COMBOBOX_ADD(store
, _("not set"), 1);
416 matcher
.model_set
= GTK_TREE_MODEL(store
);
418 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
419 COMBOBOX_ADD(store
, _("yes"), CRITERIA_PARTIAL
);
420 COMBOBOX_ADD(store
, _("no"), CRITERIA_PARTIAL
);
421 matcher
.model_partial
= GTK_TREE_MODEL(store
);
423 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
424 COMBOBOX_ADD(store
, _("Any tags"), CRITERIA_TAGGED
);
425 COMBOBOX_ADD(store
, _("Specific tag"), CRITERIA_TAG
);
426 matcher
.model_tags
= GTK_TREE_MODEL(store
);
428 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
429 COMBOBOX_ADD(store
, _("ignored"), CRITERIA_IGNORE_THREAD
);
430 COMBOBOX_ADD(store
, _("not ignored"), CRITERIA_IGNORE_THREAD
);
431 COMBOBOX_ADD(store
, _("watched"), CRITERIA_WATCH_THREAD
);
432 COMBOBOX_ADD(store
, _("not watched"), CRITERIA_WATCH_THREAD
);
433 matcher
.model_thread
= GTK_TREE_MODEL(store
);
435 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
436 COMBOBOX_ADD(store
, _("found"), 0);
437 COMBOBOX_ADD(store
, _("not found"), 1);
438 matcher
.model_found
= GTK_TREE_MODEL(store
);
440 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
441 COMBOBOX_ADD(store
, _("0 (Passed)"), 0);
442 COMBOBOX_ADD(store
, _("non-0 (Failed)"), 1);
443 matcher
.model_test
= GTK_TREE_MODEL(store
);
447 *\brief Opens the matcher dialog with a list of conditions
449 *\param matchers List of conditions
453 void prefs_matcher_open(MatcherList
*matchers
, PrefsMatcherSignal
*cb
)
457 if (!matcher
.window
) {
458 prefs_matcher_models_create();
459 prefs_matcher_create();
461 /* update color label menu */
462 gtk_cmoption_menu_set_menu(GTK_CMOPTION_MENU(matcher
.color_optmenu
),
463 colorlabel_create_color_menu());
466 manage_window_set_transient(GTK_WINDOW(matcher
.window
));
467 gtk_widget_grab_focus(matcher
.ok_btn
);
469 matchers_callback
= cb
;
471 prefs_matcher_set_dialog(matchers
);
473 gtk_widget_show(matcher
.window
);
474 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), TRUE
);
478 *\brief Save Gtk object size to prefs dataset
480 static void prefs_matcher_size_allocate_cb(GtkWidget
*widget
,
481 GtkAllocation
*allocation
)
483 cm_return_if_fail(allocation
!= NULL
);
485 prefs_common
.matcherwin_width
= allocation
->width
;
486 prefs_common
.matcherwin_height
= allocation
->height
;
490 *\brief Create the matcher dialog
492 static void prefs_matcher_create(void)
497 GtkWidget
*cancel_btn
;
498 GtkWidget
*confirm_area
;
503 GtkWidget
*upper_hbox
;
504 GtkWidget
*lower_hbox
;
505 GtkWidget
*match_hbox
;
506 GtkWidget
*criteria_combo
;
507 GtkWidget
*criteria_label
;
508 GtkWidget
*match_label
;
509 GtkWidget
*criteria_label2
;
510 GtkWidget
*headers_combo
;
511 GtkWidget
*match_combo2
;
512 GtkWidget
*match_label2
;
515 GtkWidget
*upper_filler
;
516 GtkWidget
*lower_filler
;
518 GtkWidget
*criteria_combo2
;
519 GtkWidget
*header_entry
;
520 GtkWidget
*header_addr_combo
;
521 GtkWidget
*header_addr_entry
;
522 GtkWidget
*string_entry
;
523 GtkWidget
*addressbook_folder_combo
;
524 GtkWidget
*match_combo
;
525 GtkWidget
*bool_op_combo
;
526 GtkWidget
*bool_op_label
;
528 GtkWidget
*numeric_hbox
;
529 GtkWidget
*numeric_entry
;
530 GtkWidget
*numeric_label
;
532 GtkWidget
*regexp_checkbtn
;
533 GtkWidget
*case_checkbtn
;
539 GtkWidget
*subst_btn
;
542 GtkWidget
*cond_hbox
;
543 GtkWidget
*cond_scrolledwin
;
544 GtkWidget
*cond_list_view
;
551 GtkWidget
*addressbook_select_btn
;
552 GtkWidget
*color_optmenu
;
554 GtkWidget
*time_label
;
555 GtkWidget
*time_entry
;
556 GtkWidget
*date_hbox
;
557 GtkWidget
*date_vbox
;
559 static GdkGeometry geometry
;
560 GtkSizeGroup
*size_group
;
564 debug_print("Creating matcher configuration window...\n");
566 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "prefs_matcher");
567 gtk_container_set_border_width(GTK_CONTAINER(window
), 4);
568 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
569 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
571 vbox
= gtk_vbox_new(FALSE
, 6);
572 gtk_container_add(GTK_CONTAINER(window
), vbox
);
574 gtkut_stock_button_set_create(&confirm_area
, &cancel_btn
, GTK_STOCK_CANCEL
,
575 &ok_btn
, GTK_STOCK_OK
, NULL
, NULL
);
576 gtk_box_pack_end(GTK_BOX(vbox
), confirm_area
, FALSE
, FALSE
, 0);
577 gtk_widget_grab_default(ok_btn
);
579 gtk_window_set_title(GTK_WINDOW(window
),
580 _("Condition configuration"));
581 g_signal_connect(G_OBJECT(window
), "delete_event",
582 G_CALLBACK(prefs_matcher_deleted
), NULL
);
583 g_signal_connect(G_OBJECT(window
), "size_allocate",
584 G_CALLBACK(prefs_matcher_size_allocate_cb
), NULL
);
585 g_signal_connect(G_OBJECT(window
), "key_press_event",
586 G_CALLBACK(prefs_matcher_key_pressed
), NULL
);
587 MANAGE_WINDOW_SIGNALS_CONNECT(window
);
588 g_signal_connect(G_OBJECT(ok_btn
), "clicked",
589 G_CALLBACK(prefs_matcher_ok
), NULL
);
590 g_signal_connect(G_OBJECT(cancel_btn
), "clicked",
591 G_CALLBACK(prefs_matcher_cancel
), NULL
);
593 vbox1
= gtk_vbox_new(FALSE
, VSPACING
);
594 gtk_box_pack_start(GTK_BOX(vbox
), vbox1
, TRUE
, TRUE
, 0);
595 gtk_container_set_border_width(GTK_CONTAINER (vbox1
), 2);
597 frame
= gtk_frame_new(_("Rule"));
598 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.01, 0.5);
599 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
601 table
= gtk_table_new(3, 3, FALSE
);
602 gtk_container_add(GTK_CONTAINER(frame
), table
);
603 gtk_widget_set_size_request(frame
, -1, -1);
605 upper_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
606 hbox
= gtk_hbox_new(FALSE
, 0);
607 gtk_box_pack_start(GTK_BOX(hbox
), upper_hbox
, FALSE
, FALSE
, 0);
608 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
609 gtk_table_attach(GTK_TABLE(table
), hbox
, 2, 3, 0, 1,
610 GTK_FILL
, GTK_SHRINK
, 2, 2);
612 lower_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
613 hbox
= gtk_hbox_new(FALSE
, 0);
614 gtk_box_pack_start(GTK_BOX(hbox
), lower_hbox
, FALSE
, FALSE
, 0);
615 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
616 gtk_table_attach(GTK_TABLE(table
), hbox
, 2, 3, 1, 2,
617 GTK_FILL
, GTK_SHRINK
, 2, 2);
619 size_group
= gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL
);
620 gtk_size_group_add_widget(size_group
, upper_hbox
);
621 gtk_size_group_add_widget(size_group
, lower_hbox
);
623 /* criteria combo box */
624 criteria_label
= gtk_label_new(_("Match criteria"));
625 gtk_misc_set_alignment(GTK_MISC(criteria_label
), 1, 0.5);
626 gtk_widget_set_size_request(criteria_label
, -1, -1);
627 gtk_table_attach(GTK_TABLE(table
), criteria_label
, 0, 1, 0, 1,
628 GTK_FILL
, GTK_SHRINK
, 2, 2);
630 criteria_combo
= gtkut_sc_combobox_create(NULL
, FALSE
);
631 store
= GTK_LIST_STORE(gtk_combo_box_get_model(
632 GTK_COMBO_BOX(criteria_combo
)));
633 COMBOBOX_ADD(store
, _("All messages"), MATCH_ALL
);
634 COMBOBOX_ADD(store
, _("Header"), MATCH_HEADER
);
635 COMBOBOX_ADD(store
, _("Age"), MATCH_AGE
);
636 COMBOBOX_ADD(store
, _("Phrase"), MATCH_PHRASE
);
637 COMBOBOX_ADD(store
, _("Flags"), MATCH_FLAG
);
638 COMBOBOX_ADD(store
, _("Color labels"), MATCH_LABEL
);
639 COMBOBOX_ADD(store
, _("Thread"), MATCH_THREAD
);
640 COMBOBOX_ADD(store
, _("Score"), MATCH_SCORE
);
641 COMBOBOX_ADD(store
, _("Size"), MATCH_SIZE
);
642 COMBOBOX_ADD(store
, _("Partially downloaded"), MATCH_PARTIAL
);
643 COMBOBOX_ADD(store
, _("Address book"), MATCH_ABOOK
);
644 COMBOBOX_ADD(store
, _("Tags"), MATCH_TAGS
);
645 COMBOBOX_ADD(store
, _("External program test"), MATCH_TEST
);
646 COMBOBOX_ADD(store
, _("Date"), MATCH_DATE
);
648 gtk_widget_set_size_request(criteria_combo
, 150, -1);
649 gtk_combo_box_set_active(GTK_COMBO_BOX(criteria_combo
), MATCH_ALL
);
650 gtk_table_attach(GTK_TABLE(table
), criteria_combo
, 1, 2, 0, 1,
651 GTK_FILL
, GTK_SHRINK
, 2, 2);
652 g_signal_connect(G_OBJECT(criteria_combo
), "changed",
653 G_CALLBACK(prefs_matcher_criteria_select
),
656 upper_filler
= gtk_label_new("");
657 gtk_box_pack_start(GTK_BOX(upper_hbox
), upper_filler
, TRUE
, TRUE
, 0);
659 lower_filler
= gtk_label_new("");
660 gtk_box_pack_start(GTK_BOX(lower_hbox
), lower_filler
, TRUE
, TRUE
, 0);
662 criteria_label2
= gtk_label_new("");
663 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_label2
, FALSE
, FALSE
, 0);
665 /* headers combo box entry */
666 headers_combo
= gtk_combo_box_new_with_model_and_entry(matcher
.model_headers
);
667 GtkCellRenderer
*cell
= gtk_cell_renderer_text_new();
668 gtk_cell_renderer_set_alignment(cell
, 0.0, 0.5);
669 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(headers_combo
), cell
, TRUE
);
670 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(headers_combo
), 0);
671 gtk_widget_set_size_request(headers_combo
, 100, -1);
672 gtk_box_pack_start(GTK_BOX(upper_hbox
), headers_combo
, TRUE
, TRUE
, 0);
673 header_entry
= gtk_bin_get_child(GTK_BIN((headers_combo
)));
674 CLAWS_SET_TIP(header_entry
, _("Use selector on the right to pick "
675 "the header name. Type the name of the header if not "
676 "available in the list."));
678 criteria_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
679 prefs_matcher_set_model(criteria_combo2
, matcher
.model_phrase
);
680 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_combo2
, TRUE
, TRUE
, 0);
681 g_signal_connect(G_OBJECT(criteria_combo2
), "changed",
682 G_CALLBACK(prefs_matcher_second_criteria_sel
),
685 /* book/folder value */
686 addressbook_folder_combo
= combobox_text_new(TRUE
, _("Any"), NULL
);
687 gtk_widget_set_size_request(addressbook_folder_combo
, 250, -1);
688 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_folder_combo
, TRUE
, TRUE
, 0);
690 addressbook_select_btn
= gtk_button_new_with_label(_("Select..."));
691 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_select_btn
, FALSE
, FALSE
, 0);
692 #ifndef USE_ALT_ADDRBOOK
693 g_signal_connect(G_OBJECT (addressbook_select_btn
), "clicked",
694 G_CALLBACK(prefs_matcher_addressbook_select
),
697 gtk_widget_set_sensitive(GTK_WIDGET(addressbook_select_btn
), FALSE
);
699 match_label
= gtk_label_new("");
700 gtk_misc_set_alignment(GTK_MISC(match_label
), 1, 0.5);
701 gtk_table_attach(GTK_TABLE(table
), match_label
, 0, 1, 1, 2,
702 GTK_FILL
, GTK_SHRINK
, 2, 2);
704 match_hbox
= gtk_hbox_new(FALSE
, 0);
705 gtk_table_attach(GTK_TABLE(table
), match_hbox
, 1, 2, 1, 2,
706 GTK_FILL
, GTK_SHRINK
, 2, 2);
708 match_combo
= gtkut_sc_combobox_create(NULL
, TRUE
);
709 gtk_box_pack_start(GTK_BOX(match_hbox
), match_combo
, TRUE
, TRUE
, 0);
711 /* color labels combo */
712 color_optmenu
= gtk_cmoption_menu_new();
713 gtk_cmoption_menu_set_menu(GTK_CMOPTION_MENU(color_optmenu
),
714 colorlabel_create_color_menu());
715 gtk_box_pack_start(GTK_BOX(match_hbox
), color_optmenu
, FALSE
, FALSE
, 0);
717 /* address header name */
718 header_addr_combo
= combobox_text_new(TRUE
,
719 C_("Filtering Matcher Menu", "All"), _("Any"),
720 "From", "To", "Cc", "Reply-To", "Sender", "Resent-From", "Resent-To", NULL
);
721 gtk_box_pack_start(GTK_BOX(match_hbox
), header_addr_combo
, FALSE
, FALSE
, 0);
722 header_addr_entry
= gtk_bin_get_child(GTK_BIN((header_addr_combo
)));
723 gtk_widget_set_size_request(header_addr_combo
, 150, -1);
725 match_label2
= gtk_label_new("");
726 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_label2
, FALSE
, FALSE
, 0);
729 numeric_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
730 gtk_box_pack_start(GTK_BOX(lower_hbox
), numeric_hbox
, FALSE
, FALSE
, 0);
732 numeric_entry
= gtk_spin_button_new_with_range(0, 1000, 1);
733 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(numeric_entry
), 0);
734 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_entry
, FALSE
, FALSE
, 0);
736 numeric_label
= gtk_label_new("");
737 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_label
, FALSE
, FALSE
, 0);
738 gtk_box_pack_end(GTK_BOX(numeric_hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
740 match_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
741 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_combo2
, TRUE
, TRUE
, 0);
744 string_entry
= gtk_entry_new();
745 gtk_box_pack_start(GTK_BOX(lower_hbox
), string_entry
, TRUE
, TRUE
, 0);
746 gtk_widget_set_size_request(string_entry
, 300, -1);
748 hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
749 gtk_size_group_add_widget(size_group
, hbox
);
751 vbox
= gtk_vbox_new(FALSE
, VSPACING_NARROW
);
752 PACK_CHECK_BUTTON(vbox
, case_checkbtn
, _("Case sensitive"));
753 PACK_CHECK_BUTTON(vbox
, regexp_checkbtn
, _("Use regexp"));
754 gtk_box_pack_start(GTK_BOX(hbox
), vbox
, TRUE
, TRUE
, 0);
756 gtk_box_pack_end(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
757 gtk_table_attach(GTK_TABLE(table
), hbox
, 2, 3, 2, 3,
758 GTK_FILL
, GTK_SHRINK
, 4, 0);
761 date_vbox
= gtk_vbox_new(FALSE
, VSPACING_NARROW
);
762 calendar
= gtk_calendar_new();
763 gtk_box_pack_start(GTK_BOX(hbox
), calendar
, TRUE
, TRUE
, 0);
764 gtk_box_pack_start(GTK_BOX(lower_hbox
), date_vbox
, FALSE
, FALSE
, 0);
766 date_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
767 gtk_box_pack_start(GTK_BOX(date_vbox
), date_hbox
, FALSE
, FALSE
, 0);
769 time_entry
= gtkut_time_select_combo_new();
770 gtk_box_pack_start(GTK_BOX(date_hbox
), time_entry
, FALSE
, FALSE
, 0);
771 time_label
= gtk_label_new(_("on:"));
772 gtk_misc_set_alignment(GTK_MISC(time_label
), 0, 0.5);
773 gtk_box_pack_start(GTK_BOX(date_hbox
), time_label
, FALSE
, FALSE
, 0);
775 /* test info button */
776 test_btn
= gtk_button_new_from_stock(GTK_STOCK_INFO
);
777 gtk_box_pack_start(GTK_BOX(lower_hbox
), test_btn
, FALSE
, FALSE
, 0);
778 g_signal_connect(G_OBJECT (test_btn
), "clicked",
779 G_CALLBACK(prefs_matcher_test_info
),
782 /* register / substitute / delete */
783 reg_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
784 gtk_box_pack_start(GTK_BOX(vbox1
), reg_hbox
, FALSE
, FALSE
, 0);
786 arrow
= gtk_arrow_new(GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
787 gtk_box_pack_start(GTK_BOX(reg_hbox
), arrow
, FALSE
, FALSE
, 0);
788 gtk_widget_set_size_request(arrow
, -1, 16);
790 btn_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
791 gtk_box_pack_start(GTK_BOX(reg_hbox
), btn_hbox
, FALSE
, FALSE
, 0);
793 reg_btn
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
794 gtk_box_pack_start(GTK_BOX(btn_hbox
), reg_btn
, FALSE
, TRUE
, 0);
795 g_signal_connect(G_OBJECT(reg_btn
), "clicked",
796 G_CALLBACK(prefs_matcher_register_cb
), NULL
);
798 subst_btn
= gtkut_get_replace_btn(_("_Replace"));
799 gtk_box_pack_start(GTK_BOX(btn_hbox
), subst_btn
, FALSE
, TRUE
, 0);
800 g_signal_connect(G_OBJECT(subst_btn
), "clicked",
801 G_CALLBACK(prefs_matcher_substitute_cb
),
804 del_btn
= gtk_button_new_with_mnemonic (_("D_elete"));
805 gtk_button_set_image(GTK_BUTTON(del_btn
),
806 gtk_image_new_from_stock(GTK_STOCK_REMOVE
,GTK_ICON_SIZE_BUTTON
));
807 gtk_box_pack_start(GTK_BOX(btn_hbox
), del_btn
, FALSE
, TRUE
, 0);
808 g_signal_connect(G_OBJECT(del_btn
), "clicked",
809 G_CALLBACK(prefs_matcher_delete_cb
), NULL
);
811 cond_hbox
= gtk_hbox_new(FALSE
, VBOX_BORDER
);
812 gtk_box_pack_start(GTK_BOX(vbox1
), cond_hbox
, TRUE
, TRUE
, 0);
814 cond_scrolledwin
= gtk_scrolled_window_new(NULL
, NULL
);
815 gtk_widget_set_size_request(cond_scrolledwin
, -1, 150);
816 gtk_box_pack_start(GTK_BOX(cond_hbox
), cond_scrolledwin
,
818 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
819 GTK_POLICY_AUTOMATIC
,
820 GTK_POLICY_AUTOMATIC
);
822 cond_list_view
= prefs_matcher_list_view_create();
823 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
824 GTK_SHADOW_ETCHED_IN
);
825 gtk_container_add(GTK_CONTAINER(cond_scrolledwin
), cond_list_view
);
827 btn_vbox
= gtk_vbox_new(FALSE
, VBOX_BORDER
);
828 gtk_box_pack_start(GTK_BOX(cond_hbox
), btn_vbox
, FALSE
, FALSE
, 0);
830 up_btn
= gtk_button_new_from_stock(GTK_STOCK_GO_UP
);
831 gtk_box_pack_start(GTK_BOX(btn_vbox
), up_btn
, FALSE
, FALSE
, 0);
832 g_signal_connect(G_OBJECT(up_btn
), "clicked",
833 G_CALLBACK(prefs_matcher_up
), NULL
);
835 down_btn
= gtk_button_new_from_stock(GTK_STOCK_GO_DOWN
);
836 gtk_box_pack_start(GTK_BOX(btn_vbox
), down_btn
, FALSE
, FALSE
, 0);
837 g_signal_connect(G_OBJECT(down_btn
), "clicked",
838 G_CALLBACK(prefs_matcher_down
), NULL
);
840 /* boolean operation */
841 GtkWidget
*hbox_bool
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
842 gtk_box_pack_start(GTK_BOX(vbox1
), hbox_bool
, FALSE
, FALSE
, 0);
844 bool_op_label
= gtk_label_new(_("Message must match"));
845 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_label
,
848 bool_op_combo
= combobox_text_new(FALSE
, _("at least one"),
850 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_combo
,
852 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(_("of above rules")),
854 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(""),
857 if (!geometry
.min_height
) {
858 geometry
.min_width
= 630;
859 geometry
.min_height
= 368;
862 gtk_window_set_geometry_hints(GTK_WINDOW(window
), NULL
, &geometry
,
864 gtk_widget_set_size_request(window
, prefs_common
.matcherwin_width
,
865 prefs_common
.matcherwin_height
);
867 gtk_widget_show_all(window
);
869 matcher
.window
= window
;
871 matcher
.ok_btn
= ok_btn
;
873 matcher
.criteria_combo
= criteria_combo
;
874 matcher
.criteria_combo2
= criteria_combo2
;
875 matcher
.header_entry
= header_entry
;
876 matcher
.header_addr_combo
= header_addr_combo
;
877 matcher
.header_addr_entry
= header_addr_entry
;
878 matcher
.string_entry
= string_entry
;
879 matcher
.numeric_entry
= numeric_entry
;
880 matcher
.numeric_label
= numeric_label
;
881 matcher
.addressbook_folder_combo
= addressbook_folder_combo
;
882 matcher
.match_combo
= match_combo
;
883 matcher
.case_checkbtn
= case_checkbtn
;
884 matcher
.regexp_checkbtn
= regexp_checkbtn
;
885 matcher
.bool_op_combo
= bool_op_combo
;
886 matcher
.test_btn
= test_btn
;
887 matcher
.calendar
= calendar
;
888 matcher
.time_label
= time_label
;
889 matcher
.time_entry
= time_entry
;
890 #ifndef USE_ALT_ADDRBOOK
891 matcher
.addressbook_select_btn
= addressbook_select_btn
;
893 matcher
.color_optmenu
= color_optmenu
;
894 matcher
.match_label
= match_label
;
895 matcher
.criteria_label2
= criteria_label2
;
896 matcher
.headers_combo
= headers_combo
;
897 matcher
.match_combo2
= match_combo2
;
898 matcher
.match_label2
= match_label2
;
899 matcher
.upper_filler
= upper_filler
;
900 matcher
.lower_filler
= lower_filler
;
902 matcher
.cond_list_view
= cond_list_view
;
904 matcher
.selected_criteria
= -1;
905 prefs_matcher_criteria_select(criteria_combo
, NULL
);
909 *\brief Set the contents of a row
911 *\param row Index of row to set
912 *\param prop Condition to set
914 *\return gint Row index \a prop has been added
916 static void prefs_matcher_list_view_set_row(GtkTreeIter
*row
, MatcherProp
*prop
)
921 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
922 NULL
, _("(New)"), FALSE
);
926 matcher_str
= matcherprop_to_string(prop
);
928 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
932 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
938 static gboolean
match_combo2_model_set(void)
940 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo2
));
941 if (model
== matcher
.model_age_units
||
942 model
== matcher
.model_found
||
943 model
== matcher
.model_partial
||
944 model
== matcher
.model_phrase
||
945 model
== matcher
.model_set
||
946 model
== matcher
.model_size_units
||
947 model
== matcher
.model_tags
||
948 model
== matcher
.model_thread
)
951 debug_print("match_combo2 model unset.\n");
956 static gboolean
match_combo_model_set(void)
958 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo
));
959 if (model
== matcher
.model_age
||
960 model
== matcher
.model_contain
||
961 model
== matcher
.model_flags
||
962 model
== matcher
.model_score
||
963 model
== matcher
.model_size
||
964 model
== matcher
.model_test
)
967 debug_print("match_combo model unset.\n");
973 *\brief Clears a condition in the list widget
975 static void prefs_matcher_reset_condition(void)
977 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_ALL
);
978 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
), 0);
979 if (match_combo_model_set())
980 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
), 0);
981 if (match_combo2_model_set())
982 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), 0);
983 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
), 0);
984 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
985 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), "");
986 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), "");
987 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
988 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), "");
989 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
990 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
992 gtk_calendar_select_today(GTK_CALENDAR(matcher
.calendar
));
993 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), 0, 0);
997 *\brief Initializes dialog with a set of conditions
999 *\param matchers List of conditions
1001 static void prefs_matcher_set_dialog(MatcherList
*matchers
)
1004 gboolean bool_op
= 1;
1005 GtkListStore
*store
= GTK_LIST_STORE(gtk_tree_view_get_model
1006 (GTK_TREE_VIEW(matcher
.cond_list_view
)));
1008 gtk_list_store_clear(store
);
1010 prefs_matcher_list_view_set_row(NULL
, NULL
);
1011 if (matchers
!= NULL
) {
1012 for (cur
= matchers
->matchers
; cur
!= NULL
;
1013 cur
= g_slist_next(cur
)) {
1015 prop
= (MatcherProp
*) cur
->data
;
1016 prefs_matcher_list_view_set_row(NULL
, prop
);
1019 bool_op
= matchers
->bool_and
;
1022 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.bool_op_combo
), bool_op
);
1024 prefs_matcher_reset_condition();
1026 combobox_set_sensitive(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_TAGS
,
1027 (tags_get_size() > 0) ? TRUE
: FALSE
);
1031 *\brief Converts current conditions in list box in
1032 * a matcher list used by the matcher.
1034 *\return MatcherList * List of conditions.
1036 static MatcherList
*prefs_matcher_get_list(void)
1041 GSList
*matcher_list
;
1042 MatcherList
*matchers
;
1043 GtkTreeModel
*model
;
1046 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(matcher
.cond_list_view
));
1047 if (!gtk_tree_model_get_iter_first(model
, &iter
))
1050 matcher_list
= NULL
;
1055 gtk_tree_model_get(model
, &iter
,
1056 PREFS_MATCHER_COND
, &matcher_str
,
1057 PREFS_MATCHER_COND_VALID
, &is_valid
,
1061 /* tmp = matcher_str; */
1062 prop
= matcher_parser_get_prop(matcher_str
);
1064 g_free(matcher_str
);
1068 matcher_list
= g_slist_append(matcher_list
, prop
);
1070 g_free(matcher_str
);
1071 } while (gtk_tree_model_iter_next(model
, &iter
));
1073 bool_and
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.bool_op_combo
));
1075 matchers
= matcherlist_new(matcher_list
, bool_and
);
1081 *\brief Maps a keyword id (see #get_matchparser_tab_id) to a
1082 * criteria type (see first parameter of #matcherprop_new
1083 * or #matcherprop_unquote_new)
1085 *\param matching_id Id returned by the matcher parser.
1087 *\return gint One of the CRITERIA_xxx constants.
1089 static gint
prefs_matcher_get_criteria_from_matching(gint matching_id
)
1091 switch(matching_id
) {
1092 case MATCHCRITERIA_ALL
:
1093 return CRITERIA_ALL
;
1094 case MATCHCRITERIA_NOT_UNREAD
:
1095 case MATCHCRITERIA_UNREAD
:
1096 return CRITERIA_UNREAD
;
1097 case MATCHCRITERIA_NOT_NEW
:
1098 case MATCHCRITERIA_NEW
:
1099 return CRITERIA_NEW
;
1100 case MATCHCRITERIA_NOT_MARKED
:
1101 case MATCHCRITERIA_MARKED
:
1102 return CRITERIA_MARKED
;
1103 case MATCHCRITERIA_NOT_DELETED
:
1104 case MATCHCRITERIA_DELETED
:
1105 return CRITERIA_DELETED
;
1106 case MATCHCRITERIA_NOT_REPLIED
:
1107 case MATCHCRITERIA_REPLIED
:
1108 return CRITERIA_REPLIED
;
1109 case MATCHCRITERIA_NOT_FORWARDED
:
1110 case MATCHCRITERIA_FORWARDED
:
1111 return CRITERIA_FORWARDED
;
1112 case MATCHCRITERIA_LOCKED
:
1113 case MATCHCRITERIA_NOT_LOCKED
:
1114 return CRITERIA_LOCKED
;
1115 case MATCHCRITERIA_NOT_SPAM
:
1116 case MATCHCRITERIA_SPAM
:
1117 return CRITERIA_SPAM
;
1118 case MATCHCRITERIA_HAS_ATTACHMENT
:
1119 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
1120 return CRITERIA_HAS_ATTACHMENT
;
1121 case MATCHCRITERIA_SIGNED
:
1122 case MATCHCRITERIA_NOT_SIGNED
:
1123 return CRITERIA_SIGNED
;
1124 case MATCHCRITERIA_PARTIAL
:
1125 case MATCHCRITERIA_NOT_PARTIAL
:
1126 return CRITERIA_PARTIAL
;
1127 case MATCHCRITERIA_COLORLABEL
:
1128 case MATCHCRITERIA_NOT_COLORLABEL
:
1129 return CRITERIA_COLORLABEL
;
1130 case MATCHCRITERIA_IGNORE_THREAD
:
1131 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
1132 return CRITERIA_IGNORE_THREAD
;
1133 case MATCHCRITERIA_WATCH_THREAD
:
1134 case MATCHCRITERIA_NOT_WATCH_THREAD
:
1135 return CRITERIA_WATCH_THREAD
;
1136 case MATCHCRITERIA_NOT_SUBJECT
:
1137 case MATCHCRITERIA_SUBJECT
:
1138 return CRITERIA_SUBJECT
;
1139 case MATCHCRITERIA_NOT_FROM
:
1140 case MATCHCRITERIA_FROM
:
1141 return CRITERIA_FROM
;
1142 case MATCHCRITERIA_NOT_TO
:
1143 case MATCHCRITERIA_TO
:
1145 case MATCHCRITERIA_NOT_CC
:
1146 case MATCHCRITERIA_CC
:
1148 case MATCHCRITERIA_NOT_NEWSGROUPS
:
1149 case MATCHCRITERIA_NEWSGROUPS
:
1150 return CRITERIA_NEWSGROUPS
;
1151 case MATCHCRITERIA_NOT_MESSAGEID
:
1152 case MATCHCRITERIA_MESSAGEID
:
1153 return CRITERIA_MESSAGEID
;
1154 case MATCHCRITERIA_NOT_INREPLYTO
:
1155 case MATCHCRITERIA_INREPLYTO
:
1156 return CRITERIA_INREPLYTO
;
1157 case MATCHCRITERIA_NOT_REFERENCES
:
1158 case MATCHCRITERIA_REFERENCES
:
1159 return CRITERIA_REFERENCES
;
1160 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
1161 case MATCHCRITERIA_TO_OR_CC
:
1162 return CRITERIA_TO_OR_CC
;
1163 case MATCHCRITERIA_NOT_TAG
:
1164 case MATCHCRITERIA_TAG
:
1165 return CRITERIA_TAG
;
1166 case MATCHCRITERIA_NOT_TAGGED
:
1167 case MATCHCRITERIA_TAGGED
:
1168 return CRITERIA_TAGGED
;
1169 case MATCHCRITERIA_NOT_BODY_PART
:
1170 case MATCHCRITERIA_BODY_PART
:
1171 return CRITERIA_BODY_PART
;
1172 case MATCHCRITERIA_NOT_MESSAGE
:
1173 case MATCHCRITERIA_MESSAGE
:
1174 return CRITERIA_MESSAGE
;
1175 case MATCHCRITERIA_NOT_HEADERS_PART
:
1176 case MATCHCRITERIA_HEADERS_PART
:
1177 return CRITERIA_HEADERS_PART
;
1178 case MATCHCRITERIA_NOT_HEADERS_CONT
:
1179 case MATCHCRITERIA_HEADERS_CONT
:
1180 return CRITERIA_HEADERS_CONT
;
1181 case MATCHCRITERIA_NOT_HEADER
:
1182 case MATCHCRITERIA_HEADER
:
1183 return CRITERIA_HEADER
;
1184 case MATCHCRITERIA_AGE_GREATER_HOURS
:
1185 return CRITERIA_AGE_GREATER_HOURS
;
1186 case MATCHCRITERIA_AGE_LOWER_HOURS
:
1187 return CRITERIA_AGE_LOWER_HOURS
;
1188 case MATCHCRITERIA_AGE_GREATER
:
1189 return CRITERIA_AGE_GREATER
;
1190 case MATCHCRITERIA_AGE_LOWER
:
1191 return CRITERIA_AGE_LOWER
;
1192 case MATCHCRITERIA_DATE_AFTER
:
1193 return CRITERIA_DATE_AFTER
;
1194 case MATCHCRITERIA_DATE_BEFORE
:
1195 return CRITERIA_DATE_BEFORE
;
1196 case MATCHCRITERIA_SCORE_GREATER
:
1197 return CRITERIA_SCORE_GREATER
;
1198 case MATCHCRITERIA_SCORE_LOWER
:
1199 return CRITERIA_SCORE_LOWER
;
1200 case MATCHCRITERIA_SCORE_EQUAL
:
1201 return CRITERIA_SCORE_EQUAL
;
1202 case MATCHCRITERIA_NOT_TEST
:
1203 case MATCHCRITERIA_TEST
:
1204 return CRITERIA_TEST
;
1205 case MATCHCRITERIA_SIZE_GREATER
:
1206 return CRITERIA_SIZE_GREATER
;
1207 case MATCHCRITERIA_SIZE_SMALLER
:
1208 return CRITERIA_SIZE_SMALLER
;
1209 case MATCHCRITERIA_SIZE_EQUAL
:
1210 return CRITERIA_SIZE_EQUAL
;
1211 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1212 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
1213 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1220 *\brief Returns the matcher keyword id from a criteria id
1222 *\param criteria_id Criteria id (should not be the negate
1225 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1227 static gint
prefs_matcher_get_matching_from_criteria(gint criteria_id
)
1229 switch (criteria_id
) {
1231 return MATCHCRITERIA_ALL
;
1232 case CRITERIA_UNREAD
:
1233 return MATCHCRITERIA_UNREAD
;
1235 return MATCHCRITERIA_NEW
;
1236 case CRITERIA_MARKED
:
1237 return MATCHCRITERIA_MARKED
;
1238 case CRITERIA_DELETED
:
1239 return MATCHCRITERIA_DELETED
;
1240 case CRITERIA_REPLIED
:
1241 return MATCHCRITERIA_REPLIED
;
1242 case CRITERIA_FORWARDED
:
1243 return MATCHCRITERIA_FORWARDED
;
1244 case CRITERIA_LOCKED
:
1245 return MATCHCRITERIA_LOCKED
;
1247 return MATCHCRITERIA_SPAM
;
1248 case CRITERIA_HAS_ATTACHMENT
:
1249 return MATCHCRITERIA_HAS_ATTACHMENT
;
1250 case CRITERIA_SIGNED
:
1251 return MATCHCRITERIA_SIGNED
;
1252 case CRITERIA_PARTIAL
:
1253 return MATCHCRITERIA_PARTIAL
;
1254 case CRITERIA_COLORLABEL
:
1255 return MATCHCRITERIA_COLORLABEL
;
1256 case CRITERIA_IGNORE_THREAD
:
1257 return MATCHCRITERIA_IGNORE_THREAD
;
1258 case CRITERIA_WATCH_THREAD
:
1259 return MATCHCRITERIA_WATCH_THREAD
;
1260 case CRITERIA_SUBJECT
:
1261 return MATCHCRITERIA_SUBJECT
;
1263 return MATCHCRITERIA_FROM
;
1265 return MATCHCRITERIA_TO
;
1267 return MATCHCRITERIA_CC
;
1268 case CRITERIA_TO_OR_CC
:
1269 return MATCHCRITERIA_TO_OR_CC
;
1271 return MATCHCRITERIA_TAG
;
1272 case CRITERIA_TAGGED
:
1273 return MATCHCRITERIA_TAGGED
;
1274 case CRITERIA_NEWSGROUPS
:
1275 return MATCHCRITERIA_NEWSGROUPS
;
1276 case CRITERIA_MESSAGEID
:
1277 return MATCHCRITERIA_MESSAGEID
;
1278 case CRITERIA_INREPLYTO
:
1279 return MATCHCRITERIA_INREPLYTO
;
1280 case CRITERIA_REFERENCES
:
1281 return MATCHCRITERIA_REFERENCES
;
1282 case CRITERIA_AGE_GREATER
:
1283 return MATCHCRITERIA_AGE_GREATER
;
1284 case CRITERIA_AGE_LOWER
:
1285 return MATCHCRITERIA_AGE_LOWER
;
1286 case CRITERIA_AGE_GREATER_HOURS
:
1287 return MATCHCRITERIA_AGE_GREATER_HOURS
;
1288 case CRITERIA_AGE_LOWER_HOURS
:
1289 return MATCHCRITERIA_AGE_LOWER_HOURS
;
1290 case CRITERIA_DATE_AFTER
:
1291 return MATCHCRITERIA_DATE_AFTER
;
1292 case CRITERIA_DATE_BEFORE
:
1293 return MATCHCRITERIA_DATE_BEFORE
;
1294 case CRITERIA_SCORE_GREATER
:
1295 return MATCHCRITERIA_SCORE_GREATER
;
1296 case CRITERIA_SCORE_LOWER
:
1297 return MATCHCRITERIA_SCORE_LOWER
;
1298 case CRITERIA_SCORE_EQUAL
:
1299 return MATCHCRITERIA_SCORE_EQUAL
;
1300 case CRITERIA_HEADER
:
1301 return MATCHCRITERIA_HEADER
;
1302 case CRITERIA_HEADERS_PART
:
1303 return MATCHCRITERIA_HEADERS_PART
;
1304 case CRITERIA_HEADERS_CONT
:
1305 return MATCHCRITERIA_HEADERS_CONT
;
1306 case CRITERIA_BODY_PART
:
1307 return MATCHCRITERIA_BODY_PART
;
1308 case CRITERIA_MESSAGE
:
1309 return MATCHCRITERIA_MESSAGE
;
1311 return MATCHCRITERIA_TEST
;
1312 case CRITERIA_SIZE_GREATER
:
1313 return MATCHCRITERIA_SIZE_GREATER
;
1314 case CRITERIA_SIZE_SMALLER
:
1315 return MATCHCRITERIA_SIZE_SMALLER
;
1316 case CRITERIA_SIZE_EQUAL
:
1317 return MATCHCRITERIA_SIZE_EQUAL
;
1318 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1319 return MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
;
1326 *\brief Returns the negate matcher keyword id from a matcher keyword
1329 *\param matcher_criteria Matcher keyword id.
1331 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1333 static gint
prefs_matcher_not_criteria(gint matcher_criteria
)
1335 switch(matcher_criteria
) {
1336 case MATCHCRITERIA_UNREAD
:
1337 return MATCHCRITERIA_NOT_UNREAD
;
1338 case MATCHCRITERIA_NEW
:
1339 return MATCHCRITERIA_NOT_NEW
;
1340 case MATCHCRITERIA_MARKED
:
1341 return MATCHCRITERIA_NOT_MARKED
;
1342 case MATCHCRITERIA_DELETED
:
1343 return MATCHCRITERIA_NOT_DELETED
;
1344 case MATCHCRITERIA_REPLIED
:
1345 return MATCHCRITERIA_NOT_REPLIED
;
1346 case MATCHCRITERIA_FORWARDED
:
1347 return MATCHCRITERIA_NOT_FORWARDED
;
1348 case MATCHCRITERIA_LOCKED
:
1349 return MATCHCRITERIA_NOT_LOCKED
;
1350 case MATCHCRITERIA_SPAM
:
1351 return MATCHCRITERIA_NOT_SPAM
;
1352 case MATCHCRITERIA_HAS_ATTACHMENT
:
1353 return MATCHCRITERIA_HAS_NO_ATTACHMENT
;
1354 case MATCHCRITERIA_SIGNED
:
1355 return MATCHCRITERIA_NOT_SIGNED
;
1356 case MATCHCRITERIA_PARTIAL
:
1357 return MATCHCRITERIA_NOT_PARTIAL
;
1358 case MATCHCRITERIA_COLORLABEL
:
1359 return MATCHCRITERIA_NOT_COLORLABEL
;
1360 case MATCHCRITERIA_IGNORE_THREAD
:
1361 return MATCHCRITERIA_NOT_IGNORE_THREAD
;
1362 case MATCHCRITERIA_WATCH_THREAD
:
1363 return MATCHCRITERIA_NOT_WATCH_THREAD
;
1364 case MATCHCRITERIA_SUBJECT
:
1365 return MATCHCRITERIA_NOT_SUBJECT
;
1366 case MATCHCRITERIA_FROM
:
1367 return MATCHCRITERIA_NOT_FROM
;
1368 case MATCHCRITERIA_TO
:
1369 return MATCHCRITERIA_NOT_TO
;
1370 case MATCHCRITERIA_CC
:
1371 return MATCHCRITERIA_NOT_CC
;
1372 case MATCHCRITERIA_TO_OR_CC
:
1373 return MATCHCRITERIA_NOT_TO_AND_NOT_CC
;
1374 case MATCHCRITERIA_TAG
:
1375 return MATCHCRITERIA_NOT_TAG
;
1376 case MATCHCRITERIA_TAGGED
:
1377 return MATCHCRITERIA_NOT_TAGGED
;
1378 case MATCHCRITERIA_NEWSGROUPS
:
1379 return MATCHCRITERIA_NOT_NEWSGROUPS
;
1380 case MATCHCRITERIA_MESSAGEID
:
1381 return MATCHCRITERIA_NOT_MESSAGEID
;
1382 case MATCHCRITERIA_INREPLYTO
:
1383 return MATCHCRITERIA_NOT_INREPLYTO
;
1384 case MATCHCRITERIA_REFERENCES
:
1385 return MATCHCRITERIA_NOT_REFERENCES
;
1386 case MATCHCRITERIA_HEADER
:
1387 return MATCHCRITERIA_NOT_HEADER
;
1388 case MATCHCRITERIA_HEADERS_PART
:
1389 return MATCHCRITERIA_NOT_HEADERS_PART
;
1390 case MATCHCRITERIA_HEADERS_CONT
:
1391 return MATCHCRITERIA_NOT_HEADERS_CONT
;
1392 case MATCHCRITERIA_MESSAGE
:
1393 return MATCHCRITERIA_NOT_MESSAGE
;
1394 case MATCHCRITERIA_TEST
:
1395 return MATCHCRITERIA_NOT_TEST
;
1396 case MATCHCRITERIA_BODY_PART
:
1397 return MATCHCRITERIA_NOT_BODY_PART
;
1398 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1399 return MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
;
1401 return matcher_criteria
;
1405 static gint
prefs_matcher_get_criteria(void)
1407 gint match_criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1408 matcher
.criteria_combo
));
1409 const gchar
*header
= NULL
;
1411 switch (match_criteria
) {
1413 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1415 return CRITERIA_ALL
;
1421 return combobox_get_active_data(GTK_COMBO_BOX(
1422 matcher
.match_combo
));
1424 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1425 return header_name_to_crit(header
);
1427 return CRITERIA_COLORLABEL
;
1429 return CRITERIA_PARTIAL
;
1431 return CRITERIA_TEST
;
1435 return combobox_get_active_data(GTK_COMBO_BOX(
1436 matcher
.criteria_combo2
));
1442 static gint
prefs_matcher_get_pred(const gint criteria
)
1445 case CRITERIA_SUBJECT
:
1449 case CRITERIA_TO_OR_CC
:
1450 case CRITERIA_NEWSGROUPS
:
1451 case CRITERIA_MESSAGEID
:
1452 case CRITERIA_INREPLYTO
:
1453 case CRITERIA_REFERENCES
:
1454 case CRITERIA_HEADER
:
1455 case CRITERIA_HEADERS_PART
:
1456 case CRITERIA_HEADERS_CONT
:
1457 case CRITERIA_BODY_PART
:
1458 case CRITERIA_MESSAGE
:
1460 case CRITERIA_TAGGED
:
1462 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo
));
1463 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1464 case CRITERIA_UNREAD
:
1466 case CRITERIA_MARKED
:
1467 case CRITERIA_DELETED
:
1468 case CRITERIA_REPLIED
:
1469 case CRITERIA_FORWARDED
:
1470 case CRITERIA_LOCKED
:
1472 case CRITERIA_HAS_ATTACHMENT
:
1473 case CRITERIA_SIGNED
:
1474 case CRITERIA_COLORLABEL
:
1475 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1476 case CRITERIA_WATCH_THREAD
:
1477 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
)) - 2;
1478 case CRITERIA_IGNORE_THREAD
:
1479 case CRITERIA_PARTIAL
:
1480 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
));
1487 *\brief Converts the text in the selected row to a
1490 *\return MatcherProp * Newly allocated matcher structure.
1492 static MatcherProp
*prefs_matcher_dialog_to_matcher(void)
1494 MatcherProp
*matcherprop
;
1498 gint value_criteria
= prefs_matcher_get_criteria();
1499 gboolean use_regexp
;
1500 gboolean case_sensitive
;
1501 const gchar
*header
;
1504 gint year
, month
, day
, hour
, minute
;
1506 if (value_criteria
== -1)
1509 use_regexp
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
));
1510 case_sensitive
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
));
1514 matchtype
= MATCHTYPE_REGEXP
;
1516 matchtype
= MATCHTYPE_REGEXPCASE
;
1520 matchtype
= MATCHTYPE_MATCH
;
1522 matchtype
= MATCHTYPE_MATCHCASE
;
1529 switch (value_criteria
) {
1531 case CRITERIA_UNREAD
:
1533 case CRITERIA_MARKED
:
1534 case CRITERIA_DELETED
:
1535 case CRITERIA_REPLIED
:
1536 case CRITERIA_FORWARDED
:
1537 case CRITERIA_LOCKED
:
1539 case CRITERIA_HAS_ATTACHMENT
:
1540 case CRITERIA_SIGNED
:
1541 case CRITERIA_PARTIAL
:
1542 case CRITERIA_IGNORE_THREAD
:
1543 case CRITERIA_WATCH_THREAD
:
1544 case CRITERIA_TAGGED
:
1547 case CRITERIA_SUBJECT
:
1551 case CRITERIA_TO_OR_CC
:
1553 case CRITERIA_NEWSGROUPS
:
1554 case CRITERIA_MESSAGEID
:
1555 case CRITERIA_INREPLYTO
:
1556 case CRITERIA_REFERENCES
:
1557 case CRITERIA_HEADERS_PART
:
1558 case CRITERIA_HEADERS_CONT
:
1559 case CRITERIA_BODY_PART
:
1560 case CRITERIA_MESSAGE
:
1561 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1564 alertpanel_error(_("Search pattern is not set."));
1569 case CRITERIA_DATE_AFTER
:
1570 case CRITERIA_DATE_BEFORE
:
1572 gtk_calendar_get_date(GTK_CALENDAR(matcher
.calendar
), &year
, &month
, &day
);
1573 if (gtkut_time_select_get_time(GTK_COMBO_BOX(matcher
.time_entry
), &hour
, &minute
))
1574 expr
= g_strdup_printf("%4d-%02d-%02d %02d:%02d:00",
1575 year
, month
+ 1, day
, hour
, minute
);
1578 alertpanel_error(_("Invalid hour."));
1584 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1587 alertpanel_error(_("Test command is not set."));
1592 case CRITERIA_AGE_GREATER
:
1593 case CRITERIA_AGE_LOWER
:
1594 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1595 matcher
.numeric_entry
));
1596 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1597 if(sel
== AGE_WEEKS
)
1599 else if (sel
== AGE_HOURS
) {
1600 if (value_criteria
== CRITERIA_AGE_GREATER
)
1601 value_criteria
= CRITERIA_AGE_GREATER_HOURS
;
1603 value_criteria
= CRITERIA_AGE_LOWER_HOURS
;
1607 case CRITERIA_SCORE_GREATER
:
1608 case CRITERIA_SCORE_LOWER
:
1609 case CRITERIA_SCORE_EQUAL
:
1610 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1611 matcher
.numeric_entry
));
1614 case CRITERIA_SIZE_GREATER
:
1615 case CRITERIA_SIZE_SMALLER
:
1616 case CRITERIA_SIZE_EQUAL
:
1617 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1618 matcher
.numeric_entry
));
1619 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1620 if(sel
== SIZE_UNIT_MBYTES
)
1622 if(sel
== SIZE_UNIT_KBYTES
)
1626 case CRITERIA_COLORLABEL
:
1627 value
= colorlabel_get_color_menu_active_item
1628 (gtk_cmoption_menu_get_menu(GTK_CMOPTION_MENU
1629 (matcher
.color_optmenu
)));
1632 case CRITERIA_HEADER
:
1633 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1634 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1636 if (*header
== '\0') {
1637 alertpanel_error(_("Header name is not set."));
1642 alertpanel_error(_("Search pattern is not set."));
1647 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1648 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_addr_entry
));
1649 expr
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
1651 if (*header
== '\0') {
1652 alertpanel_error(_("Header name is not set."));
1655 if (*expr
== '\0') {
1658 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1659 tmp
= g_strdup(_("all addresses in all headers"));
1661 if (g_utf8_collate(header
, _("Any")) == 0)
1662 tmp
= g_strdup(_("any address in any header"));
1664 tmp
= g_strdup_printf(_("the address(es) in header '%s'"), header
);
1665 alertpanel_error(_("Book/folder path is not set.\n\n"
1666 "If you want to match %s against the whole address book, "
1667 "you have to select '%s' from the book/folder drop-down list."),
1672 /* store UNtranslated "Any"/"All" in matcher expressions */
1673 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1676 if (g_utf8_collate(header
, _("Any")) == 0)
1678 if (g_utf8_collate(expr
, _("Any")) == 0)
1683 criteria
= prefs_matcher_get_matching_from_criteria(value_criteria
);
1685 value_pred
= prefs_matcher_get_pred(value_criteria
);
1687 criteria
= prefs_matcher_not_criteria(criteria
);
1689 matcherprop
= matcherprop_new(criteria
, header
, matchtype
,
1696 *\brief Signal handler for register button
1698 static void prefs_matcher_register_cb(void)
1700 MatcherProp
*matcherprop
;
1702 matcherprop
= prefs_matcher_dialog_to_matcher();
1703 if (matcherprop
== NULL
)
1706 prefs_matcher_list_view_set_row(NULL
, matcherprop
);
1708 matcherprop_free(matcherprop
);
1710 prefs_matcher_reset_condition();
1714 *\brief Signal handler for substitute button
1716 static void prefs_matcher_substitute_cb(void)
1718 MatcherProp
*matcherprop
;
1720 GtkTreeSelection
*selection
;
1721 GtkTreeModel
*model
;
1724 selection
= gtk_tree_view_get_selection
1725 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1727 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1730 gtk_tree_model_get(model
, &row
,
1731 PREFS_MATCHER_COND_VALID
, &is_valid
,
1736 matcherprop
= prefs_matcher_dialog_to_matcher();
1737 if (matcherprop
== NULL
)
1740 prefs_matcher_list_view_set_row(&row
, matcherprop
);
1742 matcherprop_free(matcherprop
);
1746 *\brief Signal handler for delete button
1748 static void prefs_matcher_delete_cb(void)
1751 GtkTreeSelection
*selection
;
1752 GtkTreeModel
*model
;
1755 selection
= gtk_tree_view_get_selection
1756 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1758 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1761 gtk_tree_model_get(model
, &row
,
1762 PREFS_MATCHER_COND_VALID
, &is_valid
,
1768 gtk_list_store_remove(GTK_LIST_STORE(model
), &row
);
1770 prefs_matcher_reset_condition();
1774 *\brief Signal handler for 'move up' button
1776 static void prefs_matcher_up(void)
1778 GtkTreePath
*prev
, *sel
, *try;
1780 GtkListStore
*store
= NULL
;
1781 GtkTreeModel
*model
= NULL
;
1784 if (!gtk_tree_selection_get_selected
1785 (gtk_tree_view_get_selection
1786 (GTK_TREE_VIEW(matcher
.cond_list_view
)),
1790 store
= (GtkListStore
*)model
;
1791 sel
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &isel
);
1795 /* no move if we're at row 0 or 1, looks phony, but other
1796 * solutions are more convoluted... */
1797 try = gtk_tree_path_copy(sel
);
1798 if (!gtk_tree_path_prev(try) || !gtk_tree_path_prev(try)) {
1799 gtk_tree_path_free(try);
1800 gtk_tree_path_free(sel
);
1803 gtk_tree_path_free(try);
1805 prev
= gtk_tree_path_copy(sel
);
1806 if (gtk_tree_path_prev(prev
)) {
1807 gtk_tree_model_get_iter(GTK_TREE_MODEL(store
),
1809 gtk_list_store_swap(store
, &iprev
, &isel
);
1810 /* XXX: GTK2 select row?? */
1813 gtk_tree_path_free(sel
);
1814 gtk_tree_path_free(prev
);
1818 *\brief Signal handler for 'move down' button
1820 static void prefs_matcher_down(void)
1822 GtkListStore
*store
= NULL
;
1823 GtkTreeModel
*model
= NULL
;
1824 GtkTreeIter next
, sel
;
1827 if (!gtk_tree_selection_get_selected
1828 (gtk_tree_view_get_selection
1829 (GTK_TREE_VIEW(matcher
.cond_list_view
)),
1833 store
= (GtkListStore
*)model
;
1834 try = gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &sel
);
1838 /* move when not at row 0 ... */
1839 if (gtk_tree_path_prev(try)) {
1841 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store
), &next
))
1842 gtk_list_store_swap(store
, &next
, &sel
);
1845 gtk_tree_path_free(try);
1848 static void prefs_matcher_enable_widget(GtkWidget
* widget
, const gboolean enable
)
1850 cm_return_if_fail(widget
!= NULL
);
1852 if(enable
== TRUE
) {
1853 gtk_widget_set_sensitive(widget
, TRUE
);
1854 gtk_widget_show(widget
);
1856 gtk_widget_set_sensitive(widget
, FALSE
);
1857 gtk_widget_hide(widget
);
1861 static void prefs_matcher_set_model(GtkWidget
*widget
, GtkTreeModel
*model
)
1863 cm_return_if_fail(widget
!= NULL
);
1864 cm_return_if_fail(model
!= NULL
);
1866 gtk_combo_box_set_model(GTK_COMBO_BOX(widget
), model
);
1867 gtk_combo_box_set_active(GTK_COMBO_BOX(widget
), 0);
1870 static void prefs_matcher_second_criteria_sel(GtkWidget
*widget
,
1873 gint criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1874 matcher
.criteria_combo
));
1875 gint criteria2
= combobox_get_active_data(GTK_COMBO_BOX(
1876 matcher
.criteria_combo2
));
1878 if(criteria
!= MATCH_PHRASE
&& criteria
!= MATCH_TAGS
) return;
1880 if(criteria
== MATCH_PHRASE
) {
1882 case CRITERIA_HEADERS_PART
:
1883 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1886 case CRITERIA_HEADERS_CONT
:
1887 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1888 _("Headers values"));
1890 case CRITERIA_BODY_PART
:
1891 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1894 case CRITERIA_MESSAGE
:
1895 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1896 _("Whole message"));
1901 if(criteria
== MATCH_TAGS
) {
1902 if(criteria2
== CRITERIA_TAGGED
) {
1903 prefs_matcher_enable_widget(matcher
.upper_filler
, FALSE
);
1904 prefs_matcher_enable_widget(matcher
.match_label2
, TRUE
);
1905 prefs_matcher_enable_widget(matcher
.string_entry
, FALSE
);
1906 prefs_matcher_enable_widget(matcher
.case_checkbtn
, FALSE
);
1907 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, FALSE
);
1909 prefs_matcher_enable_widget(matcher
.upper_filler
, TRUE
);
1910 prefs_matcher_enable_widget(matcher
.match_label2
, FALSE
);
1911 prefs_matcher_enable_widget(matcher
.string_entry
, TRUE
);
1912 prefs_matcher_enable_widget(matcher
.case_checkbtn
, TRUE
);
1913 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, TRUE
);
1914 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1915 matcher
.regexp_checkbtn
), FALSE
);
1916 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1917 matcher
.case_checkbtn
), FALSE
);
1922 #define MATCH_COMBO_IS_ENABLED(x) (x != MATCH_ALL && x != MATCH_ABOOK && \
1923 x != MATCH_PARTIAL && x != MATCH_THREAD && x != MATCH_LABEL) ? TRUE : FALSE
1924 #define MATCH_CASE_REGEXP(x) (x == MATCH_HEADER || x == MATCH_PHRASE) ? TRUE : FALSE
1925 #define MATCH_NUMERIC(x) (x == MATCH_AGE || x == MATCH_SCORE || \
1926 x == MATCH_SIZE) ? TRUE : FALSE
1929 *\brief Change widgets depending on the selected condition
1931 *\param criteria combo widget
1932 *\param user_data Not used
1934 static void prefs_matcher_criteria_select(GtkWidget
*widget
,
1937 gint value
, old_value
;
1939 old_value
= matcher
.selected_criteria
;
1940 matcher
.selected_criteria
= value
= gtk_combo_box_get_active
1941 (GTK_COMBO_BOX(matcher
.criteria_combo
));
1943 if (old_value
== matcher
.selected_criteria
)
1946 prefs_matcher_enable_widget(matcher
.criteria_label2
,
1947 (value
== MATCH_ABOOK
||
1948 value
== MATCH_PHRASE
||
1949 value
== MATCH_HEADER
||
1950 value
== MATCH_PARTIAL
||
1951 value
== MATCH_TAGS
||
1952 value
== MATCH_THREAD
));
1953 prefs_matcher_enable_widget(matcher
.headers_combo
,
1954 (value
== MATCH_HEADER
));
1955 prefs_matcher_enable_widget(matcher
.criteria_combo2
,
1956 (value
== MATCH_PHRASE
||
1957 value
== MATCH_PARTIAL
||
1958 value
== MATCH_TAGS
||
1959 value
== MATCH_THREAD
));
1960 prefs_matcher_enable_widget(matcher
.match_combo2
,
1961 (value
== MATCH_ABOOK
||
1962 value
== MATCH_AGE
||
1963 value
== MATCH_FLAG
||
1964 value
== MATCH_LABEL
||
1965 value
== MATCH_SIZE
));
1966 prefs_matcher_enable_widget(matcher
.match_label2
,
1967 (value
== MATCH_ABOOK
||
1968 value
== MATCH_FLAG
||
1969 value
== MATCH_LABEL
||
1970 value
== MATCH_TAGS
));
1971 prefs_matcher_enable_widget(matcher
.header_addr_combo
,
1972 (value
== MATCH_ABOOK
));
1973 prefs_matcher_enable_widget(matcher
.string_entry
,
1974 (MATCH_CASE_REGEXP(value
) ||
1975 value
== MATCH_TEST
));
1976 prefs_matcher_enable_widget(matcher
.calendar
,
1977 (value
== MATCH_DATE
));
1978 prefs_matcher_enable_widget(matcher
.time_label
,
1979 (value
== MATCH_DATE
));
1980 prefs_matcher_enable_widget(matcher
.time_entry
,
1981 (value
== MATCH_DATE
));
1982 prefs_matcher_enable_widget(matcher
.numeric_entry
,
1983 MATCH_NUMERIC(value
));
1984 prefs_matcher_enable_widget(matcher
.numeric_label
,
1985 (value
== MATCH_SCORE
));
1986 prefs_matcher_enable_widget(matcher
.addressbook_folder_combo
,
1987 (value
== MATCH_ABOOK
));
1988 prefs_matcher_enable_widget(matcher
.match_combo
,
1989 MATCH_COMBO_IS_ENABLED(value
));
1990 prefs_matcher_enable_widget(matcher
.case_checkbtn
,
1991 MATCH_CASE_REGEXP(value
));
1992 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
,
1993 MATCH_CASE_REGEXP(value
));
1994 prefs_matcher_enable_widget(matcher
.test_btn
,
1995 (value
== MATCH_TEST
));
1996 prefs_matcher_enable_widget(matcher
.addressbook_select_btn
,
1997 (value
== MATCH_ABOOK
));
1998 prefs_matcher_enable_widget(matcher
.color_optmenu
,
1999 (value
== MATCH_LABEL
));
2000 prefs_matcher_enable_widget(matcher
.upper_filler
,
2001 MATCH_CASE_REGEXP(value
));
2002 prefs_matcher_enable_widget(matcher
.lower_filler
,
2003 (value
== MATCH_ABOOK
));
2005 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), "");
2006 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
2010 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.header_addr_combo
), 0);
2011 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.addressbook_folder_combo
), 0);
2012 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_found
);
2013 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
2014 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
2015 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("content is"));
2018 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_date
);
2019 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Date is"));
2020 gtk_calendar_select_today(GTK_CALENDAR(matcher
.calendar
));
2021 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), 0, 0);
2024 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_age
);
2025 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_age_units
);
2026 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2027 matcher
.numeric_entry
), 0, 10000);
2028 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2029 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), AGE_DAYS
);
2030 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Age is"));
2033 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_flags
);
2034 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
2035 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Flag"));
2036 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
2039 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.headers_combo
), 0);
2040 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2041 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Name:"));
2042 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
2043 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2044 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2047 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
), 0);
2048 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
2049 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Label"));
2050 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
2053 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_partial
);
2054 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Value:"));
2057 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_phrase
);
2058 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2059 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
2060 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2061 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2062 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2065 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_score
);
2066 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2067 matcher
.numeric_entry
), -1000, 1000);
2068 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2069 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Score is"));
2070 gtk_label_set_text(GTK_LABEL(matcher
.numeric_label
), _("points"));
2073 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_size
);
2074 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_size_units
);
2075 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2077 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2078 matcher
.numeric_entry
), 0, 100000);
2079 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2080 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Size is"));
2083 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_tags
);
2084 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2085 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Scope:"));
2086 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Message"));
2087 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("tags"));
2088 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2091 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_thread
);
2092 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("type is"));
2095 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_test
);
2096 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Program returns"));
2102 *\brief Handle key press
2104 *\param widget Widget receiving key press
2105 *\param event Key event
2106 *\param data User data
2108 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
2111 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
2112 prefs_matcher_cancel();
2119 *\brief Cancel matcher dialog
2121 static void prefs_matcher_cancel(void)
2123 gtk_widget_hide(matcher
.window
);
2124 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2129 *\brief Accept current matchers
2131 static void prefs_matcher_ok(void)
2133 MatcherList
*matchers
;
2134 MatcherProp
*matcherprop
;
2136 gchar
*matcher_str
= NULL
;
2139 GtkTreeModel
*model
;
2142 matchers
= prefs_matcher_get_list();
2144 if (matchers
!= NULL
) {
2145 matcherprop
= prefs_matcher_dialog_to_matcher();
2146 if (matcherprop
!= NULL
) {
2147 str
= matcherprop_to_string(matcherprop
);
2148 matcherprop_free(matcherprop
);
2149 if (strcmp(str
, "all") != 0) {
2150 model
= gtk_tree_view_get_model(GTK_TREE_VIEW
2151 (matcher
.cond_list_view
));
2153 while (gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
)) {
2154 gtk_tree_model_get(model
, &iter
,
2155 PREFS_MATCHER_COND
, &matcher_str
,
2157 if (matcher_str
&& strcmp(matcher_str
, str
) == 0)
2160 g_free(matcher_str
);
2164 if (!matcher_str
|| strcmp(matcher_str
, str
) != 0) {
2165 val
= alertpanel(_("Entry not saved"),
2166 _("The entry was not saved.\nClose anyway?"),
2168 _("_Continue editing"),
2171 if (G_ALERTDEFAULT
!= val
) {
2172 g_free(matcher_str
);
2177 g_free(matcher_str
);
2181 gtk_widget_hide(matcher
.window
);
2182 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2183 if (matchers_callback
!= NULL
)
2184 matchers_callback(matchers
);
2185 matcherlist_free(matchers
);
2191 *\brief Called when closing dialog box
2193 *\param widget Dialog widget
2194 *\param event Event info
2195 *\param data User data
2199 static gint
prefs_matcher_deleted(GtkWidget
*widget
, GdkEventAny
*event
,
2202 prefs_matcher_cancel();
2207 * Strings describing test format strings
2209 * When adding new lines, remember to put 2 strings for each line
2211 static gchar
*test_desc_strings
[] = {
2212 "%%", N_("literal %"),
2213 "%s", N_("Subject"),
2218 "%i", N_("Message-ID"),
2219 "%n", N_("Newsgroups"),
2220 "%r", N_("References"),
2221 "%F", N_("filename (should not be modified)"),
2222 "\\n", N_("new line"),
2223 "\\", N_("escape character for quotes"),
2224 "\\\"", N_("quote character"),
2228 static DescriptionWindow test_desc_win
= {
2233 N_("Match Type: 'Test'"),
2234 N_("'Test' allows you to test a message or message element "
2235 "using an external program or script. The program will "
2236 "return either 0 or 1.\n\n"
2237 "The following symbols can be used:"),
2244 *\brief Show Test action's info
2246 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
)
2248 test_desc_win
.parent
= parent
;
2249 description_window_create(&test_desc_win
);
2252 #ifndef USE_ALT_ADDRBOOK
2253 static void prefs_matcher_addressbook_select(void)
2255 const gchar
*folderpath
= NULL
;
2256 gchar
*new_path
= NULL
;
2258 folderpath
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
2259 new_path
= addressbook_folder_selection(folderpath
);
2261 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), new_path
);
2271 static GtkListStore
* prefs_matcher_create_data_store(void)
2273 return gtk_list_store_new(N_PREFS_MATCHER_COLUMNS
,
2279 static void prefs_matcher_list_view_insert_matcher(GtkWidget
*list_view
,
2280 GtkTreeIter
*row_iter
,
2281 const gchar
*matcher
,
2285 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
2286 (GTK_TREE_VIEW(list_view
)));
2288 if (row_iter
== NULL
) {
2290 gtk_list_store_append(list_store
, &iter
);
2292 /* change existing */
2296 gtk_list_store_set(list_store
, &iter
,
2297 PREFS_MATCHER_COND
, matcher
,
2298 PREFS_MATCHER_COND_VALID
, is_valid
,
2302 static GtkWidget
*prefs_matcher_list_view_create(void)
2304 GtkTreeView
*list_view
;
2305 GtkTreeSelection
*selector
;
2306 GtkTreeModel
*model
;
2308 model
= GTK_TREE_MODEL(prefs_matcher_create_data_store());
2309 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
2310 g_object_unref(model
);
2312 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
2313 gtk_tree_view_set_reorderable(list_view
, TRUE
);
2315 selector
= gtk_tree_view_get_selection(list_view
);
2316 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
2317 gtk_tree_selection_set_select_function(selector
, prefs_matcher_selected
,
2320 /* create the columns */
2321 prefs_matcher_create_list_view_columns(GTK_WIDGET(list_view
));
2323 return GTK_WIDGET(list_view
);
2326 static void prefs_matcher_create_list_view_columns(GtkWidget
*list_view
)
2328 GtkTreeViewColumn
*column
;
2329 GtkCellRenderer
*renderer
;
2331 renderer
= gtk_cell_renderer_text_new();
2332 column
= gtk_tree_view_column_new_with_attributes
2333 (_("Current condition rules"),
2335 "text", PREFS_MATCHER_COND
,
2337 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
2340 static void prefs_matcher_set_criteria(const gint criteria
)
2342 gint match_criteria
= 0;
2345 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2346 match_criteria
= MATCH_ABOOK
;
2349 match_criteria
= MATCH_ALL
;
2351 case CRITERIA_AGE_GREATER
:
2352 case CRITERIA_AGE_LOWER
:
2353 case CRITERIA_AGE_GREATER_HOURS
:
2354 case CRITERIA_AGE_LOWER_HOURS
:
2355 match_criteria
= MATCH_AGE
;
2357 case CRITERIA_DATE_AFTER
:
2358 case CRITERIA_DATE_BEFORE
:
2359 match_criteria
= MATCH_DATE
;
2361 case CRITERIA_SCORE_GREATER
:
2362 case CRITERIA_SCORE_LOWER
:
2363 case CRITERIA_SCORE_EQUAL
:
2364 match_criteria
= MATCH_SCORE
;
2366 case CRITERIA_SIZE_GREATER
:
2367 case CRITERIA_SIZE_SMALLER
:
2368 case CRITERIA_SIZE_EQUAL
:
2369 match_criteria
= MATCH_SIZE
;
2371 case CRITERIA_SUBJECT
:
2375 case CRITERIA_TO_OR_CC
:
2376 case CRITERIA_NEWSGROUPS
:
2377 case CRITERIA_MESSAGEID
:
2378 case CRITERIA_INREPLYTO
:
2379 case CRITERIA_REFERENCES
:
2380 case CRITERIA_HEADER
:
2381 match_criteria
= MATCH_HEADER
;
2383 case CRITERIA_HEADERS_PART
:
2384 case CRITERIA_HEADERS_CONT
:
2385 case CRITERIA_BODY_PART
:
2386 case CRITERIA_MESSAGE
:
2387 match_criteria
= MATCH_PHRASE
;
2390 match_criteria
= MATCH_TEST
;
2392 case CRITERIA_COLORLABEL
:
2393 match_criteria
= MATCH_LABEL
;
2396 case CRITERIA_TAGGED
:
2397 match_criteria
= MATCH_TAGS
;
2399 case CRITERIA_UNREAD
:
2401 case CRITERIA_MARKED
:
2402 case CRITERIA_DELETED
:
2403 case CRITERIA_REPLIED
:
2404 case CRITERIA_FORWARDED
:
2405 case CRITERIA_LOCKED
:
2407 case CRITERIA_HAS_ATTACHMENT
:
2408 case CRITERIA_SIGNED
:
2409 match_criteria
= MATCH_FLAG
;
2411 case CRITERIA_PARTIAL
:
2412 match_criteria
= MATCH_PARTIAL
;
2414 case CRITERIA_IGNORE_THREAD
:
2415 case CRITERIA_WATCH_THREAD
:
2416 match_criteria
= MATCH_THREAD
;
2420 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
),
2423 switch(match_criteria
) {
2425 if(criteria
!= CRITERIA_HEADER
)
2426 combobox_select_by_data(GTK_COMBO_BOX(
2427 matcher
.headers_combo
),
2435 combobox_select_by_data(GTK_COMBO_BOX(
2436 matcher
.match_combo
), criteria
);
2440 combobox_select_by_data(GTK_COMBO_BOX(
2441 matcher
.criteria_combo2
), criteria
);
2446 static gboolean
prefs_matcher_selected(GtkTreeSelection
*selector
,
2447 GtkTreeModel
*model
,
2449 gboolean currently_selected
,
2454 gboolean negative_cond
;
2462 if (currently_selected
)
2465 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
2468 gtk_tree_model_get(model
, &iter
,
2469 PREFS_MATCHER_COND_VALID
, &is_valid
,
2470 PREFS_MATCHER_COND
, &matcher_str
,
2474 g_free(matcher_str
);
2475 prefs_matcher_reset_condition();
2479 negative_cond
= FALSE
;
2481 prop
= matcher_parser_get_prop(matcher_str
);
2483 g_free(matcher_str
);
2487 criteria
= prefs_matcher_get_criteria_from_matching(prop
->criteria
);
2488 prefs_matcher_set_criteria(criteria
);
2490 switch(prop
->criteria
) {
2491 case MATCHCRITERIA_NOT_UNREAD
:
2492 case MATCHCRITERIA_NOT_NEW
:
2493 case MATCHCRITERIA_NOT_MARKED
:
2494 case MATCHCRITERIA_NOT_DELETED
:
2495 case MATCHCRITERIA_NOT_REPLIED
:
2496 case MATCHCRITERIA_NOT_FORWARDED
:
2497 case MATCHCRITERIA_NOT_LOCKED
:
2498 case MATCHCRITERIA_NOT_SPAM
:
2499 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
2500 case MATCHCRITERIA_NOT_SIGNED
:
2501 case MATCHCRITERIA_NOT_PARTIAL
:
2502 case MATCHCRITERIA_NOT_COLORLABEL
:
2503 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
2504 case MATCHCRITERIA_NOT_WATCH_THREAD
:
2505 case MATCHCRITERIA_NOT_SUBJECT
:
2506 case MATCHCRITERIA_NOT_FROM
:
2507 case MATCHCRITERIA_NOT_TO
:
2508 case MATCHCRITERIA_NOT_CC
:
2509 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2510 case MATCHCRITERIA_NOT_TAG
:
2511 case MATCHCRITERIA_NOT_TAGGED
:
2512 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2513 case MATCHCRITERIA_NOT_MESSAGEID
:
2514 case MATCHCRITERIA_NOT_INREPLYTO
:
2515 case MATCHCRITERIA_NOT_REFERENCES
:
2516 case MATCHCRITERIA_NOT_HEADER
:
2517 case MATCHCRITERIA_NOT_HEADERS_PART
:
2518 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2519 case MATCHCRITERIA_NOT_MESSAGE
:
2520 case MATCHCRITERIA_NOT_BODY_PART
:
2521 case MATCHCRITERIA_NOT_TEST
:
2522 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2523 negative_cond
= TRUE
;
2527 switch(prop
->criteria
) {
2528 case MATCHCRITERIA_ALL
:
2531 case MATCHCRITERIA_NOT_SUBJECT
:
2532 case MATCHCRITERIA_NOT_FROM
:
2533 case MATCHCRITERIA_NOT_TO
:
2534 case MATCHCRITERIA_NOT_CC
:
2535 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2536 case MATCHCRITERIA_NOT_TAG
:
2537 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2538 case MATCHCRITERIA_NOT_MESSAGEID
:
2539 case MATCHCRITERIA_NOT_INREPLYTO
:
2540 case MATCHCRITERIA_NOT_REFERENCES
:
2541 case MATCHCRITERIA_NOT_HEADERS_PART
:
2542 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2543 case MATCHCRITERIA_NOT_BODY_PART
:
2544 case MATCHCRITERIA_NOT_MESSAGE
:
2545 case MATCHCRITERIA_NOT_TEST
:
2546 case MATCHCRITERIA_SUBJECT
:
2547 case MATCHCRITERIA_FROM
:
2548 case MATCHCRITERIA_TO
:
2549 case MATCHCRITERIA_CC
:
2550 case MATCHCRITERIA_TO_OR_CC
:
2551 case MATCHCRITERIA_TAG
:
2552 case MATCHCRITERIA_NEWSGROUPS
:
2553 case MATCHCRITERIA_MESSAGEID
:
2554 case MATCHCRITERIA_INREPLYTO
:
2555 case MATCHCRITERIA_REFERENCES
:
2556 case MATCHCRITERIA_HEADERS_PART
:
2557 case MATCHCRITERIA_HEADERS_CONT
:
2558 case MATCHCRITERIA_BODY_PART
:
2559 case MATCHCRITERIA_MESSAGE
:
2560 case MATCHCRITERIA_TEST
:
2561 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2564 case MATCHCRITERIA_DATE_AFTER
:
2565 case MATCHCRITERIA_DATE_BEFORE
:
2567 procheader_date_parse_to_tm(prop
->expr
, <
, zone
);
2568 gtk_calendar_select_day(GTK_CALENDAR(matcher
.calendar
), lt
.tm_mday
);
2569 gtk_calendar_select_month(GTK_CALENDAR(matcher
.calendar
), lt
.tm_mon
, lt
.tm_year
+ 1900);
2570 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), lt
.tm_hour
, lt
.tm_min
);
2574 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
2575 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2580 /* matcher expressions contain UNtranslated "Any"/"All",
2581 select the relevant translated combo item */
2582 if (strcasecmp(prop
->header
, "All") == 0)
2583 header
= (gchar
*)C_("Filtering Matcher Menu", "All");
2585 if (strcasecmp(prop
->header
, "Any") == 0)
2588 header
= prop
->header
;
2589 if (strcasecmp(prop
->expr
, "Any") == 0)
2594 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), header
);
2595 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), expr
);
2599 case MATCHCRITERIA_AGE_GREATER
:
2600 case MATCHCRITERIA_AGE_LOWER
:
2601 if(prop
->value
>= 7 && !(prop
->value
% 7)) {
2602 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2604 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2605 matcher
.numeric_entry
), prop
->value
/7);
2607 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2609 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2610 matcher
.numeric_entry
), prop
->value
);
2614 case MATCHCRITERIA_AGE_GREATER_HOURS
:
2615 case MATCHCRITERIA_AGE_LOWER_HOURS
:
2616 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2618 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2619 matcher
.numeric_entry
), prop
->value
);
2622 case MATCHCRITERIA_SCORE_GREATER
:
2623 case MATCHCRITERIA_SCORE_LOWER
:
2624 case MATCHCRITERIA_SCORE_EQUAL
:
2625 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
),
2629 case MATCHCRITERIA_SIZE_GREATER
:
2630 case MATCHCRITERIA_SIZE_SMALLER
:
2631 case MATCHCRITERIA_SIZE_EQUAL
:
2632 if(prop
->value
>= MB_SIZE
&& !(prop
->value
% MB_SIZE
)) {
2633 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2635 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2636 matcher
.numeric_entry
), prop
->value
/MB_SIZE
);
2637 } else if(prop
->value
>= KB_SIZE
&& !(prop
->value
% KB_SIZE
)) {
2638 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2640 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2641 matcher
.numeric_entry
), prop
->value
/KB_SIZE
);
2643 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2645 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2646 matcher
.numeric_entry
), prop
->value
);
2650 case MATCHCRITERIA_NOT_COLORLABEL
:
2651 case MATCHCRITERIA_COLORLABEL
:
2652 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
),
2654 menu
= gtk_cmoption_menu_get_menu(GTK_CMOPTION_MENU(matcher
.color_optmenu
));
2655 g_signal_emit_by_name(G_OBJECT(menu
), "selection-done", menu
);
2658 case MATCHCRITERIA_NOT_HEADER
:
2659 case MATCHCRITERIA_HEADER
:
2660 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), prop
->header
);
2661 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2666 case CRITERIA_SUBJECT
:
2670 case CRITERIA_TO_OR_CC
:
2671 case CRITERIA_NEWSGROUPS
:
2672 case CRITERIA_MESSAGEID
:
2673 case CRITERIA_INREPLYTO
:
2674 case CRITERIA_REFERENCES
:
2675 case CRITERIA_HEADER
:
2676 case CRITERIA_HEADERS_PART
:
2677 case CRITERIA_HEADERS_CONT
:
2678 case CRITERIA_BODY_PART
:
2679 case CRITERIA_MESSAGE
:
2681 case CRITERIA_TAGGED
:
2683 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
),
2684 negative_cond
? PREDICATE_DOES_NOT_CONTAIN
:
2685 PREDICATE_CONTAINS
);
2687 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2688 case CRITERIA_UNREAD
:
2690 case CRITERIA_MARKED
:
2691 case CRITERIA_DELETED
:
2692 case CRITERIA_REPLIED
:
2693 case CRITERIA_FORWARDED
:
2694 case CRITERIA_LOCKED
:
2696 case CRITERIA_HAS_ATTACHMENT
:
2697 case CRITERIA_SIGNED
:
2698 case CRITERIA_COLORLABEL
:
2699 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2700 negative_cond
? PREDICATE_FLAG_DISABLED
:
2701 PREDICATE_FLAG_ENABLED
);
2703 case CRITERIA_WATCH_THREAD
:
2704 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2705 negative_cond
? THREAD_NOT_WATCHED
:
2708 case CRITERIA_IGNORE_THREAD
:
2709 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2710 negative_cond
? THREAD_NOT_IGNORED
:
2713 case CRITERIA_PARTIAL
:
2714 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2715 negative_cond
? PREDICATE_FLAG_DISABLED
:
2716 PREDICATE_FLAG_ENABLED
);
2720 switch(prop
->matchtype
) {
2721 case MATCHTYPE_MATCH
:
2722 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2723 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2726 case MATCHTYPE_MATCHCASE
:
2727 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2728 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2731 case MATCHTYPE_REGEXP
:
2732 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2733 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2736 case MATCHTYPE_REGEXPCASE
:
2737 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2738 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2742 g_free(matcher_str
);