2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2021 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
, _("kilobytes"), SIZE_UNIT_KBYTES
);
364 COMBOBOX_ADD(store
, _("megabytes"), 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
, _("_Cancel"),
573 &ok_btn
, _("_OK"), 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
;
1500 gint year
, month
, day
, hour
, minute
;
1502 if (value_criteria
== -1)
1505 use_regexp
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
));
1506 case_sensitive
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
));
1510 matchtype
= MATCHTYPE_REGEXP
;
1512 matchtype
= MATCHTYPE_REGEXPCASE
;
1516 matchtype
= MATCHTYPE_MATCH
;
1518 matchtype
= MATCHTYPE_MATCHCASE
;
1525 switch (value_criteria
) {
1527 case CRITERIA_UNREAD
:
1529 case CRITERIA_MARKED
:
1530 case CRITERIA_DELETED
:
1531 case CRITERIA_REPLIED
:
1532 case CRITERIA_FORWARDED
:
1533 case CRITERIA_LOCKED
:
1535 case CRITERIA_HAS_ATTACHMENT
:
1536 case CRITERIA_SIGNED
:
1537 case CRITERIA_PARTIAL
:
1538 case CRITERIA_IGNORE_THREAD
:
1539 case CRITERIA_WATCH_THREAD
:
1540 case CRITERIA_TAGGED
:
1543 case CRITERIA_SUBJECT
:
1547 case CRITERIA_TO_OR_CC
:
1549 case CRITERIA_NEWSGROUPS
:
1550 case CRITERIA_MESSAGEID
:
1551 case CRITERIA_INREPLYTO
:
1552 case CRITERIA_REFERENCES
:
1553 case CRITERIA_HEADERS_PART
:
1554 case CRITERIA_HEADERS_CONT
:
1555 case CRITERIA_BODY_PART
:
1556 case CRITERIA_MESSAGE
:
1557 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1560 alertpanel_error(_("Search pattern is not set."));
1565 case CRITERIA_DATE_AFTER
:
1566 case CRITERIA_DATE_BEFORE
:
1568 gtk_calendar_get_date(GTK_CALENDAR(matcher
.calendar
), &year
, &month
, &day
);
1569 if (gtkut_time_select_get_time(GTK_COMBO_BOX(matcher
.time_entry
), &hour
, &minute
))
1570 expr
= g_strdup_printf("%4d-%02d-%02d %02d:%02d:00",
1571 year
, month
+ 1, day
, hour
, minute
);
1574 alertpanel_error(_("Invalid hour."));
1580 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1583 alertpanel_error(_("Test command is not set."));
1588 case CRITERIA_AGE_GREATER
:
1589 case CRITERIA_AGE_LOWER
:
1590 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1591 matcher
.numeric_entry
));
1592 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1593 if(sel
== AGE_WEEKS
)
1595 else if (sel
== AGE_HOURS
) {
1596 if (value_criteria
== CRITERIA_AGE_GREATER
)
1597 value_criteria
= CRITERIA_AGE_GREATER_HOURS
;
1599 value_criteria
= CRITERIA_AGE_LOWER_HOURS
;
1603 case CRITERIA_SCORE_GREATER
:
1604 case CRITERIA_SCORE_LOWER
:
1605 case CRITERIA_SCORE_EQUAL
:
1606 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1607 matcher
.numeric_entry
));
1610 case CRITERIA_SIZE_GREATER
:
1611 case CRITERIA_SIZE_SMALLER
:
1612 case CRITERIA_SIZE_EQUAL
:
1613 value
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(
1614 matcher
.numeric_entry
));
1615 sel
= gtk_combo_box_get_active(GTK_COMBO_BOX(matcher
.match_combo2
));
1616 if(sel
== SIZE_UNIT_MBYTES
)
1618 if(sel
== SIZE_UNIT_KBYTES
)
1622 case CRITERIA_COLORLABEL
:
1623 value
= colorlabel_get_combobox_colormenu_active(
1624 GTK_COMBO_BOX(matcher
.color_optmenu
));
1627 case CRITERIA_HEADER
:
1628 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_entry
));
1629 expr
= gtk_entry_get_text(GTK_ENTRY(matcher
.string_entry
));
1631 if (*header
== '\0') {
1632 alertpanel_error(_("Header name is not set."));
1637 alertpanel_error(_("Search pattern is not set."));
1642 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
1643 header
= gtk_entry_get_text(GTK_ENTRY(matcher
.header_addr_entry
));
1644 expr
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
1646 if (*header
== '\0') {
1647 alertpanel_error(_("Header name is not set."));
1650 if (*expr
== '\0') {
1653 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1654 tmp
= g_strdup(_("all addresses in all headers"));
1656 if (g_utf8_collate(header
, _("Any")) == 0)
1657 tmp
= g_strdup(_("any address in any header"));
1659 tmp
= g_strdup_printf(_("the address(es) in header '%s'"), header
);
1660 alertpanel_error(_("Book/folder path is not set.\n\n"
1661 "If you want to match %s against the whole address book, "
1662 "you have to select '%s' from the book/folder drop-down list."),
1667 /* store UNtranslated "Any"/"All" in matcher expressions */
1668 if (g_utf8_collate(header
, C_("Filtering Matcher Menu", "All")) == 0)
1671 if (g_utf8_collate(header
, _("Any")) == 0)
1673 if (g_utf8_collate(expr
, _("Any")) == 0)
1678 criteria
= prefs_matcher_get_matching_from_criteria(value_criteria
);
1680 value_pred
= prefs_matcher_get_pred(value_criteria
);
1682 criteria
= prefs_matcher_not_criteria(criteria
);
1684 matcherprop
= matcherprop_new(criteria
, header
, matchtype
,
1691 *\brief Signal handler for register button
1693 static void prefs_matcher_register_cb(void)
1695 MatcherProp
*matcherprop
;
1697 matcherprop
= prefs_matcher_dialog_to_matcher();
1698 if (matcherprop
== NULL
)
1701 prefs_matcher_list_view_set_row(NULL
, matcherprop
);
1703 matcherprop_free(matcherprop
);
1705 prefs_matcher_reset_condition();
1709 *\brief Signal handler for substitute button
1711 static void prefs_matcher_substitute_cb(void)
1713 MatcherProp
*matcherprop
;
1715 GtkTreeSelection
*selection
;
1716 GtkTreeModel
*model
;
1719 selection
= gtk_tree_view_get_selection
1720 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1722 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1725 gtk_tree_model_get(model
, &row
,
1726 PREFS_MATCHER_COND_VALID
, &is_valid
,
1731 matcherprop
= prefs_matcher_dialog_to_matcher();
1732 if (matcherprop
== NULL
)
1735 prefs_matcher_list_view_set_row(&row
, matcherprop
);
1737 matcherprop_free(matcherprop
);
1741 *\brief Signal handler for delete button
1743 static void prefs_matcher_delete_cb(void)
1746 GtkTreeSelection
*selection
;
1747 GtkTreeModel
*model
;
1750 selection
= gtk_tree_view_get_selection
1751 (GTK_TREE_VIEW(matcher
.cond_list_view
));
1753 if (!gtk_tree_selection_get_selected(selection
, &model
, &row
))
1756 gtk_tree_model_get(model
, &row
,
1757 PREFS_MATCHER_COND_VALID
, &is_valid
,
1763 gtk_list_store_remove(GTK_LIST_STORE(model
), &row
);
1765 prefs_matcher_reset_condition();
1769 *\brief Signal handler for 'move up' button
1771 static void prefs_matcher_up(void)
1773 GtkTreePath
*prev
, *sel
, *try;
1775 GtkListStore
*store
= NULL
;
1776 GtkTreeModel
*model
= NULL
;
1779 if (!gtk_tree_selection_get_selected
1780 (gtk_tree_view_get_selection
1781 (GTK_TREE_VIEW(matcher
.cond_list_view
)),
1785 store
= (GtkListStore
*)model
;
1786 sel
= gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &isel
);
1790 /* no move if we're at row 0 or 1, looks phony, but other
1791 * solutions are more convoluted... */
1792 try = gtk_tree_path_copy(sel
);
1793 if (!gtk_tree_path_prev(try) || !gtk_tree_path_prev(try)) {
1794 gtk_tree_path_free(try);
1795 gtk_tree_path_free(sel
);
1798 gtk_tree_path_free(try);
1800 prev
= gtk_tree_path_copy(sel
);
1801 if (gtk_tree_path_prev(prev
)) {
1802 gtk_tree_model_get_iter(GTK_TREE_MODEL(store
),
1804 gtk_list_store_swap(store
, &iprev
, &isel
);
1805 /* XXX: GTK2 select row?? */
1808 gtk_tree_path_free(sel
);
1809 gtk_tree_path_free(prev
);
1813 *\brief Signal handler for 'move down' button
1815 static void prefs_matcher_down(void)
1817 GtkListStore
*store
= NULL
;
1818 GtkTreeModel
*model
= NULL
;
1819 GtkTreeIter next
, sel
;
1822 if (!gtk_tree_selection_get_selected
1823 (gtk_tree_view_get_selection
1824 (GTK_TREE_VIEW(matcher
.cond_list_view
)),
1828 store
= (GtkListStore
*)model
;
1829 try = gtk_tree_model_get_path(GTK_TREE_MODEL(store
), &sel
);
1833 /* move when not at row 0 ... */
1834 if (gtk_tree_path_prev(try)) {
1836 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store
), &next
))
1837 gtk_list_store_swap(store
, &next
, &sel
);
1840 gtk_tree_path_free(try);
1843 static void prefs_matcher_enable_widget(GtkWidget
* widget
, const gboolean enable
)
1845 cm_return_if_fail(widget
!= NULL
);
1847 if(enable
== TRUE
) {
1848 gtk_widget_set_sensitive(widget
, TRUE
);
1849 gtk_widget_show(widget
);
1851 gtk_widget_set_sensitive(widget
, FALSE
);
1852 gtk_widget_hide(widget
);
1856 static void prefs_matcher_set_model(GtkWidget
*widget
, GtkTreeModel
*model
)
1858 cm_return_if_fail(widget
!= NULL
);
1859 cm_return_if_fail(model
!= NULL
);
1861 gtk_combo_box_set_model(GTK_COMBO_BOX(widget
), model
);
1862 gtk_combo_box_set_active(GTK_COMBO_BOX(widget
), 0);
1865 static void prefs_matcher_second_criteria_sel(GtkWidget
*widget
,
1868 gint criteria
= gtk_combo_box_get_active(GTK_COMBO_BOX(
1869 matcher
.criteria_combo
));
1870 gint criteria2
= combobox_get_active_data(GTK_COMBO_BOX(
1871 matcher
.criteria_combo2
));
1873 if(criteria
!= MATCH_PHRASE
&& criteria
!= MATCH_TAGS
) return;
1875 if(criteria
== MATCH_PHRASE
) {
1877 case CRITERIA_HEADERS_PART
:
1878 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1881 case CRITERIA_HEADERS_CONT
:
1882 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1883 _("Headers values"));
1885 case CRITERIA_BODY_PART
:
1886 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1889 case CRITERIA_MESSAGE
:
1890 gtk_label_set_text(GTK_LABEL(matcher
.match_label
),
1891 _("Whole message"));
1896 if(criteria
== MATCH_TAGS
) {
1897 if(criteria2
== CRITERIA_TAGGED
) {
1898 prefs_matcher_enable_widget(matcher
.upper_filler
, FALSE
);
1899 prefs_matcher_enable_widget(matcher
.match_label2
, TRUE
);
1900 prefs_matcher_enable_widget(matcher
.string_entry
, FALSE
);
1901 prefs_matcher_enable_widget(matcher
.case_checkbtn
, FALSE
);
1902 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, FALSE
);
1904 prefs_matcher_enable_widget(matcher
.upper_filler
, TRUE
);
1905 prefs_matcher_enable_widget(matcher
.match_label2
, FALSE
);
1906 prefs_matcher_enable_widget(matcher
.string_entry
, TRUE
);
1907 prefs_matcher_enable_widget(matcher
.case_checkbtn
, TRUE
);
1908 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
, TRUE
);
1909 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1910 matcher
.regexp_checkbtn
), FALSE
);
1911 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
1912 matcher
.case_checkbtn
), FALSE
);
1917 #define MATCH_COMBO_IS_ENABLED(x) (x != MATCH_ALL && x != MATCH_ABOOK && \
1918 x != MATCH_PARTIAL && x != MATCH_THREAD && x != MATCH_LABEL) ? TRUE : FALSE
1919 #define MATCH_CASE_REGEXP(x) (x == MATCH_HEADER || x == MATCH_PHRASE) ? TRUE : FALSE
1920 #define MATCH_NUMERIC(x) (x == MATCH_AGE || x == MATCH_SCORE || \
1921 x == MATCH_SIZE) ? TRUE : FALSE
1924 *\brief Change widgets depending on the selected condition
1926 *\param criteria combo widget
1927 *\param user_data Not used
1929 static void prefs_matcher_criteria_select(GtkWidget
*widget
,
1932 gint value
, old_value
;
1934 old_value
= matcher
.selected_criteria
;
1935 matcher
.selected_criteria
= value
= gtk_combo_box_get_active
1936 (GTK_COMBO_BOX(matcher
.criteria_combo
));
1938 if (old_value
== matcher
.selected_criteria
)
1941 prefs_matcher_enable_widget(matcher
.criteria_label2
,
1942 (value
== MATCH_ABOOK
||
1943 value
== MATCH_PHRASE
||
1944 value
== MATCH_HEADER
||
1945 value
== MATCH_PARTIAL
||
1946 value
== MATCH_TAGS
||
1947 value
== MATCH_THREAD
));
1948 prefs_matcher_enable_widget(matcher
.headers_combo
,
1949 (value
== MATCH_HEADER
));
1950 prefs_matcher_enable_widget(matcher
.criteria_combo2
,
1951 (value
== MATCH_PHRASE
||
1952 value
== MATCH_PARTIAL
||
1953 value
== MATCH_TAGS
||
1954 value
== MATCH_THREAD
));
1955 prefs_matcher_enable_widget(matcher
.match_combo2
,
1956 (value
== MATCH_ABOOK
||
1957 value
== MATCH_AGE
||
1958 value
== MATCH_FLAG
||
1959 value
== MATCH_LABEL
||
1960 value
== MATCH_SIZE
));
1961 prefs_matcher_enable_widget(matcher
.match_label2
,
1962 (value
== MATCH_ABOOK
||
1963 value
== MATCH_FLAG
||
1964 value
== MATCH_LABEL
||
1965 value
== MATCH_TAGS
));
1966 prefs_matcher_enable_widget(matcher
.header_addr_combo
,
1967 (value
== MATCH_ABOOK
));
1968 prefs_matcher_enable_widget(matcher
.string_entry
,
1969 (MATCH_CASE_REGEXP(value
) ||
1970 value
== MATCH_TEST
));
1971 prefs_matcher_enable_widget(matcher
.calendar
,
1972 (value
== MATCH_DATE
));
1973 prefs_matcher_enable_widget(matcher
.time_label
,
1974 (value
== MATCH_DATE
));
1975 prefs_matcher_enable_widget(matcher
.time_entry
,
1976 (value
== MATCH_DATE
));
1977 prefs_matcher_enable_widget(matcher
.numeric_entry
,
1978 MATCH_NUMERIC(value
));
1979 prefs_matcher_enable_widget(matcher
.numeric_label
,
1980 (value
== MATCH_SCORE
));
1981 prefs_matcher_enable_widget(matcher
.addressbook_folder_combo
,
1982 (value
== MATCH_ABOOK
));
1983 prefs_matcher_enable_widget(matcher
.match_combo
,
1984 MATCH_COMBO_IS_ENABLED(value
));
1985 prefs_matcher_enable_widget(matcher
.case_checkbtn
,
1986 MATCH_CASE_REGEXP(value
));
1987 prefs_matcher_enable_widget(matcher
.regexp_checkbtn
,
1988 MATCH_CASE_REGEXP(value
));
1989 prefs_matcher_enable_widget(matcher
.test_btn
,
1990 (value
== MATCH_TEST
));
1991 prefs_matcher_enable_widget(matcher
.addressbook_select_btn
,
1992 (value
== MATCH_ABOOK
));
1993 prefs_matcher_enable_widget(matcher
.color_optmenu
,
1994 (value
== MATCH_LABEL
));
1995 prefs_matcher_enable_widget(matcher
.upper_filler
,
1996 MATCH_CASE_REGEXP(value
));
1997 prefs_matcher_enable_widget(matcher
.lower_filler
,
1998 (value
== MATCH_ABOOK
));
2000 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), "");
2001 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), "");
2005 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.header_addr_combo
), 0);
2006 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.addressbook_folder_combo
), 0);
2007 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_found
);
2008 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
2009 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
2010 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("content is"));
2013 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_date
);
2014 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Date is"));
2015 gtk_calendar_select_today(GTK_CALENDAR(matcher
.calendar
));
2016 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), 0, 0);
2019 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_age
);
2020 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_age_units
);
2021 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2022 matcher
.numeric_entry
), 0, 10000);
2023 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2024 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
), AGE_DAYS
);
2025 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Age is"));
2028 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_flags
);
2029 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
2030 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Flag"));
2031 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
2034 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.headers_combo
), 0);
2035 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2036 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Name:"));
2037 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Header"));
2038 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2039 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2042 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.color_optmenu
), 0);
2043 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_set
);
2044 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Label"));
2045 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("is"));
2048 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_partial
);
2049 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Value:"));
2052 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_phrase
);
2053 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2054 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("in"));
2055 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2056 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2057 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2060 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_score
);
2061 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2062 matcher
.numeric_entry
), -1000, 1000);
2063 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2064 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Score is"));
2065 gtk_label_set_text(GTK_LABEL(matcher
.numeric_label
), _("points"));
2068 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_size
);
2069 prefs_matcher_set_model(matcher
.match_combo2
, matcher
.model_size_units
);
2070 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2072 gtk_spin_button_set_range(GTK_SPIN_BUTTON(
2073 matcher
.numeric_entry
), 0, 100000);
2074 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
), 0);
2075 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Size is"));
2078 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_tags
);
2079 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_contain
);
2080 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("Scope:"));
2081 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Message"));
2082 gtk_label_set_text(GTK_LABEL(matcher
.match_label2
), _("tags"));
2083 prefs_matcher_second_criteria_sel(NULL
, NULL
);
2086 prefs_matcher_set_model(matcher
.criteria_combo2
, matcher
.model_thread
);
2087 gtk_label_set_text(GTK_LABEL(matcher
.criteria_label2
), _("type is"));
2090 prefs_matcher_set_model(matcher
.match_combo
, matcher
.model_test
);
2091 gtk_label_set_text(GTK_LABEL(matcher
.match_label
), _("Program returns"));
2097 *\brief Handle key press
2099 *\param widget Widget receiving key press
2100 *\param event Key event
2101 *\param data User data
2103 static gboolean
prefs_matcher_key_pressed(GtkWidget
*widget
, GdkEventKey
*event
,
2106 if (event
&& event
->keyval
== GDK_KEY_Escape
) {
2107 prefs_matcher_cancel();
2114 *\brief Cancel matcher dialog
2116 static void prefs_matcher_cancel(void)
2118 gtk_widget_hide(matcher
.window
);
2119 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2124 *\brief Accept current matchers
2126 static void prefs_matcher_ok(void)
2128 MatcherList
*matchers
;
2129 MatcherProp
*matcherprop
;
2131 gchar
*matcher_str
= NULL
;
2134 GtkTreeModel
*model
;
2137 matchers
= prefs_matcher_get_list();
2139 if (matchers
!= NULL
) {
2140 matcherprop
= prefs_matcher_dialog_to_matcher();
2141 if (matcherprop
!= NULL
) {
2142 str
= matcherprop_to_string(matcherprop
);
2143 matcherprop_free(matcherprop
);
2144 if (strcmp(str
, "all") != 0) {
2145 model
= gtk_tree_view_get_model(GTK_TREE_VIEW
2146 (matcher
.cond_list_view
));
2148 while (gtk_tree_model_iter_nth_child(model
, &iter
, NULL
, row
)) {
2149 gtk_tree_model_get(model
, &iter
,
2150 PREFS_MATCHER_COND
, &matcher_str
,
2152 if (matcher_str
&& strcmp(matcher_str
, str
) == 0)
2155 g_free(matcher_str
);
2159 if (!matcher_str
|| strcmp(matcher_str
, str
) != 0) {
2160 val
= alertpanel(_("Entry not saved"),
2161 _("The entry was not saved.\nClose anyway?"),
2163 _("_Continue editing"),
2166 if (G_ALERTDEFAULT
!= val
) {
2167 g_free(matcher_str
);
2172 g_free(matcher_str
);
2176 gtk_widget_hide(matcher
.window
);
2177 gtk_window_set_modal(GTK_WINDOW(matcher
.window
), FALSE
);
2178 if (matchers_callback
!= NULL
)
2179 matchers_callback(matchers
);
2180 matcherlist_free(matchers
);
2186 *\brief Called when closing dialog box
2188 *\param widget Dialog widget
2189 *\param event Event info
2190 *\param data User data
2194 static gint
prefs_matcher_deleted(GtkWidget
*widget
, GdkEventAny
*event
,
2197 prefs_matcher_cancel();
2202 * Strings describing test format strings
2204 * When adding new lines, remember to put 2 strings for each line
2206 static gchar
*test_desc_strings
[] = {
2207 "%%", N_("literal %"),
2208 "%s", N_("Subject"),
2213 "%i", N_("Message-ID"),
2214 "%n", N_("Newsgroups"),
2215 "%r", N_("References"),
2216 "%F", N_("filename (should not be modified)"),
2217 "\\n", N_("new line"),
2218 "\\", N_("escape character for quotes"),
2219 "\\\"", N_("quote character"),
2223 static DescriptionWindow test_desc_win
= {
2228 N_("Match Type: 'Test'"),
2229 N_("'Test' allows you to test a message or message element "
2230 "using an external program or script. The program will "
2231 "return either 0 or 1.\n\n"
2232 "The following symbols can be used:"),
2239 *\brief Show Test action's info
2241 static void prefs_matcher_test_info(GtkWidget
*widget
, GtkWidget
*parent
)
2243 test_desc_win
.parent
= parent
;
2244 description_window_create(&test_desc_win
);
2247 #ifndef USE_ALT_ADDRBOOK
2248 static void prefs_matcher_addressbook_select(void)
2250 const gchar
*folderpath
= NULL
;
2251 gchar
*new_path
= NULL
;
2253 folderpath
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))));
2254 new_path
= addressbook_folder_selection(folderpath
);
2256 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), new_path
);
2266 static GtkListStore
* prefs_matcher_create_data_store(void)
2268 return gtk_list_store_new(N_PREFS_MATCHER_COLUMNS
,
2274 static void prefs_matcher_list_view_insert_matcher(GtkWidget
*list_view
,
2275 GtkTreeIter
*row_iter
,
2276 const gchar
*matcher
,
2280 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
2281 (GTK_TREE_VIEW(list_view
)));
2283 if (row_iter
== NULL
) {
2285 gtk_list_store_append(list_store
, &iter
);
2287 /* change existing */
2291 gtk_list_store_set(list_store
, &iter
,
2292 PREFS_MATCHER_COND
, matcher
,
2293 PREFS_MATCHER_COND_VALID
, is_valid
,
2297 static GtkWidget
*prefs_matcher_list_view_create(void)
2299 GtkTreeView
*list_view
;
2300 GtkTreeSelection
*selector
;
2301 GtkTreeModel
*model
;
2303 model
= GTK_TREE_MODEL(prefs_matcher_create_data_store());
2304 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
2305 g_object_unref(model
);
2307 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
2308 gtk_tree_view_set_reorderable(list_view
, TRUE
);
2310 selector
= gtk_tree_view_get_selection(list_view
);
2311 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
2312 gtk_tree_selection_set_select_function(selector
, prefs_matcher_selected
,
2315 /* create the columns */
2316 prefs_matcher_create_list_view_columns(GTK_WIDGET(list_view
));
2318 return GTK_WIDGET(list_view
);
2321 static void prefs_matcher_create_list_view_columns(GtkWidget
*list_view
)
2323 GtkTreeViewColumn
*column
;
2324 GtkCellRenderer
*renderer
;
2326 renderer
= gtk_cell_renderer_text_new();
2327 column
= gtk_tree_view_column_new_with_attributes
2328 (_("Current condition rules"),
2330 "text", PREFS_MATCHER_COND
,
2332 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
2335 static void prefs_matcher_set_criteria(const gint criteria
)
2337 gint match_criteria
= 0;
2340 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2341 match_criteria
= MATCH_ABOOK
;
2344 match_criteria
= MATCH_ALL
;
2346 case CRITERIA_AGE_GREATER
:
2347 case CRITERIA_AGE_LOWER
:
2348 case CRITERIA_AGE_GREATER_HOURS
:
2349 case CRITERIA_AGE_LOWER_HOURS
:
2350 match_criteria
= MATCH_AGE
;
2352 case CRITERIA_DATE_AFTER
:
2353 case CRITERIA_DATE_BEFORE
:
2354 match_criteria
= MATCH_DATE
;
2356 case CRITERIA_SCORE_GREATER
:
2357 case CRITERIA_SCORE_LOWER
:
2358 case CRITERIA_SCORE_EQUAL
:
2359 match_criteria
= MATCH_SCORE
;
2361 case CRITERIA_SIZE_GREATER
:
2362 case CRITERIA_SIZE_SMALLER
:
2363 case CRITERIA_SIZE_EQUAL
:
2364 match_criteria
= MATCH_SIZE
;
2366 case CRITERIA_SUBJECT
:
2370 case CRITERIA_TO_OR_CC
:
2371 case CRITERIA_NEWSGROUPS
:
2372 case CRITERIA_MESSAGEID
:
2373 case CRITERIA_INREPLYTO
:
2374 case CRITERIA_REFERENCES
:
2375 case CRITERIA_HEADER
:
2376 match_criteria
= MATCH_HEADER
;
2378 case CRITERIA_HEADERS_PART
:
2379 case CRITERIA_HEADERS_CONT
:
2380 case CRITERIA_BODY_PART
:
2381 case CRITERIA_MESSAGE
:
2382 match_criteria
= MATCH_PHRASE
;
2385 match_criteria
= MATCH_TEST
;
2387 case CRITERIA_COLORLABEL
:
2388 match_criteria
= MATCH_LABEL
;
2391 case CRITERIA_TAGGED
:
2392 match_criteria
= MATCH_TAGS
;
2394 case CRITERIA_UNREAD
:
2396 case CRITERIA_MARKED
:
2397 case CRITERIA_DELETED
:
2398 case CRITERIA_REPLIED
:
2399 case CRITERIA_FORWARDED
:
2400 case CRITERIA_LOCKED
:
2402 case CRITERIA_HAS_ATTACHMENT
:
2403 case CRITERIA_SIGNED
:
2404 match_criteria
= MATCH_FLAG
;
2406 case CRITERIA_PARTIAL
:
2407 match_criteria
= MATCH_PARTIAL
;
2409 case CRITERIA_IGNORE_THREAD
:
2410 case CRITERIA_WATCH_THREAD
:
2411 match_criteria
= MATCH_THREAD
;
2415 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo
),
2418 switch(match_criteria
) {
2420 if(criteria
!= CRITERIA_HEADER
)
2421 combobox_select_by_data(GTK_COMBO_BOX(
2422 matcher
.headers_combo
),
2430 combobox_select_by_data(GTK_COMBO_BOX(
2431 matcher
.match_combo
), criteria
);
2435 combobox_select_by_data(GTK_COMBO_BOX(
2436 matcher
.criteria_combo2
), criteria
);
2441 static gboolean
prefs_matcher_selected(GtkTreeSelection
*selector
,
2442 GtkTreeModel
*model
,
2444 gboolean currently_selected
,
2449 gboolean negative_cond
;
2456 if (currently_selected
)
2459 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
2462 gtk_tree_model_get(model
, &iter
,
2463 PREFS_MATCHER_COND_VALID
, &is_valid
,
2464 PREFS_MATCHER_COND
, &matcher_str
,
2468 g_free(matcher_str
);
2469 prefs_matcher_reset_condition();
2473 negative_cond
= FALSE
;
2475 prop
= matcher_parser_get_prop(matcher_str
);
2477 g_free(matcher_str
);
2481 criteria
= prefs_matcher_get_criteria_from_matching(prop
->criteria
);
2482 prefs_matcher_set_criteria(criteria
);
2484 switch(prop
->criteria
) {
2485 case MATCHCRITERIA_NOT_UNREAD
:
2486 case MATCHCRITERIA_NOT_NEW
:
2487 case MATCHCRITERIA_NOT_MARKED
:
2488 case MATCHCRITERIA_NOT_DELETED
:
2489 case MATCHCRITERIA_NOT_REPLIED
:
2490 case MATCHCRITERIA_NOT_FORWARDED
:
2491 case MATCHCRITERIA_NOT_LOCKED
:
2492 case MATCHCRITERIA_NOT_SPAM
:
2493 case MATCHCRITERIA_HAS_NO_ATTACHMENT
:
2494 case MATCHCRITERIA_NOT_SIGNED
:
2495 case MATCHCRITERIA_NOT_PARTIAL
:
2496 case MATCHCRITERIA_NOT_COLORLABEL
:
2497 case MATCHCRITERIA_NOT_IGNORE_THREAD
:
2498 case MATCHCRITERIA_NOT_WATCH_THREAD
:
2499 case MATCHCRITERIA_NOT_SUBJECT
:
2500 case MATCHCRITERIA_NOT_FROM
:
2501 case MATCHCRITERIA_NOT_TO
:
2502 case MATCHCRITERIA_NOT_CC
:
2503 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2504 case MATCHCRITERIA_NOT_TAG
:
2505 case MATCHCRITERIA_NOT_TAGGED
:
2506 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2507 case MATCHCRITERIA_NOT_MESSAGEID
:
2508 case MATCHCRITERIA_NOT_INREPLYTO
:
2509 case MATCHCRITERIA_NOT_REFERENCES
:
2510 case MATCHCRITERIA_NOT_HEADER
:
2511 case MATCHCRITERIA_NOT_HEADERS_PART
:
2512 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2513 case MATCHCRITERIA_NOT_MESSAGE
:
2514 case MATCHCRITERIA_NOT_BODY_PART
:
2515 case MATCHCRITERIA_NOT_TEST
:
2516 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2517 negative_cond
= TRUE
;
2521 switch(prop
->criteria
) {
2522 case MATCHCRITERIA_ALL
:
2525 case MATCHCRITERIA_NOT_SUBJECT
:
2526 case MATCHCRITERIA_NOT_FROM
:
2527 case MATCHCRITERIA_NOT_TO
:
2528 case MATCHCRITERIA_NOT_CC
:
2529 case MATCHCRITERIA_NOT_TO_AND_NOT_CC
:
2530 case MATCHCRITERIA_NOT_TAG
:
2531 case MATCHCRITERIA_NOT_NEWSGROUPS
:
2532 case MATCHCRITERIA_NOT_MESSAGEID
:
2533 case MATCHCRITERIA_NOT_INREPLYTO
:
2534 case MATCHCRITERIA_NOT_REFERENCES
:
2535 case MATCHCRITERIA_NOT_HEADERS_PART
:
2536 case MATCHCRITERIA_NOT_HEADERS_CONT
:
2537 case MATCHCRITERIA_NOT_BODY_PART
:
2538 case MATCHCRITERIA_NOT_MESSAGE
:
2539 case MATCHCRITERIA_NOT_TEST
:
2540 case MATCHCRITERIA_SUBJECT
:
2541 case MATCHCRITERIA_FROM
:
2542 case MATCHCRITERIA_TO
:
2543 case MATCHCRITERIA_CC
:
2544 case MATCHCRITERIA_TO_OR_CC
:
2545 case MATCHCRITERIA_TAG
:
2546 case MATCHCRITERIA_NEWSGROUPS
:
2547 case MATCHCRITERIA_MESSAGEID
:
2548 case MATCHCRITERIA_INREPLYTO
:
2549 case MATCHCRITERIA_REFERENCES
:
2550 case MATCHCRITERIA_HEADERS_PART
:
2551 case MATCHCRITERIA_HEADERS_CONT
:
2552 case MATCHCRITERIA_BODY_PART
:
2553 case MATCHCRITERIA_MESSAGE
:
2554 case MATCHCRITERIA_TEST
:
2555 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2558 case MATCHCRITERIA_DATE_AFTER
:
2559 case MATCHCRITERIA_DATE_BEFORE
:
2561 procheader_date_parse_to_tm(prop
->expr
, <
, zone
);
2562 gtk_calendar_select_day(GTK_CALENDAR(matcher
.calendar
), lt
.tm_mday
);
2563 gtk_calendar_select_month(GTK_CALENDAR(matcher
.calendar
), lt
.tm_mon
, lt
.tm_year
+ 1900);
2564 gtkut_time_select_select_by_time(GTK_COMBO_BOX(matcher
.time_entry
), lt
.tm_hour
, lt
.tm_min
);
2568 case MATCHCRITERIA_FOUND_IN_ADDRESSBOOK
:
2569 case MATCHCRITERIA_NOT_FOUND_IN_ADDRESSBOOK
:
2574 /* matcher expressions contain UNtranslated "Any"/"All",
2575 select the relevant translated combo item */
2576 if (strcasecmp(prop
->header
, "All") == 0)
2577 header
= (gchar
*)C_("Filtering Matcher Menu", "All");
2579 if (strcasecmp(prop
->header
, "Any") == 0)
2582 header
= prop
->header
;
2583 if (strcasecmp(prop
->expr
, "Any") == 0)
2588 gtk_entry_set_text(GTK_ENTRY(matcher
.header_addr_entry
), header
);
2589 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((matcher
.addressbook_folder_combo
)))), expr
);
2593 case MATCHCRITERIA_AGE_GREATER
:
2594 case MATCHCRITERIA_AGE_LOWER
:
2595 if(prop
->value
>= 7 && !(prop
->value
% 7)) {
2596 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2598 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2599 matcher
.numeric_entry
), prop
->value
/7);
2601 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2603 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2604 matcher
.numeric_entry
), prop
->value
);
2608 case MATCHCRITERIA_AGE_GREATER_HOURS
:
2609 case MATCHCRITERIA_AGE_LOWER_HOURS
:
2610 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2612 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2613 matcher
.numeric_entry
), prop
->value
);
2616 case MATCHCRITERIA_SCORE_GREATER
:
2617 case MATCHCRITERIA_SCORE_LOWER
:
2618 case MATCHCRITERIA_SCORE_EQUAL
:
2619 gtk_spin_button_set_value(GTK_SPIN_BUTTON(matcher
.numeric_entry
),
2623 case MATCHCRITERIA_SIZE_GREATER
:
2624 case MATCHCRITERIA_SIZE_SMALLER
:
2625 case MATCHCRITERIA_SIZE_EQUAL
:
2626 if(prop
->value
>= MB_SIZE
&& !(prop
->value
% MB_SIZE
)) {
2627 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2629 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2630 matcher
.numeric_entry
), prop
->value
/MB_SIZE
);
2631 } else if(prop
->value
>= KB_SIZE
&& !(prop
->value
% KB_SIZE
)) {
2632 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2634 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2635 matcher
.numeric_entry
), prop
->value
/KB_SIZE
);
2637 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2639 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
2640 matcher
.numeric_entry
), prop
->value
);
2644 case MATCHCRITERIA_NOT_COLORLABEL
:
2645 case MATCHCRITERIA_COLORLABEL
:
2646 colorlabel_set_combobox_colormenu_active(
2647 GTK_COMBO_BOX(matcher
.color_optmenu
), prop
->value
);
2650 case MATCHCRITERIA_NOT_HEADER
:
2651 case MATCHCRITERIA_HEADER
:
2652 gtk_entry_set_text(GTK_ENTRY(matcher
.header_entry
), prop
->header
);
2653 gtk_entry_set_text(GTK_ENTRY(matcher
.string_entry
), prop
->expr
);
2658 case CRITERIA_SUBJECT
:
2662 case CRITERIA_TO_OR_CC
:
2663 case CRITERIA_NEWSGROUPS
:
2664 case CRITERIA_MESSAGEID
:
2665 case CRITERIA_INREPLYTO
:
2666 case CRITERIA_REFERENCES
:
2667 case CRITERIA_HEADER
:
2668 case CRITERIA_HEADERS_PART
:
2669 case CRITERIA_HEADERS_CONT
:
2670 case CRITERIA_BODY_PART
:
2671 case CRITERIA_MESSAGE
:
2673 case CRITERIA_TAGGED
:
2675 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo
),
2676 negative_cond
? PREDICATE_DOES_NOT_CONTAIN
:
2677 PREDICATE_CONTAINS
);
2679 case CRITERIA_FOUND_IN_ADDRESSBOOK
:
2680 case CRITERIA_UNREAD
:
2682 case CRITERIA_MARKED
:
2683 case CRITERIA_DELETED
:
2684 case CRITERIA_REPLIED
:
2685 case CRITERIA_FORWARDED
:
2686 case CRITERIA_LOCKED
:
2688 case CRITERIA_HAS_ATTACHMENT
:
2689 case CRITERIA_SIGNED
:
2690 case CRITERIA_COLORLABEL
:
2691 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.match_combo2
),
2692 negative_cond
? PREDICATE_FLAG_DISABLED
:
2693 PREDICATE_FLAG_ENABLED
);
2695 case CRITERIA_WATCH_THREAD
:
2696 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2697 negative_cond
? THREAD_NOT_WATCHED
:
2700 case CRITERIA_IGNORE_THREAD
:
2701 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2702 negative_cond
? THREAD_NOT_IGNORED
:
2705 case CRITERIA_PARTIAL
:
2706 gtk_combo_box_set_active(GTK_COMBO_BOX(matcher
.criteria_combo2
),
2707 negative_cond
? PREDICATE_FLAG_DISABLED
:
2708 PREDICATE_FLAG_ENABLED
);
2712 switch(prop
->matchtype
) {
2713 case MATCHTYPE_MATCH
:
2714 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2715 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2718 case MATCHTYPE_MATCHCASE
:
2719 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), FALSE
);
2720 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2723 case MATCHTYPE_REGEXP
:
2724 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2725 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), TRUE
);
2728 case MATCHTYPE_REGEXPCASE
:
2729 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.regexp_checkbtn
), TRUE
);
2730 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matcher
.case_checkbtn
), FALSE
);
2734 g_free(matcher_str
);