Statistics
| Revision:

root / src / prefs_filter_edit.c @ 3196

History | View | Annotate | Download (64.3 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2012 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

    
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_EVENTS_FLUSH();
173
        gtk_widget_show(rule_edit_window.window);
174

    
175
        syl_plugin_signal_emit("prefs-filter-edit-open", rule, header, key,
176
                               rule_edit_window.window);
177

    
178
        rule_edit_window.new_rule = NULL;
179
        rule_edit_window.edit_finished = FALSE;
180
        while (rule_edit_window.edit_finished == FALSE)
181
                gtk_main_iteration();
182

    
183
        gtk_widget_hide(rule_edit_window.window);
184
        prefs_filter_edit_clear();
185
        prefs_filter_set_msg_header_list(NULL);
186

    
187
        new_rule = rule_edit_window.new_rule;
188
        rule_edit_window.new_rule = NULL;
189

    
190
        if (new_rule)
191
                debug_print("new rule created: %s\n", new_rule->name);
192

    
193
        lock = FALSE;
194

    
195
        return new_rule;
196
}
197

    
198
static void prefs_filter_edit_create(void)
199
{
200
        GtkWidget *window;
201

    
202
        GtkWidget *vbox;
203

    
204
        GtkWidget *hbox;
205
        GtkWidget *label;
206
        GtkWidget *name_entry;
207

    
208
        GtkWidget *bool_op_optmenu;
209
        GtkWidget *menu;
210
        GtkWidget *menuitem;
211

    
212
        GtkWidget *cond_scrolled_win;
213
        GtkWidget *cond_vbox;
214

    
215
        GtkWidget *action_scrolled_win;
216
        GtkWidget *action_vbox;
217

    
218
        GtkWidget *ok_btn;
219
        GtkWidget *cancel_btn;
220
        GtkWidget *confirm_area;
221

    
222
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
223
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
224
        gtk_widget_set_size_request(window, 632, 405);
225
        gtk_window_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
226
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
227
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
228
        gtk_widget_realize(window);
229

    
230
        vbox = gtk_vbox_new(FALSE, 6);
231
        gtk_widget_show(vbox);
232
        gtk_container_add(GTK_CONTAINER(window), vbox);
233

    
234
        gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
235
                                      &cancel_btn, GTK_STOCK_CANCEL,
236
                                      NULL, NULL);
237
        gtk_widget_show(confirm_area);
238
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
239
        gtk_widget_grab_default(ok_btn);
240

    
241
        gtk_window_set_title(GTK_WINDOW(window),
242
                             _("Filter rule"));
243
        g_signal_connect(G_OBJECT(window), "delete_event",
244
                         G_CALLBACK(prefs_filter_edit_deleted), NULL);
245
        g_signal_connect(G_OBJECT(window), "key_press_event",
246
                         G_CALLBACK(prefs_filter_edit_key_pressed), NULL);
247
        MANAGE_WINDOW_SIGNALS_CONNECT (window);
248
        g_signal_connect(G_OBJECT(ok_btn), "clicked",
249
                         G_CALLBACK(prefs_filter_edit_ok), NULL);
250
        g_signal_connect(G_OBJECT(cancel_btn), "clicked",
251
                         G_CALLBACK(prefs_filter_edit_cancel), NULL);
252

    
253
        hbox = gtk_hbox_new(FALSE, 4);
254
        gtk_widget_show(hbox);
255
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
256

    
257
        label = gtk_label_new(_("Name:"));
258
        gtk_widget_show(label);
259
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
260

    
261
        name_entry = gtk_entry_new();
262
        gtk_widget_show(name_entry);
263
        gtk_box_pack_start(GTK_BOX(hbox), name_entry, TRUE, TRUE, 0);
264

    
265
        hbox = gtk_hbox_new(FALSE, 4);
266
        gtk_widget_show(hbox);
267
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
268

    
269
        bool_op_optmenu = gtk_option_menu_new();
270
        gtk_widget_show(bool_op_optmenu);
271
        gtk_box_pack_start(GTK_BOX(hbox), bool_op_optmenu, FALSE, FALSE, 0);
272

    
273
        menu = gtk_menu_new();
274
        gtk_widget_show(menu);
275
        MENUITEM_ADD(menu, menuitem,
276
                     _("If any of the following condition matches"), FLT_OR);
277
        MENUITEM_ADD(menu, menuitem,
278
                     _("If all of the following conditions match"), FLT_AND);
279
        gtk_option_menu_set_menu(GTK_OPTION_MENU(bool_op_optmenu), menu);
280
        gtk_option_menu_set_history(GTK_OPTION_MENU(bool_op_optmenu), FLT_AND);
281

    
282
        cond_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
283
        gtk_widget_show(cond_scrolled_win);
284
        gtk_widget_set_size_request(cond_scrolled_win, -1, 125);
285
        gtk_box_pack_start(GTK_BOX(vbox), cond_scrolled_win, TRUE, TRUE, 0);
286
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(cond_scrolled_win),
287
                                       GTK_POLICY_AUTOMATIC,
288
                                       GTK_POLICY_AUTOMATIC);
289

    
290
        cond_vbox = gtk_vbox_new(FALSE, 2);
291
        gtk_widget_show(cond_vbox);
292
        gtk_container_set_border_width(GTK_CONTAINER(cond_vbox), 2);
293
        gtk_scrolled_window_add_with_viewport
294
                (GTK_SCROLLED_WINDOW(cond_scrolled_win), cond_vbox);
295

    
296
        hbox = gtk_hbox_new(FALSE, 4);
297
        gtk_widget_show(hbox);
298
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
299

    
300
        label = gtk_label_new(_("Perform the following actions:"));
301
        gtk_widget_show(label);
302
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
303

    
304
        action_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
305
        gtk_widget_show(action_scrolled_win);
306
        gtk_box_pack_start(GTK_BOX(vbox), action_scrolled_win, TRUE, TRUE, 0);
307
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(action_scrolled_win),
308
                                       GTK_POLICY_AUTOMATIC,
309
                                       GTK_POLICY_AUTOMATIC);
310

    
311
        action_vbox = gtk_vbox_new(FALSE, 2);
312
        gtk_widget_show(action_vbox);
313
        gtk_container_set_border_width(GTK_CONTAINER(action_vbox), 2);
314
        gtk_scrolled_window_add_with_viewport
315
                (GTK_SCROLLED_WINDOW(action_scrolled_win), action_vbox);
316

    
317
        rule_edit_window.window = window;
318
        rule_edit_window.name_entry = name_entry;
319

    
320
        rule_edit_window.bool_op_optmenu = bool_op_optmenu;
321
        rule_edit_window.cond_scrolled_win = cond_scrolled_win;
322
        rule_edit_window.cond_edit.cond_vbox = cond_vbox;
323
        rule_edit_window.action_scrolled_win = action_scrolled_win;
324
        rule_edit_window.action_vbox = action_vbox;
325

    
326
        rule_edit_window.ok_btn = ok_btn;
327
        rule_edit_window.cancel_btn = cancel_btn;
328
}
329

    
330
FilterCondEdit *prefs_filter_edit_cond_edit_create(void)
331
{
332
        FilterCondEdit *cond_edit;
333
        GtkWidget *cond_vbox;
334

    
335
        cond_edit = g_new(FilterCondEdit, 1);
336

    
337
        cond_vbox = gtk_vbox_new(FALSE, 2);
338
        gtk_widget_show(cond_vbox);
339
        gtk_container_set_border_width(GTK_CONTAINER(cond_vbox), 2);
340

    
341
        cond_edit->cond_vbox = cond_vbox;
342
        cond_edit->cond_hbox_list = NULL;
343
        cond_edit->hdr_list = NULL;
344
        cond_edit->rule_hdr_list = NULL;
345
        cond_edit->add_hbox = NULL;
346

    
347
        return cond_edit;
348
}
349

    
350
void prefs_filter_edit_clear_cond_edit(FilterCondEdit *cond_edit)
351
{
352
        while (cond_edit->cond_hbox_list) {
353
                CondHBox *hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
354
                prefs_filter_edit_remove_cond_hbox(cond_edit, hbox);
355
        }
356

    
357
        procheader_header_list_destroy(cond_edit->hdr_list);
358
        cond_edit->hdr_list = NULL;
359
        procheader_header_list_destroy(cond_edit->rule_hdr_list);
360
        cond_edit->rule_hdr_list = NULL;
361
}
362

    
363
static void prefs_filter_edit_clear(void)
364
{
365
        prefs_filter_edit_clear_cond_edit(&rule_edit_window.cond_edit);
366

    
367
        while (rule_edit_window.action_hbox_list) {
368
                ActionHBox *hbox =
369
                        (ActionHBox *)rule_edit_window.action_hbox_list->data;
370
                prefs_filter_edit_remove_action_hbox(hbox);
371
        }
372
}
373

    
374
static void prefs_filter_edit_rule_to_dialog(FilterRule *rule,
375
                                             const gchar *default_name)
376
{
377
        gint index = 1;
378
        static gint count = 1;
379

    
380
        if (rule && rule->name)
381
                gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
382
                                   rule->name);
383
        else if (default_name)
384
                gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
385
                                   default_name);
386
        else {
387
                gchar rule_name[32];
388
                g_snprintf(rule_name, sizeof(rule_name), "Rule %d", count++);
389
                gtk_entry_set_text(GTK_ENTRY(rule_edit_window.name_entry),
390
                                   rule_name);
391
        }
392

    
393
        if (rule) {
394
                index = menu_find_option_menu_index
395
                        (GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu),
396
                         GINT_TO_POINTER(rule->bool_op), NULL);
397
                if (index < 0)
398
                        index = 1;
399
        }
400
        if (index >= 0) {
401
                gtk_option_menu_set_history
402
                        (GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu),
403
                         index);
404
        }
405

    
406
        gtkut_scrolled_window_reset_position
407
                (GTK_SCROLLED_WINDOW(rule_edit_window.cond_scrolled_win));
408
        gtkut_scrolled_window_reset_position
409
                (GTK_SCROLLED_WINDOW(rule_edit_window.action_scrolled_win));
410

    
411
        prefs_filter_edit_add_rule_cond(&rule_edit_window.cond_edit, rule);
412
        prefs_filter_edit_add_rule_action(rule);
413
}
414

    
415
void prefs_filter_edit_set_header_list(FilterCondEdit *cond_edit,
416
                                       FilterRule *rule)
417
{
418
        GSList *list;
419
        GSList *rule_hdr_list = NULL;
420
        GSList *cur;
421
        FilterCond *cond;
422

    
423
        procheader_header_list_destroy(cond_edit->hdr_list);
424
        cond_edit->hdr_list = NULL;
425
        procheader_header_list_destroy(cond_edit->rule_hdr_list);
426
        cond_edit->rule_hdr_list = NULL;
427

    
428
        list = prefs_filter_get_header_list();
429
        cond_edit->hdr_list = list;
430

    
431
        if (!rule)
432
                return;
433

    
434
        for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
435
                cond = (FilterCond *)cur->data;
436

    
437
                if (cond->type == FLT_COND_HEADER &&
438
                    procheader_find_header_list
439
                        (rule_hdr_list, cond->header_name) < 0)
440
                        rule_hdr_list = procheader_add_header_list
441
                                (rule_hdr_list, cond->header_name, NULL);
442
        }
443

    
444
        cond_edit->rule_hdr_list = rule_hdr_list;
445
        cond_edit->hdr_list = procheader_merge_header_list_dup(list,
446
                                                               rule_hdr_list);
447
        procheader_header_list_destroy(list);
