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_after (GTK_OBJECT (cond_clist), "row_move",
446 GTK_SIGNAL_FUNC (prefs_filter_row_move),
449 btn_vbox = gtk_vbox_new (FALSE, 8);
450 gtk_widget_show (btn_vbox);
451 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
453 up_btn = gtk_button_new_with_label (_("Up"));
454 gtk_widget_show (up_btn);
455 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
456 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
457 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
459 down_btn = gtk_button_new_with_label (_("Down"));
460 gtk_widget_show (down_btn);
461 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
462 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
463 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
465 gtk_widget_show_all(window);
467 filter.window = window;
468 filter.ok_btn = ok_btn;
470 filter.hdr_combo1 = hdr_combo1;
471 filter.hdr_combo2 = hdr_combo2;
472 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
473 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
474 filter.key_entry1 = key_entry1;
475 filter.key_entry2 = key_entry2;
476 filter.pred_combo1 = pred_combo1;
477 filter.pred_combo2 = pred_combo2;
478 filter.pred_entry1 = pred_entry1;
479 filter.pred_entry2 = pred_entry2;
480 filter.cond_combo = cond_combo;
481 filter.cond_entry = cond_entry;
483 filter.dest_entry = dest_entry;
484 filter.destsel_btn = destsel_btn;
485 filter.dest_radiobtn = dest_radiobtn;
486 filter.notrecv_radiobtn = notrecv_radiobtn;
487 filter.regex_chkbtn = regex_chkbtn;
489 filter.cond_clist = cond_clist;
492 void prefs_filter_read_config(void)
496 gchar buf[PREFSBUFSIZE];
499 debug_print(_("Reading filter configuration...\n"));
501 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
502 if ((fp = fopen(rcpath, "r")) == NULL) {
503 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
509 /* remove all previous filter list */
510 while (prefs_common.fltlist != NULL) {
511 flt = (Filter *)prefs_common.fltlist->data;
513 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
517 while (fgets(buf, sizeof(buf), fp) != NULL) {
519 flt = filter_read_str(buf);
521 prefs_common.fltlist =
522 g_slist_append(prefs_common.fltlist, flt);
529 void prefs_filter_write_config(void)
535 debug_print(_("Writing filter configuration...\n"));
537 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
538 if ((pfile = prefs_write_open(rcpath)) == NULL) {
539 g_warning(_("failed to write configuration to file\n"));
544 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
545 Filter *flt = (Filter *)cur->data;
548 fstr = filter_get_str(flt);
549 if (fputs(fstr, pfile->fp) == EOF ||
550 fputc('\n', pfile->fp) == EOF) {
551 FILE_OP_ERROR(rcpath, "fputs || fputc");
552 prefs_write_close_revert(pfile);
562 if (prefs_write_close(pfile) < 0) {
563 g_warning(_("failed to write configuration to file\n"));
568 static void prefs_filter_set_dialog(const gchar *header, const gchar *key)
570 GtkCList *clist = GTK_CLIST(filter.cond_clist);
575 gtk_clist_freeze(clist);
576 gtk_clist_clear(clist);
578 cond_str[0] = _("(New)");
579 row = gtk_clist_append(clist, cond_str);
580 gtk_clist_set_row_data(clist, row, NULL);
582 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
583 Filter *flt = (Filter *)cur->data;
585 cond_str[0] = filter_get_str(flt);
586 subst_char(cond_str[0], '\t', ':');
587 row = gtk_clist_append(clist, cond_str);
588 gtk_clist_set_row_data(clist, row, flt);
593 gtk_clist_thaw(clist);
596 gtk_entry_set_text(GTK_ENTRY(filter.hdr_entry1), header);
597 gtk_entry_set_text(GTK_ENTRY(filter.key_entry1), key);
601 static void prefs_filter_set_list(void)
606 g_slist_free(prefs_common.fltlist);
607 prefs_common.fltlist = NULL;
609 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
611 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
617 #define GET_ENTRY(entry) \
618 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
620 static gint prefs_filter_clist_set_row(gint row)
622 GtkCList *clist = GTK_CLIST(filter.cond_clist);
627 g_return_val_if_fail(row != 0, -1);
629 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
630 GET_ENTRY(filter.dest_entry);
632 entry_text = FILTER_NOT_RECEIVE;
633 if (entry_text[0] == '\0') {
634 alertpanel_error(_("Destination is not set."));
637 GET_ENTRY(filter.hdr_entry1);
638 if (entry_text[0] == '\0') {
639 alertpanel_error(_("Header name is not set."));
643 flt = g_new0(Filter, 1);
645 flt->name1 = g_strdup(entry_text);
647 GET_ENTRY(filter.key_entry1);
648 if (entry_text[0] != '\0')
649 flt->body1 = g_strdup(entry_text);
651 GET_ENTRY(filter.hdr_entry2);
652 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
653 flt->name2 = g_strdup(entry_text);
655 GET_ENTRY(filter.key_entry2);
656 if (entry_text[0] != '\0')
657 flt->body2 = g_strdup(entry_text);
660 if (gtk_toggle_button_get_active
661 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
662 flt->flag1 = flt->flag2 = FLT_REGEX;
664 GET_ENTRY(filter.pred_entry1);
665 if (!strcmp(entry_text, _("contains")))
666 flt->flag1 |= FLT_CONTAIN;
667 GET_ENTRY(filter.pred_entry2);
668 if (!strcmp(entry_text, _("contains")))
669 flt->flag2 |= FLT_CONTAIN;
671 GET_ENTRY(filter.cond_entry);
672 if (!strcmp(entry_text, "and"))
677 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
678 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
679 flt->dest = g_strdup(entry_text);
680 flt->action = FLT_MOVE;
682 flt->action = FLT_NOTRECV;
684 cond_str[0] = filter_get_str(flt);
685 subst_char(cond_str[0], '\t', ':');
688 row = gtk_clist_append(clist, cond_str);
692 gtk_clist_set_text(clist, row, 0, cond_str[0]);
693 tmpflt = gtk_clist_get_row_data(clist, row);
698 gtk_clist_set_row_data(clist, row, flt);
702 prefs_filter_set_list();
707 static void prefs_filter_select_dest_cb(void)
711 dest = foldersel_folder_sel(NULL, NULL);
714 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
717 static void prefs_filter_register_cb(void)
719 prefs_filter_clist_set_row(-1);
722 static void prefs_filter_substitute_cb(void)
724 GtkCList *clist = GTK_CLIST(filter.cond_clist);
728 if (!clist->selection) return;
730 row = GPOINTER_TO_INT(clist->selection->data);
731 if (row == 0) return;
733 flt = gtk_clist_get_row_data(clist, row);
736 prefs_filter_clist_set_row(row);
739 static void prefs_filter_delete_cb(void)
741 GtkCList *clist = GTK_CLIST(filter.cond_clist);
745 if (!clist->selection) return;
746 row = GPOINTER_TO_INT(clist->selection->data);
747 if (row == 0) return;
749 if (alertpanel(_("Delete rule"),
750 _("Do you really want to delete this rule?"),
751 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
754 flt = gtk_clist_get_row_data(clist, row);
756 gtk_clist_remove(clist, row);
757 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
760 static void prefs_filter_up(void)
762 GtkCList *clist = GTK_CLIST(filter.cond_clist);
765 if (!clist->selection) return;
767 row = GPOINTER_TO_INT(clist->selection->data);
769 gtk_clist_row_move(clist, row, row - 1);
772 static void prefs_filter_down(void)
774 GtkCList *clist = GTK_CLIST(filter.cond_clist);
777 if (!clist->selection) return;
779 row = GPOINTER_TO_INT(clist->selection->data);
780 if (row > 0 && row < clist->rows - 1)
781 gtk_clist_row_move(clist, row, row + 1);
784 #define ENTRY_SET_TEXT(entry, str) \
785 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
787 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
791 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
792 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
796 flt = gtk_clist_get_row_data(clist, row);
800 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
801 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
802 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
803 ENTRY_SET_TEXT(filter.hdr_entry2,
804 flt->name2 ? flt->name2 : _("(none)"));
805 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
807 ENTRY_SET_TEXT(filter.pred_entry1,
808 FLT_IS_CONTAIN(flt->flag1)
809 ? _("contains") : _("not contain"));
810 ENTRY_SET_TEXT(filter.pred_entry2,
811 FLT_IS_CONTAIN(flt->flag2)
812 ? _("contains") : _("not contain"));
814 is_regex = FLT_IS_REGEX(flt->flag1);
815 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
816 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
817 gtk_toggle_button_set_active
818 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
820 gtk_entry_set_text(GTK_ENTRY(filter.cond_entry),
821 flt->cond == FLT_OR ? "or" : "and");
822 if (flt->action == FLT_NOTRECV)
823 gtk_toggle_button_set_active
824 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
826 gtk_toggle_button_set_active
827 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
830 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
833 prefs_filter_set_list();
834 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
835 gtk_clist_moveto(clist, dest_row, -1,
836 source_row < dest_row ? 1.0 : 0.0, 0.0);
840 static void prefs_filter_dest_radio_button_toggled(void)
842 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
843 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
846 static void prefs_filter_notrecv_radio_button_toggled(void)
848 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
849 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
852 static void prefs_filter_regex_check_button_toggled(void)
856 is_regex = gtk_toggle_button_get_active
857 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
858 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
859 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
862 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
865 prefs_filter_cancel();
869 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
872 if (event && event->keyval == GDK_Escape)
873 prefs_filter_cancel();
876 static void prefs_filter_ok(void)
878 prefs_filter_write_config();
879 gtk_widget_hide(filter.window);
883 static void prefs_filter_cancel(void)
885 prefs_filter_read_config();
886 gtk_widget_hide(filter.window);