initial message templates support
[claws.git] / src / prefs_filter.c
blobf0ae19827eb08f4855550762dcb8996d6e59bc36
1 /*
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.
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include "defs.h"
26 #include <glib.h>
27 #include <gtk/gtk.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
34 #include "intl.h"
35 #include "main.h"
36 #include "prefs.h"
37 #include "prefs_filter.h"
38 #include "prefs_common.h"
39 #include "mainwindow.h"
40 #include "foldersel.h"
41 #include "manage_window.h"
42 #include "inc.h"
43 #include "filter.h"
44 #include "utils.h"
45 #include "gtkutils.h"
46 #include "alertpanel.h"
47 #include "folder.h"
49 static struct Filter {
50 GtkWidget *window;
52 GtkWidget *ok_btn;
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 *op_combo;
65 GtkWidget *op_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;
75 } filter;
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 #define VSPACING 12
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,
104 gint row,
105 gint column,
106 GdkEvent *event);
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,
112 GdkEventAny *event,
113 gpointer data);
114 static void prefs_filter_key_pressed (GtkWidget *widget,
115 GdkEventKey *event,
116 gpointer data);
117 static void prefs_filter_cancel (void);
118 static void prefs_filter_ok (void);
120 void prefs_filter_open(void)
122 if (prefs_rc_is_readonly(FILTER_RC))
123 return;
125 inc_autocheck_timer_remove();
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();
136 gtk_widget_show(filter.window);
139 static void prefs_filter_create(void)
141 GtkWidget *window;
142 GtkWidget *vbox;
143 GtkWidget *ok_btn;
144 GtkWidget *cancel_btn;
145 GtkWidget *confirm_area;
147 GtkWidget *vbox1;
148 GtkWidget *table1;
149 GtkWidget *op_label;
150 GtkWidget *op_combo;
151 GtkWidget *op_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;
164 GtkWidget *vbox2;
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;
174 GtkWidget *reg_hbox;
175 GtkWidget *btn_hbox;
176 GtkWidget *arrow;
177 GtkWidget *reg_btn;
178 GtkWidget *subst_btn;
179 GtkWidget *del_btn;
181 GtkWidget *cond_hbox;
182 GtkWidget *cond_scrolledwin;
183 GtkWidget *cond_clist;
185 GtkWidget *btn_vbox;
186 GtkWidget *up_btn;
187 GtkWidget *down_btn;
189 gchar *title[] = {_("Registered rules")};
191 debug_print(_("Creating filter setting window...\n"));
193 window = gtk_window_new (GTK_WINDOW_DIALOG);
194 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
195 gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
196 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
197 gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
199 vbox = gtk_vbox_new (FALSE, 6);
200 gtk_widget_show (vbox);
201 gtk_container_add (GTK_CONTAINER (window), vbox);
203 gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
204 &cancel_btn, _("Cancel"), NULL, NULL);
205 gtk_widget_show (confirm_area);
206 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
207 gtk_widget_grab_default (ok_btn);
210 gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
211 NULL, NULL, NULL, NULL);
212 gtk_widget_show (confirm_area);
213 gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
214 gtk_widget_grab_default (close_btn);
217 gtk_window_set_title (GTK_WINDOW(window),
218 _("Filter setting"));
219 gtk_signal_connect (GTK_OBJECT(window), "delete_event",
220 GTK_SIGNAL_FUNC(prefs_filter_deleted), NULL);
221 gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
222 GTK_SIGNAL_FUNC(prefs_filter_key_pressed), NULL);
223 gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
224 GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
225 gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
226 GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
227 gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
228 GTK_SIGNAL_FUNC(prefs_filter_ok), NULL);
229 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
230 GTK_SIGNAL_FUNC(prefs_filter_cancel), NULL);
232 vbox1 = gtk_vbox_new (FALSE, VSPACING);
233 gtk_widget_show (vbox1);
234 gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
235 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
237 table1 = gtk_table_new (3, 4, FALSE);
238 gtk_widget_show (table1);
239 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
240 gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
241 gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
243 op_label = gtk_label_new (_("Operator"));
244 gtk_widget_show (op_label);
245 gtk_table_attach (GTK_TABLE (table1), op_label, 0, 1, 0, 1,
246 GTK_FILL, 0, 0, 0);
247 gtk_misc_set_alignment (GTK_MISC (op_label), 0, 0.5);
249 op_combo = gtk_combo_new ();
250 gtk_widget_show (op_combo);
251 gtk_table_attach (GTK_TABLE (table1), op_combo, 0, 1, 2, 3,
252 0, 0, 0, 0);
253 gtk_widget_set_usize (op_combo, 52, -1);
254 gtkut_combo_set_items (GTK_COMBO (op_combo), "and", "or", NULL);
256 op_entry = GTK_COMBO (op_combo)->entry;
257 gtk_entry_set_editable (GTK_ENTRY (op_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,
262 GTK_FILL, 0, 0, 0);
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,
268 0, 0, 0, 0);
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",
272 "Sender", "List-Id",
273 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
274 NULL);
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,
279 0, 0, 0, 0);
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",
283 "Sender", "List-Id",
284 "X-ML-Name", "X-List", "X-Sequence", "X-Mailer",
285 NULL);
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,
291 0, 0, 0);
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,
299 0, 0, 0);
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,
306 0, 0, 0);
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,
311 GTK_FILL, 0, 0, 0);
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,
317 0, 0, 0, 0);
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,
328 0, 0, 0, 0);
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);
336 /* destination */
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);
346 dest_radiobtn =
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,
351 FALSE, FALSE, 0);
352 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
353 gtk_signal_connect
354 (GTK_OBJECT (dest_radiobtn), "toggled",
355 GTK_SIGNAL_FUNC (prefs_filter_dest_radio_button_toggled),
356 NULL);
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),
369 NULL);
371 PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
372 gtk_widget_set_sensitive(regex_chkbtn, FALSE);
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);
380 gtk_signal_connect
381 (GTK_OBJECT (notrecv_radiobtn), "toggled",
382 GTK_SIGNAL_FUNC (prefs_filter_notrecv_radio_button_toggled),
383 NULL);
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),
411 NULL);
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,
427 TRUE, TRUE, 0);
428 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
429 GTK_POLICY_AUTOMATIC,
430 GTK_POLICY_AUTOMATIC);
432 cond_clist = gtk_clist_new_with_titles(1, title);
433 gtk_widget_show (cond_clist);
434 gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
435 gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
436 gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
437 GTK_SELECTION_BROWSE);
438 GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
439 GTK_CAN_FOCUS);
440 gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
441 GTK_SIGNAL_FUNC (prefs_filter_select), 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)
488 gchar *rcpath;
489 FILE *fp;
490 gchar buf[PREFSBUFSIZE];
491 Filter *flt;
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");
498 g_free(rcpath);
499 return;
501 g_free(rcpath);
503 /* remove all previous filter list */
504 while (prefs_common.fltlist != NULL) {
505 flt = (Filter *)prefs_common.fltlist->data;
506 filter_free(flt);
507 prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
508 flt);
511 while (fgets(buf, sizeof(buf), fp) != NULL) {
512 g_strchomp(buf);
513 flt = filter_read_str(buf);
514 if (flt) {
515 prefs_common.fltlist =
516 g_slist_append(prefs_common.fltlist, flt);
520 fclose(fp);
523 void prefs_filter_write_config(void)
525 gchar *rcpath;
526 PrefFile *pfile;
527 GSList *cur;
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"));
534 g_free(rcpath);
535 return;
538 for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
539 Filter *flt = (Filter *)cur->data;
540 gchar *fstr;
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);
547 g_free(rcpath);
548 g_free(fstr);
549 return;
551 g_free(fstr);
554 g_free(rcpath);
556 if (prefs_write_close(pfile) < 0) {
557 g_warning(_("failed to write configuration to file\n"));
558 return;
562 static void prefs_filter_set_dialog(void)
564 GtkCList *clist = GTK_CLIST(filter.cond_clist);
565 GSList *cur;
566 gchar *cond_str[1];
567 gint row;
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);
584 g_free(cond_str[0]);
587 gtk_clist_thaw(clist);
590 static void prefs_filter_set_list(void)
592 gint row = 1;
593 Filter *flt;
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),
599 row)) != NULL) {
600 prefs_common.fltlist = g_slist_append(prefs_common.fltlist,
601 flt);
602 row++;
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);
612 Filter *flt;
613 gchar *entry_text;
614 gchar *cond_str[1];
616 g_return_val_if_fail(row != 0, -1);
618 if (GTK_WIDGET_IS_SENSITIVE(filter.dest_entry))
619 GET_ENTRY(filter.dest_entry);
620 else
621 entry_text = FILTER_NOT_RECEIVE;
622 if (entry_text[0] == '\0') {
623 alertpanel_error(_("Destination is not set."));
624 return -1;
626 GET_ENTRY(filter.hdr_entry1);
627 if (entry_text[0] == '\0') {
628 alertpanel_error(_("Header name is not set."));
629 return -1;
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"))
658 flt->cond = FLT_AND;
659 else
660 flt->cond = FLT_OR;
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;
666 } else
667 flt->action = FLT_NOTRECV;
669 cond_str[0] = filter_get_str(flt);
670 subst_char(cond_str[0], '\t', ':');
672 if (row < 0)
673 row = gtk_clist_append(clist, cond_str);
674 else {
675 Filter *tmpflt;
677 gtk_clist_set_text(clist, row, 0, cond_str[0]);
678 tmpflt = gtk_clist_get_row_data(clist, row);
679 if (tmpflt)
680 filter_free(tmpflt);
683 gtk_clist_set_row_data(clist, row, flt);
685 g_free(cond_str[0]);
687 prefs_filter_set_list();
689 return row;
692 static void prefs_filter_select_dest_cb(void)
694 FolderItem *dest;
696 dest = foldersel_folder_sel(NULL, NULL);
697 if (!dest) return;
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);
710 Filter *flt;
711 gint row;
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);
719 if (!flt) return;
721 prefs_filter_clist_set_row(row);
724 static void prefs_filter_delete_cb(void)
726 GtkCList *clist = GTK_CLIST(filter.cond_clist);
727 Filter *flt;
728 gint row;
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)
737 return;
739 flt = gtk_clist_get_row_data(clist, row);
740 filter_free(flt);
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);
748 gint row;
750 if (!clist->selection) return;
752 row = GPOINTER_TO_INT(clist->selection->data);
753 if (row > 1) {
754 gtk_clist_row_move(clist, row, row - 1);
755 if(gtk_clist_row_is_visible(clist, row - 1) != GTK_VISIBILITY_FULL) {
756 gtk_clist_moveto(clist, row - 1, 0, 0, 0);
758 prefs_filter_set_list();
762 static void prefs_filter_down(void)
764 GtkCList *clist = GTK_CLIST(filter.cond_clist);
765 gint row;
767 if (!clist->selection) return;
769 row = GPOINTER_TO_INT(clist->selection->data);
770 if (row > 0 && row < clist->rows - 1) {
771 gtk_clist_row_move(clist, row, row + 1);
772 if(gtk_clist_row_is_visible(clist, row + 1) != GTK_VISIBILITY_FULL) {
773 gtk_clist_moveto(clist, row + 1, 0, 1, 0);
775 prefs_filter_set_list();
779 #define ENTRY_SET_TEXT(entry, str) \
780 gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
782 static void prefs_filter_select(GtkCList *clist, gint row, gint column,
783 GdkEvent *event)
785 Filter *flt;
786 Filter default_flt = {"Subject", NULL, _("(none)"), NULL,
787 FLT_CONTAIN, FLT_CONTAIN, FLT_AND,
788 NULL, FLT_MOVE};
790 flt = gtk_clist_get_row_data(clist, row);
791 if (!flt)
792 flt = &default_flt;
794 ENTRY_SET_TEXT(filter.dest_entry, flt->dest);
795 ENTRY_SET_TEXT(filter.hdr_entry1, flt->name1);
796 ENTRY_SET_TEXT(filter.key_entry1, flt->body1);
797 ENTRY_SET_TEXT(filter.hdr_entry2,
798 flt->name2 ? flt->name2 : _("(none)"));
799 ENTRY_SET_TEXT(filter.key_entry2, flt->body2);
801 ENTRY_SET_TEXT(filter.pred_entry1,
802 FLT_IS_CONTAIN(flt->flag1)
803 ? _("contains") : _("not contain"));
804 ENTRY_SET_TEXT(filter.pred_entry2,
805 FLT_IS_CONTAIN(flt->flag2)
806 ? _("contains") : _("not contain"));
808 gtk_entry_set_text(GTK_ENTRY(filter.op_entry),
809 flt->cond == FLT_OR ? "or" : "and");
810 if (flt->action == FLT_NOTRECV)
811 gtk_toggle_button_set_active
812 (GTK_TOGGLE_BUTTON(filter.notrecv_radiobtn), TRUE);
813 else
814 gtk_toggle_button_set_active
815 (GTK_TOGGLE_BUTTON(filter.dest_radiobtn), TRUE);
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,
831 gpointer data)
833 prefs_filter_cancel();
834 return TRUE;
837 static void prefs_filter_key_pressed(GtkWidget *widget, GdkEventKey *event,
838 gpointer data)
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();