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 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 title[0] = _("Registered rules");
436 cond_clist = gtk_clist_new_with_titles(1, title);
437 gtk_widget_show (cond_clist);
438 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
439 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
440 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
441 GTK_SELECTION_BROWSE);
442 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
444 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
445 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
446 gtk_signal_connect_after (GTK_OBJECT (cond_clist), "row_move",
447 GTK_SIGNAL_FUNC (prefs_filter_row_move),
450 btn_vbox = gtk_vbox_new (FALSE, 8);
451 gtk_widget_show (btn_vbox);
452 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
454 up_btn = gtk_button_new_with_label (_("Up"));
455 gtk_widget_show (up_btn);
456 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
457 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
458 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
460 down_btn = gtk_button_new_with_label (_("Down"));
461 gtk_widget_show (down_btn);
462 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
463 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
464 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
466 gtk_widget_show_all(window);
468 filter.window = window;
469 filter.ok_btn = ok_btn;
471 filter.hdr_combo1 = hdr_combo1;
472 filter.hdr_combo2 = hdr_combo2;
473 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
474 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
475 filter.key_entry1 = key_entry1;
476 filter.key_entry2 = key_entry2;
477 filter.pred_combo1 = pred_combo1;
478 filter.pred_combo2 = pred_combo2;
479 filter.pred_entry1 = pred_entry1;
480 filter.pred_entry2 = pred_entry2;
481 filter.cond_combo = cond_combo;
482 filter.cond_entry = cond_entry;
484 filter.dest_entry = dest_entry;
485 filter.destsel_btn = destsel_btn;
486 filter.dest_radiobtn = dest_radiobtn;
487 filter.notrecv_radiobtn = notrecv_radiobtn;
488 filter.regex_chkbtn = regex_chkbtn;
490 filter.cond_clist = cond_clist;
493 void prefs_filter_read_config(void)
497 gchar buf[PREFSBUFSIZE];
500 debug_print(_("Reading filter configuration...\n"));
502 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
503 if ((fp = fopen(rcpath, "r")) == NULL) {
504 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
510 /* remove all previous filter list */
511 while (prefs_common.fltlist != NULL) {
512 flt = (Filter *)prefs_common.fltlist->data;
514 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
518 while (fgets(buf, sizeof(buf), fp) != NULL) {
520 flt = filter_read_str(buf);
522 prefs_common.fltlist =
523 g_slist_append(prefs_common.fltlist, flt);
530 void prefs_filter_write_config(void)
536 debug_print(_("Writing filter configuration...\n"));
538 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
539 if ((pfile = prefs_write_open(rcpath)) == NULL) {
540 g_warning(_("failed to write configuration to file\n"));
545 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
546 Filter *flt = (Filter *)cur->data;
549 fstr = filter_get_str(flt);
550 if (fputs(fstr, pfile->fp) == EOF ||
551 fputc('\n', pfile->fp) == EOF) {
552 FILE_OP_ERROR(rcpath, "fputs || fputc");
553 prefs_write_close_revert(pfile);
563 if (prefs_write_close(pfile) < 0) {
564 g_warning(_("failed to write configuration to file\n"));
569 static void prefs_filter_set_dialog(const gchar *header, const gchar *key)
571 GtkCList *clist = GTK_CLIST(filter.cond_clist);
576 gtk_clist_freeze(clist);
577 gtk_clist_clear(clist);
579 cond_str[0] = _("(New)");
580 row = gtk_clist_append(clist, cond_str);
581 gtk_clist_set_row_data(clist, row, NULL);
583 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
584 Filter *flt = (Filter *)cur->data;
586 cond_str[0] = filter_get_str(flt);
587 subst_char(cond_str[0], '\t', ':');
588 row = gtk_clist_append(clist, cond_str);
589 gtk_clist_set_row_data(clist, row, flt);
594 gtk_clist_thaw(clist);
597 gtk_entry_set_text(GTK_ENTRY(filter.hdr_entry1), header);
598 gtk_entry_set_text(GTK_ENTRY(filter.key_entry1), key);
602 static void prefs_filter_set_list(void)
607 g_slist_free(prefs_common.fltlist);
608 prefs_common.fltlist = NULL;
610 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
612 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
618 #define GET_ENTRY(entry) \
619 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
621 static gint prefs_filter_clist_set_row(gint row)
623 GtkCList *clist = GTK_CLIST(filter.cond_clist);
628 g_return_val_if_fail(row != 0, -1);
630 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
631 GET_ENTRY(filter.dest_entry);
633 entry_text = FILTER_NOT_RECEIVE;
634 if (entry_text[0] == '\0') {
635 alertpanel_error(_("Destination is not set."));
638 GET_ENTRY(filter.hdr_entry1);
639 if (entry_text[0] == '\0') {
640 alertpanel_error(_("Header name is not set."));
644 flt = g_new0(Filter, 1);
646 flt->name1 = g_strdup(entry_text);
648 GET_ENTRY(filter.key_entry1);
649 if (entry_text[0] != '\0')
650 flt->body1 = g_strdup(entry_text);
652 GET_ENTRY(filter.hdr_entry2);
653 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
654 flt->name2 = g_strdup(entry_text);
656 GET_ENTRY(filter.key_entry2);
657 if (entry_text[0] != '\0')
658 flt->body2 = g_strdup(entry_text);
661 if (gtk_toggle_button_get_active
662 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn)))
663 flt->flag1 = flt->flag2 = FLT_REGEX;
665 GET_ENTRY(filter.pred_entry1);
666 if (!strcmp(entry_text, _("contains")))
667 flt->flag1 |= FLT_CONTAIN;
668 GET_ENTRY(filter.pred_entry2);
669 if (!strcmp(entry_text, _("contains")))
670 flt->flag2 |= FLT_CONTAIN;
672 GET_ENTRY(filter.cond_entry);
673 if (!strcmp(entry_text, "and"))
678 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
679 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
680 flt->dest = g_strdup(entry_text);
681 flt->action = FLT_MOVE;
683 flt->action = FLT_NOTRECV;
685 cond_str[0] = filter_get_str(flt);
686 subst_char(cond_str[0], '\t', ':');
689 row = gtk_clist_append(clist, cond_str);
693 gtk_clist_set_text(clist, row, 0, cond_str[0]);
694 tmpflt = gtk_clist_get_row_data(clist, row);
699 gtk_clist_set_row_data(clist, row, flt);
703 prefs_filter_set_list();
708 static void prefs_filter_select_dest_cb(void)
712 dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
715 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
718 static void prefs_filter_register_cb(void)
720 prefs_filter_clist_set_row(-1);
723 static void prefs_filter_substitute_cb(void)
725 GtkCList *clist = GTK_CLIST(filter.cond_clist);
729 if (!clist->selection) return;
731 row = GPOINTER_TO_INT(clist->selection->data);
732 if (row == 0) return;
734 flt = gtk_clist_get_row_data(clist, row);
737 prefs_filter_clist_set_row(row);
740 static void prefs_filter_delete_cb(void)
742 GtkCList *clist = GTK_CLIST(filter.cond_clist);
746 if (!clist->selection) return;
747 row = GPOINTER_TO_INT(clist->selection->data);
748 if (row == 0) return;
750 if (alertpanel(_("Delete rule"),
751 _("Do you really want to delete this rule?"),
752 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
755 flt = gtk_clist_get_row_data(clist, row);
757 gtk_clist_remove(clist, row);
758 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
761 static void prefs_filter_up(void)
763 GtkCList *clist = GTK_CLIST(filter.cond_clist);
766 if (!clist->selection) return;
768 row = GPOINTER_TO_INT(clist->selection->data);
770 gtk_clist_row_move(clist, row, row - 1);
773 static void prefs_filter_down(void)
775 GtkCList *clist = GTK_CLIST(filter.cond_clist);
778 if (!clist->selection) return;
780 row = GPOINTER_TO_INT(clist->selection->data);
781 if (row > 0 && row < clist->rows - 1)
782 gtk_clist_row_move(clist, row, row + 1);
785 #define ENTRY_SET_TEXT(entry, str) \
786 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
788 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
792 Filter default_flt = {"Subject", NULL, NULL, NULL,
793 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
797 default_flt.name2 = _("(none)");
799 flt = gtk_clist_get_row_data(clist, row);
803 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
804 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
805 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
806 ENTRY_SET_TEXT(filter.hdr_entry2,
807 flt->name2 ? flt->name2 : _("(none)"));
808 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
810 ENTRY_SET_TEXT(filter.pred_entry1,
811 FLT_IS_CONTAIN(flt->flag1)
812 ? _("contains") : _("not contain"));
813 ENTRY_SET_TEXT(filter.pred_entry2,
814 FLT_IS_CONTAIN(flt->flag2)
815 ? _("contains") : _("not contain"));
817 is_regex = FLT_IS_REGEX(flt->flag1);
818 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
819 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
820 gtk_toggle_button_set_active
821 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn), is_regex);
823 gtk_entry_set_text(GTK_ENTRY(filter.cond_entry),
824 flt->cond == FLT_OR ? "or" : "and");
825 if (flt->action == FLT_NOTRECV)
826 gtk_toggle_button_set_active
827 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
829 gtk_toggle_button_set_active
830 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
833 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
836 prefs_filter_set_list();
837 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
838 gtk_clist_moveto(clist, dest_row, -1,
839 source_row < dest_row ? 1.0 : 0.0, 0.0);
843 static void prefs_filter_dest_radio_button_toggled(void)
845 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
846 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
849 static void prefs_filter_notrecv_radio_button_toggled(void)
851 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
852 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
855 static void prefs_filter_regex_check_button_toggled(void)
859 is_regex = gtk_toggle_button_get_active
860 (GTK_TOGGLE_BUTTON(filter.regex_chkbtn));
861 gtk_widget_set_sensitive(filter.pred_combo1, !is_regex);
862 gtk_widget_set_sensitive(filter.pred_combo2, !is_regex);
865 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
868 prefs_filter_cancel();
872 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
875 if (event && event->keyval == GDK_Escape)
876 prefs_filter_cancel();
879 static void prefs_filter_ok(void)
881 prefs_filter_write_config();
882 gtk_widget_hide(filter.window);
886 static void prefs_filter_cancel(void)
888 prefs_filter_read_config();
889 gtk_widget_hide(filter.window);