448
}
449

    
450
static void prefs_filter_edit_update_header_list(FilterCondEdit *cond_edit)
451
{
452
        GSList *list;
453

    
454
        procheader_header_list_destroy(cond_edit->hdr_list);
455
        cond_edit->hdr_list = NULL;
456

    
457
        list = prefs_filter_get_header_list();
458
        cond_edit->hdr_list = procheader_merge_header_list_dup
459
                (list, cond_edit->rule_hdr_list);
460
        procheader_header_list_destroy(list);
461
}
462

    
463
CondHBox *prefs_filter_edit_cond_hbox_create(FilterCondEdit *cond_edit)
464
{
465
        CondHBox *cond_hbox;
466
        GtkWidget *hbox;
467
        GtkWidget *cond_type_optmenu;
468
        GtkWidget *match_type_optmenu;
469
        GtkWidget *size_match_optmenu;
470
        GtkWidget *age_match_optmenu;
471
        GtkWidget *status_match_optmenu;
472
        GtkWidget *menu;
473
        GtkWidget *menuitem;
474
        GtkWidget *key_entry;
475
        GtkObject *spin_btn_adj;
476
        GtkWidget *spin_btn;
477
        GtkWidget *label;
478
        GtkWidget *del_btn;
479
        GtkWidget *add_btn;
480
        GtkWidget *del_img;
481
        GtkWidget *add_img;
482
        GtkWidget *match_menu_in_addr;
483
        GtkWidget *match_menu_not_in_addr;
484

    
485
        cond_hbox = g_new0(CondHBox, 1);
486

    
487
        hbox = gtk_hbox_new(FALSE, 4);
488
        gtk_widget_show(hbox);
489

    
490
        cond_type_optmenu = gtk_option_menu_new();
491
        gtk_widget_show(cond_type_optmenu);
492
        gtk_box_pack_start(GTK_BOX(hbox), cond_type_optmenu, FALSE, FALSE, 0);
493

    
494
#define COND_MENUITEM_ADD(str, action)                                            \
495
{                                                                            \
496
        MENUITEM_ADD(menu, menuitem, str, action);                            \
497
        g_signal_connect(G_OBJECT(menuitem), "activate",                    \
498
                         G_CALLBACK(prefs_filter_cond_activated_cb),            \
499
                         cond_hbox);                                            \
500
}
501

    
502
        menu = gtk_menu_new();
503
        gtk_widget_show(menu);
504
        MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
505
        COND_MENUITEM_ADD(_("To or Cc"),          PF_COND_TO_OR_CC);
506
        COND_MENUITEM_ADD(_("Any header"),        PF_COND_ANY_HEADER);
507
        COND_MENUITEM_ADD(_("Edit header..."),    PF_COND_EDIT_HEADER);
508

    
509
        MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
510
        COND_MENUITEM_ADD(_("Message body"),      PF_COND_BODY);
511
        COND_MENUITEM_ADD(_("Result of command"), PF_COND_CMD_TEST);
512
        COND_MENUITEM_ADD(_("Size"),              PF_COND_SIZE);
513
        COND_MENUITEM_ADD(_("Age"),               PF_COND_AGE);
514

    
515
        MENUITEM_ADD(menu, menuitem, NULL,        PF_COND_SEPARATOR);
516
        COND_MENUITEM_ADD(_("Unread"),            PF_COND_UNREAD);
517
        COND_MENUITEM_ADD(_("Marked"),            PF_COND_MARK);
518
        COND_MENUITEM_ADD(_("Has color label"),   PF_COND_COLOR_LABEL);
519
        COND_MENUITEM_ADD(_("Has attachment"),    PF_COND_MIME);
520
        /* COND_MENUITEM_ADD(_("Account"),           PF_COND_ACCOUNT); */
521

    
522
        gtk_option_menu_set_menu(GTK_OPTION_MENU(cond_type_optmenu), menu);
523

    
524
#undef COND_MENUITEM_ADD
525

    
526
        match_type_optmenu = gtk_option_menu_new();
527
        gtk_widget_show(match_type_optmenu);
528
        gtk_box_pack_start(GTK_BOX(hbox), match_type_optmenu, FALSE, FALSE, 0);
529

    
530
#define MATCH_MENUITEM_ADD(str, action)                                            \
531
{                                                                            \
532
        MENUITEM_ADD(menu, menuitem, str, action);                            \
533
        g_signal_connect(G_OBJECT(menuitem), "activate",                    \
534
                         G_CALLBACK(prefs_filter_match_activated_cb),            \
535
                         cond_hbox);                                            \
536
}
537
        menu = gtk_menu_new();
538
        gtk_widget_show(menu);
539
        MATCH_MENUITEM_ADD(_("contains"),               PF_MATCH_CONTAIN);
540
        MATCH_MENUITEM_ADD(_("doesn't contain"),        PF_MATCH_NOT_CONTAIN);
541
        MATCH_MENUITEM_ADD(_("is"),                     PF_MATCH_EQUAL);
542
        MATCH_MENUITEM_ADD(_("is not"),                 PF_MATCH_NOT_EQUAL);
543
#if defined(USE_ONIGURUMA) || defined(HAVE_REGCOMP)
544
        MATCH_MENUITEM_ADD(_("match to regex"),         PF_MATCH_REGEX);
545
        MATCH_MENUITEM_ADD(_("doesn't match to regex"), PF_MATCH_NOT_REGEX);
546
#endif
547
        MATCH_MENUITEM_ADD(_("is in addressbook"),      PF_MATCH_IN_ADDRESSBOOK);
548
        match_menu_in_addr = menuitem;
549
        MATCH_MENUITEM_ADD(_("is not in addressbook"),  PF_MATCH_NOT_IN_ADDRESSBOOK);
550
        match_menu_not_in_addr = menuitem;
551
        gtk_option_menu_set_menu(GTK_OPTION_MENU(match_type_optmenu), menu);
552

    
553
#undef MATCH_MENUITEM_ADD
554

    
555
        size_match_optmenu = gtk_option_menu_new();
556
        gtk_widget_show(size_match_optmenu);
557
        gtk_box_pack_start(GTK_BOX(hbox), size_match_optmenu, FALSE, FALSE, 0);
558

    
559
        menu = gtk_menu_new();
560
        gtk_widget_show(menu);
561
        MENUITEM_ADD(menu, menuitem, _("is larger than"), PF_SIZE_LARGER);
562
        MENUITEM_ADD(menu, menuitem, _("is smaller than"), PF_SIZE_SMALLER);
563
        gtk_option_menu_set_menu(GTK_OPTION_MENU(size_match_optmenu), menu);
564

    
565
        age_match_optmenu = gtk_option_menu_new();
566
        gtk_widget_show(age_match_optmenu);
567
        gtk_box_pack_start(GTK_BOX(hbox), age_match_optmenu, FALSE, FALSE, 0);
568

    
569
        menu = gtk_menu_new();
570
        gtk_widget_show(menu);
571
        MENUITEM_ADD(menu, menuitem, _("is shorter than"), PF_AGE_SHORTER);
572
        MENUITEM_ADD(menu, menuitem, _("is longer than"), PF_AGE_LONGER);
573
        gtk_option_menu_set_menu(GTK_OPTION_MENU(age_match_optmenu), menu);
574

    
575
        status_match_optmenu = gtk_option_menu_new();
576
        gtk_widget_show(status_match_optmenu);
577
        gtk_box_pack_start(GTK_BOX(hbox), status_match_optmenu,
578
                           FALSE, FALSE, 0);
579

    
580
        menu = gtk_menu_new();
581
        gtk_widget_show(menu);
582
        MENUITEM_ADD(menu, menuitem, _("matches to status"), PF_STATUS_MATCH);
583
        MENUITEM_ADD(menu, menuitem, _("doesn't match to status"),
584
                     PF_STATUS_NOT_MATCH);
585
        gtk_option_menu_set_menu(GTK_OPTION_MENU(status_match_optmenu), menu);
586

    
587
        key_entry = gtk_entry_new();
588
        gtk_widget_show(key_entry);
589
        gtk_box_pack_start(GTK_BOX(hbox), key_entry, TRUE, TRUE, 0);
590

    
591
        spin_btn_adj = gtk_adjustment_new(0, 0, 99999, 1, 10, 0);
592
        spin_btn = gtk_spin_button_new(GTK_ADJUSTMENT(spin_btn_adj), 1, 0);
593
        gtk_box_pack_start(GTK_BOX(hbox), spin_btn, FALSE, FALSE, 0);
594
        gtk_widget_set_size_request(spin_btn, 64, -1);
595
        gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin_btn), TRUE);
596

    
597
        label = gtk_label_new(_("KB"));
598
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
599

    
600
        del_img = gtk_image_new_from_stock
