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
84 /* widget creating functions */
85 static void prefs_filter_create (void);
87 static void prefs_filter_set_dialog (void);
88 static void prefs_filter_set_list (void);
89 static gint prefs_filter_clist_set_row (gint row);
91 /* callback functions */
92 static void prefs_filter_select_dest_cb (void);
93 static void prefs_filter_register_cb (void);
94 static void prefs_filter_substitute_cb (void);
95 static void prefs_filter_delete_cb (void);
96 static void prefs_filter_up (void);
97 static void prefs_filter_down (void);
98 static void prefs_filter_select (GtkCList *clist,
102 static void prefs_filter_row_move (GtkCList *clist,
106 static void prefs_filter_dest_radio_button_toggled (void);
107 static void prefs_filter_notrecv_radio_button_toggled (void);
109 static gint prefs_filter_deleted (GtkWidget *widget,
112 static void prefs_filter_key_pressed (GtkWidget *widget,
115 static void prefs_filter_cancel (void);
116 static void prefs_filter_ok (void);
118 void prefs_filter_open(void)
120 if (prefs_rc_is_readonly(FILTER_RC))
123 inc_autocheck_timer_remove();
125 if (!filter.window) {
126 prefs_filter_create();
129 manage_window_set_transient(GTK_WINDOW(filter.window));
130 gtk_widget_grab_focus(filter.ok_btn);
132 prefs_filter_set_dialog();
134 gtk_widget_show(filter.window);
137 static void prefs_filter_create(void)
142 GtkWidget *cancel_btn;
143 GtkWidget *confirm_area;
150 GtkWidget *hdr_label;
151 GtkWidget *hdr_combo1;
152 GtkWidget *hdr_combo2;
153 GtkWidget *key_label;
154 GtkWidget *key_entry1;
155 GtkWidget *key_entry2;
156 GtkWidget *pred_label;
157 GtkWidget *pred_combo1;
158 GtkWidget *pred_entry1;
159 GtkWidget *pred_combo2;
160 GtkWidget *pred_entry2;
163 GtkWidget *dest_hbox;
164 GtkWidget *dest_entry;
165 GtkWidget *destsel_btn;
166 GtkWidget *dest_radiobtn;
167 GtkWidget *notrecv_radiobtn;
168 GSList *recv_group = NULL;
170 GtkWidget *regex_chkbtn;
176 GtkWidget *subst_btn;
179 GtkWidget *cond_hbox;
180 GtkWidget *cond_scrolledwin;
181 GtkWidget *cond_clist;
187 gchar *title[] = {_("Registered rules")};
189 debug_print(_("Creating filter setting window...\n"));
191 window = gtk_window_new (GTK_WINDOW_DIALOG);
192 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
193 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
194 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
195 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
197 vbox = gtk_vbox_new (FALSE, 6);
198 gtk_widget_show (vbox);
199 gtk_container_add (GTK_CONTAINER (window), vbox);
201 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
202 &cancel_btn, _("Cancel"), NULL, NULL);
203 gtk_widget_show (confirm_area);
204 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
205 gtk_widget_grab_default (ok_btn);
208 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
209 NULL, NULL, NULL, NULL);
210 gtk_widget_show (confirm_area);
211 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
212 gtk_widget_grab_default (close_btn);
215 gtk_window_set_title (GTK_WINDOW(window),
216 _("Filter setting"));
217 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
218 GTK_SIGNAL_FUNC(prefs_filter_deleted), NULL);
219 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
220 GTK_SIGNAL_FUNC(prefs_filter_key_pressed), NULL);
221 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
222 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
223 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
224 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
225 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
226 GTK_SIGNAL_FUNC(prefs_filter_ok), NULL);
227 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
228 GTK_SIGNAL_FUNC(prefs_filter_cancel), NULL);
230 vbox1 = gtk_vbox_new (FALSE, VSPACING);
231 gtk_widget_show (vbox1);
232 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
233 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
235 table1 = gtk_table_new (3, 4, FALSE);
236 gtk_widget_show (table1);
237 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
238 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
239 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
241 op_label = gtk_label_new (_("Operator"));
242 gtk_widget_show (op_label);
243 gtk_table_attach (GTK_TABLE (table1), op_label, 0, 1, 0, 1,
245 gtk_misc_set_alignment (GTK_MISC (op_label), 0, 0.5);
247 op_combo = gtk_combo_new ();
248 gtk_widget_show (op_combo);
249 gtk_table_attach (GTK_TABLE (table1), op_combo, 0, 1, 2, 3,
251 gtk_widget_set_usize (op_combo, 52, -1);
252 gtkut_combo_set_items (GTK_COMBO (op_combo), "and", "or", NULL);
254 op_entry = GTK_COMBO (op_combo)->entry;
255 gtk_entry_set_editable (GTK_ENTRY (op_entry), FALSE);
257 hdr_label = gtk_label_new (_("Header"));
258 gtk_widget_show (hdr_label);
259 gtk_table_attach (GTK_TABLE (table1), hdr_label, 1, 2, 0, 1,
261 gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
263 hdr_combo1 = gtk_combo_new ();
264 gtk_widget_show (hdr_combo1);
265 gtk_table_attach (GTK_TABLE (table1), hdr_combo1, 1, 2, 1, 2,
267 gtk_widget_set_usize (hdr_combo1, 96, -1);
268 gtkut_combo_set_items (GTK_COMBO (hdr_combo1),
269 "Subject", "From", "To", "Cc", "Reply-To",
271 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
274 hdr_combo2 = gtk_combo_new ();
275 gtk_widget_show (hdr_combo2);
276 gtk_table_attach (GTK_TABLE (table1), hdr_combo2, 1, 2, 2, 3,
278 gtk_widget_set_usize (hdr_combo2, 96, -1);
279 gtkut_combo_set_items (GTK_COMBO (hdr_combo2), _("(none)"),
280 "Subject", "From", "To", "Cc", "Reply-To",
282 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
285 key_label = gtk_label_new (_("Keyword"));
286 gtk_widget_show (key_label);
287 gtk_table_attach (GTK_TABLE (table1), key_label, 2, 3, 0, 1,
288 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
290 gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
292 key_entry1 = gtk_entry_new ();
293 gtk_widget_show (key_entry1);
294 gtk_widget_set_usize (key_entry1, 128, -1);
295 gtk_table_attach (GTK_TABLE (table1), key_entry1, 2, 3, 1, 2,
296 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
299 key_entry2 = gtk_entry_new ();
300 gtk_widget_show (key_entry2);
301 gtk_widget_set_usize (key_entry2, 128, -1);
302 gtk_table_attach (GTK_TABLE (table1), key_entry2, 2, 3, 2, 3,
303 GTK_EXPAND | GTK_SHRINK | GTK_FILL,
306 pred_label = gtk_label_new (_("Predicate"));
307 gtk_widget_show (pred_label);
308 gtk_table_attach (GTK_TABLE (table1), pred_label, 3, 4, 0, 1,
310 gtk_misc_set_alignment (GTK_MISC (pred_label), 0, 0.5);
312 pred_combo1 = gtk_combo_new ();
313 gtk_widget_show (pred_combo1);
314 gtk_table_attach (GTK_TABLE (table1), pred_combo1, 3, 4, 1, 2,
316 gtk_widget_set_usize (pred_combo1, 92, -1);
317 gtkut_combo_set_items (GTK_COMBO (pred_combo1),
318 _("contains"), _("not contain"), NULL);
320 pred_entry1 = GTK_COMBO (pred_combo1)->entry;
321 gtk_entry_set_editable (GTK_ENTRY (pred_entry1), FALSE);
323 pred_combo2 = gtk_combo_new ();
324 gtk_widget_show (pred_combo2);
325 gtk_table_attach (GTK_TABLE (table1), pred_combo2, 3, 4, 2, 3,
327 gtk_widget_set_usize (pred_combo2, 92, -1);
328 gtkut_combo_set_items (GTK_COMBO (pred_combo2),
329 _("contains"), _("not contain"), NULL);
331 pred_entry2 = GTK_COMBO (pred_combo2)->entry;
332 gtk_entry_set_editable (GTK_ENTRY (pred_entry2), FALSE);
336 vbox2 = gtk_vbox_new (FALSE, VSPACING_NARROW);
337 gtk_widget_show (vbox2);
338 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
340 dest_hbox = gtk_hbox_new (FALSE, 8);
341 gtk_widget_show (dest_hbox);
342 gtk_box_pack_start (GTK_BOX (vbox2), dest_hbox, FALSE, TRUE, 0);
345 gtk_radio_button_new_with_label (recv_group, _("Destination"));
346 recv_group = gtk_radio_button_group (GTK_RADIO_BUTTON (dest_radiobtn));
347 gtk_widget_show (dest_radiobtn);
348 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_radiobtn,
350 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
352 (GTK_OBJECT (dest_radiobtn), "toggled",
353 GTK_SIGNAL_FUNC (prefs_filter_dest_radio_button_toggled),
356 dest_entry = gtk_entry_new ();
357 gtk_widget_show (dest_entry);
358 gtk_widget_set_usize (dest_entry, DEFAULT_ENTRY_WIDTH, -1);
359 gtk_box_pack_start (GTK_BOX (dest_hbox), dest_entry, TRUE, TRUE, 0);
360 gtk_entry_set_editable (GTK_ENTRY (dest_entry), FALSE);
362 destsel_btn = gtk_button_new_with_label (_(" Select... "));
363 gtk_widget_show (destsel_btn);
364 gtk_box_pack_start (GTK_BOX (dest_hbox), destsel_btn, FALSE, FALSE, 0);
365 gtk_signal_connect (GTK_OBJECT (destsel_btn), "clicked",
366 GTK_SIGNAL_FUNC (prefs_filter_select_dest_cb),
369 PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
370 gtk_widget_set_sensitive(regex_chkbtn, FALSE);
372 notrecv_radiobtn = gtk_radio_button_new_with_label
373 (recv_group, _("Don't receive"));
374 recv_group = gtk_radio_button_group
375 (GTK_RADIO_BUTTON (notrecv_radiobtn));
376 gtk_widget_show (notrecv_radiobtn);
377 gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
379 (GTK_OBJECT (notrecv_radiobtn), "toggled",
380 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
383 /* register / substitute / delete */
385 reg_hbox = gtk_hbox_new (FALSE, 4);
386 gtk_widget_show (reg_hbox);
387 gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
389 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
390 gtk_widget_show (arrow);
391 gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
392 gtk_widget_set_usize (arrow, -1, 16);
394 btn_hbox = gtk_hbox_new (TRUE, 4);
395 gtk_widget_show (btn_hbox);
396 gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
398 reg_btn = gtk_button_new_with_label (_("Register"));
399 gtk_widget_show (reg_btn);
400 gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
401 gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
402 GTK_SIGNAL_FUNC (prefs_filter_register_cb), NULL);
404 subst_btn = gtk_button_new_with_label (_(" Substitute "));
405 gtk_widget_show (subst_btn);
406 gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
407 gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
408 GTK_SIGNAL_FUNC (prefs_filter_substitute_cb),
411 del_btn = gtk_button_new_with_label (_("Delete"));
412 gtk_widget_show (del_btn);
413 gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
414 gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
415 GTK_SIGNAL_FUNC (prefs_filter_delete_cb), NULL);
417 cond_hbox = gtk_hbox_new (FALSE, 8);
418 gtk_widget_show (cond_hbox);
419 gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
421 cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
422 gtk_widget_show (cond_scrolledwin);
423 gtk_widget_set_usize (cond_scrolledwin, -1, 150);
424 gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
426 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
427 GTK_POLICY_AUTOMATIC,
428 GTK_POLICY_AUTOMATIC);
430 cond_clist = gtk_clist_new_with_titles(1, title);
431 gtk_widget_show (cond_clist);
432 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
433 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
434 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
435 GTK_SELECTION_BROWSE);
436 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
438 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
439 GTK_SIGNAL_FUNC (prefs_filter_select), NULL);
440 gtk_signal_connect (GTK_OBJECT (cond_clist), "row_move",
441 GTK_SIGNAL_FUNC (prefs_filter_row_move), NULL);
443 btn_vbox = gtk_vbox_new (FALSE, 8);
444 gtk_widget_show (btn_vbox);
445 gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
447 up_btn = gtk_button_new_with_label (_("Up"));
448 gtk_widget_show (up_btn);
449 gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
450 gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
451 GTK_SIGNAL_FUNC (prefs_filter_up), NULL);
453 down_btn = gtk_button_new_with_label (_("Down"));
454 gtk_widget_show (down_btn);
455 gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
456 gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
457 GTK_SIGNAL_FUNC (prefs_filter_down), NULL);
459 gtk_widget_show_all(window);
461 filter.window = window;
462 filter.ok_btn = ok_btn;
464 filter.hdr_combo1 = hdr_combo1;
465 filter.hdr_combo2 = hdr_combo2;
466 filter.hdr_entry1 = GTK_COMBO (hdr_combo1)->entry;
467 filter.hdr_entry2 = GTK_COMBO (hdr_combo2)->entry;
468 filter.key_entry1 = key_entry1;
469 filter.key_entry2 = key_entry2;
470 filter.pred_combo1 = pred_combo1;
471 filter.pred_combo2 = pred_combo2;
472 filter.pred_entry1 = pred_entry1;
473 filter.pred_entry2 = pred_entry2;
474 filter.op_combo = op_combo;
475 filter.op_entry = op_entry;
477 filter.dest_entry = dest_entry;
478 filter.destsel_btn = destsel_btn;
479 filter.dest_radiobtn = dest_radiobtn;
480 filter.notrecv_radiobtn = notrecv_radiobtn;
481 filter.regex_chkbtn = regex_chkbtn;
483 filter.cond_clist = cond_clist;
486 void prefs_filter_read_config(void)
490 gchar buf[PREFSBUFSIZE];
493 debug_print(_("Reading filter configuration...\n"));
495 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
496 if ((fp = fopen(rcpath, "r")) == NULL) {
497 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
503 /* remove all previous filter list */
504 while (prefs_common.fltlist != NULL) {
505 flt = (Filter *)prefs_common.fltlist->data;
507 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
511 while (fgets(buf, sizeof(buf), fp) != NULL) {
513 flt = filter_read_str(buf);
515 prefs_common.fltlist =
516 g_slist_append(prefs_common.fltlist, flt);
523 void prefs_filter_write_config(void)
529 debug_print(_("Writing filter configuration...\n"));
531 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_RC, NULL);
532 if ((pfile = prefs_write_open(rcpath)) == NULL) {
533 g_warning(_("failed to write configuration to file\n"));
538 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
539 Filter *flt = (Filter *)cur->data;
542 fstr = filter_get_str(flt);
543 if (fputs(fstr, pfile->fp) == EOF ||
544 fputc('\n', pfile->fp) == EOF) {
545 FILE_OP_ERROR(rcpath, "fputs || fputc");
546 prefs_write_close_revert(pfile);
556 if (prefs_write_close(pfile) < 0) {
557 g_warning(_("failed to write configuration to file\n"));
562 static void prefs_filter_set_dialog(void)
564 GtkCList *clist = GTK_CLIST(filter.cond_clist);
569 gtk_clist_freeze(clist);
570 gtk_clist_clear(clist);
572 cond_str[0] = _("(New)");
573 row = gtk_clist_append(clist, cond_str);
574 gtk_clist_set_row_data(clist, row, NULL);
576 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
577 Filter *flt = (Filter *)cur->data;
579 cond_str[0] = filter_get_str(flt);
580 subst_char(cond_str[0], '\t', ':');
581 row = gtk_clist_append(clist, cond_str);
582 gtk_clist_set_row_data(clist, row, flt);
587 gtk_clist_thaw(clist);
590 static void prefs_filter_set_list(void)
595 g_slist_free(prefs_common.fltlist);
596 prefs_common.fltlist = NULL;
598 while ((flt = gtk_clist_get_row_data(GTK_CLIST(filter.cond_clist),
600 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
606 #define GET_ENTRY(entry) \
607 entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
609 static gint prefs_filter_clist_set_row(gint row)
611 GtkCList *clist = GTK_CLIST(filter.cond_clist);
616 g_return_val_if_fail(row != 0, -1);
618 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
619 GET_ENTRY(filter.dest_entry);
621 entry_text = FILTER_NOT_RECEIVE;
622 if (entry_text[0] == '\0') {
623 alertpanel_error(_("Destination is not set."));
626 GET_ENTRY(filter.hdr_entry1);
627 if (entry_text[0] == '\0') {
628 alertpanel_error(_("Header name is not set."));
632 flt = g_new0(Filter, 1);
634 flt->name1 = g_strdup(entry_text);
636 GET_ENTRY(filter.key_entry1);
637 if (entry_text[0] != '\0')
638 flt->body1 = g_strdup(entry_text);
640 GET_ENTRY(filter.hdr_entry2);
641 if (entry_text[0] != '\0' && strcmp(entry_text, _("(none)")) != 0) {
642 flt->name2 = g_strdup(entry_text);
644 GET_ENTRY(filter.key_entry2);
645 if (entry_text[0] != '\0')
646 flt->body2 = g_strdup(entry_text);
649 GET_ENTRY(filter.pred_entry1);
650 if (!strcmp(entry_text, _("contains")))
651 flt->flag1 = FLT_CONTAIN;
652 GET_ENTRY(filter.pred_entry2);
653 if (!strcmp(entry_text, _("contains")))
654 flt->flag2 = FLT_CONTAIN;
656 GET_ENTRY(filter.op_entry);
657 if (!strcmp(entry_text, "and"))
662 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry)) {
663 entry_text = gtk_entry_get_text(GTK_ENTRY(filter.dest_entry));
664 flt->dest = g_strdup(entry_text);
665 flt->action = FLT_MOVE;
667 flt->action = FLT_NOTRECV;
669 cond_str[0] = filter_get_str(flt);
670 subst_char(cond_str[0], '\t', ':');
673 row = gtk_clist_append(clist, cond_str);
677 gtk_clist_set_text(clist, row, 0, cond_str[0]);
678 tmpflt = gtk_clist_get_row_data(clist, row);
683 gtk_clist_set_row_data(clist, row, flt);
687 prefs_filter_set_list();
692 static void prefs_filter_select_dest_cb(void)
696 dest = foldersel_folder_sel(NULL, NULL);
699 gtk_entry_set_text(GTK_ENTRY(filter.dest_entry), dest->path);
702 static void prefs_filter_register_cb(void)
704 prefs_filter_clist_set_row(-1);
707 static void prefs_filter_substitute_cb(void)
709 GtkCList *clist = GTK_CLIST(filter.cond_clist);
713 if (!clist->selection) return;
715 row = GPOINTER_TO_INT(clist->selection->data);
716 if (row == 0) return;
718 flt = gtk_clist_get_row_data(clist, row);
721 prefs_filter_clist_set_row(row);
724 static void prefs_filter_delete_cb(void)
726 GtkCList *clist = GTK_CLIST(filter.cond_clist);
730 if (!clist->selection) return;
731 row = GPOINTER_TO_INT(clist->selection->data);
732 if (row == 0) return;
734 if (alertpanel(_("Delete rule"),
735 _("Do you really want to delete this rule?"),
736 _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
739 flt = gtk_clist_get_row_data(clist, row);
741 gtk_clist_remove(clist, row);
742 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist, flt);
745 static void prefs_filter_up(void)
747 GtkCList *clist = GTK_CLIST(filter.cond_clist);
750 if (!clist->selection) return;
752 row = GPOINTER_TO_INT(clist->selection->data);
754 gtk_clist_row_move(clist, row, row - 1);
757 static void prefs_filter_down(void)
759 GtkCList *clist = GTK_CLIST(filter.cond_clist);
762 if (!clist->selection) return;
764 row = GPOINTER_TO_INT(clist->selection->data);
765 if (row > 0 && row < clist->rows - 1)
766 gtk_clist_row_move(clist, row, row + 1);
769 #define ENTRY_SET_TEXT(entry, str) \
770 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
772 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
776 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
777 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
780 flt = gtk_clist_get_row_data(clist, row);
784 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
785 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
786 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
787 ENTRY_SET_TEXT(filter.hdr_entry2,
788 flt->name2 ? flt->name2 : _("(none)"));
789 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
791 ENTRY_SET_TEXT(filter.pred_entry1,
792 FLT_IS_CONTAIN(flt->flag1)
793 ? _("contains") : _("not contain"));
794 ENTRY_SET_TEXT(filter.pred_entry2,
795 FLT_IS_CONTAIN(flt->flag2)
796 ? _("contains") : _("not contain"));
798 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
799 flt->cond == FLT_OR ? "or" : "and");
800 if (flt->action == FLT_NOTRECV)
801 gtk_toggle_button_set_active
802 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
804 gtk_toggle_button_set_active
805 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
808 static void prefs_filter_row_move(GtkCList *clist, gint source_row,
811 prefs_filter_set_list();
812 if (gtk_clist_row_is_visible(clist, dest_row) != GTK_VISIBILITY_FULL) {
813 gtk_clist_moveto(clist, dest_row, -1,
814 source_row < dest_row ? 1.0 : 0.0, 0.0);
818 static void prefs_filter_dest_radio_button_toggled(void)
820 gtk_widget_set_sensitive(filter.dest_entry, TRUE);
821 gtk_widget_set_sensitive(filter.destsel_btn, TRUE);
824 static void prefs_filter_notrecv_radio_button_toggled(void)
826 gtk_widget_set_sensitive(filter.dest_entry, FALSE);
827 gtk_widget_set_sensitive(filter.destsel_btn, FALSE);
830 static gint prefs_filter_deleted(GtkWidget *widget, GdkEventAny *event,
833 prefs_filter_cancel();
837 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
840 if (event && event->keyval == GDK_Escape)
841 prefs_filter_cancel();
844 static void prefs_filter_ok(void)
846 prefs_filter_write_config();
847 gtk_widget_hide(filter.window);
848 inc_autocheck_timer_set();
851 static void prefs_filter_cancel(void)
853 prefs_filter_read_config();
854 gtk_widget_hide(filter.window);
855 inc_autocheck_timer_set();