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;
64 GtkWidget *cond_combo;
65 GtkWidget *cond_entry;
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 (const gchar *header,
89 static void prefs_filter_set_list (void);
90 static gint prefs_filter_clist_set_row (gint row);
92 /* callback functions */
93 static void prefs_filter_select_dest_cb (void);
94 static void prefs_filter_register_cb (void);
95 static void prefs_filter_substitute_cb (void);
96 static void prefs_filter_delete_cb (void);
97 static void prefs_filter_up (void);
98 static void prefs_filter_down (void);
99 static void prefs_filter_select (GtkCList *clist,
103 static void prefs_filter_row_move (GtkCList *clist,
107 static void prefs_filter_dest_radio_button_toggled (void);
108 static void prefs_filter_notrecv_radio_button_toggled (void);
109 static void prefs_filter_regex_check_button_toggled (void);
111 static gint prefs_filter_deleted (GtkWidget *widget,
114 static void prefs_filter_key_pressed (GtkWidget *widget,
117 static void prefs_filter_cancel (void);
118 static void prefs_filter_ok (void);
120 void prefs_filter_open(const gchar *header, const gchar *key)
122 if (prefs_rc_is_readonly(FILTER_RC))
127 if (!filter.window) {
128 prefs_filter_create();
131 manage_window_set_transient(GTK_WINDOW(filter.window));
132 gtk_widget_grab_focus(filter.ok_btn);
134 prefs_filter_set_dialog(header, key);
136 gtk_widget_show(filter.window);
139 static void prefs_filter_create(void)
144 GtkWidget *cancel_btn;
145 GtkWidget *confirm_area;
149 GtkWidget *cond_label;
150 GtkWidget *cond_combo;
151 GtkWidget *cond_entry;
152 GtkWidget *hdr_label;
153 GtkWidget *hdr_combo1;
154 GtkWidget *hdr_combo2;
155 GtkWidget *key_label;
156 GtkWidget *key_entry1;
157 GtkWidget *key_entry2;
158 GtkWidget *pred_label;
159 GtkWidget *pred_combo1;
160 GtkWidget *pred_entry1;
161 GtkWidget *pred_combo2;
162 GtkWidget *pred_entry2;
165 GtkWidget *dest_hbox;
166 GtkWidget *dest_entry;
167 GtkWidget *destsel_btn;
168 GtkWidget *dest_radiobtn;
169 GtkWidget *notrecv_radiobtn;
170 GSList *recv_group = NULL;
172 GtkWidget *regex_chkbtn;
178 GtkWidget *subst_btn;
181 GtkWidget *cond_hbox;
182 GtkWidget *cond_scrolledwin;
183 GtkWidget *cond_clist;
189 gchar *title[] = {_("Registered rules")};
191 debug_print(_("Creating filter setting window...\n"));
193 window = gtk_window_new (GTK_WINDOW_DIALOG);
194 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
195 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
196 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
197 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
199 vbox = gtk_vbox_new (FALSE, 6);
200 gtk_widget_show (vbox);
201 gtk_container_add (GTK_CONTAINER (window), vbox);
203 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
204 &cancel_btn, _("Cancel"), NULL, NULL);
205 gtk_widget_show (confirm_area);
206 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
207 gtk_widget_grab_default (ok_btn);
210 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
211 NULL, NULL, NULL, NULL);
212 gtk_widget_show (confirm_area);
213 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
214 gtk_widget_grab_default (close_btn);
217 gtk_window_set_title (GTK_WINDOW(window),
218 _("Filter setting"));
219 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
220 GTK_SIGNAL_FUNC(prefs_filter_deleted), NULL);
221 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
222 GTK_SIGNAL_FUNC(prefs_filter_key_pressed), NULL);
223 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
224 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
225 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
226 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
227 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
228 GTK_SIGNAL_FUNC(prefs_filter_ok), NULL);
229 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
230 GTK_SIGNAL_FUNC(prefs_filter_cancel), NULL);
232 vbox1 = gtk_vbox_new (FALSE, VSPACING);
233 gtk_widget_show (vbox1);
234 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
235 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
237 table1 = gtk_table_new (3, 4, FALSE);
238 gtk_widget_show (table1);
239 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
240 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
241 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
243 cond_label = gtk_label_new (_("Condition"));
244 gtk_widget_show (cond_label);
245 gtk_table_attach (GTK_TABLE (table1), cond_label, 0, 1, 0, 1,
247 gtk_misc_set_alignment (GTK_MISC (cond_label), 0, 0.5);
249 cond_combo = gtk_combo_new ();
250 gtk_widget_show (cond_combo);
251 gtk_table_attach (GTK_TABLE (table1), cond_combo, 0, 1, 2, 3,
253 gtk_widget_set_usize (cond_combo, 52, -1);
254 gtkut_combo_set_items (GTK_COMBO (cond_combo), "and", "or", NULL);
256 cond_entry = GTK_COMBO (cond_combo)->entry;
257 gtk_entry_set_editable (GTK_ENTRY (cond_entry), FALSE);
259 hdr_label = gtk_label_new (_("Header"));
260 gtk_widget_show (hdr_label);
261 gtk_table_attach (GTK_TABLE (table1), hdr_label, 1, 2, 0, 1,
263 gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
265 hdr_combo1 = gtk_combo_new ();
266 gtk_widget_show (hdr_combo1);
267 gtk_table_attach (GTK_TABLE (table1), hdr_combo1, 1, 2, 1, 2,
269 gtk_widget_set_usize (hdr_combo1, 96, -1);
270 gtkut_combo_set_items (GTK_COMBO (hdr_combo1),
271 "Subject", "From", "To", "Cc", "Reply-To",
273 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
276 hdr_combo2 = gtk_combo_new ();
277 gtk_widget_show (hdr_combo2);
278 gtk_table_attach (GTK_TABLE (table1), hdr_combo2, 1, 2, 2, 3,
280 gtk_widget_set_usize (hdr_combo2, 96, -1);
281 gtkut_combo_set_items (GTK_COMBO (hdr_combo2), _("(none)"),
282 "Subject", "From", "To", "Cc", "Reply-To",
284 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
287 key_label = gtk_label_new (_("Keyword"));
288 gtk_widget_show (key_label);
289 gtk_table_attach (GTK_TABLE (table1), key_label, 2, 3, 0, 1,
290 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
292 gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
294 key_entry1 = gtk_entry_new ();
295 gtk_widget_show (key_entry1);
296 gtk_widget_set_usize (key_entry1, 128, -1);
297 gtk_table_attach (GTK_TABLE (table1), key_entry1, 2, 3, 1, 2,
298 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
301 key_entry2 = gtk_entry_new ();
302 gtk_widget_show (key_entry2);
303 gtk_widget_set_usize (key_entry2, 128, -1);
304 gtk_table_attach (GTK_TABLE (table1), key_entry2, 2, 3, 2, 3,
305 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
308 pred_label = gtk_label_new (_("Predicate"));
309 gtk_widget_show (pred_label);
310 gtk_table_attach (GTK_TABLE (table1), pred_label, 3, 4, 0, 1,
312 gtk_misc_set_alignment (GTK_MISC (pred_label), 0, 0.5);
314 pred_combo1 = gtk_combo_new ();
315 gtk_widget_show (pred_combo1);
316 gtk_table_attach (GTK_TABLE (table1), pred_combo1, 3, 4, 1, 2,
318 gtk_widget_set_usize (pred_combo1, 92, -1);
319 gtkut_combo_set_items (GTK_COMBO (pred_combo1),
320 _("contains"), _("not contain"), NULL);
322 pred_entry1 = GTK_COMBO (pred_combo1)->entry;
323 gtk_entry_set_editable (GTK_ENTRY (pred_entry1), FALSE);
325 pred_combo2 = gtk_combo_new ();
326 gtk_widget_show (pred_combo2);
327 gtk_table_attach (GTK_TABLE (table1), pred_combo2, 3, 4, 2, 3,
329 gtk_widget_set_usize (pred_combo2, 92, -1);
330 gtkut_combo_set_items (GTK_COMBO (pred_combo2),
331 _("contains"), _("not contain"), NULL);
333 pred_entry2 = GTK_COMBO (pred_combo2)->entry;
334 gtk_entry_set_editable (GTK_ENTRY (pred_entry2), FALSE);
338 vbox2 = gtk_vbox_new (FALSE, VSPACING_NARROW);
339 gtk_widget_show (vbox2);
340 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
342 dest_hbox = gtk_hbox_new (FALSE, 8);
343 gtk_widget_show (dest_hbox);
344 gtk_box_pack_start (GTK_BOX (vbox2), dest_hbox, FALSE, TRUE, 0);
347 gtk_radio_button_new_with_label (recv_group, _("Destination"));
348 recv_group = gtk_radio_button_group (GTK_RADIO_BUTTON (dest_radiobtn));
349 gtk_widget_show (dest_radiobtn);
350 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_radiobtn,
352 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
354 (GTK_OBJECT (dest_radiobtn), "toggled",
355 GTK_SIGNAL_FUNC (prefs_filter_dest_radio_button_toggled),
358 dest_entry = gtk_entry_new ();
359 gtk_widget_show (dest_entry);
360 gtk_widget_set_usize (dest_entry, DEFAULT_ENTRY_WIDTH, -1);
361 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_entry, TRUE, TRUE, 0);
362 gtk_entry_set_editable (GTK_ENTRY (dest_entry), FALSE);
364 destsel_btn = gtk_button_new_with_label (_(" Select... "));
365 gtk_widget_show (destsel_btn);
366 gtk_box_pack_start (GTK_BOX (dest_hbox), destsel_btn, FALSE, FALSE, 0);
367 gtk_signal_connect (GTK_OBJECT (destsel_btn), "clicked",
368 GTK_SIGNAL_FUNC (prefs_filter_select_dest_cb),
371 PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
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.cond_combo = cond_combo;
480 filter.cond_entry = cond_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(const gchar *header, const gchar *key)
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 gtk_entry_set_text(GTK_ENTRY(filter.hdr_entry1), header);
596 gtk_entry_set_text(GTK_ENTRY(filter.key_entry1), key);
600 static void prefs_filter_set_list(void)
605 g_slist_free(prefs_common.fltlist);
606 prefs_common.fltlist = NULL;
608 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
610 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
616 #define GET_ENTRY(entry) \
617 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
619 static gint prefs_filter_clist_set_row(gint row)
621 GtkCList *clist = GTK_CLIST(filter.cond_clist);
626 g_return_val_if_fail(row != 0, -1);
628 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
629 GET_ENTRY(filter.dest_entry);
631 entry_text = FILTER_NOT_RECEIVE;
632 if (entry_text[0] == '\0') {
633 alertpanel_error(_("Destination is not set."));
636 GET_ENTRY(filter.hdr_entry1);
637 if (entry_text[0] == '\0') {
638 alertpanel_error(_("Header name is not set."));
642 flt = g_new0(Filter, 1);
644 flt->name1 = g_strdup(entry_text);
646 GET_ENTRY(filter.key_entry1);
647 if (entry_text[0] != '\0')
648 flt->body1 = g_strdup(entry_text);
650 GET_ENTRY(filter.hdr_entry2);
651 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
652 flt->name2 = g_strdup(entry_text);
654 GET_ENTRY(filter.key_entry2);
655 if (entry_text[0] != '\0')
656 flt->body2 = g_strdup(entry_text);
659 if (gtk_toggle_button_get_active
660 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
661 flt->flag1 = flt->flag2 = FLT_REGEX;
663 GET_ENTRY(filter.pred_entry1);
664 if (!strcmp(entry_text, _("contains")))
665 flt->flag1 |= FLT_CONTAIN;
666 GET_ENTRY(filter.pred_entry2);
667 if (!strcmp(entry_text, _("contains")))
668 flt->flag2 |= FLT_CONTAIN;
670 GET_ENTRY(filter.cond_entry);
671 if (!strcmp(entry_text, "and"))
676 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
677 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
678 flt->dest = g_strdup(entry_text);
679 flt->action = FLT_MOVE;
681 flt->action = FLT_NOTRECV;
683 cond_str[0] = filter_get_str(flt);
684 subst_char(cond_str[0], '\t', ':');
687 row = gtk_clist_append(clist, cond_str);
691 gtk_clist_set_text(clist, row, 0, cond_str[0]);
692 tmpflt = gtk_clist_get_row_data(clist, row);
697 gtk_clist_set_row_data(clist, row, flt);
701 prefs_filter_set_list();
706 static void prefs_filter_select_dest_cb(void)
710 dest = foldersel_folder_sel(NULL, NULL);
713 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
716 static void prefs_filter_register_cb(void)
718 prefs_filter_clist_set_row(-1);
721 static void prefs_filter_substitute_cb(void)
723 GtkCList *clist = GTK_CLIST(filter.cond_clist);
727 if (!clist->selection) return;
729 row = GPOINTER_TO_INT(clist->selection->data);
730 if (row == 0) return;
732 flt = gtk_clist_get_row_data(clist, row);
735 prefs_filter_clist_set_row(row);
738 static void prefs_filter_delete_cb(void)
740 GtkCList *clist = GTK_CLIST(filter.cond_clist);
744 if (!clist->selection) return;
745 row = GPOINTER_TO_INT(clist->selection->data);
746 if (row == 0) return;
748 if (alertpanel(_("Delete rule"),
749 _("Do you really want to delete this rule?"),
750 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
753 flt = gtk_clist_get_row_data(clist, row);
755 gtk_clist_remove(clist, row);
756 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
759 static void prefs_filter_up(void)
761 GtkCList *clist = GTK_CLIST(filter.cond_clist);
764 if (!clist->selection) return;
766 row = GPOINTER_TO_INT(clist->selection->data);
768 gtk_clist_row_move(clist, row, row - 1);
771 static void prefs_filter_down(void)
773 GtkCList *clist = GTK_CLIST(filter.cond_clist);
776 if (!clist->selection) return;
778 row = GPOINTER_TO_INT(clist->selection->data);
779 if (row > 0 && row < clist->rows - 1)
780 gtk_clist_row_move(clist, row, row + 1);
783 #define ENTRY_SET_TEXT(entry, str) \
784 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
786 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
790 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
791 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
795 flt = gtk_clist_get_row_data(clist, row);
799 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
800 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
801 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
802 ENTRY_SET_TEXT(filter.hdr_entry2,
803 flt->name2 ? flt->name2 : _("(none)"));
804 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
806 ENTRY_SET_TEXT(filter.pred_entry1,
807 FLT_IS_CONTAIN(flt->flag1)
808 ? _("contains") : _("not contain"));
809 ENTRY_SET_TEXT(filter.pred_entry2,
810 FLT_IS_CONTAIN(flt->flag2)
811 ? _("contains") : _("not contain"));
813 is_regex = FLT_IS_REGEX(flt->flag1);
814 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
815 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
816 gtk_toggle_button_set_active
817 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
819 gtk_entry_set_text(GTK_ENTRY(filter.cond_entry),
820 flt->cond == FLT_OR ? "or" : "and");
821 if (flt->action == FLT_NOTRECV)
822 gtk_toggle_button_set_active
823 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
825 gtk_toggle_button_set_active
826 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
829 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
832 prefs_filter_set_list();
833 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
834 gtk_clist_moveto(clist, dest_row, -1,
835 source_row < dest_row ? 1.0 : 0.0, 0.0);
839 static void prefs_filter_dest_radio_button_toggled(void)
841 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
842 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
845 static void prefs_filter_notrecv_radio_button_toggled(void)
847 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
848 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
851 static void prefs_filter_regex_check_button_toggled(void)
855 is_regex = gtk_toggle_button_get_active
856 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
857 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
858 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
861 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
864 prefs_filter_cancel();
868 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
871 if (event && event->keyval == GDK_Escape)
872 prefs_filter_cancel();
875 static void prefs_filter_ok(void)
877 prefs_filter_write_config();
878 gtk_widget_hide(filter.window);
882 static void prefs_filter_cancel(void)
884 prefs_filter_read_config();
885 gtk_widget_hide(filter.window);