2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 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))
124 inc_autocheck_timer_remove();
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"));
371 //gtk_widget_set_sensitive(regex_chkbtn, FALSE);
373 (GTK_OBJECT (regex_chkbtn), "toggled",
374 GTK_SIGNAL_FUNC (prefs_filter_regex_check_button_toggled),
377 notrecv_radiobtn = gtk_radio_button_new_with_label
378 (recv_group, _("Don't receive"));
379 recv_group = gtk_radio_button_group
380 (GTK_RADIO_BUTTON (notrecv_radiobtn));
381 gtk_widget_show (notrecv_radiobtn);
382 gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
384 (GTK_OBJECT (notrecv_radiobtn), "toggled",
385 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
388 /* register / substitute / delete */
390 reg_hbox = gtk_hbox_new (FALSE, 4);
391 gtk_widget_show (reg_hbox);
392 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
394 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
395 gtk_widget_show (arrow);
396 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
397 gtk_widget_set_usize (arrow, -1, 16);
399 btn_hbox = gtk_hbox_new (TRUE, 4);
400 gtk_widget_show (btn_hbox);
401 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
403 reg_btn = gtk_button_new_with_label (_("Register"));
404 gtk_widget_show (reg_btn);
405 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
406 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
407 GTK_SIGNAL_FUNC (prefs_filter_register_cb), NULL);
409 subst_btn = gtk_button_new_with_label (_(" Substitute "));
410 gtk_widget_show (subst_btn);
411 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
412 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
413 GTK_SIGNAL_FUNC (prefs_filter_substitute_cb),
416 del_btn = gtk_button_new_with_label (_("Delete"));
417 gtk_widget_show (del_btn);
418 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
419 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
420 GTK_SIGNAL_FUNC (prefs_filter_delete_cb), NULL);
422 cond_hbox = gtk_hbox_new (FALSE, 8);
423 gtk_widget_show (cond_hbox);
424 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
426 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
427 gtk_widget_show (cond_scrolledwin);
428 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
429 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
431 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
432 GTK_POLICY_AUTOMATIC,
433 GTK_POLICY_AUTOMATIC);
435 cond_clist = gtk_clist_new_with_titles(1, title);
436 gtk_widget_show (cond_clist);
437 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
438 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
439 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
440 GTK_SELECTION_BROWSE);
441 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
443 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
444 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
445 gtk_signal_connect (GTK_OBJECT (cond_clist), "row_move",
446 GTK_SIGNAL_FUNC (prefs_filter_row_move), NULL);
448 btn_vbox = gtk_vbox_new (FALSE, 8);
449 gtk_widget_show (btn_vbox);
450 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
452 up_btn = gtk_button_new_with_label (_("Up"));
453 gtk_widget_show (up_btn);
454 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
455 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
456 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
458 down_btn = gtk_button_new_with_label (_("Down"));
459 gtk_widget_show (down_btn);
460 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
461 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
462 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
464 gtk_widget_show_all(window);
466 filter.window = window;
467 filter.ok_btn = ok_btn;
469 filter.hdr_combo1 = hdr_combo1;
470 filter.hdr_combo2 = hdr_combo2;
471 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
472 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
473 filter.key_entry1 = key_entry1;
474 filter.key_entry2 = key_entry2;
475 filter.pred_combo1 = pred_combo1;
476 filter.pred_combo2 = pred_combo2;
477 filter.pred_entry1 = pred_entry1;
478 filter.pred_entry2 = pred_entry2;
479 filter.op_combo = op_combo;
480 filter.op_entry = op_entry;
482 filter.dest_entry = dest_entry;
483 filter.destsel_btn = destsel_btn;
484 filter.dest_radiobtn = dest_radiobtn;
485 filter.notrecv_radiobtn = notrecv_radiobtn;
486 filter.regex_chkbtn = regex_chkbtn;
488 filter.cond_clist = cond_clist;
491 void prefs_filter_read_config(void)
495 gchar buf[PREFSBUFSIZE];
498 debug_print(_("Reading filter configuration...\n"));
500 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
501 if ((fp = fopen(rcpath, "r")) == NULL) {
502 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
508 /* remove all previous filter list */
509 while (prefs_common.fltlist != NULL) {
510 flt = (Filter *)prefs_common.fltlist->data;
512 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
516 while (fgets(buf, sizeof(buf), fp) != NULL) {
518 flt = filter_read_str(buf);
520 prefs_common.fltlist =
521 g_slist_append(prefs_common.fltlist, flt);
528 void prefs_filter_write_config(void)
534 debug_print(_("Writing filter configuration...\n"));
536 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
537 if ((pfile = prefs_write_open(rcpath)) == NULL) {
538 g_warning(_("failed to write configuration to file\n"));
543 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
544 Filter *flt = (Filter *)cur->data;
547 fstr = filter_get_str(flt);
548 if (fputs(fstr, pfile->fp) == EOF ||
549 fputc('\n', pfile->fp) == EOF) {
550 FILE_OP_ERROR(rcpath, "fputs || fputc");
551 prefs_write_close_revert(pfile);
561 if (prefs_write_close(pfile) < 0) {
562 g_warning(_("failed to write configuration to file\n"));
567 static void prefs_filter_set_dialog(void)
569 GtkCList *clist = GTK_CLIST(filter.cond_clist);
574 gtk_clist_freeze(clist);
575 gtk_clist_clear(clist);
577 cond_str[0] = _("(New)");
578 row = gtk_clist_append(clist, cond_str);
579 gtk_clist_set_row_data(clist, row, NULL);
581 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
582 Filter *flt = (Filter *)cur->data;
584 cond_str[0] = filter_get_str(flt);
585 subst_char(cond_str[0], '\t', ':');
586 row = gtk_clist_append(clist, cond_str);
587 gtk_clist_set_row_data(clist, row, flt);
592 gtk_clist_thaw(clist);
595 static void prefs_filter_set_list(void)
600 g_slist_free(prefs_common.fltlist);
601 prefs_common.fltlist = NULL;
603 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
605 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
611 #define GET_ENTRY(entry) \
612 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
614 static gint prefs_filter_clist_set_row(gint row)
616 GtkCList *clist = GTK_CLIST(filter.cond_clist);
621 g_return_val_if_fail(row != 0, -1);
623 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
624 GET_ENTRY(filter.dest_entry);
626 entry_text = FILTER_NOT_RECEIVE;
627 if (entry_text[0] == '\0') {
628 alertpanel_error(_("Destination is not set."));
631 GET_ENTRY(filter.hdr_entry1);
632 if (entry_text[0] == '\0') {
633 alertpanel_error(_("Header name is not set."));
637 flt = g_new0(Filter, 1);
639 flt->name1 = g_strdup(entry_text);
641 GET_ENTRY(filter.key_entry1);
642 if (entry_text[0] != '\0')
643 flt->body1 = g_strdup(entry_text);
645 GET_ENTRY(filter.hdr_entry2);
646 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
647 flt->name2 = g_strdup(entry_text);
649 GET_ENTRY(filter.key_entry2);
650 if (entry_text[0] != '\0')
651 flt->body2 = g_strdup(entry_text);
654 if (gtk_toggle_button_get_active
655 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
656 flt->flag1 = flt->flag2 = FLT_REGEX;
658 GET_ENTRY(filter.pred_entry1);
659 if (!strcmp(entry_text, _("contains")))
660 flt->flag1 |= FLT_CONTAIN;
661 GET_ENTRY(filter.pred_entry2);
662 if (!strcmp(entry_text, _("contains")))
663 flt->flag2 |= FLT_CONTAIN;
665 GET_ENTRY(filter.op_entry);
666 if (!strcmp(entry_text, "and"))
671 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
672 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
673 flt->dest = g_strdup(entry_text);
674 flt->action = FLT_MOVE;
676 flt->action = FLT_NOTRECV;
678 cond_str[0] = filter_get_str(flt);
679 subst_char(cond_str[0], '\t', ':');
682 row = gtk_clist_append(clist, cond_str);
686 gtk_clist_set_text(clist, row, 0, cond_str[0]);
687 tmpflt = gtk_clist_get_row_data(clist, row);
692 gtk_clist_set_row_data(clist, row, flt);
696 prefs_filter_set_list();
701 static void prefs_filter_select_dest_cb(void)
705 dest = foldersel_folder_sel(NULL, NULL);
708 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
711 static void prefs_filter_register_cb(void)
713 prefs_filter_clist_set_row(-1);
716 static void prefs_filter_substitute_cb(void)
718 GtkCList *clist = GTK_CLIST(filter.cond_clist);
722 if (!clist->selection) return;
724 row = GPOINTER_TO_INT(clist->selection->data);
725 if (row == 0) return;
727 flt = gtk_clist_get_row_data(clist, row);
730 prefs_filter_clist_set_row(row);
733 static void prefs_filter_delete_cb(void)
735 GtkCList *clist = GTK_CLIST(filter.cond_clist);
739 if (!clist->selection) return;
740 row = GPOINTER_TO_INT(clist->selection->data);
741 if (row == 0) return;
743 if (alertpanel(_("Delete rule"),
744 _("Do you really want to delete this rule?"),
745 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
748 flt = gtk_clist_get_row_data(clist, row);
750 gtk_clist_remove(clist, row);
751 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
754 static void prefs_filter_up(void)
756 GtkCList *clist = GTK_CLIST(filter.cond_clist);
759 if (!clist->selection) return;
761 row = GPOINTER_TO_INT(clist->selection->data);
763 gtk_clist_row_move(clist, row, row - 1);
766 static void prefs_filter_down(void)
768 GtkCList *clist = GTK_CLIST(filter.cond_clist);
771 if (!clist->selection) return;
773 row = GPOINTER_TO_INT(clist->selection->data);
774 if (row > 0 && row < clist->rows - 1)
775 gtk_clist_row_move(clist, row, row + 1);
778 #define ENTRY_SET_TEXT(entry, str) \
779 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
781 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
785 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
786 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
790 flt = gtk_clist_get_row_data(clist, row);
794 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
795 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
796 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
797 ENTRY_SET_TEXT(filter.hdr_entry2,
798 flt->name2 ? flt->name2 : _("(none)"));
799 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
801 ENTRY_SET_TEXT(filter.pred_entry1,
802 FLT_IS_CONTAIN(flt->flag1)
803 ? _("contains") : _("not contain"));
804 ENTRY_SET_TEXT(filter.pred_entry2,
805 FLT_IS_CONTAIN(flt->flag2)
806 ? _("contains") : _("not contain"));
808 is_regex = FLT_IS_REGEX(flt->flag1);
809 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
810 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
811 gtk_toggle_button_set_active
812 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
814 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
815 flt->cond == FLT_OR ? "or" : "and");
816 if (flt->action == FLT_NOTRECV)
817 gtk_toggle_button_set_active
818 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
820 gtk_toggle_button_set_active
821 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
824 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
827 prefs_filter_set_list();
828 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
829 gtk_clist_moveto(clist, dest_row, -1,
830 source_row < dest_row ? 1.0 : 0.0, 0.0);
834 static void prefs_filter_dest_radio_button_toggled(void)
836 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
837 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
840 static void prefs_filter_notrecv_radio_button_toggled(void)
842 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
843 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
846 static void prefs_filter_regex_check_button_toggled(void)
850 is_regex = gtk_toggle_button_get_active
851 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
852 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
853 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
856 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
859 prefs_filter_cancel();
863 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
866 if (event && event->keyval == GDK_Escape)
867 prefs_filter_cancel();
870 static void prefs_filter_ok(void)
872 prefs_filter_write_config();
873 gtk_widget_hide(filter.window);
874 inc_autocheck_timer_set();
877 static void prefs_filter_cancel(void)
879 prefs_filter_read_config();
880 gtk_widget_hide(filter.window);
881 inc_autocheck_timer_set();