2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2022 the Claws Mail team and Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 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>
36 #include "prefs_gtk.h"
37 #include "prefs_matcher.h"
38 #include "prefs_common.h"
39 #include "procheader.h"
40 #include "mainwindow.h"
41 #include "foldersel.h"
42 #include "manage_window.h"
47 #include "alertpanel.h"
49 #include "description_window.h"
52 #include "matcher_parser.h"
53 #include "colorlabel.h"
55 #ifndef USE_ALT_ADDRBOOK
56 #include "addressbook.h"
59 #ifndef USE_ALT_ADDRBOOK
60 static void prefs_matcher_addressbook_select(void);
62 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
);
66 PREFS_MATCHER_COND_VALID
,
67 N_PREFS_MATCHER_COLUMNS
71 *\brief UI data for matcher dialog
73 static struct Matcher
{
78 GtkWidget
*match_combo
;
79 GtkWidget
*header_addr_combo
;
80 GtkWidget
*bool_op_combo
;
81 GtkWidget
*criteria_label2
;
82 GtkWidget
*criteria_combo
;
83 GtkWidget
*criteria_combo2
;
84 GtkWidget
*match_combo2
;
85 GtkWidget
*match_label
;
86 GtkWidget
*match_label2
;
87 GtkWidget
*headers_combo
;
88 GtkWidget
*upper_filler
;
89 GtkWidget
*lower_filler
;
91 GtkWidget
*header_entry
;
92 GtkWidget
*header_addr_entry
;
93 GtkWidget
*string_entry
;
94 GtkWidget
*numeric_entry
;
95 GtkWidget
*numeric_label
;
96 GtkWidget
*addressbook_folder_combo
;
97 GtkWidget
*case_checkbtn
;
98 GtkWidget
*regexp_checkbtn
;
99 GtkWidget
*color_optmenu
;
101 GtkWidget
*time_label
;
102 GtkWidget
*time_entry
;
105 GtkWidget
*addressbook_select_btn
;
107 GtkTreeModel
*model_age
;
108 GtkTreeModel
*model_date
;
109 GtkTreeModel
*model_age_units
;
110 GtkTreeModel
*model_contain
;
111 GtkTreeModel
*model_found
;
112 GtkTreeModel
*model_flags
;
113 GtkTreeModel
*model_headers
;
114 GtkTreeModel
*model_partial
;
115 GtkTreeModel
*model_phrase
;
116 GtkTreeModel
*model_score
;
117 GtkTreeModel
*model_set
;
118 GtkTreeModel
*model_size
;
119 GtkTreeModel
*model_size_units
;
120 GtkTreeModel
*model_tags
;
121 GtkTreeModel
*model_test
;
122 GtkTreeModel
*model_thread
;
124 GtkWidget
*cond_list_view
;
126 gint selected_criteria
; /*!< selected criteria in combobox */
130 *\brief Conditions with a negate counterpart (like unread and ~unread)
131 * have the same CRITERIA_XXX id). I.e. both unread and ~unread
132 * have criteria id CRITERIA_UNREAD. This id is passed as the
133 * first parameter to #matcherprop_new and #matcherprop_unquote_new.
138 CRITERIA_SUBJECT
= 1,
142 CRITERIA_TO_OR_CC
= 5,
143 CRITERIA_NEWSGROUPS
= 6,
144 CRITERIA_INREPLYTO
= 7,
145 CRITERIA_REFERENCES
= 8,
146 CRITERIA_AGE_GREATER
= 9,
147 CRITERIA_AGE_LOWER
= 10,
148 CRITERIA_HEADER
= 11,
149 CRITERIA_HEADERS_PART
= 12,
150 CRITERIA_BODY_PART
= 13,
151 CRITERIA_MESSAGE
= 14,
153 CRITERIA_UNREAD
= 15,
155 CRITERIA_MARKED
= 17,
156 CRITERIA_DELETED
= 18,
157 CRITERIA_REPLIED
= 19,
158 CRITERIA_FORWARDED
= 20,
159 CRITERIA_LOCKED
= 21,
161 CRITERIA_COLORLABEL
= 23,
162 CRITERIA_IGNORE_THREAD
= 24,
163 CRITERIA_WATCH_THREAD
= 25,
165 CRITERIA_SCORE_GREATER
= 26,
166 CRITERIA_SCORE_LOWER
= 27,
167 CRITERIA_SCORE_EQUAL
= 28,
171 CRITERIA_SIZE_GREATER
= 30,
172 CRITERIA_SIZE_SMALLER
= 31,
173 CRITERIA_SIZE_EQUAL
= 32,
175 CRITERIA_PARTIAL
= 33,
177 CRITERIA_FOUND_IN_ADDRESSBOOK
= 34,
180 CRITERIA_TAGGED
= 36,
182 CRITERIA_HAS_ATTACHMENT
= 37,
183 CRITERIA_SIGNED
= 38,
185 CRITERIA_AGE_GREATER_HOURS
= 39,
186 CRITERIA_AGE_LOWER_HOURS
= 40,
188 CRITERIA_MESSAGEID
= 41,
189 CRITERIA_HEADERS_CONT
= 42,
191 CRITERIA_DATE_AFTER
= 43,
192 CRITERIA_DATE_BEFORE
= 44
220 SIZE_UNIT_KBYTES
= 1,
224 #define MB_SIZE 0x100000
225 #define KB_SIZE 0x000400
229 THREAD_NOT_IGNORED
= 1,
231 THREAD_NOT_WATCHED
= 3
235 *\brief Contains predicate
238 PREDICATE_CONTAINS
= 0,
239 PREDICATE_DOES_NOT_CONTAIN
= 1
243 *\brief Enabled predicate
246 PREDICATE_FLAG_ENABLED
= 0,
247 PREDICATE_FLAG_DISABLED
= 1
253 static PrefsMatcherSignal
*matchers_callback
;
255 /* widget creating functions */
256 static void prefs_matcher_create (void);
258 static void prefs_matcher_set_dialog (MatcherList
*matchers
);
259 static void prefs_matcher_list_view_set_row (GtkTreeIter
*row
,
262 /* callback functions */
264 static void prefs_matcher_register_cb (void);
265 static void prefs_matcher_substitute_cb (void);
266 static void prefs_matcher_delete_cb (void);
267 static void prefs_matcher_up (void);
268 static void prefs_matcher_down (void);
269 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
,
272 static void prefs_matcher_ok (void);
273 static void prefs_matcher_cancel (void);
274 static gint
prefs_matcher_deleted (GtkWidget
*widget
, GdkEventAny
*event
,
276 static void prefs_matcher_criteria_select (GtkWidget
*widget
,
278 static void prefs_matcher_second_criteria_sel (GtkWidget
*widget
,
280 static void prefs_matcher_set_model (GtkWidget
*wiget
,
281 GtkTreeModel
*model
);
282 static MatcherList
*prefs_matcher_get_list (void);
284 static GtkListStore
* prefs_matcher_create_data_store (void);
286 static void prefs_matcher_list_view_insert_matcher (GtkWidget
*list_view
,
287 GtkTreeIter
*row_iter
,
288 const gchar
*matcher
,
291 static GtkWidget
*prefs_matcher_list_view_create (void);
293 static void prefs_matcher_create_list_view_columns (GtkWidget
*list_view
);
295 static gboolean
prefs_matcher_selected (GtkTreeSelection
*selector
,
298 gboolean currently_selected
,
301 static int header_name_to_crit(const gchar
*header
)
304 return CRITERIA_HEADER
;
306 if (!strcasecmp(header
, "Subject"))
307 return CRITERIA_SUBJECT
;
308 if (!strcasecmp(header
, "From"))
309 return CRITERIA_FROM
;
310 if (!strcasecmp(header
, "To"))
312 if (!strcasecmp(header
, "Cc"))
314 if (!strcasecmp(header
, "To or Cc"))
315 return CRITERIA_TO_OR_CC
;
316 if (!strcasecmp(header
, "Message-ID"))
317 return CRITERIA_MESSAGEID
;
318 if (!strcasecmp(header
, "In-Reply-To"))
319 return CRITERIA_INREPLYTO
;
320 if (!strcasecmp(header
, "Newsgroups"))
321 return CRITERIA_NEWSGROUPS
;
322 if (!strcasecmp(header
, "References"))
323 return CRITERIA_REFERENCES
;
325 return CRITERIA_HEADER
;
328 static void prefs_matcher_models_create(void)
333 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
334 COMBOBOX_ADD(store
, _("more than"), CRITERIA_AGE_GREATER
);
335 COMBOBOX_ADD(store
, _("less than"), CRITERIA_AGE_LOWER
);
336 matcher
.model_age
= GTK_TREE_MODEL(store
);
338 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
339 COMBOBOX_ADD(store
, _("hours"), AGE_HOURS
);
340 COMBOBOX_ADD(store
, _("days"), AGE_DAYS
);
341 COMBOBOX_ADD(store
, _("weeks"), AGE_WEEKS
);
342 matcher
.model_age_units
= GTK_TREE_MODEL(store
);
344 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
345 COMBOBOX_ADD(store
, _("after"), CRITERIA_DATE_AFTER
);
346 COMBOBOX_ADD(store
, _("before"), CRITERIA_DATE_BEFORE
);
347 matcher
.model_date
= GTK_TREE_MODEL(store
);
349 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
350 COMBOBOX_ADD(store
, _("higher than"), CRITERIA_SCORE_GREATER
);
351 COMBOBOX_ADD(store
, _("lower than"), CRITERIA_SCORE_LOWER
);
352 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SCORE_EQUAL
);
353 matcher
.model_score
= GTK_TREE_MODEL(store
);
355 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
356 COMBOBOX_ADD(store
, _("greater than"), CRITERIA_SIZE_GREATER
);
357 COMBOBOX_ADD(store
, _("smaller than"), CRITERIA_SIZE_SMALLER
);
358 COMBOBOX_ADD(store
, _("exactly"), CRITERIA_SIZE_EQUAL
);
359 matcher
.model_size
= GTK_TREE_MODEL(store
);
361 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
362 COMBOBOX_ADD(store
, _("bytes"), SIZE_UNIT_BYTES
);
363 COMBOBOX_ADD(store
, _("kibibytes"), SIZE_UNIT_KBYTES
);
364 COMBOBOX_ADD(store
, _("mebibytes"), SIZE_UNIT_MBYTES
);
365 matcher
.model_size_units
= GTK_TREE_MODEL(store
);
367 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
368 COMBOBOX_ADD(store
, _("contains"), 0);
369 COMBOBOX_ADD(store
, _("doesn't contain"), 0);
370 matcher
.model_contain
= GTK_TREE_MODEL(store
);
372 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
373 COMBOBOX_ADD(store
, "Subject", CRITERIA_SUBJECT
);
374 COMBOBOX_ADD(store
, "From", CRITERIA_FROM
);
375 COMBOBOX_ADD(store
, "To", CRITERIA_TO
);
376 COMBOBOX_ADD(store
, "Cc", CRITERIA_CC
);
377 COMBOBOX_ADD(store
, "To or Cc", CRITERIA_TO_OR_CC
);
378 COMBOBOX_ADD(store
, "Message-ID", CRITERIA_MESSAGEID
);
379 COMBOBOX_ADD(store
, "In-Reply-To", CRITERIA_INREPLYTO
);
380 COMBOBOX_ADD(store
, "Newsgroups", CRITERIA_NEWSGROUPS
);
381 COMBOBOX_ADD(store
, "References", CRITERIA_REFERENCES
);
382 COMBOBOX_ADD(store
, "Sender", CRITERIA_HEADER
);
383 COMBOBOX_ADD(store
, "X-ML-Name", CRITERIA_HEADER
);
384 COMBOBOX_ADD(store
, "X-List", CRITERIA_HEADER
);
385 COMBOBOX_ADD(store
, "X-Sequence", CRITERIA_HEADER
);
386 COMBOBOX_ADD(store
, "X-Mailer", CRITERIA_HEADER
);
387 COMBOBOX_ADD(store
, "X-BeenThere", CRITERIA_HEADER
);
388 COMBOBOX_ADD(store
, "List-Post", CRITERIA_HEADER
);
389 COMBOBOX_ADD(store
, "List-Id", CRITERIA_HEADER
);
390 matcher
.model_headers
= GTK_TREE_MODEL(store
);
392 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
393 COMBOBOX_ADD(store
, _("headers part"), CRITERIA_HEADERS_PART
);
394 COMBOBOX_ADD(store
, _("headers values"), CRITERIA_HEADERS_CONT
);
395 COMBOBOX_ADD(store
, _("body part"), CRITERIA_BODY_PART
);
396 COMBOBOX_ADD(store
, _("whole message"), CRITERIA_MESSAGE
);
397 matcher
.model_phrase
= GTK_TREE_MODEL(store
);
399 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
400 COMBOBOX_ADD(store
, _("Unread"), CRITERIA_UNREAD
);
401 COMBOBOX_ADD(store
, _("New"), CRITERIA_NEW
);
402 COMBOBOX_ADD(store
, _("Marked"), CRITERIA_MARKED
);
403 COMBOBOX_ADD(store
, _("Deleted"), CRITERIA_DELETED
);
404 COMBOBOX_ADD(store
, _("Replied"), CRITERIA_REPLIED
);
405 COMBOBOX_ADD(store
, _("Forwarded"), CRITERIA_FORWARDED
);
406 COMBOBOX_ADD(store
, _("Locked"), CRITERIA_LOCKED
);
407 COMBOBOX_ADD(store
, _("Spam"), CRITERIA_SPAM
);
408 COMBOBOX_ADD(store
, _("Has attachment"), CRITERIA_HAS_ATTACHMENT
);
409 COMBOBOX_ADD(store
, _("Signed"), CRITERIA_SIGNED
);
410 matcher
.model_flags
= GTK_TREE_MODEL(store
);
412 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
413 COMBOBOX_ADD(store
, _("set"), 0);
414 COMBOBOX_ADD(store
, _("not set"), 1);
415 matcher
.model_set
= GTK_TREE_MODEL(store
);
417 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
418 COMBOBOX_ADD(store
, _("yes"), CRITERIA_PARTIAL
);
419 COMBOBOX_ADD(store
, _("no"), CRITERIA_PARTIAL
);
420 matcher
.model_partial
= GTK_TREE_MODEL(store
);
422 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
423 COMBOBOX_ADD(store
, _("Any tags"), CRITERIA_TAGGED
);
424 COMBOBOX_ADD(store
, _("Specific tag"), CRITERIA_TAG
);
425 matcher
.model_tags
= GTK_TREE_MODEL(store
);
427 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
428 COMBOBOX_ADD(store
, _("ignored"), CRITERIA_IGNORE_THREAD
);
429 COMBOBOX_ADD(store
, _("not ignored"), CRITERIA_IGNORE_THREAD
);
430 COMBOBOX_ADD(store
, _("watched"), CRITERIA_WATCH_THREAD
);
431 COMBOBOX_ADD(store
, _("not watched"), CRITERIA_WATCH_THREAD
);
432 matcher
.model_thread
= GTK_TREE_MODEL(store
);
434 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
435 COMBOBOX_ADD(store
, _("found"), 0);
436 COMBOBOX_ADD(store
, _("not found"), 1);
437 matcher
.model_found
= GTK_TREE_MODEL(store
);
439 store
= gtk_list_store_new(3, G_TYPE_STRING
, G_TYPE_INT
, G_TYPE_BOOLEAN
);
440 COMBOBOX_ADD(store
, _("0 (Passed)"), 0);
441 COMBOBOX_ADD(store
, _("non-0 (Failed)"), 1);
442 matcher
.model_test
= GTK_TREE_MODEL(store
);
446 *\brief Opens the matcher dialog with a list of conditions
448 *\param matchers List of conditions
452 void prefs_matcher_open(MatcherList
*matchers
, PrefsMatcherSignal
*cb
)
456 if (!matcher
.window
) {
457 prefs_matcher_models_create();
458 prefs_matcher_create();
460 /* update color label menu */
461 colorlabel_refill_combobox_colormenu(GTK_COMBO_BOX(matcher
.color_optmenu
));
464 manage_window_set_transient(GTK_WINDOW(matcher
.window
));
465 gtk_widget_grab_focus(matcher
.ok_btn
);
467 matchers_callback
= cb
;
469 prefs_matcher_set_dialog(matchers
);
471 gtk_widget_show(matcher
.window
);
472 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), TRUE
);
476 *\brief Save Gtk object size to prefs dataset
478 static void prefs_matcher_size_allocate_cb(GtkWidget
*widget
,
479 GtkAllocation
*allocation
)
481 cm_return_if_fail(allocation
!= NULL
);
483 gtk_window_get_size(GTK_WINDOW(widget
),
484 &prefs_common
.matcherwin_width
, &prefs_common
.matcherwin_height
);
488 *\brief Create the matcher dialog
490 static void prefs_matcher_create(void)
495 GtkWidget
*cancel_btn
;
496 GtkWidget
*confirm_area
;
501 GtkWidget
*upper_hbox
;
502 GtkWidget
*lower_hbox
;
503 GtkWidget
*match_hbox
;
504 GtkWidget
*criteria_combo
;
505 GtkWidget
*criteria_label
;
506 GtkWidget
*match_label
;
507 GtkWidget
*criteria_label2
;
508 GtkWidget
*headers_combo
;
509 GtkWidget
*match_combo2
;
510 GtkWidget
*match_label2
;
513 GtkWidget
*upper_filler
;
514 GtkWidget
*lower_filler
;
516 GtkWidget
*criteria_combo2
;
517 GtkWidget
*header_entry
;
518 GtkWidget
*header_addr_combo
;
519 GtkWidget
*header_addr_entry
;
520 GtkWidget
*string_entry
;
521 GtkWidget
*addressbook_folder_combo
;
522 GtkWidget
*match_combo
;
523 GtkWidget
*bool_op_combo
;
524 GtkWidget
*bool_op_label
;
526 GtkWidget
*numeric_hbox
;
527 GtkWidget
*numeric_entry
;
528 GtkWidget
*numeric_label
;
530 GtkWidget
*regexp_checkbtn
;
531 GtkWidget
*case_checkbtn
;
537 GtkWidget
*subst_btn
;
540 GtkWidget
*cond_hbox
;
541 GtkWidget
*cond_scrolledwin
;
542 GtkWidget
*cond_list_view
;
549 GtkWidget
*addressbook_select_btn
;
550 GtkWidget
*color_optmenu
;
552 GtkWidget
*time_label
;
553 GtkWidget
*time_entry
;
554 GtkWidget
*date_hbox
;
555 GtkWidget
*date_vbox
;
557 static GdkGeometry geometry
;
558 GtkSizeGroup
*size_group
;
562 debug_print("Creating matcher configuration window...\n");
564 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "prefs_matcher");
565 gtk_container_set_border_width(GTK_CONTAINER(window
), 4);
566 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_CENTER
);
567 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
569 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 6);
570 gtk_container_add(GTK_CONTAINER(window
), vbox
);
572 gtkut_stock_button_set_create(&confirm_area
, &cancel_btn
, NULL
, _("_Cancel"),
573 &ok_btn
, NULL
, _("_OK"), NULL
, NULL
, NULL
);
574 gtk_box_pack_end(GTK_BOX(vbox
), confirm_area
, FALSE
, FALSE
, 0);
575 gtk_widget_grab_default(ok_btn
);
577 gtk_window_set_title(GTK_WINDOW(window
),
578 _("Condition configuration"));
579 g_signal_connect(G_OBJECT(window
), "delete_event",
580 G_CALLBACK(prefs_matcher_deleted
), NULL
);
581 g_signal_connect(G_OBJECT(window
), "size_allocate",
582 G_CALLBACK(prefs_matcher_size_allocate_cb
), NULL
);
583 g_signal_connect(G_OBJECT(window
), "key_press_event",
584 G_CALLBACK(prefs_matcher_key_pressed
), NULL
);
585 MANAGE_WINDOW_SIGNALS_CONNECT(window
);
586 g_signal_connect(G_OBJECT(ok_btn
), "clicked",
587 G_CALLBACK(prefs_matcher_ok
), NULL
);
588 g_signal_connect(G_OBJECT(cancel_btn
), "clicked",
589 G_CALLBACK(prefs_matcher_cancel
), NULL
);
591 vbox1
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VSPACING
);
592 gtk_box_pack_start(GTK_BOX(vbox
), vbox1
, TRUE
, TRUE
, 0);
593 gtk_container_set_border_width(GTK_CONTAINER (vbox1
), 2);
595 frame
= gtk_frame_new(_("Rule"));
596 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.01, 0.5);
597 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
599 table
= gtk_grid_new();
600 gtk_container_add(GTK_CONTAINER(frame
), table
);
601 // gtk_widget_set_size_request(frame, -1, -1);
603 upper_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
604 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
605 gtk_box_pack_start(GTK_BOX(hbox
), upper_hbox
, FALSE
, FALSE
, 0);
606 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
607 gtk_grid_attach(GTK_GRID(table
), hbox
, 2, 0, 1, 1);
608 gtk_widget_set_hexpand(hbox
, TRUE
);
609 gtk_widget_set_halign(hbox
, GTK_ALIGN_FILL
);
611 lower_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
612 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
613 gtk_box_pack_start(GTK_BOX(hbox
), lower_hbox
, FALSE
, FALSE
, 0);
614 gtk_box_pack_start(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
615 gtk_grid_attach(GTK_GRID(table
), hbox
, 2, 1, 1, 1);
616 gtk_widget_set_hexpand(hbox
, TRUE
);
617 gtk_widget_set_halign(hbox
, GTK_ALIGN_FILL
);
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_label_set_xalign(GTK_LABEL(criteria_label
), 1.0);
626 gtk_widget_set_size_request(criteria_label
, -1, -1);
627 gtk_grid_attach(GTK_GRID(table
), criteria_label
, 0, 0, 1, 1);
629 criteria_combo
= gtkut_sc_combobox_create(NULL
, FALSE
);
630 store
= GTK_LIST_STORE(gtk_combo_box_get_model(
631 GTK_COMBO_BOX(criteria_combo
)));
632 COMBOBOX_ADD(store
, _("All messages"), MATCH_ALL
);
633 COMBOBOX_ADD(store
, _("Header"), MATCH_HEADER
);
634 COMBOBOX_ADD(store
, _("Age"), MATCH_AGE
);
635 COMBOBOX_ADD(store
, _("Phrase"), MATCH_PHRASE
);
636 COMBOBOX_ADD(store
, _("Flags"), MATCH_FLAG
);
637 COMBOBOX_ADD(store
, _("Color labels"), MATCH_LABEL
);
638 COMBOBOX_ADD(store
, _("Thread"), MATCH_THREAD
);
639 COMBOBOX_ADD(store
, _("Score"), MATCH_SCORE
);
640 COMBOBOX_ADD(store
, _("Size"), MATCH_SIZE
);
641 COMBOBOX_ADD(store
, _("Partially downloaded"), MATCH_PARTIAL
);
642 COMBOBOX_ADD(store
, _("Address book"), MATCH_ABOOK
);
643 COMBOBOX_ADD(store
, _("Tags"), MATCH_TAGS
);
644 COMBOBOX_ADD(store
, _("External program test"), MATCH_TEST
);
645 COMBOBOX_ADD(store
, _("Date"), MATCH_DATE
);
647 gtk_widget_set_size_request(criteria_combo
, 150, -1);
648 gtk_combo_box_set_active(GTK_COMBO_BOX(criteria_combo
), MATCH_ALL
);
649 gtk_grid_attach(GTK_GRID(table
), criteria_combo
, 1, 0, 1, 1);
650 g_signal_connect(G_OBJECT(criteria_combo
), "changed",
651 G_CALLBACK(prefs_matcher_criteria_select
),
654 upper_filler
= gtk_label_new("");
655 gtk_box_pack_start(GTK_BOX(upper_hbox
), upper_filler
, TRUE
, TRUE
, 0);
657 lower_filler
= gtk_label_new("");
658 gtk_box_pack_start(GTK_BOX(lower_hbox
), lower_filler
, TRUE
, TRUE
, 0);
660 criteria_label2
= gtk_label_new("");
661 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_label2
, FALSE
, FALSE
, 0);
663 /* headers combo box entry */
664 headers_combo
= gtk_combo_box_new_with_model_and_entry(matcher
.model_headers
);
665 GtkCellRenderer
*cell
= gtk_cell_renderer_text_new();
666 gtk_cell_renderer_set_alignment(cell
, 0.0, 0.5);
667 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(headers_combo
), cell
, TRUE
);
668 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(headers_combo
), 0);
669 gtk_widget_set_size_request(headers_combo
, 100, -1);
670 gtk_box_pack_start(GTK_BOX(upper_hbox
), headers_combo
, TRUE
, TRUE
, 0);
671 header_entry
= gtk_bin_get_child(GTK_BIN((headers_combo
)));
672 CLAWS_SET_TIP(header_entry
, _("Use selector on the right to pick "
673 "the header name. Type the name of the header if not "
674 "available in the list."));
676 criteria_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
677 prefs_matcher_set_model(criteria_combo2
, matcher
.model_phrase
);
678 gtk_box_pack_start(GTK_BOX(upper_hbox
), criteria_combo2
, TRUE
, TRUE
, 0);
679 g_signal_connect(G_OBJECT(criteria_combo2
), "changed",
680 G_CALLBACK(prefs_matcher_second_criteria_sel
),
683 /* book/folder value */
684 addressbook_folder_combo
= combobox_text_new(TRUE
, _("Any"), NULL
);
685 gtk_widget_set_size_request(addressbook_folder_combo
, 250, -1);
686 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_folder_combo
, TRUE
, TRUE
, 0);
688 addressbook_select_btn
= gtk_button_new_with_label(_("Select..."));
689 gtk_box_pack_start(GTK_BOX(upper_hbox
), addressbook_select_btn
, FALSE
, FALSE
, 0);
690 #ifndef USE_ALT_ADDRBOOK
691 g_signal_connect(G_OBJECT (addressbook_select_btn
), "clicked",
692 G_CALLBACK(prefs_matcher_addressbook_select
),
695 gtk_widget_set_sensitive(GTK_WIDGET(addressbook_select_btn
), FALSE
);
697 match_label
= gtk_label_new("");
698 gtk_label_set_xalign(GTK_LABEL(match_label
), 1.0);
699 gtk_grid_attach(GTK_GRID(table
), match_label
, 0, 1, 1, 1);
701 match_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
702 gtk_grid_attach(GTK_GRID(table
), match_hbox
, 1, 1, 1, 1);
703 gtk_widget_set_hexpand(match_hbox
, TRUE
);
704 gtk_widget_set_halign(match_hbox
, GTK_ALIGN_FILL
);
706 match_combo
= gtkut_sc_combobox_create(NULL
, TRUE
);
707 gtk_box_pack_start(GTK_BOX(match_hbox
), match_combo
, TRUE
, TRUE
, 0);
709 /* color labels combo */
710 color_optmenu
= colorlabel_create_combobox_colormenu();
711 gtk_box_pack_start(GTK_BOX(match_hbox
), color_optmenu
, FALSE
, FALSE
, 0);
713 /* address header name */
714 header_addr_combo
= combobox_text_new(TRUE
,
715 C_("Filtering Matcher Menu", "All"), _("Any"),
716 "From", "To", "Cc", "Reply-To", "Sender", "Resent-From", "Resent-To", NULL
);
717 gtk_box_pack_start(GTK_BOX(match_hbox
), header_addr_combo
, FALSE
, FALSE
, 0);
718 header_addr_entry
= gtk_bin_get_child(GTK_BIN((header_addr_combo
)));
719 gtk_widget_set_size_request(header_addr_combo
, 150, -1);
721 match_label2
= gtk_label_new("");
722 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_label2
, FALSE
, FALSE
, 0);
725 numeric_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
726 gtk_box_pack_start(GTK_BOX(lower_hbox
), numeric_hbox
, FALSE
, FALSE
, 0);
728 numeric_entry
= gtk_spin_button_new_with_range(0, 1000, 1);
729 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(numeric_entry
), 0);
730 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_entry
, FALSE
, FALSE
, 0);
732 numeric_label
= gtk_label_new("");
733 gtk_box_pack_start(GTK_BOX(numeric_hbox
), numeric_label
, FALSE
, FALSE
, 0);
734 gtk_box_pack_end(GTK_BOX(numeric_hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
736 match_combo2
= gtkut_sc_combobox_create(NULL
, TRUE
);
737 gtk_box_pack_start(GTK_BOX(lower_hbox
), match_combo2
, TRUE
, TRUE
, 0);
740 string_entry
= gtk_entry_new();
741 gtk_box_pack_start(GTK_BOX(lower_hbox
), string_entry
, TRUE
, TRUE
, 0);
742 gtk_widget_set_size_request(string_entry
, 300, -1);
744 hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
745 gtk_size_group_add_widget(size_group
, hbox
);
747 vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VSPACING_NARROW
);
748 PACK_CHECK_BUTTON(vbox
, case_checkbtn
, _("Case sensitive"));
749 PACK_CHECK_BUTTON(vbox
, regexp_checkbtn
, _("Use regexp"));
750 gtk_box_pack_start(GTK_BOX(hbox
), vbox
, TRUE
, TRUE
, 0);
752 gtk_box_pack_end(GTK_BOX(hbox
), gtk_label_new(""), TRUE
, TRUE
, 0);
753 gtk_grid_attach(GTK_GRID(table
), hbox
, 2, 2, 1, 1);
754 gtk_widget_set_hexpand(hbox
, TRUE
);
755 gtk_widget_set_halign(hbox
, GTK_ALIGN_FILL
);
758 date_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VSPACING_NARROW
);
759 calendar
= gtk_calendar_new();
760 gtk_box_pack_start(GTK_BOX(hbox
), calendar
, TRUE
, TRUE
, 0);
761 gtk_box_pack_start(GTK_BOX(lower_hbox
), date_vbox
, FALSE
, FALSE
, 0);
763 date_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
764 gtk_box_pack_start(GTK_BOX(date_vbox
), date_hbox
, FALSE
, FALSE
, 0);
766 time_entry
= gtkut_time_select_combo_new();
767 gtk_box_pack_start(GTK_BOX(date_hbox
), time_entry
, FALSE
, FALSE
, 0);
768 time_label
= gtk_label_new(_("on:"));
769 gtk_label_set_xalign(GTK_LABEL(time_label
),0);
770 gtk_label_set_yalign(GTK_LABEL(time_label
),0.5);
771 gtk_box_pack_start(GTK_BOX(date_hbox
), time_label
, FALSE
, FALSE
, 0);
773 /* test info button */
774 test_btn
= gtkut_stock_button("dialog-information", _("_Information"));
775 gtk_box_pack_start(GTK_BOX(lower_hbox
), test_btn
, FALSE
, FALSE
, 0);
776 g_signal_connect(G_OBJECT (test_btn
), "clicked",
777 G_CALLBACK(prefs_matcher_test_info
),
780 /* register / substitute / delete */
781 reg_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
782 gtk_box_pack_start(GTK_BOX(vbox1
), reg_hbox
, FALSE
, FALSE
, 0);
784 arrow
= gtk_image_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_MENU
);
785 gtk_box_pack_start(GTK_BOX(reg_hbox
), arrow
, FALSE
, FALSE
, 0);
786 gtk_widget_set_size_request(arrow
, -1, 16);
788 btn_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
789 gtk_box_pack_start(GTK_BOX(reg_hbox
), btn_hbox
, FALSE
, FALSE
, 0);
791 reg_btn
= gtkut_stock_button("list-add", _("_Add"));
792 gtk_box_pack_start(GTK_BOX(btn_hbox
), reg_btn
, FALSE
, TRUE
, 0);
793 g_signal_connect(G_OBJECT(reg_btn
), "clicked",
794 G_CALLBACK(prefs_matcher_register_cb
), NULL
);
796 subst_btn
= gtkut_get_replace_btn(_("_Replace"));
797 gtk_box_pack_start(GTK_BOX(btn_hbox
), subst_btn
, FALSE
, TRUE
, 0);
798 g_signal_connect(G_OBJECT(subst_btn
), "clicked",
799 G_CALLBACK(prefs_matcher_substitute_cb
),
802 del_btn
= gtkut_stock_button("list-remove", _("_Remove"));
803 gtk_box_pack_start(GTK_BOX(btn_hbox
), del_btn
, FALSE
, TRUE
, 0);
804 g_signal_connect(G_OBJECT(del_btn
), "clicked",
805 G_CALLBACK(prefs_matcher_delete_cb
), NULL
);
807 cond_hbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, VBOX_BORDER
);
808 gtk_box_pack_start(GTK_BOX(vbox1
), cond_hbox
, TRUE
, TRUE
, 0);
810 cond_scrolledwin
= gtk_scrolled_window_new(NULL
, NULL
);
811 gtk_widget_set_size_request(cond_scrolledwin
, -1, 150);
812 gtk_box_pack_start(GTK_BOX(cond_hbox
), cond_scrolledwin
,
814 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
815 GTK_POLICY_AUTOMATIC
,
816 GTK_POLICY_AUTOMATIC
);
818 cond_list_view
= prefs_matcher_list_view_create();
819 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(cond_scrolledwin
),
820 GTK_SHADOW_ETCHED_IN
);
821 gtk_container_add(GTK_CONTAINER(cond_scrolledwin
), cond_list_view
);
823 btn_vbox
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VBOX_BORDER
);
824 gtk_box_pack_start(GTK_BOX(cond_hbox
), btn_vbox
, FALSE
, FALSE
, 0);
826 up_btn
= gtkut_stock_button("go-up", _("_Up"));
827 gtk_box_pack_start(GTK_BOX(btn_vbox
), up_btn
, FALSE
, FALSE
, 0);
828 g_signal_connect(G_OBJECT(up_btn
), "clicked",
829 G_CALLBACK(prefs_matcher_up
), NULL
);
831 down_btn
= gtkut_stock_button("go-down", _("_Down"));
832 gtk_box_pack_start(GTK_BOX(btn_vbox
), down_btn
, FALSE
, FALSE
, 0);
833 g_signal_connect(G_OBJECT(down_btn
), "clicked",
834 G_CALLBACK(prefs_matcher_down
), NULL
);
836 /* boolean operation */
837 GtkWidget
*hbox_bool
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, HSPACING_NARROW
);
838 gtk_box_pack_start(GTK_BOX(vbox1
), hbox_bool
, FALSE
, FALSE
, 0);
840 bool_op_label
= gtk_label_new(_("Message must match"));
841 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_label
,
844 bool_op_combo
= combobox_text_new(FALSE
, _("at least one"),
846 gtk_box_pack_start(GTK_BOX(hbox_bool
), bool_op_combo
,
848 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(_("of above rules")),
850 gtk_box_pack_start(GTK_BOX(hbox_bool
), gtk_label_new(""),
853 if (!geometry
.min_height
) {
854 geometry
.min_width
= 630;
855 geometry
.min_height
= 368;
858 gtk_window_set_geometry_hints(GTK_WINDOW(window
), NULL
, &geometry
,
860 gtk_window_set_default_size(GTK_WINDOW(window
), prefs_common
.matcherwin_width
,
861 prefs_common
.matcherwin_height
);
863 gtk_widget_show_all(window
);
865 matcher
.window
= window
;
867 matcher
.ok_btn
= ok_btn
;
869 matcher
.criteria_combo
= criteria_combo
;
870 matcher
.criteria_combo2
= criteria_combo2
;
871 matcher
.header_entry
= header_entry
;
872 matcher
.header_addr_combo
= header_addr_combo
;
873 matcher
.header_addr_entry
= header_addr_entry
;
874 matcher
.string_entry
= string_entry
;
875 matcher
.numeric_entry
= numeric_entry
;
876 matcher
.numeric_label
= numeric_label
;
877 matcher
.addressbook_folder_combo
= addressbook_folder_combo
;
878 matcher
.match_combo
= match_combo
;
879 matcher
.case_checkbtn
= case_checkbtn
;
880 matcher
.regexp_checkbtn
= regexp_checkbtn
;
881 matcher
.bool_op_combo
= bool_op_combo
;
882 matcher
.test_btn
= test_btn
;
883 matcher
.calendar
= calendar
;
884 matcher
.time_label
= time_label
;
885 matcher
.time_entry
= time_entry
;
886 #ifndef USE_ALT_ADDRBOOK
887 matcher
.addressbook_select_btn
= addressbook_select_btn
;
889 matcher
.color_optmenu
= color_optmenu
;
890 matcher
.match_label
= match_label
;
891 matcher
.criteria_label2
= criteria_label2
;
892 matcher
.headers_combo
= headers_combo
;
893 matcher
.match_combo2
= match_combo2
;
894 matcher
.match_label2
= match_label2
;
895 matcher
.upper_filler
= upper_filler
;
896 matcher
.lower_filler
= lower_filler
;
898 matcher
.cond_list_view
= cond_list_view
;
900 matcher
.selected_criteria
= -1;
901 prefs_matcher_criteria_select(criteria_combo
, NULL
);
905 *\brief Set the contents of a row
907 *\param row Index of row to set
908 *\param prop Condition to set
910 *\return gint Row index \a prop has been added
912 static void prefs_matcher_list_view_set_row(GtkTreeIter
*row
, MatcherProp
*prop
)
917 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
918 NULL
, _("(New)"), FALSE
);
922 matcher_str
= matcherprop_to_string(prop
);
924 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
928 prefs_matcher_list_view_insert_matcher(matcher
.cond_list_view
,
934 static gboolean
match_combo2_model_set(void)
936 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo2
));
937 if (model
== matcher
.model_age_units
||
938 model
== matcher
.model_found
||
939 model
== matcher
.model_partial
||
940 model
== matcher
.model_phrase
||
941 model
== matcher
.model_set
||
942 model
== matcher
.model_size_units
||
943 model
== matcher
.model_tags
||
944 model
== matcher
.model_thread
)
947 debug_print("match_combo2 model unset.\n");
952 static gboolean
match_combo_model_set(void)
954 GtkTreeModel
*model
= gtk_combo_box_get_model(GTK_COMBO_BOX(matcher
.match_combo
));
955 if (model
== matcher
.model_age
||
956 model
== matcher
.model_contain
||
957 model
== matcher
.model_flags
||
958 model
== matcher
.model_score
||
959 model
== matcher
.model_size
||
960 model
== matcher
.model_test
)
963 debug_print("match_combo model unset.\n");
969 *\brief Clears a condition in the list widget
971 static void prefs_matcher_reset_condition(void)
973 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_ALL
);
974 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
), 0);
975 if (match_combo_model_set())
976 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
), 0);
977 if (match_combo2_model_set())
978 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), 0);
979 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.color_optmenu
), 0);
980 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
981 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), "");
982 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), "");
983 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
984 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), "");
985 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
986 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
988 gtk_calendar_select_today(GTK_CALENDAR(matcher
.calendar
));
989 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), 0, 0);
993 *\brief Initializes dialog with a set of conditions
995 *\param matchers List of conditions
997 static void prefs_matcher_set_dialog(MatcherList
*matchers
)
1000 gboolean bool_op
= 1;
1001 GtkListStore
*store
= GTK_LIST_STORE(gtk_tree_view_get_model
1002 (GTK_TREE_VIEW(matcher
.cond_list_view
)));
1004 gtk_list_store_clear(store
);
1006 prefs_matcher_list_view_set_row(NULL
, NULL
);
1007 if (matchers
!= NULL
) {
1008 for (cur
= matchers
->matchers
; cur
!= NULL
;
1009 cur
= g_slist_next(cur
)) {
1011 prop
= (MatcherProp
*) cur
->data
;
1012 prefs_matcher_list_view_set_row(NULL
, prop
);
1015 bool_op
= matchers
->bool_and
;
1018 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.bool_op_combo
), bool_op
);
1020 prefs_matcher_reset_condition();
1022 combobox_set_sensitive(GTK_COMBO_BOX(matcher
.criteria_combo
), MATCH_TAGS
,
1023 (tags_get_size() > 0) ? TRUE
: FALSE
);
1027 *\brief Converts current conditions in list box in
1028 * a matcher list used by the matcher.
1030 *\return MatcherList * List of conditions.
1032 static MatcherList
*prefs_matcher_get_list(void)
1037 GSList
*matcher_list
;
1038 MatcherList
*matchers
;
1039 GtkTreeModel
*model
;
1042 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(matcher
.cond_list_view
));
1043 if (!gtk_tree_model_get_iter_first(model
, &iter
))
1046 matcher_list
= NULL
;
1051 gtk_tree_model_get(model
, &iter
,
1052 PREFS_MATCHER_COND
, &matcher_str
,
1053 PREFS_MATCHER_COND_VALID
, &is_valid
,
1057 /* tmp = matcher_str; */
1058 prop
= matcher_parser_get_prop(matcher_str
);
1060 g_free(matcher_str
);
1064 matcher_list
= g_slist_append(matcher_list
, prop
);
1066 g_free(matcher_str
);
1067 } while (gtk_tree_model_iter_next(model
, &iter
));
1069 bool_and
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.bool_op_combo
));
1071 matchers
= matcherlist_new(matcher_list
, bool_and
);
1077 *\brief Maps a keyword id (see #get_matchparser_tab_id) to a
1078 * criteria type (see first parameter of #matcherprop_new
1079 * or #matcherprop_unquote_new)
1081 *\param matching_id Id returned by the matcher parser.
1083 *\return gint One of the CRITERIA_xxx constants.
1085 static gint
prefs_matcher_get_criteria_from_matching(gint matching_id
)
1087 switch(matching_id
) {
1088 case MATCHCRITERIA_ALL
:
1089 return CRITERIA_ALL
;
1090 case MATCHCRITERIA_NOT_UNREAD
:
1091 case MATCHCRITERIA_UNREAD
:
1092 return CRITERIA_UNREAD
;
1093 case MATCHCRITERIA_NOT_NEW
:
1094 case MATCHCRITERIA_NEW
:
1095 return CRITERIA_NEW
;
1096 case MATCHCRITERIA_NOT_MARKED
:
1097 case MATCHCRITERIA_MARKED
:
1098 return CRITERIA_MARKED
;
1099 case MATCHCRITERIA_NOT_DELETED
:
1100 case MATCHCRITERIA_DELETED
:
1101 return CRITERIA_DELETED
;
1102 case MATCHCRITERIA_NOT_REPLIED
:
1103 case MATCHCRITERIA_REPLIED
:
1104 return CRITERIA_REPLIED
;
1105 case MATCHCRITERIA_NOT_FORWARDED
:
1106 case MATCHCRITERIA_FORWARDED
:
1107 return CRITERIA_FORWARDED
;
1108 case MATCHCRITERIA_LOCKED
:
1109 case MATCHCRITERIA_NOT_LOCKED
:
1110 return CRITERIA_LOCKED
;
1111 case MATCHCRITERIA_NOT_SPAM
:
1112 case MATCHCRITERIA_SPAM
:
1113 return CRITERIA_SPAM
;
1114 case MATCHCRITERIA_HAS_ATTACHMENT
:
1115 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
1116 return CRITERIA_HAS_ATTACHMENT
;
1117 case MATCHCRITERIA_SIGNED
:
1118 case MATCHCRITERIA_NOT_SIGNED
:
1119 return CRITERIA_SIGNED
;
1120 case MATCHCRITERIA_PARTIAL
:
1121 case MATCHCRITERIA_NOT_PARTIAL
:
1122 return CRITERIA_PARTIAL
;
1123 case MATCHCRITERIA_COLORLABEL
:
1124 case MATCHCRITERIA_NOT_COLORLABEL
:
1125 return CRITERIA_COLORLABEL
;
1126 case MATCHCRITERIA_IGNORE_THREAD
:
1127 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
1128 return CRITERIA_IGNORE_THREAD
;
1129 case MATCHCRITERIA_WATCH_THREAD
:
1130 case MATCHCRITERIA_NOT_WATCH_THREAD
:
1131 return CRITERIA_WATCH_THREAD
;
1132 case MATCHCRITERIA_NOT_SUBJECT
:
1133 case MATCHCRITERIA_SUBJECT
:
1134 return CRITERIA_SUBJECT
;
1135 case MATCHCRITERIA_NOT_FROM
:
1136 case MATCHCRITERIA_FROM
:
1137 return CRITERIA_FROM
;
1138 case MATCHCRITERIA_NOT_TO
:
1139 case MATCHCRITERIA_TO
:
1141 case MATCHCRITERIA_NOT_CC
:
1142 case MATCHCRITERIA_CC
:
1144 case MATCHCRITERIA_NOT_NEWSGROUPS
:
1145 case MATCHCRITERIA_NEWSGROUPS
:
1146 return CRITERIA_NEWSGROUPS
;
1147 case MATCHCRITERIA_NOT_MESSAGEID
:
1148 case MATCHCRITERIA_MESSAGEID
:
1149 return CRITERIA_MESSAGEID
;
1150 case MATCHCRITERIA_NOT_INREPLYTO
:
1151 case MATCHCRITERIA_INREPLYTO
:
1152 return CRITERIA_INREPLYTO
;
1153 case MATCHCRITERIA_NOT_REFERENCES
:
1154 case MATCHCRITERIA_REFERENCES
:
1155 return CRITERIA_REFERENCES
;
1156 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
1157 case MATCHCRITERIA_TO_OR_CC
:
1158 return CRITERIA_TO_OR_CC
;
1159 case MATCHCRITERIA_NOT_TAG
:
1160 case MATCHCRITERIA_TAG
:
1161 return CRITERIA_TAG
;
1162 case MATCHCRITERIA_NOT_TAGGED
:
1163 case MATCHCRITERIA_TAGGED
:
1164 return CRITERIA_TAGGED
;
1165 case MATCHCRITERIA_NOT_BODY_PART
:
1166 case MATCHCRITERIA_BODY_PART
:
1167 return CRITERIA_BODY_PART
;
1168 case MATCHCRITERIA_NOT_MESSAGE
:
1169 case MATCHCRITERIA_MESSAGE
:
1170 return CRITERIA_MESSAGE
;
1171 case MATCHCRITERIA_NOT_HEADERS_PART
:
1172 case MATCHCRITERIA_HEADERS_PART
:
1173 return CRITERIA_HEADERS_PART
;
1174 case MATCHCRITERIA_NOT_HEADERS_CONT
:
1175 case MATCHCRITERIA_HEADERS_CONT
:
1176 return CRITERIA_HEADERS_CONT
;
1177 case MATCHCRITERIA_NOT_HEADER
:
1178 case MATCHCRITERIA_HEADER
:
1179 return CRITERIA_HEADER
;
1180 case MATCHCRITERIA_AGE_GREATER_HOURS
:
1181 return CRITERIA_AGE_GREATER_HOURS
;
1182 case MATCHCRITERIA_AGE_LOWER_HOURS
:
1183 return CRITERIA_AGE_LOWER_HOURS
;
1184 case MATCHCRITERIA_AGE_GREATER
:
1185 return CRITERIA_AGE_GREATER
;
1186 case MATCHCRITERIA_AGE_LOWER
:
1187 return CRITERIA_AGE_LOWER
;
1188 case MATCHCRITERIA_DATE_AFTER
:
1189 return CRITERIA_DATE_AFTER
;
1190 case MATCHCRITERIA_DATE_BEFORE
:
1191 return CRITERIA_DATE_BEFORE
;
1192 case MATCHCRITERIA_SCORE_GREATER
:
1193 return CRITERIA_SCORE_GREATER
;
1194 case MATCHCRITERIA_SCORE_LOWER
:
1195 return CRITERIA_SCORE_LOWER
;
1196 case MATCHCRITERIA_SCORE_EQUAL
:
1197 return CRITERIA_SCORE_EQUAL
;
1198 case MATCHCRITERIA_NOT_TEST
:
1199 case MATCHCRITERIA_TEST
:
1200 return CRITERIA_TEST
;
1201 case MATCHCRITERIA_SIZE_GREATER
:
1202 return CRITERIA_SIZE_GREATER
;
1203 case MATCHCRITERIA_SIZE_SMALLER
:
1204 return CRITERIA_SIZE_SMALLER
;
1205 case MATCHCRITERIA_SIZE_EQUAL
:
1206 return CRITERIA_SIZE_EQUAL
;
1207 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1208 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
1209 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1216 *\brief Returns the matcher keyword id from a criteria id
1218 *\param criteria_id Criteria id (should not be the negate
1221 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1223 static gint
prefs_matcher_get_matching_from_criteria(gint criteria_id
)
1225 switch (criteria_id
) {
1227 return MATCHCRITERIA_ALL
;
1228 case CRITERIA_UNREAD
:
1229 return MATCHCRITERIA_UNREAD
;
1231 return MATCHCRITERIA_NEW
;
1232 case CRITERIA_MARKED
:
1233 return MATCHCRITERIA_MARKED
;
1234 case CRITERIA_DELETED
:
1235 return MATCHCRITERIA_DELETED
;
1236 case CRITERIA_REPLIED
:
1237 return MATCHCRITERIA_REPLIED
;
1238 case CRITERIA_FORWARDED
:
1239 return MATCHCRITERIA_FORWARDED
;
1240 case CRITERIA_LOCKED
:
1241 return MATCHCRITERIA_LOCKED
;
1243 return MATCHCRITERIA_SPAM
;
1244 case CRITERIA_HAS_ATTACHMENT
:
1245 return MATCHCRITERIA_HAS_ATTACHMENT
;
1246 case CRITERIA_SIGNED
:
1247 return MATCHCRITERIA_SIGNED
;
1248 case CRITERIA_PARTIAL
:
1249 return MATCHCRITERIA_PARTIAL
;
1250 case CRITERIA_COLORLABEL
:
1251 return MATCHCRITERIA_COLORLABEL
;
1252 case CRITERIA_IGNORE_THREAD
:
1253 return MATCHCRITERIA_IGNORE_THREAD
;
1254 case CRITERIA_WATCH_THREAD
:
1255 return MATCHCRITERIA_WATCH_THREAD
;
1256 case CRITERIA_SUBJECT
:
1257 return MATCHCRITERIA_SUBJECT
;
1259 return MATCHCRITERIA_FROM
;
1261 return MATCHCRITERIA_TO
;
1263 return MATCHCRITERIA_CC
;
1264 case CRITERIA_TO_OR_CC
:
1265 return MATCHCRITERIA_TO_OR_CC
;
1267 return MATCHCRITERIA_TAG
;
1268 case CRITERIA_TAGGED
:
1269 return MATCHCRITERIA_TAGGED
;
1270 case CRITERIA_NEWSGROUPS
:
1271 return MATCHCRITERIA_NEWSGROUPS
;
1272 case CRITERIA_MESSAGEID
:
1273 return MATCHCRITERIA_MESSAGEID
;
1274 case CRITERIA_INREPLYTO
:
1275 return MATCHCRITERIA_INREPLYTO
;
1276 case CRITERIA_REFERENCES
:
1277 return MATCHCRITERIA_REFERENCES
;
1278 case CRITERIA_AGE_GREATER
:
1279 return MATCHCRITERIA_AGE_GREATER
;
1280 case CRITERIA_AGE_LOWER
:
1281 return MATCHCRITERIA_AGE_LOWER
;
1282 case CRITERIA_AGE_GREATER_HOURS
:
1283 return MATCHCRITERIA_AGE_GREATER_HOURS
;
1284 case CRITERIA_AGE_LOWER_HOURS
:
1285 return MATCHCRITERIA_AGE_LOWER_HOURS
;
1286 case CRITERIA_DATE_AFTER
:
1287 return MATCHCRITERIA_DATE_AFTER
;
1288 case CRITERIA_DATE_BEFORE
:
1289 return MATCHCRITERIA_DATE_BEFORE
;
1290 case CRITERIA_SCORE_GREATER
:
1291 return MATCHCRITERIA_SCORE_GREATER
;
1292 case CRITERIA_SCORE_LOWER
:
1293 return MATCHCRITERIA_SCORE_LOWER
;
1294 case CRITERIA_SCORE_EQUAL
:
1295 return MATCHCRITERIA_SCORE_EQUAL
;
1296 case CRITERIA_HEADER
:
1297 return MATCHCRITERIA_HEADER
;
1298 case CRITERIA_HEADERS_PART
:
1299 return MATCHCRITERIA_HEADERS_PART
;
1300 case CRITERIA_HEADERS_CONT
:
1301 return MATCHCRITERIA_HEADERS_CONT
;
1302 case CRITERIA_BODY_PART
:
1303 return MATCHCRITERIA_BODY_PART
;
1304 case CRITERIA_MESSAGE
:
1305 return MATCHCRITERIA_MESSAGE
;
1307 return MATCHCRITERIA_TEST
;
1308 case CRITERIA_SIZE_GREATER
:
1309 return MATCHCRITERIA_SIZE_GREATER
;
1310 case CRITERIA_SIZE_SMALLER
:
1311 return MATCHCRITERIA_SIZE_SMALLER
;
1312 case CRITERIA_SIZE_EQUAL
:
1313 return MATCHCRITERIA_SIZE_EQUAL
;
1314 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1315 return MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
;
1322 *\brief Returns the negate matcher keyword id from a matcher keyword
1325 *\param matcher_criteria Matcher keyword id.
1327 *\return gint A matcher keyword id. See #get_matchparser_tab_id.
1329 static gint
prefs_matcher_not_criteria(gint matcher_criteria
)
1331 switch(matcher_criteria
) {
1332 case MATCHCRITERIA_UNREAD
:
1333 return MATCHCRITERIA_NOT_UNREAD
;
1334 case MATCHCRITERIA_NEW
:
1335 return MATCHCRITERIA_NOT_NEW
;
1336 case MATCHCRITERIA_MARKED
:
1337 return MATCHCRITERIA_NOT_MARKED
;
1338 case MATCHCRITERIA_DELETED
:
1339 return MATCHCRITERIA_NOT_DELETED
;
1340 case MATCHCRITERIA_REPLIED
:
1341 return MATCHCRITERIA_NOT_REPLIED
;
1342 case MATCHCRITERIA_FORWARDED
:
1343 return MATCHCRITERIA_NOT_FORWARDED
;
1344 case MATCHCRITERIA_LOCKED
:
1345 return MATCHCRITERIA_NOT_LOCKED
;
1346 case MATCHCRITERIA_SPAM
:
1347 return MATCHCRITERIA_NOT_SPAM
;
1348 case MATCHCRITERIA_HAS_ATTACHMENT
:
1349 return MATCHCRITERIA_HAS_NO_ATTACHMENT
;
1350 case MATCHCRITERIA_SIGNED
:
1351 return MATCHCRITERIA_NOT_SIGNED
;
1352 case MATCHCRITERIA_PARTIAL
:
1353 return MATCHCRITERIA_NOT_PARTIAL
;
1354 case MATCHCRITERIA_COLORLABEL
:
1355 return MATCHCRITERIA_NOT_COLORLABEL
;
1356 case MATCHCRITERIA_IGNORE_THREAD
:
1357 return MATCHCRITERIA_NOT_IGNORE_THREAD
;
1358 case MATCHCRITERIA_WATCH_THREAD
:
1359 return MATCHCRITERIA_NOT_WATCH_THREAD
;
1360 case MATCHCRITERIA_SUBJECT
:
1361 return MATCHCRITERIA_NOT_SUBJECT
;
1362 case MATCHCRITERIA_FROM
:
1363 return MATCHCRITERIA_NOT_FROM
;
1364 case MATCHCRITERIA_TO
:
1365 return MATCHCRITERIA_NOT_TO
;
1366 case MATCHCRITERIA_CC
:
1367 return MATCHCRITERIA_NOT_CC
;
1368 case MATCHCRITERIA_TO_OR_CC
:
1369 return MATCHCRITERIA_NOT_TO_AND_NOT_CC
;
1370 case MATCHCRITERIA_TAG
:
1371 return MATCHCRITERIA_NOT_TAG
;
1372 case MATCHCRITERIA_TAGGED
:
1373 return MATCHCRITERIA_NOT_TAGGED
;
1374 case MATCHCRITERIA_NEWSGROUPS
:
1375 return MATCHCRITERIA_NOT_NEWSGROUPS
;
1376 case MATCHCRITERIA_MESSAGEID
:
1377 return MATCHCRITERIA_NOT_MESSAGEID
;
1378 case MATCHCRITERIA_INREPLYTO
:
1379 return MATCHCRITERIA_NOT_INREPLYTO
;
1380 case MATCHCRITERIA_REFERENCES
:
1381 return MATCHCRITERIA_NOT_REFERENCES
;
1382 case MATCHCRITERIA_HEADER
:
1383 return MATCHCRITERIA_NOT_HEADER
;
1384 case MATCHCRITERIA_HEADERS_PART
:
1385 return MATCHCRITERIA_NOT_HEADERS_PART
;
1386 case MATCHCRITERIA_HEADERS_CONT
:
1387 return MATCHCRITERIA_NOT_HEADERS_CONT
;
1388 case MATCHCRITERIA_MESSAGE
:
1389 return MATCHCRITERIA_NOT_MESSAGE
;
1390 case MATCHCRITERIA_TEST
:
1391 return MATCHCRITERIA_NOT_TEST
;
1392 case MATCHCRITERIA_BODY_PART
:
1393 return MATCHCRITERIA_NOT_BODY_PART
;
1394 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
1395 return MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
;
1397 return matcher_criteria
;
1401 static gint
prefs_matcher_get_criteria(void)
1403 gint match_criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1404 matcher
.criteria_combo
));
1405 const gchar
*header
= NULL
;
1407 switch (match_criteria
) {
1409 return CRITERIA_FOUND_IN_ADDRESSBOOK
;
1411 return CRITERIA_ALL
;
1417 return combobox_get_active_data(GTK_COMBO_BOX(
1418 matcher
.match_combo
));
1420 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1421 return header_name_to_crit(header
);
1423 return CRITERIA_COLORLABEL
;
1425 return CRITERIA_PARTIAL
;
1427 return CRITERIA_TEST
;
1431 return combobox_get_active_data(GTK_COMBO_BOX(
1432 matcher
.criteria_combo2
));
1438 static gint
prefs_matcher_get_pred(const gint criteria
)
1441 case CRITERIA_SUBJECT
:
1445 case CRITERIA_TO_OR_CC
:
1446 case CRITERIA_NEWSGROUPS
:
1447 case CRITERIA_MESSAGEID
:
1448 case CRITERIA_INREPLYTO
:
1449 case CRITERIA_REFERENCES
:
1450 case CRITERIA_HEADER
:
1451 case CRITERIA_HEADERS_PART
:
1452 case CRITERIA_HEADERS_CONT
:
1453 case CRITERIA_BODY_PART
:
1454 case CRITERIA_MESSAGE
:
1456 case CRITERIA_TAGGED
:
1458 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo
));
1459 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1460 case CRITERIA_UNREAD
:
1462 case CRITERIA_MARKED
:
1463 case CRITERIA_DELETED
:
1464 case CRITERIA_REPLIED
:
1465 case CRITERIA_FORWARDED
:
1466 case CRITERIA_LOCKED
:
1468 case CRITERIA_HAS_ATTACHMENT
:
1469 case CRITERIA_SIGNED
:
1470 case CRITERIA_COLORLABEL
:
1471 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1472 case CRITERIA_WATCH_THREAD
:
1473 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
)) - 2;
1474 case CRITERIA_IGNORE_THREAD
:
1475 case CRITERIA_PARTIAL
:
1476 return gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.criteria_combo2
));
1483 *\brief Converts the text in the selected row to a
1486 *\return MatcherProp * Newly allocated matcher structure.
1488 static MatcherProp
*prefs_matcher_dialog_to_matcher(void)
1490 MatcherProp
*matcherprop
;
1494 gint value_criteria
= prefs_matcher_get_criteria();
1495 gboolean use_regexp
;
1496 gboolean case_sensitive
;
1497 const gchar
*header
;
1499 gboolean expr_to_free
= FALSE
;
1501 gint year
, month
, day
, hour
, minute
;
1503 if (value_criteria
== -1)
1506 use_regexp
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
));
1507 case_sensitive
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
));
1511 matchtype
= MATCHTYPE_REGEXP
;
1513 matchtype
= MATCHTYPE_REGEXPCASE
;
1517 matchtype
= MATCHTYPE_MATCH
;
1519 matchtype
= MATCHTYPE_MATCHCASE
;
1526 switch (value_criteria
) {
1528 case CRITERIA_UNREAD
:
1530 case CRITERIA_MARKED
:
1531 case CRITERIA_DELETED
:
1532 case CRITERIA_REPLIED
:
1533 case CRITERIA_FORWARDED
:
1534 case CRITERIA_LOCKED
:
1536 case CRITERIA_HAS_ATTACHMENT
:
1537 case CRITERIA_SIGNED
:
1538 case CRITERIA_PARTIAL
:
1539 case CRITERIA_IGNORE_THREAD
:
1540 case CRITERIA_WATCH_THREAD
:
1541 case CRITERIA_TAGGED
:
1544 case CRITERIA_SUBJECT
:
1548 case CRITERIA_TO_OR_CC
:
1550 case CRITERIA_NEWSGROUPS
:
1551 case CRITERIA_MESSAGEID
:
1552 case CRITERIA_INREPLYTO
:
1553 case CRITERIA_REFERENCES
:
1554 case CRITERIA_HEADERS_PART
:
1555 case CRITERIA_HEADERS_CONT
:
1556 case CRITERIA_BODY_PART
:
1557 case CRITERIA_MESSAGE
:
1558 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1561 alertpanel_error(_("Search pattern is not set."));
1566 case CRITERIA_DATE_AFTER
:
1567 case CRITERIA_DATE_BEFORE
:
1569 gtk_calendar_get_date(GTK_CALENDAR(matcher
.calendar
), &year
, &month
, &day
);
1570 if (gtkut_time_select_get_time(GTK_COMBO_BOX(matcher
.time_entry
), &hour
, &minute
))
1571 expr
= g_strdup_printf("%4d-%02d-%02d %02d:%02d:00",
1572 year
, month
+ 1, day
, hour
, minute
);
1575 alertpanel_error(_("Invalid hour."));
1578 expr_to_free
= TRUE
;
1582 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1585 alertpanel_error(_("Test command is not set."));
1590 case CRITERIA_AGE_GREATER
:
1591 case CRITERIA_AGE_LOWER
:
1592 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1593 matcher
.numeric_entry
));
1594 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1595 if(sel
== AGE_WEEKS
)
1597 else if (sel
== AGE_HOURS
) {
1598 if (value_criteria
== CRITERIA_AGE_GREATER
)
1599 value_criteria
= CRITERIA_AGE_GREATER_HOURS
;
1601 value_criteria
= CRITERIA_AGE_LOWER_HOURS
;
1605 case CRITERIA_SCORE_GREATER
:
1606 case CRITERIA_SCORE_LOWER
:
1607 case CRITERIA_SCORE_EQUAL
:
1608 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1609 matcher
.numeric_entry
));
1612 case CRITERIA_SIZE_GREATER
:
1613 case CRITERIA_SIZE_SMALLER
:
1614 case CRITERIA_SIZE_EQUAL
:
1615 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1616 matcher
.numeric_entry
));
1617 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1618 if(sel
== SIZE_UNIT_MBYTES
)
1620 if(sel
== SIZE_UNIT_KBYTES
)
1624 case CRITERIA_COLORLABEL
:
1625 value
= colorlabel_get_combobox_colormenu_active(
1626 GTK_COMBO_BOX(matcher
.color_optmenu
));
1629 case CRITERIA_HEADER
:
1630 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1631 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1633 if (*header
== '\0') {
1634 alertpanel_error(_("Header name is not set."));
1639 alertpanel_error(_("Search pattern is not set."));
1644 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1645 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_addr_entry
));
1646 expr
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
1648 if (*header
== '\0') {
1649 alertpanel_error(_("Header name is not set."));
1652 if (*expr
== '\0') {
1655 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1656 tmp
= g_strdup(_("all addresses in all headers"));
1658 if (g_utf8_collate(header
, _("Any")) == 0)
1659 tmp
= g_strdup(_("any address in any header"));
1661 tmp
= g_strdup_printf(_("the address(es) in header '%s'"), header
);
1662 alertpanel_error(_("Book/folder path is not set.\n\n"
1663 "If you want to match %s against the whole address book, "
1664 "you have to select '%s' from the book/folder drop-down list."),
1669 /* store UNtranslated "Any"/"All" in matcher expressions */
1670 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1673 if (g_utf8_collate(header
, _("Any")) == 0)
1675 if (g_utf8_collate(expr
, _("Any")) == 0)
1680 criteria
= prefs_matcher_get_matching_from_criteria(value_criteria
);
1682 value_pred
= prefs_matcher_get_pred(value_criteria
);
1684 criteria
= prefs_matcher_not_criteria(criteria
);
1686 matcherprop
= matcherprop_new(criteria
, header
, matchtype
,
1690 g_free((gchar
*)expr
);
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_combo_box_set_active(GTK_COMBO_BOX(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 NULL
, _("_Continue editing"),
2171 if (G_ALERTDEFAULT
!= val
) {
2172 g_free(matcher_str
);
2174 matcherlist_free(matchers
);
2178 g_free(matcher_str
);
2182 gtk_widget_hide(matcher
.window
);
2183 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2184 if (matchers_callback
!= NULL
)
2185 matchers_callback(matchers
);
2186 matcherlist_free(matchers
);
2192 *\brief Called when closing dialog box
2194 *\param widget Dialog widget
2195 *\param event Event info
2196 *\param data User data
2200 static gint
prefs_matcher_deleted(GtkWidget
*widget
, GdkEventAny
*event
,
2203 prefs_matcher_cancel();
2208 * Strings describing test format strings
2210 * When adding new lines, remember to put 2 strings for each line
2212 static gchar
*test_desc_strings
[] = {
2213 "%%", N_("literal %"),
2214 "%s", N_("Subject"),
2219 "%i", N_("Message-ID"),
2220 "%n", N_("Newsgroups"),
2221 "%r", N_("References"),
2222 "%F", N_("filename (should not be modified)"),
2223 "\\n", N_("new line"),
2224 "\\", N_("escape character for quotes"),
2225 "\\\"", N_("quote character"),
2229 static DescriptionWindow test_desc_win
= {
2234 N_("Match Type: 'Test'"),
2235 N_("'Test' allows you to test a message or message element "
2236 "using an external program or script. The program will "
2237 "return either 0 or 1.\n\n"
2238 "The following symbols can be used:"),
2245 *\brief Show Test action's info
2247 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
)
2249 test_desc_win
.parent
= parent
;
2250 description_window_create(&test_desc_win
);
2253 #ifndef USE_ALT_ADDRBOOK
2254 static void prefs_matcher_addressbook_select(void)
2256 const gchar
*folderpath
= NULL
;
2257 gchar
*new_path
= NULL
;
2259 folderpath
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
2260 new_path
= addressbook_folder_selection(folderpath
);
2262 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), new_path
);
2272 static GtkListStore
* prefs_matcher_create_data_store(void)
2274 return gtk_list_store_new(N_PREFS_MATCHER_COLUMNS
,
2280 static void prefs_matcher_list_view_insert_matcher(GtkWidget
*list_view
,
2281 GtkTreeIter
*row_iter
,
2282 const gchar
*matcher
,
2286 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
2287 (GTK_TREE_VIEW(list_view
)));
2289 if (row_iter
== NULL
) {
2291 gtk_list_store_append(list_store
, &iter
);
2293 /* change existing */
2297 gtk_list_store_set(list_store
, &iter
,
2298 PREFS_MATCHER_COND
, matcher
,
2299 PREFS_MATCHER_COND_VALID
, is_valid
,
2303 static GtkWidget
*prefs_matcher_list_view_create(void)
2305 GtkTreeView
*list_view
;
2306 GtkTreeSelection
*selector
;
2307 GtkTreeModel
*model
;
2309 model
= GTK_TREE_MODEL(prefs_matcher_create_data_store());
2310 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
2311 g_object_unref(model
);
2313 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
2314 gtk_tree_view_set_reorderable(list_view
, TRUE
);
2316 selector
= gtk_tree_view_get_selection(list_view
);
2317 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
2318 gtk_tree_selection_set_select_function(selector
, prefs_matcher_selected
,
2321 /* create the columns */
2322 prefs_matcher_create_list_view_columns(GTK_WIDGET(list_view
));
2324 return GTK_WIDGET(list_view
);
2327 static void prefs_matcher_create_list_view_columns(GtkWidget
*list_view
)
2329 GtkTreeViewColumn
*column
;
2330 GtkCellRenderer
*renderer
;
2332 renderer
= gtk_cell_renderer_text_new();
2333 column
= gtk_tree_view_column_new_with_attributes
2334 (_("Current condition rules"),
2336 "text", PREFS_MATCHER_COND
,
2338 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
2341 static void prefs_matcher_set_criteria(const gint criteria
)
2343 gint match_criteria
= 0;
2346 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2347 match_criteria
= MATCH_ABOOK
;
2350 match_criteria
= MATCH_ALL
;
2352 case CRITERIA_AGE_GREATER
:
2353 case CRITERIA_AGE_LOWER
:
2354 case CRITERIA_AGE_GREATER_HOURS
:
2355 case CRITERIA_AGE_LOWER_HOURS
:
2356 match_criteria
= MATCH_AGE
;
2358 case CRITERIA_DATE_AFTER
:
2359 case CRITERIA_DATE_BEFORE
:
2360 match_criteria
= MATCH_DATE
;
2362 case CRITERIA_SCORE_GREATER
:
2363 case CRITERIA_SCORE_LOWER
:
2364 case CRITERIA_SCORE_EQUAL
:
2365 match_criteria
= MATCH_SCORE
;
2367 case CRITERIA_SIZE_GREATER
:
2368 case CRITERIA_SIZE_SMALLER
:
2369 case CRITERIA_SIZE_EQUAL
:
2370 match_criteria
= MATCH_SIZE
;
2372 case CRITERIA_SUBJECT
:
2376 case CRITERIA_TO_OR_CC
:
2377 case CRITERIA_NEWSGROUPS
:
2378 case CRITERIA_MESSAGEID
:
2379 case CRITERIA_INREPLYTO
:
2380 case CRITERIA_REFERENCES
:
2381 case CRITERIA_HEADER
:
2382 match_criteria
= MATCH_HEADER
;
2384 case CRITERIA_HEADERS_PART
:
2385 case CRITERIA_HEADERS_CONT
:
2386 case CRITERIA_BODY_PART
:
2387 case CRITERIA_MESSAGE
:
2388 match_criteria
= MATCH_PHRASE
;
2391 match_criteria
= MATCH_TEST
;
2393 case CRITERIA_COLORLABEL
:
2394 match_criteria
= MATCH_LABEL
;
2397 case CRITERIA_TAGGED
:
2398 match_criteria
= MATCH_TAGS
;
2400 case CRITERIA_UNREAD
:
2402 case CRITERIA_MARKED
:
2403 case CRITERIA_DELETED
:
2404 case CRITERIA_REPLIED
:
2405 case CRITERIA_FORWARDED
:
2406 case CRITERIA_LOCKED
:
2408 case CRITERIA_HAS_ATTACHMENT
:
2409 case CRITERIA_SIGNED
:
2410 match_criteria
= MATCH_FLAG
;
2412 case CRITERIA_PARTIAL
:
2413 match_criteria
= MATCH_PARTIAL
;
2415 case CRITERIA_IGNORE_THREAD
:
2416 case CRITERIA_WATCH_THREAD
:
2417 match_criteria
= MATCH_THREAD
;
2421 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
),
2424 switch(match_criteria
) {
2426 if(criteria
!= CRITERIA_HEADER
)
2427 combobox_select_by_data(GTK_COMBO_BOX(
2428 matcher
.headers_combo
),
2436 combobox_select_by_data(GTK_COMBO_BOX(
2437 matcher
.match_combo
), criteria
);
2441 combobox_select_by_data(GTK_COMBO_BOX(
2442 matcher
.criteria_combo2
), criteria
);
2447 static gboolean
prefs_matcher_selected(GtkTreeSelection
*selector
,
2448 GtkTreeModel
*model
,
2450 gboolean currently_selected
,
2455 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 colorlabel_set_combobox_colormenu_active(
2653 GTK_COMBO_BOX(matcher
.color_optmenu
), prop
->value
);
2656 case MATCHCRITERIA_NOT_HEADER
:
2657 case MATCHCRITERIA_HEADER
:
2658 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), prop
->header
);
2659 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2664 case CRITERIA_SUBJECT
:
2668 case CRITERIA_TO_OR_CC
:
2669 case CRITERIA_NEWSGROUPS
:
2670 case CRITERIA_MESSAGEID
:
2671 case CRITERIA_INREPLYTO
:
2672 case CRITERIA_REFERENCES
:
2673 case CRITERIA_HEADER
:
2674 case CRITERIA_HEADERS_PART
:
2675 case CRITERIA_HEADERS_CONT
:
2676 case CRITERIA_BODY_PART
:
2677 case CRITERIA_MESSAGE
:
2679 case CRITERIA_TAGGED
:
2681 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
),
2682 negative_cond
? PREDICATE_DOES_NOT_CONTAIN
:
2683 PREDICATE_CONTAINS
);
2685 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2686 case CRITERIA_UNREAD
:
2688 case CRITERIA_MARKED
:
2689 case CRITERIA_DELETED
:
2690 case CRITERIA_REPLIED
:
2691 case CRITERIA_FORWARDED
:
2692 case CRITERIA_LOCKED
:
2694 case CRITERIA_HAS_ATTACHMENT
:
2695 case CRITERIA_SIGNED
:
2696 case CRITERIA_COLORLABEL
:
2697 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2698 negative_cond
? PREDICATE_FLAG_DISABLED
:
2699 PREDICATE_FLAG_ENABLED
);
2701 case CRITERIA_WATCH_THREAD
:
2702 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2703 negative_cond
? THREAD_NOT_WATCHED
:
2706 case CRITERIA_IGNORE_THREAD
:
2707 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2708 negative_cond
? THREAD_NOT_IGNORED
:
2711 case CRITERIA_PARTIAL
:
2712 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2713 negative_cond
? PREDICATE_FLAG_DISABLED
:
2714 PREDICATE_FLAG_ENABLED
);
2718 switch(prop
->matchtype
) {
2719 case MATCHTYPE_MATCH
:
2720 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2721 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2724 case MATCHTYPE_MATCHCASE
:
2725 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2726 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2729 case MATCHTYPE_REGEXP
:
2730 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2731 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2734 case MATCHTYPE_REGEXPCASE
:
2735 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2736 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2740 g_free(matcher_str
);