2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2002 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 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <gdk/gdkkeysyms.h>
37 #include "prefs_filter.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
46 #include "alertpanel.h"
49 static struct Filter {
54 GtkWidget *hdr_combo1;
55 GtkWidget *hdr_combo2;
56 GtkWidget *hdr_entry1;
57 GtkWidget *hdr_entry2;
58 GtkWidget *key_entry1;
59 GtkWidget *key_entry2;
60 GtkWidget *pred_combo1;
61 GtkWidget *pred_combo2;
62 GtkWidget *pred_entry1;
63 GtkWidget *pred_entry2;
67 GtkWidget *dest_entry;
68 GtkWidget *regex_chkbtn;
70 GtkWidget *destsel_btn;
71 GtkWidget *dest_radiobtn;
72 GtkWidget *notrecv_radiobtn;
74 GtkWidget *cond_clist;
78 parameter name, default value, pointer to the prefs variable, data type,
79 pointer to the widget pointer,
80 pointer to the function for data setting,
81 pointer to the function for widget setting
84 /* widget creating functions */
85 static void prefs_filter_create (void);
87 static void prefs_filter_set_dialog (void);
88 static void prefs_filter_set_list (void);
89 static gint prefs_filter_clist_set_row (gint row);
91 /* callback functions */
92 static void prefs_filter_select_dest_cb (void);
93 static void prefs_filter_register_cb (void);
94 static void prefs_filter_substitute_cb (void);
95 static void prefs_filter_delete_cb (void);
96 static void prefs_filter_up (void);
97 static void prefs_filter_down (void);
98 static void prefs_filter_select (GtkCList *clist,
102 static void prefs_filter_row_move (GtkCList *clist,
106 static void prefs_filter_dest_radio_button_toggled (void);
107 static void prefs_filter_notrecv_radio_button_toggled (void);
108 static void prefs_filter_regex_check_button_toggled (void);
110 static gint prefs_filter_deleted (GtkWidget *widget,
113 static void prefs_filter_key_pressed (GtkWidget *widget,
116 static void prefs_filter_cancel (void);
117 static void prefs_filter_ok (void);
119 void prefs_filter_open(void)
121 if (prefs_rc_is_readonly(FILTER_RC))
126 if (!filter.window) {
127 prefs_filter_create();
130 manage_window_set_transient(GTK_WINDOW(filter.window));
131 gtk_widget_grab_focus(filter.ok_btn);
133 prefs_filter_set_dialog();
135 gtk_widget_show(filter.window);
138 static void prefs_filter_create(void)
143 GtkWidget *cancel_btn;
144 GtkWidget *confirm_area;
151 GtkWidget *hdr_label;
152 GtkWidget *hdr_combo1;
153 GtkWidget *hdr_combo2;
154 GtkWidget *key_label;
155 GtkWidget *key_entry1;
156 GtkWidget *key_entry2;
157 GtkWidget *pred_label;
158 GtkWidget *pred_combo1;
159 GtkWidget *pred_entry1;
160 GtkWidget *pred_combo2;
161 GtkWidget *pred_entry2;
164 GtkWidget *dest_hbox;
165 GtkWidget *dest_entry;
166 GtkWidget *destsel_btn;
167 GtkWidget *dest_radiobtn;
168 GtkWidget *notrecv_radiobtn;
169 GSList *recv_group = NULL;
171 GtkWidget *regex_chkbtn;
177 GtkWidget *subst_btn;
180 GtkWidget *cond_hbox;
181 GtkWidget *cond_scrolledwin;
182 GtkWidget *cond_clist;
188 gchar *title[] = {_("Registered rules")};
190 debug_print(_("Creating filter setting window...\n"));
192 window = gtk_window_new (GTK_WINDOW_DIALOG);
193 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
194 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
195 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
196 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
198 vbox = gtk_vbox_new (FALSE, 6);
199 gtk_widget_show (vbox);
200 gtk_container_add (GTK_CONTAINER (window), vbox);
202 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
203 &cancel_btn, _("Cancel"), NULL, NULL);
204 gtk_widget_show (confirm_area);
205 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
206 gtk_widget_grab_default (ok_btn);
209 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
210 NULL, NULL, NULL, NULL);
211 gtk_widget_show (confirm_area);
212 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
213 gtk_widget_grab_default (close_btn);
216 gtk_window_set_title (GTK_WINDOW(window),
217 _("Filter setting"));
218 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
219 GTK_SIGNAL_FUNC(prefs_filter_deleted), NULL);
220 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
221 GTK_SIGNAL_FUNC(prefs_filter_key_pressed), NULL);
222 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
223 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
224 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
225 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
226 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
227 GTK_SIGNAL_FUNC(prefs_filter_ok), NULL);
228 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
229 GTK_SIGNAL_FUNC(prefs_filter_cancel), NULL);
231 vbox1 = gtk_vbox_new (FALSE, VSPACING);
232 gtk_widget_show (vbox1);
233 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
234 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
236 table1 = gtk_table_new (3, 4, FALSE);
237 gtk_widget_show (table1);
238 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
239 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
240 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
242 op_label = gtk_label_new (_("Operator"));
243 gtk_widget_show (op_label);
244 gtk_table_attach (GTK_TABLE (table1), op_label, 0, 1, 0, 1,
246 gtk_misc_set_alignment (GTK_MISC (op_label), 0, 0.5);
248 op_combo = gtk_combo_new ();
249 gtk_widget_show (op_combo);
250 gtk_table_attach (GTK_TABLE (table1), op_combo, 0, 1, 2, 3,
252 gtk_widget_set_usize (op_combo, 52, -1);
253 gtkut_combo_set_items (GTK_COMBO (op_combo), "and", "or", NULL);
255 op_entry = GTK_COMBO (op_combo)->entry;
256 gtk_entry_set_editable (GTK_ENTRY (op_entry), FALSE);
258 hdr_label = gtk_label_new (_("Header"));
259 gtk_widget_show (hdr_label);
260 gtk_table_attach (GTK_TABLE (table1), hdr_label, 1, 2, 0, 1,
262 gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
264 hdr_combo1 = gtk_combo_new ();
265 gtk_widget_show (hdr_combo1);
266 gtk_table_attach (GTK_TABLE (table1), hdr_combo1, 1, 2, 1, 2,
268 gtk_widget_set_usize (hdr_combo1, 96, -1);
269 gtkut_combo_set_items (GTK_COMBO (hdr_combo1),
270 "Subject", "From", "To", "Cc", "Reply-To",
272 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
275 hdr_combo2 = gtk_combo_new ();
276 gtk_widget_show (hdr_combo2);
277 gtk_table_attach (GTK_TABLE (table1), hdr_combo2, 1, 2, 2, 3,
279 gtk_widget_set_usize (hdr_combo2, 96, -1);
280 gtkut_combo_set_items (GTK_COMBO (hdr_combo2), _("(none)"),
281 "Subject", "From", "To", "Cc", "Reply-To",
283 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
286 key_label = gtk_label_new (_("Keyword"));
287 gtk_widget_show (key_label);
288 gtk_table_attach (GTK_TABLE (table1), key_label, 2, 3, 0, 1,
289 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
291 gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
293 key_entry1 = gtk_entry_new ();
294 gtk_widget_show (key_entry1);
295 gtk_widget_set_usize (key_entry1, 128, -1);
296 gtk_table_attach (GTK_TABLE (table1), key_entry1, 2, 3, 1, 2,
297 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
300 key_entry2 = gtk_entry_new ();
301 gtk_widget_show (key_entry2);
302 gtk_widget_set_usize (key_entry2, 128, -1);
303 gtk_table_attach (GTK_TABLE (table1), key_entry2, 2, 3, 2, 3,
304 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
307 pred_label = gtk_label_new (_("Predicate"));
308 gtk_widget_show (pred_label);
309 gtk_table_attach (GTK_TABLE (table1), pred_label, 3, 4, 0, 1,
311 gtk_misc_set_alignment (GTK_MISC (pred_label), 0, 0.5);
313 pred_combo1 = gtk_combo_new ();
314 gtk_widget_show (pred_combo1);
315 gtk_table_attach (GTK_TABLE (table1), pred_combo1, 3, 4, 1, 2,
317 gtk_widget_set_usize (pred_combo1, 92, -1);
318 gtkut_combo_set_items (GTK_COMBO (pred_combo1),
319 _("contains"), _("not contain"), NULL);
321 pred_entry1 = GTK_COMBO (pred_combo1)->entry;
322 gtk_entry_set_editable (GTK_ENTRY (pred_entry1), FALSE);
324 pred_combo2 = gtk_combo_new ();
325 gtk_widget_show (pred_combo2);
326 gtk_table_attach (GTK_TABLE (table1), pred_combo2, 3, 4, 2, 3,
328 gtk_widget_set_usize (pred_combo2, 92, -1);
329 gtkut_combo_set_items (GTK_COMBO (pred_combo2),
330 _("contains"), _("not contain"), NULL);
332 pred_entry2 = GTK_COMBO (pred_combo2)->entry;
333 gtk_entry_set_editable (GTK_ENTRY (pred_entry2), FALSE);
337 vbox2 = gtk_vbox_new (FALSE, VSPACING_NARROW);
338 gtk_widget_show (vbox2);
339 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
341 dest_hbox = gtk_hbox_new (FALSE, 8);
342 gtk_widget_show (dest_hbox);
343 gtk_box_pack_start (GTK_BOX (vbox2), dest_hbox, FALSE, TRUE, 0);
346 gtk_radio_button_new_with_label (recv_group, _("Destination"));
347 recv_group = gtk_radio_button_group (GTK_RADIO_BUTTON (dest_radiobtn));
348 gtk_widget_show (dest_radiobtn);
349 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_radiobtn,
351 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
353 (GTK_OBJECT (dest_radiobtn), "toggled",
354 GTK_SIGNAL_FUNC (prefs_filter_dest_radio_button_toggled),
357 dest_entry = gtk_entry_new ();
358 gtk_widget_show (dest_entry);
359 gtk_widget_set_usize (dest_entry, DEFAULT_ENTRY_WIDTH, -1);
360 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_entry, TRUE, TRUE, 0);
361 gtk_entry_set_editable (GTK_ENTRY (dest_entry), FALSE);
363 destsel_btn = gtk_button_new_with_label (_(" Select... "));
364 gtk_widget_show (destsel_btn);
365 gtk_box_pack_start (GTK_BOX (dest_hbox), destsel_btn, FALSE, FALSE, 0);
366 gtk_signal_connect (GTK_OBJECT (destsel_btn), "clicked",
367 GTK_SIGNAL_FUNC (prefs_filter_select_dest_cb),
370 PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
372 (GTK_OBJECT (regex_chkbtn), "toggled",
373 GTK_SIGNAL_FUNC (prefs_filter_regex_check_button_toggled),
376 notrecv_radiobtn = gtk_radio_button_new_with_label
377 (recv_group, _("Don't receive"));
378 recv_group = gtk_radio_button_group
379 (GTK_RADIO_BUTTON (notrecv_radiobtn));
380 gtk_widget_show (notrecv_radiobtn);
381 gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
383 (GTK_OBJECT (notrecv_radiobtn), "toggled",
384 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
387 /* register / substitute / delete */
389 reg_hbox = gtk_hbox_new (FALSE, 4);
390 gtk_widget_show (reg_hbox);
391 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
393 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
394 gtk_widget_show (arrow);
395 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
396 gtk_widget_set_usize (arrow, -1, 16);
398 btn_hbox = gtk_hbox_new (TRUE, 4);
399 gtk_widget_show (btn_hbox);
400 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
402 reg_btn = gtk_button_new_with_label (_("Register"));
403 gtk_widget_show (reg_btn);
404 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
405 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
406 GTK_SIGNAL_FUNC (prefs_filter_register_cb), NULL);
408 subst_btn = gtk_button_new_with_label (_(" Substitute "));
409 gtk_widget_show (subst_btn);
410 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
411 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
412 GTK_SIGNAL_FUNC (prefs_filter_substitute_cb),
415 del_btn = gtk_button_new_with_label (_("Delete"));
416 gtk_widget_show (del_btn);
417 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
418 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
419 GTK_SIGNAL_FUNC (prefs_filter_delete_cb), NULL);
421 cond_hbox = gtk_hbox_new (FALSE, 8);
422 gtk_widget_show (cond_hbox);
423 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
425 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
426 gtk_widget_show (cond_scrolledwin);
427 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
428 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
430 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
431 GTK_POLICY_AUTOMATIC,
432 GTK_POLICY_AUTOMATIC);
434 cond_clist = gtk_clist_new_with_titles(1, title);
435 gtk_widget_show (cond_clist);
436 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
437 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
438 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
439 GTK_SELECTION_BROWSE);
440 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
442 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
443 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
444 gtk_signal_connect (GTK_OBJECT (cond_clist), "row_move",
445 GTK_SIGNAL_FUNC (prefs_filter_row_move), NULL);
447 btn_vbox = gtk_vbox_new (FALSE, 8);
448 gtk_widget_show (btn_vbox);
449 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
451 up_btn = gtk_button_new_with_label (_("Up"));
452 gtk_widget_show (up_btn);
453 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
454 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
455 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
457 down_btn = gtk_button_new_with_label (_("Down"));
458 gtk_widget_show (down_btn);
459 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
460 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
461 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
463 gtk_widget_show_all(window);
465 filter.window = window;
466 filter.ok_btn = ok_btn;
468 filter.hdr_combo1 = hdr_combo1;
469 filter.hdr_combo2 = hdr_combo2;
470 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
471 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
472 filter.key_entry1 = key_entry1;
473 filter.key_entry2 = key_entry2;
474 filter.pred_combo1 = pred_combo1;
475 filter.pred_combo2 = pred_combo2;
476 filter.pred_entry1 = pred_entry1;
477 filter.pred_entry2 = pred_entry2;
478 filter.op_combo = op_combo;
479 filter.op_entry = op_entry;
481 filter.dest_entry = dest_entry;
482 filter.destsel_btn = destsel_btn;
483 filter.dest_radiobtn = dest_radiobtn;
484 filter.notrecv_radiobtn = notrecv_radiobtn;
485 filter.regex_chkbtn = regex_chkbtn;
487 filter.cond_clist = cond_clist;
490 void prefs_filter_read_config(void)
494 gchar buf[PREFSBUFSIZE];
497 debug_print(_("Reading filter configuration...\n"));
499 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
500 if ((fp = fopen(rcpath, "r")) == NULL) {
501 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
507 /* remove all previous filter list */
508 while (prefs_common.fltlist != NULL) {
509 flt = (Filter *)prefs_common.fltlist->data;
511 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
515 while (fgets(buf, sizeof(buf), fp) != NULL) {
517 flt = filter_read_str(buf);
519 prefs_common.fltlist =
520 g_slist_append(prefs_common.fltlist, flt);
527 void prefs_filter_write_config(void)
533 debug_print(_("Writing filter configuration...\n"));
535 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
536 if ((pfile = prefs_write_open(rcpath)) == NULL) {
537 g_warning(_("failed to write configuration to file\n"));
542 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
543 Filter *flt = (Filter *)cur->data;
546 fstr = filter_get_str(flt);
547 if (fputs(fstr, pfile->fp) == EOF ||
548 fputc('\n', pfile->fp) == EOF) {
549 FILE_OP_ERROR(rcpath, "fputs || fputc");
550 prefs_write_close_revert(pfile);
560 if (prefs_write_close(pfile) < 0) {
561 g_warning(_("failed to write configuration to file\n"));
566 static void prefs_filter_set_dialog(void)
568 GtkCList *clist = GTK_CLIST(filter.cond_clist);
573 gtk_clist_freeze(clist);
574 gtk_clist_clear(clist);
576 cond_str[0] = _("(New)");
577 row = gtk_clist_append(clist, cond_str);
578 gtk_clist_set_row_data(clist, row, NULL);
580 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
581 Filter *flt = (Filter *)cur->data;
583 cond_str[0] = filter_get_str(flt);
584 subst_char(cond_str[0], '\t', ':');
585 row = gtk_clist_append(clist, cond_str);
586 gtk_clist_set_row_data(clist, row, flt);
591 gtk_clist_thaw(clist);
594 static void prefs_filter_set_list(void)
599 g_slist_free(prefs_common.fltlist);
600 prefs_common.fltlist = NULL;
602 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
604 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
610 #define GET_ENTRY(entry) \
611 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
613 static gint prefs_filter_clist_set_row(gint row)
615 GtkCList *clist = GTK_CLIST(filter.cond_clist);
620 g_return_val_if_fail(row != 0, -1);
622 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
623 GET_ENTRY(filter.dest_entry);
625 entry_text = FILTER_NOT_RECEIVE;
626 if (entry_text[0] == '\0') {
627 alertpanel_error(_("Destination is not set."));
630 GET_ENTRY(filter.hdr_entry1);
631 if (entry_text[0] == '\0') {
632 alertpanel_error(_("Header name is not set."));
636 flt = g_new0(Filter, 1);
638 flt->name1 = g_strdup(entry_text);
640 GET_ENTRY(filter.key_entry1);
641 if (entry_text[0] != '\0')
642 flt->body1 = g_strdup(entry_text);
644 GET_ENTRY(filter.hdr_entry2);
645 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
646 flt->name2 = g_strdup(entry_text);
648 GET_ENTRY(filter.key_entry2);
649 if (entry_text[0] != '\0')
650 flt->body2 = g_strdup(entry_text);
653 if (gtk_toggle_button_get_active
654 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
655 flt->flag1 = flt->flag2 = FLT_REGEX;
657 GET_ENTRY(filter.pred_entry1);
658 if (!strcmp(entry_text, _("contains")))
659 flt->flag1 |= FLT_CONTAIN;
660 GET_ENTRY(filter.pred_entry2);
661 if (!strcmp(entry_text, _("contains")))
662 flt->flag2 |= FLT_CONTAIN;
664 GET_ENTRY(filter.op_entry);
665 if (!strcmp(entry_text, "and"))
670 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
671 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
672 flt->dest = g_strdup(entry_text);
673 flt->action = FLT_MOVE;
675 flt->action = FLT_NOTRECV;
677 cond_str[0] = filter_get_str(flt);
678 subst_char(cond_str[0], '\t', ':');
681 row = gtk_clist_append(clist, cond_str);
685 gtk_clist_set_text(clist, row, 0, cond_str[0]);
686 tmpflt = gtk_clist_get_row_data(clist, row);
691 gtk_clist_set_row_data(clist, row, flt);
695 prefs_filter_set_list();
700 static void prefs_filter_select_dest_cb(void)
704 dest = foldersel_folder_sel(NULL, NULL);
707 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
710 static void prefs_filter_register_cb(void)
712 prefs_filter_clist_set_row(-1);
715 static void prefs_filter_substitute_cb(void)
717 GtkCList *clist = GTK_CLIST(filter.cond_clist);
721 if (!clist->selection) return;
723 row = GPOINTER_TO_INT(clist->selection->data);
724 if (row == 0) return;
726 flt = gtk_clist_get_row_data(clist, row);
729 prefs_filter_clist_set_row(row);
732 static void prefs_filter_delete_cb(void)
734 GtkCList *clist = GTK_CLIST(filter.cond_clist);
738 if (!clist->selection) return;
739 row = GPOINTER_TO_INT(clist->selection->data);
740 if (row == 0) return;
742 if (alertpanel(_("Delete rule"),
743 _("Do you really want to delete this rule?"),
744 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
747 flt = gtk_clist_get_row_data(clist, row);
749 gtk_clist_remove(clist, row);
750 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
753 static void prefs_filter_up(void)
755 GtkCList *clist = GTK_CLIST(filter.cond_clist);
758 if (!clist->selection) return;
760 row = GPOINTER_TO_INT(clist->selection->data);
762 gtk_clist_row_move(clist, row, row - 1);
765 static void prefs_filter_down(void)
767 GtkCList *clist = GTK_CLIST(filter.cond_clist);
770 if (!clist->selection) return;
772 row = GPOINTER_TO_INT(clist->selection->data);
773 if (row > 0 && row < clist->rows - 1)
774 gtk_clist_row_move(clist, row, row + 1);
777 #define ENTRY_SET_TEXT(entry, str) \
778 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
780 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
784 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
785 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
789 flt = gtk_clist_get_row_data(clist, row);
793 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
794 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
795 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
796 ENTRY_SET_TEXT(filter.hdr_entry2,
797 flt->name2 ? flt->name2 : _("(none)"));
798 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
800 ENTRY_SET_TEXT(filter.pred_entry1,
801 FLT_IS_CONTAIN(flt->flag1)
802 ? _("contains") : _("not contain"));
803 ENTRY_SET_TEXT(filter.pred_entry2,
804 FLT_IS_CONTAIN(flt->flag2)
805 ? _("contains") : _("not contain"));
807 is_regex = FLT_IS_REGEX(flt->flag1);
808 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
809 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
810 gtk_toggle_button_set_active
811 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
813 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
814 flt->cond == FLT_OR ? "or" : "and");
815 if (flt->action == FLT_NOTRECV)
816 gtk_toggle_button_set_active
817 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
819 gtk_toggle_button_set_active
820 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
823 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
826 prefs_filter_set_list();
827 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
828 gtk_clist_moveto(clist, dest_row, -1,
829 source_row < dest_row ? 1.0 : 0.0, 0.0);
833 static void prefs_filter_dest_radio_button_toggled(void)
835 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
836 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
839 static void prefs_filter_notrecv_radio_button_toggled(void)
841 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
842 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
845 static void prefs_filter_regex_check_button_toggled(void)
849 is_regex = gtk_toggle_button_get_active
850 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
851 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
852 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
855 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
858 prefs_filter_cancel();
862 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
865 if (event && event->keyval == GDK_Escape)
866 prefs_filter_cancel();
869 static void prefs_filter_ok(void)
871 prefs_filter_write_config();
872 gtk_widget_hide(filter.window);
876 static void prefs_filter_cancel(void)
878 prefs_filter_read_config();
879 gtk_widget_hide(filter.window);
880 inc_autocheck_timer_set();