601
                (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
602
        gtk_widget_show(del_img);
603

    
604
        del_btn = gtk_button_new();
605
        gtk_container_add(GTK_CONTAINER(del_btn), del_img);
606
        gtk_widget_show(del_btn);
607
        gtk_box_pack_end(GTK_BOX(hbox), del_btn, FALSE, FALSE, 0);
608

    
609
        add_img = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
610
        gtk_widget_show(add_img);
611

    
612
        add_btn = gtk_button_new();
613
        gtk_container_add(GTK_CONTAINER(add_btn), add_img);
614
        gtk_widget_show(add_btn);
615
        gtk_box_pack_end(GTK_BOX(hbox), add_btn, FALSE, FALSE, 0);
616

    
617
        g_signal_connect(G_OBJECT(del_btn), "clicked",
618
                         G_CALLBACK(prefs_filter_cond_del_cb), cond_hbox);
619
        g_signal_connect(G_OBJECT(add_btn), "clicked",
620
                         G_CALLBACK(prefs_filter_cond_add_cb), cond_hbox);
621

    
622
        cond_hbox->hbox = hbox;
623
        cond_hbox->cond_type_optmenu = cond_type_optmenu;
624
        cond_hbox->match_type_optmenu = match_type_optmenu;
625
        cond_hbox->size_match_optmenu = size_match_optmenu;
626
        cond_hbox->age_match_optmenu = age_match_optmenu;
627
        cond_hbox->status_match_optmenu = status_match_optmenu;
628
        cond_hbox->key_entry = key_entry;
629
        cond_hbox->spin_btn = spin_btn;
630
        cond_hbox->label = label;
631
        cond_hbox->match_menu_in_addr = match_menu_in_addr;
632
        cond_hbox->match_menu_not_in_addr = match_menu_not_in_addr;
633
        cond_hbox->del_btn = del_btn;
634
        cond_hbox->add_btn = add_btn;
635
        cond_hbox->cur_type = PF_COND_HEADER;
636
        cond_hbox->cur_header_name = NULL;
637
        cond_hbox->cond_edit = cond_edit;
638

    
639
        prefs_filter_edit_set_cond_header_menu(cond_edit, cond_hbox);
640
        gtk_option_menu_set_history(GTK_OPTION_MENU(cond_type_optmenu), 0);
641

    
642
        return cond_hbox;
643
}
644

    
645
ActionHBox *prefs_filter_edit_action_hbox_create(void)
646
{
647
        ActionHBox *action_hbox;
648
        GtkWidget *hbox;
649
        GtkWidget *action_type_optmenu;
650
        GtkWidget *menu;
651
        GtkWidget *menuitem;
652
        GtkWidget *label;
653
        GtkWidget *folder_entry;
654
        GtkWidget *cmd_entry;
655
        GtkWidget *address_entry;
656
        GtkWidget *folder_img;
657
        GtkWidget *folder_sel_btn;
658
        GtkWidget *clabel_optmenu;
659
        GtkWidget *del_btn;
660
        GtkWidget *add_btn;
661
        GtkWidget *del_img;
662
        GtkWidget *add_img;
663

    
664
        action_hbox = g_new0(ActionHBox, 1);
665

    
666
        hbox = gtk_hbox_new(FALSE, 4);
667
        gtk_widget_show(hbox);
668

    
669
        action_type_optmenu = gtk_option_menu_new();
670
        gtk_widget_show(action_type_optmenu);
671
        gtk_box_pack_start(GTK_BOX(hbox), action_type_optmenu, FALSE, FALSE, 0);
672

    
673
        memset(action_hbox->action_type_menu_items, 0,
674
               sizeof(action_hbox->action_type_menu_items));
675

    
676
#define ACTION_MENUITEM_ADD(str, action)                                      \
677
{                                                                              \
678
        MENUITEM_ADD(menu, menuitem, str, action);                              \
679
        action_hbox->action_type_menu_items[action] = menuitem;                      \
680
        g_signal_connect(G_OBJECT(menuitem), "activate",                      \
681
                         G_CALLBACK(prefs_filter_action_activated_cb),              \
682
                         action_hbox);                                              \
683
}
684

    
685
        menu = gtk_menu_new();
686
        gtk_widget_show(menu);
687
        ACTION_MENUITEM_ADD(_("Move to"),               PF_ACTION_MOVE);
688
        ACTION_MENUITEM_ADD(_("Copy to"),               PF_ACTION_COPY);
689
        ACTION_MENUITEM_ADD(_("Don't receive"),         PF_ACTION_NOT_RECEIVE);
690
        ACTION_MENUITEM_ADD(_("Delete from server"),    PF_ACTION_DELETE);
691

    
692
        MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
693
        ACTION_MENUITEM_ADD(_("Set mark"),              PF_ACTION_MARK);
694
        ACTION_MENUITEM_ADD(_("Set color"),             PF_ACTION_COLOR_LABEL);
695
        ACTION_MENUITEM_ADD(_("Mark as read"),          PF_ACTION_MARK_READ);
696

    
697
#if 0
698
        MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
699
        ACTION_MENUITEM_ADD(_("Forward"),               PF_ACTION_FORWARD);
700
        ACTION_MENUITEM_ADD(_("Forward as attachment"), PF_ACTION_FORWARD_AS_ATTACHMENT);
701
        ACTION_MENUITEM_ADD(_("Redirect"),              PF_ACTION_REDIRECT);
702
#endif
703

    
704
        MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
705
        ACTION_MENUITEM_ADD(_("Execute command"),       PF_ACTION_EXEC);
706

    
707
        MENUITEM_ADD(menu, menuitem, NULL,              PF_ACTION_SEPARATOR);
708
        ACTION_MENUITEM_ADD(_("Stop rule evaluation"),  PF_ACTION_STOP_EVAL);
709

    
710
        gtk_option_menu_set_menu(GTK_OPTION_MENU(action_type_optmenu), menu);
711

    
712
#undef ACTION_MENUITEM_ADD
713

    
714
        label = gtk_label_new(_("folder:"));
715
        gtk_widget_show(label);
716
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
717

    
718
        folder_entry = gtk_entry_new();
719
        gtk_widget_show(folder_entry);
720
        gtk_box_pack_start(GTK_BOX(hbox), folder_entry, TRUE, TRUE, 0);
721

    
722
        folder_img = stock_pixbuf_widget(rule_edit_window.window,
723
                                         STOCK_PIXMAP_FOLDER_OPEN);
724
        gtk_widget_show(folder_img);
725

    
726
        folder_sel_btn = gtk_button_new();
727
        gtk_container_add(GTK_CONTAINER(folder_sel_btn), folder_img);
728
        gtk_widget_show(folder_sel_btn);
729
        gtk_box_pack_start(GTK_BOX(hbox), folder_sel_btn, FALSE, FALSE, 0);
730

    
731
        cmd_entry = gtk_entry_new();
732
        gtk_widget_show(cmd_entry);
733
        gtk_box_pack_start(GTK_BOX(hbox), cmd_entry, TRUE, TRUE, 0);
734

    
735
        address_entry = gtk_entry_new();
736
        gtk_widget_show(address_entry);
737
        gtk_box_pack_start(GTK_BOX(hbox), address_entry, TRUE, TRUE, 0);
738

    
739
        clabel_optmenu = gtk_option_menu_new();
740
        gtk_widget_show(clabel_optmenu);
741
        gtk_box_pack_start(GTK_BOX(hbox), clabel_optmenu, FALSE, FALSE, 0);
742

    
743
        menu = colorlabel_create_color_menu();
744
        gtk_option_menu_set_menu(GTK_OPTION_MENU(clabel_optmenu), menu);
745

    
746
        del_img = gtk_image_new_from_stock
747
                (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
748
        gtk_widget_show(del_img);
749

    
750
        del_btn = gtk_button_new();
751
        gtk_container_add(GTK_CONTAINER(del_btn), del_img);
752
        gtk_widget_show(del_btn);
753
        gtk_box_pack_end(GTK_BOX(hbox), del_btn, FALSE, FALSE, 0);
754

    
755
        add_img = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
756
        gtk_widget_show(add_img);
757

    
758
        add_btn = gtk_button_new();
759
        gtk_container_add(GTK_CONTAINER(add_btn), add_img);
760
        gtk_widget_show(add_btn);
761
        gtk_box_pack_end(GTK_BOX(hbox), add_btn, FALSE, FALSE, 0);
762

    
763
        g_signal_connect(G_OBJECT(folder_sel_btn), "clicked",
764
                         G_CALLBACK(prefs_filter_action_select_dest_cb),
765
                         action_hbox);
766
        g_signal_connect(G_OBJECT(del_btn), "clicked",
767
                         G_CALLBACK(prefs_filter_action_del_cb), action_hbox);
768
        g_signal_connect(G_OBJECT(add_btn), "clicked",
769
                         G_CALLBACK(prefs_filter_action_add_cb), action_hbox);
770

    
771
        action_hbox->hbox = hbox;
772
        action_hbox->action_type_optmenu = action_type_optmenu;
773
        action_hbox->label = label;
774
        action_hbox->folder_entry = folder_entry;
775
        action_hbox->cmd_entry = cmd_entry;
776
        action_hbox->address_entry = address_entry;
777
        action_hbox->folder_sel_btn = folder_sel_btn;
778
        action_hbox->clabel_optmenu = clabel_optmenu;
779
        action_hbox->del_btn = del_btn;
780
        action_hbox->add_btn = add_btn;
781

    
782
        return action_hbox;
783
}
784

    
785
void prefs_filter_edit_cond_hbox_set(CondHBox *hbox, FilterCond *cond)
786
{
787
        GtkOptionMenu *cond_type_optmenu =
788
                GTK_OPTION_MENU(hbox->cond_type_optmenu);
789
        GtkOptionMenu *match_type_optmenu =
790
                GTK_OPTION_MENU(hbox->match_type_optmenu);
791
        gint cond_index = -1;
792
        gint match_index = -1;
793
        CondMenuType cond_type = PF_COND_NONE;
794
        MatchMenuType match_type = PF_MATCH_NONE;
795
        SizeMatchType size_type = PF_SIZE_LARGER;
796
        AgeMatchType age_type = PF_AGE_SHORTER;
797
        StatusMatchType status_type = PF_STATUS_MATCH;
798

    
799
        switch (cond->type) {
800
        case FLT_COND_HEADER:
801
                cond_type = PF_COND_HEADER; break;
802
        case FLT_COND_TO_OR_CC:
803
                cond_type = PF_COND_TO_OR_CC; break;
804
        case FLT_COND_ANY_HEADER:
805
                cond_type = PF_COND_ANY_HEADER; break;
806
        case FLT_COND_BODY:
807
                cond_type = PF_COND_BODY; break;
808
        case FLT_COND_CMD_TEST:
809
                cond_type = PF_COND_CMD_TEST; break;
810
        case FLT_COND_SIZE_GREATER:
811
                cond_type = PF_COND_SIZE;
812
                if (FLT_IS_NOT_MATCH(cond->match_flag))
813
                        size_type = PF_SIZE_SMALLER;
814
                else
815
                        size_type = PF_SIZE_LARGER;
816
                break;
817
        case FLT_COND_AGE_GREATER:
818
                cond_type = PF_COND_AGE;
819
                if (FLT_IS_NOT_MATCH(cond->match_flag))
820
                        age_type = PF_AGE_SHORTER;
821
                else
822
                        age_type = PF_AGE_LONGER;
823
                break;
824
        case FLT_COND_UNREAD:
825
                cond_type = PF_COND_UNREAD; break;
826
        case FLT_COND_MARK:
827
                cond_type = PF_COND_MARK; break;
828
        case FLT_COND_COLOR_LABEL:
829
                cond_type = PF_COND_COLOR_LABEL; break;
830
        case FLT_COND_MIME:
831
                cond_type = PF_COND_MIME; break;
832
        case FLT_COND_ACCOUNT:
833
                cond_type = PF_COND_ACCOUNT; break;
834
        default:
835
                break;
836
        }
837

    
838
        switch (cond->type) {
839
        case FLT_COND_HEADER:
840
        case FLT_COND_TO_OR_CC:
841
        case FLT_COND_ANY_HEADER:
842
        case FLT_COND_BODY:
843
                switch (cond->match_type) {
844
                case FLT_CONTAIN:
845
                        if (FLT_IS_NOT_MATCH(cond->match_flag))
846
                                match_type = PF_MATCH_NOT_CONTAIN;
847
                        else
848
                                match_type = PF_MATCH_CONTAIN;
849
                        break;
850
                case FLT_EQUAL:
851
                        if (FLT_IS_NOT_MATCH(cond->match_flag))
852
                                match_type = PF_MATCH_NOT_EQUAL;
853
                        else
854
                                match_type = PF_MATCH_EQUAL;
855
                        break;
856
                case FLT_REGEX:
857
                        if (FLT_IS_NOT_MATCH(cond->match_flag))
858
                                match_type = PF_MATCH_NOT_REGEX;
859
                        else
860
                                match_type = PF_MATCH_REGEX;
861
                        break;
862
                case FLT_IN_ADDRESSBOOK:
863
                        if (FLT_IS_NOT_MATCH(cond->match_flag))
864
                                match_type = PF_MATCH_NOT_IN_ADDRESSBOOK;
865
                        else
866
                                match_type = PF_MATCH_IN_ADDRESSBOOK;
867
                        break;
868
                }
869
                break;
870
        case FLT_COND_UNREAD:
871
        case FLT_COND_MARK:
872
        case FLT_COND_COLOR_LABEL:
873
        case FLT_COND_MIME:
874
                if (FLT_IS_NOT_MATCH(cond->match_flag))
875
                        status_type = PF_STATUS_NOT_MATCH;
876
                else
877
                        status_type = PF_STATUS_MATCH;
878
                break;
879
        default:
880
                break;
881
        }
882

    
883
        if (cond_type == PF_COND_HEADER)
884
                cond_index = procheader_find_header_list
885
                        (hbox->cond_edit->hdr_list, cond->header_name);
886
        else
887
                cond_index = menu_find_option_menu_index
888
                        (cond_type_optmenu, GINT_TO_POINTER(cond_type), NULL);
889
        if (cond_index >= 0) {
890
                GtkWidget *menuitem;
891

    
892
                if (cond_type == PF_COND_SIZE || cond_type == PF_COND_AGE) {
893
                        gtk_spin_button_set_value
894
                                (GTK_SPIN_BUTTON(hbox->spin_btn),
895
                                 (gfloat)cond->int_value);
896
                } else {
897
                        gtk_entry_set_text(GTK_ENTRY(hbox->key_entry),
898
                                           cond->str_value ?
899
                                           cond->str_value : "");
900
                }
901
                gtk_option_menu_set_history(cond_type_optmenu, cond_index);
902
                menuitem = gtk_menu_get_active
903
                        (GTK_MENU(gtk_option_menu_get_menu(cond_type_optmenu)));
904
                gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
905
        }
906

    
907
        match_index = menu_find_option_menu_index
908
                (match_type_optmenu, GINT_TO_POINTER(match_type), NULL);
909
        if (match_index >= 0)
910
                gtk_option_menu_set_history(match_type_optmenu, match_index);
911
        if (cond_type == PF_COND_SIZE)
912
                gtk_option_menu_set_history
913
                        (GTK_OPTION_MENU(hbox->size_match_optmenu), size_type);
914
        else if (cond_type == PF_COND_AGE)
915
                gtk_option_menu_set_history
916
                        (GTK_OPTION_MENU(hbox->age_match_optmenu), age_type);
917
        else if (cond_type == PF_COND_UNREAD || cond_type == PF_COND_MARK ||
918
                 cond_type == PF_COND_COLOR_LABEL || cond_type == PF_COND_MIME)
919
                gtk_option_menu_set_history
920
                        (GTK_OPTION_MENU(hbox->status_match_optmenu),
921
                         status_type);
922

    
923
        if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
924
            match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
925
                gtk_widget_hide(hbox->key_entry);
926
}
927

    
928
void prefs_filter_edit_action_hbox_set(ActionHBox *hbox, FilterAction *action)
929
{
930
        GtkOptionMenu *type_optmenu = GTK_OPTION_MENU(hbox->action_type_optmenu);
931
        GtkWidget *menu;
932
        ActionMenuType type = PF_ACTION_NONE;
933

    
934
        menu = gtk_option_menu_get_menu(type_optmenu);
935

    
936
        switch (action->type) {
937
        case FLT_ACTION_MOVE:
938
                type = PF_ACTION_MOVE; break;
939
        case FLT_ACTION_COPY:
940
                type = PF_ACTION_COPY; break;
941
        case FLT_ACTION_NOT_RECEIVE:
942
                type = PF_ACTION_NOT_RECEIVE; break;
943
        case FLT_ACTION_DELETE:
944
                type = PF_ACTION_DELETE; break;
945
        case FLT_ACTION_EXEC:
946
                type = PF_ACTION_EXEC; break;
947
        case FLT_ACTION_MARK:
948
                type = PF_ACTION_MARK; break;
949
        case FLT_ACTION_COLOR_LABEL:
950
                type = PF_ACTION_COLOR_LABEL; break;
951
        case FLT_ACTION_MARK_READ:
952
                type = PF_ACTION_MARK_READ; break;
953
        case FLT_ACTION_STOP_EVAL:
954
                type = PF_ACTION_STOP_EVAL; break;
955
        default:
956
                break;
957
        }
958

    
959
        switch (type) {
960
        case PF_ACTION_MOVE:
961
        case PF_ACTION_COPY:
962
                gtk_entry_set_text(GTK_ENTRY(hbox->folder_entry),
963
                                   action->str_value ? action->str_value : "");
964
                break;
965
        case PF_ACTION_EXEC:
966
                gtk_entry_set_text(GTK_ENTRY(hbox->cmd_entry),
967
                                   action->str_value ? action->str_value : "");
968
                break;
969
        case PF_ACTION_COLOR_LABEL:
970
                gtk_option_menu_set_history
971
                        (GTK_OPTION_MENU(hbox->clabel_optmenu),
972
                         action->int_value - 1);
973
                break;
974
        default:
975
                break;
976
        }
977

    
978
        prefs_filter_edit_set_action_hbox_widgets(hbox, type);
979
}
980

    
981
void prefs_filter_edit_cond_hbox_select(CondHBox *hbox, CondMenuType type,
982
                                        const gchar *header_name)
983
{
984
        gint index;
985
        GtkOptionMenu *cond_type_optmenu =
986
                GTK_OPTION_MENU(hbox->cond_type_optmenu);
987
        GtkWidget *menu;
988

    
989
        if (type == PF_COND_HEADER) {
990
                if (header_name)
991
                        index = procheader_find_header_list
992
                                (hbox->cond_edit->hdr_list, header_name);
993
                else
994
                        index = 0;
995
        } else
996
                index = menu_find_option_menu_index
997
                        (cond_type_optmenu, GINT_TO_POINTER(type), NULL);
998

    
999
        if (index < 0)
1000
                index = 0;
1001

    
1002
        menu = gtk_option_menu_get_menu(cond_type_optmenu);
1003
        gtk_option_menu_set_history(cond_type_optmenu, index);
1004
}
1005

    
1006
void prefs_filter_edit_set_cond_hbox_widgets(CondHBox *hbox, CondMenuType type)
1007
{
1008
        MatchMenuType match_type;
1009

    
1010
        switch (type) {
1011
        case PF_COND_HEADER:
1012
        case PF_COND_TO_OR_CC:
1013
        case PF_COND_ANY_HEADER:
1014
        case PF_COND_BODY:
1015
                gtk_widget_show(hbox->match_type_optmenu);
1016
                gtk_widget_hide(hbox->size_match_optmenu);
1017
                gtk_widget_hide(hbox->age_match_optmenu);
1018
                gtk_widget_hide(hbox->status_match_optmenu);
1019
                match_type = menu_get_option_menu_active_index
1020
                        (GTK_OPTION_MENU(hbox->match_type_optmenu));
1021
                if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
1022
                    match_type == PF_MATCH_NOT_IN_ADDRESSBOOK)
1023
                        gtk_widget_hide(hbox->key_entry);
1024
                else
1025
                        gtk_widget_show(hbox->key_entry);
1026
                gtk_widget_hide(hbox->spin_btn);
1027
                gtk_widget_hide(hbox->label);
1028
                if (type == PF_COND_HEADER || type == PF_COND_TO_OR_CC) {
1029
                        gtk_widget_show(hbox->match_menu_in_addr);
1030
                        gtk_widget_show(hbox->match_menu_not_in_addr);
1031
                } else {
1032
                        gtk_widget_hide(hbox->match_menu_in_addr);
1033
                        gtk_widget_hide(hbox->match_menu_not_in_addr);
1034
                        if (match_type == PF_MATCH_IN_ADDRESSBOOK ||
1035
                            match_type == PF_MATCH_NOT_IN_ADDRESSBOOK) {
1036
                                gtk_option_menu_set_history(GTK_OPTION_MENU(hbox->match_type_optmenu), 0);
1037
                                gtk_widget_show(hbox->key_entry);
1038
                        }
1039
                }
1040
                break;
1041
        case PF_COND_CMD_TEST:
1042
                gtk_widget_hide(hbox->match_type_optmenu);
1043
                gtk_widget_hide(hbox->size_match_optmenu);
1044
                gtk_widget_hide(hbox->age_match_optmenu);
1045
                gtk_widget_hide(hbox->status_match_optmenu);
1046
                gtk_widget_show(hbox->key_entry);
1047
                gtk_widget_hide(hbox->spin_btn);
1048
                gtk_widget_hide(hbox->label);
1049
                break;
1050
        case PF_COND_SIZE:
1051
                gtk_widget_hide(hbox->match_type_optmenu);
1052
                gtk_widget_show(hbox->size_match_optmenu);
1053
                gtk_widget_hide(hbox->age_match_optmenu);
1054
                gtk_widget_hide(hbox->status_match_optmenu);
1055
                gtk_widget_hide(hbox->key_entry);
1056
                gtk_widget_show(hbox->spin_btn);
1057
                gtk_widget_show(hbox->label);
1058
                gtk_label_set_text(GTK_LABEL(hbox->label), _("KB"));
1059
                break;
1060
        case PF_COND_AGE:
1061
                gtk_widget_hide(hbox->match_type_optmenu);
1062
                gtk_widget_hide(hbox->size_match_optmenu);
1063
                gtk_widget_show(hbox->age_match_optmenu);
1064
                gtk_widget_hide(hbox->status_match_optmenu);
1065
                gtk_widget_hide(hbox->key_entry);
1066
                gtk_widget_show(hbox->spin_btn);
1067
                gtk_widget_show(hbox->label);
1068
                gtk_label_set_text(GTK_LABEL(hbox->label), _("day(s)"));
1069
                break;
1070
        case PF_COND_UNREAD:
1071
        case PF_COND_MARK:
1072
        case PF_COND_COLOR_LABEL:
1073
        case PF_COND_MIME:
1074
                gtk_widget_hide(hbox->match_type_optmenu);
1075
                gtk_widget_hide(hbox->size_match_optmenu);
1076
                gtk_widget_hide(hbox->age_match_optmenu);
1077
                gtk_widget_show(hbox->status_match_optmenu);
1078
                gtk_widget_hide(hbox->key_entry);
1079
                gtk_widget_hide(hbox->spin_btn);
1080
                gtk_widget_hide(hbox->label);
1081
                break;
1082
        case PF_COND_ACCOUNT:
1083
                gtk_widget_hide(hbox->match_type_optmenu);
1084
                gtk_widget_hide(hbox->size_match_optmenu);
1085
                gtk_widget_hide(hbox->age_match_optmenu);
1086
                gtk_widget_hide(hbox->status_match_optmenu);
1087
                gtk_widget_hide(hbox->key_entry);
1088
                /* gtk_widget_show(hbox->account_optmenu); */
1089
                gtk_widget_hide(hbox->spin_btn);
1090
                gtk_widget_hide(hbox->label);
1091
                break;
1092
        default:
1093
                break;
1094
        }
1095
}
1096

    
1097
void prefs_filter_edit_set_action_hbox_widgets(ActionHBox *hbox,
1098
                                               ActionMenuType type)
