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;
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 MANAGE_WINDOW_SIGNALS_CONNECT (window);
224 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
225 GTK_SIGNAL_FUNC(prefs_filter_ok), NULL);
226 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
227 GTK_SIGNAL_FUNC(prefs_filter_cancel), NULL);
229 vbox1 = gtk_vbox_new (FALSE, VSPACING);
230 gtk_widget_show (vbox1);
231 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
232 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
234 table1 = gtk_table_new (3, 4, FALSE);
235 gtk_widget_show (table1);
236 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
237 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
238 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
240 cond_label = gtk_label_new (_("Condition"));
241 gtk_widget_show (cond_label);
242 gtk_table_attach (GTK_TABLE (table1), cond_label, 0, 1, 0, 1,
244 gtk_misc_set_alignment (GTK_MISC (cond_label), 0, 0.5);
246 cond_combo = gtk_combo_new ();
247 gtk_widget_show (cond_combo);
248 gtk_table_attach (GTK_TABLE (table1), cond_combo, 0, 1, 2, 3,
250 gtk_widget_set_usize (cond_combo, 52, -1);
251 gtkut_combo_set_items (GTK_COMBO (cond_combo), "and", "or", NULL);
253 cond_entry = GTK_COMBO (cond_combo)->entry;
254 gtk_entry_set_editable (GTK_ENTRY (cond_entry), FALSE);
256 hdr_label = gtk_label_new (_("Header"));
257 gtk_widget_show (hdr_label);
258 gtk_table_attach (GTK_TABLE (table1), hdr_label, 1, 2, 0, 1,
260 gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
262 hdr_combo1 = gtk_combo_new ();
263 gtk_widget_show (hdr_combo1);
264 gtk_table_attach (GTK_TABLE (table1), hdr_combo1, 1, 2, 1, 2,
266 gtk_widget_set_usize (hdr_combo1, 96, -1);
267 gtkut_combo_set_items (GTK_COMBO (hdr_combo1),
268 "Subject", "From", "To", "Cc", "Reply-To",
270 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
273 hdr_combo2 = gtk_combo_new ();
274 gtk_widget_show (hdr_combo2);
275 gtk_table_attach (GTK_TABLE (table1), hdr_combo2, 1, 2, 2, 3,
277 gtk_widget_set_usize (hdr_combo2, 96, -1);
278 gtkut_combo_set_items (GTK_COMBO (hdr_combo2), _("(none)"),
279 "Subject", "From", "To", "Cc", "Reply-To",
281 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
284 key_label = gtk_label_new (_("Keyword"));
285 gtk_widget_show (key_label);
286 gtk_table_attach (GTK_TABLE (table1), key_label, 2, 3, 0, 1,
287 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
289 gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
291 key_entry1 = gtk_entry_new ();
292 gtk_widget_show (key_entry1);
293 gtk_widget_set_usize (key_entry1, 128, -1);
294 gtk_table_attach (GTK_TABLE (table1), key_entry1, 2, 3, 1, 2,
295 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
298 key_entry2 = gtk_entry_new ();
299 gtk_widget_show (key_entry2);
300 gtk_widget_set_usize (key_entry2, 128, -1);
301 gtk_table_attach (GTK_TABLE (table1), key_entry2, 2, 3, 2, 3,
302 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
305 pred_label = gtk_label_new (_("Predicate"));
306 gtk_widget_show (pred_label);
307 gtk_table_attach (GTK_TABLE (table1), pred_label, 3, 4, 0, 1,
309 gtk_misc_set_alignment (GTK_MISC (pred_label), 0, 0.5);
311 pred_combo1 = gtk_combo_new ();
312 gtk_widget_show (pred_combo1);
313 gtk_table_attach (GTK_TABLE (table1), pred_combo1, 3, 4, 1, 2,
315 gtk_widget_set_usize (pred_combo1, 92, -1);
316 gtkut_combo_set_items (GTK_COMBO (pred_combo1),
317 _("contains"), _("not contain"), NULL);
319 pred_entry1 = GTK_COMBO (pred_combo1)->entry;
320 gtk_entry_set_editable (GTK_ENTRY (pred_entry1), FALSE);
322 pred_combo2 = gtk_combo_new ();
323 gtk_widget_show (pred_combo2);
324 gtk_table_attach (GTK_TABLE (table1), pred_combo2, 3, 4, 2, 3,
326 gtk_widget_set_usize (pred_combo2, 92, -1);
327 gtkut_combo_set_items (GTK_COMBO (pred_combo2),
328 _("contains"), _("not contain"), NULL);
330 pred_entry2 = GTK_COMBO (pred_combo2)->entry;
331 gtk_entry_set_editable (GTK_ENTRY (pred_entry2), FALSE);
335 vbox2 = gtk_vbox_new (FALSE, VSPACING_NARROW);
336 gtk_widget_show (vbox2);
337 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
339 dest_hbox = gtk_hbox_new (FALSE, 8);
340 gtk_widget_show (dest_hbox);
341 gtk_box_pack_start (GTK_BOX (vbox2), dest_hbox, FALSE, TRUE, 0);
344 gtk_radio_button_new_with_label (recv_group, _("Destination"));
345 recv_group = gtk_radio_button_group (GTK_RADIO_BUTTON (dest_radiobtn));
346 gtk_widget_show (dest_radiobtn);
347 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_radiobtn,
349 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
351 (GTK_OBJECT (dest_radiobtn), "toggled",
352 GTK_SIGNAL_FUNC (prefs_filter_dest_radio_button_toggled),
355 dest_entry = gtk_entry_new ();
356 gtk_widget_show (dest_entry);
357 gtk_widget_set_usize (dest_entry, DEFAULT_ENTRY_WIDTH, -1);
358 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_entry, TRUE, TRUE, 0);
359 gtk_entry_set_editable (GTK_ENTRY (dest_entry), FALSE);
361 destsel_btn = gtk_button_new_with_label (_(" Select... "));
362 gtk_widget_show (destsel_btn);
363 gtk_box_pack_start (GTK_BOX (dest_hbox), destsel_btn, FALSE, FALSE, 0);
364 gtk_signal_connect (GTK_OBJECT (destsel_btn), "clicked",
365 GTK_SIGNAL_FUNC (prefs_filter_select_dest_cb),
368 PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
370 (GTK_OBJECT (regex_chkbtn), "toggled",
371 GTK_SIGNAL_FUNC (prefs_filter_regex_check_button_toggled),
374 notrecv_radiobtn = gtk_radio_button_new_with_label
375 (recv_group, _("Don't receive"));
376 recv_group = gtk_radio_button_group
377 (GTK_RADIO_BUTTON (notrecv_radiobtn));
378 gtk_widget_show (notrecv_radiobtn);
379 gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
381 (GTK_OBJECT (notrecv_radiobtn), "toggled",
382 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
385 /* register / substitute / delete */
387 reg_hbox = gtk_hbox_new (FALSE, 4);
388 gtk_widget_show (reg_hbox);
389 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
391 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
392 gtk_widget_show (arrow);
393 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
394 gtk_widget_set_usize (arrow, -1, 16);
396 btn_hbox = gtk_hbox_new (TRUE, 4);
397 gtk_widget_show (btn_hbox);
398 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
400 reg_btn = gtk_button_new_with_label (_("Register"));
401 gtk_widget_show (reg_btn);
402 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
403 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
404 GTK_SIGNAL_FUNC (prefs_filter_register_cb), NULL);
406 subst_btn = gtk_button_new_with_label (_(" Substitute "));
407 gtk_widget_show (subst_btn);
408 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
409 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
410 GTK_SIGNAL_FUNC (prefs_filter_substitute_cb),
413 del_btn = gtk_button_new_with_label (_("Delete"));
414 gtk_widget_show (del_btn);
415 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
416 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
417 GTK_SIGNAL_FUNC (prefs_filter_delete_cb), NULL);
419 cond_hbox = gtk_hbox_new (FALSE, 8);
420 gtk_widget_show (cond_hbox);
421 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
423 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
424 gtk_widget_show (cond_scrolledwin);
425 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
426 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
428 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
429 GTK_POLICY_AUTOMATIC,
430 GTK_POLICY_AUTOMATIC);
432 title[0] = _("Registered rules");
433 cond_clist = gtk_clist_new_with_titles(1, title);
434 gtk_widget_show (cond_clist);
435 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
436 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
437 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
438 GTK_SELECTION_BROWSE);
439 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
441 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
442 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
443 gtk_signal_connect_after (GTK_OBJECT (cond_clist), "row_move",
444 GTK_SIGNAL_FUNC (prefs_filter_row_move),
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.cond_combo = cond_combo;
479 filter.cond_entry = cond_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 void prefs_filter_rename_path(const gchar *old_path, const gchar *new_path)
573 g_return_if_fail(old_path != NULL);
574 g_return_if_fail(new_path != NULL);
576 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
577 Filter *flt = (Filter *)cur->data;
579 oldpathlen = strlen(old_path);
580 if (flt->dest && !strncmp(old_path, flt->dest, oldpathlen)) {
581 base = flt->dest + oldpathlen;
582 while (*base == G_DIR_SEPARATOR) base++;
584 dest_path = g_strdup(new_path);
586 dest_path = g_strconcat(new_path,
590 flt->dest = dest_path;
594 prefs_filter_write_config();
597 void prefs_filter_delete_path(const gchar *path)
602 g_return_if_fail(path != NULL);
604 for (cur = prefs_common.fltlist; cur != NULL; cur = next) {
605 Filter *flt = (Filter *)cur->data;
608 if (flt->dest && !strncmp(path, flt->dest, strlen(path))) {
610 prefs_common.fltlist =
611 g_slist_remove(prefs_common.fltlist, flt);
615 prefs_filter_write_config();
618 static void prefs_filter_set_dialog(const gchar *header, const gchar *key)
620 GtkCList *clist = GTK_CLIST(filter.cond_clist);
625 gtk_clist_freeze(clist);
626 gtk_clist_clear(clist);
628 cond_str[0] = _("(New)");
629 row = gtk_clist_append(clist, cond_str);
630 gtk_clist_set_row_data(clist, row, NULL);
632 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
633 Filter *flt = (Filter *)cur->data;
635 cond_str[0] = filter_get_str(flt);
636 subst_char(cond_str[0], '\t', ':');
637 row = gtk_clist_append(clist, cond_str);
638 gtk_clist_set_row_data(clist, row, flt);
643 gtk_clist_thaw(clist);
646 gtk_entry_set_text(GTK_ENTRY(filter.hdr_entry1), header);
647 gtk_entry_set_text(GTK_ENTRY(filter.key_entry1), key);
651 static void prefs_filter_set_list(void)
656 g_slist_free(prefs_common.fltlist);
657 prefs_common.fltlist = NULL;
659 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
661 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
667 #define GET_ENTRY(entry) \
668 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
670 static gint prefs_filter_clist_set_row(gint row)
672 GtkCList *clist = GTK_CLIST(filter.cond_clist);
677 g_return_val_if_fail(row != 0, -1);
679 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
680 GET_ENTRY(filter.dest_entry);
682 entry_text = FILTER_NOT_RECEIVE;
683 if (entry_text[0] == '\0') {
684 alertpanel_error(_("Destination is not set."));
687 GET_ENTRY(filter.hdr_entry1);
688 if (entry_text[0] == '\0') {
689 alertpanel_error(_("Header name is not set."));
693 flt = g_new0(Filter, 1);
695 flt->name1 = g_strdup(entry_text);
697 GET_ENTRY(filter.key_entry1);
698 if (entry_text[0] != '\0')
699 flt->body1 = g_strdup(entry_text);
701 GET_ENTRY(filter.hdr_entry2);
702 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
703 flt->name2 = g_strdup(entry_text);
705 GET_ENTRY(filter.key_entry2);
706 if (entry_text[0] != '\0')
707 flt->body2 = g_strdup(entry_text);
710 if (gtk_toggle_button_get_active
711 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
712 flt->flag1 = flt->flag2 = FLT_REGEX;
714 GET_ENTRY(filter.pred_entry1);
715 if (!strcmp(entry_text, _("contains")))
716 flt->flag1 |= FLT_CONTAIN;
717 GET_ENTRY(filter.pred_entry2);
718 if (!strcmp(entry_text, _("contains")))
719 flt->flag2 |= FLT_CONTAIN;
721 GET_ENTRY(filter.cond_entry);
722 if (!strcmp(entry_text, "and"))
727 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
728 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
729 flt->dest = g_strdup(entry_text);
730 flt->action = FLT_MOVE;
732 flt->action = FLT_NOTRECV;
734 cond_str[0] = filter_get_str(flt);
735 subst_char(cond_str[0], '\t', ':');
738 row = gtk_clist_append(clist, cond_str);
742 gtk_clist_set_text(clist, row, 0, cond_str[0]);
743 tmpflt = gtk_clist_get_row_data(clist, row);
748 gtk_clist_set_row_data(clist, row, flt);
752 prefs_filter_set_list();
757 static void prefs_filter_select_dest_cb(void)
761 dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
764 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
767 static void prefs_filter_register_cb(void)
769 GtkCList *clist = GTK_CLIST(filter.cond_clist);
772 row = prefs_filter_clist_set_row(-1);
773 if (gtk_clist_row_is_visible(clist, row) != GTK_VISIBILITY_FULL)
774 gtk_clist_moveto(clist, row, -1, 0.5, 0);
775 gtk_clist_select_row(clist, row, -1);
776 gtkut_clist_set_focus_row(clist, row);
779 static void prefs_filter_substitute_cb(void)
781 GtkCList *clist = GTK_CLIST(filter.cond_clist);
785 if (!clist->selection) return;
787 row = GPOINTER_TO_INT(clist->selection->data);
788 if (row == 0) return;
790 flt = gtk_clist_get_row_data(clist, row);
793 prefs_filter_clist_set_row(row);
796 static void prefs_filter_delete_cb(void)
798 GtkCList *clist = GTK_CLIST(filter.cond_clist);
802 if (!clist->selection) return;
803 row = GPOINTER_TO_INT(clist->selection->data);
804 if (row == 0) return;
806 if (alertpanel(_("Delete rule"),
807 _("Do you really want to delete this rule?"),
808 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
811 flt = gtk_clist_get_row_data(clist, row);
813 gtk_clist_remove(clist, row);
814 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
817 static void prefs_filter_up(void)
819 GtkCList *clist = GTK_CLIST(filter.cond_clist);
822 if (!clist->selection) return;
824 row = GPOINTER_TO_INT(clist->selection->data);
826 gtk_clist_row_move(clist, row, row - 1);
829 static void prefs_filter_down(void)
831 GtkCList *clist = GTK_CLIST(filter.cond_clist);
834 if (!clist->selection) return;
836 row = GPOINTER_TO_INT(clist->selection->data);
837 if (row > 0 && row < clist->rows - 1)
838 gtk_clist_row_move(clist, row, row + 1);
841 #define ENTRY_SET_TEXT(entry, str) \
842 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
844 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
848 Filter default_flt = {"Subject", NULL, NULL, NULL,
849 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
853 default_flt.name2 = _("(none)");
855 flt = gtk_clist_get_row_data(clist, row);
859 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
860 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
861 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
862 ENTRY_SET_TEXT(filter.hdr_entry2,
863 flt->name2 ? flt->name2 : _("(none)"));
864 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
866 ENTRY_SET_TEXT(filter.pred_entry1,
867 FLT_IS_CONTAIN(flt->flag1)
868 ? _("contains") : _("not contain"));
869 ENTRY_SET_TEXT(filter.pred_entry2,
870 FLT_IS_CONTAIN(flt->flag2)
871 ? _("contains") : _("not contain"));
873 is_regex = FLT_IS_REGEX(flt->flag1);
874 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
875 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
876 gtk_toggle_button_set_active
877 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
879 gtk_entry_set_text(GTK_ENTRY(filter.cond_entry),
880 flt->cond == FLT_OR ? "or" : "and");
881 if (flt->action == FLT_NOTRECV)
882 gtk_toggle_button_set_active
883 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
885 gtk_toggle_button_set_active
886 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
889 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
892 prefs_filter_set_list();
893 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
894 gtk_clist_moveto(clist, dest_row, -1,
895 source_row < dest_row ? 1.0 : 0.0, 0.0);
899 static void prefs_filter_dest_radio_button_toggled(void)
901 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
902 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
905 static void prefs_filter_notrecv_radio_button_toggled(void)
907 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
908 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
911 static void prefs_filter_regex_check_button_toggled(void)
915 is_regex = gtk_toggle_button_get_active
916 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
917 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
918 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
921 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
924 prefs_filter_cancel();
928 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
931 if (event && event->keyval == GDK_Escape)
932 prefs_filter_cancel();
935 static void prefs_filter_ok(void)
937 prefs_filter_write_config();
938 gtk_widget_hide(filter.window);
942 static void prefs_filter_cancel(void)
944 prefs_filter_read_config();
945 gtk_widget_hide(filter.window);