1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2014 Hiroyuki Yamamoto
4  *
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.
9  *
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.
14  *
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.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23 
24 #include "defs.h"
25 
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <gdk/gdkkeysyms.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 
35 #include "main.h"
36 #include "prefs.h"
37 #include "prefs_filter.h"
38 #include "prefs_filter_edit.h"
39 #include "prefs_common.h"
40 #include "mainwindow.h"
41 #include "foldersel.h"
42 #include "colorlabel.h"
43 #include "manage_window.h"
44 #include "procheader.h"
45 #include "menu.h"
46 #include "filter.h"
47 #include "utils.h"
48 #include "gtkutils.h"
49 #include "stock_pixmap.h"
50 #include "alertpanel.h"
51 #include "folder.h"
52 #include "plugin.h"
53 
54 static struct FilterRuleEditWindow {
55 	GtkWidget *window;
56 
57 	GtkWidget *name_entry;
58 	GtkWidget *bool_op_optmenu;
59 
60 	GtkWidget *cond_scrolled_win;
61 	FilterCondEdit cond_edit;
62 
63 	GtkWidget *action_scrolled_win;
64 	GtkWidget *action_vbox;
65 	GSList *action_hbox_list;
66 
67 	GtkWidget *ok_btn;
68 	GtkWidget *cancel_btn;
69 
70 	FilterRule *new_rule;
71 	gboolean edit_finished;
72 } rule_edit_window;
73 
74 static struct FilterEditHeaderListDialog {
75 	GtkWidget *window;
76 	GtkWidget *clist;
77 	GtkWidget *entry;
78 
79 	gboolean finished;
80 	gboolean ok;
81 } edit_header_list_dialog;
82 
83 static void prefs_filter_edit_create		(void);
84 static void prefs_filter_edit_clear		(void);
85 static void prefs_filter_edit_rule_to_dialog	(FilterRule	*rule,
86 						 const gchar	*default_name);
87 static void prefs_filter_edit_update_header_list(FilterCondEdit	*cond_list);
88 
89 static void prefs_filter_edit_set_action_hbox_menu_sensitive
90 						(ActionHBox	*hbox,
91 						 ActionMenuType	 type,
92 						 gboolean	 sensitive);
93 static void prefs_filter_edit_set_action_hbox_menus_sensitive
94 						(void);
95 
96 static void prefs_filter_edit_get_action_hbox_menus_selection
97 						(gboolean	*selection);
98 static ActionMenuType prefs_filter_edit_get_action_hbox_type
99 						(ActionHBox	*hbox);
100 
101 static void prefs_filter_edit_insert_action_hbox(ActionHBox	*hbox,
102 						 gint		 pos);
103 static void prefs_filter_edit_remove_cond_hbox	(FilterCondEdit	*cond_edit,
104 						 CondHBox	*hbox);
105 static void prefs_filter_edit_remove_action_hbox(ActionHBox	*hbox);
106 
107 static void prefs_filter_edit_add_rule_action	(FilterRule	*rule);
108 
109 static void prefs_filter_edit_set_cond_header_menu
110 						(FilterCondEdit	*cond_edit,
111 						 CondHBox	*hbox);
112 
113 static void prefs_filter_edit_activate_cond_header
114 						(FilterCondEdit	*cond_edit,
115 						 const gchar	*header);
116 
117 static void prefs_filter_edit_edit_header_list	(FilterCondEdit	*cond_edit);
118 
119 static FilterRule *prefs_filter_edit_dialog_to_rule	(void);
120 
121 /* callback functions */
122 static gint prefs_filter_edit_deleted		(GtkWidget	*widget,
123 						 GdkEventAny	*event,
124 						 gpointer	 data);
125 static gboolean prefs_filter_edit_key_pressed	(GtkWidget	*widget,
126 						 GdkEventKey	*event,
127 						 gpointer	 data);
128 static void prefs_filter_edit_ok		(void);
129 static void prefs_filter_edit_cancel		(void);
130 
131 static void prefs_filter_cond_activated_cb	(GtkWidget	*widget,
132 						 gpointer	 data);
133 static void prefs_filter_match_activated_cb	(GtkWidget	*widget,
134 						 gpointer	 data);
135 static void prefs_filter_action_activated_cb	(GtkWidget	*widget,
136 						 gpointer	 data);
137 
138 static void prefs_filter_action_select_dest_cb	(GtkWidget	*widget,
139 						 gpointer	 data);
140 
141 static void prefs_filter_cond_del_cb		(GtkWidget	*widget,
142 						 gpointer	 data);
143 static void prefs_filter_cond_add_cb		(GtkWidget	*widget,
144 						 gpointer	 data);
145 static void prefs_filter_action_del_cb		(GtkWidget	*widget,
146 						 gpointer	 data);
147 static void prefs_filter_action_add_cb		(GtkWidget	*widget,
148 						 gpointer	 data);
149 
150 
prefs_filter_edit_open(FilterRule * rule,const gchar * header,const gchar * key)151 FilterRule *prefs_filter_edit_open(FilterRule *rule, const gchar *header,
152 				   const gchar *key)
153 {
154 	static gboolean lock = FALSE;
155 	FilterRule *new_rule;
156 
157 	if (lock)
158 		return NULL;
159 
160 	lock = TRUE;
161 
162 	if (!rule_edit_window.window)
163 		prefs_filter_edit_create();
164 
165 	manage_window_set_transient(GTK_WINDOW(rule_edit_window.window));
166 
167 	prefs_filter_edit_set_header_list(&rule_edit_window.cond_edit, rule);
168 	prefs_filter_edit_rule_to_dialog(rule, key);
169 	if (header)
170 		prefs_filter_edit_activate_cond_header
171 			(&rule_edit_window.cond_edit, header);
172 	gtk_widget_show(rule_edit_window.window);
173 
174 	syl_plugin_signal_emit("prefs-filter-edit-open", rule, header, key,
175 			       rule_edit_window.window);
176 
177 	rule_edit_window.new_rule = NULL;
178 	rule_edit_window.edit_finished = FALSE;
179 	while (rule_edit_window.edit_finished == FALSE)
180 		gtk_main_iteration();
181 
182 	gtk_widget_hide(rule_edit_window.window);
183 	prefs_filter_edit_clear();
184 	prefs_filter_set_msg_header_list(NULL);
185 
186 	new_rule = rule_edit_window.new_rule;
187 	rule_edit_window.new_rule = NULL;
188 
189 	if (new_rule)
190 		debug_print("new rule created: %s\n", new_rule->name);
191 
192 	lock = FALSE;
193 
194 	return new_rule;
195 }
196 
prefs_filter_edit_create(void)197 static void prefs_filter_edit_create(void)
198 {
199 	GtkWidget *window;
200 
201 	GtkWidget *vbox;
202 
203 	GtkWidget *hbox;
204 	GtkWidget *label;
205 	GtkWidget *name_entry;
206 
207 	GtkWidget *bool_op_optmenu;
208 	GtkWidget *menu;
209 	GtkWidget *menuitem;
210 
211 	GtkWidget *cond_scrolled_win;
212 	GtkWidget *cond_vbox;
213 
214 	GtkWidget *action_scrolled_win;
215 	GtkWidget *action_vbox;
216 
217 	GtkWidget *ok_btn;
218 	GtkWidget *cancel_btn;
219 	GtkWidget *confirm_area;
220 
221 	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
222 	gtk_container_set_border_width(GTK_CONTAINER(window), 8);
223 	gtk_widget_set_size_request(window, 632 * gtkut_get_dpi_multiplier(), 405 * gtkut_get_dpi_multiplier());
224 	gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
225 	gtk_window_set_modal(GTK_WINDOW(window), TRUE);
226 	gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
227 	gtk_widget_realize(window);
228 
229 	vbox = gtk_vbox_new(FALSE, 6);
230 	gtk_widget_show(vbox);
231 	gtk_container_add(GTK_CONTAINER(window), vbox);
232 
233 	gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
234 				      &cancel_btn, GTK_STOCK_CANCEL,
235 				      NULL, NULL);
236 	gtk_widget_show(confirm_area);
237 	gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
238 	gtk_widget_grab_default(ok_btn);
239 
240 	gtk_window_set_title(GTK_WINDOW(window),
241 			     _("Filter rule"));
242 	g_signal_connect(G_OBJECT(window), "delete_event",
243 			 G_CALLBACK(prefs_filter_edit_deleted), NULL);
244 	g_signal_connect(G_OBJECT(window), "key_press_event",
245 			 G_CALLBACK(prefs_filter_edit_key_pressed), NULL);
246 	MANAGE_WINDOW_SIGNALS_CONNECT (window);
247 	g_signal_connect(G_OBJECT(ok_btn), "clicked",
248 			 G_CALLBACK(prefs_filter_edit_ok), NULL);
249 	g_signal_connect(G_OBJECT(cancel_btn), "clicked",
250 			 G_CALLBACK(prefs_filter_edit_cancel), NULL);
251 
252 	hbox = gtk_hbox_new(FALSE, 4);
253 	gtk_widget_show(hbox);
254 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
255 
256 	label = gtk_label_new(_("Name:"));
257 	gtk_widget_show(label);
258 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
259 
260 	name_entry = gtk_entry_new();
261 	gtk_widget_show(name_entry);
262 	gtk_box_pack_start(GTK_BOX(hbox), name_entry, TRUE, TRUE, 0);
263 
264 	hbox = gtk_hbox_new(FALSE, 4);
265 	gtk_widget_show(hbox);
266 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
267 
268 	bool_op_optmenu = gtk_option_menu_new();
269 	gtk_widget_show(bool_op_optmenu);
270 	gtk_box_pack_start(GTK_BOX(hbox), bool_op_optmenu, FALSE, FALSE, 0);
271 
272 	menu = gtk_menu_new();
273 	gtk_widget_show(menu);
274 	MENUITEM_ADD(menu, menuitem,
275 		     _("If any of the following condition matches"), FLT_OR);
276 	MENUITEM_ADD(menu, menuitem,
277 		     _("If all of the following conditions match"), FLT_AND);
278 	gtk_option_menu_set_menu(GTK_OPTION_MENU(bool_op_optmenu), menu);
279 	gtk_option_menu_set_history(GTK_OPTION_MENU(bool_op_optmenu), FLT_AND);
280 
281 	cond_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
282 	gtk_widget_show(cond_scrolled_win);
283 	gtk_widget_set_size_request(cond_scrolled_win, -1, 125 * gtkut_get_dpi_multiplier());
284 	gtk_box_pack_start(GTK_BOX(vbox), cond_scrolled_win, TRUE, TRUE, 0);
285 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolled_win),
286 				       GTK_POLICY_AUTOMATIC,
287 				       GTK_POLICY_AUTOMATIC);
288 
289 	cond_vbox = gtk_vbox_new(FALSE, 2);
290 	gtk_widget_show(cond_vbox);
291 	gtk_container_set_border_width(GTK_CONTAINER(cond_vbox), 2);
292 	gtk_scrolled_window_add_with_viewport
293 		(GTK_SCROLLED_WINDOW(cond_scrolled_win), cond_vbox);
294 
295 	hbox = gtk_hbox_new(FALSE, 4);
296 	gtk_widget_show(hbox);
297 	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
298 
299 	label = gtk_label_new(_("Perform the following actions:"));
300 	gtk_widget_show(label);
301 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
302 
303 	action_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
304 	gtk_widget_show(action_scrolled_win);
305 	gtk_box_pack_start(GTK_BOX(vbox), action_scrolled_win, TRUE, TRUE, 0);
306 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(action_scrolled_win),
307 				       GTK_POLICY_AUTOMATIC,
308 				       GTK_POLICY_AUTOMATIC);
309 
310 	action_vbox = gtk_vbox_new(FALSE, 2);
311 	gtk_widget_show(action_vbox);
312 	gtk_container_set_border_width(GTK_CONTAINER(action_vbox), 2);
313 	gtk_scrolled_window_add_with_viewport
314 		(GTK_SCROLLED_WINDOW(action_scrolled_win), action_vbox);
315 
316 	rule_edit_window.window = window;
317 	rule_edit_window.name_entry = name_entry;
318 
319 	rule_edit_window.bool_op_optmenu = bool_op_optmenu;
320 	rule_edit_window.cond_scrolled_win = cond_scrolled_win;
321 	rule_edit_window.cond_edit.cond_vbox = cond_vbox;
322 	rule_edit_window.action_scrolled_win = action_scrolled_win;
323 	rule_edit_window.action_vbox = action_vbox;
324 
325 	rule_edit_window.ok_btn = ok_btn;
326 	rule_edit_window.cancel_btn = cancel_btn;
327 }
328 
prefs_filter_edit_cond_edit_create(void)329 FilterCondEdit *prefs_filter_edit_cond_edit_create(void)
330 {
331 	FilterCondEdit *cond_edit;
332 	GtkWidget *cond_vbox;
333 
334 	cond_edit = g_new(FilterCondEdit, 1);
335 
336 	cond_vbox = gtk_vbox_new(FALSE, 2);
337 	gtk_widget_show(cond_vbox);
338 	gtk_container_set_border_width(GTK_CONTAINER(cond_vbox), 2);
339 
340 	cond_edit->cond_vbox = cond_vbox;
341 	cond_edit->cond_hbox_list = NULL;
342 	cond_edit->hdr_list = NULL;
343 	cond_edit->rule_hdr_list = NULL;
344 	cond_edit->add_hbox = NULL;
345 
346 	return cond_edit;
347 }
348 
prefs_filter_edit_clear_cond_edit(FilterCondEdit * cond_edit)349 void prefs_filter_edit_clear_cond_edit(FilterCondEdit *cond_edit)
350 {
351 	while (cond_edit->cond_hbox_list) {
352 		CondHBox *hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
353 		prefs_filter_edit_remove_cond_hbox(cond_edit, hbox);
354 	}
355 
356 	procheader_header_list_destroy(cond_edit->hdr_list);
357 	cond_edit->hdr_list = NULL;
358 	procheader_header_list_destroy(cond_edit->rule_hdr_list);
359 	cond_edit->rule_hdr_list = NULL;
360 }
361 
prefs_filter_edit_clear(void)362 static void prefs_filter_edit_clear(void)
363 {
364 	prefs_filter_edit_clear_cond_edit(&rule_edit_window.cond_edit);
365 
366 	while (rule_edit_window.action_hbox_list) {
367 		ActionHBox *hbox =
368 			(ActionHBox *)rule_edit_window.action_hbox_list->data;
369 		prefs_filter_edit_remove_action_hbox(hbox);
370 	}
371 }
372 
prefs_filter_edit_rule_to_dialog(FilterRule * rule,const gchar * default_name)373 static void prefs_filter_edit_rule_to_dialog(FilterRule *rule,
374 					     const gchar *default_name)
375 {
376 	gint index = 1;
377 	static gint count = 1;
378 
379 	if (rule && rule->name)
380 		gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
381 				   rule->name);
382 	else if (default_name)
383 		gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
384 				   default_name);
385 	else {
386 		gchar rule_name[32];
387 		g_snprintf(rule_name, sizeof(rule_name), "Rule %d", count++);
388 		gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
389 				   rule_name);
390 	}
391 
392 	if (rule) {
393 		index = menu_find_option_menu_index
394 			(GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu),
395 			 GINT_TO_POINTER(rule->bool_op), NULL);
396 		if (index < 0)
397 			index = 1;
398 	}
399 	if (index >= 0) {
400 		gtk_option_menu_set_history
401 			(GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu),
402 			 index);
403 	}
404 
405 	gtkut_scrolled_window_reset_position
406 		(GTK_SCROLLED_WINDOW(rule_edit_window.cond_scrolled_win));
407 	gtkut_scrolled_window_reset_position
408 		(GTK_SCROLLED_WINDOW(rule_edit_window.action_scrolled_win));
409 
410 	prefs_filter_edit_add_rule_cond(&rule_edit_window.cond_edit, rule);
411 	prefs_filter_edit_add_rule_action(rule);
412 }
413 
prefs_filter_edit_set_header_list(FilterCondEdit * cond_edit,FilterRule * rule)414 void prefs_filter_edit_set_header_list(FilterCondEdit *cond_edit,
415 				       FilterRule *rule)
416 {
417 	GSList *list;
418 	GSList *rule_hdr_list = NULL;
419 	GSList *cur;
420 	FilterCond *cond;
421 
422 	procheader_header_list_destroy(cond_edit->hdr_list);
423 	cond_edit->hdr_list = NULL;
424 	procheader_header_list_destroy(cond_edit->rule_hdr_list);
425 	cond_edit->rule_hdr_list = NULL;
426 
427 	list = prefs_filter_get_header_list();
428 	cond_edit->hdr_list = list;
429 
430 	if (!rule)
431 		return;
432 
433 	for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
434 		cond = (FilterCond *)cur->data;
435 
436 		if (cond->type == FLT_COND_HEADER &&
437 		    procheader_find_header_list
438 			(rule_hdr_list, cond->header_name) < 0)
439 			rule_hdr_list = procheader_add_header_list
440 				(rule_hdr_list, cond->header_name, NULL);
441 	}
442 
443 	cond_edit->rule_hdr_list = rule_hdr_list;
444 	cond_edit->hdr_list = procheader_merge_header_list_dup(list,
445 							       rule_hdr_list);
446 	procheader_header_list_destroy(list);
447 }
448 
prefs_filter_edit_update_header_list(FilterCondEdit * cond_edit)449 static void prefs_filter_edit_update_header_list(FilterCondEdit *cond_edit)
450 {
451 	GSList *list;
452 
453 	procheader_header_list_destroy(cond_edit->hdr_list);
454 	cond_edit->hdr_list = NULL;
455 
456 	list = prefs_filter_get_header_list();
457 	cond_edit->hdr_list = procheader_merge_header_list_dup
458 		(list, cond_edit->rule_hdr_list);
459 	procheader_header_list_destroy(list);
460 }
461 
prefs_filter_edit_cond_hbox_create(FilterCondEdit * cond_edit)462 CondHBox *prefs_filter_edit_cond_hbox_create(FilterCondEdit *cond_edit)
463 {
464 	CondHBox *cond_hbox;
465 	GtkWidget *hbox;
466 	GtkWidget *cond_type_optmenu;
467 	GtkWidget *match_type_optmenu;
468 	GtkWidget *size_match_optmenu;
469 	GtkWidget *age_match_optmenu;
470 	GtkWidget *status_match_optmenu;
471 	GtkWidget *menu;
472 	GtkWidget *menuitem;
473 	GtkWidget *key_entry;
474 	GtkObject *spin_btn_adj;
475 	GtkWidget *spin_btn;
476 	GtkWidget *label;
477 	GtkWidget *del_btn;
478 	GtkWidget *add_btn;
479 	GtkWidget *del_img;
480 	GtkWidget *add_img;
481 	GtkWidget *match_menu_in_addr;
482 	GtkWidget *match_menu_not_in_addr;
483 
484 	cond_hbox = g_new0(CondHBox, 1);
485 
486 	hbox = gtk_hbox_new(FALSE, 4);
487 	gtk_widget_show(hbox);
488 
489 	cond_type_optmenu = gtk_option_menu_new();
490 	gtk_widget_show(cond_type_optmenu);
491 	gtk_box_pack_start(GTK_BOX(hbox), cond_type_optmenu, FALSE, FALSE, 0);
492 
493 #define COND_MENUITEM_ADD(str, action)					    \
494 {									    \
495 	MENUITEM_ADD(menu, menuitem, str, action);			    \
496 	g_signal_connect(G_OBJECT(menuitem), "activate",		    \
497 			 G_CALLBACK(prefs_filter_cond_activated_cb),	    \
498 			 cond_hbox);					    \
499 }
500 
501 	menu = gtk_menu_new();
502 	gtk_widget_show(menu);
503 	MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
504 	COND_MENUITEM_ADD(_("To or Cc"),          PF_COND_TO_OR_CC);
505 	COND_MENUITEM_ADD(_("Any header"),        PF_COND_ANY_HEADER);
506 	COND_MENUITEM_ADD(_("Edit header..."),    PF_COND_EDIT_HEADER);
507 
508 	MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
509 	COND_MENUITEM_ADD(_("Message body"),      PF_COND_BODY);
510 	COND_MENUITEM_ADD(_("Result of command"), PF_COND_CMD_TEST);
511 	COND_MENUITEM_ADD(_("Size"),              PF_COND_SIZE);
512 	COND_MENUITEM_ADD(_("Age"),               PF_COND_AGE);
513 
514 	MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
515 	COND_MENUITEM_ADD(_("Unread"),            PF_COND_UNREAD);
516 	COND_MENUITEM_ADD(_("Marked"),            PF_COND_MARK);
517 	COND_MENUITEM_ADD(_("Has color label"),   PF_COND_COLOR_LABEL);
518 	COND_MENUITEM_ADD(_("Has attachment"),    PF_COND_MIME);
519 	/* COND_MENUITEM_ADD(_("Account"),           PF_COND_ACCOUNT); */
520 
521 	gtk_option_menu_set_menu(GTK_OPTION_MENU(cond_type_optmenu), menu);
522 
523 #undef COND_MENUITEM_ADD
524 
525 	match_type_optmenu = gtk_option_menu_new();
526 	gtk_widget_show(match_type_optmenu);
527 	gtk_box_pack_start(GTK_BOX(hbox), match_type_optmenu, FALSE, FALSE, 0);
528 
529 #define MATCH_MENUITEM_ADD(str, action)					    \
530 {									    \
531 	MENUITEM_ADD(menu, menuitem, str, action);			    \
532 	g_signal_connect(G_OBJECT(menuitem), "activate",		    \
533 			 G_CALLBACK(prefs_filter_match_activated_cb),	    \
534 			 cond_hbox);					    \
535 }
536 	menu = gtk_menu_new();
537 	gtk_widget_show(menu);
538 	MATCH_MENUITEM_ADD(_("contains"),               PF_MATCH_CONTAIN);
539 	MATCH_MENUITEM_ADD(_("doesn't contain"),        PF_MATCH_NOT_CONTAIN);
540 	MATCH_MENUITEM_ADD(_("is"),                     PF_MATCH_EQUAL);
541 	MATCH_MENUITEM_ADD(_("is not"),                 PF_MATCH_NOT_EQUAL);
542 #if defined(USE_ONIGURUMA) || defined(HAVE_REGCOMP)
543 	MATCH_MENUITEM_ADD(_("match to regex"),         PF_MATCH_REGEX);
544 	MATCH_MENUITEM_ADD(_("doesn't match to regex"), PF_MATCH_NOT_REGEX);
545 #endif
546 	MATCH_MENUITEM_ADD(_("is in addressbook"),      PF_MATCH_IN_ADDRESSBOOK);
547 	match_menu_in_addr = menuitem;
548 	MATCH_MENUITEM_ADD(_("is not in addressbook"),  PF_MATCH_NOT_IN_ADDRESSBOOK);
549 	match_menu_not_in_addr = menuitem;
550 	gtk_option_menu_set_menu(GTK_OPTION_MENU(match_type_optmenu), menu);
551 
552 #undef MATCH_MENUITEM_ADD
553 
554 	size_match_optmenu = gtk_option_menu_new();
555 	gtk_widget_show(size_match_optmenu);
556 	gtk_box_pack_start(GTK_BOX(hbox), size_match_optmenu, FALSE, FALSE, 0);
557 
558 	menu = gtk_menu_new();
559 	gtk_widget_show(menu);
560 	MENUITEM_ADD(menu, menuitem, _("is larger than"), PF_SIZE_LARGER);
561 	MENUITEM_ADD(menu, menuitem, _("is smaller than"), PF_SIZE_SMALLER);
562 	gtk_option_menu_set_menu(GTK_OPTION_MENU(size_match_optmenu), menu);
563 
564 	age_match_optmenu = gtk_option_menu_new();
565 	gtk_widget_show(age_match_optmenu);
566 	gtk_box_pack_start(GTK_BOX(hbox), age_match_optmenu, FALSE, FALSE, 0);
567 
568 	menu = gtk_menu_new();
569 	gtk_widget_show(menu);
570 	MENUITEM_ADD(menu, menuitem, _("is shorter than"), PF_AGE_SHORTER);
571 	MENUITEM_ADD(menu, menuitem, _("is longer than"), PF_AGE_LONGER);
572 	gtk_option_menu_set_menu(GTK_OPTION_MENU(age_match_optmenu), menu);
573 
574 	status_match_optmenu = gtk_option_menu_new();
575 	gtk_widget_show(status_match_optmenu);
576 	gtk_box_pack_start(GTK_BOX(hbox), status_match_optmenu,
577 			   FALSE, FALSE, 0);
578 
579 	menu = gtk_menu_new();
580 	gtk_widget_show(menu);
581 	MENUITEM_ADD(menu, menuitem, _("matches to status"), PF_STATUS_MATCH);
582 	MENUITEM_ADD(menu, menuitem, _("doesn't match to status"),
583 		     PF_STATUS_NOT_MATCH);
584 	gtk_option_menu_set_menu(GTK_OPTION_MENU(status_match_optmenu), menu);
585 
586 	key_entry = gtk_entry_new();
587 	gtk_widget_show(key_entry);
588 	gtk_box_pack_start(GTK_BOX(hbox), key_entry, TRUE, TRUE, 0);
589 
590 	spin_btn_adj = gtk_adjustment_new(0, 0, 99999, 1, 10, 0);
591 	spin_btn = gtk_spin_button_new(GTK_ADJUSTMENT(spin_btn_adj), 1, 0);
592 	gtk_box_pack_start(GTK_BOX(hbox), spin_btn, FALSE, FALSE, 0);
593 	gtk_widget_set_size_request(spin_btn, 64, -1);
594 	gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_btn), TRUE);
595 
596 	label = gtk_label_new(_("KB"));
597 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
598 
599 	del_img = gtk_image_new_from_stock
600 		(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
601 	gtk_widget_show(del_img);
602 
603 	del_btn = gtk_button_new();
604 	gtk_container_add(GTK_CONTAINER(del_btn), del_img);
605 	gtk_widget_show(del_btn);
606 	gtk_box_pack_end(GTK_BOX(hbox), del_btn, FALSE, FALSE, 0);
607 
608 	add_img = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
609 	gtk_widget_show(add_img);
610 
611 	add_btn = gtk_button_new();
612 	gtk_container_add(GTK_CONTAINER(add_btn), add_img);
613 	gtk_widget_show(add_btn);
614 	gtk_box_pack_end(GTK_BOX(hbox), add_btn, FALSE, FALSE, 0);
615 
616 	g_signal_connect(G_OBJECT(del_btn), "clicked",
617 			 G_CALLBACK(prefs_filter_cond_del_cb), cond_hbox);
618 	g_signal_connect(G_OBJECT(add_btn), "clicked",
619 			 G_CALLBACK(prefs_filter_cond_add_cb), cond_hbox);
620 
621 	cond_hbox->hbox = hbox;
622 	cond_hbox->cond_type_optmenu = cond_type_optmenu;
623 	cond_hbox->match_type_optmenu = match_type_optmenu;
624 	cond_hbox->size_match_optmenu = size_match_optmenu;
625 	cond_hbox->age_match_optmenu = age_match_optmenu;
626 	cond_hbox->status_match_optmenu = status_match_optmenu;
627 	cond_hbox->key_entry = key_entry;
628 	cond_hbox->spin_btn = spin_btn;
629 	cond_hbox->label = label;
630 	cond_hbox->match_menu_in_addr = match_menu_in_addr;
631 	cond_hbox->match_menu_not_in_addr = match_menu_not_in_addr;
632 	cond_hbox->del_btn = del_btn;
633 	cond_hbox->add_btn = add_btn;
634 	cond_hbox->cur_type = PF_COND_HEADER;
635 	cond_hbox->cur_header_name = NULL;
636 	cond_hbox->cond_edit = cond_edit;
637 
638 	prefs_filter_edit_set_cond_header_menu(cond_edit, cond_hbox);
639 	gtk_option_menu_set_history(GTK_OPTION_MENU(cond_type_optmenu), 0);
640 
641 	return cond_hbox;
642 }
643 
prefs_filter_edit_action_hbox_create(void)644 ActionHBox *prefs_filter_edit_action_hbox_create(void)
645 {
646 	ActionHBox *action_hbox;
647 	GtkWidget *hbox;
648 	GtkWidget *action_type_optmenu;
649 	GtkWidget *menu;
650 	GtkWidget *menuitem;
651 	GtkWidget *label;
652 	GtkWidget *folder_entry;
653 	GtkWidget *cmd_entry;
654 	GtkWidget *address_entry;
655 	GtkWidget *folder_img;
656 	GtkWidget *folder_sel_btn;
657 	GtkWidget *clabel_optmenu;
658 	GtkWidget *del_btn;
659 	GtkWidget *add_btn;
660 	GtkWidget *del_img;
661 	GtkWidget *add_img;
662 
663 	action_hbox = g_new0(ActionHBox, 1);
664 
665 	hbox = gtk_hbox_new(FALSE, 4);
666 	gtk_widget_show(hbox);
667 
668 	action_type_optmenu = gtk_option_menu_new();
669 	gtk_widget_show(action_type_optmenu);
670 	gtk_box_pack_start(GTK_BOX(hbox), action_type_optmenu, FALSE, FALSE, 0);
671 
672 	memset(action_hbox->action_type_menu_items, 0,
673 	       sizeof(action_hbox->action_type_menu_items));
674 
675 #define ACTION_MENUITEM_ADD(str, action)				      \
676 {									      \
677 	MENUITEM_ADD(menu, menuitem, str, action);			      \
678 	action_hbox->action_type_menu_items[action] = menuitem;		      \
679 	g_signal_connect(G_OBJECT(menuitem), "activate",		      \
680 			 G_CALLBACK(prefs_filter_action_activated_cb),	      \
681 			 action_hbox);					      \
682 }
683 
684 	menu = gtk_menu_new();
685 	gtk_widget_show(menu);
686 	ACTION_MENUITEM_ADD(_("Move to"),               PF_ACTION_MOVE);
687 	ACTION_MENUITEM_ADD(_("Copy to"),               PF_ACTION_COPY);
688 	ACTION_MENUITEM_ADD(_("Don't receive"),         PF_ACTION_NOT_RECEIVE);
689 	ACTION_MENUITEM_ADD(_("Delete from server"),    PF_ACTION_DELETE);
690 
691 	MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
692 	ACTION_MENUITEM_ADD(_("Set mark"),              PF_ACTION_MARK);
693 	ACTION_MENUITEM_ADD(_("Set color"),             PF_ACTION_COLOR_LABEL);
694 	ACTION_MENUITEM_ADD(_("Mark as read"),          PF_ACTION_MARK_READ);
695 
696 #if 0
697 	MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
698 	ACTION_MENUITEM_ADD(_("Forward"),               PF_ACTION_FORWARD);
699 	ACTION_MENUITEM_ADD(_("Forward as attachment"), PF_ACTION_FORWARD_AS_ATTACHMENT);
700 	ACTION_MENUITEM_ADD(_("Redirect"),              PF_ACTION_REDIRECT);
701 #endif
702 
703 	MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
704 	ACTION_MENUITEM_ADD(_("Execute command"),       PF_ACTION_EXEC);
705 
706 	MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
707 	ACTION_MENUITEM_ADD(_("Stop rule evaluation"),  PF_ACTION_STOP_EVAL);
708 
709 	gtk_option_menu_set_menu(GTK_OPTION_MENU(action_type_optmenu), menu);
710 
711 #undef ACTION_MENUITEM_ADD
712 
713 	label = gtk_label_new(_("folder:"));
714 	gtk_widget_show(label);
715 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
716 
717 	folder_entry = gtk_entry_new();
718 	gtk_widget_show(folder_entry);
719 	gtk_box_pack_start(GTK_BOX(hbox), folder_entry, TRUE, TRUE, 0);
720 
721 	folder_img = stock_pixbuf_widget(rule_edit_window.window,
722 					 STOCK_PIXMAP_FOLDER_OPEN);
723 	gtk_widget_show(folder_img);
724 
725 	folder_sel_btn = gtk_button_new();
726 	gtk_container_add(GTK_CONTAINER(folder_sel_btn), folder_img);
727 	gtk_widget_show(folder_sel_btn);
728 	gtk_box_pack_start(GTK_BOX(hbox), folder_sel_btn, FALSE, FALSE, 0);
729 
730 	cmd_entry = gtk_entry_new();
731 	gtk_widget_show(cmd_entry);
732 	gtk_box_pack_start(GTK_BOX(hbox), cmd_entry, TRUE, TRUE, 0);
733 
734 	address_entry = gtk_entry_new();
735 	gtk_widget_show(address_entry);
736 	gtk_box_pack_start(GTK_BOX(hbox), address_entry, TRUE, TRUE, 0);
737 
738 	clabel_optmenu = gtk_option_menu_new();
739 	gtk_widget_show(clabel_optmenu);
740 	gtk_box_pack_start(GTK_BOX(hbox), clabel_optmenu, FALSE, FALSE, 0);
741 
742 	menu = colorlabel_create_color_menu();
743 	gtk_option_menu_set_menu(GTK_OPTION_MENU(clabel_optmenu), menu);
744 
745 	del_img = gtk_image_new_from_stock
746 		(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
747 	gtk_widget_show(del_img);
748 
749 	del_btn = gtk_button_new();
750 	gtk_container_add(GTK_CONTAINER(del_btn), del_img);
751 	gtk_widget_show(del_btn);
752 	gtk_box_pack_end(GTK_BOX(hbox), del_btn, FALSE, FALSE, 0);
753 
754 	add_img = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
755 	gtk_widget_show(add_img);
756 
757 	add_btn = gtk_button_new();
758 	gtk_container_add(GTK_CONTAINER(add_btn), add_img);
759 	gtk_widget_show(add_btn);
760 	gtk_box_pack_end(GTK_BOX(hbox), add_btn, FALSE, FALSE, 0);
761 
762 	g_signal_connect(G_OBJECT(folder_sel_btn), "clicked",
763 			 G_CALLBACK(prefs_filter_action_select_dest_cb),
764 			 action_hbox);
765 	g_signal_connect(G_OBJECT(del_btn), "clicked",
766 			 G_CALLBACK(prefs_filter_action_del_cb), action_hbox);
767 	g_signal_connect(G_OBJECT(add_btn), "clicked",
768 			 G_CALLBACK(prefs_filter_action_add_cb), action_hbox);
769 
770 	action_hbox->hbox = hbox;
771 	action_hbox->action_type_optmenu = action_type_optmenu;
772 	action_hbox->label = label;
773 	action_hbox->folder_entry = folder_entry;
774 	action_hbox->cmd_entry = cmd_entry;
775 	action_hbox->address_entry = address_entry;
776 	action_hbox->folder_sel_btn = folder_sel_btn;
777 	action_hbox->clabel_optmenu = clabel_optmenu;
778 	action_hbox->del_btn = del_btn;
779 	action_hbox->add_btn = add_btn;
780 
781 	return action_hbox;
782 }
783 
prefs_filter_edit_cond_hbox_set(CondHBox * hbox,FilterCond * cond)784 void prefs_filter_edit_cond_hbox_set(CondHBox *hbox, FilterCond *cond)
785 {
786 	GtkOptionMenu *cond_type_optmenu =
787 		GTK_OPTION_MENU(hbox->cond_type_optmenu);
788 	GtkOptionMenu *match_type_optmenu =
789 		GTK_OPTION_MENU(hbox->match_type_optmenu);
790 	gint cond_index = -1;
791 	gint match_index = -1;
792 	CondMenuType cond_type = PF_COND_NONE;
793 	MatchMenuType match_type = PF_MATCH_NONE;
794 	SizeMatchType size_type = PF_SIZE_LARGER;
795 	AgeMatchType age_type = PF_AGE_SHORTER;
796 	StatusMatchType status_type = PF_STATUS_MATCH;
797 
798 	switch (cond->type) {
799 	case FLT_COND_HEADER:
800 		cond_type = PF_COND_HEADER; break;
801 	case FLT_COND_TO_OR_CC:
802 		cond_type = PF_COND_TO_OR_CC; break;
803 	case FLT_COND_ANY_HEADER:
804 		cond_type = PF_COND_ANY_HEADER; break;
805 	case FLT_COND_BODY:
806 		cond_type = PF_COND_BODY; break;
807 	case FLT_COND_CMD_TEST:
808 		cond_type = PF_COND_CMD_TEST; break;
809 	case FLT_COND_SIZE_GREATER:
810 		cond_type = PF_COND_SIZE;
811 		if (FLT_IS_NOT_MATCH(cond->match_flag))
812 			size_type = PF_SIZE_SMALLER;
813 		else
814 			size_type = PF_SIZE_LARGER;
815 		break;
816 	case FLT_COND_AGE_GREATER:
817 		cond_type = PF_COND_AGE;
818 		if (FLT_IS_NOT_MATCH(cond->match_flag))
819 			age_type = PF_AGE_SHORTER;
820 		else
821 			age_type = PF_AGE_LONGER;
822 		break;
823 	case FLT_COND_UNREAD:
824 		cond_type = PF_COND_UNREAD; break;
825 	case FLT_COND_MARK:
826 		cond_type = PF_COND_MARK; break;
827 	case FLT_COND_COLOR_LABEL:
828 		cond_type = PF_COND_COLOR_LABEL; break;
829 	case FLT_COND_MIME:
830 		cond_type = PF_COND_MIME; break;
831 	case FLT_COND_ACCOUNT:
832 		cond_type = PF_COND_ACCOUNT; break;
833 	default:
834 		break;
835 	}
836 
837 	switch (cond->type) {
838 	case FLT_COND_HEADER:
839 	case FLT_COND_TO_OR_CC:
840 	case FLT_COND_ANY_HEADER:
841 	case FLT_COND_BODY:
842 		switch (cond->match_type) {
843 		case FLT_CONTAIN:
844 			if (FLT_IS_NOT_MATCH(cond->match_flag))
845 				match_type = PF_MATCH_NOT_CONTAIN;
846 			else
847 				match_type = PF_MATCH_CONTAIN;
848 			break;
849 		case FLT_EQUAL:
850 			if (FLT_IS_NOT_MATCH(cond->match_flag))
851 				match_type = PF_MATCH_NOT_EQUAL;
852 			else
853 				match_type = PF_MATCH_EQUAL;
854 			break;
855 		case FLT_REGEX:
856 			if (FLT_IS_NOT_MATCH(cond->match_flag))
857 				match_type = PF_MATCH_NOT_REGEX;
858 			else
859 				match_type = PF_MATCH_REGEX;
860 			break;
861 		case FLT_IN_ADDRESSBOOK:
862 			if (FLT_IS_NOT_MATCH(cond->match_flag))
863 				match_type = PF_MATCH_NOT_IN_ADDRESSBOOK;
864 			else
865 				match_type = PF_MATCH_IN_ADDRESSBOOK;
866 			break;
867 		}
868 		break;
869 	case FLT_COND_UNREAD:
870 	case FLT_COND_MARK:
871 	case FLT_COND_COLOR_LABEL:
872 	case FLT_COND_MIME:
873 		if (FLT_IS_NOT_MATCH(cond->match_flag))
874 			status_type = PF_STATUS_NOT_MATCH;
875 		else
876 			status_type = PF_STATUS_MATCH;
877 		break;
878 	default:
879 		break;
880 	}
881 
882 	if (cond_type == PF_COND_HEADER)
883 		cond_index = procheader_find_header_list
884 			(hbox->cond_edit->hdr_list, cond->header_name);
885 	else
886 		cond_index = menu_find_option_menu_index
887 			(cond_type_optmenu, GINT_TO_POINTER(cond_type), NULL);
888 	if (cond_index >= 0) {
889 		GtkWidget *menuitem;
890 
891 		if (cond_type == PF_COND_SIZE || cond_type == PF_COND_AGE) {
892 			gtk_spin_button_set_value
893 				(GTK_SPIN_BUTTON(hbox->spin_btn),
894 				 (gfloat)cond->int_value);
895 		} else {
896 			gtk_entry_set_text(GTK_ENTRY(hbox->key_entry),
897 					   cond->str_value ?
898 					   cond->str_value : "");
899 		}
900 		gtk_option_menu_set_history(cond_type_optmenu, cond_index);
901 		menuitem = gtk_menu_get_active
902 			(GTK_MENU(gtk_option_menu_get_menu(cond_type_optmenu)));
903 		gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
904 	}
905 
906 	match_index = menu_find_option_menu_index
907 		(match_type_optmenu, GINT_TO_POINTER(match_type), NULL);
908 	if (match_index >= 0)
909 		gtk_option_menu_set_history(match_type_optmenu, match_index);
910 	if (cond_type == PF_COND_SIZE)
911 		gtk_option_menu_set_history
912 			(GTK_OPTION_MENU(hbox->size_match_optmenu), size_type);
913 	else if (cond_type == PF_COND_AGE)
914 		gtk_option_menu_set_history
915 			(GTK_OPTION_MENU(hbox->age_match_optmenu), age_type);
916 	else if (cond_type == PF_COND_UNREAD || cond_type == PF_COND_MARK ||
917 		 cond_type == PF_COND_COLOR_LABEL || cond_type == PF_COND_MIME)
918 		gtk_option_menu_set_history
919 			(GTK_OPTION_MENU(hbox->status_match_optmenu),
920 			 status_type);
921 
922 	if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
923 	    match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
924 		gtk_widget_hide(hbox->key_entry);
925 }
926 
prefs_filter_edit_action_hbox_set(ActionHBox * hbox,FilterAction * action)927 void prefs_filter_edit_action_hbox_set(ActionHBox *hbox, FilterAction *action)
928 {
929 	GtkOptionMenu *type_optmenu = GTK_OPTION_MENU(hbox->action_type_optmenu);
930 	GtkWidget *menu;
931 	ActionMenuType type = PF_ACTION_NONE;
932 
933 	menu = gtk_option_menu_get_menu(type_optmenu);
934 
935 	switch (action->type) {
936 	case FLT_ACTION_MOVE:
937 		type = PF_ACTION_MOVE; break;
938 	case FLT_ACTION_COPY:
939 		type = PF_ACTION_COPY; break;
940 	case FLT_ACTION_NOT_RECEIVE:
941 		type = PF_ACTION_NOT_RECEIVE; break;
942 	case FLT_ACTION_DELETE:
943 		type = PF_ACTION_DELETE; break;
944 	case FLT_ACTION_EXEC:
945 		type = PF_ACTION_EXEC; break;
946 	case FLT_ACTION_MARK:
947 		type = PF_ACTION_MARK; break;
948 	case FLT_ACTION_COLOR_LABEL:
949 		type = PF_ACTION_COLOR_LABEL; break;
950 	case FLT_ACTION_MARK_READ:
951 		type = PF_ACTION_MARK_READ; break;
952 	case FLT_ACTION_STOP_EVAL:
953 		type = PF_ACTION_STOP_EVAL; break;
954 	default:
955 		break;
956 	}
957 
958 	switch (type) {
959 	case PF_ACTION_MOVE:
960 	case PF_ACTION_COPY:
961 		gtk_entry_set_text(GTK_ENTRY(hbox->folder_entry),
962 				   action->str_value ? action->str_value : "");
963 		break;
964 	case PF_ACTION_EXEC:
965 		gtk_entry_set_text(GTK_ENTRY(hbox->cmd_entry),
966 				   action->str_value ? action->str_value : "");
967 		break;
968 	case PF_ACTION_COLOR_LABEL:
969 		gtk_option_menu_set_history
970 			(GTK_OPTION_MENU(hbox->clabel_optmenu),
971 			 action->int_value - 1);
972 		break;
973 	default:
974 		break;
975 	}
976 
977 	prefs_filter_edit_set_action_hbox_widgets(hbox, type);
978 }
979 
prefs_filter_edit_cond_hbox_select(CondHBox * hbox,CondMenuType type,const gchar * header_name)980 void prefs_filter_edit_cond_hbox_select(CondHBox *hbox, CondMenuType type,
981 					const gchar *header_name)
982 {
983 	gint index;
984 	GtkOptionMenu *cond_type_optmenu =
985 		GTK_OPTION_MENU(hbox->cond_type_optmenu);
986 	GtkWidget *menu;
987 
988 	if (type == PF_COND_HEADER) {
989 		if (header_name)
990 			index = procheader_find_header_list
991 				(hbox->cond_edit->hdr_list, header_name);
992 		else
993 			index = 0;
994 	} else
995 		index = menu_find_option_menu_index
996 			(cond_type_optmenu, GINT_TO_POINTER(type), NULL);
997 
998 	if (index < 0)
999 		index = 0;
1000 
1001 	menu = gtk_option_menu_get_menu(cond_type_optmenu);
1002 	gtk_option_menu_set_history(cond_type_optmenu, index);
1003 }
1004 
prefs_filter_edit_set_cond_hbox_widgets(CondHBox * hbox,CondMenuType type)1005 void prefs_filter_edit_set_cond_hbox_widgets(CondHBox *hbox, CondMenuType type)
1006 {
1007 	MatchMenuType match_type;
1008 
1009 	switch (type) {
1010 	case PF_COND_HEADER:
1011 	case PF_COND_TO_OR_CC:
1012 	case PF_COND_ANY_HEADER:
1013 	case PF_COND_BODY:
1014 		gtk_widget_show(hbox->match_type_optmenu);
1015 		gtk_widget_hide(hbox->size_match_optmenu);
1016 		gtk_widget_hide(hbox->age_match_optmenu);
1017 		gtk_widget_hide(hbox->status_match_optmenu);
1018 		match_type = menu_get_option_menu_active_index
1019 			(GTK_OPTION_MENU(hbox->match_type_optmenu));
1020 		if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
1021 		    match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
1022 			gtk_widget_hide(hbox->key_entry);
1023 		else
1024 			gtk_widget_show(hbox->key_entry);
1025 		gtk_widget_hide(hbox->spin_btn);
1026 		gtk_widget_hide(hbox->label);
1027 		if (type == PF_COND_HEADER || type == PF_COND_TO_OR_CC) {
1028 			gtk_widget_show(hbox->match_menu_in_addr);
1029 			gtk_widget_show(hbox->match_menu_not_in_addr);
1030 		} else {
1031 			gtk_widget_hide(hbox->match_menu_in_addr);
1032 			gtk_widget_hide(hbox->match_menu_not_in_addr);
1033 			if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
1034 			    match_type == PF_MATCH_NOT_IN_ADDRESSBOOK) {
1035 				gtk_option_menu_set_history(GTK_OPTION_MENU(hbox->match_type_optmenu), 0);
1036 				gtk_widget_show(hbox->key_entry);
1037 			}
1038 		}
1039 		break;
1040 	case PF_COND_CMD_TEST:
1041 		gtk_widget_hide(hbox->match_type_optmenu);
1042 		gtk_widget_hide(hbox->size_match_optmenu);
1043 		gtk_widget_hide(hbox->age_match_optmenu);
1044 		gtk_widget_hide(hbox->status_match_optmenu);
1045 		gtk_widget_show(hbox->key_entry);
1046 		gtk_widget_hide(hbox->spin_btn);
1047 		gtk_widget_hide(hbox->label);
1048 		break;
1049 	case PF_COND_SIZE:
1050 		gtk_widget_hide(hbox->match_type_optmenu);
1051 		gtk_widget_show(hbox->size_match_optmenu);
1052 		gtk_widget_hide(hbox->age_match_optmenu);
1053 		gtk_widget_hide(hbox->status_match_optmenu);
1054 		gtk_widget_hide(hbox->key_entry);
1055 		gtk_widget_show(hbox->spin_btn);
1056 		gtk_widget_show(hbox->label);
1057 		gtk_label_set_text(GTK_LABEL(hbox->label), _("KB"));
1058 		break;
1059 	case PF_COND_AGE:
1060 		gtk_widget_hide(hbox->match_type_optmenu);
1061 		gtk_widget_hide(hbox->size_match_optmenu);
1062 		gtk_widget_show(hbox->age_match_optmenu);
1063 		gtk_widget_hide(hbox->status_match_optmenu);
1064 		gtk_widget_hide(hbox->key_entry);
1065 		gtk_widget_show(hbox->spin_btn);
1066 		gtk_widget_show(hbox->label);
1067 		gtk_label_set_text(GTK_LABEL(hbox->label), _("day(s)"));
1068 		break;
1069 	case PF_COND_UNREAD:
1070 	case PF_COND_MARK:
1071 	case PF_COND_COLOR_LABEL:
1072 	case PF_COND_MIME:
1073 		gtk_widget_hide(hbox->match_type_optmenu);
1074 		gtk_widget_hide(hbox->size_match_optmenu);
1075 		gtk_widget_hide(hbox->age_match_optmenu);
1076 		gtk_widget_show(hbox->status_match_optmenu);
1077 		gtk_widget_hide(hbox->key_entry);
1078 		gtk_widget_hide(hbox->spin_btn);
1079 		gtk_widget_hide(hbox->label);
1080 		break;
1081 	case PF_COND_ACCOUNT:
1082 		gtk_widget_hide(hbox->match_type_optmenu);
1083 		gtk_widget_hide(hbox->size_match_optmenu);
1084 		gtk_widget_hide(hbox->age_match_optmenu);
1085 		gtk_widget_hide(hbox->status_match_optmenu);
1086 		gtk_widget_hide(hbox->key_entry);
1087 		/* gtk_widget_show(hbox->account_optmenu); */
1088 		gtk_widget_hide(hbox->spin_btn);
1089 		gtk_widget_hide(hbox->label);
1090 		break;
1091 	default:
1092 		break;
1093 	}
1094 }
1095 
prefs_filter_edit_set_action_hbox_widgets(ActionHBox * hbox,ActionMenuType type)1096 void prefs_filter_edit_set_action_hbox_widgets(ActionHBox *hbox,
1097 					       ActionMenuType type)
1098 {
1099 	GtkOptionMenu *type_optmenu = GTK_OPTION_MENU(hbox->action_type_optmenu);
1100 	gint index;
1101 
1102 	switch (type) {
1103 	case PF_ACTION_MOVE:
1104 	case PF_ACTION_COPY:
1105 		gtk_widget_show(hbox->label);
1106 		gtk_label_set_text(GTK_LABEL(hbox->label), _("folder:"));
1107 		gtk_widget_show(hbox->folder_entry);
1108 		gtk_widget_show(hbox->folder_sel_btn);
1109 		gtk_widget_hide(hbox->cmd_entry);
1110 		gtk_widget_hide(hbox->address_entry);
1111 		gtk_widget_hide(hbox->clabel_optmenu);
1112 		break;
1113 	case PF_ACTION_NOT_RECEIVE:
1114 	case PF_ACTION_DELETE:
1115 	case PF_ACTION_MARK:
1116 	case PF_ACTION_MARK_READ:
1117 	case PF_ACTION_STOP_EVAL:
1118 		gtk_widget_hide(hbox->label);
1119 		gtk_widget_hide(hbox->folder_entry);
1120 		gtk_widget_hide(hbox->folder_sel_btn);
1121 		gtk_widget_hide(hbox->cmd_entry);
1122 		gtk_widget_hide(hbox->address_entry);
1123 		gtk_widget_hide(hbox->clabel_optmenu);
1124 		break;
1125 	case PF_ACTION_EXEC:
1126 	case PF_ACTION_EXEC_ASYNC:
1127 		gtk_widget_hide(hbox->label);
1128 		gtk_widget_hide(hbox->folder_entry);
1129 		gtk_widget_hide(hbox->folder_sel_btn);
1130 		gtk_widget_show(hbox->cmd_entry);
1131 		gtk_widget_hide(hbox->address_entry);
1132 		gtk_widget_hide(hbox->clabel_optmenu);
1133 		break;
1134 	case PF_ACTION_COLOR_LABEL:
1135 		gtk_widget_hide(hbox->label);
1136 		gtk_widget_hide(hbox->folder_entry);
1137 		gtk_widget_hide(hbox->folder_sel_btn);
1138 		gtk_widget_hide(hbox->cmd_entry);
1139 		gtk_widget_hide(hbox->address_entry);
1140 		gtk_widget_show(hbox->clabel_optmenu);
1141 		break;
1142 	case PF_ACTION_FORWARD:
1143 	case PF_ACTION_FORWARD_AS_ATTACHMENT:
1144 	case PF_ACTION_REDIRECT:
1145 		gtk_widget_show(hbox->label);
1146 		gtk_label_set_text(GTK_LABEL(hbox->label), _("address:"));
1147 		gtk_widget_hide(hbox->folder_entry);
1148 		gtk_widget_hide(hbox->folder_sel_btn);
1149 		gtk_widget_hide(hbox->cmd_entry);
1150 		gtk_widget_show(hbox->address_entry);
1151 		gtk_widget_hide(hbox->clabel_optmenu);
1152 		break;
1153 	default:
1154 		break;
1155 	}
1156 
1157 	index = menu_find_option_menu_index(type_optmenu, GINT_TO_POINTER(type),
1158 					    NULL);
1159 	gtk_option_menu_set_history(type_optmenu, index);
1160 	prefs_filter_edit_set_action_hbox_menus_sensitive();
1161 }
1162 
prefs_filter_edit_set_action_hbox_menu_sensitive(ActionHBox * hbox,ActionMenuType type,gboolean sensitive)1163 static void prefs_filter_edit_set_action_hbox_menu_sensitive
1164 	(ActionHBox *hbox, ActionMenuType type, gboolean sensitive)
1165 {
1166 	GtkWidget *menuitem;
1167 
1168 	menuitem = hbox->action_type_menu_items[type];
1169 	if (menuitem)
1170 		gtk_widget_set_sensitive(menuitem, sensitive);
1171 }
1172 
prefs_filter_edit_set_action_hbox_menus_sensitive(void)1173 static void prefs_filter_edit_set_action_hbox_menus_sensitive(void)
1174 {
1175 	GSList *cur;
1176 	ActionHBox *cur_hbox;
1177 	ActionMenuType menu_type;
1178 	ActionMenuType cur_type;
1179 	gboolean action_menu_selection[PF_ACTION_NONE];
1180 	gboolean action_menu_sensitive[PF_ACTION_NONE];
1181 
1182 	prefs_filter_edit_get_action_hbox_menus_selection
1183 		(action_menu_selection);
1184 
1185 	for (cur = rule_edit_window.action_hbox_list; cur != NULL;
1186 	     cur = cur->next) {
1187 		cur_hbox = (ActionHBox *)cur->data;
1188 		menu_type = prefs_filter_edit_get_action_hbox_type(cur_hbox);
1189 		for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1190 		     cur_type++)
1191 			action_menu_sensitive[cur_type] = TRUE;
1192 
1193 		for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1194 		     cur_type++) {
1195 			switch (cur_type) {
1196 			case PF_ACTION_MOVE:
1197 			case PF_ACTION_NOT_RECEIVE:
1198 			case PF_ACTION_DELETE:
1199 				if (action_menu_selection[cur_type] == TRUE &&
1200 				    menu_type != cur_type) {
1201 					action_menu_sensitive[PF_ACTION_MOVE] = FALSE;
1202 					action_menu_sensitive[PF_ACTION_NOT_RECEIVE] = FALSE;
1203 					action_menu_sensitive[PF_ACTION_DELETE] = FALSE;
1204 				}
1205 				break;
1206 			case PF_ACTION_MARK:
1207 			case PF_ACTION_COLOR_LABEL:
1208 			case PF_ACTION_MARK_READ:
1209 			case PF_ACTION_STOP_EVAL:
1210 				if (action_menu_selection[cur_type] == TRUE &&
1211 				    menu_type != cur_type)
1212 					action_menu_sensitive[cur_type] = FALSE;
1213 				break;
1214 			default:
1215 				break;
1216 			}
1217 		}
1218 
1219 		for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1220 		     cur_type++) {
1221 			prefs_filter_edit_set_action_hbox_menu_sensitive
1222 				(cur_hbox, cur_type,
1223 				 action_menu_sensitive[cur_type]);
1224 		}
1225 	}
1226 }
1227 
prefs_filter_edit_get_action_hbox_menus_selection(gboolean * selection)1228 static void prefs_filter_edit_get_action_hbox_menus_selection(gboolean *selection)
1229 {
1230 	GSList *cur;
1231 	ActionHBox *cur_hbox;
1232 	ActionMenuType menu_type;
1233 	ActionMenuType cur_type;
1234 
1235 	for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE; cur_type++)
1236 		selection[cur_type] = FALSE;
1237 
1238 	for (cur = rule_edit_window.action_hbox_list; cur != NULL;
1239 	     cur = cur->next) {
1240 		cur_hbox = (ActionHBox *)cur->data;
1241 		menu_type = prefs_filter_edit_get_action_hbox_type(cur_hbox);
1242 		if (menu_type >= PF_ACTION_MOVE && menu_type < PF_ACTION_NONE)
1243 			selection[menu_type] = TRUE;
1244 	}
1245 }
1246 
prefs_filter_edit_get_action_hbox_type(ActionHBox * hbox)1247 static ActionMenuType prefs_filter_edit_get_action_hbox_type(ActionHBox *hbox)
1248 {
1249 	GtkWidget *menuitem;
1250 	ActionMenuType type;
1251 
1252 	g_return_val_if_fail(hbox != NULL, PF_ACTION_NONE);
1253 
1254 	menuitem = gtk_menu_get_active
1255 		(GTK_MENU(gtk_option_menu_get_menu
1256 			(GTK_OPTION_MENU(hbox->action_type_optmenu))));
1257 	type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem),
1258 						 MENU_VAL_ID));
1259 
1260 	return type;
1261 }
1262 
prefs_filter_edit_insert_cond_hbox(FilterCondEdit * cond_edit,CondHBox * hbox,gint pos)1263 void prefs_filter_edit_insert_cond_hbox(FilterCondEdit *cond_edit,
1264 					CondHBox *hbox, gint pos)
1265 {
1266 	g_return_if_fail(cond_edit != NULL);
1267 	g_return_if_fail(hbox != NULL);
1268 
1269 	if (!cond_edit->cond_hbox_list) {
1270 		gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1271 	} else if (cond_edit->cond_hbox_list &&
1272 		   !cond_edit->cond_hbox_list->next) {
1273 		CondHBox *top_hbox =
1274 			(CondHBox *)cond_edit->cond_hbox_list->data;
1275 		gtk_widget_set_sensitive(top_hbox->del_btn, TRUE);
1276 	}
1277 
1278 	gtk_box_pack_start(GTK_BOX(cond_edit->cond_vbox),
1279 			   hbox->hbox, FALSE, FALSE, 0);
1280 	if (pos >= 0) {
1281 		gtk_box_reorder_child(GTK_BOX(cond_edit->cond_vbox),
1282 				      hbox->hbox, pos);
1283 	}
1284 
1285 	cond_edit->cond_hbox_list =
1286 		g_slist_insert(cond_edit->cond_hbox_list, hbox, pos);
1287 }
1288 
prefs_filter_edit_insert_action_hbox(ActionHBox * hbox,gint pos)1289 static void prefs_filter_edit_insert_action_hbox(ActionHBox *hbox, gint pos)
1290 {
1291 	g_return_if_fail(hbox != NULL);
1292 
1293 	if (!rule_edit_window.action_hbox_list) {
1294 		gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1295 	} else if (rule_edit_window.action_hbox_list &&
1296 		   !rule_edit_window.action_hbox_list->next) {
1297 		ActionHBox *top_hbox =
1298 			(ActionHBox *)rule_edit_window.action_hbox_list->data;
1299 		gtk_widget_set_sensitive(top_hbox->del_btn, TRUE);
1300 	}
1301 
1302 	gtk_box_pack_start(GTK_BOX(rule_edit_window.action_vbox),
1303 			   hbox->hbox, FALSE, FALSE, 0);
1304 	if (pos >= 0) {
1305 		gtk_box_reorder_child(GTK_BOX(rule_edit_window.action_vbox),
1306 				      hbox->hbox, pos);
1307 	}
1308 
1309 	rule_edit_window.action_hbox_list =
1310 		g_slist_insert(rule_edit_window.action_hbox_list, hbox, pos);
1311 }
1312 
prefs_filter_edit_remove_cond_hbox(FilterCondEdit * cond_edit,CondHBox * hbox)1313 static void prefs_filter_edit_remove_cond_hbox(FilterCondEdit *cond_edit,
1314 					       CondHBox *hbox)
1315 {
1316 	g_return_if_fail(cond_edit != NULL);
1317 	g_return_if_fail(hbox != NULL);
1318 	g_return_if_fail(cond_edit->cond_hbox_list != NULL);
1319 
1320 	cond_edit->cond_hbox_list =
1321 		g_slist_remove(cond_edit->cond_hbox_list, hbox);
1322 	gtk_widget_destroy(hbox->hbox);
1323 	g_free(hbox);
1324 
1325 	if (cond_edit->cond_hbox_list && !cond_edit->cond_hbox_list->next) {
1326 		hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
1327 		gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1328 	}
1329 }
1330 
prefs_filter_edit_remove_action_hbox(ActionHBox * hbox)1331 static void prefs_filter_edit_remove_action_hbox(ActionHBox *hbox)
1332 {
1333 	g_return_if_fail(hbox != NULL);
1334 	g_return_if_fail(rule_edit_window.action_hbox_list != NULL);
1335 
1336 	rule_edit_window.action_hbox_list =
1337 		g_slist_remove(rule_edit_window.action_hbox_list, hbox);
1338 	gtk_widget_destroy(hbox->hbox);
1339 	g_free(hbox);
1340 
1341 	prefs_filter_edit_set_action_hbox_menus_sensitive();
1342 
1343 	if (rule_edit_window.action_hbox_list &&
1344 	    !rule_edit_window.action_hbox_list->next) {
1345 		hbox = (ActionHBox *)rule_edit_window.action_hbox_list->data;
1346 		gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1347 	}
1348 }
1349 
prefs_filter_edit_add_rule_cond(FilterCondEdit * cond_edit,FilterRule * rule)1350 void prefs_filter_edit_add_rule_cond(FilterCondEdit *cond_edit,
1351 				     FilterRule *rule)
1352 {
1353 	CondHBox *hbox;
1354 	GSList *cur;
1355 	FilterCond *cond;
1356 
1357 	if (!rule || !rule->cond_list) {
1358 		hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
1359 		prefs_filter_edit_set_cond_hbox_widgets(hbox, PF_COND_HEADER);
1360 		prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
1361 		if (cond_edit->add_hbox)
1362 			cond_edit->add_hbox(hbox);
1363 		return;
1364 	}
1365 
1366 	for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
1367 		cond = (FilterCond *)cur->data;
1368 
1369 		hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
1370 		prefs_filter_edit_cond_hbox_set(hbox, cond);
1371 		prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
1372 		if (cond_edit->add_hbox)
1373 			cond_edit->add_hbox(hbox);
1374 	}
1375 }
1376 
prefs_filter_edit_add_rule_action(FilterRule * rule)1377 static void prefs_filter_edit_add_rule_action(FilterRule *rule)
1378 {
1379 	ActionHBox *hbox;
1380 	GSList *cur;
1381 
1382 	if (!rule || !rule->action_list) {
1383 		hbox = prefs_filter_edit_action_hbox_create();
1384 		prefs_filter_edit_insert_action_hbox(hbox, -1);
1385 		prefs_filter_edit_set_action_hbox_widgets(hbox, PF_ACTION_MOVE);
1386 		return;
1387 	}
1388 
1389 	for (cur = rule->action_list; cur != NULL; cur = cur->next) {
1390 		FilterAction *action = (FilterAction *)cur->data;
1391 
1392 		hbox = prefs_filter_edit_action_hbox_create();
1393 		prefs_filter_edit_insert_action_hbox(hbox, -1);
1394 		prefs_filter_edit_action_hbox_set(hbox, action);
1395 	}
1396 }
1397 
prefs_filter_edit_set_cond_header_menu(FilterCondEdit * cond_edit,CondHBox * hbox)1398 static void prefs_filter_edit_set_cond_header_menu(FilterCondEdit *cond_edit,
1399 						   CondHBox *hbox)
1400 {
1401 	GSList *cur;
1402 	GtkWidget *menu;
1403 	GtkWidget *menuitem;
1404 	gint pos = 0;
1405 	GList *child;
1406 
1407 	menu = gtk_option_menu_get_menu
1408 		(GTK_OPTION_MENU(hbox->cond_type_optmenu));
1409 
1410 	/* destroy header items */
1411 	child = GTK_MENU_SHELL(menu)->children;
1412 	while (child != NULL) {
1413 		GList *next = child->next;
1414 		menuitem = GTK_WIDGET(child->data);
1415 		if (!g_object_get_data(G_OBJECT(menuitem), "header_str"))
1416 			break;
1417 		gtk_widget_destroy(menuitem);
1418 		child = next;
1419 	}
1420 
1421 	for (cur = cond_edit->hdr_list; cur != NULL; cur = cur->next, pos++) {
1422 		Header *header = (Header *)cur->data;
1423 
1424 		menuitem = gtk_menu_item_new_with_label(header->name);
1425 		gtk_widget_show(menuitem);
1426 		gtk_menu_insert(GTK_MENU(menu), menuitem, pos);
1427 		g_object_set_data(G_OBJECT(menuitem), MENU_VAL_ID,
1428 				  GINT_TO_POINTER(PF_COND_HEADER));
1429 		g_object_set_data(G_OBJECT(menuitem), "header_str",
1430 				  header->name);
1431 		g_signal_connect(G_OBJECT(menuitem), "activate",
1432 				 G_CALLBACK(prefs_filter_cond_activated_cb),
1433 				 hbox);
1434 	}
1435 
1436 	if (hbox->cur_type == PF_COND_HEADER)
1437 		prefs_filter_edit_cond_hbox_select
1438 			(hbox, hbox->cur_type, hbox->cur_header_name);
1439 }
1440 
prefs_filter_edit_activate_cond_header(FilterCondEdit * cond_edit,const gchar * header)1441 static void prefs_filter_edit_activate_cond_header(FilterCondEdit *cond_edit,
1442 						   const gchar *header)
1443 {
1444 	gint index;
1445 	CondHBox *hbox;
1446 	GtkWidget *menu;
1447 	GtkWidget *menuitem;
1448 	GList *cur;
1449 	gchar *menu_header;
1450 
1451 	g_return_if_fail(header != NULL);
1452 	g_return_if_fail(cond_edit != NULL);
1453 	g_return_if_fail(cond_edit->cond_hbox_list != NULL);
1454 
1455 	hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
1456 	menu = gtk_option_menu_get_menu
1457 		(GTK_OPTION_MENU(hbox->cond_type_optmenu));
1458 
1459 	for (cur = GTK_MENU_SHELL(menu)->children, index = 0;
1460 	     cur != NULL; cur = cur->next, index++) {
1461 		menuitem = GTK_WIDGET(cur->data);
1462 		menu_header = g_object_get_data(G_OBJECT(menuitem),
1463 						"header_str");
1464 		if (!menu_header)
1465 			break;
1466 		if (!g_ascii_strcasecmp(menu_header, header)) {
1467 			gtk_option_menu_set_history
1468 				(GTK_OPTION_MENU(hbox->cond_type_optmenu),
1469 				 index);
1470 			gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
1471 			break;
1472 		}
1473 	}
1474 }
1475 
edit_header_list_dialog_deleted(GtkWidget * widget,GdkEventAny * event,gpointer data)1476 static gint edit_header_list_dialog_deleted(GtkWidget *widget,
1477 					    GdkEventAny *event, gpointer data)
1478 {
1479 	edit_header_list_dialog.finished = TRUE;
1480 	return TRUE;
1481 }
1482 
edit_header_list_dialog_key_pressed(GtkWidget * widget,GdkEventKey * event,gpointer data)1483 static gboolean edit_header_list_dialog_key_pressed(GtkWidget *widget,
1484 						    GdkEventKey *event,
1485 						    gpointer data)
1486 {
1487 	if (event && event->keyval == GDK_Escape)
1488 		edit_header_list_dialog.finished = TRUE;
1489 	return FALSE;
1490 }
1491 
edit_header_list_dialog_add(void)1492 static void edit_header_list_dialog_add(void)
1493 {
1494 	GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1495 	const gchar *text;
1496 	gchar *ctext[1];
1497 	gint row;
1498 	gchar *row_text;
1499 
1500 	text = gtk_entry_get_text(GTK_ENTRY(edit_header_list_dialog.entry));
1501 	if (text[0] == '\0') return;
1502 
1503 	for (row = 0; gtk_clist_get_text(clist, row, 0, &row_text) != 0;
1504 	     row++) {
1505 		if (g_ascii_strcasecmp(row_text, text) == 0) return;
1506 	}
1507 
1508 	ctext[0] = (gchar *)text;
1509 	gtk_clist_append(clist, ctext);
1510 }
1511 
edit_header_list_dialog_delete(void)1512 static void edit_header_list_dialog_delete(void)
1513 {
1514 	GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1515 	gint row;
1516 
1517 	if (!clist->selection) return;
1518 
1519 	row = GPOINTER_TO_INT(clist->selection->data);
1520 	gtk_clist_remove(clist, row);
1521 }
1522 
edit_header_list_dialog_ok(void)1523 static void edit_header_list_dialog_ok(void)
1524 {
1525 	edit_header_list_dialog.finished = TRUE;
1526 	edit_header_list_dialog.ok = TRUE;
1527 }
1528 
edit_header_list_dialog_cancel(void)1529 static void edit_header_list_dialog_cancel(void)
1530 {
1531 	edit_header_list_dialog.finished = TRUE;
1532 }
1533 
prefs_filter_edit_edit_header_list_dialog_create(void)1534 static void prefs_filter_edit_edit_header_list_dialog_create(void)
1535 {
1536 	GtkWidget *window;
1537 	GtkWidget *vbox;
1538 	GtkWidget *hbox;
1539 
1540 	GtkWidget *vbox2;
1541 	GtkWidget *scrwin;
1542 	GtkWidget *clist;
1543 
1544 	GtkWidget *entry_hbox;
1545 	GtkWidget *label;
1546 	GtkWidget *entry;
1547 
1548 	GtkWidget *btn_vbox;
1549 	GtkWidget *add_btn;
1550 	GtkWidget *del_btn;
1551 
1552 	GtkWidget *confirm_area;
1553 	GtkWidget *ok_btn;
1554 	GtkWidget *cancel_btn;
1555 
1556 	gchar *title[1];
1557 
1558 	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1559 	gtk_container_set_border_width(GTK_CONTAINER(window), 8);
1560 	gtk_window_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
1561 	gtk_window_set_modal(GTK_WINDOW(window), TRUE);
1562 	gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
1563 	gtk_window_set_title(GTK_WINDOW(window), _("Edit header list"));
1564 
1565 	g_signal_connect(G_OBJECT(window), "delete_event",
1566 			 G_CALLBACK(edit_header_list_dialog_deleted), NULL);
1567 	g_signal_connect(G_OBJECT(window), "key_press_event",
1568 			 G_CALLBACK(edit_header_list_dialog_key_pressed), NULL);
1569 
1570 	vbox = gtk_vbox_new(FALSE, 6);
1571 	gtk_container_add(GTK_CONTAINER(window), vbox);
1572 
1573 	hbox = gtk_hbox_new(FALSE, 8);
1574 	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
1575 
1576 	vbox2 = gtk_vbox_new(FALSE, 8);
1577 	gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
1578 
1579 	scrwin = gtk_scrolled_window_new(NULL, NULL);
1580 	gtk_widget_set_size_request(scrwin, 140 * gtkut_get_dpi_multiplier(), 180 * gtkut_get_dpi_multiplier());
1581 	gtk_box_pack_start(GTK_BOX(vbox2), scrwin, TRUE, TRUE, 0);
1582 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
1583 				       GTK_POLICY_AUTOMATIC,
1584 				       GTK_POLICY_AUTOMATIC);
1585 
1586 	title[0] = _("Headers");
1587 	clist = gtk_clist_new_with_titles(1, title);
1588 	gtk_container_add(GTK_CONTAINER(scrwin), clist);
1589 	gtk_clist_set_column_width(GTK_CLIST(clist), 0, 80);
1590 	gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE);
1591 	gtkut_clist_set_redraw(GTK_CLIST(clist));
1592 	GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[0].button,
1593 			       GTK_CAN_FOCUS);
1594 
1595 	entry_hbox = gtk_hbox_new(FALSE, 8);
1596 	gtk_box_pack_start(GTK_BOX(vbox), entry_hbox, FALSE, TRUE, 0);
1597 
1598 	label = gtk_label_new(_("Header:"));
1599 	gtk_box_pack_start(GTK_BOX(entry_hbox), label, FALSE, FALSE, 0);
1600 
1601 	entry = gtk_entry_new();
1602 	gtk_box_pack_start(GTK_BOX(entry_hbox), entry, TRUE, TRUE, 0);
1603 
1604 	btn_vbox = gtk_vbox_new(FALSE, 8);
1605 	gtk_box_pack_start(GTK_BOX(hbox), btn_vbox, FALSE, FALSE, 0);
1606 
1607 	add_btn = gtk_button_new_with_label(_("Add"));
1608 	gtk_box_pack_start(GTK_BOX(btn_vbox), add_btn, FALSE, FALSE, 0);
1609 
1610 	del_btn = gtk_button_new_with_label(_(" Delete "));
1611 	gtk_box_pack_start(GTK_BOX(btn_vbox), del_btn, FALSE, FALSE, 0);
1612 
1613 	gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
1614 				      &cancel_btn, GTK_STOCK_CANCEL,
1615 				      NULL, NULL);
1616 	gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
1617 	gtk_widget_grab_default(ok_btn);
1618 
1619 	g_signal_connect(G_OBJECT(add_btn), "clicked",
1620 			 G_CALLBACK(edit_header_list_dialog_add), NULL);
1621 	g_signal_connect(G_OBJECT(del_btn), "clicked",
1622 			 G_CALLBACK(edit_header_list_dialog_delete), NULL);
1623 	g_signal_connect(G_OBJECT(ok_btn), "clicked",
1624 			 G_CALLBACK(edit_header_list_dialog_ok), NULL);
1625 	g_signal_connect(G_OBJECT(cancel_btn), "clicked",
1626 			 G_CALLBACK(edit_header_list_dialog_cancel), NULL);
1627 
1628 	manage_window_set_transient(GTK_WINDOW(window));
1629 
1630 	gtk_widget_show_all(window);
1631 
1632 	edit_header_list_dialog.window = window;
1633 	edit_header_list_dialog.clist = clist;
1634 	edit_header_list_dialog.entry = entry;
1635 	edit_header_list_dialog.finished = FALSE;
1636 	edit_header_list_dialog.ok = FALSE;
1637 }
1638 
prefs_filter_edit_edit_header_list_dialog_set(void)1639 static void prefs_filter_edit_edit_header_list_dialog_set(void)
1640 {
1641 	GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1642 	GSList *list;
1643 	GSList *cur;
1644 	gchar *text[1];
1645 
1646 	gtk_clist_freeze(clist);
1647 
1648 	list = prefs_filter_get_user_header_list();
1649 	for (cur = list; cur != NULL; cur = cur->next) {
1650 		Header *header = (Header *)cur->data;
1651 		text[0] = header->name;
1652 		gtk_clist_append(clist, text);
1653 	}
1654 
1655 	gtk_clist_thaw(clist);
1656 }
1657 
prefs_filter_edit_edit_header_list_dialog_get(void)1658 static GSList *prefs_filter_edit_edit_header_list_dialog_get(void)
1659 {
1660 	GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1661 	gint row;
1662 	gchar *text;
1663 	GSList *list = NULL;
1664 
1665 	for (row = 0; gtk_clist_get_text(clist, row, 0, &text) != 0; row++)
1666 		list = procheader_add_header_list(list, text, NULL);
1667 
1668 	return list;
1669 }
1670 
prefs_filter_edit_edit_header_list(FilterCondEdit * cond_edit)1671 static void prefs_filter_edit_edit_header_list(FilterCondEdit *cond_edit)
1672 {
1673 	GSList *list;
1674 	GSList *cur;
1675 
1676 	prefs_filter_edit_edit_header_list_dialog_create();
1677 	prefs_filter_edit_edit_header_list_dialog_set();
1678 
1679 	while (edit_header_list_dialog.finished == FALSE)
1680 		gtk_main_iteration();
1681 
1682 	if (edit_header_list_dialog.ok == TRUE) {
1683 		list = prefs_filter_edit_edit_header_list_dialog_get();
1684 		prefs_filter_set_user_header_list(list);
1685 		prefs_filter_edit_update_header_list(cond_edit);
1686 		for (cur = cond_edit->cond_hbox_list; cur != NULL;
1687 		     cur = cur->next) {
1688 			CondHBox *hbox = (CondHBox *)cur->data;
1689 			prefs_filter_edit_set_cond_header_menu(cond_edit, hbox);
1690 		}
1691 		prefs_filter_write_user_header_list();
1692 	}
1693 
1694 	gtk_widget_destroy(edit_header_list_dialog.window);
1695 	edit_header_list_dialog.window = NULL;
1696 	edit_header_list_dialog.clist = NULL;
1697 	edit_header_list_dialog.entry = NULL;
1698 	edit_header_list_dialog.finished = FALSE;
1699 	edit_header_list_dialog.ok = FALSE;
1700 }
1701 
prefs_filter_edit_cond_hbox_to_cond(CondHBox * hbox,gboolean case_sens,gchar ** error_msg)1702 FilterCond *prefs_filter_edit_cond_hbox_to_cond(CondHBox *hbox,
1703 						gboolean case_sens,
1704 						gchar **error_msg)
1705 {
1706 	FilterCond *cond = NULL;
1707 	GtkWidget *cond_type_menuitem;
1708 	CondMenuType cond_menu_type;
1709 	MatchMenuType match_menu_type;
1710 	const gchar *header_name;
1711 	const gchar *key_str;
1712 	gint int_value;
1713 	FilterMatchType match_type = FLT_CONTAIN;
1714 	FilterMatchFlag match_flag = 0;
1715 	SizeMatchType size_type;
1716 	AgeMatchType age_type;
1717 	StatusMatchType status_type;
1718 	gchar *error_msg_ = NULL;
1719 
1720 	cond_type_menuitem = gtk_menu_get_active
1721 		(GTK_MENU(gtk_option_menu_get_menu
1722 			(GTK_OPTION_MENU(hbox->cond_type_optmenu))));
1723 	cond_menu_type = GPOINTER_TO_INT
1724 		(g_object_get_data(G_OBJECT(cond_type_menuitem), MENU_VAL_ID));
1725 
1726 	match_menu_type = menu_get_option_menu_active_index
1727 		(GTK_OPTION_MENU(hbox->match_type_optmenu));
1728 
1729 	key_str = gtk_entry_get_text(GTK_ENTRY(hbox->key_entry));
1730 
1731 	switch (match_menu_type) {
1732 	case PF_MATCH_CONTAIN:
1733 		match_type = FLT_CONTAIN;
1734 		break;
1735 	case PF_MATCH_NOT_CONTAIN:
1736 		match_type = FLT_CONTAIN;
1737 		match_flag |= FLT_NOT_MATCH;
1738 		break;
1739 	case PF_MATCH_EQUAL:
1740 		match_type = FLT_EQUAL;
1741 		break;
1742 	case PF_MATCH_NOT_EQUAL:
1743 		match_type = FLT_EQUAL;
1744 		match_flag |= FLT_NOT_MATCH;
1745 		break;
1746 	case PF_MATCH_REGEX:
1747 		match_type = FLT_REGEX;
1748 		break;
1749 	case PF_MATCH_NOT_REGEX:
1750 		match_type = FLT_REGEX;
1751 		match_flag |= FLT_NOT_MATCH;
1752 		break;
1753 	case PF_MATCH_IN_ADDRESSBOOK:
1754 		match_type = FLT_IN_ADDRESSBOOK;
1755 		break;
1756 	case PF_MATCH_NOT_IN_ADDRESSBOOK:
1757 		match_type = FLT_IN_ADDRESSBOOK;
1758 		match_flag |= FLT_NOT_MATCH;
1759 		break;
1760 	default:
1761 		break;
1762 	}
1763 
1764 	if (case_sens)
1765 		match_flag |= FLT_CASE_SENS;
1766 
1767 	switch (cond_menu_type) {
1768 	case PF_COND_HEADER:
1769 		header_name = g_object_get_data
1770 			(G_OBJECT(cond_type_menuitem), "header_str");
1771 		cond = filter_cond_new(FLT_COND_HEADER,
1772 				       match_type, match_flag,
1773 				       header_name, key_str);
1774 		break;
1775 	case PF_COND_TO_OR_CC:
1776 		cond = filter_cond_new(FLT_COND_TO_OR_CC, match_type,
1777 				       match_flag, NULL, key_str);
1778 		break;
1779 	case PF_COND_ANY_HEADER:
1780 		cond = filter_cond_new(FLT_COND_ANY_HEADER, match_type,
1781 				       match_flag, NULL, key_str);
1782 		break;
1783 	case PF_COND_BODY:
1784 		cond = filter_cond_new(FLT_COND_BODY, match_type,
1785 				       match_flag, NULL, key_str);
1786 		break;
1787 	case PF_COND_CMD_TEST:
1788 		if (key_str && *key_str)
1789 			cond = filter_cond_new(FLT_COND_CMD_TEST,
1790 					       0, 0, NULL, key_str);
1791 		else
1792 			error_msg_ = _("Command is not specified.");
1793 		break;
1794 	case PF_COND_SIZE:
1795 		size_type = menu_get_option_menu_active_index
1796 			 (GTK_OPTION_MENU(hbox->size_match_optmenu));
1797 		match_flag = size_type == PF_SIZE_LARGER ? 0 : FLT_NOT_MATCH;
1798 		int_value = gtk_spin_button_get_value_as_int
1799 			(GTK_SPIN_BUTTON(hbox->spin_btn));
1800 		cond = filter_cond_new(FLT_COND_SIZE_GREATER,
1801 				       0, match_flag, NULL, itos(int_value));
1802 		break;
1803 	case PF_COND_AGE:
1804 		age_type = menu_get_option_menu_active_index
1805 			 (GTK_OPTION_MENU(hbox->age_match_optmenu));
1806 		match_flag = age_type == PF_AGE_LONGER ? 0 : FLT_NOT_MATCH;
1807 		int_value = gtk_spin_button_get_value_as_int
1808 			(GTK_SPIN_BUTTON(hbox->spin_btn));
1809 		cond = filter_cond_new(FLT_COND_AGE_GREATER,
1810 				       0, match_flag, NULL, itos(int_value));
1811 		break;
1812 	case PF_COND_UNREAD:
1813 		status_type = menu_get_option_menu_active_index
1814 			(GTK_OPTION_MENU(hbox->status_match_optmenu));
1815 		match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1816 		cond = filter_cond_new(FLT_COND_UNREAD, 0, match_flag,
1817 				       NULL, NULL);
1818 		break;
1819 	case PF_COND_MARK:
1820 		status_type = menu_get_option_menu_active_index
1821 			(GTK_OPTION_MENU(hbox->status_match_optmenu));
1822 		match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1823 		cond = filter_cond_new(FLT_COND_MARK, 0, match_flag,
1824 				       NULL, NULL);
1825 		break;
1826 	case PF_COND_COLOR_LABEL:
1827 		status_type = menu_get_option_menu_active_index
1828 			(GTK_OPTION_MENU(hbox->status_match_optmenu));
1829 		match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1830 		cond = filter_cond_new(FLT_COND_COLOR_LABEL, 0, match_flag,
1831 				       NULL, NULL);
1832 		break;
1833 	case PF_COND_MIME:
1834 		status_type = menu_get_option_menu_active_index
1835 			(GTK_OPTION_MENU(hbox->status_match_optmenu));
1836 		match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1837 		cond = filter_cond_new(FLT_COND_MIME, 0, match_flag,
1838 				       NULL, NULL);
1839 		break;
1840 	case PF_COND_ACCOUNT:
1841 	case PF_COND_EDIT_HEADER:
1842 	default:
1843 		break;
1844 	}
1845 
1846 	if (error_msg)
1847 		*error_msg = error_msg_;
1848 
1849 	return cond;
1850 }
1851 
check_dest_folder(const gchar * dest,gchar ** error_msg)1852 static gboolean check_dest_folder(const gchar *dest, gchar **error_msg)
1853 {
1854 	FolderItem *item;
1855 
1856 	if (!dest || *dest == '\0') {
1857 		*error_msg = _("Destination folder is not specified.");
1858 		return FALSE;
1859 	}
1860 
1861 	item = folder_find_item_from_identifier(dest);
1862 	if (!item || !item->path || !item->parent) {
1863 		*error_msg = _("The specified destination folder does not exist.");
1864 		return FALSE;
1865 	}
1866 
1867 	return TRUE;
1868 }
1869 
prefs_filter_edit_action_hbox_to_action(ActionHBox * hbox,gchar ** error_msg)1870 FilterAction *prefs_filter_edit_action_hbox_to_action(ActionHBox *hbox,
1871 						      gchar **error_msg)
1872 {
1873 	FilterAction *action = NULL;
1874 	ActionMenuType action_menu_type;
1875 	const gchar *str;
1876 	guint color;
1877 	gchar *error_msg_ = NULL;
1878 
1879 	action_menu_type = prefs_filter_edit_get_action_hbox_type(hbox);
1880 
1881 	switch (action_menu_type) {
1882 	case PF_ACTION_MOVE:
1883 		str = gtk_entry_get_text(GTK_ENTRY(hbox->folder_entry));
1884 		if (check_dest_folder(str, &error_msg_))
1885 			action = filter_action_new(FLT_ACTION_MOVE, str);
1886 		break;
1887 	case PF_ACTION_COPY:
1888 		str = gtk_entry_get_text(GTK_ENTRY(hbox->folder_entry));
1889 		if (check_dest_folder(str, &error_msg_))
1890 			action = filter_action_new(FLT_ACTION_COPY, str);
1891 		break;
1892 	case PF_ACTION_NOT_RECEIVE:
1893 		action = filter_action_new(FLT_ACTION_NOT_RECEIVE, NULL);
1894 		break;
1895 	case PF_ACTION_DELETE:
1896 		action = filter_action_new(FLT_ACTION_DELETE, NULL);
1897 		break;
1898 	case PF_ACTION_EXEC:
1899 		str = gtk_entry_get_text(GTK_ENTRY(hbox->cmd_entry));
1900 		if (str && *str)
1901 			action = filter_action_new(FLT_ACTION_EXEC, str);
1902 		else
1903 			error_msg_ = _("Command is not specified.");
1904 		break;
1905 	case PF_ACTION_EXEC_ASYNC:
1906 		str = gtk_entry_get_text(GTK_ENTRY(hbox->cmd_entry));
1907 		if (str && *str)
1908 			action = filter_action_new(FLT_ACTION_EXEC_ASYNC, str);
1909 		else
1910 			error_msg_ = _("Command is not specified.");
1911 		break;
1912 	case PF_ACTION_MARK:
1913 		action = filter_action_new(FLT_ACTION_MARK, NULL);
1914 		break;
1915 	case PF_ACTION_COLOR_LABEL:
1916 		color = colorlabel_get_color_menu_active_item
1917 			(gtk_option_menu_get_menu
1918 			 (GTK_OPTION_MENU(hbox->clabel_optmenu)));
1919 		action = filter_action_new(FLT_ACTION_COLOR_LABEL,
1920 					   itos(color));
1921 		break;
1922 	case PF_ACTION_MARK_READ:
1923 		action = filter_action_new(FLT_ACTION_MARK_READ, NULL);
1924 		break;
1925 	case PF_ACTION_FORWARD:
1926 	case PF_ACTION_FORWARD_AS_ATTACHMENT:
1927 	case PF_ACTION_REDIRECT:
1928 		break;
1929 	case PF_ACTION_STOP_EVAL:
1930 		action = filter_action_new(FLT_ACTION_STOP_EVAL, NULL);
1931 		break;
1932 	case PF_ACTION_SEPARATOR:
1933 	default:
1934 		break;
1935 	}
1936 
1937 	if (error_msg)
1938 		*error_msg = error_msg_;
1939 
1940 	return action;
1941 }
1942 
prefs_filter_edit_cond_edit_to_list(FilterCondEdit * cond_edit,gboolean case_sens)1943 GSList *prefs_filter_edit_cond_edit_to_list(FilterCondEdit *cond_edit,
1944 					    gboolean case_sens)
1945 {
1946 	GSList *cur;
1947 	FilterCond *cond;
1948 	GSList *cond_list = NULL;
1949 
1950 	for (cur = cond_edit->cond_hbox_list; cur != NULL; cur = cur->next) {
1951 		CondHBox *hbox = (CondHBox *)cur->data;
1952 		gchar *error_msg;
1953 
1954 		cond = prefs_filter_edit_cond_hbox_to_cond(hbox, case_sens,
1955 							   &error_msg);
1956 		if (cond) {
1957 			cond_list = g_slist_append(cond_list, cond);
1958 		} else {
1959 			if (!error_msg)
1960 				error_msg = _("Invalid condition exists.");
1961 			alertpanel_error("%s", error_msg);
1962 			filter_cond_list_free(cond_list);
1963 			return NULL;
1964 		}
1965 	}
1966 
1967 	return cond_list;
1968 }
1969 
prefs_filter_edit_dialog_to_rule(void)1970 static FilterRule *prefs_filter_edit_dialog_to_rule(void)
1971 {
1972 	FilterRule *rule = NULL;
1973 	GSList *cur;
1974 	const gchar *rule_name;
1975 	FilterBoolOp bool_op;
1976 	GSList *cond_list = NULL;
1977 	GSList *action_list = NULL;
1978 	GtkWidget *bool_op_menuitem;
1979 	gchar *error_msg = NULL;
1980 
1981 	rule_name = gtk_entry_get_text(GTK_ENTRY(rule_edit_window.name_entry));
1982 	if (!rule_name || *rule_name == '\0') {
1983 		error_msg = _("Rule name is not specified.");
1984 		goto error;
1985 	}
1986 
1987 	bool_op_menuitem = gtk_menu_get_active
1988 		(GTK_MENU(gtk_option_menu_get_menu
1989 			(GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu))));
1990 	bool_op = GPOINTER_TO_INT
1991 		(g_object_get_data(G_OBJECT(bool_op_menuitem), MENU_VAL_ID));
1992 
1993 	cond_list = prefs_filter_edit_cond_edit_to_list
1994 		(&rule_edit_window.cond_edit, FALSE);
1995 	if (!cond_list)
1996 		return NULL;
1997 
1998 	for (cur = rule_edit_window.action_hbox_list; cur != NULL;
1999 	     cur = cur->next) {
2000 		ActionHBox *hbox = (ActionHBox *)cur->data;
2001 		FilterAction *action;
2002 
2003 		action = prefs_filter_edit_action_hbox_to_action(hbox,
2004 								 &error_msg);
2005 		if (action)
2006 			action_list = g_slist_append(action_list, action);
2007 		else {
2008 			if (!error_msg)
2009 				error_msg = _("Invalid action exists.");
2010 			goto error;
2011 		}
2012 	}
2013 
2014 error:
2015 	if (error_msg || !cond_list || !action_list) {
2016 		if (!error_msg) {
2017 			if (!cond_list)
2018 				error_msg = _("Condition not exist.");
2019 			else
2020 				error_msg = _("Action not exist.");
2021 		}
2022 		alertpanel_error("%s", error_msg);
2023 		if (cond_list)
2024 			filter_cond_list_free(cond_list);
2025 		if (action_list)
2026 			filter_action_list_free(action_list);
2027 		return NULL;
2028 	}
2029 
2030 	rule = filter_rule_new(rule_name, bool_op, cond_list, action_list);
2031 
2032 	return rule;
2033 }
2034 
2035 /* callback functions */
2036 
prefs_filter_edit_deleted(GtkWidget * widget,GdkEventAny * event,gpointer data)2037 static gint prefs_filter_edit_deleted(GtkWidget *widget, GdkEventAny *event,
2038 				      gpointer data)
2039 {
2040 	prefs_filter_edit_cancel();
2041 	return TRUE;
2042 }
2043 
prefs_filter_edit_key_pressed(GtkWidget * widget,GdkEventKey * event,gpointer data)2044 static gboolean prefs_filter_edit_key_pressed(GtkWidget *widget,
2045 					      GdkEventKey *event,
2046 					      gpointer data)
2047 {
2048 	if (event && event->keyval == GDK_Escape)
2049 		prefs_filter_edit_cancel();
2050 	return FALSE;
2051 }
2052 
prefs_filter_edit_ok(void)2053 static void prefs_filter_edit_ok(void)
2054 {
2055 	FilterRule *rule;
2056 
2057 	rule = prefs_filter_edit_dialog_to_rule();
2058 	if (rule) {
2059 		rule_edit_window.new_rule = rule;
2060 		rule_edit_window.edit_finished = TRUE;
2061 	}
2062 }
2063 
prefs_filter_edit_cancel(void)2064 static void prefs_filter_edit_cancel(void)
2065 {
2066 	rule_edit_window.new_rule = NULL;
2067 	rule_edit_window.edit_finished = TRUE;
2068 }
2069 
prefs_filter_cond_activated_cb(GtkWidget * widget,gpointer data)2070 static void prefs_filter_cond_activated_cb(GtkWidget *widget, gpointer data)
2071 {
2072 	CondHBox *hbox = (CondHBox *)data;
2073 	FilterCondEdit *cond_edit = hbox->cond_edit;
2074 	CondMenuType type;
2075 
2076 	type = GPOINTER_TO_INT
2077 		(g_object_get_data(G_OBJECT(widget), MENU_VAL_ID));
2078 
2079 	if (type == PF_COND_EDIT_HEADER) {
2080 		prefs_filter_edit_edit_header_list(cond_edit);
2081 		prefs_filter_edit_cond_hbox_select
2082 			(hbox, hbox->cur_type, hbox->cur_header_name);
2083 	} else {
2084 		hbox->cur_type = type;
2085 		g_free(hbox->cur_header_name);
2086 		hbox->cur_header_name = NULL;
2087 
2088 		prefs_filter_edit_set_cond_hbox_widgets(hbox, type);
2089 		if (type == PF_COND_HEADER) {
2090 			gchar *header_name;
2091 			gchar *header_field;
2092 
2093 			header_name = (gchar *)g_object_get_data
2094 				(G_OBJECT(widget), "header_str");
2095 			header_field = prefs_filter_get_msg_header_field
2096 				(header_name);
2097 			if (header_field)
2098 				gtk_entry_set_text(GTK_ENTRY(hbox->key_entry),
2099 						   header_field);
2100 			hbox->cur_header_name = g_strdup(header_name);
2101 		}
2102 	}
2103 }
2104 
prefs_filter_match_activated_cb(GtkWidget * widget,gpointer data)2105 static void prefs_filter_match_activated_cb(GtkWidget *widget, gpointer data)
2106 {
2107 	CondHBox *hbox = (CondHBox *)data;
2108 	GtkWidget *cond_type_menuitem;
2109 	CondMenuType cond_menu_type;
2110 
2111 	cond_type_menuitem = gtk_menu_get_active
2112 		(GTK_MENU(gtk_option_menu_get_menu
2113 			(GTK_OPTION_MENU(hbox->cond_type_optmenu))));
2114 	cond_menu_type = GPOINTER_TO_INT
2115 		(g_object_get_data(G_OBJECT(cond_type_menuitem), MENU_VAL_ID));
2116 
2117 	prefs_filter_edit_set_cond_hbox_widgets(hbox, cond_menu_type);
2118 }
2119 
prefs_filter_action_activated_cb(GtkWidget * widget,gpointer data)2120 static void prefs_filter_action_activated_cb(GtkWidget *widget, gpointer data)
2121 {
2122 	ActionHBox *hbox = (ActionHBox *)data;
2123 	ActionMenuType type;
2124 
2125 	type = GPOINTER_TO_INT
2126 		(g_object_get_data(G_OBJECT(widget), MENU_VAL_ID));
2127 	prefs_filter_edit_set_action_hbox_widgets(hbox, type);
2128 }
2129 
prefs_filter_action_select_dest_cb(GtkWidget * widget,gpointer data)2130 static void prefs_filter_action_select_dest_cb(GtkWidget *widget, gpointer data)
2131 {
2132 	ActionHBox *hbox = (ActionHBox *)data;
2133 
2134 	FolderItem *dest;
2135 	gchar *id;
2136 
2137 	dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
2138 	if (!dest || !dest->path) return;
2139 
2140 	id = folder_item_get_identifier(dest);
2141 	if (id) {
2142 		gtk_entry_set_text(GTK_ENTRY(hbox->folder_entry), id);
2143 		g_free(id);
2144 	}
2145 }
2146 
prefs_filter_cond_del_cb(GtkWidget * widget,gpointer data)2147 static void prefs_filter_cond_del_cb(GtkWidget *widget, gpointer data)
2148 {
2149 	CondHBox *hbox = (CondHBox *)data;
2150 	FilterCondEdit *cond_edit = hbox->cond_edit;
2151 
2152 	if (cond_edit->cond_hbox_list && cond_edit->cond_hbox_list->next)
2153 		prefs_filter_edit_remove_cond_hbox(cond_edit, hbox);
2154 }
2155 
prefs_filter_cond_add_cb(GtkWidget * widget,gpointer data)2156 static void prefs_filter_cond_add_cb(GtkWidget *widget, gpointer data)
2157 {
2158 	CondHBox *hbox = (CondHBox *)data;
2159 	CondHBox *new_hbox;
2160 	FilterCondEdit *cond_edit = hbox->cond_edit;
2161 	gint index;
2162 
2163 	index = g_slist_index(cond_edit->cond_hbox_list, hbox);
2164 	g_return_if_fail(index >= 0);
2165 	new_hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
2166 	prefs_filter_edit_set_cond_hbox_widgets(new_hbox, PF_COND_HEADER);
2167 	prefs_filter_edit_insert_cond_hbox(cond_edit, new_hbox, index + 1);
2168 	if (cond_edit->add_hbox)
2169 		cond_edit->add_hbox(new_hbox);
2170 }
2171 
prefs_filter_action_del_cb(GtkWidget * widget,gpointer data)2172 static void prefs_filter_action_del_cb(GtkWidget *widget, gpointer data)
2173 {
2174 	ActionHBox *hbox = (ActionHBox *)data;
2175 
2176 	if (rule_edit_window.action_hbox_list &&
2177 	    rule_edit_window.action_hbox_list->next)
2178 		prefs_filter_edit_remove_action_hbox(hbox);
2179 }
2180 
prefs_filter_action_add_cb(GtkWidget * widget,gpointer data)2181 static void prefs_filter_action_add_cb(GtkWidget *widget, gpointer data)
2182 {
2183 	ActionHBox *hbox = (ActionHBox *)data;
2184 	ActionHBox *new_hbox;
2185 	gboolean action_menu_selection[PF_ACTION_NONE];
2186 	gint index;
2187 
2188 	prefs_filter_edit_get_action_hbox_menus_selection(action_menu_selection);
2189 
2190 	index = g_slist_index(rule_edit_window.action_hbox_list, hbox);
2191 	g_return_if_fail(index >= 0);
2192 	new_hbox = prefs_filter_edit_action_hbox_create();
2193 	prefs_filter_edit_insert_action_hbox(new_hbox, index + 1);
2194 	if (action_menu_selection[PF_ACTION_MOVE] == TRUE ||
2195 	    action_menu_selection[PF_ACTION_NOT_RECEIVE] == TRUE ||
2196 	    action_menu_selection[PF_ACTION_DELETE] == TRUE)
2197 		prefs_filter_edit_set_action_hbox_widgets(new_hbox,
2198 							  PF_ACTION_COPY);
2199 	else
2200 		prefs_filter_edit_set_action_hbox_widgets(new_hbox,
2201 							  PF_ACTION_MOVE);
2202 }
2203