2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2014 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/>.
22 #include "claws-features.h"
28 #include <glib/gi18n.h>
30 #include <gdk/gdkkeysyms.h>
36 #if !GTK_CHECK_VERSION(3, 0, 0)
37 #include "gtkcmoptionmenu.h"
40 #include "prefs_gtk.h"
41 #include "prefs_matcher.h"
42 #include "prefs_common.h"
43 #include "mainwindow.h"
44 #include "foldersel.h"
45 #include "manage_window.h"
50 #include "alertpanel.h"
52 #include "description_window.h"
55 #include "matcher_parser.h"
56 #include "colorlabel.h"
58 #ifndef USE_ALT_ADDRBOOK
59 #include "addressbook.h"
62 #ifndef USE_ALT_ADDRBOOK
63 static void prefs_matcher_addressbook_select(void);
65 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
);
69 PREFS_MATCHER_COND_VALID
,
70 N_PREFS_MATCHER_COLUMNS
74 *\brief UI data for matcher dialog
76 static struct Matcher
{
81 GtkWidget
*match_combo
;
82 GtkWidget
*header_addr_combo
;
83 GtkWidget
*bool_op_combo
;
84 GtkWidget
*criteria_label2
;
85 GtkWidget
*criteria_combo
;
86 GtkWidget
*criteria_combo2
;
87 GtkWidget
*match_combo2
;
88 GtkWidget
*match_label
;
89 GtkWidget
*match_label2
;
90 GtkWidget
*headers_combo
;
91 GtkWidget
*upper_filler
;
92 GtkWidget
*lower_filler
;
94 GtkWidget
*header_entry
;
95 GtkWidget
*header_addr_entry
;
96 GtkWidget
*string_entry
;
97 GtkWidget
*numeric_entry
;
98 GtkWidget
*numeric_label
;
99 GtkWidget
*addressbook_folder_combo
;
100 GtkWidget
*case_checkbtn
;
101 GtkWidget
*regexp_checkbtn
;
102 #if !GTK_CHECK_VERSION(3, 0, 0)
103 GtkWidget
*color_optmenu
;
107 GtkWidget
*addressbook_select_btn
;
109 GtkTreeModel
*model_age
;
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
217 SIZE_UNIT_KBYTES
= 1,
221 #define MB_SIZE 0x100000
222 #define KB_SIZE 0x000400
226 THREAD_NOT_IGNORED
= 1,
228 THREAD_NOT_WATCHED
= 3
232 *\brief Contains predicate
235 PREDICATE_CONTAINS
= 0,
236 PREDICATE_DOES_NOT_CONTAIN
= 1
240 *\brief Enabled predicate
243 PREDICATE_FLAG_ENABLED
= 0,
244 PREDICATE_FLAG_DISABLED
= 1
250 static PrefsMatcherSignal
*matchers_callback
;
252 /* widget creating functions */
253 static void prefs_matcher_create (void);
255 static void prefs_matcher_set_dialog (MatcherList
*matchers
);
256 static void prefs_matcher_list_view_set_row (GtkTreeIter
*row
,
259 /* callback functions */
261 static void prefs_matcher_register_cb (void);
262 static void prefs_matcher_substitute_cb (void);
263 static void prefs_matcher_delete_cb (void);
264 static void prefs_matcher_up (void);
265 static void prefs_matcher_down (void);
266 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
,
269 static void prefs_matcher_ok (void);
270 static void prefs_matcher_cancel (void);
271 static gint
prefs_matcher_deleted (GtkWidget
*widget
, GdkEventAny
*event
,
273 static void prefs_matcher_criteria_select (GtkWidget
*widget
,
275 static void prefs_matcher_second_criteria_sel (GtkWidget
*widget
,
277 static void prefs_matcher_set_model (GtkWidget
*wiget
,
278 GtkTreeModel
*model
);
279 static MatcherList
*prefs_matcher_get_list (void);
281 static GtkListStore
* prefs_matcher_create_data_store (void);
283 static void prefs_matcher_list_view_insert_matcher (GtkWidget
*list_view
,
284 GtkTreeIter
*row_iter
,
285 const gchar
*matcher
,
288 static GtkWidget
*prefs_matcher_list_view_create (void);
290 static void prefs_matcher_create_list_view_columns (GtkWidget
*list_view
);
292 static gboolean
prefs_matcher_selected (GtkTreeSelection
*selector
,
295 gboolean currently_selected
,
298 static int header_name_to_crit(const gchar
*header
)
301 return CRITERIA_HEADER
;
303 if (!strcasecmp(header
, "Subject"))
304 return CRITERIA_SUBJECT
;
305 if (!strcasecmp(header
, "From"))
306 return CRITERIA_FROM
;
307 if (!strcasecmp(header
, "To"))
309 if (!strcasecmp(header
, "Cc"))
311 if (!strcasecmp(header
, "To or Cc"))
312 return CRITERIA_TO_OR_CC
;
313 if (!strcasecmp(header
, "Message-ID"))
314 return CRITERIA_MESSAGEID
;
315 if (!strcasecmp(header
, "In-Reply-To"))
316 return CRITERIA_INREPLYTO
;
317 if (!strcasecmp(header
, "Newsgroups"))
318 return CRITERIA_NEWSGROUPS
;
319 if (!strcasecmp(header
, "References"))
320 return CRITERIA_REFERENCES
;
322 return CRITERIA_HEADER
;
325 static void prefs_matcher_models_create(void)
330 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
331 COMBOBOX_ADD(store
, _("more than"), CRITERIA_AGE_GREATER
);
332 COMBOBOX_ADD(store
, _("less than"), CRITERIA_AGE_LOWER
);
333 matcher
.model_age
= GTK_TREE_MODEL(store
);
335 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
336 COMBOBOX_ADD(store
, _("hours"), AGE_HOURS
);
337 COMBOBOX_ADD(store
, _("days"), AGE_DAYS
);
338 COMBOBOX_ADD(store
, _("weeks"), AGE_WEEKS
);
339 matcher
.model_age_units
= GTK_TREE_MODEL(store
);
341 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
342 COMBOBOX_ADD(store
, _("higher than"), CRITERIA_SCORE_GREATER
);
343 COMBOBOX_ADD(store
, _("lower than"), CRITERIA_SCORE_LOWER
);
344 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SCORE_EQUAL
);
345 matcher
.model_score
= GTK_TREE_MODEL(store
);
347 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
348 COMBOBOX_ADD(store
, _("greater than"), CRITERIA_SIZE_GREATER
);
349 COMBOBOX_ADD(store
, _("smaller than"), CRITERIA_SIZE_SMALLER
);
350 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SIZE_EQUAL
);
351 matcher
.model_size
= GTK_TREE_MODEL(store
);
353 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
354 COMBOBOX_ADD(store
, _("bytes"), SIZE_UNIT_BYTES
);
355 COMBOBOX_ADD(store
, _("kilobytes"), SIZE_UNIT_KBYTES
);
356 COMBOBOX_ADD(store
, _("megabytes"), SIZE_UNIT_MBYTES
);
357 matcher
.model_size_units
= GTK_TREE_MODEL(store
);
359 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
360 COMBOBOX_ADD(store
, _("contains"), 0);
361 COMBOBOX_ADD(store
, _("doesn't contain"), 0);
362 matcher
.model_contain
= GTK_TREE_MODEL(store
);
364 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
365 COMBOBOX_ADD(store
, "Subject", CRITERIA_SUBJECT
);
366 COMBOBOX_ADD(store
, "From", CRITERIA_FROM
);
367 COMBOBOX_ADD(store
, "To", CRITERIA_TO
);
368 COMBOBOX_ADD(store
, "Cc", CRITERIA_CC
);
369 COMBOBOX_ADD(store
, "To or Cc", CRITERIA_TO_OR_CC
);
370 COMBOBOX_ADD(store
, "Message-ID", CRITERIA_MESSAGEID
);
371 COMBOBOX_ADD(store
, "In-Reply-To", CRITERIA_INREPLYTO
);
372 COMBOBOX_ADD(store
, "Newsgroups", CRITERIA_NEWSGROUPS
);
373 COMBOBOX_ADD(store
, "References", CRITERIA_REFERENCES
);
374 COMBOBOX_ADD(store
, "Sender", CRITERIA_HEADER
);
375 COMBOBOX_ADD(store
, "X-ML-Name", CRITERIA_HEADER
);
376 COMBOBOX_ADD(store
, "X-List", CRITERIA_HEADER
);
377 COMBOBOX_ADD(store
, "X-Sequence", CRITERIA_HEADER
);
378 COMBOBOX_ADD(store
, "X-Mailer", CRITERIA_HEADER
);
379 COMBOBOX_ADD(store
, "X-BeenThere", CRITERIA_HEADER
);
380 COMBOBOX_ADD(store
, "List-Post", CRITERIA_HEADER
);
381 COMBOBOX_ADD(store
, "List-Id", CRITERIA_HEADER
);
382 matcher
.model_headers
= GTK_TREE_MODEL(store
);
384 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
385 COMBOBOX_ADD(store
, _("headers part"), CRITERIA_HEADERS_PART
);
386 COMBOBOX_ADD(store
, _("headers values"), CRITERIA_HEADERS_CONT
);
387 COMBOBOX_ADD(store
, _("body part"), CRITERIA_BODY_PART
);
388 COMBOBOX_ADD(store
, _("whole message"), CRITERIA_MESSAGE
);
389 matcher
.model_phrase
= GTK_TREE_MODEL(store
);
391 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
392 COMBOBOX_ADD(store
, _("Unread"), CRITERIA_UNREAD
);
393 COMBOBOX_ADD(store
, _("New"), CRITERIA_NEW
);
394 COMBOBOX_ADD(store
, _("Marked"), CRITERIA_MARKED
);
395 COMBOBOX_ADD(store
, _("Deleted"), CRITERIA_DELETED
);
396 COMBOBOX_ADD(store
, _("Replied"), CRITERIA_REPLIED
);
397 COMBOBOX_ADD(store
, _("Forwarded"), CRITERIA_FORWARDED
);
398 COMBOBOX_ADD(store
, _("Locked"), CRITERIA_LOCKED
);
399 COMBOBOX_ADD(store
, _("Spam"), CRITERIA_SPAM
);
400 COMBOBOX_ADD(store
, _("Has attachment"), CRITERIA_HAS_ATTACHMENT
);
401 COMBOBOX_ADD(store
, _("Signed"), CRITERIA_SIGNED
);
402 matcher
.model_flags
= GTK_TREE_MODEL(store
);
404 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
405 COMBOBOX_ADD(store
, _("set"), 0);
406 COMBOBOX_ADD(store
, _("not set"), 1);
407 matcher
.model_set
= GTK_TREE_MODEL(store
);
409 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
410 COMBOBOX_ADD(store
, _("yes"), CRITERIA_PARTIAL
);
411 COMBOBOX_ADD(store
, _("no"), CRITERIA_PARTIAL
);
412 matcher
.model_partial
= GTK_TREE_MODEL(store
);
414 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
415 COMBOBOX_ADD(store
, _("Any tags"), CRITERIA_TAGGED
);
416 COMBOBOX_ADD(store
, _("Specific tag"), CRITERIA_TAG
);
417 matcher
.model_tags
= GTK_TREE_MODEL(store
);
419 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
420 COMBOBOX_ADD(store
, _("ignored"), CRITERIA_IGNORE_THREAD
);
421 COMBOBOX_ADD(store
, _("not ignored"), CRITERIA_IGNORE_THREAD
);
422 COMBOBOX_ADD(store
, _("watched"), CRITERIA_WATCH_THREAD
);
423 COMBOBOX_ADD(store
, _("not watched"), CRITERIA_WATCH_THREAD
);
424 matcher
.model_thread
= GTK_TREE_MODEL(store
);
426 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
427 COMBOBOX_ADD(store
, _("found"), 0);
428 COMBOBOX_ADD(store
, _("not found"), 1);
429 matcher
.model_found
= GTK_TREE_MODEL(store
);
431 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
432 COMBOBOX_ADD(store
, _("0 (Passed)"), 0);
433 COMBOBOX_ADD(store
, _("non-0 (Failed)"), 1);
434 matcher
.model_test
= GTK_TREE_MODEL(store
);
438 *\brief Opens the matcher dialog with a list of conditions
440 *\param matchers List of conditions
444 void prefs_matcher_open(MatcherList
*matchers
, PrefsMatcherSignal
*cb
)
448 if (!matcher
.window
) {
449 prefs_matcher_models_create();
450 prefs_matcher_create();
452 #if !GTK_CHECK_VERSION(3, 0, 0)
453 /* update color label menu */
454 gtk_cmoption_menu_set_menu(GTK_CMOPTION_MENU(matcher
.color_optmenu
),
455 colorlabel_create_color_menu());
459 manage_window_set_transient(GTK_WINDOW(matcher
.window
));
460 gtk_widget_grab_focus(matcher
.ok_btn
);
462 matchers_callback
= cb
;
464 prefs_matcher_set_dialog(matchers
);
466 gtk_widget_show(matcher
.window
);
467 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), TRUE
);
471 *\brief Save Gtk object size to prefs dataset
473 static void prefs_matcher_size_allocate_cb(GtkWidget
*widget
,
474 GtkAllocation
*allocation
)
476 cm_return_if_fail(allocation
!= NULL
);
478 prefs_common
.matcherwin_width
= allocation
->width
;
479 prefs_common
.matcherwin_height
= allocation
->height
;
483 *\brief Create the matcher dialog
485 static void prefs_matcher_create(void)
490 GtkWidget
*cancel_btn
;
491 GtkWidget
*confirm_area
;
496 GtkWidget
*upper_hbox
;
497 GtkWidget
*lower_hbox
;
498 GtkWidget
*match_hbox
;
499 GtkWidget
*criteria_combo
;
500 GtkWidget
*criteria_label
;
501 GtkWidget
*match_label
;
502 GtkWidget
*criteria_label2
;
503 GtkWidget
*headers_combo
;
504 GtkWidget
*match_combo2
;
505 GtkWidget
*match_label2
;
508 GtkWidget
*upper_filler
;
509 GtkWidget
*lower_filler
;
511 GtkWidget
*criteria_combo2
;
512 GtkWidget
*header_entry
;
513 GtkWidget
*header_addr_combo
;
514 GtkWidget
*header_addr_entry
;
515 GtkWidget
*string_entry
;
516 GtkWidget
*addressbook_folder_combo
;
517 GtkWidget
*match_combo
;
518 GtkWidget
*bool_op_combo
;
519 GtkWidget
*bool_op_label
;
521 GtkWidget
*numeric_hbox
;
522 GtkWidget
*numeric_entry
;
523 GtkWidget
*numeric_label
;
525 GtkWidget
*regexp_checkbtn
;
526 GtkWidget
*case_checkbtn
;
532 GtkWidget
*subst_btn
;
535 GtkWidget
*cond_hbox
;
536 GtkWidget
*cond_scrolledwin
;
537 GtkWidget
*cond_list_view
;
544 GtkWidget
*addressbook_select_btn
;
545 #if !GTK_CHECK_VERSION(3, 0, 0)
546 GtkWidget
*color_optmenu
;
549 static GdkGeometry geometry
;
550 GtkSizeGroup
*size_group
;
554 debug_print("Creating matcher configuration window...\n");
556 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "prefs_matcher");
557 gtk_container_set_border_width(GTK_CONTAINER(window
), 4);
558 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
560 vbox
= gtk_vbox_new(FALSE
, 6);
561 gtk_container_add(GTK_CONTAINER(window
), vbox
);
563 gtkut_stock_button_set_create(&confirm_area
, &cancel_btn
, GTK_STOCK_CANCEL
,
564 &ok_btn
, GTK_STOCK_OK
, NULL
, NULL
);
565 gtk_box_pack_end(GTK_BOX(vbox
), confirm_area
, FALSE
, FALSE
, 0);
566 gtk_widget_grab_default(ok_btn
);
568 gtk_window_set_title(GTK_WINDOW(window
),
569 _("Condition configuration"));
570 g_signal_connect(G_OBJECT(window
), "delete_event",
571 G_CALLBACK(prefs_matcher_deleted
), NULL
);
572 g_signal_connect(G_OBJECT(window
), "size_allocate",
573 G_CALLBACK(prefs_matcher_size_allocate_cb
), NULL
);
574 g_signal_connect(G_OBJECT(window
), "key_press_event",
575 G_CALLBACK(prefs_matcher_key_pressed
), NULL
);
576 MANAGE_WINDOW_SIGNALS_CONNECT(window
);
577 g_signal_connect(G_OBJECT(ok_btn
), "clicked",
578 G_CALLBACK(prefs_matcher_ok
), NULL
);
579 g_signal_connect(G_OBJECT(cancel_btn
), "clicked",
580 G_CALLBACK(prefs_matcher_cancel
), NULL
);
582 vbox1
= gtk_vbox_new(FALSE
, VSPACING
);
583 gtk_box_pack_start(GTK_BOX(vbox
), vbox1
, TRUE
, TRUE
, 0);
584 gtk_container_set_border_width(GTK_CONTAINER (vbox1
), 2);
586 frame
= gtk_frame_new(_("Rule"));
587 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.01, 0.5);
588 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
590 table
= gtk_table_new(3, 3, FALSE
);
591 gtk_container_add(GTK_CONTAINER(frame
), table
);
592 gtk_widget_set_size_request(frame
, -1, -1);
594 upper_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
595 hbox
= gtk_hbox_new(FALSE
, 0);
596 gtk_box_pack_start(GTK_BOX(hbox
), upper_hbox
, FALSE
, FALSE
, 0);
597 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
598 gtk_table_attach(GTK_TABLE(table
), hbox
, 2, 3, 0, 1,
599 GTK_FILL
, GTK_SHRINK
, 2, 2);
601 lower_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
602 hbox
= gtk_hbox_new(FALSE
, 0);
603 gtk_box_pack_start(GTK_BOX(hbox
), lower_hbox
, FALSE
, FALSE
, 0);
604 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
605 gtk_table_attach(GTK_TABLE(table
), hbox
,2, 3, 1, 2,
606 GTK_FILL
, GTK_SHRINK
, 2, 2);
608 size_group
= gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL
);
609 gtk_size_group_add_widget(size_group
, upper_hbox
);
610 gtk_size_group_add_widget(size_group
, lower_hbox
);
612 /* criteria combo box */
613 criteria_label
= gtk_label_new(_("Match criteria:"));
614 gtk_misc_set_alignment(GTK_MISC(criteria_label
), 1, 0.5);
615 gtk_widget_set_size_request(criteria_label
, -1, -1);
616 gtk_table_attach(GTK_TABLE(table
), criteria_label
, 0, 1, 0, 1,
617 GTK_FILL
, GTK_SHRINK
, 2, 2);
619 criteria_combo
= gtkut_sc_combobox_create(NULL
, FALSE
);
620 store
= GTK_LIST_STORE(gtk_combo_box_get_model(
621 GTK_COMBO_BOX(criteria_combo
)));
622 COMBOBOX_ADD(store
, _("All messages"), 0);
623 COMBOBOX_ADD(store
, _("Header"), 1);
624 COMBOBOX_ADD(store
, _("Age"), 2);
625 COMBOBOX_ADD(store
, _("Phrase"), 3);
626 COMBOBOX_ADD(store
, _("Flags"), 4);
627 COMBOBOX_ADD(store
, _("Color labels"), 5);
628 COMBOBOX_ADD(store
, _("Thread"), 6);
629 COMBOBOX_ADD(store
, _("Score"), 7);
630 COMBOBOX_ADD(store
, _("Size"), 8);
631 COMBOBOX_ADD(store
, _("Partially downloaded"), 9);
632 COMBOBOX_ADD(store
, _("Address book"), 10);
633 COMBOBOX_ADD(store
, _("Tags"), 11);
634 COMBOBOX_ADD(store
, _("External program test"), 12);
636 gtk_widget_set_size_request(criteria_combo
, 150, -1);
637 gtk_combo_box_set_active(GTK_COMBO_BOX(criteria_combo
), MATCH_ALL
);
638 gtk_table_attach(GTK_TABLE(table
), criteria_combo
, 1, 2, 0, 1,
639 GTK_FILL
, GTK_SHRINK
, 2, 2);
640 g_signal_connect(G_OBJECT(criteria_combo
), "changed",
641 G_CALLBACK(prefs_matcher_criteria_select
),
644 upper_filler
= gtk_label_new("");
645 gtk_box_pack_start(GTK_BOX(upper_hbox
), upper_filler
, TRUE
, TRUE
, 0);
647 lower_filler
= gtk_label_new("");
648 gtk_box_pack_start(GTK_BOX(lower_hbox
), lower_filler
, TRUE
, TRUE
, 0);
650 criteria_label2
= gtk_label_new("");
651 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_label2
, FALSE
, FALSE
, 0);
653 /* headers combo box entry */
654 #if !GTK_CHECK_VERSION(2, 24, 0)
655 headers_combo
= gtk_combo_box_entry_new_with_model(matcher
.model_headers
, 0);
657 headers_combo
= gtk_combo_box_new_with_model_and_entry(matcher
.model_headers
);
658 GtkCellRenderer
*cell
= gtk_cell_renderer_text_new();
659 gtk_cell_renderer_set_alignment(cell
, 0.0, 0.5);
660 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(headers_combo
), cell
, TRUE
);
661 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(headers_combo
), 0);
663 gtk_widget_set_size_request(headers_combo
, 100, -1);
664 gtk_box_pack_start(GTK_BOX(upper_hbox
), headers_combo
, TRUE
, TRUE
, 0);
665 header_entry
= gtk_bin_get_child(GTK_BIN((headers_combo
)));
667 criteria_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
668 prefs_matcher_set_model(criteria_combo2
, matcher
.model_phrase
);
669 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_combo2
, TRUE
, TRUE
, 0);
670 g_signal_connect(G_OBJECT(criteria_combo2
), "changed",
671 G_CALLBACK(prefs_matcher_second_criteria_sel
),
674 /* book/folder value */
675 addressbook_folder_combo
= combobox_text_new(TRUE
, _("Any"), NULL
);
676 gtk_widget_set_size_request(addressbook_folder_combo
, 150, -1);
677 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_folder_combo
, TRUE
, TRUE
, 0);
679 addressbook_select_btn
= gtk_button_new_with_label(_("Select..."));
680 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_select_btn
, FALSE
, FALSE
, 0);
681 #ifndef USE_ALT_ADDRBOOK
682 g_signal_connect(G_OBJECT (addressbook_select_btn
), "clicked",
683 G_CALLBACK(prefs_matcher_addressbook_select
),
686 gtk_widget_set_sensitive(GTK_WIDGET(addressbook_select_btn
), FALSE
);
688 match_label
= gtk_label_new("");
689 gtk_misc_set_alignment(GTK_MISC(match_label
), 1, 0.5);
690 gtk_table_attach(GTK_TABLE(table
), match_label
, 0, 1, 1, 2,
691 GTK_FILL
, GTK_SHRINK
, 2, 2);
693 match_hbox
= gtk_hbox_new(FALSE
, 0);
694 gtk_table_attach(GTK_TABLE(table
), match_hbox
, 1, 2, 1, 2,
695 GTK_FILL
, GTK_SHRINK
, 2, 2);
697 match_combo
= gtkut_sc_combobox_create(NULL
, TRUE
);
698 gtk_box_pack_start(GTK_BOX(match_hbox
), match_combo
, TRUE
, TRUE
, 0);
700 #if !GTK_CHECK_VERSION(3, 0, 0)
701 /* color labels combo */
702 color_optmenu
= gtk_cmoption_menu_new();
703 gtk_cmoption_menu_set_menu(GTK_CMOPTION_MENU(color_optmenu
),
704 colorlabel_create_color_menu());
705 gtk_box_pack_start(GTK_BOX(match_hbox
), color_optmenu
, FALSE
, FALSE
, 0);
708 /* address header name */
709 header_addr_combo
= combobox_text_new(TRUE
,
710 C_("Filtering Matcher Menu", "All"), _("Any"),
711 "From", "To", "Cc", "Reply-To", "Sender", NULL
);
712 gtk_box_pack_start(GTK_BOX(match_hbox
), header_addr_combo
, FALSE
, FALSE
, 0);
713 header_addr_entry
= gtk_bin_get_child(GTK_BIN((header_addr_combo
)));
714 gtk_widget_set_size_request(header_addr_combo
, 150, -1);
716 match_label2
= gtk_label_new("");
717 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_label2
, FALSE
, FALSE
, 0);
720 numeric_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
721 gtk_box_pack_start(GTK_BOX(lower_hbox
), numeric_hbox
, FALSE
, FALSE
, 0);
723 numeric_entry
= gtk_spin_button_new_with_range(0, 1000, 1);
724 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(numeric_entry
), 0);
725 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_entry
, FALSE
, FALSE
, 0);
727 numeric_label
= gtk_label_new("");
728 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_label
, FALSE
, FALSE
, 0);
729 gtk_box_pack_end(GTK_BOX(numeric_hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
731 match_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
732 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_combo2
, TRUE
, TRUE
, 0);
735 string_entry
= gtk_entry_new();
736 gtk_box_pack_start(GTK_BOX(lower_hbox
), string_entry
, TRUE
, TRUE
, 0);
738 hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
739 gtk_size_group_add_widget(size_group
, hbox
);
741 vbox
= gtk_vbox_new(FALSE
, VSPACING_NARROW
);
742 PACK_CHECK_BUTTON(vbox
, case_checkbtn
, _("Case sensitive"));
743 PACK_CHECK_BUTTON(vbox
, regexp_checkbtn
, _("Use regexp"));
744 gtk_box_pack_start(GTK_BOX(hbox
), vbox
, TRUE
, TRUE
, 0);
746 gtk_box_pack_end(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
747 gtk_table_attach(GTK_TABLE(table
), hbox
, 2, 3, 2, 3,
748 GTK_FILL
, GTK_SHRINK
, 4, 0);
750 /* test info button */
751 test_btn
= gtk_button_new_from_stock(GTK_STOCK_INFO
);
752 gtk_box_pack_start(GTK_BOX(lower_hbox
), test_btn
, FALSE
, FALSE
, 0);
753 g_signal_connect(G_OBJECT (test_btn
), "clicked",
754 G_CALLBACK(prefs_matcher_test_info
),
757 /* register / substitute / delete */
758 reg_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
759 gtk_box_pack_start(GTK_BOX(vbox1
), reg_hbox
, FALSE
, FALSE
, 0);
761 arrow
= gtk_arrow_new(GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
762 gtk_box_pack_start(GTK_BOX(reg_hbox
), arrow
, FALSE
, FALSE
, 0);
763 gtk_widget_set_size_request(arrow
, -1, 16);
765 btn_hbox
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
766 gtk_box_pack_start(GTK_BOX(reg_hbox
), btn_hbox
, FALSE
, FALSE
, 0);
768 reg_btn
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
769 gtk_box_pack_start(GTK_BOX(btn_hbox
), reg_btn
, FALSE
, TRUE
, 0);
770 g_signal_connect(G_OBJECT(reg_btn
), "clicked",
771 G_CALLBACK(prefs_matcher_register_cb
), NULL
);
773 subst_btn
= gtkut_get_replace_btn(_("_Replace"));
774 gtk_box_pack_start(GTK_BOX(btn_hbox
), subst_btn
, FALSE
, TRUE
, 0);
775 g_signal_connect(G_OBJECT(subst_btn
), "clicked",
776 G_CALLBACK(prefs_matcher_substitute_cb
),
779 del_btn
= gtk_button_new_with_mnemonic (_("D_elete"));
780 gtk_button_set_image(GTK_BUTTON(del_btn
),
781 gtk_image_new_from_stock(GTK_STOCK_REMOVE
,GTK_ICON_SIZE_BUTTON
));
782 gtk_box_pack_start(GTK_BOX(btn_hbox
), del_btn
, FALSE
, TRUE
, 0);
783 g_signal_connect(G_OBJECT(del_btn
), "clicked",
784 G_CALLBACK(prefs_matcher_delete_cb
), NULL
);
786 cond_hbox
= gtk_hbox_new(FALSE
, VBOX_BORDER
);
787 gtk_box_pack_start(GTK_BOX(vbox1
), cond_hbox
, TRUE
, TRUE
, 0);
789 cond_scrolledwin
= gtk_scrolled_window_new(NULL
, NULL
);
790 gtk_widget_set_size_request(cond_scrolledwin
, -1, 150);
791 gtk_box_pack_start(GTK_BOX(cond_hbox
), cond_scrolledwin
,
793 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
794 GTK_POLICY_AUTOMATIC
,
795 GTK_POLICY_AUTOMATIC
);
797 cond_list_view
= prefs_matcher_list_view_create();
798 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
799 GTK_SHADOW_ETCHED_IN
);
800 gtk_container_add(GTK_CONTAINER(cond_scrolledwin
), cond_list_view
);
802 btn_vbox
= gtk_vbox_new(FALSE
, VBOX_BORDER
);
803 gtk_box_pack_start(GTK_BOX(cond_hbox
), btn_vbox
, FALSE
, FALSE
, 0);
805 up_btn
= gtk_button_new_from_stock(GTK_STOCK_GO_UP
);
806 gtk_box_pack_start(GTK_BOX(btn_vbox
), up_btn
, FALSE
, FALSE
, 0);
807 g_signal_connect(G_OBJECT(up_btn
), "clicked",
808 G_CALLBACK(prefs_matcher_up
), NULL
);
810 down_btn
= gtk_button_new_from_stock(GTK_STOCK_GO_DOWN
);
811 gtk_box_pack_start(GTK_BOX(btn_vbox
), down_btn
, FALSE
, FALSE
, 0);
812 g_signal_connect(G_OBJECT(down_btn
), "clicked",
813 G_CALLBACK(prefs_matcher_down
), NULL
);
815 /* boolean operation */
816 GtkWidget
*hbox_bool
= gtk_hbox_new(FALSE
, HSPACING_NARROW
);
817 gtk_box_pack_start(GTK_BOX(vbox1
), hbox_bool
, FALSE
, FALSE
, 0);
819 bool_op_label
= gtk_label_new(_("Message must match"));
820 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_label
,
823 bool_op_combo
= combobox_text_new(FALSE
, _("at least one"),
825 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_combo
,
827 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(_("of above rules")),
829 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(""),
832 if (!geometry
.min_height
) {
833 geometry
.min_width
= 550;
834 geometry
.min_height
= 368;
837 gtk_window_set_geometry_hints(GTK_WINDOW(window
), NULL
, &geometry
,
839 gtk_widget_set_size_request(window
, prefs_common
.matcherwin_width
,
840 prefs_common
.matcherwin_height
);
842 gtk_widget_show_all(window
);
844 matcher
.window
= window
;
846 matcher
.ok_btn
= ok_btn
;
848 matcher
.criteria_combo
= criteria_combo
;
849 matcher
.criteria_combo2
= criteria_combo2
;
850 matcher
.header_entry
= header_entry
;
851 matcher
.header_addr_combo
= header_addr_combo
;
852 matcher
.header_addr_entry
= header_addr_entry
;
853 matcher
.string_entry
= string_entry
;
854 matcher
.numeric_entry
= numeric_entry
;
855 matcher
.numeric_label
= numeric_label
;
856 matcher
.addressbook_folder_combo
= addressbook_folder_combo
;
857 matcher
.match_combo
= match_combo
;
858 matcher
.case_checkbtn
= case_checkbtn
;
859 matcher
.regexp_checkbtn
= regexp_checkbtn
;
860 matcher
.bool_op_combo
= bool_op_combo
;
861 matcher
.test_btn
= test_btn
;
862 #ifndef USE_ALT_ADDRBOOK
863 matcher
.addressbook_select_btn
= addressbook_select_btn
;
865 #if !GTK_CHECK_VERSION(3, 0, 0)
866 matcher
.color_optmenu
= color_optmenu
;
868 matcher
.match_label
= match_label
;
869 matcher
.criteria_label2
= criteria_label2
;
870 matcher
.headers_combo
= headers_combo
;
871 matcher
.match_combo2
= match_combo2
;
872 matcher
.match_label2
= match_label2
;
873 matcher
.upper_filler
= upper_filler
;
874 matcher
.lower_filler
= lower_filler
;
876 matcher
.cond_list_view
= cond_list_view
;
878 matcher
.selected_criteria
= -1;
879 prefs_matcher_criteria_select(criteria_combo
, NULL
);
883 *\brief Set the contents of a row
885 *\param row Index of row to set
886 *\param prop Condition to set
888 *\return gint Row index \a prop has been added
890 static void prefs_matcher_list_view_set_row(GtkTreeIter
*row
, MatcherProp
*prop
)
895 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
896 NULL
, _("(New)"), FALSE
);
900 matcher_str
= matcherprop_to_string(prop
);
902 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
906 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
912 static gboolean
match_combo2_model_set(void)
914 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo2
));
915 if (model
== matcher
.model_age_units
||
916 model
== matcher
.model_found
||
917 model
== matcher
.model_partial
||
918 model
== matcher
.model_phrase
||
919 model
== matcher
.model_set
||
920 model
== matcher
.model_size_units
||
921 model
== matcher
.model_tags
||
922 model
== matcher
.model_thread
)
925 debug_print("match_combo2 model unset.\n");
930 static gboolean
match_combo_model_set(void)
932 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo
));
933 if (model
== matcher
.model_age
||
934 model
== matcher
.model_contain
||
935 model
== matcher
.model_flags
||
936 model
== matcher
.model_score
||
937 model
== matcher
.model_size
||
938 model
== matcher
.model_test
)
941 debug_print("match_combo model unset.\n");
947 *\brief Clears a condition in the list widget
949 static void prefs_matcher_reset_condition(void)
951 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_ALL
);
952 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
), 0);
953 if (match_combo_model_set())
954 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
), 0);
955 if (match_combo2_model_set())
956 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), 0);
957 #if !GTK_CHECK_VERSION(3, 0, 0)
958 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
), 0);
960 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
961 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), "");
962 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), "");
963 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
964 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), "");
965 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
966 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
970 *\brief Initializes dialog with a set of conditions
972 *\param matchers List of conditions
974 static void prefs_matcher_set_dialog(MatcherList
*matchers
)
977 gboolean bool_op
= 1;
978 GtkListStore
*store
= GTK_LIST_STORE(gtk_tree_view_get_model
979 (GTK_TREE_VIEW(matcher
.cond_list_view
)));
981 gtk_list_store_clear(store
);
983 prefs_matcher_list_view_set_row(NULL
, NULL
);
984 if (matchers
!= NULL
) {
985 for (cur
= matchers
->matchers
; cur
!= NULL
;
986 cur
= g_slist_next(cur
)) {
988 prop
= (MatcherProp
*) cur
->data
;
989 prefs_matcher_list_view_set_row(NULL
, prop
);
992 bool_op
= matchers
->bool_and
;
995 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.bool_op_combo
), bool_op
);
997 prefs_matcher_reset_condition();
999 combobox_set_sensitive(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_TAGS
,
1000 (tags_get_size() > 0) ? TRUE
: FALSE
);
1004 *\brief Converts current conditions in list box in
1005 * a matcher list used by the matcher.
1007 *\return MatcherList * List of conditions.
1009 static MatcherList
*prefs_matcher_get_list(void)
1014 GSList
*matcher_list
;
1015 MatcherList
*matchers
;
1016 GtkTreeModel
*model
;
1019 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(matcher
.cond_list_view
));
1020 if (!gtk_tree_model_get_iter_first(model
, &iter
))
1023 matcher_list
= NULL
;
1028 gtk_tree_model_get(model
, &iter
,
1029 PREFS_MATCHER_COND
, &matcher_str
,
1030 PREFS_MATCHER_COND_VALID
, &is_valid
,
1034 /* tmp = matcher_str; */
1035 prop
= matcher_parser_get_prop(matcher_str
);
1036 g_free(matcher_str
);
1040 matcher_list
= g_slist_append(matcher_list
, prop
);
1042 } while (gtk_tree_model_iter_next(model
, &iter
));
1044 bool_and
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.bool_op_combo
));
1046 matchers
= matcherlist_new(matcher_list
, bool_and
);
1052 *\brief Maps a keyword id (see #get_matchparser_tab_id) to a
1053 * criteria type (see first parameter of #matcherprop_new
1054 * or #matcherprop_unquote_new)
1056 *\param matching_id Id returned by the matcher parser.
1058 *\return gint One of the CRITERIA_xxx constants.
1060 static gint
prefs_matcher_get_criteria_from_matching(gint matching_id
)
1062 switch(matching_id
) {
1063 case MATCHCRITERIA_ALL
:
1064 return CRITERIA_ALL
;
1065 case MATCHCRITERIA_NOT_UNREAD
:
1066 case MATCHCRITERIA_UNREAD
:
1067 return CRITERIA_UNREAD
;
1068 case MATCHCRITERIA_NOT_NEW
:
1069 case MATCHCRITERIA_NEW
:
1070 return CRITERIA_NEW
;
1071 case MATCHCRITERIA_NOT_MARKED
:
1072 case MATCHCRITERIA_MARKED
:
1073 return CRITERIA_MARKED
;
1074 case MATCHCRITERIA_NOT_DELETED
:
1075 case MATCHCRITERIA_DELETED
:
1076 return CRITERIA_DELETED
;
1077 case MATCHCRITERIA_NOT_REPLIED
:
1078 case MATCHCRITERIA_REPLIED
:
1079 return CRITERIA_REPLIED
;
1080 case MATCHCRITERIA_NOT_FORWARDED
:
1081 case MATCHCRITERIA_FORWARDED
:
1082 return CRITERIA_FORWARDED
;
1083 case MATCHCRITERIA_LOCKED
:
1084 case MATCHCRITERIA_NOT_LOCKED
:
1085 return CRITERIA_LOCKED
;
1086 case MATCHCRITERIA_NOT_SPAM
:
1087 case MATCHCRITERIA_SPAM
:
1088 return CRITERIA_SPAM
;
1089 case MATCHCRITERIA_HAS_ATTACHMENT
:
1090 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
1091 return CRITERIA_HAS_ATTACHMENT
;
1092 case MATCHCRITERIA_SIGNED
:
1093 case MATCHCRITERIA_NOT_SIGNED
:
1094 return CRITERIA_SIGNED
;
1095 case MATCHCRITERIA_PARTIAL
:
1096 case MATCHCRITERIA_NOT_PARTIAL
:
1097 return CRITERIA_PARTIAL
;
1098 #if !GTK_CHECK_VERSION(3, 0, 0)
1099 case MATCHCRITERIA_COLORLABEL
:
1100 case MATCHCRITERIA_NOT_COLORLABEL
:
1101 return CRITERIA_COLORLABEL
;
1103 case MATCHCRITERIA_IGNORE_THREAD
:
1104 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
1105 return CRITERIA_IGNORE_THREAD
;
1106 case MATCHCRITERIA_WATCH_THREAD
:
1107 case MATCHCRITERIA_NOT_WATCH_THREAD
:
1108 return CRITERIA_WATCH_THREAD
;
1109 case MATCHCRITERIA_NOT_SUBJECT
:
1110 case MATCHCRITERIA_SUBJECT
:
1111 return CRITERIA_SUBJECT
;
1112 case MATCHCRITERIA_NOT_FROM
:
1113 case MATCHCRITERIA_FROM
:
1114 return CRITERIA_FROM
;
1115 case MATCHCRITERIA_NOT_TO
:
1116 case MATCHCRITERIA_TO
:
1118 case MATCHCRITERIA_NOT_CC
:
1119 case MATCHCRITERIA_CC
:
1121 case MATCHCRITERIA_NOT_NEWSGROUPS
:
1122 case MATCHCRITERIA_NEWSGROUPS
:
1123 return CRITERIA_NEWSGROUPS
;
1124 case MATCHCRITERIA_NOT_MESSAGEID
:
1125 case MATCHCRITERIA_MESSAGEID
:
1126 return CRITERIA_MESSAGEID
;
1127 case MATCHCRITERIA_NOT_INREPLYTO
:
1128 case MATCHCRITERIA_INREPLYTO
:
1129 return CRITERIA_INREPLYTO
;
1130 case MATCHCRITERIA_NOT_REFERENCES
:
1131 case MATCHCRITERIA_REFERENCES
:
1132 return CRITERIA_REFERENCES
;
1133 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
1134 case MATCHCRITERIA_TO_OR_CC
:
1135 return CRITERIA_TO_OR_CC
;
1136 case MATCHCRITERIA_NOT_TAG
:
1137 case MATCHCRITERIA_TAG
:
1138 return CRITERIA_TAG
;
1139 case MATCHCRITERIA_NOT_TAGGED
:
1140 case MATCHCRITERIA_TAGGED
:
1141 return CRITERIA_TAGGED
;
1142 case MATCHCRITERIA_NOT_BODY_PART
:
1143 case MATCHCRITERIA_BODY_PART
:
1144 return CRITERIA_BODY_PART
;
1145 case MATCHCRITERIA_NOT_MESSAGE
:
1146 case MATCHCRITERIA_MESSAGE
:
1147 return CRITERIA_MESSAGE
;
1148 case MATCHCRITERIA_NOT_HEADERS_PART
:
1149 case MATCHCRITERIA_HEADERS_PART
:
1150 return CRITERIA_HEADERS_PART
;
1151 case MATCHCRITERIA_NOT_HEADERS_CONT
:
1152 case MATCHCRITERIA_HEADERS_CONT
:
1153 return CRITERIA_HEADERS_CONT
;
1154 case MATCHCRITERIA_NOT_HEADER
:
1155 case MATCHCRITERIA_HEADER
:
1156 return CRITERIA_HEADER
;
1157 case MATCHCRITERIA_AGE_GREATER_HOURS
:
1158 return CRITERIA_AGE_GREATER_HOURS
;
1159 case MATCHCRITERIA_AGE_LOWER_HOURS
:
1160 return CRITERIA_AGE_LOWER_HOURS
;
1161 case MATCHCRITERIA_AGE_GREATER
:
1162 return CRITERIA_AGE_GREATER
;
1163 case MATCHCRITERIA_AGE_LOWER
:
1164 return CRITERIA_AGE_LOWER
;
1165 case MATCHCRITERIA_SCORE_GREATER
:
1166 return CRITERIA_SCORE_GREATER
;
1167 case MATCHCRITERIA_SCORE_LOWER
:
1168 return CRITERIA_SCORE_LOWER
;
1169 case MATCHCRITERIA_SCORE_EQUAL
:
1170 return CRITERIA_SCORE_EQUAL
;
1171 case MATCHCRITERIA_NOT_TEST
:
1172 case MATCHCRITERIA_TEST
:
1173 return CRITERIA_TEST
;
1174 case MATCHCRITERIA_SIZE_GREATER
:
1175 return CRITERIA_SIZE_GREATER
;
1176 case MATCHCRITERIA_SIZE_SMALLER
:
1177 return CRITERIA_SIZE_SMALLER
;
1178 case MATCHCRITERIA_SIZE_EQUAL
:
1179 return CRITERIA_SIZE_EQUAL
;
1180 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1181 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
1182 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1189 *\brief Returns the matcher keyword id from a criteria id
1191 *\param criteria_id Criteria id (should not be the negate
1194 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1196 static gint
prefs_matcher_get_matching_from_criteria(gint criteria_id
)
1198 switch (criteria_id
) {
1200 return MATCHCRITERIA_ALL
;
1201 case CRITERIA_UNREAD
:
1202 return MATCHCRITERIA_UNREAD
;
1204 return MATCHCRITERIA_NEW
;
1205 case CRITERIA_MARKED
:
1206 return MATCHCRITERIA_MARKED
;
1207 case CRITERIA_DELETED
:
1208 return MATCHCRITERIA_DELETED
;
1209 case CRITERIA_REPLIED
:
1210 return MATCHCRITERIA_REPLIED
;
1211 case CRITERIA_FORWARDED
:
1212 return MATCHCRITERIA_FORWARDED
;
1213 case CRITERIA_LOCKED
:
1214 return MATCHCRITERIA_LOCKED
;
1216 return MATCHCRITERIA_SPAM
;
1217 case CRITERIA_HAS_ATTACHMENT
:
1218 return MATCHCRITERIA_HAS_ATTACHMENT
;
1219 case CRITERIA_SIGNED
:
1220 return MATCHCRITERIA_SIGNED
;
1221 case CRITERIA_PARTIAL
:
1222 return MATCHCRITERIA_PARTIAL
;
1223 #if !GTK_CHECK_VERSION(3, 0, 0)
1224 case CRITERIA_COLORLABEL
:
1225 return MATCHCRITERIA_COLORLABEL
;
1227 case CRITERIA_IGNORE_THREAD
:
1228 return MATCHCRITERIA_IGNORE_THREAD
;
1229 case CRITERIA_WATCH_THREAD
:
1230 return MATCHCRITERIA_WATCH_THREAD
;
1231 case CRITERIA_SUBJECT
:
1232 return MATCHCRITERIA_SUBJECT
;
1234 return MATCHCRITERIA_FROM
;
1236 return MATCHCRITERIA_TO
;
1238 return MATCHCRITERIA_CC
;
1239 case CRITERIA_TO_OR_CC
:
1240 return MATCHCRITERIA_TO_OR_CC
;
1242 return MATCHCRITERIA_TAG
;
1243 case CRITERIA_TAGGED
:
1244 return MATCHCRITERIA_TAGGED
;
1245 case CRITERIA_NEWSGROUPS
:
1246 return MATCHCRITERIA_NEWSGROUPS
;
1247 case CRITERIA_MESSAGEID
:
1248 return MATCHCRITERIA_MESSAGEID
;
1249 case CRITERIA_INREPLYTO
:
1250 return MATCHCRITERIA_INREPLYTO
;
1251 case CRITERIA_REFERENCES
:
1252 return MATCHCRITERIA_REFERENCES
;
1253 case CRITERIA_AGE_GREATER
:
1254 return MATCHCRITERIA_AGE_GREATER
;
1255 case CRITERIA_AGE_LOWER
:
1256 return MATCHCRITERIA_AGE_LOWER
;
1257 case CRITERIA_AGE_GREATER_HOURS
:
1258 return MATCHCRITERIA_AGE_GREATER_HOURS
;
1259 case CRITERIA_AGE_LOWER_HOURS
:
1260 return MATCHCRITERIA_AGE_LOWER_HOURS
;
1261 case CRITERIA_SCORE_GREATER
:
1262 return MATCHCRITERIA_SCORE_GREATER
;
1263 case CRITERIA_SCORE_LOWER
:
1264 return MATCHCRITERIA_SCORE_LOWER
;
1265 case CRITERIA_SCORE_EQUAL
:
1266 return MATCHCRITERIA_SCORE_EQUAL
;
1267 case CRITERIA_HEADER
:
1268 return MATCHCRITERIA_HEADER
;
1269 case CRITERIA_HEADERS_PART
:
1270 return MATCHCRITERIA_HEADERS_PART
;
1271 case CRITERIA_HEADERS_CONT
:
1272 return MATCHCRITERIA_HEADERS_CONT
;
1273 case CRITERIA_BODY_PART
:
1274 return MATCHCRITERIA_BODY_PART
;
1275 case CRITERIA_MESSAGE
:
1276 return MATCHCRITERIA_MESSAGE
;
1278 return MATCHCRITERIA_TEST
;
1279 case CRITERIA_SIZE_GREATER
:
1280 return MATCHCRITERIA_SIZE_GREATER
;
1281 case CRITERIA_SIZE_SMALLER
:
1282 return MATCHCRITERIA_SIZE_SMALLER
;
1283 case CRITERIA_SIZE_EQUAL
:
1284 return MATCHCRITERIA_SIZE_EQUAL
;
1285 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1286 return MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
;
1293 *\brief Returns the negate matcher keyword id from a matcher keyword
1296 *\param matcher_criteria Matcher keyword id.
1298 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1300 static gint
prefs_matcher_not_criteria(gint matcher_criteria
)
1302 switch(matcher_criteria
) {
1303 case MATCHCRITERIA_UNREAD
:
1304 return MATCHCRITERIA_NOT_UNREAD
;
1305 case MATCHCRITERIA_NEW
:
1306 return MATCHCRITERIA_NOT_NEW
;
1307 case MATCHCRITERIA_MARKED
:
1308 return MATCHCRITERIA_NOT_MARKED
;
1309 case MATCHCRITERIA_DELETED
:
1310 return MATCHCRITERIA_NOT_DELETED
;
1311 case MATCHCRITERIA_REPLIED
:
1312 return MATCHCRITERIA_NOT_REPLIED
;
1313 case MATCHCRITERIA_FORWARDED
:
1314 return MATCHCRITERIA_NOT_FORWARDED
;
1315 case MATCHCRITERIA_LOCKED
:
1316 return MATCHCRITERIA_NOT_LOCKED
;
1317 case MATCHCRITERIA_SPAM
:
1318 return MATCHCRITERIA_NOT_SPAM
;
1319 case MATCHCRITERIA_HAS_ATTACHMENT
:
1320 return MATCHCRITERIA_HAS_NO_ATTACHMENT
;
1321 case MATCHCRITERIA_SIGNED
:
1322 return MATCHCRITERIA_NOT_SIGNED
;
1323 case MATCHCRITERIA_PARTIAL
:
1324 return MATCHCRITERIA_NOT_PARTIAL
;
1325 #if !GTK_CHECK_VERSION(3, 0, 0)
1326 case MATCHCRITERIA_COLORLABEL
:
1327 return MATCHCRITERIA_NOT_COLORLABEL
;
1329 case MATCHCRITERIA_IGNORE_THREAD
:
1330 return MATCHCRITERIA_NOT_IGNORE_THREAD
;
1331 case MATCHCRITERIA_WATCH_THREAD
:
1332 return MATCHCRITERIA_NOT_WATCH_THREAD
;
1333 case MATCHCRITERIA_SUBJECT
:
1334 return MATCHCRITERIA_NOT_SUBJECT
;
1335 case MATCHCRITERIA_FROM
:
1336 return MATCHCRITERIA_NOT_FROM
;
1337 case MATCHCRITERIA_TO
:
1338 return MATCHCRITERIA_NOT_TO
;
1339 case MATCHCRITERIA_CC
:
1340 return MATCHCRITERIA_NOT_CC
;
1341 case MATCHCRITERIA_TO_OR_CC
:
1342 return MATCHCRITERIA_NOT_TO_AND_NOT_CC
;
1343 case MATCHCRITERIA_TAG
:
1344 return MATCHCRITERIA_NOT_TAG
;
1345 case MATCHCRITERIA_TAGGED
:
1346 return MATCHCRITERIA_NOT_TAGGED
;
1347 case MATCHCRITERIA_NEWSGROUPS
:
1348 return MATCHCRITERIA_NOT_NEWSGROUPS
;
1349 case MATCHCRITERIA_MESSAGEID
:
1350 return MATCHCRITERIA_NOT_MESSAGEID
;
1351 case MATCHCRITERIA_INREPLYTO
:
1352 return MATCHCRITERIA_NOT_INREPLYTO
;
1353 case MATCHCRITERIA_REFERENCES
:
1354 return MATCHCRITERIA_NOT_REFERENCES
;
1355 case MATCHCRITERIA_HEADER
:
1356 return MATCHCRITERIA_NOT_HEADER
;
1357 case MATCHCRITERIA_HEADERS_PART
:
1358 return MATCHCRITERIA_NOT_HEADERS_PART
;
1359 case MATCHCRITERIA_HEADERS_CONT
:
1360 return MATCHCRITERIA_NOT_HEADERS_CONT
;
1361 case MATCHCRITERIA_MESSAGE
:
1362 return MATCHCRITERIA_NOT_MESSAGE
;
1363 case MATCHCRITERIA_TEST
:
1364 return MATCHCRITERIA_NOT_TEST
;
1365 case MATCHCRITERIA_BODY_PART
:
1366 return MATCHCRITERIA_NOT_BODY_PART
;
1367 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1368 return MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
;
1370 return matcher_criteria
;
1374 static gint
prefs_matcher_get_criteria(void)
1376 gint match_criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1377 matcher
.criteria_combo
));
1378 const gchar
*header
= NULL
;
1380 switch (match_criteria
) {
1382 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1384 return CRITERIA_ALL
;
1389 return combobox_get_active_data(GTK_COMBO_BOX(
1390 matcher
.match_combo
));
1392 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1393 return header_name_to_crit(header
);
1394 #if !GTK_CHECK_VERSION(3, 0, 0)
1396 return CRITERIA_COLORLABEL
;
1399 return CRITERIA_PARTIAL
;
1401 return CRITERIA_TEST
;
1405 return combobox_get_active_data(GTK_COMBO_BOX(
1406 matcher
.criteria_combo2
));
1412 static gint
prefs_matcher_get_pred(const gint criteria
)
1415 case CRITERIA_SUBJECT
:
1419 case CRITERIA_TO_OR_CC
:
1420 case CRITERIA_NEWSGROUPS
:
1421 case CRITERIA_MESSAGEID
:
1422 case CRITERIA_INREPLYTO
:
1423 case CRITERIA_REFERENCES
:
1424 case CRITERIA_HEADER
:
1425 case CRITERIA_HEADERS_PART
:
1426 case CRITERIA_HEADERS_CONT
:
1427 case CRITERIA_BODY_PART
:
1428 case CRITERIA_MESSAGE
:
1430 case CRITERIA_TAGGED
:
1432 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo
));
1433 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1434 case CRITERIA_UNREAD
:
1436 case CRITERIA_MARKED
:
1437 case CRITERIA_DELETED
:
1438 case CRITERIA_REPLIED
:
1439 case CRITERIA_FORWARDED
:
1440 case CRITERIA_LOCKED
:
1442 case CRITERIA_HAS_ATTACHMENT
:
1443 case CRITERIA_SIGNED
:
1444 case CRITERIA_COLORLABEL
:
1445 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1446 case CRITERIA_WATCH_THREAD
:
1447 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
)) - 2;
1448 case CRITERIA_IGNORE_THREAD
:
1449 case CRITERIA_PARTIAL
:
1450 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
));
1457 *\brief Converts the text in the selected row to a
1460 *\return MatcherProp * Newly allocated matcher structure.
1462 static MatcherProp
*prefs_matcher_dialog_to_matcher(void)
1464 MatcherProp
*matcherprop
;
1468 gint value_criteria
= prefs_matcher_get_criteria();
1469 gboolean use_regexp
;
1470 gboolean case_sensitive
;
1471 const gchar
*header
;
1475 if (value_criteria
== -1)
1478 use_regexp
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
));
1479 case_sensitive
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
));
1483 matchtype
= MATCHTYPE_REGEXP
;
1485 matchtype
= MATCHTYPE_REGEXPCASE
;
1489 matchtype
= MATCHTYPE_MATCH
;
1491 matchtype
= MATCHTYPE_MATCHCASE
;
1498 switch (value_criteria
) {
1500 case CRITERIA_UNREAD
:
1502 case CRITERIA_MARKED
:
1503 case CRITERIA_DELETED
:
1504 case CRITERIA_REPLIED
:
1505 case CRITERIA_FORWARDED
:
1506 case CRITERIA_LOCKED
:
1508 case CRITERIA_HAS_ATTACHMENT
:
1509 case CRITERIA_SIGNED
:
1510 case CRITERIA_PARTIAL
:
1511 case CRITERIA_IGNORE_THREAD
:
1512 case CRITERIA_WATCH_THREAD
:
1513 case CRITERIA_TAGGED
:
1516 case CRITERIA_SUBJECT
:
1520 case CRITERIA_TO_OR_CC
:
1522 case CRITERIA_NEWSGROUPS
:
1523 case CRITERIA_MESSAGEID
:
1524 case CRITERIA_INREPLYTO
:
1525 case CRITERIA_REFERENCES
:
1526 case CRITERIA_HEADERS_PART
:
1527 case CRITERIA_HEADERS_CONT
:
1528 case CRITERIA_BODY_PART
:
1529 case CRITERIA_MESSAGE
:
1530 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1533 alertpanel_error(_("Search pattern is not set."));
1539 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1542 alertpanel_error(_("Test command is not set."));
1547 case CRITERIA_AGE_GREATER
:
1548 case CRITERIA_AGE_LOWER
:
1549 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1550 matcher
.numeric_entry
));
1551 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1552 if(sel
== AGE_WEEKS
)
1554 else if (sel
== AGE_HOURS
) {
1555 if (value_criteria
== CRITERIA_AGE_GREATER
)
1556 value_criteria
= CRITERIA_AGE_GREATER_HOURS
;
1558 value_criteria
= CRITERIA_AGE_LOWER_HOURS
;
1562 case CRITERIA_SCORE_GREATER
:
1563 case CRITERIA_SCORE_LOWER
:
1564 case CRITERIA_SCORE_EQUAL
:
1565 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1566 matcher
.numeric_entry
));
1569 case CRITERIA_SIZE_GREATER
:
1570 case CRITERIA_SIZE_SMALLER
:
1571 case CRITERIA_SIZE_EQUAL
:
1572 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1573 matcher
.numeric_entry
));
1574 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1575 if(sel
== SIZE_UNIT_MBYTES
)
1577 if(sel
== SIZE_UNIT_KBYTES
)
1581 #if !GTK_CHECK_VERSION(3, 0, 0)
1582 case CRITERIA_COLORLABEL
:
1583 value
= colorlabel_get_color_menu_active_item
1584 (gtk_cmoption_menu_get_menu(GTK_CMOPTION_MENU
1585 (matcher
.color_optmenu
)));
1589 case CRITERIA_HEADER
:
1590 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1591 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1593 if (*header
== '\0') {
1594 alertpanel_error(_("Header name is not set."));
1599 alertpanel_error(_("Search pattern is not set."));
1604 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1605 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_addr_entry
));
1606 expr
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
1608 if (*header
== '\0') {
1609 alertpanel_error(_("Header name is not set."));
1612 if (*expr
== '\0') {
1615 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1616 tmp
= g_strdup(_("all addresses in all headers"));
1618 if (g_utf8_collate(header
, _("Any")) == 0)
1619 tmp
= g_strdup(_("any address in any header"));
1621 tmp
= g_strdup_printf(_("the address(es) in header '%s'"), header
);
1622 alertpanel_error(_("Book/folder path is not set.\n\n"
1623 "If you want to match %s against the whole address book, "
1624 "you have to select '%s' from the book/folder drop-down list."),
1629 /* store UNtranslated "Any"/"All" in matcher expressions */
1630 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1633 if (g_utf8_collate(header
, _("Any")) == 0)
1635 if (g_utf8_collate(expr
, _("Any")) == 0)
1640 criteria
= prefs_matcher_get_matching_from_criteria(value_criteria
);
1642 value_pred
= prefs_matcher_get_pred(value_criteria
);
1644 criteria
= prefs_matcher_not_criteria(criteria
);
1646 matcherprop
= matcherprop_new(criteria
, header
, matchtype
,
1653 *\brief Signal handler for register button
1655 static void prefs_matcher_register_cb(void)
1657 MatcherProp
*matcherprop
;
1659 matcherprop
= prefs_matcher_dialog_to_matcher();
1660 if (matcherprop
== NULL
)
1663 prefs_matcher_list_view_set_row(NULL
, matcherprop
);
1665 matcherprop_free(matcherprop
);
1667 prefs_matcher_reset_condition();
1671 *\brief Signal handler for substitute button
1673 static void prefs_matcher_substitute_cb(void)
1675 MatcherProp
*matcherprop
;
1677 GtkTreeSelection
*selection
;
1678 GtkTreeModel
*model
;
1681 selection
= gtk_tree_view_get_selection
1682 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1684 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1687 gtk_tree_model_get(model
, &row
,
1688 PREFS_MATCHER_COND_VALID
, &is_valid
,
1693 matcherprop
= prefs_matcher_dialog_to_matcher();
1694 if (matcherprop
== NULL
)
1697 prefs_matcher_list_view_set_row(&row
, matcherprop
);
1699 matcherprop_free(matcherprop
);
1703 *\brief Signal handler for delete button
1705 static void prefs_matcher_delete_cb(void)
1708 GtkTreeSelection
*selection
;
1709 GtkTreeModel
*model
;
1712 selection
= gtk_tree_view_get_selection
1713 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1715 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1718 gtk_tree_model_get(model
, &row
,
1719 PREFS_MATCHER_COND_VALID
, &is_valid
,
1725 gtk_list_store_remove(GTK_LIST_STORE(model
), &row
);
1727 prefs_matcher_reset_condition();
1731 *\brief Signal handler for 'move up' button
1733 static void prefs_matcher_up(void)
1735 GtkTreePath
*prev
, *sel
, *try;
1737 GtkListStore
*store
= NULL
;
1738 GtkTreeModel
*model
= NULL
;
1741 if (!gtk_tree_selection_get_selected
1742 (gtk_tree_view_get_selection
1743 (GTK_TREE_VIEW(matcher
.cond_list_view
)),
1747 store
= (GtkListStore
*)model
;
1748 sel
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &isel
);
1752 /* no move if we're at row 0 or 1, looks phony, but other
1753 * solutions are more convoluted... */
1754 try = gtk_tree_path_copy(sel
);
1755 if (!gtk_tree_path_prev(try) || !gtk_tree_path_prev(try)) {
1756 gtk_tree_path_free(try);
1757 gtk_tree_path_free(sel
);
1760 gtk_tree_path_free(try);
1762 prev
= gtk_tree_path_copy(sel
);
1763 if (gtk_tree_path_prev(prev
)) {
1764 gtk_tree_model_get_iter(GTK_TREE_MODEL(store
),
1766 gtk_list_store_swap(store
, &iprev
, &isel
);
1767 /* XXX: GTK2 select row?? */
1770 gtk_tree_path_free(sel
);
1771 gtk_tree_path_free(prev
);
1775 *\brief Signal handler for 'move down' button
1777 static void prefs_matcher_down(void)
1779 GtkListStore
*store
= NULL
;
1780 GtkTreeModel
*model
= NULL
;
1781 GtkTreeIter next
, sel
;
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 try = gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &sel
);
1795 /* move when not at row 0 ... */
1796 if (gtk_tree_path_prev(try)) {
1798 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store
), &next
))
1799 gtk_list_store_swap(store
, &next
, &sel
);
1802 gtk_tree_path_free(try);
1805 static void prefs_matcher_enable_widget(GtkWidget
* widget
, const gboolean enable
)
1807 cm_return_if_fail(widget
!= NULL
);
1809 if(enable
== TRUE
) {
1810 gtk_widget_set_sensitive(widget
, TRUE
);
1811 gtk_widget_show(widget
);
1813 gtk_widget_set_sensitive(widget
, FALSE
);
1814 gtk_widget_hide(widget
);
1818 static void prefs_matcher_set_model(GtkWidget
*widget
, GtkTreeModel
*model
)
1820 cm_return_if_fail(widget
!= NULL
);
1821 cm_return_if_fail(model
!= NULL
);
1823 gtk_combo_box_set_model(GTK_COMBO_BOX(widget
), model
);
1824 gtk_combo_box_set_active(GTK_COMBO_BOX(widget
), 0);
1827 static void prefs_matcher_second_criteria_sel(GtkWidget
*widget
,
1830 gint criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1831 matcher
.criteria_combo
));
1832 gint criteria2
= combobox_get_active_data(GTK_COMBO_BOX(
1833 matcher
.criteria_combo2
));
1835 if(criteria
!= MATCH_PHRASE
&& criteria
!= MATCH_TAGS
) return;
1837 if(criteria
== MATCH_PHRASE
) {
1839 case CRITERIA_HEADERS_PART
:
1840 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1843 case CRITERIA_HEADERS_CONT
:
1844 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1845 _("Headers values"));
1847 case CRITERIA_BODY_PART
:
1848 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1851 case CRITERIA_MESSAGE
:
1852 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1853 _("Whole message"));
1858 if(criteria
== MATCH_TAGS
) {
1859 if(criteria2
== CRITERIA_TAGGED
) {
1860 prefs_matcher_enable_widget(matcher
.upper_filler
, FALSE
);
1861 prefs_matcher_enable_widget(matcher
.match_label2
, TRUE
);
1862 prefs_matcher_enable_widget(matcher
.string_entry
, FALSE
);
1863 prefs_matcher_enable_widget(matcher
.case_checkbtn
, FALSE
);
1864 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, FALSE
);
1866 prefs_matcher_enable_widget(matcher
.upper_filler
, TRUE
);
1867 prefs_matcher_enable_widget(matcher
.match_label2
, FALSE
);
1868 prefs_matcher_enable_widget(matcher
.string_entry
, TRUE
);
1869 prefs_matcher_enable_widget(matcher
.case_checkbtn
, TRUE
);
1870 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, TRUE
);
1871 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1872 matcher
.regexp_checkbtn
), FALSE
);
1873 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1874 matcher
.case_checkbtn
), FALSE
);
1879 #define MATCH_COMBO_IS_ENABLED(x) (x != MATCH_ALL && x != MATCH_ABOOK && \
1880 x != MATCH_PARTIAL && x != MATCH_THREAD && x != MATCH_LABEL) ? TRUE : FALSE
1881 #define MATCH_CASE_REGEXP(x) (x == MATCH_HEADER || x == MATCH_PHRASE) ? TRUE : FALSE
1882 #define MATCH_NUMERIC(x) (x == MATCH_AGE || x == MATCH_SCORE || \
1883 x == MATCH_SIZE) ? TRUE : FALSE
1886 *\brief Change widgets depending on the selected condition
1888 *\param criteria combo widget
1889 *\param user_data Not used
1891 static void prefs_matcher_criteria_select(GtkWidget
*widget
,
1894 gint value
, old_value
;
1896 old_value
= matcher
.selected_criteria
;
1897 matcher
.selected_criteria
= value
= gtk_combo_box_get_active
1898 (GTK_COMBO_BOX(matcher
.criteria_combo
));
1900 if (old_value
== matcher
.selected_criteria
)
1903 prefs_matcher_enable_widget(matcher
.criteria_label2
,
1904 (value
== MATCH_ABOOK
||
1905 value
== MATCH_PHRASE
||
1906 value
== MATCH_HEADER
||
1907 value
== MATCH_PARTIAL
||
1908 value
== MATCH_TAGS
||
1909 value
== MATCH_THREAD
));
1910 prefs_matcher_enable_widget(matcher
.headers_combo
,
1911 (value
== MATCH_HEADER
));
1912 prefs_matcher_enable_widget(matcher
.criteria_combo2
,
1913 (value
== MATCH_PHRASE
||
1914 value
== MATCH_PARTIAL
||
1915 value
== MATCH_TAGS
||
1916 value
== MATCH_THREAD
));
1917 prefs_matcher_enable_widget(matcher
.match_combo2
,
1918 (value
== MATCH_ABOOK
||
1919 value
== MATCH_AGE
||
1920 value
== MATCH_FLAG
||
1921 value
== MATCH_LABEL
||
1922 value
== MATCH_SIZE
));
1923 prefs_matcher_enable_widget(matcher
.match_label2
,
1924 (value
== MATCH_ABOOK
||
1925 value
== MATCH_FLAG
||
1926 value
== MATCH_LABEL
||
1927 value
== MATCH_TAGS
));
1928 prefs_matcher_enable_widget(matcher
.header_addr_combo
,
1929 (value
== MATCH_ABOOK
));
1930 prefs_matcher_enable_widget(matcher
.string_entry
,
1931 (MATCH_CASE_REGEXP(value
) ||
1932 value
== MATCH_TEST
));
1933 prefs_matcher_enable_widget(matcher
.numeric_entry
,
1934 MATCH_NUMERIC(value
));
1935 prefs_matcher_enable_widget(matcher
.numeric_label
,
1936 (value
== MATCH_SCORE
));
1937 prefs_matcher_enable_widget(matcher
.addressbook_folder_combo
,
1938 (value
== MATCH_ABOOK
));
1939 prefs_matcher_enable_widget(matcher
.match_combo
,
1940 MATCH_COMBO_IS_ENABLED(value
));
1941 prefs_matcher_enable_widget(matcher
.case_checkbtn
,
1942 MATCH_CASE_REGEXP(value
));
1943 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
,
1944 MATCH_CASE_REGEXP(value
));
1945 prefs_matcher_enable_widget(matcher
.test_btn
,
1946 (value
== MATCH_TEST
));
1947 prefs_matcher_enable_widget(matcher
.addressbook_select_btn
,
1948 (value
== MATCH_ABOOK
));
1949 #if !GTK_CHECK_VERSION(3, 0, 0)
1950 prefs_matcher_enable_widget(matcher
.color_optmenu
,
1951 (value
== MATCH_LABEL
));
1953 prefs_matcher_enable_widget(matcher
.upper_filler
,
1954 MATCH_CASE_REGEXP(value
));
1955 prefs_matcher_enable_widget(matcher
.lower_filler
,
1956 (value
== MATCH_ABOOK
));
1958 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), "");
1959 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
1963 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.header_addr_combo
), 0);
1964 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.addressbook_folder_combo
), 0);
1965 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_found
);
1966 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
1967 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
1968 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("content is"));
1971 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_age
);
1972 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_age_units
);
1973 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
1974 matcher
.numeric_entry
), 0, 10000);
1975 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
1976 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), AGE_DAYS
);
1977 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Age is"));
1980 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_flags
);
1981 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
1982 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Flag"));
1983 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
1986 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.headers_combo
), 0);
1987 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
1988 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Name:"));
1989 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
1990 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
1991 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
1993 #if !GTK_CHECK_VERSION(3, 0, 0)
1995 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
), 0);
1996 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
1997 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Label"));
1998 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
2002 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_partial
);
2003 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Value:"));
2006 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_phrase
);
2007 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2008 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
2009 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2010 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2011 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2014 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_score
);
2015 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2016 matcher
.numeric_entry
), -1000, 1000);
2017 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2018 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Score is"));
2019 gtk_label_set_text(GTK_LABEL(matcher
.numeric_label
), _("points"));
2022 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_size
);
2023 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_size_units
);
2024 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2026 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2027 matcher
.numeric_entry
), 0, 100000);
2028 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2029 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Size is"));
2032 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_tags
);
2033 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2034 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Scope:"));
2035 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Message"));
2036 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("tags"));
2037 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2040 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_thread
);
2041 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("type is"));
2044 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_test
);
2045 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Program returns"));
2051 *\brief Handle key press
2053 *\param widget Widget receiving key press
2054 *\param event Key event
2055 *\param data User data
2057 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
2060 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
2061 prefs_matcher_cancel();
2068 *\brief Cancel matcher dialog
2070 static void prefs_matcher_cancel(void)
2072 gtk_widget_hide(matcher
.window
);
2073 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2078 *\brief Accept current matchers
2080 static void prefs_matcher_ok(void)
2082 MatcherList
*matchers
;
2083 MatcherProp
*matcherprop
;
2085 gchar
*matcher_str
= NULL
;
2088 GtkTreeModel
*model
;
2091 matchers
= prefs_matcher_get_list();
2093 if (matchers
!= NULL
) {
2094 matcherprop
= prefs_matcher_dialog_to_matcher();
2095 if (matcherprop
!= NULL
) {
2096 str
= matcherprop_to_string(matcherprop
);
2097 matcherprop_free(matcherprop
);
2098 if (strcmp(str
, "all") != 0) {
2099 model
= gtk_tree_view_get_model(GTK_TREE_VIEW
2100 (matcher
.cond_list_view
));
2102 while (gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
)) {
2103 gtk_tree_model_get(model
, &iter
,
2104 PREFS_MATCHER_COND
, &matcher_str
,
2106 if (matcher_str
&& strcmp(matcher_str
, str
) == 0)
2109 g_free(matcher_str
);
2113 if (!matcher_str
|| strcmp(matcher_str
, str
) != 0) {
2114 val
= alertpanel(_("Entry not saved"),
2115 _("The entry was not saved.\nClose anyway?"),
2117 g_strconcat("+", _("_Continue editing"), NULL
),
2119 if (G_ALERTDEFAULT
!= val
) {
2120 g_free(matcher_str
);
2125 g_free(matcher_str
);
2129 gtk_widget_hide(matcher
.window
);
2130 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2131 if (matchers_callback
!= NULL
)
2132 matchers_callback(matchers
);
2133 matcherlist_free(matchers
);
2139 *\brief Called when closing dialog box
2141 *\param widget Dialog widget
2142 *\param event Event info
2143 *\param data User data
2147 static gint
prefs_matcher_deleted(GtkWidget
*widget
, GdkEventAny
*event
,
2150 prefs_matcher_cancel();
2155 * Strings describing test format strings
2157 * When adding new lines, remember to put 2 strings for each line
2159 static gchar
*test_desc_strings
[] = {
2160 "%%", N_("literal %"),
2161 "%s", N_("Subject"),
2166 "%i", N_("Message-ID"),
2167 "%n", N_("Newsgroups"),
2168 "%r", N_("References"),
2169 "%F", N_("filename (should not be modified)"),
2170 "\\n", N_("new line"),
2171 "\\", N_("escape character for quotes"),
2172 "\\\"", N_("quote character"),
2176 static DescriptionWindow test_desc_win
= {
2181 N_("Match Type: 'Test'"),
2182 N_("'Test' allows you to test a message or message element "
2183 "using an external program or script. The program will "
2184 "return either 0 or 1.\n\n"
2185 "The following symbols can be used:"),
2192 *\brief Show Test action's info
2194 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
)
2196 test_desc_win
.parent
= parent
;
2197 description_window_create(&test_desc_win
);
2200 #ifndef USE_ALT_ADDRBOOK
2201 static void prefs_matcher_addressbook_select(void)
2203 const gchar
*folderpath
= NULL
;
2204 gchar
*new_path
= NULL
;
2206 folderpath
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
2207 new_path
= addressbook_folder_selection(folderpath
);
2209 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), new_path
);
2219 static GtkListStore
* prefs_matcher_create_data_store(void)
2221 return gtk_list_store_new(N_PREFS_MATCHER_COLUMNS
,
2227 static void prefs_matcher_list_view_insert_matcher(GtkWidget
*list_view
,
2228 GtkTreeIter
*row_iter
,
2229 const gchar
*matcher
,
2233 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
2234 (GTK_TREE_VIEW(list_view
)));
2236 if (row_iter
== NULL
) {
2238 gtk_list_store_append(list_store
, &iter
);
2240 /* change existing */
2244 gtk_list_store_set(list_store
, &iter
,
2245 PREFS_MATCHER_COND
, matcher
,
2246 PREFS_MATCHER_COND_VALID
, is_valid
,
2250 static GtkWidget
*prefs_matcher_list_view_create(void)
2252 GtkTreeView
*list_view
;
2253 GtkTreeSelection
*selector
;
2254 GtkTreeModel
*model
;
2256 model
= GTK_TREE_MODEL(prefs_matcher_create_data_store());
2257 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
2258 g_object_unref(model
);
2260 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
2261 gtk_tree_view_set_reorderable(list_view
, TRUE
);
2263 selector
= gtk_tree_view_get_selection(list_view
);
2264 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
2265 gtk_tree_selection_set_select_function(selector
, prefs_matcher_selected
,
2268 /* create the columns */
2269 prefs_matcher_create_list_view_columns(GTK_WIDGET(list_view
));
2271 return GTK_WIDGET(list_view
);
2274 static void prefs_matcher_create_list_view_columns(GtkWidget
*list_view
)
2276 GtkTreeViewColumn
*column
;
2277 GtkCellRenderer
*renderer
;
2279 renderer
= gtk_cell_renderer_text_new();
2280 column
= gtk_tree_view_column_new_with_attributes
2281 (_("Current condition rules"),
2283 "text", PREFS_MATCHER_COND
,
2285 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
2288 static void prefs_matcher_set_criteria(const gint criteria
)
2290 gint match_criteria
= 0;
2293 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2294 match_criteria
= MATCH_ABOOK
;
2297 match_criteria
= MATCH_ALL
;
2299 case CRITERIA_AGE_GREATER
:
2300 case CRITERIA_AGE_LOWER
:
2301 case CRITERIA_AGE_GREATER_HOURS
:
2302 case CRITERIA_AGE_LOWER_HOURS
:
2303 match_criteria
= MATCH_AGE
;
2305 case CRITERIA_SCORE_GREATER
:
2306 case CRITERIA_SCORE_LOWER
:
2307 case CRITERIA_SCORE_EQUAL
:
2308 match_criteria
= MATCH_SCORE
;
2310 case CRITERIA_SIZE_GREATER
:
2311 case CRITERIA_SIZE_SMALLER
:
2312 case CRITERIA_SIZE_EQUAL
:
2313 match_criteria
= MATCH_SIZE
;
2315 case CRITERIA_SUBJECT
:
2319 case CRITERIA_TO_OR_CC
:
2320 case CRITERIA_NEWSGROUPS
:
2321 case CRITERIA_MESSAGEID
:
2322 case CRITERIA_INREPLYTO
:
2323 case CRITERIA_REFERENCES
:
2324 case CRITERIA_HEADER
:
2325 match_criteria
= MATCH_HEADER
;
2327 case CRITERIA_HEADERS_PART
:
2328 case CRITERIA_HEADERS_CONT
:
2329 case CRITERIA_BODY_PART
:
2330 case CRITERIA_MESSAGE
:
2331 match_criteria
= MATCH_PHRASE
;
2334 match_criteria
= MATCH_TEST
;
2336 #if !GTK_CHECK_VERSION(3, 0, 0)
2337 case CRITERIA_COLORLABEL
:
2338 match_criteria
= MATCH_LABEL
;
2342 case CRITERIA_TAGGED
:
2343 match_criteria
= MATCH_TAGS
;
2345 case CRITERIA_UNREAD
:
2347 case CRITERIA_MARKED
:
2348 case CRITERIA_DELETED
:
2349 case CRITERIA_REPLIED
:
2350 case CRITERIA_FORWARDED
:
2351 case CRITERIA_LOCKED
:
2353 case CRITERIA_HAS_ATTACHMENT
:
2354 case CRITERIA_SIGNED
:
2355 match_criteria
= MATCH_FLAG
;
2357 case CRITERIA_PARTIAL
:
2358 match_criteria
= MATCH_PARTIAL
;
2360 case CRITERIA_IGNORE_THREAD
:
2361 case CRITERIA_WATCH_THREAD
:
2362 match_criteria
= MATCH_THREAD
;
2366 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
),
2369 switch(match_criteria
) {
2371 if(criteria
!= CRITERIA_HEADER
)
2372 combobox_select_by_data(GTK_COMBO_BOX(
2373 matcher
.headers_combo
),
2380 combobox_select_by_data(GTK_COMBO_BOX(
2381 matcher
.match_combo
), criteria
);
2385 combobox_select_by_data(GTK_COMBO_BOX(
2386 matcher
.criteria_combo2
), criteria
);
2391 static gboolean
prefs_matcher_selected(GtkTreeSelection
*selector
,
2392 GtkTreeModel
*model
,
2394 gboolean currently_selected
,
2399 gboolean negative_cond
;
2405 if (currently_selected
)
2408 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
2411 gtk_tree_model_get(model
, &iter
,
2412 PREFS_MATCHER_COND_VALID
, &is_valid
,
2413 PREFS_MATCHER_COND
, &matcher_str
,
2417 g_free(matcher_str
);
2418 prefs_matcher_reset_condition();
2422 negative_cond
= FALSE
;
2424 prop
= matcher_parser_get_prop(matcher_str
);
2426 g_free(matcher_str
);
2430 criteria
= prefs_matcher_get_criteria_from_matching(prop
->criteria
);
2431 prefs_matcher_set_criteria(criteria
);
2433 switch(prop
->criteria
) {
2434 case MATCHCRITERIA_NOT_UNREAD
:
2435 case MATCHCRITERIA_NOT_NEW
:
2436 case MATCHCRITERIA_NOT_MARKED
:
2437 case MATCHCRITERIA_NOT_DELETED
:
2438 case MATCHCRITERIA_NOT_REPLIED
:
2439 case MATCHCRITERIA_NOT_FORWARDED
:
2440 case MATCHCRITERIA_NOT_LOCKED
:
2441 case MATCHCRITERIA_NOT_SPAM
:
2442 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
2443 case MATCHCRITERIA_NOT_SIGNED
:
2444 case MATCHCRITERIA_NOT_PARTIAL
:
2445 case MATCHCRITERIA_NOT_COLORLABEL
:
2446 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
2447 case MATCHCRITERIA_NOT_WATCH_THREAD
:
2448 case MATCHCRITERIA_NOT_SUBJECT
:
2449 case MATCHCRITERIA_NOT_FROM
:
2450 case MATCHCRITERIA_NOT_TO
:
2451 case MATCHCRITERIA_NOT_CC
:
2452 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2453 case MATCHCRITERIA_NOT_TAG
:
2454 case MATCHCRITERIA_NOT_TAGGED
:
2455 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2456 case MATCHCRITERIA_NOT_MESSAGEID
:
2457 case MATCHCRITERIA_NOT_INREPLYTO
:
2458 case MATCHCRITERIA_NOT_REFERENCES
:
2459 case MATCHCRITERIA_NOT_HEADER
:
2460 case MATCHCRITERIA_NOT_HEADERS_PART
:
2461 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2462 case MATCHCRITERIA_NOT_MESSAGE
:
2463 case MATCHCRITERIA_NOT_BODY_PART
:
2464 case MATCHCRITERIA_NOT_TEST
:
2465 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2466 negative_cond
= TRUE
;
2470 switch(prop
->criteria
) {
2471 case MATCHCRITERIA_ALL
:
2474 case MATCHCRITERIA_NOT_SUBJECT
:
2475 case MATCHCRITERIA_NOT_FROM
:
2476 case MATCHCRITERIA_NOT_TO
:
2477 case MATCHCRITERIA_NOT_CC
:
2478 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2479 case MATCHCRITERIA_NOT_TAG
:
2480 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2481 case MATCHCRITERIA_NOT_MESSAGEID
:
2482 case MATCHCRITERIA_NOT_INREPLYTO
:
2483 case MATCHCRITERIA_NOT_REFERENCES
:
2484 case MATCHCRITERIA_NOT_HEADERS_PART
:
2485 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2486 case MATCHCRITERIA_NOT_BODY_PART
:
2487 case MATCHCRITERIA_NOT_MESSAGE
:
2488 case MATCHCRITERIA_NOT_TEST
:
2489 case MATCHCRITERIA_SUBJECT
:
2490 case MATCHCRITERIA_FROM
:
2491 case MATCHCRITERIA_TO
:
2492 case MATCHCRITERIA_CC
:
2493 case MATCHCRITERIA_TO_OR_CC
:
2494 case MATCHCRITERIA_TAG
:
2495 case MATCHCRITERIA_NEWSGROUPS
:
2496 case MATCHCRITERIA_MESSAGEID
:
2497 case MATCHCRITERIA_INREPLYTO
:
2498 case MATCHCRITERIA_REFERENCES
:
2499 case MATCHCRITERIA_HEADERS_PART
:
2500 case MATCHCRITERIA_HEADERS_CONT
:
2501 case MATCHCRITERIA_BODY_PART
:
2502 case MATCHCRITERIA_MESSAGE
:
2503 case MATCHCRITERIA_TEST
:
2504 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2507 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
2508 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2513 /* matcher expressions contain UNtranslated "Any"/"All",
2514 select the relevant translated combo item */
2515 if (strcasecmp(prop
->header
, "All") == 0)
2516 header
= (gchar
*)C_("Filtering Matcher Menu", "All");
2518 if (strcasecmp(prop
->header
, "Any") == 0)
2521 header
= prop
->header
;
2522 if (strcasecmp(prop
->expr
, "Any") == 0)
2527 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), header
);
2528 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), expr
);
2532 case MATCHCRITERIA_AGE_GREATER
:
2533 case MATCHCRITERIA_AGE_LOWER
:
2534 if(prop
->value
>= 7 && !(prop
->value
% 7)) {
2535 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2537 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2538 matcher
.numeric_entry
), prop
->value
/7);
2540 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2542 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2543 matcher
.numeric_entry
), prop
->value
);
2547 case MATCHCRITERIA_AGE_GREATER_HOURS
:
2548 case MATCHCRITERIA_AGE_LOWER_HOURS
:
2549 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2551 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2552 matcher
.numeric_entry
), prop
->value
);
2555 case MATCHCRITERIA_SCORE_GREATER
:
2556 case MATCHCRITERIA_SCORE_LOWER
:
2557 case MATCHCRITERIA_SCORE_EQUAL
:
2558 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
),
2562 case MATCHCRITERIA_SIZE_GREATER
:
2563 case MATCHCRITERIA_SIZE_SMALLER
:
2564 case MATCHCRITERIA_SIZE_EQUAL
:
2565 if(prop
->value
>= MB_SIZE
&& !(prop
->value
% MB_SIZE
)) {
2566 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2568 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2569 matcher
.numeric_entry
), prop
->value
/MB_SIZE
);
2570 } else if(prop
->value
>= KB_SIZE
&& !(prop
->value
% KB_SIZE
)) {
2571 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2573 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2574 matcher
.numeric_entry
), prop
->value
/KB_SIZE
);
2576 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2578 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2579 matcher
.numeric_entry
), prop
->value
);
2583 #if !GTK_CHECK_VERSION(3, 0, 0)
2584 case MATCHCRITERIA_NOT_COLORLABEL
:
2585 case MATCHCRITERIA_COLORLABEL
:
2586 gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(matcher
.color_optmenu
),
2588 menu
= gtk_cmoption_menu_get_menu(GTK_CMOPTION_MENU(matcher
.color_optmenu
));
2589 g_signal_emit_by_name(G_OBJECT(menu
), "selection-done", menu
);
2593 case MATCHCRITERIA_NOT_HEADER
:
2594 case MATCHCRITERIA_HEADER
:
2595 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), prop
->header
);
2596 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2601 case CRITERIA_SUBJECT
:
2605 case CRITERIA_TO_OR_CC
:
2606 case CRITERIA_NEWSGROUPS
:
2607 case CRITERIA_MESSAGEID
:
2608 case CRITERIA_INREPLYTO
:
2609 case CRITERIA_REFERENCES
:
2610 case CRITERIA_HEADER
:
2611 case CRITERIA_HEADERS_PART
:
2612 case CRITERIA_HEADERS_CONT
:
2613 case CRITERIA_BODY_PART
:
2614 case CRITERIA_MESSAGE
:
2616 case CRITERIA_TAGGED
:
2618 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
),
2619 negative_cond
? PREDICATE_DOES_NOT_CONTAIN
:
2620 PREDICATE_CONTAINS
);
2622 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2623 case CRITERIA_UNREAD
:
2625 case CRITERIA_MARKED
:
2626 case CRITERIA_DELETED
:
2627 case CRITERIA_REPLIED
:
2628 case CRITERIA_FORWARDED
:
2629 case CRITERIA_LOCKED
:
2631 case CRITERIA_HAS_ATTACHMENT
:
2632 case CRITERIA_SIGNED
:
2633 case CRITERIA_COLORLABEL
:
2634 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2635 negative_cond
? PREDICATE_FLAG_DISABLED
:
2636 PREDICATE_FLAG_ENABLED
);
2638 case CRITERIA_WATCH_THREAD
:
2639 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2640 negative_cond
? THREAD_NOT_WATCHED
:
2643 case CRITERIA_IGNORE_THREAD
:
2644 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2645 negative_cond
? THREAD_NOT_IGNORED
:
2648 case CRITERIA_PARTIAL
:
2649 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2650 negative_cond
? PREDICATE_FLAG_DISABLED
:
2651 PREDICATE_FLAG_ENABLED
);
2655 switch(prop
->matchtype
) {
2656 case MATCHTYPE_MATCH
:
2657 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2658 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2661 case MATCHTYPE_MATCHCASE
:
2662 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2663 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2666 case MATCHTYPE_REGEXP
:
2667 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2668 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2671 case MATCHTYPE_REGEXPCASE
:
2672 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2673 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2677 g_free(matcher_str
);