1099
{
1100
        GtkOptionMenu *type_optmenu = GTK_OPTION_MENU(hbox->action_type_optmenu);
1101
        gint index;
1102

    
1103
        switch (type) {
1104
        case PF_ACTION_MOVE:
1105
        case PF_ACTION_COPY:
1106
                gtk_widget_show(hbox->label);
1107
                gtk_label_set_text(GTK_LABEL(hbox->label), _("folder:"));
1108
                gtk_widget_show(hbox->folder_entry);
1109
                gtk_widget_show(hbox->folder_sel_btn);
1110
                gtk_widget_hide(hbox->cmd_entry);
1111
                gtk_widget_hide(hbox->address_entry);
1112
                gtk_widget_hide(hbox->clabel_optmenu);
1113
                break;
1114
        case PF_ACTION_NOT_RECEIVE:
1115
        case PF_ACTION_DELETE:
1116
        case PF_ACTION_MARK:
1117
        case PF_ACTION_MARK_READ:
1118
        case PF_ACTION_STOP_EVAL:
1119
                gtk_widget_hide(hbox->label);
1120
                gtk_widget_hide(hbox->folder_entry);
1121
                gtk_widget_hide(hbox->folder_sel_btn);
1122
                gtk_widget_hide(hbox->cmd_entry);
1123
                gtk_widget_hide(hbox->address_entry);
1124
                gtk_widget_hide(hbox->clabel_optmenu);
1125
                break;
1126
        case PF_ACTION_EXEC:
1127
        case PF_ACTION_EXEC_ASYNC:
1128
                gtk_widget_hide(hbox->label);
1129
                gtk_widget_hide(hbox->folder_entry);
1130
                gtk_widget_hide(hbox->folder_sel_btn);
1131
                gtk_widget_show(hbox->cmd_entry);
1132
                gtk_widget_hide(hbox->address_entry);
1133
                gtk_widget_hide(hbox->clabel_optmenu);
1134
                break;
1135
        case PF_ACTION_COLOR_LABEL:
1136
                gtk_widget_hide(hbox->label);
1137
                gtk_widget_hide(hbox->folder_entry);
1138
                gtk_widget_hide(hbox->folder_sel_btn);
1139
                gtk_widget_hide(hbox->cmd_entry);
1140
                gtk_widget_hide(hbox->address_entry);
1141
                gtk_widget_show(hbox->clabel_optmenu);
1142
                break;
1143
        case PF_ACTION_FORWARD:
1144
        case PF_ACTION_FORWARD_AS_ATTACHMENT:
1145
        case PF_ACTION_REDIRECT:
1146
                gtk_widget_show(hbox->label);
1147
                gtk_label_set_text(GTK_LABEL(hbox->label), _("address:"));
1148
                gtk_widget_hide(hbox->folder_entry);
1149
                gtk_widget_hide(hbox->folder_sel_btn);
1150
                gtk_widget_hide(hbox->cmd_entry);
1151
                gtk_widget_show(hbox->address_entry);
1152
                gtk_widget_hide(hbox->clabel_optmenu);
1153
                break;
1154
        default:
1155
                break;
1156
        }
1157

    
1158
        index = menu_find_option_menu_index(type_optmenu, GINT_TO_POINTER(type),
1159
                                            NULL);
1160
        gtk_option_menu_set_history(type_optmenu, index);
1161
        prefs_filter_edit_set_action_hbox_menus_sensitive();
1162
}
1163

    
1164
static void prefs_filter_edit_set_action_hbox_menu_sensitive
1165
        (ActionHBox *hbox, ActionMenuType type, gboolean sensitive)
