2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2001 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <gdk/gdkkeysyms.h>
37 #include "prefs_filter.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
46 #include "alertpanel.h"
49 static struct Filter {
54 GtkWidget *hdr_combo1;
55 GtkWidget *hdr_combo2;
56 GtkWidget *hdr_entry1;
57 GtkWidget *hdr_entry2;
58 GtkWidget *key_entry1;
59 GtkWidget *key_entry2;
60 GtkWidget *pred_combo1;
61 GtkWidget *pred_combo2;
62 GtkWidget *pred_entry1;
63 GtkWidget *pred_entry2;
67 GtkWidget *dest_entry;
68 GtkWidget *regex_chkbtn;
70 GtkWidget *destsel_btn;
71 GtkWidget *dest_radiobtn;
72 GtkWidget *notrecv_radiobtn;
74 GtkWidget *cond_clist;
78 parameter name, default value, pointer to the prefs variable, data type,
79 pointer to the widget pointer,
80 pointer to the function for data setting,
81 pointer to the function for widget setting
85 #define VSPACING_NARROW 4
86 #define DEFAULT_ENTRY_WIDTH 80
87 #define PREFSBUFSIZE 1024
89 /* widget creating functions */
90 static void prefs_filter_create (void);
92 static void prefs_filter_set_dialog (void);
93 static void prefs_filter_set_list (void);
94 static gint prefs_filter_clist_set_row (gint row);
96 /* callback functions */
97 static void prefs_filter_select_dest_cb (void);
98 static void prefs_filter_register_cb (void);
99 static void prefs_filter_substitute_cb (void);
100 static void prefs_filter_delete_cb (void);
101 static void prefs_filter_up (void);
102 static void prefs_filter_down (void);
103 static void prefs_filter_select (GtkCList *clist,
108 static void prefs_filter_dest_radio_button_toggled (void);
109 static void prefs_filter_notrecv_radio_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(void)
122 inc_autocheck_timer_remove();
124 if (!filter.window) {
125 prefs_filter_create();
128 manage_window_set_transient(GTK_WINDOW(filter.window));
129 gtk_widget_grab_focus(filter.ok_btn);
131 prefs_filter_set_dialog();
133 gtk_widget_show(filter.window);
136 static void prefs_filter_create(void)
141 GtkWidget *cancel_btn;
142 GtkWidget *confirm_area;
149 GtkWidget *hdr_label;
150 GtkWidget *hdr_combo1;
151 GtkWidget *hdr_combo2;
152 GtkWidget *key_label;
153 GtkWidget *key_entry1;
154 GtkWidget *key_entry2;
155 GtkWidget *pred_label;
156 GtkWidget *pred_combo1;
157 GtkWidget *pred_entry1;
158 GtkWidget *pred_combo2;
159 GtkWidget *pred_entry2;
162 GtkWidget *dest_hbox;
163 GtkWidget *dest_entry;
164 GtkWidget *destsel_btn;
165 GtkWidget *dest_radiobtn;
166 GtkWidget *notrecv_radiobtn;
167 GSList *recv_group = NULL;
169 GtkWidget *regex_chkbtn;
175 GtkWidget *subst_btn;
178 GtkWidget *cond_hbox;
179 GtkWidget *cond_scrolledwin;
180 GtkWidget *cond_clist;
186 gchar *title[] = {_("Registered rules")};
188 debug_print(_("Creating filter setting window...\n"));
190 window = gtk_window_new (GTK_WINDOW_DIALOG);
191 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
192 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
193 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
194 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
196 vbox = gtk_vbox_new (FALSE, 6);
197 gtk_widget_show (vbox);
198 gtk_container_add (GTK_CONTAINER (window), vbox);
200 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
201 &cancel_btn, _("Cancel"), NULL, NULL);
202 gtk_widget_show (confirm_area);
203 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
204 gtk_widget_grab_default (ok_btn);
207 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
208 NULL, NULL, NULL, NULL);
209 gtk_widget_show (confirm_area);
210 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
211 gtk_widget_grab_default (close_btn);
214 gtk_window_set_title (GTK_WINDOW(window),
215 _("Filter setting"));
216 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
217 GTK_SIGNAL_FUNC(prefs_filter_deleted), NULL);
218 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
219 GTK_SIGNAL_FUNC(prefs_filter_key_pressed), NULL);
220 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
221 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
222 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
223 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
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 op_label = gtk_label_new (_("Operator"));
241 gtk_widget_show (op_label);
242 gtk_table_attach (GTK_TABLE (table1), op_label, 0, 1, 0, 1,
244 gtk_misc_set_alignment (GTK_MISC (op_label), 0, 0.5);
246 op_combo = gtk_combo_new ();
247 gtk_widget_show (op_combo);
248 gtk_table_attach (GTK_TABLE (table1), op_combo, 0, 1, 2, 3,
250 gtk_widget_set_usize (op_combo, 52, -1);
251 gtkut_combo_set_items (GTK_COMBO (op_combo), "and", "or", NULL);
253 op_entry = GTK_COMBO (op_combo)->entry;
254 gtk_entry_set_editable (GTK_ENTRY (op_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",
269 "Sender", "X-ML-Name", "X-List", "X-Sequence",
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",
280 "Sender", "X-ML-Name", "X-List", "X-Sequence",
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"));
369 gtk_widget_set_sensitive(regex_chkbtn, FALSE);
371 notrecv_radiobtn = gtk_radio_button_new_with_label
372 (recv_group, _("Don't receive"));
373 recv_group = gtk_radio_button_group
374 (GTK_RADIO_BUTTON (notrecv_radiobtn));
375 gtk_widget_show (notrecv_radiobtn);
376 gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
378 (GTK_OBJECT (notrecv_radiobtn), "toggled",
379 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
382 /* register / substitute / delete */
384 reg_hbox = gtk_hbox_new (FALSE, 4);
385 gtk_widget_show (reg_hbox);
386 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
388 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
389 gtk_widget_show (arrow);
390 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
391 gtk_widget_set_usize (arrow, -1, 16);
393 btn_hbox = gtk_hbox_new (TRUE, 4);
394 gtk_widget_show (btn_hbox);
395 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
397 reg_btn = gtk_button_new_with_label (_("Register"));
398 gtk_widget_show (reg_btn);
399 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
400 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
401 GTK_SIGNAL_FUNC (prefs_filter_register_cb), NULL);
403 subst_btn = gtk_button_new_with_label (_(" Substitute "));
404 gtk_widget_show (subst_btn);
405 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
406 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
407 GTK_SIGNAL_FUNC (prefs_filter_substitute_cb),
410 del_btn = gtk_button_new_with_label (_("Delete"));
411 gtk_widget_show (del_btn);
412 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
413 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
414 GTK_SIGNAL_FUNC (prefs_filter_delete_cb), NULL);
416 cond_hbox = gtk_hbox_new (FALSE, 8);
417 gtk_widget_show (cond_hbox);
418 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
420 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
421 gtk_widget_show (cond_scrolledwin);
422 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
423 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
425 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
426 GTK_POLICY_AUTOMATIC,
427 GTK_POLICY_AUTOMATIC);
429 cond_clist = gtk_clist_new_with_titles(1, title);
430 gtk_widget_show (cond_clist);
431 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
432 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
433 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
434 GTK_SELECTION_BROWSE);
435 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
437 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
438 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
440 btn_vbox = gtk_vbox_new (FALSE, 8);
441 gtk_widget_show (btn_vbox);
442 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
444 up_btn = gtk_button_new_with_label (_("Up"));
445 gtk_widget_show (up_btn);
446 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
447 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
448 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
450 down_btn = gtk_button_new_with_label (_("Down"));
451 gtk_widget_show (down_btn);
452 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
453 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
454 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
456 gtk_widget_show_all(window);
458 filter.window = window;
459 filter.ok_btn = ok_btn;
461 filter.hdr_combo1 = hdr_combo1;
462 filter.hdr_combo2 = hdr_combo2;
463 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
464 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
465 filter.key_entry1 = key_entry1;
466 filter.key_entry2 = key_entry2;
467 filter.pred_combo1 = pred_combo1;
468 filter.pred_combo2 = pred_combo2;
469 filter.pred_entry1 = pred_entry1;
470 filter.pred_entry2 = pred_entry2;
471 filter.op_combo = op_combo;
472 filter.op_entry = op_entry;
474 filter.dest_entry = dest_entry;
475 filter.destsel_btn = destsel_btn;
476 filter.dest_radiobtn = dest_radiobtn;
477 filter.notrecv_radiobtn = notrecv_radiobtn;
478 filter.regex_chkbtn = regex_chkbtn;
480 filter.cond_clist = cond_clist;
483 void prefs_filter_read_config(void)
487 gchar buf[PREFSBUFSIZE];
490 debug_print(_("Reading filter configuration...\n"));
492 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
493 if ((fp = fopen(rcpath, "r")) == NULL) {
494 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
500 /* remove all previous filter list */
501 while (prefs_common.fltlist != NULL) {
502 flt = (Filter *)prefs_common.fltlist->data;
504 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
508 while (fgets(buf, sizeof(buf), fp) != NULL) {
510 flt = filter_read_str(buf);
512 prefs_common.fltlist =
513 g_slist_append(prefs_common.fltlist, flt);
520 void prefs_filter_write_config(void)
526 debug_print(_("Writing filter configuration...\n"));
528 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
529 if ((pfile = prefs_write_open(rcpath)) == NULL) {
530 g_warning(_("failed to write configuration to file\n"));
535 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
536 Filter *flt = (Filter *)cur->data;
539 fstr = filter_get_str(flt);
540 if (fputs(fstr, pfile->fp) == EOF ||
541 fputc('\n', pfile->fp) == EOF) {
542 FILE_OP_ERROR(rcpath, "fputs || fputc");
543 prefs_write_close_revert(pfile);
553 if (prefs_write_close(pfile) < 0) {
554 g_warning(_("failed to write configuration to file\n"));
559 static void prefs_filter_set_dialog(void)
561 GtkCList *clist = GTK_CLIST(filter.cond_clist);
566 gtk_clist_freeze(clist);
567 gtk_clist_clear(clist);
569 cond_str[0] = _("(New)");
570 row = gtk_clist_append(clist, cond_str);
571 gtk_clist_set_row_data(clist, row, NULL);
573 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
574 Filter *flt = (Filter *)cur->data;
576 cond_str[0] = filter_get_str(flt);
577 subst_char(cond_str[0], '\t', ':');
578 row = gtk_clist_append(clist, cond_str);
579 gtk_clist_set_row_data(clist, row, flt);
584 gtk_clist_thaw(clist);
587 static void prefs_filter_set_list(void)
592 g_slist_free(prefs_common.fltlist);
593 prefs_common.fltlist = NULL;
595 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
597 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
603 #define GET_ENTRY(entry) \
604 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
606 static gint prefs_filter_clist_set_row(gint row)
608 GtkCList *clist = GTK_CLIST(filter.cond_clist);
613 g_return_val_if_fail(row != 0, -1);
615 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
616 GET_ENTRY(filter.dest_entry);
618 entry_text = FILTER_NOT_RECEIVE;
619 if (entry_text[0] == '\0') {
620 alertpanel_error(_("Destination is not set."));
623 GET_ENTRY(filter.hdr_entry1);
624 if (entry_text[0] == '\0') {
625 alertpanel_error(_("Header name is not set."));
629 flt = g_new0(Filter, 1);
631 flt->name1 = g_strdup(entry_text);
633 GET_ENTRY(filter.key_entry1);
634 if (entry_text[0] != '\0')
635 flt->body1 = g_strdup(entry_text);
637 GET_ENTRY(filter.hdr_entry2);
638 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
639 flt->name2 = g_strdup(entry_text);
641 GET_ENTRY(filter.key_entry2);
642 if (entry_text[0] != '\0')
643 flt->body2 = g_strdup(entry_text);
646 GET_ENTRY(filter.pred_entry1);
647 if (!strcmp(entry_text, _("contains")))
648 flt->flag1 = FLT_CONTAIN;
649 GET_ENTRY(filter.pred_entry2);
650 if (!strcmp(entry_text, _("contains")))
651 flt->flag2 = FLT_CONTAIN;
653 GET_ENTRY(filter.op_entry);
654 if (!strcmp(entry_text, "and"))
659 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
660 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
661 flt->dest = g_strdup(entry_text);
662 flt->action = FLT_MOVE;
664 flt->action = FLT_NOTRECV;
666 cond_str[0] = filter_get_str(flt);
667 subst_char(cond_str[0], '\t', ':');
670 row = gtk_clist_append(clist, cond_str);
674 gtk_clist_set_text(clist, row, 0, cond_str[0]);
675 tmpflt = gtk_clist_get_row_data(clist, row);
680 gtk_clist_set_row_data(clist, row, flt);
684 prefs_filter_set_list();
689 static void prefs_filter_select_dest_cb(void)
693 dest = foldersel_folder_sel(NULL);
696 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
699 static void prefs_filter_register_cb(void)
701 prefs_filter_clist_set_row(-1);
704 static void prefs_filter_substitute_cb(void)
706 GtkCList *clist = GTK_CLIST(filter.cond_clist);
710 if (!clist->selection) return;
712 row = GPOINTER_TO_INT(clist->selection->data);
713 if (row == 0) return;
715 flt = gtk_clist_get_row_data(clist, row);
718 prefs_filter_clist_set_row(row);
721 static void prefs_filter_delete_cb(void)
723 GtkCList *clist = GTK_CLIST(filter.cond_clist);
727 if (!clist->selection) return;
728 row = GPOINTER_TO_INT(clist->selection->data);
729 if (row == 0) return;
731 if (alertpanel(_("Delete rule"),
732 _("Do you really want to delete this rule?"),
733 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
736 flt = gtk_clist_get_row_data(clist, row);
738 gtk_clist_remove(clist, row);
739 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
742 static void prefs_filter_up(void)
744 GtkCList *clist = GTK_CLIST(filter.cond_clist);
747 if (!clist->selection) return;
749 row = GPOINTER_TO_INT(clist->selection->data);
751 gtk_clist_row_move(clist, row, row - 1);
752 prefs_filter_set_list();
756 static void prefs_filter_down(void)
758 GtkCList *clist = GTK_CLIST(filter.cond_clist);
761 if (!clist->selection) return;
763 row = GPOINTER_TO_INT(clist->selection->data);
764 if (row > 0 && row < clist->rows - 1) {
765 gtk_clist_row_move(clist, row, row + 1);
766 prefs_filter_set_list();
770 #define ENTRY_SET_TEXT(entry, str) \
771 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
773 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
777 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
778 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
781 flt = gtk_clist_get_row_data(clist, row);
785 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
786 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
787 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
788 ENTRY_SET_TEXT(filter.hdr_entry2,
789 flt->name2 ? flt->name2 : _("(none)"));
790 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
792 ENTRY_SET_TEXT(filter.pred_entry1,
793 FLT_IS_CONTAIN(flt->flag1)
794 ? _("contains") : _("not contain"));
795 ENTRY_SET_TEXT(filter.pred_entry2,
796 FLT_IS_CONTAIN(flt->flag2)
797 ? _("contains") : _("not contain"));
799 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
800 flt->cond == FLT_OR ? "or" : "and");
801 if (flt->action == FLT_NOTRECV)
802 gtk_toggle_button_set_active
803 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
805 gtk_toggle_button_set_active
806 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
809 static void prefs_filter_dest_radio_button_toggled(void)
811 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
812 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
815 static void prefs_filter_notrecv_radio_button_toggled(void)
817 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
818 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
821 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
824 prefs_filter_cancel();
828 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
831 if (event && event->keyval == GDK_Escape)
832 prefs_filter_cancel();
835 static void prefs_filter_ok(void)
837 prefs_filter_write_config();
838 gtk_widget_hide(filter.window);
839 inc_autocheck_timer_set();
842 static void prefs_filter_cancel(void)
844 prefs_filter_read_config();
845 gtk_widget_hide(filter.window);
846 inc_autocheck_timer_set();