1166
{
1167
        GtkWidget *menuitem;
1168

    
1169
        menuitem = hbox->action_type_menu_items[type];
1170
        if (menuitem)
1171
                gtk_widget_set_sensitive(menuitem, sensitive);
1172
}
1173

    
1174
static void prefs_filter_edit_set_action_hbox_menus_sensitive(void)
1175
{
1176
        GSList *cur;
1177
        ActionHBox *cur_hbox;
1178
        ActionMenuType menu_type;
1179
        ActionMenuType cur_type;
1180
        gboolean action_menu_selection[PF_ACTION_NONE];
1181
        gboolean action_menu_sensitive[PF_ACTION_NONE];
1182

    
1183
        prefs_filter_edit_get_action_hbox_menus_selection
1184
                (action_menu_selection);
1185

    
1186
        for (cur = rule_edit_window.action_hbox_list; cur != NULL;
1187
             cur = cur->next) {
1188
                cur_hbox = (ActionHBox *)cur->data;
1189
                menu_type = prefs_filter_edit_get_action_hbox_type(cur_hbox);
1190
                for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1191
                     cur_type++)
1192
                        action_menu_sensitive[cur_type] = TRUE;
1193

    
1194
                for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1195
                     cur_type++) {
1196
                        switch (cur_type) {
1197
                        case PF_ACTION_MOVE:
1198
                        case PF_ACTION_NOT_RECEIVE:
1199
                        case PF_ACTION_DELETE:
1200
                                if (action_menu_selection[cur_type] == TRUE &&
1201
                                    menu_type != cur_type) {
1202
                                        action_menu_sensitive[PF_ACTION_MOVE] = FALSE;
1203
                                        action_menu_sensitive[PF_ACTION_NOT_RECEIVE] = FALSE;
1204
                                        action_menu_sensitive[PF_ACTION_DELETE] = FALSE;
1205
                                }
1206
                                break;
1207
                        case PF_ACTION_MARK:
1208
                        case PF_ACTION_COLOR_LABEL:
1209
                        case PF_ACTION_MARK_READ:
1210
                        case PF_ACTION_STOP_EVAL:
1211
                                if (action_menu_selection[cur_type] == TRUE &&
1212
                                    menu_type != cur_type)
1213
                                        action_menu_sensitive[cur_type] = FALSE;
1214
                                break;
1215
                        default:
1216
                                break;
1217
                        }
1218
                }
1219

    
1220
                for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE;
1221
                     cur_type++) {
1222
                        prefs_filter_edit_set_action_hbox_menu_sensitive
1223
                                (cur_hbox, cur_type,
1224
                                 action_menu_sensitive[cur_type]);
1225
                }
1226
        }
1227
}
1228

    
1229
static void prefs_filter_edit_get_action_hbox_menus_selection(gboolean *selection)
1230
{
1231
        GSList *cur;
1232
        ActionHBox *cur_hbox;
1233
        ActionMenuType menu_type;
1234
        ActionMenuType cur_type;
1235

    
1236
        for (cur_type = PF_ACTION_MOVE; cur_type < PF_ACTION_NONE; cur_type++)
1237
                selection[cur_type] = FALSE;
1238

    
1239
        for (cur = rule_edit_window.action_hbox_list; cur != NULL;
1240
             cur = cur->next) {
1241
                cur_hbox = (ActionHBox *)cur->data;
1242
                menu_type = prefs_filter_edit_get_action_hbox_type(cur_hbox);
1243
                if (menu_type >= PF_ACTION_MOVE && menu_type < PF_ACTION_NONE)
1244
                        selection[menu_type] = TRUE;
1245
        }
1246
}
1247

    
1248
static ActionMenuType prefs_filter_edit_get_action_hbox_type(ActionHBox *hbox)
1249
{
1250
        GtkWidget *menuitem;
1251
        ActionMenuType type;
1252

    
1253
        g_return_val_if_fail(hbox != NULL, PF_ACTION_NONE);
1254

    
1255
        menuitem = gtk_menu_get_active
1256
                (GTK_MENU(gtk_option_menu_get_menu
1257
                        (GTK_OPTION_MENU(hbox->action_type_optmenu))));
1258
        type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem),
1259
                                                 MENU_VAL_ID));
1260

    
1261
        return type;
1262
}
1263

    
1264
void prefs_filter_edit_insert_cond_hbox(FilterCondEdit *cond_edit,
1265
                                        CondHBox *hbox, gint pos)
1266
{
1267
        g_return_if_fail(cond_edit != NULL);
1268
        g_return_if_fail(hbox != NULL);
1269

    
1270
        if (!cond_edit->cond_hbox_list) {
1271
                gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1272
        } else if (cond_edit->cond_hbox_list &&
1273
                   !cond_edit->cond_hbox_list->next) {
1274
                CondHBox *top_hbox =
1275
                        (CondHBox *)cond_edit->cond_hbox_list->data;
1276
                gtk_widget_set_sensitive(top_hbox->del_btn, TRUE);
1277
        }
1278

    
1279
        gtk_box_pack_start(GTK_BOX(cond_edit->cond_vbox),
1280
                           hbox->hbox, FALSE, FALSE, 0);
1281
        if (pos >= 0) {
1282
                gtk_box_reorder_child(GTK_BOX(cond_edit->cond_vbox),
1283
                                      hbox->hbox, pos);
1284
        }
1285

    
1286
        cond_edit->cond_hbox_list =
1287
                g_slist_insert(cond_edit->cond_hbox_list, hbox, pos);
1288
}
1289

    
1290
static void prefs_filter_edit_insert_action_hbox(ActionHBox *hbox, gint pos)
1291
{
1292
        g_return_if_fail(hbox != NULL);
1293

    
1294
        if (!rule_edit_window.action_hbox_list) {
1295
                gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1296
        } else if (rule_edit_window.action_hbox_list &&
1297
                   !rule_edit_window.action_hbox_list->next) {
1298
                ActionHBox *top_hbox =
1299
                        (ActionHBox *)rule_edit_window.action_hbox_list->data;
1300
                gtk_widget_set_sensitive(top_hbox->del_btn, TRUE);
1301
        }
1302

    
1303
        gtk_box_pack_start(GTK_BOX(rule_edit_window.action_vbox),
1304
                           hbox->hbox, FALSE, FALSE, 0);
1305
        if (pos >= 0) {
1306
                gtk_box_reorder_child(GTK_BOX(rule_edit_window.action_vbox),
1307
                                      hbox->hbox, pos);
1308
        }
1309

    
1310
        rule_edit_window.action_hbox_list =
1311
                g_slist_insert(rule_edit_window.action_hbox_list, hbox, pos);
1312
}
1313

    
1314
static void prefs_filter_edit_remove_cond_hbox(FilterCondEdit *cond_edit,
1315
                                               CondHBox *hbox)
1316
{
1317
        g_return_if_fail(cond_edit != NULL);
1318
        g_return_if_fail(hbox != NULL);
1319
        g_return_if_fail(cond_edit->cond_hbox_list != NULL);
1320

    
1321
        cond_edit->cond_hbox_list =
1322
                g_slist_remove(cond_edit->cond_hbox_list, hbox);
1323
        gtk_widget_destroy(hbox->hbox);
1324
        g_free(hbox);
1325

    
1326
        if (cond_edit->cond_hbox_list && !cond_edit->cond_hbox_list->next) {
1327
                hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
1328
                gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1329
        }
1330
}
1331

    
1332
static void prefs_filter_edit_remove_action_hbox(ActionHBox *hbox)
1333
{
1334
        g_return_if_fail(hbox != NULL);
1335
        g_return_if_fail(rule_edit_window.action_hbox_list != NULL);
1336

    
1337
        rule_edit_window.action_hbox_list =
1338
                g_slist_remove(rule_edit_window.action_hbox_list, hbox);
1339
        gtk_widget_destroy(hbox->hbox);
1340
        g_free(hbox);
1341

    
1342
        prefs_filter_edit_set_action_hbox_menus_sensitive();
1343

    
1344
        if (rule_edit_window.action_hbox_list &&
1345
            !rule_edit_window.action_hbox_list->next) {
1346
                hbox = (ActionHBox *)rule_edit_window.action_hbox_list->data;
1347
                gtk_widget_set_sensitive(hbox->del_btn, FALSE);
1348
        }
1349
}
1350

    
1351
void prefs_filter_edit_add_rule_cond(FilterCondEdit *cond_edit,
1352
                                     FilterRule *rule)
1353
{
1354
        CondHBox *hbox;
1355
        GSList *cur;
1356
        FilterCond *cond;
1357

    
1358
        if (!rule || !rule->cond_list) {
1359
                hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
1360
                prefs_filter_edit_set_cond_hbox_widgets(hbox, PF_COND_HEADER);
1361
                prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
1362
                if (cond_edit->add_hbox)
1363
                        cond_edit->add_hbox(hbox);
1364
                return;
1365
        }
1366

    
1367
        for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
1368
                cond = (FilterCond *)cur->data;
1369

    
1370
                hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
1371
                prefs_filter_edit_cond_hbox_set(hbox, cond);
1372
                prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
1373
                if (cond_edit->add_hbox)
1374
                        cond_edit->add_hbox(hbox);
1375
        }
1376
}
1377

    
1378
static void prefs_filter_edit_add_rule_action(FilterRule *rule)
1379
{
1380
        ActionHBox *hbox;
1381
        GSList *cur;
1382

    
1383
        if (!rule || !rule->action_list) {
1384
                hbox = prefs_filter_edit_action_hbox_create();
1385
                prefs_filter_edit_insert_action_hbox(hbox, -1);
1386
                prefs_filter_edit_set_action_hbox_widgets(hbox, PF_ACTION_MOVE);
1387
                return;
1388
        }
1389

    
1390
        for (cur = rule->action_list; cur != NULL; cur = cur->next) {
1391
                FilterAction *action = (FilterAction *)cur->data;
1392

    
1393
                hbox = prefs_filter_edit_action_hbox_create();
1394
                prefs_filter_edit_insert_action_hbox(hbox, -1);
1395
                prefs_filter_edit_action_hbox_set(hbox, action);
1396
        }
1397
}
1398

    
1399
static void prefs_filter_edit_set_cond_header_menu(FilterCondEdit *cond_edit,
1400
                                                   CondHBox *hbox)
1401
{
1402
        GSList *cur;
1403
        GtkWidget *menu;
1404
        GtkWidget *menuitem;
1405
        gint pos = 0;
1406
        GList *child;
1407

    
1408
        menu = gtk_option_menu_get_menu
1409
                (GTK_OPTION_MENU(hbox->cond_type_optmenu));
1410

    
1411
        /* destroy header items */
1412
        child = GTK_MENU_SHELL(menu)->children;
1413
        while (child != NULL) {
1414
                GList *next = child->next;
1415
                menuitem = GTK_WIDGET(child->data);
1416
                if (!g_object_get_data(G_OBJECT(menuitem), "header_str"))
1417
                        break;
1418
                gtk_widget_destroy(menuitem);
1419
                child = next;
1420
        }
1421

    
1422
        for (cur = cond_edit->hdr_list; cur != NULL; cur = cur->next, pos++) {
1423
                Header *header = (Header *)cur->data;
1424

    
1425
                menuitem = gtk_menu_item_new_with_label(header->name);
1426
                gtk_widget_show(menuitem);
1427
                gtk_menu_insert(GTK_MENU(menu), menuitem, pos);
1428
                g_object_set_data(G_OBJECT(menuitem), MENU_VAL_ID,
1429
                                  GINT_TO_POINTER(PF_COND_HEADER));
1430
                g_object_set_data(G_OBJECT(menuitem), "header_str",
1431
                                  header->name);
1432
                g_signal_connect(G_OBJECT(menuitem), "activate",
1433
                                 G_CALLBACK(prefs_filter_cond_activated_cb),
1434
                                 hbox);
1435
        }
1436

    
1437
        if (hbox->cur_type == PF_COND_HEADER)
1438
                prefs_filter_edit_cond_hbox_select
1439
                        (hbox, hbox->cur_type, hbox->cur_header_name);
1440
}
1441

    
1442
static void prefs_filter_edit_activate_cond_header(FilterCondEdit *cond_edit,
1443
                                                   const gchar *header)
1444
{
1445
        gint index;
1446
        CondHBox *hbox;
1447
        GtkWidget *menu;
1448
        GtkWidget *menuitem;
1449
        GList *cur;
1450
        gchar *menu_header;
1451

    
1452
        g_return_if_fail(header != NULL);
1453
        g_return_if_fail(cond_edit != NULL);
1454
        g_return_if_fail(cond_edit->cond_hbox_list != NULL);
1455

    
1456
        hbox = (CondHBox *)cond_edit->cond_hbox_list->data;
1457
        menu = gtk_option_menu_get_menu
1458
                (GTK_OPTION_MENU(hbox->cond_type_optmenu));
1459

    
1460
        for (cur = GTK_MENU_SHELL(menu)->children, index = 0;
1461
             cur != NULL; cur = cur->next, index++) {
1462
                menuitem = GTK_WIDGET(cur->data);
1463
                menu_header = g_object_get_data(G_OBJECT(menuitem),
1464
                                                "header_str");
1465
                if (!menu_header)
1466
                        break;
1467
                if (!g_ascii_strcasecmp(menu_header, header)) {
1468
                        gtk_option_menu_set_history
1469
                                (GTK_OPTION_MENU(hbox->cond_type_optmenu),
1470
                                 index);
1471
                        gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
1472
                        break;
1473
                }
1474
        }
1475
}
1476

    
1477
static gint edit_header_list_dialog_deleted(GtkWidget *widget,
1478
                                            GdkEventAny *event, gpointer data)
1479
{
1480
        edit_header_list_dialog.finished = TRUE;
1481
        return TRUE;
1482
}
1483

    
1484
static gboolean edit_header_list_dialog_key_pressed(GtkWidget *widget,
1485
                                                    GdkEventKey *event,
1486
                                                    gpointer data)
1487
{
1488
        if (event && event->keyval == GDK_Escape)
1489
                edit_header_list_dialog.finished = TRUE;
1490
        return FALSE;
1491
}
1492

    
1493
static void edit_header_list_dialog_add(void)
1494
{
1495
        GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1496
        const gchar *text;
1497
        gchar *ctext[1];
1498
        gint row;
1499
        gchar *row_text;
1500

    
1501
        text = gtk_entry_get_text(GTK_ENTRY(edit_header_list_dialog.entry));
1502
        if (text[0] == '\0') return;
1503

    
1504
        for (row = 0; gtk_clist_get_text(clist, row, 0, &row_text) != 0;
1505
             row++) {
1506
                if (g_ascii_strcasecmp(row_text, text) == 0) return;
1507
        }
1508

    
1509
        ctext[0] = (gchar *)text;
1510
        gtk_clist_append(clist, ctext);
1511
}
1512

    
1513
static void edit_header_list_dialog_delete(void)
1514
{
1515
        GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1516
        gint row;
1517

    
1518
        if (!clist->selection) return;
1519

    
1520
        row = GPOINTER_TO_INT(clist->selection->data);
1521
        gtk_clist_remove(clist, row);
1522
}
1523

    
1524
static void edit_header_list_dialog_ok(void)
1525
{
1526
        edit_header_list_dialog.finished = TRUE;
1527
        edit_header_list_dialog.ok = TRUE;
1528
}
1529

    
1530
static void edit_header_list_dialog_cancel(void)
1531
{
1532
        edit_header_list_dialog.finished = TRUE;
1533
}
1534

    
1535
static void prefs_filter_edit_edit_header_list_dialog_create(void)
1536
{
1537
        GtkWidget *window;
1538
        GtkWidget *vbox;
1539
        GtkWidget *hbox;
1540

    
1541
        GtkWidget *vbox2;
1542
        GtkWidget *scrwin;
1543
        GtkWidget *clist;
1544

    
1545
        GtkWidget *entry_hbox;
1546
        GtkWidget *label;
1547
        GtkWidget *entry;
1548

    
1549
        GtkWidget *btn_vbox;
1550
        GtkWidget *add_btn;
1551
        GtkWidget *del_btn;
1552

    
1553
        GtkWidget *confirm_area;
1554
        GtkWidget *ok_btn;
1555
        GtkWidget *cancel_btn;
1556

    
1557
        gchar *title[1];
1558

    
1559
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1560
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
1561
        gtk_window_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
1562
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
1563
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
1564
        gtk_window_set_title(GTK_WINDOW(window), _("Edit header list"));
1565

    
1566
        g_signal_connect(G_OBJECT(window), "delete_event",
1567
                         G_CALLBACK(edit_header_list_dialog_deleted), NULL);
1568
        g_signal_connect(G_OBJECT(window), "key_press_event",
1569
                         G_CALLBACK(edit_header_list_dialog_key_pressed), NULL);
1570

    
1571
        vbox = gtk_vbox_new(FALSE, 6);
1572
        gtk_container_add(GTK_CONTAINER(window), vbox);
1573

    
1574
        hbox = gtk_hbox_new(FALSE, 8);
1575
        gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
1576

    
1577
        vbox2 = gtk_vbox_new(FALSE, 8);
1578
        gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
1579

    
1580
        scrwin = gtk_scrolled_window_new(NULL, NULL);
1581
        gtk_widget_set_size_request(scrwin, 120, 160);
1582
        gtk_box_pack_start(GTK_BOX(vbox2), scrwin, TRUE, TRUE, 0);
1583
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
1584
                                       GTK_POLICY_AUTOMATIC,
1585
                                       GTK_POLICY_AUTOMATIC);
1586

    
1587
        title[0] = _("Headers");
1588
        clist = gtk_clist_new_with_titles(1, title);
1589
        gtk_container_add(GTK_CONTAINER(scrwin), clist);
1590
        gtk_clist_set_column_width(GTK_CLIST(clist), 0, 80);
1591
        gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE);
1592
        gtkut_clist_set_redraw(GTK_CLIST(clist));
1593
        GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(clist)->column[0].button,
1594
                               GTK_CAN_FOCUS);
1595

    
1596
        entry_hbox = gtk_hbox_new(FALSE, 8);
1597
        gtk_box_pack_start(GTK_BOX(vbox), entry_hbox, FALSE, TRUE, 0);
1598

    
1599
        label = gtk_label_new(_("Header:"));
1600
        gtk_box_pack_start(GTK_BOX(entry_hbox), label, FALSE, FALSE, 0);
1601

    
1602
        entry = gtk_entry_new();
1603
        gtk_box_pack_start(GTK_BOX(entry_hbox), entry, TRUE, TRUE, 0);
1604

    
1605
        btn_vbox = gtk_vbox_new(FALSE, 8);
1606
        gtk_box_pack_start(GTK_BOX(hbox), btn_vbox, FALSE, FALSE, 0);
1607

    
1608
        add_btn = gtk_button_new_with_label(_("Add"));
1609
        gtk_box_pack_start(GTK_BOX(btn_vbox), add_btn, FALSE, FALSE, 0);
1610

    
1611
        del_btn = gtk_button_new_with_label(_(" Delete "));
1612
        gtk_box_pack_start(GTK_BOX(btn_vbox), del_btn, FALSE, FALSE, 0);
1613

    
1614
        gtkut_stock_button_set_create(&confirm_area, &ok_btn, GTK_STOCK_OK,
1615
                                      &cancel_btn, GTK_STOCK_CANCEL,
1616
                                      NULL, NULL);
1617
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
1618
        gtk_widget_grab_default(ok_btn);
1619

    
1620
        g_signal_connect(G_OBJECT(add_btn), "clicked",
1621
                         G_CALLBACK(edit_header_list_dialog_add), NULL);
1622
        g_signal_connect(G_OBJECT(del_btn), "clicked",
1623
                         G_CALLBACK(edit_header_list_dialog_delete), NULL);
1624
        g_signal_connect(G_OBJECT(ok_btn), "clicked",
1625
                         G_CALLBACK(edit_header_list_dialog_ok), NULL);
1626
        g_signal_connect(G_OBJECT(cancel_btn), "clicked",
1627
                         G_CALLBACK(edit_header_list_dialog_cancel), NULL);
1628

    
1629
        manage_window_set_transient(GTK_WINDOW(window));
1630

    
1631
        gtk_widget_show_all(window);
1632

    
1633
        edit_header_list_dialog.window = window;
1634
        edit_header_list_dialog.clist = clist;
1635
        edit_header_list_dialog.entry = entry;
1636
        edit_header_list_dialog.finished = FALSE;
1637
        edit_header_list_dialog.ok = FALSE;
1638
}
1639

    
1640
static void prefs_filter_edit_edit_header_list_dialog_set(void)
1641
{
1642
        GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1643
        GSList *list;
1644
        GSList *cur;
1645
        gchar *text[1];
1646

    
1647
        gtk_clist_freeze(clist);
1648

    
1649
        list = prefs_filter_get_user_header_list();
1650
        for (cur = list; cur != NULL; cur = cur->next) {
1651
                Header *header = (Header *)cur->data;
1652
                text[0] = header->name;
1653
                gtk_clist_append(clist, text);
1654
        }
1655

    
1656
        gtk_clist_thaw(clist);
1657
}
1658

    
1659
static GSList *prefs_filter_edit_edit_header_list_dialog_get(void)
1660
{
1661
        GtkCList *clist = GTK_CLIST(edit_header_list_dialog.clist);
1662
        gint row;
1663
        gchar *text;
1664
        GSList *list = NULL;
1665

    
1666
        for (row = 0; gtk_clist_get_text(clist, row, 0, &text) != 0; row++)
1667
                list = procheader_add_header_list(list, text, NULL);
1668

    
1669
        return list;
1670
}
1671

    
1672
static void prefs_filter_edit_edit_header_list(FilterCondEdit *cond_edit)
1673
{
1674
        GSList *list;
1675
        GSList *cur;
1676

    
1677
        prefs_filter_edit_edit_header_list_dialog_create();
1678
        prefs_filter_edit_edit_header_list_dialog_set();
1679

    
1680
        while (edit_header_list_dialog.finished == FALSE)
1681
                gtk_main_iteration();
1682

    
1683
        if (edit_header_list_dialog.ok == TRUE) {
1684
                list = prefs_filter_edit_edit_header_list_dialog_get();
1685
                prefs_filter_set_user_header_list(list);
1686
                prefs_filter_edit_update_header_list(cond_edit);
1687
                for (cur = cond_edit->cond_hbox_list; cur != NULL;
1688
                     cur = cur->next) {
1689
                        CondHBox *hbox = (CondHBox *)cur->data;
1690
                        prefs_filter_edit_set_cond_header_menu(cond_edit, hbox);
1691
                }
1692
                prefs_filter_write_user_header_list();
1693
        }
1694

    
1695
        gtk_widget_destroy(edit_header_list_dialog.window);
1696
        edit_header_list_dialog.window = NULL;
1697
        edit_header_list_dialog.clist = NULL;
1698
        edit_header_list_dialog.entry = NULL;
1699
        edit_header_list_dialog.finished = FALSE;
1700
        edit_header_list_dialog.ok = FALSE;
1701
}
1702

    
1703
FilterCond *prefs_filter_edit_cond_hbox_to_cond(CondHBox *hbox,
1704
                                                gboolean case_sens,
1705
                                                gchar **error_msg)
1706
{
1707
        FilterCond *cond = NULL;
1708
        GtkWidget *cond_type_menuitem;
1709
        CondMenuType cond_menu_type;
1710
        MatchMenuType match_menu_type;
1711
        const gchar *header_name;
1712
        const gchar *key_str;
1713
        gint int_value;
1714
        FilterMatchType match_type = FLT_CONTAIN;
1715
        FilterMatchFlag match_flag = 0;
1716
        SizeMatchType size_type;
1717
        AgeMatchType age_type;
1718
        StatusMatchType status_type;
1719
        gchar *error_msg_ = NULL;
1720

    
1721
        cond_type_menuitem = gtk_menu_get_active
1722
                (GTK_MENU(gtk_option_menu_get_menu
1723
                        (GTK_OPTION_MENU(hbox->cond_type_optmenu))));
1724
        cond_menu_type = GPOINTER_TO_INT
1725
                (g_object_get_data(G_OBJECT(cond_type_menuitem), MENU_VAL_ID));
1726

    
1727
        match_menu_type = menu_get_option_menu_active_index
1728
                (GTK_OPTION_MENU(hbox->match_type_optmenu));
1729

    
1730
        key_str = gtk_entry_get_text(GTK_ENTRY(hbox->key_entry));
1731

    
1732
        switch (match_menu_type) {
1733
        case PF_MATCH_CONTAIN:
1734
                match_type = FLT_CONTAIN;
1735
                break;
1736
        case PF_MATCH_NOT_CONTAIN:
1737
                match_type = FLT_CONTAIN;
1738
                match_flag |= FLT_NOT_MATCH;
1739
                break;
1740
        case PF_MATCH_EQUAL:
1741
                match_type = FLT_EQUAL;
1742
                break;
1743
        case PF_MATCH_NOT_EQUAL:
1744
                match_type = FLT_EQUAL;
1745
                match_flag |= FLT_NOT_MATCH;
1746
                break;
1747
        case PF_MATCH_REGEX:
1748
                match_type = FLT_REGEX;
1749
                break;
1750
        case PF_MATCH_NOT_REGEX:
1751
                match_type = FLT_REGEX;
1752
                match_flag |= FLT_NOT_MATCH;
1753
                break;
1754
        case PF_MATCH_IN_ADDRESSBOOK:
1755
                match_type = FLT_IN_ADDRESSBOOK;
1756
                break;
1757
        case PF_MATCH_NOT_IN_ADDRESSBOOK:
1758
                match_type = FLT_IN_ADDRESSBOOK;
1759
                match_flag |= FLT_NOT_MATCH;
1760
                break;
1761
        default:
1762
                break;
1763
        }
1764

    
1765
        if (case_sens)
1766
                match_flag |= FLT_CASE_SENS;
1767

    
1768
        switch (cond_menu_type) {
1769
        case PF_COND_HEADER:
1770
                header_name = g_object_get_data
1771
                        (G_OBJECT(cond_type_menuitem), "header_str");
1772
                cond = filter_cond_new(FLT_COND_HEADER,
1773
                                       match_type, match_flag,
1774
                                       header_name, key_str);
1775
                break;
1776
        case PF_COND_TO_OR_CC:
1777
                cond = filter_cond_new(FLT_COND_TO_OR_CC, match_type,
1778
                                       match_flag, NULL, key_str);
1779
                break;
1780
        case PF_COND_ANY_HEADER:
1781
                cond = filter_cond_new(FLT_COND_ANY_HEADER, match_type,
1782
                                       match_flag, NULL, key_str);
1783
                break;
1784
        case PF_COND_BODY:
1785
                cond = filter_cond_new(FLT_COND_BODY, match_type,
1786
                                       match_flag, NULL, key_str);
1787
                break;
1788
        case PF_COND_CMD_TEST:
1789
                if (key_str && *key_str)
1790
                        cond = filter_cond_new(FLT_COND_CMD_TEST,
1791
                                               0, 0, NULL, key_str);
1792
                else
1793
                        error_msg_ = _("Command is not specified.");
1794
                break;
1795
        case PF_COND_SIZE:
1796
                size_type = menu_get_option_menu_active_index
1797
                         (GTK_OPTION_MENU(hbox->size_match_optmenu));
1798
                match_flag = size_type == PF_SIZE_LARGER ? 0 : FLT_NOT_MATCH;
1799
                int_value = gtk_spin_button_get_value_as_int
1800
                        (GTK_SPIN_BUTTON(hbox->spin_btn));
1801
                cond = filter_cond_new(FLT_COND_SIZE_GREATER,
1802
                                       0, match_flag, NULL, itos(int_value));
1803
                break;
1804
        case PF_COND_AGE:
1805
                age_type = menu_get_option_menu_active_index
1806
                         (GTK_OPTION_MENU(hbox->age_match_optmenu));
1807
                match_flag = age_type == PF_AGE_LONGER ? 0 : FLT_NOT_MATCH;
1808
                int_value = gtk_spin_button_get_value_as_int
1809
                        (GTK_SPIN_BUTTON(hbox->spin_btn));
1810
                cond = filter_cond_new(FLT_COND_AGE_GREATER,
1811
                                       0, match_flag, NULL, itos(int_value));
1812
                break;
1813
        case PF_COND_UNREAD:
1814
                status_type = menu_get_option_menu_active_index
1815
                        (GTK_OPTION_MENU(hbox->status_match_optmenu));
1816
                match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1817
                cond = filter_cond_new(FLT_COND_UNREAD, 0, match_flag,
1818
                                       NULL, NULL);
1819
                break;
1820
        case PF_COND_MARK:
1821
                status_type = menu_get_option_menu_active_index
1822
                        (GTK_OPTION_MENU(hbox->status_match_optmenu));
1823
                match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1824
                cond = filter_cond_new(FLT_COND_MARK, 0, match_flag,
1825
                                       NULL, NULL);
1826
                break;
1827
        case PF_COND_COLOR_LABEL:
1828
                status_type = menu_get_option_menu_active_index
1829
                        (GTK_OPTION_MENU(hbox->status_match_optmenu));
1830
                match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1831
                cond = filter_cond_new(FLT_COND_COLOR_LABEL, 0, match_flag,
1832
                                       NULL, NULL);
1833
                break;
1834
        case PF_COND_MIME:
1835
                status_type = menu_get_option_menu_active_index
1836
                        (GTK_OPTION_MENU(hbox->status_match_optmenu));
1837
                match_flag = status_type == PF_STATUS_MATCH ? 0 : FLT_NOT_MATCH;
1838
                cond = filter_cond_new(FLT_COND_MIME, 0, match_flag,
1839
                                       NULL, NULL);
1840
                break;
1841
        case PF_COND_ACCOUNT:
1842
        case PF_COND_EDIT_HEADER:
1843
        default:
1844
                break;
1845
        }
1846

    
1847
        if (error_msg)
1848
                *error_msg = error_msg_;
1849

    
1850
        return cond;
1851
}
1852

    
1853
static gboolean check_dest_folder(const gchar *dest, gchar **error_msg)
1854
{
1855
        FolderItem *item;
1856

    
1857
        if (!dest || *dest == '\0') {
1858
                *error_msg = _("Destination folder is not specified.");
1859
                return FALSE;
1860
        }
1861

    
1862
        item = folder_find_item_from_identifier(dest);
1863
        if (!item || !item->path || !item->parent) {
1864
                *error_msg = _("The specified destination folder does not exist.");
1865
                return FALSE;
1866
        }
1867

    
1868
        return TRUE;
1869
}
1870

    
1871
FilterAction *prefs_filter_edit_action_hbox_to_action(ActionHBox *hbox,
1872
                                                      gchar **error_msg)
1873
{
1874
        FilterAction *action = NULL;
1875
        ActionMenuType action_menu_type;
1876
        const gchar *str;
1877
        guint color;
1878
        gchar *error_msg_ = NULL;
1879

    
1880
        action_menu_type = prefs_filter_edit_get_action_hbox_type(hbox);
1881

    
1882
        switch (action_menu_type) {
1883
        case PF_ACTION_MOVE:
1884
                str = gtk_entry_get_text(GTK_ENTRY(hbox->folder_entry));
1885
                if (check_dest_folder(str, &error_msg_))
1886
                        action = filter_action_new(FLT_ACTION_MOVE, str);
1887
                break;
1888
        case PF_ACTION_COPY:
1889
                str = gtk_entry_get_text(GTK_ENTRY(hbox->folder_entry));
1890
                if (check_dest_folder(str, &error_msg_))
1891
                        action = filter_action_new(FLT_ACTION_COPY, str);
1892
                break;
1893
        case PF_ACTION_NOT_RECEIVE:
1894
                action = filter_action_new(FLT_ACTION_NOT_RECEIVE, NULL);
1895
                break;
1896
        case PF_ACTION_DELETE:
1897
                action = filter_action_new(FLT_ACTION_DELETE, NULL);
1898
                break;
1899
        case PF_ACTION_EXEC:
1900
                str = gtk_entry_get_text(GTK_ENTRY(hbox->cmd_entry));
1901
                if (str && *str)
1902
                        action = filter_action_new(FLT_ACTION_EXEC, str);
1903
                else
1904
                        error_msg_ = _("Command is not specified.");
1905
                break;
1906
        case PF_ACTION_EXEC_ASYNC:
1907
                str = gtk_entry_get_text(GTK_ENTRY(hbox->cmd_entry));
1908
                if (str && *str)
1909
                        action = filter_action_new(FLT_ACTION_EXEC_ASYNC, str);
1910
                else
1911
                        error_msg_ = _("Command is not specified.");
1912
                break;
1913
        case PF_ACTION_MARK:
1914
                action = filter_action_new(FLT_ACTION_MARK, NULL);
1915
                break;
1916
        case PF_ACTION_COLOR_LABEL:
1917
                color = colorlabel_get_color_menu_active_item
1918
                        (gtk_option_menu_get_menu
1919
                         (GTK_OPTION_MENU(hbox->clabel_optmenu)));
1920
                action = filter_action_new(FLT_ACTION_COLOR_LABEL,
1921
                                           itos(color));
1922
                break;
1923
        case PF_ACTION_MARK_READ:
1924
                action = filter_action_new(FLT_ACTION_MARK_READ, NULL);
1925
                break;
1926
        case PF_ACTION_FORWARD:
1927
        case PF_ACTION_FORWARD_AS_ATTACHMENT:
1928
        case PF_ACTION_REDIRECT:
1929
                break;
1930
        case PF_ACTION_STOP_EVAL:
1931
                action = filter_action_new(FLT_ACTION_STOP_EVAL, NULL);
1932
                break;
1933
        case PF_ACTION_SEPARATOR:
1934
        default:
1935
                break;
1936
        }
1937

    
1938
        if (error_msg)
1939
                *error_msg = error_msg_;
1940

    
1941
        return action;
1942
}
1943

    
1944
GSList *prefs_filter_edit_cond_edit_to_list(FilterCondEdit *cond_edit,
1945
                                            gboolean case_sens)
1946
{
1947
        GSList *cur;
1948
        FilterCond *cond;
1949
        GSList *cond_list = NULL;
1950

    
1951
        for (cur = cond_edit->cond_hbox_list; cur != NULL; cur = cur->next) {
1952
                CondHBox *hbox = (CondHBox *)cur->data;
1953
                gchar *error_msg;
1954

    
1955
                cond = prefs_filter_edit_cond_hbox_to_cond(hbox, case_sens,
1956
                                                           &error_msg);
1957
                if (cond) {
1958
                        cond_list = g_slist_append(cond_list, cond);
1959
                } else {
1960
                        if (!error_msg)
1961
                                error_msg = _("Invalid condition exists.");
1962
                        alertpanel_error("%s", error_msg);
1963
                        filter_cond_list_free(cond_list);
1964
                        return NULL;
1965
                }
1966
        }
1967

    
1968
        return cond_list;
1969
}
1970

    
1971
static FilterRule *prefs_filter_edit_dialog_to_rule(void)
1972
{
1973
        FilterRule *rule = NULL;
1974
        GSList *cur;
1975
        const gchar *rule_name;
1976
        FilterBoolOp bool_op;
1977
        GSList *cond_list = NULL;
1978
        GSList *action_list = NULL;
1979
        GtkWidget *bool_op_menuitem;
1980
        gchar *error_msg = NULL;
1981

    
1982
        rule_name = gtk_entry_get_text(GTK_ENTRY(rule_edit_window.name_entry));
1983
        if (!rule_name || *rule_name == '\0') {
1984
                error_msg = _("Rule name is not specified.");
1985
                goto error;
1986
        }
1987

    
1988
        bool_op_menuitem = gtk_menu_get_active
1989
                (GTK_MENU(gtk_option_menu_get_menu
1990
                        (GTK_OPTION_MENU(rule_edit_window.bool_op_optmenu))));
1991
        bool_op = GPOINTER_TO_INT
1992
                (g_object_get_data(G_OBJECT(bool_op_menuitem), MENU_VAL_ID));
1993

    
1994
        cond_list = prefs_filter_edit_cond_edit_to_list
1995
                (&rule_edit_window.cond_edit, FALSE);
1996
        if (!cond_list)
1997
                return NULL;
1998

    
1999
        for (cur = rule_edit_window.action_hbox_list; cur != NULL;
2000
             cur = cur->next) {
2001
                ActionHBox *hbox = (ActionHBox *)cur->data;
2002
                FilterAction *action;
2003

    
2004
                action = prefs_filter_edit_action_hbox_to_action(hbox,
2005
                                                                 &error_msg);
2006
                if (action)
2007
                        action_list = g_slist_append(action_list, action);
2008
                else {
2009
                        if (!error_msg)
2010
                                error_msg = _("Invalid action exists.");
2011
                        goto error;
2012
                }
2013
        }
2014

    
2015
error:
2016
        if (error_msg || !cond_list || !action_list) {
2017
                if (!error_msg) {
2018
                        if (!cond_list)
2019
                                error_msg = _("Condition not exist.");
2020
                        else
2021
                                error_msg = _("Action not exist.");
2022
                }
2023
                alertpanel_error("%s", error_msg);
2024
                if (cond_list)
2025
                        filter_cond_list_free(cond_list);
2026
                if (action_list)
2027
                        filter_action_list_free(action_list);
2028
                return NULL;
2029
        }
2030

    
2031
        rule = filter_rule_new(rule_name, bool_op, cond_list, action_list);
2032

    
2033
        return rule;
2034
}
2035

    
2036
/* callback functions */
2037

    
2038
static gint prefs_filter_edit_deleted(GtkWidget *widget, GdkEventAny *event,
2039
                                      gpointer data)
2040
{
2041
        prefs_filter_edit_cancel();
2042
        return TRUE;
2043
}
2044

    
2045
static gboolean prefs_filter_edit_key_pressed(GtkWidget *widget,
2046
                                              GdkEventKey *event,
2047
                                              gpointer data)
2048
{
2049
        if (event && event->keyval == GDK_Escape)
2050
                prefs_filter_edit_cancel();
2051
        return FALSE;
2052
}
2053

    
2054
static void prefs_filter_edit_ok(void)
2055
{
2056
        FilterRule *rule;
2057

    
2058
        rule = prefs_filter_edit_dialog_to_rule();
2059
        if (rule) {
2060
                rule_edit_window.new_rule = rule;
2061
                rule_edit_window.edit_finished = TRUE;
2062
        }
2063
}
2064

    
2065
static void prefs_filter_edit_cancel(void)
2066
{
2067
        rule_edit_window.new_rule = NULL;
2068
        rule_edit_window.edit_finished = TRUE;
2069
}
2070

    
2071
static void prefs_filter_cond_activated_cb(GtkWidget *widget, gpointer data)
2072
{
2073
        CondHBox *hbox = (CondHBox *)data;
2074
        FilterCondEdit *cond_edit = hbox->cond_edit;
2075
        CondMenuType type;
2076

    
2077
        type = GPOINTER_TO_INT
2078
                (g_object_get_data(G_OBJECT(widget), MENU_VAL_ID));
2079

    
2080
        if (type == PF_COND_EDIT_HEADER) {
2081
                prefs_filter_edit_edit_header_list(cond_edit);
2082
                prefs_filter_edit_cond_hbox_select
2083
                        (hbox, hbox->cur_type, hbox->cur_header_name);
2084
        } else {
2085
                hbox->cur_type = type;
2086
                g_free(hbox->cur_header_name);
2087
                hbox->cur_header_name = NULL;
2088

    
2089
                prefs_filter_edit_set_cond_hbox_widgets(hbox, type);
2090
                if (type == PF_COND_HEADER) {
2091
                        gchar *header_name;
2092
                        gchar *header_field;
2093

    
2094
                        header_name = (gchar *)g_object_get_data
2095
                                (G_OBJECT(widget), "header_str");
2096
                        header_field = prefs_filter_get_msg_header_field
2097
                                (header_name);
2098
                        if (header_field)
2099
                                gtk_entry_set_text(GTK_ENTRY(hbox->key_entry),
2100
                                                   header_field);
2101
                        hbox->cur_header_name = g_strdup(header_name);
2102
                }
2103
        }
2104
}
2105

    
2106
static void prefs_filter_match_activated_cb(GtkWidget *widget, gpointer data)
2107
{
2108
        CondHBox *hbox = (CondHBox *)data;
2109
        GtkWidget *cond_type_menuitem;
2110
        CondMenuType cond_menu_type;
2111

    
2112
        cond_type_menuitem = gtk_menu_get_active
2113
                (GTK_MENU(gtk_option_menu_get_menu
2114
                        (GTK_OPTION_MENU(hbox->cond_type_optmenu))));
2115
        cond_menu_type = GPOINTER_TO_INT
2116
                (g_object_get_data(G_OBJECT(cond_type_menuitem), MENU_VAL_ID));
2117

    
2118
        prefs_filter_edit_set_cond_hbox_widgets(hbox, cond_menu_type);
2119
}
2120

    
2121
static void prefs_filter_action_activated_cb(GtkWidget *widget, gpointer data)
2122
{
2123
        ActionHBox *hbox = (ActionHBox *)data;
2124
        ActionMenuType type;
2125

    
2126
        type = GPOINTER_TO_INT
2127
                (g_object_get_data(G_OBJECT(widget), MENU_VAL_ID));
2128
        prefs_filter_edit_set_action_hbox_widgets(hbox, type);
2129
}
2130

    
2131
static void prefs_filter_action_select_dest_cb(GtkWidget *widget, gpointer data)
2132
{
2133
        ActionHBox *hbox = (ActionHBox *)data;
2134

    
2135
        FolderItem *dest;
2136
        gchar *id;
2137

    
2138
        dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
2139
        if (!dest || !dest->path) return;
2140

    
2141
        id = folder_item_get_identifier(dest);
2142
        if (id) {
2143
                gtk_entry_set_text(GTK_ENTRY(hbox->folder_entry), id);
2144
                g_free(id);
2145
        }
2146
}
2147

    
2148
static void prefs_filter_cond_del_cb(GtkWidget *widget, gpointer data)
2149
{
2150
        CondHBox *hbox = (CondHBox *)data;
2151
        FilterCondEdit *cond_edit = hbox->cond_edit;
2152

    
2153
        if (cond_edit->cond_hbox_list && cond_edit->cond_hbox_list->next)
2154
                prefs_filter_edit_remove_cond_hbox(cond_edit, hbox);
2155
}
2156

    
2157
static void prefs_filter_cond_add_cb(GtkWidget *widget, gpointer data)
2158
{
2159
        CondHBox *hbox = (CondHBox *)data;
2160
        CondHBox *new_hbox;
2161
        FilterCondEdit *cond_edit = hbox->cond_edit;
2162
        gint index;
2163

    
2164
        index = g_slist_index(cond_edit->cond_hbox_list, hbox);
2165
        g_return_if_fail(index >= 0);
2166
        new_hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
2167
        prefs_filter_edit_set_cond_hbox_widgets(new_hbox, PF_COND_HEADER);
2168
        prefs_filter_edit_insert_cond_hbox(cond_edit, new_hbox, index + 1);
2169
        if (cond_edit->add_hbox)
2170
                cond_edit->add_hbox(new_hbox);
2171
}
2172

    
2173
static void prefs_filter_action_del_cb(GtkWidget *widget, gpointer data)
2174
{
2175
        ActionHBox *hbox = (ActionHBox *)data;
2176

    
2177
        if (rule_edit_window.action_hbox_list &&
2178
            rule_edit_window.action_hbox_list->next)
2179
                prefs_filter_edit_remove_action_hbox(hbox);
2180
}
2181

    
2182
static void prefs_filter_action_add_cb(GtkWidget *widget, gpointer data)
2183
{
2184
        ActionHBox *hbox = (ActionHBox *)data;
2185
        ActionHBox *new_hbox;
2186
        gboolean action_menu_selection[PF_ACTION_NONE];
2187
        gint index;
2188

    
2189
        prefs_filter_edit_get_action_hbox_menus_selection(action_menu_selection);
2190

    
2191
        index = g_slist_index(rule_edit_window.action_hbox_list, hbox);
2192
        g_return_if_fail(index >= 0);
2193
        new_hbox = prefs_filter_edit_action_hbox_create();
2194
        prefs_filter_edit_insert_action_hbox(new_hbox, index + 1);
2195
        if (action_menu_selection[PF_ACTION_MOVE] == TRUE ||
2196
            action_menu_selection[PF_ACTION_NOT_RECEIVE] == TRUE ||
2197
            action_menu_selection[PF_ACTION_DELETE] == TRUE)
2198
                prefs_filter_edit_set_action_hbox_widgets(new_hbox,
2199
                                                          PF_ACTION_COPY);
2200
        else
2201
                prefs_filter_edit_set_action_hbox_widgets(new_hbox,
2202
                                                          PF_ACTION_MOVE);
2203
}